using System.Collections.Generic; namespace Wizard; public static class AIEvalAttackRemoveUtility { private const int REMOVE_TYPE_INDEX = 1; private const int REMOVE_COUNT_INDEX = 0; public static float EvalAttackRemove(AIVirtualCard tagOwner, AIVirtualField field, List playPtn, AISituationInfo situation, List argList) { List list = (tagOwner.IsAlly ? field.EnemyInplayCards : field.AllyInplayCards); if (list.Count <= 0) { return 0f; } List list2 = null; List list3 = null; for (int i = 0; i < list.Count; i++) { AIVirtualCard aIVirtualCard = list[i]; if (aIVirtualCard.IsUnit && !aIVirtualCard.IsCantUnderAnyAttack()) { if (aIVirtualCard.IsGuard) { list2 = AIParamQuery.AddElementToList(aIVirtualCard, list2); } else { list3 = AIParamQuery.AddElementToList(aIVirtualCard, list3); } } } int num = list2?.Count ?? 0; int num2 = list3?.Count ?? 0; if (num + num2 <= 0) { return 0f; } int removeCount = (int)argList[0].Value; AIScriptTokenArgType removeType = GetRemoveType(argList[1]); List replacedTargetSideInplayCardList = new List(list); return CalculateAttackRemoveValue(tagOwner, field, playPtn, removeCount, removeType, list2, list3, replacedTargetSideInplayCardList); } private static float CalculateAttackRemoveValue(AIVirtualCard tagOwner, AIVirtualField field, List playPtn, int removeCount, AIScriptTokenArgType removeType, List guardList, List nonGuardList, List replacedTargetSideInplayCardList) { AIVirtualCard sourceCard = AIInstantAttackUtility.CreateDummyAttacker(field, tagOwner, 1, 1, 1, isEvalRush: true); Dictionary dictionary = null; if (removeCount > 1) { dictionary = new Dictionary(); } float num = 0f; for (int i = 0; i < removeCount; i++) { List list = ((guardList == null || guardList.Count <= 0) ? nonGuardList : guardList); if (list == null) { break; } float num2 = float.MinValue; AIVirtualCard aIVirtualCard = null; bool flag = false; for (int j = 0; j < list.Count; j++) { AIVirtualCard aIVirtualCard2 = list[j]; AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(sourceCard, aIVirtualCard2); bool isRemoved = false; if (!AIAttackSimulationUtility.IsAttackPossible(field, aIVirtualAttackInfo, replacedTargetSideInplayCardList)) { continue; } float num3; if (removeCount > 1 && dictionary.ContainsKey(aIVirtualCard2.CardIndex)) { (num3, isRemoved) = dictionary[aIVirtualCard2.CardIndex]; } else { num3 = CalculateSingleRemoveValue(aIVirtualAttackInfo, field, playPtn, removeType, ref isRemoved); if (removeCount > 1) { dictionary.Add(aIVirtualCard2.CardIndex, (num3, isRemoved)); } } if (num3 > num2) { num2 = num3; aIVirtualCard = aIVirtualCard2; flag = isRemoved; } } if (aIVirtualCard == null) { break; } num += num2; if (flag) { list.Remove(aIVirtualCard); replacedTargetSideInplayCardList.Remove(aIVirtualCard); if (removeCount > 1) { dictionary.Remove(aIVirtualCard.CardIndex); } } } AIInstantAttackUtility.RemoveDummyCardFromField(field); return num; } private static float CalculateSingleRemoveValue(AIVirtualAttackInfo situation, AIVirtualField field, List playPtn, AIScriptTokenArgType removeType, ref bool isRemoved) { AIVirtualCard attackTarget = situation.AttackTarget; isRemoved = true; AIRemovalType removeType2; switch (removeType) { case AIScriptTokenArgType.DESTROY: removeType2 = AIRemovalType.Destroy; isRemoved = !attackTarget.IsIndependent && !attackTarget.IsIndestructible; break; case AIScriptTokenArgType.BANISH: removeType2 = AIRemovalType.Banish; isRemoved = !attackTarget.IsIndependent && !attackTarget.IsUnbanishable; break; default: AIConsoleUtility.LogError("AIEvalAttackRemoveUtility.CalculateSingleRemoveValue() error!! Not implemented removeType = " + removeType); isRemoved = false; return 0f; } if (isRemoved) { return AISimulationRemovalUtility.CalculateRemovalValue(attackTarget, field, playPtn, situation, removeType2, null); } return 0f; } private static AIScriptTokenArgType GetRemoveType(AIScriptTokenBase token) { if (token is AIScriptArgumentToken aIScriptArgumentToken) { return aIScriptArgumentToken.ArgumentType; } return AIScriptTokenArgType.NONE; } }