Files
VOIDRPG/Assets/90 - Scripts/Generic/Status/Effect/Positional/JumpEffect.cs
T
2026-07-09 21:33:33 +02:00

101 lines
3.8 KiB
C#

using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
using VOID.Generic.Objects.Unit;
using VOID.Generic.Objects.Unit.Events;
using VOID.Generic.Projectile;
using VOID.ScriptableObjects;
namespace VOID.Generic.Status.Effect.Positional
{
[TypeRegistryItem("Jump")]
public class JumpEffect : BasicEffect
{
private enum JumpEffectState
{
Pre,
Waiting,
Jump,
End
}
private JumpEffectState _state;
private ProjectileObject _projectile;
private UnitObject _forUnit;
public override void OnApply()
{
if (forObject is not UnitObject forUnit) return;
_forUnit = forUnit;
if (_state == JumpEffectState.Pre)
{
// "PRE" is firing from ability, but this will fire instant effect
// Here we will create new status+effect for jump that will handle whole jump
var newJumpEffect = new JumpEffect();
newJumpEffect._state = JumpEffectState.Waiting;
var newJumpStatus = ScriptableObject.CreateInstance<BasicStatus>();
newJumpStatus.effects = new List<BasicEffect> { newJumpEffect };
newJumpStatus.hidden = true;
newJumpStatus.permanent = true;
_forUnit.statusManager.AddStatus(newJumpStatus, _forUnit, false);
}
else if (_state == JumpEffectState.Waiting)
{
// "WAITING" this state is waiting for projectile to fire, after that unit can attach to projectile
_forUnit.unitEvents.onAbilityProjectileStart.AddListener(OnProjectileStart);
_forUnit.unitEvents.onAbilityProjectileEnd.AddListener(OnProjectileEnd);
}
}
public override void OnEnd()
{
if (!_forUnit) return;
// Just to be sure - remove all listeners after jump is finished
_forUnit.basicEvents.onFixedUpdate.RemoveListener(MoveWithProjectile);
_forUnit.unitEvents.onAbilityProjectileStart.RemoveListener(OnProjectileStart);
_forUnit.unitEvents.onAbilityProjectileEnd.RemoveListener(OnProjectileEnd);
}
public override void OnTurnSelfEnd() {}
public override void OnTurnSelfStart() {}
public override void OnCancel() => OnEnd();
public sealed override string GetSimpleDescription() => "Unit jump like a projectile";
private void OnProjectileStart(AbilityProjectileEvent projectileEvent)
{
// just to be sure that unit stick only to first projectile, if somehow there is more
if (projectileEvent.projectileIndex != 0) return;
_projectile = projectileEvent.projectile;
_state = JumpEffectState.Jump;
_forUnit.basicEvents.onFixedUpdate.AddListener(MoveWithProjectile);
_forUnit.unitEvents.onAbilityProjectileStart.RemoveListener(OnProjectileStart);
}
private void OnProjectileEnd(AbilityProjectileEvent projectileEvent)
{
// just to be sure that unit stick only to first projectile, if somehow there is more
if (projectileEvent.projectileIndex != 0) return;
_state = JumpEffectState.End;
_forUnit.basicEvents.onFixedUpdate.RemoveListener(MoveWithProjectile);
_forUnit.unitEvents.onAbilityProjectileEnd.RemoveListener(OnProjectileEnd);
// End whole jump status when projectile along with unit end their "jump"
forStatus.End();
}
private void MoveWithProjectile()
{
_forUnit.transform.position = _projectile.transform.position;
}
}
}