feat(battle-engine): M1 auto-copy closure (782 battle-logic files)

Compile-driven bulk-copy loop (tools/engine-port/m1_copy_loop.py) pulled the precise reference closure of the battle-core roots, stopping at the classify god-object/View-VFX-UI boundary. 782 files; no re-explosion (M0 had estimated ~order 1000). Residual frontier = 52 shim-classified + 80 external (Unity/BCL) types to author next.
This commit is contained in:
gamer147
2026-06-05 16:57:20 -04:00
parent 23a6596558
commit 0d9d8acae0
778 changed files with 165107 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
using System.Collections.Generic;
namespace Wizard;
public class AIAccelerateInformation
{
public int Cost;
public int CardId;
public AIConditionExpressions Condition { get; private set; }
public void SetCondition(AIConditionExpressions cond)
{
Condition = cond;
}
public bool CheckCondition(AIVirtualCard owner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (Condition == null || Condition.IsEmpty)
{
return true;
}
return Condition.CheckCondition(owner, playPtn, field, situation);
}
}

View File

@@ -0,0 +1,55 @@
namespace Wizard;
public class AIActivateCountTagArgument : AIScriptArgumentExpressions
{
private static readonly AIScriptTokenArgType[] LegalResetSideTypes = new AIScriptTokenArgType[4]
{
AIScriptTokenArgType.ALLY,
AIScriptTokenArgType.OPPONENT,
AIScriptTokenArgType.BOTH,
AIScriptTokenArgType.NONE
};
protected const int RESET_SIDE_TYPE_OFFSET = 3;
protected const int SKILL_OWNER_ID_OFFSET = 2;
protected const int SKILL_INDEX_OFFSET = 1;
public AIScriptTokenArgType ResetSideType { get; protected set; }
public int SkillOwnerId { get; protected set; }
public int SkillIndex { get; protected set; }
public int TurnMaxActivateCount { get; protected set; }
public AIActivateCountTagArgument(string text)
: base(text)
{
}
protected override void InitExpressions(string text)
{
base.InitExpressions(text);
TurnMaxActivateCount = -1;
if (_exprList[_exprList.Count - 1].TokenList[0] is AIScriptNumericToken aIScriptNumericToken)
{
SkillIndex = (int)aIScriptNumericToken.Value;
ResetSideType = AIPlayTagInitializingUtility.CreateSingleArgType(_exprList[_exprList.Count - 3], LegalResetSideTypes);
if (_exprList[_exprList.Count - 2].TokenList[0] is AIScriptIDToken aIScriptIDToken)
{
SkillOwnerId = aIScriptIDToken.ID;
}
else
{
SkillOwnerId = -1;
}
}
else
{
SkillIndex = 0;
SkillOwnerId = -1;
}
}
}

View File

@@ -0,0 +1,151 @@
using System.Collections.Generic;
namespace Wizard;
public class AIActivateCounter
{
private AIPlayTag _sourceTag;
private AIActivateCountTagArgument _sourceTagArgument;
public int ActivateCount { get; private set; }
public int TurnMaxActivateCount => _sourceTagArgument.TurnMaxActivateCount;
public AIScriptTokenArgType ResetSideType => _sourceTagArgument.ResetSideType;
public int SourceCardId => _sourceTagArgument.SkillOwnerId;
public int CounterIndex => _sourceTagArgument.SkillIndex;
public AIPlayTagType CounterType => _sourceTag.Type;
public AIActivateCounter(AIPlayTag tag, int count = 0)
{
ActivateCount = count;
_sourceTag = tag;
_sourceTagArgument = tag.ArgumentExpressions as AIActivateCountTagArgument;
if (_sourceTagArgument == null)
{
AIConsoleUtility.LogError("AIActivateCounter error!! _sourceTagArgument == null!!!!!!");
}
}
public AIActivateCounter Clone()
{
return new AIActivateCounter(_sourceTag, ActivateCount);
}
public void CheckConditionAndIncrement(AIVirtualCard owner, AISituationInfo situation, AIVirtualCard triggerCard)
{
AIVirtualField selfField = owner.SelfField;
List<int> bestPlayPtn = selfField.BestPlayPtn;
if (CanIncrement() && _sourceTag.CheckCondition(owner, bestPlayPtn, selfField, situation) && (!(_sourceTagArgument is AIFilteringActivateCountArgument aIFilteringActivateCountArgument) || (triggerCard != null && AIFilteringUtility.CheckMatchTargetFiltering(triggerCard, null, aIFilteringActivateCountArgument.Filters, bestPlayPtn, owner, situation))))
{
ActivateCount++;
}
}
public void CheckConditionAndIncrement(AIVirtualCard owner, AISituationInfo situation, List<AIVirtualCard> triggerCardList)
{
AIVirtualField selfField = owner.SelfField;
List<int> bestPlayPtn = selfField.BestPlayPtn;
if (!CanIncrement() || !_sourceTag.CheckCondition(owner, bestPlayPtn, selfField, situation))
{
return;
}
bool flag = false;
if (_sourceTagArgument is AIFilteringActivateCountArgument aIFilteringActivateCountArgument)
{
if (triggerCardList == null || triggerCardList.Count <= 0)
{
return;
}
for (int i = 0; i < triggerCardList.Count; i++)
{
if (AIFilteringUtility.CheckMatchTargetFiltering(triggerCardList[i], null, aIFilteringActivateCountArgument.Filters, bestPlayPtn, owner, situation))
{
flag = true;
break;
}
}
}
else
{
flag = true;
}
if (flag)
{
ActivateCount++;
}
}
private bool CanIncrement()
{
if (TurnMaxActivateCount == -1 || ActivateCount < TurnMaxActivateCount)
{
return true;
}
return false;
}
public int GetCountIfMatched(int sourceCardId, int index)
{
if (SourceCardId == sourceCardId && CounterIndex == index)
{
return ActivateCount;
}
return 0;
}
public bool IsSkillOccurred()
{
if (TurnMaxActivateCount == -1)
{
return false;
}
return ActivateCount >= TurnMaxActivateCount;
}
public void Reset(bool isOwnerTurn)
{
switch (ResetSideType)
{
case AIScriptTokenArgType.BOTH:
ActivateCount = 0;
break;
case AIScriptTokenArgType.ALLY:
if (isOwnerTurn)
{
ActivateCount = 0;
}
break;
case AIScriptTokenArgType.OPPONENT:
if (!isOwnerTurn)
{
ActivateCount = 0;
}
break;
}
}
public bool IsDuplicate(AIPlayTag tag)
{
return tag.Hash == _sourceTag.Hash;
}
public bool InheritFromOtherCounter(AIActivateCounter counter)
{
if (IsDuplicate(counter))
{
ActivateCount = counter.ActivateCount;
return true;
}
return false;
}
private bool IsDuplicate(AIActivateCounter counter)
{
return counter.IsDuplicate(_sourceTag);
}
}

View File

@@ -0,0 +1,64 @@
using System.Collections.Generic;
namespace Wizard;
public class AIAfterDamageStopCollection : AITagPreprocessCollectionBase
{
public AIAfterDamageStopCollection Clone(List<AIVirtualCard> overrideCardList)
{
AIAfterDamageStopCollection aIAfterDamageStopCollection = new AIAfterDamageStopCollection();
aIAfterDamageStopCollection.CopyInfoListWithReplaceCardReference(overrideCardList, base.InfoList);
return aIAfterDamageStopCollection;
}
public void SimulateActionAll(AIVirtualCard damagedCard)
{
List<AITagPreprocessInformationBase> list = null;
for (int i = 0; i < base.InfoList.Count; i++)
{
if (base.InfoList[i] is AIAfterDamageStopInformation aIAfterDamageStopInformation && aIAfterDamageStopInformation.ExecuteReservedAction(damagedCard))
{
list = AIParamQuery.AddElementToList(aIAfterDamageStopInformation, list);
}
}
if (list != null && list.Count > 0)
{
for (int j = 0; j < list.Count; j++)
{
base.InfoList.Remove(list[j]);
}
}
}
public void AppendInfo(AITagPreprocessCreationOptionBase option)
{
AIAfterDamageStopInformation aIAfterDamageStopInformation = CreateInfo(option);
if (aIAfterDamageStopInformation != null)
{
base.InfoList.Add(aIAfterDamageStopInformation);
}
}
private AIAfterDamageStopInformation CreateInfo(AITagPreprocessCreationOptionBase option)
{
if (option.PreprocessInfoType == AITagPreprocessInfoType.BARRIER_STOP)
{
return new AIBarrierAfterDamageStopInformation(option as AIBarrierStopPreprocessOption);
}
AIConsoleUtility.LogError("AITurnEndStopInfoContainer-CreateInfo(): Missing TurnEndInfo type");
return null;
}
protected override void GetOverrideCardAndAppendCopyInfo(List<AIVirtualCard> overrideCardList, AITagPreprocessInformationBase originalInfo)
{
if (overrideCardList != null && overrideCardList.Count > 0)
{
AIVirtualCard overrideTargetCard = originalInfo.GetOverrideTargetCard(overrideCardList);
if (overrideTargetCard != null)
{
AITagPreprocessCreationOptionBase option = originalInfo.CreateOptionInfoForOverride(overrideTargetCard);
AppendInfo(option);
}
}
}
}

View File

@@ -0,0 +1,23 @@
namespace Wizard;
public class AIAfterDamageStopInformation : AITagPreprocessInformationBase
{
public AIAfterDamageStopInformation(AIVirtualCard card)
: base(card)
{
}
public bool ExecuteReservedAction(AIVirtualCard damagedCard)
{
if (damagedCard.IsSameCard(base.TargetCard))
{
StopMethod();
return true;
}
return false;
}
protected virtual void StopMethod()
{
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using Wizard.Battle.View.Vfx;
namespace Wizard;
public class AIAttachOperateMgrBattleEventCache
{
public Action<BattleCardBase, BattleCardBase, IEnumerable<BattleCardBase>> OnSetCardSuccessEvent;
public Func<BattleCardBase, VfxBase> OnSetCardExecutedEvent;
public Action<BattleCardBase, BattleCardBase, IEnumerable<BattleCardBase>> OnEvolveSuccessEvent;
public Func<BattleCardBase, VfxBase> OnEvolveCompleteEvent;
public Func<BattleCardBase, BattleCardBase, SkillProcessor, VfxBase> OnBeforeAttackEvent;
public Func<BattleCardBase, BattleCardBase, bool, VfxBase> OnAttackExecutedEvent;
public Action<BattleCardBase, IEnumerable<BattleCardBase>> OnBeforeFusionEvent;
public Func<BattleCardBase, VfxBase> OnAfterFusionEvent;
}

View File

@@ -0,0 +1,18 @@
using System;
namespace Wizard;
public class AIAttachPlayerBattleEventCache
{
public Action<BattleCardBase, BattlePlayerBase.CEMETERY_TYPE, bool, SkillBase> AllyAddCemeteryEvent;
public Action<BattleCardBase, BattlePlayerBase.CEMETERY_TYPE, bool, SkillBase> OpponentAddCemeteryEvent;
public Action OpponentTurnStartCompleteEvent;
public Action AllyTurnStartCompleteEvent;
public Action AllySelfTurnEndEvent;
public Action OpponentSelfTurnEndEvent;
}

View File

@@ -0,0 +1,124 @@
using System.Collections.Generic;
namespace Wizard;
public class AIAttachedTagCollection
{
public List<AIAttachedTagInformation> AllList;
public List<AIPlayTag> RemovedTagCacheList { get; private set; }
public bool HasAnyTag
{
get
{
if (AllList != null)
{
return AllList.Count > 0;
}
return false;
}
}
public bool HasRemovedInfoCaches
{
get
{
if (RemovedTagCacheList != null)
{
return RemovedTagCacheList.Count > 0;
}
return false;
}
}
public AIAttachedTagCollection()
{
AllList = null;
}
public AIAttachedTagCollection Clone()
{
return new AIAttachedTagCollection
{
AllList = AIParamQuery.CloneList(AllList)
};
}
public void AddAttachedTagInformation(AIAttachedTagInformation info)
{
AllList = AIParamQuery.AddElementToList(info, AllList);
}
public void RemoveMatchedAttachedTagInformation(bool ownerIsAlly, int ownerCardIndex, AIPlayTag removeingTag, bool needsInheritRemovedTags)
{
if (AllList == null || AllList.Count <= 0)
{
return;
}
for (int i = 0; i < AllList.Count; i++)
{
AIAttachedTagInformation aIAttachedTagInformation = AllList[i];
if (aIAttachedTagInformation.IsReceiverAlly == ownerIsAlly && aIAttachedTagInformation.ReceiverIndex == ownerCardIndex && aIAttachedTagInformation.Tag.Hash == removeingTag.Hash)
{
AllList.RemoveAt(i);
if (needsInheritRemovedTags)
{
RemovedTagCacheList = AIParamQuery.AddElementToList(removeingTag, RemovedTagCacheList);
}
break;
}
}
}
public void RemoveAllAttachedTagInformation(AISituationInfo situation)
{
if (AllList == null || AllList.Count <= 0)
{
return;
}
bool flag = situation?.IsLatestAction ?? false;
while (AllList.Count > 0)
{
if (flag)
{
AIAttachedTagInformation aIAttachedTagInformation = AllList[0];
RemovedTagCacheList = AIParamQuery.AddElementToList(aIAttachedTagInformation.Tag, RemovedTagCacheList);
}
AllList.RemoveAt(0);
}
}
public void AttachTagToReceiver(AIVirtualCard receiver)
{
if (AllList == null || AllList.Count <= 0)
{
return;
}
for (int i = 0; i < AllList.Count; i++)
{
AIAttachedTagInformation aIAttachedTagInformation = AllList[i];
if (aIAttachedTagInformation.IsReceiverAlly == receiver.IsAlly && aIAttachedTagInformation.ReceiverIndex == receiver.CardIndex)
{
receiver.TagCollectionContainer.AttachTag(aIAttachedTagInformation, receiver, null);
}
}
}
public int GetAttachedTagCountFromId(int id)
{
if (!HasAnyTag)
{
return 0;
}
int num = 0;
for (int i = 0; i < AllList.Count; i++)
{
if (AllList[i].ProviderCardId == id)
{
num++;
}
}
return num;
}
}

View File

@@ -0,0 +1,49 @@
namespace Wizard;
public class AIAttachedTagInformation
{
public AIPlayTag Tag { get; private set; }
public AIScriptTokenArgType RemoveTiming { get; private set; }
public int ProviderIndex { get; private set; }
public bool IsProviderAlly { get; private set; }
public int ProviderCardId { get; private set; }
public int ReceiverIndex { get; private set; }
public bool IsReceiverAlly { get; private set; }
public ulong Hash { get; private set; }
public AIAttachedTagInformation(AIPlayTag attachTag, AIScriptTokenArgType removeTiming, AIVirtualCard provider, AIVirtualCard receiver)
{
Tag = attachTag;
RemoveTiming = removeTiming;
ProviderIndex = provider.CardIndex;
IsProviderAlly = provider.IsAlly;
ProviderCardId = provider.BaseId;
ReceiverIndex = receiver.CardIndex;
IsReceiverAlly = receiver.IsAlly;
Hash = GetHash();
}
public AIAttachedTagInformation(AIPlayTag attachTag, AIScriptTokenArgType removeTiming, int providerCardId, int providerIndex, bool providerIsAlly, int receiverIndex, bool receiverIsAlly)
{
Tag = attachTag;
RemoveTiming = removeTiming;
ProviderIndex = providerIndex;
IsProviderAlly = providerIsAlly;
ProviderCardId = providerCardId;
ReceiverIndex = receiverIndex;
IsReceiverAlly = receiverIsAlly;
Hash = GetHash();
}
public ulong GetHash()
{
return (ulong)(((long)(Tag.Hash * 6323) + (long)RemoveTiming.GetHashCode() * 15187L + (long)ProviderIndex * 682009L + (long)ProviderCardId * 733L + (long)ReceiverIndex * 192149L) * (IsProviderAlly ? 641 : 43) * (IsReceiverAlly ? 503 : 4211));
}
}

View File

@@ -0,0 +1,42 @@
using System.Collections.Generic;
namespace Wizard;
public class AIAttackPreCheckInformation
{
public float AttackBonus { get; private set; }
public AISimulationBuffInfoCollection BuffInfo { get; private set; }
public bool HasBuffInfo
{
get
{
if (BuffInfo != null)
{
return BuffInfo.Count > 0;
}
return false;
}
}
public AIAttackPreCheckInformation(float attackBonus, AISimulationBuffInfoCollection buffInfo)
{
AttackBonus = attackBonus;
BuffInfo = buffInfo;
}
public void ApplyBuff(ulong tagHash, AIVirtualField field, List<int> playPtn, AIVirtualAttackInfo situation)
{
BuffInfo.ApplySingleBuff(tagHash, field, playPtn, situation);
}
public bool HasPreCheckBuffInfo(AIPlayTag tag)
{
if (BuffInfo == null)
{
return false;
}
return BuffInfo.HasBuffInfo(tag.Hash);
}
}

View File

@@ -0,0 +1,103 @@
using System.Collections.Generic;
namespace Wizard;
public abstract class AIBarrierInfoBase
{
public int BarrierAmount { get; protected set; }
public AIDamageType DamageType { get; protected set; }
public List<AIBarrierStopTiming> StopTimingList { get; protected set; }
public abstract AIBarrierType BarrierType { get; }
public ulong Hash { get; protected set; }
public AIBarrierInfoBase(int amount, AIDamageType damageType, AIBarrierStopTiming stopTiming = AIBarrierStopTiming.None)
{
BarrierAmount = amount;
DamageType = damageType;
if (stopTiming != AIBarrierStopTiming.None)
{
StopTimingList = new List<AIBarrierStopTiming> { stopTiming };
}
else
{
StopTimingList = null;
}
}
public AIBarrierInfoBase(int amount, AIDamageType damageType, List<AIBarrierStopTiming> stopTimingList)
{
BarrierAmount = amount;
DamageType = damageType;
StopTimingList = stopTimingList;
}
public int GetDamageAmount(AIVirtualCard owner, int damage, bool isSkillDamage, bool isSpellDamage)
{
if (IsDamageType(isSkillDamage, isSpellDamage))
{
return CalcDamage(owner, damage);
}
return damage;
}
public bool IsDamageType(bool isSkillDamage, bool isSpellDamage)
{
if (DamageType == AIDamageType.All)
{
return true;
}
if (DamageType == AIDamageType.Skill && (isSkillDamage || isSpellDamage))
{
return true;
}
if (DamageType == AIDamageType.Spell && isSpellDamage)
{
return true;
}
if (DamageType == AIDamageType.Attack && !isSkillDamage && !isSpellDamage)
{
return true;
}
return false;
}
public bool IsMatchingStopTiming(AIBarrierStopTiming timing)
{
if (StopTimingList == null || StopTimingList.Count <= 0)
{
return timing == AIBarrierStopTiming.None;
}
for (int i = 0; i < StopTimingList.Count; i++)
{
if (timing == StopTimingList[i])
{
return true;
}
}
return false;
}
protected virtual void UpdateHash()
{
Hash = AIBarrierSimulationUtility.CalculateBarrierInfoBaseHash(DamageType, BarrierType, StopTimingList);
}
public bool IsDuplicate(AIBarrierType barrierType, AIDamageType damageType, int barrierAmount)
{
if ((long)BarrierAmount * (long)AIBarrierSimulationUtility.BARRIER_AMOUNT_HASH_COEFFICIENT + (long)DamageType * (long)AIBarrierSimulationUtility.DAMAGE_TYPE_HASH_COEFFICIENT + (long)BarrierType * (long)AIBarrierSimulationUtility.BARRIER_TYPE_HASH_COEFFICIENT == (long)Hash)
{
return true;
}
return false;
}
public abstract AIBarrierInfoBase Clone();
public abstract bool IsShield();
protected abstract int CalcDamage(AIVirtualCard owner, int damage);
}

View File

@@ -0,0 +1,224 @@
using System.Collections.Generic;
namespace Wizard;
public class AIBarrierInfoCollection
{
private int _shieldAllCount;
private int _shieldAttackCount;
private int _shieldSpellCount;
private int _shieldSkillCount;
public List<AIBarrierInfoBase> BarrierList { get; private set; }
public bool HasBarrier
{
get
{
if (BarrierList != null)
{
return BarrierList.Count > 0;
}
return false;
}
}
public int BarrierCount
{
get
{
if (BarrierList == null)
{
return 0;
}
return BarrierList.Count;
}
}
public bool HasShieldAll => _shieldAllCount > 0;
public bool HasShieldAttack => _shieldAttackCount > 0;
public bool HasShieldSpell
{
get
{
if (_shieldSpellCount <= 0)
{
return HasShieldSkill;
}
return true;
}
}
public bool HasShieldSkill => _shieldSkillCount > 0;
public AIBarrierInfoCollection Clone()
{
AIBarrierInfoCollection aIBarrierInfoCollection = new AIBarrierInfoCollection();
if (HasBarrier)
{
for (int i = 0; i < BarrierList.Count; i++)
{
aIBarrierInfoCollection.AddBarrierInfo(BarrierList[i].Clone());
}
}
return aIBarrierInfoCollection;
}
public AIBarrierInfoCollection GetInheritanceForNewVirtualField()
{
AIBarrierInfoCollection aIBarrierInfoCollection = new AIBarrierInfoCollection();
if (HasBarrier)
{
for (int i = 0; i < BarrierList.Count; i++)
{
AIBarrierInfoBase barrierInfo = BarrierList[i];
aIBarrierInfoCollection.AddBarrierInfo(barrierInfo);
}
}
return aIBarrierInfoCollection;
}
public void GetBarrierInfoFromPreviousField(AIBarrierInfoCollection previousBarrierCollection)
{
if (HasBarrier)
{
for (int num = BarrierList.Count - 1; num >= 0; num--)
{
_ = BarrierList[num];
BarrierList.RemoveAt(num);
}
}
if (previousBarrierCollection.HasBarrier)
{
for (int i = 0; i < previousBarrierCollection.BarrierList.Count; i++)
{
AddBarrierInfo(previousBarrierCollection.BarrierList[i].Clone());
}
}
}
public ulong GetHash()
{
ulong num = 0uL;
if (!HasBarrier)
{
return num;
}
for (int i = 0; i < BarrierList.Count; i++)
{
num += BarrierList[i].Hash;
}
return num;
}
public void AddBarrierInfo(AIBarrierInfoBase barrierInfo)
{
BarrierList = AIParamQuery.AddElementToList(barrierInfo, BarrierList);
IncrementHasShieldCount(barrierInfo);
}
public void DepriveAllBarrierOfOneTiming(AIBarrierStopTiming timing)
{
if (!HasBarrier)
{
return;
}
for (int num = BarrierList.Count - 1; num >= 0; num--)
{
AIBarrierInfoBase aIBarrierInfoBase = BarrierList[num];
if (aIBarrierInfoBase.IsMatchingStopTiming(timing))
{
BarrierList.RemoveAt(num);
DecrementHasShieldCount(aIBarrierInfoBase);
}
}
}
public void DepriveCertainBarrier(ulong depriveShieldHash, AIBarrierStopTiming timing)
{
if (!HasBarrier)
{
return;
}
for (int num = BarrierList.Count - 1; num >= 0; num--)
{
AIBarrierInfoBase aIBarrierInfoBase = BarrierList[num];
if (aIBarrierInfoBase.Hash == depriveShieldHash && aIBarrierInfoBase.IsMatchingStopTiming(timing))
{
BarrierList.RemoveAt(num);
DecrementHasShieldCount(aIBarrierInfoBase);
break;
}
}
}
private bool HasDuplicateBarrier(AIBarrierType barrierType, AIDamageType damageType, int barrierAmount)
{
if (BarrierList == null || BarrierList.Count <= 0)
{
return false;
}
for (int i = 0; i < BarrierList.Count; i++)
{
if (BarrierList[i].IsDuplicate(barrierType, damageType, barrierAmount))
{
return true;
}
}
return false;
}
public int CalcDamageAmount(AIVirtualCard owner, int damage, bool isSkillDamage, bool isSpellDamage)
{
if (BarrierList == null || BarrierList.Count <= 0)
{
return damage;
}
int num = damage;
for (int i = 0; i < BarrierList.Count; i++)
{
num = BarrierList[i].GetDamageAmount(owner, num, isSkillDamage, isSpellDamage);
}
return num;
}
private void IncrementHasShieldCount(AIBarrierInfoBase appendInfo)
{
if (appendInfo != null && appendInfo.IsShield())
{
AppendShieldCount(appendInfo.DamageType, 1);
}
}
private void DecrementHasShieldCount(AIBarrierInfoBase removedInfo)
{
if (removedInfo != null && removedInfo.IsShield())
{
AppendShieldCount(removedInfo.DamageType, -1);
}
}
private void AppendShieldCount(AIDamageType type, int appendValue)
{
switch (type)
{
case AIDamageType.All:
_shieldAllCount += appendValue;
break;
case AIDamageType.Attack:
_shieldAttackCount += appendValue;
break;
case AIDamageType.Spell:
_shieldSpellCount += appendValue;
break;
case AIDamageType.Skill:
_shieldSkillCount += appendValue;
break;
}
}
}

View File

@@ -0,0 +1,43 @@
using UnityEngine;
namespace Wizard;
public class AIBarrierPseudoSimulationInfo
{
private AIBarrierInfoCollection _barrierCollection;
public AIVirtualCard Owner { get; private set; }
public AIBarrierPseudoSimulationInfo(AIVirtualCard owner)
{
Owner = owner;
_barrierCollection = ((owner.BarrierInfoCollection != null) ? owner.BarrierInfoCollection.Clone() : new AIBarrierInfoCollection());
}
public AIBarrierPseudoSimulationInfo(AIBarrierPseudoSimulationInfo info)
{
Owner = info.Owner;
_barrierCollection = info._barrierCollection.Clone();
}
public void AddBarrierInfo(AIBarrierInfoBase barrier)
{
_barrierCollection.AddBarrierInfo(barrier);
}
public void DepriveBarrier(AIBarrierStopTiming timing)
{
_barrierCollection.DepriveAllBarrierOfOneTiming(timing);
}
public void DepriveCertainBarrier(AIBarrierStopTiming timing, ulong barrierHash)
{
_barrierCollection.DepriveCertainBarrier(barrierHash, timing);
}
public int SimulateDamageAmount(int damage, bool isSpellDamage, bool isSkillDamage = true)
{
int b = _barrierCollection.CalcDamageAmount(Owner, damage, isSkillDamage, isSpellDamage);
return Mathf.Max(0, b);
}
}

View File

@@ -0,0 +1,12 @@
namespace Wizard;
public enum AIBarrierStopTiming
{
None,
AllyTurnEnd,
OpponentTurnEnd,
WhenLeaveStop,
AfterDamage,
AllyTurnStart,
OpponentTurnStart
}

View File

@@ -0,0 +1,10 @@
namespace Wizard;
public enum AIBarrierType
{
None,
DamageCut,
DamageClipping,
DamageClippingLifeLowerLimit,
Shield
}

View File

@@ -0,0 +1,16 @@
namespace Wizard;
public class AIBattleInfoReceivedData
{
public AttachedSkillInfoReceiveDataCollection AttachedInfoReceiveCollection { get; private set; }
public AIBattleInfoReceivedData()
{
AttachedInfoReceiveCollection = new AttachedSkillInfoReceiveDataCollection();
}
public void ClearAll()
{
AttachedInfoReceiveCollection.Clear();
}
}

View File

@@ -0,0 +1,56 @@
namespace Wizard;
public class AIBuffExecutingInfo_old
{
public int AttackValue;
public int LifeValue;
public bool IsMultiplyAttack;
public bool IsMultiplyLife;
public bool IsEmpty()
{
if (AttackValue == 0 && LifeValue == 0 && !IsMultiplyAttack)
{
return !IsMultiplyLife;
}
return false;
}
public bool IsBuff()
{
bool flag = ((!IsMultiplyAttack) ? (AttackValue >= 0) : (AttackValue >= 1));
bool flag2 = ((!IsMultiplyLife) ? (LifeValue >= 0) : (LifeValue >= 1));
return flag && flag2;
}
public int GetExpectedAttackBuffValue(AIVirtualCard target)
{
return GetExpectedAttackBuffValue(target.Attack);
}
public int GetExpectedAttackBuffValue(int attack)
{
if (IsMultiplyAttack)
{
return attack * AttackValue - attack;
}
return AttackValue;
}
public int GetExpectedLifeBuffValue(AIVirtualCard target)
{
return GetExpectedLifeBuffValue(target.Life);
}
public int GetExpectedLifeBuffValue(int life)
{
if (IsMultiplyLife)
{
return life * LifeValue - life;
}
return LifeValue;
}
}

View File

@@ -0,0 +1,115 @@
using System.Collections.Generic;
namespace Wizard;
public class AIBuffRecorderCollection
{
public class AIBuffRecorder : BuffCountInfo
{
public int SimulateAtkBuffValue;
public int SimulateLifeBuffValue;
public AIBuffRecorder(int turn, bool isSelfTurn, int atkBuff = 0, int lifeBuff = 0)
: base(turn, isSelfTurn)
{
SimulateAtkBuffValue = atkBuff;
SimulateLifeBuffValue = lifeBuff;
}
}
public List<AIBuffRecorder> RecorderList { get; private set; }
public int Count
{
get
{
if (RecorderList != null)
{
return RecorderList.Count;
}
return 0;
}
}
public AIBuffRecorderCollection()
{
RecorderList = null;
}
public AIBuffRecorderCollection(List<BuffCountInfo> turnBuffCountList)
{
RecorderList = null;
CreateRecorderListFromTurnBuffCountList(turnBuffCountList);
}
private AIBuffRecorderCollection(AIBuffRecorderCollection original)
{
RecorderList = AIParamQuery.CloneList(original.RecorderList);
}
public AIBuffRecorderCollection Clone()
{
return new AIBuffRecorderCollection(this);
}
public void AddBuffRecord(int turn, bool isSelfTurn, int atkBuff = 0, int lifeBuff = 0)
{
AIBuffRecorder element = new AIBuffRecorder(turn, isSelfTurn, atkBuff, lifeBuff);
RecorderList = AIParamQuery.AddElementToList(element, RecorderList);
}
public int GetTurnBuffCount(int turn, bool isSelfTurn)
{
if (Count <= 0)
{
return 0;
}
int num = 0;
for (int i = 0; i < RecorderList.Count; i++)
{
AIBuffRecorder aIBuffRecorder = RecorderList[i];
if (aIBuffRecorder.Turn == turn && aIBuffRecorder.IsSelfTurn == isSelfTurn)
{
num++;
}
}
return num;
}
public (int atkSum, int lifeSum) GetSimulateBuff()
{
int num = 0;
int num2 = 0;
if (0 < Count)
{
for (int i = 0; i < RecorderList.Count; i++)
{
AIBuffRecorder aIBuffRecorder = RecorderList[i];
num += aIBuffRecorder.SimulateAtkBuffValue;
num2 += aIBuffRecorder.SimulateLifeBuffValue;
}
}
return (atkSum: num, lifeSum: num2);
}
public void Clear()
{
RecorderList.Clear();
RecorderList = null;
}
public void CreateRecorderListFromTurnBuffCountList(List<BuffCountInfo> turnBuffCountList)
{
if (turnBuffCountList != null && turnBuffCountList.Count > 0)
{
RecorderList = new List<AIBuffRecorder>();
for (int i = 0; i < turnBuffCountList.Count; i++)
{
BuffCountInfo buffCountInfo = turnBuffCountList[i];
AIBuffRecorder item = new AIBuffRecorder(buffCountInfo.Turn, !buffCountInfo.IsSelfTurn);
RecorderList.Add(item);
}
}
}
}

View File

@@ -0,0 +1,83 @@
using System.Collections.Generic;
namespace Wizard;
public class AIBuffWithTargetsInformation
{
private ulong _tagHash;
public List<AIVirtualCard> TargetList { get; private set; }
public AISimulationBuffInfo BuffInfo { get; private set; }
public AIBuffWithTargetsInformation(List<AIVirtualCard> targets, AISimulationBuffInfo buff, ulong hash)
{
TargetList = targets;
BuffInfo = buff;
_tagHash = hash;
}
public void PseudoApplyBuffForSimpleAttack(AIVirtualCard currentAttacker, List<AIVirtualCard> attackerList, Tuple<int, int>[] statusArray)
{
if (TargetList == null || TargetList.Count <= 0)
{
return;
}
for (int i = 0; i < TargetList.Count; i++)
{
AIVirtualCard aIVirtualCard = TargetList[i];
if (aIVirtualCard.IsAlly == currentAttacker.IsAlly)
{
int num = attackerList.IndexOf(aIVirtualCard);
statusArray[num].first += BuffInfo.TotalAttackBuff;
statusArray[num].second += BuffInfo.TotalLifeBuff;
}
}
}
public bool VerifyArgumentAndApply(ulong hash, AIVirtualField field, List<int> playPtn, AIVirtualAttackInfo situation)
{
if (hash != _tagHash)
{
return false;
}
Apply(field, playPtn, situation);
return true;
}
private void Apply(AIVirtualField field, List<int> playPtn, AIVirtualAttackInfo situation)
{
int totalAttackBuff = BuffInfo.TotalAttackBuff;
int totalLifeBuff = BuffInfo.TotalLifeBuff;
AIBuffExecutingInfo_old buffInfo = new AIBuffExecutingInfo_old
{
AttackValue = totalAttackBuff,
LifeValue = totalLifeBuff,
IsMultiplyAttack = false,
IsMultiplyLife = false
};
bool isTemp = BuffInfo.TempAttackBuff > 0 || BuffInfo.TempLifeBuff > 0;
AIBuffSimulationUtility.BuffAll_old(TargetList, field, buffInfo, isTemp, playPtn, situation);
}
public bool ContainsTarget(AIVirtualCard target)
{
if (TargetList == null || TargetList.Count <= 0)
{
return false;
}
for (int i = 0; i < TargetList.Count; i++)
{
if (target.IsSameCard(TargetList[i]))
{
return true;
}
}
return false;
}
public bool IsHashEqual(ulong hash)
{
return _tagHash == hash;
}
}

View File

@@ -0,0 +1,52 @@
using System.Collections.Generic;
namespace Wizard;
public class AICannotAttackInformation
{
private List<AIScriptTokenBase> _filters;
public AICannotAttackInformation(List<AIScriptTokenBase> filters)
{
_filters = filters;
}
public bool IsEqual(AICannotAttackInformation info)
{
return IsSameFilterList(info._filters);
}
private bool IsSameFilterList(List<AIScriptTokenBase> compare)
{
if (_filters == null || _filters.Count <= 0)
{
if (compare != null)
{
return compare.Count <= 0;
}
return true;
}
if (_filters.Count != compare.Count)
{
return false;
}
for (int i = 0; i < _filters.Count; i++)
{
if (!_filters[i].IsEqual(compare[i]))
{
return false;
}
}
return true;
}
public bool IsCannotAttack(AIVirtualField field, AIVirtualAttackInfo situation)
{
if (situation.ActionType != AIOperationType.ATTACK)
{
return true;
}
List<AIVirtualCard> candidates = (situation.Actor.IsAlly ? field.CardListSet.EnemyClassAndInplayCards : field.CardListSet.AllyClassAndInplayCards);
return AIFilteringUtility.CheckMatchTargetFiltering(situation.AttackTarget, candidates, _filters, field.BestPlayPtn, situation.Actor, situation);
}
}

View File

@@ -0,0 +1,53 @@
using System.Collections.Generic;
namespace Wizard;
public class AICannotPlayInformation
{
public AIVirtualCard Owner;
public List<AIScriptTokenBase> Filters;
public AICannotPlayInformation(AIVirtualCard owner, List<AIScriptTokenBase> filters)
{
Owner = owner;
Filters = filters;
}
public bool IsEqual(AIVirtualCard card, List<AIScriptTokenBase> filters)
{
if (!Owner.IsSameCard(card))
{
return false;
}
if (!IsSameFilterList(filters))
{
return false;
}
return true;
}
private bool IsSameFilterList(List<AIScriptTokenBase> compare)
{
if (Filters == null || Filters.Count <= 0)
{
if (compare != null)
{
return compare.Count <= 0;
}
return true;
}
if (Filters.Count != compare.Count)
{
return false;
}
for (int i = 0; i < Filters.Count; i++)
{
if (!Filters[i].IsEqual(compare[i]))
{
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,70 @@
using System.Collections.Generic;
namespace Wizard;
public class AICardData
{
private List<AIPlayTag> tagList;
public int CardID { get; private set; }
public int CardNum { get; private set; }
public List<AIPlayTag> TagList => tagList;
public AIPolishConvertedExpression BattleBonusExpr { get; set; }
public AIPolishConvertedExpression PlayBonusExpr { get; set; }
public AIPolishConvertedExpression PriorityExpr { get; set; }
private string BattleBonus { get; set; }
private string PlayBonus { get; set; }
private string Priority { get; set; }
public AICardData(AICardDataAsset asset)
{
CardID = asset.CardID;
CardNum = asset.CardNum;
BattleBonus = asset.BattleBonus;
PlayBonus = asset.PlayBonus;
Priority = asset.Priority;
tagList = new List<AIPlayTag>();
foreach (AIPlayTagAsset tag in asset.TagList)
{
AIPlayTag aIPlayTag = new AIPlayTag();
if (aIPlayTag.InitFromTextAsset(tag))
{
tagList.Add(aIPlayTag);
}
else
{
aIPlayTag = null;
}
}
BattleBonusExpr = new AIPolishConvertedExpression(asset.BattleBonus);
PlayBonusExpr = new AIPolishConvertedExpression(asset.PlayBonus);
PriorityExpr = new AIPolishConvertedExpression(asset.Priority);
}
public void MergeCardData(AICardData data)
{
BattleBonus = data.BattleBonus;
PlayBonus = data.PlayBonus;
BattleBonusExpr = data.BattleBonusExpr;
PlayBonusExpr = data.PlayBonusExpr;
if (Priority == null || Priority == "")
{
Priority = data.Priority;
PriorityExpr = data.PriorityExpr;
}
MergeTagFromAnotherData(data);
}
public void MergeTagFromAnotherData(AICardData data)
{
tagList.InsertRange(0, data.TagList);
}
}

View File

@@ -0,0 +1,58 @@
using System.Collections.Generic;
namespace Wizard;
public class AICardDataAsset
{
public List<AIPlayTagAsset> TagList;
public int CardID { get; private set; }
public int CardNum { get; private set; }
public bool UseCommon { get; private set; }
public string CardName { get; private set; }
public string BattleBonus { get; private set; }
public string PlayBonus { get; private set; }
public string Priority { get; private set; }
public AICardDataAsset(string[] columns)
{
int num = 0;
CardID = AIScriptParser.ParseInt(columns[num++]);
if (columns[num++] == "")
{
UseCommon = true;
}
else
{
UseCommon = false;
}
CardName = columns[num++];
CardNum = AIScriptParser.ParseInt(columns[num++]);
BattleBonus = columns[num++];
PlayBonus = columns[num++];
Priority = columns[num++];
TagList = new List<AIPlayTagAsset>();
int num2 = (columns.Length - num - 1) / 3;
for (int i = 0; i < num2; i++)
{
AIPlayTagAsset item = new AIPlayTagAsset
{
Type = columns[num++],
Arg = columns[num++],
Condition = columns[num++]
};
TagList.Add(item);
}
}
public bool IsSameCard(AICardDataAsset data)
{
return CardID == data.CardID;
}
}

View File

@@ -0,0 +1,88 @@
using System.Collections.Generic;
namespace Wizard;
public class AICardDataAssetSet
{
private class AICardDataAssetTemporaryRecord
{
public string[] Data { get; set; }
public int DiffFromLatestRotationPack { get; set; }
}
public List<AICardDataAsset> Set { get; private set; }
public AICardDataAssetSet()
{
Set = new List<AICardDataAsset>();
}
public void ConvertCsvTextToAsset(List<string[]> csv)
{
int latestRotationCardPack = GetRotationLatestCardPackNumber();
Dictionary<int, AICardDataAssetTemporaryRecord> latestCardCandidateDic = new Dictionary<int, AICardDataAssetTemporaryRecord>();
foreach (string[] item in csv)
{
if (IsRegister(item))
{
Set.Add(new AICardDataAsset(item));
}
}
foreach (AICardDataAssetTemporaryRecord value2 in latestCardCandidateDic.Values)
{
Set.Add(new AICardDataAsset(value2.Data));
}
bool IsRegister(string[] cardData)
{
string text = cardData[0];
int num;
int key;
if (text.Length > 9)
{
num = int.Parse(text.Substring(text.Length - 2));
key = int.Parse(text.Substring(0, text.Length - 2));
}
else
{
key = int.Parse(text);
num = 0;
}
if (num == 0)
{
return true;
}
if (num < latestRotationCardPack)
{
return false;
}
cardData[0] = key.ToString();
if (latestCardCandidateDic.TryGetValue(key, out var value))
{
int num2 = num - latestRotationCardPack;
if (num2 < value.DiffFromLatestRotationPack)
{
latestCardCandidateDic[key] = new AICardDataAssetTemporaryRecord
{
Data = cardData,
DiffFromLatestRotationPack = num2
};
}
}
else
{
latestCardCandidateDic.Add(key, new AICardDataAssetTemporaryRecord
{
Data = cardData,
DiffFromLatestRotationPack = num - latestRotationCardPack
});
}
return false;
}
}
private int GetRotationLatestCardPackNumber()
{
return Data.Load.data.RotationLatestCardPackId % 100;
}
}

View File

@@ -0,0 +1,14 @@
namespace Wizard;
public enum AICategory
{
ALL,
ELF,
ROYAL,
WITCH,
DRAGON,
NECROMANCE,
VAMPIRE,
BISHOP,
NEMESIS
}

View File

@@ -0,0 +1,24 @@
using System.Collections.Generic;
namespace Wizard;
public class AIChoiceTransformCostInformation
{
public AIPolishConvertedExpression Cost;
public AIConditionExpressions Condition { get; private set; }
public void SetCondition(AIConditionExpressions cond)
{
Condition = cond;
}
public bool CheckCondition(AIVirtualCard owner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (Condition == null || Condition.IsEmpty)
{
return true;
}
return Condition.CheckCondition(owner, playPtn, field, situation);
}
}

View File

@@ -0,0 +1,43 @@
using System.Collections.Generic;
namespace Wizard;
public class AIConditionExpressions
{
private AIPolishConvertedExpression _expr;
public List<int> ReferringIds { get; private set; }
public bool IsEmpty => _expr == null;
public AIConditionExpressions(string text)
{
if (!(text == ""))
{
_expr = new AIPolishConvertedExpression(text);
ReferringIds = _expr.GetReferringIDLists();
}
}
public bool CheckCondition(AIVirtualCard tagOwner, List<int> playPtn, AIVirtualField field, AISituationInfo situation)
{
if (_expr == null)
{
return true;
}
if (!_expr.CheckCondition(tagOwner, playPtn, field, situation))
{
return false;
}
return true;
}
public bool IsHoldingEVAL()
{
if (_expr != null)
{
return _expr.IsHoldingEVAL();
}
return false;
}
}

View File

@@ -0,0 +1,8 @@
namespace Wizard;
public class AICrystalizeInformation
{
public int Cost;
public int CardId;
}

View File

@@ -0,0 +1,17 @@
namespace Wizard;
public class AICsvLoadingInfo
{
public int DeckId { get; private set; }
public int StyleId { get; private set; }
public int EmoteId { get; private set; }
public AICsvLoadingInfo(int deckId, int styleId, int emoteId)
{
DeckId = deckId;
StyleId = styleId;
EmoteId = emoteId;
}
}

View File

@@ -0,0 +1,65 @@
using System.Collections.Generic;
namespace Wizard;
public class AIDamageModifierCollection
{
private List<AIDamageModifierInfo> _modifierList;
public AIDamageModifierCollection Clone(AIVirtualField field)
{
AIDamageModifierCollection aIDamageModifierCollection = new AIDamageModifierCollection();
if (_modifierList != null)
{
for (int i = 0; i < _modifierList.Count; i++)
{
AIDamageModifierInfo aIDamageModifierInfo = _modifierList[i];
AIVirtualCard aIVirtualCard = aIDamageModifierInfo.FindCloneTarget(field);
if (aIVirtualCard != null)
{
aIDamageModifierCollection.AddDamageModifierInfo(aIDamageModifierInfo.Clone(field, aIVirtualCard));
}
}
}
return aIDamageModifierCollection;
}
public int CalcModifiedDamage(AIVirtualField field, List<int> playPtn, AISituationInfo situation, AIVirtualCard damageOwner, int baseDamage)
{
if (_modifierList == null || _modifierList.Count <= 0)
{
return baseDamage;
}
int num = baseDamage;
for (int i = 0; i < _modifierList.Count; i++)
{
AIDamageModifierInfo aIDamageModifierInfo = _modifierList[i];
if (aIDamageModifierInfo.IsLegalDamageOwner(damageOwner, playPtn, situation))
{
num = aIDamageModifierInfo.GetModifiedDamage(field, playPtn, situation, num);
}
}
return num;
}
public void AddDamageModifierInfo(AIDamageModifierInfo info)
{
_modifierList = AIParamQuery.AddElementToList(info, _modifierList);
}
public void DepriveDamageModifierInfo(AIVirtualCard owner, int textHash)
{
if (_modifierList == null || _modifierList.Count <= 0)
{
return;
}
for (int i = 0; i < _modifierList.Count; i++)
{
if (_modifierList[i].IsMatch(owner, textHash))
{
_modifierList.RemoveAt(i);
break;
}
}
}
}

View File

@@ -0,0 +1,73 @@
using System.Collections.Generic;
namespace Wizard;
public class AIDamageModifierInfo
{
private int _textHash;
private AIVirtualCard _owner;
private List<AIScriptTokenBase> _damageOwnerFilter;
private AIScriptTokenArgType _calcType;
private AIPolishConvertedExpression _optionalDamageValue;
private static AIVirtualField.AIVirtualFieldSearchCardOption _searchOptionForClone = new AIVirtualField.AIVirtualFieldSearchCardOption
{
IsSearchFromDeck = false,
IsOutputCannotFindError = false,
IsSearchFromBeforeLatestActionDeck = false,
OptionalSearchRange = BattleCardRealTargetInformation.TargetRange.Default
};
public AIDamageModifierInfo(AIVirtualCard owner, List<AIScriptTokenBase> filters, AIScriptTokenArgType calcType, AIPolishConvertedExpression optionalDamage, int textHash)
{
_textHash = textHash;
_owner = owner;
_damageOwnerFilter = filters;
_calcType = calcType;
_optionalDamageValue = optionalDamage;
}
public AIDamageModifierInfo Clone(AIVirtualField field, AIVirtualCard newOwner)
{
return new AIDamageModifierInfo(newOwner, _damageOwnerFilter, _calcType, _optionalDamageValue, _textHash);
}
public bool IsLegalDamageOwner(AIVirtualCard damageOwner, List<int> playPtn, AISituationInfo situation)
{
return AIFilteringUtility.CheckMatchTargetFiltering(damageOwner, null, _damageOwnerFilter, playPtn, _owner, situation);
}
public int GetModifiedDamage(AIVirtualField field, List<int> playPtn, AISituationInfo situation, int baseDamage)
{
int num = baseDamage;
int num2 = (int)_optionalDamageValue.EvalArg(_owner, playPtn, field, situation);
switch (_calcType)
{
case AIScriptTokenArgType.ADD:
num += num2;
break;
case AIScriptTokenArgType.SET:
num = num2;
break;
}
return num;
}
public bool IsMatch(AIVirtualCard owner, int textHash)
{
if (_owner.IsSameCard(owner))
{
return _textHash == textHash;
}
return false;
}
public AIVirtualCard FindCloneTarget(AIVirtualField field)
{
return field.SearchVirtualCard(_owner, _searchOptionForClone);
}
}

View File

@@ -0,0 +1,9 @@
namespace Wizard;
public enum AIDamageType
{
All,
Attack,
Skill,
Spell
}

View File

@@ -0,0 +1,184 @@
using System.Collections.Generic;
namespace Wizard;
public class AIDataLibrary
{
private readonly AIDeckData _basicDic;
private readonly AIDeckData _commonDic;
private readonly AIDeckData _allyCommonDic;
private readonly Dictionary<string, AIDeckData> _deckDic;
private readonly AIStyleData _commonStyle;
private readonly Dictionary<string, AIStyleData> _deckStyleDic;
private AISetUpData setupInfoBuf;
private readonly Dictionary<string, AIEmoteSet> emoteDic;
public AISetUpData SetupInfoBuf => setupInfoBuf;
public AIDataLibrary()
{
_basicDic = new AIDeckData();
_commonDic = new AIDeckData();
_allyCommonDic = new AIDeckData();
_commonStyle = new AIStyleData();
_deckStyleDic = new Dictionary<string, AIStyleData>();
_deckDic = new Dictionary<string, AIDeckData>();
emoteDic = new Dictionary<string, AIEmoteSet>();
}
public void Clear()
{
_basicDic.Clear();
_commonDic.Clear();
_allyCommonDic.Clear();
_deckDic.Clear();
_commonStyle.Clear();
_deckStyleDic.Clear();
emoteDic.Clear();
}
public void SaveBattleSetUpInfo(int classID, AI_LOGIC_LV logicLv, string deckName, string styleName, string emoteName, bool useEmote, bool useInnerEmote, int enemyAiID, List<int> specialAbilityList)
{
setupInfoBuf = new AISetUpData(classID, logicLv, deckName, styleName, emoteName, useEmote, useInnerEmote, enemyAiID, specialAbilityList);
}
public AIStyleData CreateStyle(int enemyClassID, AIStyleData deckStyle)
{
AIStyleData aIStyleData = new AIStyleData(new List<AICategory>
{
AICategory.ALL,
AIPolicyData.ConvertClassIDToCategory(enemyClassID)
});
aIStyleData.MixInStyle(_commonStyle);
if (deckStyle != null)
{
aIStyleData.MixInStyle(deckStyle);
}
return aIStyleData;
}
public void RegisterBasicData(AICardDataAsset asset)
{
_basicDic.RegisterCardData(asset);
}
public bool RegisterCommonData(AICardDataAsset asset)
{
AICardData mergeData = _basicDic.SearchCardData(asset.CardID);
return _commonDic.RegisterCardData(asset, mergeData);
}
public bool RegisterAllyCommonData(AICardDataAsset asset)
{
AICardData mergeData = _basicDic.SearchCardData(asset.CardID);
return _allyCommonDic.RegisterCardData(asset, mergeData);
}
public void RegisterDeckToDeckDic(string deckName, List<AICardDataAsset> cardDataAssetList)
{
AIDeckData aIDeckData = new AIDeckData();
for (int i = 0; i < cardDataAssetList.Count; i++)
{
AICardDataAsset aICardDataAsset = cardDataAssetList[i];
int cardID = aICardDataAsset.CardID;
bool useCommon = aICardDataAsset.UseCommon;
AICardData mergeData = ((!useCommon) ? _basicDic.SearchCardData(cardID) : _allyCommonDic.SearchCardData(cardID));
aIDeckData.RegisterCardData(aICardDataAsset, mergeData, useCommon);
}
RegisterDeck(deckName, aIDeckData);
}
public bool RegisterDeck(string deckName, AIDeckData deck)
{
if (_deckDic.ContainsKey(deckName))
{
return false;
}
_deckDic.Add(deckName, deck);
return true;
}
public bool RegisterEmoteSet(string emoteSetName, AIEmoteSet emoteSet)
{
if (emoteDic.ContainsKey(emoteSetName))
{
return false;
}
emoteDic.Add(emoteSetName, emoteSet);
return true;
}
public AIDeckData SearchDeckData(string name)
{
if (!_deckDic.ContainsKey(name))
{
return null;
}
return _deckDic[name];
}
public AIStyleData SearchDeckStyle(string name)
{
if (!_deckStyleDic.ContainsKey(name))
{
return null;
}
return _deckStyleDic[name];
}
public AIEmoteSet SearchEmoteSet(string name)
{
if (!emoteDic.ContainsKey(name))
{
return null;
}
return emoteDic[name];
}
public AIDeckData GetCommonDic()
{
return _commonDic;
}
public AIDeckData GetAllyCommonDic()
{
return _allyCommonDic;
}
public void RegisterCommonStyle(List<AIPolicyDataAsset> assetList)
{
_commonStyle.CreateFromAsset(assetList);
}
public bool RegisterDeckStyle(string styleName, List<AIPolicyDataAsset> assetList)
{
if (_deckStyleDic.ContainsKey(styleName))
{
return false;
}
AIStyleData aIStyleData = new AIStyleData();
aIStyleData.CreateFromAsset(assetList);
_deckStyleDic.Add(styleName, aIStyleData);
return true;
}
public static List<int> GetAIDeckCardList(string deckname)
{
List<int> list = new List<int>();
foreach (AICardData value in GameMgr.GetIns().GetDataMgr().m_AIDataLibrary.SearchDeckData(deckname).CardDic.Values)
{
for (int i = 0; i < value.CardNum; i++)
{
list.Add(value.CardID);
}
}
return list;
}
}

View File

@@ -0,0 +1,41 @@
namespace Wizard;
public class AIDeckAcccessor
{
private AIDeckData commonDic;
private AIDeckData allyCommonDic;
private AIDeckData curDic;
public AIDeckAcccessor(AIDeckData _curDic, AIDeckData _commonDic, AIDeckData _allyCommonDic)
{
curDic = _curDic;
commonDic = _commonDic;
allyCommonDic = _allyCommonDic;
}
private AICardData SearchAllyCardData(int card_id)
{
AICardData aICardData = null;
if (curDic != null)
{
aICardData = curDic.SearchCardData(card_id);
}
if (aICardData == null)
{
aICardData = allyCommonDic.SearchCardData(card_id);
}
return aICardData;
}
public AICardData SearchCardData(int cardId, bool isAlly)
{
AICardData aICardData = null;
if (isAlly)
{
return SearchAllyCardData(cardId);
}
return commonDic.SearchCardData(cardId);
}
}

View File

@@ -0,0 +1,52 @@
using System.Collections.Generic;
namespace Wizard;
public class AIDeckData
{
private Dictionary<int, AICardData> cardDic;
public Dictionary<int, AICardData> CardDic => cardDic;
public AIDeckData()
{
cardDic = new Dictionary<int, AICardData>();
}
public void Clear()
{
cardDic.Clear();
}
public bool RegisterCardData(AICardDataAsset asset, AICardData mergeData = null, bool isMergeDefaultParameter = false)
{
if (cardDic.ContainsKey(asset.CardID))
{
return false;
}
AICardData aICardData = new AICardData(asset);
if (mergeData != null)
{
if (isMergeDefaultParameter)
{
aICardData.MergeCardData(mergeData);
}
else
{
aICardData.MergeTagFromAnotherData(mergeData);
}
}
cardDic.Add(asset.CardID, aICardData);
return true;
}
public AICardData SearchCardData(int card_id)
{
AICardData value = null;
if (CardDic.TryGetValue(card_id, out value))
{
return value;
}
return null;
}
}

View File

@@ -0,0 +1,33 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public class AIDeckFileNameList
{
private const int DECK_ID_INDEX = 0;
private const int FILE_NAME_INDEX = 1;
private readonly Dictionary<int, string> _dataTable = new Dictionary<int, string>();
public AIDeckFileNameList(List<string[]> csvData)
{
foreach (string[] csvDatum in csvData)
{
int key = int.Parse(csvDatum[0]);
string value = csvDatum[1];
_dataTable.Add(key, value);
}
}
public string GetFileName(int id)
{
return _dataTable[id];
}
public List<string> GetFileNameList()
{
return _dataTable.Values.ToList();
}
}

View File

@@ -0,0 +1,39 @@
using System.Collections.Generic;
namespace Wizard;
public class AIDiscardInfo
{
public AIVirtualCard Owner;
public List<AIVirtualCard> TargetList;
public bool IsSuccess;
public bool IsNGByAI;
public bool IsValuable
{
get
{
if (IsSuccess && !IsNGByAI && TargetList != null)
{
return TargetList.Count > 0;
}
return false;
}
}
public AIDiscardInfo(AIVirtualCard owner, bool isSuccess, List<AIVirtualCard> targets)
{
Owner = owner;
IsSuccess = isSuccess;
TargetList = targets;
IsNGByAI = false;
}
public void MarkAsNG()
{
IsNGByAI = true;
}
}

View File

@@ -0,0 +1,50 @@
using System.Collections.Generic;
namespace Wizard;
public class AIDummyDeckContainer
{
private List<DeckVirtualCard> _allyDummyDeck;
private List<DeckVirtualCard> _enemyDummyDeck;
public AIDummyDeckContainer()
{
_allyDummyDeck = new List<DeckVirtualCard>();
_enemyDummyDeck = new List<DeckVirtualCard>();
}
public AIDummyDeckContainer Clone(AIVirtualField field)
{
AIDummyDeckContainer aIDummyDeckContainer = new AIDummyDeckContainer();
CopyDeck(_allyDummyDeck, aIDummyDeckContainer._allyDummyDeck, field);
CopyDeck(_enemyDummyDeck, aIDummyDeckContainer._enemyDummyDeck, field);
return aIDummyDeckContainer;
}
private void CopyDeck(List<DeckVirtualCard> srcDeck, List<DeckVirtualCard> dstDeck, AIVirtualField field)
{
for (int i = 0; i < srcDeck.Count; i++)
{
dstDeck.Add(new DeckVirtualCard(srcDeck[i], field));
}
}
public List<DeckVirtualCard> GetDeck(bool isAlly)
{
if (!isAlly)
{
return _enemyDummyDeck;
}
return _allyDummyDeck;
}
public void AppendDummyCard(DeckVirtualCard card, bool isAlly)
{
List<DeckVirtualCard> deck = GetDeck(isAlly);
if (!deck.Contains(card))
{
deck.Add(card);
}
}
}

View File

@@ -0,0 +1,55 @@
namespace Wizard;
public class AIEmoteCmd
{
public ClassCharaPrm.EmotionType emoteType { get; set; }
public int ID { get; set; }
public int CategoryKey { get; set; }
public int faceID { get; set; }
public int motionID { get; set; }
public string voiceID { get; set; }
public string textID { get; set; }
public bool isAI { get; set; }
public AIEmoteCmd()
{
emoteType = ClassCharaPrm.EmotionType.GREET;
ID = 0;
CategoryKey = 0;
faceID = 0;
motionID = 0;
voiceID = "";
textID = "";
isAI = true;
}
public AIEmoteCmd(AIEmoteDataAsset asset)
{
ID = asset.ID;
CategoryKey = asset.Category;
faceID = asset.FaceID;
motionID = asset.MotionID;
voiceID = asset.VoiceID;
textID = asset.TextID;
isAI = true;
}
public AIEmoteCmd(ClassCharaPrm.EmotionType _emoteType)
{
emoteType = _emoteType;
ID = 0;
CategoryKey = 0;
faceID = 0;
motionID = 0;
voiceID = "";
textID = "";
isAI = true;
}
}

View File

@@ -0,0 +1,22 @@
namespace Wizard;
public enum AIEmoteCmdType
{
ON_FIRST_TURN,
ON_ITERATION_START,
ON_ALLY_TURN_START,
ON_OPPONENT_TURN_START,
ON_ALLY_TURN_END,
ON_OPPONENT_TURN_END,
ON_ALLY_ATTACK,
ON_OPPONENT_ATTACK,
ON_ALLY_EVOLUTION,
ON_RECEIVE,
ON_CARD_DESTROY,
ON_CARD_PLAY_ALLY,
ON_CARD_PLAY_OPPONENT,
ON_DEBUG_SEARCH_ID,
ON_DEBUG_SEARCH_CATEGORY,
ON_LEADER_DAMAGED,
ON_PLAYER_LEADER_DAMAGED
}

View File

@@ -0,0 +1,507 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Wizard.Battle.Card;
using Wizard.Battle.View.Vfx;
namespace Wizard;
public class AIEmoteCtrl : IAIEmoteCtrl
{
public static AIPlayTagType[] EMOTE_TAG_TYPES = new AIPlayTagType[6]
{
AIPlayTagType.EmoteOnPlay,
AIPlayTagType.EmoteOnAtk,
AIPlayTagType.EmoteOnEvo,
AIPlayTagType.EmoteOnDestroy,
AIPlayTagType.ForceEmoteOnDestroy,
AIPlayTagType.EmoteOnTurnEnd
};
private EnemyAI AI;
private bool _isEmoOnDestroyPlayed;
public AIEmoteCtrl(EnemyAI ai)
{
AI = ai;
}
public void SetUpEmoteEvent(BattlePlayerBase self, BattlePlayerBase opponent, OperateMgr operateManager)
{
opponent.OnTurnStartBeforeDraw += (SkillProcessor arg) => GetEmoteWithTurnStartSimulate(isAllyTurnStart: false);
self.OnTurnStartBeforeDraw += delegate
{
AI.EmoteMng.ResetOpponentTurnEmoteFlag();
return GetEmoteWithTurnStartSimulate(isAllyTurnStart: true);
};
Func<SkillProcessor, VfxBase> func = null;
func = delegate
{
VfxBase emote = AI.GetEmote(AIEmoteCmdType.ON_OPPONENT_TURN_END);
ImmediateVfxMgr.GetInstance().Register(emote);
return NullVfx.GetInstance();
};
opponent.OnTurnEnd += func;
self.OnAddCemeteryEvent += delegate(BattleCardBase card, BattlePlayerBase.CEMETERY_TYPE cemeteryType, bool isOpen, SkillBase skill)
{
if (cemeteryType == BattlePlayerBase.CEMETERY_TYPE.NORMAL && !(card is NullBattleCard) && !(card is IVirtualBattleCard) && card.SelfBattlePlayer.ClassAndInPlayCardList.Contains(card))
{
AIUnknownAction situation = new AIUnknownAction(AI.CurrentVirtualField.SearchVirtualCard(card));
SequentialVfxPlayer sequential = SequentialVfxPlayer.Create();
VfxBase emote = AI.GetEmote(AIEmoteCmdType.ON_CARD_DESTROY, situation);
sequential.Register(emote);
if (emote != NullVfx.GetInstance())
{
_isEmoOnDestroyPlayed = true;
card.OnDestroy += (BattleCardBase destroyCard, SkillProcessor skillProcessor) => sequential;
}
}
};
self.Class.OnDamageAfter += (SkillProcessor skillProcessorOneTime) => (self.Class.Life <= 0) ? NullVfx.GetInstance() : AI.GetEmote(AIEmoteCmdType.ON_LEADER_DAMAGED);
opponent.Class.OnDamageAfter += (SkillProcessor skillProcessorOneTime) => (opponent.Class.Life <= 0) ? NullVfx.GetInstance() : AI.GetEmote(AIEmoteCmdType.ON_PLAYER_LEADER_DAMAGED);
operateManager.OnBeforeSetCard += delegate
{
AI.EmoteMng.EvalFieldOnBeforeSetCard();
};
operateManager.OnSetCardExecuted += delegate(BattleCardBase card)
{
AIUnknownAction situation = new AIUnknownAction(new AIVirtualCard(card, AI.CurrentVirtualField));
return AI.GetEmote(AIEmoteCmdType.ON_CARD_PLAY_OPPONENT, situation);
};
operateManager.OnBeforeAttack += delegate
{
AI.EmoteMng.EvalFieldOnBeforeAttack();
return NullVfx.GetInstance();
};
operateManager.OnAttackExecuted += (BattleCardBase attacker, BattleCardBase target, bool needAttack) => AI.GetEmote(AIEmoteCmdType.ON_OPPONENT_ATTACK);
}
private VfxBase GetEmoteWithTurnStartSimulate(bool isAllyTurnStart)
{
AIVirtualField aIVirtualField = new AIVirtualField((AI.BeforeLatestActionField != null) ? AI.BeforeLatestActionField : AI.CurrentVirtualField);
if (aIVirtualField.AllyTurnCount > 0 || aIVirtualField.EnemyTurnCount > 0)
{
AIVirtualTurnEndSimulator.TurnEnd(new AIVirtualTurnEndInfo(isAllyTurnStart ? aIVirtualField.EnemyClass : aIVirtualField.AllyClass), aIVirtualField);
}
AIVirtualTurnStartInfo situation = new AIVirtualTurnStartInfo(isAllyTurnStart ? aIVirtualField.AllyClass : aIVirtualField.EnemyClass);
aIVirtualField.TurnStartFieldProcess(situation);
return AI.GetEmote(isAllyTurnStart ? AIEmoteCmdType.ON_ALLY_TURN_START : AIEmoteCmdType.ON_OPPONENT_TURN_START, situation);
}
public AIEmoteCmd OnOpponentEmotion(ClassCharaPrm.EmotionType emoteType)
{
if (AI.EmoteMng.IsCheckmated())
{
return null;
}
if (AI.IsThisTurnEmotePlayed)
{
return null;
}
if (!AI.EmoteQuery.UseInnerEmote)
{
return null;
}
ClassCharaPrm.EmotionType replyEmote = ClassCharaPrm.EmotionType.NULL;
if (AI.EmoteMng.IsReplyAllowed(emoteType, ref replyEmote))
{
return new AIEmoteCmd(replyEmote);
}
return null;
}
public AIEmoteCmd OnAllyTurnStart(AISituationInfo situation)
{
AI.EmoteMng.SetUpOnAllyTurnStart();
AI.EmoteMng.EvalFieldOnTurnStart();
_isEmoOnDestroyPlayed = false;
int emoteOnTurnStart = AI.StyleQuery.GetEmoteOnTurnStart(isAllyTurn: true, situation.Actor.SelfField);
if (emoteOnTurnStart >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteOnTurnStart);
}
return null;
}
public AIEmoteCmd OnOpponentTurnStart(AISituationInfo situation)
{
AI.EmoteMng.EvalFieldOnOpponentTurnStart();
_isEmoOnDestroyPlayed = false;
AIVirtualField selfField = situation.Actor.SelfField;
int emoteOnTurnStart = AI.StyleQuery.GetEmoteOnTurnStart(isAllyTurn: false, selfField);
if (emoteOnTurnStart >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteOnTurnStart);
}
emoteOnTurnStart = AI.StyleQuery.GetPlayerEmoteOnTurnStart(selfField);
if (emoteOnTurnStart >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteOnTurnStart, isAlly: false);
}
return null;
}
public AIEmoteCmd OnAllyTurnEnd()
{
if (AI.IsTurnEndLethal)
{
return AI.EmoteQuery.SearchEmoteAtRandom(22);
}
for (int i = 0; i < AI.CurrentVirtualField.CardListSet.BothClassAndInplayCards.Count; i++)
{
int emoteOnTurnEndCategory = AI.CurrentVirtualField.CardListSet.BothClassAndInplayCards[i].GetEmoteOnTurnEndCategory(isAllyTurnEnd: true);
if (emoteOnTurnEndCategory >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteOnTurnEndCategory);
}
}
int emoteOnTurnEnd = AI.StyleQuery.GetEmoteOnTurnEnd(isAllyTurn: true);
if (emoteOnTurnEnd >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteOnTurnEnd);
}
emoteOnTurnEnd = AI.StyleQuery.GetPlayerEmoteOnTurnEnd(isPlayerTurn: false);
if (emoteOnTurnEnd >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteOnTurnEnd, isAlly: false);
}
if (AI.EmoteMng.IsCheckmated())
{
return AI.EmoteQuery.SearchEmoteAtRandom(13);
}
if (AI.EmoteMng.IsHuntDown())
{
return AI.EmoteQuery.SearchEmoteAtRandom(14);
}
if (AI.IsRoyal() && AI.EmoteMng.IsEnoughUnit())
{
return AI.EmoteQuery.SearchEmoteAtRandom(102);
}
if (AI.IsNecromancer() && AI.EmoteMng.IsEnoughGrave())
{
return AI.EmoteQuery.SearchEmoteAtRandom(501);
}
if (AI.EmoteMng.IsAwaking(1))
{
return AI.EmoteQuery.SearchEmoteAtRandom(401);
}
if (AI.EmoteMng.IsUnexpectedBattle())
{
return AI.EmoteQuery.SearchEmoteAtRandom(11);
}
if (AI.ALLY.InPlayCards.Count() < 5 && AI.EmoteMng.IsRemainTooPP())
{
return AI.EmoteQuery.SearchEmoteAtRandom(15);
}
return null;
}
public AIEmoteCmd OnOpponentTurnEnd()
{
if (AI.EmoteMng.IsOpponentTurnEmoteOccured)
{
return null;
}
for (int i = 0; i < AI.CurrentVirtualField.CardListSet.BothClassAndInplayCards.Count; i++)
{
int emoteOnTurnEndCategory = AI.CurrentVirtualField.CardListSet.BothClassAndInplayCards[i].GetEmoteOnTurnEndCategory(isAllyTurnEnd: false);
if (emoteOnTurnEndCategory >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteOnTurnEndCategory);
}
}
int emoteOnTurnEnd = AI.StyleQuery.GetEmoteOnTurnEnd(isAllyTurn: false);
if (emoteOnTurnEnd >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteOnTurnEnd);
}
emoteOnTurnEnd = AI.StyleQuery.GetPlayerEmoteOnTurnEnd(isPlayerTurn: true);
if (emoteOnTurnEnd >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteOnTurnEnd, isAlly: false);
}
if (AI.EmoteMng.IsCheckmated())
{
return null;
}
if (AI.EmoteMng.IsOpponentEarnGreatMerit())
{
return AI.EmoteQuery.SearchEmoteAtRandom(33);
}
if (AI.OPPONENT.InPlayCards.Count() < 5 && AI.EmoteMng.IsOpponentRemainTooPP())
{
return AI.EmoteQuery.SearchEmoteAtRandom(31);
}
return null;
}
public AIEmoteCmd OnIterationStart()
{
if (AI.EmoteMng.IsCheckmated())
{
return null;
}
float num = AI.EmoteMng.EvalDisplacement_PlayedValue();
AI.EmoteMng.ResetLastOpr();
if (num < -4f)
{
return null;
}
if (num > 4f)
{
return AI.EmoteQuery.SearchEmoteAtRandom(1);
}
return null;
}
public AIEmoteCmd OnCardPlay(AISituationInfo situation)
{
if (situation == null || situation.Actor == null)
{
return null;
}
int num = AI.CurrentVirtualField.AllyHandCards.FindIndex((AIVirtualCard c) => c.IsSameCard(situation.Actor));
if (num < 0)
{
return null;
}
AIVirtualField aIVirtualField = new AIVirtualField(AI.CurrentVirtualField)
{
BestPlayPtn = new List<int> { num }
};
AIVirtualCard aIVirtualCard = aIVirtualField.SearchVirtualCard(situation.Actor);
AISelectedTargetInfoSet aISelectedTargetInfoSet = new AISelectedTargetInfoSet();
if (situation.SelectedTargets != null)
{
for (int num2 = 0; num2 < AISelectedTargetInfoSet.LENGTH; num2++)
{
AISelectedTargetInfo aISelectedTargetInfo = situation.SelectedTargets.Get(num2);
if (aISelectedTargetInfo == null || !aISelectedTargetInfo.HasTarget)
{
continue;
}
AISelectedTargetInfo aISelectedTargetInfo2 = new AISelectedTargetInfo(aISelectedTargetInfo.Type);
int count = aISelectedTargetInfo.Targets.Count;
for (int num3 = 0; num3 < count; num3++)
{
if (aISelectedTargetInfo.Type == TargetSelectType.Choice)
{
aISelectedTargetInfo2.AddTarget(aISelectedTargetInfo.Targets[num3]);
continue;
}
AIVirtualCard target = aIVirtualField.SearchVirtualCard(aISelectedTargetInfo.Targets[num3]);
aISelectedTargetInfo2.AddTarget(target);
}
aISelectedTargetInfoSet.Set(aISelectedTargetInfo2, num2);
}
if (situation.SelectedTargets.HasChoiceTarget)
{
aISelectedTargetInfoSet.SetChoiceTarget(situation.SelectedTargets.ChoiceTarget);
}
}
AIVirtualTargetSelectAction aIVirtualTargetSelectAction = new AIVirtualTargetSelectAction(aIVirtualCard, aIVirtualCard, situation.ActionType, aISelectedTargetInfoSet);
PlaySimulationInfo playSimulationInfo = AIPlayCardSimulationUtility.CreatePlaySimulationInfo(aIVirtualCard, aIVirtualTargetSelectAction, aIVirtualField);
if (playSimulationInfo == null)
{
AIConsoleUtility.LogError("AIEmoteCtrl:OnCardPlay() playSimulationInfo is null. CardName:" + ((aIVirtualCard != null) ? aIVirtualCard.CardName : ""));
return null;
}
if (playSimulationInfo.Type == PlaySimulationType.Accelerate || playSimulationInfo.Type == PlaySimulationType.Crystalize)
{
AISinglePlayptnRecord playptnRecord = AI.PlayPtnRecorder.FindMatchedPlayPtnRecord(aIVirtualField.BestPlayPtn, aIVirtualField);
aIVirtualTargetSelectAction.SetActor(aIVirtualCard.FindRealActor(playptnRecord));
}
AIVirtualPlaySimulator.PlayCard(aIVirtualTargetSelectAction, aIVirtualField, playSimulationInfo);
if (aIVirtualField.EnemyClass.Life <= 0 || aIVirtualField.EnemyClass.IsDead)
{
return AI.EmoteQuery.SearchEmoteAtRandom(22);
}
if (AI.EmoteMng.IsCheckmated())
{
return null;
}
AIRealBattleCardSearcher.SearchBattleCardFromSituation(AI.PlayerPair, situation, out var actor, out var targetList);
if (actor == null || (situation.ActionTarget != null && (targetList == null || targetList.Count < 1 || targetList[0] == null)) || (situation.SecondActionTarget != null && (targetList == null || targetList.Count < 2 || targetList[1] == null)))
{
return null;
}
if (AI.ALLY.IsSelfTurn && AI.IsAllyCard(actor))
{
AIVirtualCard actor2 = situation.Actor;
int emoteCategory = actor2.GetEmoteCategory(AIPlayTagType.EmoteOnPlay);
if (emoteCategory >= 0)
{
AIEmoteCmd result = AI.EmoteQuery.SearchEmoteAtRandom(emoteCategory);
AI.EmoteQuery.OnCardPlayEmotion();
return result;
}
new BattlePlayerPair(actor.SelfBattlePlayer, actor.OpponentBattlePlayer);
int num4 = actor2.BattleSkills.Count();
for (int num5 = 0; num5 < num4; num5++)
{
SkillBase skill = actor2.BattleSkills.ElementAt(num5);
if (AI.ParamQuery.IsBanishSkill(skill))
{
return OnBanishSkill(actor, aIVirtualField);
}
}
}
return null;
}
public AIEmoteCmd OnAllyAttack(AISituationInfo situation)
{
if (!(situation is AIVirtualAttackInfo { Actor: not null, AttackTarget: not null }))
{
AIConsoleUtility.LogError("OnAllyAttack() error!!! situation is not valid attackSituation");
return null;
}
AI.EmoteMng.EvalFieldOnAttack();
AIVirtualField aIVirtualField = new AIVirtualField(AI.CurrentVirtualField);
AIVirtualAttackInfo aIVirtualAttackInfo2 = AISimulationUtility.CreateActionInfoOnFieldFromSituation(aIVirtualField, situation) as AIVirtualAttackInfo;
if (!situation.IsSameSituation(aIVirtualAttackInfo2))
{
AIConsoleUtility.LogError("OnAllyAttack() error!!! Failed situation clone");
return null;
}
AIVirtualAttackSimulator.Attack(aIVirtualAttackInfo2, aIVirtualField);
if (aIVirtualField.EnemyClass.IsDead)
{
return AI.EmoteQuery.SearchEmoteAtRandom(22);
}
if (AI.EmoteMng.IsCheckmated())
{
return null;
}
int emoteCategory = aIVirtualAttackInfo2.Actor.GetEmoteCategory(AIPlayTagType.EmoteOnAtk);
if (emoteCategory >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteCategory);
}
return null;
}
public AIEmoteCmd OnAllyEvolution(AISituationInfo situation)
{
if (situation == null || situation.Actor == null || situation.ActionType != AIOperationType.EVOLVE)
{
return null;
}
AIVirtualField aIVirtualField = new AIVirtualField(AI.CurrentVirtualField);
AIVirtualActionInfo aIVirtualActionInfo = AISimulationUtility.CreateActionInfoOnFieldFromSituation(aIVirtualField, situation);
if (!situation.IsSameSituation(aIVirtualActionInfo))
{
return null;
}
AIVirtualEvolutionSimulator.ManualEvolve(aIVirtualActionInfo, aIVirtualField);
if (aIVirtualField.EnemyClass.IsDead)
{
return AI.EmoteQuery.SearchEmoteAtRandom(22);
}
if (AI.EmoteMng.IsCheckmated())
{
return null;
}
int emoteCategory = aIVirtualActionInfo.Actor.GetEmoteCategory(AIPlayTagType.EmoteOnEvo);
if (emoteCategory >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteCategory);
}
return null;
}
public AIEmoteCmd OnBanishSkill(BattleCardBase actCard, AIVirtualField fieldAfterPlayed)
{
if (AI.EmoteMng.IsBanishOverExpected(actCard, fieldAfterPlayed))
{
return AI.EmoteQuery.SearchEmoteAtRandom(21);
}
return null;
}
public AIEmoteCmd OnOpponentPlayCardExecuted(AISituationInfo situation)
{
if (AI.EmoteMng.IsCheckmated() || situation == null || situation.Actor == null)
{
return null;
}
AIVirtualCard actor = situation.Actor;
if (AI.EmoteMng.IsOpponentBanishSplendid(actor))
{
return AI.EmoteQuery.SearchEmoteAtRandom(35);
}
if (AI.EmoteMng.IsOpponentBanishBad(actor))
{
return AI.EmoteQuery.SearchEmoteAtRandom(36);
}
if (!actor.IsAlly && AI.EmoteMng.IsGiantPlayed())
{
return AI.EmoteQuery.SearchEmoteAtRandom(34);
}
if (AI.EmoteMng.IsOpponentHealClassLifeLargeOnCardPlay())
{
return AI.EmoteQuery.SearchEmoteAtRandom(37);
}
return null;
}
public AIEmoteCmd OnOpponentAttackExecuted()
{
if (AI.EmoteMng.IsCheckmated())
{
return null;
}
if (AI.EmoteMng.IsOpponentHealClassLifeLargeOnAttack())
{
return AI.EmoteQuery.SearchEmoteAtRandom(37);
}
return null;
}
public AIEmoteCmd OnCardDestroy(AISituationInfo situation)
{
if (situation == null || situation.Actor == null || situation.ActionType != AIOperationType.UNKNOWN)
{
return null;
}
AIVirtualCard actor = situation.Actor;
if (actor.IsAlly)
{
int emoteCategory = actor.GetEmoteCategory(AIPlayTagType.ForceEmoteOnDestroy);
if (emoteCategory >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteCategory);
}
}
if (AI.EmoteMng.IsCheckmated() || _isEmoOnDestroyPlayed)
{
return null;
}
if (actor.IsAlly)
{
int emoteCategory2 = actor.GetEmoteCategory(AIPlayTagType.EmoteOnDestroy);
if (emoteCategory2 >= 0)
{
return AI.EmoteQuery.SearchEmoteAtRandom(emoteCategory2);
}
if (AI.OPPONENT.IsSelfTurn && AI.EmoteMng.IsEliminatedAllyLegion(situation.Actor))
{
return AI.EmoteQuery.SearchEmoteAtRandom(101);
}
}
return null;
}
public AIEmoteCmd OnLeaderDamaged(AIVirtualField field)
{
int emoteOnLeaderDamaged = AI.StyleQuery.GetEmoteOnLeaderDamaged(field);
return AI.EmoteQuery.SearchEmoteAtRandom(emoteOnLeaderDamaged);
}
public AIEmoteCmd OnPlayerLeaderDamaged(AIVirtualField field)
{
int playerEmoteOnLeaderDamaged = AI.StyleQuery.GetPlayerEmoteOnLeaderDamaged(field);
return AI.EmoteQuery.SearchEmoteAtRandom(playerEmoteOnLeaderDamaged, isAlly: false);
}
}

View File

@@ -0,0 +1,36 @@
namespace Wizard;
public class AIEmoteDataAsset
{
public int ID;
public int Category;
public int FaceID;
public int MotionID;
public string VoiceID;
public string TextID;
public AIEmoteDataAsset(string[] columns)
{
int num = 0;
ID = AIScriptParser.ParseInt(columns[num++]);
Category = AIScriptParser.ParseInt(columns[num++]);
FaceID = AIScriptParser.ParseInt(columns[num++]);
MotionID = AIScriptParser.ParseInt(columns[num++]);
VoiceID = columns[num++];
TextID = ConvEmoteMasterText(columns[num++]);
}
private string ConvEmoteMasterText(string id)
{
if (string.IsNullOrEmpty(id))
{
return "";
}
return Data.Master.GetEmoteWordText(id);
}
}

View File

@@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public class AIEmoteFileNameList
{
private const int EMOTE_ID_INDEX = 0;
private const int FILE_NAME_INDEX = 1;
private readonly Dictionary<int, string> _dataTable = new Dictionary<int, string>();
public AIEmoteFileNameList(List<string[]> csvData)
{
foreach (string[] csvDatum in csvData)
{
int key = int.Parse(csvDatum[0]);
string value = csvDatum[1];
_dataTable.Add(key, value);
}
}
public string GetFileName(int emoteId)
{
if (_dataTable.ContainsKey(emoteId))
{
return _dataTable[emoteId];
}
return "";
}
public List<string> GetFileNameList()
{
return _dataTable.Values.ToList();
}
}

View File

@@ -0,0 +1,417 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace Wizard;
public class AIEmoteMng
{
private EnemyAI AI;
private float _allyAdvOnTurnStart;
private float _opponentAdvOnTurnStart;
private int _allyLegionNumOnTurnStart;
private float _allyAdvOnFirstAttack;
private float _advOnBeforeSetCard;
private int _opponentLifeOnBeforeSetCard;
private int _opponentLifeOnBeforeAttack;
private bool _isLastOpr_CardPlay;
private float _playedCardValue;
private float _allyAdvOnCardPlay;
private bool _isFirstAttacked;
private bool _isOpponentTurnEmoteOccured;
private bool _isAIGreeted;
private bool _isAIThanked;
private readonly Stopwatch _stopwatch;
private bool _isThinkingEmoteOccured;
public Dictionary<int, int> EmoteCategoryPlayedCounter { get; private set; }
public bool IsOpponentTurnEmoteOccured => _isOpponentTurnEmoteOccured;
public Stopwatch Stopwatch => _stopwatch;
public int EmoteRandomSeed { get; private set; }
public AIEmoteMng(EnemyAI ai)
{
AI = ai;
EmoteRandomSeed = new Random().Next();
_stopwatch = new Stopwatch();
_isAIGreeted = false;
_isAIThanked = false;
EmoteCategoryPlayedCounter = new Dictionary<int, int>();
}
public float EvalDisplacement_PlayedValue()
{
if (!_isLastOpr_CardPlay)
{
return 0f;
}
return AI.CalcFieldAdvantage() - (_allyAdvOnCardPlay + _playedCardValue);
}
public void ResetLastOpr()
{
_isLastOpr_CardPlay = false;
}
public void SetUpOnAllyTurnStart()
{
_isFirstAttacked = false;
ResetLastOpr();
AI.EmoteQuery.UpdateCategoryInterval();
_stopwatch.Reset();
_stopwatch.Start();
_isThinkingEmoteOccured = false;
}
public void EvalFieldOnTurnStart()
{
_allyAdvOnTurnStart = AI.CalcFieldAdvantage();
_allyLegionNumOnTurnStart = AI.ALLY.InPlayCards.Count((BattleCardBase c) => c.IsTribe(CardBasePrm.TribeType.LEGION));
}
public void EvalFieldOnOpponentTurnStart()
{
_opponentAdvOnTurnStart = AI.CalcFieldAdvantage();
}
public void EvalFieldOnAttack()
{
if (!_isFirstAttacked)
{
_allyAdvOnFirstAttack = AI.CalcFieldAdvantage();
_isFirstAttacked = true;
}
}
public void EvalFieldOnBeforeSetCard()
{
_advOnBeforeSetCard = AI.CalcFieldAdvantage();
_opponentLifeOnBeforeSetCard = AI.OPPONENT.Class.Life;
}
public void EvalFieldOnBeforeAttack()
{
_opponentLifeOnBeforeAttack = AI.OPPONENT.Class.Life;
}
public void EvalAllyOnCardPlay(AIVirtualCard playCard, AISinglePlayptnRecord playptnRecord)
{
if (playptnRecord != null && playptnRecord.PlayPtn != null && playptnRecord.PlayPtn.Count > 0)
{
_isLastOpr_CardPlay = true;
_allyAdvOnCardPlay = AI.CalcFieldAdvantage();
AIVirtualTargetSelectAction play = new AIVirtualTargetSelectAction(playCard, playCard, AIOperationType.PLAY);
_playedCardValue = AI.EnemyAIPlay.EvaluateHandValue(playCard, playptnRecord.PlayPtn, play, isOnBattleSimulate: false, playptnRecord);
}
}
public void OnOpponentTurnEmote()
{
_isOpponentTurnEmoteOccured = true;
}
public void ResetOpponentTurnEmoteFlag()
{
_isOpponentTurnEmoteOccured = false;
}
public AIEmoteCmd OnAllyCardDestroy()
{
return null;
}
public bool IsReverseDisAdv()
{
if (_allyAdvOnTurnStart >= 0f)
{
return false;
}
return AI.CalcFieldAdvantage() >= 0f;
}
public bool IsOpponentEarnGreatMerit()
{
float num = AI.CalcFieldAdvantage();
int ppTotal = AI.OPPONENT.PpTotal;
return _opponentAdvOnTurnStart - num > (float)ppTotal * 2f;
}
public bool IsFailedReverseDisAdv()
{
if (_allyAdvOnTurnStart >= 0f)
{
return false;
}
return AI.CalcFieldAdvantage() < 0f;
}
public bool IsOpponentFailedReverseDisAdv()
{
if (_opponentAdvOnTurnStart <= 0f)
{
return false;
}
return AI.CalcFieldAdvantage() > 0f;
}
public bool IsRemainTooPP()
{
return AI.ALLY.Pp >= 2;
}
public bool IsOpponentRemainTooPP()
{
return AI.OPPONENT.Pp > AI.OPPONENT.PpTotal / 2;
}
public bool IsGiantPlayed()
{
float num = 10f;
return AI.FieldInplayValueDifference >= num;
}
public bool IsEnoughUnit()
{
return AI.ALLY.InPlayCards.Count() >= 3;
}
public bool IsEnoughGrave()
{
return AI.ALLY.CemeteryList.Count >= 6;
}
public bool IsCheckmated()
{
int num = 0;
foreach (BattleCardBase inPlayCard in AI.OPPONENT.InPlayCards)
{
if (inPlayCard.IsUnit)
{
num += inPlayCard.Atk;
}
}
if (AI.OPPONENT.IsEvolve && AI.OPPONENT.InPlayCards.Any((BattleCardBase card) => card.IsUnit && !card.IsEvolution))
{
num += AI.OPPONENT.InPlayCards.Max((BattleCardBase card) => (!card.IsEvolution) ? (card.BaseParameter.EvoAtk - card.BaseParameter.Atk) : 0);
}
int num2 = 0;
List<AIVirtualCard> bothClassAndInplayCards = AI.CurrentVirtualField.CardListSet.BothClassAndInplayCards;
for (int num3 = 0; num3 < bothClassAndInplayCards.Count; num3++)
{
AIVirtualCard aIVirtualCard = bothClassAndInplayCards[num3];
if (aIVirtualCard.TagCollectionContainer.HasTag(AIPlayTagType.TurnEndDamage))
{
num2 += aIVirtualCard.TagCollectionContainer.TurnEndTags.GetTurnEndDamageToAllyLeader(aIVirtualCard);
}
}
return num + num2 >= AI.ALLY.Class.Life;
}
public bool IsHuntDown()
{
if (AI.OPPONENT.InPlayCards.Any((BattleCardBase c) => c.SkillApplyInformation.IsGuard))
{
return false;
}
int num = 0;
foreach (BattleCardBase inPlayCard in AI.ALLY.InPlayCards)
{
if (inPlayCard.IsUnit)
{
num += inPlayCard.Atk;
}
}
if (AI.ALLY.CurrentEpCount > 0)
{
num += 2;
}
return num >= AI.OPPONENT.Class.Life;
}
public bool IsEliminatedAllyLegion(AIVirtualCard destroyingCard)
{
if (_allyLegionNumOnTurnStart < 2)
{
return false;
}
if (AI.CurrentVirtualField.AllyInplayCards.Count((AIVirtualCard c) => c.IsTribe(CardBasePrm.TribeType.LEGION) && c.IsSameCard(destroyingCard)) > 0)
{
return false;
}
return true;
}
public bool IsAwaking(int turnOffset)
{
if (AI.ALLY.Pp + turnOffset == 7)
{
return true;
}
return false;
}
public bool IsUnexpectedBattle()
{
if (!_isFirstAttacked)
{
return false;
}
return AI.CalcFieldAdvantage() < _allyAdvOnFirstAttack;
}
public bool IsBanishOverExpected(BattleCardBase actCard, AIVirtualField fieldAfterPlayed)
{
if (!actCard.IsSpell)
{
return false;
}
float num = (float)actCard.Cost * 2f + 4f;
float num2 = AI.ParamQuery.EvaluateBattlePlayerPair(AI.CurrentVirtualField);
if (AI.ParamQuery.EvaluateBattlePlayerPair(fieldAfterPlayed) - num2 >= num)
{
return true;
}
return false;
}
public bool IsOpponentBanishSplendid(AIVirtualCard actCard)
{
if (actCard.IsAlly)
{
return false;
}
float num = (float)actCard.Cost * 2f + 4f;
float num2 = AI.CalcFieldAdvantage();
if (_advOnBeforeSetCard - num2 >= num)
{
return true;
}
return false;
}
public bool IsOpponentBanishBad(AIVirtualCard actCard)
{
if (actCard.IsAlly)
{
return false;
}
float num = actCard.Cost;
float num2 = AI.CalcFieldAdvantage();
if (_advOnBeforeSetCard - num2 < num)
{
return true;
}
return false;
}
public bool IsOpponentHealClassLifeLargeOnCardPlay()
{
int num = 4;
if (AI.OPPONENT.Class.Life - _opponentLifeOnBeforeSetCard >= num)
{
return true;
}
return false;
}
public bool IsOpponentHealClassLifeLargeOnAttack()
{
int num = 4;
if (AI.OPPONENT.Class.Life - _opponentLifeOnBeforeAttack >= num)
{
return true;
}
return false;
}
public bool IsThinkingLong()
{
float num = 20000f;
if (!_isThinkingEmoteOccured)
{
return (float)_stopwatch.ElapsedMilliseconds > num;
}
return false;
}
public void OnThinkingEmote()
{
_isThinkingEmoteOccured = true;
_stopwatch.Reset();
}
public void OnOperationRequest()
{
if (!_isThinkingEmoteOccured)
{
_stopwatch.Reset();
_stopwatch.Start();
}
}
public bool IsReplyAllowed(ClassCharaPrm.EmotionType emoteType, ref ClassCharaPrm.EmotionType replyEmote)
{
switch (emoteType)
{
case ClassCharaPrm.EmotionType.GREET:
if (_isAIGreeted)
{
return false;
}
replyEmote = ClassCharaPrm.EmotionType.GREET;
_isAIGreeted = true;
return true;
case ClassCharaPrm.EmotionType.THANK:
if (_isAIThanked)
{
return false;
}
replyEmote = ClassCharaPrm.EmotionType.THANK;
_isAIThanked = true;
return true;
default:
return false;
}
}
public void AddPlayedCountOnEmotePlaying(int category)
{
if (EmoteCategoryPlayedCounter.ContainsKey(category))
{
EmoteCategoryPlayedCounter[category]++;
}
else
{
EmoteCategoryPlayedCounter.Add(category, 1);
}
}
public int GetEmotePlayCount(int category)
{
if (EmoteCategoryPlayedCounter.ContainsKey(category))
{
return EmoteCategoryPlayedCounter[category];
}
return 0;
}
}

View File

@@ -0,0 +1,214 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public class AIEmoteQuery
{
public enum Category
{
UnexpectedPlayResult_Good = 1,
UnexpectedPlayResult_Bad = 2,
LongThinking = 3,
UnexpectedBattleResult = 11,
ReverseDisAdv = 12,
CheckMated = 13,
HuntDown = 14,
RemainTooPP = 15,
SpellBanishOverExpected = 21,
FatalAttack = 22,
OpponentRemainTooPP = 31,
OpponentReverseDisAdvFail = 32,
OpponentGetGreatMerit = 33,
OpponentPlayGiant = 34,
OpponentBanishSpell_Good = 35,
OpponentBanishSpell_Bad = 36,
OpponentWellHealing = 37,
EliminatedAllyLegion = 101,
EnoughUnit = 102,
Awake = 401,
EnoughGrave = 501
}
private EnemyAI enemyAI;
private bool _isActivate = true;
private AIEmoteSet _curEmoteSet;
private bool _emotePermission;
private bool _useInnerEmote;
private Queue<int> _previousEmoteQueue;
private Queue<int> _previousPlayerEmoteQueue;
private Dictionary<int, int> _categoryIntervalDic;
private const int EMOTE_QUEUE_LENGTH = 3;
public bool UseInnerEmote => _useInnerEmote;
public AIEmoteQuery(EnemyAI ai)
{
enemyAI = ai;
_emotePermission = true;
_useInnerEmote = false;
_previousEmoteQueue = new Queue<int>(3);
_previousPlayerEmoteQueue = new Queue<int>(3);
_categoryIntervalDic = new Dictionary<int, int>();
}
public void SetOnOffEmote(bool isActivate, bool useInnerEmote)
{
_isActivate = isActivate;
_useInnerEmote = useInnerEmote;
}
public void SetEmoteSet(AIEmoteSet emoteSet)
{
_curEmoteSet = emoteSet;
}
public void UpdateCategoryInterval()
{
foreach (int item in new List<int>(_categoryIntervalDic.Keys))
{
int num = _categoryIntervalDic[item];
if (num > 0)
{
_categoryIntervalDic[item] = num - 1;
}
}
}
public void SetInterval(int emoteKey, int turnCount)
{
if (_categoryIntervalDic.ContainsKey(emoteKey))
{
_categoryIntervalDic[emoteKey] = turnCount;
}
else
{
_categoryIntervalDic.Add(emoteKey, turnCount);
}
}
public int GetCategoryInterval(int emoteKey)
{
if (!_categoryIntervalDic.ContainsKey(emoteKey))
{
return 0;
}
return _categoryIntervalDic[emoteKey];
}
public AIEmoteCmd SearchEmoteAtRandom(int emoteKey, bool isAlly = true)
{
if (!_isActivate)
{
return null;
}
if (_curEmoteSet == null)
{
return null;
}
if (!_curEmoteSet.EmoteCmds.Any((AIEmoteCmd c) => c.CategoryKey == emoteKey))
{
return null;
}
if (!_emotePermission)
{
return null;
}
if (!_useInnerEmote && emoteKey <= 1000)
{
return null;
}
AIEmoteCmd aIEmoteCmd = null;
IList<AIEmoteCmd> list = FilterEmoteByPreviousPlayed(_curEmoteSet.EmoteCmds.Where((AIEmoteCmd c) => c.CategoryKey == emoteKey), isAlly);
int count = list.Count;
if (count <= 0)
{
return null;
}
if (count > 1)
{
int index = enemyAI.AIStableRandom() % count;
aIEmoteCmd = list[index];
}
else
{
aIEmoteCmd = list[0];
}
if (aIEmoteCmd != null)
{
Queue<int> queue = (isAlly ? _previousEmoteQueue : _previousPlayerEmoteQueue);
if (queue.Count == 3)
{
queue.Dequeue();
}
queue.Enqueue(aIEmoteCmd.ID);
aIEmoteCmd.isAI = isAlly;
}
return aIEmoteCmd;
}
public AIEmoteCmd SearchEmoteByID(int emoteID)
{
if (_curEmoteSet == null)
{
return null;
}
if (!_curEmoteSet.EmoteCmds.Any((AIEmoteCmd c) => c.ID == emoteID))
{
return null;
}
return _curEmoteSet.EmoteCmds.First((AIEmoteCmd c) => c.ID == emoteID);
}
public IEnumerable<AIEmoteCmd> SearchEmoteByCategory(int emoteCategory)
{
if (_curEmoteSet == null)
{
return null;
}
if (!_curEmoteSet.EmoteCmds.Any((AIEmoteCmd c) => c.CategoryKey == emoteCategory))
{
return null;
}
return _curEmoteSet.EmoteCmds.Where((AIEmoteCmd c) => c.CategoryKey == emoteCategory);
}
public void OnOperation()
{
_emotePermission = true;
}
public void OnCardPlayEmotion()
{
_emotePermission = false;
}
private IList<AIEmoteCmd> FilterEmoteByPreviousPlayed(IEnumerable<AIEmoteCmd> emoteCmds, bool isAlly)
{
IList<AIEmoteCmd> list = new List<AIEmoteCmd>();
Queue<int> queue = (isAlly ? _previousEmoteQueue : _previousPlayerEmoteQueue);
foreach (AIEmoteCmd emoteCmd in emoteCmds)
{
if (queue.Contains(emoteCmd.ID))
{
if (enemyAI.AIStableRandom() % 4 == 0)
{
list.Add(emoteCmd);
}
}
else
{
list.Add(emoteCmd);
}
}
return list;
}
}

View File

@@ -0,0 +1,19 @@
using System.Collections.Generic;
namespace Wizard;
public class AIEmoteSet
{
private List<AIEmoteCmd> cmdList = new List<AIEmoteCmd>();
public IEnumerable<AIEmoteCmd> EmoteCmds => cmdList;
public void CreateFromAsset(List<AIEmoteDataAsset> assetList)
{
cmdList.Clear();
foreach (AIEmoteDataAsset asset in assetList)
{
cmdList.Add(new AIEmoteCmd(asset));
}
}
}

View File

@@ -0,0 +1,49 @@
using System.Collections.Generic;
namespace Wizard;
public class AIFunctionResultContainer
{
private Dictionary<AIScriptTokenFuncType, Dictionary<ulong, float>> _functionResultDic;
public AIFunctionResultContainer()
{
_functionResultDic = new Dictionary<AIScriptTokenFuncType, Dictionary<ulong, float>>();
}
public void Clear()
{
foreach (AIScriptTokenFuncType key in _functionResultDic.Keys)
{
_functionResultDic[key].Clear();
}
_functionResultDic.Clear();
}
public void AddRecord(AIScriptTokenFuncType funcType, ulong hash, float result)
{
if (!_functionResultDic.TryGetValue(funcType, out var value))
{
value = new Dictionary<ulong, float>();
_functionResultDic.Add(funcType, value);
}
if (value.ContainsKey(hash))
{
AIConsoleUtility.LogError($"AIFunctionResultContainer.AddRecord() error!! conflict key = {hash}");
}
else
{
value.Add(hash, result);
}
}
public bool GetContainsResultValue(AIScriptTokenFuncType funcType, ulong hash, out float getResult)
{
if (_functionResultDic.TryGetValue(funcType, out var value))
{
return value.TryGetValue(hash, out getResult);
}
getResult = 0f;
return false;
}
}

View File

@@ -0,0 +1,48 @@
using System.Collections.Generic;
namespace Wizard;
public class AIFusionSituationInfo : AISituationInfo
{
public List<AIVirtualCard> Targets;
public float Priority { get; private set; }
public List<AIScriptTokenBase> Range { get; private set; }
public AIPolishConvertedExpression PriorityExpression { get; private set; }
public bool HasTargets
{
get
{
if (Targets != null)
{
return Targets.Count > 0;
}
return false;
}
}
public AIFusionSituationInfo(AIVirtualCard actor, List<AIVirtualCard> targets)
: base(actor, null, null, AIOperationType.FUSION)
{
Targets = targets;
}
public void UpdatePriority(List<int> playPtn)
{
Priority = PriorityExpression.EvalArg(base.Actor, playPtn, base.Actor.SelfField, this);
}
public bool InitializeFusionParameter(AIVirtualField field, List<int> playPtn)
{
return base.Actor.TagCollectionContainer.FusionTags.InitializeFusionSituationParameter(base.Actor, field, playPtn, this);
}
public void SetParameter(List<AIScriptTokenBase> range, AIPolishConvertedExpression priority)
{
Range = range;
PriorityExpression = priority;
}
}

View File

@@ -0,0 +1,126 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public class AIGenerateTagOwnerTable
{
public class GenerateTagOwnerInfo
{
public int OwnerBaseCardId { get; private set; }
public int OwnerCardIndex { get; private set; }
public bool OwnerIsPlayer { get; private set; }
public List<AIPlayTag> GenerateTagList { get; private set; }
public GenerateTagOwnerInfo(int baseCardId, int cardIndex, bool isPlayer)
{
OwnerBaseCardId = baseCardId;
OwnerCardIndex = cardIndex;
OwnerIsPlayer = isPlayer;
GenerateTagList = new List<AIPlayTag>();
}
public bool IsOwner(int baseCardId, int cardIndex, bool isPlayer)
{
if (OwnerBaseCardId == baseCardId && OwnerCardIndex == cardIndex)
{
return OwnerIsPlayer == isPlayer;
}
return false;
}
public void RegisterNewGenerateTag(List<AIPlayTag> tagList)
{
List<AIPlayTag> list = null;
for (int i = 0; i < tagList.Count; i++)
{
AIPlayTag aIPlayTag = tagList[i];
if (aIPlayTag.Type == AIPlayTagType.GenerateTag && !GenerateTagList.Contains(aIPlayTag))
{
list = AIParamQuery.AddElementToList(aIPlayTag, list);
}
}
if (list != null)
{
GenerateTagList.AddRange(list);
}
}
public GenerateTagOwnerInfo Clone()
{
return new GenerateTagOwnerInfo(OwnerBaseCardId, OwnerCardIndex, OwnerIsPlayer)
{
GenerateTagList = new List<AIPlayTag>(GenerateTagList)
};
}
}
private List<GenerateTagOwnerInfo> _ownerInfoList;
public AIGenerateTagOwnerTable()
{
_ownerInfoList = new List<GenerateTagOwnerInfo>();
}
public void ClearAll()
{
_ownerInfoList.Clear();
}
public AIGenerateTagOwnerTable Clone()
{
AIGenerateTagOwnerTable aIGenerateTagOwnerTable = new AIGenerateTagOwnerTable();
for (int i = 0; i < _ownerInfoList.Count; i++)
{
aIGenerateTagOwnerTable._ownerInfoList.Add(_ownerInfoList[i].Clone());
}
return aIGenerateTagOwnerTable;
}
public void RegisterAllGenerateTagOwner(AIVirtualField field)
{
BattlePlayerPair playerPair = new BattlePlayerPair(field.AllyBattlePlayer, field.EnemyBattlePlayer);
List<AIVirtualCard> allReferableCards = field.CardListSet.AllReferableCards;
for (int i = 0; i < allReferableCards.Count; i++)
{
if (allReferableCards[i].TagCollectionContainer.HasTag(AIPlayTagType.GenerateTag))
{
RegisterGenerateTagOwnerOneCard(playerPair, allReferableCards[i]);
}
}
List<AIVirtualCard> enemyHandCardList = field.GetEnemyHandCardList();
for (int j = 0; j < enemyHandCardList.Count; j++)
{
if (enemyHandCardList[j].TagCollectionContainer.HasTag(AIPlayTagType.GenerateTag))
{
RegisterGenerateTagOwnerOneCard(playerPair, enemyHandCardList[j]);
}
}
}
private void RegisterGenerateTagOwnerOneCard(BattlePlayerPair playerPair, AIVirtualCard card)
{
BattleCardBase battleCard = AIRealBattleCardSearcher.SearchBattleCardFromVirtualCard(playerPair, card);
if (battleCard != null)
{
GenerateTagOwnerInfo generateTagOwnerInfo = _ownerInfoList.FirstOrDefault((GenerateTagOwnerInfo o) => o.IsOwner(battleCard.BaseParameter.BaseCardId, battleCard.Index, battleCard.IsPlayer));
if (generateTagOwnerInfo == null)
{
generateTagOwnerInfo = new GenerateTagOwnerInfo(battleCard.BaseParameter.BaseCardId, battleCard.Index, battleCard.IsPlayer);
_ownerInfoList.Add(generateTagOwnerInfo);
}
if (card.TagCollectionContainer.HasTag(AIPlayTagType.GenerateTag))
{
generateTagOwnerInfo.RegisterNewGenerateTag(card.TagCollectionContainer.GenerateTags.TagList);
}
}
}
public GenerateTagOwnerInfo GetGenerateTagOwnerInfo(int baseCardId, int ownerIndex, bool ownerIsPlayer)
{
return _ownerInfoList.FirstOrDefault((GenerateTagOwnerInfo o) => o.IsOwner(baseCardId, ownerIndex, ownerIsPlayer));
}
}

View File

@@ -0,0 +1,52 @@
using System.Collections.Generic;
namespace Wizard;
public class AIHandPlayEstimator
{
public List<AIVirtualCard> InplayEstimations { get; private set; }
public AIHandPlayEstimator(AIParamQuery paramQuery, int handIndex, AIVirtualCard handOriginal, BattlePlayerPair sourcePair, EnemyAI ai)
{
BattleCardBase baseCard = handOriginal.BaseCard;
int num = ai.CurrentVirtualField.AllyInplayCards.Count;
if (baseCard.IsUnit || baseCard.IsField)
{
num++;
}
List<int> playPtn = new List<int> { handOriginal.SelfField.AllyHandCards.FindIndex((AIVirtualCard c) => c.CardIndex == handOriginal.CardIndex) };
AISinglePlayptnRecord playptnRecord = ai.PlayPtnRecorder.FindMatchedPlayPtnRecord(playPtn, ai.CurrentVirtualField);
AIVirtualCard aIVirtualCard = handOriginal.FindRealActor(playptnRecord);
if (!aIVirtualCard.IsSameCard(handOriginal))
{
ai.tokenManager.AddTokenFromCard(aIVirtualCard);
}
AIVirtualTargetSelectAction situation = new AIVirtualTargetSelectAction(aIVirtualCard, handOriginal, AIOperationType.PLAY);
if (aIVirtualCard.BaseCard.Movable())
{
List<AITokenInformation> allySideTokenIdsOfPlaySituation = AIPlayTokenSimulationUtility.GetAllySideTokenIdsOfPlaySituation(ai.CurrentVirtualField, new List<int> { handOriginal.SelfField.AllyHandCards.FindIndex((AIVirtualCard c) => c.CardIndex == handOriginal.CardIndex) }, situation);
if (allySideTokenIdsOfPlaySituation == null || allySideTokenIdsOfPlaySituation.Count <= 0)
{
return;
}
for (int num2 = 0; num2 < allySideTokenIdsOfPlaySituation.Count; num2++)
{
AIVirtualCard tokenFromId = ai.tokenManager.GetTokenFromId(allySideTokenIdsOfPlaySituation[num2].TokenId, isAlly: true, ai.CurrentVirtualField, needsClone: true);
if (InplayEstimations == null)
{
InplayEstimations = new List<AIVirtualCard>();
}
InplayEstimations.Add(tokenFromId);
num++;
if (num >= 6)
{
break;
}
}
}
else
{
InplayEstimations = null;
}
}
}

View File

@@ -0,0 +1,74 @@
using System.Collections.Generic;
namespace Wizard;
public class AIHealRecorderCollection
{
public class AIHealRecorder
{
public int TurnCount { get; private set; }
public AIVirtualCard Card { get; private set; }
public AIHealRecorder(int turnCount, AIVirtualCard healedCard)
{
TurnCount = turnCount;
Card = healedCard;
}
}
public List<AIHealRecorder> AllyHealRecorderList { get; private set; }
public List<AIHealRecorder> EnemyHealRecorderList { get; private set; }
public AIHealRecorderCollection()
{
AllyHealRecorderList = new List<AIHealRecorder>();
EnemyHealRecorderList = new List<AIHealRecorder>();
}
private AIHealRecorderCollection(AIHealRecorderCollection original)
{
AllyHealRecorderList = new List<AIHealRecorder>(original.AllyHealRecorderList);
EnemyHealRecorderList = new List<AIHealRecorder>(original.EnemyHealRecorderList);
}
public AIHealRecorderCollection Clone()
{
return new AIHealRecorderCollection(this);
}
public int GetTurnHealCount(int turn, List<AIVirtualCard> checkTargets, bool isAlly)
{
List<AIHealRecorder> list = (isAlly ? AllyHealRecorderList : EnemyHealRecorderList);
int num = 0;
for (int i = 0; i < list.Count; i++)
{
AIHealRecorder aIHealRecorder = list[i];
if (aIHealRecorder.TurnCount != turn)
{
continue;
}
for (int j = 0; j < checkTargets.Count; j++)
{
if (aIHealRecorder.Card.IsSameCard(checkTargets[j]))
{
num++;
break;
}
}
}
return num;
}
public void AppendHealCount(int turn, AIVirtualCard healedCard, bool isAlly)
{
(isAlly ? AllyHealRecorderList : EnemyHealRecorderList).Add(new AIHealRecorder(turn, healedCard));
}
public void Clear()
{
AllyHealRecorderList.Clear();
EnemyHealRecorderList.Clear();
}
}

View File

@@ -0,0 +1,82 @@
using System.Collections.Generic;
namespace Wizard;
public class AILeaveStopCollection : AITagPreprocessCollectionBase
{
public AILeaveStopCollection Clone(List<AIVirtualCard> overrideCardList)
{
AILeaveStopCollection aILeaveStopCollection = new AILeaveStopCollection();
aILeaveStopCollection.CopyInfoListWithReplaceCardReference(overrideCardList, base.InfoList);
return aILeaveStopCollection;
}
public void SimulateActionAll(AIVirtualCard leaveCard, AISituationInfo situation)
{
List<AITagPreprocessInformationBase> list = null;
for (int i = 0; i < base.InfoList.Count; i++)
{
if (base.InfoList[i] is AILeaveStopInformation aILeaveStopInformation && aILeaveStopInformation.ExecuteReservedAction(leaveCard, situation))
{
list = AIParamQuery.AddElementToList(aILeaveStopInformation, list);
}
}
if (list != null && list.Count > 0)
{
for (int j = 0; j < list.Count; j++)
{
base.InfoList.Remove(list[j]);
}
}
}
public void PseudoSimulateForEvalRandomMultiDamage(List<AIBarrierPseudoSimulationInfo> barrierInfoList, AIVirtualCard leaveCard)
{
for (int i = 0; i < base.InfoList.Count; i++)
{
if (base.InfoList[i] is AILeaveStopInformation aILeaveStopInformation)
{
aILeaveStopInformation.PseudoExecuteForEvalRandomMultiDamage(leaveCard, barrierInfoList);
}
}
}
public void AppendInfo(AITagPreprocessCreationOptionBase option, AIVirtualCard provider)
{
AILeaveStopInformation aILeaveStopInformation = CreateInfo(option, provider);
if (aILeaveStopInformation != null)
{
base.InfoList.Add(aILeaveStopInformation);
}
}
private AILeaveStopInformation CreateInfo(AITagPreprocessCreationOptionBase option, AIVirtualCard provider)
{
switch (option.PreprocessInfoType)
{
case AITagPreprocessInfoType.BARRIER_STOP:
return new AIBarrierLeaveStopInformation(option as AIBarrierStopPreprocessOption, provider);
case AITagPreprocessInfoType.REMOVE_ATTACHED_TAG:
return new AIAttachedTagLeaveStopInformation(option as AIAttachedTagStopPreprocessOption, provider);
case AITagPreprocessInfoType.UNTOUCHABLE_STOP:
return new AIUntouchableLeaveStopInformation(option, provider);
default:
AIConsoleUtility.LogError("AITurnEndStopInfoContainer-CreateInfo(): Missing TurnEndInfo type");
return null;
}
}
protected override void GetOverrideCardAndAppendCopyInfo(List<AIVirtualCard> overrideCardList, AITagPreprocessInformationBase originalInfo)
{
if (overrideCardList != null && overrideCardList.Count > 0 && originalInfo is AILeaveStopInformation aILeaveStopInformation)
{
AIVirtualCard overrideTargetCard = aILeaveStopInformation.GetOverrideTargetCard(overrideCardList);
AIVirtualCard overrideProviderCard = aILeaveStopInformation.GetOverrideProviderCard(overrideCardList);
if (overrideTargetCard != null && overrideProviderCard != null)
{
AITagPreprocessCreationOptionBase option = originalInfo.CreateOptionInfoForOverride(overrideTargetCard);
AppendInfo(option, overrideProviderCard);
}
}
}
}

View File

@@ -0,0 +1,53 @@
using System.Collections.Generic;
namespace Wizard;
public class AILeaveStopInformation : AITagPreprocessInformationBase
{
private AIVirtualCard _provider;
public AILeaveStopInformation(AIVirtualCard target, AIVirtualCard provider)
: base(target)
{
_provider = provider;
}
public bool ExecuteReservedAction(AIVirtualCard leaveCard, AISituationInfo situation)
{
if (leaveCard.IsSameCard(_provider))
{
StopMethod(situation);
return true;
}
return false;
}
protected virtual void StopMethod(AISituationInfo situation)
{
}
public void PseudoExecuteForEvalRandomMultiDamage(AIVirtualCard leaveCard, List<AIBarrierPseudoSimulationInfo> barrierInfoList)
{
if (leaveCard.IsSameCard(_provider))
{
PseudoStopMethodForEvalRandomMultiDamage(barrierInfoList);
}
}
protected virtual void PseudoStopMethodForEvalRandomMultiDamage(List<AIBarrierPseudoSimulationInfo> barrierInfoList)
{
}
public AIVirtualCard GetOverrideProviderCard(List<AIVirtualCard> overrideCardList)
{
for (int i = 0; i < overrideCardList.Count; i++)
{
AIVirtualCard aIVirtualCard = overrideCardList[i];
if (aIVirtualCard.IsSameCard(_provider))
{
return aIVirtualCard;
}
}
return null;
}
}

View File

@@ -0,0 +1,29 @@
using System.Collections.Generic;
namespace Wizard;
public class AILethalPlan
{
public bool IsSuccess;
public List<AISituationInfo> ActionSequence;
public AILethalPlan()
{
IsSuccess = false;
ActionSequence = null;
}
public void AddAction(AISituationInfo action)
{
ActionSequence = AIParamQuery.AddElementToList(action, ActionSequence);
}
public AILethalPlan Clone()
{
AILethalPlan aILethalPlan = new AILethalPlan();
aILethalPlan.IsSuccess = IsSuccess;
aILethalPlan.ActionSequence = AIParamQuery.AddRangeToList(ActionSequence, aILethalPlan.ActionSequence);
return aILethalPlan;
}
}

View File

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

View File

@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Wizard.Battle.Operation;
namespace Wizard;
public class AIOperationSimulatorAccessor
{
private EnemyAI _ai;
private List<BattleCardBase> _selectedSkillTargetList = new List<BattleCardBase>();
public AIVirtualField CurrentField { get; private set; }
public AIGenerateTagOwnerTable GenerateTagOwnerTable { get; private set; }
public AIBattleInfoReceivedData BattleInfoReceiveDate { get; private set; } = new AIBattleInfoReceivedData();
public AIOperationSimulatorAccessor(EnemyAI ai)
{
CurrentField = null;
Initialize(ai);
}
public AIOperationSimulatorAccessor(EnemyAI ai, AIVirtualField field)
{
CurrentField = field;
Initialize(ai);
}
private void Initialize(EnemyAI ai)
{
_ai = ai;
GenerateTagOwnerTable = ai.GenerateTagOwnerTable.Clone();
}
public BattlePlayerPair CallAttack(BattlePlayerPair sourcePair, BattleCardBase attackCardId, BattleCardBase targetCardId, List<int> playPtn)
{
UpdateCurrentField(sourcePair, playPtn);
SetUpBattleInfoReceiver();
BattlePlayerPair battlePlayerPair = OperationSimulator.Attack(sourcePair, attackCardId, targetCardId, isPrediction: false, SetVirtualPairEvent);
CleanUpBattleInfoReceiver();
UpdateCurrentField(battlePlayerPair, playPtn);
return battlePlayerPair;
}
public BattlePlayerPair CallPlay(BattlePlayerPair sourcePair, BattleCardBase playCardId, List<BattleCardBase> skillTargets, List<int> playPtn)
{
UpdateCurrentField(sourcePair, playPtn);
Action<BattleCardBase> playCardSkillEvent = delegate(BattleCardBase card)
{
BattlePlayerPair pair = new BattlePlayerPair(card.SelfBattlePlayer, card.OpponentBattlePlayer);
EnemyAIUtil.SetupPlayCardSkillOptionValue(card, pair);
};
SetUpBattleInfoReceiver();
BattlePlayerPair battlePlayerPair = OperationSimulator.Play(sourcePair, playCardId, skillTargets, SetVirtualPairEvent, playCardSkillEvent);
CleanUpBattleInfoReceiver();
List<int> list = new List<int>();
for (int num = 1; num < playPtn.Count; num++)
{
BattleCardBase oldCard = sourcePair.Self.HandCardList[playPtn[num]];
BattleCardBase battleCardBase = battlePlayerPair.Self.HandCardList.FirstOrDefault((BattleCardBase c) => c.Index == oldCard.Index || c.BaseParameter.BaseCardId == oldCard.BaseParameter.BaseCardId);
if (battleCardBase != null)
{
list.Add(battlePlayerPair.Self.HandCardList.IndexOf(battleCardBase));
}
}
UpdateCurrentField(battlePlayerPair, list);
return battlePlayerPair;
}
public BattlePlayerPair CallEvolve(BattlePlayerPair sourcePair, BattleCardBase evolutionCardId, List<BattleCardBase> skillTargets, List<int> playPtn)
{
UpdateCurrentField(sourcePair, playPtn);
SetUpBattleInfoReceiver();
BattlePlayerPair battlePlayerPair = OperationSimulator.Evolve(sourcePair, evolutionCardId, skillTargets, SetVirtualPairEvent);
CleanUpBattleInfoReceiver();
UpdateCurrentField(battlePlayerPair, playPtn);
return battlePlayerPair;
}
public BattlePlayerPair CallTurnEnd(BattlePlayerPair sourcePair)
{
SetUpBattleInfoReceiver();
BattlePlayerPair result = OperationSimulator.TurnEnd(sourcePair);
CleanUpBattleInfoReceiver();
return result;
}
public BattlePlayerPair CallOpponentTurnStart(BattlePlayerPair sourcePair)
{
BattlePlayerPair sourcePair2 = new BattlePlayerPair(sourcePair.Opponent, sourcePair.Self);
SetUpBattleInfoReceiver();
BattlePlayerPair battlePlayerPair = OperationSimulator.TurnStart(sourcePair2);
CleanUpBattleInfoReceiver();
return new BattlePlayerPair(battlePlayerPair.Opponent, battlePlayerPair.Self);
}
public void UpdateCurrentField(BattlePlayerPair sourcePair, List<int> playPtn)
{
AIVirtualFieldBuildParameterCollction buildParameters = new AIVirtualFieldBuildParameterCollction(CurrentField);
CurrentField = AIVirtualField.CreateTemporaryVirtualField(_ai, _ai.ParamQuery, _ai.StyleQuery, sourcePair, playPtn, buildParameters);
GenerateTagOwnerTable.RegisterAllGenerateTagOwner(CurrentField);
_selectedSkillTargetList.Clear();
}
public void SetVirtualPairEvent(BattlePlayerPair virtualPair)
{
AIAttachEventToBattleModuleUtility.SetupVirtualPairEventForOperationSimulator(virtualPair, this);
}
private void SetUpBattleInfoReceiver()
{
AIBattleInfoReceiver.GetInstance()?.SetUpOprSimAccessor(this);
}
private void CleanUpBattleInfoReceiver()
{
AIBattleInfoReceiver.GetInstance()?.CleanUpOprSimAccessor();
}
}

View File

@@ -0,0 +1,12 @@
namespace Wizard;
public enum AIOperationType
{
ATTACK,
EVOLVE,
PLAY,
FUSION,
TURNEND,
TURNSTART,
UNKNOWN
}

View File

@@ -0,0 +1,64 @@
using System.Collections.Generic;
namespace Wizard;
public class AIOwnSkillProcessRecord
{
public List<AIVirtualCard> OwnDestroyedCards { get; private set; }
public List<AIVirtualCard> OwnBanishedCards { get; private set; }
public List<AIVirtualCard> OwnSummonedCards { get; private set; }
public List<AIVirtualCard> OwnLatestSummonedCards { get; private set; }
public List<AIVirtualCard> OwnLatestDrewCards { get; private set; }
public List<AIVirtualCard> LatestTargets { get; private set; }
public int DefaultDamage { get; private set; } = -1;
public void AddOwnDestroyedCard(AIVirtualCard card)
{
OwnDestroyedCards = AIParamQuery.AddElementToList(card, OwnDestroyedCards);
}
public void AddOwnBanishedCard(AIVirtualCard card)
{
OwnBanishedCards = AIParamQuery.AddElementToList(card, OwnBanishedCards);
}
public void AddOwnSummonedCards(List<AIVirtualCard> list)
{
OwnSummonedCards = AIParamQuery.AddRangeToList(list, OwnSummonedCards);
OwnLatestSummonedCards = list;
}
public void AddOwnDrewCards(List<AIVirtualCard> list)
{
OwnLatestDrewCards = list;
}
public void RegisterSingleLatestTarget(AIVirtualCard card)
{
if (LatestTargets != null)
{
LatestTargets.Clear();
}
else
{
LatestTargets = new List<AIVirtualCard>();
}
LatestTargets.Add(card);
}
public void RegisterLatestTargetList(List<AIVirtualCard> list)
{
LatestTargets = list;
}
public void RegisterDefaultDamage(int damage)
{
DefaultDamage = damage;
}
}

View File

@@ -0,0 +1,420 @@
using System.Collections.Generic;
using System.Linq;
using Cute;
using UnityEngine;
using Wizard.Battle;
namespace Wizard;
public class AIParamQuery
{
private const float MAX_ADVANTAGE = 1000f;
public EnemyAI enemyAI;
public AIStyleQuery styleQuery;
private int classID;
private AI_LOGIC_LV logicLv = AI_LOGIC_LV.STRONG;
private AIDeckAcccessor deck;
public AIParamQuery(EnemyAI ai)
{
enemyAI = ai;
}
public void SetUp(AIStyleQuery _styleQuery)
{
styleQuery = _styleQuery;
}
public void SetDeck(int _classID, AI_LOGIC_LV _logicLv, AIDeckData _curDeck, AIDeckData _commonDic, AIDeckData _allyCommonDic)
{
classID = _classID;
logicLv = _logicLv;
deck = new AIDeckAcccessor(_curDeck, _commonDic, _allyCommonDic);
}
public AICardData SearchAICardData(AIVirtualCard card)
{
if (!card.IsLeader && deck != null)
{
return deck.SearchCardData(card.BaseId, card.IsAlly);
}
return null;
}
public int GetClassID()
{
return classID;
}
public AI_LOGIC_LV GetLogicLv()
{
return logicLv;
}
public bool IsEnabledTag(AIVirtualCard card, AIVirtualField field, AIPlayTagType type, List<int> playPtn, AISituationInfo situation)
{
int tagCount = GetTagCount(card);
if (tagCount <= 0)
{
return false;
}
for (int i = 0; i < tagCount; i++)
{
AIPlayTag tag = GetTag(card, i);
if (tag.Type == type && tag.CheckCondition(card, playPtn, card.SelfField, situation))
{
return true;
}
}
return false;
}
public int GetTagCount(AIVirtualCard owner, AICardData data = null)
{
if (deck == null)
{
return 0;
}
AICardData aICardData = null;
if (!owner.IsLeader)
{
aICardData = ((data == null) ? deck.SearchCardData(owner.BaseId, enemyAI.IsAllyCard(owner)) : data);
}
int num = 0;
if (aICardData != null && aICardData.TagList != null && !owner.IsSkillLost)
{
if (owner.IsRobbedLastword)
{
for (int i = 0; i < aICardData.TagList.Count; i++)
{
if (!aICardData.TagList[i].IsLastwordTag())
{
num++;
}
}
}
else
{
num += aICardData.TagList.Count;
}
}
return num;
}
public AIPlayTag GetTag(AIVirtualCard owner, int index, AICardData data = null)
{
AICardData aICardData = null;
if (!owner.IsLeader)
{
aICardData = ((data == null) ? deck.SearchCardData(owner.BaseId, enemyAI.IsAllyCard(owner)) : data);
}
int num = 0;
if (aICardData != null && aICardData.TagList != null && !owner.IsSkillLost)
{
if (owner.IsRobbedLastword)
{
for (int i = 0; i < aICardData.TagList.Count; i++)
{
if (!aICardData.TagList[i].IsLastwordTag())
{
if (num == index)
{
return aICardData.TagList[i];
}
num++;
}
}
}
else
{
num = aICardData.TagList.Count;
if (aICardData.TagList.Count > index)
{
return aICardData.TagList[index];
}
}
}
return null;
}
public bool IsRobbedLastword(BattleCardBase card)
{
for (int i = 0; i < card.BuffInfoList.Count; i++)
{
BuffInfo buffInfo = card.BuffInfoList[i];
if (buffInfo.PreviousOwner == null && buffInfo.SkillFrom is Skill_rob_skill)
{
return true;
}
}
return false;
}
public float EvaluateBattlePlayerPair(AIVirtualField field, bool useStyle = true)
{
float num = 0f;
for (int i = 0; i < field.AllyInplayCards.Count; i++)
{
AIVirtualCard aIVirtualCard = field.AllyInplayCards[i];
if (!aIVirtualCard.IsDead && aIVirtualCard.IsOnField)
{
float num2 = aIVirtualCard.EvaluateValueOnField(EnemyAI.EmptyPlayPtn, null, useStyle);
num += num2;
}
}
for (int j = 0; j < field.EnemyInplayCards.Count; j++)
{
AIVirtualCard aIVirtualCard2 = field.EnemyInplayCards[j];
if (!aIVirtualCard2.IsDead && aIVirtualCard2.IsOnField)
{
float num3 = aIVirtualCard2.EvaluateValueOnField(EnemyAI.EmptyPlayPtn, null, useStyle);
num -= num3;
}
}
return num;
}
public IEnumerable<BattleCardBase> RemoveDuplicatedCards(IEnumerable<BattleCardBase> targetCards, IEnumerable<BattleCardBase> filterCards)
{
if (!targetCards.IsNotNullOrEmpty() || !filterCards.IsNotNullOrEmpty())
{
yield break;
}
foreach (BattleCardBase targetCard in targetCards)
{
bool flag = false;
foreach (BattleCardBase filterCard in filterCards)
{
if (filterCard != null && targetCard.IsPlayer == filterCard.IsPlayer && targetCard.Index == filterCard.Index)
{
flag = true;
break;
}
}
if (!flag)
{
yield return targetCard;
}
}
}
public bool IsBanishSkill(SkillBase skill)
{
if (!(skill is Skill_banish) && !(skill is Skill_destroy) && !(skill is Skill_damage) && !(skill is Skill_return_card))
{
return skill is Skill_metamorphose;
}
return true;
}
public float CalcHandCardOverflowPenalty(AIVirtualField field, List<int> playPtn, float penalty, ref int dstHandCount)
{
float num = 0f;
for (int i = 0; i < playPtn.Count; i++)
{
int index = playPtn[i];
AIVirtualCard aIVirtualCard = field.AllyHandCards[index];
int handPlusCount = aIVirtualCard.GetHandPlusCount(playPtn);
_ = aIVirtualCard.IsSpell;
dstHandCount--;
dstHandCount += handPlusCount;
if (dstHandCount > 9)
{
num += penalty * (float)(dstHandCount - 9);
dstHandCount = 9;
}
}
for (int j = 0; j < field.AllyInplayCards.Count; j++)
{
AIVirtualCard tagOwner = field.AllyInplayCards[j];
dstHandCount += tagOwner.GetHandPlusCount(playPtn);
}
if (dstHandCount > 8)
{
num += penalty * (float)(dstHandCount - 8);
}
return num;
}
public List<BattleCardBase> GetEvoSelectCandidates(BattleCardBase evoCard, BattlePlayerPair pair)
{
List<SkillBase> list = evoCard.GetSelectTypeSkill(isEvolve: true).ToList();
if (list.IsNotNullOrEmpty())
{
return GetSkillTargetsForEstimator(evoCard, list, pair);
}
return null;
}
public List<BattleCardBase> GetSkillTargetsForEstimator(BattleCardBase actCard, List<SkillBase> selectSkills, BattlePlayerPair pair)
{
List<BattleCardBase> list = new List<BattleCardBase>();
for (int i = 0; i < selectSkills.Count; i++)
{
SkillBase skillBase = selectSkills[i];
IEnumerable<BattleCardBase> burialSelectableCards = AIBurialRiteSimulationUtility.GetBurialSelectableCards(skillBase, actCard);
if (burialSelectableCards.IsNotNullOrEmpty())
{
List<BattleCardBase> list2 = burialSelectableCards.ToList();
for (int j = 0; j < list2.Count; j++)
{
BattleCardBase item = list2[j];
if (!list.Contains(item))
{
list.Add(item);
break;
}
}
}
IEnumerable<BattleCardBase> selectableCards = GetSelectableCards(skillBase, pair);
if (!selectableCards.IsNotNullOrEmpty())
{
continue;
}
List<BattleCardBase> list3 = selectableCards.ToList();
list3.AddRange(from c in GetSelectableCards(skillBase, pair, isSkipForceSelect: true)
where !selectableCards.Contains(c)
select c);
int num = Mathf.Min(skillBase.GetSkillSelectCount(), list3.Count());
for (int num2 = 0; num2 < num; num2++)
{
if (list3.Contains(pair.Opponent.Class) && !list.Contains(pair.Opponent.Class))
{
list.Add(pair.Opponent.Class);
continue;
}
for (int num3 = 0; num3 < list3.Count; num3++)
{
BattleCardBase item2 = list3[num3];
if (!list.Contains(item2))
{
list.Add(item2);
break;
}
}
}
}
return list;
}
public int CalcAllyUnitTotalDamage()
{
int num = 0;
foreach (BattleCardBase inPlayCard in enemyAI.ALLY.InPlayCards)
{
if (inPlayCard.IsUnit)
{
int num2 = inPlayCard.MaxLife - inPlayCard.Life;
num += num2;
}
}
return num;
}
public int GetEnemyGuardiansCount()
{
int num = 0;
foreach (BattleCardBase inPlayCard in enemyAI.OPPONENT.InPlayCards)
{
if (inPlayCard.SkillApplyInformation.IsGuard)
{
num++;
}
}
return num;
}
public IEnumerable<BattleCardBase> GetSelectSkillTargetCandidates(BattleCardBase card, BattlePlayerReadOnlyInfoPair pair)
{
SkillBase actSkill = null;
return ActionProcessor.GetSkillUserSelectableTargets(card.Skills, pair, ref actSkill);
}
public bool IsDestroyBeforeAttack(BattleCardBase card)
{
if (card.IsUnit)
{
return card.Skills.Any((SkillBase skill) => skill is Skill_destroy && skill.IsBeforAttackSkill);
}
return false;
}
public IEnumerable<IReadOnlyBattleCardInfo> GetBrokenAll(BattleCardBase card)
{
SkillTargetDestroyedCardListFilter skillTargetDestroyedCardListFilter = new SkillTargetDestroyedCardListFilter();
SkillConditionCheckerOption option = new SkillConditionCheckerOption();
IBattlePlayerReadOnlyInfo[] battlePlayerInfos = new IBattlePlayerReadOnlyInfo[1] { card.SelfBattlePlayer };
return skillTargetDestroyedCardListFilter.Filtering(battlePlayerInfos, option);
}
public IEnumerable<BattleCardBase> GetSelectableCards(SkillBase skill, BattlePlayerPair pair, bool isSkipForceSelect = false)
{
if (skill.IsUserSelectType || skill.IsChoiceType)
{
SkillConditionCheckerOption option = new SkillConditionCheckerOption();
return skill.GetSelectableCards(pair, option, isSkipForceSelect);
}
return new List<BattleCardBase>();
}
public static List<T> AddElementToList<T>(T element, List<T> container, bool isBlockDuplicate = false)
{
if (container == null)
{
container = new List<T>();
}
if (!isBlockDuplicate || !container.Contains(element))
{
container.Add(element);
}
return container;
}
public static List<T> AddRangeToList<T>(List<T> elements, List<T> container, bool isBlockDuplicate = false)
{
if (elements == null || elements.Count <= 0)
{
return container;
}
if (container == null)
{
container = new List<T>();
}
for (int i = 0; i < elements.Count; i++)
{
T item = elements[i];
if (!isBlockDuplicate || !container.Contains(item))
{
container.Add(item);
}
}
return container;
}
public static List<T> CloneList<T>(List<T> src)
{
if (src == null)
{
return null;
}
return new List<T>(src);
}
public static AIVirtualCard FindSameCardFromList<T>(AIVirtualCard origin, List<T> list) where T : AIVirtualCard
{
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (aIVirtualCard.IsSameCard(origin))
{
return aIVirtualCard;
}
}
return null;
}
}

View File

@@ -0,0 +1,30 @@
using System.Collections.Generic;
namespace Wizard;
public class AIPlayOutAction
{
public int UseCardIndex { get; private set; }
public AIOperationType Command { get; private set; }
public List<BattleCardBase> TargetCardList { get; private set; }
public AIPlayOutAction(AIOperationType command, BattleCardBase useCard, List<BattleCardBase> targetCards)
{
Command = command;
if (useCard != null)
{
UseCardIndex = useCard.Index;
}
else
{
UseCardIndex = -1;
}
TargetCardList = new List<BattleCardBase>();
if (targetCards != null && targetCards.Count > 0)
{
TargetCardList.AddRange(targetCards);
}
}
}

View File

@@ -0,0 +1,960 @@
using System.Collections.Generic;
namespace Wizard;
public class AIPlayTag
{
public static readonly int TAG_WORDS_LENTGH = 3;
private string _typeText;
private string _argText;
private string _conditionText;
private AIScriptArgumentExpressions argExpr;
private AIConditionExpressions condExpr;
public AIPlayTagType Type { get; private set; }
public string Arg => _argText;
public string Condition => _conditionText;
public ulong Hash { get; private set; }
public AIScriptArgumentExpressions ArgumentExpressions => argExpr;
public AIConditionExpressions ConditionExpressions => condExpr;
public bool InitFromTextAsset(AIPlayTagAsset asset)
{
Type = AIScriptParser.ConvertWordToTagType(asset.Type);
if (Type == AIPlayTagType.None)
{
return false;
}
if (CheckInvalidTagPattern(asset, out var _))
{
return false;
}
_typeText = asset.Type;
_argText = asset.Arg;
_conditionText = asset.Condition;
Hash = GetHash();
argExpr = CreateArgument(_argText);
condExpr = new AIConditionExpressions(_conditionText);
return true;
}
private bool CheckInvalidTagPattern(AIPlayTagAsset asset, out string errorLog)
{
errorLog = "";
bool flag = false;
switch (Type)
{
case AIPlayTagType.FanfareToken:
case AIPlayTagType.PlayToken:
flag = asset.Arg.IndexOf("PLAY_TOKEN_COUNT") >= 0 || asset.Condition.IndexOf("PLAY_TOKEN_COUNT") >= 0;
if (flag)
{
errorLog = "タグ " + asset.Type + " のArgに PLAY_TOKEN_COUNT が使用されています。\n";
}
break;
case AIPlayTagType.TurnEndActivateCount:
flag = asset.Condition.IndexOf("IS_IN_HAND") < 0 && asset.Condition.IndexOf("IS_ON_FIELD") < 0;
if (flag)
{
errorLog = "タグ " + asset.Type + " のCondに IS_IN_HAND,IS_ON_FIELD のどちらも指定されていません。\n";
}
break;
}
AIPlayTagType type = Type;
if ((uint)(type - 23) > 2u && (uint)(type - 27) > 1u && asset.Condition.IndexOf("NEXT_PLAY_PRIORITY ") > 0)
{
flag = true;
errorLog = "PlaySkip系以外のタグ " + asset.Type + " のCondには NEXT_PLAY_PRIORITY を使用することを許可されていません。\n";
}
if (flag)
{
errorLog = errorLog + "tag:" + asset.Type + ", arg:" + asset.Arg + ", cond:" + asset.Condition;
}
return flag;
}
private AIScriptArgumentExpressions CreateArgument(string arg)
{
switch (Type)
{
case AIPlayTagType.AllyPlayBonus:
case AIPlayTagType.EnemyPlayBonus:
return new AIOtherPlayBonus(arg);
case AIPlayTagType.MemberBattleBonusRate:
case AIPlayTagType.EnemyBattleBonusRate:
return new AIOtherBattleBonusRate(arg);
case AIPlayTagType.MemberEvoBonus:
case AIPlayTagType.EnemyEvoBonus:
return new AIOtherEvoBonus(arg);
case AIPlayTagType.PlayAttachTag:
case AIPlayTagType.FanfareAttachTag:
return new AIWhenPlayAttachTag(arg);
case AIPlayTagType.PlayCopyTag:
case AIPlayTagType.FanfareCopyTag:
return new AIWhenPlayCopyTag(arg);
case AIPlayTagType.AttackAttachTag:
return new AIAttackAttachTag(arg);
case AIPlayTagType.LastwordAttachTag:
return new AILastwordAttachTag(arg);
case AIPlayTagType.EvoAttachTag:
return new AIEvoAttachTag(arg);
case AIPlayTagType.SummonAttachTag:
return new AISummonAttachTag(arg);
case AIPlayTagType.OtherSummonAttachTag:
return new AIOtherSummonAttachTag(arg);
case AIPlayTagType.FanfareAttachStyle:
return new AIWhenPlayAttachStyle(arg);
case AIPlayTagType.FanfareToken:
case AIPlayTagType.PlayToken:
return new AIWhenPlaySummonToken(arg);
case AIPlayTagType.BreakAttachTag:
return new AIBreakAttachTag(arg);
case AIPlayTagType.NecromanceAttachTag:
return new AINecromanceAttachTag(arg);
case AIPlayTagType.NecromanceAddCemetery:
return new AINecromanceAddCemetery(arg);
case AIPlayTagType.TurnStartAttachTag:
return new AITurnStartAttachTag(arg);
case AIPlayTagType.TurnStartSubtractCountdown:
return new AITurnStartSubtractCountdown(arg);
case AIPlayTagType.TurnStartDamageCut:
return new AITurnStartDamageCut(arg);
case AIPlayTagType.TurnStartShield:
return new AITurnStartShield(arg);
case AIPlayTagType.TurnStartDamage:
return new AITurnStartDamage(arg);
case AIPlayTagType.TurnEndAttachTag:
return new AITurnEndAttachTag(arg);
case AIPlayTagType.HealAttachTag:
return new AIHealAttachTag(arg);
case AIPlayTagType.DiscardedToken:
return new AIDiscardedToken(arg);
case AIPlayTagType.LeaveToken:
return new AILeaveToken(arg);
case AIPlayTagType.DamagedToken:
return new AIDamagedToken(arg);
case AIPlayTagType.PlayDamage:
case AIPlayTagType.FanfareDamage:
return new AIWhenPlayDamage(arg);
case AIPlayTagType.PlayBuff:
case AIPlayTagType.FanfareBuff:
return new AIWhenPlayBuff(arg);
case AIPlayTagType.PlaySetMaxStatus:
case AIPlayTagType.FanfareSetMaxStatus:
return new AIWhenPlaySetMaxStatus(arg);
case AIPlayTagType.PlaySetLeaderMaxLife:
return new AIWhenPlaySetLeaderMaxLife(arg);
case AIPlayTagType.PlayDestroy:
case AIPlayTagType.FanfareDestroy:
return new AIWhenPlayDestroy(arg);
case AIPlayTagType.PlayBanish:
case AIPlayTagType.FanfareBanish:
return new AIWhenPlayBanish(arg);
case AIPlayTagType.PlayBounce:
case AIPlayTagType.FanfareBounce:
return new AIWhenPlayBounce(arg);
case AIPlayTagType.PlayMetamorphose:
case AIPlayTagType.FanfareMetamorphose:
return new AIWhenPlayMetamorphose(arg);
case AIPlayTagType.PlayHandMetamorphose:
case AIPlayTagType.FanfareHandMetamorphose:
return new AIWhenPlayHandMetamorphose(arg);
case AIPlayTagType.FanfareSpellboost:
case AIPlayTagType.PlaySpellboost:
return new AIWhenPlaySpellboost(arg);
case AIPlayTagType.FanfareAddCemetery:
case AIPlayTagType.PlayAddCemetery:
return new AIWhenPlayAddCemetery(arg);
case AIPlayTagType.PlayReanimate:
case AIPlayTagType.FanfareReanimate:
return new AIWhenPlayReanimate(arg);
case AIPlayTagType.PlayBanAttack:
case AIPlayTagType.FanfareBanAttack:
return new AIWhenPlayBanAttack(arg);
case AIPlayTagType.FanfareHandBuff:
case AIPlayTagType.PlayHandBuff:
return new AIWhenPlayHandBuff(arg);
case AIPlayTagType.PlayChangeCost:
case AIPlayTagType.FanfareChangeCost:
return new AIWhenPlayChangeCost(arg);
case AIPlayTagType.FanfareBonusInSimulation:
case AIPlayTagType.PlayBonusInSimulation:
return new AIWhenPlayBonusInSimulation(arg);
case AIPlayTagType.Target:
case AIPlayTagType.IgnoreTarget:
case AIPlayTagType.AttackByLife:
case AIPlayTagType.FirstEvo:
return new AIFiltersArgument(arg);
case AIPlayTagType.PlaySkip:
return new AIPlaySkipTagArgument(arg);
case AIPlayTagType.PlaySkipWithEvo:
return new AIPlaySkipWithEvo(arg);
case AIPlayTagType.PlaySkipIfEvo:
return new AIPlaySkipIfEvo(arg);
case AIPlayTagType.PlaySkipWithAction:
return new AIPlaySkipWithAction(arg);
case AIPlayTagType.PlaySkipWithActionIfEvo:
return new AIPlaySkipWithActionIfEvo(arg);
case AIPlayTagType.AttackDamage:
return new AIAttackDamage(arg);
case AIPlayTagType.AttackDestroy:
return new AIAttackDestroy(arg);
case AIPlayTagType.ClashBanish:
case AIPlayTagType.AttackBanish:
return new AIAttackOrClashBanish(arg);
case AIPlayTagType.ClashHeal:
case AIPlayTagType.AttackHeal:
return new AIAttackOrClashHeal(arg);
case AIPlayTagType.AttackEvo:
return new AIAttackEvo(arg);
case AIPlayTagType.AttackBreakDamage:
return new AIAttackBreakDamage(arg);
case AIPlayTagType.AttackBreakEvo:
return new AIAttackBreakEvo(arg);
case AIPlayTagType.AttackBreakRecoverPp:
return new AIAttackBreakRecoverPp(arg);
case AIPlayTagType.AttackBreakAttackTwice:
return new AIAttackBreakAttackTwice(arg);
case AIPlayTagType.ClashToken:
case AIPlayTagType.AttackToken:
return new AIAttackOrClashToken(arg);
case AIPlayTagType.AttackAttackableCount:
return new AIAttackAttackableCount(arg);
case AIPlayTagType.AttackQuick:
return new AIAttackOrClashKeywordSkill(arg, AIScriptTokenArgType.QUICK);
case AIPlayTagType.PlayHeal:
case AIPlayTagType.FanfareHeal:
return new AIWhenPlayHeal(arg);
case AIPlayTagType.AttackBuff:
return new AIAttackBuff(arg);
case AIPlayTagType.AttackHandBuff:
return new AIAttackHandBuff(arg);
case AIPlayTagType.SummonBuff:
return new AISummonBuff(arg);
case AIPlayTagType.SummonDestroy:
return new AISummonDestroy(arg);
case AIPlayTagType.SummonBanAttack:
return new AISummonBanAttack(arg);
case AIPlayTagType.BreakDamage:
return new AIBreakDamage(arg);
case AIPlayTagType.BreakRecoverAttackableCount:
return new AIBreakRecoverAttackableCount(arg);
case AIPlayTagType.LastwordDestroy:
return new AILastwordDestroy(arg);
case AIPlayTagType.DamagedBonus:
return new AIDamagedBonus(arg);
case AIPlayTagType.DamagedBuff:
return new AIDamagedBuff(arg);
case AIPlayTagType.DamagedDamage:
return new AIDamagedDamage(arg);
case AIPlayTagType.DamagedHeal:
return new AIDamagedHeal(arg);
case AIPlayTagType.DamagedCantUnderAttack:
return new AIDamagedCantUnderAttack(arg);
case AIPlayTagType.OtherDamagedDamage:
return new AIOtherDamagedDamage(arg);
case AIPlayTagType.OtherDamagedHeal:
return new AIOtherDamagedHeal(arg);
case AIPlayTagType.OtherDamagedSetLeaderMaxLife:
return new AIOtherDamagedSetLeaderMaxLife(arg);
case AIPlayTagType.OtherDamagedSubtractCountdown:
return new AIOtherDamagedSubtractCountdown(arg);
case AIPlayTagType.OtherDamagedBanish:
return new AIOtherDamagedBanish(arg);
case AIPlayTagType.SummonEvo:
return new AISummonEvo(arg);
case AIPlayTagType.EvoToken:
return new AIEvoToken(arg);
case AIPlayTagType.LastwordToken:
return new AILastwordToken(arg);
case AIPlayTagType.SummonRush:
return new AISummonKeywordSkill(arg, AIScriptTokenArgType.RUSH);
case AIPlayTagType.SummonQuick:
return new AISummonKeywordSkill(arg, AIScriptTokenArgType.QUICK);
case AIPlayTagType.OtherSummonRush:
return new AIOtherSummonKeywordSkill(arg, AIScriptTokenArgType.RUSH);
case AIPlayTagType.SummonDamage:
return new AISummonDamage(arg);
case AIPlayTagType.SummonBanish:
return new AISummonBanish(arg);
case AIPlayTagType.SummonHeal:
return new AISummonHeal(arg);
case AIPlayTagType.OtherSummonDamage:
return new AIOtherSummonDamage(arg);
case AIPlayTagType.OtherSummonGuard:
return new AIOtherSummonKeywordSkill(arg, AIScriptTokenArgType.GUARD);
case AIPlayTagType.OtherSummonQuick:
return new AIOtherSummonKeywordSkill(arg, AIScriptTokenArgType.QUICK);
case AIPlayTagType.OtherSummonKiller:
return new AIOtherSummonKeywordSkill(arg, AIScriptTokenArgType.KILLER);
case AIPlayTagType.OtherSummonDrain:
return new AIOtherSummonKeywordSkill(arg, AIScriptTokenArgType.DRAIN);
case AIPlayTagType.OtherSummonBanish:
return new AIOtherSummonBanish(arg);
case AIPlayTagType.OtherSummonHeal:
return new AIOtherSummonHeal(arg);
case AIPlayTagType.OtherSummonBuff:
return new AIOtherSummonBuff(arg);
case AIPlayTagType.OtherSummonEvo:
return new AIOtherSummonEvo(arg);
case AIPlayTagType.OtherSummonDamageCut:
return new AIOtherSummonDamageCut(arg);
case AIPlayTagType.OtherSummonDamageClip:
return new AIOtherSummonDamageClip(arg);
case AIPlayTagType.OtherSummonSubtractCountdown:
return new AIOtherSummonSubtractCountdown(arg);
case AIPlayTagType.OtherSummonAddCemetery:
return new AIOtherSummonAddCemetery(arg);
case AIPlayTagType.OtherSummonUntouchable:
return new AIOtherSummonKeywordSkill(arg, AIScriptTokenArgType.UNTOUCHABLE);
case AIPlayTagType.OtherSummonDestory:
return new AIOtherSummonDestroy(arg);
case AIPlayTagType.OtherSummonDraw:
return new AIOtherSummonDraw(arg);
case AIPlayTagType.Necromance:
return new AINecromance(arg);
case AIPlayTagType.EarthRite:
return new AIEarthRite(arg);
case AIPlayTagType.BurialRite:
return new AIBurialRite(arg);
case AIPlayTagType.LastwordDamage:
return new AILastwordDamage(arg);
case AIPlayTagType.LastwordHeal:
return new AILastwordHeal(arg);
case AIPlayTagType.LastwordMetamorphose:
return new AILastwordMetamorphose(arg);
case AIPlayTagType.LastwordBanish:
return new AILastwordBanish(arg);
case AIPlayTagType.LastwordDraw:
return new AILastwordDraw(arg);
case AIPlayTagType.LastwordAddDeck:
return new AILastwordAddDeck(arg);
case AIPlayTagType.LastwordSetStatus:
return new AILastwordSetStatus(arg);
case AIPlayTagType.TurnEndDamage:
return new AITurnEndDamage(arg);
case AIPlayTagType.ClashDamage:
return new AIClashDamage(arg);
case AIPlayTagType.AfterClashDamage:
return new AIAfterClashDamage(arg);
case AIPlayTagType.ClashDestroy:
return new AIClashDestroy(arg);
case AIPlayTagType.ClashBuff:
return new AIClashBuff(arg);
case AIPlayTagType.ClashKiller:
case AIPlayTagType.AttackKiller:
return new AIAttackOrClashKeywordSkill(arg, AIScriptTokenArgType.KILLER);
case AIPlayTagType.AttackRemoveTag:
case AIPlayTagType.ClashRemoveTag:
return new AIAttackOrClashRemoveTag(arg);
case AIPlayTagType.ClashRemoveSkill:
case AIPlayTagType.AttackRemoveSkill:
return new AIAttackOrClashRemoveSkill(arg);
case AIPlayTagType.ClashSpellboost:
return new AIAttackOrClashSpellboost(arg);
case AIPlayTagType.AfterClashHeal:
return new AIAfterClashHeal(arg);
case AIPlayTagType.RemoveSkill:
return new AIRemoveSkill(arg);
case AIPlayTagType.HealDamage:
return new AIHealDamage(arg);
case AIPlayTagType.HealBuff:
return new AIHealBuff(arg);
case AIPlayTagType.HealToken:
return new AIHealToken(arg);
case AIPlayTagType.HealHeal:
return new AIHealHeal(arg);
case AIPlayTagType.HealEvo:
return new AIHealEvo(arg);
case AIPlayTagType.TurnEndMetamorphose:
return new AITurnEndMetamorphose(arg);
case AIPlayTagType.BreakBuff:
return new AIBreakBuff(arg);
case AIPlayTagType.BreakSetLeaderMaxLife:
return new AIBreakSetLeaderMaxLife(arg);
case AIPlayTagType.LastwordBuff:
return new AILastwordBuff(arg);
case AIPlayTagType.EvoBuff:
return new AIEvoBuff(arg);
case AIPlayTagType.EvoHeal:
return new AIEvoHeal(arg);
case AIPlayTagType.EvoBanish:
return new AIEvoBanish(arg);
case AIPlayTagType.EvoSubtractCountdown:
return new AIEvoSubtractCountdown(arg);
case AIPlayTagType.EvoEvo:
return new AIEvoEvo(arg);
case AIPlayTagType.EvoDamage:
return new AIEvoDamage(arg);
case AIPlayTagType.EvoDestroy:
return new AIEvoDestroy(arg);
case AIPlayTagType.EvoMetamorphose:
return new AIEvoMetamorphose(arg);
case AIPlayTagType.EvoHandMetamorphose:
return new AIEvoHandMetamorphose(arg);
case AIPlayTagType.EvoBounce:
return new AIEvoBounce(arg);
case AIPlayTagType.EvoRush:
return new AIEvoGiveBasicSkill(arg, AIScriptTokenArgType.RUSH);
case AIPlayTagType.EvoQuick:
return new AIEvoGiveBasicSkill(arg, AIScriptTokenArgType.QUICK);
case AIPlayTagType.EvoGuard:
return new AIEvoGiveBasicSkill(arg, AIScriptTokenArgType.GUARD);
case AIPlayTagType.EvoKiller:
return new AIEvoGiveBasicSkill(arg, AIScriptTokenArgType.KILLER);
case AIPlayTagType.EvoDrain:
return new AIEvoGiveBasicSkill(arg, AIScriptTokenArgType.DRAIN);
case AIPlayTagType.EvoAttackableCount:
return new AIEvoAttackableCount(arg);
case AIPlayTagType.EvoChangeCost:
return new AIEvoChangeCost(arg);
case AIPlayTagType.EvoHandSelect:
return new AIEvoHandSelect(arg);
case AIPlayTagType.EvoTokenDraw:
return new AIEvoTokenDraw(arg);
case AIPlayTagType.EvoShield:
return new AIEvoShield(arg);
case AIPlayTagType.EvoDamageCut:
return new AIEvoDamageCut(arg);
case AIPlayTagType.EvoReanimate:
return new AIEvoReanimate(arg);
case AIPlayTagType.EvoAddDeck:
return new AIEvoAddDeck(arg);
case AIPlayTagType.TurnEndDestroy:
return new AITurnEndDestroy(arg);
case AIPlayTagType.TurnEndHeal:
return new AITurnEndHeal(arg);
case AIPlayTagType.TurnEndBanish:
return new AITurnEndBanish(arg);
case AIPlayTagType.TurnEndSetLeaderMaxLife:
return new AITurnEndSetLeaderMaxLife(arg);
case AIPlayTagType.TurnEndDiscard:
return new AITurnEndDiscard(arg);
case AIPlayTagType.TurnEndBuff:
return new AITurnEndBuff(arg);
case AIPlayTagType.TurnEndSubtractCountdown:
return new AITurnEndSubtractCountdown(arg);
case AIPlayTagType.TurnEndToken:
return new AITurnEndToken(arg);
case AIPlayTagType.TurnEndBounce:
return new AITurnEndBounce(arg);
case AIPlayTagType.TurnEndAddDeck:
return new AITurnEndAddDeck(arg);
case AIPlayTagType.TurnEndEvo:
return new AITurnEndEvo(arg);
case AIPlayTagType.TurnEndDraw:
return new AITurnEndDraw(arg);
case AIPlayTagType.TurnEndRemoveTag:
return new AITurnEndRemoveTag(arg);
case AIPlayTagType.TurnEndShield:
return new AITurnEndShield(arg);
case AIPlayTagType.TurnEndDamageClip:
return new AITurnEndDamageClip(arg);
case AIPlayTagType.TurnEndDamageCut:
return new AITurnEndDamageCut(arg);
case AIPlayTagType.TurnEndGuard:
return new AITurnEndKeywordSkill(arg, AIScriptTokenArgType.GUARD);
case AIPlayTagType.TurnEndBanAttack:
return new AITurnEndBanAttack(arg);
case AIPlayTagType.EvoSetLeaderMaxLife:
return new AIEvoSetLeaderMaxLife(arg);
case AIPlayTagType.EvolvedAttackableCount:
return new AIEvolvedAttackableCount(arg);
case AIPlayTagType.EvolvedAttackable:
return new AIEvolvedAttackable(arg);
case AIPlayTagType.EvolvedSkill:
return new AIEvolvedSkill(arg);
case AIPlayTagType.AfterAttackEvo:
return new AIAfterAttackEvo(arg);
case AIPlayTagType.AfterAttackDraw:
return new AIAfterAttackDraw(arg);
case AIPlayTagType.AfterAttackBanish:
return new AIAfterAttackBanish(arg);
case AIPlayTagType.BreakDestroy:
return new AIBreakDestroy(arg);
case AIPlayTagType.PlayRecoverPP:
case AIPlayTagType.FanfareRecoverPp:
return new AIWhenPlayRecoverPp(arg);
case AIPlayTagType.BuffRecoverPP:
return new AIBuffRecoverPp(arg);
case AIPlayTagType.BreakRecoverPp:
return new AIBreakRecoverPp(arg);
case AIPlayTagType.Fusion:
return new AIFusion(arg);
case AIPlayTagType.FusionDraw:
return new AIFusionDraw(arg);
case AIPlayTagType.HandBonus:
return new AIBonusArgumentWithIgnoreInBattle(arg);
case AIPlayTagType.EvoRecoverPp:
return new AIEvoRecoverPp(arg);
case AIPlayTagType.PlayptnBaseStatsRate:
return new AIPlayptnBaseStatsRate(arg);
case AIPlayTagType.GiveSkill:
return new AIGiveSkill(arg);
case AIPlayTagType.PlayDiscard:
case AIPlayTagType.FanfareDiscard:
return new AIWhenPlayDiscard(arg);
case AIPlayTagType.AttackDiscard:
return new AIAttackDiscard(arg);
case AIPlayTagType.DiscardDamage:
return new AIDiscardDamage(arg);
case AIPlayTagType.BreakHeal:
return new AIBreakHeal(arg);
case AIPlayTagType.BuffDamage:
return new AIBuffDamage(arg);
case AIPlayTagType.BuffDestroy:
return new AIBuffDestroy(arg);
case AIPlayTagType.BuffToken:
return new AIBuffToken(arg);
case AIPlayTagType.BuffEvo:
return new AIBuffEvo(arg);
case AIPlayTagType.BuffDraw:
return new AIBuffDraw(arg);
case AIPlayTagType.BuffShield:
return new AIBuffShield(arg);
case AIPlayTagType.EvoDiscard:
return new AIEvoDiscard(arg);
case AIPlayTagType.BounceDamage:
return new AIBounceDamage(arg);
case AIPlayTagType.ResonanceDamage:
return new AIResonanceDamage(arg);
case AIPlayTagType.ResonanceHeal:
return new AIResonanceHeal(arg);
case AIPlayTagType.ResonanceKiller:
return new AIResonanceGiveBasicSkill(arg, AIScriptTokenArgType.KILLER);
case AIPlayTagType.DiscardHeal:
return new AIDiscardHeal(arg);
case AIPlayTagType.AllyDiscardBonus:
return new AIAllyDiscardBonus(arg);
case AIPlayTagType.BanishAttachTag:
return new AIBanishAttachTag(arg);
case AIPlayTagType.OtherBanishToken:
return new AIOtherBanishToken(arg);
case AIPlayTagType.OtherBanishAddCemetery:
return new AIOtherBanishAddCemetery(arg);
case AIPlayTagType.EvoChoice:
case AIPlayTagType.PlayChoice:
case AIPlayTagType.FanfareChoice:
return new AIChoiceTagArgument(arg);
case AIPlayTagType.ChoiceBrave:
return new AIChoiceBrave();
case AIPlayTagType.Enhance:
return new AIEnhance(arg);
case AIPlayTagType.Accelerate:
return new AIAccelerate(arg);
case AIPlayTagType.Crystalize:
return new AICrystalize(arg);
case AIPlayTagType.ChoiceTransform:
return new AIChoiceTransform(arg);
case AIPlayTagType.PlaySubtractCountdown:
case AIPlayTagType.FanfareSubtractCountdown:
return new AIWhenPlaySubtractCountdown(arg);
case AIPlayTagType.FanfareRecoverAttackableCount:
return new AIWhenPlayRecoverAttackableCount(arg);
case AIPlayTagType.FanfareSneak:
case AIPlayTagType.PlaySneak:
return new AIWhenPlayKeywordSkill(arg, AIScriptTokenArgType.SNEAK);
case AIPlayTagType.FanfareQuick:
case AIPlayTagType.PlayQuick:
return new AIWhenPlayKeywordSkill(arg, AIScriptTokenArgType.QUICK);
case AIPlayTagType.FanfareRush:
case AIPlayTagType.PlayRush:
return new AIWhenPlayKeywordSkill(arg, AIScriptTokenArgType.RUSH);
case AIPlayTagType.FanfareGuard:
case AIPlayTagType.PlayGuard:
return new AIWhenPlayKeywordSkill(arg, AIScriptTokenArgType.GUARD);
case AIPlayTagType.FanfareKiller:
case AIPlayTagType.PlayKiller:
return new AIWhenPlayKeywordSkill(arg, AIScriptTokenArgType.KILLER);
case AIPlayTagType.FanfareDrain:
case AIPlayTagType.PlayDrain:
return new AIWhenPlayKeywordSkill(arg, AIScriptTokenArgType.DRAIN);
case AIPlayTagType.FanfareUntouchable:
case AIPlayTagType.PlayUntouchable:
return new AIWhenPlayKeywordSkill(arg, AIScriptTokenArgType.UNTOUCHABLE);
case AIPlayTagType.FanfareForceTargeting:
return new AIWhenPlayKeywordSkill(arg, AIScriptTokenArgType.FORCE_TARGETING);
case AIPlayTagType.PlayIgnoreGuard:
case AIPlayTagType.FanfareIgnoreGuard:
return new AIWhenPlayKeywordSkill(arg, AIScriptTokenArgType.IGNORE_GUARD);
case AIPlayTagType.PlaySummonHandCard:
case AIPlayTagType.FanfareSummonHandCard:
return new AIWhenPlaySummonHandCard(arg);
case AIPlayTagType.PlaySelect:
case AIPlayTagType.FanfareSelect:
return new AIWhenPlaySelect(arg);
case AIPlayTagType.PlayHandSelect:
case AIPlayTagType.FanfareHandSelect:
return new AIWhenPlayHandSelect(arg);
case AIPlayTagType.EmoteOnTurnEnd:
return new AIEmoteOnTurnTransition(arg);
case AIPlayTagType.LastwordReanimate:
return new AILastwordReanimate(arg);
case AIPlayTagType.ModifyHeal:
return new AIModifyValue(arg);
case AIPlayTagType.LeaveBonus:
case AIPlayTagType.DiscardedBonus:
return new AIBonusArgumentWithIgnoreInBattle(arg);
case AIPlayTagType.LeaveHeal:
return new AILeaveHeal(arg);
case AIPlayTagType.LeaveDamage:
return new AILeaveDamage(arg);
case AIPlayTagType.LeaveAttachTag:
return new AILeaveAttachTag(arg);
case AIPlayTagType.LeaveBanish:
return new AILeaveBanish(arg);
case AIPlayTagType.OtherLeaveDamage:
return new AIOtherLeaveDamage(arg);
case AIPlayTagType.OtherLeaveToken:
return new AIOtherLeaveToken(arg);
case AIPlayTagType.AllyPlayoutDamageBonus:
return new AIOtherPlayoutDamageBonus(arg);
case AIPlayTagType.OtherBreakBonus:
case AIPlayTagType.OtherBanishBonus:
case AIPlayTagType.OtherLeaveBonus:
return new AIOtherBreakBonus(arg);
case AIPlayTagType.BuffRush:
return new AIBuffRush(arg);
case AIPlayTagType.BuffHeal:
return new AIBuffHeal(arg);
case AIPlayTagType.BuffBuff:
return new AIBuffBuff(arg);
case AIPlayTagType.GetOn:
return new AIGetOn(arg);
case AIPlayTagType.GetOnBanish:
return new AIGetOnBanish(arg);
case AIPlayTagType.GetOnDamage:
return new AIGetOnDamage(arg);
case AIPlayTagType.GetOnEvo:
return new AIGetOnEvo(arg);
case AIPlayTagType.GetOffMetamorphose:
return new AIGetOffMetamorphose(arg);
case AIPlayTagType.GetOffEvo:
return new AIGetOffEvo(arg);
case AIPlayTagType.AfterAttackHeal:
return new AIAfterAttackHeal(arg);
case AIPlayTagType.OtherAttackBuff:
return new AIOtherAttackBuff(arg);
case AIPlayTagType.OtherAttackDamage:
return new AIOtherAttackDamage(arg);
case AIPlayTagType.OtherAttackHeal:
return new AIOtherAttackHeal(arg);
case AIPlayTagType.OtherAttackToken:
return new AIOtherAttackToken(arg);
case AIPlayTagType.OtherAttackAttachTag:
return new AIOtherAttackAttachTag(arg);
case AIPlayTagType.OtherAttackRemoveTag:
return new AIOtherAttackRemoveTag(arg);
case AIPlayTagType.OtherEvoBuff:
return new AIOtherEvoBuff(arg);
case AIPlayTagType.OtherEvoDamage:
case AIPlayTagType.SelfAndOtherEvoDamage:
return new AIOtherEvoDamage(arg);
case AIPlayTagType.OtherEvoBanish:
return new AIOtherEvoBanish(arg);
case AIPlayTagType.OtherEvoSubtractCountdown:
return new AIOtherEvoSubtractCountdown(arg);
case AIPlayTagType.OtherEvoEvo:
return new AIOtherEvoEvo(arg);
case AIPlayTagType.OtherEvoToken:
case AIPlayTagType.SelfAndOtherEvoToken:
return new AIOtherEvoToken(arg);
case AIPlayTagType.OtherEvoShield:
case AIPlayTagType.SelfAndOtherEvoShield:
return new AIOtherEvoShield(arg);
case AIPlayTagType.SelfAndOtherEvoAttachTag:
return new AIOtherEvoAttachTag(arg);
case AIPlayTagType.SelfAndOtherEvoDestroy:
return new AIOtherEvoDestroy(arg);
case AIPlayTagType.SelfAndOtherEvoBounce:
return new AIOtherEvoBounce(arg);
case AIPlayTagType.SelfAndOtherEvoDraw:
return new AIOtherEvoDraw(arg);
case AIPlayTagType.SelfAndOtherEvoAddCemetery:
return new AIOtherEvoAddCemetery(arg);
case AIPlayTagType.SelfAndOtherEvoHeal:
return new AIOtherEvoHeal(arg);
case AIPlayTagType.SelfAndOtherEvoTokenDraw:
return new AIOtherEvoTokenDraw(arg);
case AIPlayTagType.RallyCountPlus:
return new AIFiltersArgument(arg);
case AIPlayTagType.TurnEndActivateCount:
return new AIActivateCountTagArgument(arg);
case AIPlayTagType.PlayActivateCount:
case AIPlayTagType.AttackActivateCount:
case AIPlayTagType.BreakActivateCount:
case AIPlayTagType.BanishActivateCount:
case AIPlayTagType.DamagedActivateCount:
case AIPlayTagType.BuffActivateCounnt:
case AIPlayTagType.HealActivateCount:
case AIPlayTagType.NecromanceActivateCount:
case AIPlayTagType.EvoActivateCount:
case AIPlayTagType.SummonActivateCount:
return new AIFilteringActivateCountArgument(arg);
case AIPlayTagType.SetAITribe:
return new AISetTribe(arg);
case AIPlayTagType.GenerateTag:
return new AIGenerateTag(arg);
case AIPlayTagType.PlayTokenDraw:
case AIPlayTagType.FanfareTokenDraw:
return new AIWhenPlayTokenDraw(arg);
case AIPlayTagType.PlayChangeClass:
case AIPlayTagType.FanfareChangeClass:
return new AIWhenPlayChangeClass(arg);
case AIPlayTagType.PlayChangeTribe:
case AIPlayTagType.FanfareChangeTribe:
return new AIWhenPlayChangeTribe(arg);
case AIPlayTagType.RemoveByDestroy:
return new AIRemoveByDestroy(arg);
case AIPlayTagType.EvoHandBuff:
return new AIEvoHandBuff(arg);
case AIPlayTagType.PlayNotBeAttacked:
case AIPlayTagType.FanfareNotBeAttacked:
return new AIWhenPlayNotBeAttacked(arg);
case AIPlayTagType.PlayAttackableCount:
case AIPlayTagType.FanfareAttackableCount:
return new AIWhenPlayAttackableCount(arg);
case AIPlayTagType.PlayRemoveSkill:
case AIPlayTagType.FanfareRemoveSkill:
return new AIWhenPlayRemoveSkill(arg);
case AIPlayTagType.BreakAddStack:
return new AIBreakAddStack(arg);
case AIPlayTagType.ChangeInplayImmediateRemoveByBanish:
return new AIChangeInplayFixRemoveType(arg, FixedRemoveType.RemoveByBanish, isImmediate: true);
case AIPlayTagType.ChangeInplayImmediateRemoveByDestroy:
return new AIChangeInplayFixRemoveType(arg, FixedRemoveType.RemoveByDestroy, isImmediate: true);
case AIPlayTagType.ChangeInplayCannotPlay:
return new AIChangeInplayCannotPlay(arg, isImmediate: false);
case AIPlayTagType.ChangeInplayCannotAttack:
return new AIChangeInplayCannotAttack(arg, isImmediate: false);
case AIPlayTagType.ChangeInplayAttachTag:
return new AIChangeInplayAttachTag(arg, isImmediate: false);
case AIPlayTagType.ChangeInplayImmediateShield:
return new AIChangeInplayImmediateShield(arg);
case AIPlayTagType.ChangeInplayImmediateDamageCut:
return new AIChangeInplayImmediateDamageCut(arg);
case AIPlayTagType.ChangeInplayImmediateDamageClip:
return new AIChangeInplayImmediateDamageClip(arg);
case AIPlayTagType.ChangeInplayImmediateLifeLowerLimit:
return new AIChangeInplayImmediateLifeLowerLimit(arg);
case AIPlayTagType.ChangeInplayImmediateDamageModifier:
return new AIChangeInplayImmediateDamageModifier(arg);
case AIPlayTagType.ChangeInplayImmediateUntouchable:
return new AIChangeInplayImmediateKeywordSkill(arg, AIScriptTokenArgType.UNTOUCHABLE);
case AIPlayTagType.ChangeInplayImmediateIndestructible:
return new AIChangeInplayImmediateIndestructible(arg);
case AIPlayTagType.ChangePpTotalBuff:
return new AIChangePpTotalBuff(arg, isImmediate: false);
case AIPlayTagType.EvoSetStatus:
return new AIEvoSetStatus(arg);
case AIPlayTagType.PlayModifyConsumeEp:
case AIPlayTagType.FanfareModifyConsumeEp:
return new AIWhenPlayModifyConsumeEp(arg);
case AIPlayTagType.PlayEvo:
case AIPlayTagType.FanfareEvo:
return new AIWhenPlayEvo(arg);
case AIPlayTagType.OtherPlayEvo:
return new AIOtherWhenPlayEvo(arg, PlaySimulationType.Undefined);
case AIPlayTagType.OtherEnhanceEvo:
return new AIOtherWhenPlayEvo(arg, PlaySimulationType.Enhance);
case AIPlayTagType.OtherPlayDamage:
return new AIOtherWhenPlayDamage(arg);
case AIPlayTagType.OtherPlayRecoverPp:
return new AIOtherWhenPlayRecoverPp(arg);
case AIPlayTagType.OtherPlayDestroy:
return new AIOtherWhenPlayDestroy(arg);
case AIPlayTagType.OtherPlayBounce:
return new AIOtherWhenPlayBounce(arg);
case AIPlayTagType.OtherPlayBuff:
return new AIOtherWhenPlayBuff(arg);
case AIPlayTagType.OtherPlayToken:
return new AIOtherWhenPlayToken(arg);
case AIPlayTagType.OtherPlayRemoveTag:
return new AIOtherWhenPlayRemoveTag(arg);
case AIPlayTagType.OtherPlayQuick:
return new AIOtherWhenPlayKeywordSkill(arg, AIScriptTokenArgType.QUICK);
case AIPlayTagType.AttackSubtractCountdown:
return new AIAttackSubtractCountdown(arg);
case AIPlayTagType.EvolveToOther:
return new AIEvolveToOtherTagArgument(arg);
case AIPlayTagType.LastwordEvo:
return new AILastwordEvo(arg);
case AIPlayTagType.LastwordRemoveSkill:
return new AILastwordRemoveSkill(arg);
case AIPlayTagType.LastwordAddCemetery:
return new AILastwordAddCemetery(arg);
case AIPlayTagType.LastwordDamageClip:
return new AILastwordDamageClip(arg);
case AIPlayTagType.LastwordShield:
return new AILastwordShield(arg);
case AIPlayTagType.PlayShield:
case AIPlayTagType.FanfareShield:
return new AIWhenPlayShield(arg);
case AIPlayTagType.PlayDamageCut:
case AIPlayTagType.FanfareDamageCut:
return new AIWhenPlayDamageCut(arg);
case AIPlayTagType.PlayDamageClip:
case AIPlayTagType.FanfareDamageClip:
return new AIWhenPlayDamageClip(arg);
case AIPlayTagType.OtherPlayAttachTag:
return new AIOtherWhenPlayAttachTag(arg);
case AIPlayTagType.AttackShield:
case AIPlayTagType.ClashShield:
return new AIAttackOrClashShield(arg);
case AIPlayTagType.AttackDamageClip:
case AIPlayTagType.ClashDamageClip:
return new AIAttackOrClashDamageClip(arg);
case AIPlayTagType.NecromanceDamage:
return new AINecromanceDamage(arg);
case AIPlayTagType.NecromanceHeal:
return new AINecromanceHeal(arg);
case AIPlayTagType.FanfareRemoveGuard:
return new AIWhenPlayRemoveKeywordSkill(arg, AIScriptTokenArgType.GUARD);
case AIPlayTagType.Stack:
return new AIStack(arg);
case AIPlayTagType.EvoAddStack:
return new AIEvoAddStack(arg);
case AIPlayTagType.FusionMetamorphose:
return new AIFusionMetamorphose(arg);
case AIPlayTagType.LastwordSubtractCountdown:
return new AILastwordSubtractCountdown(arg);
case AIPlayTagType.AttackSetStatus:
return new AIAttackSetStatus(arg);
case AIPlayTagType.PlayAddDeck:
case AIPlayTagType.FanfareAddDeck:
return new AIWhenPlayAddDeck(arg);
case AIPlayTagType.AttackAddDeck:
return new AIAttackAddDeck(arg);
default:
return new AIScriptArgumentExpressions(arg);
}
}
public bool CheckCondition(AIVirtualCard tagOwner, List<int> playPtn, AIVirtualField field, AISituationInfo situation)
{
return condExpr.CheckCondition(tagOwner, playPtn, field, situation);
}
public float EvalArg(AIVirtualCard tagOwner, List<int> playPtn, AIVirtualField field, AISituationInfo situation, int index = 0)
{
return argExpr.EvalArg(index, tagOwner, playPtn, field, situation);
}
public int EvalID(int index = 0)
{
return argExpr.EvalID(index);
}
public bool IsArgID(int index)
{
return argExpr.IsArgID(index);
}
public bool IsHoldingEVAL()
{
if (!ArgumentExpressions.IsHoldingEVAL())
{
return condExpr.IsHoldingEVAL();
}
return true;
}
public static bool IsAttachTagType(AIPlayTagType type)
{
if (type > AIPlayTagType.AttachTag_Start)
{
return type < AIPlayTagType.AttachTag_End;
}
return false;
}
public static bool IsRemoveTagType(AIPlayTagType tagType)
{
if (tagType == AIPlayTagType.AttackRemoveTag || tagType == AIPlayTagType.ClashRemoveTag || tagType == AIPlayTagType.TurnEndRemoveTag)
{
return true;
}
return false;
}
public bool IsClashTagType()
{
if (Type != AIPlayTagType.ClashDestroy && Type != AIPlayTagType.ClashBanish && Type != AIPlayTagType.ClashDamage && Type != AIPlayTagType.ClashHeal && Type != AIPlayTagType.ClashKiller && Type != AIPlayTagType.ClashBuff && Type != AIPlayTagType.ClashRemoveSkill && Type != AIPlayTagType.ClashToken && Type != AIPlayTagType.ClashShield && Type != AIPlayTagType.ClashDamageClip && Type != AIPlayTagType.ClashRemoveTag)
{
return Type == AIPlayTagType.ClashSpellboost;
}
return true;
}
public bool IsAttackTagType()
{
if (Type != AIPlayTagType.AttackBuff && Type != AIPlayTagType.AttackDamage && Type != AIPlayTagType.AttackHeal && Type != AIPlayTagType.AttackDestroy && Type != AIPlayTagType.AttackBanish && Type != AIPlayTagType.AttackToken && Type != AIPlayTagType.AttackDiscard && Type != AIPlayTagType.AttackAttackableCount && Type != AIPlayTagType.AttackAttachTag && Type != AIPlayTagType.AttackEvo && Type != AIPlayTagType.AttackSubtractCountdown && Type != AIPlayTagType.AttackKiller && Type != AIPlayTagType.AttackShield && Type != AIPlayTagType.AttackDamageClip && Type != AIPlayTagType.AttackRemoveTag && Type != AIPlayTagType.AttackRemoveSkill && Type != AIPlayTagType.AttackSetStatus && Type != AIPlayTagType.AttackAddDeck)
{
return Type == AIPlayTagType.AttackHandBuff;
}
return true;
}
public bool IsLastwordTag()
{
switch (Type)
{
case AIPlayTagType.IgnoreBreak:
case AIPlayTagType.LastwordToken:
case AIPlayTagType.LastwordBuff:
case AIPlayTagType.LastwordDestroy:
case AIPlayTagType.LastwordDamage:
case AIPlayTagType.LastwordHeal:
case AIPlayTagType.LastwordMetamorphose:
case AIPlayTagType.LastwordBanish:
case AIPlayTagType.LastwordDraw:
case AIPlayTagType.LastwordSetStatus:
case AIPlayTagType.Break:
case AIPlayTagType.LastwordReanimate:
case AIPlayTagType.LastwordAttachTag:
case AIPlayTagType.LastwordEvo:
case AIPlayTagType.LastwordRemoveSkill:
case AIPlayTagType.LastwordAddCemetery:
case AIPlayTagType.LastwordDamageClip:
case AIPlayTagType.LastwordShield:
case AIPlayTagType.LastwordSubtractCountdown:
return true;
default:
return false;
}
}
public bool IsTokenTag()
{
switch (Type)
{
case AIPlayTagType.FanfareToken:
case AIPlayTagType.PlayToken:
case AIPlayTagType.LastwordToken:
case AIPlayTagType.AttackToken:
case AIPlayTagType.EvoToken:
case AIPlayTagType.HealToken:
case AIPlayTagType.BuffToken:
case AIPlayTagType.OtherAttackToken:
case AIPlayTagType.OtherBanishToken:
return true;
default:
return false;
}
}
public ulong GetHash()
{
return (ulong)(_argText.GetHashCode() * 79 + _conditionText.GetHashCode() * 167 + Type.GetHashCode() * 2851);
}
}

View File

@@ -0,0 +1,10 @@
namespace Wizard;
public class AIPlayTagAsset
{
public string Type { get; set; }
public string Arg { get; set; }
public string Condition { get; set; }
}

View File

@@ -0,0 +1,478 @@
namespace Wizard;
public enum AIPlayTagType
{
PlayBonus,
PlayBonusRate,
FanfareBonus,
IgnoreFanfareBonus,
IgnoreBreak,
PlayptnBonus,
Priority,
PlayoutDamageBonus,
AllyPlayoutDamageBonus,
PlayoutNextTurn,
CostBonus,
PlayLimit,
PlayPlus,
Target,
IgnoreTarget,
AllyPlayBonus,
EnemyPlayBonus,
FanfareToken,
PlayToken,
AddCardToPlayoutPlayPtn,
PlayDraw,
HandBonus,
NoInstantAttack,
PlaySkip,
PlaySkipWithEvo,
PlaySkipIfEvo,
BreakBeforePlay,
PlaySkipWithAction,
PlaySkipWithActionIfEvo,
EvoBonus,
MemberEvoBonus,
EnemyEvoBonus,
EvoHandPlus,
NoNormalEvo,
EvoEvo,
EvoDamage,
EvoHandBuff,
ClashBonus,
AttackBonus,
ClashDestroy,
ClashHeal,
ClashToken,
ClashBanish,
ClashSpellboost,
AfterClashHeal,
AttackBuff,
AttackHandBuff,
AttackDestroy,
AttackBanish,
AttackHeal,
AttackDiscard,
AttackAttackableCount,
AttackQuick,
AttackRemoveTag,
AttackSetStatus,
AfterAttackEvo,
AfterAttackDraw,
AfterAttackBanish,
SummonBuff,
BreakBuff,
BreakSetLeaderMaxLife,
SummonEvo,
SummonRush,
SummonQuick,
SummonDamage,
SummonBanish,
SummonRecoverPp,
SummonHeal,
SummonDestroy,
SummonBanAttack,
OtherSummonDamage,
OtherSummonRush,
OtherSummonGuard,
OtherSummonQuick,
OtherSummonKiller,
OtherSummonDrain,
OtherSummonBanish,
OtherSummonHeal,
OtherSummonBuff,
OtherSummonEvo,
OtherSummonDamageCut,
OtherSummonDamageClip,
OtherSummonSubtractCountdown,
OtherSummonAddCemetery,
OtherSummonUntouchable,
OtherSummonDestory,
OtherSummonDraw,
PlayoutAttackBonus,
TurnEndDestroy,
TurnEndBanish,
TurnEndDamage,
TurnEndHeal,
TurnEndSetLeaderMaxLife,
TurnEndDiscard,
TurnEndBuff,
TurnEndSubtractCountdown,
TurnEndToken,
TurnEndBounce,
TurnEndAddDeck,
TurnEndEvo,
TurnEndDraw,
TurnEndShield,
TurnEndDamageClip,
TurnEndDamageCut,
TurnEndGuard,
TurnEndBanAttack,
ReincarnationSimulation,
PlayDestroy,
PlayDamage,
PlayHeal,
FanfareHeal,
PlayBanish,
FanfareBanish,
PlayBounce,
PlaySubtractCountdown,
FanfareSubtractCountdown,
AllyClashDamage,
CantBeAttacked,
AttackableClass,
ClashBuff,
PlayptnBaseStatsRate,
LastwordToken,
AttackByLife,
AttackToken,
PuppetAttack,
NoSkipAttack,
EvoToken,
HealDamage,
HealBuff,
HealToken,
HealHeal,
HealEvo,
TurnEndMetamorphose,
LastwordBuff,
FirstEvo,
LeaveHeal,
LeaveDamage,
LeaveBanish,
GiveSkill,
BreakHeal,
BuffDamage,
BuffDestroy,
BuffShield,
BounceDamage,
FanfareDamage,
PlayBuff,
FanfareBuff,
FanfareDestroy,
FanfareBounce,
FanfareRecoverAttackableCount,
FanfareSneak,
PlaySneak,
FanfareQuick,
PlayQuick,
FanfareRush,
PlayRush,
FanfareGuard,
PlayGuard,
FanfareDrain,
PlayDrain,
FanfareKiller,
PlayKiller,
FanfareHandBuff,
PlayHandBuff,
FanfareUntouchable,
PlayUntouchable,
FanfareForceTargeting,
ResonanceDamage,
ResonanceHeal,
ResonanceKiller,
BuffToken,
PlaySelect,
FanfareSelect,
PlayHandSelect,
FanfareHandSelect,
PlayRemoveSkill,
FanfareRemoveSkill,
PlayReanimate,
FanfareReanimate,
PlayMetamorphose,
FanfareMetamorphose,
PlayHandMetamorphose,
FanfareHandMetamorphose,
PlaySetMaxStatus,
FanfareSetMaxStatus,
PlaySetLeaderMaxLife,
FanfareBonusInSimulation,
PlayBonusInSimulation,
DamagedBonus,
DamagedBuff,
DamagedDamage,
DamagedToken,
DamagedHeal,
DamagedCantUnderAttack,
OtherDamagedDamage,
OtherDamagedHeal,
OtherDamagedSetLeaderMaxLife,
OtherDamagedSubtractCountdown,
OtherDamagedBanish,
LastwordDestroy,
BreakDamage,
LastwordDamage,
LastwordHeal,
LastwordMetamorphose,
LastwordBanish,
LastwordDraw,
LastwordAddDeck,
LastwordSetStatus,
AttackDamage,
AttackEvo,
AttackBreakDamage,
AttackBreakEvo,
AttackBreakRecoverPp,
AttackBreakAttackTwice,
AfterAttackHeal,
ClashDamage,
AfterClashDamage,
BreakFirst,
BreakLast,
BreakRecoverAttackableCount,
ClashKiller,
AttackKiller,
EvolvedAttackable,
EvolvedAttackableCount,
EvolvedSkill,
EvoDestroy,
EvoBuff,
EvoHeal,
EvoBanish,
EvoSubtractCountdown,
EvoRecoverPp,
EvoSetLeaderMaxLife,
EvoDiscard,
EvoMetamorphose,
EvoHandMetamorphose,
EvoBounce,
EvoRush,
EvoQuick,
EvoGuard,
EvoKiller,
EvoDrain,
EvoAttackableCount,
EvoChangeCost,
EvoHandSelect,
EvoShield,
EvoDamageCut,
EvoReanimate,
EvoAddDeck,
ClashRemoveSkill,
ClashRemoveTag,
AttackRemoveSkill,
CantAttack,
ForceAttackUnit,
OtherAttackBuff,
OtherAttackDamage,
OtherAttackHeal,
OtherAttackToken,
OtherAttackAttachTag,
OtherAttackRemoveTag,
OtherEvoBuff,
OtherEvoDamage,
OtherEvoBanish,
OtherEvoSubtractCountdown,
OtherEvoEvo,
OtherEvoToken,
OtherEvoShield,
SelfAndOtherEvoDamage,
SelfAndOtherEvoAttachTag,
SelfAndOtherEvoShield,
SelfAndOtherEvoDestroy,
SelfAndOtherEvoBounce,
SelfAndOtherEvoToken,
SelfAndOtherEvoDraw,
SelfAndOtherEvoAddCemetery,
SelfAndOtherEvoHeal,
SelfAndOtherEvoTokenDraw,
BattleBonus,
BattleBonusRate,
HandPlus,
Break,
OtherBreakBonus,
OtherBanishBonus,
OtherLeaveBonus,
MemberBattleBonus,
MemberBattleBonusRate,
EnemyBattleBonus,
EnemyBattleBonusRate,
BounceBonus,
BanishBonus,
RemoveSkill,
OneMoreLastword,
BreakDestroy,
ModifyHeal,
LeaveBonus,
ForceBerserk,
BanishAttachTag,
OtherBanishToken,
OtherBanishAddCemetery,
MulliganKeep,
MulliganChange,
Necromance,
EarthRite,
BurialRite,
Enhance,
Accelerate,
Crystalize,
ChoiceTransform,
LastwordReanimate,
ReanimateBonus,
ReanimateEvo,
PlayRecoverPP,
FanfareRecoverPp,
BuffRecoverPP,
BreakRecoverPp,
CondChoice,
EvoChoice,
PlayChoice,
FanfareChoice,
ChoiceBrave,
AttachTag_Start,
AttackAttachTag,
LastwordAttachTag,
EvoAttachTag,
SummonAttachTag,
OtherSummonAttachTag,
BreakAttachTag,
NecromanceAttachTag,
TurnStartAttachTag,
TurnEndAttachTag,
HealAttachTag,
FusionAttachTag,
PlayAttachTag,
OtherPlayAttachTag,
FanfareAttachTag,
ChangeInplayAttachTag,
FanfareAttachStyle,
AttachTag_End,
TurnEndRemoveTag,
PlayCopyTag,
FanfareCopyTag,
LeaveToken,
EvoTokenDraw,
PlayTokenDraw,
FanfareTokenDraw,
PlaySummonHandCard,
FanfareSummonHandCard,
PlayDiscard,
FanfareDiscard,
DiscardedBonus,
DiscardedToken,
DiscardDamage,
DiscardHeal,
AllyDiscardBonus,
EmoteOnPlay,
EmoteOnEvo,
EmoteOnAtk,
EmoteOnDestroy,
ForceEmoteOnDestroy,
EmoteOnTurnEnd,
PlagueCity,
Fusion,
FusionBonus,
FusionDraw,
BuffRush,
BuffHeal,
BuffBuff,
BuffEvo,
BuffDraw,
GetOn,
GetOnBanish,
GetOnDamage,
GetOnEvo,
GetOffMetamorphose,
GetOffEvo,
RallyCountPlus,
PlayActivateCount,
AttackActivateCount,
BreakActivateCount,
BanishActivateCount,
DamagedActivateCount,
BuffActivateCounnt,
TurnEndActivateCount,
HealActivateCount,
NecromanceActivateCount,
EvoActivateCount,
SummonActivateCount,
SetAITribe,
FanfareSpellboost,
PlaySpellboost,
FanfareAddCemetery,
PlayAddCemetery,
NecromanceAddCemetery,
NecromanceDamage,
NecromanceHeal,
PlayBanAttack,
FanfareBanAttack,
PlayIgnoreGuard,
FanfareIgnoreGuard,
GenerateTag,
PlayChangeClass,
FanfareChangeClass,
PlayChangeTribe,
FanfareChangeTribe,
PlayChangeCost,
FanfareChangeCost,
RemoveByDestroy,
PlayNotBeAttacked,
FanfareNotBeAttacked,
PlayAttackableCount,
FanfareAttackableCount,
Stack,
BreakAddStack,
EvoAddStack,
ChangeInplayImmediateRemoveByBanish,
ChangeInplayImmediateRemoveByDestroy,
ChangeInplayCannotPlay,
ChangeInplayCannotAttack,
ChangeInplayImmediateShield,
ChangeInplayImmediateDamageCut,
ChangeInplayImmediateDamageClip,
ChangeInplayImmediateLifeLowerLimit,
ChangeInplayImmediateDamageModifier,
ChangeInplayImmediateUntouchable,
ChangeInplayImmediateIndestructible,
ChangePpTotalBuff,
EvoSetStatus,
PlayModifyConsumeEp,
FanfareModifyConsumeEp,
PlayEvo,
FanfareEvo,
OtherPlayEvo,
OtherEnhanceEvo,
OtherPlayDamage,
OtherPlayRecoverPp,
OtherPlayDestroy,
OtherPlayBuff,
OtherPlayToken,
OtherPlayRemoveTag,
OtherPlayBounce,
OtherPlayQuick,
OtherLeaveDamage,
OtherLeaveToken,
AttackSubtractCountdown,
EvolveToOther,
LastwordEvo,
LastwordRemoveSkill,
LastwordAddCemetery,
LastwordDamageClip,
LastwordShield,
TurnStartSubtractCountdown,
TurnStartDamageCut,
TurnStartShield,
TurnStartDamage,
PlayShield,
FanfareShield,
AttackShield,
ClashShield,
PlayDamageCut,
FanfareDamageCut,
PlayDamageClip,
FanfareDamageClip,
AttackDamageClip,
ClashDamageClip,
BuffBonus,
FanfareRemoveGuard,
ForceImmediateAttack,
FusionMetamorphose,
LastwordSubtractCountdown,
LeaveAttachTag,
PlayAddDeck,
FanfareAddDeck,
AttackAddDeck,
None
}

View File

@@ -0,0 +1,192 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public class AIPlayedCardContainer
{
private List<AIVirtualCard> _allyTurnPlayedCardList;
private List<AIVirtualCard> _allyInGamePlayedCardList;
private List<AIVirtualCard> _allyPreviousTurnPlayedCardList;
private List<AIVirtualCard> _enemyTurnPlayedCardList;
private List<AIVirtualCard> _enemyInGamePlayedCardList;
private List<AIVirtualCard> _enemyPreviousTurnPlayedCardList;
public int AllyTurnPlayedCardCount => _allyTurnPlayedCardList.Count;
public int AllyInGamePlayedCardCount => _allyInGamePlayedCardList.Count;
public AIPlayedCardContainer()
{
_allyTurnPlayedCardList = new List<AIVirtualCard>();
_allyInGamePlayedCardList = new List<AIVirtualCard>();
_allyPreviousTurnPlayedCardList = new List<AIVirtualCard>();
_enemyTurnPlayedCardList = new List<AIVirtualCard>();
_enemyInGamePlayedCardList = new List<AIVirtualCard>();
_enemyPreviousTurnPlayedCardList = new List<AIVirtualCard>();
}
public AIPlayedCardContainer(AIPlayedCardContainer source)
{
_allyTurnPlayedCardList = new List<AIVirtualCard>(source._allyTurnPlayedCardList);
_allyInGamePlayedCardList = new List<AIVirtualCard>(source._allyInGamePlayedCardList);
_allyPreviousTurnPlayedCardList = new List<AIVirtualCard>(source._allyPreviousTurnPlayedCardList);
_enemyTurnPlayedCardList = new List<AIVirtualCard>(source._enemyTurnPlayedCardList);
_enemyInGamePlayedCardList = new List<AIVirtualCard>(source._enemyInGamePlayedCardList);
_enemyPreviousTurnPlayedCardList = new List<AIVirtualCard>(source._enemyPreviousTurnPlayedCardList);
}
public AIPlayedCardContainer Clone()
{
return new AIPlayedCardContainer(this);
}
public void Validate(AIPlayedCardContainer source)
{
}
private void CopyPreviousPlayCardOnTurnShift(AIVirtualTurnStartInfo turnStartSituation)
{
if (turnStartSituation != null)
{
if (turnStartSituation.Actor.IsAlly)
{
_enemyPreviousTurnPlayedCardList = new List<AIVirtualCard>(_enemyTurnPlayedCardList);
}
else
{
_allyPreviousTurnPlayedCardList = new List<AIVirtualCard>(_allyTurnPlayedCardList);
}
}
}
public void ClearInTurn(AIVirtualTurnStartInfo turnStartSituation = null)
{
CopyPreviousPlayCardOnTurnShift(turnStartSituation);
_allyTurnPlayedCardList.Clear();
_enemyTurnPlayedCardList.Clear();
}
public void ClearAll()
{
ClearInTurn();
_allyInGamePlayedCardList.Clear();
_enemyInGamePlayedCardList.Clear();
_allyPreviousTurnPlayedCardList.Clear();
_enemyPreviousTurnPlayedCardList.Clear();
}
public int GetPlayedCountInTurn(List<AIScriptTokenBase> filters, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
{
return AIFilteringUtility.MultipleFiltering(tagOwner.IsAlly ? _allyTurnPlayedCardList : _enemyTurnPlayedCardList, filters, tagOwner, playPtn, situation, isBlockDeadCard: false)?.Count ?? 0;
}
public int GetPlayedCountInPreviousTurn(bool isAllyList, List<AIScriptTokenBase> filters, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
{
return AIFilteringUtility.MultipleFiltering(isAllyList ? _allyPreviousTurnPlayedCardList : _enemyPreviousTurnPlayedCardList, filters, tagOwner, playPtn, situation, isBlockDeadCard: false)?.Count ?? 0;
}
public int GetAllPlayedCountInTurn(bool isAITurn)
{
return (isAITurn ? _allyTurnPlayedCardList : _enemyTurnPlayedCardList)?.Count ?? 0;
}
public int GetPlayedCountInGame(List<AIScriptTokenBase> filters, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
{
int num = 0;
num = ((!AIPlayPtnUtility.IsInPlayPtn(tagOwner, playPtn)) ? (num + AIPlayPtnUtility.GetPlayPtnCardCount(filters, tagOwner, playPtn, situation)) : (num + AIPlayPtnUtility.GetBeforePlayPtnCount(filters, tagOwner, playPtn, situation)));
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(tagOwner.IsAlly ? _allyInGamePlayedCardList : _enemyInGamePlayedCardList, filters, tagOwner, playPtn, situation, isBlockDeadCard: false);
if (list != null)
{
num += list.Count;
}
return num;
}
public int GetPlayedNameCount(List<AIScriptTokenBase> filters, AIScriptTokenArgType turnOrGame, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> list = null;
switch (turnOrGame)
{
case AIScriptTokenArgType.TURN:
list = (tagOwner.IsAlly ? _allyTurnPlayedCardList : _enemyTurnPlayedCardList);
break;
case AIScriptTokenArgType.GAME:
list = (tagOwner.IsAlly ? _allyInGamePlayedCardList : _enemyInGamePlayedCardList);
break;
default:
AIConsoleUtility.LogError($"GetPlayedNameCount() error!! turnOrGame == {turnOrGame}");
return 0;
}
if (list == null || list.Count <= 0)
{
return 0;
}
return AIFilteringUtility.GetCardNameCountFromList(list, filters, tagOwner, playPtn, situation);
}
public bool IsPlayedAsAccelerate(AIVirtualCard card)
{
CardParameter baseParameter = card.BaseCard.BaseParameter;
if (!card.IsSpell || baseParameter.BaseCardId == baseParameter.ResourceCardId || !IsPlayedCard(card))
{
return false;
}
CardParameter cardParameterFromId = CardMaster.GetInstanceForBattle().GetCardParameterFromId(baseParameter.ResourceCardId);
if (cardParameterFromId == null)
{
return false;
}
if (cardParameterFromId.Cost > baseParameter.Cost && cardParameterFromId.CharType == CardBasePrm.CharaType.NORMAL)
{
return true;
}
return false;
}
public bool IsPlayedAsCrystalize(AIVirtualCard card)
{
if (!IsPlayedCard(card) || !card.IsAmulet)
{
return false;
}
if (card.BaseCard.TransformInfo.Type != BattleCardBase.TransformType.Crystallize)
{
return false;
}
return true;
}
public bool IsPlayedCard(AIVirtualCard card)
{
return (card.IsAlly ? _allyInGamePlayedCardList : _enemyInGamePlayedCardList).Any((AIVirtualCard c) => c.IsSameCard(card));
}
public void AddPlayedCard(AIVirtualCard card)
{
if (!IsPlayedCard(card))
{
List<AIVirtualCard> container = (card.IsAlly ? _allyTurnPlayedCardList : _enemyTurnPlayedCardList);
AIParamQuery.AddElementToList(card, container);
List<AIVirtualCard> container2 = (card.IsAlly ? _allyInGamePlayedCardList : _enemyInGamePlayedCardList);
AIParamQuery.AddElementToList(card, container2);
}
}
public void RollBackFromOneRecord(AIVirtualFieldRollBackRecord.PlayedCardContainerRecord rollBackRecord)
{
for (int num = _allyTurnPlayedCardList.Count - 1; num >= rollBackRecord.AllyTurnPlayedCardCount; num--)
{
_allyTurnPlayedCardList.RemoveAt(num);
}
for (int num2 = _allyInGamePlayedCardList.Count - 1; num2 >= rollBackRecord.AllyInGamePlayedCardCount; num2--)
{
_allyInGamePlayedCardList.RemoveAt(num2);
}
}
}

View File

@@ -0,0 +1,433 @@
using System.Collections.Generic;
using UnityEngine;
namespace Wizard;
public class AIPlayptnRecorder
{
private List<AISinglePlayptnRecord> _allPlayPtnList;
private List<AIVirtualField> _referenceFieldList;
private bool _isRegisteringPlayPtn;
private bool _isCalculatingPriority;
public List<AISinglePlayptnRecord> ValidPlayPtnList { get; private set; }
public AIPlayptnRecorder()
{
ValidPlayPtnList = new List<AISinglePlayptnRecord>();
_allPlayPtnList = new List<AISinglePlayptnRecord>();
_referenceFieldList = new List<AIVirtualField>();
_isRegisteringPlayPtn = false;
}
public static void BuildSinglePlayptnRecord(List<int> playPtn, AISinglePlayptnRecord currentRecord, AIVirtualField field, AIVirtualFieldRollBackBasicProcessor rollBackProcessor)
{
List<int> list = new List<int>();
int num = 0;
for (int i = 0; i < currentRecord.PlayedCardList.Count; i++)
{
if (!currentRecord.PlayedCardList[i].IsProcessed)
{
num = i;
break;
}
list.Add(playPtn[i]);
}
for (int j = num; j < playPtn.Count; j++)
{
int num2 = playPtn[j];
list.Add(num2);
PlayedCardInfo playedCardInfo = currentRecord.PlayedCardList[j];
AIVirtualCard aIVirtualCard = field.AllyHandCards[num2];
AIVirtualTargetSelectAction aIVirtualTargetSelectAction = new AIVirtualTargetSelectAction(aIVirtualCard, aIVirtualCard, AIOperationType.PLAY);
PlaySimulationType playType;
int num3 = (playedCardInfo.UsedCost = aIVirtualCard.GetUseCost(currentRecord.LastRestPp, list, aIVirtualTargetSelectAction, out playType));
if (num3 >= 0)
{
int num4 = currentRecord.LastRestPp - num3;
playedCardInfo.PlayType = playType;
num4 += AIEvaluateBonusFromOhterUtility.GetTotalRecoverPp(aIVirtualCard, playPtn, aIVirtualTargetSelectAction);
playedCardInfo.RestPp = num4;
playedCardInfo.DrawCount = aIVirtualCard.GetPlayDrawCount(list, aIVirtualTargetSelectAction);
SetTransformCardToPlayedInfo(playedCardInfo, aIVirtualCard, field, list, aIVirtualTargetSelectAction, num3, playType);
}
else
{
playedCardInfo.RestPp = -1;
playedCardInfo.PlayType = PlaySimulationType.Undefined;
}
if (num == 0)
{
playedCardInfo.IsPassedPlayCondition = aIVirtualCard.BaseCard.BaseMovable;
}
else
{
playedCardInfo.IsPassedPlayCondition = true;
}
currentRecord.UpdatePlayPtnRecord(playedCardInfo);
if (!currentRecord.IsValid)
{
break;
}
AIPreprocessSimulationUtility.SimulatePreprocess(aIVirtualTargetSelectAction.Actor, aIVirtualTargetSelectAction, field, AIScriptTokenArgType.WHEN_PLAY, isPseudo: true);
currentRecord.RegisterPreprocess(playedCardInfo, aIVirtualTargetSelectAction, field);
PseudoExecuteCardPlayProcess(field, currentRecord, playedCardInfo, aIVirtualTargetSelectAction);
}
rollBackProcessor.ResetVirtualFieldToStart();
}
public void CreateValidPlayPtnList(AIVirtualField field)
{
AIVirtualFieldRollBackBasicProcessor rollBackProcessor = new AIVirtualFieldRollBackBasicProcessor(field);
int fieldIndex = RegisterFieldAndGetFieldIndex(field);
List<Tuple<int, List<int>>> list = AIHandPtnCalculator.CreateSortedPlayPtnList(field.AI);
_isRegisteringPlayPtn = true;
for (int i = 0; i < list.Count; i++)
{
AISinglePlayptnRecord aISinglePlayptnRecord = new AISinglePlayptnRecord(list[i].second, field, fieldIndex);
_allPlayPtnList.Add(aISinglePlayptnRecord);
ProcessPlayPtnRecord(aISinglePlayptnRecord, field, rollBackProcessor);
}
_isRegisteringPlayPtn = false;
}
private void ProcessPlayPtnRecord(AISinglePlayptnRecord currentRecord, AIVirtualField field, AIVirtualFieldRollBackBasicProcessor rollBackProcessor)
{
List<int> playPtn = currentRecord.PlayPtn;
AISinglePlayptnRecord aISinglePlayptnRecord = FindMostlyMatchedPlayPtn(currentRecord);
if (aISinglePlayptnRecord != null)
{
if (!aISinglePlayptnRecord.IsValid)
{
_allPlayPtnList.Remove(currentRecord);
return;
}
currentRecord = RegisterMatchedRecordToNewRecord(aISinglePlayptnRecord, field, currentRecord);
}
if (!currentRecord.IsValid)
{
rollBackProcessor.ResetVirtualFieldToStart();
return;
}
BuildSinglePlayptnRecord(playPtn, currentRecord, field, rollBackProcessor);
if (currentRecord.IsToBeRegister() && currentRecord.IsValid && !CheckSimilarValidPlayPtnRecord(currentRecord.PlayPtnHash))
{
ValidPlayPtnList.Add(currentRecord);
}
}
public AISinglePlayptnRecord FindMatchedPlayPtnRecord(List<int> playPtn, AIVirtualField playPtnField)
{
ulong hash = playPtnField.GetHash();
int num = GetFieldIndex(hash);
for (int i = 0; i < _allPlayPtnList.Count; i++)
{
AISinglePlayptnRecord aISinglePlayptnRecord = _allPlayPtnList[i];
if (aISinglePlayptnRecord.PlayPtn.Count != playPtn.Count || num != aISinglePlayptnRecord.ReferenceFieldIndex)
{
continue;
}
bool flag = true;
for (int j = 0; j < playPtn.Count; j++)
{
if (!playPtnField.AllyHandCards[playPtn[j]].IsSameCard(aISinglePlayptnRecord.PlayedCardList[j].Card))
{
flag = false;
break;
}
}
if (flag)
{
return aISinglePlayptnRecord;
}
}
if (_isRegisteringPlayPtn)
{
AIConsoleUtility.LogError("FindMatchedPlayPtnRecordで無限ループが発生しそうです");
return null;
}
_isRegisteringPlayPtn = true;
if (num < 0)
{
_referenceFieldList.Add(playPtnField);
num = _referenceFieldList.Count - 1;
}
AISinglePlayptnRecord aISinglePlayptnRecord2 = new AISinglePlayptnRecord(playPtn, playPtnField, num);
_allPlayPtnList.Add(aISinglePlayptnRecord2);
AIVirtualFieldRollBackBasicProcessor rollBackProcessor = new AIVirtualFieldRollBackBasicProcessor(playPtnField);
ProcessPlayPtnRecord(aISinglePlayptnRecord2, playPtnField, rollBackProcessor);
_isRegisteringPlayPtn = false;
return aISinglePlayptnRecord2;
}
public void StartCalculatingPriority()
{
_isCalculatingPriority = true;
}
public void StopCalculatingPriority()
{
_isCalculatingPriority = false;
}
public int GetRestPp(List<int> playPtn, AIVirtualField field)
{
if (_isCalculatingPriority)
{
AIConsoleUtility.LogWarning("AIPlayptnRecorder.GetRestPp() warning!! Calling GetRestPp() during calculating priority!!!!!");
return 0;
}
int allyPp = field.AllyPp;
if (playPtn == null || playPtn.Count <= 0)
{
return allyPp;
}
AISinglePlayptnRecord playptnRecordOnSim = field.GetPlayptnRecordOnSim(playPtn);
if (playptnRecordOnSim == null)
{
return allyPp;
}
allyPp = playptnRecordOnSim.LastRestPp;
return Mathf.Max(0, allyPp);
}
public int GetFixedCostWithCheckingPlayType(AIVirtualCard card, AIVirtualField field, List<int> playPtn, out PlaySimulationType playType)
{
int restPp = (card.IsAlly ? field.AllyPp : field.EnemyPp);
if (playPtn == null || playPtn.Count <= 0 || !card.IsAlly)
{
return card.GetUseCost(restPp, playPtn, null, out playType);
}
int cardPlayPtnIndex = GetCardPlayPtnIndex(card, field, playPtn);
if (cardPlayPtnIndex == -1)
{
return card.GetUseCost(restPp, playPtn, null, out playType);
}
return GetCardCostAndTypeFromPlayPtnRecord(card, cardPlayPtnIndex, field, playPtn, out playType);
}
public bool IsCardPlayingSimulationType(AIVirtualCard card, AIVirtualField field, List<int> playPtn, AISituationInfo situation, PlaySimulationType targetPlayType)
{
List<int> list = (card.IsAlly ? playPtn : null);
int restPp = (card.IsAlly ? field.AllyPp : field.EnemyPp);
int num = -1;
if (card.IsAlly && list != null && list.Count > 0)
{
num = field.AI.PlayPtnRecorder.GetCardPlayPtnIndex(card, field, list);
}
if (num != -1)
{
field.AI.PlayPtnRecorder.GetCardCostAndTypeFromPlayPtnRecord(card, num, field, list, out var playType);
return playType == targetPlayType;
}
return card.IsPlayingSimulationType(restPp, playPtn, situation, targetPlayType);
}
public int GetCardPlaySimulationTypeCost(AIVirtualCard card, AIVirtualField field, List<int> playPtn, AISituationInfo situation, PlaySimulationType targetPlayType)
{
List<int> list = (card.IsAlly ? playPtn : null);
int restPp = (card.IsAlly ? field.AllyPp : field.EnemyPp);
int num = -1;
if (card.IsAlly && list != null && list.Count > 0)
{
num = field.AI.PlayPtnRecorder.GetCardPlayPtnIndex(card, field, list);
}
if (num != -1)
{
PlaySimulationType playType;
int cardCostAndTypeFromPlayPtnRecord = field.AI.PlayPtnRecorder.GetCardCostAndTypeFromPlayPtnRecord(card, num, field, list, out playType);
if (playType != targetPlayType)
{
return -1;
}
return cardCostAndTypeFromPlayPtnRecord;
}
return card.GetPlaySimulationTypeCost(restPp, playPtn, situation, targetPlayType);
}
public int GetCardPlayPtnIndex(AIVirtualCard card, AIVirtualField field, List<int> playPtn)
{
int item = -1;
for (int i = 0; i < field.AllyHandCards.Count; i++)
{
if (field.AllyHandCards[i].IsSameCard(card))
{
item = i;
break;
}
}
int num = playPtn.IndexOf(item);
if (num < 0)
{
AIConsoleUtility.LogError("AIPlayPtnRecorder.GetFixedCostWithCheckingPlayType() error!! card is not in playPtn!!!!!");
}
return num;
}
public int GetCardCostAndTypeFromPlayPtnRecord(AIVirtualCard card, int playPtnIndex, AIVirtualField field, List<int> playPtn, out PlaySimulationType playType)
{
AISinglePlayptnRecord aISinglePlayptnRecord = FindMatchedPlayPtnRecord(playPtn, field);
playType = PlaySimulationType.Undefined;
if (aISinglePlayptnRecord != null)
{
PlayedCardInfo playedCardInfo = aISinglePlayptnRecord.PlayedCardList[playPtnIndex];
if (playedCardInfo.Card.IsSameCard(card))
{
playType = playedCardInfo.PlayType;
return playedCardInfo.UsedCost;
}
AIConsoleUtility.LogError("AIPlayPtnRecorder.GetCardCostAndTypeInPlayPtnRecord() error!! Cannot find same card from matched playPtn record!!!!!");
return -1;
}
AIConsoleUtility.LogError("AIPlayPtnRecorder.GetCardCostAndTypeInPlayPtnRecord() error!! Cannot find record!!!!!");
return -1;
}
private AISinglePlayptnRecord RegisterMatchedRecordToNewRecord(AISinglePlayptnRecord matched, AIVirtualField field, AISinglePlayptnRecord newRecord)
{
for (int i = 0; i < matched.PlayedCardList.Count; i++)
{
PlayedCardInfo playedCardInfo = newRecord.PlayedCardList[i];
playedCardInfo.CloneFromPartlyMatchedInfo(matched.PlayedCardList[i]);
AIVirtualCard card = playedCardInfo.Card;
AIVirtualCard obj = ((playedCardInfo.TransformCard == null) ? card : playedCardInfo.TransformCard);
AIVirtualTargetSelectAction situation = new AIVirtualTargetSelectAction(obj, card, AIOperationType.PLAY);
AIPreprocessSimulationUtility.SimulatePreprocess(obj, situation, field, AIScriptTokenArgType.WHEN_PLAY, isPseudo: true);
newRecord.RegisterPreprocess(playedCardInfo, situation, field);
newRecord.UpdatePlayPtnRecord(playedCardInfo);
PseudoExecuteCardPlayProcess(field, newRecord, playedCardInfo, situation);
if (!newRecord.IsValid)
{
break;
}
}
return newRecord;
}
private AISinglePlayptnRecord FindMostlyMatchedPlayPtn(AISinglePlayptnRecord record)
{
AISinglePlayptnRecord result = null;
int num = 0;
List<int> playPtn = record.PlayPtn;
for (int i = 0; i < _allPlayPtnList.Count; i++)
{
AISinglePlayptnRecord aISinglePlayptnRecord = _allPlayPtnList[i];
int count = aISinglePlayptnRecord.PlayPtn.Count;
if (record.ReferenceFieldIndex == aISinglePlayptnRecord.ReferenceFieldIndex && playPtn.Count > count && aISinglePlayptnRecord.IsMatchedPattern(playPtn) && count > num)
{
num = count;
result = aISinglePlayptnRecord;
}
}
return result;
}
private static void SetTransformCardToPlayedInfo(PlayedCardInfo info, AIVirtualCard playedCard, AIVirtualField field, List<int> playPtn, AIVirtualTargetSelectAction situation, int usedCost, PlaySimulationType type)
{
if (AIPlayCardSimulationUtility.SetRealActorToPlaySituation(situation, field, usedCost, type))
{
info.SetTransformCard(situation.Actor);
}
}
private static void PseudoExecuteCardPlayProcess(AIVirtualField field, AISinglePlayptnRecord record, PlayedCardInfo playedCardInfo, AIVirtualTargetSelectAction situation)
{
AIVirtualCard card = playedCardInfo.Card;
if (card.IsSpell || card.IsAccelerated(field, null, situation))
{
AIPlayCardSimulationUtility.UpdateFieldWhenEvaluateSpellCard(card, field);
}
if (card.IsUnit)
{
record.FirstSummonedAllyFollower = card;
}
field.PlayedCardContainer.AddPlayedCard(card);
card.PseudoExecuteWhenPlayTags(field, record, playedCardInfo, situation);
field.AllActivateCountHolderIncrement(situation, AIPlayTagType.PlayActivateCount, card);
field.IsNoInstantAttackRecheck();
}
private bool CheckSimilarValidPlayPtnRecord(ulong currentRecordHash)
{
for (int i = 0; i < ValidPlayPtnList.Count; i++)
{
if (ValidPlayPtnList[i].PlayPtnHash == currentRecordHash)
{
return true;
}
}
return false;
}
private int RegisterFieldAndGetFieldIndex(AIVirtualField field)
{
ulong hash = field.GetHash();
for (int i = 0; i < _referenceFieldList.Count; i++)
{
if (_referenceFieldList[i].GetHash() == hash)
{
return i;
}
}
_referenceFieldList.Add(field);
return _referenceFieldList.Count - 1;
}
private int GetFieldIndex(ulong fieldHash)
{
for (int i = 0; i < _referenceFieldList.Count; i++)
{
if (fieldHash == _referenceFieldList[i].GetHash())
{
return i;
}
}
return -1;
}
public AISinglePlayptnRecord GetEmptyPlayPtnRecord()
{
AISinglePlayptnRecord aISinglePlayptnRecord = ValidPlayPtnList[0];
if (aISinglePlayptnRecord.PlayedCardList.Count > 0)
{
AIConsoleUtility.LogError("AIPlayPtnRecorder.GetEmptyPlayPtnRecord() error!! first record is not empty!!!!!");
}
return aISinglePlayptnRecord;
}
public AISinglePlayptnRecord CreateRecordForNextPlayTargetSelectSimulation(AIVirtualTargetSelectAction action, AISinglePlayptnRecord previousRecord, AIVirtualField field)
{
bool num = action.ActionType == AIOperationType.PLAY;
int fieldIndex = RegisterFieldAndGetFieldIndex(field);
List<int> list = new List<int>();
for (int i = (num ? 1 : 0); i < previousRecord.PlayedCardList.Count; i++)
{
AIVirtualCard card = previousRecord.PlayedCardList[i].Card;
AIVirtualCard aIVirtualCard = field.SearchVirtualCard(card);
if (aIVirtualCard == null)
{
AIConsoleUtility.LogError("AIPlayptnRecorder.CreateRecordForNextPlayTargetSelectSimulation() error!! Cannot find play card!!!!!");
}
else if (aIVirtualCard.IsInHand)
{
int num2 = field.AllyHandCards.IndexOf(aIVirtualCard);
if (num2 < 0 || field.AllyHandCards.Count <= num2)
{
AIConsoleUtility.LogError($"CreateRecordForNextPlayTargetSelectSimulation() error!! handIndex: {num2}, CardName: {aIVirtualCard.CardName}");
return null;
}
list.Add(num2);
}
}
AISinglePlayptnRecord aISinglePlayptnRecord = new AISinglePlayptnRecord(list, field, fieldIndex);
_isRegisteringPlayPtn = true;
_allPlayPtnList.Add(aISinglePlayptnRecord);
AIVirtualFieldRollBackBasicProcessor rollBackProcessor = new AIVirtualFieldRollBackBasicProcessor(field);
ProcessPlayPtnRecord(aISinglePlayptnRecord, field, rollBackProcessor);
_isRegisteringPlayPtn = false;
return aISinglePlayptnRecord;
}
}

View File

@@ -0,0 +1,42 @@
using System.Collections.Generic;
namespace Wizard;
public class AIPolicyCollection
{
public List<AIPolicyData> PolicyList { get; protected set; }
public bool HasPolicy
{
get
{
if (PolicyList != null)
{
return 0 < PolicyList.Count;
}
return false;
}
}
public AIPolicyCollection()
{
PolicyList = null;
}
public void AddPolicy(AIPolicyData policy)
{
if (PolicyList == null)
{
PolicyList = new List<AIPolicyData>();
}
PolicyList.Add(policy);
}
public void RemovePolicy(AIPolicyData policy)
{
if (PolicyList.Contains(policy))
{
PolicyList.Remove(policy);
}
}
}

View File

@@ -0,0 +1,113 @@
using System.Collections.Generic;
namespace Wizard;
public class AIPolicyCollectionContainer
{
private List<AIPolicyType> _holdingPolicyTypes;
private List<PolicyCollectionWithTypeBase> _policyCollectionTable;
public AIPolicyCollectionContainer()
{
_holdingPolicyTypes = null;
_policyCollectionTable = null;
}
public bool HasPolicy(AIPolicyType policyType)
{
if (_holdingPolicyTypes != null)
{
return _holdingPolicyTypes.Contains(policyType);
}
return false;
}
public AIPolicyCollection GetPolicyCollection(AIPolicyType policyType)
{
if (_policyCollectionTable != null)
{
for (int i = 0; i < _policyCollectionTable.Count; i++)
{
PolicyCollectionWithTypeBase policyCollectionWithTypeBase = _policyCollectionTable[i];
if (policyCollectionWithTypeBase.HasTag(policyType))
{
return policyCollectionWithTypeBase.PolicyCollection;
}
}
}
return null;
}
public void InitializeAllCollections(List<AIPolicyData> policyList)
{
for (int i = 0; i < policyList.Count; i++)
{
AIPolicyData policy = policyList[i];
RegisterNewPolicy(policy);
}
}
public void RegisterNewPolicy(AIPolicyData policy)
{
PolicyCollectionWithTypeBase policyCollectionWithTypeBase = FindPolicyCollectionWityType(policy.PolicyType);
if (policyCollectionWithTypeBase != null)
{
policyCollectionWithTypeBase.AddPolicy(policy);
if (_holdingPolicyTypes == null)
{
_holdingPolicyTypes = new List<AIPolicyType>();
}
if (!_holdingPolicyTypes.Contains(policy.PolicyType))
{
_holdingPolicyTypes.Add(policy.PolicyType);
}
}
}
public void RemoveAttachedPolicies(List<AIPolicyData> attachedPolicies)
{
for (int i = 0; i < attachedPolicies.Count; i++)
{
AIPolicyData aIPolicyData = attachedPolicies[i];
PolicyCollectionWithTypeBase policyCollectionWithTypeBase = FindPolicyCollectionWityType(aIPolicyData.PolicyType, isCreateNewCollection: false);
if (policyCollectionWithTypeBase != null && policyCollectionWithTypeBase.RemovePolicyAndCheckIsNoLongerHoldThisType(aIPolicyData))
{
_holdingPolicyTypes.Remove(aIPolicyData.PolicyType);
if (policyCollectionWithTypeBase is PolicyCollectionWithSingleType)
{
_policyCollectionTable.Remove(policyCollectionWithTypeBase);
}
}
}
}
private PolicyCollectionWithTypeBase FindPolicyCollectionWityType(AIPolicyType policyType, bool isCreateNewCollection = true)
{
if (_policyCollectionTable != null)
{
for (int i = 0; i < _policyCollectionTable.Count; i++)
{
PolicyCollectionWithTypeBase policyCollectionWithTypeBase = _policyCollectionTable[i];
if (policyCollectionWithTypeBase.IsUnderManagement(policyType))
{
return policyCollectionWithTypeBase;
}
}
}
if (isCreateNewCollection)
{
PolicyCollectionWithTypeBase policyCollectionWithTypeBase2 = PolicyCollectionWithTypeCreator.Create(policyType);
if (policyCollectionWithTypeBase2 != null)
{
if (_policyCollectionTable == null)
{
_policyCollectionTable = new List<PolicyCollectionWithTypeBase>();
}
_policyCollectionTable.Add(policyCollectionWithTypeBase2);
}
return policyCollectionWithTypeBase2;
}
return null;
}
}

View File

@@ -0,0 +1,145 @@
using System.Collections.Generic;
namespace Wizard;
public class AIPolicyData
{
private AIConditionExpressions _conditionExpr;
public int ID { get; private set; }
public AICategory Category { get; private set; }
public int Priority { get; private set; }
public AIPolicyType PolicyType { get; private set; }
public string ARG { get; private set; }
public string CONDITION { get; private set; }
public AIScriptArgumentExpressions Argument { get; private set; }
public AIPolicyData(AIPolicyDataAsset asset)
{
ID = asset.ID;
Category = ConvertStringToCategory(asset.Category);
Priority = asset.Priority;
PolicyType = ConvertStringToPolicyType(asset.Type);
ARG = asset.Arg;
CONDITION = asset.Cond;
Argument = CreateArgument(asset.Arg);
_conditionExpr = new AIConditionExpressions(asset.Cond);
}
private AIScriptArgumentExpressions CreateArgument(string arg)
{
switch (PolicyType)
{
case AIPolicyType.PlayBreak:
return new AIPlayBreak(arg);
case AIPolicyType.EmoOnTurnEnd:
case AIPolicyType.EmoOnTurnStart:
case AIPolicyType.PlayerEmoOnTurnEnd:
return new AIEmoteOnTurnTransition(arg);
case AIPolicyType.AllyPlayBonus:
return new AIOtherPlayBonus(arg);
case AIPolicyType.AllyPlayBonusRate:
return new AIOtherPlayBonusRate(arg);
case AIPolicyType.DelayTurnEndTime:
return new AIDelayTurnEndTime(arg);
case AIPolicyType.MoveFirstBonus:
return new AIFirstMoveBonus(arg);
case AIPolicyType.GameStartAttachTag:
return new AIGameStartAttachTag(arg);
default:
return new AIScriptArgumentExpressions(arg);
}
}
public static AICategory ConvertStringToCategory(string str)
{
return str switch
{
"All" => AICategory.ALL,
"Elf" => AICategory.ELF,
"Royal" => AICategory.ROYAL,
"Witch" => AICategory.WITCH,
"Dragon" => AICategory.DRAGON,
"Necromance" => AICategory.NECROMANCE,
"Vampire" => AICategory.VAMPIRE,
"Bishop" => AICategory.BISHOP,
"Nemesis" => AICategory.NEMESIS,
_ => AICategory.ALL,
};
}
public static AIPolicyType ConvertStringToPolicyType(string str)
{
return str switch
{
"epValue" => AIPolicyType.EpValue,
"modUnitRate" => AIPolicyType.ModUnitRate,
"unitBonus" => AIPolicyType.UnitBonus,
"emoOnTurnEnd" => AIPolicyType.EmoOnTurnEnd,
"emoOnTurnStart" => AIPolicyType.EmoOnTurnStart,
"playptnBonus" => AIPolicyType.PlayptnBonus,
"playBreak" => AIPolicyType.PlayBreak,
"barrierBonus" => AIPolicyType.BarrierBonus,
"allyPlayB" => AIPolicyType.AllyPlayBonus,
"allyPlayBonusRate" => AIPolicyType.AllyPlayBonusRate,
"disableLethalCheck" => AIPolicyType.DisableLethalCheck,
"delayTurnEndTime" => AIPolicyType.DelayTurnEndTime,
"emoOnLeaderDamaged" => AIPolicyType.EmoOnLeaderDamaged,
"setReferenceId" => AIPolicyType.SetReferenceId,
"setReferenceTribe" => AIPolicyType.SetReferenceTribe,
"playerEmoOnTurnEnd" => AIPolicyType.PlayerEmoOnTurnEnd,
"playerEmoOnTurnStart" => AIPolicyType.PlayerEmoOnTurnStart,
"playerEmoOnLeaderDamaged" => AIPolicyType.PlayerEmoOnLeaderDamaged,
"moveFirstBonus" => AIPolicyType.MoveFirstBonus,
"gameStartAttachTag" => AIPolicyType.GameStartAttachTag,
_ => AIPolicyType.None,
};
}
public static AICategory ConvertClassIDToCategory(int id)
{
return id switch
{
1 => AICategory.ELF,
2 => AICategory.ROYAL,
3 => AICategory.WITCH,
4 => AICategory.DRAGON,
5 => AICategory.NECROMANCE,
6 => AICategory.VAMPIRE,
7 => AICategory.BISHOP,
8 => AICategory.NEMESIS,
_ => AICategory.ALL,
};
}
public bool CheckCondition(AIVirtualCard owner, List<int> playPtn, AIVirtualField field, AISituationInfo situation)
{
return _conditionExpr.CheckCondition(owner, playPtn, field, situation);
}
public float EvalArg(AIVirtualCard owner, List<int> playPtn, AIVirtualField field, AISituationInfo situation = null)
{
return Argument.EvalArg(0, owner, playPtn, field, situation);
}
public int EvalId(int index = 0)
{
return Argument.EvalID(index);
}
public List<int> EvalIdList(int startindex = 0)
{
return Argument.EvalIDList(startindex);
}
public string EvalText(int index = 0)
{
return Argument.EvalText(index);
}
}

View File

@@ -0,0 +1,37 @@
namespace Wizard;
public class AIPolicyDataAsset
{
public int ID { get; set; }
public string Category { get; set; }
public int Priority { get; set; }
public string Type { get; set; }
public string Arg { get; set; }
public string Cond { get; set; }
public AIPolicyDataAsset()
{
ID = -1;
Category = "";
Priority = 0;
Type = "";
Arg = "";
Cond = "";
}
public AIPolicyDataAsset(string[] columns)
{
int num = 0;
ID = AIScriptParser.ParseInt(columns[num++]);
Category = columns[num++];
Priority = AIScriptParser.ParseInt(columns[num++]);
Type = columns[num++];
Arg = columns[num++];
Cond = columns[num++];
}
}

View File

@@ -0,0 +1,26 @@
namespace Wizard;
public enum AIPolicyType
{
None,
EpValue,
ModUnitRate,
UnitBonus,
PlayptnBonus,
PlayBreak,
BarrierBonus,
AllyPlayBonus,
AllyPlayBonusRate,
DisableLethalCheck,
DelayTurnEndTime,
SetReferenceId,
SetReferenceTribe,
EmoOnTurnEnd,
EmoOnTurnStart,
EmoOnLeaderDamaged,
PlayerEmoOnTurnEnd,
PlayerEmoOnTurnStart,
PlayerEmoOnLeaderDamaged,
MoveFirstBonus,
GameStartAttachTag
}

View File

@@ -0,0 +1,324 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public class AIPolishConvertedExpression
{
private readonly AIScriptTokenFuncType[] EvalFuncList = new AIScriptTokenFuncType[22]
{
AIScriptTokenFuncType.EVAL_ALL_DAMAGE,
AIScriptTokenFuncType.EVAL_TARGETING_DAMAGE,
AIScriptTokenFuncType.EVAL_TARGETING_AND_RANDOM_MULTI_DAMAGE,
AIScriptTokenFuncType.EVAL_ALL_DESTROY,
AIScriptTokenFuncType.EVAL_ALL_BOUNCE,
AIScriptTokenFuncType.EVAL_TARGETING_BOUNCE,
AIScriptTokenFuncType.EVAL_TARGETING_BANISH,
AIScriptTokenFuncType.EVAL_RANDOM_BANISH,
AIScriptTokenFuncType.EVAL_ALL_BANISH,
AIScriptTokenFuncType.EVAL_ALL_METAMORPHOSE,
AIScriptTokenFuncType.EVAL_TARGETING_METAMORPHOSE,
AIScriptTokenFuncType.EVAL_ALL_BUFF,
AIScriptTokenFuncType.EVAL_RANDOM_BUFF,
AIScriptTokenFuncType.EVAL_TARGETING_DESTROY,
AIScriptTokenFuncType.EVAL_TARGETING_HEAL,
AIScriptTokenFuncType.EVAL_ALL_HEAL,
AIScriptTokenFuncType.EVAL_RANDOM_BOUNCE,
AIScriptTokenFuncType.EVAL_RANDOM_DESTROY,
AIScriptTokenFuncType.EVAL_RANDOM_METAMORPHOSE,
AIScriptTokenFuncType.EVAL_RANDOM_MULTI_DAMAGE,
AIScriptTokenFuncType.EVAL_RANDOM_MULTI_SELECT_DAMAGE,
AIScriptTokenFuncType.EVAL_DIVIDED_DAMAGE
};
public List<AIScriptTokenBase> TokenList { get; private set; }
public int Hash { get; private set; }
public bool IsMultiplyMarked { get; private set; }
public AIPolishConvertedExpression(string text, bool isMultiplyMarked = false)
{
IsMultiplyMarked = isMultiplyMarked;
TokenList = CreateExpression(text);
Hash = text.GetHashCode();
}
public int EvalID()
{
if (TokenList == null || TokenList.Count != 1)
{
return 0;
}
if (!(TokenList[0] is AIScriptIDToken))
{
return 0;
}
return (TokenList[0] as AIScriptIDToken).ID;
}
public bool IsID()
{
return TokenList[0] is AIScriptIDToken;
}
public List<int> GetReferringIDLists()
{
List<int> list = null;
for (int i = 0; i < TokenList.Count; i++)
{
AIScriptTokenBase aIScriptTokenBase = TokenList[i];
if (aIScriptTokenBase is AIScriptIDToken)
{
if (list == null)
{
list = new List<int>();
}
list.Add(((AIScriptIDToken)aIScriptTokenBase).ID);
}
}
return list;
}
public string EvalText()
{
if (TokenList == null || TokenList.Count != 1)
{
return "";
}
if (TokenList[0] is AIScriptTextToken aIScriptTextToken)
{
return aIScriptTextToken.Text;
}
return "";
}
public float EvalArg(AIVirtualCard tagOwner, List<int> playPtn, AIVirtualField field, AISituationInfo situation = null)
{
if (TokenList == null || TokenList.Count <= 0)
{
return 0f;
}
return GetFloatValue(tagOwner, situation, playPtn, field);
}
public bool CheckCondition(AIVirtualCard tagOwner, List<int> playPtn, AIVirtualField field, AISituationInfo situation)
{
if (TokenList == null || TokenList.Count <= 0)
{
return true;
}
return GetFloatValue(tagOwner, situation, playPtn, field) > 0f;
}
public bool IsZeroOrNone()
{
if (TokenList == null || TokenList.Count <= 0)
{
return true;
}
if (TokenList.Count > 1)
{
return false;
}
AIScriptTokenBase aIScriptTokenBase = TokenList[0];
if (aIScriptTokenBase is AIScriptArgumentToken { ArgumentType: AIScriptTokenArgType.NONE } || aIScriptTokenBase is AIScriptNumericToken { Value: 0f })
{
return true;
}
return false;
}
public bool IsMathematicExpress()
{
if (TokenList == null || TokenList.Count <= 0)
{
return false;
}
if (TokenList.Count > 1)
{
return true;
}
AIScriptTokenBase aIScriptTokenBase = TokenList[0];
if (!(aIScriptTokenBase is AIScriptNumericToken))
{
return aIScriptTokenBase is AIScriptVariableToken;
}
return true;
}
public bool IsCertainArgumentTypeExpress(AIScriptTokenArgType argType)
{
if (TokenList == null || TokenList.Count <= 0 || TokenList.Count > 1)
{
return false;
}
if (TokenList[0] is AIScriptArgumentToken aIScriptArgumentToken && aIScriptArgumentToken.ArgumentType == argType)
{
return true;
}
return false;
}
private float GetFloatValue(AIVirtualCard tagOwner, AISituationInfo situation, List<int> playPtn, AIVirtualField field)
{
if (TokenList == null || TokenList.Count <= 0)
{
return 0f;
}
return AIScriptExpressionCalculator.CalculateExpression(TokenList, playPtn, field, tagOwner, situation);
}
private List<AIScriptTokenBase> CreateExpression(string expression)
{
if (expression == "")
{
return null;
}
List<AIScriptTokenBase> list = CreateScriptTokenList(expression);
if (list == null || list.Count <= 0)
{
return null;
}
if (list.Count == 1 && list[0] is AIScriptNumericToken)
{
return list;
}
return _ConvertExprToIPolish(list);
}
private List<AIScriptTokenBase> CreateScriptTokenList(string text)
{
List<AIScriptTokenBase> list = new List<AIScriptTokenBase>();
string[] array = text.Split(' ');
bool flag = false;
string[] array2 = array;
foreach (string text2 in array2)
{
if (!(text2 == ""))
{
AIScriptTokenBase aIScriptTokenBase = AIScriptParser.ConvertWordToToken(text2);
if (aIScriptTokenBase != null)
{
list.Add(aIScriptTokenBase);
}
else
{
flag = true;
}
}
}
return list;
}
private List<AIScriptTokenBase> _ConvertExprToIPolish(List<AIScriptTokenBase> expression)
{
List<AIScriptTokenBase> list = new List<AIScriptTokenBase>();
Stack<AIScriptTokenBase> stack = new Stack<AIScriptTokenBase>();
AIScriptFunctionToken aIScriptFunctionToken = null;
for (int i = 0; i < expression.Count; i++)
{
AIScriptTokenBase aIScriptTokenBase = expression[i];
if (aIScriptTokenBase is AIScriptNumericToken || aIScriptTokenBase is AIScriptArgumentToken || aIScriptTokenBase is AIScriptVariableToken || aIScriptTokenBase is AIScriptIDToken)
{
list.Add(aIScriptTokenBase);
continue;
}
if (aIScriptTokenBase is AIScriptOperatorSymbolToken)
{
if (aIScriptTokenBase.Type == AIScriptTokenType.COMMA)
{
while (stack.Count > 0)
{
AIScriptTokenBase aIScriptTokenBase2 = stack.Pop();
if (aIScriptTokenBase2 is AIScriptOperatorSymbolToken && aIScriptTokenBase2.Type == AIScriptTokenType.LEFT_BLACKET)
{
break;
}
if (aIScriptTokenBase2 == aIScriptFunctionToken)
{
aIScriptFunctionToken = stack.LastOrDefault((AIScriptTokenBase t) => t is AIScriptFunctionToken) as AIScriptFunctionToken;
}
list.Add(aIScriptTokenBase2);
}
aIScriptFunctionToken.ArgCount++;
stack.Push(new AIScriptOperatorSymbolToken(AIScriptTokenType.LEFT_BLACKET));
continue;
}
if (aIScriptTokenBase.Type == AIScriptTokenType.LEFT_BLACKET)
{
stack.Push(aIScriptTokenBase);
continue;
}
if (aIScriptTokenBase.Type == AIScriptTokenType.RIGHT_BLACKET)
{
while (stack.Count > 0)
{
AIScriptTokenBase aIScriptTokenBase3 = stack.Pop();
if (aIScriptTokenBase3 is AIScriptOperatorSymbolToken && aIScriptTokenBase3.Type == AIScriptTokenType.LEFT_BLACKET)
{
break;
}
if (aIScriptTokenBase3 == aIScriptFunctionToken)
{
aIScriptFunctionToken = stack.LastOrDefault((AIScriptTokenBase t) => t is AIScriptFunctionToken) as AIScriptFunctionToken;
}
list.Add(aIScriptTokenBase3);
}
continue;
}
}
if (aIScriptTokenBase is AIScriptFunctionToken)
{
aIScriptFunctionToken = aIScriptTokenBase as AIScriptFunctionToken;
aIScriptFunctionToken.ArgCount = 1;
}
if (stack.Count <= 0)
{
stack.Push(aIScriptTokenBase);
continue;
}
while (stack.Count > 0)
{
AIScriptTokenBase aIScriptTokenBase4 = stack.Peek();
if (aIScriptTokenBase4.Type == AIScriptTokenType.LEFT_BLACKET || aIScriptTokenBase4.Priority < aIScriptTokenBase.Priority)
{
break;
}
if (aIScriptTokenBase4 == aIScriptFunctionToken)
{
aIScriptFunctionToken = stack.LastOrDefault((AIScriptTokenBase t) => t is AIScriptFunctionToken) as AIScriptFunctionToken;
}
list.Add(stack.Pop());
}
stack.Push(aIScriptTokenBase);
}
while (stack.Count > 0)
{
list.Add(stack.Pop());
}
return list;
}
public AIScriptCalculationToken CreateCalculationToken()
{
return new AIScriptCalculationToken(TokenList);
}
public bool IsHoldingEVAL()
{
if (TokenList == null)
{
return false;
}
for (int i = 0; i < TokenList.Count; i++)
{
AIScriptTokenBase aIScriptTokenBase = TokenList[i];
if (aIScriptTokenBase is AIScriptFunctionToken && EvalFuncList.Contains(((AIScriptFunctionToken)aIScriptTokenBase).FuncType))
{
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,208 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Wizard.Battle.View.Vfx;
namespace Wizard;
public class AIRealActionInformation
{
public BattleCardBase OriginalActor;
public BattleCardBase Actor;
public List<BattleCardBase> SelectedTargetCardSet;
public List<BattleCardRealTargetInformation> RealTargetInformationList;
public AIOperationType OperationType;
private AIVirtualField.AIVirtualFieldSearchCardOption _searchTargetOption;
public AIRealActionInformation(AIOperationType type, BattleCardBase actCard, BattleCardBase originalCard, IEnumerable<BattleCardBase> targetCards)
{
OperationType = type;
OriginalActor = originalCard;
if (actCard == null)
{
Actor = OriginalActor;
}
else
{
Actor = actCard;
}
SelectedTargetCardSet = targetCards?.ToList();
_searchTargetOption = new AIVirtualField.AIVirtualFieldSearchCardOption
{
IsSearchFromDeck = false,
IsOutputCannotFindError = false
};
RealTargetInformationList = null;
}
public AISituationInfo CreateSituationInfo(AIVirtualField field)
{
AIVirtualCard aIVirtualCard = field.SearchVirtualCard(OriginalActor);
if (aIVirtualCard == null)
{
AIConsoleUtility.LogError("AIRealActionInformation.CreateSituationInfo() error!! virtualActor is not found");
return null;
}
if (!aIVirtualCard.IsAlly && aIVirtualCard is EnemyHandVirtualCard)
{
aIVirtualCard = new AIVirtualCard(aIVirtualCard, field);
}
AIVirtualCard aIVirtualCard2 = aIVirtualCard;
if (OriginalActor != Actor)
{
aIVirtualCard2 = new AIVirtualCard(Actor, field);
aIVirtualCard2.InitializeTags(field.ParamQuery, null, null);
}
AISituationInfo aISituationInfo;
switch (OperationType)
{
case AIOperationType.TURNEND:
aISituationInfo = new AIVirtualTurnEndInfo(aIVirtualCard);
break;
case AIOperationType.ATTACK:
aISituationInfo = GetTargetRegisteredAttackSituation(aIVirtualCard, field);
break;
case AIOperationType.EVOLVE:
case AIOperationType.PLAY:
case AIOperationType.FUSION:
aISituationInfo = GetTargetRegisteredTargetSelectSituation(aIVirtualCard2, aIVirtualCard, field);
break;
default:
AIConsoleUtility.LogError("AIRealActionInformation.CreateSituationInfo() error!! OperationType " + OperationType.ToString() + " is illegal");
return null;
}
if (aISituationInfo != null && RealTargetInformationList != null)
{
aISituationInfo.RegisterRealTargetInfo(RealTargetInformationList);
}
return aISituationInfo;
}
private AIVirtualAttackInfo GetTargetRegisteredAttackSituation(AIVirtualCard attacker, AIVirtualField field)
{
if (SelectedTargetCardSet == null || SelectedTargetCardSet.Count <= 0)
{
AIConsoleUtility.LogError("AIRealActionInformation.GetTargetRegisteredAttackSituation error!! Attack situation cannot find target!!!!!");
return null;
}
AIVirtualCard target = field.SearchVirtualCard(SelectedTargetCardSet.First());
return new AIVirtualAttackInfo(attacker, target);
}
private AIVirtualTargetSelectAction GetTargetRegisteredTargetSelectSituation(AIVirtualCard playActor, AIVirtualCard originalCard, AIVirtualField field)
{
AIVirtualTargetSelectAction aIVirtualTargetSelectAction = new AIVirtualTargetSelectAction(playActor, originalCard, OperationType, (AISelectedTargetInfoSet)null);
if (SelectedTargetCardSet == null || SelectedTargetCardSet.Count <= 0)
{
return aIVirtualTargetSelectAction;
}
AIVirtualCard owner = playActor;
if (!playActor.IsSameCard(originalCard) && aIVirtualTargetSelectAction.IsChoiceAndChangeActor(field))
{
owner = originalCard;
}
List<AIVirtualTargetSelectInfo> list = owner.CreateAIVirtualSelectInfo(field, aIVirtualTargetSelectAction);
if (list == null || list.Count <= 0)
{
AIConsoleUtility.LogError("AIRealActionInformation.CreateSituationInfo error!! Target selection is required while TargetCardSet is empty!!!!! Card ID == " + originalCard.BaseId);
return aIVirtualTargetSelectAction;
}
int num = 0;
int num2 = 0;
for (int i = 0; i < list.Count; i++)
{
AIVirtualTargetSelectInfo aIVirtualTargetSelectInfo = list[i];
int num3;
if (aIVirtualTargetSelectAction.ActionType == AIOperationType.FUSION)
{
num3 = SelectedTargetCardSet.Count;
}
else
{
AIPlayTag selectRule = aIVirtualTargetSelectInfo.SelectRule;
num3 = ((selectRule != null && selectRule.Type == AIPlayTagType.ChoiceBrave) ? 1 : Math.Min(aIVirtualTargetSelectInfo.Candidates.Count, aIVirtualTargetSelectInfo.Count));
}
List<AIVirtualCard> list2 = new List<AIVirtualCard>();
if (SelectedTargetCardSet.Count - num < num3)
{
AIConsoleUtility.LogError("AIRealActionInformation.CreateSituationInfo error!! Targets are not enough!!!!!");
break;
}
for (int j = 0; j < num3; j++)
{
BattleCardBase battleCardBase = SelectedTargetCardSet[num];
AIVirtualCard aIVirtualCard = field.SearchVirtualCard(battleCardBase, _searchTargetOption);
if (aIVirtualCard == null)
{
aIVirtualCard = new AIVirtualCard(battleCardBase, field);
aIVirtualCard.InitializeTags(field.ParamQuery, null, null);
}
list2.Add(aIVirtualCard);
num++;
}
if (aIVirtualTargetSelectInfo.Type == TargetSelectType.Choice)
{
aIVirtualTargetSelectAction.SetChoicedMultipleTargetInInfo(list2);
continue;
}
AIScriptTokenArgType whichTarget = ((num2 != 0) ? AIScriptTokenArgType.SECOND_TARGET_SELECT : AIScriptTokenArgType.TARGET_SELECT);
aIVirtualTargetSelectAction.SetMultipleTargetsInInfo(list2, aIVirtualTargetSelectInfo.Type, aIVirtualTargetSelectInfo.RemovalType, whichTarget);
num2++;
}
return aIVirtualTargetSelectAction;
}
public void CreateRandomTargetInformation(BattleCardBase actor, Func<SkillBase, bool> skillCheckFunc, bool forceCheckEvolveSkills = false)
{
BattleCardRealTargetInformation information = GetRealRandomTargetInformation(actor);
SkillCollectionBase skillCollectionBase = (forceCheckEvolveSkills ? actor.EvolutionSkills : actor.Skills);
int num = skillCollectionBase.Count();
for (int i = 0; i < num; i++)
{
SkillBase skillBase = skillCollectionBase.Get(i);
if (skillCheckFunc(skillBase))
{
skillBase.OnSkillEnd += OnSkillEndRegistTargets;
}
}
VfxBase OnSkillEndRegistTargets(SkillBase currentSkill, List<BattleCardBase> skillTargets, SkillConditionCheckerOption option, SkillProcessor skillProcessor)
{
if (skillTargets != null && skillTargets.Count > 0)
{
information.AddTargetList(skillTargets, currentSkill.ApplyingTargetFilter);
}
currentSkill.OnSkillEnd -= OnSkillEndRegistTargets;
return NullVfx.GetInstance();
}
}
private BattleCardRealTargetInformation GetRealRandomTargetInformation(BattleCardBase skillOwner)
{
if (RealTargetInformationList == null)
{
RealTargetInformationList = new List<BattleCardRealTargetInformation>();
}
BattleCardRealTargetInformation battleCardRealTargetInformation = null;
for (int i = 0; i < RealTargetInformationList.Count; i++)
{
BattleCardRealTargetInformation battleCardRealTargetInformation2 = RealTargetInformationList[i];
BattleCardBase skillOwner2 = battleCardRealTargetInformation2.SkillOwner;
if (skillOwner.IsPlayer == skillOwner2.IsPlayer && skillOwner.Index == skillOwner2.Index && skillOwner.BaseParameter.BaseCardId == skillOwner2.BaseParameter.BaseCardId)
{
battleCardRealTargetInformation = battleCardRealTargetInformation2;
break;
}
}
if (battleCardRealTargetInformation == null)
{
battleCardRealTargetInformation = new BattleCardRealTargetInformation(skillOwner);
RealTargetInformationList.Add(battleCardRealTargetInformation);
}
return battleCardRealTargetInformation;
}
}

View File

@@ -0,0 +1,11 @@
namespace Wizard;
public enum AIRemovalType
{
None,
Damage,
Destroy,
Banish,
Bounce,
Metamorphose
}

View File

@@ -0,0 +1,55 @@
using System.Collections.Generic;
namespace Wizard;
public class AIRemovedTagCollection
{
public List<AIRemovedTagInformation> AllList;
public AIRemovedTagCollection()
{
AllList = null;
}
public AIRemovedTagCollection Clone()
{
AIRemovedTagCollection aIRemovedTagCollection = new AIRemovedTagCollection();
if (AllList != null)
{
aIRemovedTagCollection.AllList = new List<AIRemovedTagInformation>(AllList);
}
return aIRemovedTagCollection;
}
public void Add(AIRemovedTagInformation info)
{
AllList = AIParamQuery.AddElementToList(info, AllList);
}
public void RemoveTagFromCard(AIVirtualCard card)
{
if (AllList == null || AllList.Count <= 0)
{
return;
}
AIVirtualField selfField = card.SelfField;
for (int i = 0; i < AllList.Count; i++)
{
AIRemovedTagInformation aIRemovedTagInformation = AllList[i];
if (aIRemovedTagInformation.IsAlly == card.IsAlly && aIRemovedTagInformation.CardIndex == card.CardIndex)
{
card.TagCollectionContainer.RemoveOneTagWithUpdatingFieldCardList(card, aIRemovedTagInformation.Tag, selfField);
card.TagCollectionContainer.RemovedTagCollection.Add(aIRemovedTagInformation);
}
}
}
public void ClearAll()
{
if (AllList != null)
{
AllList.Clear();
AllList = null;
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Wizard;
public class AIRemovedTagInformation
{
public AIPlayTag Tag;
public int CardIndex { get; private set; }
public bool IsAlly { get; private set; }
public AIRemovedTagInformation(AIVirtualCard remover, AIPlayTag tag)
{
CardIndex = remover.CardIndex;
IsAlly = remover.IsAlly;
Tag = tag;
}
}

View File

@@ -0,0 +1,269 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Wizard;
public class AIScriptArgumentExpressions
{
protected List<AIPolishConvertedExpression> _exprList;
private List<int> _referringIds;
protected AIScriptTokenArgType[] LegalSelectTypes { get; set; }
public AIScriptArgumentExpressions(string text)
{
CreateLegalSelectTypes();
if (!(text == ""))
{
InitExpressions(text);
}
}
protected virtual void InitExpressions(string text)
{
InitExprList(text);
}
protected void InitExprList(string text)
{
string[] array = text.Split(';');
_exprList = new List<AIPolishConvertedExpression>();
foreach (string expression in array)
{
AIPolishConvertedExpression aIPolishConvertedExpression = CreateArgumentExpression(expression);
_exprList.Add(aIPolishConvertedExpression);
List<int> referringIDLists = aIPolishConvertedExpression.GetReferringIDLists();
if (referringIDLists != null)
{
if (_referringIds == null)
{
_referringIds = new List<int>();
}
_referringIds.AddRange(referringIDLists);
}
}
}
private AIPolishConvertedExpression CreateArgumentExpression(string expression)
{
string text = expression.TrimStart();
if (text[0] == '*')
{
return new AIPolishConvertedExpression(text.Substring(1), isMultiplyMarked: true);
}
return new AIPolishConvertedExpression(expression);
}
public bool IsArgID(int index)
{
return _exprList[index].IsID();
}
public int EvalID(int index)
{
if (_exprList == null || index >= _exprList.Count)
{
return 0;
}
return _exprList[index].EvalID();
}
public List<int> EvalIDList(int startIndex)
{
List<int> list = new List<int>();
if (_exprList != null && startIndex < _exprList.Count)
{
for (int i = startIndex; i < _exprList.Count; i++)
{
list.Add(_exprList[i].EvalID());
}
}
return list;
}
public string EvalText(int index)
{
if (_exprList == null || index >= _exprList.Count)
{
return "";
}
return _exprList[index].EvalText();
}
public virtual List<int> GetReferringOtherInplayIds()
{
return _referringIds;
}
public float EvalArg(int index, AIVirtualCard tagOwner, List<int> playPtn, AIVirtualField field, AISituationInfo situation)
{
if (_exprList == null || index >= _exprList.Count)
{
return 0f;
}
return _exprList[index].EvalArg(tagOwner, playPtn, field, situation);
}
public bool IsHoldingEVAL()
{
if (_exprList != null)
{
return _exprList.Any((AIPolishConvertedExpression expr) => expr.IsHoldingEVAL());
}
return false;
}
protected string[] SplitTextToWords(string text)
{
string pattern = "\\s\\;\\s(?=\\{)";
return Regex.Split(text, pattern);
}
protected List<AIScriptTokenBase> GetFilters(List<AIPolishConvertedExpression> exprs)
{
List<AIScriptTokenBase> list = new List<AIScriptTokenBase>();
for (int i = 0; i < exprs.Count; i++)
{
AIPolishConvertedExpression aIPolishConvertedExpression = exprs[i];
if (aIPolishConvertedExpression.TokenList == null)
{
continue;
}
if (aIPolishConvertedExpression.TokenList.Count > 1)
{
list.Add(aIPolishConvertedExpression.CreateCalculationToken());
continue;
}
AIScriptTokenBase aIScriptTokenBase = aIPolishConvertedExpression.TokenList[0];
if (!(aIScriptTokenBase is AIScriptArgumentToken { ArgumentType: AIScriptTokenArgType.FILTER_END }))
{
list.Add(aIScriptTokenBase);
}
}
return list;
}
public virtual void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
{
}
public virtual void ExecuteWhenRemove(AIVirtualCard tagOwner, AIVirtualField field, AIPlayTag removingTag)
{
}
protected AIScriptTokenArgType GetFirstTokenArgType(AIPolishConvertedExpression arg)
{
AIScriptTokenArgType result = AIScriptTokenArgType.NONE;
if (arg.TokenList != null && arg.TokenList.Count > 0)
{
AIScriptTokenBase aIScriptTokenBase = arg.TokenList[0];
if (aIScriptTokenBase is AIScriptArgumentToken)
{
result = ((AIScriptArgumentToken)aIScriptTokenBase).ArgumentType;
}
}
return result;
}
public virtual AITokenIdCollection GetAllRegisterTokenPoolInfo(AIVirtualCard owner)
{
if (_exprList == null || _exprList.Count <= 0)
{
return null;
}
List<int> list = null;
for (int i = 0; i < _exprList.Count; i++)
{
List<AIScriptTokenBase> tokenList = _exprList[i].TokenList;
if (tokenList != null && tokenList.Count > 0 && tokenList.Count == 1 && tokenList[0] is AIScriptIDToken aIScriptIDToken)
{
list = AIParamQuery.AddElementToList(aIScriptIDToken.ID, list);
}
}
if (list == null)
{
return null;
}
return CreateRegisterTokenPoolInfo(owner, list);
}
protected virtual AITokenIdCollection CreateRegisterTokenPoolInfo(AIVirtualCard owner, List<int> idList)
{
return AISummonTokenUtility.CreateTokenIdCollectionFromIdList(owner, AIScriptTokenArgType.ALLY, idList, AITokenType.Default);
}
protected bool IsFirstFiltersEnd(AIPolishConvertedExpression arg, AIScriptTokenArgType[] InitFilters, out AIScriptTokenArgType dstType)
{
dstType = AIScriptTokenArgType.NONE;
if (arg.TokenList != null && arg.TokenList.Count > 0)
{
AIScriptTokenBase aIScriptTokenBase = arg.TokenList[0];
if (aIScriptTokenBase is AIScriptArgumentToken)
{
dstType = ((AIScriptArgumentToken)aIScriptTokenBase).ArgumentType;
if (InitFilters.Contains(dstType))
{
return true;
}
}
}
return false;
}
protected bool IsTimingTokenArgType(AIPolishConvertedExpression arg, out AIScriptTokenArgType dstTokenArgType)
{
dstTokenArgType = GetFirstTokenArgType(arg);
switch (dstTokenArgType)
{
case AIScriptTokenArgType.WHEN_PLAY:
case AIScriptTokenArgType.WHEN_DESTROY:
case AIScriptTokenArgType.WHEN_ATTACK:
case AIScriptTokenArgType.WHEN_CLASH:
case AIScriptTokenArgType.WHEN_DAMAGED:
case AIScriptTokenArgType.WHEN_EVO:
case AIScriptTokenArgType.WHEN_TURNEND:
case AIScriptTokenArgType.WHEN_ALLY_TURNEND:
case AIScriptTokenArgType.WHEN_OPPONENT_TURNEND:
case AIScriptTokenArgType.WHEN_ALLY_TURNSTART:
case AIScriptTokenArgType.WHEN_OPPONENT_TURNSTART:
case AIScriptTokenArgType.WHEN_FUSION:
return true;
default:
return false;
}
}
protected bool IsSideTokenArgType(AIPolishConvertedExpression arg, out AIScriptTokenArgType dstTokenARgType)
{
dstTokenARgType = GetFirstTokenArgType(arg);
AIScriptTokenArgType aIScriptTokenArgType = dstTokenARgType;
if ((uint)(aIScriptTokenArgType - 84) <= 2u)
{
return true;
}
return false;
}
protected bool IsLegalSelectType(AIPolishConvertedExpression arg, out AIScriptTokenArgType selectType)
{
selectType = AIScriptTokenArgType.NONE;
if (arg.TokenList != null && arg.TokenList.Count > 0 && arg.TokenList[0] is AIScriptArgumentToken { ArgumentType: var argumentType } && Array.IndexOf(LegalSelectTypes, argumentType) >= 0)
{
selectType = argumentType;
return true;
}
return false;
}
protected virtual void CreateLegalSelectTypes()
{
LegalSelectTypes = new AIScriptTokenArgType[2]
{
AIScriptTokenArgType.ALL_SELECT,
AIScriptTokenArgType.RANDOM_SELECT
};
}
}

View File

@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
namespace Wizard;
public class AIScriptCalculationToken : AIScriptTokenBase
{
public Func<AIVirtualCard, AIVirtualCard, AIVirtualField, List<int>, AISituationInfo, float> Expression;
public AIScriptCalculationToken(List<AIScriptTokenBase> tokens)
: base(AIScriptTokenType.FUNC, 0f)
{
CreateExpression(tokens);
}
public AIScriptCalculationToken(Func<AIVirtualCard, AIVirtualCard, AIVirtualField, List<int>, AISituationInfo, float> expression)
: base(AIScriptTokenType.FUNC, 0f)
{
Expression = expression;
}
private void CreateExpression(List<AIScriptTokenBase> tokens)
{
Stack<AIScriptTokenBase> stack = new Stack<AIScriptTokenBase>();
for (int i = 0; i < tokens.Count; i++)
{
AIScriptTokenBase token = tokens[i];
if (token is AIScriptNumericToken || token is AIScriptIDToken)
{
stack.Push(token);
continue;
}
AIScriptArgumentToken argument = token as AIScriptArgumentToken;
if (argument != null)
{
AIScriptCalculationToken item = new AIScriptCalculationToken(delegate(AIVirtualCard owner, AIVirtualCard candidate, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
AIFilteringUtility.FilteringParameter filter = new AIFilteringUtility.FilteringParameter
{
Type = argument.ArgumentType,
IsNot = argument.IsNot,
IsSkipNextToken = false,
FilteringThreshold = -1
};
if (argument is AIScriptTextToken aIScriptTextToken)
{
filter.SubParameter = aIScriptTextToken.Text;
}
situation.SetCurrentCheckCard(candidate);
float result = (AIFilteringUtility.CheckFilterPassOrNot(candidate, filter, owner, playPtn, situation) ? 1f : 0f);
situation.ResetCurrentCheckCard();
return result;
});
stack.Push(item);
}
if (token is AIScriptVariableToken)
{
AIScriptCalculationToken item2 = new AIScriptCalculationToken(delegate(AIVirtualCard owner, AIVirtualCard candidate, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
situation.SetCurrentCheckCard(candidate);
AIScriptTokenBase aIScriptTokenBase = AIScriptExpressionCalculator.CalculateVariableToken(token, playPtn, field, owner, situation);
situation.ResetCurrentCheckCard();
return aIScriptTokenBase.Value;
});
stack.Push(item2);
}
AIScriptFunctionToken funcToken = token as AIScriptFunctionToken;
if (funcToken != null)
{
int argCount = ((AIScriptFunctionToken)token).ArgCount;
List<AIScriptTokenBase> argList = new List<AIScriptTokenBase>();
for (int num = 0; num < argCount; num++)
{
AIScriptTokenBase item3 = stack.Pop();
argList.Add(item3);
}
AIScriptCalculationToken item4 = new AIScriptCalculationToken(delegate(AIVirtualCard owner, AIVirtualCard candidate, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
situation.SetCurrentCheckCard(candidate);
AIScriptTokenBase aIScriptTokenBase = AIScriptExpressionCalculator.CalculateFunctionToken(argList, funcToken, field, playPtn, owner, situation);
situation.ResetCurrentCheckCard();
return aIScriptTokenBase.Value;
});
stack.Push(item4);
}
if (token is AIScriptOperatorSymbolToken)
{
AIScriptTokenBase right = stack.Pop();
AIScriptTokenBase left = stack.Pop();
AIScriptCalculationToken item5 = new AIScriptCalculationToken(delegate(AIVirtualCard owner, AIVirtualCard candidate, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
float tokenValue = GetTokenValue(left, owner, candidate, field, playPtn, situation);
float tokenValue2 = GetTokenValue(right, owner, candidate, field, playPtn, situation);
return AIScriptExpressionCalculator.CalculateByOperatorSymbol(token.Type, tokenValue, tokenValue2);
});
stack.Push(item5);
}
}
if (stack.Count <= 1 && stack.Count > 0 && stack.Pop() is AIScriptCalculationToken aIScriptCalculationToken)
{
Expression = aIScriptCalculationToken.Expression;
}
}
public float GetTokenValue(AIScriptTokenBase token, AIVirtualCard owner, AIVirtualCard candidate, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (token is AIScriptCalculationToken aIScriptCalculationToken)
{
return aIScriptCalculationToken.Expression(owner, candidate, field, playPtn, situation);
}
if (token is AIScriptIDToken aIScriptIDToken)
{
if (!((aIScriptIDToken.ID == candidate.BaseId) ^ aIScriptIDToken.IsNot))
{
return 0f;
}
return 1f;
}
return token.Value;
}
}

View File

@@ -0,0 +1,198 @@
namespace Wizard;
public enum AIScriptTokenArgType
{
NONE = 0,
LEGION = 1,
LORD = 2,
WHITE_RITUAL = 3,
ARTIFACT = 4,
MANARIA = 5,
MACHINE = 6,
FOOD = 7,
LEVIN = 8,
NATURE = 9,
LOOT = 10,
BANQUET = 11,
HERO = 12,
ARMED = 13,
HELLBOUND = 14,
SCHOOL = 15,
CHESS = 16,
ANY_TRIBE = 17,
ALL = 18,
CLASS = 19,
SPELL = 20,
SPELL_CARD_TYPE = 21,
ALL_SPELLBOOST = 22,
FIELD = 23,
CHANT_FIELD = 24,
ALLY_CLASS = 25,
ENEMY_CLASS = 26,
ACCELERATE = 27,
CRYSTALIZE = 28,
LASTWORD = 29,
KILLER = 30,
SNEAK = 31,
MEDUSA = 32,
QUICK = 33,
RUSH = 34,
DRAIN = 35,
GUARD = 36,
NOT_BE_ATTACKED = 37,
UNION_BURST = 38,
CRYSTALIZE_HOLDER = 39,
DESTRUCTIBLE = 40,
UNTOUCHABLE = 41,
FORCE_TARGETING = 42,
UNBANISHABLE = 43,
NO_SKILL = 44,
IGNORE_GUARD = 45,
DAMAGE_CLIP = 46,
DAMAGE_CUT = 47,
ALL_DAMAGE = 48,
ATTACK_DAMAGE = 49,
SPELL_DAMAGE = 50,
SKILL_DAMAGE = 51,
ELF = 52,
ROYAL = 53,
WITCH = 54,
DRAGON = 55,
NECROMANCER = 56,
VAMPIRE = 57,
BISHOP = 58,
NEMESIS = 59,
WHEN_PLAY = 60,
WHEN_DESTROY = 61,
WHEN_ATTACK = 62,
WHEN_CLASH = 63,
WHEN_DAMAGED = 64,
WHEN_EVO = 65,
WHEN_TURNEND = 66,
WHEN_SUMMON = 67,
WHEN_HEAL = 68,
WHEN_LEAVE = 69,
WHEN_ALLY_TURNEND = 70,
WHEN_OPPONENT_TURNEND = 71,
WHEN_ALLY_TURNSTART = 72,
WHEN_OPPONENT_TURNSTART = 73,
WHEN_NEXT_TURNEND = 74,
WHEN_FUSION = 75,
FIRST_TURN = 76,
EVOLVED = 77,
ATTACKABLE = 78,
CANT_ATTACK = 79,
PREVIOUS_TURN_ATTACKED = 80,
ATTACKED = 81,
CONSUME_EP_ZERO = 82,
AI_FILTER_INITIAL_START = 83,
ALLY = 84,
OPPONENT = 85,
BOTH = 86,
SELF = 87,
SUMMON_FOLLOWER = 88,
LATEST_SUMMON_CARD = 89,
LATEST_DRAW_CARD = 90,
ROMELIA_TARGET = 91,
SUMMON_AMULET = 92,
CLASH_TARGET = 93,
ATTACKER = 94,
EVOLVER = 95,
PLAYED_CARD = 96,
CHOICED_TARGET = 97,
SELECTED_TARGET = 98,
SECOND_SELECTED_TARGET = 99,
SELECTED_TARGET_SIDE = 100,
TRIGGER = 101,
REAL_SKILL_TARGET = 102,
FILTER_END = 103,
BANISHED_TARGET = 104,
GETOFF_CARD = 105,
AI_FILTER_INITIAL_END = 106,
OTHER_FOLLOWER = 107,
MIN_ATTACK = 108,
MAX_ATTACK = 109,
MIN_COST = 110,
MAX_COST = 111,
ALLY_AMULET = 112,
FOLLOWER = 113,
FOLLOWER_CARD_TYPE = 114,
AMULET = 115,
NOT_COUNTDOWN_AMULET = 116,
DAMAGED_FOLLOWER = 117,
NO_DAMAGED_FOLLOWER = 118,
EVOLVED_FOLLOWER = 119,
BUFFED_FOLLOWER = 120,
BUFFED_FOLLOWER_CARD_TYPE = 121,
NEUTRAL = 122,
SELECTED_TARGET_ID = 123,
DESTROYED_CARD = 124,
DESTROYED_IN_CURRENT_TURN = 125,
RANDOM_SELECT = 126,
ALL_SELECT = 127,
TARGET_SELECT = 128,
RANDOM_MULTI_SELECT = 129,
SECOND_TARGET_SELECT = 130,
REVERSE_TARGET = 131,
FIRST_SELECT = 132,
DIVIDED_SELECT = 133,
OLDEST_SELECT = 134,
DESTROY = 135,
BANISH = 136,
TOKEN_DRAW = 137,
TEMP = 138,
PERM = 139,
ADD = 140,
SET = 141,
TURN = 142,
GAME = 143,
TARGET_ID = 144,
USE_MIN = 145,
IGNORE_IN_BATTLE = 146,
IGNORE_IN_FUSION = 147,
IN_HAND = 148,
IN_PLAY = 149,
LAST_DRAW_CARD = 150,
NEWER = 151,
OLDEST_FOLLOWER = 152,
OTHER_OLDEST_HAND_CARD_TYPE = 153,
PLAYED = 154,
PLAYPTN = 155,
BEFORE_PLAYPTN = 156,
NOW = 157,
AI_TRIBE = 158,
CANDIDATE = 159,
ENHANCED = 160,
LEAST_VALUE = 161,
ALLY_ATTACK_FOLLOWER = 162,
NEXT_PLAY = 163,
WHEN_PLAY_DAMAGE = 164,
WHEN_PLAY_DESTROY = 165,
FIRST_SUMMON_FOLLOWER_IN_PLAYPTN = 166,
SELECT_LOGIC_TYPE_BEGIN = 167,
DEFAULT_LOGIC = 168,
DESTROY_LOGIC = 169,
DAMAGE_LOGIC = 170,
BANISH_LOGIC = 171,
BOUNCE_LOGIC = 172,
METAMORPHOSE_LOGIC = 173,
MAX_ATTACK_LOGIC = 174,
TYRANT_ORDER_LOGIC = 175,
REVERSE_DISCARD_LOGIC = 176,
WHITEFROST_WHISPER_LOGIC = 177,
SELECT_LOGIC_TYPE_END = 178,
LIFE_INF = 1001,
ATK_INF = 1002,
COST_INF = 1003,
BASE_COST_INF = 1004,
LIFE_SUP = 1005,
ATK_SUP = 1006,
COST_SUP = 1007,
BASE_COST_SUP = 1008,
ATK_EQL = 1009,
LIFE_EQL = 1010,
COST_EQL = 1011,
BASE_COST_EQL = 1012,
COUNTDOWN_EQL = 1013,
PLAY_COUNT_EQL = 1014
}

View File

@@ -0,0 +1,48 @@
namespace Wizard;
public class AIScriptTokenBase
{
public AIScriptTokenType Type { get; private set; }
public virtual float Value { get; private set; }
public int Priority => Type switch
{
AIScriptTokenType.OR => -3,
AIScriptTokenType.AND => -2,
AIScriptTokenType.PLUS => 0,
AIScriptTokenType.MINUS => 0,
AIScriptTokenType.MULTI => 2,
AIScriptTokenType.DIV => 2,
AIScriptTokenType.REMAIN => 2,
AIScriptTokenType.MORE_THAN => -1,
AIScriptTokenType.LESS_THAN => -1,
AIScriptTokenType.MORE_EQUAL => -1,
AIScriptTokenType.LESS_EQUAL => -1,
AIScriptTokenType.EQUAL => -1,
AIScriptTokenType.MAX => 3,
AIScriptTokenType.MIN => 3,
AIScriptTokenType.FUNC => 6,
_ => 0,
};
protected AIScriptTokenBase(AIScriptTokenType type, float value)
{
Type = type;
Value = value;
}
public virtual AIScriptTokenBase Clone()
{
return new AIScriptTokenBase(Type, Value);
}
public virtual bool IsEqual(AIScriptTokenBase token)
{
if (Type == token.Type)
{
return Value == token.Value;
}
return false;
}
}

View File

@@ -0,0 +1,119 @@
namespace Wizard;
public enum AIScriptTokenFuncType
{
MEMBER_COUNT,
HAND_COUNT,
HAND_NAME_COUNT,
DECK_COUNT,
INPLAY_COUNT,
PLAYOUT_ATTACKER_COUNT,
BEFORE_PLAYPTN_COUNT,
PLAY_TOKEN_COUNT,
EVO_COUNT_IN_GAME,
EVO_COUNT_IN_PREVIOUS_TURN,
EVAL_TARGETING_DAMAGE,
EVAL_TARGETING_AND_RANDOM_MULTI_DAMAGE,
EVAL_TARGETING_DESTROY,
EVAL_TARGETING_OTHER_DESTROY,
EVAL_TARGETING_MULTI_DESTROY,
EVAL_TARGETING_BOUNCE,
EVAL_TARGETING_BANISH,
EVAL_TARGETING_HEAL,
EVAL_TARGETING_METAMORPHOSE,
EVAL_TARGETING_BUFF,
EVAL_ECHO_DAMAGE,
EVAL_ALL_DAMAGE,
EVAL_ALL_DESTROY,
EVAL_ALL_BOUNCE,
EVAL_ALL_METAMORPHOSE,
EVAL_ALL_BUFF,
EVAL_RANDOM_BUFF,
EVAL_ALL_HEAL,
EVAL_ALL_BANISH,
EVAL_RANDOM_DESTROY,
EVAL_RANDOM_BANISH,
EVAL_RANDOM_METAMORPHOSE,
EVAL_LEADER_DAMAGE,
EVAL_RANDOM_BOUNCE,
EVAL_LEADER_HEAL,
EVAL_RANDOM_MULTI_DAMAGE,
EVAL_RANDOM_MULTI_SELECT_DAMAGE,
EVAL_RANDOM_MULTI_DAMAGE_MAX,
EVAL_INSTANT_ATTACK,
EVAL_RUSH,
EVAL_REANIMATE,
EVAL_DIVIDED_DAMAGE,
EVAL_ALL_MULTI_DAMAGE,
EVAL_ATTACK_REMOVE,
FORCED_EXCHANGE,
LIFE,
ATTACK,
POW,
CEILING,
FLOOR,
EVAL_CHANT_COUNT_CHANGE,
EVAL_CHANT_COUNT_CHANGE_ALL,
IS_CLASH_TARGET,
IS_ATTACK_TARGET,
IS_SELECTED_TARGET,
IS_NEXT_PLAY,
DECK_NAME_COUNT,
BROKEN_COUNT,
BROKEN_NAME_COUNT,
BROKEN_COST_SUM,
LEAVE_NAME_COUNT,
DESTROYED_COUNT,
IS_TRIBE,
SKILL_COUNT_FROM_ID,
TAG_COUNT_FROM_ID,
PLAYED_COUNT,
PLAYED_COUNT_IN_GAME,
PLAYED_COUNT_IN_PREVIOUS_TURN,
PLAYED_NAME_COUNT,
RANDOM,
IS_REANIMATE,
DAMAGE_COUNT,
HEAL_COUNT,
TOTAL_DAMAGE,
FUSION_COUNT,
NOW_FUSION_COUNT,
FUSION_COUNT_AT_ONCE,
FUSION_NAME_COUNT,
IS_SKILL_OCCURRED,
SKILL_ACTIVATE_COUNT,
HAND_MAX_ATTACK,
DECK_MAX_COST,
INPLAY_LARGEST_LIFE,
LEADER_MAX_LIFE,
IS_DISCARD_TARGET,
DISCARD_COUNT,
BOUNCE_COUNT,
EMOTE_PLAY_COUNT,
DRAW_COUNT,
MEMBER_MAX_ATK,
IS_BURIAL_RITE,
BURIAL_COUNT,
RESONANCE_START_COUNT,
SUMMON_COUNT,
BUFF_COUNT,
IS_HOLDING_BATTLE_SKILL,
IS_LEADER_HOLDING_BATTLE_SKILL,
STACK_COUNT,
LEAVE_COUNT,
OWN_DESTROY_COUNT,
IS_SELECTABLE,
IS_ENEMY_AI_ID,
ADD_HAND_COUNT,
BASE_COST,
RECEIVED_DAMAGE_SUM,
FUSION_COUNT_IN_GAME,
FUSION_NAME_COUNT_IN_GAME,
BANISH_COUNT,
HAND_BANISH_COUNT,
ADDED_DECK_COUNT_IN_GAME,
IS_PLAYER_CHARA_ID,
IS_PLAYER_ABILITY_ID,
IS_BOTH_CLASS,
NONE
}

View File

@@ -0,0 +1,27 @@
namespace Wizard;
public enum AIScriptTokenType
{
NUMERIC,
PLUS,
MINUS,
MULTI,
DIV,
REMAIN,
LEFT_BLACKET,
RIGHT_BLACKET,
COMMA,
MORE_THAN,
LESS_THAN,
MORE_EQUAL,
LESS_EQUAL,
EQUAL,
MAX,
MIN,
FUNC,
ARG,
ID,
VARIABLE,
OR,
AND
}

View File

@@ -0,0 +1,118 @@
namespace Wizard;
public enum AIScriptTokenVariableType
{
NONE,
NOW_TURN,
COUNTDOWN,
REINCARNATION_MAX,
SPELLBOOST,
FIELD_SPACE,
ALLY_UNIT_MIN,
ALLY_UNIT_MAX,
ALLY_ATTACKABLE_ATK_MAX,
ALLY_NON_ATTACKABLE_ATK_MAX,
ALLY_MAX_ATTACKABLE_LIFE,
ENEMY_UNIT_MIN,
ENEMY_UNIT_MAX,
HAND_COUNT_E,
DECK_COUNT_E,
PLAYPTN_COUNT,
MEMBER_MAX_LIFE,
MEMBER_ATK_SUM,
MEMBER_LIFE_SUM,
INPLAY_ATTACK_SUM_TO_LEADER,
ATTACK_TARGET_ATK_MAX,
SUMMON_DRUNKEN_ATK_MAX,
ENEMY_MIN_ATK,
ENEMY_MAX_ATK,
ENEMY_ATK_SUM,
ALLY_INPLAY_MAX_ATK,
GRAVE_COUNT,
ALLY_MAX_PP,
ENEMY_MAX_PP,
REST_PP,
NOW_REST_PP,
ALLY_EP,
ENEMY_EP,
OWN_ATK,
OWN_LIFE,
OWN_COST,
OWN_BASE_ATK,
OWN_BASE_LIFE,
KILLER_ATTACK_VALUE,
ENHANCE_COST,
PLAY_ACTOR_ENHANCE_COST,
ACCELERATE_COST,
CHOICE_TRANSFORM_COST,
BASE_SKILL_COUNT,
LAST_LIFE,
LEADER_DEF_LIFE,
LEADER_CURRENT_LIFE,
MAX_ATTACKABLE_COUNT,
HAND_MIN_COST,
HAND_MAX_COST,
UNION_BURST_COUNT,
CONSUME_EP,
LAST_HEAL_AMOUNT,
JUST_BEFORE_TURN_DAMAGE,
RALLY_COUNT,
SKYBOUND_ART_COUNT,
SUPER_SKYBOUND_ART_COUNT,
USED_EP_COUNT,
USED_PP_COUNT,
EARTH_RITE_COUNT,
NECROMANCE_COUNT,
USED_STACK_COUNT,
DEFAULT_DAMAGE,
NEXT_PLAY_PRIORITY,
NECROMANCED_COUNT_IN_GAME,
IS_EVO_TURN,
IS_ABLE_EVO,
IS_F_ADV,
IS_F_DISADV,
IS_AWAKE,
IS_BERSERK,
IS_TO_BE_BERSERK,
IS_ON_FIELD,
IS_IN_HAND,
IS_IN_PLAYPTN,
IS_OWNER_TURN,
IS_ALLY,
IS_ENEMY,
IS_ALLY_FIRST,
IS_SNEAK,
IS_MEDUSA,
IS_KILLER,
IS_EVOLVED,
IS_GUARD,
IS_RUSH,
IS_PLAYOUT_ATTACKER,
IS_ENHANCED,
IS_ACCELERATE,
IS_CRYSTALIZE,
IS_ATTACK_LEADER,
IS_FANFARE,
IS_SKILL_REMOVED,
IS_BARBAROSSA,
IS_RESONANCE,
IS_LETHAL,
IS_USED_EVO,
IS_FIRST_TURN,
IS_DAMAGED,
IS_DELAY_HEAL,
IS_NOT_ATTACK_YET,
IS_EVOLVING,
IS_LEADER,
IS_GET_ON,
IS_SKILL_SUMMONED,
IS_UNTOUCHABLE,
IS_FORCE_TARGETING,
IS_QUICK,
IS_NOT_BE_ATTACKED,
IS_IN_SIMULATION,
IS_IGNORE_GUARD,
IS_ATTACKED,
IS_ONEMORELASTWORD_TAGGED,
IS_DRAIN
}

View File

@@ -0,0 +1,150 @@
using System.Collections.Generic;
namespace Wizard;
public class AISelectedTargetInfo
{
public TargetSelectType Type;
public AIRemovalType RemovalType;
public List<AIVirtualCard> Targets { get; private set; }
public AIVirtualCard FirstTarget => Targets[0];
public bool HasTarget
{
get
{
if (Targets != null)
{
return Targets.Count > 0;
}
return false;
}
}
public AISelectedTargetInfo(TargetSelectType type, AIRemovalType removalType = AIRemovalType.None)
{
Type = type;
RemovalType = removalType;
}
public AISelectedTargetInfo(AIVirtualCard target, TargetSelectType type, AIRemovalType removalType = AIRemovalType.None)
{
AddTarget(target);
Type = type;
RemovalType = removalType;
}
public AISelectedTargetInfo(List<AIVirtualCard> targets, TargetSelectType type, AIRemovalType removalType = AIRemovalType.None)
{
Type = type;
RemovalType = removalType;
for (int i = 0; i < targets.Count; i++)
{
AddTarget(targets[i]);
}
}
public void AddTarget(AIVirtualCard target)
{
if (target == null)
{
AIConsoleUtility.LogError("AISelectedTargetInfo.AddTarget error!! Trying to add null into target list!!!!!");
}
else
{
Targets = AIParamQuery.AddElementToList(target, Targets);
}
}
public bool ContainsTarget(AIVirtualCard card)
{
if (Targets == null || Targets.Count <= 0)
{
return false;
}
for (int i = 0; i < Targets.Count; i++)
{
if (Targets[i].IsSameCard(card))
{
return true;
}
}
return false;
}
public AISelectedTargetInfo GetSimilarTargetInfo(AIVirtualField field)
{
AISelectedTargetInfo aISelectedTargetInfo = new AISelectedTargetInfo(Type, RemovalType);
if (Targets == null || Targets.Count <= 0)
{
return aISelectedTargetInfo;
}
for (int i = 0; i < Targets.Count; i++)
{
AIVirtualCard aIVirtualCard = Targets[i];
AIVirtualCard target = ((Type == TargetSelectType.Choice) ? aIVirtualCard : field.SearchVirtualCard(aIVirtualCard));
aISelectedTargetInfo.AddTarget(target);
}
return aISelectedTargetInfo;
}
public bool IsDuplicate(AISelectedTargetInfo compare)
{
if (Type != compare.Type)
{
return false;
}
if (HasTarget)
{
if (!compare.HasTarget || compare.Targets.Count != Targets.Count)
{
return false;
}
for (int i = 0; i < Targets.Count; i++)
{
if (!Targets[i].IsSameCard(compare.Targets[i]))
{
return false;
}
}
}
else if (compare.HasTarget)
{
return false;
}
return true;
}
public bool IsSelectedSameTarget(AISelectedTargetInfo otherTargetInfo)
{
if (!HasTarget || otherTargetInfo == null || !otherTargetInfo.HasTarget)
{
return false;
}
for (int i = 0; i < Targets.Count; i++)
{
if (otherTargetInfo.ContainsTarget(Targets[i]))
{
return true;
}
}
return false;
}
public List<int> GetTargetIdList()
{
if (!HasTarget)
{
return null;
}
List<int> list = new List<int>();
for (int i = 0; i < Targets.Count; i++)
{
list.Add(Targets[i].BaseId);
}
return list;
}
}

View File

@@ -0,0 +1,232 @@
using System.Collections.Generic;
namespace Wizard;
public class AISelectedTargetInfoSet
{
public static readonly int LENGTH = 2;
private AISelectedTargetInfo[] _set;
public AISelectedTargetInfo PreprocessTarget { get; private set; }
public AISelectedTargetInfo ChoiceTarget { get; private set; }
public bool HasChoiceTarget
{
get
{
if (ChoiceTarget != null)
{
return ChoiceTarget.HasTarget;
}
return false;
}
}
public AISelectedTargetInfoSet()
{
_set = new AISelectedTargetInfo[LENGTH];
}
public AISelectedTargetInfoSet Clone()
{
return new AISelectedTargetInfoSet(this);
}
private AISelectedTargetInfoSet(AISelectedTargetInfoSet set)
{
_set = new AISelectedTargetInfo[LENGTH];
for (int i = 0; i < LENGTH; i++)
{
AISelectedTargetInfo aISelectedTargetInfo = set.Get(i);
_set[i] = aISelectedTargetInfo;
}
PreprocessTarget = set.PreprocessTarget;
ChoiceTarget = set.ChoiceTarget;
}
public AISelectedTargetInfo Get(int index)
{
if (index < 0 || index > 1)
{
return null;
}
return _set[index];
}
public void Set(AISelectedTargetInfo info, int index)
{
if (index >= 0 && index <= 1)
{
_set[index] = info;
}
}
public void SetPreprocessTarget(AISelectedTargetInfo info)
{
PreprocessTarget = info;
}
public void SetChoiceTarget(AISelectedTargetInfo info)
{
ChoiceTarget = info;
}
public bool IsTargetExist(int index)
{
if (index < 0 || index > 1)
{
return false;
}
return _set[index]?.HasTarget ?? false;
}
public bool IsAnyTargetExists()
{
if (PreprocessTarget != null && PreprocessTarget.HasTarget)
{
return true;
}
if (HasChoiceTarget)
{
return true;
}
AISelectedTargetInfo[] set = _set;
foreach (AISelectedTargetInfo aISelectedTargetInfo in set)
{
if (aISelectedTargetInfo != null && aISelectedTargetInfo.HasTarget)
{
return true;
}
}
return false;
}
public AISelectedTargetInfo GetChoiceInfo()
{
if (HasChoiceTarget)
{
return ChoiceTarget;
}
AISelectedTargetInfo[] set = _set;
foreach (AISelectedTargetInfo aISelectedTargetInfo in set)
{
if (aISelectedTargetInfo != null && aISelectedTargetInfo.Type == TargetSelectType.Choice)
{
return aISelectedTargetInfo;
}
}
return null;
}
public AISelectedTargetInfoSet GetSimilarTargetInfoSet(AIVirtualField field)
{
AISelectedTargetInfoSet aISelectedTargetInfoSet = new AISelectedTargetInfoSet();
if (PreprocessTarget != null)
{
AISelectedTargetInfo similarTargetInfo = PreprocessTarget.GetSimilarTargetInfo(field);
aISelectedTargetInfoSet.SetPreprocessTarget(similarTargetInfo);
}
if (ChoiceTarget != null)
{
AISelectedTargetInfo similarTargetInfo2 = ChoiceTarget.GetSimilarTargetInfo(field);
aISelectedTargetInfoSet.SetChoiceTarget(similarTargetInfo2);
}
for (int i = 0; i < _set.Length; i++)
{
AISelectedTargetInfo aISelectedTargetInfo = _set[i];
AISelectedTargetInfo info = null;
if (aISelectedTargetInfo != null)
{
info = aISelectedTargetInfo.GetSimilarTargetInfo(field);
}
aISelectedTargetInfoSet.Set(info, i);
}
return aISelectedTargetInfoSet;
}
public bool IsDuplicate(AISelectedTargetInfoSet compare)
{
if (compare == null)
{
return false;
}
if (PreprocessTarget == null)
{
if (compare.PreprocessTarget != null)
{
return false;
}
}
else if (!PreprocessTarget.IsDuplicate(compare.PreprocessTarget))
{
return false;
}
if (ChoiceTarget == null)
{
if (compare.ChoiceTarget != null)
{
return false;
}
}
else if (!ChoiceTarget.IsDuplicate(compare.ChoiceTarget))
{
return false;
}
for (int i = 0; i < LENGTH; i++)
{
AISelectedTargetInfo aISelectedTargetInfo = _set[i];
AISelectedTargetInfo aISelectedTargetInfo2 = compare.Get(i);
if (aISelectedTargetInfo == null)
{
if (aISelectedTargetInfo2 != null)
{
return false;
}
}
else if (!aISelectedTargetInfo.IsDuplicate(aISelectedTargetInfo2))
{
return false;
}
}
return true;
}
public List<int> GetTargetIdList(AIScriptTokenArgType selectType)
{
AISelectedTargetInfo aISelectedTargetInfo;
switch (selectType)
{
case AIScriptTokenArgType.CHOICED_TARGET:
aISelectedTargetInfo = ChoiceTarget;
break;
case AIScriptTokenArgType.SELECTED_TARGET:
aISelectedTargetInfo = _set[0];
break;
case AIScriptTokenArgType.SECOND_SELECTED_TARGET:
aISelectedTargetInfo = _set[1];
break;
default:
AIConsoleUtility.LogError("AISelectedTargetInfoSet.GetTargetIdList() error!! selectType = " + selectType);
aISelectedTargetInfo = null;
break;
}
return aISelectedTargetInfo?.GetTargetIdList();
}
public void UpdateRemovalType(AIScriptTokenArgType whichTarget, AIRemovalType removalType)
{
if (whichTarget != AIScriptTokenArgType.TARGET_SELECT && whichTarget != AIScriptTokenArgType.SECOND_TARGET_SELECT)
{
AIConsoleUtility.LogError($"whichTarget=={whichTarget} is invalid!!");
return;
}
int num = ((whichTarget != AIScriptTokenArgType.TARGET_SELECT) ? 1 : 0);
AISelectedTargetInfo aISelectedTargetInfo = _set[num];
if (aISelectedTargetInfo != null)
{
aISelectedTargetInfo.RemovalType = removalType;
}
}
}

View File

@@ -0,0 +1,37 @@
using System.Collections.Generic;
namespace Wizard;
public class AISetUpData
{
public int classID;
public AI_LOGIC_LV logicLv;
public string deckName;
public string styleName;
public string emoteName;
public bool doesUseEmote;
public bool useInnerEmote;
public int enemyAiID;
public List<int> specialAbilityList;
public AISetUpData(int _classID, AI_LOGIC_LV _logicLv, string _deckName, string _styleName, string _emoteName, bool _doesUseEmote, bool _useInnerEmote, int _enemyAiID, List<int> _specialAbilityList = null)
{
classID = _classID;
logicLv = _logicLv;
deckName = _deckName;
styleName = _styleName;
emoteName = _emoteName;
doesUseEmote = _doesUseEmote;
useInnerEmote = _useInnerEmote;
enemyAiID = _enemyAiID;
specialAbilityList = _specialAbilityList;
}
}

View File

@@ -0,0 +1,25 @@
namespace Wizard;
public class AISimulationBuffInfo
{
public int TempAttackBuff;
public int TempLifeBuff;
public int TotalAttackBuff;
public int TotalLifeBuff;
public AISimulationBuffInfo(int tempAttack, int tempLife, int totalAttack, int totalLife)
{
TempAttackBuff = tempAttack;
TempLifeBuff = tempLife;
TotalAttackBuff = totalAttack;
TotalLifeBuff = totalLife;
}
public static AISimulationBuffInfo operator +(AISimulationBuffInfo a, AISimulationBuffInfo b)
{
return new AISimulationBuffInfo(a.TempAttackBuff + b.TempAttackBuff, a.TempLifeBuff + b.TempLifeBuff, a.TotalAttackBuff + b.TotalAttackBuff, a.TotalLifeBuff + b.TotalLifeBuff);
}
}

View File

@@ -0,0 +1,96 @@
using System.Collections.Generic;
namespace Wizard;
public class AISimulationBuffInfoCollection
{
public List<AIBuffWithTargetsInformation> BuffInfoList { get; private set; }
public int Count
{
get
{
if (BuffInfoList != null)
{
return BuffInfoList.Count;
}
return 0;
}
}
public AISimulationBuffInfoCollection()
{
BuffInfoList = null;
}
public void Add(ulong tagHash, List<AIVirtualCard> target, AISimulationBuffInfo buffInfo)
{
AIBuffWithTargetsInformation element = new AIBuffWithTargetsInformation(target, buffInfo, tagHash);
BuffInfoList = AIParamQuery.AddElementToList(element, BuffInfoList);
}
public void PseudoApplyBuffForSimpleAttack(AIVirtualCard currentAttacker, List<AIVirtualCard> attackerList, Tuple<int, int>[] statusArray)
{
if (BuffInfoList != null && BuffInfoList.Count > 0)
{
for (int i = 0; i < BuffInfoList.Count; i++)
{
BuffInfoList[i].PseudoApplyBuffForSimpleAttack(currentAttacker, attackerList, statusArray);
}
}
}
public void ApplySingleBuff(ulong tagHash, AIVirtualField field, List<int> playPtn, AIVirtualAttackInfo situation)
{
if (BuffInfoList != null && BuffInfoList.Count > 0)
{
for (int i = 0; i < BuffInfoList.Count && !BuffInfoList[i].VerifyArgumentAndApply(tagHash, field, playPtn, situation); i++)
{
}
}
}
public AISimulationBuffInfo GetBuffInfoToCertainCard(AIVirtualCard card)
{
AISimulationBuffInfo result = null;
if (BuffInfoList != null && BuffInfoList.Count > 0)
{
int num = 0;
int num2 = 0;
int num3 = 0;
int num4 = 0;
for (int i = 0; i < BuffInfoList.Count; i++)
{
AIBuffWithTargetsInformation aIBuffWithTargetsInformation = BuffInfoList[i];
if (aIBuffWithTargetsInformation.ContainsTarget(card))
{
num += aIBuffWithTargetsInformation.BuffInfo.TempAttackBuff;
num2 += aIBuffWithTargetsInformation.BuffInfo.TempLifeBuff;
num3 += aIBuffWithTargetsInformation.BuffInfo.TotalAttackBuff;
num4 += aIBuffWithTargetsInformation.BuffInfo.TotalLifeBuff;
}
}
if (num != 0 || num2 != 0 || num3 != 0 || num4 != 0)
{
result = new AISimulationBuffInfo(num, num2, num3, num4);
}
}
return result;
}
public bool HasBuffInfo(ulong hash)
{
if (BuffInfoList == null || BuffInfoList.Count <= 0)
{
return false;
}
for (int i = 0; i < BuffInfoList.Count; i++)
{
if (BuffInfoList[i].IsHashEqual(hash))
{
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,50 @@
using System.Collections.Generic;
namespace Wizard;
public class AISimulationPreprocessRecorder
{
public List<AISinglePreprocessRecord> RecordList;
public int TotalBurialCount { get; private set; }
public bool HasRecord
{
get
{
if (RecordList != null)
{
return RecordList.Count > 0;
}
return false;
}
}
public AISimulationPreprocessRecorder()
{
TotalBurialCount = 0;
}
public void AddRecord(AISinglePreprocessRecord record)
{
RecordList = AIParamQuery.AddElementToList(record, RecordList);
if (record.BurialRiteCount > 0)
{
TotalBurialCount += record.BurialRiteCount;
}
}
public void RemoveAll()
{
if (RecordList != null)
{
RecordList.Clear();
RecordList = null;
}
}
public void ClearBurialCount()
{
TotalBurialCount = 0;
}
}

View File

@@ -0,0 +1,246 @@
using System.Collections.Generic;
namespace Wizard;
public class AISinglePlayptnRecord
{
public List<int> PlayPtn;
public ulong PlayPtnHash;
public List<PlayedCardInfo> PlayedCardList;
public bool IsValid;
public int LastRestPp;
public int TotalDrawCount;
public float FirstPlayCardPriority;
public AIVirtualCard FirstSummonedAllyFollower;
public int ReferenceFieldIndex { get; private set; }
public List<AIVirtualCard> UsableHandCardList { get; private set; }
public List<AIVirtualCard> RestHandCardList { get; private set; }
public List<AIVirtualCard> AllDiscardedCardList { get; private set; }
public int DiscardCount
{
get
{
if (AllDiscardedCardList != null)
{
return AllDiscardedCardList.Count;
}
return 0;
}
}
public int PlayPtnCount
{
get
{
if (PlayPtn != null)
{
return PlayPtn.Count;
}
return 0;
}
}
public AISinglePlayptnRecord(List<int> playPtn, AIVirtualField field, int fieldIndex)
{
PlayPtn = playPtn;
PlayPtnHash = AIHandPtnCalculator.CalculatePlayPtnHash(field, playPtn);
IsValid = true;
LastRestPp = field.AllyPp;
ReferenceFieldIndex = fieldIndex;
TotalDrawCount = 0;
InitializeHandCardList(field);
AllDiscardedCardList = null;
PlayedCardList = new List<PlayedCardInfo>();
for (int i = 0; i < playPtn.Count; i++)
{
int num = playPtn[i];
AIVirtualCard card = field.AllyHandCards[num];
PlayedCardList.Add(new PlayedCardInfo(num, card));
if (i == 0)
{
FirstPlayCardPriority = card.GetPriority(playPtn);
}
}
}
public void UpdatePlayPtnRecord(PlayedCardInfo info)
{
TotalDrawCount += info.DrawCount;
LastRestPp = info.RestPp;
if (!info.IsPlayable)
{
IsValid = false;
}
RestHandCardList.Remove(info.Card);
info.IsProcessed = true;
}
public bool IsToBeRegister()
{
return PlayPtn.Count == PlayedCardList.Count;
}
public AIVirtualCard FindRealActor(AIVirtualCard originalCard)
{
List<PlayedCardInfo> playedCardList = PlayedCardList;
for (int i = 0; i < playedCardList.Count; i++)
{
PlayedCardInfo playedCardInfo = playedCardList[i];
if (originalCard.IsSameCard(playedCardInfo.Card) && playedCardInfo.TransformCard != null)
{
return playedCardInfo.TransformCard;
}
}
return originalCard;
}
public bool IsMatchedPattern(List<int> playPtn)
{
for (int i = 0; i < PlayPtn.Count; i++)
{
int num = PlayPtn[i];
int num2 = playPtn[i];
if (num != num2)
{
return false;
}
}
return true;
}
private void InitializeHandCardList(AIVirtualField field)
{
UsableHandCardList = new List<AIVirtualCard>();
RestHandCardList = new List<AIVirtualCard>();
for (int i = 0; i < field.AllyHandCards.Count; i++)
{
AIVirtualCard item = field.AllyHandCards[i];
RestHandCardList.Add(item);
if (!PlayPtn.Contains(i))
{
UsableHandCardList.Add(item);
}
}
}
public bool IsAllTargetsUsableHandCard(List<AIVirtualCard> targets)
{
if (UsableHandCardList == null)
{
return false;
}
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard item = targets[i];
if (!UsableHandCardList.Contains(item))
{
return false;
}
}
return true;
}
public bool IsUsableHandCard(AIVirtualCard card)
{
if (UsableHandCardList == null)
{
return false;
}
for (int i = 0; i < UsableHandCardList.Count; i++)
{
if (UsableHandCardList[i].IsSameCard(card))
{
return true;
}
}
return false;
}
public void CheckRegisteredDiscardInfo(AIDiscardInfo discardInfo)
{
if (discardInfo.IsNGByAI)
{
IsValid = false;
}
else if (discardInfo.IsSuccess)
{
List<AIVirtualCard> targetList = discardInfo.TargetList;
UpdateHandCardList(targetList);
AllDiscardedCardList = AIParamQuery.AddRangeToList(targetList, AllDiscardedCardList);
}
}
public void UpdateHandCardList(List<AIVirtualCard> usedHandCardList)
{
if (usedHandCardList != null && usedHandCardList.Count > 0)
{
for (int i = 0; i < usedHandCardList.Count; i++)
{
AIVirtualCard item = usedHandCardList[i];
UsableHandCardList.Remove(item);
RestHandCardList.Remove(item);
}
}
}
public void RegisterPreprocess(PlayedCardInfo info, AIVirtualTargetSelectAction situation, AIVirtualField field)
{
AISimulationPreprocessRecorder preprocessRecorder = situation.PreprocessRecorder;
info.RegisterPreprocess(preprocessRecorder);
AIVirtualCard card = info.Card;
if (preprocessRecorder.TotalBurialCount <= 0)
{
return;
}
AIVirtualTargetSelectInfo burialSelectInfo = card.GetBurialSelectInfo(field, situation);
bool flag = false;
bool isBreakPlayptn = false;
if (burialSelectInfo != null)
{
AISelectedTargetInfo burialSelectTargets = burialSelectInfo.GetBurialSelectTargets(situation, field, burialSelectInfo, this, out isBreakPlayptn);
if (burialSelectTargets != null)
{
info.RegisterPreDecidedPreprocessTarget(burialSelectTargets);
UpdateHandCardList(burialSelectTargets.Targets);
flag = true;
}
}
if (flag)
{
IsValid = !isBreakPlayptn;
}
else
{
preprocessRecorder.ClearBurialCount();
}
}
public PlayedCardInfo FindPlayedCardInfo(AIVirtualCard actor)
{
if (PlayedCardList == null || PlayedCardList.Count <= 0)
{
return null;
}
for (int i = 0; i < PlayedCardList.Count; i++)
{
PlayedCardInfo playedCardInfo = PlayedCardList[i];
if (actor.IsSameCard(playedCardInfo.Card))
{
return playedCardInfo;
}
}
return null;
}
}

View File

@@ -0,0 +1,92 @@
using System.Collections.Generic;
namespace Wizard;
public class AISinglePreprocessRecord
{
public int NecromanceCount;
public int BurialRiteCount;
public AIVirtualCard RealActor { get; private set; }
public AIVirtualCard OriginalCard { get; private set; }
public AIScriptTokenArgType Timing { get; private set; }
public int EarthRiteCount { get; private set; }
public List<EarthRiteRecordContainer> EarthRiteContainer { get; private set; }
public AISinglePreprocessRecord(AIVirtualCard realActor, AIVirtualCard originalCard, AIScriptTokenArgType timing)
{
RealActor = realActor;
OriginalCard = originalCard;
Timing = timing;
NecromanceCount = 0;
BurialRiteCount = 0;
EarthRiteCount = 0;
EarthRiteContainer = new List<EarthRiteRecordContainer>();
}
public void AddConsumedEarthRite(AIVirtualCard consumedTarget, int consumedStack)
{
if (consumedTarget == null)
{
AIConsoleUtility.LogError("AISinglePreprocessRecord.AddConsumedEarthRite(): Consumed stack target is null.");
return;
}
if (consumedStack <= 0)
{
AIConsoleUtility.LogError("AISinglePreprocessRecord.AddConsumedEarthRite(): Consumed stack count is less than 1");
return;
}
EarthRiteCount += consumedStack;
EarthRiteContainer.Add(new EarthRiteRecordContainer(consumedTarget, consumedStack));
}
public void RestoreAllEarthRiteCount(AIVirtualField field)
{
if (field == null)
{
AIConsoleUtility.LogError("RestoreAllEarthRiteCount(): field is null.");
return;
}
List<AIVirtualCard> list = (RealActor.IsAlly ? field.AllyInplayCards : field.EnemyInplayCards);
int num = 0;
for (int i = 0; i < list.Count; i++)
{
if (RestoreEarthRiteCount(list[i]))
{
num++;
}
}
if (EarthRiteContainer.Count != num)
{
AIConsoleUtility.LogError("RestoreAllEarthRiteCount(): Failed to restore all stacks!!!! ");
}
}
private bool RestoreEarthRiteCount(AIVirtualCard card)
{
if (card == null)
{
AIConsoleUtility.LogError("RestoreEarthRiteCount(): card is null.");
return false;
}
if (!card.IsTribe(CardBasePrm.TribeType.WHITE_RITUAL))
{
return false;
}
for (int i = 0; i < EarthRiteContainer.Count; i++)
{
EarthRiteRecordContainer earthRiteRecordContainer = EarthRiteContainer[i];
if (card.IsSameCard(earthRiteRecordContainer.ConsumedTarget))
{
card.ResetEarthRite(earthRiteRecordContainer.ConsumedStack);
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,333 @@
using System.Collections.Generic;
namespace Wizard;
public abstract class AISituationInfo
{
public AISelectedTargetInfoSet SelectedTargets;
public List<AIVirtualCard> BounceCardList;
public AISimulationPreprocessRecorder PreprocessRecorder;
public List<BattleCardRealTargetInformation> RealTargetInformationList;
public AIVirtualCard Actor { get; protected set; }
public AIVirtualCard OriginalCard { get; protected set; }
public AIVirtualCard ActionTarget => SelectedTargets.Get(0)?.FirstTarget;
public AIVirtualCard SecondActionTarget => SelectedTargets.Get(1)?.FirstTarget;
public AIOperationType ActionType { get; private set; }
public AIVirtualCard CurrentCheckCard { get; private set; }
public AIDiscardInfo DiscardInfo { get; private set; }
public AISkillProcessInfoCollection ProcessCollection { get; private set; }
public AISkillProcessInformation CurrentSkillProcessInfo { get; private set; }
public bool IsLatestAction { get; private set; }
public AISituationInfo(AIVirtualCard actor, AIVirtualCard target, AIVirtualCard secondTarget = null, AIOperationType type = AIOperationType.ATTACK)
{
Actor = actor;
OriginalCard = actor;
ActionType = type;
SelectedTargets = new AISelectedTargetInfoSet();
ProcessCollection = new AISkillProcessInfoCollection();
if (target != null)
{
SelectedTargets.Set(new AISelectedTargetInfo(target, TargetSelectType.Default), 0);
}
if (secondTarget != null)
{
SelectedTargets.Set(new AISelectedTargetInfo(secondTarget, TargetSelectType.Default), 1);
}
PreprocessRecorder = new AISimulationPreprocessRecorder();
IsLatestAction = false;
RealTargetInformationList = null;
}
public AISituationInfo(AIVirtualCard actor, AIOperationType type, AISelectedTargetInfoSet selectedTargetInfoSet)
{
Actor = actor;
OriginalCard = actor;
ActionType = type;
ProcessCollection = new AISkillProcessInfoCollection();
if (selectedTargetInfoSet == null)
{
SelectedTargets = new AISelectedTargetInfoSet();
}
else
{
SelectedTargets = selectedTargetInfoSet;
}
PreprocessRecorder = new AISimulationPreprocessRecorder();
IsLatestAction = false;
RealTargetInformationList = null;
}
public void SetActor(AIVirtualCard newActor)
{
Actor = newActor;
}
public void SetOriginalCard(AIVirtualCard card)
{
OriginalCard = card;
}
public AISelectedTargetInfo GetSituationTarget(AIScriptTokenArgType whichTarget)
{
switch (whichTarget)
{
case AIScriptTokenArgType.SELECTED_TARGET:
case AIScriptTokenArgType.TARGET_SELECT:
return SelectedTargets.Get(0);
case AIScriptTokenArgType.SECOND_SELECTED_TARGET:
case AIScriptTokenArgType.SECOND_TARGET_SELECT:
return SelectedTargets.Get(1);
case AIScriptTokenArgType.CHOICED_TARGET:
return SelectedTargets.GetChoiceInfo();
default:
return null;
}
}
public AISelectedTargetInfo GetBurialRiteTarget()
{
if (SelectedTargets != null && SelectedTargets.PreprocessTarget != null && SelectedTargets.PreprocessTarget.Type == TargetSelectType.BurialRite)
{
return SelectedTargets.PreprocessTarget;
}
return null;
}
public AISelectedTargetInfo GetChoiceTarget()
{
if (SelectedTargets != null && SelectedTargets.HasChoiceTarget)
{
return SelectedTargets.ChoiceTarget;
}
return null;
}
public bool IsFirstTarget(AIVirtualCard card)
{
if (ActionTarget != null && ActionTarget.IsSameCard(card))
{
return true;
}
return false;
}
public bool IsSecondTarget(AIVirtualCard card)
{
if (SecondActionTarget != null && SecondActionTarget.IsSameCard(card))
{
return true;
}
return false;
}
public bool IsTargetExists(AIScriptTokenArgType whichTarget)
{
return whichTarget switch
{
AIScriptTokenArgType.TARGET_SELECT => SelectedTargets.IsTargetExist(0),
AIScriptTokenArgType.SECOND_TARGET_SELECT => SelectedTargets.IsTargetExist(1),
_ => false,
};
}
public void SetTarget(AISelectedTargetInfo info, AIScriptTokenArgType whichTarget)
{
switch (whichTarget)
{
case AIScriptTokenArgType.TARGET_SELECT:
SelectedTargets.Set(info, 0);
break;
case AIScriptTokenArgType.SECOND_TARGET_SELECT:
SelectedTargets.Set(info, 1);
break;
}
}
public void SetMultipleTargetsInInfo(List<AIVirtualCard> targets, TargetSelectType type, AIRemovalType removalType, AIScriptTokenArgType whichTarget)
{
AISelectedTargetInfo info = new AISelectedTargetInfo(targets, type, removalType);
SetTarget(info, whichTarget);
}
public void SetSingleTargetInInfo(AIVirtualCard target, TargetSelectType type, AIScriptTokenArgType whichTarget)
{
AISelectedTargetInfo info = ((target != null) ? new AISelectedTargetInfo(target, type) : null);
SetTarget(info, whichTarget);
}
public void SetChoicedTargetInInfo(AIVirtualCard target)
{
AISelectedTargetInfo choiceTarget = ((target != null) ? new AISelectedTargetInfo(target, TargetSelectType.Choice) : null);
SelectedTargets.SetChoiceTarget(choiceTarget);
}
public void SetChoicedMultipleTargetInInfo(List<AIVirtualCard> targets)
{
AISelectedTargetInfo choiceTarget = ((targets != null) ? new AISelectedTargetInfo(targets, TargetSelectType.Choice) : null);
SelectedTargets.SetChoiceTarget(choiceTarget);
}
public void SetDiscardInfo(AIDiscardInfo info)
{
DiscardInfo = info;
}
public bool IsSameSituation(AISituationInfo situation)
{
if (ActionType != situation.ActionType || !Actor.IsSameCard(situation.Actor))
{
return false;
}
if (!SelectedTargets.IsDuplicate(situation.SelectedTargets))
{
return false;
}
return true;
}
public List<int> GetTargetIdList(AIScriptTokenArgType selectType)
{
if (SelectedTargets == null)
{
return null;
}
return SelectedTargets.GetTargetIdList(selectType);
}
public void SetExecutingSkillProcess(AISkillProcessInformation processInfo)
{
CurrentSkillProcessInfo = processInfo;
}
public AISkillProcessInformation RegisterNewProcessInfo(AIVirtualCard triggerCard, AISituationTriggerInformation.TriggerType triggerType)
{
AISkillProcessInformation aISkillProcessInformation = new AISkillProcessInformation(new AISituationTriggerInformation(triggerCard, triggerType));
ProcessCollection.RegisterProcess(aISkillProcessInformation);
return aISkillProcessInformation;
}
public AISkillProcessInformation RegisterNewPreprocessProcessInfo(AIVirtualCard triggerCard, AISituationTriggerInformation.TriggerType triggerType)
{
AISkillProcessInformation aISkillProcessInformation = new AISkillProcessInformation(new AISituationTriggerInformation(triggerCard, triggerType));
ProcessCollection.RegisterPreprocessProcessInfo(aISkillProcessInformation);
return aISkillProcessInformation;
}
public void AddProcessInfos(List<AISkillProcessInformation> processInfo)
{
ProcessCollection.RegisterProcess(processInfo);
}
public void ExecuteAllSkillProcess()
{
ProcessCollection.ExecuteAllProcess(this);
}
public void SetCurrentCheckCard(AIVirtualCard card)
{
CurrentCheckCard = card;
}
public void ResetCurrentCheckCard()
{
CurrentCheckCard = null;
}
public void RegisterRealTargetInfo(List<BattleCardRealTargetInformation> info)
{
RealTargetInformationList = info;
}
public bool IsRealSkillTarget(AIVirtualCard target, AIVirtualCard owner)
{
if (RealTargetInformationList == null || RealTargetInformationList.Count <= 0)
{
return false;
}
for (int i = 0; i < RealTargetInformationList.Count; i++)
{
BattleCardRealTargetInformation battleCardRealTargetInformation = RealTargetInformationList[i];
if (owner.IsEqual(battleCardRealTargetInformation.SkillOwner) && battleCardRealTargetInformation.IsTarget(target))
{
return true;
}
}
return false;
}
public AIVirtualCardRealTargetInformation DequeueRealTargetInfo(AIVirtualCard owner, AIVirtualField field)
{
if (RealTargetInformationList == null || RealTargetInformationList.Count <= 0)
{
return null;
}
AIVirtualField.AIVirtualFieldSearchCardOption searchOption = new AIVirtualField.AIVirtualFieldSearchCardOption
{
IsOutputCannotFindError = true,
IsSearchFromDeck = true,
IsSearchFromBeforeLatestActionDeck = true
};
BattleCardRealTargetInformation battleCardRealTargetInformation = null;
for (int i = 0; i < RealTargetInformationList.Count; i++)
{
BattleCardRealTargetInformation battleCardRealTargetInformation2 = RealTargetInformationList[i];
if (owner.IsEqual(battleCardRealTargetInformation2.SkillOwner))
{
battleCardRealTargetInformation = battleCardRealTargetInformation2;
break;
}
}
if (battleCardRealTargetInformation != null)
{
RealTargetInformationList.Remove(battleCardRealTargetInformation);
return battleCardRealTargetInformation.CreateAIVirtualTargetInformation(field, owner, searchOption);
}
return null;
}
public List<int> GetTokenIdListFromDequeuedRealTargetInfo(AIVirtualCard owner, AITokenType tokenType)
{
if (RealTargetInformationList == null || RealTargetInformationList.Count <= 0)
{
return null;
}
for (int i = 0; i < RealTargetInformationList.Count; i++)
{
BattleCardRealTargetInformation battleCardRealTargetInformation = RealTargetInformationList[i];
if (owner.IsEqual(battleCardRealTargetInformation.SkillOwner))
{
List<int> result = battleCardRealTargetInformation.DequeueFirstTargetInfoAndCreateTokenIdList(owner, tokenType);
if (!battleCardRealTargetInformation.HasAnyTarget)
{
RealTargetInformationList.Remove(battleCardRealTargetInformation);
}
return result;
}
}
return null;
}
public void SetLatestActionSimulationParameter()
{
IsLatestAction = true;
}
public void SetLatestActionSimulationParameterFromPreAction(AISituationInfo preAction)
{
IsLatestAction = preAction.IsLatestAction;
}
}

View File

@@ -0,0 +1,49 @@
namespace Wizard;
public class AISituationTriggerInformation
{
public enum TriggerType
{
Evolver,
Damage,
Banish,
Bounce,
Leave,
Summon,
WhenPlay,
Undefined
}
public AIVirtualCard TriggerCard { get; private set; }
public TriggerType Type { get; private set; }
public AISituationTriggerInformation()
{
Type = TriggerType.Undefined;
}
public AISituationTriggerInformation(AIVirtualCard trigger, TriggerType type)
{
Type = type;
TriggerCard = trigger;
}
public bool IsTriggerCard(AIVirtualCard card)
{
if (TriggerCard == null)
{
return false;
}
return TriggerCard.IsSameCard(card);
}
public bool IsTriggerCardAndTriggerType(AIVirtualCard card, TriggerType type)
{
if (type != Type || TriggerCard == null)
{
return false;
}
return TriggerCard.IsSameCard(card);
}
}

View File

@@ -0,0 +1,65 @@
using System.Collections.Generic;
namespace Wizard;
public class AISkillProcessInfoCollection
{
private Queue<AISkillProcessInformation> _processQueue;
private List<AISkillProcessInformation> _tempPreprocessList;
public AISkillProcessInfoCollection()
{
_processQueue = new Queue<AISkillProcessInformation>();
}
public void RegisterProcess(AISkillProcessInformation process)
{
_processQueue.Enqueue(process);
}
public void RegisterProcess(List<AISkillProcessInformation> processList)
{
if (processList == null)
{
return;
}
for (int i = 0; i < processList.Count; i++)
{
if (processList[i] != null)
{
_processQueue.Enqueue(processList[i]);
}
}
}
public void RegisterPreprocessProcessInfo(AISkillProcessInformation process)
{
_tempPreprocessList = AIParamQuery.AddElementToList(process, _tempPreprocessList, isBlockDuplicate: true);
}
public void CombinePreprocessToProcessQueue()
{
if (_tempPreprocessList != null && _tempPreprocessList.Count > 0)
{
RegisterProcess(_tempPreprocessList);
_tempPreprocessList.Clear();
}
}
public void ClearTempPreprocessList()
{
if (_tempPreprocessList != null)
{
_tempPreprocessList.Clear();
}
}
public void ExecuteAllProcess(AISituationInfo situation)
{
while (_processQueue.Count > 0)
{
_processQueue.Dequeue().ExecuteAllAction(situation);
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using Cute;
namespace Wizard;
public class AISkillProcessInformation
{
private List<Action> _executingAction;
public AISituationTriggerInformation TriggerInfo { get; private set; }
public AIOwnSkillProcessRecord OwnProcessRecord { get; private set; }
public AISkillProcessInformation(AISituationTriggerInformation triggerInfo)
{
TriggerInfo = triggerInfo;
OwnProcessRecord = new AIOwnSkillProcessRecord();
}
public void AddExecutingAction(Action action)
{
_executingAction = AIParamQuery.AddElementToList(action, _executingAction);
}
public void ExecuteAllAction(AISituationInfo situation)
{
if (_executingAction != null && _executingAction.Count > 0)
{
situation.SetExecutingSkillProcess(this);
for (int i = 0; i < _executingAction.Count; i++)
{
_executingAction[i].Call();
}
}
}
}

View File

@@ -0,0 +1,99 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public class AIStyleData
{
private List<AICategory> categoryFilter;
private Dictionary<AIStyleKey, List<AIPolicyData>> policyDic = new Dictionary<AIStyleKey, List<AIPolicyData>>();
public AIStyleData()
{
}
public AIStyleData(List<AICategory> filter)
{
categoryFilter = filter;
}
public void Clear()
{
categoryFilter = null;
policyDic.Clear();
}
public void CreateFromAsset(List<AIPolicyDataAsset> assetList)
{
foreach (AIPolicyDataAsset asset in assetList)
{
AIPolicyData aIPolicyData = new AIPolicyData(asset);
AIStyleKey key = new AIStyleKey(aIPolicyData.Category, aIPolicyData.PolicyType);
MixInPolicy(key, aIPolicyData);
}
}
public List<AIPolicyData> ConvertToPolicyList()
{
List<AIPolicyData> list = new List<AIPolicyData>();
foreach (KeyValuePair<AIStyleKey, List<AIPolicyData>> item in policyDic)
{
foreach (AIPolicyData item2 in item.Value)
{
list.Add(item2);
}
}
return list;
}
public bool MixInPolicy(AIStyleKey key, AIPolicyData value)
{
if (categoryFilter != null && !categoryFilter.Any((AICategory c) => c == key.category))
{
return false;
}
if (policyDic.ContainsKey(key))
{
List<AIPolicyData> list = policyDic[key];
if (list == null)
{
list = new List<AIPolicyData>();
list.Add(value);
return true;
}
int priority = list[0].Priority;
if (value.Priority > priority)
{
list.Clear();
list.Add(value);
return true;
}
if (value.Priority == priority)
{
list.Add(value);
return true;
}
return false;
}
List<AIPolicyData> list2 = new List<AIPolicyData>();
list2.Add(value);
policyDic.Add(key, list2);
return true;
}
public void MixInStyle(AIStyleData addStyle)
{
foreach (KeyValuePair<AIStyleKey, List<AIPolicyData>> pair in addStyle.policyDic)
{
if (pair.Value == null || (categoryFilter != null && !categoryFilter.Any((AICategory c) => c == pair.Key.category)))
{
continue;
}
foreach (AIPolicyData item in pair.Value)
{
MixInPolicy(pair.Key, item);
}
}
}
}

View File

@@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public class AIStyleFileNameList
{
private const int STYLE_ID_INDEX = 0;
private const int FILE_NAME_INDEX = 1;
private readonly Dictionary<int, string> _dataTable = new Dictionary<int, string>();
public AIStyleFileNameList(List<string[]> csvData)
{
foreach (string[] csvDatum in csvData)
{
int key = int.Parse(csvDatum[0]);
string value = csvDatum[1];
_dataTable.Add(key, value);
}
}
public string GetFileName(int id)
{
if (_dataTable.ContainsKey(id))
{
return _dataTable[id];
}
return "";
}
public List<string> GetFileNameList()
{
return _dataTable.Values.ToList();
}
}

View File

@@ -0,0 +1,38 @@
namespace Wizard;
public class AIStyleKey
{
public AICategory category;
public AIPolicyType policy;
public AIStyleKey(AICategory _category, AIPolicyType _policy)
{
category = _category;
policy = _policy;
}
public static bool operator ==(AIStyleKey lhs, AIStyleKey rhs)
{
if (lhs.category == rhs.category)
{
return lhs.policy == rhs.policy;
}
return false;
}
public static bool operator !=(AIStyleKey lhs, AIStyleKey rhs)
{
return !(lhs == rhs);
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}

View File

@@ -0,0 +1,248 @@
using System.Collections.Generic;
namespace Wizard;
public class AIStyleQuery
{
private EnemyAI _enemyAI;
private AIStyleData _deckStyle;
private AIStyleData _curStyle;
private List<AIPolicyData> _curPolicies;
private List<AIPolicyData> _attachedPolicies;
private AIPolicyCollectionContainer _policyCollections;
public AIStyleQuery(EnemyAI ai, AIParamQuery _paramQuery)
{
_enemyAI = ai;
_curStyle = new AIStyleData();
_curPolicies = new List<AIPolicyData>();
}
public void SetDeckStyle(AIStyleData _style)
{
_deckStyle = _style;
}
public void UpdateStyle()
{
AIDataLibrary aIDataLibrary = GameMgr.GetIns().GetDataMgr().m_AIDataLibrary;
_curStyle = aIDataLibrary.CreateStyle(GameMgr.GetIns().GetDataMgr().GetPlayerClassId(), _deckStyle);
_curPolicies = _curStyle.ConvertToPolicyList();
_policyCollections = new AIPolicyCollectionContainer();
_policyCollections.InitializeAllCollections(_curPolicies);
if (_attachedPolicies != null)
{
_policyCollections.InitializeAllCollections(_attachedPolicies);
}
InitializeReferenceIdTable();
InitializeReferenceTribeTable();
}
public void ExecuteAttachStyle(AIPolicyData data)
{
if (_attachedPolicies == null)
{
_attachedPolicies = new List<AIPolicyData>();
}
_attachedPolicies.Add(data);
_policyCollections.RegisterNewPolicy(data);
}
public void RemoveAllAttachedStyle()
{
if (_attachedPolicies != null)
{
_policyCollections.RemoveAttachedPolicies(_attachedPolicies);
_attachedPolicies.Clear();
_attachedPolicies = null;
}
}
public float GetEpValue(AISituationInfo situation, List<int> playPtn)
{
if (!_policyCollections.HasPolicy(AIPolicyType.EpValue))
{
return 0f;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.EpValue) as EpValuePolicyCollection).GetEpValue(situation, playPtn);
}
public float GetUnitRate(AIVirtualField field, AIVirtualCard card, List<int> playPtn)
{
if (!_policyCollections.HasPolicy(AIPolicyType.ModUnitRate))
{
return 1f;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.ModUnitRate) as ModUnitRatePolicyCollection).GetUnitRate(card, field, playPtn);
}
public float GetUnitBonus(AIVirtualField field, AIVirtualCard card, List<int> playPtn)
{
if (!_policyCollections.HasPolicy(AIPolicyType.UnitBonus))
{
return 0f;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.UnitBonus) as UnitBonusPolicyCollection).GetUnitBonus(card, field, playPtn);
}
public float GetPlayptnBonus(AIVirtualField field, List<int> playPtn)
{
if (!_policyCollections.HasPolicy(AIPolicyType.PlayptnBonus))
{
return 0f;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.PlayptnBonus) as PlayptnBonusPolicyCollection).GetPlayptnBonus(field, playPtn);
}
public float GetAllyPlayBonus(AIVirtualCard playCard, List<int> playPtn, AISituationInfo situation, ref float currentUseMinValue)
{
if (!_policyCollections.HasPolicy(AIPolicyType.AllyPlayBonus))
{
return 0f;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.AllyPlayBonus) as AllyPlayBonusPolicyCollection).GetAllyPlayBonus(playCard, playPtn, situation, ref currentUseMinValue);
}
public float GetAllyPlayBonusRate(AIVirtualCard playCard, List<int> playPtn, AISituationInfo situation)
{
if (!_policyCollections.HasPolicy(AIPolicyType.AllyPlayBonusRate))
{
return 1f;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.AllyPlayBonusRate) as AllyPlayBonusRatePolicyCollection).GetAllyPlayBonusRate(playCard, playPtn, situation);
}
public bool IsPlayBreak(AIVirtualCard card, List<int> playPtn, AISituationInfo situation)
{
if (!_policyCollections.HasPolicy(AIPolicyType.PlayBreak))
{
return false;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.PlayBreak) as PlayBreakPolicyCollection).IsPlayBreak(card, playPtn, situation);
}
public float GetBarrierBonus(AIVirtualCard card)
{
if (!_policyCollections.HasPolicy(AIPolicyType.BarrierBonus))
{
return 0f;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.BarrierBonus) as BarrierBonusPolicyCollection).GetBarrierBonus(card);
}
public bool IsDisableLethalCheck(AIVirtualField field, List<int> playPtn)
{
if (!_policyCollections.HasPolicy(AIPolicyType.DisableLethalCheck))
{
return false;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.DisableLethalCheck) as DisableLethalCheckPolicyCollection).IsDisableLethalCheck(field, playPtn);
}
public float GetDelayTurnEndTime(AIVirtualCard owner, List<int> playPtn)
{
if (!_policyCollections.HasPolicy(AIPolicyType.DelayTurnEndTime))
{
return 0f;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.DelayTurnEndTime) as AIDelayTurnEndTimePolicyCollection).GetDelayTime(owner, playPtn);
}
public int GetEmoteOnTurnEnd(bool isAllyTurn)
{
if (!_policyCollections.HasPolicy(AIPolicyType.EmoOnTurnEnd))
{
return -1;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.EmoOnTurnEnd) as EmoOnTurnEndPolicyCollection).GetEmoOnTurnEnd(_enemyAI.CurrentVirtualField, isAllyTurn);
}
public int GetEmoteOnTurnStart(bool isAllyTurn, AIVirtualField field)
{
if (!_policyCollections.HasPolicy(AIPolicyType.EmoOnTurnStart))
{
return -1;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.EmoOnTurnStart) as EmoOnTurnStartPolicyCollection).GetEmoOnTurnStart(field, isAllyTurn);
}
public int GetEmoteOnLeaderDamaged(AIVirtualField field)
{
if (!_policyCollections.HasPolicy(AIPolicyType.EmoOnLeaderDamaged))
{
return -1;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.EmoOnLeaderDamaged) as EmoOnLeaderDamagedPolicyCollection).GetEmoOnLeaderDamaged(field);
}
public int GetPlayerEmoteOnTurnEnd(bool isPlayerTurn)
{
if (!_policyCollections.HasPolicy(AIPolicyType.PlayerEmoOnTurnEnd))
{
return -1;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.PlayerEmoOnTurnEnd) as PlayerEmoOnTurnEndPolicyCollection).GetPlayerEmoOnTurnEnd(_enemyAI.CurrentVirtualField, isPlayerTurn);
}
public int GetPlayerEmoteOnTurnStart(AIVirtualField field)
{
if (!_policyCollections.HasPolicy(AIPolicyType.PlayerEmoOnTurnStart))
{
return -1;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.PlayerEmoOnTurnStart) as PlayerEmoOnTurnStartPolicyCollection).GetPlayerEmoOnTurnStart(field);
}
public int GetPlayerEmoteOnLeaderDamaged(AIVirtualField field)
{
if (!_policyCollections.HasPolicy(AIPolicyType.PlayerEmoOnLeaderDamaged))
{
return -1;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.PlayerEmoOnLeaderDamaged) as PlayerEmoOnLeaderDamagedPolicyCollection).GetPlayerEmoOnLeaderDamaged(field);
}
private void InitializeReferenceIdTable()
{
if (!_policyCollections.HasPolicy(AIPolicyType.SetReferenceId))
{
_enemyAI.ReferenceIdTable = new Dictionary<int, int>();
return;
}
SetReferenceIdPolicyCollection setReferenceIdPolicyCollection = _policyCollections.GetPolicyCollection(AIPolicyType.SetReferenceId) as SetReferenceIdPolicyCollection;
_enemyAI.ReferenceIdTable = setReferenceIdPolicyCollection.CreateReferenceIdTable();
}
private void InitializeReferenceTribeTable()
{
if (!_policyCollections.HasPolicy(AIPolicyType.SetReferenceTribe))
{
_enemyAI.ReferenceTribeTable = new Dictionary<string, List<int>>();
return;
}
SetReferenceTribePolicyCollection setReferenceTribePolicyCollection = _policyCollections.GetPolicyCollection(AIPolicyType.SetReferenceTribe) as SetReferenceTribePolicyCollection;
_enemyAI.ReferenceTribeTable = setReferenceTribePolicyCollection.CreateReferenceTribeTable();
}
public float GetFirstMoveBonus(AIVirtualCard playCard, List<AIVirtualActionInfo> moves)
{
if (!_policyCollections.HasPolicy(AIPolicyType.MoveFirstBonus))
{
return 0f;
}
return (_policyCollections.GetPolicyCollection(AIPolicyType.MoveFirstBonus) as MoveFirstBonusPolicyCollection).GetMoveFirstBonus(playCard, playCard.SelfField, moves);
}
public void ExecuteGameStartAttachTag(AIVirtualField field)
{
if (_policyCollections.HasPolicy(AIPolicyType.GameStartAttachTag))
{
(_policyCollections.GetPolicyCollection(AIPolicyType.GameStartAttachTag) as GameStartAttachTagPolicyCollection).ExecuteAttachTag(field);
}
}
}

View File

@@ -0,0 +1,115 @@
using System.Collections.Generic;
namespace Wizard;
public class AISummonedCardContainer
{
private class SummonedCardListSet
{
public List<AIVirtualCard> TurnSummonedCards { get; private set; }
public List<AIVirtualCard> GameSummonedCards { get; private set; }
public SummonedCardListSet()
{
TurnSummonedCards = new List<AIVirtualCard>();
GameSummonedCards = new List<AIVirtualCard>();
}
private SummonedCardListSet(SummonedCardListSet clone)
{
TurnSummonedCards = new List<AIVirtualCard>(clone.TurnSummonedCards);
GameSummonedCards = new List<AIVirtualCard>(clone.GameSummonedCards);
}
public SummonedCardListSet Clone()
{
return new SummonedCardListSet(this);
}
public void AddSummonedCard(AIVirtualCard card)
{
AddTurnSummonedCard(card);
AddGameSummonedCard(card);
}
public void AddTurnSummonedCard(AIVirtualCard card)
{
TurnSummonedCards.Add(card);
}
private void AddGameSummonedCard(AIVirtualCard card)
{
GameSummonedCards.Add(card);
}
public void LoadListSet(AIVirtualField field, BattlePlayerBase player)
{
BattleManagerBase ins = BattleManagerBase.GetIns();
int currentTurn = ins.CurrentTurn;
bool isSelfTurn = ins.BattlePlayer.IsSelfTurn;
for (int i = 0; i < player.GameSummonCards.Count; i++)
{
BattlePlayerBase.TurnAndCard turnAndCard = player.GameSummonCards[i];
SummonedVirtualCard card = new SummonedVirtualCard(turnAndCard.Card as BattleCardBase, field);
AddGameSummonedCard(card);
if (turnAndCard.Turn == currentTurn && turnAndCard.IsSelfTurn == isSelfTurn)
{
AddTurnSummonedCard(card);
}
}
}
}
private SummonedCardListSet _allySummonedListSet = new SummonedCardListSet();
private SummonedCardListSet _enemySummonedListSet = new SummonedCardListSet();
public int AllyTurnSummonedListCount => _allySummonedListSet.TurnSummonedCards.Count;
public AISummonedCardContainer()
{
}
private AISummonedCardContainer(AISummonedCardContainer clone)
{
_allySummonedListSet = clone._allySummonedListSet.Clone();
_enemySummonedListSet = clone._enemySummonedListSet.Clone();
}
public AISummonedCardContainer Clone()
{
return new AISummonedCardContainer(this);
}
public void LoadSummonedCardList(AIVirtualField field, BattlePlayerBase ally, BattlePlayerBase enemy)
{
_allySummonedListSet.LoadListSet(field, ally);
_enemySummonedListSet.LoadListSet(field, enemy);
}
public List<AIVirtualCard> GetSummonedList(bool isAlly, bool isTurnList)
{
SummonedCardListSet summonedCardListSet = (isAlly ? _allySummonedListSet : _enemySummonedListSet);
if (!isTurnList)
{
return summonedCardListSet.GameSummonedCards;
}
return summonedCardListSet.TurnSummonedCards;
}
public void AddSummonedCard(AIVirtualCard card)
{
(card.IsAlly ? _allySummonedListSet : _enemySummonedListSet).AddSummonedCard(card);
}
public void RollBackSummonedCard(int beforeTurnSummonedCount)
{
int num = _allySummonedListSet.TurnSummonedCards.Count - beforeTurnSummonedCount;
if (0 < num)
{
_allySummonedListSet.TurnSummonedCards.RemoveRange(beforeTurnSummonedCount, num);
_allySummonedListSet.GameSummonedCards.RemoveRange(beforeTurnSummonedCount, num);
}
}
}

View File

@@ -0,0 +1,665 @@
using System;
using System.Collections.Generic;
namespace Wizard;
public class AITagCollectionContainer
{
protected List<AIPlayTagType> _holdingTagTypes;
protected List<TagCollectionType> _holdingTagCollectionTypes;
private static ulong[] PRIME_NUMBERS_FOR_HASH_CALCULATION = new ulong[20]
{
23uL, 479uL, 811uL, 1447uL, 3541uL, 383uL, 281uL, 733uL, 71uL, 1201uL,
2293uL, 991uL, 59uL, 1931uL, 251uL, 673uL, 1613uL, 12491uL, 5uL, 2699uL
};
private readonly AIPlayTagType[] DISABLED_TAG_TYPES_INPLAY = new AIPlayTagType[96]
{
AIPlayTagType.HandPlus,
AIPlayTagType.CostBonus,
AIPlayTagType.Priority,
AIPlayTagType.PlayLimit,
AIPlayTagType.PlayPlus,
AIPlayTagType.PlayBonus,
AIPlayTagType.FanfareBonus,
AIPlayTagType.EmoteOnPlay,
AIPlayTagType.MulliganKeep,
AIPlayTagType.MulliganChange,
AIPlayTagType.FanfareToken,
AIPlayTagType.PlayToken,
AIPlayTagType.AddCardToPlayoutPlayPtn,
AIPlayTagType.PlayoutNextTurn,
AIPlayTagType.PlayDraw,
AIPlayTagType.PlayReanimate,
AIPlayTagType.Fusion,
AIPlayTagType.HandBonus,
AIPlayTagType.FusionBonus,
AIPlayTagType.FusionDraw,
AIPlayTagType.CondChoice,
AIPlayTagType.PlayDestroy,
AIPlayTagType.PlayDamage,
AIPlayTagType.PlayHeal,
AIPlayTagType.PlayBounce,
AIPlayTagType.PlayBanish,
AIPlayTagType.FanfareBanish,
AIPlayTagType.FanfareBounce,
AIPlayTagType.FanfareDamage,
AIPlayTagType.PlayBuff,
AIPlayTagType.FanfareBuff,
AIPlayTagType.PlaySetMaxStatus,
AIPlayTagType.FanfareSetMaxStatus,
AIPlayTagType.PlaySetLeaderMaxLife,
AIPlayTagType.FanfareDestroy,
AIPlayTagType.FanfareSpellboost,
AIPlayTagType.PlaySpellboost,
AIPlayTagType.FanfareAddCemetery,
AIPlayTagType.PlayAddCemetery,
AIPlayTagType.FanfareHeal,
AIPlayTagType.PlaySubtractCountdown,
AIPlayTagType.FanfareSubtractCountdown,
AIPlayTagType.PlayBanAttack,
AIPlayTagType.FanfareBanAttack,
AIPlayTagType.PlayIgnoreGuard,
AIPlayTagType.FanfareIgnoreGuard,
AIPlayTagType.PlayMetamorphose,
AIPlayTagType.FanfareMetamorphose,
AIPlayTagType.PlayHandMetamorphose,
AIPlayTagType.FanfareHandMetamorphose,
AIPlayTagType.FanfareRecoverAttackableCount,
AIPlayTagType.FanfareSneak,
AIPlayTagType.PlaySneak,
AIPlayTagType.FanfareQuick,
AIPlayTagType.PlayQuick,
AIPlayTagType.FanfareRush,
AIPlayTagType.PlayRush,
AIPlayTagType.FanfareGuard,
AIPlayTagType.PlayGuard,
AIPlayTagType.FanfareKiller,
AIPlayTagType.PlayKiller,
AIPlayTagType.FanfareDrain,
AIPlayTagType.PlayDrain,
AIPlayTagType.FanfareChangeClass,
AIPlayTagType.PlayChangeClass,
AIPlayTagType.FanfareChangeTribe,
AIPlayTagType.PlayChangeTribe,
AIPlayTagType.FanfareUntouchable,
AIPlayTagType.PlayUntouchable,
AIPlayTagType.FanfareSummonHandCard,
AIPlayTagType.PlaySummonHandCard,
AIPlayTagType.FanfareHandBuff,
AIPlayTagType.PlayHandBuff,
AIPlayTagType.FanfareForceTargeting,
AIPlayTagType.PlayChangeCost,
AIPlayTagType.FanfareChangeCost,
AIPlayTagType.PlaySelect,
AIPlayTagType.FanfareSelect,
AIPlayTagType.PlayHandSelect,
AIPlayTagType.FanfareHandSelect,
AIPlayTagType.PlayNotBeAttacked,
AIPlayTagType.FanfareNotBeAttacked,
AIPlayTagType.PlayAttackableCount,
AIPlayTagType.FanfareAttackableCount,
AIPlayTagType.PlayRemoveSkill,
AIPlayTagType.FanfareRemoveSkill,
AIPlayTagType.PlayModifyConsumeEp,
AIPlayTagType.FanfareModifyConsumeEp,
AIPlayTagType.PlayEvo,
AIPlayTagType.FanfareEvo,
AIPlayTagType.PlayBonusInSimulation,
AIPlayTagType.FanfareBonusInSimulation,
AIPlayTagType.FanfareRemoveGuard,
AIPlayTagType.FusionMetamorphose,
AIPlayTagType.PlayAddDeck,
AIPlayTagType.FanfareAddDeck
};
public List<TagCollectionWithTypeBase> TagDictionary { get; protected set; }
public AIAttachedTagCollection AttachedTags { get; private set; }
public AIRemovedTagCollection RemovedTagCollection { get; private set; }
public List<int> ReferringOtherInplayIds { get; private set; }
public int Count
{
get
{
if (TagDictionary != null)
{
return TagDictionary.Count;
}
return 0;
}
}
public PuppetAttackTagCollection PuppetAttackTags => GetTagCollection<PuppetAttackTagCollection>(TagCollectionType.PuppetAttack);
public DamagedTagCollection DamagedTags => GetTagCollection<DamagedTagCollection>(TagCollectionType.WhenDamaged);
public OtherDamagedTagCollection OtherDamagedTags => GetTagCollection<OtherDamagedTagCollection>(TagCollectionType.WhenOtherDamaged);
public AttackTagCollection AttackTags => GetTagCollection<AttackTagCollection>(TagCollectionType.WhenAttack);
public OtherAttackTagCollection OtherAttackTags => GetTagCollection<OtherAttackTagCollection>(TagCollectionType.WhenOtherAttack);
public BreakTagCollection BreakTags => GetTagCollection<BreakTagCollection>(TagCollectionType.WhenBreak);
public AfterAttackTagCollection AfterAttackTags => GetTagCollection<AfterAttackTagCollection>(TagCollectionType.WhenAfterAttack);
public SummonTagCollection SummonTags => GetTagCollection<SummonTagCollection>(TagCollectionType.WhenSummon);
public OtherSummonTagCollection OtherSummonTags => GetTagCollection<OtherSummonTagCollection>(TagCollectionType.WhenOtherSummon);
public FanfareTagCollection FanfareTags => GetTagCollection<FanfareTagCollection>(TagCollectionType.Fanfare);
public PlayTagCollection PlayTags => GetTagCollection<PlayTagCollection>(TagCollectionType.Play);
public LastwordTagCollection LastwordTags => GetTagCollection<LastwordTagCollection>(TagCollectionType.Lastword);
public LeaveTagCollection LeaveTags => GetTagCollection<LeaveTagCollection>(TagCollectionType.WhenLeave);
public OtherLeaveTagCollection OtherLeaveTags => GetTagCollection<OtherLeaveTagCollection>(TagCollectionType.WhenOtherLeave);
public BounceTagCollection BounceTags => GetTagCollection<BounceTagCollection>(TagCollectionType.WhenBounce);
public TurnStartTagCollection TurnStartTags => GetTagCollection<TurnStartTagCollection>(TagCollectionType.WhenTurnStart);
public TurnEndTagCollection TurnEndTags => GetTagCollection<TurnEndTagCollection>(TagCollectionType.WhenTurnEnd);
public AfterClashTagCollection AfterClashTags => GetTagCollection<AfterClashTagCollection>(TagCollectionType.WhenAfterClash);
public EvoTagCollection EvoTags => GetTagCollection<EvoTagCollection>(TagCollectionType.WhenEvo);
public OtherEvoTagCollection OtherEvoTags => GetTagCollection<OtherEvoTagCollection>(TagCollectionType.WhenOtherEvo);
public SelfAndOtherEvoTagCollection SelfAndOtherEvoTags => GetTagCollection<SelfAndOtherEvoTagCollection>(TagCollectionType.WhenSelfAndOtherEvo);
public HealTagCollection HealTags => GetTagCollection<HealTagCollection>(TagCollectionType.WhenHeal);
public DiscardedTagCollection DiscardedTags => GetTagCollection<DiscardedTagCollection>(TagCollectionType.WhenDiscarded);
public AfterDiscardTagCollection AfterDiscardTags => GetTagCollection<AfterDiscardTagCollection>(TagCollectionType.WhenAfterDiscard);
public BuffTriggerTagCollection BuffTriggerTags => GetTagCollection<BuffTriggerTagCollection>(TagCollectionType.WhenBuff);
public BanishTagCollection BanishTags => GetTagCollection<BanishTagCollection>(TagCollectionType.WhenBanish);
public OtherBanishTagCollection OtherBanishTags => GetTagCollection<OtherBanishTagCollection>(TagCollectionType.WhenOtherBanish);
public GetOnTriggerTagCollection GetOnTriggerTags => GetTagCollection<GetOnTriggerTagCollection>(TagCollectionType.WhenGetOn);
public WhenGetOffTagCollection WhenGetOffTags => GetTagCollection<WhenGetOffTagCollection>(TagCollectionType.WhenGetOff);
public ActivateCountTagCollection ActivateCountTags => GetTagCollection<ActivateCountTagCollection>(TagCollectionType.ActivateCount);
public ClashBonusTagCollection ClashBonusTags => GetTagCollection<ClashBonusTagCollection>(TagCollectionType.ClashBonus);
public ReincarnationSimulationTagCollection ReincarnationSimulationTags => GetTagCollection<ReincarnationSimulationTagCollection>(TagCollectionType.Reincarnation);
public CantBeAttackedTagCollection CantBeAttackedTags => GetTagCollection<CantBeAttackedTagCollection>(TagCollectionType.CantBeAttacked);
public ChoiceTagCollection ChoiceTags => GetTagCollection<ChoiceTagCollection>(TagCollectionType.Choice);
public ChangeInplayTagCollection ChangeInplayTags => GetTagCollection<ChangeInplayTagCollection>(TagCollectionType.WhenChangeInplay);
public EvolveToOtherTagCollection EvolveToOtherTags => GetTagCollection<EvolveToOtherTagCollection>(TagCollectionType.EvolveToOther);
public OtherPlayTagCollection OtherPlayTags => GetTagCollection<OtherPlayTagCollection>(TagCollectionType.WhenOtherPlay);
public BuffBonusTagCollection BuffBonusTags => GetTagCollection<BuffBonusTagCollection>(TagCollectionType.BuffBonus);
public EvolvedResidentTagCollection EvolvedResidentTags => GetTagCollection<EvolvedResidentTagCollection>(TagCollectionType.EvolvedResident);
public GenerateTagCollection GenerateTags => GetTagCollection<GenerateTagCollection>(TagCollectionType.GenerateTag);
public BounceBonusTagCollection BounceBonusTags => GetTagCollection<BounceBonusTagCollection>(TagCollectionType.BounceBonus);
public PriorityTagCollection PriorityTags => GetTagCollection<PriorityTagCollection>(TagCollectionType.Priority);
public PlayBonusTagCollection PlayBonusTags => GetTagCollection<PlayBonusTagCollection>(TagCollectionType.PlayBonus);
public PlayBonusRateTagCollection PlayBonusRateTags => GetTagCollection<PlayBonusRateTagCollection>(TagCollectionType.PlayBonusRate);
public FanfareBonusTagCollection FanfareBonusTags => GetTagCollection<FanfareBonusTagCollection>(TagCollectionType.FanfareBonus);
public IgnoreFanfareBonusTagCollection IgnoreFanfareBonusTags => GetTagCollection<IgnoreFanfareBonusTagCollection>(TagCollectionType.IgnoreFanfareBonus);
public HandPlusTagCollection HandPlusTags => GetTagCollection<HandPlusTagCollection>(TagCollectionType.HandPlus);
public AllyPlayBonusTagCollection AllyPlayBonusTags => GetTagCollection<AllyPlayBonusTagCollection>(TagCollectionType.AllyPlayBonus);
public EnemyPlayBonusTagCollection EnemyPlayBonusTags => GetTagCollection<EnemyPlayBonusTagCollection>(TagCollectionType.EnemyPlayBonus);
public CostBonusTagCollection CostBonusTags => GetTagCollection<CostBonusTagCollection>(TagCollectionType.CostBonus);
public PlayDrawTagCollection PlayDrawTags => GetTagCollection<PlayDrawTagCollection>(TagCollectionType.PlayDraw);
public PlayLimitTagCollection PlayLimitTags => GetTagCollection<PlayLimitTagCollection>(TagCollectionType.PlayLimit);
public PlayPtnBonusTagCollection PlayptnBonusTags => GetTagCollection<PlayPtnBonusTagCollection>(TagCollectionType.PlayptnBonus);
public AttackBonusTagCollection AttackBonusTags => GetTagCollection<AttackBonusTagCollection>(TagCollectionType.AttackBonus);
public BattleBonusTagCollection BattleBonusTags => GetTagCollection<BattleBonusTagCollection>(TagCollectionType.BattleBonus);
public MemberBattleBonusTagCollection MemberBattleBonusTags => GetTagCollection<MemberBattleBonusTagCollection>(TagCollectionType.MemberBattleBonus);
public EnemyBattleBonusTagCollection EnemyBattleBonusTags => GetTagCollection<EnemyBattleBonusTagCollection>(TagCollectionType.EnemyBattleBonus);
public BattleBonusRateTagCollection BattleBonusRateTags => GetTagCollection<BattleBonusRateTagCollection>(TagCollectionType.BattleBonusRate);
public MemberBattleBonusRateTagCollection MemberBattleBonusRateTags => GetTagCollection<MemberBattleBonusRateTagCollection>(TagCollectionType.MemberBattleBonusRate);
public EnemyBattleBonusRateTagCollection EnemyBattleBonusRateTags => GetTagCollection<EnemyBattleBonusRateTagCollection>(TagCollectionType.EnemyBattleBonusRate);
public EvoBonusTagCollection EvoBonusTags => GetTagCollection<EvoBonusTagCollection>(TagCollectionType.EvoBonus);
public MemberEvoBonusTagCollection MemberEvoBonusTags => GetTagCollection<MemberEvoBonusTagCollection>(TagCollectionType.MemberEvoBonus);
public EnemyEvoBonusTagCollection EnemyEvoBonusTags => GetTagCollection<EnemyEvoBonusTagCollection>(TagCollectionType.EnemyEvoBonus);
public IgnoreBreakTagCollection IgnoreBreakTags => GetTagCollection<IgnoreBreakTagCollection>(TagCollectionType.IgnoreBreak);
public BreakBonusTagCollection BreakBonusTags => GetTagCollection<BreakBonusTagCollection>(TagCollectionType.BreakBonus);
public OtherBreakBonusTagCollection OtherBreakBonusTags => GetTagCollection<OtherBreakBonusTagCollection>(TagCollectionType.OtherBreakBonus);
public BanishBonusTagCollection BanishBonusTags => GetTagCollection<BanishBonusTagCollection>(TagCollectionType.BanishBonus);
public OtherBanishBonusTagCollection OtherBanishBonusTags => GetTagCollection<OtherBanishBonusTagCollection>(TagCollectionType.OtherBanishBonus);
public LeaveBonusTagCollection LeaveBonusTags => GetTagCollection<LeaveBonusTagCollection>(TagCollectionType.LeaveBonus);
public OtherLeaveBonusTagCollection OtherLeaveBonusTags => GetTagCollection<OtherLeaveBonusTagCollection>(TagCollectionType.OtherLeaveBonus);
public DiscardedBonusTagCollection DiscardedBonusTags => GetTagCollection<DiscardedBonusTagCollection>(TagCollectionType.DiscardedBonus);
public PreprocessTagCollection PreprocessTags => GetTagCollection<PreprocessTagCollection>(TagCollectionType.Preprocess);
public ReanimateBonusTagCollection ReanimateBonusTags => GetTagCollection<ReanimateBonusTagCollection>(TagCollectionType.ReanimateBonus);
public ReanimateEvoTagCollection ReanimateEvoTags => GetTagCollection<ReanimateEvoTagCollection>(TagCollectionType.ReanimateEvo);
public BreakFirstTagCollection BreakFirstTags => GetTagCollection<BreakFirstTagCollection>(TagCollectionType.BreakFirst);
public BreakLastTagCollection BreakLastTags => GetTagCollection<BreakLastTagCollection>(TagCollectionType.BreakLast);
public BreakBeforePlayTagCollection BreakBeforePlayTags => GetTagCollection<BreakBeforePlayTagCollection>(TagCollectionType.BreakBeforePlay);
public FusionTagCollection FusionTags => GetTagCollection<FusionTagCollection>(TagCollectionType.Fusion);
public FusionMetamorphoseTagCollection FusionMetamorphoseTags => GetTagCollection<FusionMetamorphoseTagCollection>(TagCollectionType.FusionMetamorphose);
public FirstEvoTagCollection FirstEvoTags => GetTagCollection<FirstEvoTagCollection>(TagCollectionType.FirstEvo);
public PlayPlusTagCollection PlayPlusTags => GetTagCollection<PlayPlusTagCollection>(TagCollectionType.PlayPlus);
public PlayoutBonusTagCollection PlayoutBonusTags => GetTagCollection<PlayoutBonusTagCollection>(TagCollectionType.PlayoutBonus);
public OtherPlayoutBonusTagCollection OtherPlayoutBonusTags => GetTagCollection<OtherPlayoutBonusTagCollection>(TagCollectionType.OtherPlayoutBonus);
public HandBonusTagCollection HandBonusTags => GetTagCollection<HandBonusTagCollection>(TagCollectionType.HandBonus);
public FusionBonusTagCollection FusionBonusTags => GetTagCollection<FusionBonusTagCollection>(TagCollectionType.FusionBonus);
public FusionDrawTagCollection FusionDrawTags => GetTagCollection<FusionDrawTagCollection>(TagCollectionType.FusionDraw);
public CondChoiceTagCollection CondChoiceTags => GetTagCollection<CondChoiceTagCollection>(TagCollectionType.CondChoice);
public AddCardToPlayoutPlayPtnTagCollection AddCardToPlayoutPlayPtnTags => GetTagCollection<AddCardToPlayoutPlayPtnTagCollection>(TagCollectionType.AddCardToPlayoutPlayPtn);
public NoInstantAttackTagCollection NoInstantAttackTags => GetTagCollection<NoInstantAttackTagCollection>(TagCollectionType.NoInstantAttack);
public EmoteTagCollection EmoteTags => GetTagCollection<EmoteTagCollection>(TagCollectionType.Emote);
public EvoHandPlusTagCollection EvoHandPlusTags => GetTagCollection<EvoHandPlusTagCollection>(TagCollectionType.EvoHandPlus);
public NoNormalEvoTagCollection NoNormalEvoTags => GetTagCollection<NoNormalEvoTagCollection>(TagCollectionType.NoNormalEvo);
public PlagueCityTagCollection PlagueCityTags => GetTagCollection<PlagueCityTagCollection>(TagCollectionType.PlagueCity);
public RemoveByDestroyTagCollection RemoveByDestroyTags => GetTagCollection<RemoveByDestroyTagCollection>(TagCollectionType.RemoveByDestroy);
public SetAITribeTagCollection SetAITribeTags => GetTagCollection<SetAITribeTagCollection>(TagCollectionType.SetAITribe);
public PlaySkipTagCollection PlaySkipTags => GetTagCollection<PlaySkipTagCollection>(TagCollectionType.PlaySkip);
public GiveSkillTagCollection GiveSkillTags => GetTagCollection<GiveSkillTagCollection>(TagCollectionType.GiveSkill);
public ForceImmediateAttackTagCollection ForceImmediateAttackTags => GetTagCollection<ForceImmediateAttackTagCollection>(TagCollectionType.ForceImmediateAttack);
public RemoveSkillTagCollection RemoveSkillTags => GetTagCollection<RemoveSkillTagCollection>(TagCollectionType.RemoveSkill);
public OneMoreLastwordTagCollection OneMoreLastwordTags => GetTagCollection<OneMoreLastwordTagCollection>(TagCollectionType.OneMoreLastword);
public NoSkipAttackTagCollection NoSkipAttackTags => GetTagCollection<NoSkipAttackTagCollection>(TagCollectionType.NoSkipAttack);
public ResonanceTagCollection ResonanceTags => GetTagCollection<ResonanceTagCollection>(TagCollectionType.WhenResonance);
public AttackByLifeTagCollection AttackByLifeTags => GetTagCollection<AttackByLifeTagCollection>(TagCollectionType.AttackByLife);
public FixedCostTagCollection FixedCostTags => GetTagCollection<FixedCostTagCollection>(TagCollectionType.FixedCost);
public ForceBerserkTagCollection ForceBerserkTags => GetTagCollection<ForceBerserkTagCollection>(TagCollectionType.ForceBerserk);
public GetOnTagCollection GetOnTags => GetTagCollection<GetOnTagCollection>(TagCollectionType.GetOn);
public ModifyHealTagCollection ModifyHealTags => GetTagCollection<ModifyHealTagCollection>(TagCollectionType.ModifyHeal);
public PlayptnBaseStatsRateTagCollection PlayptnBaseStatsRateTags => GetTagCollection<PlayptnBaseStatsRateTagCollection>(TagCollectionType.PlayptnBaseStatsRate);
public RallyCountPlusTagCollection RallyCountPlusTags => GetTagCollection<RallyCountPlusTagCollection>(TagCollectionType.RallyCountPlus);
public AttackableClassTagCollection AttackableClassTags => GetTagCollection<AttackableClassTagCollection>(TagCollectionType.AttackableClass);
public WhenNecromanceTagCollection NecromanceTags => GetTagCollection<WhenNecromanceTagCollection>(TagCollectionType.WhenNecromance);
public TargetTagCollection TargetTags => GetTagCollection<TargetTagCollection>(TagCollectionType.Target);
public IgnoreTargetTagCollection IgnoreTargetTags => GetTagCollection<IgnoreTargetTagCollection>(TagCollectionType.IgnoreTarget);
public PlayoutNextTurnTagCollection PlayoutNextTurnTags => GetTagCollection<PlayoutNextTurnTagCollection>(TagCollectionType.PlayoutNextTurn);
private T GetTagCollection<T>(TagCollectionType type) where T : TagCollection
{
for (int i = 0; i < Count; i++)
{
TagCollection collection = TagDictionary[i].Collection;
if (collection.Type == type)
{
return collection as T;
}
}
return null;
}
public AITagCollectionContainer()
{
_holdingTagTypes = null;
_holdingTagCollectionTypes = null;
TagDictionary = null;
AttachedTags = new AIAttachedTagCollection();
RemovedTagCollection = new AIRemovedTagCollection();
}
public AITagCollectionContainer(AITagCollectionContainer container, AIVirtualCard owner)
{
if (container.Count <= 0)
{
_holdingTagTypes = null;
_holdingTagCollectionTypes = null;
TagDictionary = null;
AttachedTags = new AIAttachedTagCollection();
RemovedTagCollection = new AIRemovedTagCollection();
return;
}
_holdingTagTypes = new List<AIPlayTagType>();
_holdingTagCollectionTypes = new List<TagCollectionType>();
TagDictionary = new List<TagCollectionWithTypeBase>();
for (int i = 0; i < container.Count; i++)
{
TagCollectionWithTypeBase tagCollectionWithTypeBase = container.TagDictionary[i];
TagDictionary.Add(tagCollectionWithTypeBase.Clone());
tagCollectionWithTypeBase.RegisterTypes(_holdingTagTypes);
_holdingTagCollectionTypes.Add(tagCollectionWithTypeBase.Collection.Type);
}
AttachedTags = container.AttachedTags.Clone();
RemovedTagCollection = container.RemovedTagCollection.Clone();
CreateFixedUseCostListWhenInit(owner, owner.SelfField);
}
public virtual void InitTags(AIVirtualCard owner, AIParamQuery query)
{
if (owner.IsCountdownAmulet)
{
AIPlayTag tag = AIPlayTagInitializingUtility.CreateTurnStartSubtractCountdownTagForCountdownAmulet();
AddTag(tag, owner, null);
}
int tagCount = query.GetTagCount(owner);
for (int i = 0; i < tagCount; i++)
{
AIPlayTag tag2 = query.GetTag(owner, i);
AddTag(tag2, owner, null);
}
CreateFixedUseCostListWhenInit(owner, owner.SelfField);
}
protected void CreateFixedUseCostListWhenInit(AIVirtualCard owner, AIVirtualField field)
{
if (HasTagCollection(TagCollectionType.FixedCost))
{
FixedCostTags.CreateFixedUseCostLists(owner, field);
}
}
public TagCollectionWithTypeBase AddTag(AIPlayTag tag, AIVirtualCard owner, AISituationInfo situation)
{
if (_holdingTagTypes == null)
{
_holdingTagTypes = new List<AIPlayTagType>();
}
if (TagDictionary == null)
{
TagDictionary = new List<TagCollectionWithTypeBase>();
}
TagCollectionWithTypeBase ownerTagCollectionWithTypes = GetOwnerTagCollectionWithTypes(tag.Type);
if (ownerTagCollectionWithTypes == null)
{
return null;
}
ownerTagCollectionWithTypes.AddTag(tag);
if (!_holdingTagTypes.Contains(tag.Type))
{
_holdingTagTypes.Add(tag.Type);
}
UpdateReferringOtherInplayIds(tag);
ownerTagCollectionWithTypes?.Collection.ExecuteWhenAddTag(owner, owner.SelfField, tag, situation);
return ownerTagCollectionWithTypes;
}
public void RemoveOneTagWithUpdatingFieldCardList(AIVirtualCard owner, AIPlayTag removingTag, AIVirtualField field)
{
if (_holdingTagTypes == null || !_holdingTagTypes.Contains(removingTag.Type))
{
return;
}
TagCollectionWithTypeBase ownerTagCollectionWithTypes = GetOwnerTagCollectionWithTypes(removingTag.Type);
if (ownerTagCollectionWithTypes.RemoveOneTag(owner, field, removingTag))
{
_holdingTagTypes.Remove(removingTag.Type);
if (ownerTagCollectionWithTypes is TagCollectionWithSingleType || ownerTagCollectionWithTypes.IsEmpty())
{
TagDictionary.Remove(ownerTagCollectionWithTypes);
_holdingTagCollectionTypes.Remove(ownerTagCollectionWithTypes.Collection.Type);
}
}
}
public void RemoveAllTagWithUpdatingFieldCardList(AIVirtualCard owner, AIVirtualField field, AISituationInfo situation)
{
if (TagDictionary == null || Count <= 0)
{
if (AttachedTags != null)
{
AttachedTags.RemoveAllAttachedTagInformation(situation);
}
return;
}
for (int num = Count - 1; num >= 0; num--)
{
TagCollectionWithTypeBase tagCollectionWithTypeBase = TagDictionary[num];
if (!tagCollectionWithTypeBase.IsUnderManagement(AIPlayTagType.PuppetAttack))
{
tagCollectionWithTypeBase.RemoveTypes(_holdingTagTypes);
_holdingTagCollectionTypes.Remove(tagCollectionWithTypeBase.Collection.Type);
tagCollectionWithTypeBase.RemoveAllTags(owner, field);
TagDictionary.Remove(tagCollectionWithTypeBase);
}
}
AttachedTags.RemoveAllAttachedTagInformation(situation);
}
public void AttachTag(AIAttachedTagInformation info, AIVirtualCard owner, AISituationInfo situation)
{
AttachedTags.AddAttachedTagInformation(info);
AddTag(info.Tag, owner, situation);
owner.SelfField.CardListSet.TagClassificationWhenAttachTag(owner, info.Tag);
}
public void CreateChoiceBraveTag(AIVirtualCard leader)
{
if (!leader.IsLeader || leader.IsAlly)
{
AIConsoleUtility.LogError("AITagCollectionContainer.CreateChoiceBraveTag() error!! Card is not leader!!!!!");
return;
}
AIPlayTag aIPlayTag = new AIPlayTag();
AIPlayTagAsset asset = new AIPlayTagAsset
{
Type = "choiceBrave",
Arg = "",
Condition = ""
};
aIPlayTag.InitFromTextAsset(asset);
AIAttachedTagInformation info = new AIAttachedTagInformation(aIPlayTag, AIScriptTokenArgType.NONE, leader, leader);
AttachTag(info, leader, null);
}
private TagCollectionWithTypeBase GetOwnerTagCollectionWithTypes(AIPlayTagType type)
{
for (int i = 0; i < Count; i++)
{
TagCollectionWithTypeBase tagCollectionWithTypeBase = TagDictionary[i];
if (tagCollectionWithTypeBase.IsUnderManagement(type))
{
return tagCollectionWithTypeBase;
}
}
TagCollectionWithTypeBase tagCollectionWithTypeBase2 = TagCollectionWithTypeCreator.Create(type);
if (tagCollectionWithTypeBase2 != null)
{
TagDictionary.Add(tagCollectionWithTypeBase2);
_holdingTagCollectionTypes = AIParamQuery.AddElementToList(tagCollectionWithTypeBase2.Collection.Type, _holdingTagCollectionTypes, isBlockDuplicate: true);
}
return tagCollectionWithTypeBase2;
}
public bool HasWhenPlayDestroyPlayPtnTags()
{
if (_holdingTagTypes == null || _holdingTagTypes.Count <= 0)
{
return false;
}
if (!_holdingTagTypes.Contains(AIPlayTagType.PlaySummonHandCard))
{
return _holdingTagTypes.Contains(AIPlayTagType.FanfareSummonHandCard);
}
return true;
}
public bool HasTag(AIPlayTagType type)
{
if (_holdingTagTypes != null)
{
return _holdingTagTypes.Contains(type);
}
return false;
}
public bool HasTagCollection(TagCollectionType type)
{
if (_holdingTagCollectionTypes != null)
{
return _holdingTagCollectionTypes.Contains(type);
}
return false;
}
public bool HasAnyTag(AIPlayTagType[] typeArray)
{
if (_holdingTagTypes == null || _holdingTagTypes.Count <= 0)
{
return false;
}
for (int i = 0; i < _holdingTagTypes.Count; i++)
{
AIPlayTagType value = _holdingTagTypes[i];
if (Array.IndexOf(typeArray, value) >= 0)
{
return true;
}
}
return false;
}
private void UpdateReferringOtherInplayIds(AIPlayTag tag)
{
if (Array.IndexOf(DISABLED_TAG_TYPES_INPLAY, tag.Type) >= 0)
{
return;
}
List<int> referringOtherInplayIds = tag.ArgumentExpressions.GetReferringOtherInplayIds();
List<int> referringIds = tag.ConditionExpressions.ReferringIds;
if (referringOtherInplayIds != null)
{
if (ReferringOtherInplayIds == null)
{
ReferringOtherInplayIds = new List<int>();
}
ReferringOtherInplayIds.AddRange(referringOtherInplayIds);
}
if (referringIds != null)
{
if (ReferringOtherInplayIds == null)
{
ReferringOtherInplayIds = new List<int>();
}
ReferringOtherInplayIds.AddRange(referringIds);
}
}
public ulong GetHash(AIVirtualCard card)
{
ulong num = 0uL;
int num2 = 0;
for (int i = 0; i < Count; i++)
{
TagCollection collection = TagDictionary[i].Collection;
for (int j = 0; j < collection.TagList.Count; j++)
{
AIPlayTag aIPlayTag = collection.TagList[j];
if (!card.IsOnField || Array.IndexOf(DISABLED_TAG_TYPES_INPLAY, aIPlayTag.Type) < 0)
{
num += collection.TagList[j].Hash * PRIME_NUMBERS_FOR_HASH_CALCULATION[num2];
num2 = ((num2 < PRIME_NUMBERS_FOR_HASH_CALCULATION.Length - 1) ? (num2 + 1) : 0);
}
}
}
return num;
}
public AITokenIdCollection GetAllRegisterTokenPoolInfo(AIVirtualCard owner)
{
if (TagDictionary == null || TagDictionary.Count <= 0)
{
return null;
}
AITokenIdCollection aITokenIdCollection = null;
for (int i = 0; i < TagDictionary.Count; i++)
{
TagCollection collection = TagDictionary[i].Collection;
if (collection != null && collection.HasTag)
{
for (int j = 0; j < collection.TagList.Count; j++)
{
AITokenIdCollection allRegisterTokenPoolInfo = collection.TagList[j].ArgumentExpressions.GetAllRegisterTokenPoolInfo(owner);
aITokenIdCollection = AITokenIdCollection.CombineTwoCollection(aITokenIdCollection, allRegisterTokenPoolInfo);
}
}
}
return aITokenIdCollection;
}
}

Some files were not shown because too many files have changed in this diff Show More