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:
32
SVSim.BattleEngine/Engine/Wizard/AIAccelerate.cs
Normal file
32
SVSim.BattleEngine/Engine/Wizard/AIAccelerate.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAccelerate : AIScriptArgumentExpressions
|
||||
{
|
||||
public AIAccelerate(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
public void RegisterSelfToOwner(AIVirtualCard owner, AIVirtualField field, AIConditionExpressions cond)
|
||||
{
|
||||
int num = 0;
|
||||
while (num < _exprList.Count)
|
||||
{
|
||||
AIAccelerateInformation aIAccelerateInformation = new AIAccelerateInformation();
|
||||
aIAccelerateInformation.Cost = (int)EvalArg(num, owner, EnemyAI.EmptyPlayPtn, field, null);
|
||||
num++;
|
||||
if (num < _exprList.Count)
|
||||
{
|
||||
aIAccelerateInformation.CardId = EvalID(num);
|
||||
if (!cond.IsEmpty)
|
||||
{
|
||||
aIAccelerateInformation.SetCondition(cond);
|
||||
}
|
||||
owner.AccelerateCostList = AIParamQuery.AddElementToList(aIAccelerateInformation, owner.AccelerateCostList);
|
||||
num++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
47
SVSim.BattleEngine/Engine/Wizard/AIAfterAttackBanish.cs
Normal file
47
SVSim.BattleEngine/Engine/Wizard/AIAfterAttackBanish.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAfterAttackBanish : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private const int SELECT_TYPE_ARG_INDEX = 1;
|
||||
|
||||
public AIScriptTokenArgType SelectType { get; private set; }
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 1;
|
||||
|
||||
public AIAfterAttackBanish(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
if (AIPlayTagInitializingUtility.TryCreateSelectType(_exprList[_exprList.Count - 1], base.LegalSelectTypes, out var selectType))
|
||||
{
|
||||
SelectType = selectType;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectType = AIScriptTokenArgType.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIBanishSimulationUtility.BanishAll(targets, situation);
|
||||
}
|
||||
else
|
||||
{
|
||||
AIConsoleUtility.LogError($"AIAfterAttackBanish.Execute(): Unsupported selecttype. type:{SelectType}");
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
}
|
||||
32
SVSim.BattleEngine/Engine/Wizard/AIAfterAttackDraw.cs
Normal file
32
SVSim.BattleEngine/Engine/Wizard/AIAfterAttackDraw.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAfterAttackDraw : AIFiltersArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _drawCountArg;
|
||||
|
||||
private const int DRAW_COUNT_ARG_OFFSET = 1;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 1;
|
||||
|
||||
public AIAfterAttackDraw(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_drawCountArg = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
if (situation != null && situation.Actor != null && AIFilteringUtility.CheckMatchTargetFiltering(situation.Actor, null, base.Filters, playPtn, tagOwner, situation))
|
||||
{
|
||||
int drawCount = (int)_drawCountArg.EvalArg(tagOwner, playPtn, field, situation);
|
||||
field.DrawCard(tagOwner.IsAlly, drawCount, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
SVSim.BattleEngine/Engine/Wizard/AIAfterAttackEvo.cs
Normal file
53
SVSim.BattleEngine/Engine/Wizard/AIAfterAttackEvo.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAfterAttackEvo : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private const int SELECT_TYPE_ARG_INDEX = 1;
|
||||
|
||||
public AIScriptTokenArgType SelectType { get; private set; }
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 1;
|
||||
|
||||
public AIAfterAttackEvo(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
if (IsLegalSelectType(_exprList[_exprList.Count - 1], out var selectType))
|
||||
{
|
||||
SelectType = selectType;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogSelectTypeError(selectType);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
AIAutoEvolutionSimulationUtility.AutoEvolution(field, targets, playPtn, situation, SelectType);
|
||||
}
|
||||
}
|
||||
|
||||
private void LogSelectTypeError(AIScriptTokenArgType selectType)
|
||||
{
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForFollowerOnly(candidates, tagOwner, base.TargetFilters, playPtn, situation, isBlockDead);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.AllyInplayCards;
|
||||
}
|
||||
}
|
||||
38
SVSim.BattleEngine/Engine/Wizard/AIAfterAttackHeal.cs
Normal file
38
SVSim.BattleEngine/Engine/Wizard/AIAfterAttackHeal.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAfterAttackHeal : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private const int HEAL_AMOUNT_ARG_INDEX = 1;
|
||||
|
||||
public AIPolishConvertedExpression HealAmount { get; private set; }
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 1;
|
||||
|
||||
public AIAfterAttackHeal(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
HealAmount = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
int heal = (int)HealAmount.EvalArg(tagOwner, null, field, situation);
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
AISkillSimulationUtility.HealAll(targets, field, heal, field.BestPlayPtn, situation);
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.TargetFilters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
}
|
||||
46
SVSim.BattleEngine/Engine/Wizard/AIAfterClashDamage.cs
Normal file
46
SVSim.BattleEngine/Engine/Wizard/AIAfterClashDamage.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAfterClashDamage : AIFiltersAndSelectTypeArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _damage;
|
||||
|
||||
private readonly int DAMAGE_AMOUNT_ARG_OFFSET = 1;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public AIAfterClashDamage(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_damage = _exprList[_exprList.Count - DAMAGE_AMOUNT_ARG_OFFSET];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
int damage = (int)_damage.EvalArg(tagOwner, playPtn, field, situation);
|
||||
switch (base.SelectType)
|
||||
{
|
||||
case AIScriptTokenArgType.ALL_SELECT:
|
||||
AIDamageSimulationUtility.DamageAll(targetsFromField, tagOwner, field, damage, situation);
|
||||
break;
|
||||
case AIScriptTokenArgType.RANDOM_SELECT:
|
||||
AIDamageSimulationUtility.DamageRandom(targetsFromField, tagOwner, field, damage, situation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
}
|
||||
41
SVSim.BattleEngine/Engine/Wizard/AIAfterClashHeal.cs
Normal file
41
SVSim.BattleEngine/Engine/Wizard/AIAfterClashHeal.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAfterClashHeal : AIFiltersAndSelectTypeArgument
|
||||
{
|
||||
private readonly int HEAL_AMOUNT_ARG_OFFSET = 1;
|
||||
|
||||
public AIPolishConvertedExpression HealAmount { get; private set; }
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public AIAfterClashHeal(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
HealAmount = _exprList[_exprList.Count - HEAL_AMOUNT_ARG_OFFSET];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
int heal = (int)HealAmount.EvalArg(tagOwner, playPtn, field, situation);
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AISkillSimulationUtility.HealAll(targetsFromField, field, heal, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
}
|
||||
37
SVSim.BattleEngine/Engine/Wizard/AIAllyDiscardBonus.cs
Normal file
37
SVSim.BattleEngine/Engine/Wizard/AIAllyDiscardBonus.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAllyDiscardBonus : AIBonusArgumentWithIgnoreInBattle
|
||||
{
|
||||
private List<AIScriptTokenBase> _filters;
|
||||
|
||||
public AIAllyDiscardBonus(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_filters = GetFilters(_exprList.GetRange(0, _exprList.Count - _valueIndexOffset));
|
||||
}
|
||||
|
||||
public void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, bool useIgnoreInBattle, AISituationInfo situation = null)
|
||||
{
|
||||
AIDiscardInfo discardInfo = situation.DiscardInfo;
|
||||
if (discardInfo != null && discardInfo.IsValuable)
|
||||
{
|
||||
field.SimulationExtraBonus += GetBonusValue(tagOwner, playPtn, situation, useIgnoreInBattle) * (float)discardInfo.TargetList.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetBonusValue(AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool useIgnoreInBattle)
|
||||
{
|
||||
if (!AIFilteringUtility.CheckMatchTargetFiltering(situation.Actor, null, _filters, playPtn, tagOwner, situation))
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
return base.GetBonusValue(tagOwner, playPtn, situation, useIgnoreInBattle);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Wizard.Battle.View.Vfx;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public static class AIAttachEventToBattleModuleUtility
|
||||
{
|
||||
public static void SetupEventWhenInitGame(BattlePlayerBase ally, BattlePlayerBase opponent, OperateMgr operateMgr, EnemyAI ai)
|
||||
{
|
||||
SetupOnAddCemeteryEvent(ally, opponent, ai);
|
||||
SetupOnTurnStartComplete(ally, opponent, ai);
|
||||
SetupOnTurnEndStart(ally, opponent, ai);
|
||||
SetupOperateMgrEvent(operateMgr, ai);
|
||||
}
|
||||
|
||||
public static void DepriveAttachedAIBattleModule(BattlePlayerBase ally, BattlePlayerBase opponent, OperateMgr operateMgr, EnemyAI ai)
|
||||
{
|
||||
DepriveAttachedPlayerBattleEvent(ally, opponent, ai.PlayerBattleEvent);
|
||||
DepriveAttachedOperateMgrBattleEvent(operateMgr, ai.OprMgrBattleEvent);
|
||||
}
|
||||
|
||||
private static void DepriveAttachedPlayerBattleEvent(BattlePlayerBase ally, BattlePlayerBase opponent, AIAttachPlayerBattleEventCache playerBattleEvent)
|
||||
{
|
||||
if (playerBattleEvent.AllyAddCemeteryEvent != null)
|
||||
{
|
||||
ally.OnAddCemeteryEvent -= playerBattleEvent.AllyAddCemeteryEvent;
|
||||
playerBattleEvent.AllyAddCemeteryEvent = null;
|
||||
}
|
||||
if (playerBattleEvent.OpponentAddCemeteryEvent != null)
|
||||
{
|
||||
opponent.OnAddCemeteryEvent -= playerBattleEvent.OpponentAddCemeteryEvent;
|
||||
playerBattleEvent.OpponentAddCemeteryEvent = null;
|
||||
}
|
||||
if (playerBattleEvent.AllyTurnStartCompleteEvent != null)
|
||||
{
|
||||
ally.OnTurnStartComplete = (Action)Delegate.Remove(ally.OnTurnStartComplete, playerBattleEvent.AllyTurnStartCompleteEvent);
|
||||
playerBattleEvent.AllyTurnStartCompleteEvent = null;
|
||||
}
|
||||
if (playerBattleEvent.OpponentTurnStartCompleteEvent != null)
|
||||
{
|
||||
opponent.OnTurnStartComplete = (Action)Delegate.Remove(opponent.OnTurnStartComplete, playerBattleEvent.OpponentTurnStartCompleteEvent);
|
||||
playerBattleEvent.OpponentTurnStartCompleteEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void DepriveAttachedOperateMgrBattleEvent(OperateMgr oprMgr, AIAttachOperateMgrBattleEventCache oprMgrBattleEvent)
|
||||
{
|
||||
if (oprMgrBattleEvent.OnSetCardSuccessEvent != null)
|
||||
{
|
||||
oprMgr.OnSetCardSuccess -= oprMgrBattleEvent.OnSetCardSuccessEvent;
|
||||
oprMgrBattleEvent.OnSetCardSuccessEvent = null;
|
||||
}
|
||||
if (oprMgrBattleEvent.OnSetCardExecutedEvent != null)
|
||||
{
|
||||
oprMgr.OnSetCardExecuted -= oprMgrBattleEvent.OnSetCardExecutedEvent;
|
||||
oprMgrBattleEvent.OnSetCardExecutedEvent = null;
|
||||
}
|
||||
if (oprMgrBattleEvent.OnEvolveSuccessEvent != null)
|
||||
{
|
||||
oprMgr.OnEvolveSuccess -= oprMgrBattleEvent.OnEvolveSuccessEvent;
|
||||
oprMgrBattleEvent.OnEvolveSuccessEvent = null;
|
||||
}
|
||||
if (oprMgrBattleEvent.OnEvolveCompleteEvent != null)
|
||||
{
|
||||
oprMgr.OnEvoleComplete -= oprMgrBattleEvent.OnEvolveCompleteEvent;
|
||||
oprMgrBattleEvent.OnEvolveCompleteEvent = null;
|
||||
}
|
||||
if (oprMgrBattleEvent.OnBeforeAttackEvent != null)
|
||||
{
|
||||
oprMgr.OnBeforeAttack -= oprMgrBattleEvent.OnBeforeAttackEvent;
|
||||
oprMgrBattleEvent.OnBeforeAttackEvent = null;
|
||||
}
|
||||
if (oprMgrBattleEvent.OnAttackExecutedEvent != null)
|
||||
{
|
||||
oprMgr.OnAttackExecuted -= oprMgrBattleEvent.OnAttackExecutedEvent;
|
||||
oprMgrBattleEvent.OnAttackExecutedEvent = null;
|
||||
}
|
||||
if (oprMgrBattleEvent.OnBeforeFusionEvent != null)
|
||||
{
|
||||
oprMgr.OnBeforeFusion -= oprMgrBattleEvent.OnBeforeFusionEvent;
|
||||
oprMgrBattleEvent.OnBeforeFusionEvent = null;
|
||||
}
|
||||
if (oprMgrBattleEvent.OnAfterFusionEvent != null)
|
||||
{
|
||||
oprMgr.OnAfterFusion -= oprMgrBattleEvent.OnAfterFusionEvent;
|
||||
oprMgrBattleEvent.OnAfterFusionEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetupOnAddCemeteryEvent(BattlePlayerBase ally, BattlePlayerBase opponent, EnemyAI ai)
|
||||
{
|
||||
ai.PlayerBattleEvent.AllyAddCemeteryEvent = delegate(BattleCardBase card, BattlePlayerBase.CEMETERY_TYPE cemeteryType, bool isOpen, SkillBase skill)
|
||||
{
|
||||
if (cemeteryType == BattlePlayerBase.CEMETERY_TYPE.NORMAL && !(card is NullBattleCard) && card.SelfBattlePlayer.ClassAndInPlayCardList.Contains(card) && card.HasSkillWhenDestroy && ai.LatestAction != null)
|
||||
{
|
||||
ai.LatestAction.CreateRandomTargetInformation(card, (SkillBase skillBase) => skillBase.IsWhenDestroySkill && RegisterTool.IsSkillRandom(skillBase));
|
||||
}
|
||||
};
|
||||
ally.OnAddCemeteryEvent += ai.PlayerBattleEvent.AllyAddCemeteryEvent;
|
||||
ai.PlayerBattleEvent.OpponentAddCemeteryEvent = delegate(BattleCardBase card, BattlePlayerBase.CEMETERY_TYPE cemeteryType, bool isOpen, SkillBase skill)
|
||||
{
|
||||
if (cemeteryType == BattlePlayerBase.CEMETERY_TYPE.NORMAL && !(card is NullBattleCard) && card.SelfBattlePlayer.ClassAndInPlayCardList.Contains(card))
|
||||
{
|
||||
RecordOpponentBarbarossa(card, ai);
|
||||
if (card.HasSkillWhenDestroy && ai.LatestAction != null)
|
||||
{
|
||||
ai.LatestAction.CreateRandomTargetInformation(card, (SkillBase skillBase) => skillBase.IsWhenDestroySkill && RegisterTool.IsSkillRandom(skillBase));
|
||||
}
|
||||
}
|
||||
};
|
||||
opponent.OnAddCemeteryEvent += ai.PlayerBattleEvent.OpponentAddCemeteryEvent;
|
||||
}
|
||||
|
||||
private static void SetupOnTurnStartComplete(BattlePlayerBase ally, BattlePlayerBase opponent, EnemyAI ai)
|
||||
{
|
||||
ai.PlayerBattleEvent.AllyTurnStartCompleteEvent = delegate
|
||||
{
|
||||
ai.UpdateAICurrentVirtualField();
|
||||
AIVirtualField currentVirtualField = ai.CurrentVirtualField;
|
||||
if (ai.LatestAction != null && ai.BeforeLatestActionField != null)
|
||||
{
|
||||
currentVirtualField.UpdateTagInformationFromLatestAction(ai.LatestAction, ai.BeforeLatestActionField);
|
||||
}
|
||||
ai.LatestAction = null;
|
||||
ai.BeforeLatestActionField = null;
|
||||
};
|
||||
ally.OnTurnStartComplete = (Action)Delegate.Combine(ally.OnTurnStartComplete, ai.PlayerBattleEvent.AllyTurnStartCompleteEvent);
|
||||
ai.PlayerBattleEvent.OpponentTurnStartCompleteEvent = delegate
|
||||
{
|
||||
if (!ai.IsBattleEnd)
|
||||
{
|
||||
if (ai.IsOpponentBarbarossaDestroyed)
|
||||
{
|
||||
ai.IsOpponentBarbarossaDestroyed = false;
|
||||
}
|
||||
ai.UpdateAICurrentVirtualField();
|
||||
AIVirtualField currentVirtualField = ai.CurrentVirtualField;
|
||||
if (ai.LatestAction != null && ai.BeforeLatestActionField != null)
|
||||
{
|
||||
currentVirtualField.UpdateTagInformationFromLatestAction(ai.LatestAction, ai.BeforeLatestActionField);
|
||||
}
|
||||
ai.LatestAction = null;
|
||||
ai.BeforeLatestActionField = null;
|
||||
}
|
||||
};
|
||||
opponent.OnTurnStartComplete = (Action)Delegate.Combine(opponent.OnTurnStartComplete, ai.PlayerBattleEvent.OpponentTurnStartCompleteEvent);
|
||||
}
|
||||
|
||||
private static void SetupOnTurnEndStart(BattlePlayerBase ally, BattlePlayerBase opponent, EnemyAI ai)
|
||||
{
|
||||
ai.PlayerBattleEvent.AllySelfTurnEndEvent = delegate
|
||||
{
|
||||
ai.LatestAction = new AIRealActionInformation(AIOperationType.TURNEND, ally.Class, ally.Class, null);
|
||||
ai.SaveBeforeLatestActionInformation();
|
||||
for (int i = 0; i < ally.ClassAndInPlayCardList.Count; i++)
|
||||
{
|
||||
ai.LatestAction.CreateRandomTargetInformation(ally.ClassAndInPlayCardList[i], (SkillBase skill) => skill.OnSelfTurnEndStart != 0 && RegisterTool.IsSkillRandom(skill));
|
||||
}
|
||||
for (int num = 0; num < opponent.ClassAndInPlayCardList.Count; num++)
|
||||
{
|
||||
ai.LatestAction.CreateRandomTargetInformation(opponent.ClassAndInPlayCardList[num], (SkillBase skill) => skill.OnOpponentTurnEndStart != 0 && RegisterTool.IsSkillRandom(skill));
|
||||
}
|
||||
};
|
||||
ally.OnTurnEndStart += ai.PlayerBattleEvent.AllySelfTurnEndEvent;
|
||||
ai.PlayerBattleEvent.OpponentSelfTurnEndEvent = delegate
|
||||
{
|
||||
ai.LatestAction = new AIRealActionInformation(AIOperationType.TURNEND, opponent.Class, opponent.Class, null);
|
||||
ai.SaveBeforeLatestActionInformation();
|
||||
for (int i = 0; i < opponent.ClassAndInPlayCardList.Count; i++)
|
||||
{
|
||||
ai.LatestAction.CreateRandomTargetInformation(opponent.ClassAndInPlayCardList[i], (SkillBase skill) => skill.OnSelfTurnEndStart != 0 && RegisterTool.IsSkillRandom(skill));
|
||||
}
|
||||
for (int num = 0; num < ally.ClassAndInPlayCardList.Count; num++)
|
||||
{
|
||||
ai.LatestAction.CreateRandomTargetInformation(ally.ClassAndInPlayCardList[num], (SkillBase skill) => skill.OnOpponentTurnEndStart != 0 && RegisterTool.IsSkillRandom(skill));
|
||||
}
|
||||
};
|
||||
opponent.OnTurnEndStart += ai.PlayerBattleEvent.OpponentSelfTurnEndEvent;
|
||||
}
|
||||
|
||||
private static void SetupVirtualPairOnAfterPickCard(BattlePlayerPair pair, AIOperationSimulatorAccessor accessor)
|
||||
{
|
||||
pair.Self.OnAfterPickCard += delegate
|
||||
{
|
||||
accessor.UpdateCurrentField(pair, EnemyAI.EmptyPlayPtn);
|
||||
};
|
||||
pair.Opponent.OnAfterPickCard += delegate
|
||||
{
|
||||
accessor.UpdateCurrentField(pair, EnemyAI.EmptyPlayPtn);
|
||||
};
|
||||
}
|
||||
|
||||
private static void SetupOperateMgrEvent(OperateMgr operateMgr, EnemyAI ai)
|
||||
{
|
||||
SetupOperateMgrOnSetCardSuccess(operateMgr, ai);
|
||||
SetupOperateMgrOnSetCardExecuted(operateMgr, ai);
|
||||
SetupOperateMgrOnEvolveSuccess(operateMgr, ai);
|
||||
SetupOperateMgrOnEvolveComplete(operateMgr, ai);
|
||||
SetupOperateMgrOnBeforeAttack(operateMgr, ai);
|
||||
SetupOperateMgrOnAttackExecuted(operateMgr, ai);
|
||||
SetupOperateMgrOnBeforeFusion(operateMgr, ai);
|
||||
SetupOperateMgrOnAfterFusion(operateMgr, ai);
|
||||
}
|
||||
|
||||
private static void SetupOperateMgrOnSetCardSuccess(OperateMgr operateMgr, EnemyAI ai)
|
||||
{
|
||||
ai.OprMgrBattleEvent.OnSetCardSuccessEvent = delegate(BattleCardBase originalCard, BattleCardBase playCard, IEnumerable<BattleCardBase> selectedCards)
|
||||
{
|
||||
ai.LatestAction = new AIRealActionInformation(AIOperationType.PLAY, playCard, originalCard, selectedCards);
|
||||
ai.SaveBeforeLatestActionInformation();
|
||||
ai.LatestAction.CreateRandomTargetInformation(playCard, (SkillBase skill) => skill.IsWhenPlaySkill && RegisterTool.IsSkillRandom(skill));
|
||||
};
|
||||
operateMgr.OnSetCardSuccess += ai.OprMgrBattleEvent.OnSetCardSuccessEvent;
|
||||
}
|
||||
|
||||
private static void SetupOperateMgrOnSetCardExecuted(OperateMgr operateMgr, EnemyAI ai)
|
||||
{
|
||||
ai.OprMgrBattleEvent.OnSetCardExecutedEvent = delegate
|
||||
{
|
||||
if (ai.IsBattleEnd)
|
||||
{
|
||||
return NullVfx.GetInstance();
|
||||
}
|
||||
ai.UpdateAICurrentVirtualField();
|
||||
AIVirtualField currentVirtualField = ai.CurrentVirtualField;
|
||||
if (ai.LatestAction != null && ai.BeforeLatestActionField != null)
|
||||
{
|
||||
currentVirtualField.UpdateTagInformationFromLatestAction(ai.LatestAction, ai.BeforeLatestActionField);
|
||||
}
|
||||
ai.LatestAction = null;
|
||||
ai.BeforeLatestActionField = null;
|
||||
return NullVfx.GetInstance();
|
||||
};
|
||||
operateMgr.OnSetCardExecuted += ai.OprMgrBattleEvent.OnSetCardExecutedEvent;
|
||||
}
|
||||
|
||||
private static void RecordOpponentBarbarossa(BattleCardBase destroyCard, EnemyAI ai)
|
||||
{
|
||||
if (destroyCard.BaseParameter.BaseCardId == 106241020)
|
||||
{
|
||||
ai.IsOpponentBarbarossaDestroyed = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetupOperateMgrOnEvolveSuccess(OperateMgr operateMgr, EnemyAI ai)
|
||||
{
|
||||
ai.OprMgrBattleEvent.OnEvolveSuccessEvent = delegate(BattleCardBase originalEvolver, BattleCardBase realEvolver, IEnumerable<BattleCardBase> selectedTargets)
|
||||
{
|
||||
ai.SaveBeforeLatestActionInformation();
|
||||
ai.LatestAction = new AIRealActionInformation(AIOperationType.EVOLVE, realEvolver, originalEvolver, selectedTargets);
|
||||
ai.LatestAction.CreateRandomTargetInformation(realEvolver, (SkillBase skill) => skill.IsWhenEvolveSkill && RegisterTool.IsSkillRandom(skill), forceCheckEvolveSkills: true);
|
||||
};
|
||||
operateMgr.OnEvolveSuccess += ai.OprMgrBattleEvent.OnEvolveSuccessEvent;
|
||||
}
|
||||
|
||||
private static void SetupOperateMgrOnEvolveComplete(OperateMgr operateMgr, EnemyAI ai)
|
||||
{
|
||||
ai.OprMgrBattleEvent.OnEvolveCompleteEvent = delegate
|
||||
{
|
||||
if (!ai.IsBattleEnd)
|
||||
{
|
||||
ai.UpdateAICurrentVirtualField();
|
||||
AIVirtualField currentVirtualField = ai.CurrentVirtualField;
|
||||
if (ai.LatestAction != null && ai.BeforeLatestActionField != null)
|
||||
{
|
||||
currentVirtualField.UpdateTagInformationFromLatestAction(ai.LatestAction, ai.BeforeLatestActionField);
|
||||
}
|
||||
ai.LatestAction = null;
|
||||
ai.BeforeLatestActionField = null;
|
||||
}
|
||||
return NullVfx.GetInstance();
|
||||
};
|
||||
operateMgr.OnEvoleComplete += ai.OprMgrBattleEvent.OnEvolveCompleteEvent;
|
||||
}
|
||||
|
||||
private static void SetupOperateMgrOnBeforeAttack(OperateMgr operateMgr, EnemyAI ai)
|
||||
{
|
||||
ai.OprMgrBattleEvent.OnBeforeAttackEvent = delegate(BattleCardBase attacker, BattleCardBase target, SkillProcessor skillProcessorOneTime)
|
||||
{
|
||||
ai.LatestAction = new AIRealActionInformation(AIOperationType.ATTACK, attacker, attacker, new List<BattleCardBase> { target });
|
||||
ai.SaveBeforeLatestActionInformation();
|
||||
ai.LatestAction.CreateRandomTargetInformation(attacker, (SkillBase skill) => skill.IsBeforAttackSkill && RegisterTool.IsSkillRandom(skill));
|
||||
return NullVfx.GetInstance();
|
||||
};
|
||||
operateMgr.OnBeforeAttack += ai.OprMgrBattleEvent.OnBeforeAttackEvent;
|
||||
}
|
||||
|
||||
private static void SetupOperateMgrOnAttackExecuted(OperateMgr operateMgr, EnemyAI ai)
|
||||
{
|
||||
ai.OprMgrBattleEvent.OnAttackExecutedEvent = delegate
|
||||
{
|
||||
if (!ai.IsBattleEnd)
|
||||
{
|
||||
ai.UpdateAICurrentVirtualField();
|
||||
AIVirtualField currentVirtualField = ai.CurrentVirtualField;
|
||||
if (ai.LatestAction != null && ai.BeforeLatestActionField != null)
|
||||
{
|
||||
currentVirtualField.UpdateTagInformationFromLatestAction(ai.LatestAction, ai.BeforeLatestActionField);
|
||||
}
|
||||
ai.LatestAction = null;
|
||||
ai.BeforeLatestActionField = null;
|
||||
}
|
||||
return NullVfx.GetInstance();
|
||||
};
|
||||
operateMgr.OnAttackExecuted += ai.OprMgrBattleEvent.OnAttackExecutedEvent;
|
||||
}
|
||||
|
||||
private static void SetupOperateMgrOnBeforeFusion(OperateMgr operateMgr, EnemyAI ai)
|
||||
{
|
||||
ai.OprMgrBattleEvent.OnBeforeFusionEvent = delegate(BattleCardBase fusionActor, IEnumerable<BattleCardBase> targets)
|
||||
{
|
||||
ai.LatestAction = new AIRealActionInformation(AIOperationType.FUSION, fusionActor, fusionActor, targets);
|
||||
ai.SaveBeforeLatestActionInformation();
|
||||
};
|
||||
operateMgr.OnBeforeFusion += ai.OprMgrBattleEvent.OnBeforeFusionEvent;
|
||||
}
|
||||
|
||||
private static void SetupOperateMgrOnAfterFusion(OperateMgr operateMgr, EnemyAI ai)
|
||||
{
|
||||
ai.OprMgrBattleEvent.OnAfterFusionEvent = delegate
|
||||
{
|
||||
if (!ai.IsBattleEnd)
|
||||
{
|
||||
ai.UpdateAICurrentVirtualField();
|
||||
AIVirtualField currentVirtualField = ai.CurrentVirtualField;
|
||||
if (ai.LatestAction != null && ai.BeforeLatestActionField != null)
|
||||
{
|
||||
currentVirtualField.UpdateTagInformationFromLatestAction(ai.LatestAction, ai.BeforeLatestActionField);
|
||||
}
|
||||
ai.LatestAction = null;
|
||||
ai.BeforeLatestActionField = null;
|
||||
}
|
||||
return NullVfx.GetInstance();
|
||||
};
|
||||
operateMgr.OnAfterFusion += ai.OprMgrBattleEvent.OnAfterFusionEvent;
|
||||
}
|
||||
|
||||
public static void SetupVirtualPairEventForOperationSimulator(BattlePlayerPair pair, AIOperationSimulatorAccessor accessor)
|
||||
{
|
||||
SetupVirtualPairOnAfterPickCard(pair, accessor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttachedTagLeaveStopInformation : AILeaveStopInformation
|
||||
{
|
||||
private AIPlayTag _targetTag;
|
||||
|
||||
public AIAttachedTagLeaveStopInformation(AIAttachedTagStopPreprocessOption option, AIVirtualCard provider)
|
||||
: base(option.TargetCard, provider)
|
||||
{
|
||||
base.Type = AITagPreprocessInfoType.REMOVE_ATTACHED_TAG;
|
||||
_targetTag = option.TargetTag;
|
||||
}
|
||||
|
||||
protected override void StopMethod(AISituationInfo situation)
|
||||
{
|
||||
AIRemoveTagUtility.RemoveTemporaryAttachedTag(base.TargetCard, base.TargetCard.SelfField, _targetTag, situation);
|
||||
}
|
||||
|
||||
public override AITagPreprocessCreationOptionBase CreateOptionInfoForOverride(AIVirtualCard overridedTarget)
|
||||
{
|
||||
return new AIAttachedTagStopPreprocessOption(overridedTarget)
|
||||
{
|
||||
TargetTag = _targetTag
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttachedTagStopPreprocessOption : AITagPreprocessCreationOptionBase
|
||||
{
|
||||
public AIPlayTag TargetTag;
|
||||
|
||||
public AIAttachedTagStopPreprocessOption(AIVirtualCard targetCard)
|
||||
: base(AITagPreprocessInfoType.REMOVE_ATTACHED_TAG, targetCard)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttachedTagTurnEndStopInformation : AITurnEndStopInformation
|
||||
{
|
||||
private AIPlayTag _targetTag;
|
||||
|
||||
public AIAttachedTagTurnEndStopInformation(AIAttachedTagStopPreprocessOption option, int defaultIncrement)
|
||||
: base(option.TargetCard, defaultIncrement)
|
||||
{
|
||||
base.Type = AITagPreprocessInfoType.REMOVE_ATTACHED_TAG;
|
||||
_targetTag = option.TargetTag;
|
||||
}
|
||||
|
||||
protected override void RunMethod(bool isAllyTurnEnd, AIVirtualTurnEndInfo situation)
|
||||
{
|
||||
AIRemoveTagUtility.RemoveTemporaryAttachedTag(base.TargetCard, base.TargetCard.SelfField, _targetTag, situation);
|
||||
}
|
||||
|
||||
public override AITagPreprocessCreationOptionBase CreateOptionInfoForOverride(AIVirtualCard overridedTarget)
|
||||
{
|
||||
return new AIAttachedTagStopPreprocessOption(overridedTarget)
|
||||
{
|
||||
TargetTag = _targetTag
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttachedTagTurnStartStopInformation : AITurnStartStopInformation
|
||||
{
|
||||
private AIPlayTag _targetTag;
|
||||
|
||||
public AIAttachedTagTurnStartStopInformation(AIAttachedTagStopPreprocessOption option)
|
||||
: base(option.TargetCard)
|
||||
{
|
||||
base.Type = AITagPreprocessInfoType.REMOVE_ATTACHED_TAG;
|
||||
_targetTag = option.TargetTag;
|
||||
}
|
||||
|
||||
public override void ExecuteReservedAction(bool isAllyTurnEnd, AISituationInfo situation)
|
||||
{
|
||||
AIRemoveTagUtility.RemoveTemporaryAttachedTag(base.TargetCard, base.TargetCard.SelfField, _targetTag, situation);
|
||||
}
|
||||
|
||||
public override AITagPreprocessCreationOptionBase CreateOptionInfoForOverride(AIVirtualCard overridedTarget)
|
||||
{
|
||||
return new AIAttachedTagStopPreprocessOption(overridedTarget)
|
||||
{
|
||||
TargetTag = _targetTag
|
||||
};
|
||||
}
|
||||
}
|
||||
33
SVSim.BattleEngine/Engine/Wizard/AIAttackAddDeck.cs
Normal file
33
SVSim.BattleEngine/Engine/Wizard/AIAttackAddDeck.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackAddDeck : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _count;
|
||||
|
||||
private AIPolishConvertedExpression _id;
|
||||
|
||||
private const int COUNT_ARG_INDEX = 1;
|
||||
|
||||
private const int ID_ARG_INDEX = 0;
|
||||
|
||||
public AIAttackAddDeck(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
InitExprList(text);
|
||||
_id = _exprList[0];
|
||||
_count = _exprList[1];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
int tokenCount = (int)_count.EvalArg(tagOwner, playPtn, field, situation);
|
||||
int tokenId = _id.EvalID();
|
||||
field.AddDeckCard(tokenId, tokenCount, tagOwner, playPtn, situation);
|
||||
}
|
||||
}
|
||||
57
SVSim.BattleEngine/Engine/Wizard/AIAttackAttachTag.cs
Normal file
57
SVSim.BattleEngine/Engine/Wizard/AIAttackAttachTag.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackAttachTag : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private AIScriptTokenArgType _removeTiming;
|
||||
|
||||
private const int REMOVE_TIMING_OFFSET = 1;
|
||||
|
||||
private const int TAG_WORD_START_INDEX = 1;
|
||||
|
||||
public AIPlayTag Tag { get; private set; }
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public AIAttackAttachTag(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
List<string> list = AIPlayTagInitializingUtility.SplitTagText(text);
|
||||
base.InitExpressions(list[0]);
|
||||
Tag = AIPlayTagInitializingUtility.CreateAIPlayTagFromWords(list[1], list[2], list[3]);
|
||||
_removeTiming = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - 1]);
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0 && base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIAttachTagSimulationUtility.SimulateAttachTagToAll(targetsFromField, tagOwner, Tag, _removeTiming, situation);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.AllReferableCards;
|
||||
}
|
||||
|
||||
public override AITokenIdCollection GetAllRegisterTokenPoolInfo(AIVirtualCard owner)
|
||||
{
|
||||
if (Tag != null)
|
||||
{
|
||||
return Tag.ArgumentExpressions.GetAllRegisterTokenPoolInfo(owner);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
51
SVSim.BattleEngine/Engine/Wizard/AIAttackAttackableCount.cs
Normal file
51
SVSim.BattleEngine/Engine/Wizard/AIAttackAttackableCount.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackAttackableCount : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _attackableCountArg;
|
||||
|
||||
private const int ATTACKABLE_COUNT_ARG_OFFSET = 1;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public AIAttackAttackableCount(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_attackableCountArg = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
int attackableCount = (int)_attackableCountArg.EvalArg(tagOwner, playPtn, tagOwner.SelfField, situation);
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIAttackableCountSimulationUtility.ExecuteChangeAttackableCountAll(targetsFromField, attackableCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForFollowerOnly(candidates, tagOwner, base.Filters, playPtn, situation, isBlockDead);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
}
|
||||
16
SVSim.BattleEngine/Engine/Wizard/AIAttackBreakAttackTwice.cs
Normal file
16
SVSim.BattleEngine/Engine/Wizard/AIAttackBreakAttackTwice.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackBreakAttackTwice : AIScriptArgumentExpressions
|
||||
{
|
||||
public AIAttackBreakAttackTwice(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
tagOwner.GiveAttackableCount(2);
|
||||
}
|
||||
}
|
||||
46
SVSim.BattleEngine/Engine/Wizard/AIAttackBreakDamage.cs
Normal file
46
SVSim.BattleEngine/Engine/Wizard/AIAttackBreakDamage.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackBreakDamage : AIFiltersAndSelectTypeArgument
|
||||
{
|
||||
private readonly int DAMAGE_ARG_OFFSET = 1;
|
||||
|
||||
public AIPolishConvertedExpression Damage { get; private set; }
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public AIAttackBreakDamage(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
Damage = _exprList[_exprList.Count - DAMAGE_ARG_OFFSET];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
base.Execute(tagOwner, field, playPtn, situation);
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, field.BestPlayPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
int damage = (int)Damage.EvalArg(tagOwner, field.BestPlayPtn, field, situation);
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIDamageSimulationUtility.DamageAll(targetsFromField, tagOwner, field, damage, situation);
|
||||
}
|
||||
else if (base.SelectType == AIScriptTokenArgType.RANDOM_SELECT)
|
||||
{
|
||||
AIDamageSimulationUtility.DamageRandom(targetsFromField, tagOwner, field, damage, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
}
|
||||
20
SVSim.BattleEngine/Engine/Wizard/AIAttackBreakEvo.cs
Normal file
20
SVSim.BattleEngine/Engine/Wizard/AIAttackBreakEvo.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackBreakEvo : AIScriptArgumentExpressions
|
||||
{
|
||||
public AIAttackBreakEvo(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
base.Execute(tagOwner, field, playPtn, situation);
|
||||
if (!situation.Actor.IsEvolution)
|
||||
{
|
||||
AIAutoEvolutionSimulationUtility.AutoEvolveSingle(situation.Actor, field, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
28
SVSim.BattleEngine/Engine/Wizard/AIAttackBreakRecoverPp.cs
Normal file
28
SVSim.BattleEngine/Engine/Wizard/AIAttackBreakRecoverPp.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackBreakRecoverPp : AIScriptArgumentExpressions
|
||||
{
|
||||
private AIPolishConvertedExpression _recoverValue;
|
||||
|
||||
public AIAttackBreakRecoverPp(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
if (_exprList != null && _exprList.Count > 0)
|
||||
{
|
||||
_recoverValue = _exprList[0];
|
||||
}
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
int amount = (int)_recoverValue.EvalArg(tagOwner, playPtn, field, situation);
|
||||
field.RecoverPp(amount);
|
||||
}
|
||||
}
|
||||
100
SVSim.BattleEngine/Engine/Wizard/AIAttackBuff.cs
Normal file
100
SVSim.BattleEngine/Engine/Wizard/AIAttackBuff.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackBuff : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _attack;
|
||||
|
||||
private AIPolishConvertedExpression _life;
|
||||
|
||||
private AIScriptTokenArgType _tempOrPerm;
|
||||
|
||||
private readonly int TEMP_OR_PERM_ARG_OFFSET = 1;
|
||||
|
||||
private readonly int LIFE_ARG_OFFSET = 2;
|
||||
|
||||
private readonly int ATTACK_ARG_OFFSET = 3;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 4;
|
||||
|
||||
public override bool IsActivateWhenEvalInstantAttack => true;
|
||||
|
||||
public AIAttackBuff(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
if (_exprList.Count > SELECT_TYPE_OFFSET)
|
||||
{
|
||||
_attack = _exprList[_exprList.Count - ATTACK_ARG_OFFSET];
|
||||
_life = _exprList[_exprList.Count - LIFE_ARG_OFFSET];
|
||||
_tempOrPerm = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - TEMP_OR_PERM_ARG_OFFSET], AIBuffEvaluationUtility.LEGAL_TEMP_OR_PERM_ARGUMENTS);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
AIBuffExecutingInfo_old buffExecutingInfo_old = AIBuffSimulationUtility.GetBuffExecutingInfo_old(tagOwner, field, situation, playPtn, _attack, _life);
|
||||
bool isTemp = _tempOrPerm == AIScriptTokenArgType.TEMP;
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIBuffSimulationUtility.BuffAll_old(targetsFromField, field, buffExecutingInfo_old, isTemp, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
bool isAttackEffective = !_attack.IsZeroOrNone();
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective, isBlockDead);
|
||||
}
|
||||
|
||||
public void RegisterBuffInfo(AISimulationBuffInfoCollection collection, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, ulong tagHash)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
AIBuffExecutingInfo_old buffExecutingInfo_old = AIBuffSimulationUtility.GetBuffExecutingInfo_old(tagOwner, field, situation, playPtn, _attack, _life);
|
||||
if (!buffExecutingInfo_old.IsMultiplyAttack && !buffExecutingInfo_old.IsMultiplyLife)
|
||||
{
|
||||
bool num = _tempOrPerm == AIScriptTokenArgType.TEMP;
|
||||
int attackValue = buffExecutingInfo_old.AttackValue;
|
||||
int lifeValue = buffExecutingInfo_old.LifeValue;
|
||||
AISimulationBuffInfo buffInfo = (num ? new AISimulationBuffInfo(attackValue, lifeValue, attackValue, lifeValue) : new AISimulationBuffInfo(0, 0, attackValue, lifeValue));
|
||||
collection.Add(tagHash, targetsFromField, buffInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void PseudoSimulateForEvalInstantAttack(AIVirtualCard tagOwner, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, EvalInstantAttackInformation information)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField == null || targetsFromField.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool flag = situation.Actor.IsSameCardIncluded(targetsFromField);
|
||||
bool flag2 = situation.AttackTarget.IsSameCardIncluded(targetsFromField);
|
||||
if (flag || flag2)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
int attack = (int)_attack.EvalArg(tagOwner, playPtn, field, situation);
|
||||
int life = (int)_life.EvalArg(tagOwner, playPtn, field, situation);
|
||||
information.AddAttackerWhenAttackBuff(attack, life);
|
||||
}
|
||||
if (flag2)
|
||||
{
|
||||
int value = (int)_life.EvalArg(tagOwner, playPtn, field, situation);
|
||||
information.AddTargetLifeBuff(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
SVSim.BattleEngine/Engine/Wizard/AIAttackDamage.cs
Normal file
120
SVSim.BattleEngine/Engine/Wizard/AIAttackDamage.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackDamage : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _damage;
|
||||
|
||||
private readonly int DAMAGE_ARG_OFFSET = 1;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public override bool IsActivateWhenEvalInstantAttack => true;
|
||||
|
||||
public AIAttackDamage(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_damage = _exprList[_exprList.Count - DAMAGE_ARG_OFFSET];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
int damage = (int)_damage.EvalArg(tagOwner, playPtn, field, situation);
|
||||
switch (base.SelectType)
|
||||
{
|
||||
case AIScriptTokenArgType.ALL_SELECT:
|
||||
AIDamageSimulationUtility.DamageAll(targetsFromField, tagOwner, field, damage, situation);
|
||||
break;
|
||||
case AIScriptTokenArgType.RANDOM_SELECT:
|
||||
AIDamageSimulationUtility.DamageRandom(targetsFromField, tagOwner, field, damage, situation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int GetAttackDamageToCertainTarget(AIVirtualCard tagOwner, AISituationInfo situation, AIVirtualField field, List<int> playPtn, AIVirtualCard damageTarget)
|
||||
{
|
||||
if (damageTarget.IsIndependent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField.Contains(damageTarget))
|
||||
{
|
||||
int num = (int)_damage.EvalArg(tagOwner, playPtn, field, situation);
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT || (base.SelectType == AIScriptTokenArgType.RANDOM_SELECT && damageTarget.IsSameCard(AIDamageSimulationUtility.SelectDamageTarget(targetsFromField, field, playPtn, situation, num, isSpell: false, AISelectTargetPattern.Worst))))
|
||||
{
|
||||
return num;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
|
||||
public override bool CanKillTarget(AIVirtualCard tagOwner, AIVirtualCard target, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, AIBarrierPseudoSimulationInfo simBarrier, ref int totalDamage)
|
||||
{
|
||||
totalDamage += PseudoSimulateWhenAttackDamageToCertainCard(tagOwner, target, field, situation, playPtn, simBarrier);
|
||||
return totalDamage >= target.Life;
|
||||
}
|
||||
|
||||
public override int PseudoSimulateWhenAttackDamageToCertainCard(AIVirtualCard tagOwner, AIVirtualCard damageTarget, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, AIBarrierPseudoSimulationInfo simBarrier)
|
||||
{
|
||||
int attackDamageToCertainTarget = GetAttackDamageToCertainTarget(tagOwner, situation, field, playPtn, damageTarget);
|
||||
if (attackDamageToCertainTarget <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
bool isSpell = tagOwner.IsSpell;
|
||||
int result = simBarrier.SimulateDamageAmount(damageTarget.SimulateDamageShield(attackDamageToCertainTarget, isSkillDamage: true, isSpell), isSpell);
|
||||
simBarrier.DepriveBarrier(AIBarrierStopTiming.AfterDamage);
|
||||
return result;
|
||||
}
|
||||
|
||||
public override bool CanKillAnyTarget(AIVirtualCard tagOwner, List<AIVirtualCard> targetList, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, List<AIBarrierPseudoSimulationInfo> simBarrierList, int[] realDamageList)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField == null || targetsFromField.Count <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int num = (int)_damage.EvalArg(tagOwner, playPtn, field, situation);
|
||||
if (num <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool isSpell = tagOwner.IsSpell;
|
||||
for (int i = 0; i < targetList.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = targetList[i];
|
||||
if (aIVirtualCard.IsIndependent || !aIVirtualCard.IsSameCardIncluded(targetsFromField))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
AIBarrierPseudoSimulationInfo aIBarrierPseudoSimulationInfo = simBarrierList[i];
|
||||
int num2 = aIBarrierPseudoSimulationInfo.SimulateDamageAmount(aIVirtualCard.SimulateDamageShield(num, isSkillDamage: true, isSpell), isSpell);
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT || (base.SelectType == AIScriptTokenArgType.RANDOM_SELECT && aIVirtualCard.IsSameCard(AIDamageSimulationUtility.SelectDamageTarget(targetsFromField, field, playPtn, situation, num2, isSpell: false, AISelectTargetPattern.Worst))))
|
||||
{
|
||||
aIBarrierPseudoSimulationInfo.DepriveBarrier(AIBarrierStopTiming.AfterDamage);
|
||||
realDamageList[i] += num2;
|
||||
if (realDamageList[i] >= aIVirtualCard.Life)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
95
SVSim.BattleEngine/Engine/Wizard/AIAttackDestroy.cs
Normal file
95
SVSim.BattleEngine/Engine/Wizard/AIAttackDestroy.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackDestroy : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
public override bool IsActivateWhenEvalInstantAttack => true;
|
||||
|
||||
public AIAttackDestroy(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
switch (base.SelectType)
|
||||
{
|
||||
case AIScriptTokenArgType.ALL_SELECT:
|
||||
AISkillSimulationUtility.DestroyAll(targetsFromField, field, situation);
|
||||
break;
|
||||
case AIScriptTokenArgType.RANDOM_SELECT:
|
||||
AISkillSimulationUtility.DestroyRandom(targetsFromField, tagOwner, field, playPtn, situation);
|
||||
break;
|
||||
default:
|
||||
LogSelectTypeError(base.SelectType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanKillTarget(AIVirtualCard tagOwner, AIVirtualCard target, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, AIBarrierPseudoSimulationInfo simBarrier, ref int totalDamage)
|
||||
{
|
||||
if (target.IsIndependent || target.IsIndestructible)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Contains(target))
|
||||
{
|
||||
switch (base.SelectType)
|
||||
{
|
||||
case AIScriptTokenArgType.ALL_SELECT:
|
||||
return true;
|
||||
case AIScriptTokenArgType.RANDOM_SELECT:
|
||||
{
|
||||
AIVirtualCard card = AISimulationRemovalUtility.SelectRemovalTarget(targetsFromField, tagOwner, field, playPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Destroy);
|
||||
return target.IsSameCard(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CanKillAnyTarget(AIVirtualCard tagOwner, List<AIVirtualCard> targetList, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, List<AIBarrierPseudoSimulationInfo> simBarrierList, int[] realDamageList)
|
||||
{
|
||||
if (targetList == null || targetList.Count <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField == null || targetsFromField.Count <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
switch (base.SelectType)
|
||||
{
|
||||
case AIScriptTokenArgType.ALL_SELECT:
|
||||
{
|
||||
for (int i = 0; i < targetList.Count; i++)
|
||||
{
|
||||
if (targetList[i].IsSameCardIncluded(targetsFromField))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AIScriptTokenArgType.RANDOM_SELECT:
|
||||
return AISimulationRemovalUtility.SelectRemovalTarget(targetsFromField, tagOwner, field, playPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Destroy).IsSameCardIncluded(targetList);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void LogSelectTypeError(AIScriptTokenArgType selectType)
|
||||
{
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
}
|
||||
67
SVSim.BattleEngine/Engine/Wizard/AIAttackDiscard.cs
Normal file
67
SVSim.BattleEngine/Engine/Wizard/AIAttackDiscard.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackDiscard : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _discardCountArg;
|
||||
|
||||
private const int DISCARD_COUNT_ARG_OFFSET = 1;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public AIAttackDiscard(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_discardCountArg = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
int discardCount = GetDiscardCount(tagOwner, playPtn, situation);
|
||||
switch (base.SelectType)
|
||||
{
|
||||
case AIScriptTokenArgType.RANDOM_SELECT:
|
||||
AISkillSimulationUtility.DiscardRandom(tagOwner, field, targetsFromField, discardCount, situation);
|
||||
break;
|
||||
case AIScriptTokenArgType.ALL_SELECT:
|
||||
AISkillSimulationUtility.DiscardAll(tagOwner, targetsFromField, field, situation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAttackDiscardTargetInPlayPtn(AIVirtualCard tagOwner, List<AIVirtualCard> handCards, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
for (int i = 0; i < playPtn.Count; i++)
|
||||
{
|
||||
if (AIFilteringUtility.CheckMatchTargetFiltering(handCards[playPtn[i]], handCards, base.Filters, playPtn, tagOwner, situation))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private int GetDiscardCount(AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (_discardCountArg == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (int)_discardCountArg.EvalArg(tagOwner, playPtn, tagOwner.SelfField, situation);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.GetSimulationHandCards();
|
||||
}
|
||||
}
|
||||
35
SVSim.BattleEngine/Engine/Wizard/AIAttackEvo.cs
Normal file
35
SVSim.BattleEngine/Engine/Wizard/AIAttackEvo.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackEvo : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
public AIAttackEvo(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0 && base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIAutoEvolutionSimulationUtility.AutoEvolution(field, targetsFromField, playPtn, situation, base.SelectType);
|
||||
}
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForFollowerOnly(candidates, tagOwner, base.Filters, playPtn, situation, isBlockDead);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.AllyInplayCards;
|
||||
}
|
||||
}
|
||||
100
SVSim.BattleEngine/Engine/Wizard/AIAttackHandBuff.cs
Normal file
100
SVSim.BattleEngine/Engine/Wizard/AIAttackHandBuff.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackHandBuff : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _attack;
|
||||
|
||||
private AIPolishConvertedExpression _life;
|
||||
|
||||
private readonly int ATTACK_BUFF_ARG_OFFSET = 2;
|
||||
|
||||
private readonly int LIFE_BUFF_ARG_OFFSET = 1;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 3;
|
||||
|
||||
public AIAttackHandBuff(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_attack = _exprList[_exprList.Count - ATTACK_BUFF_ARG_OFFSET];
|
||||
_life = _exprList[_exprList.Count - LIFE_BUFF_ARG_OFFSET];
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.RANDOM_SELECT };
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.GetSimulationHandCards();
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective: true, isBlockDead);
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
AIBuffExecutingInfo_old buffExecutingInfo_old = AIBuffSimulationUtility.GetBuffExecutingInfo_old(tagOwner, field, situation, playPtn, _attack, _life);
|
||||
if (base.SelectType == AIScriptTokenArgType.RANDOM_SELECT)
|
||||
{
|
||||
ExecuteRandomSelectHandBuff(targetsFromField, buffExecutingInfo_old, tagOwner, field, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteRandomSelectHandBuff(List<AIVirtualCard> candidates, AIBuffExecutingInfo_old buffInfo, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIVirtualCardRealTargetInformation aIVirtualCardRealTargetInformation = null;
|
||||
if (situation.IsLatestAction)
|
||||
{
|
||||
aIVirtualCardRealTargetInformation = situation.DequeueRealTargetInfo(tagOwner, field);
|
||||
if (aIVirtualCardRealTargetInformation == null || aIVirtualCardRealTargetInformation.TargetList.Count <= 0)
|
||||
{
|
||||
AIConsoleUtility.LogError("AIAttackHandBuff.ExecuteRandomSelectHandBuff error!! Cannot find real target!!!!!! tagOwner.BaseId = " + tagOwner.BaseId);
|
||||
}
|
||||
else if (IsCandidateLegal(aIVirtualCardRealTargetInformation, candidates, tagOwner.BaseId))
|
||||
{
|
||||
AIHandBuffSimulationUtility.ExecuteHandBuffAll(aIVirtualCardRealTargetInformation.TargetList, buffInfo, situation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AIHandBuffSimulationUtility.ExecuteHandBuffRandom(candidates, buffInfo, playPtn, situation);
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsCandidateLegal(AIVirtualCardRealTargetInformation realTargets, List<AIVirtualCard> virtualCandidates, int tagOwnerId)
|
||||
{
|
||||
for (int i = 0; i < realTargets.TargetList.Count; i++)
|
||||
{
|
||||
AIVirtualCard card = realTargets.TargetList[i];
|
||||
bool flag = false;
|
||||
for (int j = 0; j < virtualCandidates.Count; j++)
|
||||
{
|
||||
if (virtualCandidates[j].IsSameCard(card))
|
||||
{
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag)
|
||||
{
|
||||
AIConsoleUtility.LogError("AIAttackHandBuff.IsCandidateLegal() error!! Candidates does not include target!!!!! tagOwner.BaseId == " + tagOwnerId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
20
SVSim.BattleEngine/Engine/Wizard/AIAttackMove.cs
Normal file
20
SVSim.BattleEngine/Engine/Wizard/AIAttackMove.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace Wizard;
|
||||
|
||||
internal class AIAttackMove : AIMove
|
||||
{
|
||||
public BattleCardBase Src { get; private set; }
|
||||
|
||||
public BattleCardBase Target { get; private set; }
|
||||
|
||||
public AIAttackMove(BattleCardBase src, BattleCardBase target)
|
||||
: base(AIOperationType.ATTACK)
|
||||
{
|
||||
Src = src;
|
||||
Target = target;
|
||||
}
|
||||
|
||||
public override void RunOperation(BattleManagerBase mgr, bool isPlayer)
|
||||
{
|
||||
mgr.VfxMgr.RegisterSequentialVfx(mgr.OperateMgr.Attack(Src, Target, isPlayer));
|
||||
}
|
||||
}
|
||||
57
SVSim.BattleEngine/Engine/Wizard/AIAttackOrClashBanish.cs
Normal file
57
SVSim.BattleEngine/Engine/Wizard/AIAttackOrClashBanish.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackOrClashBanish : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
public override bool IsActivateWhenEvalInstantAttack => true;
|
||||
|
||||
public AIAttackOrClashBanish(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
switch (base.SelectType)
|
||||
{
|
||||
case AIScriptTokenArgType.ALL_SELECT:
|
||||
AIBanishSimulationUtility.BanishAll(targetsFromField, situation);
|
||||
break;
|
||||
case AIScriptTokenArgType.RANDOM_SELECT:
|
||||
AIBanishSimulationUtility.BanishRandom(targetsFromField, tagOwner, field, playPtn, situation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanKillTarget(AIVirtualCard tagOwner, AIVirtualCard target, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, AIBarrierPseudoSimulationInfo simBarrier, ref int totalDamage)
|
||||
{
|
||||
if (target.IsIndependent || target.IsUnbanishable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Contains(target))
|
||||
{
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (base.SelectType == AIScriptTokenArgType.RANDOM_SELECT)
|
||||
{
|
||||
AIVirtualCard card = AISimulationRemovalUtility.SelectRemovalTarget(targetsFromField, tagOwner, field, field.BestPlayPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Banish);
|
||||
return target.IsSameCard(card);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public abstract class AIAttackOrClashBarrierBase : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
protected AIScriptTokenArgType _stopTiming;
|
||||
|
||||
protected AIScriptTokenArgType _damageType;
|
||||
|
||||
protected bool _isDamageTypeDefinedByMaster;
|
||||
|
||||
protected abstract int _defaultDamageTypeOffset { get; }
|
||||
|
||||
protected abstract int _stopTimingOffset { get; }
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 1 + (_isDamageTypeDefinedByMaster ? _defaultDamageTypeOffset : _stopTimingOffset);
|
||||
|
||||
public override bool IsActivateWhenEvalInstantAttack => true;
|
||||
|
||||
public AIAttackOrClashBarrierBase(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
InitExprList(text);
|
||||
_stopTiming = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - _stopTimingOffset]);
|
||||
_damageType = AIPlayTagInitializingUtility.GetDamageTypeFromExprList(_exprList[_exprList.Count - _defaultDamageTypeOffset], out _isDamageTypeDefinedByMaster);
|
||||
InitSelectType();
|
||||
InitializeFilter();
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0 && base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
GiveBarrierToAllTargets(targetsFromField, tagOwner, field, playPtn, situation);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanKillTarget(AIVirtualCard tagOwner, AIVirtualCard target, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, AIBarrierPseudoSimulationInfo simBarrier, ref int totalDamage)
|
||||
{
|
||||
PseudoSimulateWhenAttackDamageToCertainCard(tagOwner, target, field, situation, playPtn, simBarrier);
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int PseudoSimulateWhenAttackDamageToCertainCard(AIVirtualCard tagOwner, AIVirtualCard damageTarget, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, AIBarrierPseudoSimulationInfo simBarrier)
|
||||
{
|
||||
if (situation == null || situation.ActionType != AIOperationType.ATTACK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (AIFilteringUtility.CheckMatchTargetFiltering(simBarrier.Owner, null, base.Filters, playPtn, tagOwner, situation))
|
||||
{
|
||||
PseudoGiveBarrierToCertainTarget(simBarrier, tagOwner, field, playPtn, situation);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected abstract void GiveBarrierToAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation);
|
||||
|
||||
protected abstract void PseudoGiveBarrierToCertainTarget(AIBarrierPseudoSimulationInfo simBarrier, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackOrClashDamageClip : AIAttackOrClashBarrierBase
|
||||
{
|
||||
private AIPolishConvertedExpression _clipAmount;
|
||||
|
||||
private const int CLIP_AMOUNT_OFFSET = 1;
|
||||
|
||||
protected override int _defaultDamageTypeOffset => 3;
|
||||
|
||||
protected override int _stopTimingOffset => 2;
|
||||
|
||||
public AIAttackOrClashDamageClip(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_clipAmount = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
protected override void GiveBarrierToAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
int clipAmount = (int)_clipAmount.EvalArg(tagOwner, playPtn, field, situation);
|
||||
AIBarrierSimulationUtility.AddDamageClipToAll(targets, tagOwner, field, _damageType, _stopTiming, clipAmount);
|
||||
}
|
||||
|
||||
protected override void PseudoGiveBarrierToCertainTarget(AIBarrierPseudoSimulationInfo simBarrier, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
int clipAmount = (int)_clipAmount.EvalArg(tagOwner, playPtn, field, situation);
|
||||
AIDamageType damageTypeFromArgType = AIBarrierSimulationUtility.GetDamageTypeFromArgType(_damageType);
|
||||
AIBarrierStopTiming barrierStopTimingFromArgType = AIBarrierSimulationUtility.GetBarrierStopTimingFromArgType(_stopTiming, tagOwner);
|
||||
AIBarrierSimulationUtility.PseudoAddDamageClipToSingle(simBarrier, damageTypeFromArgType, barrierStopTimingFromArgType, clipAmount);
|
||||
}
|
||||
|
||||
public override void PseudoSimulateForEvalInstantAttack(AIVirtualCard tagOwner, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, EvalInstantAttackInformation information)
|
||||
{
|
||||
int clipAmount = (int)_clipAmount.EvalArg(tagOwner, playPtn, field, situation);
|
||||
AIDamageType damageTypeFromArgType = AIBarrierSimulationUtility.GetDamageTypeFromArgType(_damageType);
|
||||
AIBarrierStopTiming barrierStopTimingFromArgType = AIBarrierSimulationUtility.GetBarrierStopTimingFromArgType(_stopTiming, tagOwner);
|
||||
if (AIFilteringUtility.CheckMatchTargetFiltering(information.AttackerBarrierInfo.Owner, null, base.Filters, playPtn, tagOwner, situation))
|
||||
{
|
||||
AIBarrierSimulationUtility.PseudoAddDamageClipToSingle(information.AttackerBarrierInfo, damageTypeFromArgType, barrierStopTimingFromArgType, clipAmount);
|
||||
}
|
||||
if (AIFilteringUtility.CheckMatchTargetFiltering(information.TargetBarrierInfo.Owner, null, base.Filters, playPtn, tagOwner, situation))
|
||||
{
|
||||
AIBarrierSimulationUtility.PseudoAddDamageClipToSingle(information.TargetBarrierInfo, damageTypeFromArgType, barrierStopTimingFromArgType, clipAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
SVSim.BattleEngine/Engine/Wizard/AIAttackOrClashHeal.cs
Normal file
41
SVSim.BattleEngine/Engine/Wizard/AIAttackOrClashHeal.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackOrClashHeal : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _healValueArg;
|
||||
|
||||
private const int HEAL_VALUE_OFFSET = 1;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public AIAttackOrClashHeal(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_healValueArg = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
int heal = (int)_healValueArg.EvalArg(tagOwner, playPtn, field, situation);
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AISkillSimulationUtility.HealAll(targetsFromField, field, heal, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackOrClashKeywordSkill : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private readonly AIScriptTokenArgType _skillType;
|
||||
|
||||
public AIAttackOrClashKeywordSkill(string text, AIScriptTokenArgType skill)
|
||||
: base(text)
|
||||
{
|
||||
_skillType = skill;
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0 && base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AISkillSimulationUtility.GiveSkillToAll(targetsFromField, field, _skillType);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.AllReferableCards;
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForFollowerOnly(candidates, tagOwner, base.Filters, playPtn, situation, isBlockDead);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackOrClashRemoveSkill : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
public AIAttackOrClashRemoveSkill(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
AIScriptTokenArgType selectType = base.SelectType;
|
||||
if (selectType != AIScriptTokenArgType.RANDOM_SELECT && selectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIRemoveSkillSimulationUtility.RemoveSkillAll(targetsFromField, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
SVSim.BattleEngine/Engine/Wizard/AIAttackOrClashRemoveTag.cs
Normal file
36
SVSim.BattleEngine/Engine/Wizard/AIAttackOrClashRemoveTag.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackOrClashRemoveTag : AIWhenAttackOrWhenFightTagArgument, IAIRemoveTagArgument
|
||||
{
|
||||
private const int NEEDS_SPLITED_WORDS_LENGS = 3;
|
||||
|
||||
private const int REMOVE_TAG_START_SPLITED_INDEX = 0;
|
||||
|
||||
public AIPlayTag RemoveTag { get; private set; }
|
||||
|
||||
public AIAttackOrClashRemoveTag(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
List<string> list = AIPlayTagInitializingUtility.SplitTagText(text);
|
||||
if (list == null || list.Count < 3)
|
||||
{
|
||||
AIConsoleUtility.LogError("AIClashRemoveTag error!! splitedText.Length is not enough");
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveTag = AIPlayTagInitializingUtility.CreateAIPlayTagFromWords(list[0], list[1], list[2]);
|
||||
}
|
||||
}
|
||||
|
||||
public void Execute(AIVirtualCard tagOwner, AIVirtualField field, AISituationInfo situation, AIPlayTag ownerTag, List<int> playPtn = null)
|
||||
{
|
||||
AIRemoveTagUtility.RemoveOneTag(tagOwner, field, RemoveTag, situation);
|
||||
AIRemoveTagUtility.RemoveOneTag(tagOwner, field, ownerTag, situation);
|
||||
}
|
||||
}
|
||||
52
SVSim.BattleEngine/Engine/Wizard/AIAttackOrClashShield.cs
Normal file
52
SVSim.BattleEngine/Engine/Wizard/AIAttackOrClashShield.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackOrClashShield : AIAttackOrClashBarrierBase
|
||||
{
|
||||
private List<AIScriptTokenArgType> _stopTimingList;
|
||||
|
||||
protected override int _defaultDamageTypeOffset => 2;
|
||||
|
||||
protected override int _stopTimingOffset => 1;
|
||||
|
||||
public AIAttackOrClashShield(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
InitExprList(text);
|
||||
_stopTimingList = AIPlayTagInitializingUtility.InitializeStopTimingList(_exprList[_exprList.Count - _stopTimingOffset]);
|
||||
_damageType = AIPlayTagInitializingUtility.GetDamageTypeFromExprList(_exprList[_exprList.Count - _defaultDamageTypeOffset], out _isDamageTypeDefinedByMaster);
|
||||
InitSelectType();
|
||||
InitializeFilter();
|
||||
}
|
||||
|
||||
protected override void GiveBarrierToAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIBarrierSimulationUtility.AddMultipleStopTimingShieldToAll(targets, tagOwner, field, _damageType, _stopTimingList);
|
||||
}
|
||||
|
||||
protected override void PseudoGiveBarrierToCertainTarget(AIBarrierPseudoSimulationInfo simBarrier, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIDamageType damageTypeFromArgType = AIBarrierSimulationUtility.GetDamageTypeFromArgType(_damageType);
|
||||
List<AIBarrierStopTiming> barrierStopTimingListFromArgType = AIBarrierSimulationUtility.GetBarrierStopTimingListFromArgType(_stopTimingList, tagOwner);
|
||||
AIBarrierSimulationUtility.PseudoAddMultipleStopTimingShieldToSingle(simBarrier, damageTypeFromArgType, barrierStopTimingListFromArgType);
|
||||
}
|
||||
|
||||
public override void PseudoSimulateForEvalInstantAttack(AIVirtualCard tagOwner, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, EvalInstantAttackInformation information)
|
||||
{
|
||||
AIDamageType damageTypeFromArgType = AIBarrierSimulationUtility.GetDamageTypeFromArgType(_damageType);
|
||||
List<AIBarrierStopTiming> barrierStopTimingListFromArgType = AIBarrierSimulationUtility.GetBarrierStopTimingListFromArgType(_stopTimingList, tagOwner);
|
||||
if (AIFilteringUtility.CheckMatchTargetFiltering(information.AttackerBarrierInfo.Owner, null, base.Filters, playPtn, tagOwner, situation))
|
||||
{
|
||||
AIBarrierSimulationUtility.PseudoAddMultipleStopTimingShieldToSingle(information.AttackerBarrierInfo, damageTypeFromArgType, barrierStopTimingListFromArgType);
|
||||
}
|
||||
if (AIFilteringUtility.CheckMatchTargetFiltering(information.TargetBarrierInfo.Owner, null, base.Filters, playPtn, tagOwner, situation))
|
||||
{
|
||||
AIBarrierSimulationUtility.PseudoAddMultipleStopTimingShieldToSingle(information.TargetBarrierInfo, damageTypeFromArgType, barrierStopTimingListFromArgType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackOrClashSpellboost : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _spellboostValue;
|
||||
|
||||
private const int SPELLBOOST_VALUE_OFFSET = 1;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public AIAttackOrClashSpellboost(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_spellboostValue = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.GetSimulationHandCards();
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForSpellboost(candidates, tagOwner, base.Filters, playPtn, situation);
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
int count = (int)_spellboostValue.EvalArg(tagOwner, playPtn, field, situation);
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AISpellboostSimulationUtility.SpellboostAll(targetsFromField, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
45
SVSim.BattleEngine/Engine/Wizard/AIAttackOrClashToken.cs
Normal file
45
SVSim.BattleEngine/Engine/Wizard/AIAttackOrClashToken.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackOrClashToken : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _tokenCount;
|
||||
|
||||
private const int TOKEN_COUNT_OFFSET = 1;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 1;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 0;
|
||||
|
||||
public AIAttackOrClashToken(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_tokenCount = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
protected override void InitSelectType()
|
||||
{
|
||||
base.SelectType = AIScriptTokenArgType.ALL_SELECT;
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
AISummonTokenUtility.ExecuteSummonToken(GetTargetsFromField(tagOwner, field, playPtn, situation, isBlockDead: false), base.Filters, _tokenCount, AIScriptTokenArgType.ALLY, tagOwner, field, playPtn, situation);
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetTargetsFromField(AIVirtualCard owner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return GetCandidateRange(field);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
}
|
||||
118
SVSim.BattleEngine/Engine/Wizard/AIAttackSetStatus.cs
Normal file
118
SVSim.BattleEngine/Engine/Wizard/AIAttackSetStatus.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackSetStatus : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _attackExpression;
|
||||
|
||||
private AIPolishConvertedExpression _lifeExpression;
|
||||
|
||||
private readonly int ATTACK_ARG_OFFSET = 2;
|
||||
|
||||
private readonly int LIFE_ARG_OFFSET = 1;
|
||||
|
||||
private bool _isSetAttack;
|
||||
|
||||
private bool _isSetLife;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 3;
|
||||
|
||||
public AIAttackSetStatus(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_attackExpression = _exprList[_exprList.Count - ATTACK_ARG_OFFSET];
|
||||
_lifeExpression = _exprList[_exprList.Count - LIFE_ARG_OFFSET];
|
||||
_isSetAttack = !AISetStatusSimulationUtility.IsNoneSetValue(_attackExpression);
|
||||
_isSetLife = !AISetStatusSimulationUtility.IsNoneSetValue(_lifeExpression);
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0 && base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
ExecuteSetStatusToAll(targetsFromField, tagOwner, field, playPtn, situation);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteSetStatusToAll(List<AIVirtualCard> targetList, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
int attack = (_isSetAttack ? ((int)_attackExpression.EvalArg(tagOwner, playPtn, field, situation)) : 0);
|
||||
int newLife = (_isSetLife ? ((int)_lifeExpression.EvalArg(tagOwner, playPtn, field, situation)) : 0);
|
||||
for (int i = 0; i < targetList.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = targetList[i];
|
||||
if (_isSetAttack)
|
||||
{
|
||||
aIVirtualCard.SetAttack(attack);
|
||||
}
|
||||
if (_isSetLife)
|
||||
{
|
||||
aIVirtualCard.SetLife(newLife, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanKillTarget(AIVirtualCard tagOwner, AIVirtualCard target, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, AIBarrierPseudoSimulationInfo simBarrier, ref int totalDamage)
|
||||
{
|
||||
if (!_isSetLife)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (AIFilteringUtility.CheckMatchTargetFiltering(target, GetCandidateRange(field), base.Filters, playPtn, tagOwner, situation))
|
||||
{
|
||||
int num = (int)_lifeExpression.EvalArg(tagOwner, playPtn, field, situation);
|
||||
int num2 = target.Life - totalDamage;
|
||||
totalDamage = num2 - num;
|
||||
if (num <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CanKillAnyTarget(AIVirtualCard tagOwner, List<AIVirtualCard> targetList, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, List<AIBarrierPseudoSimulationInfo> simBarrierList, int[] realDamageList)
|
||||
{
|
||||
if (!_isSetLife)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (targetList == null || targetList.Count <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < simBarrierList.Count; i++)
|
||||
{
|
||||
AIBarrierPseudoSimulationInfo aIBarrierPseudoSimulationInfo = simBarrierList[i];
|
||||
AIVirtualCard owner = aIBarrierPseudoSimulationInfo.Owner;
|
||||
int totalDamage = realDamageList[i];
|
||||
if (CanKillTarget(tagOwner, owner, field, situation, playPtn, aIBarrierPseudoSimulationInfo, ref totalDamage))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective: true, isBlockDead);
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
}
|
||||
156
SVSim.BattleEngine/Engine/Wizard/AIAttackSimulationUtility.cs
Normal file
156
SVSim.BattleEngine/Engine/Wizard/AIAttackSimulationUtility.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public static class AIAttackSimulationUtility
|
||||
{
|
||||
public static bool IsUsePreCheckBuff(AIPlayTag tag, AIVirtualAttackInfo situation)
|
||||
{
|
||||
if (!situation.IsUsePreCheck || tag.Type != AIPlayTagType.AttackBuff)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
AIAttackPreCheckInformation preCheckInformation = situation.PreCheckInformation;
|
||||
if (preCheckInformation.HasBuffInfo)
|
||||
{
|
||||
return preCheckInformation.HasPreCheckBuffInfo(tag);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void SimulateAttackIfValuable(AIVirtualAttackInfo situation, AIVirtualField field, bool useAttackLeaderPreCheck, ref bool isAttackerUsed)
|
||||
{
|
||||
AIVirtualCard actor = situation.Actor;
|
||||
AIVirtualCard attackTarget = situation.AttackTarget;
|
||||
situation.IsAttackSuccessed = false;
|
||||
AIVirtualCard allyClass = field.AllyClass;
|
||||
int attackDamageToCertainCard = AIAttackTagSimulator.GetAttackDamageToCertainCard(field, situation, allyClass);
|
||||
if (field.AllyClass.SimulateDamageAmount(attackDamageToCertainCard, isSkillDamage: true) >= allyClass.Life)
|
||||
{
|
||||
isAttackerUsed = true;
|
||||
return;
|
||||
}
|
||||
if (AIDiscardUtility.CheckAttackDiscardTargetInPlayPtn(actor.SelfField, field.BestPlayPtn, situation))
|
||||
{
|
||||
isAttackerUsed = true;
|
||||
return;
|
||||
}
|
||||
if (attackTarget.IsLeader)
|
||||
{
|
||||
int attackDamageToCertainCard2 = AIAttackTagSimulator.GetAttackDamageToCertainCard(field, situation, actor);
|
||||
AISimulationBuffInfoCollection buffInfoListWhenCertainAttack = AIAttackTagSimulator.GetBuffInfoListWhenCertainAttack(field, situation);
|
||||
float attackBonus = actor.GetAttackBonus(field.BestPlayPtn, situation);
|
||||
AISimulationBuffInfo buffInfo = buffInfoListWhenCertainAttack?.GetBuffInfoToCertainCard(actor);
|
||||
if (useAttackLeaderPreCheck && !IsExecuteAttackValuable(field, actor, actor.Attack, actor.Life, attackDamageToCertainCard2, buffInfo, attackBonus))
|
||||
{
|
||||
isAttackerUsed = true;
|
||||
return;
|
||||
}
|
||||
AIAttackPreCheckInformation preCheckInformation = new AIAttackPreCheckInformation(attackBonus, buffInfoListWhenCertainAttack);
|
||||
situation.SetPreCheckInformation(preCheckInformation);
|
||||
}
|
||||
AIVirtualAttackSimulator.Attack(situation, field);
|
||||
if (actor.IsDead || !actor.IsAttackable(EnemyAI.EmptyPlayPtn))
|
||||
{
|
||||
isAttackerUsed = true;
|
||||
}
|
||||
if (!field.CardListSet.HasAttackableClassHolder)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < field.CardListSet.AttackableClassHolders.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = field.CardListSet.AttackableClassHolders[i];
|
||||
if (aIVirtualCard.IsUnit && !aIVirtualCard.IsDead)
|
||||
{
|
||||
aIVirtualCard.TagCollectionContainer.AttackableClassTags.ChangeAttackableClassStatus(aIVirtualCard, field, field.BestPlayPtn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsAttackPossible(AIVirtualField field, AIVirtualAttackInfo attackSituation, List<AIVirtualCard> replacedEnemyInplayCards = null)
|
||||
{
|
||||
if (attackSituation == null || attackSituation.ActionType != AIOperationType.ATTACK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
AIVirtualCard actor = attackSituation.Actor;
|
||||
AIVirtualCard attackTarget = attackSituation.AttackTarget;
|
||||
if (actor.IsDead || attackTarget.IsDead || !actor.IsAttackable(EnemyAI.EmptyPlayPtn))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool flag = attackTarget == field.EnemyClass;
|
||||
if (actor.IsSkillCantAttackUnit)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
return !actor.IsCantAttackClass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (flag && actor.IsCantAttackClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(actor.IsAlly ? field.AllyInplayCards : field.EnemyInplayCards).Contains(actor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (attackTarget.IsAmulet || attackTarget.IsCantUnderAttack(field.ParamQuery, actor, null, field))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (actor.IsCannotAttackByTag(attackSituation))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
List<AIVirtualCard> list = ((!actor.IsAlly) ? field.AllyInplayCards : ((replacedEnemyInplayCards == null) ? field.EnemyInplayCards : replacedEnemyInplayCards));
|
||||
bool flag2 = false;
|
||||
if (list != null)
|
||||
{
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = list[i];
|
||||
if (aIVirtualCard.IsGuard && !aIVirtualCard.IsDead && !aIVirtualCard.IsCantUnderAttack(field.ParamQuery, actor, null, field))
|
||||
{
|
||||
flag2 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool isGuard = attackTarget.IsGuard;
|
||||
if (flag2 && !actor.IsIgnoreGuard && !isGuard)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!flag && actor.IsSkillCantAtkUnitNotHasGuard && !isGuard)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsExecuteAttackValuable(AIVirtualField field, AIVirtualCard attacker, int attack, int life, int preDamage, AISimulationBuffInfo buffInfo, float attackBonus)
|
||||
{
|
||||
int num = attack;
|
||||
int num2 = life;
|
||||
num2 -= preDamage;
|
||||
if (buffInfo != null)
|
||||
{
|
||||
num += buffInfo.TotalAttackBuff;
|
||||
num2 += buffInfo.TotalLifeBuff;
|
||||
}
|
||||
if (num2 > 0 && num > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
float num3 = attackBonus;
|
||||
if (num2 <= 0)
|
||||
{
|
||||
float num4 = attacker.EvaluateBreakValue(field.BestPlayPtn, useIgnoreBreak: true) + attacker.EvaluateLeaveValue(field.BestPlayPtn, useIgnoreInBattle: true);
|
||||
num3 += num4 - attacker.Value;
|
||||
}
|
||||
return num3 > 0f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIAttackSubtractCountdown : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _countChange;
|
||||
|
||||
private const int COUNT_CHANGE_ARG_OFFSET = 1;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public AIAttackSubtractCountdown(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_countChange = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
int value = (int)_countChange.EvalArg(tagOwner, playPtn, field, situation);
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AISubtractCountdownSimulationUtility.SubtractCountdownAll(targetsFromField, value, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForCountdownAmuletOnly(candidates, tagOwner, base.Filters, playPtn, situation, isBlockDead);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.AllyInplayCards;
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
}
|
||||
115
SVSim.BattleEngine/Engine/Wizard/AIAttackTagSimulator.cs
Normal file
115
SVSim.BattleEngine/Engine/Wizard/AIAttackTagSimulator.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public static class AIAttackTagSimulator
|
||||
{
|
||||
public static int GetAttackDamageToCertainCard(AIVirtualField field, AIVirtualAttackInfo situation, AIVirtualCard damageTarget)
|
||||
{
|
||||
if (damageTarget.IsIndependent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int num = 0;
|
||||
AIVirtualCard actor = situation.Actor;
|
||||
List<int> bestPlayPtn = field.BestPlayPtn;
|
||||
AIBarrierPseudoSimulationInfo aIBarrierPseudoSimulationInfo = new AIBarrierPseudoSimulationInfo(damageTarget);
|
||||
num += actor.GetAttackDamageToCertainTarget(situation, field, bestPlayPtn, aIBarrierPseudoSimulationInfo);
|
||||
if (field.CardListSet.HasOtherAttackDamage())
|
||||
{
|
||||
for (int i = 0; i < field.CardListSet.OtherAttackDamageHolders.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = field.CardListSet.OtherAttackDamageHolders[i];
|
||||
if (aIVirtualCard.TagCollectionContainer.HasTag(AIPlayTagType.OtherAttackDamage))
|
||||
{
|
||||
num += aIVirtualCard.TagCollectionContainer.OtherAttackTags.GetAttackDamageToCertainTarget(aIVirtualCard, field, bestPlayPtn, situation, aIBarrierPseudoSimulationInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
public static AISimulationBuffInfoCollection GetBuffInfoListWhenCertainAttack(AIVirtualField field, AISituationInfo situation)
|
||||
{
|
||||
AISimulationBuffInfoCollection aISimulationBuffInfoCollection = new AISimulationBuffInfoCollection();
|
||||
AIVirtualCard actor = situation.Actor;
|
||||
AIPreprocessSimulationUtility.SimulatePreprocess(actor, situation, field, AIScriptTokenArgType.WHEN_ATTACK, isPseudo: true);
|
||||
if (actor.TagCollectionContainer.HasTag(AIPlayTagType.AttackBuff))
|
||||
{
|
||||
actor.TagCollectionContainer.AttackTags.RegisterBuffInfoToCollection(field, actor, situation, aISimulationBuffInfoCollection);
|
||||
}
|
||||
if (field.CardListSet.HasOtherAttackBuffHolder)
|
||||
{
|
||||
for (int i = 0; i < field.CardListSet.OtherAttackBuffTagHolders.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = field.CardListSet.OtherAttackBuffTagHolders[i];
|
||||
if (!aIVirtualCard.IsSameCard(actor) && aIVirtualCard.TagCollectionContainer.HasTag(AIPlayTagType.OtherAttackBuff))
|
||||
{
|
||||
aIVirtualCard.TagCollectionContainer.OtherAttackTags.RegisterBuffInfoToCollection(field, aIVirtualCard, situation, aISimulationBuffInfoCollection);
|
||||
}
|
||||
}
|
||||
}
|
||||
AIPreprocessSimulationUtility.ResetPreprocess(situation, field);
|
||||
return aISimulationBuffInfoCollection;
|
||||
}
|
||||
|
||||
public static void ExecuteAttackByLife(AIVirtualField field, AIVirtualCard attacker, AIVirtualCard target, ref int attackerAtk, ref int targetAtk)
|
||||
{
|
||||
attacker.AttackByLifeCount = 0;
|
||||
target.AttackByLifeCount = 0;
|
||||
List<AIVirtualCard> tagHolders = field.CardListSet.GetTagHolders(CardListsForReference.TagHolderReferenceType.AttackByLife);
|
||||
if (tagHolders == null || tagHolders.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < tagHolders.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = tagHolders[i];
|
||||
if (!aIVirtualCard.IsDead && aIVirtualCard.TagCollectionContainer.HasTag(AIPlayTagType.AttackByLife))
|
||||
{
|
||||
AttackByLifeTagCollection attackByLifeTags = aIVirtualCard.TagCollectionContainer.AttackByLifeTags;
|
||||
if (attacker.AttackByLifeCount <= 0)
|
||||
{
|
||||
attackerAtk = attackByLifeTags.GetRealAttack(aIVirtualCard, attacker, attackerAtk);
|
||||
}
|
||||
if (target.AttackByLifeCount <= 0)
|
||||
{
|
||||
targetAtk = attackByLifeTags.GetRealAttack(aIVirtualCard, target, targetAtk);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ApplyOtherAfterAttackOrClashTags(AIVirtualField field, AIVirtualAttackInfo situation)
|
||||
{
|
||||
if (situation == null || situation.Actor == null || situation.AttackTarget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
AIVirtualCard actor = situation.Actor;
|
||||
AIVirtualCard attackTarget = situation.AttackTarget;
|
||||
if (!actor.IsDead && actor.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenAfterAttack))
|
||||
{
|
||||
actor.TagCollectionContainer.AfterAttackTags.RegisterConditionPassedTags(actor, field, situation);
|
||||
}
|
||||
if (attackTarget != null && attackTarget.IsUnit)
|
||||
{
|
||||
if (!actor.IsDead && actor.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenAfterClash))
|
||||
{
|
||||
actor.TagCollectionContainer.AfterClashTags.RegisterConditionPassedTags(actor, field, situation);
|
||||
}
|
||||
if (!attackTarget.IsDead && attackTarget.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenAfterClash))
|
||||
{
|
||||
attackTarget.TagCollectionContainer.AfterClashTags.RegisterConditionPassedTags(attackTarget, field, situation);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < field.CardListSet.BothClassAndInplayCards.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = field.CardListSet.BothClassAndInplayCards[i];
|
||||
if (!aIVirtualCard.IsSameCard(situation.Actor) && aIVirtualCard.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenAfterAttack))
|
||||
{
|
||||
aIVirtualCard.TagCollectionContainer.AfterAttackTags.RegisterConditionPassedTags(aIVirtualCard, field, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public static class AIAutoEvolutionSimulationUtility
|
||||
{
|
||||
public static void AutoEvolution(AIVirtualField field, List<AIVirtualCard> targets, List<int> playPtn, AISituationInfo situation, AIScriptTokenArgType selecyType)
|
||||
{
|
||||
switch (selecyType)
|
||||
{
|
||||
case AIScriptTokenArgType.RANDOM_SELECT:
|
||||
AutoEvolveRandom(targets, field, playPtn, situation);
|
||||
break;
|
||||
case AIScriptTokenArgType.ALL_SELECT:
|
||||
AutoEvolveAll(targets, field, situation);
|
||||
break;
|
||||
case AIScriptTokenArgType.TARGET_SELECT:
|
||||
case AIScriptTokenArgType.SECOND_TARGET_SELECT:
|
||||
AutoEvolveTarget(situation, field, targets, selecyType);
|
||||
break;
|
||||
case AIScriptTokenArgType.RANDOM_MULTI_SELECT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void AutoEvolveRandom(List<AIVirtualCard> targets, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = targets.FindMin((AIVirtualCard c) => c.EvaluateValueOnField(playPtn, situation, useStyle: true, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true) * (float)(c.IsAlly ? 1 : (-1)));
|
||||
if (aIVirtualCard != null)
|
||||
{
|
||||
AutoEvolveSingle(aIVirtualCard, field, situation);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AutoEvolveAll(List<AIVirtualCard> targets, AIVirtualField field, AISituationInfo situation)
|
||||
{
|
||||
List<AIVirtualCard> list = null;
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = targets[i];
|
||||
if (!aIVirtualCard.IsEvolution && !aIVirtualCard.IsDead)
|
||||
{
|
||||
list = AIParamQuery.AddElementToList(aIVirtualCard, list);
|
||||
}
|
||||
}
|
||||
if (list != null && list.Count > 0)
|
||||
{
|
||||
for (int j = 0; j < list.Count; j++)
|
||||
{
|
||||
AIVirtualEvolutionSimulator.AutoEvolve(list[j], field, situation);
|
||||
}
|
||||
field.AllActivateCountHolderIncrement(situation, AIPlayTagType.EvoActivateCount, list);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AutoEvolveTarget(AISituationInfo situation, AIVirtualField field, List<AIVirtualCard> candidates, AIScriptTokenArgType whichTarget)
|
||||
{
|
||||
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
|
||||
if (situationTarget == null || !situationTarget.HasTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
List<AIVirtualCard> targets = situationTarget.Targets;
|
||||
List<AIVirtualCard> list = null;
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = targets[i];
|
||||
if (candidates.Contains(aIVirtualCard) && !aIVirtualCard.IsEvolution)
|
||||
{
|
||||
list = AIParamQuery.AddElementToList(aIVirtualCard, list);
|
||||
}
|
||||
}
|
||||
if (list != null && list.Count > 0)
|
||||
{
|
||||
AutoEvolveAll(list, field, situation);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AutoEvolveSingle(AIVirtualCard target, AIVirtualField field, AISituationInfo situation)
|
||||
{
|
||||
if (!target.IsEvolution && !target.IsDead)
|
||||
{
|
||||
AIVirtualEvolutionSimulator.AutoEvolve(target, field, situation);
|
||||
field.AllActivateCountHolderIncrement(situation, AIPlayTagType.EvoActivateCount, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
SVSim.BattleEngine/Engine/Wizard/AIBanishAttachTag.cs
Normal file
57
SVSim.BattleEngine/Engine/Wizard/AIBanishAttachTag.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBanishAttachTag : AITargetSelectTagArgument
|
||||
{
|
||||
private AIScriptTokenArgType _removeTiming;
|
||||
|
||||
private readonly int REMOVE_TIMING_OFFSET = 1;
|
||||
|
||||
private const int TAG_WORD_START_INDEX = 1;
|
||||
|
||||
public AIPlayTag Tag { get; private set; }
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public AIBanishAttachTag(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
List<string> list = AIPlayTagInitializingUtility.SplitTagText(text);
|
||||
base.InitExpressions(list[0]);
|
||||
_removeTiming = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - REMOVE_TIMING_OFFSET]);
|
||||
Tag = AIPlayTagInitializingUtility.CreateAIPlayTagFromWords(list[1], list[2], list[3]);
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0 && base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIAttachTagSimulationUtility.SimulateAttachTagToAll(targetsFromField, tagOwner, Tag, _removeTiming, situation);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.AllReferableCards;
|
||||
}
|
||||
|
||||
public override AITokenIdCollection GetAllRegisterTokenPoolInfo(AIVirtualCard owner)
|
||||
{
|
||||
if (Tag != null)
|
||||
{
|
||||
return Tag.ArgumentExpressions.GetAllRegisterTokenPoolInfo(owner);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBarrierAfterDamageStopInformation : AIAfterDamageStopInformation
|
||||
{
|
||||
private ulong _barrierHash;
|
||||
|
||||
public AIBarrierAfterDamageStopInformation(AIBarrierStopPreprocessOption option)
|
||||
: base(option.TargetCard)
|
||||
{
|
||||
_barrierHash = option.BarrierHash;
|
||||
base.Type = AITagPreprocessInfoType.BARRIER_STOP;
|
||||
}
|
||||
|
||||
protected override void StopMethod()
|
||||
{
|
||||
base.TargetCard.BarrierInfoCollection.DepriveCertainBarrier(_barrierHash, AIBarrierStopTiming.AfterDamage);
|
||||
}
|
||||
|
||||
public override AITagPreprocessCreationOptionBase CreateOptionInfoForOverride(AIVirtualCard overridedTarget)
|
||||
{
|
||||
return new AIBarrierStopPreprocessOption(overridedTarget, _barrierHash);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBarrierLeaveStopInformation : AILeaveStopInformation
|
||||
{
|
||||
private ulong _barrierHash;
|
||||
|
||||
public AIBarrierLeaveStopInformation(AIBarrierStopPreprocessOption option, AIVirtualCard provider)
|
||||
: base(option.TargetCard, provider)
|
||||
{
|
||||
_barrierHash = option.BarrierHash;
|
||||
base.Type = AITagPreprocessInfoType.BARRIER_STOP;
|
||||
}
|
||||
|
||||
protected override void StopMethod(AISituationInfo situation)
|
||||
{
|
||||
base.TargetCard.BarrierInfoCollection.DepriveCertainBarrier(_barrierHash, AIBarrierStopTiming.WhenLeaveStop);
|
||||
}
|
||||
|
||||
protected override void PseudoStopMethodForEvalRandomMultiDamage(List<AIBarrierPseudoSimulationInfo> barrierInfoList)
|
||||
{
|
||||
for (int i = 0; i < barrierInfoList.Count; i++)
|
||||
{
|
||||
AIBarrierPseudoSimulationInfo aIBarrierPseudoSimulationInfo = barrierInfoList[i];
|
||||
if (aIBarrierPseudoSimulationInfo.Owner.IsSameCard(base.TargetCard))
|
||||
{
|
||||
aIBarrierPseudoSimulationInfo.DepriveCertainBarrier(AIBarrierStopTiming.WhenLeaveStop, _barrierHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override AITagPreprocessCreationOptionBase CreateOptionInfoForOverride(AIVirtualCard overridedTarget)
|
||||
{
|
||||
return new AIBarrierStopPreprocessOption(overridedTarget, _barrierHash);
|
||||
}
|
||||
}
|
||||
296
SVSim.BattleEngine/Engine/Wizard/AIBarrierSimulationUtility.cs
Normal file
296
SVSim.BattleEngine/Engine/Wizard/AIBarrierSimulationUtility.cs
Normal file
@@ -0,0 +1,296 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public static class AIBarrierSimulationUtility
|
||||
{
|
||||
public static AIScriptTokenArgType[] LegalBarrierType = new AIScriptTokenArgType[2]
|
||||
{
|
||||
AIScriptTokenArgType.DAMAGE_CUT,
|
||||
AIScriptTokenArgType.DAMAGE_CLIP
|
||||
};
|
||||
|
||||
public static AIScriptTokenArgType[] LegalDamageType = new AIScriptTokenArgType[4]
|
||||
{
|
||||
AIScriptTokenArgType.ALL_DAMAGE,
|
||||
AIScriptTokenArgType.SKILL_DAMAGE,
|
||||
AIScriptTokenArgType.ATTACK_DAMAGE,
|
||||
AIScriptTokenArgType.SPELL_DAMAGE
|
||||
};
|
||||
|
||||
public static AIScriptTokenArgType[] LegalStopTimingList = new AIScriptTokenArgType[7]
|
||||
{
|
||||
AIScriptTokenArgType.WHEN_ALLY_TURNEND,
|
||||
AIScriptTokenArgType.WHEN_ALLY_TURNSTART,
|
||||
AIScriptTokenArgType.WHEN_OPPONENT_TURNEND,
|
||||
AIScriptTokenArgType.WHEN_OPPONENT_TURNSTART,
|
||||
AIScriptTokenArgType.WHEN_DAMAGED,
|
||||
AIScriptTokenArgType.WHEN_LEAVE,
|
||||
AIScriptTokenArgType.NONE
|
||||
};
|
||||
|
||||
public static ulong BARRIER_AMOUNT_HASH_COEFFICIENT = 137uL;
|
||||
|
||||
public static ulong DAMAGE_TYPE_HASH_COEFFICIENT = 199uL;
|
||||
|
||||
public static ulong BARRIER_TYPE_HASH_COEFFICIENT = 223uL;
|
||||
|
||||
public static ulong DAMAGE_CLIP_RANGE_COEFFICIENT = 1109uL;
|
||||
|
||||
private static readonly ulong[] STOP_TIMING_HASH_COEFFICIENT_ARRAY = new ulong[5] { 907uL, 911uL, 919uL, 929uL, 937uL };
|
||||
|
||||
public static void AddShieldToAll(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, AIScriptTokenArgType damageTypeArgument, AIScriptTokenArgType stopTimingArgument)
|
||||
{
|
||||
AIDamageType damageTypeFromArgType = GetDamageTypeFromArgType(damageTypeArgument);
|
||||
AIBarrierStopTiming barrierStopTimingFromArgType = GetBarrierStopTimingFromArgType(stopTimingArgument, tagOwner);
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
AddShieldToSingle(targets[i], tagOwner, field, damageTypeFromArgType, barrierStopTimingFromArgType);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddShieldToSingle(AIVirtualCard card, AIVirtualCard tagOwner, AIVirtualField field, AIDamageType damageType, AIBarrierStopTiming stopTiming)
|
||||
{
|
||||
AIShieldInfo aIShieldInfo = new AIShieldInfo(damageType, stopTiming);
|
||||
card.BarrierInfoCollection.AddBarrierInfo(aIShieldInfo);
|
||||
RegisterBarrierStopPreprocess(card, tagOwner, field, stopTiming, aIShieldInfo.Hash);
|
||||
}
|
||||
|
||||
public static void AddMultipleStopTimingShieldToAll(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, AIScriptTokenArgType damageTypeArgument, List<AIScriptTokenArgType> stopTimingArgumentList)
|
||||
{
|
||||
AIDamageType damageTypeFromArgType = GetDamageTypeFromArgType(damageTypeArgument);
|
||||
List<AIBarrierStopTiming> barrierStopTimingListFromArgType = GetBarrierStopTimingListFromArgType(stopTimingArgumentList, tagOwner);
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
AddMultipleStopTimingShieldToSingle(targets[i], tagOwner, field, damageTypeFromArgType, barrierStopTimingListFromArgType);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddMultipleStopTimingShieldToTarget(AISituationInfo situation, AIScriptTokenArgType whichTarget, AIVirtualCard tagOwner, AIVirtualField field, AIScriptTokenArgType damageTypeArgument, List<AIScriptTokenArgType> stopTimingArgumentList)
|
||||
{
|
||||
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
|
||||
if (situationTarget == null || !situationTarget.HasTarget)
|
||||
{
|
||||
AIConsoleUtility.LogError("AddMultipleStopTimingShieldToTarget error!! No target!!!!!");
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMultipleStopTimingShieldToAll(situationTarget.Targets, tagOwner, field, damageTypeArgument, stopTimingArgumentList);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddMultipleStopTimingShieldToSingle(AIVirtualCard card, AIVirtualCard tagOwner, AIVirtualField field, AIDamageType damageType, List<AIBarrierStopTiming> stopTimingList)
|
||||
{
|
||||
AIShieldInfo aIShieldInfo = new AIShieldInfo(damageType, stopTimingList);
|
||||
card.BarrierInfoCollection.AddBarrierInfo(aIShieldInfo);
|
||||
if (stopTimingList != null && stopTimingList.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < stopTimingList.Count; i++)
|
||||
{
|
||||
RegisterBarrierStopPreprocess(card, tagOwner, field, stopTimingList[i], aIShieldInfo.Hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void PseudoAddMultipleStopTimingShieldToSingle(AIBarrierPseudoSimulationInfo info, AIDamageType damageType, List<AIBarrierStopTiming> stopTimingList)
|
||||
{
|
||||
AIShieldInfo barrier = new AIShieldInfo(damageType, stopTimingList);
|
||||
info.AddBarrierInfo(barrier);
|
||||
}
|
||||
|
||||
public static void AddDamageCutToAll(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, AIScriptTokenArgType damageTypeArgument, AIScriptTokenArgType stopTimingArgument, int cutAmount)
|
||||
{
|
||||
AIDamageType damageTypeFromArgType = GetDamageTypeFromArgType(damageTypeArgument);
|
||||
AIBarrierStopTiming barrierStopTimingFromArgType = GetBarrierStopTimingFromArgType(stopTimingArgument, tagOwner);
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
AddDamageCutToSingle(targets[i], tagOwner, field, damageTypeFromArgType, barrierStopTimingFromArgType, cutAmount);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddDamageCutToSingle(AIVirtualCard card, AIVirtualCard tagOwner, AIVirtualField field, AIDamageType damageType, AIBarrierStopTiming stopTiming, int cutAmount)
|
||||
{
|
||||
AIDamageCutInfo aIDamageCutInfo = new AIDamageCutInfo(cutAmount, damageType, stopTiming);
|
||||
card.BarrierInfoCollection.AddBarrierInfo(aIDamageCutInfo);
|
||||
RegisterBarrierStopPreprocess(card, tagOwner, field, stopTiming, aIDamageCutInfo.Hash);
|
||||
}
|
||||
|
||||
public static void AddDamageClipToAll(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, AIScriptTokenArgType damageTypeArgument, AIScriptTokenArgType stopTimingArgument, int clipAmount, int clipRange = 9999)
|
||||
{
|
||||
AIDamageType damageTypeFromArgType = GetDamageTypeFromArgType(damageTypeArgument);
|
||||
AIBarrierStopTiming barrierStopTimingFromArgType = GetBarrierStopTimingFromArgType(stopTimingArgument, tagOwner);
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
AddDamageClipToSingle(targets[i], tagOwner, field, damageTypeFromArgType, barrierStopTimingFromArgType, clipAmount, clipRange);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddDamageClipToSingle(AIVirtualCard card, AIVirtualCard tagOwner, AIVirtualField field, AIDamageType damageType, AIBarrierStopTiming stopTiming, int clipAmount, int clipRange)
|
||||
{
|
||||
AIDamageClippingInfo aIDamageClippingInfo = new AIDamageClippingInfo(clipAmount, clipRange, damageType, stopTiming);
|
||||
card.BarrierInfoCollection.AddBarrierInfo(aIDamageClippingInfo);
|
||||
RegisterBarrierStopPreprocess(card, tagOwner, field, stopTiming, aIDamageClippingInfo.Hash);
|
||||
}
|
||||
|
||||
public static void PseudoAddDamageClipToSingle(AIBarrierPseudoSimulationInfo info, AIDamageType damageType, AIBarrierStopTiming stopTiming, int clipAmount, int clipRange = 9999)
|
||||
{
|
||||
AIDamageClippingInfo barrier = new AIDamageClippingInfo(clipAmount, clipRange, damageType, stopTiming);
|
||||
info.AddBarrierInfo(barrier);
|
||||
}
|
||||
|
||||
public static void AddLifeLowerLimitToAll(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, AIScriptTokenArgType damageTypeArgToken, AIScriptTokenArgType stopTimingArgToken)
|
||||
{
|
||||
AIDamageType damageTypeFromArgType = GetDamageTypeFromArgType(damageTypeArgToken);
|
||||
AIBarrierStopTiming barrierStopTimingFromArgType = GetBarrierStopTimingFromArgType(stopTimingArgToken, tagOwner);
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
AddLifeLowerLimitToSingle(targets[i], tagOwner, field, damageTypeFromArgType, barrierStopTimingFromArgType);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddLifeLowerLimitToSingle(AIVirtualCard target, AIVirtualCard tagOwner, AIVirtualField field, AIDamageType damageType, AIBarrierStopTiming stopTiming)
|
||||
{
|
||||
AILifeLowerLimitInfo aILifeLowerLimitInfo = new AILifeLowerLimitInfo(damageType, stopTiming);
|
||||
target.BarrierInfoCollection.AddBarrierInfo(aILifeLowerLimitInfo);
|
||||
RegisterBarrierStopPreprocess(target, tagOwner, field, stopTiming, aILifeLowerLimitInfo.Hash);
|
||||
}
|
||||
|
||||
private static void RegisterBarrierStopPreprocess(AIVirtualCard target, AIVirtualCard tagOwner, AIVirtualField field, AIBarrierStopTiming stopTiming, ulong barrierHash)
|
||||
{
|
||||
AIBarrierStopPreprocessOption option = new AIBarrierStopPreprocessOption(target, barrierHash);
|
||||
switch (stopTiming)
|
||||
{
|
||||
case AIBarrierStopTiming.AllyTurnEnd:
|
||||
field.TagPreprocessContainer.AppendAllyTurnEndStopInfo(option);
|
||||
break;
|
||||
case AIBarrierStopTiming.OpponentTurnEnd:
|
||||
field.TagPreprocessContainer.AppendOpponentTurnEndStopInfo(option);
|
||||
break;
|
||||
case AIBarrierStopTiming.AllyTurnStart:
|
||||
field.TagPreprocessContainer.AppendAllyTurnStartStopInfo(option);
|
||||
break;
|
||||
case AIBarrierStopTiming.OpponentTurnStart:
|
||||
field.TagPreprocessContainer.AppendOpponentTurnStartStopInfo(option);
|
||||
break;
|
||||
case AIBarrierStopTiming.WhenLeaveStop:
|
||||
field.TagPreprocessContainer.AppendLeaveStopInfo(option, tagOwner);
|
||||
break;
|
||||
case AIBarrierStopTiming.AfterDamage:
|
||||
field.TagPreprocessContainer.AppendAfterDamageStopInfo(option);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static AIDamageType GetDamageTypeFromArgType(AIScriptTokenArgType damageTypeArgument)
|
||||
{
|
||||
switch (damageTypeArgument)
|
||||
{
|
||||
case AIScriptTokenArgType.SKILL_DAMAGE:
|
||||
return AIDamageType.Skill;
|
||||
case AIScriptTokenArgType.ATTACK_DAMAGE:
|
||||
return AIDamageType.Attack;
|
||||
case AIScriptTokenArgType.SPELL_DAMAGE:
|
||||
return AIDamageType.Spell;
|
||||
case AIScriptTokenArgType.ALL_DAMAGE:
|
||||
return AIDamageType.All;
|
||||
default:
|
||||
AIConsoleUtility.LogError("AIBarrierSimulationUtility.GetDamageTypeFromArgType() error!! argument " + damageTypeArgument.ToString() + " is illegal!!!!!");
|
||||
return AIDamageType.All;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<AIBarrierStopTiming> GetBarrierStopTimingListFromArgType(List<AIScriptTokenArgType> arguments, AIVirtualCard tagOwner)
|
||||
{
|
||||
List<AIBarrierStopTiming> list = null;
|
||||
for (int i = 0; i < arguments.Count; i++)
|
||||
{
|
||||
AIBarrierStopTiming barrierStopTimingFromArgType = GetBarrierStopTimingFromArgType(arguments[i], tagOwner);
|
||||
if (barrierStopTimingFromArgType != AIBarrierStopTiming.None)
|
||||
{
|
||||
list = AIParamQuery.AddElementToList(barrierStopTimingFromArgType, list);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static AIBarrierStopTiming GetBarrierStopTimingFromArgType(AIScriptTokenArgType argument, AIVirtualCard tagOwner)
|
||||
{
|
||||
switch (argument)
|
||||
{
|
||||
case AIScriptTokenArgType.NONE:
|
||||
return AIBarrierStopTiming.None;
|
||||
case AIScriptTokenArgType.WHEN_LEAVE:
|
||||
return AIBarrierStopTiming.WhenLeaveStop;
|
||||
case AIScriptTokenArgType.WHEN_DAMAGED:
|
||||
return AIBarrierStopTiming.AfterDamage;
|
||||
case AIScriptTokenArgType.WHEN_ALLY_TURNEND:
|
||||
if (!tagOwner.IsAlly)
|
||||
{
|
||||
return AIBarrierStopTiming.OpponentTurnEnd;
|
||||
}
|
||||
return AIBarrierStopTiming.AllyTurnEnd;
|
||||
case AIScriptTokenArgType.WHEN_OPPONENT_TURNEND:
|
||||
if (!tagOwner.IsAlly)
|
||||
{
|
||||
return AIBarrierStopTiming.AllyTurnEnd;
|
||||
}
|
||||
return AIBarrierStopTiming.OpponentTurnEnd;
|
||||
case AIScriptTokenArgType.WHEN_ALLY_TURNSTART:
|
||||
if (!tagOwner.IsAlly)
|
||||
{
|
||||
return AIBarrierStopTiming.OpponentTurnStart;
|
||||
}
|
||||
return AIBarrierStopTiming.AllyTurnStart;
|
||||
case AIScriptTokenArgType.WHEN_OPPONENT_TURNSTART:
|
||||
if (!tagOwner.IsAlly)
|
||||
{
|
||||
return AIBarrierStopTiming.AllyTurnStart;
|
||||
}
|
||||
return AIBarrierStopTiming.OpponentTurnStart;
|
||||
default:
|
||||
AIConsoleUtility.LogError("AIBarrierSimulationUtility.GetBarrierStopTimingFromArgType() error!! argument " + argument.ToString() + " is illegal!!!!!");
|
||||
return AIBarrierStopTiming.None;
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong CalculateBarrierInfoBaseHash(AIDamageType damageType, AIBarrierType barrierType, List<AIBarrierStopTiming> stopTimingList)
|
||||
{
|
||||
ulong num = 0uL;
|
||||
num += (ulong)((long)damageType * (long)DAMAGE_TYPE_HASH_COEFFICIENT);
|
||||
num += (ulong)((long)barrierType * (long)BARRIER_TYPE_HASH_COEFFICIENT);
|
||||
if (stopTimingList != null && stopTimingList.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < stopTimingList.Count; i++)
|
||||
{
|
||||
int num2 = i % 5;
|
||||
num += (ulong)((long)stopTimingList[i] * (long)STOP_TIMING_HASH_COEFFICIENT_ARRAY[num2]);
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
public static ulong CalculateBarrierInfoBaseHash(AIDamageType damageType, AIBarrierType barrierType, AIBarrierStopTiming stopTiming)
|
||||
{
|
||||
return (ulong)(0 + (long)damageType * (long)DAMAGE_TYPE_HASH_COEFFICIENT + (long)barrierType * (long)BARRIER_TYPE_HASH_COEFFICIENT + (long)stopTiming * (long)STOP_TIMING_HASH_COEFFICIENT_ARRAY[0]);
|
||||
}
|
||||
|
||||
public static ulong CalculateDamageCutInfoHash(AIDamageType damageType, AIBarrierType barrierType, List<AIBarrierStopTiming> stopTimingList, int cutAmount)
|
||||
{
|
||||
return CalculateBarrierInfoBaseHash(damageType, barrierType, stopTimingList) + (ulong)((long)cutAmount * (long)BARRIER_AMOUNT_HASH_COEFFICIENT);
|
||||
}
|
||||
|
||||
public static ulong CalculateDamageCutInfoHash(AIDamageType damageType, AIBarrierType barrierType, AIBarrierStopTiming stopTiming, int cutAmount)
|
||||
{
|
||||
return CalculateBarrierInfoBaseHash(damageType, barrierType, stopTiming) + (ulong)((long)cutAmount * (long)BARRIER_AMOUNT_HASH_COEFFICIENT);
|
||||
}
|
||||
|
||||
public static ulong CalculateDamageClipInfoHash(AIDamageType damageType, AIBarrierType barrierType, List<AIBarrierStopTiming> stopTimingList, int clipAmount, int clipRange)
|
||||
{
|
||||
return (ulong)((long)CalculateBarrierInfoBaseHash(damageType, barrierType, stopTimingList) + (long)clipAmount * (long)BARRIER_AMOUNT_HASH_COEFFICIENT + (long)clipRange * (long)DAMAGE_CLIP_RANGE_COEFFICIENT);
|
||||
}
|
||||
|
||||
public static ulong CalculateDamageClipInfoHash(AIDamageType damageType, AIBarrierType barrierType, AIBarrierStopTiming stopTiming, int clipAmount, int clipRange)
|
||||
{
|
||||
return (ulong)((long)CalculateBarrierInfoBaseHash(damageType, barrierType, stopTiming) + (long)clipAmount * (long)BARRIER_AMOUNT_HASH_COEFFICIENT + (long)clipRange * (long)DAMAGE_CLIP_RANGE_COEFFICIENT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBarrierStopPreprocessOption : AITagPreprocessCreationOptionBase
|
||||
{
|
||||
public ulong BarrierHash { get; private set; }
|
||||
|
||||
public AIBarrierStopPreprocessOption(AIVirtualCard target, ulong hash)
|
||||
: base(AITagPreprocessInfoType.BARRIER_STOP, target)
|
||||
{
|
||||
BarrierHash = hash;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBarrierTurnEndStopInformation : AITurnEndStopInformation
|
||||
{
|
||||
private ulong _barrierHash;
|
||||
|
||||
public AIBarrierTurnEndStopInformation(AIBarrierStopPreprocessOption option)
|
||||
: base(option.TargetCard)
|
||||
{
|
||||
_barrierHash = option.BarrierHash;
|
||||
base.Type = AITagPreprocessInfoType.BARRIER_STOP;
|
||||
}
|
||||
|
||||
protected override void RunMethod(bool isAllyTurnEnd, AIVirtualTurnEndInfo situation)
|
||||
{
|
||||
if (base.TargetCard != null)
|
||||
{
|
||||
if (isAllyTurnEnd)
|
||||
{
|
||||
base.TargetCard.BarrierInfoCollection.DepriveCertainBarrier(_barrierHash, AIBarrierStopTiming.AllyTurnEnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.TargetCard.BarrierInfoCollection.DepriveCertainBarrier(_barrierHash, AIBarrierStopTiming.OpponentTurnEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override AITagPreprocessCreationOptionBase CreateOptionInfoForOverride(AIVirtualCard overridedTarget)
|
||||
{
|
||||
return new AIBarrierStopPreprocessOption(overridedTarget, _barrierHash);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBarrierTurnStartStopInformation : AITurnStartStopInformation
|
||||
{
|
||||
private ulong _barrierHash;
|
||||
|
||||
public AIBarrierTurnStartStopInformation(AIBarrierStopPreprocessOption option)
|
||||
: base(option.TargetCard)
|
||||
{
|
||||
base.Type = AITagPreprocessInfoType.BARRIER_STOP;
|
||||
_barrierHash = option.BarrierHash;
|
||||
}
|
||||
|
||||
public override void ExecuteReservedAction(bool isAllyTurnEnd, AISituationInfo situation)
|
||||
{
|
||||
if (base.TargetCard != null)
|
||||
{
|
||||
if (isAllyTurnEnd)
|
||||
{
|
||||
base.TargetCard.BarrierInfoCollection.DepriveCertainBarrier(_barrierHash, AIBarrierStopTiming.AllyTurnStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.TargetCard.BarrierInfoCollection.DepriveCertainBarrier(_barrierHash, AIBarrierStopTiming.OpponentTurnStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override AITagPreprocessCreationOptionBase CreateOptionInfoForOverride(AIVirtualCard overridedTarget)
|
||||
{
|
||||
return new AIBarrierStopPreprocessOption(overridedTarget, _barrierHash);
|
||||
}
|
||||
}
|
||||
121
SVSim.BattleEngine/Engine/Wizard/AIBattleInfoReceiver.cs
Normal file
121
SVSim.BattleEngine/Engine/Wizard/AIBattleInfoReceiver.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBattleInfoReceiver
|
||||
{
|
||||
private const string NOT_FOUND_INSTANCE_LOG = "AIBattleInfoReceiver.GetInstance() error. battleMgr does not have battleInfoReceiver.";
|
||||
|
||||
private IEnemyAIBattleInfoRecieveDataAccessor _enemyAI;
|
||||
|
||||
private AIGenerateTagOwnerTable _oprSimGenerateTagOwnerTable;
|
||||
|
||||
private AIBattleInfoReceivedData _oprSimBattleInfoReceiveData;
|
||||
|
||||
private bool _isExecutingOprSim;
|
||||
|
||||
public bool IsNotNullOprSimCollections
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_oprSimGenerateTagOwnerTable != null)
|
||||
{
|
||||
return _oprSimBattleInfoReceiveData != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckCreatedValidEnemyAI()
|
||||
{
|
||||
return BattleManagerBase.GetIns().EnemyAI is IEnemyAIBattleInfoRecieveDataAccessor;
|
||||
}
|
||||
|
||||
public static AIBattleInfoReceiver GetInstance()
|
||||
{
|
||||
AIBattleInfoReceiver result = null;
|
||||
BattleManagerBase ins = BattleManagerBase.GetIns();
|
||||
if (ins is SingleBattleMgr singleBattleMgr)
|
||||
{
|
||||
result = singleBattleMgr.BattleInfoReceiver;
|
||||
}
|
||||
else if (ins is AINetworkBattleManager aINetworkBattleManager)
|
||||
{
|
||||
result = aINetworkBattleManager.BattleInfoReceiver;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void ShowNotFoundInstanceLog()
|
||||
{
|
||||
LocalLog.AccumulateTraceLog("AIBattleInfoReceiver.GetInstance() error. battleMgr does not have battleInfoReceiver.");
|
||||
}
|
||||
|
||||
public AIBattleInfoReceiver(IEnemyAI enemyAI)
|
||||
{
|
||||
_enemyAI = enemyAI as IEnemyAIBattleInfoRecieveDataAccessor;
|
||||
}
|
||||
|
||||
public void ReceiveAttachedSkillInfo(BattleCardBase skillOwner, BattleCardBase target)
|
||||
{
|
||||
string lastAttachedSkillHash = GetLastAttachedSkillHash(target);
|
||||
if (_isExecutingOprSim && IsNotNullOprSimCollections)
|
||||
{
|
||||
RegisterAttachedSkillInfoToOperationSimulator(skillOwner, target, lastAttachedSkillHash);
|
||||
}
|
||||
else
|
||||
{
|
||||
RegisterAttachedSkillInfoToRealField(skillOwner, target, lastAttachedSkillHash);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void RegisterAttachedSkillInfoToRealField(BattleCardBase skillOwner, BattleCardBase target, string skillHash)
|
||||
{
|
||||
if (_enemyAI != null)
|
||||
{
|
||||
RegisterGenerateTagExecutingParameters(_enemyAI.GenerateTagOwnerTable, _enemyAI.BattleInfoReceivedData, skillOwner, target, skillHash);
|
||||
}
|
||||
}
|
||||
|
||||
protected string GetLastAttachedSkillHash(BattleCardBase target)
|
||||
{
|
||||
AttachedSkillInformation attachedSkillsInfo = target.SkillApplyInformation.AttachedSkillsInfo;
|
||||
if (attachedSkillsInfo == null || attachedSkillsInfo.AttachedSkills == null || attachedSkillsInfo.AttachedSkills.Count() <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
SkillBase skillBase = attachedSkillsInfo.AttachedSkills.Get(attachedSkillsInfo.AttachedSkills.Count() - 1);
|
||||
if (skillBase == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return CardSkillHashUtility.GetSingleSkillBaseHash(skillBase).ToString();
|
||||
}
|
||||
|
||||
protected void RegisterGenerateTagExecutingParameters(AIGenerateTagOwnerTable generateTagOwnerTable, AIBattleInfoReceivedData battleInfoReceivedData, BattleCardBase skillOwner, BattleCardBase target, string skillHash)
|
||||
{
|
||||
battleInfoReceivedData.AttachedInfoReceiveCollection.GetInfoFromOwner(skillOwner.BaseParameter.BaseCardId, skillOwner.Index, skillOwner.IsPlayer)?.AddTargetAndSkillHash(target, skillHash);
|
||||
}
|
||||
|
||||
public void SetUpOprSimAccessor(AIOperationSimulatorAccessor oprSimAccessor)
|
||||
{
|
||||
_isExecutingOprSim = true;
|
||||
_oprSimGenerateTagOwnerTable = oprSimAccessor.GenerateTagOwnerTable;
|
||||
_oprSimBattleInfoReceiveData = oprSimAccessor.BattleInfoReceiveDate;
|
||||
}
|
||||
|
||||
public void CleanUpOprSimAccessor()
|
||||
{
|
||||
_isExecutingOprSim = false;
|
||||
_oprSimGenerateTagOwnerTable = null;
|
||||
_oprSimBattleInfoReceiveData = null;
|
||||
}
|
||||
|
||||
protected void RegisterAttachedSkillInfoToOperationSimulator(BattleCardBase skillOwner, BattleCardBase target, string skillHash)
|
||||
{
|
||||
if (IsNotNullOprSimCollections)
|
||||
{
|
||||
RegisterGenerateTagExecutingParameters(_oprSimGenerateTagOwnerTable, _oprSimBattleInfoReceiveData, skillOwner, target, skillHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBattleSimulationLauncher
|
||||
{
|
||||
private EnemyAI _ai;
|
||||
|
||||
private bool _isTimeOverLogic;
|
||||
|
||||
private bool _isUseEmptyPlayPtnSimulator;
|
||||
|
||||
private bool _isEvol;
|
||||
|
||||
private AIVirtualField _field;
|
||||
|
||||
private SimulationAdditionalActionInfoSet _additionalActions;
|
||||
|
||||
public IBattleSimulationAI BattleSimAI { get; private set; }
|
||||
|
||||
public AIBattleSimulationLauncher(AIVirtualField field, EnemyAI ai, bool useEvo, IBattleSimulationAI emptyPlayPtnSimulator = null, SimulationAdditionalActionInfoSet additionalActionInfoSet = null)
|
||||
{
|
||||
_ai = ai;
|
||||
_isEvol = useEvo;
|
||||
_field = field;
|
||||
_additionalActions = additionalActionInfoSet;
|
||||
CreateSimulator(emptyPlayPtnSimulator);
|
||||
}
|
||||
|
||||
private void CreateSimulator(IBattleSimulationAI emptyPlayPtnSimulator)
|
||||
{
|
||||
if (_ai.IsRunWeakLogic)
|
||||
{
|
||||
_isTimeOverLogic = true;
|
||||
if (_isEvol && _ai.BestPlayPtn.Count <= 0 && emptyPlayPtnSimulator != null)
|
||||
{
|
||||
BattleSimAI = emptyPlayPtnSimulator;
|
||||
_isUseEmptyPlayPtnSimulator = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BattleSimAI = new AITimeOverAttackSimulator();
|
||||
}
|
||||
return;
|
||||
}
|
||||
List<AIVirtualActionInfo> allMovesForFullSimulation = AISimulationUtility.GetAllMovesForFullSimulation(_field, _isEvol, _additionalActions);
|
||||
if (allMovesForFullSimulation.Count <= AISimulationUtility.FULL_SIMULATION_MOVE_COUNT_TURESHOLD)
|
||||
{
|
||||
BattleSimAI = new FullSimulationAI(_ai, allMovesForFullSimulation);
|
||||
}
|
||||
else if (_isEvol && _ai.BestPlayPtn.Count <= 0 && emptyPlayPtnSimulator != null)
|
||||
{
|
||||
BattleSimAI = emptyPlayPtnSimulator;
|
||||
_isUseEmptyPlayPtnSimulator = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BattleSimAI = new BestInPlayMoveAI(_ai);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator ExecuteBattleSimulationAI(PlayPtnWithToken[] playPtnWithToken, bool checkTimeOverLogic)
|
||||
{
|
||||
if (!_isUseEmptyPlayPtnSimulator)
|
||||
{
|
||||
yield return EnemyAICoroutine.GetInstance().StartCoroutine(BattleSimAI._CrSimulate(_field, _isEvol, !_isTimeOverLogic && checkTimeOverLogic, playPtnWithToken, _additionalActions));
|
||||
if (_ai.IsRunWeakLogic && !_isTimeOverLogic && checkTimeOverLogic)
|
||||
{
|
||||
BattleSimAI = new AITimeOverAttackSimulator();
|
||||
yield return EnemyAICoroutine.GetInstance().StartCoroutine(BattleSimAI._CrSimulate(_field, _isEvol, checkTimeOverLogic: false, playPtnWithToken, _additionalActions));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
SVSim.BattleEngine/Engine/Wizard/AIBattleStartData.cs
Normal file
13
SVSim.BattleEngine/Engine/Wizard/AIBattleStartData.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBattleStartData : HeaderData
|
||||
{
|
||||
public AIBattleStartDetail Data;
|
||||
|
||||
public int TurnState = -1;
|
||||
|
||||
public AIBattleStartData()
|
||||
{
|
||||
Data = new AIBattleStartDetail();
|
||||
}
|
||||
}
|
||||
28
SVSim.BattleEngine/Engine/Wizard/AIBattleStartDetail.cs
Normal file
28
SVSim.BattleEngine/Engine/Wizard/AIBattleStartDetail.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBattleStartDetail
|
||||
{
|
||||
public class UserInfo
|
||||
{
|
||||
public Dictionary<string, object> DataDictionary;
|
||||
|
||||
public UserInfo()
|
||||
{
|
||||
DataDictionary = new Dictionary<string, object>();
|
||||
}
|
||||
}
|
||||
|
||||
public int AIid;
|
||||
|
||||
public UserInfo SelfInfo;
|
||||
|
||||
public UserInfo OppoInfo;
|
||||
|
||||
public AIBattleStartDetail()
|
||||
{
|
||||
SelfInfo = new UserInfo();
|
||||
OppoInfo = new UserInfo();
|
||||
}
|
||||
}
|
||||
54
SVSim.BattleEngine/Engine/Wizard/AIBattleStartTask.cs
Normal file
54
SVSim.BattleEngine/Engine/Wizard/AIBattleStartTask.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using LitJson;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBattleStartTask : BaseTask
|
||||
{
|
||||
public AIBattleStartTask()
|
||||
{
|
||||
base.type = ((Data.CurrentFormat == Format.Rotation) ? ApiType.Type.AIRotationRankBattleStart : ApiType.Type.AIUnlimitedRankBattleStart);
|
||||
}
|
||||
|
||||
protected override int Parse()
|
||||
{
|
||||
int num = base.Parse();
|
||||
if (num != 1)
|
||||
{
|
||||
return num;
|
||||
}
|
||||
JsonData jsonData = base.ResponseData["data"];
|
||||
Data.AIBattleStartData = new AIBattleStartData();
|
||||
Data.AIBattleStartData.Data.AIid = (jsonData.Keys.Contains("ai_id") ? jsonData["ai_id"].ToInt() : (-1));
|
||||
Data.AIBattleStartData.TurnState = (jsonData.Keys.Contains("turnState") ? jsonData["turnState"].ToInt() : (-1));
|
||||
SetAIBattleStartDetail(Data.AIBattleStartData.Data.SelfInfo, jsonData, "self_info");
|
||||
SetAIBattleStartDetail(Data.AIBattleStartData.Data.OppoInfo, jsonData, "oppo_info");
|
||||
return num;
|
||||
}
|
||||
|
||||
private void SetAIBattleStartDetail(AIBattleStartDetail.UserInfo info, JsonData data, string userKey)
|
||||
{
|
||||
JsonData jsonData = null;
|
||||
if (data.Keys.Contains(userKey))
|
||||
{
|
||||
jsonData = data[userKey];
|
||||
}
|
||||
if (jsonData != null)
|
||||
{
|
||||
info.DataDictionary.Add("country_code", jsonData.Keys.Contains("country_code") ? jsonData["country_code"] : ((JsonData)"NONE"));
|
||||
info.DataDictionary.Add("userName", jsonData.Keys.Contains("userName") ? jsonData["userName"] : ((JsonData)"NONE"));
|
||||
info.DataDictionary.Add("sleeveId", jsonData.Keys.Contains("sleeveId") ? jsonData["sleeveId"].ToInt() : (-1));
|
||||
info.DataDictionary.Add("emblemId", jsonData.Keys.Contains("emblemId") ? jsonData["emblemId"].ToInt() : (-1));
|
||||
info.DataDictionary.Add("degreeId", jsonData.Keys.Contains("degreeId") ? jsonData["degreeId"].ToInt() : (-1));
|
||||
info.DataDictionary.Add("fieldId", jsonData.Keys.Contains("fieldId") ? jsonData["fieldId"].ToInt() : (-1));
|
||||
info.DataDictionary.Add("isOfficial", jsonData.Keys.Contains("isOfficial") ? jsonData["isOfficial"].ToInt() : (-1));
|
||||
info.DataDictionary.Add("oppoId", jsonData.Keys.Contains("oppoId") ? jsonData["oppoId"].ToInt() : (-1));
|
||||
info.DataDictionary.Add("seed", jsonData.Keys.Contains("seed") ? jsonData["seed"].ToInt() : (-1));
|
||||
info.DataDictionary.Add("rank", jsonData.Keys.Contains("rank") ? jsonData["rank"].ToInt() : (-1));
|
||||
info.DataDictionary.Add("battlePoint", jsonData.Keys.Contains("battlePoint") ? jsonData["battlePoint"].ToInt() : (-1));
|
||||
info.DataDictionary.Add("classId", jsonData.Keys.Contains("classId") ? jsonData["classId"].ToInt() : (-1));
|
||||
info.DataDictionary.Add("charaId", jsonData.Keys.Contains("charaId") ? jsonData["charaId"].ToInt() : (-1));
|
||||
info.DataDictionary.Add("isMasterRank", jsonData.Keys.Contains("isMasterRank") ? jsonData["isMasterRank"].ToInt() : (-1));
|
||||
info.DataDictionary.Add("masterPoint", jsonData.Keys.Contains("masterPoint") ? jsonData["masterPoint"].ToInt() : (-1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public static class AIBestFusionPatternCalculator
|
||||
{
|
||||
public static AIFusionSituationInfo CalculateBestFusionPattern(AIVirtualField field, AISinglePlayptnRecord playPtnRecord)
|
||||
{
|
||||
AIFusionSituationInfo aIFusionSituationInfo = null;
|
||||
float num = 0f;
|
||||
List<int> playPtn = playPtnRecord.PlayPtn;
|
||||
List<float> collection = CalculateAllHandBonus(field, playPtnRecord);
|
||||
float num2 = 0f;
|
||||
if (playPtn == null || playPtn.Count <= 0)
|
||||
{
|
||||
num2 -= CalculateHandOverflowPenalty(field, null, null);
|
||||
}
|
||||
for (int i = 0; i < field.AllyHandCards.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = field.AllyHandCards[i];
|
||||
if (!aIVirtualCard.TagCollectionContainer.HasTag(AIPlayTagType.Fusion) || !aIVirtualCard.IsFusionable)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
AIFusionSituationInfo aIFusionSituationInfo2 = CreateFusionSituation(aIVirtualCard, field, playPtn);
|
||||
float value = CalculateHandBonusForFusion(aIVirtualCard, field, playPtnRecord, aIFusionSituationInfo2, isIgnoreInFusion: true);
|
||||
List<float> list = new List<float>(collection);
|
||||
list[i] = value;
|
||||
float num3 = list.Sum() + num2;
|
||||
List<AIVirtualCard> fusionCandidates = GetFusionCandidates(aIVirtualCard, field, aIFusionSituationInfo2, playPtn);
|
||||
if (fusionCandidates == null || fusionCandidates.Count <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int count = fusionCandidates.Count;
|
||||
int num4 = (int)Mathf.Pow(2f, count);
|
||||
AISelectedTargetInfo info = null;
|
||||
bool flag = false;
|
||||
for (int j = 1; j < num4; j++)
|
||||
{
|
||||
AISelectedTargetInfo aISelectedTargetInfo = new AISelectedTargetInfo(ConvertPatternIndexToList(fusionCandidates, j), TargetSelectType.NormalRuleBase);
|
||||
aIFusionSituationInfo2.SetTarget(aISelectedTargetInfo, AIScriptTokenArgType.TARGET_SELECT);
|
||||
float num5 = CalculateAfterFusionHandValue(aIFusionSituationInfo2, field, playPtnRecord, list) - num3;
|
||||
if (num5 > num)
|
||||
{
|
||||
flag = true;
|
||||
num = num5;
|
||||
info = aISelectedTargetInfo;
|
||||
}
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
aIFusionSituationInfo = aIFusionSituationInfo2;
|
||||
aIFusionSituationInfo.SetTarget(info, AIScriptTokenArgType.TARGET_SELECT);
|
||||
}
|
||||
}
|
||||
return aIFusionSituationInfo;
|
||||
}
|
||||
|
||||
private static AIFusionSituationInfo CreateFusionSituation(AIVirtualCard actor, AIVirtualField field, List<int> playPtn)
|
||||
{
|
||||
AIFusionSituationInfo aIFusionSituationInfo = new AIFusionSituationInfo(actor, null);
|
||||
if (!aIFusionSituationInfo.InitializeFusionParameter(field, playPtn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return aIFusionSituationInfo;
|
||||
}
|
||||
|
||||
private static List<AIVirtualCard> GetFusionCandidates(AIVirtualCard actor, AIVirtualField field, AIFusionSituationInfo fusion, List<int> playPtn)
|
||||
{
|
||||
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.AllyHandCards, fusion.Range, actor, playPtn, fusion);
|
||||
if (list == null || list.Count <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
list.Remove(actor);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<AIVirtualCard> ConvertPatternIndexToList(List<AIVirtualCard> candidates, int patternIndex)
|
||||
{
|
||||
int num = patternIndex;
|
||||
List<AIVirtualCard> list = new List<AIVirtualCard>();
|
||||
int num2 = 0;
|
||||
while (num > 0)
|
||||
{
|
||||
bool flag = num % 2 > 0;
|
||||
num /= 2;
|
||||
if (flag)
|
||||
{
|
||||
list.Add(candidates[num2]);
|
||||
}
|
||||
num2++;
|
||||
if (num2 >= candidates.Count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<float> CalculateAllHandBonus(AIVirtualField field, AISinglePlayptnRecord playPtnRecord)
|
||||
{
|
||||
List<float> list = new List<float>();
|
||||
for (int i = 0; i < field.AllyHandCards.Count; i++)
|
||||
{
|
||||
float item = CalculateHandBonusForFusion(field.AllyHandCards[i], field, playPtnRecord, null, isIgnoreInFusion: false);
|
||||
list.Add(item);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static float CalculateAfterFusionHandValue(AIFusionSituationInfo fusion, AIVirtualField field, AISinglePlayptnRecord playPtnRecord, List<float> allHandBonusList)
|
||||
{
|
||||
float num = 0f;
|
||||
List<int> playPtn = playPtnRecord.PlayPtn;
|
||||
List<AIVirtualCard> targets = fusion.GetSituationTarget(AIScriptTokenArgType.TARGET_SELECT).Targets;
|
||||
for (int i = 0; i < field.AllyHandCards.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = field.AllyHandCards[i];
|
||||
if (!targets.Contains(aIVirtualCard))
|
||||
{
|
||||
num = ((!aIVirtualCard.IsSameCard(fusion.Actor)) ? (num + allHandBonusList[i]) : (num + CalculateHandBonusForFusion(aIVirtualCard, field, playPtnRecord, fusion, isIgnoreInFusion: true)));
|
||||
}
|
||||
}
|
||||
num += fusion.Actor.GetFusionBonus(playPtn, fusion);
|
||||
if (playPtn == null || playPtn.Count <= 0)
|
||||
{
|
||||
num -= CalculateHandOverflowPenalty(field, targets, fusion);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
private static float CalculateHandBonusForFusion(AIVirtualCard card, AIVirtualField field, AISinglePlayptnRecord playPtnRecord, AIFusionSituationInfo fusion, bool isIgnoreInFusion)
|
||||
{
|
||||
List<int> playPtn = playPtnRecord.PlayPtn;
|
||||
float num = card.GetHandBonus(playPtn, fusion, isIgnoreInFusion);
|
||||
bool flag = false;
|
||||
float num2 = card.Cost;
|
||||
int num3 = field.AllyPp;
|
||||
for (int i = 0; i < playPtnRecord.PlayedCardList.Count; i++)
|
||||
{
|
||||
PlayedCardInfo playedCardInfo = playPtnRecord.PlayedCardList[i];
|
||||
if (playedCardInfo.Card.IsSameCard(card))
|
||||
{
|
||||
flag = true;
|
||||
num2 = num3 - playedCardInfo.RestPp;
|
||||
break;
|
||||
}
|
||||
num3 = playedCardInfo.RestPp;
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
num = 2f * (num + 2f);
|
||||
}
|
||||
return num - Mathf.Abs(num2 - (float)field.AllyPpTotal) * 0.01f;
|
||||
}
|
||||
|
||||
private static float CalculateHandOverflowPenalty(AIVirtualField field, List<AIVirtualCard> fusionCandidates, AISituationInfo fusionSituation)
|
||||
{
|
||||
float num = 0f;
|
||||
int num2 = field.AllyHandCards.Count;
|
||||
if (fusionCandidates != null && fusionSituation != null && fusionSituation.ActionType == AIOperationType.FUSION)
|
||||
{
|
||||
num2 -= fusionCandidates.Count;
|
||||
int fusionDrawCount = fusionSituation.Actor.GetFusionDrawCount(EnemyAI.EmptyPlayPtn, fusionSituation);
|
||||
num2 += fusionDrawCount;
|
||||
if (num2 > 9)
|
||||
{
|
||||
num += 2f * (float)(num2 - 9);
|
||||
num2 = 9;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < field.AllyInplayCards.Count; i++)
|
||||
{
|
||||
AIVirtualCard tagOwner = field.AllyInplayCards[i];
|
||||
num2 += tagOwner.GetHandPlusCount(EnemyAI.EmptyPlayPtn);
|
||||
}
|
||||
if (num2 > 8)
|
||||
{
|
||||
num += 2f * (float)(num2 - 8);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBonusArgumentWithIgnoreInBattle : AIScriptArgumentExpressions
|
||||
{
|
||||
protected AIPolishConvertedExpression _bonusValueArg;
|
||||
|
||||
protected int _valueIndexOffset;
|
||||
|
||||
public bool IsIgnoreInBattle { get; private set; }
|
||||
|
||||
public AIBonusArgumentWithIgnoreInBattle(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
if (!(_exprList[_exprList.Count - 1].TokenList[0] is AIScriptArgumentToken aIScriptArgumentToken) || (aIScriptArgumentToken.ArgumentType != AIScriptTokenArgType.IGNORE_IN_BATTLE && aIScriptArgumentToken.ArgumentType != AIScriptTokenArgType.IGNORE_IN_FUSION))
|
||||
{
|
||||
_valueIndexOffset = 1;
|
||||
IsIgnoreInBattle = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_valueIndexOffset = 2;
|
||||
IsIgnoreInBattle = true;
|
||||
}
|
||||
_bonusValueArg = _exprList[_exprList.Count - _valueIndexOffset];
|
||||
}
|
||||
|
||||
public virtual float GetBonusValue(AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool useIgnoreInBattle)
|
||||
{
|
||||
if (tagOwner == null || (useIgnoreInBattle && IsIgnoreInBattle))
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
return _bonusValueArg.EvalArg(tagOwner, playPtn, tagOwner.SelfField, situation);
|
||||
}
|
||||
}
|
||||
53
SVSim.BattleEngine/Engine/Wizard/AIBounceDamage.cs
Normal file
53
SVSim.BattleEngine/Engine/Wizard/AIBounceDamage.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBounceDamage : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private readonly int DAMAGE_OFFSET = 1;
|
||||
|
||||
private readonly int SELECT_TYPE_OFFSET = 2;
|
||||
|
||||
public AIScriptTokenArgType SelectType { get; private set; }
|
||||
|
||||
public AIPolishConvertedExpression Damage { get; private set; }
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => SELECT_TYPE_OFFSET;
|
||||
|
||||
public AIBounceDamage(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
if (IsLegalSelectType(_exprList[_exprList.Count - SELECT_TYPE_OFFSET], out var selectType))
|
||||
{
|
||||
SelectType = selectType;
|
||||
}
|
||||
Damage = _exprList[_exprList.Count - DAMAGE_OFFSET];
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
int damage = (int)Damage.EvalArg(tagOwner, playPtn, field, situation);
|
||||
if (SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIDamageSimulationUtility.DamageAll(targets, tagOwner, field, damage, situation);
|
||||
}
|
||||
else if (SelectType == AIScriptTokenArgType.RANDOM_SELECT)
|
||||
{
|
||||
AIDamageSimulationUtility.DamageRandom(targets, tagOwner, field, damage, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.TargetFilters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
}
|
||||
52
SVSim.BattleEngine/Engine/Wizard/AIBreakAddStack.cs
Normal file
52
SVSim.BattleEngine/Engine/Wizard/AIBreakAddStack.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBreakAddStack : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private readonly int RITUAL_COUNT_OFFSET = 1;
|
||||
|
||||
public AIPolishConvertedExpression RitualCount { get; private set; }
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => RITUAL_COUNT_OFFSET;
|
||||
|
||||
public AIBreakAddStack(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
RitualCount = _exprList[_exprList.Count - RITUAL_COUNT_OFFSET];
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets == null || targets.Count <= 0)
|
||||
{
|
||||
AIConsoleUtility.LogError("AIBreakAddStack : RunTagMethod() Error!!! Missing Target");
|
||||
}
|
||||
else
|
||||
{
|
||||
AIWhiteRitualSimulationUtility.AddWhiteRitualSingle((int)RitualCount.EvalArg(tagOwner, playPtn, field, situation), targets);
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetTargets(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
List<AIVirtualCard> candidateRange = GetCandidateRange(field);
|
||||
return GetFilteredTargets(candidateRange, tagOwner, playPtn, situation);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForWhiteRitualOnly(candidates, tagOwner, playPtn, situation, isBlockDead);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
}
|
||||
57
SVSim.BattleEngine/Engine/Wizard/AIBreakAttachTag.cs
Normal file
57
SVSim.BattleEngine/Engine/Wizard/AIBreakAttachTag.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBreakAttachTag : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private const int TIMING_OFFSET = 1;
|
||||
|
||||
public AIPlayTag AttachedTag { get; private set; }
|
||||
|
||||
public AIScriptTokenArgType RemoveTiming { get; private set; }
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 1;
|
||||
|
||||
public AIBreakAttachTag(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
List<string> list = AIPlayTagInitializingUtility.SplitTagText(text);
|
||||
base.InitExpressions(list[0]);
|
||||
RemoveTiming = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - 1]);
|
||||
if (list.Count <= AIPlayTag.TAG_WORDS_LENTGH)
|
||||
{
|
||||
AttachedTag = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachedTag = AIPlayTagInitializingUtility.CreateAIPlayTagFromWords(list[1], list[2], list[3]);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
AIAttachTagSimulationUtility.SimulateAttachTagToAll(targets, tagOwner, AttachedTag, RemoveTiming, situation);
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.AllReferableCards;
|
||||
}
|
||||
|
||||
public override AITokenIdCollection GetAllRegisterTokenPoolInfo(AIVirtualCard owner)
|
||||
{
|
||||
if (AttachedTag != null)
|
||||
{
|
||||
return AttachedTag.ArgumentExpressions.GetAllRegisterTokenPoolInfo(owner);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
71
SVSim.BattleEngine/Engine/Wizard/AIBreakBuff.cs
Normal file
71
SVSim.BattleEngine/Engine/Wizard/AIBreakBuff.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBreakBuff : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private readonly int LIFE_ARG_OFFSET = 1;
|
||||
|
||||
private readonly int ATTACK_ARG_OFFSET = 2;
|
||||
|
||||
private readonly int SELECT_TYPE_ARG_OFFSET = 3;
|
||||
|
||||
public AIPolishConvertedExpression Attack { get; private set; }
|
||||
|
||||
public AIPolishConvertedExpression Life { get; private set; }
|
||||
|
||||
public AIScriptTokenArgType SelectType { get; protected set; }
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => SELECT_TYPE_ARG_OFFSET;
|
||||
|
||||
public AIBreakBuff(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
Attack = _exprList[_exprList.Count - ATTACK_ARG_OFFSET];
|
||||
Life = _exprList[_exprList.Count - LIFE_ARG_OFFSET];
|
||||
SelectType = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - SELECT_TYPE_ARG_OFFSET], base.LegalSelectTypes);
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
AIBuffExecutingInfo_old buffExecutingInfo_old = AIBuffSimulationUtility.GetBuffExecutingInfo_old(tagOwner, field, situation, playPtn, Attack, Life);
|
||||
switch (SelectType)
|
||||
{
|
||||
case AIScriptTokenArgType.ALL_SELECT:
|
||||
AIBuffSimulationUtility.BuffAll_old(targets, field, buffExecutingInfo_old, isTemp: false, playPtn, situation);
|
||||
break;
|
||||
case AIScriptTokenArgType.RANDOM_SELECT:
|
||||
AIBuffSimulationUtility.BuffRandom_old(targets, field, playPtn, situation, buffExecutingInfo_old, isTemp: false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
bool isAttackEffective = !Attack.IsZeroOrNone();
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.TargetFilters, playPtn, situation, isAttackEffective, isBlockDead);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[2]
|
||||
{
|
||||
AIScriptTokenArgType.ALL_SELECT,
|
||||
AIScriptTokenArgType.RANDOM_SELECT
|
||||
};
|
||||
}
|
||||
}
|
||||
54
SVSim.BattleEngine/Engine/Wizard/AIBreakDamage.cs
Normal file
54
SVSim.BattleEngine/Engine/Wizard/AIBreakDamage.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBreakDamage : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private readonly int DAMAGE_OFFSET = 1;
|
||||
|
||||
private readonly int SELECT_TYPE_OFFSET = 2;
|
||||
|
||||
public AIScriptTokenArgType SelectType { get; private set; }
|
||||
|
||||
public AIPolishConvertedExpression Damage { get; private set; }
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => SELECT_TYPE_OFFSET;
|
||||
|
||||
public AIBreakDamage(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
AIScriptTokenArgType selectType = AIScriptTokenArgType.NONE;
|
||||
if (IsLegalSelectType(_exprList[_exprList.Count - SELECT_TYPE_OFFSET], out selectType))
|
||||
{
|
||||
SelectType = selectType;
|
||||
}
|
||||
Damage = _exprList[_exprList.Count - DAMAGE_OFFSET];
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
int damage = (int)Damage.EvalArg(tagOwner, playPtn, field, situation);
|
||||
if (SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIDamageSimulationUtility.DamageAll(targets, tagOwner, field, damage, situation);
|
||||
}
|
||||
else if (SelectType == AIScriptTokenArgType.RANDOM_SELECT)
|
||||
{
|
||||
AIDamageSimulationUtility.DamageRandom(targets, tagOwner, field, damage, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.TargetFilters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
}
|
||||
48
SVSim.BattleEngine/Engine/Wizard/AIBreakDestroy.cs
Normal file
48
SVSim.BattleEngine/Engine/Wizard/AIBreakDestroy.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBreakDestroy : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private readonly int SELECT_TYPE_OFFSET = 1;
|
||||
|
||||
public AIScriptTokenArgType SelectType { get; private set; }
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => SELECT_TYPE_OFFSET;
|
||||
|
||||
public AIBreakDestroy(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
AIScriptTokenArgType selectType = AIScriptTokenArgType.NONE;
|
||||
if (IsLegalSelectType(_exprList[_exprList.Count - SELECT_TYPE_OFFSET], out selectType))
|
||||
{
|
||||
SelectType = selectType;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
if (SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AISkillSimulationUtility.DestroyAll(targets, field, situation);
|
||||
}
|
||||
else if (SelectType == AIScriptTokenArgType.RANDOM_SELECT)
|
||||
{
|
||||
AISkillSimulationUtility.DestroyRandom(targets, tagOwner, field, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
}
|
||||
51
SVSim.BattleEngine/Engine/Wizard/AIBreakHeal.cs
Normal file
51
SVSim.BattleEngine/Engine/Wizard/AIBreakHeal.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBreakHeal : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private readonly int HEAL_AMOUNT_OFFSET = 1;
|
||||
|
||||
private readonly int SELECT_TYPE_OFFSET = 2;
|
||||
|
||||
public AIScriptTokenArgType SelectType { get; private set; }
|
||||
|
||||
public AIPolishConvertedExpression Heal { get; private set; }
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => SELECT_TYPE_OFFSET;
|
||||
|
||||
public AIBreakHeal(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
AIScriptTokenArgType selectType = AIScriptTokenArgType.NONE;
|
||||
if (IsLegalSelectType(_exprList[_exprList.Count - SELECT_TYPE_OFFSET], out selectType))
|
||||
{
|
||||
SelectType = selectType;
|
||||
}
|
||||
Heal = _exprList[_exprList.Count - HEAL_AMOUNT_OFFSET];
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
int heal = (int)Heal.EvalArg(tagOwner, playPtn, field, situation);
|
||||
AIScriptTokenArgType selectType = SelectType;
|
||||
if (selectType != AIScriptTokenArgType.RANDOM_SELECT && selectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AISkillSimulationUtility.HealAll(targets, field, heal, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.TargetFilters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBreakRecoverAttackableCount : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 0;
|
||||
|
||||
public AIBreakRecoverAttackableCount(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets == null || targets.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (AIVirtualCard target in targets)
|
||||
{
|
||||
target.RecoverAttackableCount();
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
}
|
||||
38
SVSim.BattleEngine/Engine/Wizard/AIBreakRecoverPp.cs
Normal file
38
SVSim.BattleEngine/Engine/Wizard/AIBreakRecoverPp.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBreakRecoverPp : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private AIPolishConvertedExpression _recoverPpValue;
|
||||
|
||||
private const int VALUE_OFFSET = 1;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 1;
|
||||
|
||||
public AIBreakRecoverPp(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_recoverPpValue = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
private int GetRecoverValue(AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (_recoverPpValue == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (int)_recoverPpValue.EvalArg(tagOwner, playPtn, tagOwner.SelfField, situation);
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
field.RecoverPp(GetRecoverValue(tagOwner, playPtn, situation));
|
||||
}
|
||||
}
|
||||
34
SVSim.BattleEngine/Engine/Wizard/AIBreakSetLeaderMaxLife.cs
Normal file
34
SVSim.BattleEngine/Engine/Wizard/AIBreakSetLeaderMaxLife.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBreakSetLeaderMaxLife : AIFiltersArgument
|
||||
{
|
||||
private AIScriptTokenArgType _side;
|
||||
|
||||
private AIPolishConvertedExpression _life;
|
||||
|
||||
private const int SIDE_OFFSET = 2;
|
||||
|
||||
private const int VALUE_OFFSET = 1;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 2;
|
||||
|
||||
public AIBreakSetLeaderMaxLife(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_side = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - 2]);
|
||||
_life = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
protected override void RunMethod(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
int maxLife = (int)_life.EvalArg(tagOwner, playPtn, field, situation);
|
||||
AISetStatusSimulationUtility.SetLeaderMaxLife(tagOwner, maxLife, _side, field, situation);
|
||||
}
|
||||
}
|
||||
71
SVSim.BattleEngine/Engine/Wizard/AIBuffBuff.cs
Normal file
71
SVSim.BattleEngine/Engine/Wizard/AIBuffBuff.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBuffBuff : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private static readonly AIScriptTokenArgType[] PermOrTempArgs = new AIScriptTokenArgType[2]
|
||||
{
|
||||
AIScriptTokenArgType.PERM,
|
||||
AIScriptTokenArgType.TEMP
|
||||
};
|
||||
|
||||
private AIScriptTokenArgType _selectType;
|
||||
|
||||
private AIPolishConvertedExpression _attackBuffValue;
|
||||
|
||||
private AIPolishConvertedExpression _lifeBuffValue;
|
||||
|
||||
private AIScriptTokenArgType _permOrTemp;
|
||||
|
||||
private const int PERM_OR_TEMP_OFFSET = 1;
|
||||
|
||||
private const int LIFE_BUFF_OFFSET = 2;
|
||||
|
||||
private const int ATTACK_BUFF_OFFSET = 3;
|
||||
|
||||
private const int SELECT_TYPE_OFFSET = 4;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 4;
|
||||
|
||||
public AIBuffBuff(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_selectType = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - 4], base.LegalSelectTypes);
|
||||
_attackBuffValue = _exprList[_exprList.Count - 3];
|
||||
_lifeBuffValue = _exprList[_exprList.Count - 2];
|
||||
_permOrTemp = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - 1], PermOrTempArgs);
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
AIBuffExecutingInfo_old buffExecutingInfo_old = AIBuffSimulationUtility.GetBuffExecutingInfo_old(tagOwner, field, situation, playPtn, _attackBuffValue, _lifeBuffValue);
|
||||
bool isTemp = _permOrTemp == AIScriptTokenArgType.TEMP;
|
||||
switch (_selectType)
|
||||
{
|
||||
case AIScriptTokenArgType.ALL_SELECT:
|
||||
AIBuffSimulationUtility.BuffAll_old(targets, field, buffExecutingInfo_old, isTemp, playPtn, situation);
|
||||
break;
|
||||
case AIScriptTokenArgType.RANDOM_SELECT:
|
||||
AIBuffSimulationUtility.BuffRandom_old(targets, field, playPtn, situation, buffExecutingInfo_old, isTemp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
bool isAttackEffective = !_attackBuffValue.IsZeroOrNone();
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.TargetFilters, playPtn, situation, isAttackEffective, isBlockDead);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.AllReferableCards;
|
||||
}
|
||||
}
|
||||
63
SVSim.BattleEngine/Engine/Wizard/AIBuffDamage.cs
Normal file
63
SVSim.BattleEngine/Engine/Wizard/AIBuffDamage.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBuffDamage : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private const int DAMAGE_ARG_OFFSET = 1;
|
||||
|
||||
private AIPolishConvertedExpression _damageArg;
|
||||
|
||||
public AIScriptTokenArgType SelectType { get; private set; }
|
||||
|
||||
protected int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 2;
|
||||
|
||||
public AIBuffDamage(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
AIScriptTokenArgType selectType = AIScriptTokenArgType.NONE;
|
||||
if (IsLegalSelectType(_exprList[_exprList.Count - SELECT_TYPE_OFFSET], out selectType))
|
||||
{
|
||||
SelectType = selectType;
|
||||
}
|
||||
_damageArg = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
int damage = GetDamage(tagOwner, playPtn, situation);
|
||||
if (SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIDamageSimulationUtility.DamageAll(targets, tagOwner, field, damage, situation);
|
||||
}
|
||||
else if (SelectType == AIScriptTokenArgType.RANDOM_SELECT)
|
||||
{
|
||||
AIDamageSimulationUtility.DamageRandom(targets, tagOwner, field, damage, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int GetDamage(AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (_damageArg == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (int)_damageArg.EvalArg(tagOwner, playPtn, tagOwner.SelfField, situation);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.TargetFilters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
}
|
||||
48
SVSim.BattleEngine/Engine/Wizard/AIBuffDestroy.cs
Normal file
48
SVSim.BattleEngine/Engine/Wizard/AIBuffDestroy.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBuffDestroy : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private readonly int SELECT_TYPE_OFFSET = 1;
|
||||
|
||||
public AIScriptTokenArgType SelectType { get; private set; }
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => SELECT_TYPE_OFFSET;
|
||||
|
||||
public AIBuffDestroy(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
AIScriptTokenArgType selectType = AIScriptTokenArgType.NONE;
|
||||
if (IsLegalSelectType(_exprList[_exprList.Count - SELECT_TYPE_OFFSET], out selectType))
|
||||
{
|
||||
SelectType = selectType;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
if (SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AISkillSimulationUtility.DestroyAll(targets, field, situation);
|
||||
}
|
||||
else if (SelectType == AIScriptTokenArgType.RANDOM_SELECT)
|
||||
{
|
||||
AISkillSimulationUtility.DestroyRandom(targets, tagOwner, field, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
}
|
||||
30
SVSim.BattleEngine/Engine/Wizard/AIBuffDraw.cs
Normal file
30
SVSim.BattleEngine/Engine/Wizard/AIBuffDraw.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBuffDraw : AIScriptArgumentExpressions
|
||||
{
|
||||
private const int COUNT_ARG_INDEX = 1;
|
||||
|
||||
public AIPolishConvertedExpression DrawCount { get; private set; }
|
||||
|
||||
public AIBuffDraw(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
DrawCount = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
if (DrawCount != null)
|
||||
{
|
||||
int drawCount = (int)DrawCount.EvalArg(tagOwner, playPtn, field, situation);
|
||||
tagOwner.SelfField.DrawCard(tagOwner.IsAlly, drawCount, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
SVSim.BattleEngine/Engine/Wizard/AIBuffEvo.cs
Normal file
20
SVSim.BattleEngine/Engine/Wizard/AIBuffEvo.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBuffEvo : AIScriptArgumentExpressions
|
||||
{
|
||||
public AIBuffEvo(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
base.Execute(tagOwner, field, playPtn, situation);
|
||||
if (!tagOwner.IsEvolution)
|
||||
{
|
||||
AIAutoEvolutionSimulationUtility.AutoEvolveSingle(tagOwner, field, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
50
SVSim.BattleEngine/Engine/Wizard/AIBuffHeal.cs
Normal file
50
SVSim.BattleEngine/Engine/Wizard/AIBuffHeal.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBuffHeal : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private const int HEAL_AMOUNT_ARG_OFFSET = 1;
|
||||
|
||||
private AIPolishConvertedExpression _healArg;
|
||||
|
||||
public AIScriptTokenArgType SelectType { get; private set; }
|
||||
|
||||
protected int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 2;
|
||||
|
||||
public AIBuffHeal(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
SelectType = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - SELECT_TYPE_OFFSET], base.LegalSelectTypes);
|
||||
_healArg = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
int heal = (int)_healArg.EvalArg(tagOwner, playPtn, tagOwner.SelfField, situation);
|
||||
if (SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AISkillSimulationUtility.HealAll(targets, field, heal, playPtn, situation);
|
||||
}
|
||||
else if (SelectType == AIScriptTokenArgType.RANDOM_SELECT)
|
||||
{
|
||||
AISkillSimulationUtility.HealSingle(targets[0], field, heal, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.TargetFilters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
}
|
||||
36
SVSim.BattleEngine/Engine/Wizard/AIBuffRecoverPp.cs
Normal file
36
SVSim.BattleEngine/Engine/Wizard/AIBuffRecoverPp.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBuffRecoverPp : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
private const int HEAL_ARG_OFFSET = 1;
|
||||
|
||||
private AIPolishConvertedExpression _healArg;
|
||||
|
||||
public AIBuffRecoverPp(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_healArg = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
field.RecoverPp(GetHealCount(tagOwner, playPtn, situation));
|
||||
}
|
||||
|
||||
private int GetHealCount(AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (_healArg == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (int)_healArg.EvalArg(tagOwner, playPtn, tagOwner.SelfField, situation);
|
||||
}
|
||||
}
|
||||
51
SVSim.BattleEngine/Engine/Wizard/AIBuffRush.cs
Normal file
51
SVSim.BattleEngine/Engine/Wizard/AIBuffRush.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBuffRush : AITriggerAndTargetFiltersTagBase
|
||||
{
|
||||
public AIScriptTokenArgType SelectType { get; private set; }
|
||||
|
||||
protected int SELECT_TYPE_OFFSET => 1;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 1;
|
||||
|
||||
public AIBuffRush(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
AIScriptTokenArgType selectType = AIScriptTokenArgType.NONE;
|
||||
if (IsLegalSelectType(_exprList[_exprList.Count - SELECT_TYPE_OFFSET], out selectType))
|
||||
{
|
||||
SelectType = selectType;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
protected override void RunTagMethod(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
base.RunTagMethod(targets, field, tagOwner, playPtn, situation);
|
||||
if (targets != null && targets.Count > 0 && SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AISkillSimulationUtility.GiveSkillToAll(targets, field, AIScriptTokenArgType.RUSH);
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForFollowerOnly(candidates, tagOwner, base.TargetFilters, playPtn, situation, isBlockDead);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.AllReferableCards;
|
||||
}
|
||||
}
|
||||
54
SVSim.BattleEngine/Engine/Wizard/AIBuffShield.cs
Normal file
54
SVSim.BattleEngine/Engine/Wizard/AIBuffShield.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBuffShield : AIFiltersAndSelectTypeArgument
|
||||
{
|
||||
private List<AIScriptTokenArgType> _stopTimingList;
|
||||
|
||||
private AIScriptTokenArgType _damageType;
|
||||
|
||||
private const int DEFAULT_DAMAGE_TYPE_OFFSET = 2;
|
||||
|
||||
private const int STOP_TIMING_OFFSET = 1;
|
||||
|
||||
private bool _isDamageTypeDefinedByMaster;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 1 + ((!_isDamageTypeDefinedByMaster) ? 1 : 2);
|
||||
|
||||
public AIBuffShield(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
InitExprList(text);
|
||||
_stopTimingList = AIPlayTagInitializingUtility.InitializeStopTimingList(_exprList[_exprList.Count - 1]);
|
||||
_damageType = AIPlayTagInitializingUtility.GetDamageTypeFromExprList(_exprList[_exprList.Count - 2], out _isDamageTypeDefinedByMaster);
|
||||
base.SelectType = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - SELECT_TYPE_OFFSET], base.LegalSelectTypes);
|
||||
InitializeFilter();
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
AIBarrierSimulationUtility.AddMultipleStopTimingShieldToAll(targetsFromField, tagOwner, field, _damageType, _stopTimingList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
110
SVSim.BattleEngine/Engine/Wizard/AIBuffSimulationUtility.cs
Normal file
110
SVSim.BattleEngine/Engine/Wizard/AIBuffSimulationUtility.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public static class AIBuffSimulationUtility
|
||||
{
|
||||
public static void BuffAll_old(List<AIVirtualCard> targets, AIVirtualField field, AIBuffExecutingInfo_old buffInfo, bool isTemp, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (buffInfo.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = targets[i];
|
||||
if (aIVirtualCard.IsUnit)
|
||||
{
|
||||
aIVirtualCard.GiveBuff(situation, buffInfo, isTemp);
|
||||
}
|
||||
}
|
||||
if (buffInfo.IsBuff())
|
||||
{
|
||||
BuffActivation(targets, field, playPtn, situation);
|
||||
}
|
||||
}
|
||||
|
||||
public static void BuffRandom_old(List<AIVirtualCard> candidates, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AIBuffExecutingInfo_old buffInfo, bool isTemp)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = AISimulationRemovalUtility.SelectWorstTargetForBuff(candidates, buffInfo);
|
||||
if (aIVirtualCard != null)
|
||||
{
|
||||
BuffSingle_old(aIVirtualCard, field, buffInfo, isTemp, playPtn, situation);
|
||||
}
|
||||
}
|
||||
|
||||
public static void BuffTarget_old(AISituationInfo situation, List<AIVirtualCard> candidates, AIVirtualField field, List<int> playPtn, AIScriptTokenArgType whichTarget, AIBuffExecutingInfo_old buffInfo, bool isTemp)
|
||||
{
|
||||
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
|
||||
if (situationTarget == null || !situationTarget.HasTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
List<AIVirtualCard> targets = situationTarget.Targets;
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = targets[i];
|
||||
if (candidates.Contains(aIVirtualCard))
|
||||
{
|
||||
BuffSingle_old(aIVirtualCard, field, buffInfo, isTemp, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void BuffSingle_old(AIVirtualCard target, AIVirtualField field, AIBuffExecutingInfo_old buffInfo, bool isTemp, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (!buffInfo.IsEmpty() && target.IsUnit)
|
||||
{
|
||||
target.GiveBuff(situation, buffInfo, isTemp);
|
||||
if (buffInfo.IsBuff())
|
||||
{
|
||||
BuffActivation(new List<AIVirtualCard> { target }, field, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void BuffFirst_old(List<AIVirtualCard> targets, AIVirtualField field, AIBuffExecutingInfo_old buffInfo, bool isTemp, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
BuffSingle_old(targets[0], field, buffInfo, isTemp, playPtn, situation);
|
||||
}
|
||||
}
|
||||
|
||||
private static void BuffActivation(List<AIVirtualCard> buffTargets, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (buffTargets == null || buffTargets.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < buffTargets.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = buffTargets[i];
|
||||
if (!aIVirtualCard.IsDead)
|
||||
{
|
||||
if (aIVirtualCard.TagCollectionContainer.HasTag(AIPlayTagType.BuffBonus))
|
||||
{
|
||||
field.ApplyBuffBonus(aIVirtualCard, playPtn, situation);
|
||||
}
|
||||
if (aIVirtualCard.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenBuff))
|
||||
{
|
||||
aIVirtualCard.TagCollectionContainer.BuffTriggerTags.Execute(aIVirtualCard, aIVirtualCard, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
field.AllActivateCountHolderIncrement(situation, AIPlayTagType.BuffActivateCounnt, buffTargets);
|
||||
}
|
||||
|
||||
public static AIBuffExecutingInfo_old GetBuffExecutingInfo_old(AIVirtualCard tagOwner, AIVirtualField field, AISituationInfo situation, List<int> playPtn, AIPolishConvertedExpression attackExpression, AIPolishConvertedExpression lifeExpression)
|
||||
{
|
||||
int attackValue = (int)attackExpression.EvalArg(tagOwner, playPtn, field, situation);
|
||||
int lifeValue = (int)lifeExpression.EvalArg(tagOwner, playPtn, field, situation);
|
||||
return new AIBuffExecutingInfo_old
|
||||
{
|
||||
AttackValue = attackValue,
|
||||
LifeValue = lifeValue,
|
||||
IsMultiplyAttack = attackExpression.IsMultiplyMarked,
|
||||
IsMultiplyLife = lifeExpression.IsMultiplyMarked
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBuffStopPreprocessOption : AITagPreprocessCreationOptionBase
|
||||
{
|
||||
public AIBuffStopPreprocessOption(AIVirtualCard target)
|
||||
: base(AITagPreprocessInfoType.STATUS_CHANGE_STOP, target)
|
||||
{
|
||||
}
|
||||
}
|
||||
38
SVSim.BattleEngine/Engine/Wizard/AIBuffToken.cs
Normal file
38
SVSim.BattleEngine/Engine/Wizard/AIBuffToken.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBuffToken : AIFiltersArgument
|
||||
{
|
||||
private AIPolishConvertedExpression _tokenCount;
|
||||
|
||||
private int TOKEN_COUNT_INDEX_OFFSET = 1;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => TOKEN_COUNT_INDEX_OFFSET;
|
||||
|
||||
public AIBuffToken(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_tokenCount = _exprList[_exprList.Count - TOKEN_COUNT_INDEX_OFFSET];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
AISummonTokenUtility.ExecuteSummonToken(GetTargetsFromField(tagOwner, field, playPtn, situation, isBlockDead: false), base.Filters, _tokenCount, AIScriptTokenArgType.ALLY, tagOwner, field, playPtn, situation);
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetTargetsFromField(AIVirtualCard owner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return GetCandidateRange(field);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBuffTurnEndStopInformation : AITurnEndStopInformation
|
||||
{
|
||||
public AIBuffTurnEndStopInformation(AIVirtualCard card)
|
||||
: base(card)
|
||||
{
|
||||
base.Type = AITagPreprocessInfoType.STATUS_CHANGE_STOP;
|
||||
}
|
||||
|
||||
protected override void RunMethod(bool isAllyTurnEnd, AIVirtualTurnEndInfo situation)
|
||||
{
|
||||
if (base.TargetCard != null)
|
||||
{
|
||||
base.TargetCard.RemoveTempBuff();
|
||||
}
|
||||
}
|
||||
}
|
||||
47
SVSim.BattleEngine/Engine/Wizard/AIBurialRite.cs
Normal file
47
SVSim.BattleEngine/Engine/Wizard/AIBurialRite.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIBurialRite : AIScriptArgumentExpressions
|
||||
{
|
||||
private AIPolishConvertedExpression _value;
|
||||
|
||||
private readonly int VALUE_INDEX;
|
||||
|
||||
private readonly int TIMING_INDEX = 1;
|
||||
|
||||
public AIScriptTokenArgType Timing { get; private set; }
|
||||
|
||||
public AIBurialRite(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
if (_exprList != null && _exprList.Count >= TIMING_INDEX + 1)
|
||||
{
|
||||
_value = _exprList[VALUE_INDEX];
|
||||
Timing = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[TIMING_INDEX]);
|
||||
if (!CheckValidTimingType(Timing))
|
||||
{
|
||||
Timing = AIScriptTokenArgType.NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckValidTimingType(AIScriptTokenArgType type)
|
||||
{
|
||||
if (type == AIScriptTokenArgType.WHEN_PLAY || type == AIScriptTokenArgType.WHEN_EVO)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int GetBurialRiteCount(AIVirtualCard tagOwner, AIVirtualField field, AISituationInfo situation, List<int> playPtn)
|
||||
{
|
||||
return (int)_value.EvalArg(tagOwner, playPtn, field, situation);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public static class AIBurialRiteSimulationUtility
|
||||
{
|
||||
public static void ExecuteBurialRite(AIVirtualField field, AISituationInfo situation, AISelectedTargetInfo burialTargetInfo)
|
||||
{
|
||||
List<AIVirtualCard> targets = burialTargetInfo.Targets;
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
targets[i].RemoveAllSkills(situation);
|
||||
}
|
||||
AISummonTokenUtility.ExecuteSummonCardAll(situation.Actor, field, targets, situation);
|
||||
AISkillSimulationUtility.DestroyAll(targets, field, situation);
|
||||
if (situation.Actor.IsAlly)
|
||||
{
|
||||
for (int j = 0; j < targets.Count; j++)
|
||||
{
|
||||
field.CardListSet.AddAllyBurialCard(targets[j]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int k = 0; k < targets.Count; k++)
|
||||
{
|
||||
field.CardListSet.AddEnemyBurialCard(targets[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static AIVirtualTargetSelectInfo GetBurialSelectInfo(this AIVirtualCard card, AIVirtualField field, AISituationInfo situation)
|
||||
{
|
||||
int totalBurialCount = situation.PreprocessRecorder.TotalBurialCount;
|
||||
if (totalBurialCount <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (card.IsAlly)
|
||||
{
|
||||
return GetAllyBurialSelectInfo(card, field, situation, totalBurialCount);
|
||||
}
|
||||
return GetOpponentBurialSelectInfo(card, field, situation, totalBurialCount);
|
||||
}
|
||||
|
||||
private static AIVirtualTargetSelectInfo GetAllyBurialSelectInfo(AIVirtualCard owner, AIVirtualField field, AISituationInfo situation, int burialCount)
|
||||
{
|
||||
if (5 - field.AllyInplayCards.Count < burialCount)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
List<AIVirtualCard> burialSelectableCards = GetBurialSelectableCards(field.AllyHandCards, owner, situation.OriginalCard);
|
||||
if (burialSelectableCards == null || burialSelectableCards.Count < burialCount)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
burialSelectableCards = AITargetSelectFilteringUtility.ExecuteTargetFilteringTags(owner, burialSelectableCards, field.BestPlayPtn, situation, burialCount);
|
||||
return new AIVirtualTargetSelectInfo(burialCount, burialSelectableCards, TargetSelectType.BurialRite, isForbiddenSelectedTarget: true);
|
||||
}
|
||||
|
||||
private static AIVirtualTargetSelectInfo GetOpponentBurialSelectInfo(AIVirtualCard owner, AIVirtualField field, AISituationInfo situation, int burialCount)
|
||||
{
|
||||
List<AIVirtualCard> burialSelectableCards = GetBurialSelectableCards(field.GetEnemyHandCardList(), owner, situation.OriginalCard);
|
||||
if (burialSelectableCards == null || burialSelectableCards.Count < burialCount)
|
||||
{
|
||||
AIConsoleUtility.LogError("GetOpponentBurialSelectInfo() error!! Cannot find enough candidates!!!!!");
|
||||
return null;
|
||||
}
|
||||
return new AIVirtualTargetSelectInfo(burialCount, burialSelectableCards, TargetSelectType.BurialRite, isForbiddenSelectedTarget: true);
|
||||
}
|
||||
|
||||
public static List<AIVirtualCard> GetBurialSelectableCards(List<AIVirtualCard> candidates, AIVirtualCard burialOwner, AIVirtualCard originalBurialCard)
|
||||
{
|
||||
List<AIVirtualCard> list = null;
|
||||
for (int i = 0; i < candidates.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = candidates[i];
|
||||
if (aIVirtualCard.IsUnit && !aIVirtualCard.IsSameCard(burialOwner) && !aIVirtualCard.IsSameCard(originalBurialCard))
|
||||
{
|
||||
list = AIParamQuery.AddElementToList(aIVirtualCard, list);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static AIVirtualCard GetBestBurialRiteTargetForOperationSimulator(AIVirtualCard burialActor, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIVirtualCard> candidates)
|
||||
{
|
||||
AIScriptTokenArgType timing = AIPreprocessSimulationUtility.ConvertAIOperationTypeToTiming(situation.ActionType);
|
||||
if (burialActor.GetBurialRiteCount(field, situation, playPtn, timing) <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return candidates.FindMax((AIVirtualCard card) => Mathf.Abs(field.AllyPpTotal - card.Cost));
|
||||
}
|
||||
|
||||
public static int GetBurialCount(AIScriptTokenArgType burialListType, AIVirtualField field)
|
||||
{
|
||||
return burialListType switch
|
||||
{
|
||||
AIScriptTokenArgType.ALLY => field.CardListSet.AllyBurialCards.Count,
|
||||
AIScriptTokenArgType.OPPONENT => field.CardListSet.EnemyBurialCards.Count,
|
||||
_ => 0,
|
||||
};
|
||||
}
|
||||
|
||||
public static IEnumerable<BattleCardBase> GetBurialSelectableCards(SkillBase skill, BattleCardBase card)
|
||||
{
|
||||
if (skill.IsBurialRite)
|
||||
{
|
||||
return SkillPreprocessBurialRite.GetBurialRiteTarget(card.SelfBattlePlayer, card);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
47
SVSim.BattleEngine/Engine/Wizard/AIChangeInplayAttachTag.cs
Normal file
47
SVSim.BattleEngine/Engine/Wizard/AIChangeInplayAttachTag.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChangeInplayAttachTag : AIWhenChangeInplayTagArgument
|
||||
{
|
||||
private AIScriptTokenArgType _removeTiming;
|
||||
|
||||
private readonly int REMOVE_TIMING_OFFSET = 1;
|
||||
|
||||
private const int TAG_WORD_START_INDEX = 1;
|
||||
|
||||
public AIPlayTag Tag { get; private set; }
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public AIChangeInplayAttachTag(string text, bool isImmediate)
|
||||
: base(text, isImmediate)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
List<string> list = AIPlayTagInitializingUtility.SplitTagText(text);
|
||||
base.InitExpressions(list[0]);
|
||||
_removeTiming = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - REMOVE_TIMING_OFFSET]);
|
||||
Tag = AIPlayTagInitializingUtility.CreateAIPlayTagFromWords(list[1], list[2], list[3]);
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.AllReferableCards;
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStartProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIAttachTagSimulationUtility.SimulateAttachTagToAll(targets, tagOwner, Tag, _removeTiming, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChangeInplayCannotAttack : AIWhenChangeInplayTagArgument
|
||||
{
|
||||
private AICannotAttackInformation _info;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => -1;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 0;
|
||||
|
||||
public AIChangeInplayCannotAttack(string text, bool isImmediate)
|
||||
: base(text, isImmediate)
|
||||
{
|
||||
_info = null;
|
||||
}
|
||||
|
||||
protected override void InitSelectType()
|
||||
{
|
||||
base.SelectType = AIScriptTokenArgType.ALL_SELECT;
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetTargetsFromField(AIVirtualCard owner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return GetCandidateRange(field);
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStartProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (_info == null)
|
||||
{
|
||||
_info = new AICannotAttackInformation(base.Filters);
|
||||
}
|
||||
tagOwner.AddCannotAttackInformation(_info);
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStopProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
tagOwner.RemoveCannotAttackInformation(_info);
|
||||
}
|
||||
}
|
||||
53
SVSim.BattleEngine/Engine/Wizard/AIChangeInplayCannotPlay.cs
Normal file
53
SVSim.BattleEngine/Engine/Wizard/AIChangeInplayCannotPlay.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChangeInplayCannotPlay : AIWhenChangeInplayTagArgument
|
||||
{
|
||||
private List<AIScriptTokenBase> _cannotPlayCardFilterList;
|
||||
|
||||
public AIChangeInplayCannotPlay(string text, bool isImmediate)
|
||||
: base(text, isImmediate)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
InitExprList(text);
|
||||
if (!AIPlayTagInitializingUtility.IsInitOfFilterSet(_exprList[0]))
|
||||
{
|
||||
AIConsoleUtility.LogError("AIChangeInplayCannotPlay.InitExpressions() Error!! Filters.First is not side arg!!!!!");
|
||||
return;
|
||||
}
|
||||
int num = -1;
|
||||
for (int i = 1; i < _exprList.Count; i++)
|
||||
{
|
||||
if (AIPlayTagInitializingUtility.IsInitOfFilterSet(_exprList[i]))
|
||||
{
|
||||
num = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (num <= 0)
|
||||
{
|
||||
_cannotPlayCardFilterList = GetFilters(_exprList.GetRange(0, _exprList.Count - NON_FILTER_FIRST_OFFSET));
|
||||
base.Filters = new List<AIScriptTokenBase>();
|
||||
}
|
||||
else
|
||||
{
|
||||
base.Filters = GetFilters(_exprList.GetRange(0, num));
|
||||
_cannotPlayCardFilterList = GetFilters(_exprList.GetRange(num, _exprList.Count - NON_FILTER_FIRST_OFFSET - num));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStartProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AICannotPlayInformation info = new AICannotPlayInformation(tagOwner, _cannotPlayCardFilterList);
|
||||
field.AddCannotPlayInformation(info);
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStopProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
field.RemoveCannotPlayInformation(tagOwner, _cannotPlayCardFilterList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChangeInplayFixRemoveType : AIWhenChangeInplayTagArgument
|
||||
{
|
||||
private readonly FixedRemoveType _removeType;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 0;
|
||||
|
||||
public AIChangeInplayFixRemoveType(string text, FixedRemoveType type, bool isImmediate)
|
||||
: base(text, isImmediate)
|
||||
{
|
||||
_removeType = type;
|
||||
}
|
||||
|
||||
protected override void InitSelectType()
|
||||
{
|
||||
base.SelectType = AIScriptTokenArgType.ALL_SELECT;
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStartProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
FixRemoveType(targets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStopProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
StopFixRemoveType(targets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void FixRemoveType(AIVirtualCard target)
|
||||
{
|
||||
switch (_removeType)
|
||||
{
|
||||
case FixedRemoveType.RemoveByBanish:
|
||||
target.GiveRemoveByBanish();
|
||||
break;
|
||||
case FixedRemoveType.RemoveByDestroy:
|
||||
target.GiveRemoveByDestroy();
|
||||
break;
|
||||
default:
|
||||
AIConsoleUtility.LogError("AIChangeInplayFixRemoveType.FixRemoveType() error!! _removeType == " + _removeType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void StopFixRemoveType(AIVirtualCard target)
|
||||
{
|
||||
switch (_removeType)
|
||||
{
|
||||
case FixedRemoveType.RemoveByBanish:
|
||||
target.DepriveRemoveByBanish();
|
||||
break;
|
||||
case FixedRemoveType.RemoveByDestroy:
|
||||
target.DepriveRemoveByDestroy();
|
||||
break;
|
||||
default:
|
||||
AIConsoleUtility.LogError("AIChangeInplayFixRemoveType.StopFixRemoveType() error!! _removeType == " + _removeType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public abstract class AIChangeInplayImmediateBarrierBase : AIWhenChangeInplayTagArgument
|
||||
{
|
||||
protected AIScriptTokenArgType _stopTiming;
|
||||
|
||||
protected AIScriptTokenArgType _damageType;
|
||||
|
||||
protected bool _isDamageTypeDefinedByMaster;
|
||||
|
||||
protected abstract int _defaultDamageTypeOffset { get; }
|
||||
|
||||
protected abstract int _stopTimingOffset { get; }
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 1 + (_isDamageTypeDefinedByMaster ? _defaultDamageTypeOffset : _stopTimingOffset);
|
||||
|
||||
public AIChangeInplayImmediateBarrierBase(string text)
|
||||
: base(text, isImmediate: true)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
InitExprList(text);
|
||||
_stopTiming = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - _stopTimingOffset]);
|
||||
_damageType = AIPlayTagInitializingUtility.GetDamageTypeFromExprList(_exprList[_exprList.Count - _defaultDamageTypeOffset], out _isDamageTypeDefinedByMaster);
|
||||
InitSelectType();
|
||||
InitializeFilter();
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStartProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
GiveBarrierToAllTargets(targets, tagOwner, field, playPtn, situation);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStopProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
DepriveBarrierFromAllTargets(targets, tagOwner, field, playPtn, situation);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void GiveBarrierToAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation);
|
||||
|
||||
protected abstract void DepriveBarrierFromAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChangeInplayImmediateDamageClip : AIChangeInplayImmediateBarrierBase
|
||||
{
|
||||
private AIPolishConvertedExpression _clipAmount;
|
||||
|
||||
private AIPolishConvertedExpression _clipRange;
|
||||
|
||||
private const int DEFAULT_CLIP_AMOUNT_OFFSET = 1;
|
||||
|
||||
private bool _isClipRangeDefinedByMaster;
|
||||
|
||||
protected override int _stopTimingOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_isClipRangeDefinedByMaster)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
protected override int _defaultDamageTypeOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_isClipRangeDefinedByMaster)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
public AIChangeInplayImmediateDamageClip(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
InitExprList(text);
|
||||
InitClipAmountAndClipRange();
|
||||
_stopTiming = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - _stopTimingOffset]);
|
||||
_damageType = AIPlayTagInitializingUtility.GetDamageTypeFromExprList(_exprList[_exprList.Count - _defaultDamageTypeOffset], out _isDamageTypeDefinedByMaster);
|
||||
InitSelectType();
|
||||
InitializeFilter();
|
||||
}
|
||||
|
||||
private void InitClipAmountAndClipRange()
|
||||
{
|
||||
AIPolishConvertedExpression aIPolishConvertedExpression = _exprList[_exprList.Count - 1];
|
||||
AIPolishConvertedExpression aIPolishConvertedExpression2 = _exprList[_exprList.Count - 2];
|
||||
if (aIPolishConvertedExpression2.IsMathematicExpress())
|
||||
{
|
||||
_isClipRangeDefinedByMaster = true;
|
||||
_clipAmount = aIPolishConvertedExpression2;
|
||||
_clipRange = aIPolishConvertedExpression;
|
||||
}
|
||||
else
|
||||
{
|
||||
_clipAmount = aIPolishConvertedExpression;
|
||||
_clipRange = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void GiveBarrierToAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
int clipAmount = (int)_clipAmount.EvalArg(tagOwner, playPtn, field, situation);
|
||||
int clipRange = GetClipRange(tagOwner, field, playPtn, situation);
|
||||
AIBarrierSimulationUtility.AddDamageClipToAll(targets, tagOwner, field, _damageType, _stopTiming, clipAmount, clipRange);
|
||||
}
|
||||
|
||||
protected override void DepriveBarrierFromAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIDamageType damageTypeFromArgType = AIBarrierSimulationUtility.GetDamageTypeFromArgType(_damageType);
|
||||
AIBarrierStopTiming barrierStopTimingFromArgType = AIBarrierSimulationUtility.GetBarrierStopTimingFromArgType(_stopTiming, tagOwner);
|
||||
int clipAmount = (int)_clipAmount.EvalArg(tagOwner, playPtn, field, situation);
|
||||
int clipRange = GetClipRange(tagOwner, field, playPtn, situation);
|
||||
ulong depriveShieldHash = AIBarrierSimulationUtility.CalculateDamageClipInfoHash(damageTypeFromArgType, AIBarrierType.DamageClipping, barrierStopTimingFromArgType, clipAmount, clipRange);
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
targets[i].BarrierInfoCollection.DepriveCertainBarrier(depriveShieldHash, barrierStopTimingFromArgType);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetClipRange(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (_clipRange == null)
|
||||
{
|
||||
return 9999;
|
||||
}
|
||||
return (int)_clipRange.EvalArg(tagOwner, playPtn, field, situation);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChangeInplayImmediateDamageCut : AIChangeInplayImmediateBarrierBase
|
||||
{
|
||||
private AIPolishConvertedExpression _cutAmount;
|
||||
|
||||
private const int CUT_AMOUNT_OFFSET = 1;
|
||||
|
||||
protected override int _stopTimingOffset => 2;
|
||||
|
||||
protected override int _defaultDamageTypeOffset => 3;
|
||||
|
||||
public AIChangeInplayImmediateDamageCut(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_cutAmount = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
protected override void GiveBarrierToAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
int cutAmount = (int)_cutAmount.EvalArg(tagOwner, playPtn, field, situation);
|
||||
AIBarrierSimulationUtility.AddDamageCutToAll(targets, tagOwner, field, _damageType, _stopTiming, cutAmount);
|
||||
}
|
||||
|
||||
protected override void DepriveBarrierFromAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIDamageType damageTypeFromArgType = AIBarrierSimulationUtility.GetDamageTypeFromArgType(_damageType);
|
||||
AIBarrierStopTiming barrierStopTimingFromArgType = AIBarrierSimulationUtility.GetBarrierStopTimingFromArgType(_stopTiming, tagOwner);
|
||||
int cutAmount = (int)_cutAmount.EvalArg(tagOwner, playPtn, field, situation);
|
||||
ulong depriveShieldHash = AIBarrierSimulationUtility.CalculateDamageCutInfoHash(damageTypeFromArgType, AIBarrierType.Shield, barrierStopTimingFromArgType, cutAmount);
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
targets[i].BarrierInfoCollection.DepriveCertainBarrier(depriveShieldHash, barrierStopTimingFromArgType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChangeInplayImmediateDamageModifier : AIWhenChangeInplayTagArgument
|
||||
{
|
||||
private static readonly AIScriptTokenArgType[] _legalOptionTypes = new AIScriptTokenArgType[2]
|
||||
{
|
||||
AIScriptTokenArgType.ADD,
|
||||
AIScriptTokenArgType.SET
|
||||
};
|
||||
|
||||
private AIScriptTokenArgType _modifyOption;
|
||||
|
||||
private AIPolishConvertedExpression _modifyValue;
|
||||
|
||||
private const int MODIFY_OPTION_ARG_OFFSET = 2;
|
||||
|
||||
private const int MODIFY_VALUE_ARG_OFFSET = 1;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => -1;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 2;
|
||||
|
||||
public AIChangeInplayImmediateDamageModifier(string text)
|
||||
: base(text, isImmediate: true)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_modifyOption = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - 2], _legalOptionTypes);
|
||||
_modifyValue = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
protected override void InitSelectType()
|
||||
{
|
||||
base.SelectType = AIScriptTokenArgType.NONE;
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISkillProcessInformation processInfo, AISituationInfo situation = null)
|
||||
{
|
||||
ChangeInplayTagStartProcess(null, field, tagOwner, playPtn, situation);
|
||||
}
|
||||
|
||||
public override void Stop(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISkillProcessInformation processInfo, AISituationInfo situation)
|
||||
{
|
||||
ChangeInplayTagStopProcess(null, field, tagOwner, playPtn, situation);
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStartProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIDamageModifierInfo info = new AIDamageModifierInfo(tagOwner, base.Filters, _modifyOption, _modifyValue, base.TextHash);
|
||||
field.DamageModifierCollection.AddDamageModifierInfo(info);
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStopProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
field.DamageModifierCollection.DepriveDamageModifierInfo(tagOwner, base.TextHash);
|
||||
}
|
||||
|
||||
public override void ExecuteWhenRemove(AIVirtualCard tagOwner, AIVirtualField field, AIPlayTag removingTag)
|
||||
{
|
||||
field.DamageModifierCollection.DepriveDamageModifierInfo(tagOwner, base.TextHash);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChangeInplayImmediateIndestructible : AIWhenChangeInplayTagArgument
|
||||
{
|
||||
public AIChangeInplayImmediateIndestructible(string text)
|
||||
: base(text, isImmediate: true)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.BothInplayCards;
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStartProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
GiveIndestructibleToAll(targets);
|
||||
}
|
||||
}
|
||||
|
||||
private void GiveIndestructibleToAll(List<AIVirtualCard> targets)
|
||||
{
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
targets[i].IsIndestructible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChangeInplayImmediateKeywordSkill : AIWhenChangeInplayTagArgument
|
||||
{
|
||||
protected AIScriptTokenArgType _stopTiming;
|
||||
|
||||
private readonly AIScriptTokenArgType _skillType;
|
||||
|
||||
private IEnumerable<AIVirtualCard> _giveCardList;
|
||||
|
||||
protected virtual int StopTimingOffset => 1;
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => SELECT_TYPE_OFFSET;
|
||||
|
||||
public AIChangeInplayImmediateKeywordSkill(string text, AIScriptTokenArgType skill)
|
||||
: base(text, isImmediate: true)
|
||||
{
|
||||
_skillType = skill;
|
||||
base.SelectType = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - SELECT_TYPE_OFFSET], base.LegalSelectTypes);
|
||||
if (!IsImplementedSelecvtType(base.SelectType))
|
||||
{
|
||||
base.SelectType = AIScriptTokenArgType.ALL_SELECT;
|
||||
}
|
||||
List<AIPolishConvertedExpression> range = _exprList.GetRange(0, _exprList.Count - NON_FILTER_FIRST_OFFSET);
|
||||
base.Filters = GetFilters(range);
|
||||
_stopTiming = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - StopTimingOffset]);
|
||||
}
|
||||
|
||||
protected override List<AIVirtualCard> GetCandidateRange(AIVirtualField field)
|
||||
{
|
||||
return field.CardListSet.AllReferableCards;
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISkillProcessInformation processInfo, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AISkillSimulationUtility.GiveSkillToAll(targetsFromField, field, _skillType);
|
||||
}
|
||||
ChangeInplayStopPreprocess(targetsFromField, field);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CreateLegalSelectTypes()
|
||||
{
|
||||
base.LegalSelectTypes = new AIScriptTokenArgType[1] { AIScriptTokenArgType.ALL_SELECT };
|
||||
}
|
||||
|
||||
private bool IsImplementedSelecvtType(AIScriptTokenArgType type)
|
||||
{
|
||||
return type == AIScriptTokenArgType.ALL_SELECT;
|
||||
}
|
||||
|
||||
protected void ChangeInplayStopPreprocess(List<AIVirtualCard> targets, AIVirtualField field)
|
||||
{
|
||||
if (targets != null && targets.Count > 0 && _stopTiming == AIScriptTokenArgType.WHEN_LEAVE)
|
||||
{
|
||||
WhenLeaveStop(targets, field);
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenLeaveStop(List<AIVirtualCard> targets, AIVirtualField field)
|
||||
{
|
||||
if (_skillType != AIScriptTokenArgType.UNTOUCHABLE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (AIVirtualCard target in targets)
|
||||
{
|
||||
WhenLeaveStopUntouchable(target, field);
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenLeaveStopUntouchable(AIVirtualCard card, AIVirtualField field)
|
||||
{
|
||||
AIUntouchableStopPreprocessOption option = new AIUntouchableStopPreprocessOption(card);
|
||||
field.TagPreprocessContainer.AppendLeaveStopInfo(option, card);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChangeInplayImmediateLifeLowerLimit : AIChangeInplayImmediateBarrierBase
|
||||
{
|
||||
protected override int _stopTimingOffset => 1;
|
||||
|
||||
protected override int _defaultDamageTypeOffset => 2;
|
||||
|
||||
public AIChangeInplayImmediateLifeLowerLimit(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void GiveBarrierToAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIBarrierSimulationUtility.AddLifeLowerLimitToAll(targets, tagOwner, field, _damageType, _stopTiming);
|
||||
}
|
||||
|
||||
protected override void DepriveBarrierFromAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIDamageType damageTypeFromArgType = AIBarrierSimulationUtility.GetDamageTypeFromArgType(_damageType);
|
||||
AIBarrierStopTiming barrierStopTimingFromArgType = AIBarrierSimulationUtility.GetBarrierStopTimingFromArgType(_stopTiming, tagOwner);
|
||||
ulong depriveShieldHash = AIBarrierSimulationUtility.CalculateBarrierInfoBaseHash(damageTypeFromArgType, AIBarrierType.DamageClippingLifeLowerLimit, barrierStopTimingFromArgType);
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
targets[i].BarrierInfoCollection.DepriveCertainBarrier(depriveShieldHash, barrierStopTimingFromArgType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChangeInplayImmediateShield : AIChangeInplayImmediateBarrierBase
|
||||
{
|
||||
protected override int _defaultDamageTypeOffset => 2;
|
||||
|
||||
protected override int _stopTimingOffset => 1;
|
||||
|
||||
public AIChangeInplayImmediateShield(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void GiveBarrierToAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIBarrierSimulationUtility.AddShieldToAll(targets, tagOwner, field, _damageType, _stopTiming);
|
||||
}
|
||||
|
||||
protected override void DepriveBarrierFromAllTargets(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIDamageType damageTypeFromArgType = AIBarrierSimulationUtility.GetDamageTypeFromArgType(_damageType);
|
||||
AIBarrierStopTiming barrierStopTimingFromArgType = AIBarrierSimulationUtility.GetBarrierStopTimingFromArgType(_stopTiming, tagOwner);
|
||||
ulong depriveShieldHash = AIBarrierSimulationUtility.CalculateBarrierInfoBaseHash(damageTypeFromArgType, AIBarrierType.Shield, barrierStopTimingFromArgType);
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
{
|
||||
targets[i].BarrierInfoCollection.DepriveCertainBarrier(depriveShieldHash, barrierStopTimingFromArgType);
|
||||
}
|
||||
}
|
||||
}
|
||||
60
SVSim.BattleEngine/Engine/Wizard/AIChangePpTotalBuff.cs
Normal file
60
SVSim.BattleEngine/Engine/Wizard/AIChangePpTotalBuff.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChangePpTotalBuff : AIWhenChangeInplayTagArgument
|
||||
{
|
||||
private const int LIFE_OFFSET = 1;
|
||||
|
||||
private const int ATTACK_OFFSET = 2;
|
||||
|
||||
public AIPolishConvertedExpression Attack { get; private set; }
|
||||
|
||||
public AIPolishConvertedExpression Life { get; private set; }
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 3;
|
||||
|
||||
public AIChangePpTotalBuff(string text, bool isImmediate)
|
||||
: base(text, isImmediate)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
Attack = _exprList[_exprList.Count - 2];
|
||||
Life = _exprList[_exprList.Count - 1];
|
||||
}
|
||||
|
||||
private void BuffTargets(List<AIVirtualCard> targets, AIBuffExecutingInfo_old buffInfo, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIBuffSimulationUtility.BuffAll_old(targets, field, buffInfo, isTemp: false, playPtn, situation);
|
||||
}
|
||||
else
|
||||
{
|
||||
AIConsoleUtility.LogError($"AIChangePpTotalBuff.BuffTargets(): SelectType is Ileagl [type:{base.SelectType}]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStartProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIBuffExecutingInfo_old buffExecutingInfo_old = AIBuffSimulationUtility.GetBuffExecutingInfo_old(tagOwner, field, situation, playPtn, Attack, Life);
|
||||
BuffTargets(targets, buffExecutingInfo_old, tagOwner, field, playPtn, situation);
|
||||
}
|
||||
|
||||
protected override void ChangeInplayTagStopProcess(List<AIVirtualCard> targets, AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
|
||||
{
|
||||
AIBuffExecutingInfo_old buffExecutingInfo_old = AIBuffSimulationUtility.GetBuffExecutingInfo_old(tagOwner, field, situation, playPtn, Attack, Life);
|
||||
if (!buffExecutingInfo_old.IsMultiplyAttack && !buffExecutingInfo_old.IsMultiplyLife)
|
||||
{
|
||||
buffExecutingInfo_old.AttackValue *= -1;
|
||||
buffExecutingInfo_old.LifeValue *= -1;
|
||||
BuffTargets(targets, buffExecutingInfo_old, tagOwner, field, playPtn, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
27
SVSim.BattleEngine/Engine/Wizard/AIChoiceBrave.cs
Normal file
27
SVSim.BattleEngine/Engine/Wizard/AIChoiceBrave.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChoiceBrave : AIChoiceTagArgument
|
||||
{
|
||||
public AIChoiceBrave()
|
||||
: base("")
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
_choiceCount = null;
|
||||
_choiceIds = null;
|
||||
}
|
||||
|
||||
public override int GetChoiceCount(AIVirtualCard owner, AIVirtualField field, AISituationInfo situation)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetChoiceTargets(AIVirtualCard owner, AIVirtualField field)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
84
SVSim.BattleEngine/Engine/Wizard/AIChoiceTagArgument.cs
Normal file
84
SVSim.BattleEngine/Engine/Wizard/AIChoiceTagArgument.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChoiceTagArgument : AIScriptArgumentExpressions
|
||||
{
|
||||
protected List<int> _choiceIds;
|
||||
|
||||
protected AIPolishConvertedExpression _choiceCount;
|
||||
|
||||
private const int CHOICE_COUNT_OFFSET = 1;
|
||||
|
||||
private List<AIVirtualCard> _playerChoiceFakeCards;
|
||||
|
||||
private List<AIVirtualCard> _enemyChoiceFakeCards;
|
||||
|
||||
public AIChoiceTagArgument(string text)
|
||||
: base(text)
|
||||
{
|
||||
_playerChoiceFakeCards = null;
|
||||
_enemyChoiceFakeCards = null;
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
_choiceCount = _exprList[_exprList.Count - 1];
|
||||
_choiceIds = new List<int>();
|
||||
for (int i = 0; i < _exprList.Count - 1; i++)
|
||||
{
|
||||
_choiceIds.Add(_exprList[i].EvalID());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual List<AIVirtualCard> GetChoiceTargets(AIVirtualCard owner, AIVirtualField field)
|
||||
{
|
||||
if (owner.IsPlayer && _playerChoiceFakeCards == null)
|
||||
{
|
||||
CreateChoiceTargets(owner, field, out _playerChoiceFakeCards);
|
||||
}
|
||||
else if (!owner.IsPlayer && _enemyChoiceFakeCards == null)
|
||||
{
|
||||
CreateChoiceTargets(owner, field, out _enemyChoiceFakeCards);
|
||||
}
|
||||
if (!owner.IsPlayer)
|
||||
{
|
||||
return _enemyChoiceFakeCards;
|
||||
}
|
||||
return _playerChoiceFakeCards;
|
||||
}
|
||||
|
||||
private void CreateChoiceTargets(AIVirtualCard owner, AIVirtualField field, out List<AIVirtualCard> choiceFakeCards)
|
||||
{
|
||||
choiceFakeCards = new List<AIVirtualCard>();
|
||||
AITokenManager tokenManager = field.AI.tokenManager;
|
||||
for (int i = 0; i < _choiceIds.Count; i++)
|
||||
{
|
||||
AIVirtualCard choiceTokenFromId = tokenManager.GetChoiceTokenFromId(_choiceIds[i], owner.IsAlly);
|
||||
if (choiceTokenFromId == null)
|
||||
{
|
||||
AIConsoleUtility.LogError("GetChoiceTarget error!! choiceBaseCard is null");
|
||||
break;
|
||||
}
|
||||
ChoiceVirtualCard choiceVirtualCard = new ChoiceVirtualCard(choiceTokenFromId.BaseCard, owner.IsAlly, field);
|
||||
choiceVirtualCard.InitializeTags(field.ParamQuery, null, null);
|
||||
choiceFakeCards.Add(choiceVirtualCard);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int GetChoiceCount(AIVirtualCard owner, AIVirtualField field, AISituationInfo situation)
|
||||
{
|
||||
return (int)_choiceCount.EvalArg(owner, null, field, situation);
|
||||
}
|
||||
|
||||
public List<int> GetChoiceIdList()
|
||||
{
|
||||
return _choiceIds;
|
||||
}
|
||||
|
||||
protected override AITokenIdCollection CreateRegisterTokenPoolInfo(AIVirtualCard owner, List<int> idList)
|
||||
{
|
||||
return AISummonTokenUtility.CreateTokenIdCollectionFromIdList(owner, AIScriptTokenArgType.ALLY, idList, AITokenType.Choice);
|
||||
}
|
||||
}
|
||||
25
SVSim.BattleEngine/Engine/Wizard/AIChoiceTransform.cs
Normal file
25
SVSim.BattleEngine/Engine/Wizard/AIChoiceTransform.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIChoiceTransform : AIScriptArgumentExpressions
|
||||
{
|
||||
public AIChoiceTransform(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
public void RegisterSelfToOwner(AIVirtualCard owner, AIVirtualField field, AIConditionExpressions cond)
|
||||
{
|
||||
for (int i = 0; i < _exprList.Count; i++)
|
||||
{
|
||||
AIChoiceTransformCostInformation aIChoiceTransformCostInformation = new AIChoiceTransformCostInformation
|
||||
{
|
||||
Cost = _exprList[i]
|
||||
};
|
||||
if (!cond.IsEmpty)
|
||||
{
|
||||
aIChoiceTransformCostInformation.SetCondition(cond);
|
||||
}
|
||||
owner.ChoiceTransformCostList = AIParamQuery.AddElementToList(aIChoiceTransformCostInformation, owner.ChoiceTransformCostList);
|
||||
}
|
||||
}
|
||||
}
|
||||
45
SVSim.BattleEngine/Engine/Wizard/AIChoiceTransformUtility.cs
Normal file
45
SVSim.BattleEngine/Engine/Wizard/AIChoiceTransformUtility.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public static class AIChoiceTransformUtility
|
||||
{
|
||||
public static int GetChoiceTransformCost(AIVirtualCard card, AIVirtualField field, List<int> playPtn)
|
||||
{
|
||||
if (card == null || card.ChoiceTransformCostList == null || !card.IsInHand)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
List<int> playPtn2 = (card.IsAlly ? playPtn : null);
|
||||
return field.AI.PlayPtnRecorder.GetCardPlaySimulationTypeCost(card, field, playPtn2, null, PlaySimulationType.ChoiceTransform);
|
||||
}
|
||||
|
||||
public static bool IsChoiceTransform(AIVirtualField field, AIVirtualTargetSelectAction situation)
|
||||
{
|
||||
if (situation.ActionType != AIOperationType.PLAY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
AIVirtualCard originalCard = situation.OriginalCard;
|
||||
if (originalCard.ChoiceTransformCostList == null || originalCard.ChoiceTransformCostList.Count <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
List<int> emptyPlayPtn = EnemyAI.EmptyPlayPtn;
|
||||
int num = (originalCard.IsAlly ? field.AllyPp : field.EnemyPp);
|
||||
int num2 = -1;
|
||||
for (int i = 0; i < originalCard.ChoiceTransformCostList.Count; i++)
|
||||
{
|
||||
AIChoiceTransformCostInformation aIChoiceTransformCostInformation = originalCard.ChoiceTransformCostList[i];
|
||||
if (aIChoiceTransformCostInformation.CheckCondition(originalCard, field, emptyPlayPtn, situation))
|
||||
{
|
||||
int num3 = (int)aIChoiceTransformCostInformation.Cost.EvalArg(originalCard, emptyPlayPtn, field, situation);
|
||||
if (num >= num3 && num3 > num2)
|
||||
{
|
||||
num2 = num3;
|
||||
}
|
||||
}
|
||||
}
|
||||
return num2 >= 0;
|
||||
}
|
||||
}
|
||||
18
SVSim.BattleEngine/Engine/Wizard/AIClashBuff.cs
Normal file
18
SVSim.BattleEngine/Engine/Wizard/AIClashBuff.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace Wizard;
|
||||
|
||||
public class AIClashBuff : AIAttackBuff
|
||||
{
|
||||
protected override int SELECT_TYPE_OFFSET => 0;
|
||||
|
||||
protected override int NON_FILTER_FIRST_OFFSET => 3;
|
||||
|
||||
public AIClashBuff(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitSelectType()
|
||||
{
|
||||
base.SelectType = AIScriptTokenArgType.ALL_SELECT;
|
||||
}
|
||||
}
|
||||
119
SVSim.BattleEngine/Engine/Wizard/AIClashDamage.cs
Normal file
119
SVSim.BattleEngine/Engine/Wizard/AIClashDamage.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wizard;
|
||||
|
||||
public class AIClashDamage : AIWhenAttackOrWhenFightTagArgument
|
||||
{
|
||||
private readonly int DAMAGE_ARG_OFFSET = 1;
|
||||
|
||||
public AIPolishConvertedExpression Damage { get; private set; }
|
||||
|
||||
protected override int SELECT_TYPE_OFFSET => 2;
|
||||
|
||||
public override bool IsActivateWhenEvalInstantAttack => true;
|
||||
|
||||
public AIClashDamage(string text)
|
||||
: base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitExpressions(string text)
|
||||
{
|
||||
base.InitExpressions(text);
|
||||
Damage = _exprList[_exprList.Count - DAMAGE_ARG_OFFSET];
|
||||
}
|
||||
|
||||
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField != null && targetsFromField.Count > 0)
|
||||
{
|
||||
int damage = (int)Damage.EvalArg(tagOwner, playPtn, field, situation);
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
|
||||
{
|
||||
AIDamageSimulationUtility.DamageAll(targetsFromField, tagOwner, field, damage, situation);
|
||||
}
|
||||
else if (base.SelectType == AIScriptTokenArgType.RANDOM_SELECT)
|
||||
{
|
||||
AIDamageSimulationUtility.DamageRandom(targetsFromField, tagOwner, field, damage, situation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
|
||||
{
|
||||
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective: false, isBlockDead);
|
||||
}
|
||||
|
||||
public override bool CanKillTarget(AIVirtualCard tagOwner, AIVirtualCard target, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, AIBarrierPseudoSimulationInfo simBarrier, ref int totalDamage)
|
||||
{
|
||||
totalDamage += PseudoSimulateWhenAttackDamageToCertainCard(tagOwner, target, field, situation, playPtn, simBarrier);
|
||||
return totalDamage >= target.Life;
|
||||
}
|
||||
|
||||
public override int PseudoSimulateWhenAttackDamageToCertainCard(AIVirtualCard tagOwner, AIVirtualCard damageTarget, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, AIBarrierPseudoSimulationInfo simBarrier)
|
||||
{
|
||||
int damageToCertainTarget = GetDamageToCertainTarget(tagOwner, situation, field, playPtn, damageTarget);
|
||||
if (damageToCertainTarget <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
bool isSpell = tagOwner.IsSpell;
|
||||
int result = simBarrier.SimulateDamageAmount(damageTarget.SimulateDamageShield(damageToCertainTarget, isSkillDamage: true, isSpell), isSpell);
|
||||
simBarrier.DepriveBarrier(AIBarrierStopTiming.AfterDamage);
|
||||
return result;
|
||||
}
|
||||
|
||||
private int GetDamageToCertainTarget(AIVirtualCard tagOwner, AISituationInfo situation, AIVirtualField field, List<int> playPtn, AIVirtualCard damageTarget)
|
||||
{
|
||||
if (damageTarget.IsIndependent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (damageTarget.IsSameCardIncluded(targetsFromField))
|
||||
{
|
||||
int num = (int)Damage.EvalArg(tagOwner, playPtn, field, situation);
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT || (base.SelectType == AIScriptTokenArgType.RANDOM_SELECT && damageTarget.IsSameCard(AIDamageSimulationUtility.SelectDamageTarget(targetsFromField, field, playPtn, situation, num, isSpell: false, AISelectTargetPattern.Worst))))
|
||||
{
|
||||
return num;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override bool CanKillAnyTarget(AIVirtualCard tagOwner, List<AIVirtualCard> targetList, AIVirtualField field, AIVirtualAttackInfo situation, List<int> playPtn, List<AIBarrierPseudoSimulationInfo> simBarrierList, int[] realDamageList)
|
||||
{
|
||||
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
|
||||
if (targetsFromField == null || targetsFromField.Count <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int num = (int)Damage.EvalArg(tagOwner, playPtn, field, situation);
|
||||
if (num <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool isSpell = tagOwner.IsSpell;
|
||||
for (int i = 0; i < targetList.Count; i++)
|
||||
{
|
||||
AIVirtualCard aIVirtualCard = targetList[i];
|
||||
if (aIVirtualCard.IsIndependent || !aIVirtualCard.IsSameCardIncluded(targetsFromField))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
AIBarrierPseudoSimulationInfo aIBarrierPseudoSimulationInfo = simBarrierList[i];
|
||||
int num2 = aIBarrierPseudoSimulationInfo.SimulateDamageAmount(aIVirtualCard.SimulateDamageShield(num, isSkillDamage: true, isSpell), isSpell);
|
||||
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT || (base.SelectType == AIScriptTokenArgType.RANDOM_SELECT && aIVirtualCard.IsSameCard(AIDamageSimulationUtility.SelectDamageTarget(targetsFromField, field, playPtn, situation, num2, isSpell: false, AISelectTargetPattern.Worst))))
|
||||
{
|
||||
aIBarrierPseudoSimulationInfo.DepriveBarrier(AIBarrierStopTiming.AfterDamage);
|
||||
realDamageList[i] += num2;
|
||||
if (realDamageList[i] >= aIVirtualCard.Life)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user