using System; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Wizard; public class AIVirtualCard { public class AIVirtualBanishInfo { public int Turn { get; private set; } public bool IsCardOwnerTurn { get; private set; } public BattleCardBase.BanishInfo.BanishPlace Place { get; private set; } public AIVirtualBanishInfo(int turn, bool isCardOwnerTurn, BattleCardBase.BanishInfo.BanishPlace place) { Turn = turn; IsCardOwnerTurn = isCardOwnerTurn; Place = place; } } protected AIVirtualField _field; public bool IsFirstTurn; public int BaseCost; public int Cost; public int RealCost; public int PlayedCost = -1; public List EnhanceCostList; public List AccelerateCostList; public List CrystalizeCostList; public List ChoiceTransformCostList; public int LastHealAmount; public int AttackableCount; public bool IsSummonDrunkenness; private bool IsDebuffCantEvolve; public bool IsCantAttackAll; public bool IsSkillCantAttackClass; public bool IsSkillCantAttackUnit; public bool IsSkillCantAtkUnitNotHasGuard; private List _cannotAttackInfoList; private bool _isCantUnderAttack; public bool IsSkillCantUnderAnyAttack; public bool IsUseEvo; public bool IsGuard; public bool IsIgnoreGuard; public bool IsSkillLost; public bool IsSelfTurn; public bool IsNotAttackYet; public bool IsMinimumBreakBonus; public bool IsRobbedLastword; public bool IsNotConsumeEp; public bool IsSkillSummoned; public bool HasAnySkill; public bool HasSkillNecromance; public bool IsPlayer; public bool IsForceTargeting; public bool IsUnbanishable; public bool IsMetamorphosed; private int UntouchableCount; public AIBarrierInfoCollection BarrierInfoCollection; public bool IsIndestructible; public bool IsIndependent; private int _destroyByBanishCount; private int _bounceByBanishCount; private int _banishByDestroyCount; public int AttackByLifeCount; public bool IsSneak; private List _giveSneakTagList; public bool IsKiller; public bool IsDrain; public bool IsRush; public bool IsQuick; public bool IsDestroyWhenAttack; public bool HasSpellboost; public int SpellboostCount; public int RealSpellboostCount; private int _originalWhiteRitualCount; public bool IsStackWhiteRitual; public int TempAtkBuff; public int TempLifeBuff; public bool HasAfterAttackHeal; public bool IsRecoveredAttackableCount; public bool IsAmulet; public bool IsCountdownAmulet; public int ChantCount; public bool IsSpell; public bool IsUnit; public bool IsLeader; protected bool _isCompletedRemove; public bool IsDead; private AIHandPlayEstimator _handPlayEstimator; protected List _tribeList; public readonly AIVirtualAttackInfo AttackLeaderSituation; public int GetOnCardId; public AIVirtualCard GetOffCard; public AIVirtualCard BeforeTransformedCardForSimulation; public List PermanentAITribeList; public int ReferringSelfCount; protected readonly ulong[] PRIME_NUMBERS_FOR_CLAN = new ulong[12] { 282143uL, 282157uL, 282167uL, 282221uL, 282229uL, 282239uL, 282241uL, 282253uL, 282281uL, 282287uL, 282299uL, 282307uL }; protected readonly ulong[] PRIME_NUMBERS_FOR_TRIBE = new ulong[13] { 47521uL, 47527uL, 47533uL, 47543uL, 47563uL, 47569uL, 47581uL, 47591uL, 47599uL, 47609uL, 47623uL, 47629uL, 47639uL }; public AIVirtualField SelfField => _field; public AICardData AIData { get; private set; } public BattlePlayerBase SelfBattlePlayer { get; protected set; } public int BaseId { get { return CardParameter.BaseId; } protected set { CardParameter.BaseId = value; } } public int CardIndex { get; protected set; } public string CardName => CardParameter.CardName; public int EvolutionAttack => CardParameter.Attack + CardParameter.EvoAttackPlus; public int EvolutionLife => CardParameter.Life + CardParameter.EvoLifePlus; public CardBasePrm.ClanType Clan { get; protected set; } public bool IsEvolution { get; private set; } public bool IsPreviousTurnAttacked { get; private set; } public bool IsOnField { get; protected set; } public bool IsInHand { get; protected set; } public BattleCardBase BaseCard { get; protected set; } public SkillCollectionBase BattleSkills { get; protected set; } public List BattleSkillHashList { get; protected set; } public AIVirtualCardParameter BaseParameter { get; private set; } public AIVirtualCardParameter OtherEvolveParameter { get; private set; } public AIVirtualCardParameter CardParameter { get { if (OtherEvolveParameter != null) { return OtherEvolveParameter; } return BaseParameter; } } public int Life { get { return CardParameter.Life; } set { CardParameter.Life = value; } } public int MaxLife { get { return CardParameter.MaxLife; } set { CardParameter.MaxLife = value; } } public int DefLife { get { return CardParameter.DefLife; } set { CardParameter.DefLife = value; } } public int LastLife { get { return CardParameter.LastLife; } set { CardParameter.LastLife = value; } } public int Attack { get { return CardParameter.Attack; } set { CardParameter.Attack = value; } } public int MaxAttackableCount { get { return CardParameter.MaxAttackableCount; } set { CardParameter.MaxAttackableCount = value; } } public int DefaultLife { get { return CardParameter.DefaultLife; } set { CardParameter.DefaultLife = value; } } public int DefaultAttack { get { return CardParameter.DefaultAttack; } set { CardParameter.DefaultAttack = value; } } public int DefaultMaxAttackableCount { get { return CardParameter.DefaultMaxAttackableCount; } set { CardParameter.DefaultMaxAttackableCount = value; } } public bool IsAttacked => AttackableCount < MaxAttackableCount; public bool IsUntouchable => UntouchableCount > 0; public int DestroyedTurn { get; protected set; } public int EvoAttackPlus { get { return CardParameter.EvoAttackPlus; } private set { CardParameter.EvoAttackPlus = value; } } public int EvoLifePlus { get { return CardParameter.EvoLifePlus; } private set { CardParameter.EvoLifePlus = value; } } public int BuffCount { get; private set; } public AIBuffRecorderCollection BuffRecorderCollection { get; private set; } public int SelfTurnDamagedCount { get; private set; } public int OpponentTurnDamagedCount { get; private set; } public int HealCount { get; private set; } public bool IsAllShield { get { if (BarrierInfoCollection == null) { return false; } return BarrierInfoCollection.HasShieldAll; } } public bool IsDestroyByBanish => _destroyByBanishCount > 0; public bool IsBounceByBanish => _bounceByBanishCount > 0; public bool IsBanishByDestroy => _banishByDestroyCount > 0; public bool IsAttackByLife => AttackByLifeCount > 0; public bool IsLastword { get; private set; } public float Value { get; private set; } public float DefaultValue { get; private set; } public int WhiteRitualCount { get; protected set; } public bool IsAlly { get; protected set; } public bool DeadTurn { get; set; } public AITagCollectionContainer TagCollectionContainer { get; protected set; } public List ChildrenIndexList { get; private set; } public bool HasUnionBurst { get; private set; } public int UnionBurstCount { get; private set; } public bool HasSkyboundArt { get; private set; } public int SkyboundArtCount { get; private set; } public bool HasSuperSkyboundArt { get; private set; } public int SuperSkyboundArtCount { get; private set; } public bool IsFusionCard => TagCollectionContainer.HasTag(AIPlayTagType.Fusion); public bool IsFusionable { get; private set; } public AIVirtualFusionIngredientsInfo FusionIngredients { get; protected set; } public BeforeTransformVirtualCard BeforeTransformCard { get; private set; } public bool IsGetOn => GetOnCardId > 0; public bool CantBeFocusedSkill { get { if (!IsSneak) { return IsUntouchable; } return true; } } public AIVirtualBanishInfo BanishedInfo { get; private set; } public bool IsTribe(CardBasePrm.TribeType tribe) { if (_tribeList == null) { return false; } for (int i = 0; i < _tribeList.Count; i++) { if (_tribeList[i] == tribe) { return true; } } return false; } public bool HasAnyTribe() { if (_tribeList == null) { return false; } for (int i = 0; i < _tribeList.Count; i++) { if (_tribeList[i] != CardBasePrm.TribeType.ALL) { return true; } } return false; } public AIVirtualCard() { } public AIVirtualCard(BattleCardBase card, AIVirtualField field) { _field = field; IsAlly = _field.AI.IsAllyCard(card); TagCollectionContainer = new AITagCollectionContainer(); BarrierInfoCollection = new AIBarrierInfoCollection(); InitializeFromBattleCardBase(card); InitializeAIParameter(); if (IsAlly && !IsLeader) { AttackLeaderSituation = new AIVirtualAttackInfo(this, _field.EnemyClass); } else { AttackLeaderSituation = null; } } public AIVirtualCard(AIVirtualCard virtualCard, AIVirtualField field) { _field = field; SelfBattlePlayer = virtualCard.SelfBattlePlayer; AIData = virtualCard.AIData; IsAlly = virtualCard.IsAlly; BaseCost = virtualCard.BaseCost; Cost = virtualCard.Cost; RealCost = virtualCard.RealCost; PlayedCost = virtualCard.PlayedCost; IsDead = virtualCard.IsDead; _isCompletedRemove = virtualCard._isCompletedRemove; ChildrenIndexList = virtualCard.ChildrenIndexList; IsPlayer = virtualCard.IsPlayer; BaseCard = virtualCard.BaseCard; CardIndex = virtualCard.CardIndex; BattleSkills = virtualCard.BattleSkills; BattleSkillHashList = virtualCard.BattleSkillHashList; BaseParameter = virtualCard.BaseParameter.Clone(); OtherEvolveParameter = ((virtualCard.OtherEvolveParameter != null) ? virtualCard.OtherEvolveParameter.Clone() : null); IsSpell = virtualCard.IsSpell; IsUnit = virtualCard.IsUnit; IsLeader = virtualCard.IsLeader; Clan = virtualCard.Clan; AttackableCount = virtualCard.AttackableCount; IsCantAttackAll = virtualCard.IsCantAttackAll; IsFirstTurn = virtualCard.IsFirstTurn; IsSummonDrunkenness = virtualCard.IsSummonDrunkenness; IsSkillCantAttackClass = virtualCard.IsSkillCantAttackClass; IsSkillCantAttackUnit = virtualCard.IsSkillCantAttackUnit; _cannotAttackInfoList = AIParamQuery.CloneList(virtualCard._cannotAttackInfoList); _isCantUnderAttack = virtualCard._isCantUnderAttack; IsSkillCantAtkUnitNotHasGuard = virtualCard.IsSkillCantAtkUnitNotHasGuard; IsGuard = virtualCard.IsGuard; IsSkillCantUnderAnyAttack = virtualCard.IsSkillCantUnderAnyAttack; IsIgnoreGuard = virtualCard.IsIgnoreGuard; IsSkillLost = virtualCard.IsSkillLost; IsSelfTurn = virtualCard.IsSelfTurn; IsNotAttackYet = virtualCard.IsNotAttackYet; IsMinimumBreakBonus = virtualCard.IsMinimumBreakBonus; IsRobbedLastword = virtualCard.IsRobbedLastword; IsNotConsumeEp = virtualCard.IsNotConsumeEp; IsSkillSummoned = virtualCard.IsSkillSummoned; HasAnySkill = virtualCard.HasAnySkill; IsOnField = virtualCard.IsOnField; IsInHand = virtualCard.IsInHand; IsUseEvo = virtualCard.IsUseEvo; IsEvolution = virtualCard.IsEvolution; IsPreviousTurnAttacked = virtualCard.IsPreviousTurnAttacked; IsIndestructible = virtualCard.IsIndestructible; IsIndependent = virtualCard.IsIndependent; IsMetamorphosed = virtualCard.IsMetamorphosed; IsLastword = virtualCard.IsLastword; IsSneak = virtualCard.IsSneak; _giveSneakTagList = AIParamQuery.CloneList(virtualCard._giveSneakTagList); IsKiller = virtualCard.IsKiller; IsDrain = virtualCard.IsDrain; IsRush = virtualCard.IsRush; IsQuick = virtualCard.IsQuick; IsDestroyWhenAttack = virtualCard.IsDestroyWhenAttack; IsRecoveredAttackableCount = virtualCard.IsRecoveredAttackableCount; IsForceTargeting = virtualCard.IsForceTargeting; IsUnbanishable = virtualCard.IsUnbanishable; UntouchableCount = virtualCard.UntouchableCount; IsDebuffCantEvolve = virtualCard.IsDebuffCantEvolve; _destroyByBanishCount = virtualCard._destroyByBanishCount; _bounceByBanishCount = virtualCard._bounceByBanishCount; _banishByDestroyCount = virtualCard._banishByDestroyCount; HasSpellboost = virtualCard.HasSpellboost; SpellboostCount = virtualCard.SpellboostCount; RealSpellboostCount = virtualCard.RealSpellboostCount; WhiteRitualCount = virtualCard.WhiteRitualCount; _originalWhiteRitualCount = virtualCard._originalWhiteRitualCount; IsStackWhiteRitual = virtualCard.IsStackWhiteRitual; AttackByLifeCount = virtualCard.AttackByLifeCount; TempAtkBuff = virtualCard.TempAtkBuff; TempLifeBuff = virtualCard.TempLifeBuff; BuffCount = virtualCard.BuffCount; if (virtualCard.BuffRecorderCollection != null) { BuffRecorderCollection = virtualCard.BuffRecorderCollection.Clone(); } SelfTurnDamagedCount = virtualCard.SelfTurnDamagedCount; OpponentTurnDamagedCount = virtualCard.OpponentTurnDamagedCount; HealCount = virtualCard.HealCount; HasAfterAttackHeal = virtualCard.HasAfterAttackHeal; DestroyedTurn = virtualCard.DestroyedTurn; ReferringSelfCount = virtualCard.ReferringSelfCount; TagCollectionContainer = new AITagCollectionContainer(virtualCard.TagCollectionContainer, this); BarrierInfoCollection = virtualCard.BarrierInfoCollection.Clone(); IsAmulet = virtualCard.IsAmulet; IsCountdownAmulet = virtualCard.IsCountdownAmulet; ChantCount = virtualCard.ChantCount; Value = virtualCard.Value; DefaultValue = virtualCard.DefaultValue; if (virtualCard._tribeList != null) { _tribeList = new List(virtualCard._tribeList); } IsFusionable = virtualCard.IsFusionable; if (virtualCard.FusionIngredients != null) { FusionIngredients = new AIVirtualFusionIngredientsInfo(virtualCard.FusionIngredients); } HasUnionBurst = virtualCard.HasUnionBurst; UnionBurstCount = virtualCard.UnionBurstCount; HasSkyboundArt = virtualCard.HasSkyboundArt; SkyboundArtCount = virtualCard.SkyboundArtCount; HasSuperSkyboundArt = virtualCard.HasSuperSkyboundArt; SuperSkyboundArtCount = virtualCard.SuperSkyboundArtCount; GetOnCardId = virtualCard.GetOnCardId; GetOffCard = virtualCard.GetOffCard; BeforeTransformCard = null; if (virtualCard.BeforeTransformCard != null) { BeforeTransformCard = new BeforeTransformVirtualCard(virtualCard.BeforeTransformCard, _field); } if (IsAlly && !IsLeader) { AttackLeaderSituation = new AIVirtualAttackInfo(this, _field.EnemyClass); } else { AttackLeaderSituation = null; } BanishedInfo = virtualCard.BanishedInfo; BeforeTransformedCardForSimulation = virtualCard.BeforeTransformedCardForSimulation; PermanentAITribeList = virtualCard.PermanentAITribeList; } public AIVirtualCard(AIVirtualField field, AIVirtualCardParameter baseParameter, AIVirtualCard evalInstantAttackOwner, bool isEvalRush) { _field = field; BaseParameter = baseParameter; OtherEvolveParameter = null; IsAlly = evalInstantAttackOwner.IsAlly; IsPlayer = evalInstantAttackOwner.IsPlayer; SelfBattlePlayer = evalInstantAttackOwner.SelfBattlePlayer; AIData = evalInstantAttackOwner.AIData; BaseCost = 0; Cost = 0; RealCost = 0; PlayedCost = 0; ChildrenIndexList = null; BaseCard = evalInstantAttackOwner.BaseCard; CardIndex = evalInstantAttackOwner.CardIndex; BattleSkills = evalInstantAttackOwner.BattleSkills; BattleSkillHashList = evalInstantAttackOwner.BattleSkillHashList; IsUnit = true; Clan = evalInstantAttackOwner.Clan; AttackableCount = BaseParameter.MaxAttackableCount; IsFirstTurn = true; IsSummonDrunkenness = false; IsSelfTurn = evalInstantAttackOwner.IsSelfTurn; IsNotAttackYet = true; IsMinimumBreakBonus = evalInstantAttackOwner.IsMinimumBreakBonus; HasAnySkill = evalInstantAttackOwner.HasAnySkill; IsOnField = true; IsRush = isEvalRush; IsQuick = !isEvalRush; _destroyByBanishCount = 0; _bounceByBanishCount = 0; _banishByDestroyCount = 0; SpellboostCount = 0; RealSpellboostCount = 0; WhiteRitualCount = 0; _originalWhiteRitualCount = 0; AttackByLifeCount = 0; TempAtkBuff = 0; TempLifeBuff = 0; BuffCount = 0; SelfTurnDamagedCount = 0; OpponentTurnDamagedCount = 0; HealCount = 0; DestroyedTurn = evalInstantAttackOwner.DestroyedTurn; ReferringSelfCount = 0; ChantCount = 0; UnionBurstCount = 0; SkyboundArtCount = 0; SuperSkyboundArtCount = 0; TagCollectionContainer = new AITagCollectionContainer(evalInstantAttackOwner.TagCollectionContainer, this); BarrierInfoCollection = new AIBarrierInfoCollection(); BuffRecorderCollection = null; if (evalInstantAttackOwner._tribeList != null) { _tribeList = new List(evalInstantAttackOwner._tribeList); } if (IsAlly && !IsLeader) { AttackLeaderSituation = new AIVirtualAttackInfo(this, _field.EnemyClass); } else { AttackLeaderSituation = null; } } protected virtual void InitializeFromBattleCardBase(BattleCardBase origin) { InitializeFromBattleCardBaseBasic(origin); SelfBattlePlayer = origin.SelfBattlePlayer; Value = 0f; DefaultValue = 0f; CardIndex = origin.Index; IsDead = origin.IsDead; IsPlayer = origin.IsPlayer; BattleSkills = origin.Skills; BattleSkillHashList = CardSkillHashUtility.GetSingleSkillHashStringList(BattleSkills); IsSkillSummoned = origin.SelfBattlePlayer.SkillSummonedCards != null && origin.SelfBattlePlayer.SkillSummonedCards.Any((BattleCardBase c) => c.Index == origin.Index); ISkillApplyInformation skillApplyInformation = origin.SkillApplyInformation; Cost = origin.Cost; RealCost = origin.Cost; PlayedCost = origin.PlayedCost; if (origin.Tribe != null && origin.Tribe.Count > 0) { for (int num = 0; num < origin.Tribe.Count; num++) { AppendTribe(origin.Tribe[num]); } } IsOnField = origin.IsInplay; IsInHand = origin.IsInHand; IsSelfTurn = origin.IsSelfTurn; IsFirstTurn = origin.IsFirstTurn; IsSummonDrunkenness = origin.IsSummonDrunkenness; IsCantAttackAll = origin.IsCantAttack; IsSkillCantAttackClass = skillApplyInformation.IsSkillCantAtkClass; IsSkillCantAttackUnit = skillApplyInformation.IsSkillCantAtkUnit; IsSkillCantAtkUnitNotHasGuard = skillApplyInformation.IsSkillCantAtkUnitNotHasGuard; IsSkillCantUnderAnyAttack = skillApplyInformation.NotBeAttackedInfoList.Count > 0; _isCantUnderAttack = skillApplyInformation.IsSneak || IsSkillCantUnderAnyAttack; IsIgnoreGuard = skillApplyInformation.IsIgnoreGuard; IsNotConsumeEp = origin.SelfBattlePlayer.CheckNotConsumeEpCard(origin); IsEvolution = IsUnit && origin.IsEvolution; IsPreviousTurnAttacked = IsUnit && origin.IsPreviousTurnAttacked; HasAnySkill = origin.HasAnySkill; HasSkillNecromance = origin.HasSkillNecromance; IsSkillLost = origin.IsSkillLost; IsLastword = origin.Skills._skillTimingInfo.IsWhenDestroy; IsSneak = IsUnit && skillApplyInformation.IsSneak; IsKiller = IsUnit && skillApplyInformation.IsKiller; IsDrain = IsUnit && skillApplyInformation.IsDrain; IsRush = IsUnit && skillApplyInformation.IsRush; IsQuick = skillApplyInformation.IsQuick; IsGuard = IsUnit && skillApplyInformation.IsGuard; IsIndestructible = skillApplyInformation.IndestructibleCount > 0; IsIndependent = skillApplyInformation.IndependentCount > 0; DestroyedTurn = origin.DestroyedTurn; UntouchableCount = skillApplyInformation.UntouchableCount; IsForceTargeting = skillApplyInformation.IsForceSkillTarget; IsUnbanishable = false; HasSpellboost = origin.HasSpellCharge; SpellboostCount = origin.SpellChargeCount; RealSpellboostCount = origin.SpellChargeCount; WhiteRitualCount = (IsAmulet ? skillApplyInformation.WhiteRitualCount : 0); _originalWhiteRitualCount = WhiteRitualCount; IsStackWhiteRitual = origin.HasSkillStackWhiteRitual; IsDebuffCantEvolve = skillApplyInformation.CantEvolutionList != null && skillApplyInformation.CantEvolutionList.Any((int f) => (f & Skill_cant_evolution.BIT_FLAG_EPUSE) != 0); _banishByDestroyCount = skillApplyInformation.BanishByDestroyCount; _destroyByBanishCount = skillApplyInformation.DestroyByBanishCount; _bounceByBanishCount = skillApplyInformation.ReturnByBanishCount; if (IsCountdownAmulet) { ChantCount = ((ChantFieldBattleCard)origin).ChantCount; } AttackableCount = (IsUnit ? origin.AttackableCount : 0); BuffCount = (IsUnit ? skillApplyInformation.BuffCount : 0); BuffRecorderCollection = (IsUnit ? new AIBuffRecorderCollection(skillApplyInformation.TurnBuffCountList) : null); SelfTurnDamagedCount = ((!IsAmulet) ? origin.DamagedCounter.SelfTurnDamage : 0); OpponentTurnDamagedCount = ((!IsAmulet) ? origin.DamagedCounter.OpponentTurnDamage : 0); HealCount = ((!IsAmulet && skillApplyInformation.HealList != null) ? skillApplyInformation.HealList.Count : 0); HasUnionBurst = origin.HasUnionBurst; if (HasUnionBurst) { UnionBurstCount = skillApplyInformation.UnionBurstCount; } HasSkyboundArt = origin.HasSkyboundArt; if (HasSkyboundArt) { SkyboundArtCount = skillApplyInformation.SkyboundArtCount; } HasSuperSkyboundArt = origin.HasSuperSkyboundArt; if (HasSuperSkyboundArt) { SuperSkyboundArtCount = skillApplyInformation.SuperSkyboundArtCount; } BeforeTransformCard = null; BattleCardBase.TransformInformation transformInfo = origin.TransformInfo; if (transformInfo.Type != BattleCardBase.TransformType.Metamorphose && transformInfo.OriginalCard != null) { BeforeTransformCard = new BeforeTransformVirtualCard(transformInfo.OriginalCard, _field); } if (skillApplyInformation.GetOnCards != null && skillApplyInformation.GetOnCards.Count > 0) { GetOnCardId = skillApplyInformation.GetOnCards[0].BaseParameter.BaseCardId; } if (origin.GetOffCards != null && origin.GetOffCards.Count > 0) { GetOffCard = new AIVirtualCard(origin.GetOffCards[0], _field); } IsFusionable = origin.IsFusionable; FusionIngredients = new AIVirtualFusionIngredientsInfo(); if (skillApplyInformation.FusionIngredients != null && skillApplyInformation.FusionIngredients.Count > 0) { FusionIngredients.CopyFusionIngredientsFromBattleCard(skillApplyInformation.FusionIngredients, _field); } ConvertBaseBanishInfo(origin.BanishedInfo); BeforeTransformedCardForSimulation = null; } protected void InitializeFromBattleCardBaseBasic(BattleCardBase origin) { BaseCard = origin; BaseCost = origin.BaseCost; Clan = origin.Clan; IsUnit = origin.IsUnit; IsSpell = origin.IsSpell; IsAmulet = origin.IsField; IsCountdownAmulet = origin.IsChantField; IsLeader = origin.IsClass; IsRecoveredAttackableCount = false; BaseParameter = new AIVirtualCardParameter(origin); OtherEvolveParameter = null; PermanentAITribeList = _field.GetReferenceTribe(BaseId); int referenceId = _field.GetReferenceId(origin.CardId); if (referenceId > 0) { BaseId = referenceId; } } protected virtual void InitializeAIParameter() { IsUseEvo = false; IsNotAttackYet = !IsAmulet; IsMinimumBreakBonus = false; IsRobbedLastword = false; IsDestroyWhenAttack = false; HasAfterAttackHeal = false; IsMetamorphosed = false; Value = 0f; DefaultValue = 0f; AttackByLifeCount = 0; TempAtkBuff = 0; TempLifeBuff = 0; ChildrenIndexList = null; } public void InitializeEnemyHandParameter() { IsAlly = false; IsInHand = true; IsOnField = false; } private void InitializeFollowerTags(AIParamQuery query) { BattleCardBase baseCard = BaseCard; if (IsSkillLost) { IsRobbedLastword = false; IsDestroyWhenAttack = false; HasAfterAttackHeal = false; } else { IsRobbedLastword = query.IsRobbedLastword(baseCard); IsDestroyWhenAttack = query.IsDestroyBeforeAttack(baseCard); TagCollectionContainer.InitTags(this, query); HasAfterAttackHeal = TagCollectionContainer.HasTag(AIPlayTagType.AfterAttackHeal); } } private void InitializeAmuletTags(AIParamQuery query) { if (!IsSkillLost) { TagCollectionContainer.InitTags(this, query); } } public virtual void InitializeTags(AIParamQuery query, AIAttachedTagCollection attachedTagCollection, AIRemovedTagCollection removedTagCollection) { AIData = query.SearchAICardData(this); if (IsAmulet) { InitializeAmuletTags(query); } else { InitializeFollowerTags(query); } attachedTagCollection?.AttachTagToReceiver(this); removedTagCollection?.RemoveTagFromCard(this); } public void InitAtSummonToken(AIVirtualCard parent, AISituationInfo situation, bool isSkillSummon, bool isUpdateTokenIndex = true) { AIPreprocessSimulationUtility.SimulatePreprocess(this, situation, _field, AIScriptTokenArgType.WHEN_SUMMON, isPseudo: false); IsOnField = true; if (isUpdateTokenIndex) { if (_field.IsLatestActionField) { if (IsAlly) { CardIndex = _field.AllyCardTotalNum; _field.AllyCardTotalNum++; } else { CardIndex = _field.EnemyCardTotalNum; _field.EnemyCardTotalNum++; } } else { CardIndex = _field.TokenIndex; _field.TokenIndex--; } } parent.AddChildren(CardIndex); AttackableCount = MaxAttackableCount; IsFirstTurn = true; IsSkillSummoned = isSkillSummon; if (IsUseEvo) { AttackableCount = 1; AIAutoEvolutionSimulationUtility.AutoEvolveSingle(this, _field, situation); } } public void PseudoInitAtSummonToken(AIVirtualCard parent, AISituationInfo situation, bool isSkillSummon) { IsOnField = true; AttackableCount = MaxAttackableCount; IsFirstTurn = true; IsSkillSummoned = isSkillSummon; if (IsUseEvo) { AttackableCount = ((AttackableCount <= 1) ? 1 : AttackableCount); AIAutoEvolutionSimulationUtility.AutoEvolveSingle(this, _field, situation); } } public void InitAtDrawToken(AIVirtualCard parent, AISituationInfo situation) { AIPreprocessSimulationUtility.SimulatePreprocess(this, situation, _field, AIScriptTokenArgType.TOKEN_DRAW, isPseudo: false); IsOnField = false; IsInHand = true; if (_field.IsLatestActionField) { if (IsAlly) { CardIndex = _field.AllyCardTotalNum; _field.AllyCardTotalNum++; } else { CardIndex = _field.EnemyCardTotalNum; _field.EnemyCardTotalNum++; } } else { CardIndex = _field.TokenIndex; _field.TokenIndex--; } parent.AddChildren(CardIndex); AddToHand(); } public void InitAtMetamorphose(AIVirtualCard originCard, AIVirtualCard parent) { IsOnField = true; CardIndex = originCard.CardIndex; parent.AddChildren(CardIndex); AttackableCount = MaxAttackableCount; IsFirstTurn = true; IsSkillSummoned = false; } public void InitAtHandMetamorphose(AIVirtualCard originCard, AIVirtualCard parent) { IsInHand = true; CardIndex = originCard.CardIndex; parent.AddChildren(CardIndex); } public void ReplaceSelfField(AIVirtualField field) { _field = field; } public void AddChildren(int index) { if (ChildrenIndexList == null) { ChildrenIndexList = new List(); } ChildrenIndexList.Add(index); } public virtual bool IsFollower(List playPtn) { if (IsUnit) { if (!this.IsAccelerated(_field, playPtn)) { return !this.IsCrystalize(_field, playPtn); } return false; } return false; } public virtual bool BasePlayable() { if (!IsAlly || !IsInHand) { return false; } return true; } public bool IsHoldKeywordSkill(AIScriptTokenArgType skill) { return skill switch { AIScriptTokenArgType.SNEAK => IsSneak, AIScriptTokenArgType.KILLER => IsKiller, AIScriptTokenArgType.GUARD => IsGuard, AIScriptTokenArgType.RUSH => IsRush, AIScriptTokenArgType.QUICK => IsQuick, AIScriptTokenArgType.DRAIN => IsDrain, AIScriptTokenArgType.UNTOUCHABLE => IsUntouchable, AIScriptTokenArgType.FORCE_TARGETING => IsForceTargeting, AIScriptTokenArgType.UNBANISHABLE => IsUnbanishable, AIScriptTokenArgType.IGNORE_GUARD => IsIgnoreGuard, _ => false, }; } public bool IsAttackable(List playPtn) { bool flag = AttackableCount > 0 && !IsCantAttackAll && (!IsSummonDrunkenness || IsEvolution); if (IsAlly && !flag && IsInHand && playPtn != null && playPtn.Count > 0) { for (int i = 0; i < playPtn.Count; i++) { if (_field.AllyHandCards[playPtn[i]].IsSameCard(this)) { flag = AISkillSimulationUtility.HasSkill(this, AIScriptTokenArgType.QUICK, _field.AI, playPtn) || AISkillSimulationUtility.HasSkill(this, AIScriptTokenArgType.RUSH, _field.AI, playPtn); break; } } } return flag; } public bool IsEvolDrunkenness() { if (IsFirstTurn && IsSummonDrunkenness) { return !IsQuick; } return false; } public bool IsCantAttackClass() { if (!IsSkillCantAttackClass && !IsEvolDrunkenness()) { if (IsFirstTurn && IsRush) { return !IsQuick; } return false; } return true; } public void RecoverAttackableCount() { AttackableCount = MaxAttackableCount; IsRecoveredAttackableCount = true; } public void ChangeClass(CardBasePrm.ClanType classType) { if (classType >= CardBasePrm.ClanType.ALL && classType < CardBasePrm.ClanType.MAX) { Clan = classType; } } public bool IsTribe(AIScriptTokenArgType tribeType) { CardBasePrm.TribeType tribeType2 = AITribeSimulationUtility.ConvertTokenArgTypeToTribeType(tribeType); if (tribeType2 >= CardBasePrm.TribeType.MAX) { return false; } return IsTribe(tribeType2); } public void AppendTribe(CardBasePrm.TribeType tribe) { if (_tribeList == null) { _tribeList = new List(); } if (!_tribeList.Contains(tribe)) { _tribeList.Add(tribe); } } public void ChangeTribe(CardBasePrm.TribeType tribe) { if (_tribeList == null) { _tribeList = new List(); } else { _tribeList.Clear(); } _tribeList.Add(tribe); } public float UpdateValue(AIParamQuery paramQuery, AIStyleQuery styleQuery, List playPtn, bool doesUseLostLife) { if (IsDead) { Value = 0f; return Value; } if (IsUnit) { if (Life <= 0) { Value = 0f; return Value; } Value = this.EvaluateValueOnField(playPtn, null, useStyle: true, doesUseLostLife, useOthersTag: true, useIgnoreInBattle: true); Value += (this.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) + this.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false)) * EnemyAI.BREAKBONUS_RATE_ON_FIELD; } else if (IsLeader) { Value = this.GetBattleBonus(playPtn); } else { Value = this.GetFieldBonus(playPtn); } return Value; } public void SetDefaultValue() { DefaultValue = Value; } public int SimulateAttackAmount(AISituationInfo situation) { return SimulateAttackAmount(Attack, situation); } public int SimulateAttackAmount(int attack, AISituationInfo situation) { return _field.DamageModifierCollection.CalcModifiedDamage(_field, EnemyAI.EmptyPlayPtn, situation, this, attack); } public int SimulateDamageAmount(int damageAmount, bool isSkillDamage = false, bool isSpellDamage = false) { damageAmount = BarrierInfoCollection.CalcDamageAmount(this, damageAmount, isSkillDamage, isSpellDamage); return Math.Max(damageAmount, 0); } public int SimulateDamageShield(int damageAmount, bool isSkillDamage = false, bool isSpellDamage = false) { bool flag = !isSkillDamage && !isSpellDamage; if ((isSkillDamage && BarrierInfoCollection.HasShieldSkill) || (isSpellDamage && BarrierInfoCollection.HasShieldSpell) || (flag && BarrierInfoCollection.HasShieldAttack)) { return 0; } return damageAmount; } public int AddDamage(AISituationInfo situation, int baseDamage, bool isSkillDamage) { if (IsDead) { return 0; } bool isSpellDamage = situation.ActionType == AIOperationType.PLAY && situation.Actor.IsSpell; int num = SimulateDamageAmount(baseDamage, isSkillDamage, isSpellDamage); Life -= num; if (Life > 0) { LastLife = Life; SelfField.DamagedCardsByLastAction.Add(new Tuple(this, num)); } else { IsDead = true; } _field.TagPreprocessContainer.SimulateAfterDamageInfo(this); _field.ExecuteWhenDamageTags(this, baseDamage, SelfField.BestPlayPtn, situation); _field.AllActivateCountHolderIncrement(situation, AIPlayTagType.DamagedActivateCount, this); return num; } public void Heal(int healLife) { if (!IsDead) { int life = Life; Life = Math.Min(Life + healLife, MaxLife); LastHealAmount = Life - life; LastLife = Life; int turn = (IsAlly ? _field.AllyTurnCount : _field.EnemyTurnCount); _field.HealRecorderCollection.AppendHealCount(turn, this, IsAlly); } } private void ModifyAttack(int buff, bool isMultiply, bool isTemp) { int attack = Attack; if (isMultiply) { Attack *= buff; } else { Attack += buff; } if (isTemp) { TempAtkBuff += Attack - attack; } } private void ModifyLife(AISituationInfo situation, int buff, bool isMultiply, bool isTemp) { int life = Life; if (isMultiply) { Life *= buff; } else { Life += buff; } if (Life <= 0) { RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: false); } int newLife = (isMultiply ? (MaxLife * buff) : (MaxLife + buff)); SetMaxLife(situation, newLife); if (isTemp && !IsDead) { TempLifeBuff += Life - life; } LastLife = Life; } public void GiveBuff(AISituationInfo situation, AIBuffExecutingInfo_old buff, bool isTemp) { int attack = Attack; int life = Life; ModifyAttack(buff.AttackValue, buff.IsMultiplyAttack, isTemp); ModifyLife(situation, buff.LifeValue, buff.IsMultiplyLife, isTemp); int turn = (IsAlly ? _field.AllyTurnCount : _field.EnemyTurnCount); if (BuffRecorderCollection == null) { BuffRecorderCollection = new AIBuffRecorderCollection(); } int atkBuff = Attack - attack; int lifeBuff = Life - life; BuffRecorderCollection.AddBuffRecord(turn, IsSelfTurn, atkBuff, lifeBuff); if (isTemp) { AIBuffStopPreprocessOption option = new AIBuffStopPreprocessOption(this); _field.TagPreprocessContainer.AppendAllyTurnEndStopInfo(option); _field.TagPreprocessContainer.AppendOpponentTurnEndStopInfo(option); } } public void MultiplyAttack(int rate) { Attack *= rate; } public void MultiplyLife(int rate) { Life *= rate; } public void SetAttack(int newAttack) { Attack = newAttack; } public void SetLife(int newLife, AISituationInfo situation) { Life = newLife; MaxLife = newLife; TempLifeBuff = 0; if (Life <= 0) { RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: false); } } public void SetMaxLife(AISituationInfo situation, int newLife) { MaxLife = newLife; if (Life > MaxLife) { Life = MaxLife; } if (Life <= 0) { RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: false); } } public void SetNewStatus(AISituationInfo situation, int newAttack, int newLife) { Attack = newAttack; Life = newLife; SetMaxLife(situation, newLife); LastLife = Life; TempAtkBuff = 0; TempLifeBuff = 0; } public void ChantCountDown(AISituationInfo situation, int value) { ChantCount -= value; if (ChantCount <= 0) { RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: false); } } public int EarthRite(int count, AISituationInfo situation, bool isPseudo) { int num = Math.Min(WhiteRitualCount, count); WhiteRitualCount -= num; if (!isPseudo) { _originalWhiteRitualCount -= num; } if (WhiteRitualCount <= 0) { if (isPseudo) { IsDead = true; } else { Destroy(situation, isFromSkill: true); } } return num; } public void SetWhiteRitual(int count) { if (count <= 0) { AIConsoleUtility.LogError($"SetWhiteRitual : Ilegal add count Error [count={count}]"); } else if (!IsDead && IsStackWhiteRitual && WhiteRitualCount > 0) { WhiteRitualCount = count; } } public bool AddWhiteRitual(int count) { if (count <= 0) { AIConsoleUtility.LogError($"AddWhiteRitual : Ilegal add count Error [count={count}]"); return false; } if (IsDead || !IsStackWhiteRitual || WhiteRitualCount <= 0) { return false; } WhiteRitualCount += count; return true; } public void ResetEarthRite(int resetCount) { if (WhiteRitualCount <= 0 && IsDead) { IsDead = false; } WhiteRitualCount += Mathf.Max(0, resetCount); } public void ResetAllEvaluationUpdatedParameter() { if (WhiteRitualCount <= 0 && IsDead) { IsDead = false; } WhiteRitualCount = _originalWhiteRitualCount; } public void ChangeIsCantUnderAttack(bool isCantUnderAttack) { _isCantUnderAttack = isCantUnderAttack; } public void RegisterGiveSneakTag(AIPlayTag tag) { _giveSneakTagList = AIParamQuery.AddElementToList(tag, _giveSneakTagList); } public void DepriveSneakWithGiveSneakTag() { IsSneak = false; if (_giveSneakTagList != null && _giveSneakTagList.Count > 0) { for (int i = 0; i < _giveSneakTagList.Count; i++) { AIPlayTag removingTag = _giveSneakTagList[i]; TagCollectionContainer.RemoveOneTagWithUpdatingFieldCardList(this, removingTag, SelfField); } _giveSneakTagList.Clear(); } } public bool IsCantUnderAttack(AIParamQuery query, AIVirtualCard attacker, List playPtn, AIVirtualField field) { if (TagCollectionContainer.HasTag(AIPlayTagType.CantBeAttacked) && TagCollectionContainer.CantBeAttackedTags.CantBeAttacked(this, attacker, playPtn, field)) { return false; } return _isCantUnderAttack; } public bool IsCantUnderAnyAttack() { return _isCantUnderAttack; } public void AfterClash(AIVirtualCard clashTarget, int finalDamage, bool isAttacker, List playPtn, AIVirtualAttackInfo situation) { if (!clashTarget.IsIndependent && IsKiller) { clashTarget.RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: true); } if (isAttacker) { if (IsSneak) { DepriveSneakWithGiveSneakTag(); } DealDamageDrain(finalDamage, playPtn, situation); } if (Life <= 0 && !IsDead) { RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: false); } } public void DealDamageDrain(int damage, List playPtn, AISituationInfo situation) { if (IsDrain && damage >= 0) { AISkillSimulationUtility.HealSingle(IsAlly ? _field.AllyClass : _field.EnemyClass, SelfField, damage, playPtn, situation); } } public void RemoveTempBuff() { if (TempAtkBuff != 0) { Attack -= TempAtkBuff; TempAtkBuff = 0; } if (TempLifeBuff != 0) { Life -= TempLifeBuff; LastLife = Life; TempLifeBuff = 0; } } public bool IsEqual(BattleCardBase card) { if (card.Index == CardIndex && _field.AI.IsAllyCard(card) == IsAlly) { return card.BaseParameter.BaseCardId == BaseId; } return false; } public bool IsSameCard(AIVirtualCard card) { if (card.CardIndex == CardIndex && card.IsAlly == IsAlly) { return card.BaseParameter.BaseId == BaseParameter.BaseId; } return false; } public bool IsSameCardType(AIVirtualCard card) { if (card.IsUnit == IsUnit && card.IsSpell == IsSpell) { return (card.IsAmulet || card.IsCountdownAmulet) == (IsAmulet || IsCountdownAmulet); } return false; } public bool IsSameCardIncluded(List list) { if (list == null || list.Count <= 0) { return false; } for (int i = 0; i < list.Count; i++) { AIVirtualCard card = list[i]; if (IsSameCard(card)) { return true; } } return false; } public void NormalPlay() { IsOnField = true; IsInHand = false; IsFirstTurn = true; AttackableCount = MaxAttackableCount; IsSummonDrunkenness = !IsQuick && !IsRush; } public void ResetPosition(AIOperationType actionType) { if (actionType == AIOperationType.PLAY) { IsInHand = true; IsOnField = false; } } public void EvolveStatusUp() { Life += EvoLifePlus; LastLife = Life; MaxLife += EvoLifePlus; Attack += EvoAttackPlus; IsEvolution = true; } public void AddToHand() { IsInHand = true; IsOnField = false; if (IsAlly) { _field.AllyHandCards.Add(this); } else { _field.GetEnemyHandCardList().Add(this); } _field.CardListSet.AddHandCard(this); } private void LeaveFromField(AISituationInfo situation) { IsDead = true; IsOnField = false; _isCompletedRemove = true; if (IsAlly) { _field.CardListSet.AddAllyLeftCard(this); _field.CardListSet.AddAllyLeftCardThisTurn(this); } else { _field.CardListSet.AddEnemyLeftCard(this); _field.CardListSet.AddEnemyLeftCardThisTurn(this); } _field.WhenCardLeaveFromField(this, situation); GetOff(situation); } private void ExecuteLeaveSkills(AISituationInfo situation) { _field.SimulationExtraBonus += (float)(IsAlly ? 1 : (-1)) * this.GetAllLeaveBonus(_field.BestPlayPtn, useIgnoreInBattle: true); if (TagCollectionContainer.HasTagCollection(TagCollectionType.WhenLeave)) { TagCollectionContainer.LeaveTags.Execute(this, _field.BestPlayPtn, situation); } if (!_field.CardListSet.HasLeaveOtherTagHolders) { return; } for (int i = 0; i < _field.CardListSet.WhenLeaveOtherTagHolders.Count; i++) { AIVirtualCard aIVirtualCard = _field.CardListSet.WhenLeaveOtherTagHolders[i]; if (!aIVirtualCard.IsSameCard(this)) { aIVirtualCard.TagCollectionContainer.OtherLeaveTags.RegisterPassedConditionTags(aIVirtualCard, SelfField, SelfField.BestPlayPtn, situation, this); } } } private void Destroy(AISituationInfo situation, bool isFromSkill) { if (_field == null || _isCompletedRemove || (isFromSkill && IsIndestructible)) { return; } AISkillProcessInformation processInfo = situation.RegisterNewProcessInfo(this, AISituationTriggerInformation.TriggerType.Undefined); List emptyPlayPtn = EnemyAI.EmptyPlayPtn; situation.RegisterOwnDestroyedCard(this); LeaveFromField(situation); _field.ExecuteWhenChangeInplayTags(emptyPlayPtn, situation); ExecuteLeaveSkills(situation); if (IsLeader) { return; } _field.VirtualCemetery.AddCemetery(1, IsAlly); if (TagCollectionContainer.HasTag(AIPlayTagType.RemoveSkill)) { TagCollectionContainer.RemoveSkillTags.Execute(this, AIScriptTokenArgType.WHEN_DESTROY, null); } if (this.IsBreakBeforePlay(_field.BestPlayPtn)) { _field.IsBreakBeforePlayKilled = true; } if (!IsSkillLost && (this.HasBreakBonus(_field) || TagCollectionContainer.HasTagCollection(TagCollectionType.Lastword))) { if (IsAmulet) { _field.SimulationExtraBonus += (float)(IsAlly ? 1 : (-1)) * this.GetAllBreakBonus(_field.BestPlayPtn, useIgnoreInBattle: true); ExecuteLastwordSkills(processInfo, situation); } else { AIVirtualCard aIVirtualCard = (IsAlly ? _field.AllyClass : _field.EnemyClass); int num = 1; if (aIVirtualCard.TagCollectionContainer.HasTag(AIPlayTagType.OneMoreLastword) && aIVirtualCard.TagCollectionContainer.OneMoreLastwordTags.CheckConditionAndRemovePassedTags(aIVirtualCard, _field, situation)) { num++; } _field.SimulationExtraBonus += (float)(IsAlly ? 1 : (-1)) * this.GetBreakBonus(_field.BestPlayPtn, useIgnoreBreak: true) * (float)num; _field.SimulationExtraBonus += (float)(IsAlly ? 1 : (-1)) * AIEvaluateBonusFromOhterUtility.GetOtherBreakBonus(this, _field, _field.BestPlayPtn, useIgnoreInBattle: true); for (int i = 0; i < num; i++) { ExecuteLastwordSkills(processInfo, situation); } } } if (IsAlly) { _field.CardListSet.AddAllyDestroyedCard(this, isDestroyTurn: true); } else { _field.CardListSet.AddEnemyDestroyedCard(this); } if (SelfField.CardListSet.HasBreakTagHolder) { ApplyWhenDestroyTags(situation); } _field.AllActivateCountHolderIncrement(situation, AIPlayTagType.BreakActivateCount, this); } public void BurialRite() { if (IsInHand) { IsInHand = false; _field.RemoveAllyHandCard(this); _field.VirtualCemetery.AddCemetery(1, IsAlly); } } private void ExecuteLastwordSkills(AISkillProcessInformation processInfo, AISituationInfo situation) { AIPreprocessSimulationUtility.SimulatePreprocess(this, situation, _field, AIScriptTokenArgType.WHEN_DESTROY, isPseudo: false); if (TagCollectionContainer.HasTagCollection(TagCollectionType.Lastword)) { TagCollectionContainer.LastwordTags.RegisterExecutingTagActions(this, processInfo, situation); } situation.ProcessCollection.CombinePreprocessToProcessQueue(); } private void Banish(AISituationInfo situation) { if (!_isCompletedRemove) { if (situation == null) { AIConsoleUtility.LogError("AIVirtualCard.Banish() error!! situation == null!!!!!"); } situation.RegisterNewProcessInfo(this, AISituationTriggerInformation.TriggerType.Banish); List emptyPlayPtn = EnemyAI.EmptyPlayPtn; SetBanishedCardInfo(); situation.RegisterOwnBanishedCard(this); LeaveFromField(situation); _field.ExecuteWhenChangeInplayTags(emptyPlayPtn, situation); ExecuteLeaveSkills(situation); ApplyWhenBanishTags(situation); _field.AllActivateCountHolderIncrement(situation, AIPlayTagType.BanishActivateCount, this); _field.CardListSet.AddBanishedCard(this); } } private void SetBanishedCardInfo() { if (_field == null) { AIConsoleUtility.LogError("SetBanishedCardInfo() Error : Field is Null"); return; } int currentTurnCount = _field.CurrentTurnCount; BattleCardBase.BanishInfo.BanishPlace place = (IsOnField ? BattleCardBase.BanishInfo.BanishPlace.Field : (IsInHand ? BattleCardBase.BanishInfo.BanishPlace.Hand : BattleCardBase.BanishInfo.BanishPlace.Deck)); BanishedInfo = new AIVirtualBanishInfo(currentTurnCount, IsSelfTurn, place); } public bool IsBanishedTargetTurn(int turn) { if (BanishedInfo == null) { return false; } if (BanishedInfo.Place == BattleCardBase.BanishInfo.BanishPlace.None || BanishedInfo.Place == BattleCardBase.BanishInfo.BanishPlace.Deck) { return false; } if (BanishedInfo.Turn != turn || BanishedInfo.IsCardOwnerTurn != IsSelfTurn) { return false; } return true; } private void ConvertBaseBanishInfo(BattleCardBase.BanishInfo baseInfo) { if (baseInfo == null) { AIConsoleUtility.LogError("ConvertBaseBanishInfo() : convert target is Null"); return; } bool isSelfTurn = baseInfo.IsSelfTurn; bool isCardOwnerTurn = (IsPlayer ? isSelfTurn : (!isSelfTurn)); BanishedInfo = new AIVirtualBanishInfo(baseInfo.Turn, isCardOwnerTurn, baseInfo.Place); } public void MetamorphoseLeave(AISituationInfo situation) { if (!_isCompletedRemove) { IsDead = true; IsOnField = false; LeaveFromField(situation); } } private void Bounce(AISituationInfo situation) { if (!_isCompletedRemove) { _field.SimulationExtraBonus += (float)(IsAlly ? 1 : (-1)) * this.GetBounceBonus(); LeaveFromField(situation); ExecuteLeaveSkills(situation); List emptyPlayPtn = EnemyAI.EmptyPlayPtn; situation.BounceCardList = AIParamQuery.AddElementToList(this, situation.BounceCardList); this.ExecuteBounceSkills(this, _field, emptyPlayPtn, situation); List list; if (IsAlly) { list = _field.AllyHandCards; _field.AllyInplayCards.Remove(this); _field.CardListSet.RemoveAllyInplayCard(this); } else { list = _field.GetEnemyHandCardList(); _field.EnemyInplayCards.Remove(this); _field.CardListSet.RemoveEnemyInplayCard(this); } if (list.Count >= 9) { _field.VirtualCemetery.AddCemetery(1, IsAlly); } else { AIVirtualCard aIVirtualCard = new AIVirtualCard(BaseCard, _field) { IsInHand = true }; aIVirtualCard.InitializeTags(_field.ParamQuery, null, null); list.Add(aIVirtualCard); _field.CardListSet.AddHandCard(aIVirtualCard); } _field.ExecuteWhenChangeInplayTags(emptyPlayPtn, situation); } } public void Reanimate(AISituationInfo situation) { if (this.IsReanimateEvo(_field.BestPlayPtn)) { AttackableCount = 1; AIAutoEvolutionSimulationUtility.AutoEvolveSingle(this, _field, situation); } } public void GetOn(AIVirtualCard rideCard, AISituationInfo situation) { if (TagCollectionContainer.HasTag(AIPlayTagType.GetOn) && rideCard != null && rideCard.IsAlly == IsAlly && rideCard.IsUnit && !IsGetOn) { GetOnCardId = rideCard.BaseId; rideCard.ToRide(); IsCantAttackAll = false; IsSkillCantAttackUnit = false; List emptyPlayPtn = EnemyAI.EmptyPlayPtn; _field.ExecuteWhenChangeInplayTags(emptyPlayPtn, situation); AIGetOnSimulationUtility.ExecuteGetOnTriggerTags(this, _field, situation); } } public void GetOff(AISituationInfo situation) { if (IsGetOn) { GetOffCard = AIGetOnSimulationUtility.GetoffTokenOnVirtualField(GetOnCardId, this, _field, situation); List emptyPlayPtn = EnemyAI.EmptyPlayPtn; _field.ExecuteWhenChangeInplayTags(emptyPlayPtn, situation); } } public void ToRide() { IsDead = true; } public void Spellboost(int count) { if (IsInHand && HasSpellboost) { SpellboostCount += count; } } public void SetSpellboostCount(int count) { SpellboostCount = count; } public float EvaluateClashBonus() { if (!TagCollectionContainer.HasTagCollection(TagCollectionType.ClashBonus)) { return 0f; } return TagCollectionContainer.ClashBonusTags.GetClashBonus(this, SelfField, SelfField.BestPlayPtn); } private void ApplyWhenDestroyTags(AISituationInfo situation) { for (int i = 0; i < SelfField.CardListSet.BreakTagHolders.Count; i++) { AIVirtualCard aIVirtualCard = SelfField.CardListSet.BreakTagHolders[i]; if (!aIVirtualCard.IsDead && (aIVirtualCard.CardIndex != CardIndex || aIVirtualCard.BaseId != BaseId) && aIVirtualCard.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenBreak)) { aIVirtualCard.TagCollectionContainer.BreakTags.RegisterExecutingTagActions(SelfField, aIVirtualCard, this, SelfField.BestPlayPtn, situation); } } } private void ApplyWhenBanishTags(AISituationInfo situation) { if (TagCollectionContainer.HasTagCollection(TagCollectionType.WhenBanish)) { TagCollectionContainer.BanishTags.RegisterExecutingTagActions(SelfField, this, SelfField.BestPlayPtn, situation); } if (!SelfField.CardListSet.HasBanishTagHolder) { return; } for (int i = 0; i < SelfField.CardListSet.BanishTagHolders.Count; i++) { AIVirtualCard aIVirtualCard = SelfField.CardListSet.BanishTagHolders[i]; if (!aIVirtualCard.IsDead && !aIVirtualCard.IsSameCard(this) && aIVirtualCard.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenOtherBanish)) { aIVirtualCard.TagCollectionContainer.OtherBanishTags.RegisterExecutingTagActions(SelfField, aIVirtualCard, this, SelfField.BestPlayPtn, situation); } } } public void GiveAttackable() { IsCantAttackAll = false; IsSkillCantAttackUnit = false; IsSkillCantAttackClass = false; } public void GiveAttackableCount(int count) { int maxAttackableCount = MaxAttackableCount; if (count > maxAttackableCount) { AttackableCount = Math.Min(AttackableCount + (count - maxAttackableCount), count); } else if (count < maxAttackableCount) { AttackableCount = Math.Min(count, AttackableCount); } MaxAttackableCount = count; } public void RemoveAllSkills(AISituationInfo situation) { DepriveSneakWithGiveSneakTag(); IsKiller = false; IsDrain = false; IsRush = false; IsQuick = false; IsDestroyWhenAttack = false; HasSpellboost = false; IsForceTargeting = false; IsUnbanishable = false; UntouchableCount = 0; _bounceByBanishCount = 0; _banishByDestroyCount = 0; _destroyByBanishCount = 0; TagCollectionContainer.RemoveAllTagWithUpdatingFieldCardList(this, SelfField, situation); IsSkillLost = true; } public void CallOnAfterBattleSimulation(AIVirtualTurnEndInfo turnEndSituation) { turnEndSituation.ProcessCollection.ClearTempPreprocessList(); AIPreprocessSimulationUtility.SimulatePreprocess(this, turnEndSituation, _field, AIScriptTokenArgType.WHEN_TURNEND, isPseudo: false); AISkillProcessInformation aISkillProcessInformation = turnEndSituation.RegisterNewProcessInfo(null, AISituationTriggerInformation.TriggerType.Undefined); if (TagCollectionContainer.HasTagCollection(TagCollectionType.WhenTurnEnd)) { TurnEndTagCollection turnEndTags = TagCollectionContainer.TurnEndTags; if (turnEndTags.HasTagExecuteWhenAllyTurnEnd(turnEndSituation.Actor.IsAlly == IsAlly)) { turnEndTags.RegisterConditionPassedTagActions(this, SelfField.BestPlayPtn, turnEndSituation, aISkillProcessInformation); } } turnEndSituation.ProcessCollection.CombinePreprocessToProcessQueue(); aISkillProcessInformation.AddExecutingAction(delegate { if (!turnEndSituation.Actor.IsLeader) { AIConsoleUtility.LogError("turnEndSituation.Actor is not Leader!!"); } else { this.Increment(turnEndSituation, AIPlayTagType.TurnEndActivateCount); } }); } public bool IsAbleEvolution() { if (!IsUnit) { return false; } if (IsEvolution) { return false; } if (!_field.IsExceededWaitEvolveTurn) { return false; } if (!_field.IsLeftTurnEvol) { return false; } if (_field.AllyEvolutionCount <= 0 && !IsNotConsumeEp) { return false; } if (IsDebuffCantEvolve) { return false; } return true; } public bool IsAbleToPlay(List playPtn, AIVirtualTargetSelectAction playSituation) { if (playSituation == null) { AIConsoleUtility.LogError("IsAbleToPlay() : situation is null"); return false; } return AIPlayCardSimulationUtility.IsAbleToPlayCard(playSituation, _field, playPtn); } public int GetUseCost(int restPp, List playPtn, AISituationInfo situation, out PlaySimulationType playType) { int result = GetPlayEnhancedCost(restPp, out playType); if (playType == PlaySimulationType.Undefined) { result = GetPlayChoiceTransformedCost(restPp, playPtn, situation, out playType); } if (playType == PlaySimulationType.Undefined) { result = GetPlayNormalCost(restPp, playPtn, situation, out playType); } if (playType == PlaySimulationType.Undefined) { result = GetPlayAcceleratedCost(restPp, playPtn, situation, out playType); } if (playType == PlaySimulationType.Undefined) { result = GetPlayCrystalizedCost(restPp, out playType); } if (situation is AIVirtualActionInfo aIVirtualActionInfo) { aIVirtualActionInfo.ReservedPlayType = playType; } return result; } public bool IsPlayingSimulationType(int restPp, List playPtn, AISituationInfo situation, PlaySimulationType checkPlayType) { PlaySimulationType playType = PlaySimulationType.Undefined; switch (checkPlayType) { case PlaySimulationType.Accelerate: GetPlayNormalCost(restPp, playPtn, situation, out playType); if (playType != PlaySimulationType.Normal) { GetPlayAcceleratedCost(restPp, playPtn, situation, out playType); } break; case PlaySimulationType.ChoiceTransform: GetPlayChoiceTransformedCost(restPp, playPtn, null, out playType); break; case PlaySimulationType.Crystalize: GetPlayNormalCost(restPp, playPtn, situation, out playType); if (playType != PlaySimulationType.Normal) { GetPlayCrystalizedCost(restPp, out playType); } break; case PlaySimulationType.Enhance: GetPlayEnhancedCost(restPp, out playType); break; case PlaySimulationType.Normal: GetPlayNormalCost(restPp, playPtn, situation, out playType); break; default: AIConsoleUtility.LogError("IsPlayingSimulationType() : Check Target is Undefined Play Type!"); break; } return playType == checkPlayType; } public int GetPlaySimulationTypeCost(int restPp, List playPtn, AISituationInfo situation, PlaySimulationType checkPlayType) { PlaySimulationType playType = PlaySimulationType.Undefined; int result = -1; switch (checkPlayType) { case PlaySimulationType.Accelerate: result = GetPlayNormalCost(restPp, playPtn, situation, out playType); if (playType != PlaySimulationType.Normal) { result = GetPlayAcceleratedCost(restPp, playPtn, situation, out playType); } break; case PlaySimulationType.ChoiceTransform: result = GetPlayChoiceTransformedCost(restPp, playPtn, null, out playType); break; case PlaySimulationType.Crystalize: result = GetPlayNormalCost(restPp, playPtn, situation, out playType); if (playType != PlaySimulationType.Normal) { result = GetPlayCrystalizedCost(restPp, out playType); } break; case PlaySimulationType.Enhance: result = GetPlayEnhancedCost(restPp, out playType); break; case PlaySimulationType.Normal: result = GetPlayNormalCost(restPp, playPtn, situation, out playType); break; default: AIConsoleUtility.LogError("GetPlaySimulationTypeCost() : Check Target is Undefined Play Type!"); break; } if (playType != checkPlayType) { return -1; } return result; } public int GetPlayNormalCost(int restPp, List playPtn, AISituationInfo situation, out PlaySimulationType playType) { playType = PlaySimulationType.Undefined; int num = Mathf.Max(0, Cost - this.GetCostBonus(playPtn, situation)); if (restPp >= num) { playType = PlaySimulationType.Normal; } return num; } public int GetPlayEnhancedCost(int restPp, out PlaySimulationType playType) { playType = PlaySimulationType.Undefined; int num = -1; if (EnhanceCostList != null && EnhanceCostList.Count > 0) { for (int i = 0; i < EnhanceCostList.Count; i++) { int num2 = EnhanceCostList[i]; if (restPp >= num2 && num2 > num) { num = num2; } } if (num >= 0) { playType = PlaySimulationType.Enhance; } } return num; } public int GetPlayChoiceTransformedCost(int restPp, List playPtn, AISituationInfo situation, out PlaySimulationType playType) { playType = PlaySimulationType.Undefined; int num = -1; if (ChoiceTransformCostList != null && ChoiceTransformCostList.Count > 0) { for (int i = 0; i < ChoiceTransformCostList.Count; i++) { AIChoiceTransformCostInformation aIChoiceTransformCostInformation = ChoiceTransformCostList[i]; if (aIChoiceTransformCostInformation.CheckCondition(this, _field, playPtn, situation)) { int num2 = (int)aIChoiceTransformCostInformation.Cost.EvalArg(this, playPtn, _field, situation); if (restPp >= num2 && num2 > num) { num = num2; } } } if (num >= 0) { playType = PlaySimulationType.ChoiceTransform; } } return num; } public int GetPlayAcceleratedCost(int restPp, List playPtn, AISituationInfo situation, out PlaySimulationType playType) { playType = PlaySimulationType.Undefined; int num = -1; if (AccelerateCostList != null && AccelerateCostList.Count > 0) { for (int i = 0; i < AccelerateCostList.Count; i++) { AIAccelerateInformation aIAccelerateInformation = AccelerateCostList[i]; if (aIAccelerateInformation.CheckCondition(this, _field, playPtn, situation)) { int cost = aIAccelerateInformation.Cost; if (restPp >= cost && cost > num) { num = cost; } } } if (num >= 0) { playType = PlaySimulationType.Accelerate; } } return num; } public int GetPlayCrystalizedCost(int restPp, out PlaySimulationType playType) { playType = PlaySimulationType.Undefined; int num = -1; if (CrystalizeCostList != null && CrystalizeCostList.Count > 0) { for (int i = 0; i < CrystalizeCostList.Count; i++) { AICrystalizeInformation aICrystalizeInformation = CrystalizeCostList[i]; if (restPp >= aICrystalizeInformation.Cost && aICrystalizeInformation.Cost > num) { num = aICrystalizeInformation.Cost; } } if (num >= 0) { playType = PlaySimulationType.Crystalize; } } return num; } public void SetCurrentCost(int target_cost) { if (target_cost < 0) { AIConsoleUtility.LogError($"SetCurrentCost: Set ilegal values [{target_cost}]"); } Cost = target_cost; } public void AddCurrentCost(int add_cost) { Cost = Mathf.Max(0, Cost + add_cost); } public void CreateHandPlayEstimator(AIParamQuery paramQuery, int handIndex, BattlePlayerPair sourcePair, EnemyAI ai) { _handPlayEstimator = new AIHandPlayEstimator(paramQuery, handIndex, this, sourcePair, ai); } public AIHandPlayEstimator GetHandPlayEstimator() { return _handPlayEstimator; } public int GetBaseSkillCount() { return BattleSkills.Count(); } public bool IsHoldingBattleSkill(string hash) { if (BattleSkillHashList == null || BattleSkillHashList.Count <= 0) { return false; } for (int i = 0; i < BattleSkillHashList.Count; i++) { if (hash == BattleSkillHashList[i].ToString()) { return true; } } return false; } public void ResetParameterAfterPlayPtnEvaluation() { SpellboostCount = RealSpellboostCount; Cost = RealCost; if (_originalWhiteRitualCount != WhiteRitualCount) { if (IsDead && WhiteRitualCount <= 0 && _originalWhiteRitualCount > 0) { IsDead = false; } WhiteRitualCount = _originalWhiteRitualCount; } } public void RollBackFromOneRecord(AIVirtualFieldRollBackRecord.CardParamRecord record) { Cost = record.Cost; SpellboostCount = record.SpellBoost; IsDead = record.IsDead; WhiteRitualCount = record.WhiteRitualCount; if (TagCollectionContainer.HasTagCollection(TagCollectionType.ActivateCount)) { TagCollectionContainer.ActivateCountTags.UpdateCounterList(record.ActivateCounterList); } } public void NotBeAttacked() { IsSkillCantUnderAnyAttack = true; } public float EvalKillerAttackValue(List playPtn, AISituationInfo situation) { float num = (IsUnit ? (0f - this.EvaluateValueOnField(playPtn, situation, useStyle: true, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true) + this.EvaluateBreakValue(playPtn, useIgnoreBreak: true) + this.EvaluateLeaveValue(playPtn, useIgnoreInBattle: true)) : 0f); float num2 = float.MinValue; AIVirtualCard aIVirtualCard = null; bool flag = _field.EnemyInplayCards.Any((AIVirtualCard card) => card.IsGuard); for (int num3 = 0; num3 < _field.EnemyInplayCards.Count; num3++) { float num4 = 0f; AIVirtualCard aIVirtualCard2 = _field.EnemyInplayCards[num3]; if (!aIVirtualCard2.IsUnit || aIVirtualCard2.IsCantUnderAnyAttack() || (flag && !aIVirtualCard2.IsGuard && !IsIgnoreGuard) || new AIVirtualAttackInfo(this, aIVirtualCard2).WillTargetDestroyByAttackTags(_field, playPtn, this)) { continue; } bool flag2 = true; if (aIVirtualCard2.IsIndependent || aIVirtualCard2.IsIndestructible) { int damage = BaseCard.DamageCalculationAtkTypeAttack.Damage; if (aIVirtualCard2.BaseCard.CalculateFinalDamageAmount(damage) < aIVirtualCard2.Life) { flag2 = false; } } if (flag2) { float num5 = aIVirtualCard2.EvaluateValueOnField(EnemyAI.EmptyPlayPtn, null, useStyle: true, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true) - aIVirtualCard2.EvaluateBreakValue(EnemyAI.EmptyPlayPtn, useIgnoreBreak: true) - aIVirtualCard2.EvaluateLeaveValue(EnemyAI.EmptyPlayPtn, useIgnoreInBattle: true); num4 += num5; } int damage2 = aIVirtualCard2.BaseCard.DamageCalculationAtkTypeBeAttacked.Damage; if (BaseCard.CalculateFinalDamageAmount(damage2) >= Life) { num4 += num; } if (num4 > num2) { num2 = num4; aIVirtualCard = aIVirtualCard2; } } if (aIVirtualCard != null) { return num2; } return 0f; } public void GiveRemoveByBanish() { _destroyByBanishCount++; _bounceByBanishCount++; } public void DepriveRemoveByBanish() { if (_destroyByBanishCount > 0) { _destroyByBanishCount--; } if (_bounceByBanishCount > 0) { _bounceByBanishCount--; } } public void GiveRemoveByDestroy() { _banishByDestroyCount++; } public void DepriveRemoveByDestroy() { if (_banishByDestroyCount > 0) { _banishByDestroyCount--; } } public void AddUntouchableCount() { UntouchableCount++; } public void SubUntouchableCount() { UntouchableCount--; if (UntouchableCount < 0) { UntouchableCount = 0; } } public void RemoveCard(AISituationInfo situation, AIRemovalType type, bool isFromSkill) { switch (type) { case AIRemovalType.Destroy: TryDestroyCard(situation, isFromSkill); break; case AIRemovalType.Banish: TryBanishCard(situation); break; case AIRemovalType.Bounce: TryBounceCard(situation); break; } RemoveTempBuff(); } private void TryDestroyCard(AISituationInfo situation, bool isFromSkill) { if (IsDestroyByBanish) { if (IsBanishByDestroy || this.IsRemoveByDestroy(EnemyAI.EmptyPlayPtn, situation)) { Destroy(situation, isFromSkill); } else if (!isFromSkill || !IsIndestructible) { Banish(situation); } } else { Destroy(situation, isFromSkill); } } private void TryBanishCard(AISituationInfo situation) { if (IsBanishByDestroy || this.IsRemoveByDestroy(EnemyAI.EmptyPlayPtn, situation)) { Destroy(situation, isFromSkill: true); } else { Banish(situation); } } private void TryBounceCard(AISituationInfo situation) { if (IsBounceByBanish) { if (IsBanishByDestroy || this.IsRemoveByDestroy(EnemyAI.EmptyPlayPtn, situation)) { if (IsIndestructible) { Bounce(situation); } else { Destroy(situation, isFromSkill: true); } } else { Banish(situation); } } else { Bounce(situation); } } public bool CreateOtherEvolveParameterFromBattleCardBase(EnemyAI ai, BattleCardBase origin, BattleCardBase baseParamCard, AISituationInfo situation) { if (origin == null) { AIConsoleUtility.LogError("CreateOtherEvolvedCardParam() error!! param origin card is null"); return false; } if (baseParamCard == null) { AIConsoleUtility.LogError("CreateOtherEvolvedCardParam() error!! new param card is null!"); return false; } if (OtherEvolveParameter != null) { AIConsoleUtility.LogError("SetOtherEvolvedCardParam() error!! exist param data already!"); return false; } OtherEvolveParameter = new AIVirtualCardParameter(origin, baseParamCard, BuffRecorderCollection); AIAttachedTagCollection attachedTags = TagCollectionContainer.AttachedTags; AIRemovedTagCollection removedTagCollection = TagCollectionContainer.RemovedTagCollection; TagCollectionContainer.RemoveAllTagWithUpdatingFieldCardList(this, SelfField, situation); InitializeTags(ai.ParamQuery, attachedTags, removedTagCollection); return true; } public void SetOtherEvolveParameterFromVirtualCard(AIVirtualCard source) { if (source.OtherEvolveParameter != null) { OtherEvolveParameter = source.OtherEvolveParameter; BaseParameter = source.BaseParameter; } } public void SetOtherEvolveParameterFromBuildParameter(ReferableVirtualCardBuildParameterCollection buildParameter) { if (buildParameter.OtherEvolveCardParameter != null) { OtherEvolveParameter = buildParameter.OtherEvolveCardParameter; BaseParameter = buildParameter.BaseParameter; } } public void AddCannotAttackInformation(AICannotAttackInformation info) { _cannotAttackInfoList = AIParamQuery.AddElementToList(info, _cannotAttackInfoList); } public void CopyCannotAttackInfoList(AIVirtualCard sourceCard) { _cannotAttackInfoList = AIParamQuery.CloneList(sourceCard._cannotAttackInfoList); } public void RemoveCannotAttackInformation(AICannotAttackInformation info) { if (_cannotAttackInfoList == null || _cannotAttackInfoList.Count <= 0) { return; } for (int num = _cannotAttackInfoList.Count - 1; num >= 0; num--) { if (_cannotAttackInfoList[num].IsEqual(info)) { _cannotAttackInfoList.RemoveAt(num); break; } } } public bool IsCannotAttackByTag(AIVirtualAttackInfo situation) { if (_cannotAttackInfoList == null || _cannotAttackInfoList.Count <= 0) { return false; } for (int i = 0; i < _cannotAttackInfoList.Count; i++) { if (_cannotAttackInfoList[i].IsCannotAttack(_field, situation)) { return true; } } return false; } public virtual ulong GetHash() { if (IsDead && !IsLeader) { return 0uL; } ulong num = 0uL; num += (ulong)((long)Attack * 6337L); num += (ulong)((long)Life * 11383L); num += (ulong)((long)DefLife * 173L); num += (ulong)((long)EvolutionAttack * 1488017L); num += (ulong)((long)EvolutionLife * 937477L); num += (ulong)((long)Cost * 14401L); num += PRIME_NUMBERS_FOR_CLAN[(int)Clan % PRIME_NUMBERS_FOR_CLAN.Length]; num += (ulong)((long)SpellboostCount * 8389L); num += (ulong)((long)WhiteRitualCount * 3571L); if (_tribeList != null) { for (int i = 0; i < _tribeList.Count; i++) { num += PRIME_NUMBERS_FOR_TRIBE[(int)_tribeList[i] % PRIME_NUMBERS_FOR_TRIBE.Length]; } } num += TagCollectionContainer.GetHash(this) * 5237; bool flag = false; if (!IsLeader && AIData != null) { flag = true; } if (FusionIngredients != null) { num += FusionIngredients.GetHash(); } if (IsOnField) { num += (ulong)((long)AttackableCount * 557L); num += (ulong)((long)ChantCount * 5683L); num += (ulong)((long)ReferringSelfCount * 558869L); num += BarrierInfoCollection.GetHash(); if (flag) { num += (ulong)((long)AIData.BattleBonusExpr.Hash * 761L); } if (IsAlly) { num += (ulong)(IsFirstTurn ? 191 : 19); if (IsAttackable(EnemyAI.EmptyPlayPtn)) { num = ((!AIAttackSimulationUtility.IsAttackPossible(_field, AttackLeaderSituation)) ? (num * 37) : (num * 151)); } num *= 11; } num *= (ulong)(IsUnit ? 103 : 1); num *= (ulong)(IsEvolution ? 59 : 1); num *= (ulong)(IsGetOn ? 577 : 1); num *= (ulong)(IsPreviousTurnAttacked ? 9749 : 1); num *= (ulong)(IsCantAttackAll ? 8089 : 1); num *= (ulong)(IsNotConsumeEp ? 3527 : 1); num *= (ulong)(IsLastword ? 809 : 1); num *= (ulong)(IsSneak ? 811 : 1); num *= (ulong)(IsKiller ? 821 : 1); num *= (ulong)(IsDrain ? 823 : 1); num *= (ulong)(IsRush ? 827 : 1); num *= (ulong)(IsQuick ? 829 : 1); num *= (ulong)(IsDestroyWhenAttack ? 839 : 1); num *= (ulong)(IsGuard ? 853 : 1); num *= (ulong)(IsIgnoreGuard ? 857 : 1); num *= (ulong)(IsUntouchable ? 859 : 1); num *= (ulong)(IsForceTargeting ? 863 : 1); num *= (ulong)(IsUnbanishable ? 877 : 1); } if (IsInHand && flag) { num += (ulong)((long)AIData.PlayBonusExpr.Hash * 12007L); num += (ulong)((long)AIData.BattleBonusExpr.Hash * 761L); num += (ulong)((long)AIData.PriorityExpr.Hash * 101L); } return num; } }