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

296 lines
11 KiB
C#

using System.Collections.Generic;
using System.Linq;
using Cute;
using Wizard.Battle.Card;
using Wizard.Battle.View.Vfx;
namespace Wizard;
public class AIOperationProcessor
{
private BattleManagerBase _battleMgr;
private EnemyAI _ai;
public AIOperationProcessor(BattleManagerBase mgr, EnemyAI ai)
{
_battleMgr = mgr;
_ai = ai;
}
public VfxBase AIPlayCard(AISituationInfo situation)
{
_ai.BestPlayPtnRecord = null;
SequentialVfxPlayer sequentialVfxPlayer = SequentialVfxPlayer.Create();
VfxBase emote = _ai.GetEmote(AIEmoteCmdType.ON_CARD_PLAY_ALLY, situation);
sequentialVfxPlayer.Register(emote);
AIRealBattleCardSearcher.SearchBattleCardFromSituation(_ai.PlayerPair, situation, out var actor, out var targetList);
AISelectedTargetInfoSet selectedTargets = situation.SelectedTargets;
if (targetList.IsNotNullOrEmpty() && !selectedTargets.HasChoiceTarget)
{
SequentialVfxPlayer sequentialVfxPlayer2 = SequentialVfxPlayer.Create();
for (int i = 0; i < targetList.Count; i++)
{
BattleCardBase battleCardBase = targetList[i];
if (!battleCardBase.IsClass && !battleCardBase.BattleCardView.IsLoadResorces)
{
sequentialVfxPlayer2.Register(WaitVfx.Create(0.07f));
sequentialVfxPlayer2.Register(battleCardBase.LoadResource());
sequentialVfxPlayer2.Register(WaitVfx.Create(0.2f));
}
}
sequentialVfxPlayer.Register(sequentialVfxPlayer2);
}
BattleCardBase battleCardBase2 = actor;
int num = 0;
if (actor.HasSkillAccelerate || actor.HasSkillCrystallize)
{
int num2 = CalcFixedUseCostTransformId(actor, actor.SelfBattlePlayer.Pp);
if (num2 > 0)
{
battleCardBase2 = BattleManagerBase.GetIns().CreateTransformCardRegisterVfx(actor, num2, actor.IsPlayer);
}
}
else if (actor.Skills.CheckWhenPlayChoice && actor.Skills.Count() > 1)
{
SkillBase skillBase = actor.Skills.Get(0);
SkillBase skillBase2 = actor.Skills.Get(1);
if (skillBase.IsChoiceType && skillBase2 is Skill_transform)
{
battleCardBase2 = targetList[0];
num = 1;
}
}
BattlePlayerPair battlePlayerPair = _ai.PlayerPair.VirtualClone(CloneActualFlags.All);
battlePlayerPair.Self.AddCurrentTrunPlayCount(1);
BattleCardBase battleCardBase3 = battlePlayerPair.Self.HandCardList.Where((BattleCardBase c) => c.Index == actor.Index && c.CardId == actor.CardId && c.IsPlayer == actor.IsPlayer).FirstOrDefault();
if (battleCardBase3 != null)
{
battlePlayerPair.Self.HandCardList.Remove(battleCardBase3);
}
List<SkillBase> checkSkillList = GetCheckSkillList(battleCardBase2.Skills, battlePlayerPair);
if (CheckSelectTypeSkillTargetCount(actor, checkSkillList, targetList, num, "[PlayCard]") || targetList != null)
{
CheckSelectTypeSkillTarget(actor, battlePlayerPair, checkSkillList, targetList, num, "[PlayCard]");
}
if (!targetList.IsNotNullOrEmpty() || !targetList.Any((BattleCardBase c) => c is IVirtualBattleCard) || !actor.Skills.HaveChoiceTransformSkill())
{
sequentialVfxPlayer.Register(_battleMgr.OperateMgr.InitSetCard(actor, actor.IsPlayer, targetList.IsNotNullOrEmpty()));
}
sequentialVfxPlayer.Register(_battleMgr.OperateMgr.PlayCard(actor, actor.IsPlayer, targetList));
return sequentialVfxPlayer;
}
public VfxBase AIEvolutionCard(AISituationInfo situation)
{
AIRealBattleCardSearcher.SearchBattleCardFromSituation(_ai.PlayerPair, situation, out var actor, out var targetList);
if (!actor.CanEvolution(isSkill: false, isSelfBattlePlayer: true))
{
AIConsoleUtility.LogError("Evolution Condition Error!!!");
}
if (actor.EvolutionSkills.HasEvolutionSkillWithSelection)
{
List<SkillBase> checkSkillList = GetCheckSkillList(actor.EvolutionSkills, _ai.PlayerPair);
CheckSelectTypeSkillTarget(actor, _ai.PlayerPair, checkSkillList, targetList, 0, "[Evolution]");
}
SequentialVfxPlayer sequentialVfxPlayer = SequentialVfxPlayer.Create();
VfxBase emote = _ai.GetEmote(AIEmoteCmdType.ON_ALLY_EVOLUTION, situation);
sequentialVfxPlayer.Register(emote);
if (emote != NullVfx.GetInstance())
{
_ai.EmoteQuery.OnCardPlayEmotion();
}
sequentialVfxPlayer.Register(_battleMgr.OperateMgr.EvolutionCard(actor, actor.IsPlayer, targetList));
return sequentialVfxPlayer;
}
public VfxBase AIFusionCard(AISituationInfo situation)
{
AIRealBattleCardSearcher.SearchBattleCardFromSituation(_ai.PlayerPair, situation, out var actor, out var targetList);
SkillBase item = actor.Skills.FirstOrDefault((SkillBase s) => s is Skill_fusion);
CheckSelectTypeSkillTarget(actor, _ai.PlayerPair, new List<SkillBase> { item }, targetList, 0, "[Fusion]");
return _battleMgr.OperateMgr.FusionCard(actor, actor.IsPlayer, targetList);
}
private List<SkillBase> GetCheckSkillList(SkillCollectionBase skillCollection, BattlePlayerPair playerPair)
{
List<SkillBase> list = new List<SkillBase>();
IEnumerable<SkillBase> selectTypeSkill = skillCollection.GetSelectTypeSkill(isEvolve: true, isFusion: false, isActivateFanfare: false, playerPair);
SkillConditionCheckerOption option = new SkillConditionCheckerOption();
foreach (SkillBase item in skillCollection.Where((SkillBase s) => s.IsChoiceType && s.CheckCondition(playerPair, option, isPrePlay: true)))
{
if (!list.Contains(item))
{
list.Add(item);
}
}
foreach (SkillBase item2 in selectTypeSkill)
{
if (!list.Contains(item2))
{
list.Add(item2);
}
}
return list;
}
private void CheckSelectTypeSkillTarget(BattleCardBase actor, BattlePlayerPair playerPair, IEnumerable<SkillBase> skills, List<BattleCardBase> targetList, int selectTargetNumber, string checkTimingName)
{
int num = selectTargetNumber;
bool flag = false;
foreach (SkillBase skill in skills)
{
if (skill.IsBurialRite)
{
BattleCardBase card = targetList[num];
if (!actor.SelfBattlePlayer.HandCardList.Any((BattleCardBase c) => c.Index == card.Index && c.IsPlayer == card.IsPlayer))
{
string message = actor.BaseParameter.CardName + checkTimingName + "BURIAL_RITE Target not in Hand list Error!!!";
ThrowErrorMessage(message);
}
else if (!card.IsInHand || !card.IsUnit)
{
string message2 = actor.BaseParameter.CardName + checkTimingName + "BURIAL_RITE Wrong targeted selection criteria Error!!!";
ThrowErrorMessage(message2);
}
flag = true;
num++;
}
if (skill.ApplySelectFilter is SkillRandomSelectFilter || skill.ApplySelectFilter is SkillSelectAllFilter || (!skill.IsChoiceType && skill.ApplySelectFilter is SkillSelectNullFilter))
{
continue;
}
IEnumerable<BattleCardBase> selectableCards = skill.GetSelectableCards(playerPair, new SkillConditionCheckerOption());
int skillSelectCount = skill.GetSkillSelectCount();
int num2 = targetList.Count - num;
skillSelectCount = ((skillSelectCount > num2) ? num2 : skillSelectCount);
List<BattleCardBase> list = new List<BattleCardBase>(targetList.GetRange(num, skillSelectCount));
num += skillSelectCount;
if (list.Count > 1)
{
for (int num3 = 0; num3 < list.Count; num3++)
{
BattleCardBase card2 = list[num3];
List<BattleCardBase> list2 = list.Where((BattleCardBase c) => c.Index == card2.Index && c.IsPlayer == card2.IsPlayer).ToList();
if (list2.Count > 1)
{
string message3 = $"{actor.BaseParameter.CardName}{checkTimingName}Duplicate {list2.Count} selected card Error!!!";
ThrowErrorMessage(message3);
}
}
}
int num4 = 0;
for (int num5 = 0; num5 < list.Count; num5++)
{
BattleCardBase card3 = list[num5];
if (!selectableCards.Any((BattleCardBase c) => c.Index == card3.Index && c.IsPlayer == card3.IsPlayer))
{
if (num4 < selectableCards.Count() && !flag)
{
targetList[num5] = selectableCards.ElementAt(num4);
num4++;
}
string message4 = actor.BaseParameter.CardName + checkTimingName + "Target not in selection list Error!!!";
ThrowErrorMessage(message4);
}
}
}
}
private bool CheckSelectTypeSkillTargetCount(BattleCardBase actor, IEnumerable<SkillBase> skills, List<BattleCardBase> targetList, int selectCardCount, string checkTimingName)
{
string text = checkTimingName + actor.BaseParameter.CardName + "\n";
int num = selectCardCount;
foreach (SkillBase skill in skills)
{
if (skill.IsBurialRite)
{
selectCardCount++;
num++;
text += "BurialRite1回";
if (skill is Skill_none)
{
continue;
}
}
if (!(skill.ApplySelectFilter is SkillRandomSelectFilter) && !(skill.ApplySelectFilter is SkillSelectAllFilter) && (!skill.IsBurialRite || skill.ApplySelectFilter is SkillUserSelectFilter) && (skill.IsChoiceType || !(skill.ApplySelectFilter is SkillSelectNullFilter)))
{
BattlePlayerReadOnlyInfoPair playerInfoPair = new BattlePlayerReadOnlyInfoPair(actor.SelfBattlePlayer, actor.OpponentBattlePlayer);
SkillConditionCheckerOption option = new SkillConditionCheckerOption();
if (skill.CheckCondition(playerInfoPair, option, isPrePlay: true))
{
int skillSelectCount = skill.GetSkillSelectCount();
selectCardCount += skillSelectCount;
num += ((!actor.IsUnit && !actor.IsField) ? 1 : 0);
text += $"{skill}{skillSelectCount}回";
}
}
}
if (selectCardCount <= 0)
{
return false;
}
bool flag = false;
if (targetList == null || targetList.Count <= 0)
{
if (num <= 0)
{
return false;
}
text += "\n選択されていません";
flag = true;
}
else
{
int count = targetList.Count;
int num2 = count - selectCardCount;
if (num2 < 0 && count < num)
{
text += "\n少なく選択されています";
flag = true;
}
if (num2 > 0)
{
text += $"\n{num2}回多く選択されています";
flag = true;
}
}
if (flag)
{
ThrowErrorMessage(text);
}
return flag;
}
public int CalcFixedUseCostTransformId(BattleCardBase actor, int currentPp)
{
int num = -1;
int cost = actor.Cost;
int result = -1;
for (int i = 0; i < actor.Skills.Count(); i++)
{
if (!(actor.Skills.ElementAt(i) is Skill_pp_fixeduse skill_pp_fixeduse) || currentPp < skill_pp_fixeduse._fixedUsePP)
{
continue;
}
bool num2 = skill_pp_fixeduse.CheckCondition(_ai.PlayerPair, new SkillConditionCheckerOption(), isPrePlay: true);
bool flag = num2 && num < skill_pp_fixeduse._fixedUsePP;
bool flag2 = num2 && skill_pp_fixeduse._fixedUsePP < cost && currentPp < cost;
if (flag || flag2)
{
if (actor.Skills.ElementAt(i + 1) is Skill_transform skill_transform)
{
result = skill_transform.TransformId;
}
num = skill_pp_fixeduse._fixedUsePP;
}
}
return result;
}
private void ThrowErrorMessage(string message)
{
AIConsoleUtility.LogError(message);
}
}