Ejemplo n.º 1
0
        /// <summary>
        /// Performs an ability using the specified parameters.
        /// </summary>
        /// <param name="action">The object containing the original battle commands.</param>
        /// <param name="actor">The CombatEntity performing the ability.</param>
        /// <param name="actorFormation">The Formation of the CombatEntity performing the Ability.</param>
        /// <param name="isAttacker">Set to true if the CombatEntity is on the attacking side in battle.</param>
        /// <param name="ability">The Ability being performed.</param>
        /// <param name="result">A reference to the BattleActionResult object.</param>
        /// <returns>Returns an IEnumerable of CombatEntities affected by the Ability.</returns>
        private IEnumerable <CombatEntity> PerformAbility(BattleAction action,
                                                          CombatEntity actor,
                                                          Formation actorFormation,
                                                          bool isAttacker,
                                                          Ability ability,
                                                          ref BattleActionResult result)
        {
            IEnumerable <CombatEntity> affectedEntities;
            Item item = null;

            // If using an item, prepare item to have it's charges deducted later
            if (action.IsUsingItem)
            {
                item = actor.EquippedItems.FirstOrDefault(i => i.ConsumableAbility.Id == action.AbilityId);
                if (item == null)
                {
                    item = actor.PlayerInventory
                           .Items
                           .FirstOrDefault(i => i != null && i.ConsumableAbility.Id == action.AbilityId);
                }

                if (item == null)
                {
                    result.FailureReason = BattleErrorWriter.WriteItemDoesntExist(actor);
                    result.IsSuccess     = false;
                    return(null);
                }

                ability = item.ConsumableAbility;
            }
            // Not an item, check to see if character is restricted from using Ability
            else
            {
                ability = actor.Abilities.FirstOrDefault(abi => abi.Id == action.AbilityId);
                if (ability == null)
                {
                    result.FailureReason = BattleErrorWriter.WriteAbilityDoesntExist(actor);
                    result.IsSuccess     = false;
                    return(null);
                }

                if (ability.IsSpell && actor.StatusEffects.Any(se => se.BaseStatus.IsSilenced))
                {
                    result.FailureReason = BattleErrorWriter.WriteEntityIsSilenced(actor, ability);
                    result.IsSuccess     = false;
                    return(null);
                }

                if (!ability.IsSpell && actor.StatusEffects.Any(se => se.BaseStatus.IsRestricted))
                {
                    result.FailureReason = BattleErrorWriter.WriteEntityIsRestricted(actor, ability);
                    result.IsSuccess     = false;
                    return(null);
                }
            }

            var targetFormation = GetFormation(action.TargetFormationId, out bool throwAway);

            // If the ability has a delay, create a DelayedAbility
            if (ability.DelayedTurns > 0)
            {
                var delayedAbilityResult = _abilityManager.CreateDelayedAbility(actor, ability, action, targetFormation);
                if (delayedAbilityResult.DelayedAbility == null)
                {
                    result.FailureReason = delayedAbilityResult.FailureReason;
                    result.IsSuccess     = false;
                    return(null);
                }

                if (isAttacker)
                {
                    _battle.AttackerDelayedAbilities.Add(delayedAbilityResult.DelayedAbility);
                }
                else
                {
                    _battle.DefenderDelayedAbilities.Add(delayedAbilityResult.DelayedAbility);
                }
                affectedEntities = new List <CombatEntity> {
                    actor
                };
            }
            // Not a delayed ability, try to apply effects immediately
            else
            {
                var abilityResult = _abilityManager.PerformAbility(actor, ability, action.TargetPosition, targetFormation);
                if (abilityResult.FailureReason != null)
                {
                    result.FailureReason = abilityResult.FailureReason;
                    result.IsSuccess     = false;
                    return(null);
                }

                affectedEntities = abilityResult.AffectedEntities;
            }

            CheckForDeadEntities(affectedEntities, targetFormation);

            // Action was successful, remove the actor from characters free to act
            _battle.ActionsLeftPerFormation[actorFormation].Remove(actor);

            // If Ability was granted by an item, reduce the charges of the item
            if (item != null)
            {
                _equipmentManager.ReduceCharges(actor, item);
            }



            return(affectedEntities);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Performs an action and returns true if the action was a success.
        /// </summary>
        /// <param name="action">The action to perform, containing data about the actor and the abilities used.</param>
        /// <returns></returns>
        public async Task <BattleActionResult> PerformActionAsync(BattleAction action)
        {
            IEnumerable <CombatEntity> affectedEntities = null;
            CombatEntity nextActiveEntity = null;
            Ability      ability          = null;
            CombatEntity actor            = null;
            var          result           = new BattleActionResult {
                IsSuccess = true
            };

            lock (_key)
            {
                if (_battle == null)
                {
                    result.FailureReason = BattleErrorWriter.WriteNotInitiated();
                    result.IsSuccess     = false;
                    return(result);
                }

                var actorFormation = GetFormation(action.OwnerId, out bool isAttacker);
                if (actorFormation == null)
                {
                    result.FailureReason = BattleErrorWriter.WriteNotParticipating();
                    result.IsSuccess     = false;
                    return(result);
                }

                actor = actorFormation.Positions.FirstOrDefaultTwoD(entity => entity != null && entity.Id == action.ActorId);
                if (actor == null)
                {
                    result.FailureReason = BattleErrorWriter.WriteActorNotFound();
                    result.IsSuccess     = false;
                    return(result);
                }

                // Not player's turn
                if (_battle.IsDefenderTurn != !isAttacker)
                {
                    result.FailureReason = BattleErrorWriter.WriteNotPlayersTurn();
                    result.IsSuccess     = false;
                    return(result);
                }

                if (!_battle.ActionsLeftPerFormation.ContainsKey(actorFormation))
                {
                    result.FailureReason = BattleErrorWriter.WriteNoMoreActions();
                    result.IsSuccess     = false;
                    return(result);
                }

                if (!_battle.ActionsLeftPerFormation[actorFormation].Contains(actor))
                {
                    result.FailureReason = BattleErrorWriter.WriteEntityCannotAct(actor);
                    result.IsSuccess     = false;
                    return(result);
                }

                if (actor.StatusEffects.Any(se => se.BaseStatus.IsStunned))
                {
                    result.FailureReason = BattleErrorWriter.WriteEntityIsStunned(actor);
                    result.IsSuccess     = false;
                    return(result);
                }

                if (!action.IsDefending &&
                    !action.IsFleeing)
                {
                    affectedEntities = PerformAbility(action,
                                                      actor,
                                                      actorFormation,
                                                      isAttacker,
                                                      ability,
                                                      ref result);

                    if (affectedEntities == null)
                    {
                        return(result);
                    }
                }
                // Is defending or fleeing
                else
                {
                    if (action.IsDefending)
                    {
                        affectedEntities = PerformDefend(actor, actorFormation, out nextActiveEntity);
                    }
                    else if (action.IsFleeing)
                    {
                        affectedEntities = PerformFlee(actor, actorFormation);
                    }
                }
            }

            await Task.Run(() => SuccessfulActionEvent.Invoke(this, new SuccessfulActionEventArgs
            {
                Ability            = ability,
                Action             = action,
                Actor              = actor,
                AffectedEntities   = affectedEntities,
                ParticipantIds     = _participantIds,
                NextActiveEntityId = nextActiveEntity != null ? nextActiveEntity.Id : -1
            }));

            return(result);
        }