Files
SVSimServer/SVSim.BattleEngine/Engine/Wizard/AISkillSimulationUtility.cs
gamer147 957af3d1ec 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.
2026-06-05 17:22:20 -04:00

496 lines
18 KiB
C#

using System.Collections.Generic;
namespace Wizard;
public static class AISkillSimulationUtility
{
public static void GiveSkillToAll(List<AIVirtualCard> targets, AIVirtualField field, AIScriptTokenArgType skillType)
{
for (int i = 0; i < targets.Count; i++)
{
GiveSkill(targets[i], field, skillType);
}
}
private static void GiveSkillToTarget(AISituationInfo situation, List<AIVirtualCard> candidates, AIVirtualField field, AIScriptTokenArgType skillType, AIScriptTokenArgType whichTarget)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
AIConsoleUtility.LogError("GiveSkillToTarget error!! No target!!!!!");
return;
}
List<AIVirtualCard> targets = situationTarget.Targets;
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (candidates.Contains(aIVirtualCard))
{
GiveSkill(aIVirtualCard, field, skillType);
}
}
}
public static void GiveSkillRandom(List<AIVirtualCard> candidates, int selectCount, AIVirtualField field, AIScriptTokenArgType skillType)
{
if (selectCount > 1)
{
AIConsoleUtility.LogError("GiveSkillRandom(): 複数選択のキーワード能力付与は未実装です");
return;
}
AIVirtualCard aIVirtualCard = AIBasicTargetSelectUtility.SelectSingleBasicSkillTarget(candidates, skillType, AISelectTargetPattern.Worst);
if (aIVirtualCard != null)
{
GiveSkill(aIVirtualCard, field, skillType);
}
}
public static void ExecuteTargetSelectGiveSkill(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AIScriptTokenArgType skillType, AIScriptTokenArgType selectType, int selectCount = 1)
{
if (situation == null)
{
AIConsoleUtility.LogError("ExecuteTargetSelectGiveSkill() Error!! situation is null!!!!!");
}
else if (situation.IsTargetExists(selectType))
{
GiveSkillToTarget(situation, candidates, field, skillType, selectType);
}
else
{
GiveSkillToTargetPrediction(candidates, selectCount, field, situation, skillType, selectType);
}
}
private static void GiveSkillToTargetPrediction(List<AIVirtualCard> candidates, int selectCount, AIVirtualField field, AISituationInfo situation, AIScriptTokenArgType skillType, AIScriptTokenArgType whichTarget)
{
if (selectCount > 1)
{
AIConsoleUtility.LogError("GiveSkillToTargetPrediction(): 複数選択のキーワード能力付与は未実装です");
return;
}
AIVirtualCard aIVirtualCard = AIBasicTargetSelectUtility.SelectSingleBasicSkillTarget(candidates, skillType, AISelectTargetPattern.Best);
if (aIVirtualCard != null)
{
situation.SetSingleTargetInInfo(aIVirtualCard, TargetSelectType.Default, whichTarget);
GiveSkill(aIVirtualCard, field, skillType);
}
}
public static void GiveSkill(AIVirtualCard target, AIVirtualField field, AIScriptTokenArgType skill)
{
switch (skill)
{
case AIScriptTokenArgType.KILLER:
target.IsKiller = true;
break;
case AIScriptTokenArgType.MEDUSA:
target.IsDestroyWhenAttack = true;
break;
case AIScriptTokenArgType.DRAIN:
target.IsDrain = true;
break;
case AIScriptTokenArgType.GUARD:
target.IsGuard = true;
break;
case AIScriptTokenArgType.QUICK:
AttachQuick(target, field);
break;
case AIScriptTokenArgType.RUSH:
AttachRush(target, field);
break;
case AIScriptTokenArgType.SNEAK:
target.IsSneak = true;
break;
case AIScriptTokenArgType.UNTOUCHABLE:
target.AddUntouchableCount();
break;
case AIScriptTokenArgType.FORCE_TARGETING:
target.IsForceTargeting = true;
break;
case AIScriptTokenArgType.UNBANISHABLE:
target.IsUnbanishable = true;
break;
case AIScriptTokenArgType.IGNORE_GUARD:
target.IsIgnoreGuard = true;
break;
default:
AIConsoleUtility.LogError("ivnalid skill : tag_ClashSkill");
break;
}
}
public static void RemoveKeywordSkillToAll(List<AIVirtualCard> targets, AIScriptTokenArgType skillType)
{
for (int i = 0; i < targets.Count; i++)
{
RemoveKeywordSkill(targets[i], skillType);
}
}
public static void RemoveKeywordSkill(AIVirtualCard target, AIScriptTokenArgType skill)
{
switch (skill)
{
case AIScriptTokenArgType.GUARD:
target.IsGuard = false;
break;
case AIScriptTokenArgType.UNTOUCHABLE:
target.SubUntouchableCount();
break;
default:
AIConsoleUtility.LogError($"AISkillSimulationUtility.RemoveKeywordSkill(): Invalid skill type. type:{skill}");
break;
}
}
public static bool HasSkill(AIVirtualCard target, AIScriptTokenArgType skill, EnemyAI ai, List<int> playPtn, bool isNot = false)
{
if (!target.IsInHand)
{
return target.IsHoldKeywordSkill(skill);
}
int num = ai.CurrentVirtualField.AllyHandCards.FindIndex((AIVirtualCard c) => c.IsSameCard(target));
if (num < 0)
{
return false;
}
if (target.TagCollectionContainer.HasTag(AIPlayTagType.GiveSkill) && target.TagCollectionContainer.GiveSkillTags.ExecuteSkill(target, playPtn, skill))
{
return true;
}
AIHandPlayEstimator handPlayEstimator = ai.CurrentVirtualField.AllyHandCards[num].GetHandPlayEstimator();
if (handPlayEstimator == null || handPlayEstimator.InplayEstimations == null || handPlayEstimator.InplayEstimations.Count <= 0)
{
return false;
}
for (int num2 = 0; num2 < handPlayEstimator.InplayEstimations.Count; num2++)
{
if (HasSkill(handPlayEstimator.InplayEstimations[num2], skill, ai, EnemyAI.EmptyPlayPtn, isNot))
{
return true;
}
}
return false;
}
public static bool IsFollowerOnlySkillType(AIScriptTokenArgType skillType)
{
if (skillType != AIScriptTokenArgType.QUICK && skillType != AIScriptTokenArgType.RUSH && skillType != AIScriptTokenArgType.GUARD && skillType != AIScriptTokenArgType.DRAIN && skillType != AIScriptTokenArgType.KILLER && skillType != AIScriptTokenArgType.SNEAK)
{
return skillType == AIScriptTokenArgType.IGNORE_GUARD;
}
return true;
}
public static void HealAll(List<AIVirtualCard> targets, AIVirtualField field, int heal, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> list = new List<AIVirtualCard>();
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (aIVirtualCard.IsOnField && !aIVirtualCard.IsAmulet && !aIVirtualCard.IsCountdownAmulet && !aIVirtualCard.IsIndependent)
{
int healLife = AIHealSimulationUtility.CalcHealModifier(aIVirtualCard, playPtn, situation, heal);
aIVirtualCard.Heal(healLife);
list.Add(aIVirtualCard);
}
}
if (list.Count > 0)
{
HealActivation(list, field, playPtn, situation);
}
}
public static void HealSingle(AIVirtualCard target, AIVirtualField field, int heal, List<int> playPtn, AISituationInfo situation)
{
if (target.IsOnField && !target.IsAmulet && !target.IsCountdownAmulet && !target.IsIndependent)
{
int healLife = AIHealSimulationUtility.CalcHealModifier(target, playPtn, situation, heal);
target.Heal(healLife);
HealActivation(new List<AIVirtualCard> { target }, field, playPtn, situation);
}
}
public static void HealTarget(AISituationInfo situation, AIVirtualField field, AIScriptTokenArgType whichTarget, int heal)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget != null && situationTarget.HasTarget)
{
List<AIVirtualCard> targets = situationTarget.Targets;
List<int> emptyPlayPtn = EnemyAI.EmptyPlayPtn;
HealAll(targets, field, heal, emptyPlayPtn, situation);
}
}
public static void HealTargetPrediction(AISituationInfo situation, List<AIVirtualCard> candidates, AIVirtualCard healOwner, AIVirtualField field, List<int> playPtn, AIScriptTokenArgType whichTarget, int heal)
{
AIVirtualCard target = AIHealSimulationUtility.SelectBestTarget(AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(candidates, healOwner, playPtn), heal);
situation.SetSingleTargetInInfo(target, TargetSelectType.Default, whichTarget);
HealTarget(situation, field, whichTarget, heal);
}
private static void HealActivation(List<AIVirtualCard> healedTargets, AIVirtualField field, List<int> playptn, AISituationInfo situation)
{
List<AIVirtualCard> tagHolders = field.CardListSet.GetTagHolders(CardListsForReference.TagHolderReferenceType.WhenHeal);
if (tagHolders == null || tagHolders.Count <= 0)
{
return;
}
for (int i = 0; i < healedTargets.Count; i++)
{
AIVirtualCard healedCard = healedTargets[i];
for (int j = 0; j < tagHolders.Count; j++)
{
AIVirtualCard aIVirtualCard = tagHolders[j];
if (!aIVirtualCard.IsDead && aIVirtualCard.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenHeal))
{
aIVirtualCard.TagCollectionContainer.HealTags.RegisterPassedConditionTags(aIVirtualCard, healedCard, playptn, situation);
}
}
}
field.AllActivateCountHolderIncrement(situation, AIPlayTagType.HealActivateCount, healedTargets);
}
public static void DestroyAll(List<AIVirtualCard> targets, AIVirtualField field, AISituationInfo situation)
{
for (int i = 0; i < targets.Count; i++)
{
if (!targets[i].IsDead && !targets[i].IsIndependent)
{
targets[i].RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: true);
}
}
}
public static void DestroyOldest(List<AIVirtualCard> targets, AIVirtualField field, AISituationInfo situation, int selectCount = 1)
{
List<AIVirtualCard> targets2 = ((targets.Count > selectCount) ? targets.GetRange(0, selectCount) : targets);
DestroyAll(targets2, field, situation);
}
public static void DestroyRandom(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, int selectCount = 1)
{
if (selectCount <= 1)
{
AIVirtualCard aIVirtualCard = AISimulationRemovalUtility.SelectRemovalTarget(targets, tagOwner, field, playPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Destroy);
if (aIVirtualCard != null && !aIVirtualCard.IsDead && !aIVirtualCard.IsIndependent)
{
aIVirtualCard.RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: true);
}
}
else
{
DestroyAll(AISimulationRemovalUtility.SelectMultipleRemovalTargets(targets, tagOwner, field, playPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Destroy, selectCount), field, situation);
}
}
public static void DestroyTarget(AISituationInfo situation, List<AIVirtualCard> candidates, AIScriptTokenArgType whichTarget)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
AIConsoleUtility.LogError("DestroyTarget error!! No target!!!!!");
return;
}
List<AIVirtualCard> targets = situationTarget.Targets;
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (candidates.Contains(aIVirtualCard) && !aIVirtualCard.IsIndependent)
{
aIVirtualCard.RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: true);
}
}
}
public static void ExecuteTargetSelectDiscard(List<AIVirtualCard> candidates, int discardCount, AIScriptTokenArgType selectType, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (tagOwner.IsAlly)
{
if (situation == null)
{
AIConsoleUtility.LogError("ExecuteTargetSelectDiscard() Error!! situation is null!!!!!");
}
else if (situation.IsTargetExists(selectType))
{
DiscardTarget(tagOwner, selectType, field, situation);
}
else
{
DiscardTargetPrediction(candidates, discardCount, tagOwner, field, playPtn, situation);
}
}
}
private static void DiscardTarget(AIVirtualCard ownerCard, AIScriptTokenArgType selectType, AIVirtualField field, AISituationInfo situation)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(selectType);
if (situationTarget != null && situationTarget.HasTarget)
{
ExecuteDiscard(ownerCard, situationTarget.Targets, field, situation);
}
}
private static void DiscardTargetPrediction(List<AIVirtualCard> candidates, int discardCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> list = AIDiscardUtility.SelectBestDiscardTarget(tagOwner, field, candidates, discardCount, tagOwner.SelfField.BestPlayPtn, situation);
if (list != null && list.Count > 0)
{
ExecuteDiscard(tagOwner, list, field, situation);
}
}
public static void DiscardRandom(AIVirtualCard ownerCard, AIVirtualField field, List<AIVirtualCard> discardCandidates, int discardCount, AISituationInfo situation)
{
if (ownerCard.IsAlly)
{
List<AIVirtualCard> discardTargets = AIDiscardUtility.SelectWorstDiscardTarget(ownerCard, field, discardCandidates, discardCount, field.BestPlayPtn, situation);
ExecuteDiscard(ownerCard, discardTargets, field, situation);
}
}
public static void DiscardAll(AIVirtualCard ownerCard, List<AIVirtualCard> discardCandidates, AIVirtualField field, AISituationInfo situation)
{
if (ownerCard.IsAlly)
{
ExecuteDiscard(ownerCard, discardCandidates, field, situation);
}
}
public static void ExecuteDiscard(AIVirtualCard ownerCard, List<AIVirtualCard> discardTargets, AIVirtualField field, AISituationInfo situation)
{
if (discardTargets == null || discardTargets.Count <= 0 || field.AllyHandCards.Count <= 0)
{
return;
}
for (int i = 0; i < discardTargets.Count; i++)
{
AIVirtualCard hand = discardTargets[i];
field.RemoveAllyHandCard(hand);
}
AIDiscardInfo discardInfo = new AIDiscardInfo(ownerCard, isSuccess: true, discardTargets);
situation.SetDiscardInfo(discardInfo);
for (int j = 0; j < discardTargets.Count; j++)
{
AIVirtualCard aIVirtualCard = discardTargets[j];
field.SimulationExtraBonus += AIDiscardUtility.EvaluateDiscardedBonus(aIVirtualCard, field.BestPlayPtn, situation, field, isIgnoreInBattle: true, isCalcCostDiff: false, isCalcTokenValue: false);
if (aIVirtualCard.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenDiscarded))
{
aIVirtualCard.TagCollectionContainer.DiscardedTags.RegisterPassedConditionTags(aIVirtualCard, field.BestPlayPtn, situation);
}
}
if (field.CardListSet.HasAfterDiscardTagHolder)
{
for (int k = 0; k < field.CardListSet.AfterDiscardTagHolders.Count; k++)
{
field.CardListSet.AfterDiscardTagHolders[k].TagCollectionContainer.AfterDiscardTags.RegisterPassedConditionTags(ownerCard, field.BestPlayPtn, situation);
}
}
}
private static void AttachRush(AIVirtualCard card, AIVirtualField field)
{
if (!card.IsRush && !card.IsQuick)
{
card.IsRush = true;
card.IsSummonDrunkenness = false;
}
}
private static void AttachQuick(AIVirtualCard card, AIVirtualField field)
{
if (!card.IsQuick)
{
card.IsQuick = true;
card.IsSummonDrunkenness = false;
}
}
public static void SetStatusAll(List<AIVirtualCard> targets, int attack, int life, AISituationInfo situation)
{
if (attack < 0 || life < 0)
{
return;
}
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (aIVirtualCard.IsUnit)
{
aIVirtualCard.SetNewStatus(situation, attack, life);
}
}
}
public static void SetStatusTarget(List<AIVirtualCard> candidates, AIScriptTokenArgType whichTarget, int attack, int life, AISituationInfo situation)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
AIConsoleUtility.LogError("SetStatusTarget error!! No target!!!!!");
return;
}
List<AIVirtualCard> targets = situationTarget.Targets;
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (candidates.Contains(aIVirtualCard))
{
SetStatusSingle(aIVirtualCard, attack, life, situation);
}
}
}
public static void SetStatusSingle(AIVirtualCard target, int attack, int life, AISituationInfo situation)
{
if (attack >= 0 && life >= 0 && target.IsUnit)
{
target.SetNewStatus(situation, attack, life);
}
}
public static void ModifierNotConsumeEpALL(List<AIVirtualCard> targets)
{
if (targets == null || targets.Count <= 0)
{
AIConsoleUtility.LogError("ModifierNotConsumeEpALL() : Target List is Missing Error !!");
return;
}
for (int i = 0; i < targets.Count; i++)
{
ModifierNotConsumeEpSingle(targets[i]);
}
}
public static void ModifierNotConsumeEpTargets(List<AIVirtualCard> candidate, AIScriptTokenArgType selectType, AISituationInfo situation)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(selectType);
if (situationTarget == null || !situationTarget.HasTarget)
{
AIConsoleUtility.LogError("ModifierNotConsumeEpTargets() : Selected Target is Missing Error !!");
return;
}
List<AIVirtualCard> targets = situationTarget.Targets;
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (candidate.Contains(aIVirtualCard))
{
ModifierNotConsumeEpSingle(aIVirtualCard);
}
}
}
public static void ModifierNotConsumeEpSingle(AIVirtualCard card)
{
if (card == null)
{
AIConsoleUtility.LogError("ModifierNotConsumeEpSingle() : Target card is Missing Error !!");
}
else if (card.IsUnit && !card.IsDead)
{
card.IsNotConsumeEp = true;
}
}
}