/// <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); }
/// <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(); }