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.
This commit is contained in:
355
SVSim.BattleEngine/Engine/Wizard/EnemyAI_Attack.cs
Normal file
355
SVSim.BattleEngine/Engine/Wizard/EnemyAI_Attack.cs
Normal file
@@ -0,0 +1,355 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class EnemyAI_Attack
|
||||
{
|
||||
private class PlaySkipExecutingInfo
|
||||
{
|
||||
public bool IsEvolutionPermitted;
|
||||
|
||||
public List<AIVirtualActionInfo> SimulationExtraActionBaseList;
|
||||
|
||||
public PlaySkipExecutingInfo()
|
||||
{
|
||||
IsEvolutionPermitted = false;
|
||||
SimulationExtraActionBaseList = null;
|
||||
}
|
||||
|
||||
public void AddExtraAction(AIVirtualActionInfo action)
|
||||
{
|
||||
SimulationExtraActionBaseList = AIParamQuery.AddElementToList(action, SimulationExtraActionBaseList);
|
||||
}
|
||||
}
|
||||
|
||||
private EnemyAI _ai;
|
||||
|
||||
private IBattleSimulationAI _simulationResultWithEmptyPlayPtn;
|
||||
|
||||
public bool IsLethalAttackPlan { get; private set; }
|
||||
|
||||
public EnemyAI_Attack(EnemyAI ai)
|
||||
{
|
||||
_ai = ai;
|
||||
_simulationResultWithEmptyPlayPtn = null;
|
||||
}
|
||||
|
||||
public void InitOnTurnStart()
|
||||
{
|
||||
_simulationResultWithEmptyPlayPtn = null;
|
||||
}
|
||||
|
||||
public void InitOnIterationStart()
|
||||
{
|
||||
_simulationResultWithEmptyPlayPtn = null;
|
||||
}
|
||||
|
||||
public IEnumerator BattleAI_UseHighSimu()
|
||||
{
|
||||
AIVirtualField currentVirtualField = _ai.CurrentVirtualField;
|
||||
AISinglePlayptnRecord playPtnRecord = _ai.BestPlayPtnRecord;
|
||||
PlaySkipExecutingInfo playSkipExecutingInfo = CreatePlaySkipExecutingInfo(playPtnRecord);
|
||||
bool flag = playSkipExecutingInfo?.IsEvolutionPermitted ?? true;
|
||||
bool isEvol = _ai.IsEvoPermissionOnSimu && flag && !_ai.IsBreakBeforePlay;
|
||||
float fastEvoMaxValue = float.MinValue;
|
||||
AIVirtualCard evolveFollower = null;
|
||||
AIVirtualActionInfo firstAction = null;
|
||||
bool isLethalByEvo = false;
|
||||
if (isEvol)
|
||||
{
|
||||
int allyIndex = 0;
|
||||
while (allyIndex < currentVirtualField.AllyInplayCards.Count)
|
||||
{
|
||||
AIVirtualCard inplayTemp = currentVirtualField.AllyInplayCards[allyIndex];
|
||||
if (inplayTemp.IsAbleEvolution())
|
||||
{
|
||||
AIVirtualTargetSelectAction situation = new AIVirtualTargetSelectAction(inplayTemp, inplayTemp, AIOperationType.EVOLVE, (AISelectedTargetInfoSet)null);
|
||||
SimulationResult ref_skillSim = new SimulationResult();
|
||||
List<AIVirtualTargetSelectInfo> list = inplayTemp.CreateAIVirtualSelectInfo(currentVirtualField, situation);
|
||||
if (list != null)
|
||||
{
|
||||
AIVirtualTargetSelectSimulationInfo simulationInfo = new AIVirtualTargetSelectSimulationInfo
|
||||
{
|
||||
OriginalActor = inplayTemp,
|
||||
RealActor = inplayTemp,
|
||||
SelectInfoList = list,
|
||||
OperationType = AIOperationType.EVOLVE,
|
||||
NextPlayCardInfo = null,
|
||||
IsFirstAction = true
|
||||
};
|
||||
yield return EnemyAICoroutine.GetInstance().StartCoroutine(AIVirtualTargetSelectSimulator.SimulateTargetSelect(simulationInfo, _ai.CurrentVirtualField, playPtnRecord, ref_skillSim, isBattleSim: true));
|
||||
if (IsTargetSelectEvolutionValid(ref_skillSim, inplayTemp, fastEvoMaxValue))
|
||||
{
|
||||
isLethalByEvo = ref_skillSim.IsLethalPlan;
|
||||
fastEvoMaxValue = ref_skillSim.MaxFieldValue;
|
||||
firstAction = ref_skillSim.FirstActionInfo;
|
||||
evolveFollower = inplayTemp;
|
||||
}
|
||||
}
|
||||
}
|
||||
int num = allyIndex + 1;
|
||||
allyIndex = num;
|
||||
}
|
||||
}
|
||||
AIVirtualField field = new AIVirtualField(_ai.CurrentVirtualField)
|
||||
{
|
||||
BestPlayPtn = _ai.BestPlayPtn
|
||||
};
|
||||
SimulationAdditionalActionInfoSet additionalActionInfoSet = new SimulationAdditionalActionInfoSet
|
||||
{
|
||||
ForceEvoAction = null,
|
||||
ExtraActionBaseList = playSkipExecutingInfo?.SimulationExtraActionBaseList,
|
||||
PlayPtnRecord = playPtnRecord
|
||||
};
|
||||
AIBattleSimulationLauncher battleSimLauncher = new AIBattleSimulationLauncher(field, _ai, isEvol, _simulationResultWithEmptyPlayPtn, additionalActionInfoSet);
|
||||
yield return battleSimLauncher.ExecuteBattleSimulationAI(null, checkTimeOverLogic: true);
|
||||
IBattleSimulationAI battleSimAI = battleSimLauncher.BattleSimAI;
|
||||
if (_ai.IsBreakBeforePlay && battleSimAI.Cr_MaxField != null && !battleSimAI.Cr_MaxField.IsBreakBeforePlayKilled)
|
||||
{
|
||||
_ai.cr_isOprAtk = false;
|
||||
yield break;
|
||||
}
|
||||
if (battleSimAI.Cr_MaxFieldValue > fastEvoMaxValue)
|
||||
{
|
||||
if (battleSimAI.Cr_FirstActionInfo != null && !(battleSimAI.Cr_FirstActionInfo is AIVirtualTurnEndInfo))
|
||||
{
|
||||
firstAction = battleSimAI.Cr_FirstActionInfo;
|
||||
evolveFollower = battleSimAI.Cr_MaxField.EvoUsedCard;
|
||||
IsLethalAttackPlan = battleSimAI.Cr_MaxField.EnemyClass.IsDead;
|
||||
}
|
||||
else
|
||||
{
|
||||
firstAction = null;
|
||||
IsLethalAttackPlan = isLethalByEvo;
|
||||
evolveFollower = null;
|
||||
}
|
||||
}
|
||||
if (firstAction == null)
|
||||
{
|
||||
_ai.cr_isOprAtk = false;
|
||||
}
|
||||
else if (!IsPlaySkipPermitted(evolveFollower))
|
||||
{
|
||||
_ai.cr_isOprAtk = false;
|
||||
}
|
||||
else if (firstAction.ActionType == AIOperationType.PLAY)
|
||||
{
|
||||
foreach (PlayedCardInfo playedCard in _ai.BestPlayPtnRecord.PlayedCardList)
|
||||
{
|
||||
if (playedCard.PreDecidedSelectTargets != null && firstAction.OriginalCard.IsSameCard(playedCard.Card))
|
||||
{
|
||||
_ai.SetPreDecidedTargets(playedCard.PreDecidedSelectTargets);
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ai.OprPlay(firstAction.OriginalCard, _ai.BestPlayPtnRecord);
|
||||
_ai.cr_isOprAtk = true;
|
||||
}
|
||||
else if (firstAction.ActionType == AIOperationType.EVOLVE)
|
||||
{
|
||||
_ai.CurrentBattleBeforeSimEvoEvolCount = _ai.PlayerPair.Self.CurrentEpCount;
|
||||
_ai.OprEvolution(firstAction.Actor);
|
||||
_ai.CurrentBattleSimEvoCard = evolveFollower;
|
||||
_ai.cr_isOprAtk = true;
|
||||
}
|
||||
else if (firstAction.ActionType == AIOperationType.ATTACK)
|
||||
{
|
||||
_ai.OprAttack(firstAction);
|
||||
_ai.cr_isOprAtk = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ai.cr_isOprAtk = false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPlaySkipPermitted(AIVirtualCard evolveFollower)
|
||||
{
|
||||
if (_ai.PlaySkipInfo == null || !_ai.PlaySkipInfo.Any())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool result = false;
|
||||
for (int i = 0; i < _ai.PlaySkipInfo.Count; i++)
|
||||
{
|
||||
if (_ai.PlaySkipInfo[i].IsEvoCardLegal(evolveFollower))
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private PlaySkipExecutingInfo CreatePlaySkipExecutingInfo(AISinglePlayptnRecord playPtnRecord)
|
||||
{
|
||||
List<PlaySkipInformation> playSkipInfo = _ai.PlaySkipInfo;
|
||||
if (playSkipInfo == null || playSkipInfo.Count <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
PlaySkipExecutingInfo playSkipExecutingInfo = new PlaySkipExecutingInfo();
|
||||
List<AIScriptTokenArgType> checkedActionTypeList = null;
|
||||
for (int i = 0; i < playSkipInfo.Count; i++)
|
||||
{
|
||||
PlaySkipInformation playSkipInformation = playSkipInfo[i];
|
||||
if (playSkipInformation.IsEvolutionPermittedTag)
|
||||
{
|
||||
playSkipExecutingInfo.IsEvolutionPermitted = true;
|
||||
}
|
||||
AIVirtualActionInfo aIVirtualActionInfo = null;
|
||||
if (!(playSkipInformation is PlaySkipWithActionInformation playSkipWithActionInformation))
|
||||
{
|
||||
if (playSkipInformation is PlaySkipWithActionIfEvoInformation playSkipWithActionIfEvoInformation)
|
||||
{
|
||||
aIVirtualActionInfo = playSkipWithActionIfEvoInformation.GetExtraActionBase(playPtnRecord, ref checkedActionTypeList);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aIVirtualActionInfo = playSkipWithActionInformation.GetExtraActionBase(playPtnRecord, ref checkedActionTypeList);
|
||||
}
|
||||
if (aIVirtualActionInfo != null)
|
||||
{
|
||||
playSkipExecutingInfo.AddExtraAction(aIVirtualActionInfo);
|
||||
}
|
||||
}
|
||||
return playSkipExecutingInfo;
|
||||
}
|
||||
|
||||
private bool IsTargetSelectEvolutionValid(SimulationResult result, AIVirtualCard targetSelectEvoOwner, float valueForComparing)
|
||||
{
|
||||
if (result.BestResultField == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
AIVirtualCard evoUsedCard = result.BestResultField.EvoUsedCard;
|
||||
if (evoUsedCard == null || !evoUsedCard.IsSameCard(targetSelectEvoOwner))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (result.MaxFieldValue <= valueForComparing)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool BattleAI_TurnEndAttack()
|
||||
{
|
||||
AIVirtualField aIVirtualField = new AIVirtualField(_ai.CurrentVirtualField)
|
||||
{
|
||||
BestPlayPtn = _ai.BestPlayPtn
|
||||
};
|
||||
AIVirtualField aIVirtualField2 = new AIVirtualField(aIVirtualField);
|
||||
List<AIVirtualActionInfo> moves = new List<AIVirtualActionInfo>();
|
||||
AIVirtualTurnEndInfo aIVirtualTurnEndInfo = new AIVirtualTurnEndInfo(aIVirtualField2.AllyClass);
|
||||
moves.Add(aIVirtualTurnEndInfo);
|
||||
BattleSequencer.OnAfterExecuteAttackCommon(aIVirtualField2, aIVirtualTurnEndInfo, ref moves);
|
||||
float num = AISimulationUtility.EvaluateField(aIVirtualField2, EvaluationType.SIMPLE);
|
||||
float num2 = float.MinValue;
|
||||
AIVirtualCard aIVirtualCard = null;
|
||||
AIVirtualCard aIVirtualCard2 = null;
|
||||
for (int i = 0; i < aIVirtualField.AllyInplayCards.Count; i++)
|
||||
{
|
||||
if (!aIVirtualField.AllyInplayCards[i].IsUnit)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (int j = -1; j < aIVirtualField.EnemyInplayCards.Count; j++)
|
||||
{
|
||||
if (j >= 0 && !aIVirtualField.EnemyInplayCards[j].IsUnit)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
aIVirtualField2 = new AIVirtualField(aIVirtualField);
|
||||
moves.Clear();
|
||||
AIVirtualCard aIVirtualCard3 = aIVirtualField2.AllyInplayCards[i];
|
||||
AIVirtualCard aIVirtualCard4 = ((j < 0) ? aIVirtualField2.EnemyClass : aIVirtualField2.EnemyInplayCards[j]);
|
||||
AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(aIVirtualCard3, aIVirtualCard4);
|
||||
if (AIAttackSimulationUtility.IsAttackPossible(aIVirtualField2, aIVirtualAttackInfo))
|
||||
{
|
||||
moves.Add(aIVirtualAttackInfo);
|
||||
AIVirtualAttackSimulator.Attack(aIVirtualAttackInfo, aIVirtualField2);
|
||||
AIVirtualTurnEndInfo aIVirtualTurnEndInfo2 = new AIVirtualTurnEndInfo(aIVirtualField2.AllyClass);
|
||||
moves.Add(aIVirtualTurnEndInfo2);
|
||||
BattleSequencer.OnAfterExecuteAttackCommon(aIVirtualField2, aIVirtualTurnEndInfo2, ref moves);
|
||||
num2 = AISimulationUtility.EvaluateField(aIVirtualField2, EvaluationType.SIMPLE);
|
||||
if (num2 > num)
|
||||
{
|
||||
num = num2;
|
||||
aIVirtualCard = aIVirtualCard3;
|
||||
aIVirtualCard2 = aIVirtualCard4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aIVirtualCard != null && aIVirtualCard2 != null)
|
||||
{
|
||||
_ai.OprAttack(new AIVirtualAttackInfo(aIVirtualCard, aIVirtualCard2));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEnumerator Cr_BattleAI_ImmediateAttack()
|
||||
{
|
||||
AIVirtualField aIVirtualField = new AIVirtualField(_ai.CurrentVirtualField);
|
||||
AIVirtualTurnEndInfo turnEndSituation = new AIVirtualTurnEndInfo(aIVirtualField.AllyClass);
|
||||
BattleSequencer.ProcessAllyTurnEndToOpponentTurnStart(aIVirtualField, turnEndSituation);
|
||||
if (aIVirtualField.IsSuccess())
|
||||
{
|
||||
_ai.cr_isTerminate = true;
|
||||
_ai.IsTurnEndLethal = true;
|
||||
yield break;
|
||||
}
|
||||
if (!_ai.CurrentVirtualField.isForceImmediateAttack())
|
||||
{
|
||||
int num = _ai.CurrentVirtualField.EnemyInplayCards.Count((AIVirtualCard card) => card.IsGuard);
|
||||
int num2 = _ai.CurrentVirtualField.AllyInplayCards.Count((AIVirtualCard card) => card.IsAttackable(EnemyAI.EmptyPlayPtn));
|
||||
bool flag = _ai.CurrentVirtualField.AllyInplayCards.Any((AIVirtualCard card) => card.IsIgnoreGuard);
|
||||
if (num >= num2 && !flag)
|
||||
{
|
||||
_ai.cr_isTerminate = false;
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
_simulationResultWithEmptyPlayPtn = new BestInPlayMoveAI(_ai);
|
||||
yield return EnemyAICoroutine.GetInstance().StartCoroutine(_simulationResultWithEmptyPlayPtn._CrSimulate(_ai.CurrentVirtualField, doesUseEvo: true, checkTimeOverLogic: true));
|
||||
if (_ai.IsRunWeakLogic)
|
||||
{
|
||||
_simulationResultWithEmptyPlayPtn = new AITimeOverAttackSimulator();
|
||||
yield return _simulationResultWithEmptyPlayPtn._CrSimulate(_ai.CurrentVirtualField, doesUseEvo: true, checkTimeOverLogic: false);
|
||||
}
|
||||
AIVirtualField cr_MaxField = _simulationResultWithEmptyPlayPtn.Cr_MaxField;
|
||||
if (cr_MaxField == null || !cr_MaxField.EnemyClass.IsDead || cr_MaxField.AllyClass.IsDead)
|
||||
{
|
||||
_ai.cr_isTerminate = false;
|
||||
yield break;
|
||||
}
|
||||
AIVirtualActionInfo cr_FirstActionInfo = _simulationResultWithEmptyPlayPtn.Cr_FirstActionInfo;
|
||||
if (cr_FirstActionInfo == null)
|
||||
{
|
||||
_ai.cr_isTerminate = false;
|
||||
yield break;
|
||||
}
|
||||
_ai.cr_isTerminate = true;
|
||||
if (cr_FirstActionInfo.ActionType == AIOperationType.EVOLVE && !cr_FirstActionInfo.Actor.BaseCard.IsEvolution)
|
||||
{
|
||||
_ai.OprEvolution(cr_FirstActionInfo.Actor);
|
||||
}
|
||||
else if (cr_FirstActionInfo.ActionType == AIOperationType.ATTACK)
|
||||
{
|
||||
if ((cr_FirstActionInfo as AIVirtualAttackInfo).AttackTarget != null)
|
||||
{
|
||||
_ai.OprAttack(cr_FirstActionInfo);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ai.cr_isTerminate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user