using System.Linq; using VOID.Generic.Dict; using VOID.Generic.Dict.Ability; using VOID.Generic.Objects.Unit.Actions.Exceptions; using VOID.Generic.Objects.Unit.Events; using VOID.ScriptableObjects.Abilities; namespace VOID.Generic.Objects.Unit.Actions { /// /// Simply make go into "casting" state allowing player or AI to aim and select targets. ///

/// :
/// ///
public class CastingAction : AbstractAction { private readonly UnitObject _unit; private readonly BasicAbility _ability; public CastingAction(UnitObject unit, BasicAbility ability) { _unit = unit; _ability = ability; } public override bool IsInRange() => true; public override void CanDoIt() { Check( state == ActionState.Ready, UnitActionErrorType.ActionStateIsNotReady); if (_unit.basicState.turnManager) { Check( _unit.unitState.isSelfTurn, UnitActionErrorType.UnitSelfTurnNotActive); Check( _unit.unitData.currentResources.actionPoints >= _ability.actionPointCost, UnitActionErrorType.UnitNotEnoughActionPoints); Check( _unit.unitData.currentResources.movePoints >= _ability.movePointCost, UnitActionErrorType.UnitNotEnoughMovePoints); } Check( _unit.unitState.isControllable, UnitActionErrorType.UnitStateIsNotControllable); Check( _ability.requirements.All(requirement => requirement.Check(_unit)), UnitActionErrorType.RequirementsNotMeetToUseThatAbility); } protected override void OnDoIt() { BeforePerform(); if (_ability.castingType is AbilityCastingType.Instant or AbilityCastingType.InstantCasting) { // Ending action early AfterPerform(); EndIt(); // Make sure that there is no more actions after CASTING and before ABILITY _unit.OrderStop(false); // Instantly starting ability _unit.Order(new AbilityAction(_unit, _ability)); return; } var animationGenericEvent = new AnimationGenericEvent { animationType = AnimationType.Casting, unit = _unit, ability = _ability }; // Enables "casting" mode for this unit (usually only for player) to select targets before firing ability _unit.unitEvents.onStartCasting.Invoke(new CastingEvent { caster = _unit, ability = _ability }); // Starting loop animation of selected ability _unit.unitAnimator.SetLoopAnimation(AnimationType.Casting, _ability.castingAnimationList); _unit.unitAnimator.StartLoopAnimation(animationGenericEvent); } protected override void OnEndIt() { AfterPerform(); // Instant abilities don't have casting - do nothing if (_ability.castingType is AbilityCastingType.Instant or AbilityCastingType.InstantCasting) return; // Somehow casting ended (no matter is by player or something else) _unit.unitAnimator.EndLoopAnimation(); _unit.unitEvents.onEndCasting.Invoke(new CastingEvent { caster = _unit, ability = _ability }); } protected override void OnCancelIt() { OnEndIt(); } } }