using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Cute; using UnityEngine; namespace Wizard; public class AITimeOverAttackSimulator : IBattleSimulationAI { private const int NONE_EVOLVE_INDEX = -1; private AIRuleBaseBattleSimulator _ruleBaseSimulator; private SimulationResult _bestResult; private int _originalFieldInplayCount; private ulong[] _defaultPlayptnHashArray; private SimulationAdditionalActionInfoSet _simAdditionalOptions; public AIVirtualField Cr_MaxField { get { if (_bestResult == null) { return null; } return _bestResult.BestResultField; } } public float Cr_MaxFieldValue { get { if (_bestResult == null) { return 0f; } return _bestResult.MaxFieldValue; } } public float Cr_MaxFieldValueAtSelfTurnEnd { get { if (_bestResult == null) { return 0f; } return _bestResult.MaxFieldValueAtSelfTurnEnd; } } public List Cr_MaxActionInfoSequence => _bestResult.ActionSequence; public PlayPtnWithToken Cr_BestPlayPtnWithToken { get; private set; } public AIVirtualActionInfo Cr_FirstActionInfo { get; private set; } public IEnumerator _CrSimulate(AIVirtualField originalField, bool doesUseEvo, bool checkTimeOverLogic, PlayPtnWithToken[] bestPlayPtnWithToken = null, SimulationAdditionalActionInfoSet additionalActions = null) { originalField.AI.IsInVirutalSimulation = true; _ruleBaseSimulator = new AIRuleBaseBattleSimulator(originalField.AI, bestPlayPtnWithToken, canChangeToTimeOverLogic: true); _bestResult = new SimulationResult(); _originalFieldInplayCount = originalField.AllyInplayCards.Count((AIVirtualCard c) => !c.IsDead); _defaultPlayptnHashArray = AISimulationUtility.CalculatePlayptnWithTokenHashs(originalField, bestPlayPtnWithToken); _simAdditionalOptions = additionalActions; ParallelJob job = ParallelJob.Dispatch(delegate { try { AIVirtualField field = new AIVirtualField(originalField); int[] attackerIdxList = SortByOneAttackBreak(field); if (additionalActions != null) { _ = additionalActions.ForceEvoAction; } SimulateEvoPatternBattle(field, attackerIdxList, doesUseEvo); if (bestPlayPtnWithToken != null && Cr_MaxField != null) { int num = Cr_MaxField.AllyInplayCards.Count((AIVirtualCard c) => !c.IsDead); int num2 = Mathf.Min(Mathf.Max(0, _originalFieldInplayCount - num), bestPlayPtnWithToken.Length - 1); Cr_BestPlayPtnWithToken = null; for (int num3 = num2; num3 >= 0; num3--) { if (bestPlayPtnWithToken[num3] != null) { Cr_BestPlayPtnWithToken = bestPlayPtnWithToken[num3]; break; } } } } catch (Exception) { } }); while (!job.isDone) { yield return null; } if (Cr_MaxField != null) { Cr_FirstActionInfo = BattleSequencer.GetFirstActionInfo(_bestResult.ActionSequence, Cr_MaxField, Cr_MaxField.BestPlayPtn); } originalField.AI.IsInVirutalSimulation = false; } private int[] SortByOneAttackBreak(AIVirtualField field) { List sortedAttackerIndexList = GetSortedAttackerIndexList(field); int num = ((field.EnemyInplayCards != null) ? field.EnemyInplayCards.Count : 0); if (num == 0) { return sortedAttackerIndexList.ToArray(); } List list = new List(); List list2 = new List(); List list3 = new List(sortedAttackerIndexList); for (int i = 0; i < sortedAttackerIndexList.Count; i++) { int num2 = 0; bool flag = false; int num3 = 0; for (int j = 0; j < num; j++) { AIVirtualCard aIVirtualCard = field.AllyInplayCards[sortedAttackerIndexList[i]]; AIVirtualCard aIVirtualCard2 = field.EnemyInplayCards[j]; if (!aIVirtualCard2.IsUnit) { continue; } int num4 = aIVirtualCard2.SimulateDamageAmount(aIVirtualCard.Attack); if (aIVirtualCard2.Life <= num4) { num2++; if (!flag) { flag = aIVirtualCard2.IsBreakFirst(field.BestPlayPtn); } if (aIVirtualCard2.IsBreakLast(field.BestPlayPtn)) { num3++; } break; } } if (num2 > 0 && flag) { int item = sortedAttackerIndexList[i]; list.Add(item); list3.Remove(item); } else if (num2 == 0 || (num2 > 0 && num3 == num2)) { int item2 = sortedAttackerIndexList[i]; list2.Add(item2); list3.Remove(item2); } } list.AddRange(list3); list.AddRange(list2); return list.ToArray(); } private void SimulateEvoPatternBattle(AIVirtualField field, int[] attackerIdxList, bool useEve) { List sortedAttackTargetIndexList = GetSortedAttackTargetIndexList(field); if (((_simAdditionalOptions != null) ? _simAdditionalOptions.ForceEvoAction : null) != null) { SimulateTargetsBreakPattern(field, attackerIdxList, -1, sortedAttackTargetIndexList); return; } int num = (useEve ? field.AllyInplayCards.Count : 0); for (int i = -1; i < num; i++) { if (AISimulationUtility.IsValuableEvoIndex(i, field)) { SimulateTargetsBreakPattern(field, attackerIdxList, i, sortedAttackTargetIndexList); } } } private void SimulateTargetsBreakPattern(AIVirtualField field, int[] attackrIndecies, int evoIndex, List enemyAllTargets) { List list = new List(); List list2 = new List(); _ruleBaseSimulator.RunSequence(field, attackrIndecies, evoIndex, new List(), _bestResult, _simAdditionalOptions, null, checkActFailure: false); list.Add(AISimulationUtility.CalculateTargetSequenceHash(list2.ToArray(), field)); int num = enemyAllTargets.Count; while (num > 0 && !field.AI.IsBattleEnd) { int[] patternGroup = AISimulationUtility.GetPatternGroup(num); if (patternGroup != null) { for (int i = 0; i < patternGroup.Length; i++) { List enemyTargets = AISimulationUtility.GetEnemyTargets(field.EnemyInplayCards, enemyAllTargets, patternGroup[i], field.BestPlayPtn); ulong item = AISimulationUtility.CalculateTargetSequenceHash(enemyTargets.ToArray(), field); if (!list.Contains(item)) { AIOneMoreLastwordUtility.SortEnemyTargetByBreakBonus(field, enemyTargets); if (!AISimulationUtility.IsValidEnemyTargetIndexes(field.EnemyInplayCards, enemyTargets)) { return; } _ruleBaseSimulator.RunSequence(field, attackrIndecies, evoIndex, enemyTargets, _bestResult, _simAdditionalOptions, null, checkActFailure: false); list.Add(item); } } } num--; } } private List GetSortedAttackerIndexList(AIVirtualField field) { List list = new List(); List list2 = new List(); List allyInplayCards = field.AllyInplayCards; for (int i = 0; i < allyInplayCards.Count; i++) { list2.Add(AIAttackSimulationUtility.IsAttackPossible(field, allyInplayCards[i].AttackLeaderSituation)); } for (int j = 0; j < allyInplayCards.Count; j++) { AIVirtualCard aIVirtualCard = allyInplayCards[j]; if (!aIVirtualCard.IsUnit) { continue; } int num = -1; for (int k = 0; k < list.Count; k++) { int index = list[k]; AIVirtualCard aIVirtualCard2 = allyInplayCards[index]; if (aIVirtualCard.Attack < aIVirtualCard2.Attack) { num = k; break; } if (aIVirtualCard.Attack == aIVirtualCard2.Attack && (!list2[j] || list2[index]) && ((!list2[j] && list2[index]) || aIVirtualCard.Life < aIVirtualCard2.Life)) { num = k; break; } } if (num >= 0 && num < list.Count) { list.Insert(num, j); } else { list.Add(j); } } return list; } private List GetSortedAttackTargetIndexList(AIVirtualField field) { List list = new List(); List list2 = new List(); List enemyInplayCards = field.EnemyInplayCards; for (int i = 0; i < enemyInplayCards.Count; i++) { AIVirtualCard aIVirtualCard = enemyInplayCards[i]; if (!aIVirtualCard.IsUnit) { continue; } int num = -1; List list3 = (aIVirtualCard.IsGuard ? list2 : list); for (int j = 0; j < list3.Count; j++) { AIVirtualCard aIVirtualCard2 = enemyInplayCards[list3[j]]; if (aIVirtualCard.Life < aIVirtualCard2.Life || (aIVirtualCard.Life == aIVirtualCard2.Life && aIVirtualCard.Attack > aIVirtualCard2.Attack)) { num = j; break; } } if (num >= 0 && num < list3.Count) { list3.Insert(num, i); } else { list3.Add(i); } } list2.AddRange(list); return list2; } }