using System.Collections.Generic; using System.Linq; namespace Wizard; public static class BattleSequencer { public static void ExecSimulation(AIVirtualField field, List actionInfoSequence, List enemyTargetSequence, SimulationSetting setting) { AIVirtualActionInfo aIVirtualActionInfo = actionInfoSequence.FirstOrDefault((AIVirtualActionInfo a) => a.ActionType == AIOperationType.EVOLVE); AIVirtualActionInfo aIVirtualActionInfo2 = null; while (actionInfoSequence.Any((AIVirtualActionInfo a) => !a.IsAlreadyUsed)) { field.EnemyTokenQueue.Clear(); int num = -1; for (int num2 = 0; num2 < actionInfoSequence.Count; num2++) { AIVirtualActionInfo aIVirtualActionInfo3 = actionInfoSequence[num2]; if (!aIVirtualActionInfo3.IsAlreadyUsed) { aIVirtualActionInfo2 = aIVirtualActionInfo3; num = num2; break; } } if (aIVirtualActionInfo2 != null) { if (aIVirtualActionInfo2 == aIVirtualActionInfo) { aIVirtualActionInfo = null; } bool flag = AISimulationUtility.ExecuteVirtualAction(aIVirtualActionInfo2, aIVirtualActionInfo, enemyTargetSequence, setting); if (num == 0 && !flag && setting.CheckFirstActionFailure) { return; } } if (field.EnemyClass.IsDead || field.AllyClass.IsDead) { return; } List bestPlayPtn = field.BestPlayPtn; for (int num3 = 0; num3 < field.AllyInplayCards.Count; num3++) { AIVirtualCard aIVirtualCard = field.AllyInplayCards[num3]; if (!aIVirtualCard.IsAttackable(bestPlayPtn)) { continue; } bool flag2 = false; for (int num4 = 0; num4 < actionInfoSequence.Count; num4++) { if (actionInfoSequence[num4].Actor.CardIndex == aIVirtualCard.CardIndex) { flag2 = true; break; } } if (!flag2) { actionInfoSequence.Insert(num + 1, new AIVirtualAttackInfo(aIVirtualCard, isAttackFollower: true, aIVirtualActionInfo2)); } } while (field.EnemyTokenQueue.Count > 0) { Tuple tuple = field.EnemyTokenQueue.Dequeue(); AIVirtualCard first = tuple.first; AIVirtualCard second = tuple.second; int num5 = enemyTargetSequence.IndexOf(first); if (num5 >= 0 && (IsToBeKilled(field) || second.IsGuard)) { enemyTargetSequence.Insert(num5 + 1, second); if (first.IsMetamorphosed) { enemyTargetSequence.Remove(first); } } } if (aIVirtualActionInfo2 != null && aIVirtualActionInfo2 is AIVirtualAttackInfo { IsAttackSuccessed: not false } && field.AllyInplayCards.Count((AIVirtualCard card) => !card.IsDead) < 5 && aIVirtualActionInfo2.Actor.TagCollectionContainer.HasTag(AIPlayTagType.PuppetAttack)) { aIVirtualActionInfo2.Actor.TagCollectionContainer.PuppetAttackTags.ExecutePuppetAttack(aIVirtualActionInfo2.Actor, aIVirtualActionInfo2, actionInfoSequence); } } field.CallAfterLeaderAttackSimulation(); } public static AIVirtualCard FindAttackTarget(AIVirtualField field, AIVirtualAttackInfo attack, List enemyTargetSequence, AIVirtualActionInfo evolutionInfo, bool isHandAllRemovalValid, bool isNoSkipAttack, bool isAttackFollower) { AIVirtualCard aIVirtualCard = null; if (isAttackFollower) { for (int i = 0; i < enemyTargetSequence.Count; i++) { AIVirtualCard aIVirtualCard2 = enemyTargetSequence[i]; attack.SetAttackTarget(aIVirtualCard2); if (AIAttackSimulationUtility.IsAttackPossible(field, attack)) { AIVirtualCard nextTarget = ((enemyTargetSequence.Count > i + 1) ? enemyTargetSequence[i + 1] : field.EnemyClass); if (isNoSkipAttack || !IsSkipAttack(field, attack, nextTarget, evolutionInfo, isHandAllRemovalValid)) { aIVirtualCard = aIVirtualCard2; break; } } } } if (aIVirtualCard == null) { attack.SetAttackTarget(field.EnemyClass); if (AIAttackSimulationUtility.IsAttackPossible(field, attack)) { aIVirtualCard = field.EnemyClass; } else { attack.SetAttackTarget(null); } } else { attack.SetAttackTarget(aIVirtualCard); } return aIVirtualCard; } private static bool IsSkipAttack(AIVirtualField field, AIVirtualAttackInfo situation, AIVirtualCard nextTarget, AIVirtualActionInfo evolutionInfo, bool isHandAllRemovalValid) { AIVirtualCard actor = situation.Actor; AIVirtualCard attackTarget = situation.AttackTarget; if (!attackTarget.IsGuard && AISimulationRemovalUtility.WillDieBySkillPrediction(attackTarget, field, field.BestPlayPtn, situation, isHandAllRemovalValid)) { return true; } if (evolutionInfo != null && !attackTarget.IsGuard && !attackTarget.IsIndependent && !attackTarget.IsIndestructible && field.CheckDestroyByEvoTags(evolutionInfo, attackTarget)) { return true; } AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(actor, nextTarget); if (!attackTarget.IsGuard && !attackTarget.IsIndependent && aIVirtualAttackInfo.WillTargetDestroyByAttackTags(field, field.BestPlayPtn, attackTarget)) { return true; } if (situation.WillTargetDestroyByAttackTags(field, field.BestPlayPtn, attackTarget)) { return true; } if (situation.WillAnyOtherAttackerDestroyed(field, field.BestPlayPtn)) { return true; } return false; } public static void OnAfterExecuteAttackCommon(AIVirtualField field, AIVirtualTurnEndInfo turnEndSituation, ref List moves, bool isAttackToLeaderAgain = false) { if (moves == null || moves.Count <= 0) { AIConsoleUtility.LogError("OnAfterExecuteAttackCommon error!! moves is empty!!!!!"); return; } List beforeCards = new List(field.AllyInplayCards); AIPlayCardSimulationUtility.ExecuteRestPlayPtnAfterAttack(field, ref moves); if (isAttackToLeaderAgain) { AttackToLeaderByNewInplayCards(field, beforeCards); } ProcessAllyTurnEndToOpponentTurnStart(field, turnEndSituation); } public static void ProcessAllyTurnEndToOpponentTurnStart(AIVirtualField field, AIVirtualTurnEndInfo turnEndSituation) { AIVirtualTurnEndSimulator.TurnEnd(turnEndSituation, field); AIVirtualTurnStartInfo situation = new AIVirtualTurnStartInfo(field.EnemyClass); AIVirtualTurnStartSimulator.TurnStart(situation, field); field.DrawCard(isAlly: false, 1, EnemyAI.EmptyPlayPtn, situation); } private static void AttackToLeaderByNewInplayCards(AIVirtualField currentField, List beforeCards) { if (currentField.AllyInplayCards.Count <= beforeCards.Count) { return; } AIVirtualCard enemyClass = currentField.EnemyClass; int actionLength = currentField.ActionLength; for (int i = beforeCards.Count; i < currentField.AllyInplayCards.Count; i++) { AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(currentField.AllyInplayCards[i], enemyClass); if (AIAttackSimulationUtility.IsAttackPossible(currentField, aIVirtualAttackInfo)) { bool isAttackerUsed = false; AIAttackSimulationUtility.SimulateAttackIfValuable(aIVirtualAttackInfo, currentField, useAttackLeaderPreCheck: false, ref isAttackerUsed); if (enemyClass.IsDead) { currentField.ActionLength -= actionLength; break; } } } } private static bool IsToBeKilled(AIVirtualField field) { int life = field.AllyClass.Life; int num = field.GetInplayAttackSumToLeader(isAlly: false); if (field.AI.OPPONENT.IsEvolve) { num += field.EnemyInplayCards.Max((AIVirtualCard card) => card.EvolutionAttack - card.Attack); } return num - life >= 0; } public static AIVirtualActionInfo GetFirstActionInfo(List actionInfoSequence, AIVirtualField field, List playPtn) { AIVirtualActionInfo aIVirtualActionInfo = null; int num = 0; while (num < actionInfoSequence.Count) { AIVirtualActionInfo aIVirtualActionInfo2 = actionInfoSequence[num]; int nextIndexInFindingFirstAction = GetNextIndexInFindingFirstAction(actionInfoSequence, aIVirtualActionInfo2, num); if (aIVirtualActionInfo2.ActionType == AIOperationType.PLAY || aIVirtualActionInfo2.ActionType == AIOperationType.TURNEND) { aIVirtualActionInfo = aIVirtualActionInfo2; break; } AIVirtualCard actor = aIVirtualActionInfo2.Actor; List list = (actor.IsAlly ? field.AllyInplayCards : field.EnemyInplayCards); bool flag = false; for (int i = 0; i < list.Count; i++) { AIVirtualCard aIVirtualCard = list[i]; if (actor.CardIndex == aIVirtualCard.CardIndex) { flag = true; break; } } if (!flag) { num = nextIndexInFindingFirstAction; continue; } if (aIVirtualActionInfo2.ActionType == AIOperationType.EVOLVE) { aIVirtualActionInfo = aIVirtualActionInfo2; break; } if (aIVirtualActionInfo2.ActionType == AIOperationType.ATTACK) { if (!(aIVirtualActionInfo2 is AIVirtualAttackInfo { AttackTarget: var attackTarget } aIVirtualAttackInfo)) { AIConsoleUtility.LogError("GetFirstAction() error!! candidate is not virtualAttackInfo"); continue; } if (attackTarget == null) { num = nextIndexInFindingFirstAction; continue; } if (!aIVirtualAttackInfo.IsAttackSuccessed) { num = nextIndexInFindingFirstAction; continue; } if (attackTarget.IsBreakLast(playPtn) && !attackTarget.IsGuard) { if (aIVirtualActionInfo == null) { aIVirtualActionInfo = aIVirtualActionInfo2; } num = nextIndexInFindingFirstAction; continue; } List list2 = (attackTarget.IsAlly ? field.CardListSet.AllyClassAndInplayCards : field.CardListSet.EnemyClassAndInplayCards); bool flag2 = false; for (int j = 0; j < list2.Count; j++) { AIVirtualCard aIVirtualCard2 = list2[j]; if (attackTarget.CardIndex == aIVirtualCard2.CardIndex) { flag2 = true; break; } } if (flag2) { aIVirtualActionInfo = aIVirtualActionInfo2; break; } } num = nextIndexInFindingFirstAction; } return aIVirtualActionInfo; } private static int GetNextIndexInFindingFirstAction(List actionInfoSequence, AIVirtualActionInfo candidate, int currentIndex) { int result = currentIndex + 1; for (int i = currentIndex + 1; i < actionInfoSequence.Count && actionInfoSequence[i].PremiseAction == candidate; i++) { result = i; } return result; } }