104 lines
3.8 KiB
C#
104 lines
3.8 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// Simply make <see cref="UnitObject"/> go into "casting" state allowing player or AI to aim and select targets.
|
|
/// <br/><br/>
|
|
/// <see cref="AbstractAction"/>:<br/>
|
|
/// <inheritdoc cref="AbstractAction"/>
|
|
/// </summary>
|
|
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();
|
|
}
|
|
}
|
|
} |