using System.Collections.Generic; using System.Linq; namespace Wizard; public static class AIBanishSimulationUtility { public static float EvalTargetingBanish(List argList, List playPtn, AIVirtualField field, AIVirtualCard tagOwner, AISituationInfo situation) { List list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothInplayCards, argList, tagOwner, playPtn, null); if (list == null || list.Count <= 0) { return 0f; } list = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(list, tagOwner, playPtn); int num = 0; float num2 = float.MinValue; for (int i = 0; i < list.Count; i++) { AIVirtualCard aIVirtualCard = list[i]; if (!aIVirtualCard.IsIndependent && !aIVirtualCard.IsUnbanishable && (aIVirtualCard.IsAlly == tagOwner.IsAlly || (!aIVirtualCard.IsUntouchable && !aIVirtualCard.IsSneak))) { num++; float num3 = aIVirtualCard.EvaluateValueOnField(playPtn, situation, useStyle: true); float num4 = (aIVirtualCard.IsAlly ? (0f - num3 - aIVirtualCard.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) + aIVirtualCard.GetAllBanishBonus(playPtn, useIgnoreInBattle: false) + aIVirtualCard.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false)) : (num3 + aIVirtualCard.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) - aIVirtualCard.GetAllBanishBonus(playPtn, useIgnoreInBattle: false) - aIVirtualCard.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false))); if (num4 > num2) { num2 = num4; } } } if (num == 0) { num2 = 0f; } return num2; } public static float EvalRandomBanish(List argList, AIVirtualCard tagOwner, AIVirtualField field, List playPtn, int count, AISituationInfo situation) { List list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothInplayCards, argList, tagOwner, playPtn, null); if (list != null && list.Count > 0) { List list2 = new List(); float num = 0f; for (int i = 0; i < list.Count; i++) { AIVirtualCard aIVirtualCard = list[i]; if (!aIVirtualCard.IsUnbanishable && !aIVirtualCard.IsIndependent) { float num2 = aIVirtualCard.EvaluateValueOnField(playPtn, situation, useStyle: true, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true); float num3 = aIVirtualCard.EvaluateBreakValue(playPtn, useIgnoreBreak: true); float allBanishBonus = aIVirtualCard.GetAllBanishBonus(playPtn, useIgnoreInBattle: true); float num4 = aIVirtualCard.EvaluateLeaveValue(playPtn, useIgnoreInBattle: true); float num5 = (aIVirtualCard.IsAlly ? (-1f) : 1f) * (num2 + num3 - allBanishBonus - num4); list2.Add(num5); num += num5; } } if (list.Count <= count) { return num; } List list3 = AIMathematicsLibrary.EnumerateCombinations(list2, count).ToList(); float num6 = 0f; for (int j = 0; j < list3.Count; j++) { for (int k = 0; k < list3[j].Length; k++) { num6 += list3[j][k]; } } return num6 / (float)list3.Count; } return 0f; } public static float EvalAllBanish(List argList, AIVirtualCard tagOwner, AIVirtualField field, List playPtn, AISituationInfo situation) { List list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothInplayCards, argList, tagOwner, playPtn, null); if (list == null || list.Count <= 0) { return 0f; } float num = 0f; for (int i = 0; i < list.Count; i++) { AIVirtualCard aIVirtualCard = list[i]; if (!aIVirtualCard.IsIndependent && !aIVirtualCard.IsUnbanishable) { float num2 = aIVirtualCard.EvaluateValueOnField(playPtn, situation, useStyle: true, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true); float num3 = aIVirtualCard.EvaluateBreakValue(playPtn, useIgnoreBreak: true); float allBanishBonus = aIVirtualCard.GetAllBanishBonus(playPtn, useIgnoreInBattle: true); float num4 = aIVirtualCard.EvaluateLeaveValue(playPtn, useIgnoreInBattle: true); num += (aIVirtualCard.IsAlly ? (-1f) : 1f) * (num2 + num3 - allBanishBonus - num4); } } return num; } public static void BanishAll(List targetCards, AISituationInfo situation) { for (int i = 0; i < targetCards.Count; i++) { BanishSingle(targetCards[i], situation); } } public static void ExecuteTargetSelectBanish(AIVirtualCard owner, List targets, AIVirtualField field, List playPtn, AISituationInfo situation, AIScriptTokenArgType selectType, int selectCount = 1) { if (situation == null) { AIConsoleUtility.LogError("ExecuteTargetSelectBanish() Error!! situation is null!!!!!"); } else if (situation.IsTargetExists(selectType)) { BanishTarget(situation, targets, selectType); } else { BanishTargetPrediction(situation, targets, owner, field, playPtn, selectType, selectCount); } } private static void BanishTargetPrediction(AISituationInfo situation, List candidates, AIVirtualCard banishOwner, AIVirtualField field, List playPtn, AIScriptTokenArgType selectType, int selectCount) { List candidates2 = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(candidates, banishOwner, playPtn); if (selectCount <= 1) { AIVirtualCard target = AISimulationRemovalUtility.SelectRemovalTarget(candidates2, banishOwner, field, playPtn, situation, AISelectTargetPattern.Best, AIRemovalType.Banish); situation.SetSingleTargetInInfo(target, TargetSelectType.Default, selectType); BanishTarget(situation, candidates, selectType); } else { BanishAll(AISimulationRemovalUtility.SelectMultipleRemovalTargets(candidates2, banishOwner, field, playPtn, situation, AISelectTargetPattern.Best, AIRemovalType.Banish, selectCount), situation); } } public static void BanishTarget(AISituationInfo situation, List candidates, AIScriptTokenArgType whichTarget) { AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget); if (situationTarget == null || !situationTarget.HasTarget) { AIConsoleUtility.LogError("BanishTarget error!! No target!!!!!"); return; } List targets = situationTarget.Targets; for (int i = 0; i < targets.Count; i++) { AIVirtualCard aIVirtualCard = targets[i]; if (candidates.Contains(aIVirtualCard)) { BanishSingle(aIVirtualCard, situation); } } } public static void BanishSingle(AIVirtualCard target, AISituationInfo situation) { if (!target.IsDead && !target.IsIndependent && !target.IsUnbanishable) { target.RemoveCard(situation, AIRemovalType.Banish, isFromSkill: true); } } public static void BanishRandom(List targets, AIVirtualCard tagOwner, AIVirtualField field, List playPtn, AISituationInfo situation, int selectCount = 1) { if (selectCount <= 1) { AIVirtualCard aIVirtualCard = AISimulationRemovalUtility.SelectRemovalTarget(targets, tagOwner, field, playPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Banish); if (aIVirtualCard != null) { BanishSingle(aIVirtualCard, situation); } } else { BanishAll(AISimulationRemovalUtility.SelectMultipleRemovalTargets(targets, tagOwner, field, playPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Banish, selectCount), situation); } } public static int GetInplayBanishedCount(AIVirtualCard tagOwner, AIVirtualField field, List playPtn, AISituationInfo situation, List argList) { return GetFilterdBanishCardList(tagOwner, field, playPtn, situation, argList, BattleCardBase.BanishInfo.BanishPlace.Field)?.Count ?? 0; } public static int GetHandBanishedCount(AIVirtualCard tagOwner, AIVirtualField field, List playPtn, AISituationInfo situation, List argList) { return GetFilterdBanishCardList(tagOwner, field, playPtn, situation, argList, BattleCardBase.BanishInfo.BanishPlace.Hand)?.Count ?? 0; } private static List GetFilterdBanishCardList(AIVirtualCard tagOwner, AIVirtualField field, List playPtn, AISituationInfo situation, List argList, BattleCardBase.BanishInfo.BanishPlace place) { List banishedCards = field.CardListSet.BanishedCards; if (banishedCards == null || banishedCards.Count <= 0) { return null; } SeparateArgListToFilterAndTimingArg(argList, out var filters, out var turnOrGame); if (filters == null || filters.Count <= 0 || (turnOrGame != AIScriptTokenArgType.TURN && turnOrGame != AIScriptTokenArgType.GAME)) { return null; } List list = AIFilteringUtility.MultipleFiltering(banishedCards, filters, tagOwner, playPtn, situation, isBlockDeadCard: false); if (list == null || list.Count <= 0) { return null; } if (turnOrGame == AIScriptTokenArgType.TURN) { list.RemoveAll((AIVirtualCard c) => !c.IsBanishedTargetTurn(field.CurrentTurnCount)); } list.RemoveAll((AIVirtualCard c) => c.BanishedInfo.Place != place); return list; } private static void SeparateArgListToFilterAndTimingArg(List argList, out List filters, out AIScriptTokenArgType turnOrGame) { if (argList == null || argList.Count <= 0) { AIConsoleUtility.LogError("AIBanishSimulationUtility.SeparateArgListToFilterAndTimingArg() error!! argList is null!!"); filters = null; turnOrGame = AIScriptTokenArgType.NONE; return; } if (argList[argList.Count - 1] is AIScriptArgumentToken aIScriptArgumentToken) { turnOrGame = aIScriptArgumentToken.ArgumentType; } else { AIConsoleUtility.LogError("AIBanishSimulationUtility.SeparateArgListToFilterAndTimingArg() error!! lastToken is not ArgumentToken!!"); turnOrGame = AIScriptTokenArgType.NONE; } filters = argList.GetRange(0, argList.Count - 1); } }