147 lines
3.4 KiB
C#
147 lines
3.4 KiB
C#
|
using RoR2;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace EntityStates.Merc;
|
||
|
|
||
|
public class WhirlwindBase : BaseState
|
||
|
{
|
||
|
public static GameObject swingEffectPrefab;
|
||
|
|
||
|
public static GameObject hitEffectPrefab;
|
||
|
|
||
|
public static string attackSoundString;
|
||
|
|
||
|
public static string hitSoundString;
|
||
|
|
||
|
public static float slashPitch;
|
||
|
|
||
|
public static float hitPauseDuration;
|
||
|
|
||
|
[SerializeField]
|
||
|
public float baseDuration;
|
||
|
|
||
|
[SerializeField]
|
||
|
public float baseDamageCoefficient;
|
||
|
|
||
|
[SerializeField]
|
||
|
public string slashChildName;
|
||
|
|
||
|
[SerializeField]
|
||
|
public float selfForceMagnitude;
|
||
|
|
||
|
[SerializeField]
|
||
|
public float moveSpeedBonusCoefficient;
|
||
|
|
||
|
[SerializeField]
|
||
|
public float smallHopVelocity;
|
||
|
|
||
|
[SerializeField]
|
||
|
public string hitboxString;
|
||
|
|
||
|
protected Animator animator;
|
||
|
|
||
|
protected float duration;
|
||
|
|
||
|
protected float hitInterval;
|
||
|
|
||
|
protected int swingCount;
|
||
|
|
||
|
protected float hitPauseTimer;
|
||
|
|
||
|
protected bool isInHitPause;
|
||
|
|
||
|
protected OverlapAttack overlapAttack;
|
||
|
|
||
|
protected HitStopCachedState hitStopCachedState;
|
||
|
|
||
|
private static int SwordactiveParamHash = Animator.StringToHash("Sword.active");
|
||
|
|
||
|
private static int WhirlwindplaybackRateParamHash = Animator.StringToHash("Whirlwind.playbackRate");
|
||
|
|
||
|
public override void OnEnter()
|
||
|
{
|
||
|
base.OnEnter();
|
||
|
animator = GetModelAnimator();
|
||
|
duration = baseDuration / attackSpeedStat;
|
||
|
overlapAttack = InitMeleeOverlap(baseDamageCoefficient, hitEffectPrefab, GetModelTransform(), hitboxString);
|
||
|
if ((bool)base.characterDirection && (bool)base.inputBank)
|
||
|
{
|
||
|
base.characterDirection.forward = base.inputBank.aimDirection;
|
||
|
}
|
||
|
SmallHop(base.characterMotor, smallHopVelocity);
|
||
|
PlayAnim();
|
||
|
}
|
||
|
|
||
|
protected virtual void PlayAnim()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
public override void OnExit()
|
||
|
{
|
||
|
base.OnExit();
|
||
|
}
|
||
|
|
||
|
public override void FixedUpdate()
|
||
|
{
|
||
|
base.FixedUpdate();
|
||
|
hitPauseTimer -= GetDeltaTime();
|
||
|
if (animator.GetFloat("Sword.active") > (float)swingCount)
|
||
|
{
|
||
|
swingCount++;
|
||
|
Util.PlayAttackSpeedSound(attackSoundString, base.gameObject, slashPitch);
|
||
|
EffectManager.SimpleMuzzleFlash(swingEffectPrefab, base.gameObject, slashChildName, transmit: false);
|
||
|
if (base.isAuthority)
|
||
|
{
|
||
|
overlapAttack.ResetIgnoredHealthComponents();
|
||
|
if ((bool)base.characterMotor)
|
||
|
{
|
||
|
base.characterMotor.ApplyForce(selfForceMagnitude * base.characterDirection.forward, alwaysApply: true);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!base.isAuthority)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
if (FireMeleeOverlap(overlapAttack, animator, SwordactiveParamHash, 0f))
|
||
|
{
|
||
|
Util.PlaySound(hitSoundString, base.gameObject);
|
||
|
if (!isInHitPause)
|
||
|
{
|
||
|
hitStopCachedState = CreateHitStopCachedState(base.characterMotor, animator, "Whirlwind.playbackRate");
|
||
|
hitPauseTimer = hitPauseDuration / attackSpeedStat;
|
||
|
isInHitPause = true;
|
||
|
}
|
||
|
}
|
||
|
if (hitPauseTimer <= 0f && isInHitPause)
|
||
|
{
|
||
|
ConsumeHitStopCachedState(hitStopCachedState, base.characterMotor, animator);
|
||
|
isInHitPause = false;
|
||
|
}
|
||
|
if (!isInHitPause)
|
||
|
{
|
||
|
if ((bool)base.characterMotor && (bool)base.characterDirection)
|
||
|
{
|
||
|
Vector3 velocity = base.characterDirection.forward * moveSpeedStat * Mathf.Lerp(moveSpeedBonusCoefficient, 1f, base.age / duration);
|
||
|
velocity.y = base.characterMotor.velocity.y;
|
||
|
base.characterMotor.velocity = velocity;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base.characterMotor.velocity = Vector3.zero;
|
||
|
hitPauseTimer -= GetDeltaTime();
|
||
|
animator.SetFloat(WhirlwindplaybackRateParamHash, 0f);
|
||
|
}
|
||
|
if (base.fixedAge >= duration)
|
||
|
{
|
||
|
while (swingCount < 2)
|
||
|
{
|
||
|
swingCount++;
|
||
|
overlapAttack.Fire();
|
||
|
}
|
||
|
outer.SetNextStateToMain();
|
||
|
}
|
||
|
}
|
||
|
}
|