167 lines
4.8 KiB
C#
167 lines
4.8 KiB
C#
|
using RoR2;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace EntityStates.FalseSon;
|
||
|
|
||
|
public class ClubGroundSlam : BaseState
|
||
|
{
|
||
|
public float charge;
|
||
|
|
||
|
public static float airControl;
|
||
|
|
||
|
public static float minimumDuration;
|
||
|
|
||
|
public static float blastRadius;
|
||
|
|
||
|
public static float blastProcCoefficient;
|
||
|
|
||
|
public static float blastDamageCoefficient;
|
||
|
|
||
|
public static float blastForce;
|
||
|
|
||
|
public static string enterSoundString;
|
||
|
|
||
|
public static float initialVerticalVelocity;
|
||
|
|
||
|
public static float exitVerticalVelocity;
|
||
|
|
||
|
public static float verticalAcceleration;
|
||
|
|
||
|
public static float exitSlowdownCoefficient;
|
||
|
|
||
|
public static Vector3 blastBonusForce;
|
||
|
|
||
|
public static GameObject blastImpactEffectPrefab;
|
||
|
|
||
|
public static GameObject blastEffectPrefab;
|
||
|
|
||
|
public static float normalizedVFXPositionBetweenFootAndClub;
|
||
|
|
||
|
public static float normalizedBlastPositionBetweenFootAndClub;
|
||
|
|
||
|
public static float smallHopVelocity;
|
||
|
|
||
|
public static float heightInfluencePercent;
|
||
|
|
||
|
private float previousAirControl;
|
||
|
|
||
|
private float timeInAir;
|
||
|
|
||
|
private float airClubTimer;
|
||
|
|
||
|
private bool hitTheGround;
|
||
|
|
||
|
private float delayBeforeExit;
|
||
|
|
||
|
private bool detonateNextFrame;
|
||
|
|
||
|
public override void OnEnter()
|
||
|
{
|
||
|
base.OnEnter();
|
||
|
PlayCrossfade("Body", "GroundSlam", 0.2f);
|
||
|
if (base.isAuthority)
|
||
|
{
|
||
|
base.characterMotor.onHitGroundAuthority += OnHitGroundAuthority;
|
||
|
base.characterMotor.velocity.y = initialVerticalVelocity;
|
||
|
}
|
||
|
Util.PlaySound(enterSoundString, base.gameObject);
|
||
|
previousAirControl = base.characterMotor.airControl;
|
||
|
base.characterMotor.airControl = airControl;
|
||
|
base.characterBody.bodyFlags |= CharacterBody.BodyFlags.IgnoreFallDamage;
|
||
|
}
|
||
|
|
||
|
public override void FixedUpdate()
|
||
|
{
|
||
|
base.FixedUpdate();
|
||
|
float deltaTime = GetDeltaTime();
|
||
|
airClubTimer += deltaTime;
|
||
|
timeInAir = 0f;
|
||
|
if (airClubTimer > 0.5f)
|
||
|
{
|
||
|
timeInAir = airClubTimer;
|
||
|
}
|
||
|
if (base.isAuthority && (bool)base.characterMotor)
|
||
|
{
|
||
|
base.characterMotor.moveDirection = base.inputBank.moveVector;
|
||
|
base.characterDirection.moveVector = base.characterMotor.moveDirection;
|
||
|
base.characterMotor.velocity.y += verticalAcceleration * deltaTime;
|
||
|
if (!hitTheGround && base.fixedAge >= minimumDuration && (detonateNextFrame || (base.characterMotor.Motor.GroundingStatus.IsStableOnGround && !base.characterMotor.Motor.LastGroundingStatus.IsStableOnGround)))
|
||
|
{
|
||
|
PlayAnimation("Body", "GroundSlamExit");
|
||
|
DetonateAuthority();
|
||
|
hitTheGround = true;
|
||
|
delayBeforeExit = base.fixedAge;
|
||
|
}
|
||
|
else if (hitTheGround && base.fixedAge >= delayBeforeExit + 0.1f)
|
||
|
{
|
||
|
outer.SetNextStateToMain();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base.characterBody.SetSpreadBloom(charge);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void OnExit()
|
||
|
{
|
||
|
if (!base.isAuthority)
|
||
|
{
|
||
|
PlayAnimation("Body", "GroundSlamExit");
|
||
|
}
|
||
|
base.characterBody.SetSpreadBloom(0f, canOnlyIncreaseBloom: false);
|
||
|
if (base.isAuthority)
|
||
|
{
|
||
|
base.characterMotor.onHitGroundAuthority -= OnHitGroundAuthority;
|
||
|
base.characterMotor.velocity *= exitSlowdownCoefficient;
|
||
|
base.characterMotor.velocity.y = exitVerticalVelocity;
|
||
|
if (!hitTheGround)
|
||
|
{
|
||
|
PlayAnimation("Body", "Idle");
|
||
|
}
|
||
|
}
|
||
|
base.characterMotor.airControl = previousAirControl;
|
||
|
base.characterBody.bodyFlags &= ~CharacterBody.BodyFlags.IgnoreFallDamage;
|
||
|
SmallHop(base.characterMotor, smallHopVelocity + airClubTimer * heightInfluencePercent);
|
||
|
base.OnExit();
|
||
|
}
|
||
|
|
||
|
private void OnHitGroundAuthority(ref CharacterMotor.HitGroundInfo hitGroundInfo)
|
||
|
{
|
||
|
detonateNextFrame = true;
|
||
|
}
|
||
|
|
||
|
protected BlastAttack.Result DetonateAuthority()
|
||
|
{
|
||
|
Vector3 position = FindModelChild("ClubExplosionPoint").transform.position;
|
||
|
Vector3 footPosition = base.characterBody.footPosition;
|
||
|
Vector3 origin = footPosition + (position - footPosition) * normalizedVFXPositionBetweenFootAndClub;
|
||
|
Vector3 position2 = footPosition + (position - footPosition) * normalizedBlastPositionBetweenFootAndClub;
|
||
|
EffectManager.SpawnEffect(blastEffectPrefab, new EffectData
|
||
|
{
|
||
|
origin = origin,
|
||
|
scale = blastRadius * (charge + 1.25f + timeInAir * 2f)
|
||
|
}, transmit: true);
|
||
|
return new BlastAttack
|
||
|
{
|
||
|
attacker = base.gameObject,
|
||
|
baseDamage = damageStat * (blastDamageCoefficient * charge) + (base.characterBody.maxHealth - (base.characterBody.baseMaxHealth + base.characterBody.levelMaxHealth * (float)((int)base.characterBody.level - 1))) * 0.01f,
|
||
|
baseForce = blastForce,
|
||
|
bonusForce = blastBonusForce,
|
||
|
crit = RollCrit(),
|
||
|
falloffModel = BlastAttack.FalloffModel.None,
|
||
|
procCoefficient = blastProcCoefficient,
|
||
|
radius = blastRadius * (charge + 1.25f + timeInAir * 2f),
|
||
|
position = position2,
|
||
|
attackerFiltering = AttackerFiltering.NeverHitSelf,
|
||
|
impactEffect = EffectCatalog.FindEffectIndexFromPrefab(blastImpactEffectPrefab),
|
||
|
teamIndex = base.teamComponent.teamIndex
|
||
|
}.Fire();
|
||
|
}
|
||
|
|
||
|
public override InterruptPriority GetMinimumInterruptPriority()
|
||
|
{
|
||
|
return InterruptPriority.Frozen;
|
||
|
}
|
||
|
}
|