Files
SVSimServer/SVSim.BattleEngine/Engine/Wizard/EnemyAI_Play.cs
gamer147 0d9d8acae0 feat(battle-engine): M1 auto-copy closure (782 battle-logic files)
Compile-driven bulk-copy loop (tools/engine-port/m1_copy_loop.py) pulled the precise reference closure of the battle-core roots, stopping at the classify god-object/View-VFX-UI boundary. 782 files; no re-explosion (M0 had estimated ~order 1000). Residual frontier = 52 shim-classified + 80 external (Unity/BCL) types to author next.
2026-06-05 16:57:20 -04:00

642 lines
25 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using Cute;
using UnityEngine;
namespace Wizard;
public class EnemyAI_Play
{
private class CalcMostValuableHandPtnObj
{
public AISinglePlayptnRecord PlayOutPlan;
public PlayPtnWithToken[] BestPlayPtnCandidatesWithToken;
}
private EnemyAI _ai;
private AIVirtualFieldRollBackStackProcessor _fieldRollBackProcessor;
private bool _isOpenSpaceAttackCarryOut;
public bool IsFusion { get; private set; }
public AIFusionSituationInfo FusionPattern { get; private set; }
public AIVirtualCard PriorityCard { get; private set; }
public PlayedCardInfo PriorityCardPlayInfo { get; private set; }
public PlayPtnWithToken BestPlayPtnWithToken { get; private set; }
public AIVirtualActionInfo InstantAttackActionInfo { get; private set; }
public EnemyAI_Play(EnemyAI ai)
{
_ai = ai;
}
public void InitOnIterationStart()
{
_isOpenSpaceAttackCarryOut = false;
IsFusion = false;
FusionPattern = null;
PriorityCard = null;
PriorityCardPlayInfo = null;
BestPlayPtnWithToken = null;
InstantAttackActionInfo = null;
}
public IEnumerator BattleAI_HandPlay()
{
if (_ai.CurrentVirtualField.AllyHandCards.Count <= 0)
{
_ai.BestPlayPtnRecord = _ai.PlayPtnRecorder.GetEmptyPlayPtnRecord();
_ai.cr_isOprPlay = false;
yield break;
}
CalcMostValuableHandPtnObj obj = new CalcMostValuableHandPtnObj();
yield return CalcMostValuableHandPtnJob(obj);
AISinglePlayptnRecord playOutPlan = obj.PlayOutPlan;
PlayPtnWithToken[] bestPlayPtnCandidatesWithToken = obj.BestPlayPtnCandidatesWithToken;
BestPlayPtnWithToken = null;
InstantAttackActionInfo = null;
if (_isOpenSpaceAttackCarryOut)
{
List<AIVirtualActionInfo> allMovesForFullSimulation = AISimulationUtility.GetAllMovesForFullSimulation(_ai.CurrentVirtualField, doesUseEvo: false, null);
if (allMovesForFullSimulation.Count <= AISimulationUtility.FULL_SIMULATION_MOVE_COUNT_TURESHOLD)
{
FullSimulationAI fullSimulationInstantAttack = new FullSimulationAI(_ai, allMovesForFullSimulation);
yield return fullSimulationInstantAttack._CrSimulate(_ai.CurrentVirtualField, doesUseEvo: false, checkTimeOverLogic: true, bestPlayPtnCandidatesWithToken);
if (!_ai.IsRunWeakLogic && fullSimulationInstantAttack.Cr_BestPlayPtnWithToken != null)
{
BestPlayPtnWithToken = fullSimulationInstantAttack.Cr_BestPlayPtnWithToken;
InstantAttackActionInfo = fullSimulationInstantAttack.Cr_FirstActionInfo;
}
}
else
{
BestOpenSpaceAttackAI instantAttack = new BestOpenSpaceAttackAI(_ai);
yield return instantAttack._CrSimulate(_ai.CurrentVirtualField, bestPlayPtnCandidatesWithToken);
if (!_ai.IsRunWeakLogic && instantAttack.Cr_BestPlayPtnWithToken != null)
{
BestPlayPtnWithToken = instantAttack.Cr_BestPlayPtnWithToken;
InstantAttackActionInfo = instantAttack.Cr_FirstActionInfo;
}
}
if (_ai.IsRunWeakLogic)
{
AITimeOverAttackSimulator timeOverLogic = new AITimeOverAttackSimulator();
yield return timeOverLogic._CrSimulate(_ai.CurrentVirtualField, doesUseEvo: false, checkTimeOverLogic: false, bestPlayPtnCandidatesWithToken);
if (timeOverLogic.Cr_BestPlayPtnWithToken != null)
{
BestPlayPtnWithToken = timeOverLogic.Cr_BestPlayPtnWithToken;
InstantAttackActionInfo = timeOverLogic.Cr_FirstActionInfo;
}
}
}
else
{
BestPlayPtnWithToken = bestPlayPtnCandidatesWithToken[0];
}
List<int> priorityList;
if (BestPlayPtnWithToken == null)
{
priorityList = EnemyAI.EmptyPlayPtn;
BestPlayPtnWithToken = null;
_ai.BestPlayPtnRecord = _ai.PlayPtnRecorder.GetEmptyPlayPtnRecord();
}
else
{
priorityList = BestPlayPtnWithToken.PlayPtn;
_ai.BestPlayPtnRecord = BestPlayPtnWithToken.Record;
}
if (playOutPlan != null && playOutPlan.PlayPtnCount > 0)
{
AILethalSimulator aILethalSimulator = new AILethalSimulator(_ai);
_ai.OutputLethalPlan = null;
yield return EnemyAICoroutine.GetInstance().StartCoroutine(aILethalSimulator.SimulateByAISimulator(playOutPlan));
if (_ai.OutputLethalPlan != null && _ai.OutputLethalPlan.IsSuccess)
{
AISituationInfo action = _ai.OutputLethalPlan.ActionSequence[0];
if (_ai.OprLethalAction(action))
{
_ai.cr_isOprPlay = true;
yield break;
}
}
}
PriorityCard = null;
PriorityCardPlayInfo = null;
float priority = float.MinValue;
AISinglePlayptnRecord bestPlayPtnRecord = _ai.BestPlayPtnRecord;
if (priorityList != null && priorityList.Count > 0)
{
PriorityCard = GetPriorCard(priorityList, bestPlayPtnRecord, ref priority);
if (bestPlayPtnRecord != null && PriorityCard != null)
{
PriorityCardPlayInfo = bestPlayPtnRecord.PlayedCardList.Find((PlayedCardInfo info) => PriorityCard.IsSameCard(info.Card));
}
}
IsFusion = false;
FusionPattern = AIBestFusionPatternCalculator.CalculateBestFusionPattern(_ai.CurrentVirtualField, bestPlayPtnRecord);
if (FusionPattern != null && FusionPattern.IsTargetExists(AIScriptTokenArgType.TARGET_SELECT))
{
FusionPattern.UpdatePriority(priorityList);
if (!EnemyAI.IsLargerThan(priority, FusionPattern.Priority))
{
IsFusion = true;
PriorityCard = FusionPattern.Actor;
_ = FusionPattern.Priority;
}
}
if (PriorityCard == null)
{
_ai.cr_isOprPlay = false;
yield break;
}
AIVirtualTargetSelectAction situation = new AIVirtualTargetSelectAction(PriorityCard.FindRealActor(bestPlayPtnRecord), PriorityCard, AIOperationType.PLAY);
if (!IsFusion)
{
_ai.PlaySkipInfo = PriorityCard.GetPlaySkipInformation(priorityList, _ai.PlaySkipInfo, situation);
}
for (int num = 0; num < _ai.CurrentVirtualField.CardListSet.BothClassAndInplayCards.Count; num++)
{
AIVirtualCard owner = _ai.CurrentVirtualField.CardListSet.BothClassAndInplayCards[num];
_ai.PlaySkipInfo = owner.GetPlaySkipInformation(priorityList, _ai.PlaySkipInfo, situation);
}
if (_ai.PlaySkipInfo != null)
{
_ai.cr_isOprPlay = false;
yield break;
}
for (int num2 = 0; num2 < _ai.CurrentVirtualField.CardListSet.BothInplayCards.Count; num2++)
{
if (_ai.CurrentVirtualField.CardListSet.BothInplayCards[num2].IsBreakBeforePlay(priorityList))
{
_ai.IsBreakBeforePlay = true;
_ai.cr_isOprPlay = false;
yield break;
}
}
yield return _ai.HandCardAction();
}
private IEnumerator CalcMostValuableHandPtnJob(CalcMostValuableHandPtnObj obj)
{
ParallelJob job = ParallelJob.Dispatch(delegate
{
try
{
AISinglePlayptnRecord playOutPlan;
PlayPtnWithToken[] bestPlayPtnCandidatesWithToken = CalcMostValuableHandPtn(out playOutPlan);
obj.PlayOutPlan = playOutPlan;
obj.BestPlayPtnCandidatesWithToken = bestPlayPtnCandidatesWithToken;
}
catch (Exception)
{
}
});
while (!job.isDone)
{
yield return null;
}
}
public AIVirtualCard GetPriorCard(List<int> priorityList, AISinglePlayptnRecord playptnRecord, ref float priority)
{
if (priorityList.Count <= 0)
{
return null;
}
AIVirtualCard result = null;
for (int i = 0; i < priorityList.Count; i++)
{
int num = priorityList[i];
AIVirtualCard aIVirtualCard = _ai.CurrentVirtualField.AllyHandCards[num];
aIVirtualCard.FindRealActor(playptnRecord);
if (aIVirtualCard.IsSpell ? aIVirtualCard.BaseCard.Movable() : aIVirtualCard.BaseCard.BaseMovable)
{
priority = EvaluateHandPriority(num, priorityList);
result = aIVirtualCard;
break;
}
}
return result;
}
private PlayPtnWithToken[] CalcMostValuableHandPtn(out AISinglePlayptnRecord playOutPlan)
{
PlayPtnWithToken[] bestPlayPtnsWithToken = new PlayPtnWithToken[6];
float[] maxValues = new float[6];
for (int i = 0; i < 6; i++)
{
bestPlayPtnsWithToken[i] = null;
maxValues[i] = float.MinValue;
}
playOutPlan = null;
int num = 6 - _ai.CurrentVirtualField.CardListSet.AllyClassAndInplayCards.Count;
int num2 = 0;
AISinglePlayptnRecord aISinglePlayptnRecord = null;
AIVirtualField aIVirtualField = new AIVirtualField(_ai.CurrentVirtualField);
_fieldRollBackProcessor = new AIVirtualFieldRollBackStackProcessor(_ai.CurrentVirtualField);
AIPlayptnRecorder playPtnRecorder = _ai.PlayPtnRecorder;
for (int j = 0; j < playPtnRecorder.ValidPlayPtnList.Count; j++)
{
AISinglePlayptnRecord aISinglePlayptnRecord2 = playPtnRecorder.ValidPlayPtnList[j];
List<int> playPtn = aISinglePlayptnRecord2.PlayPtn;
if (!CheckPlayConditon(aIVirtualField, aISinglePlayptnRecord2))
{
continue;
}
int num3 = Mathf.Max(aIVirtualField.CalculateHandPtnRequiredSpace(aISinglePlayptnRecord2) - num, 0);
EvaluateHandPtn_Normal(playPtn, aISinglePlayptnRecord2, ref bestPlayPtnsWithToken, ref maxValues);
if (_fieldRollBackProcessor.HasRecord)
{
AIConsoleUtility.LogError("EnemyAI_Play.CalcMostValuableHandPtn() error!! Called ForceResetVirtualField()");
_fieldRollBackProcessor.ResetVirtualFieldToStart();
}
if (num3 <= 0)
{
int num4 = AIPlayOutChecker.CalculatePlayOutDamageProspected(_ai.ParamQuery, aIVirtualField, aISinglePlayptnRecord2, _ai);
if (num4 > num2)
{
num2 = num4;
aISinglePlayptnRecord = aISinglePlayptnRecord2;
}
else if (num4 == num2)
{
int num5 = aISinglePlayptnRecord?.PlayPtnCount ?? 0;
if (playPtn.Count < num5)
{
aISinglePlayptnRecord = aISinglePlayptnRecord2;
}
}
}
if (_ai.IsRunWeakLogic)
{
break;
}
}
if (num2 >= aIVirtualField.EnemyBattlePlayer.Class.Life)
{
playOutPlan = aISinglePlayptnRecord;
}
for (int k = 1; k < bestPlayPtnsWithToken.Length; k++)
{
PlayPtnWithToken playPtnWithToken = bestPlayPtnsWithToken[k];
if (playPtnWithToken != null && playPtnWithToken.PlayPtn != null && playPtnWithToken.PlayPtn.Count > 0)
{
_isOpenSpaceAttackCarryOut = true;
break;
}
}
return bestPlayPtnsWithToken;
}
private void EvaluateHandPtn_Normal(List<int> handList, AISinglePlayptnRecord playPtnRecord, ref PlayPtnWithToken[] bestPlayPtnsWithToken, ref float[] maxValues)
{
float num = 2f;
float num2 = 0f;
float[] array = new float[handList.Count];
AIVirtualField currentVirtualField = _ai.CurrentVirtualField;
bool isPlagueCity = _ai.IsPlagueCityTagged;
AIVirtualFieldRollBackBasicProcessor aIVirtualFieldRollBackBasicProcessor = new AIVirtualFieldRollBackBasicProcessor(currentVirtualField);
for (int i = 0; i < handList.Count; i++)
{
int index = handList[i];
PlayedCardInfo playedCardInfo = playPtnRecord.PlayedCardList[i];
AIVirtualCard aIVirtualCard = currentVirtualField.AllyHandCards[index];
AIVirtualTargetSelectAction aIVirtualTargetSelectAction = new AIVirtualTargetSelectAction(aIVirtualCard, aIVirtualCard, AIOperationType.PLAY);
aIVirtualTargetSelectAction.SetDiscardInfo(playedCardInfo.DiscardInfo);
AIPreprocessSimulationUtility.ExecuteRecordingToPlayedCardInfo(playedCardInfo, aIVirtualCard, currentVirtualField, aIVirtualTargetSelectAction, isPseudo: true);
array[i] = EvaluateHandValue(aIVirtualCard, handList, isOnBattleSimulate: false, aIVirtualTargetSelectAction, ref isPlagueCity, playPtnRecord);
currentVirtualField.UpdateVirtualFieldWhenEvaluation(aIVirtualCard, aIVirtualTargetSelectAction);
}
aIVirtualFieldRollBackBasicProcessor.ResetVirtualFieldToStart();
int dstHandCount = currentVirtualField.AllyHandCards.Count;
float num3 = _ai.ParamQuery.CalcHandCardOverflowPenalty(_ai.CurrentVirtualField, handList, num, ref dstHandCount);
num2 -= num3;
if (currentVirtualField.AllyBattlePlayer.IsEvolve)
{
float num4 = 0f;
for (int j = 0; j < handList.Count; j++)
{
int index2 = handList[j];
AIVirtualCard aIVirtualCard2 = currentVirtualField.AllyHandCards[index2];
if (!aIVirtualCard2.IsFollower(handList))
{
continue;
}
AIVirtualTargetSelectAction situation = new AIVirtualTargetSelectAction(aIVirtualCard2, aIVirtualCard2, AIOperationType.EVOLVE, (AISelectedTargetInfoSet)null);
int evoTokenCount = aIVirtualCard2.GetEvoTokenCount(currentVirtualField, handList, situation);
if (0 < evoTokenCount && evoTokenCount > _ai.GetAllySpaceNum())
{
continue;
}
float num5 = (float)Mathf.Max(aIVirtualCard2.GetEvoHandPlusCount(currentVirtualField, handList, situation) + dstHandCount - 8, 0) * num;
float num6 = aIVirtualCard2.EvaluateAllEvoBonus(handList, situation) - num5;
if (num6 > num4)
{
num4 = num6;
}
if (aIVirtualCard2.CreateAIVirtualSelectInfo(currentVirtualField, situation) != null)
{
float num7 = 0f - num5;
if (num7 > num4)
{
num4 = num7;
}
}
}
num2 += num4;
}
num2 += AIEvaluateBonusFromOhterUtility.GetPlayPtnBonus(currentVirtualField, handList) + _ai.StyleQuery.GetPlayptnBonus(currentVirtualField, handList);
List<TokenPlayPattern> list = new List<TokenPlayPattern>();
List<int> list2 = new List<int>(handList);
if (list2.Count <= 0)
{
if (num2 > maxValues[0])
{
bestPlayPtnsWithToken[0] = new PlayPtnWithToken(list2, playPtnRecord, list);
maxValues[0] = num2;
}
return;
}
int currentSpace = 6 - currentVirtualField.CardListSet.AllyClassAndInplayCards.Count;
List<float> list3 = new List<float> { 0f };
for (int k = 0; k < _ai.AllySuicideList.Count; k++)
{
AIVirtualCard aIVirtualCard3 = _ai.AllySuicideList[k];
float num8 = aIVirtualCard3.EvaluateValueOnField(list2, null, useStyle: true, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true) - aIVirtualCard3.EvaluateBreakValue(handList, useIgnoreBreak: true) - aIVirtualCard3.EvaluateLeaveValue(handList, useIgnoreInBattle: true) - (float)aIVirtualCard3.Attack;
list3.Add(list3[k] - num8);
}
EstimateMaxPlayPtnWithToken(playPtnRecord, list3, array, num2, isPlagueCity, 0, 0, currentSpace, list, 0f, ref bestPlayPtnsWithToken, ref maxValues);
}
private void EstimateMaxPlayPtnWithToken(AISinglePlayptnRecord playPtnRecord, List<float> suicideList, float[] handValues, float optionValue, bool isPlagueCity, int playPtnIndex, int suicideIndex, int currentSpace, List<TokenPlayPattern> currentPlayedCardsPattern, float currentValue, ref PlayPtnWithToken[] bestPlayPtnsWithToken, ref float[] maxValues)
{
List<int> playPtn = playPtnRecord.PlayPtn;
AIVirtualField currentVirtualField = _ai.CurrentVirtualField;
int i = playPtnIndex;
int num = 0;
float num2 = currentValue;
int num3 = 0;
foreach (AIVirtualCard allyInplayCard in currentVirtualField.AllyInplayCards)
{
if (allyInplayCard.WhiteRitualCount > 0)
{
num3++;
}
}
for (; i < playPtn.Count; i++)
{
int index = playPtn[i];
PlayedCardInfo playedCardInfo = playPtnRecord.PlayedCardList[i];
AIVirtualCard aIVirtualCard = currentVirtualField.AllyHandCards[index];
AIVirtualCard sourceCard = aIVirtualCard;
if (playedCardInfo.TransformCard != null)
{
sourceCard = playedCardInfo.TransformCard;
}
AIVirtualTargetSelectAction aIVirtualTargetSelectAction = new AIVirtualTargetSelectAction(sourceCard, aIVirtualCard, AIOperationType.PLAY);
aIVirtualTargetSelectAction.SetDiscardInfo(playedCardInfo.DiscardInfo);
_fieldRollBackProcessor.RegisterRecord();
AIPreprocessSimulationUtility.ExecuteRecordingToPlayedCardInfo(playedCardInfo, aIVirtualCard, currentVirtualField, aIVirtualTargetSelectAction, isPseudo: true);
int playSpaceRequired = currentVirtualField.GetPlaySpaceRequired(aIVirtualCard, playPtn, aIVirtualTargetSelectAction, needsTokenCount: false);
AITokenIdCollection bothSideTokenIdsOfPlaySituation = AIPlayTokenSimulationUtility.GetBothSideTokenIdsOfPlaySituation(currentVirtualField, playPtn, aIVirtualTargetSelectAction);
List<AITokenInformation> allDiscardedTokenIds = AIDiscardUtility.GetAllDiscardedTokenIds(aIVirtualTargetSelectAction.DiscardInfo, currentVirtualField, playPtn, aIVirtualTargetSelectAction);
List<AITokenInformation> list = new List<AITokenInformation>();
aIVirtualTargetSelectAction.SetActor(aIVirtualCard);
currentVirtualField.UpdateVirtualFieldWhenEvaluation(aIVirtualCard, aIVirtualTargetSelectAction);
bool flag = false;
if (bothSideTokenIdsOfPlaySituation != null && bothSideTokenIdsOfPlaySituation.HasAllyToken)
{
List<AITokenInformation> allyTokenIdList = bothSideTokenIdsOfPlaySituation.AllyTokenIdList;
for (int j = 0; j < allyTokenIdList.Count; j++)
{
list.Add(allyTokenIdList[j]);
if (num3 > 0)
{
AIVirtualCard tokenFromId = currentVirtualField.AI.tokenManager.GetTokenFromId(allyTokenIdList[j].TokenId, isAlly: true, currentVirtualField);
if (tokenFromId != null && tokenFromId.IsStackWhiteRitual)
{
flag = true;
}
}
}
}
if (allDiscardedTokenIds != null)
{
for (int k = 0; k < allDiscardedTokenIds.Count; k++)
{
list.Add(allDiscardedTokenIds[k]);
}
}
int num4 = playSpaceRequired + list.Count;
if (flag)
{
bool num5 = i == playPtn.Count - 1;
bool flag2 = currentSpace - num4 < 0;
num3 = ((!(num5 && flag2)) ? num3 : 0);
num4 -= num3;
}
bool flag3 = _ai.StyleQuery.IsPlayBreak(aIVirtualCard, playPtn, aIVirtualTargetSelectAction);
int num6 = 0;
if (flag3)
{
num6 = aIVirtualCard.GetAllyLastwordTokenCount(playPtn);
num4 += num6;
num4 -= playSpaceRequired;
}
float num7 = 0f;
if (bothSideTokenIdsOfPlaySituation != null && bothSideTokenIdsOfPlaySituation.HasOpponentToken)
{
List<AITokenInformation> opponentTokenIdList = bothSideTokenIdsOfPlaySituation.OpponentTokenIdList;
for (int l = 0; l < opponentTokenIdList.Count; l++)
{
int tokenId = opponentTokenIdList[l].TokenId;
num7 += GetTokenValueFromId(tokenId, AITokenType.Default, playPtn, isAllyToken: false, isPlagueCity);
}
}
if (num + num4 <= currentSpace)
{
num += num4;
float num8 = 0f;
for (int m = 0; m < list.Count; m++)
{
AITokenInformation aITokenInformation = list[m];
num8 += GetTokenValueFromId(aITokenInformation.TokenId, aITokenInformation.TokenType, playPtn, isAllyToken: true, isPlagueCity);
}
num8 -= num7;
float num9 = handValues[i] + num8 + AIDiscardUtility.CalcAllDiscardedBonus(_ai.CurrentVirtualField, aIVirtualTargetSelectAction, playPtn);
if (num9 < aIVirtualCard.GetPlayLimit(playPtn))
{
_fieldRollBackProcessor.RollBackFieldWithIteration(i - playPtnIndex + 1);
return;
}
num2 += num9;
TokenPlayPattern item = new TokenPlayPattern(index, num8, list);
currentPlayedCardsPattern.Add(item);
continue;
}
currentSpace -= num;
for (int n = suicideIndex; n < suicideList.Count; n++)
{
float num10 = num2;
int num11 = currentSpace + (n - suicideIndex) - playSpaceRequired;
if (num11 < 0)
{
continue;
}
bool flag4 = num11 >= list.Count;
List<AITokenInformation> list2 = (flag4 ? new List<AITokenInformation>(list) : list.GetRange(0, num11));
num11 -= list2.Count;
if (flag3)
{
num11 += playSpaceRequired;
bool flag5 = num11 >= num6;
flag4 = flag5 && flag4;
num11 -= (flag5 ? num6 : num11);
}
float num12 = 0f;
for (int num13 = 0; num13 < list2.Count; num13++)
{
AITokenInformation aITokenInformation2 = list2[num13];
num12 += GetTokenValueFromId(aITokenInformation2.TokenId, aITokenInformation2.TokenType, playPtn, isAllyToken: true, isPlagueCity);
}
num12 -= num7;
float num14 = handValues[i] + num12 + AIDiscardUtility.CalcAllDiscardedBonus(currentVirtualField, aIVirtualTargetSelectAction, playPtn);
if (num14 < aIVirtualCard.GetPlayLimit(playPtn))
{
continue;
}
num10 += num14;
TokenPlayPattern tokenPlayPattern = new TokenPlayPattern(index, num12, list2);
currentPlayedCardsPattern.Add(tokenPlayPattern);
EstimateMaxPlayPtnWithToken(playPtnRecord, suicideList, handValues, optionValue, isPlagueCity, i + 1, n, num11, currentPlayedCardsPattern, num10, ref bestPlayPtnsWithToken, ref maxValues);
for (int num15 = currentPlayedCardsPattern.Count - 1; num15 >= 0; num15--)
{
TokenPlayPattern tokenPlayPattern2 = currentPlayedCardsPattern[num15];
currentPlayedCardsPattern.Remove(tokenPlayPattern2);
if (tokenPlayPattern2 == tokenPlayPattern)
{
break;
}
}
if (flag4)
{
break;
}
}
_fieldRollBackProcessor.RollBackFieldWithIteration(i - playPtnIndex + 1);
return;
}
_fieldRollBackProcessor.RollBackFieldWithIteration(i - playPtnIndex);
if (i == playPtn.Count)
{
float num16 = num2 + suicideList[suicideIndex] + optionValue;
if (bestPlayPtnsWithToken[suicideIndex] == null || num16 >= maxValues[suicideIndex])
{
PlayPtnWithToken playPtnWithToken = new PlayPtnWithToken(playPtn, playPtnRecord, new List<TokenPlayPattern>(currentPlayedCardsPattern));
bestPlayPtnsWithToken[suicideIndex] = playPtnWithToken;
maxValues[suicideIndex] = num16;
}
}
}
private float GetTokenValueFromId(int id, AITokenType tokenType, List<int> playPtn, bool isAllyToken, bool isPlagueCity)
{
AIVirtualCard aIVirtualCard = _ai.tokenManager.GetTokenFromId(id, isAllyToken, _ai.CurrentVirtualField);
if (aIVirtualCard == null)
{
AIConsoleUtility.LogError("CalculateMaxTokenPatternValue: Could not get a token from the tokenPool.");
return 0f;
}
if (isPlagueCity && aIVirtualCard.IsUnit)
{
aIVirtualCard = _ai.tokenManager.GetZombieToken(isAlly: true, _ai.CurrentVirtualField);
}
float num = aIVirtualCard.EvaluateValueOnField(playPtn, null, useStyle: true, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true) + (aIVirtualCard.EvaluateBreakValue(playPtn, useIgnoreBreak: false) + aIVirtualCard.EvaluateLeaveValue(playPtn, useIgnoreInBattle: false)) * EnemyAI.BREAKBONUS_RATE_IN_HAND;
if (tokenType == AITokenType.Reanimate)
{
num += aIVirtualCard.GetReanimateBonus(playPtn);
}
return num;
}
public float EvaluateHandValue(AIVirtualCard handCard, List<int> handList, bool isOnBattleSimulate, AIVirtualTargetSelectAction play, ref bool isPlagueCity, AISinglePlayptnRecord playptnRecord)
{
if (isPlagueCity && handCard.IsUnit)
{
handCard = _ai.tokenManager.GetZombieToken(isAlly: true, _ai.CurrentVirtualField);
}
else if (!isPlagueCity && handCard.IsPlagueCity(_ai.CurrentVirtualField, handList))
{
isPlagueCity = true;
}
AIVirtualCard aIVirtualCard = new AIVirtualCard(handCard, _ai.CurrentVirtualField);
AIPlayptnBaseStatsRateUtility.Execute(_ai.CurrentVirtualField.CardListSet.AllyClassAndInplayCards, new List<AIVirtualCard> { aIVirtualCard }, EnemyAI.EmptyPlayPtn);
AIPlayptnBaseStatsRateUtility.Execute(_ai.CurrentVirtualField.CardListSet.EnemyClassAndInplayCards, new List<AIVirtualCard> { aIVirtualCard }, EnemyAI.EmptyPlayPtn);
return EvaluateHandValue(aIVirtualCard, handList, play, isOnBattleSimulate, playptnRecord);
}
public float EvaluateHandValue(AIVirtualCard card, List<int> handList, AIVirtualTargetSelectAction play, bool isOnBattleSimulate, AISinglePlayptnRecord playptnRecord)
{
if (AITargetSelectFilteringUtility.IsOnlyIgnoreTarget(card, _ai.CurrentVirtualField, handList, playptnRecord))
{
return 0f;
}
if (card.IsSpell || card.IsAccelerated(_ai.CurrentVirtualField, handList) || card.IsCrystalize(_ai.CurrentVirtualField, handList))
{
return card.EvaluatePlayValue(handList, play) * _ai.StyleQuery.GetAllyPlayBonusRate(card, handList, play);
}
float num = 0f;
if (_ai.StyleQuery.IsPlayBreak(card, handList, play))
{
num = card.EvaluatePlayValue(handList, play) + card.EvaluateBreakValue(handList, useIgnoreBreak: true) + card.EvaluateLeaveValue(handList, useIgnoreInBattle: true);
}
else
{
num = card.EvaluatePlayValue(handList, play);
num += card.EvaluateValueOnField(handList, null, useStyle: true);
num += (card.EvaluateBreakValue(handList, useIgnoreBreak: false) + card.EvaluateLeaveValue(handList, useIgnoreInBattle: false)) * EnemyAI.BREAKBONUS_RATE_IN_HAND;
}
return num * _ai.StyleQuery.GetAllyPlayBonusRate(card, handList, play);
}
public float EvaluateHandPriority(int handIndex, List<int> playPtn)
{
return _ai.CurrentVirtualField.AllyHandCards[handIndex].GetPriority(playPtn);
}
private bool CheckPlayConditon(AIVirtualField field, AISinglePlayptnRecord playPtnRecord)
{
List<int> playPtn = playPtnRecord.PlayPtn;
if (CalcHandPtnLifeCost(field, playPtn) >= field.AllyBattlePlayer.Class.Life)
{
return false;
}
if (!field.IsPlayableHandList(playPtnRecord, field.AI.AllySuicideList))
{
return false;
}
return true;
}
private int CalcHandPtnLifeCost(AIVirtualField field, List<int> handList)
{
int num = 0;
EnemyAI aI = field.AI;
for (int i = 0; i < handList.Count; i++)
{
int index = handList[i];
AIVirtualCard aIVirtualCard = field.AllyHandCards[index];
num += AIPlayOnSkillUtility.GetLifePenaltyOnPlay(aIVirtualCard.BaseCard, aI);
}
return num;
}
}