Files
SVSimServer/SVSim.BattleEngine/Engine/Wizard/AISimulationUtility.cs
gamer147 957af3d1ec feat(battle-engine): full Unity/VFX/god-object shims + expanded copy closure (2570 files)
Authored Unity primitive/object-model shim, VFX layer (control-flow-preserving, InstantVfx never invokes its action -- headless suppression), god-object stubs (GameMgr/EffectMgr/UIManager with faithfully-extracted nested enums), View/UI/Touch tree, LitJson+BetterList+Tuple copied, third-party stubs. Discovered Roslyn header-error masking: fixing class-header type errors unmasks body references, so the true copy closure is ~2570 files (was 782 under masking). Errors: masked-25720 -> 268; our shim files compile clean. Remaining: ~50 residual shim/external types, 24 NGUI UI-base overrides, static-type fixes, plus likely 1-2 more unmask waves.
2026-06-05 17:22:20 -04:00

747 lines
27 KiB
C#

using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Wizard;
public static class AISimulationUtility
{
public static int FULL_SIMULATION_MOVE_COUNT_TURESHOLD = 16;
public static float ILLEGAL_PLAYPTN_VALUE = -1000f;
private static readonly int[] PATTERN_GROUP_FOR_5 = new int[1] { 31 };
private static readonly int[] PATTERN_GROUP_FOR_4 = new int[5] { 30, 29, 27, 23, 15 };
private static readonly int[] PATTERN_GROUP_FOR_3 = new int[10] { 28, 26, 25, 22, 21, 19, 14, 13, 11, 7 };
private static readonly int[] PATTERN_GROUP_FOR_2 = new int[10] { 24, 20, 18, 17, 12, 10, 9, 6, 5, 3 };
private static readonly int[] PATTERN_GROUP_FOR_1 = new int[5] { 16, 8, 4, 2, 1 };
private static ulong[] PRIME_NUMBERS_FOR_ENEMY = new ulong[6] { 67uL, 9221uL, 181uL, 271939uL, 3001uL, 12277uL };
private static ulong[] PRIME_NUMBERS_FOR_ALLY = new ulong[6] { 4919uL, 11149uL, 187651uL, 139uL, 3011uL, 2003uL };
public static List<AIVirtualActionInfo> GetActionInfoSequence(AIVirtualField field, int[] permList, bool[] isAttackFollowerFlags, int evoIndex)
{
List<AIVirtualActionInfo> list = new List<AIVirtualActionInfo>();
if (permList != null && permList.Length <= field.AllyInplayCards.Count((AIVirtualCard c) => c.IsUnit) && permList.Length == isAttackFollowerFlags.Length)
{
for (int num = 0; num < permList.Length; num++)
{
int num2 = permList[num];
AIVirtualCard originalActor = field.AllyInplayCards[num2];
AIVirtualCard currentFieldActor = field.AllyInplayCards.FirstOrDefault((AIVirtualCard card) => card.CardIndex == originalActor.CardIndex);
if (currentFieldActor == null)
{
break;
}
if (num2 == evoIndex && !currentFieldActor.IsEvolution)
{
field.AllyInplayCards[num2].IsUseEvo = true;
if (field.CardListSet.AllyClassAndInplayCards.Any((AIVirtualCard c) => c.IsFirstEvo(currentFieldActor, field.BestPlayPtn)))
{
list.Insert(0, new AIVirtualTargetSelectAction(currentFieldActor, currentFieldActor, AIOperationType.EVOLVE));
}
else
{
list.Add(new AIVirtualTargetSelectAction(currentFieldActor, currentFieldActor, AIOperationType.EVOLVE));
}
}
list.Add(new AIVirtualAttackInfo(currentFieldActor, isAttackFollowerFlags[num]));
}
}
field.ActionLength = 0;
return list;
}
public static List<int> GetEnemyTargets(List<AIVirtualCard> enemyInplayCards, List<int> targetCandidates, int breakPtnIndex, List<int> playPtn)
{
List<int> list = new List<int>();
for (int i = 0; i < targetCandidates.Count; i++)
{
int num = targetCandidates[i];
if (!enemyInplayCards[num].IsAmulet && ((breakPtnIndex >> i) & 1) > 0)
{
AddTarget(enemyInplayCards, num, list, playPtn);
}
}
return list;
}
private static void AddTarget(List<AIVirtualCard> targetCandidates, int targetIndex, List<int> virtualCardList, List<int> playPtn)
{
AIVirtualCard tagOwner = targetCandidates[targetIndex];
int num = -1;
for (int i = 0; i < virtualCardList.Count; i++)
{
if (targetCandidates[virtualCardList[i]].IsBreakLast(playPtn))
{
num = i;
break;
}
}
if (tagOwner.IsBreakFirst(playPtn))
{
virtualCardList.Insert(0, targetIndex);
}
else if (tagOwner.IsBreakLast(playPtn))
{
virtualCardList.Add(targetIndex);
}
else if (num >= 0)
{
virtualCardList.Insert(num, targetIndex);
}
else
{
virtualCardList.Add(targetIndex);
}
}
public static List<AIVirtualCard> GetEnemyTargetSequence(AIVirtualField field, List<int> enemyTargetIndexes)
{
List<AIVirtualCard> list = new List<AIVirtualCard>();
for (int i = 0; i < enemyTargetIndexes.Count; i++)
{
if (enemyTargetIndexes[i] < field.EnemyInplayCards.Count && enemyTargetIndexes[i] >= 0)
{
list.Add(field.EnemyInplayCards[enemyTargetIndexes[i]]);
}
}
return list;
}
public static bool IsValidEnemyTargetIndexes(List<AIVirtualCard> enemyCards, List<int> enemyTargetIndexes)
{
if (enemyTargetIndexes.Count > enemyCards.Count)
{
return false;
}
for (int i = 0; i < enemyTargetIndexes.Count; i++)
{
if (enemyCards[enemyTargetIndexes[i]].IsAmulet)
{
return false;
}
}
return true;
}
public static bool IsValuableEvoIndex(int evoIndex, AIVirtualField originalField)
{
if (evoIndex >= 0 && !originalField.AllyInplayCards[evoIndex].IsUnit)
{
return false;
}
if (evoIndex >= 0)
{
AIVirtualCard aIVirtualCard = originalField.AllyInplayCards[evoIndex];
AIVirtualTargetSelectAction situation = new AIVirtualTargetSelectAction(aIVirtualCard, aIVirtualCard, AIOperationType.EVOLVE, (AISelectedTargetInfoSet)null);
if (!aIVirtualCard.IsAbleEvolution() || aIVirtualCard.CreateAIVirtualSelectInfo(originalField, situation) != null)
{
return false;
}
}
return true;
}
public static bool IsBestRecord(AIVirtualField field, float currentFieldValue, float valueAtSelfTurnEnd, SimulationResult bestRecord)
{
if (field.EnemyClass.IsDead)
{
int actionLength = field.ActionLength;
if (actionLength < bestRecord.MinActionLengthOfLethal || (actionLength == bestRecord.MinActionLengthOfLethal && EnemyAI.IsLargerThan(currentFieldValue, bestRecord.MaxFieldValue)))
{
return true;
}
}
else
{
if (EnemyAI.IsLargerThan(currentFieldValue, bestRecord.MaxFieldValue))
{
return true;
}
if (EnemyAI.IsSameValue(currentFieldValue, bestRecord.MaxFieldValue) && EnemyAI.IsLargerThan(valueAtSelfTurnEnd, bestRecord.MaxFieldValueAtSelfTurnEnd))
{
return true;
}
}
return false;
}
public static bool ExecuteVirtualAction(AIVirtualActionInfo actionInfo, AIVirtualActionInfo evolutionInfo, List<AIVirtualCard> enemyTargetSequence, SimulationSetting setting)
{
AIVirtualField selfField = actionInfo.Actor.SelfField;
if (actionInfo.IsAlreadyUsed)
{
_ = (actionInfo.Actor.IsPlayer ? "p" : "e") + actionInfo.Actor.CardIndex;
return false;
}
if (actionInfo.Actor.IsDead)
{
actionInfo.IsAlreadyUsed = true;
return false;
}
if (actionInfo.ActionType == AIOperationType.EVOLVE)
{
actionInfo.IsAlreadyUsed = true;
if (actionInfo.Actor.IsEvolution)
{
return false;
}
if (!actionInfo.Actor.IsUseEvo)
{
return false;
}
AIVirtualEvolutionSimulator.ManualEvolve(actionInfo, selfField);
selfField.EvoUsedCard = actionInfo.Actor;
}
else if (actionInfo is AIVirtualAttackInfo aIVirtualAttackInfo)
{
AIVirtualAttackInfo aIVirtualAttackInfo2 = aIVirtualAttackInfo;
if (aIVirtualAttackInfo.AttackTarget != null)
{
aIVirtualAttackInfo2 = new AIVirtualAttackInfo(aIVirtualAttackInfo.Actor, aIVirtualAttackInfo.IsAttackFollower, aIVirtualAttackInfo.PremiseAction);
}
AIVirtualCard aIVirtualCard = BattleSequencer.FindAttackTarget(selfField, aIVirtualAttackInfo2, enemyTargetSequence, evolutionInfo, setting.IsHandRemovalValid, setting.NoSkipAttack, aIVirtualAttackInfo2.IsAttackFollower);
bool isAttackerUsed = false;
if (aIVirtualCard != null)
{
AIAttackSimulationUtility.SimulateAttackIfValuable(aIVirtualAttackInfo2, selfField, setting.UseLeaderAttackPreCheck, ref isAttackerUsed);
if (aIVirtualCard.IsDead)
{
aIVirtualAttackInfo2.IsBreakTarget = true;
}
}
else
{
aIVirtualAttackInfo2.SetAttackTarget(null);
isAttackerUsed = true;
}
actionInfo.IsAlreadyUsed = isAttackerUsed;
if (!aIVirtualAttackInfo2.IsAttackSuccessed)
{
return false;
}
}
return true;
}
public static float EvaluateField(AIVirtualField field, EvaluationType type)
{
switch (type)
{
case EvaluationType.FULL:
return field.EvaluateField() - (field.EnemyClass.IsDead ? 0f : field.EvaluateThreaten());
case EvaluationType.SELF_TURN:
case EvaluationType.SIMPLE:
return field.EvaluateField();
default:
return 0f;
}
}
public static float EvaluateLegalPlayPtnAfterSimulation(AIVirtualField fieldTemp, List<AIVirtualActionInfo> actionInfoSequence, PlayPtnWithToken[] playPtnsWithToken, int openCount, ulong[] defaultPlayptnHashs, out PlayPtnWithToken bestPlayPtnWithToken, out int bestFirstDeadActionIndex)
{
bestFirstDeadActionIndex = int.MaxValue;
bestPlayPtnWithToken = null;
ulong[] array = CalculatePlayptnWithTokenHashs(fieldTemp, playPtnsWithToken);
PlayPtnWithToken[] array2 = new PlayPtnWithToken[playPtnsWithToken.Length];
for (int i = 0; i < playPtnsWithToken.Length; i++)
{
PlayPtnWithToken playPtnWithToken = playPtnsWithToken[i];
if (playPtnWithToken == null || array[i] != defaultPlayptnHashs[i])
{
array2[i] = null;
}
else
{
array2[i] = playPtnWithToken;
}
}
if (array2.Any((PlayPtnWithToken p) => p != null))
{
return EvaluatePlayPtnValue(fieldTemp, actionInfoSequence, array2, openCount, out bestPlayPtnWithToken, out bestFirstDeadActionIndex);
}
return ILLEGAL_PLAYPTN_VALUE;
}
private static float EvaluatePlayPtnValue(AIVirtualField fieldTemp, List<AIVirtualActionInfo> actionInfoSequence, PlayPtnWithToken[] playPtnsWithToken, int openCount, out PlayPtnWithToken bestPlayPtnWithToken, out int bestFirstDeadActionIndex)
{
AIVirtualFieldRollBackBasicProcessor aIVirtualFieldRollBackBasicProcessor = new AIVirtualFieldRollBackBasicProcessor(fieldTemp);
AIStyleQuery styleQuery = fieldTemp.ParamQuery.styleQuery;
float num = float.MinValue;
bestFirstDeadActionIndex = int.MaxValue;
bestPlayPtnWithToken = null;
for (int num2 = openCount; num2 >= 0; num2--)
{
if (playPtnsWithToken[num2] != null)
{
PlayPtnWithToken playPtnWithToken = playPtnsWithToken[num2];
if (playPtnWithToken != null)
{
List<int> list = (fieldTemp.BestPlayPtn = playPtnWithToken.PlayPtn);
fieldTemp.UpdateBestPlayptnRecordOnSim(list);
List<TokenPlayPattern> tokenPtn = playPtnWithToken.TokenPtn;
if (list.Count == tokenPtn.Count)
{
float num3 = float.MinValue;
for (int i = 0; i < fieldTemp.AllyInplayCards.Count; i++)
{
AIVirtualCard aIVirtualCard = fieldTemp.AllyInplayCards[i];
if (aIVirtualCard.IsUnit && !aIVirtualCard.IsDead && aIVirtualCard.IsAbleEvolution())
{
float num4 = aIVirtualCard.EvaluateAllEvoBonus(list, new AIVirtualTargetSelectAction(aIVirtualCard, aIVirtualCard, AIOperationType.EVOLVE, (AISelectedTargetInfoSet)null));
if (num4 > num3)
{
num3 = num4;
}
}
}
float num5 = 0f;
AISinglePlayptnRecord playptnRecordOnSim = fieldTemp.GetPlayptnRecordOnSim(list);
for (int j = 0; j < tokenPtn.Count; j++)
{
TokenPlayPattern tokenPlayPattern = tokenPtn[j];
AIVirtualCard aIVirtualCard2 = fieldTemp.AllyHandCards[list[j]];
AIVirtualTargetSelectAction situation = new AIVirtualTargetSelectAction(aIVirtualCard2, aIVirtualCard2, AIOperationType.PLAY, (AISelectedTargetInfoSet)null);
AIPreprocessSimulationUtility.SimulatePreprocess(aIVirtualCard2, situation, fieldTemp, AIScriptTokenArgType.WHEN_PLAY, isPseudo: true);
bool flag = fieldTemp.StyleQuery.IsPlayBreak(aIVirtualCard2, list, situation);
bool flag2 = playptnRecordOnSim.PlayedCardList[j].PlayType == PlaySimulationType.Accelerate;
if (!flag && !flag2)
{
num5 += aIVirtualCard2.EvaluateValueOnField(list, null, useStyle: true);
}
num5 += aIVirtualCard2.EvaluatePlayValue(list, situation);
num5 += (aIVirtualCard2.GetAllBreakBonus(list, useIgnoreInBattle: false) + aIVirtualCard2.GetAllLeaveBonus(list, useIgnoreInBattle: false)) * (flag ? 1f : EnemyAI.BREAKBONUS_RATE_IN_HAND);
fieldTemp.UpdateVirtualFieldWhenEvaluation(aIVirtualCard2, situation);
if (tokenPlayPattern.TokenInfoPairList != null && tokenPlayPattern.TokenInfoPairList.Count > 0)
{
for (int k = 0; k < tokenPlayPattern.TokenInfoPairList.Count; k++)
{
AITokenInformation aITokenInformation = tokenPlayPattern.TokenInfoPairList[k];
int tokenId = aITokenInformation.TokenId;
AIVirtualCard tokenFromId = fieldTemp.AI.tokenManager.GetTokenFromId(tokenId, aIVirtualCard2.IsAlly, fieldTemp);
num5 += tokenFromId.EvaluateValueOnField(list, null, useStyle: true);
num5 += (tokenFromId.GetAllBreakBonus(list, useIgnoreInBattle: false) + tokenFromId.GetAllLeaveBonus(list, useIgnoreInBattle: false)) * EnemyAI.BREAKBONUS_RATE_IN_HAND;
if (aITokenInformation.TokenType == AITokenType.Reanimate)
{
num5 += tokenFromId.GetReanimateBonus(list);
}
}
}
if (j == 0 && aIVirtualCard2.IsFollower(list) && aIVirtualCard2.IsAbleEvolution())
{
float num6 = aIVirtualCard2.EvaluateAllEvoBonus(list, new AIVirtualTargetSelectAction(aIVirtualCard2, aIVirtualCard2, AIOperationType.EVOLVE, (AISelectedTargetInfoSet)null));
if (num6 > num3)
{
num5 += num6;
}
}
}
aIVirtualFieldRollBackBasicProcessor.ResetVirtualFieldToStart();
num5 += AIEvaluateBonusFromOhterUtility.GetPlayPtnBonus(fieldTemp, list) + styleQuery.GetPlayptnBonus(fieldTemp, list);
int num7 = int.MaxValue;
for (int l = 0; l < actionInfoSequence.Count; l++)
{
if (actionInfoSequence[l].Actor != null && actionInfoSequence[l].Actor.IsDead)
{
num7 = l;
break;
}
}
if (EnemyAI.IsLargerThan(num5, num) || (EnemyAI.IsSameValue(num5, num) && num7 < bestFirstDeadActionIndex))
{
num = num5;
bestFirstDeadActionIndex = num7;
bestPlayPtnWithToken = playPtnWithToken;
}
}
}
}
}
return num;
}
public static float CalculateMoveFirstBonusValue(List<AIVirtualActionInfo> moves)
{
if (moves == null || !moves.Any())
{
return 0f;
}
AIVirtualCard actor = moves[0].Actor;
return actor.SelfField.StyleQuery.GetFirstMoveBonus(actor, moves);
}
public static float CalculateOneOnOneBothDeadBonus(List<AIVirtualActionInfo> moves)
{
if (moves.Count <= 1 || !(moves[0] is AIVirtualAttackInfo))
{
return 0f;
}
AIVirtualAttackInfo aIVirtualAttackInfo = moves[0] as AIVirtualAttackInfo;
if (aIVirtualAttackInfo.Actor.IsDead && aIVirtualAttackInfo.IsBreakTarget)
{
return 0.002f;
}
return 0f;
}
public static List<AIVirtualActionInfo> GetAllMovesForFullSimulation(AIVirtualField field, bool doesUseEvo, SimulationAdditionalActionInfoSet additionalActionInfoSet)
{
AIVirtualTargetSelectAction aIVirtualTargetSelectAction = null;
List<AIVirtualActionInfo> extraActions = null;
AISinglePlayptnRecord playPtnRecord = null;
if (additionalActionInfoSet != null)
{
aIVirtualTargetSelectAction = additionalActionInfoSet.ForceEvoAction;
extraActions = additionalActionInfoSet.ExtraActionBaseList;
playPtnRecord = additionalActionInfoSet.PlayPtnRecord;
}
List<AIVirtualActionInfo> list = null;
if (doesUseEvo)
{
list = GetAllVirtualInplayMove(field);
}
else
{
list = GetAllVirtualAttackMove(field);
if (aIVirtualTargetSelectAction != null)
{
AIVirtualActionInfo aIVirtualActionInfo = CreateActionInfoOnFieldFromSituation(field, aIVirtualTargetSelectAction);
if (aIVirtualActionInfo != null)
{
list.Add(aIVirtualActionInfo);
}
}
}
List<AIVirtualActionInfo> allExtraActionList = GetAllExtraActionList(field, extraActions, playPtnRecord);
if (allExtraActionList != null && allExtraActionList.Count > 0)
{
list.AddRange(allExtraActionList);
}
list.Add(new AIVirtualTurnEndInfo(field.AllyClass));
return list;
}
private static List<AIVirtualActionInfo> GetAllVirtualInplayMove(AIVirtualField field)
{
List<AIVirtualActionInfo> list = new List<AIVirtualActionInfo>();
List<AIVirtualActionInfo> allVirtualEvolMove = GetAllVirtualEvolMove(field);
List<AIVirtualActionInfo> allVirtualAttackMove = GetAllVirtualAttackMove(field);
for (int i = 0; i < allVirtualEvolMove.Count; i++)
{
list.Add(allVirtualEvolMove[i]);
}
for (int j = 0; j < allVirtualAttackMove.Count; j++)
{
list.Add(allVirtualAttackMove[j]);
}
return list;
}
private static List<AIVirtualActionInfo> GetAllVirtualEvolMove(AIVirtualField field)
{
List<AIVirtualActionInfo> list = new List<AIVirtualActionInfo>();
if (field.EvoUsedCard != null)
{
return list;
}
for (int i = 0; i < field.AllyInplayCards.Count; i++)
{
AIVirtualCard aIVirtualCard = field.AllyInplayCards[i];
if (!aIVirtualCard.IsDead)
{
AIVirtualTargetSelectAction aIVirtualTargetSelectAction = new AIVirtualTargetSelectAction(aIVirtualCard, aIVirtualCard, AIOperationType.EVOLVE);
if (aIVirtualCard.IsAbleEvolution() && aIVirtualCard.CreateAIVirtualSelectInfo(field, aIVirtualTargetSelectAction) == null)
{
list.Add(aIVirtualTargetSelectAction);
}
}
}
return list;
}
private static List<AIVirtualActionInfo> GetAllVirtualAttackMove(AIVirtualField field)
{
List<AIVirtualActionInfo> list = new List<AIVirtualActionInfo>();
for (int i = 0; i < field.AllyInplayCards.Count; i++)
{
AIVirtualCard aIVirtualCard = field.AllyInplayCards[i];
if (aIVirtualCard.IsDead)
{
continue;
}
for (int j = 0; j < field.EnemyInplayCards.Count; j++)
{
AIVirtualCard aIVirtualCard2 = field.EnemyInplayCards[j];
AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(aIVirtualCard, aIVirtualCard2);
if (!aIVirtualCard2.IsDead && AIAttackSimulationUtility.IsAttackPossible(field, aIVirtualAttackInfo))
{
list.Add(aIVirtualAttackInfo);
}
}
}
for (int k = 0; k < field.AllyInplayCards.Count; k++)
{
AIVirtualCard aIVirtualCard3 = field.AllyInplayCards[k];
if (!aIVirtualCard3.IsDead)
{
AIVirtualAttackInfo aIVirtualAttackInfo2 = new AIVirtualAttackInfo(aIVirtualCard3, field.EnemyClass);
if (!field.EnemyClass.IsDead && AIAttackSimulationUtility.IsAttackPossible(field, aIVirtualAttackInfo2))
{
list.Add(aIVirtualAttackInfo2);
}
}
}
return list;
}
private static List<AIVirtualActionInfo> GetAllExtraActionList(AIVirtualField field, List<AIVirtualActionInfo> extraActions, AISinglePlayptnRecord playPtnRecord)
{
if (extraActions == null || extraActions.Count <= 0)
{
return null;
}
List<AIVirtualActionInfo> list = null;
for (int i = 0; i < extraActions.Count; i++)
{
AIVirtualActionInfo aIVirtualActionInfo = extraActions[i];
if (aIVirtualActionInfo.ActionType != AIOperationType.PLAY || !(CreateActionInfoOnFieldFromSituation(field, aIVirtualActionInfo) is AIVirtualTargetSelectAction aIVirtualTargetSelectAction))
{
continue;
}
List<AIVirtualTargetSelectInfo> list2 = aIVirtualTargetSelectAction.Actor.CreateAIVirtualSelectInfo(field, aIVirtualTargetSelectAction);
if (list2 == null || list2.Count <= 0)
{
if (AIPlayCardSimulationUtility.IsAbleToPlayCard(aIVirtualTargetSelectAction, field, EnemyAI.EmptyPlayPtn) && field.AllyInplayCards.Count((AIVirtualCard c) => !c.IsDead) < 5)
{
list = AIParamQuery.AddElementToList(aIVirtualTargetSelectAction, list);
}
continue;
}
AISelectedTargetInfoSet preDecidedTargetSet = null;
if (aIVirtualTargetSelectAction.SelectedTargets.IsAnyTargetExists())
{
preDecidedTargetSet = aIVirtualTargetSelectAction.SelectedTargets;
}
List<AISelectedTargetInfoSet> allTargetSelectSimulationPattern = AIVirtualTargetSelectSimulator.GetAllTargetSelectSimulationPattern(list2, preDecidedTargetSet, aIVirtualTargetSelectAction, field, playPtnRecord);
if (allTargetSelectSimulationPattern == null || allTargetSelectSimulationPattern.Count <= 0)
{
continue;
}
for (int num = 0; num < allTargetSelectSimulationPattern.Count; num++)
{
AISelectedTargetInfoSet selectedTargetList = allTargetSelectSimulationPattern[num];
AIVirtualTargetSelectAction aIVirtualTargetSelectAction2 = new AIVirtualTargetSelectAction(aIVirtualTargetSelectAction.Actor, aIVirtualTargetSelectAction.OriginalCard, AIOperationType.PLAY, selectedTargetList);
if (AIPlayCardSimulationUtility.IsAbleToPlayCard(aIVirtualTargetSelectAction2, field, EnemyAI.EmptyPlayPtn) && field.AllyInplayCards.Count < 5)
{
list = AIParamQuery.AddElementToList(aIVirtualTargetSelectAction2, list);
}
}
}
return list;
}
public static float EvaluateAttackValueAfterAllSkill(AIVirtualField field, AISituationInfo situation, List<AIVirtualCardStatusInfo> allyAttackers, List<AIVirtualCardStatusInfo> enemyRemains, List<int> playPtn)
{
for (int i = 0; i < allyAttackers.Count; i++)
{
allyAttackers[i].CalculateCardValueWhenDestroyed(playPtn, situation);
}
for (int j = 0; j < enemyRemains.Count; j++)
{
enemyRemains[j].CalculateCardValueWhenDestroyed(playPtn, situation);
}
enemyRemains.OrderBy((AIVirtualCardStatusInfo info) => info.ValueWhenDestroyed);
float num = 0f;
AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(null, null);
for (int num2 = 0; num2 < enemyRemains.Count; num2++)
{
AIVirtualCardStatusInfo aIVirtualCardStatusInfo = enemyRemains[num2];
aIVirtualAttackInfo.SetAttackTarget(aIVirtualCardStatusInfo.BaseCard);
float num3 = 0f;
List<AIVirtualCardStatusInfo> usedAttackers = null;
int num4 = 0;
List<int> list = null;
int num5 = (int)Mathf.Pow(2f, allyAttackers.Count);
for (int num6 = 0; num6 < num5; num6++)
{
int num7 = num6;
int num8 = 0;
int num9 = 0;
int num10 = 0;
float num11 = 0f;
float num12 = 0f;
List<AIVirtualCardStatusInfo> list2 = new List<AIVirtualCardStatusInfo>();
List<int> list3 = new List<int>();
while (num7 > 0)
{
if (num7 % 2 == 1)
{
AIVirtualCardStatusInfo aIVirtualCardStatusInfo2 = allyAttackers[num8];
if (!aIVirtualCardStatusInfo2.BaseCard.IsAttackable(EnemyAI.EmptyPlayPtn))
{
num8++;
num7 /= 2;
continue;
}
aIVirtualAttackInfo.SetActor(aIVirtualCardStatusInfo2.BaseCard);
list2.Add(aIVirtualCardStatusInfo2);
num9 += aIVirtualCardStatusInfo.BaseCard.SimulateDamageAmount(aIVirtualCardStatusInfo2.BaseCard.SimulateAttackAmount(aIVirtualCardStatusInfo2.Attack, aIVirtualAttackInfo));
num10 += aIVirtualCardStatusInfo.BaseCard.SimulateDamageAmount(aIVirtualCardStatusInfo2.BaseCard.SimulateAttackAmount(aIVirtualAttackInfo));
int num13 = aIVirtualCardStatusInfo2.BaseCard.SimulateDamageAmount(aIVirtualCardStatusInfo.BaseCard.SimulateAttackAmount(aIVirtualCardStatusInfo.Attack, aIVirtualAttackInfo));
int num14 = aIVirtualCardStatusInfo2.BaseCard.SimulateDamageAmount(aIVirtualCardStatusInfo.BaseCard.SimulateAttackAmount(aIVirtualAttackInfo));
list3.Add(num13);
if (num13 >= aIVirtualCardStatusInfo2.Life)
{
num11 += aIVirtualCardStatusInfo2.ValueWhenDestroyed;
}
int num15 = Mathf.Max(0, aIVirtualCardStatusInfo2.Life - num13);
int num16 = Mathf.Max(0, aIVirtualCardStatusInfo2.BaseCard.Life - num14);
num12 += (float)(num15 - num16);
}
num8++;
num7 /= 2;
}
float num17 = 0f;
num17 = ((num10 >= aIVirtualCardStatusInfo.BaseCard.Life) ? 0f : ((num9 >= aIVirtualCardStatusInfo.Life) ? (aIVirtualCardStatusInfo.ValueWhenDestroyed - num11) : 0f));
num17 += num12;
if (num3 < num17)
{
num3 = num17;
usedAttackers = list2;
num4 = num9;
list = list3;
}
}
if (usedAttackers != null && list != null)
{
allyAttackers.RemoveAll((AIVirtualCardStatusInfo card) => usedAttackers.Contains(card));
num += num3;
for (int num18 = 0; num18 < usedAttackers.Count; num18++)
{
AIVirtualCardStatusInfo aIVirtualCardStatusInfo3 = usedAttackers[num18];
int num19 = list[num18];
aIVirtualCardStatusInfo3.ModifyStatus(aIVirtualCardStatusInfo3.Attack, aIVirtualCardStatusInfo3.Life - num19);
}
aIVirtualCardStatusInfo.ModifyStatus(aIVirtualCardStatusInfo.Attack, aIVirtualCardStatusInfo.Life - num4);
}
}
return num;
}
public static int[] GetPatternGroup(int count)
{
return count switch
{
5 => PATTERN_GROUP_FOR_5,
4 => PATTERN_GROUP_FOR_4,
3 => PATTERN_GROUP_FOR_3,
2 => PATTERN_GROUP_FOR_2,
1 => PATTERN_GROUP_FOR_1,
_ => null,
};
}
public static int Factorial(int n)
{
if (n <= 1)
{
return 1;
}
return n * Factorial(n - 1);
}
public static ulong CalculateTargetSequenceHash(int[] permList, AIVirtualField field)
{
ulong num = 0uL;
for (int i = 0; i < permList.Length; i++)
{
AIVirtualCard aIVirtualCard = field.EnemyInplayCards[permList[i]];
num += aIVirtualCard.GetHash() * PRIME_NUMBERS_FOR_ENEMY[i];
}
return num;
}
public static ulong CalculateAttackSequenceHash(int[] permList, AIVirtualField field)
{
ulong num = 0uL;
for (int i = 0; i < permList.Length; i++)
{
AIVirtualCard aIVirtualCard = field.AllyInplayCards[permList[i]];
num += aIVirtualCard.GetHash() * PRIME_NUMBERS_FOR_ALLY[i];
}
return num;
}
public static ulong[] CalculatePlayptnWithTokenHashs(AIVirtualField field, PlayPtnWithToken[] bestPlayptnWithTokens)
{
if (bestPlayptnWithTokens == null)
{
return null;
}
ulong[] array = new ulong[bestPlayptnWithTokens.Length];
for (int i = 0; i < bestPlayptnWithTokens.Length; i++)
{
PlayPtnWithToken playPtnWithToken = bestPlayptnWithTokens[i];
if (playPtnWithToken == null)
{
array[i] = 0uL;
}
else
{
array[i] = field.CalculatePlayptnHash(playPtnWithToken.PlayPtn);
}
}
return array;
}
public static AIVirtualActionInfo CreateActionInfoOnFieldFromSituation(AIVirtualField fieldTemp, AISituationInfo situation)
{
if (situation == null || situation.Actor == null)
{
return null;
}
switch (situation.ActionType)
{
case AIOperationType.ATTACK:
{
AIVirtualAttackInfo attackInfo = situation as AIVirtualAttackInfo;
if (attackInfo != null)
{
AIVirtualCard sourceCard = fieldTemp.AllyInplayCards.Find((AIVirtualCard c) => c.IsSameCard(attackInfo.Actor));
AIVirtualCard target = fieldTemp.CardListSet.EnemyClassAndInplayCards.Find((AIVirtualCard c) => c.IsSameCard(attackInfo.AttackTarget));
return new AIVirtualAttackInfo(sourceCard, target);
}
return null;
}
case AIOperationType.EVOLVE:
{
AIVirtualCard aIVirtualCard2 = fieldTemp.AllyInplayCards.Find((AIVirtualCard c) => c.IsSameCard(situation.Actor));
if (aIVirtualCard2.IsEvolution)
{
return null;
}
aIVirtualCard2.IsUseEvo = true;
AISelectedTargetInfoSet similarTargetInfoSet = situation.SelectedTargets.GetSimilarTargetInfoSet(fieldTemp);
return new AIVirtualTargetSelectAction(aIVirtualCard2, aIVirtualCard2, AIOperationType.EVOLVE, similarTargetInfoSet);
}
case AIOperationType.PLAY:
{
AIVirtualCard aIVirtualCard = fieldTemp.AllyHandCards.Find((AIVirtualCard c) => c.IsSameCard(situation.OriginalCard));
if (aIVirtualCard == null)
{
return null;
}
return new AIVirtualTargetSelectAction(aIVirtualCard.IsSameCard(situation.Actor) ? aIVirtualCard : new AIVirtualCard(situation.Actor, fieldTemp), aIVirtualCard, AIOperationType.PLAY);
}
default:
return null;
}
}
}