Skip to content

Commit

Permalink
Merge branch 'master' into entity-system-v2
Browse files Browse the repository at this point in the history
# Conflicts:
#	HKMP/Animation/Effects/DashBase.cs
#	HKMP/Animation/Effects/DashSlash.cs
#	HKMP/Animation/Effects/SlashBase.cs
#	HKMP/Version.cs
  • Loading branch information
Extremelyd1 committed Oct 8, 2023
2 parents b5f4693 + 139d734 commit 897821b
Show file tree
Hide file tree
Showing 18 changed files with 382 additions and 84 deletions.
26 changes: 22 additions & 4 deletions HKMP/Animation/Effects/CycloneSlash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,18 @@ namespace Hkmp.Animation.Effects;
/// <summary>
/// Animation effect class for the Cyclone Slash ability.
/// </summary>
internal class CycloneSlash : DamageAnimationEffect {
internal class CycloneSlash : ParryableEffect {
/// <summary>
/// The GameObject for block effect of 'tinking' nails against each other.
/// Used as the effect when players are bouncing on the Cyclone Slash.
/// </summary>
private readonly GameObject _tinkBlockEffect;

public CycloneSlash() {
var cycloneTink = HkmpMod.PreloadedObjects["GG_Sly"]["Battle Scene/Sly Boss/Cyclone Tink"];
_tinkBlockEffect = cycloneTink.GetComponent<TinkEffect>().blockEffect;
}

/// <inheritdoc/>
public override void Play(GameObject playerObject, bool[] effectInfo) {
// Cancel the nail art charge animation if it exists
Expand Down Expand Up @@ -54,9 +65,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) {
var tinkL = hitLComponent.AddComponent<TinkEffect>();
var tinkR = hitRComponent.AddComponent<TinkEffect>();
tinkL.blockEffect = _tinkBlockEffect;
tinkR.blockEffect = _tinkBlockEffect;

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
17 changes: 13 additions & 4 deletions HKMP/Animation/Effects/DashBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Hkmp.Animation.Effects;
/// <summary>
/// Abstract base class for the animation effect of dashing.
/// </summary>
internal abstract class DashBase : AnimationEffect {
internal abstract class DashBase : DamageAnimationEffect {
/// <inheritdoc/>
public abstract override void Play(GameObject playerObject, bool[] effectInfo);

Expand Down Expand Up @@ -75,7 +75,7 @@ protected void Play(GameObject playerObject, bool[] effectInfo, bool shadowDash,
// Instantiate the dash effect relative to the player position
var dashEffectPrefab = HeroController.instance.shadowdashBurstPrefab;
var dashEffect = Object.Instantiate(dashEffectPrefab);
var dashEffectTransform = dashEffect.transform;
Transform dashEffectTransform = dashEffect.transform;
dashEffectTransform.position = playerTransform.position + spawnPosition;
dashEffectTransform.rotation = playerTransform.rotation;
dashEffectTransform.localScale = playerTransform.localScale;
Expand Down Expand Up @@ -119,6 +119,7 @@ protected void Play(GameObject playerObject, bool[] effectInfo, bool shadowDash,
// Start a coroutine with the recharge animation, since we need to wait in it
MonoBehaviourUtil.Instance.StartCoroutine(PlayRechargeAnimation(playerObject, playerEffects));

var damage = ServerSettings.SharpShadowDamage;
if (!sharpShadow) {
// Lastly, disable the player collider, since we are in a shadow dash
// We only do this, if we don't have sharp shadow
Expand All @@ -137,12 +138,20 @@ protected void Play(GameObject playerObject, bool[] effectInfo, bool shadowDash,
sharpShadowObject.SetActive(true);
sharpShadowObject.layer = 17;

if (!ServerSettings.IsBodyDamageEnabled && ServerSettings.IsPvpEnabled) {
if (
!ServerSettings.IsBodyDamageEnabled &&
ServerSettings.IsPvpEnabled &&
ShouldDoDamage &&
damage != 0
) {
// If body damage is disabled, but PvP is enabled and we are performing a sharp shadow dash
// we need to enable the DamageHero component and move the player object to the correct layer
// to allow the local player to collide with it
playerObject.layer = 11;
playerObject.GetComponent<DamageHero>().enabled = true;

var damageHero = playerObject.GetComponent<DamageHero>();
damageHero.enabled = true;
damageHero.damageDealt = damage;
}

// As a failsafe, we remove the sharp shadow object again on a timer
Expand Down
9 changes: 6 additions & 3 deletions HKMP/Animation/Effects/DashEnd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ internal class DashEnd : AnimationEffect {
public override void Play(GameObject playerObject, bool[] effectInfo) {
// Enable the player collider again
playerObject.GetComponent<BoxCollider2D>().enabled = true;
// Disable the DamageHero component and reset the layer if body damage is disabled, but PvP is enabled
// Because it might have been a shadow dash that was ended
// Disable the DamageHero component and reset the damage and the layer of the player if body damage is
// disabled, but PvP is enabled. Because it might have been a shadow dash that was ended
if (!ServerSettings.IsBodyDamageEnabled && ServerSettings.IsPvpEnabled) {
playerObject.layer = 9;
playerObject.GetComponent<DamageHero>().enabled = false;

var damageHero = playerObject.GetComponent<DamageHero>();
damageHero.damageDealt = 1;
damageHero.enabled = false;
}

var playerEffects = playerObject.FindGameObjectInChildren("Effects");
Expand Down
49 changes: 35 additions & 14 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 @@ -47,18 +47,19 @@ public override void Play(GameObject playerObject, bool[] effectInfo) {
dashSlashScale.y,
dashSlashScale.z
);
dashSlash.layer = 17;

dashSlash.layer = 22;

ChangeAttackTypeOfFsm(dashSlash);

// Get the "damages_enemy" FSM from the dash slash object
var slashFsm = dashSlash.LocateMyFSM("damages_enemy");
// Find the variable that controls the slash direction for damaging enemies
var directionVar = slashFsm.FsmVariables.GetFsmFloat("direction");

// Set it based on the direction the knight is facing
var facingRight = playerScaleX > 0;
directionVar.Value = facingRight ? 180f : 0f;
// // Get the "damages_enemy" FSM from the dash slash object
// var slashFsm = dashSlash.LocateMyFSM("damages_enemy");
// // Find the variable that controls the slash direction for damaging enemies
// var directionVar = slashFsm.FsmVariables.GetFsmFloat("direction");
//
// // Set it based on the direction the knight is facing
// var facingRight = playerScaleX > 0;
// directionVar.Value = facingRight ? 180f : 0f;

dashSlash.SetActive(true);

Expand All @@ -69,11 +70,31 @@ public override void Play(GameObject playerObject, bool[] effectInfo) {
// in case the local player was already performing it
dashSlash.LocateMyFSM("Control Collider").SetState("Init");

dashSlash.GetComponent<PolygonCollider2D>().enabled = true;

var damage = ServerSettings.DashSlashDamage;
if (ServerSettings.IsPvpEnabled && ShouldDoDamage && damage != 0) {
dashSlash.AddComponent<DamageHero>().damageDealt = damage;
if (ServerSettings.IsPvpEnabled && ShouldDoDamage) {
// Somehow adding a DamageHero component or the parry FSM 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)
),
dashSlash.transform
);
dashSlashCollider.SetActive(true);
dashSlashCollider.layer = 22;

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

if (ServerSettings.AllowParries) {
AddParryFsm(dashSlashCollider);
}

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

// Get the animator, figure out the duration of the animation and destroy the object accordingly afterwards
Expand Down
12 changes: 9 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 @@ -56,8 +56,14 @@ 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 && ShouldDoDamage) {
if (ServerSettings.AllowParries) {
AddParryFsm(greatSlash);
}

if (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
110 changes: 82 additions & 28 deletions HKMP/Animation/Effects/SlashBase.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
using System.Collections.Generic;
using Hkmp.Util;
using HutongGames.PlayMaker.Actions;
using UnityEngine;
using Object = UnityEngine.Object;

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,27 +60,21 @@ 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);
slash.layer = 22;

// 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);

ChangeAttackTypeOfFsm(slash);

// Get the "damages_enemy" FSM from the slash object
var slashFsm = slash.LocateMyFSM("damages_enemy");
// Find the variable that controls the slash direction for damaging enemies
var directionVar = slashFsm.FsmVariables.GetFsmFloat("direction");

if (type is SlashType.Wall or SlashType.Normal or SlashType.Alt) {
// For wall, normal and alt slash, we need to check the direction the knight is facing
var facingRight = playerObject.transform.localScale.x > 0;
directionVar.Value = facingRight ? 180f : 0f;
} else if (type is SlashType.Up) {
directionVar.Value = 90f;
} else {
directionVar.Value = 270f;
}

slash.SetActive(true);

// Get the slash audio source and its clip
Expand Down Expand Up @@ -98,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 @@ -147,15 +150,66 @@ protected void Play(GameObject playerObject, bool[] effectInfo, GameObject prefa

polygonCollider.enabled = true;

// Instantiate additional game object that can interact with enemies so remote enemies can be hit
GameObject enemySlash;
{
enemySlash = Object.Instantiate(prefab, playerAttacks.transform);
enemySlash.layer = 17;
enemySlash.name = "Enemy Slash";
enemySlash.transform.localScale = slash.transform.localScale;

var typesToRemove = new[] {
typeof(MeshFilter), typeof(MeshRenderer), typeof(tk2dSprite), typeof(tk2dSpriteAnimator),
typeof(NailSlash),
typeof(AudioSource)
};
foreach (var typeToRemove in typesToRemove) {
Object.Destroy(enemySlash.GetComponent(typeToRemove));
}

for (var i = 0; i < enemySlash.transform.childCount; i++) {
Object.Destroy(enemySlash.transform.GetChild(i));
}

polygonCollider = enemySlash.GetComponent<PolygonCollider2D>();
polygonCollider.enabled = true;

var damagesEnemyFsm = slash.LocateMyFSM("damages_enemy");
Object.Destroy(damagesEnemyFsm);

ChangeAttackTypeOfFsm(enemySlash);

// Get the "damages_enemy" FSM from the slash object
var slashFsm = enemySlash.LocateMyFSM("damages_enemy");
// Find the variable that controls the slash direction for damaging enemies
var directionVar = slashFsm.FsmVariables.GetFsmFloat("direction");

if (type is SlashType.Wall or SlashType.Normal or SlashType.Alt) {
// For wall, normal and alt slash, we need to check the direction the knight is facing
var facingRight = playerObject.transform.localScale.x > 0;
directionVar.Value = facingRight ? 180f : 0f;
} else if (type is SlashType.Up) {
directionVar.Value = 90f;
} else {
directionVar.Value = 270f;
}
}

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

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

// After the animation is finished, we can destroy the slash object
var animationDuration = slashAnimator.CurrentClip.Duration;
Object.Destroy(slash, animationDuration);
Object.Destroy(enemySlash, animationDuration);

if (!hasGrubberflyElegyCharm
|| isOnOneHealth && !hasFuryCharm
Expand Down
Loading

0 comments on commit 897821b

Please sign in to comment.