Skip to content

Commit

Permalink
Allow player attacks to be parried and fix nail slash hitboxes
Browse files Browse the repository at this point in the history
  • Loading branch information
Extremelyd1 committed Oct 2, 2023
1 parent 55ac9cf commit d5e61ea
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 39 deletions.
15 changes: 11 additions & 4 deletions HKMP/Animation/Effects/CycloneSlash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Hkmp.Animation.Effects;
/// <summary>
/// Animation effect class for the Cyclone Slash ability.
/// </summary>
internal class CycloneSlash : DamageAnimationEffect {
internal class CycloneSlash : ParryableEffect {
/// <inheritdoc/>
public override void Play(GameObject playerObject, bool[] effectInfo) {
// Cancel the nail art charge animation if it exists
Expand Down Expand Up @@ -54,9 +54,16 @@ public override void Play(GameObject playerObject, bool[] effectInfo) {
cycloneSlash.LocateMyFSM("Control Collider").SetState("Init");

var damage = ServerSettings.CycloneSlashDamage;
if (ServerSettings.IsPvpEnabled && ShouldDoDamage && damage != 0) {
hitLComponent.AddComponent<DamageHero>().damageDealt = damage;
hitRComponent.AddComponent<DamageHero>().damageDealt = damage;
if (ServerSettings.IsPvpEnabled) {
if (ServerSettings.AllowParries) {
var fsm = cycloneSlash.AddComponent<PlayMakerFSM>();
fsm.SetFsmTemplate(NailClashTink.FsmTemplate);
}

if (ShouldDoDamage && damage != 0) {
hitLComponent.AddComponent<DamageHero>().damageDealt = damage;
hitRComponent.AddComponent<DamageHero>().damageDealt = damage;
}
}

// As a failsafe, destroy the cyclone slash after 4 seconds
Expand Down
47 changes: 27 additions & 20 deletions HKMP/Animation/Effects/DashSlash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Hkmp.Animation.Effects;
/// <summary>
/// Animation effect class for the Dash Slash ability.
/// </summary>
internal class DashSlash : DamageAnimationEffect {
internal class DashSlash : ParryableEffect {
/// <inheritdoc/>
public override void Play(GameObject playerObject, bool[] effectInfo) {
// Cancel the nail art charge animation if it exists
Expand Down Expand Up @@ -61,25 +61,32 @@ public override void Play(GameObject playerObject, bool[] effectInfo) {
dashSlash.LocateMyFSM("Control Collider").SetState("Init");

var damage = ServerSettings.DashSlashDamage;
if (ServerSettings.IsPvpEnabled && ShouldDoDamage && damage != 0) {
// Somehow adding a DamageHero component simply to the dash slash object doesn't work,
// so we create a separate object for it
var dashSlashCollider = Object.Instantiate(
new GameObject(
"DashSlashCollider",
typeof(PolygonCollider2D),
typeof(DamageHero)
),
dashSlash.transform
);
dashSlashCollider.SetActive(true);
dashSlashCollider.layer = 22;

// Copy over the polygon collider points
dashSlashCollider.GetComponent<PolygonCollider2D>().points =
dashSlash.GetComponent<PolygonCollider2D>().points;

dashSlashCollider.GetComponent<DamageHero>().damageDealt = damage;
if (ServerSettings.IsPvpEnabled) {
if (ServerSettings.AllowParries) {
var fsm = dashSlash.AddComponent<PlayMakerFSM>();
fsm.SetFsmTemplate(NailClashTink.FsmTemplate);
}

if (ShouldDoDamage && damage != 0) {
// Somehow adding a DamageHero component simply to the dash slash object doesn't work,
// so we create a separate object for it
var dashSlashCollider = Object.Instantiate(
new GameObject(
"DashSlashCollider",
typeof(PolygonCollider2D),
typeof(DamageHero)
),
dashSlash.transform
);
dashSlashCollider.SetActive(true);
dashSlashCollider.layer = 22;

// Copy over the polygon collider points
dashSlashCollider.GetComponent<PolygonCollider2D>().points =
dashSlash.GetComponent<PolygonCollider2D>().points;

dashSlashCollider.GetComponent<DamageHero>().damageDealt = damage;
}
}

// Get the animator, figure out the duration of the animation and destroy the object accordingly afterwards
Expand Down
13 changes: 10 additions & 3 deletions HKMP/Animation/Effects/GreatSlash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Hkmp.Animation.Effects;
/// <summary>
/// Animation effect class for the Great Slash ability.
/// </summary>
internal class GreatSlash : DamageAnimationEffect {
internal class GreatSlash : ParryableEffect {
/// <inheritdoc/>
public override void Play(GameObject playerObject, bool[] effectInfo) {
// Cancel the nail art charge animation if it exists
Expand Down Expand Up @@ -47,8 +47,15 @@ public override void Play(GameObject playerObject, bool[] effectInfo) {
greatSlash.LocateMyFSM("Control Collider").SetState("Init");

var damage = ServerSettings.GreatSlashDamage;
if (ServerSettings.IsPvpEnabled && ShouldDoDamage && damage != 0) {
greatSlash.AddComponent<DamageHero>().damageDealt = damage;
if (ServerSettings.IsPvpEnabled) {
if (ServerSettings.AllowParries) {
var fsm = greatSlash.AddComponent<PlayMakerFSM>();
fsm.SetFsmTemplate(NailClashTink.FsmTemplate);
}

if (ShouldDoDamage && damage != 0) {
greatSlash.AddComponent<DamageHero>().damageDealt = damage;
}
}

// Get the animator, figure out the duration of the animation and destroy the object accordingly afterwards
Expand Down
16 changes: 16 additions & 0 deletions HKMP/Animation/Effects/ParryableEffect.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Hkmp.Animation.Effects;

/// <summary>
/// Represents an animation effect that can be parried, such as nail slashes or nail arts.
/// </summary>
internal abstract class ParryableEffect : DamageAnimationEffect {
/// <summary>
/// The FSM for the nail parry effect.
/// </summary>
protected readonly PlayMakerFSM NailClashTink;

protected ParryableEffect() {
var hiveKnightSlash = HkmpMod.PreloadedObjects["Hive_05"]["Battle Scene/Hive Knight/Slash 1"];
NailClashTink = hiveKnightSlash.GetComponent<PlayMakerFSM>();
}
}
46 changes: 36 additions & 10 deletions HKMP/Animation/Effects/SlashBase.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Generic;
using Hkmp.Util;
using HutongGames.PlayMaker.Actions;
using UnityEngine;
Expand All @@ -7,7 +8,18 @@ namespace Hkmp.Animation.Effects;
/// <summary>
/// Abstract base class for the animation effect of nail slashes.
/// </summary>
internal abstract class SlashBase : DamageAnimationEffect {
internal abstract class SlashBase : ParryableEffect {
/// <summary>
/// Base X and Y scales for the various slash types.
/// </summary>
private static readonly Dictionary<SlashType, Vector2> _baseScales = new() {
{ SlashType.Normal, new Vector2(1.6011f, 1.6452f) },
{ SlashType.Alt, new Vector2(1.257f, 1.4224f) },
{ SlashType.Down, new Vector2(1.125f, 1.28f) },
{ SlashType.Up, new Vector2(1.15f, 1.4f) },
{ SlashType.Wall, new Vector2(1.62f, 1.6452f) }
};

/// <inheritdoc/>
public abstract override void Play(GameObject playerObject, bool[] effectInfo);

Expand Down Expand Up @@ -47,6 +59,16 @@ protected void Play(GameObject playerObject, bool[] effectInfo, GameObject prefa
// Instantiate the slash gameObject from the given prefab
// and use the attack gameObject as transform reference
var slash = Object.Instantiate(prefab, playerAttacks.transform);

// Set the base scale of the slash based on the slash type, this prevents remote nail slashes to occur
// larger than they should be if they are based on the prefab from Long Nail/Mark of Pride/both slash
var baseScale = _baseScales[type];
slash.transform.localScale = new Vector3(
baseScale.x,
baseScale.y,
0f
);

// Get the NailSlash component and destroy it, since we don't want to interfere with the local player
var originalNailSlash = slash.GetComponent<NailSlash>();
Object.Destroy(originalNailSlash);
Expand Down Expand Up @@ -83,16 +105,12 @@ protected void Play(GameObject playerObject, bool[] effectInfo, GameObject prefa
// Scale the nail slash based on Long nail and Mark of pride charms
if (hasLongNailCharm) {
if (hasMarkOfPrideCharm) {
slash.transform.localScale = new Vector3(scale.x * 1.4f, scale.y * 1.4f,
scale.z);
slash.transform.localScale = new Vector3(scale.x * 1.4f, scale.y * 1.4f, scale.z);
} else {
slash.transform.localScale = new Vector3(scale.x * 1.25f,
scale.y * 1.25f,
scale.z);
slash.transform.localScale = new Vector3(scale.x * 1.15f, scale.y * 1.15f, scale.z);
}
} else if (hasMarkOfPrideCharm) {
slash.transform.localScale = new Vector3(scale.x * 1.15f, scale.y * 1.15f,
scale.z);
slash.transform.localScale = new Vector3(scale.x * 1.25f, scale.y * 1.25f, scale.z);
}
}

Expand Down Expand Up @@ -133,9 +151,17 @@ protected void Play(GameObject playerObject, bool[] effectInfo, GameObject prefa
polygonCollider.enabled = true;

var damage = ServerSettings.NailDamage;
if (ServerSettings.IsPvpEnabled && ShouldDoDamage && damage != 0) {
if (ServerSettings.IsPvpEnabled) {
// TODO: make it possible to pogo on players
slash.AddComponent<DamageHero>().damageDealt = damage;

if (ServerSettings.AllowParries) {
var fsm = slash.AddComponent<PlayMakerFSM>();
fsm.SetFsmTemplate(NailClashTink.FsmTemplate);
}

if (ShouldDoDamage && damage != 0) {
slash.AddComponent<DamageHero>().damageDealt = damage;
}
}

// After the animation is finished, we can destroy the slash object
Expand Down
5 changes: 5 additions & 0 deletions HKMP/Api/Server/IServerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public interface IServerSettings {
/// Whether skins are allowed.
/// </summary>
public bool AllowSkins { get; }

/// <summary>
/// Whether other player's attacks can be parried.
/// </summary>
public bool AllowParries { get; }

/// <summary>
/// The damage that nail swings from other players deal to the local player.
Expand Down
3 changes: 3 additions & 0 deletions HKMP/Game/Settings/ServerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public class ServerSettings : IServerSettings, IEquatable<ServerSettings> {
/// <inheritdoc />
public bool AllowSkins { get; set; } = true;

/// <inheritdoc />
public bool AllowParries { get; set; } = true;

/// <inheritdoc />
public byte NailDamage { get; set; } = 1;

Expand Down
19 changes: 17 additions & 2 deletions HKMP/HkmpMod.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Hkmp.Game.Settings;
using System.Collections.Generic;
using Hkmp.Game.Settings;
using Hkmp.Logging;
using Hkmp.Util;
using Modding;
Expand All @@ -11,6 +12,11 @@ namespace Hkmp;
/// Mod class for the HKMP mod.
/// </summary>
internal class HkmpMod : Mod, IGlobalSettings<ModSettings> {
/// <summary>
/// Dictionary containing preloaded objects by scene name and object path.
/// </summary>
public static Dictionary<string, Dictionary<string, GameObject>> PreloadedObjects;

/// <summary>
/// Statically create Settings object, so it can be accessed early.
/// </summary>
Expand All @@ -28,7 +34,16 @@ public override string GetVersion() {
}

/// <inheritdoc />
public override void Initialize() {
public override List<(string, string)> GetPreloadNames() {
return new List<(string, string)> {
("Hive_05", "Battle Scene/Hive Knight/Slash 1")
};
}

/// <inheritdoc />
public override void Initialize(Dictionary<string, Dictionary<string, GameObject>> preloadedObjects) {
PreloadedObjects = preloadedObjects;

// Add the logger that logs to the ModLog
Logger.AddLogger(new ModLogger());

Expand Down

0 comments on commit d5e61ea

Please sign in to comment.