using System.Collections; using System.Collections.Generic; using System.Linq; namespace Wizard; public class EnemyAI_Attack { private class PlaySkipExecutingInfo { public bool IsEvolutionPermitted; public List SimulationExtraActionBaseList; public PlaySkipExecutingInfo() { IsEvolutionPermitted = false; SimulationExtraActionBaseList = null; } public void AddExtraAction(AIVirtualActionInfo action) { SimulationExtraActionBaseList = AIParamQuery.AddElementToList(action, SimulationExtraActionBaseList); } } private EnemyAI _ai; private IBattleSimulationAI _simulationResultWithEmptyPlayPtn; public bool IsLethalAttackPlan { get; private set; } public EnemyAI_Attack(EnemyAI ai) { _ai = ai; _simulationResultWithEmptyPlayPtn = null; } public void InitOnTurnStart() { _simulationResultWithEmptyPlayPtn = null; } public void InitOnIterationStart() { _simulationResultWithEmptyPlayPtn = null; } public IEnumerator BattleAI_UseHighSimu() { AIVirtualField currentVirtualField = _ai.CurrentVirtualField; AISinglePlayptnRecord playPtnRecord = _ai.BestPlayPtnRecord; PlaySkipExecutingInfo playSkipExecutingInfo = CreatePlaySkipExecutingInfo(playPtnRecord); bool flag = playSkipExecutingInfo?.IsEvolutionPermitted ?? true; bool isEvol = _ai.IsEvoPermissionOnSimu && flag && !_ai.IsBreakBeforePlay; float fastEvoMaxValue = float.MinValue; AIVirtualCard evolveFollower = null; AIVirtualActionInfo firstAction = null; bool isLethalByEvo = false; if (isEvol) { int allyIndex = 0; while (allyIndex < currentVirtualField.AllyInplayCards.Count) { AIVirtualCard inplayTemp = currentVirtualField.AllyInplayCards[allyIndex]; if (inplayTemp.IsAbleEvolution()) { AIVirtualTargetSelectAction situation = new AIVirtualTargetSelectAction(inplayTemp, inplayTemp, AIOperationType.EVOLVE, (AISelectedTargetInfoSet)null); SimulationResult ref_skillSim = new SimulationResult(); List list = inplayTemp.CreateAIVirtualSelectInfo(currentVirtualField, situation); if (list != null) { AIVirtualTargetSelectSimulationInfo simulationInfo = new AIVirtualTargetSelectSimulationInfo { OriginalActor = inplayTemp, RealActor = inplayTemp, SelectInfoList = list, OperationType = AIOperationType.EVOLVE, NextPlayCardInfo = null, IsFirstAction = true }; yield return EnemyAICoroutine.GetInstance().StartCoroutine(AIVirtualTargetSelectSimulator.SimulateTargetSelect(simulationInfo, _ai.CurrentVirtualField, playPtnRecord, ref_skillSim, isBattleSim: true)); if (IsTargetSelectEvolutionValid(ref_skillSim, inplayTemp, fastEvoMaxValue)) { isLethalByEvo = ref_skillSim.IsLethalPlan; fastEvoMaxValue = ref_skillSim.MaxFieldValue; firstAction = ref_skillSim.FirstActionInfo; evolveFollower = inplayTemp; } } } int num = allyIndex + 1; allyIndex = num; } } AIVirtualField field = new AIVirtualField(_ai.CurrentVirtualField) { BestPlayPtn = _ai.BestPlayPtn }; SimulationAdditionalActionInfoSet additionalActionInfoSet = new SimulationAdditionalActionInfoSet { ForceEvoAction = null, ExtraActionBaseList = playSkipExecutingInfo?.SimulationExtraActionBaseList, PlayPtnRecord = playPtnRecord }; AIBattleSimulationLauncher battleSimLauncher = new AIBattleSimulationLauncher(field, _ai, isEvol, _simulationResultWithEmptyPlayPtn, additionalActionInfoSet); yield return battleSimLauncher.ExecuteBattleSimulationAI(null, checkTimeOverLogic: true); IBattleSimulationAI battleSimAI = battleSimLauncher.BattleSimAI; if (_ai.IsBreakBeforePlay && battleSimAI.Cr_MaxField != null && !battleSimAI.Cr_MaxField.IsBreakBeforePlayKilled) { _ai.cr_isOprAtk = false; yield break; } if (battleSimAI.Cr_MaxFieldValue > fastEvoMaxValue) { if (battleSimAI.Cr_FirstActionInfo != null && !(battleSimAI.Cr_FirstActionInfo is AIVirtualTurnEndInfo)) { firstAction = battleSimAI.Cr_FirstActionInfo; evolveFollower = battleSimAI.Cr_MaxField.EvoUsedCard; IsLethalAttackPlan = battleSimAI.Cr_MaxField.EnemyClass.IsDead; } else { firstAction = null; IsLethalAttackPlan = isLethalByEvo; evolveFollower = null; } } if (firstAction == null) { _ai.cr_isOprAtk = false; } else if (!IsPlaySkipPermitted(evolveFollower)) { _ai.cr_isOprAtk = false; } else if (firstAction.ActionType == AIOperationType.PLAY) { foreach (PlayedCardInfo playedCard in _ai.BestPlayPtnRecord.PlayedCardList) { if (playedCard.PreDecidedSelectTargets != null && firstAction.OriginalCard.IsSameCard(playedCard.Card)) { _ai.SetPreDecidedTargets(playedCard.PreDecidedSelectTargets); break; } } _ai.OprPlay(firstAction.OriginalCard, _ai.BestPlayPtnRecord); _ai.cr_isOprAtk = true; } else if (firstAction.ActionType == AIOperationType.EVOLVE) { _ai.CurrentBattleBeforeSimEvoEvolCount = _ai.PlayerPair.Self.CurrentEpCount; _ai.OprEvolution(firstAction.Actor); _ai.CurrentBattleSimEvoCard = evolveFollower; _ai.cr_isOprAtk = true; } else if (firstAction.ActionType == AIOperationType.ATTACK) { _ai.OprAttack(firstAction); _ai.cr_isOprAtk = true; } else { _ai.cr_isOprAtk = false; } } public bool IsPlaySkipPermitted(AIVirtualCard evolveFollower) { if (_ai.PlaySkipInfo == null || !_ai.PlaySkipInfo.Any()) { return true; } bool result = false; for (int i = 0; i < _ai.PlaySkipInfo.Count; i++) { if (_ai.PlaySkipInfo[i].IsEvoCardLegal(evolveFollower)) { result = true; break; } } return result; } private PlaySkipExecutingInfo CreatePlaySkipExecutingInfo(AISinglePlayptnRecord playPtnRecord) { List playSkipInfo = _ai.PlaySkipInfo; if (playSkipInfo == null || playSkipInfo.Count <= 0) { return null; } PlaySkipExecutingInfo playSkipExecutingInfo = new PlaySkipExecutingInfo(); List checkedActionTypeList = null; for (int i = 0; i < playSkipInfo.Count; i++) { PlaySkipInformation playSkipInformation = playSkipInfo[i]; if (playSkipInformation.IsEvolutionPermittedTag) { playSkipExecutingInfo.IsEvolutionPermitted = true; } AIVirtualActionInfo aIVirtualActionInfo = null; if (!(playSkipInformation is PlaySkipWithActionInformation playSkipWithActionInformation)) { if (playSkipInformation is PlaySkipWithActionIfEvoInformation playSkipWithActionIfEvoInformation) { aIVirtualActionInfo = playSkipWithActionIfEvoInformation.GetExtraActionBase(playPtnRecord, ref checkedActionTypeList); } } else { aIVirtualActionInfo = playSkipWithActionInformation.GetExtraActionBase(playPtnRecord, ref checkedActionTypeList); } if (aIVirtualActionInfo != null) { playSkipExecutingInfo.AddExtraAction(aIVirtualActionInfo); } } return playSkipExecutingInfo; } private bool IsTargetSelectEvolutionValid(SimulationResult result, AIVirtualCard targetSelectEvoOwner, float valueForComparing) { if (result.BestResultField == null) { return false; } AIVirtualCard evoUsedCard = result.BestResultField.EvoUsedCard; if (evoUsedCard == null || !evoUsedCard.IsSameCard(targetSelectEvoOwner)) { return false; } if (result.MaxFieldValue <= valueForComparing) { return false; } return true; } public bool BattleAI_TurnEndAttack() { AIVirtualField aIVirtualField = new AIVirtualField(_ai.CurrentVirtualField) { BestPlayPtn = _ai.BestPlayPtn }; AIVirtualField aIVirtualField2 = new AIVirtualField(aIVirtualField); List moves = new List(); AIVirtualTurnEndInfo aIVirtualTurnEndInfo = new AIVirtualTurnEndInfo(aIVirtualField2.AllyClass); moves.Add(aIVirtualTurnEndInfo); BattleSequencer.OnAfterExecuteAttackCommon(aIVirtualField2, aIVirtualTurnEndInfo, ref moves); float num = AISimulationUtility.EvaluateField(aIVirtualField2, EvaluationType.SIMPLE); float num2 = float.MinValue; AIVirtualCard aIVirtualCard = null; AIVirtualCard aIVirtualCard2 = null; for (int i = 0; i < aIVirtualField.AllyInplayCards.Count; i++) { if (!aIVirtualField.AllyInplayCards[i].IsUnit) { continue; } for (int j = -1; j < aIVirtualField.EnemyInplayCards.Count; j++) { if (j >= 0 && !aIVirtualField.EnemyInplayCards[j].IsUnit) { continue; } aIVirtualField2 = new AIVirtualField(aIVirtualField); moves.Clear(); AIVirtualCard aIVirtualCard3 = aIVirtualField2.AllyInplayCards[i]; AIVirtualCard aIVirtualCard4 = ((j < 0) ? aIVirtualField2.EnemyClass : aIVirtualField2.EnemyInplayCards[j]); AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(aIVirtualCard3, aIVirtualCard4); if (AIAttackSimulationUtility.IsAttackPossible(aIVirtualField2, aIVirtualAttackInfo)) { moves.Add(aIVirtualAttackInfo); AIVirtualAttackSimulator.Attack(aIVirtualAttackInfo, aIVirtualField2); AIVirtualTurnEndInfo aIVirtualTurnEndInfo2 = new AIVirtualTurnEndInfo(aIVirtualField2.AllyClass); moves.Add(aIVirtualTurnEndInfo2); BattleSequencer.OnAfterExecuteAttackCommon(aIVirtualField2, aIVirtualTurnEndInfo2, ref moves); num2 = AISimulationUtility.EvaluateField(aIVirtualField2, EvaluationType.SIMPLE); if (num2 > num) { num = num2; aIVirtualCard = aIVirtualCard3; aIVirtualCard2 = aIVirtualCard4; } } } } if (aIVirtualCard != null && aIVirtualCard2 != null) { _ai.OprAttack(new AIVirtualAttackInfo(aIVirtualCard, aIVirtualCard2)); return true; } return false; } public IEnumerator Cr_BattleAI_ImmediateAttack() { AIVirtualField aIVirtualField = new AIVirtualField(_ai.CurrentVirtualField); AIVirtualTurnEndInfo turnEndSituation = new AIVirtualTurnEndInfo(aIVirtualField.AllyClass); BattleSequencer.ProcessAllyTurnEndToOpponentTurnStart(aIVirtualField, turnEndSituation); if (aIVirtualField.IsSuccess()) { _ai.cr_isTerminate = true; _ai.IsTurnEndLethal = true; yield break; } if (!_ai.CurrentVirtualField.isForceImmediateAttack()) { int num = _ai.CurrentVirtualField.EnemyInplayCards.Count((AIVirtualCard card) => card.IsGuard); int num2 = _ai.CurrentVirtualField.AllyInplayCards.Count((AIVirtualCard card) => card.IsAttackable(EnemyAI.EmptyPlayPtn)); bool flag = _ai.CurrentVirtualField.AllyInplayCards.Any((AIVirtualCard card) => card.IsIgnoreGuard); if (num >= num2 && !flag) { _ai.cr_isTerminate = false; yield break; } } _simulationResultWithEmptyPlayPtn = new BestInPlayMoveAI(_ai); yield return EnemyAICoroutine.GetInstance().StartCoroutine(_simulationResultWithEmptyPlayPtn._CrSimulate(_ai.CurrentVirtualField, doesUseEvo: true, checkTimeOverLogic: true)); if (_ai.IsRunWeakLogic) { _simulationResultWithEmptyPlayPtn = new AITimeOverAttackSimulator(); yield return _simulationResultWithEmptyPlayPtn._CrSimulate(_ai.CurrentVirtualField, doesUseEvo: true, checkTimeOverLogic: false); } AIVirtualField cr_MaxField = _simulationResultWithEmptyPlayPtn.Cr_MaxField; if (cr_MaxField == null || !cr_MaxField.EnemyClass.IsDead || cr_MaxField.AllyClass.IsDead) { _ai.cr_isTerminate = false; yield break; } AIVirtualActionInfo cr_FirstActionInfo = _simulationResultWithEmptyPlayPtn.Cr_FirstActionInfo; if (cr_FirstActionInfo == null) { _ai.cr_isTerminate = false; yield break; } _ai.cr_isTerminate = true; if (cr_FirstActionInfo.ActionType == AIOperationType.EVOLVE && !cr_FirstActionInfo.Actor.BaseCard.IsEvolution) { _ai.OprEvolution(cr_FirstActionInfo.Actor); } else if (cr_FirstActionInfo.ActionType == AIOperationType.ATTACK) { if ((cr_FirstActionInfo as AIVirtualAttackInfo).AttackTarget != null) { _ai.OprAttack(cr_FirstActionInfo); } } else { _ai.cr_isTerminate = false; } } }