Exemplo n.º 1
0
        public static bool AbilityCanTarget(QueuedAbility queuedAbility)
        {
            //ability can target if the target is alive, or the target is dead but we have appropriate retarget behavior
            if (queuedAbility.Target.IsAlive == false && queuedAbility.Ability.DeadTargetBehavior == DeadTargetBehavior.AbandonAbilityExecution)
            {
                return false;
            }

            return true;
        }
Exemplo n.º 2
0
        protected void HandleQueuedAbilityActivation(QueuedAbility queuedAbility)
        {
            //TODO: When a battle entity dies, reset their HasQueuedAbility flag.

            //if the source has died since this ability was queued, just bail. We can't do anything else
            if (queuedAbility.Source.IsAlive == false)
            {
                return;
            }

            //we will be trying to execute the ability
            //start by setting the executing ability. This will display the name of the ability, as well as signal that we're busy processing this ability
            BattleModel.Instance.BattlefieldData.ExecutingAbility = queuedAbility.Ability;

            //first, we need to queue up the battle entity attack animation, followed by the logic to execute the ability steps
            var abilityExecutionSteps = new List<DelayedAction>
            {
                //start with battle entity attack animation
                DelayedAction.New(() =>
                    {
                        if (queuedAbility.Source is PartyMemberInBattle)
                        {
                            //TODO: Party member step forward?
                        }
                        else
                        {
                            (queuedAbility.Source as EnemyInBattle).SpriteSheet.AttackFlash();
                        }
                    }, 0) //no delay here, the step animations will handle their individual delay
            };

            //next, we check to see if our target is still valid. If it's not, we'll skip the actual execution of the ability
            if (BattleUtility.AbilityCanTarget(queuedAbility))
            {
                //we have a source that's alive, and can actually get targets. We need to check the costs of the ability
                //like does the source have enough energy, or does the item exist in inventory
                if (queuedAbility.Ability.ExecuteCost(queuedAbility.Source.BattleEntity))
                {
                    //we met all of our ability costs, we can execute the steps
                    foreach (var step in queuedAbility.Ability.GetAbilitySteps(queuedAbility.Source.BattleEntity))
                    {
                        var allTargets = new BattleEntityInBattle[0];

                        abilityExecutionSteps.Add(DelayedAction.New(() =>
                        {
                            //retarget the primary target, if necessary
                            queuedAbility.Target = BattleUtility.GetPrimaryTargetForAbilityStep(queuedAbility.Source, queuedAbility.Target, queuedAbility.Ability.DeadTargetBehavior);

                            //get secondary targets based on new primary target
                            allTargets = BattleUtility.GetAllTargetsForAbilityStep(queuedAbility.Source, queuedAbility.Target, queuedAbility.Ability.Target, step);
                        }, 1));

                        //handle ability animations (in parallel)
                        abilityExecutionSteps.Add(DelayedAction.New(
                            () => BattleUtility.HandleAbilityStepAnimations(queuedAbility.Source, allTargets, step.Animation), step.GetTotalFrames(GameState.InBattle)));

                        //apply effects to targets, long enough to display damage/battle status
                        abilityExecutionSteps.Add(DelayedAction.New(
                            () => step.ApplyEffectToTargets(queuedAbility.Source.BattleEntity, allTargets.Select(x => x.BattleEntity).ToArray()), Constants.BATTLE_TIMING_DISPLAY_DAMAGE_TICKS));
                    }
                }
                else
                {
                    //TODO: Do we want to somehow signal that we couldn't execute a prerequesite? (no energy, or no item in inventory, etc...)
                    //TODO: BATTLE_TIMING_ABILITY_FAILED_COST_WAIT_TICKS may be reudced (or completely eliminted) when I get the step forward / step back animations taken care of.
                    abilityExecutionSteps.Add(DelayedAction.New(() => { }, Constants.BATTLE_TIMING_ABILITY_FAILED_COST_WAIT_TICKS)); //just delay for a few seconds
                }
            }

            //TODO: We need to handle the situation of the party member stepping back as well

            //finally, queue up finish queued ability logic
            abilityExecutionSteps.Add(DelayedAction.New(
                () => Bus.Broadcast(BattleQueuedAbilityFinishedMessage.New(queuedAbility)), 0));

            //TODO: Also, do we want actions for things such as checking to see if the battle is won/lost, if things have died, etc...

            TimerUtility.ExecuteChainOfActions(abilityExecutionSteps);
        }
 protected BattleQueuedAbilityFinishedMessage(QueuedAbility queuedAbility)
 {
     QueuedAbility = queuedAbility;
 }
 public static BattleQueuedAbilityFinishedMessage New(QueuedAbility queuedAbility)
 {
     return new BattleQueuedAbilityFinishedMessage(queuedAbility);
 }