Files
SVSimServer/SVSim.BattleEngine/Engine/Wizard/EnemyAI.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

1701 lines
50 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Cute;
using UnityEngine;
using Wizard.Battle.View.Vfx;
namespace Wizard;
public abstract class EnemyAI : IEnemyAI, IEnemyAIBattleInfoRecieveDataAccessor
{
public const int INPLAY_CARD_LIMIT = 5;
public static float BREAKBONUS_RATE_IN_HAND = 0.75f;
public static float BREAKBONUS_RATE_ON_FIELD = 0.1f;
public const int VALUE_PRECISION = 1000;
private static List<int> _emptyPlayPtn = new List<int>();
protected BattleManagerBase battleMgr;
protected AIParamQuery paramQuery;
protected AIStyleQuery styleQuery;
protected AIEmoteMng emoteMng;
protected AIEmoteCtrl emoteCtrl;
protected AIEmoteQuery emoteQuery;
public bool isUsedEvo;
public List<PlaySkipInformation> PlaySkipInfo;
public bool IsBreakBeforePlay;
private int spareSpace;
protected bool isPlagueCityTagged;
private float _previousFieldInplayValue;
public List<AIPlayOutAction> Cr_playoutActionSequence;
public AILethalPlan OutputLethalPlan;
protected float m_fieldAdvantage;
public bool cr_isOprAtk;
public bool cr_isOprPlay;
public bool cr_isTerminate;
public bool is_onSelectSkillTarget;
public bool IsTurnEndLethal;
public bool IsFullSimulation;
public const int WeakLogicThresholdSecond = 7;
protected int _timeOverLogicSec;
protected Coroutine weakLogicCoroutine;
protected int oprationQueueActCount;
public AITokenManager tokenManager;
private AIVirtualField _currentVirtualField;
public AIRealActionInformation LatestAction;
public AIVirtualField BeforeLatestActionField;
public BattlePlayerBase ALLY;
public BattlePlayerBase OPPONENT;
public AISinglePlayptnRecord BestPlayPtnRecord;
protected IEnumerator aiCoroutine;
protected bool isForceBreak;
protected Queue<Action> AIOperationQueue;
protected AIOperationProcessor OperationProcessor;
public bool IsOpponentBarbarossaDestroyed;
public Dictionary<int, int> ReferenceIdTable;
public Dictionary<string, List<int>> ReferenceTribeTable;
protected bool isAIEmoteRegistered;
public Dictionary<ulong, float> FieldHashAndValueTable;
public Dictionary<ulong, float> FieldHashAndThreatenTable;
private AIFunctionResultContainer _funcResultContainer;
private AIVariableResultContainer _valResultContainer;
private List<int> _playerAbilityIdList;
public const float DEFAULT_WAIT_TIME = 2f;
private const int UNKNOWN_VALUE = -123456;
public CardBasePrm.ClanType AISubClassType = CardBasePrm.ClanType.NONE;
public CardBasePrm.ClanType PlayerSubClassType = CardBasePrm.ClanType.NONE;
private AIBattleInfoReceivedData _battleInfoReceiveData;
private System.Random stableRandom;
protected bool _isStackAction;
protected bool _isConnectNetwork = true;
protected const float THINKING_INTERVAL_SEC = 3f;
protected float _currentThinkingIntervalTime;
protected bool _enabledThinkingCounter;
protected float _elapsedThinkingTime;
protected bool _isRunTurnEndLimitTimer;
protected float _elapsedTurnTimeAfterTurnStartVfx;
protected float _turnStartVfxFinishTime;
public static List<int> EmptyPlayPtn => _emptyPlayPtn;
public EnemyAI_Play EnemyAIPlay { get; private set; }
public EnemyAI_Attack EnemyAIAttack { get; private set; }
public EnemyAI_Skill EnemyAISkill { get; private set; }
public EnemyAI_WeakLogic EnemyAIWeakLogic { get; private set; }
public EnemyAIFusion EnemyAIFusion { get; private set; }
public BattleManagerBase BattleMgr => battleMgr;
public bool IsThisTurnEmotePlayed { get; protected set; }
public AIAttachPlayerBattleEventCache PlayerBattleEvent { get; private set; }
public AIAttachOperateMgrBattleEventCache OprMgrBattleEvent { get; private set; }
public int PlayerCharaId { get; private set; }
public bool IsEvoPermissionOnSimu { get; private set; }
public AIVirtualCard CurrentBattleSimEvoCard { get; set; }
public int CurrentBattleBeforeSimEvoEvolCount { get; set; }
public List<AIVirtualCard> AllySuicideList { get; protected set; }
public bool IsPlagueCityTagged => isPlagueCityTagged;
public float FieldInplayValueDifference
{
get
{
if (CurrentVirtualField != null)
{
return _previousFieldInplayValue - CurrentVirtualField.GetInplayTotalValue();
}
return 0f;
}
}
public bool IsAllyFirst => ALLY.IsGameFirst;
public bool IsBattleEnd => battleMgr.IsBattleEnd;
public bool _isSetCardReady { get; protected set; }
public bool IsRunWeakLogic { get; private set; }
public AIVirtualField CurrentVirtualField => _currentVirtualField;
public List<AIVirtualCard> AllyDeckCards { get; private set; }
public List<AIVirtualCard> EnemyDeckCards { get; private set; }
public List<AIVirtualCard> DiscardedCards { get; private set; }
public AIPlayptnRecorder PlayPtnRecorder { get; private set; }
public AISelectedTargetInfoSet PreDecidedTargets { get; private set; }
public List<AIVirtualCard> BeforeLatestActionAllyDeckCards { get; private set; }
public List<AIVirtualCard> BeforeLatestActionEnemyDeckCards { get; private set; }
public BattlePlayerPair PlayerPair { get; private set; }
public List<int> BestPlayPtn
{
get
{
if (BestPlayPtnRecord != null)
{
return BestPlayPtnRecord.PlayPtn;
}
return EmptyPlayPtn;
}
}
public bool IsAIExecution => aiCoroutine != null;
public float FieldAdvantage => m_fieldAdvantage;
public int SpareSpace => spareSpace;
public AIFunctionResultContainer FuncResultContainer => _funcResultContainer;
public AIVariableResultContainer ValResultContainer => _valResultContainer;
public AIEmoteMng EmoteMng => emoteMng;
public AIEmoteQuery EmoteQuery => emoteQuery;
public AIParamQuery ParamQuery => paramQuery;
public AIStyleQuery StyleQuery => styleQuery;
public static int EnemyAIID { get; set; } = -1;
public AIGenerateTagOwnerTable GenerateTagOwnerTable { get; }
public AIBattleInfoReceivedData BattleInfoReceivedData { get; }
public bool IsInVirutalSimulation { get; set; }
public int TurnCount => PlayerPair.Self.Turn;
public int OpponentTurnCount => PlayerPair.Opponent.Turn;
public bool IsRankMatchAI { get; protected set; }
public abstract bool IsStackAction { get; }
public abstract bool IsConnectNetwork { get; }
public bool IsStopThinkingLogic { get; protected set; }
protected bool IsThinkingInterval => _currentThinkingIntervalTime > 0f;
public IAIEmoteCtrl EmoteCtrl()
{
return emoteCtrl;
}
public EnemyAI()
{
battleMgr = BattleManagerBase.GetIns();
EnemyAIPlay = new EnemyAI_Play(this);
EnemyAIAttack = new EnemyAI_Attack(this);
EnemyAISkill = new EnemyAI_Skill(this);
EnemyAIFusion = new EnemyAIFusion(this);
EnemyAIWeakLogic = new EnemyAI_WeakLogic(this);
PlayPtnRecorder = new AIPlayptnRecorder();
paramQuery = new AIParamQuery(this);
styleQuery = new AIStyleQuery(this, paramQuery);
emoteCtrl = new AIEmoteCtrl(this);
emoteMng = new AIEmoteMng(this);
emoteQuery = new AIEmoteQuery(this);
paramQuery.SetUp(styleQuery);
stableRandom = new System.Random(emoteMng.EmoteRandomSeed);
AIOperationQueue = new Queue<Action>();
OperationProcessor = new AIOperationProcessor(battleMgr, this);
IsOpponentBarbarossaDestroyed = false;
GenerateTagOwnerTable = new AIGenerateTagOwnerTable();
BattleInfoReceivedData = new AIBattleInfoReceivedData();
}
public void ExecuteEnemyAI(bool useWait)
{
aiCoroutine = EnemyAI_Move(useWait);
EnemyAICoroutine.GetInstance().StartCoroutine(aiCoroutine);
}
public void StopEnemyAI()
{
EnemyAICoroutine.GetInstance().StopAllCoroutines();
aiCoroutine = null;
if (weakLogicCoroutine != null)
{
BattleCoroutine.GetInstance().StopCoroutine(weakLogicCoroutine);
}
}
public bool SetUpBattleState(int classId, AI_LOGIC_LV logicLv, string deckName, string styleName, string emoteName, int enemyAiID = -1)
{
AIDataLibrary aIDataLibrary = GameMgr.GetIns().GetDataMgr().m_AIDataLibrary;
AIDeckData curDeck = aIDataLibrary.SearchDeckData(deckName);
paramQuery.SetDeck(classId, logicLv, curDeck, aIDataLibrary.GetCommonDic(), aIDataLibrary.GetAllyCommonDic());
AIStyleData deckStyle = aIDataLibrary.SearchDeckStyle(styleName);
styleQuery.SetDeckStyle(deckStyle);
styleQuery.UpdateStyle();
EnemyAIID = enemyAiID;
if (!IsRankMatchAI && EmoteQuery != null && emoteName != "")
{
AIEmoteSet aIEmoteSet = aIDataLibrary.SearchEmoteSet(emoteName);
if (aIEmoteSet != null)
{
EmoteQuery.SetEmoteSet(aIEmoteSet);
}
}
return true;
}
public void InitOnGame(BattlePlayerBase selfBattlePlayer, BattlePlayerBase opponentBattlePlayer)
{
tokenManager = new AITokenManager(selfBattlePlayer, opponentBattlePlayer, this);
ALLY = selfBattlePlayer;
OPPONENT = opponentBattlePlayer;
PlayerPair = new BattlePlayerPair(selfBattlePlayer, opponentBattlePlayer);
DataMgr dataMgr = GameMgr.GetIns().GetDataMgr();
if (dataMgr != null)
{
PlayerCharaId = dataMgr.GetPlayerCharaId();
AISubClassType = (CardBasePrm.ClanType)dataMgr.GetEnemySubClassId();
PlayerSubClassType = (CardBasePrm.ClanType)dataMgr.GetPlayerSubClassId();
}
styleQuery.UpdateStyle();
isUsedEvo = false;
IsEvoPermissionOnSimu = true;
PlaySkipInfo = null;
IsBreakBeforePlay = false;
BestPlayPtnRecord = null;
m_fieldAdvantage = 0f;
is_onSelectSkillTarget = false;
IsOpponentBarbarossaDestroyed = false;
IsThisTurnEmotePlayed = false;
PlayerBattleEvent = new AIAttachPlayerBattleEventCache();
OprMgrBattleEvent = new AIAttachOperateMgrBattleEventCache();
OperateMgr operateMgr = selfBattlePlayer.BattleMgr.OperateMgr;
AIAttachEventToBattleModuleUtility.SetupEventWhenInitGame(selfBattlePlayer, opponentBattlePlayer, operateMgr, this);
IsTurnEndLethal = false;
FieldHashAndValueTable = new Dictionary<ulong, float>();
FieldHashAndThreatenTable = new Dictionary<ulong, float>();
_funcResultContainer = new AIFunctionResultContainer();
_valResultContainer = new AIVariableResultContainer();
LatestAction = null;
BeforeLatestActionField = null;
IsInVirutalSimulation = false;
}
protected void UpdateCurrentVirtualField(AIParamQuery paramQuery, AIStyleQuery styleQuery, BattlePlayerPair pair, List<int> bestPlayPtn, bool isUsePreviousFieldParameter)
{
AIVirtualField currentVirtualField = _currentVirtualField;
_previousFieldInplayValue = ((_currentVirtualField != null) ? _currentVirtualField.GetInplayTotalValue() : 0f);
AIVirtualFieldBuildParameterCollction buildParameters = ((!isUsePreviousFieldParameter) ? new AIVirtualFieldBuildParameterCollction(null)
{
PlayedCardContainer = currentVirtualField.PlayedCardContainer
} : new AIVirtualFieldBuildParameterCollction(currentVirtualField));
_currentVirtualField = new AIVirtualField(this, paramQuery, styleQuery, pair, bestPlayPtn, buildParameters);
GenerateTagOwnerTable.RegisterAllGenerateTagOwner(_currentVirtualField);
UpdateDeckCards(pair);
UpdateDiscardedCards(pair.Self);
tokenManager.UpdateTokenPool(_currentVirtualField);
_currentVirtualField.InitializeBothDefValue();
}
private void UpdateDeckCards(BattlePlayerPair pair)
{
if (pair.Self.DeckCardList == null || pair.Opponent.DeckCardList == null)
{
AIConsoleUtility.LogError("UpdateDeckCards error!! deck is null!!!!!");
}
List<Tuple<int, AIAttachedTagCollection>> list;
if (AllyDeckCards == null)
{
AllyDeckCards = new List<AIVirtualCard>();
list = null;
}
else
{
list = new List<Tuple<int, AIAttachedTagCollection>>();
for (int i = 0; i < AllyDeckCards.Count; i++)
{
AIVirtualCard aIVirtualCard = AllyDeckCards[i];
list.Add(new Tuple<int, AIAttachedTagCollection>(aIVirtualCard.CardIndex, aIVirtualCard.TagCollectionContainer.AttachedTags));
}
AllyDeckCards.Clear();
}
for (int j = 0; j < pair.Self.DeckCardList.Count; j++)
{
AIVirtualCard aIVirtualCard2 = new DeckVirtualCard(pair.Self.DeckCardList[j], CurrentVirtualField);
aIVirtualCard2.InitializeTags(ParamQuery, FindInheritanceAttachedTagForDeckCard(aIVirtualCard2.CardIndex, list), null);
AllyDeckCards.Add(aIVirtualCard2);
}
if (EnemyDeckCards == null)
{
EnemyDeckCards = new List<AIVirtualCard>();
list = null;
}
else
{
list = new List<Tuple<int, AIAttachedTagCollection>>();
for (int k = 0; k < EnemyDeckCards.Count; k++)
{
AIVirtualCard aIVirtualCard3 = EnemyDeckCards[k];
list.Add(new Tuple<int, AIAttachedTagCollection>(aIVirtualCard3.CardIndex, aIVirtualCard3.TagCollectionContainer.AttachedTags));
}
EnemyDeckCards.Clear();
}
for (int l = 0; l < pair.Opponent.DeckCardList.Count; l++)
{
AIVirtualCard aIVirtualCard4 = new DeckVirtualCard(pair.Opponent.DeckCardList[l], CurrentVirtualField);
aIVirtualCard4.InitializeTags(ParamQuery, FindInheritanceAttachedTagForDeckCard(aIVirtualCard4.CardIndex, list), null);
EnemyDeckCards.Add(aIVirtualCard4);
}
}
private AIAttachedTagCollection FindInheritanceAttachedTagForDeckCard(int deckCardIndex, List<Tuple<int, AIAttachedTagCollection>> attachedTagPool)
{
if (attachedTagPool == null || attachedTagPool.Count <= 0)
{
return null;
}
for (int i = 0; i < attachedTagPool.Count; i++)
{
Tuple<int, AIAttachedTagCollection> tuple = attachedTagPool[i];
if (deckCardIndex == tuple.first)
{
return tuple.second;
}
}
return null;
}
private void UpdateDiscardedCards(BattlePlayerBase self)
{
if (self.DiscardedCardList != null)
{
if (DiscardedCards == null)
{
DiscardedCards = new List<AIVirtualCard>();
}
else
{
DiscardedCards.Clear();
}
for (int i = 0; i < self.DiscardedCardList.Count; i++)
{
DiscardedCards.Add(new DiscardedVirtualCard(self.DiscardedCardList[i], _currentVirtualField));
}
}
}
public void SaveBeforeLatestActionInformation()
{
BeforeLatestActionField = new AIVirtualField(_currentVirtualField, isLatestAction: true);
BeforeLatestActionAllyDeckCards = new List<AIVirtualCard>(AllyDeckCards);
BeforeLatestActionEnemyDeckCards = new List<AIVirtualCard>(EnemyDeckCards);
}
public void LoadBufferedBattleState()
{
AISetUpData setupInfoBuf = GameMgr.GetIns().GetDataMgr().m_AIDataLibrary.SetupInfoBuf;
if (setupInfoBuf != null)
{
SetUpBattleState(setupInfoBuf.classID, setupInfoBuf.logicLv, setupInfoBuf.deckName, setupInfoBuf.styleName, setupInfoBuf.emoteName, setupInfoBuf.enemyAiID);
if (!IsRankMatchAI && EmoteQuery != null)
{
EmoteQuery.SetOnOffEmote(setupInfoBuf.doesUseEmote, setupInfoBuf.useInnerEmote);
}
if (setupInfoBuf.specialAbilityList != null)
{
_playerAbilityIdList = new List<int>(setupInfoBuf.specialAbilityList);
}
}
}
private void InitOnTurnStart()
{
PlaySkipInfo = null;
IsBreakBeforePlay = false;
BestPlayPtnRecord = null;
m_fieldAdvantage = 0f;
EnemyAIAttack.InitOnTurnStart();
CurrentBattleSimEvoCard = null;
CurrentBattleBeforeSimEvoEvolCount = ALLY.CurrentEpCount;
if (paramQuery.GetLogicLv() == AI_LOGIC_LV.MIDDLE)
{
int num = ((CalcFieldAdvantage() <= -8f) ? 100 : 30);
int num2 = AIStableRandom(100);
IsEvoPermissionOnSimu = num2 <= num;
}
else
{
IsEvoPermissionOnSimu = true;
}
IsInVirutalSimulation = false;
IsTurnEndLethal = false;
tokenManager.RegistPermanentlyToken();
FieldHashAndValueTable.Clear();
FieldHashAndThreatenTable.Clear();
}
public void Mulligan(List<BattleCardBase> dstList, BattlePlayerBase selfBattlePlayer, BattlePlayerBase opponentBattlePlayer)
{
UpdateCurrentVirtualField(paramQuery, styleQuery, new BattlePlayerPair(selfBattlePlayer, opponentBattlePlayer), EmptyPlayPtn, isUsePreviousFieldParameter: true);
_currentVirtualField.InitializeGameStartInnerTags();
int count = CurrentVirtualField.AllyHandCards.Count;
int num = 0;
int[] array = new int[count];
for (int i = 0; i < count; i++)
{
array[i] = 0;
}
for (int j = 0; j < count - 1; j++)
{
AIVirtualCard aIVirtualCard = CurrentVirtualField.AllyHandCards[j];
for (int k = j + 1; k < count; k++)
{
if (CurrentVirtualField.AllyHandCards[k].BaseId == aIVirtualCard.BaseId)
{
array[j] = 2;
break;
}
}
}
for (int l = 0; l < count; l++)
{
if (array[l] == 0)
{
AIVirtualCard card = CurrentVirtualField.AllyHandCards[l];
if (paramQuery.IsEnabledTag(card, CurrentVirtualField, AIPlayTagType.MulliganKeep, EmptyPlayPtn, null))
{
array[l] = 1;
num++;
}
if (paramQuery.IsEnabledTag(card, CurrentVirtualField, AIPlayTagType.MulliganChange, EmptyPlayPtn, null))
{
array[l] = 2;
}
}
}
if (num == count)
{
return;
}
bool flag = false;
for (int m = 0; m < count; m++)
{
AIVirtualCard aIVirtualCard2 = CurrentVirtualField.AllyHandCards[m];
if (array[m] == 0 && aIVirtualCard2.Cost == 2 && isKeepableCard(aIVirtualCard2))
{
array[m] = 1;
num++;
flag = true;
break;
}
}
if (num == count)
{
return;
}
bool flag2 = false;
bool flag3 = false;
if (num > 0 && flag)
{
for (int n = 0; n < count; n++)
{
AIVirtualCard aIVirtualCard3 = CurrentVirtualField.AllyHandCards[n];
if ((aIVirtualCard3.Cost == 1 || aIVirtualCard3.Cost == 3) && array[n] == 0 && isKeepableCard(aIVirtualCard3))
{
array[n] = 1;
num++;
if (aIVirtualCard3.Cost == 1)
{
flag2 = true;
}
else if (aIVirtualCard3.Cost == 3)
{
flag3 = true;
}
break;
}
}
}
if (num == count)
{
return;
}
if (num > 0 && flag && (flag2 || flag3))
{
for (int num2 = 0; num2 < count; num2++)
{
AIVirtualCard aIVirtualCard4 = CurrentVirtualField.AllyHandCards[num2];
if (array[num2] == 0)
{
if (!isKeepableCard(aIVirtualCard4))
{
break;
}
if ((flag2 && aIVirtualCard4.Cost == 3) || (flag3 && aIVirtualCard4.Cost == 4))
{
array[num2] = 1;
num++;
break;
}
}
}
}
if (num == count)
{
return;
}
for (int num3 = 0; num3 < count; num3++)
{
if (array[num3] == 2 || array[num3] == 0)
{
dstList.Add(CurrentVirtualField.AllyHandCards[num3].BaseCard);
}
}
bool isKeepableCard(AIVirtualCard aIVirtualCard5)
{
if (!aIVirtualCard5.IsUnit)
{
if (IsBishop())
{
return aIVirtualCard5.IsAmulet;
}
return false;
}
return true;
}
}
public void ChangeWeakLogic()
{
if (battleMgr is SingleBattleMgr singleBattleMgr)
{
singleBattleMgr.RecordChangeAI("weak", oprationQueueActCount);
oprationQueueActCount = 0;
}
IsRunWeakLogic = true;
}
public void ChangeNormalLogic()
{
IsRunWeakLogic = false;
_timeOverLogicSec = 0;
}
protected virtual IEnumerator WeakLogicTimerCoroutine()
{
_timeOverLogicSec = 0;
while (!IsBattleEnd)
{
if (!IsRunWeakLogic)
{
_timeOverLogicSec++;
if (_timeOverLogicSec > 7 && battleMgr.VfxMgr.IsEnd)
{
ChangeWeakLogic();
}
}
yield return new WaitForSecondsRealtime(1f);
}
}
public bool IsLethal(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (situation is AIVirtualTargetSelectAction { forceLethalMode: not false })
{
return true;
}
AIVariableResultContainer valResultContainer = field.AI.ValResultContainer;
ulong hash = AIFunctionResultHashCalculator.GetHash(tagOwner, field, playPtn, situation, 0uL);
if (valResultContainer.GetContainsResultValue(AIScriptTokenVariableType.IS_LETHAL, hash, out var getResult))
{
return getResult == 1f;
}
AISinglePlayptnRecord playPtnRecord = PlayPtnRecorder.FindMatchedPlayPtnRecord(playPtn, field);
bool flag = AIPlayOutChecker.CalculatePlayOutDamageProspected(paramQuery, field, playPtnRecord, this) >= field.EnemyClass.Life;
valResultContainer.CheckDuplicateAndAddRecord(AIScriptTokenVariableType.IS_LETHAL, hash, flag ? 1f : 0f, $"IsLethal(): Already hashed target and not equal value. CardName:[{tagOwner.CardName}] hash:[{hash}]");
return flag;
}
private IEnumerator EnemyAI_Move(bool useWait)
{
is_onSelectSkillTarget = false;
IsRunWeakLogic = false;
IsStopThinkingLogic = false;
if (weakLogicCoroutine != null)
{
BattleCoroutine.GetInstance().StopCoroutine(weakLogicCoroutine);
weakLogicCoroutine = null;
}
if (!BattleMgr.IsRecovery)
{
weakLogicCoroutine = BattleCoroutine.GetInstance().StartCoroutine(WeakLogicTimerCoroutine());
}
InitOnTurnStart();
WaitForSeconds shortWait = new WaitForSeconds(0.2f);
WaitForSeconds longWait = new WaitForSeconds(0.5f);
isForceBreak = false;
oprationQueueActCount = 0;
while (true)
{
if (IsRankMatchAI && IsStopThinkingLogic)
{
continue;
}
yield return useWait ? shortWait : null;
if (AIOperationQueue.Count > 0)
{
if (!battleMgr.VfxMgr.IsEnd || (IsRankMatchAI && IsThinkingInterval))
{
continue;
}
if (IsRankMatchAI)
{
if (_isConnectNetwork)
{
AIOperationQueue.Dequeue().Call();
oprationQueueActCount++;
_isStackAction = false;
}
else
{
_isStackAction = true;
}
}
else
{
AIOperationQueue.Dequeue().Call();
oprationQueueActCount++;
}
continue;
}
if (isForceBreak)
{
break;
}
if (battleMgr.IsBattleEnd || is_onSelectSkillTarget)
{
continue;
}
BestPlayPtnRecord = null;
ChangeNormalLogic();
EnemyAIPlay.InitOnIterationStart();
EnemyAIAttack.InitOnIterationStart();
EnemyAIFusion.InitOnIterationStart();
PlaySkipInfo = null;
IsBreakBeforePlay = false;
AllySuicideList = new List<AIVirtualCard>();
spareSpace = 5;
IsFullSimulation = false;
PreDecidedTargets = null;
LatestAction = null;
BeforeLatestActionField = null;
_funcResultContainer.Clear();
_valResultContainer.Clear();
if (IsRankMatchAI)
{
_enabledThinkingCounter = true;
_elapsedThinkingTime = 0f;
}
AllySuicideList = GetSuicideAllyFollowerSequence(CurrentVirtualField, paramQuery, styleQuery);
PlayPtnRecorder = new AIPlayptnRecorder();
PlayPtnRecorder.CreateValidPlayPtnList(_currentVirtualField);
BestPlayPtnRecord = PlayPtnRecorder.GetEmptyPlayPtnRecord();
yield return EnemyAICoroutine.GetInstance().StartCoroutine(HandPlayEstimationCoroutine());
m_fieldAdvantage = CalcFieldAdvantage();
isPlagueCityTagged = CurrentVirtualField.IsPlagueCity();
VfxBase emote = GetEmote(AIEmoteCmdType.ON_ITERATION_START);
ImmediateVfxMgr.GetInstance().Register(emote);
cr_isTerminate = false;
IsTurnEndLethal = false;
yield return EnemyAICoroutine.GetInstance().StartCoroutine(EnemyAIAttack.Cr_BattleAI_ImmediateAttack());
if (cr_isTerminate)
{
if (!IsTurnEndLethal)
{
continue;
}
break;
}
cr_isOprPlay = false;
IsTurnEndLethal = false;
yield return EnemyAICoroutine.GetInstance().StartCoroutine(EnemyAIPlay.BattleAI_HandPlay());
AIGetOnSimulationUtility.RegisterGetOnTokenInPlayPtn(this);
if (cr_isOprPlay)
{
if (!IsTurnEndLethal)
{
continue;
}
break;
}
if (paramQuery.GetLogicLv() == AI_LOGIC_LV.STRONG || paramQuery.GetLogicLv() == AI_LOGIC_LV.MIDDLE)
{
cr_isOprAtk = false;
yield return EnemyAICoroutine.GetInstance().StartCoroutine(EnemyAIAttack.BattleAI_UseHighSimu());
if (cr_isOprAtk)
{
continue;
}
}
else if (paramQuery.GetLogicLv() == AI_LOGIC_LV.WEAK && (EnemyAIWeakLogic.BattleAI_AttackWeak() || EnemyAIWeakLogic.BattleAI_EvoWeak()))
{
continue;
}
if ((PlaySkipInfo != null || IsBreakBeforePlay) && ((BestPlayPtn != null && BestPlayPtn.Count > 0) || EnemyAIPlay.IsFusion))
{
yield return EnemyAICoroutine.GetInstance().StartCoroutine(HandCardAction());
if (cr_isOprPlay)
{
if (IsTurnEndLethal)
{
break;
}
continue;
}
}
if ((paramQuery.GetLogicLv() != AI_LOGIC_LV.WEAK || !EnemyAIAttack.BattleAI_TurnEndAttack()) && AIOperationQueue.Count <= 0)
{
break;
}
}
yield return useWait ? longWait : null;
while (!battleMgr.VfxMgr.IsEnd)
{
yield return null;
}
if (IsRankMatchAI && !battleMgr.IsRecovery)
{
float delayTurnEndTime = StyleQuery.GetDelayTurnEndTime(CurrentVirtualField.AllyClass, BestPlayPtn);
while (_elapsedTurnTimeAfterTurnStartVfx < delayTurnEndTime)
{
yield return null;
}
}
emoteQuery.OnOperation();
VfxBase vfxBase = ((TurnCount != 1) ? GetEmote(AIEmoteCmdType.ON_ALLY_TURN_END) : GetEmote(AIEmoteCmdType.ON_FIRST_TURN));
if (vfxBase != null)
{
battleMgr.VfxMgr.RegisterSequentialVfx(vfxBase);
}
IsThisTurnEmotePlayed = false;
battleMgr.VfxMgr.RegisterSequentialVfx(battleMgr.OperateMgr.TurnEndOperation(ALLY.IsPlayer));
if (weakLogicCoroutine != null)
{
BattleCoroutine.GetInstance().StopCoroutine(weakLogicCoroutine);
weakLogicCoroutine = null;
}
}
public IEnumerator HandCardAction()
{
if (EnemyAIPlay.PriorityCard == null)
{
AIConsoleUtility.LogError("HandCardAction error!! PriorityCard is null!!!!!");
cr_isOprPlay = false;
yield break;
}
if (EnemyAIPlay.IsFusion && EnemyAIPlay.FusionPattern != null)
{
EnemyAIFusion.SetFusionSituation(EnemyAIPlay.FusionPattern);
if (EnemyAIFusion.FusionAI())
{
cr_isOprPlay = true;
}
yield break;
}
AIVirtualCard aIVirtualCard = EnemyAIPlay.PriorityCard.FindRealActor(BestPlayPtnRecord);
AIVirtualTargetSelectAction situation = new AIVirtualTargetSelectAction(aIVirtualCard, EnemyAIPlay.PriorityCard, AIOperationType.PLAY);
int playSpaceRequired = CurrentVirtualField.GetPlaySpaceRequired(aIVirtualCard, BestPlayPtn, situation);
int num = 6 - CurrentVirtualField.CardListSet.AllyClassAndInplayCards.Count;
bool flag = true;
if (playSpaceRequired > num)
{
flag = false;
}
else if (EnemyAIPlay.BestPlayPtnWithToken != null)
{
bool num2 = StyleQuery.IsPlayBreak(EnemyAIPlay.PriorityCard, BestPlayPtn, null);
int count = EnemyAIPlay.BestPlayPtnWithToken.TokenPtn[0].TokenInfoPairList.Count;
if (num2)
{
int allyLastwordTokenCount = EnemyAIPlay.PriorityCard.GetAllyLastwordTokenCount(BestPlayPtn);
count += allyLastwordTokenCount;
}
else
{
count += playSpaceRequired;
}
if (count > num)
{
flag = false;
}
}
if (EnemyAIPlay.InstantAttackActionInfo != null && !flag)
{
int item = CurrentVirtualField.AllyHandCards.IndexOf(EnemyAIPlay.PriorityCard);
int index = EnemyAIPlay.BestPlayPtnWithToken.PlayPtn.IndexOf(item);
TokenPlayPattern tokenPlayPattern = EnemyAIPlay.BestPlayPtnWithToken.TokenPtn[index];
if (CurrentVirtualField.GetPlaySpaceRequired(EnemyAIPlay.PriorityCard, BestPlayPtn, situation, needsTokenCount: false) + tokenPlayPattern.TokenInfoPairList.Count > 6 - CurrentVirtualField.CardListSet.AllyClassAndInplayCards.Count)
{
AIVirtualCard aIVirtualCard2 = null;
if (EnemyAIPlay.InstantAttackActionInfo is AIVirtualAttackInfo aIVirtualAttackInfo)
{
aIVirtualCard2 = aIVirtualAttackInfo.AttackTarget;
}
if (aIVirtualCard2 != null)
{
OprAttack(EnemyAIPlay.InstantAttackActionInfo);
cr_isOprPlay = true;
}
else
{
AIConsoleUtility.LogError("InstantAttack error!! Cannot find attack target!!!!!");
}
yield break;
}
}
if (!EnemyAIPlay.PriorityCard.BaseCard.Movable())
{
cr_isOprPlay = false;
yield break;
}
if (EnemyAIPlay.PriorityCardPlayInfo != null && EnemyAIPlay.PriorityCardPlayInfo.HasPreDecidedSelectTargets)
{
List<BattleCardBase> list = new List<BattleCardBase>();
AISelectedTargetInfoSet preDecidedSelectTargets = EnemyAIPlay.PriorityCardPlayInfo.PreDecidedSelectTargets;
for (int i = 0; i < AISelectedTargetInfoSet.LENGTH; i++)
{
AISelectedTargetInfo aISelectedTargetInfo = preDecidedSelectTargets.Get(i);
if (aISelectedTargetInfo != null && aISelectedTargetInfo.HasTarget)
{
for (int j = 0; j < aISelectedTargetInfo.Targets.Count; j++)
{
list.Add(aISelectedTargetInfo.Targets[j].BaseCard);
}
}
}
EnemyAISkill.SetPreDecidedTarget(list);
SetPreDecidedTargets(preDecidedSelectTargets);
}
OprPlay(EnemyAIPlay.PriorityCard, BestPlayPtnRecord);
cr_isOprPlay = true;
}
public void SelectSkillTarget(AIVirtualCard actCard, AIOperationType operationType, AISinglePlayptnRecord playptnRecord)
{
is_onSelectSkillTarget = true;
AISinglePlayptnRecord aISinglePlayptnRecord = playptnRecord;
List<int> list = ((playptnRecord != null) ? playptnRecord.PlayPtn : EmptyPlayPtn);
AIVirtualCard aIVirtualCard = _currentVirtualField.SearchVirtualCard(actCard);
AIVirtualCard aIVirtualCard2 = ((operationType != AIOperationType.PLAY || list == null || list.Count <= 0) ? aIVirtualCard : aIVirtualCard.FindRealActor(aISinglePlayptnRecord));
List<int> list2 = list;
if (aIVirtualCard2.HasDestroyPlayPtnTag(operationType))
{
list2 = ((operationType != AIOperationType.PLAY) ? EmptyPlayPtn : new List<int> { _currentVirtualField.AllyHandCards.IndexOf(actCard) });
aISinglePlayptnRecord = PlayPtnRecorder.FindMatchedPlayPtnRecord(list2, _currentVirtualField);
}
AIVirtualTargetSelectAction aIVirtualTargetSelectAction = new AIVirtualTargetSelectAction(aIVirtualCard2, aIVirtualCard, operationType, (AISelectedTargetInfoSet)null);
if (operationType == AIOperationType.PLAY && PreDecidedTargets != null)
{
aIVirtualTargetSelectAction.SelectedTargets = PreDecidedTargets;
}
List<AIVirtualTargetSelectInfo> list3 = aIVirtualCard2.CreateAIVirtualSelectInfo(_currentVirtualField, aIVirtualTargetSelectAction);
if (aIVirtualTargetSelectAction.GetChoiceTarget() != null)
{
SetPreDecidedTargets(aIVirtualTargetSelectAction.SelectedTargets);
}
AIVirtualCard aIVirtualCard3 = null;
if (list2 != null)
{
switch (operationType)
{
case AIOperationType.EVOLVE:
if (list2.Count > 0)
{
aIVirtualCard3 = _currentVirtualField.AllyHandCards[list2[0]];
}
break;
case AIOperationType.PLAY:
if (list2.Count > 1)
{
aIVirtualCard3 = _currentVirtualField.AllyHandCards[list2[1]];
}
break;
}
}
PlayedCardInfo nextPlayCardInfo = null;
if (aIVirtualCard3 != null && aISinglePlayptnRecord != null)
{
nextPlayCardInfo = aISinglePlayptnRecord.FindPlayedCardInfo(aIVirtualCard3);
}
AIVirtualTargetSelectSimulationInfo simulationInfo = new AIVirtualTargetSelectSimulationInfo
{
OriginalActor = aIVirtualCard,
RealActor = aIVirtualCard2,
SelectInfoList = list3,
OperationType = operationType,
NextPlayCardInfo = nextPlayCardInfo,
IsFirstAction = true
};
if (list3 != null && list3.Count > 0)
{
EnemyAICoroutine.GetInstance().StartCoroutine(AIVirtualTargetSelectSimulator.ExecuteTargetSelect(simulationInfo, _currentVirtualField, aISinglePlayptnRecord));
}
else
{
EnemyAICoroutine.GetInstance().StartCoroutine(EnemyAISkill._Cr_SelectSkillTarget(actCard, operationType, aISinglePlayptnRecord));
}
PreDecidedTargets = null;
}
protected IEnumerator HandPlayEstimationCoroutine()
{
int handCardCount = ALLY.HandCardList.Count;
BattlePlayerPair sourcePair = new BattlePlayerPair(ALLY, OPPONENT);
int index = 0;
while (index < handCardCount)
{
CurrentVirtualField.AllyHandCards[index].CreateHandPlayEstimator(paramQuery, index, sourcePair, this);
yield return null;
int num = index + 1;
index = num;
}
}
public static List<AIVirtualCard> GetSuicideAllyFollowerSequence(AIVirtualField field, AIParamQuery ParamQuery, AIStyleQuery styleQuery)
{
AIVirtualField aIVirtualField = new AIVirtualField(field);
List<AIVirtualCard> list = new List<AIVirtualCard>();
for (int i = 0; i < aIVirtualField.AllyInplayCards.Count; i++)
{
AIVirtualCard aIVirtualCard = aIVirtualField.AllyInplayCards[i];
if (!aIVirtualCard.IsUnit || !aIVirtualCard.IsAttackable(EmptyPlayPtn))
{
continue;
}
if (list.Count == 0)
{
list.Add(aIVirtualCard);
continue;
}
int num = 0;
for (num = 0; num < list.Count; num++)
{
AIVirtualCard aIVirtualCard2 = list[num];
if (aIVirtualCard.Value < aIVirtualCard2.Value)
{
break;
}
}
list.Insert(num, aIVirtualCard);
}
if (list == null || list.Count <= 0)
{
return new List<AIVirtualCard>();
}
List<AIVirtualActionInfo> list2 = new List<AIVirtualActionInfo>();
for (int j = 0; j < list.Count; j++)
{
AIVirtualCard sourceCard = list[j];
list2.Add(new AIVirtualAttackInfo(sourceCard, isAttackFollower: true));
}
List<AIVirtualCard> list3 = new List<AIVirtualCard>();
for (int k = 0; k < aIVirtualField.EnemyInplayCards.Count; k++)
{
AIVirtualCard aIVirtualCard3 = aIVirtualField.EnemyInplayCards[k];
if (!aIVirtualCard3.IsUnit)
{
continue;
}
if (list3.Count == 0)
{
list3.Add(aIVirtualCard3);
continue;
}
int num2 = 0;
for (num2 = 0; num2 < list3.Count; num2++)
{
AIVirtualCard aIVirtualCard4 = list3[num2];
if ((aIVirtualCard3.IsGuard || !aIVirtualCard4.IsGuard) && ((aIVirtualCard3.IsGuard && !aIVirtualCard4.IsGuard) || aIVirtualCard3.IsKiller || aIVirtualCard3.Attack > aIVirtualCard4.Attack))
{
break;
}
}
list3.Insert(num2, aIVirtualCard3);
}
BattleSequencer.ExecSimulation(aIVirtualField, list2, list3, new SimulationSetting(isHandRemovalValid: false, useLeaderAttackPreCheck: false, noSkipAttack: true, checkAct: false));
list.RemoveAll((AIVirtualCard c) => !c.IsDead);
List<AIVirtualCard> list4 = new List<AIVirtualCard>();
for (int num3 = 0; num3 < list.Count; num3++)
{
for (int num4 = 0; num4 < field.AllyInplayCards.Count; num4++)
{
if (field.AllyInplayCards[num4].CardIndex == list[num3].CardIndex && field.AllyInplayCards[num4].BaseId == list[num3].BaseId)
{
list4.Add(field.AllyInplayCards[num4]);
break;
}
}
}
return list4;
}
public float GetEvoPenalty()
{
float num = 4f;
if (!isUsedEvo && TurnCount >= 6)
{
num /= 2f;
}
return num;
}
public static int GetBaseId(int id)
{
return CardMaster.GetInstanceForBattle().GetCardParameterFromId(id).BaseCardId;
}
public int AIStableRandom()
{
return stableRandom.Next();
}
public int AIStableRandom(int val)
{
return (int)Math.Floor((double)val * stableRandom.NextDouble());
}
public float CalcFieldAdvantage()
{
float num = 0f;
for (int i = 0; i < CurrentVirtualField.AllyInplayCards.Count; i++)
{
float num2 = CurrentVirtualField.AllyInplayCards[i].EvaluateValueOnField(EmptyPlayPtn, null, useStyle: true);
if (num2 > 0f)
{
num += num2;
}
}
float num3 = 0f;
for (int j = 0; j < CurrentVirtualField.EnemyInplayCards.Count; j++)
{
float num4 = CurrentVirtualField.EnemyInplayCards[j].EvaluateValueOnField(EmptyPlayPtn, null, useStyle: true);
if (num4 > 0f)
{
num3 += num4;
}
}
return num - num3;
}
public int GetAllySpaceNum()
{
return 5 - CurrentVirtualField.AllyInplayCards.Count;
}
public void OprEvolution(AIVirtualCard virtualCard)
{
AIOperationQueue.Enqueue(delegate
{
SetupThinkingInterval();
isUsedEvo = true;
emoteQuery.OnOperation();
SelectSkillTarget(virtualCard, AIOperationType.EVOLVE, BestPlayPtnRecord);
emoteMng.OnOperationRequest();
});
}
public void OprPlay(AIVirtualCard card, AISinglePlayptnRecord playptnRecord)
{
AIVirtualCard currentFieldCard = _currentVirtualField.SearchVirtualCard(card);
AIOperationQueue.Enqueue(delegate
{
SetupThinkingInterval();
emoteMng.EvalAllyOnCardPlay(currentFieldCard, playptnRecord);
emoteQuery.OnOperation();
_isSetCardReady = false;
SelectSkillTarget(currentFieldCard, AIOperationType.PLAY, playptnRecord);
_isSetCardReady = true;
emoteMng.OnOperationRequest();
});
}
public void OprAttack(AISituationInfo situation)
{
AIVirtualAttackInfo attackSituation = situation as AIVirtualAttackInfo;
if (attackSituation == null || attackSituation.Actor == null || attackSituation.AttackTarget == null)
{
AIConsoleUtility.LogError("OprAttack error!!! situation is invalid");
return;
}
AIOperationQueue.Enqueue(delegate
{
AIRealBattleCardSearcher.SearchAttackPairFromSituation(PlayerPair, attackSituation, out var attacker, out var attackTarget);
if (attackTarget != null && attackTarget != null)
{
SequentialVfxPlayer sequentialVfxPlayer = SequentialVfxPlayer.Create();
VfxBase emote = GetEmote(AIEmoteCmdType.ON_ALLY_ATTACK, situation);
sequentialVfxPlayer.Register(emote);
if (AttackSelectControl.CanCardAttackTarget(attacker, attackTarget, attackTarget.SelfBattlePlayer.InPlayCards))
{
VfxBase vfx = battleMgr.OperateMgr.Attack(attacker, attackTarget, ALLY.IsPlayer);
sequentialVfxPlayer.Register(vfx);
battleMgr.VfxMgr.RegisterSequentialVfx(sequentialVfxPlayer);
}
else
{
if (attackTarget != null)
{
_ = attacker.BaseParameter.CardName;
}
_ = attackTarget?.BaseParameter.CardName;
isForceBreak = true;
}
}
else
{
isForceBreak = true;
}
emoteMng.OnOperationRequest();
if (IsRankMatchAI)
{
CheckIsStackAction();
}
});
}
public void OprTargetSelect(AIVirtualCard virtualActor, AISelectedTargetInfoSet targetInfoSet, AIOperationType operationType)
{
AIOperationQueue.Enqueue(delegate
{
if (!battleMgr.IsBattleEnd)
{
AIVirtualTargetSelectAction situation = new AIVirtualTargetSelectAction(virtualActor, virtualActor, operationType, targetInfoSet);
VfxBase vfx = null;
switch (operationType)
{
case AIOperationType.EVOLVE:
vfx = OperationProcessor.AIEvolutionCard(situation);
break;
case AIOperationType.PLAY:
vfx = OperationProcessor.AIPlayCard(situation);
break;
case AIOperationType.FUSION:
vfx = OperationProcessor.AIFusionCard(situation);
break;
}
is_onSelectSkillTarget = false;
battleMgr.VfxMgr.RegisterSequentialVfx(vfx);
emoteMng.OnOperationRequest();
if (IsRankMatchAI)
{
SetupThinkingInterval();
CheckIsStackAction();
}
}
});
EnemyAISkill.ClearPreDecidedTarget();
}
public bool OprLethalAction(AISituationInfo action)
{
AIVirtualCard originalCard = action.OriginalCard;
AISelectedTargetInfoSet selectedTargets = action.SelectedTargets;
AIOperationType actionType = action.ActionType;
switch (actionType)
{
case AIOperationType.EVOLVE:
case AIOperationType.PLAY:
OprTargetSelect(originalCard, selectedTargets, actionType);
return true;
case AIOperationType.ATTACK:
OprAttack(action);
return true;
default:
return false;
}
}
private static AIVirtualCard FindCardFromCardIndex(List<AIVirtualCard> cardList, int index)
{
if (cardList.Any((AIVirtualCard card) => card.CardIndex == index))
{
return cardList.First((AIVirtualCard card) => card.CardIndex == index);
}
return null;
}
public static bool IsSameValue(float value1, float value2)
{
return (int)Math.Round(value1 * 1000f) == (int)Math.Round(value2 * 1000f);
}
public static bool IsLargerThan(float value1, float value2)
{
return (int)Math.Round(value1 * 1000f) > (int)Math.Round(value2 * 1000f);
}
public virtual VfxBase GetEmote(AIEmoteCmdType cmdType, AISituationInfo situation = null, ClassCharaPrm.EmotionType receivedEmoteType = ClassCharaPrm.EmotionType.NULL, int emoteInput = -1)
{
if (IsBattleEnd)
{
return NullVfx.GetInstance();
}
if (isAIEmoteRegistered && cmdType != AIEmoteCmdType.ON_OPPONENT_TURN_START && cmdType != AIEmoteCmdType.ON_ALLY_TURN_START)
{
AIConsoleUtility.Log("<color=green>既にEmoteを登録中です</color>");
return NullVfx.GetInstance();
}
isAIEmoteRegistered = true;
float num = 0f;
float num2 = 0f;
AIEmoteCmd aIEmoteCmd = null;
VfxBase vfxBase = NullVfx.GetInstance();
switch (cmdType)
{
case AIEmoteCmdType.ON_RECEIVE:
aIEmoteCmd = emoteCtrl.OnOpponentEmotion(receivedEmoteType);
if (aIEmoteCmd != null)
{
vfxBase = ALLY.Emotion.PlayEmotion(aIEmoteCmd.emoteType, 1.5f);
num = 2f;
}
break;
case AIEmoteCmdType.ON_FIRST_TURN:
vfxBase = ALLY.Emotion.PlayEmotion(ClassCharaPrm.EmotionType.PROVOCATION, 1.5f);
break;
case AIEmoteCmdType.ON_ITERATION_START:
aIEmoteCmd = emoteCtrl.OnIterationStart();
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
}
break;
case AIEmoteCmdType.ON_ALLY_TURN_START:
aIEmoteCmd = emoteCtrl.OnAllyTurnStart(situation);
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
}
break;
case AIEmoteCmdType.ON_OPPONENT_TURN_START:
aIEmoteCmd = emoteCtrl.OnOpponentTurnStart(situation);
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
}
break;
case AIEmoteCmdType.ON_ALLY_TURN_END:
aIEmoteCmd = emoteCtrl.OnAllyTurnEnd();
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
}
break;
case AIEmoteCmdType.ON_OPPONENT_TURN_END:
aIEmoteCmd = emoteCtrl.OnOpponentTurnEnd();
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
}
break;
case AIEmoteCmdType.ON_ALLY_ATTACK:
aIEmoteCmd = emoteCtrl.OnAllyAttack(situation);
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
}
break;
case AIEmoteCmdType.ON_OPPONENT_ATTACK:
aIEmoteCmd = emoteCtrl.OnOpponentAttackExecuted();
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
}
break;
case AIEmoteCmdType.ON_ALLY_EVOLUTION:
aIEmoteCmd = emoteCtrl.OnAllyEvolution(situation);
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
}
break;
case AIEmoteCmdType.ON_CARD_DESTROY:
aIEmoteCmd = emoteCtrl.OnCardDestroy(situation);
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
}
break;
case AIEmoteCmdType.ON_CARD_PLAY_ALLY:
aIEmoteCmd = emoteCtrl.OnCardPlay(situation);
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
}
break;
case AIEmoteCmdType.ON_CARD_PLAY_OPPONENT:
aIEmoteCmd = emoteCtrl.OnOpponentPlayCardExecuted(situation);
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
}
break;
case AIEmoteCmdType.ON_LEADER_DAMAGED:
aIEmoteCmd = emoteCtrl.OnLeaderDamaged(_currentVirtualField);
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
num = 2f;
}
break;
case AIEmoteCmdType.ON_PLAYER_LEADER_DAMAGED:
aIEmoteCmd = emoteCtrl.OnPlayerLeaderDamaged(_currentVirtualField);
if (aIEmoteCmd != null)
{
vfxBase = PlayEmotionDefault(aIEmoteCmd);
num = 2f;
}
break;
case AIEmoteCmdType.ON_DEBUG_SEARCH_ID:
aIEmoteCmd = emoteQuery.SearchEmoteByID(emoteInput);
if (aIEmoteCmd != null)
{
isAIEmoteRegistered = false;
return PlayEmotionDefault(aIEmoteCmd, isForcePlay: true);
}
break;
case AIEmoteCmdType.ON_DEBUG_SEARCH_CATEGORY:
{
IEnumerable<AIEmoteCmd> enumerable = emoteQuery.SearchEmoteByCategory(emoteInput);
if (enumerable == null)
{
break;
}
SequentialVfxPlayer sequentialVfxPlayer = SequentialVfxPlayer.Create();
foreach (AIEmoteCmd item in enumerable)
{
sequentialVfxPlayer.Register(PlayEmotionDefault(item, isForcePlay: true));
sequentialVfxPlayer.Register(WaitVfx.Create(2f));
}
ImmediateVfxMgr.GetInstance().Register(sequentialVfxPlayer);
isAIEmoteRegistered = false;
return NullVfx.GetInstance();
}
}
if (vfxBase == NullVfx.GetInstance())
{
isAIEmoteRegistered = false;
return NullVfx.GetInstance();
}
IsThisTurnEmotePlayed = true;
SequentialVfxPlayer sequentialVfxPlayer2 = SequentialVfxPlayer.Create();
if (num > 0f)
{
sequentialVfxPlayer2.Register(WaitVfx.Create(num));
}
sequentialVfxPlayer2.Register(vfxBase);
if (num2 > 0f)
{
sequentialVfxPlayer2.Register(WaitVfx.Create(num2));
}
sequentialVfxPlayer2.Register(InstantVfx.Create(delegate
{
isAIEmoteRegistered = false;
}));
return sequentialVfxPlayer2;
}
private VfxBase PlayEmotionDefault(AIEmoteCmd emoteCmd, bool isForcePlay = false)
{
if (!isForcePlay)
{
if (emoteQuery.GetCategoryInterval(emoteCmd.CategoryKey) > 0)
{
return NullVfx.GetInstance();
}
if (AIEmoteUtility.IsSystemEmoteKey(emoteCmd.CategoryKey) && ALLY.Turn < 4)
{
return NullVfx.GetInstance();
}
if (!ALLY.IsSelfTurn)
{
emoteMng.OnOpponentTurnEmote();
}
if (AIEmoteUtility.IsSystemEmoteKey(emoteCmd.CategoryKey))
{
emoteQuery.SetInterval(emoteCmd.CategoryKey, AIStableRandom() % 2 + 1);
}
}
emoteMng.AddPlayedCountOnEmotePlaying(emoteCmd.CategoryKey);
if (emoteCmd.isAI)
{
return ALLY.Emotion.PlayEmotion((ClassCharaPrm.MotionType)emoteCmd.motionID, (ClassCharaPrm.FaceType)emoteCmd.faceID, emoteCmd.voiceID, emoteCmd.textID);
}
return OPPONENT.Emotion.PlayEmotion((ClassCharaPrm.MotionType)emoteCmd.motionID, (ClassCharaPrm.FaceType)emoteCmd.faceID, emoteCmd.voiceID, emoteCmd.textID);
}
public bool IsBishop()
{
return paramQuery.GetClassID() == 7;
}
public bool IsNecromancer()
{
return paramQuery.GetClassID() == 5;
}
public bool IsRoyal()
{
return paramQuery.GetClassID() == 2;
}
public bool IsAbleEvo()
{
if (ALLY.EvolveWaitTurnCount <= 0)
{
return ALLY.NowTurnEvol;
}
return false;
}
public bool IsAllyCard(BattleCardBase card)
{
return PlayerPair.Self.IsPlayer == card.IsPlayer;
}
public bool IsAllyCard(AIVirtualCard card)
{
return PlayerPair.Self.IsPlayer == card.IsPlayer;
}
public bool IsOpponentCard(BattleCardBase card)
{
return PlayerPair.Self.IsPlayer != card.IsPlayer;
}
public void SetPreDecidedTargets(AISelectedTargetInfoSet set)
{
PreDecidedTargets = set;
}
public bool HasPlayerAbilityId(int id)
{
if (_playerAbilityIdList == null || _playerAbilityIdList.Count <= 0)
{
return false;
}
for (int i = 0; i < _playerAbilityIdList.Count; i++)
{
if (_playerAbilityIdList[i] == id)
{
return true;
}
}
return false;
}
public void UpdateAICurrentVirtualField(bool isUsePreviousFieldParameter = true)
{
UpdateCurrentVirtualField(paramQuery, styleQuery, PlayerPair, EmptyPlayPtn, isUsePreviousFieldParameter);
}
public abstract void Retire();
public abstract void Disconnect();
public abstract void Reconnect();
public abstract void CleanupStackedAction();
protected abstract void OnFinishOprAttack();
protected abstract void OnFinishOprTargetSelect();
protected abstract void OnBeforeTurnEnd();
public void TurnEnd()
{
OnBeforeTurnEnd();
BattleCoroutine instance = BattleCoroutine.GetInstance();
if (weakLogicCoroutine != null)
{
instance.StopCoroutine(weakLogicCoroutine);
weakLogicCoroutine = null;
}
EnemyAICoroutine.GetInstance().StopAllCoroutines();
EnemyAIUtil.TurnEnd(BattleMgr, PlayerPair.Self.IsPlayer);
}
public virtual void RegistActionOperationQueue(Action action)
{
AIOperationQueue.Enqueue(action);
}
public virtual void ExecuteActionOperationQueue()
{
if (battleMgr.VfxMgr.IsEnd && AIOperationQueue.Count > 0)
{
AIOperationQueue.Dequeue().Call();
if (!IsRunWeakLogic)
{
oprationQueueActCount++;
}
}
}
protected abstract void CheckIsStackAction();
protected abstract void SetupThinkingInterval();
public int CalcHandNextTurnDamage(AIVirtualField field)
{
int num = 0;
List<AIVirtualCard> list = new List<AIVirtualCard>();
List<AIVirtualCard> list2 = new List<AIVirtualCard>();
foreach (AIVirtualCard allyHandCard in field.AllyHandCards)
{
if (allyHandCard.TagCollectionContainer.HasTag(AIPlayTagType.PlayoutNextTurn))
{
list.Add(allyHandCard);
}
}
if (0 < list.Count)
{
int num2 = Mathf.Min(10, ALLY.PpTotal + 1);
int num3 = (int)Mathf.Pow(2f, list.Count);
for (int i = 0; i < num3; i++)
{
int num4 = 0;
int totalCost = 0;
ConvertPlayoutNextTurnHandPtnList(list, list2, i, out totalCost);
if (num2 < totalCost)
{
continue;
}
for (int j = 0; j < list2.Count; j++)
{
if (!list2[j].TagCollectionContainer.HasTag(AIPlayTagType.PlayoutNextTurn))
{
continue;
}
PlayoutNextTurnTagCollection playoutNextTurnTags = list2[j].TagCollectionContainer.PlayoutNextTurnTags;
for (int k = 0; k < playoutNextTurnTags.TagList.Count; k++)
{
if (playoutNextTurnTags.TagList[k].CheckCondition(list[j], EmptyPlayPtn, field, null))
{
num4 += (int)playoutNextTurnTags.TagList[k].EvalArg(list2[j], null, field, null);
}
}
}
if (num < num4)
{
num = num4;
}
}
}
return num;
}
private void ConvertPlayoutNextTurnHandPtnList(List<AIVirtualCard> srcList, List<AIVirtualCard> dstList, int index, out int totalCost)
{
totalCost = 0;
int count = srcList.Count;
int num = index;
dstList.Clear();
for (int i = 0; i < count; i++)
{
AIVirtualCard aIVirtualCard = srcList[i];
int num2 = (int)Mathf.Pow(2f, count - i - 1);
if (0 < num / num2)
{
num -= num2;
dstList.Add(aIVirtualCard);
totalCost += aIVirtualCard.Cost;
}
}
}
}