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

442 lines
14 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Cute;
using Wizard;
using Wizard.Battle.View;
using Wizard.Battle.View.Vfx;
public class SkillProcessor
{
private struct InplayCardInfo
{
public int _index;
public bool _isPlayer;
}
public enum ProcessCallType
{
Start,
ResidentStop
}
public abstract class ProcessInfo
{
protected SkillProcessor _skillProcessor;
protected BattlePlayerReadOnlyInfoPair _playerInfoPair;
protected SkillConditionCheckerOption _checkerOption;
public BattleCardBase OwnerCard { get; private set; }
public bool NeedOwnerDeadCheck { get; set; }
public bool IsImmediate { get; set; }
public abstract bool IsContainDeckSkill { get; }
public abstract List<SkillBase> GetDeckSkills { get; }
public ProcessInfo(BattleCardBase ownerCard, SkillProcessor skillProcessor, BattlePlayerReadOnlyInfoPair playerInfoPair, SkillConditionCheckerOption checkerOption)
{
OwnerCard = ownerCard;
IsImmediate = false;
_skillProcessor = skillProcessor;
_playerInfoPair = playerInfoPair;
_checkerOption = checkerOption;
}
public abstract VfxBase CallStart();
public abstract List<SkillBase> GetActiveSkill();
}
public class ProcessInfoCollection : ProcessInfo
{
protected SkillCollectionBase _skillCollection;
protected List<SkillBase> _activeSkill;
public override bool IsContainDeckSkill => _activeSkill.Any((SkillBase s) => s.IsDeckSelfSkill);
public override List<SkillBase> GetDeckSkills => _activeSkill.Where((SkillBase s) => s.IsDeckSelfSkill).ToList();
public ProcessInfoCollection(BattleCardBase ownerCard, SkillCollectionBase skills, SkillProcessor skillProcessor, BattlePlayerReadOnlyInfoPair playerInfoPair, SkillConditionCheckerOption checkerOption, List<SkillBase> activeSkill)
: base(ownerCard, skillProcessor, playerInfoPair, checkerOption)
{
_skillCollection = skills;
_activeSkill = activeSkill;
}
public override VfxBase CallStart()
{
return _skillCollection.CallStart(_skillProcessor, _playerInfoPair, _checkerOption, _activeSkill);
}
public override List<SkillBase> GetActiveSkill()
{
return _activeSkill;
}
}
public class ProcessInfoSkill : ProcessInfo
{
protected SkillBase _skill;
public override bool IsContainDeckSkill => _skill.IsDeckSelfSkill;
public override List<SkillBase> GetDeckSkills
{
get
{
List<SkillBase> list = new List<SkillBase>();
if (_skill.IsDeckSelfSkill)
{
list.Add(_skill);
}
return list;
}
}
public ProcessInfoSkill(BattleCardBase ownerCard, SkillBase skill, bool isPlayer, SkillProcessor skillProcessor, BattlePlayerReadOnlyInfoPair playerInfoPair, SkillConditionCheckerOption checkerOption)
: base(ownerCard, skillProcessor, playerInfoPair, checkerOption)
{
_skill = skill;
}
public override VfxBase CallStart()
{
SkillBase.CallParameter callParameter = new SkillBase.CallParameter();
callParameter.skillProcessor = _skillProcessor;
callParameter.calledSkillResultInfo = new SkillBase.SkillResultInfo();
return _skill.CallStart(_skillProcessor, _playerInfoPair, _checkerOption, callParameter);
}
public override List<SkillBase> GetActiveSkill()
{
return new List<SkillBase> { _skill };
}
}
public class StopProcessInfoResidentSkill : ProcessInfoSkill
{
public StopProcessInfoResidentSkill(BattleCardBase ownerCard, SkillBase skill, bool isPlayer, SkillProcessor skillProcessor, BattlePlayerReadOnlyInfoPair playerInfoPair, SkillConditionCheckerOption checkerOption)
: base(ownerCard, skill, isPlayer, skillProcessor, playerInfoPair, checkerOption)
{
}
public override VfxBase CallStart()
{
SkillBase.CallParameter callParameter = new SkillBase.CallParameter();
callParameter.skillProcessor = _skillProcessor;
callParameter.calledSkillResultInfo = new SkillBase.SkillResultInfo();
return _skill.CallStart(_skillProcessor, _playerInfoPair, _checkerOption, callParameter, ProcessCallType.ResidentStop);
}
}
protected List<SkillBase> _processSkillList = new List<SkillBase>();
private List<SkillBase> _inactiveSkillList = new List<SkillBase>();
public Func<VfxBase> OnSkillProcedureEnd;
private Queue<ProcessInfo> _collectionQueue = new Queue<ProcessInfo>();
private bool m_needOwnerDeadCheck;
public event Func<BattleCardBase, VfxBase> OnSkillStart;
public void Register(ProcessInfo info, bool ignoreOwnerDeadCheck = false)
{
if (info != null)
{
int needOwnerDeadCheck2;
if (!ignoreOwnerDeadCheck)
{
bool flag = (info.NeedOwnerDeadCheck = m_needOwnerDeadCheck);
needOwnerDeadCheck2 = (flag ? 1 : 0);
}
else
{
needOwnerDeadCheck2 = 0;
}
info.NeedOwnerDeadCheck = (byte)needOwnerDeadCheck2 != 0;
_collectionQueue.Enqueue(info);
}
}
public void InsertRegister(Queue<ProcessInfo> infos, bool ignoreOwnerDeadCheck = false)
{
if (infos.IsNotNullOrEmpty())
{
Queue<ProcessInfo> queue = new Queue<ProcessInfo>();
while (_collectionQueue.Any())
{
queue.Enqueue(_collectionQueue.Dequeue());
}
while (infos.Any())
{
_collectionQueue.Enqueue(infos.Dequeue());
}
while (queue.Any())
{
_collectionQueue.Enqueue(queue.Dequeue());
}
}
}
private Queue<ProcessInfo> ReplacementQueue(Queue<ProcessInfo> ownerQueue, Queue<ProcessInfo> pushQueue)
{
while (pushQueue.Count > 0)
{
ProcessInfo item = pushQueue.Dequeue();
ownerQueue.Enqueue(item);
}
return ownerQueue;
}
private InplayCardInfo[] CreateInplayCardInfo(IEnumerable<BattleCardBase> inplayCards)
{
int num = 0;
InplayCardInfo[] array = new InplayCardInfo[inplayCards.Count()];
foreach (BattleCardBase inplayCard in inplayCards)
{
array[num++] = new InplayCardInfo
{
_index = inplayCard.Index,
_isPlayer = inplayCard.IsPlayer
};
}
return array;
}
public void AddProcessSkilList(SkillBase skill)
{
_processSkillList.Add(skill);
}
public void ClearProcessSkillList()
{
_processSkillList.Clear();
}
public List<SkillBase> GetProcessSkillList()
{
return _processSkillList;
}
public void AddInactiveSkilList(List<SkillBase> skills)
{
_inactiveSkillList.AddRange(skills);
}
private void ClearInactiveSkillList()
{
_inactiveSkillList.Clear();
}
public List<SkillBase> GetDeckSkils()
{
List<SkillBase> list = new List<SkillBase>();
for (int i = 0; i < _collectionQueue.Count; i++)
{
list.AddRange(_collectionQueue.ElementAt(i).GetDeckSkills);
}
return list;
}
private void SortDeckSkillProcess(List<ProcessInfo> tmpList, BattlePlayerPair battlePlayerPair, bool isNotCheckUlist)
{
int i = 0;
for (int count = tmpList.Count; i < count; i++)
{
int num = 0;
ProcessInfo processInfo = null;
if (isNotCheckUlist)
{
num = battlePlayerPair.Self.BattleMgr.StableRandomOnlySelf(tmpList.Count());
processInfo = tmpList[num];
}
else
{
NetworkBattleReceiver.ReceiveData receivedData = (battlePlayerPair.Self.BattleMgr as NetworkBattleManagerBase).networkBattleData.GetReceiveData();
int k;
for (k = 0; k < receivedData.unapprovedList.Count; k++)
{
ProcessInfo processInfo2 = tmpList.FirstOrDefault((ProcessInfo t) => t.OwnerCard.Index == receivedData.unapprovedList[k].Index);
if (processInfo2 != null)
{
processInfo = processInfo2;
break;
}
}
}
if (processInfo != null)
{
tmpList.Remove(processInfo);
_collectionQueue.Enqueue(processInfo);
}
}
}
public VfxBase Process(BattlePlayerPair battlePlayerPair, bool isImmediate = false)
{
SequentialVfxPlayer sequentialVfxPlayer = SequentialVfxPlayer.Create();
InplayCardInfo[] clonedSelf = CreateInplayCardInfo(battlePlayerPair.Self.InPlayCards.Where((BattleCardBase s) => battlePlayerPair.Self.SummonedCards.Count == 0 || battlePlayerPair.Self.SummonedCards.Any((BattleCardBase a) => s != a)));
InplayCardInfo[] clonedOp = CreateInplayCardInfo(battlePlayerPair.Opponent.InPlayCards.Where((BattleCardBase s) => battlePlayerPair.Opponent.SummonedCards.Count == 0 || battlePlayerPair.Opponent.SummonedCards.Any((BattleCardBase a) => s != a)));
m_needOwnerDeadCheck = true;
bool isNotCheckUlist = !GameMgr.GetIns().IsUseUnapprovedList(battlePlayerPair.Self.IsPlayer);
if (_collectionQueue.Where((ProcessInfo p) => p.IsContainDeckSkill).ToList().Count() >= 2)
{
List<ProcessInfo> list = _collectionQueue.ToList();
List<ProcessInfo> list2 = new List<ProcessInfo>();
_collectionQueue.Clear();
int num = 0;
for (int count = list.Count; num < count; num++)
{
ProcessInfo processInfo = list[num];
if (processInfo.IsContainDeckSkill)
{
list2.Add(processInfo);
continue;
}
SortDeckSkillProcess(list2, battlePlayerPair, isNotCheckUlist);
_collectionQueue.Enqueue(processInfo);
}
SortDeckSkillProcess(list2, battlePlayerPair, isNotCheckUlist);
}
for (int num2 = 0; num2 < _inactiveSkillList.Count; num2++)
{
_inactiveSkillList[num2].CallOnInactiveSkill();
}
while (_collectionQueue.Count > 0)
{
ProcessInfo info = _collectionQueue.Dequeue();
VfxBase vfx = ProcessOneSkill(info, battlePlayerPair);
sequentialVfxPlayer.Register(vfx);
}
PlayVoiceOnCharacterDeath(clonedSelf, clonedOp, battlePlayerPair);
VfxBase allFuncVfxResults = OnSkillProcedureEnd.GetAllFuncVfxResults();
sequentialVfxPlayer.Register(allFuncVfxResults);
if (!isImmediate)
{
battlePlayerPair.Self.SkillsEndProcess();
battlePlayerPair.Opponent.SkillsEndProcess();
if (battlePlayerPair.Self.BattleView != null && !(battlePlayerPair.Self.BattleView is NullBattlePlayerView))
{
sequentialVfxPlayer.Register(battlePlayerPair.Self.BattleView.GetSideLogControl(isSkillTargetSelect: false).ClearLastShowLogCard());
BattleManagerBase.GetIns().OperateMgr.CallOnClearSideLog(battlePlayerPair.Self.IsPlayer);
}
ClearProcessSkillList();
ClearInactiveSkillList();
}
return sequentialVfxPlayer;
}
private VfxBase ProcessOneSkill(ProcessInfo info, BattlePlayerPair battlePlayerPair)
{
SequentialVfxPlayer sequentialVfxPlayer = SequentialVfxPlayer.Create();
bool flag = true;
if (info.NeedOwnerDeadCheck)
{
flag = !info.OwnerCard.IsDead;
}
if (flag)
{
BattleManagerBase.GetIns().OperateMgr.CallOnSkillProcessStart();
VfxBase vfxBase = info.CallStart();
if (vfxBase.IsVfxNonEmpty())
{
VfxBase vfxCollection = this.OnSkillStart.GetAllFuncVfxResults(info.OwnerCard);
InstantVfx vfx = InstantVfx.Create(delegate
{
ImmediateVfxMgr.GetInstance().Register(vfxCollection);
});
sequentialVfxPlayer.Register(vfx);
}
BattleManagerBase.GetIns().OperateMgr.CallOnSkillProcessEnd();
sequentialVfxPlayer.Register(vfxBase);
}
battlePlayerPair.Self.OnCallOneSkillProcess();
battlePlayerPair.Opponent.OnCallOneSkillProcess();
this.OnSkillStart = null;
return sequentialVfxPlayer;
}
private List<BattleCardBase> GetDestroyedCard(InplayCardInfo[] inplayInfo, List<BattleCardBase> cemeteryList)
{
List<BattleCardBase> list = new List<BattleCardBase>();
BattleCardBase battleCardBase = null;
int i = 0;
for (int num = inplayInfo.Length; i < num; i++)
{
battleCardBase = GetCardInCemetery(ref inplayInfo[i], cemeteryList);
if (battleCardBase != null)
{
list.Add(battleCardBase);
}
}
return list;
}
private BattleCardBase GetCardInCemetery(ref InplayCardInfo inplayInfo, List<BattleCardBase> cemeteryList)
{
int i = 0;
for (int count = cemeteryList.Count; i < count; i++)
{
if (cemeteryList[i].IsPlayer == inplayInfo._isPlayer && cemeteryList[i].Index == inplayInfo._index)
{
return cemeteryList[i];
}
}
return null;
}
private void PlayVoiceOnCharacterDeath(InplayCardInfo[] clonedSelf, InplayCardInfo[] clonedOp, BattlePlayerPair actualPair)
{
List<BattleCardBase> list = new List<BattleCardBase>();
list.AddRange(GetDestroyedCard(clonedSelf, actualPair.Self.CemeteryList));
list.AddRange(GetDestroyedCard(clonedOp, actualPair.Opponent.CemeteryList));
list.AddRange(GetDestroyedCard(clonedSelf, actualPair.Self.NecromanceZoneList));
list.AddRange(GetDestroyedCard(clonedOp, actualPair.Opponent.NecromanceZoneList));
if (!list.Any())
{
return;
}
BattleCardBase battleCardBase = SelectCardToHaveDestroyVoicePlay(list, BattleManagerBase.GetIns().IsRecovery);
if (battleCardBase != null)
{
if (!BattleManagerBase.GetIns().IsRecovery || !(battleCardBase.BattleCardView is NullBattleCardView))
{
battleCardBase.BattleCardView.playVoiceOnDeath = true;
battleCardBase.BattleCardView.VoiceInfo.SetDestroyCardId(-1);
}
battleCardBase.SelfBattlePlayer.CallOnPlayVoiceOnDeath(battleCardBase);
}
}
private BattleCardBase SelectCardToHaveDestroyVoicePlay(List<BattleCardBase> destroyedCards, bool isRecovery)
{
destroyedCards.FisherYatesShuffle();
for (int i = 0; i < destroyedCards.Count; i++)
{
BattleCardBase battleCardBase = destroyedCards[i];
if (!isRecovery)
{
_ = battleCardBase.BattleCardView.VoiceInfo;
}
else
{
CardVoiceInfoCache.GetCardVoiceInfoForBattle(battleCardBase.CardId);
}
if (!string.IsNullOrEmpty(battleCardBase.BattleCardView.VoiceInfo.GetDestroyVoice(battleCardBase.IsEvolution, battleCardBase.IsExecutedEarthRite).Voice) || (isRecovery && !string.IsNullOrEmpty(CardVoiceInfoCache.GetCardVoiceInfoForBattle(battleCardBase.CardId).GetDestroyVoice(battleCardBase.IsEvolution, battleCardBase.IsExecutedEarthRite).Voice)))
{
return battleCardBase;
}
}
return null;
}
}