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.
This commit is contained in:
301
SVSim.BattleEngine/Engine/Wizard/AITimeOverAttackSimulator.cs
Normal file
301
SVSim.BattleEngine/Engine/Wizard/AITimeOverAttackSimulator.cs
Normal file
@@ -0,0 +1,301 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Cute;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AITimeOverAttackSimulator : IBattleSimulationAI
|
||||
{
|
||||
private const int NONE_EVOLVE_INDEX = -1;
|
||||
|
||||
private AIRuleBaseBattleSimulator _ruleBaseSimulator;
|
||||
|
||||
private SimulationResult _bestResult;
|
||||
|
||||
private int _originalFieldInplayCount;
|
||||
|
||||
private ulong[] _defaultPlayptnHashArray;
|
||||
|
||||
private SimulationAdditionalActionInfoSet _simAdditionalOptions;
|
||||
|
||||
public AIVirtualField Cr_MaxField
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bestResult == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return _bestResult.BestResultField;
|
||||
}
|
||||
}
|
||||
|
||||
public float Cr_MaxFieldValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bestResult == null)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
return _bestResult.MaxFieldValue;
|
||||
}
|
||||
}
|
||||
|
||||
public float Cr_MaxFieldValueAtSelfTurnEnd
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bestResult == null)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
return _bestResult.MaxFieldValueAtSelfTurnEnd;
|
||||
}
|
||||
}
|
||||
|
||||
public List<AIVirtualActionInfo> Cr_MaxActionInfoSequence => _bestResult.ActionSequence;
|
||||
|
||||
public PlayPtnWithToken Cr_BestPlayPtnWithToken { get; private set; }
|
||||
|
||||
public AIVirtualActionInfo Cr_FirstActionInfo { get; private set; }
|
||||
|
||||
public IEnumerator _CrSimulate(AIVirtualField originalField, bool doesUseEvo, bool checkTimeOverLogic, PlayPtnWithToken[] bestPlayPtnWithToken = null, SimulationAdditionalActionInfoSet additionalActions = null)
|
||||
{
|
||||
originalField.AI.IsInVirutalSimulation = true;
|
||||
_ruleBaseSimulator = new AIRuleBaseBattleSimulator(originalField.AI, bestPlayPtnWithToken, canChangeToTimeOverLogic: true);
|
||||
_bestResult = new SimulationResult();
|
||||
_originalFieldInplayCount = originalField.AllyInplayCards.Count((AIVirtualCard c) => !c.IsDead);
|
||||
_defaultPlayptnHashArray = AISimulationUtility.CalculatePlayptnWithTokenHashs(originalField, bestPlayPtnWithToken);
|
||||
_simAdditionalOptions = additionalActions;
|
||||
ParallelJob job = ParallelJob.Dispatch(delegate
|
||||
{
|
||||
try
|
||||
{
|
||||
AIVirtualField field = new AIVirtualField(originalField);
|
||||
int[] attackerIdxList = SortByOneAttackBreak(field);
|
||||
if (additionalActions != null)
|
||||
{
|
||||
_ = additionalActions.ForceEvoAction;
|
||||
}
|
||||
SimulateEvoPatternBattle(field, attackerIdxList, doesUseEvo);
|
||||
if (bestPlayPtnWithToken != null && Cr_MaxField != null)
|
||||
{
|
||||
int num = Cr_MaxField.AllyInplayCards.Count((AIVirtualCard c) => !c.IsDead);
|
||||
int num2 = Mathf.Min(Mathf.Max(0, _originalFieldInplayCount - num), bestPlayPtnWithToken.Length - 1);
|
||||
Cr_BestPlayPtnWithToken = null;
|
||||
for (int num3 = num2; num3 >= 0; num3--)
|
||||
{
|
||||
if (bestPlayPtnWithToken[num3] != null)
|
||||
{
|
||||
Cr_BestPlayPtnWithToken = bestPlayPtnWithToken[num3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
});
|
||||
while (!job.isDone)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
if (Cr_MaxField != null)
|
||||
{
|
||||
Cr_FirstActionInfo = BattleSequencer.GetFirstActionInfo(_bestResult.ActionSequence, Cr_MaxField, Cr_MaxField.BestPlayPtn);
|
||||
}
|
||||
originalField.AI.IsInVirutalSimulation = false;
|
||||
}
|
||||
|
||||
private int[] SortByOneAttackBreak(AIVirtualField field)
|
||||
{
|
||||
List<int> sortedAttackerIndexList = GetSortedAttackerIndexList(field);
|
||||
int num = ((field.EnemyInplayCards != null) ? field.EnemyInplayCards.Count : 0);
|
||||
if (num == 0)
|
||||
{
|
||||
return sortedAttackerIndexList.ToArray();
|
||||
}
|
||||
List<int> list = new List<int>();
|
||||
List<int> list2 = new List<int>();
|
||||
List<int> list3 = new List<int>(sortedAttackerIndexList);
|
||||
for (int i = 0; i < sortedAttackerIndexList.Count; i++)
|
||||
{
|
||||
int num2 = 0;
|
||||
bool flag = false;
|
||||
int num3 = 0;
|
||||
for (int j = 0; j < num; j++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = field.AllyInplayCards[sortedAttackerIndexList[i]];
|
||||
AIVirtualCard aIVirtualCard2 = field.EnemyInplayCards[j];
|
||||
if (!aIVirtualCard2.IsUnit)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int num4 = aIVirtualCard2.SimulateDamageAmount(aIVirtualCard.Attack);
|
||||
if (aIVirtualCard2.Life <= num4)
|
||||
{
|
||||
num2++;
|
||||
if (!flag)
|
||||
{
|
||||
flag = aIVirtualCard2.IsBreakFirst(field.BestPlayPtn);
|
||||
}
|
||||
if (aIVirtualCard2.IsBreakLast(field.BestPlayPtn))
|
||||
{
|
||||
num3++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (num2 > 0 && flag)
|
||||
{
|
||||
int item = sortedAttackerIndexList[i];
|
||||
list.Add(item);
|
||||
list3.Remove(item);
|
||||
}
|
||||
else if (num2 == 0 || (num2 > 0 && num3 == num2))
|
||||
{
|
||||
int item2 = sortedAttackerIndexList[i];
|
||||
list2.Add(item2);
|
||||
list3.Remove(item2);
|
||||
}
|
||||
}
|
||||
list.AddRange(list3);
|
||||
list.AddRange(list2);
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
private void SimulateEvoPatternBattle(AIVirtualField field, int[] attackerIdxList, bool useEve)
|
||||
{
|
||||
List<int> sortedAttackTargetIndexList = GetSortedAttackTargetIndexList(field);
|
||||
if (((_simAdditionalOptions != null) ? _simAdditionalOptions.ForceEvoAction : null) != null)
|
||||
{
|
||||
SimulateTargetsBreakPattern(field, attackerIdxList, -1, sortedAttackTargetIndexList);
|
||||
return;
|
||||
}
|
||||
int num = (useEve ? field.AllyInplayCards.Count : 0);
|
||||
for (int i = -1; i < num; i++)
|
||||
{
|
||||
if (AISimulationUtility.IsValuableEvoIndex(i, field))
|
||||
{
|
||||
SimulateTargetsBreakPattern(field, attackerIdxList, i, sortedAttackTargetIndexList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SimulateTargetsBreakPattern(AIVirtualField field, int[] attackrIndecies, int evoIndex, List<int> enemyAllTargets)
|
||||
{
|
||||
List<ulong> list = new List<ulong>();
|
||||
List<int> list2 = new List<int>();
|
||||
_ruleBaseSimulator.RunSequence(field, attackrIndecies, evoIndex, new List<int>(), _bestResult, _simAdditionalOptions, null, checkActFailure: false);
|
||||
list.Add(AISimulationUtility.CalculateTargetSequenceHash(list2.ToArray(), field));
|
||||
int num = enemyAllTargets.Count;
|
||||
while (num > 0 && !field.AI.IsBattleEnd)
|
||||
{
|
||||
int[] patternGroup = AISimulationUtility.GetPatternGroup(num);
|
||||
if (patternGroup != null)
|
||||
{
|
||||
for (int i = 0; i < patternGroup.Length; i++)
|
||||
{
|
||||
List<int> enemyTargets = AISimulationUtility.GetEnemyTargets(field.EnemyInplayCards, enemyAllTargets, patternGroup[i], field.BestPlayPtn);
|
||||
ulong item = AISimulationUtility.CalculateTargetSequenceHash(enemyTargets.ToArray(), field);
|
||||
if (!list.Contains(item))
|
||||
{
|
||||
AIOneMoreLastwordUtility.SortEnemyTargetByBreakBonus(field, enemyTargets);
|
||||
if (!AISimulationUtility.IsValidEnemyTargetIndexes(field.EnemyInplayCards, enemyTargets))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_ruleBaseSimulator.RunSequence(field, attackrIndecies, evoIndex, enemyTargets, _bestResult, _simAdditionalOptions, null, checkActFailure: false);
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
num--;
|
||||
}
|
||||
}
|
||||
|
||||
private List<int> GetSortedAttackerIndexList(AIVirtualField field)
|
||||
{
|
||||
List<int> list = new List<int>();
|
||||
List<bool> list2 = new List<bool>();
|
||||
List<AIVirtualCard> allyInplayCards = field.AllyInplayCards;
|
||||
for (int i = 0; i < allyInplayCards.Count; i++)
|
||||
{
|
||||
list2.Add(AIAttackSimulationUtility.IsAttackPossible(field, allyInplayCards[i].AttackLeaderSituation));
|
||||
}
|
||||
for (int j = 0; j < allyInplayCards.Count; j++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = allyInplayCards[j];
|
||||
if (!aIVirtualCard.IsUnit)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int num = -1;
|
||||
for (int k = 0; k < list.Count; k++)
|
||||
{
|
||||
int index = list[k];
|
||||
AIVirtualCard aIVirtualCard2 = allyInplayCards[index];
|
||||
if (aIVirtualCard.Attack < aIVirtualCard2.Attack)
|
||||
{
|
||||
num = k;
|
||||
break;
|
||||
}
|
||||
if (aIVirtualCard.Attack == aIVirtualCard2.Attack && (!list2[j] || list2[index]) && ((!list2[j] && list2[index]) || aIVirtualCard.Life < aIVirtualCard2.Life))
|
||||
{
|
||||
num = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (num >= 0 && num < list.Count)
|
||||
{
|
||||
list.Insert(num, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(j);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<int> GetSortedAttackTargetIndexList(AIVirtualField field)
|
||||
{
|
||||
List<int> list = new List<int>();
|
||||
List<int> list2 = new List<int>();
|
||||
List<AIVirtualCard> enemyInplayCards = field.EnemyInplayCards;
|
||||
for (int i = 0; i < enemyInplayCards.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = enemyInplayCards[i];
|
||||
if (!aIVirtualCard.IsUnit)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int num = -1;
|
||||
List<int> list3 = (aIVirtualCard.IsGuard ? list2 : list);
|
||||
for (int j = 0; j < list3.Count; j++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard2 = enemyInplayCards[list3[j]];
|
||||
if (aIVirtualCard.Life < aIVirtualCard2.Life || (aIVirtualCard.Life == aIVirtualCard2.Life && aIVirtualCard.Attack > aIVirtualCard2.Attack))
|
||||
{
|
||||
num = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (num >= 0 && num < list3.Count)
|
||||
{
|
||||
list3.Insert(num, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
list3.Add(i);
|
||||
}
|
||||
}
|
||||
list2.AddRange(list);
|
||||
return list2;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user