Esempio n. 1
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);
        }
Esempio n. 2
0
        /// <summary>
        /// Performs an action for one Ai CombatEntity that is available to act this turn.
        /// </summary>
        private void PerformAiAction()
        {
            CombatAiDecision           decision         = null;
            IEnumerable <Formation>    myAllies         = null;
            IEnumerable <Formation>    myEnemies        = null;
            IEnumerable <CombatEntity> affectedEntities = null;
            CombatEntity nextActiveEntity = null;

            lock (_key)
            {
                var available = _battle.ActionsLeftPerFormation.Where(kvp => kvp.Key.OwnerId == GameplayConstants.AiId)
                                .Where(kvp => kvp.Value != null && kvp.Value.Count > 0)
                                .FirstOrDefault();
                // If no available ai actions left in turn
                if (available.Equals(default(KeyValuePair <Formation, List <CombatEntity> >)))
                {
                    return;
                }

                var myFormation = available.Key;
                var myEntity    = available.Value.FirstOrDefault();

                // If defenders turn, ai is a defender, all defenders are allies and attackers are enemies
                if (_battle.IsDefenderTurn)
                {
                    myAllies  = _battle.Defenders;
                    myEnemies = _battle.Attackers;
                }
                else
                {
                    myAllies  = _battle.Attackers;
                    myEnemies = _battle.Defenders;
                }

                decision = _combatAi.MakeDecision(myFormation, myEntity, myAllies, myEnemies);
                if (decision == null)
                {
                    return;
                }

                if (decision.IsDefending)
                {
                    affectedEntities = PerformDefend(myEntity, myFormation, out nextActiveEntity);
                }
                else
                {
                    var result = PerformAiDecision(decision, myFormation);
                    affectedEntities = result.AffectedEntities;

                    CheckForDeadEntities(affectedEntities, decision.TargetFormation);
                }
            }

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