using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Wizard; public class AIScriptExpressionCalculator { public static float CalculateExpression(List iPolish, List playPtn, AIVirtualField field, AIVirtualCard tagOwner, AISituationInfo situation) { if (iPolish == null || iPolish.Count <= 0) { return 0f; } if (iPolish.Count == 1 && iPolish[0] is AIScriptNumericToken) { return iPolish[0].Value; } if (playPtn == null) { playPtn = EnemyAI.EmptyPlayPtn; } return Calculation(iPolish, playPtn, field, tagOwner, situation); } private static float Calculation(List expr, List playPtn, AIVirtualField field, AIVirtualCard tagOwner, AISituationInfo situation) { Stack stack = new Stack(); int count = expr.Count; for (int i = 0; i < count; i++) { AIScriptTokenBase aIScriptTokenBase = expr[i]; if (aIScriptTokenBase is AIScriptNumericToken || aIScriptTokenBase is AIScriptArgumentToken || aIScriptTokenBase is AIScriptIDToken) { stack.Push(aIScriptTokenBase); } else if (aIScriptTokenBase is AIScriptVariableToken) { AIScriptTokenBase aIScriptTokenBase2 = CalculateVariableToken(aIScriptTokenBase, playPtn, field, tagOwner, situation); if (aIScriptTokenBase2 != null) { stack.Push(aIScriptTokenBase2); } } else if (aIScriptTokenBase is AIScriptFunctionToken) { int argCount = ((AIScriptFunctionToken)aIScriptTokenBase).ArgCount; List list = new List(); for (int j = 0; j < argCount; j++) { AIScriptTokenBase item = stack.Pop(); list.Add(item); } stack.Push(CalculateFunctionToken(list, aIScriptTokenBase as AIScriptFunctionToken, field, playPtn, tagOwner, situation)); } else { float value = stack.Pop().Value; float value2 = stack.Pop().Value; float value3 = CalculateByOperatorSymbol(aIScriptTokenBase.Type, value2, value); stack.Push(new AIScriptNumericToken(value3)); } } if (stack.Count > 1 || stack.Count <= 0) { return 0f; } return stack.Pop().Value; } public static float CalculateByOperatorSymbol(AIScriptTokenType symbol, float left, float right) { switch (symbol) { case AIScriptTokenType.PLUS: return left + right; case AIScriptTokenType.MINUS: return left - right; case AIScriptTokenType.MULTI: return left * right; case AIScriptTokenType.DIV: return left / right; case AIScriptTokenType.REMAIN: return left % right; case AIScriptTokenType.MORE_THAN: if (!(left > right)) { return 0f; } return 1f; case AIScriptTokenType.MORE_EQUAL: if (!(left >= right)) { return 0f; } return 1f; case AIScriptTokenType.LESS_THAN: if (!(left < right)) { return 0f; } return 1f; case AIScriptTokenType.LESS_EQUAL: if (!(left <= right)) { return 0f; } return 1f; case AIScriptTokenType.EQUAL: if (left != right) { return 0f; } return 1f; case AIScriptTokenType.MAX: return Mathf.Max(left, right); case AIScriptTokenType.MIN: return Mathf.Min(left, right); case AIScriptTokenType.OR: if (!(left > 0f) && !(right > 0f)) { return 0f; } return 1f; case AIScriptTokenType.AND: if (!(left > 0f) || !(right > 0f)) { return 0f; } return 1f; default: return 0f; } } public static AIScriptTokenBase CalculateVariableToken(AIScriptTokenBase token, List playPtn, AIVirtualField field, AIVirtualCard tagOwner, AISituationInfo situation) { _ = token is AIScriptVariableToken; switch (((AIScriptVariableToken)token).VariableType) { case AIScriptTokenVariableType.NOW_TURN: return new AIScriptNumericToken(tagOwner.IsAlly ? field.AllyTurnCount : field.EnemyTurnCount); case AIScriptTokenVariableType.COUNTDOWN: return new AIScriptNumericToken(tagOwner.ChantCount); case AIScriptTokenVariableType.REINCARNATION_MAX: return new AIScriptNumericToken(AIReincarnationUtility.EvalMaxReincarnationBonus(tagOwner, playPtn)); case AIScriptTokenVariableType.SPELLBOOST: return new AIScriptNumericToken(tagOwner.SpellboostCount); case AIScriptTokenVariableType.FIELD_SPACE: return new AIScriptNumericToken(field.GetPredictiveAllyFieldSpace()); case AIScriptTokenVariableType.ALLY_UNIT_MIN: return new AIScriptNumericToken(field.CalcMinEvaluateValue(playPtn, isAlly: true)); case AIScriptTokenVariableType.ALLY_UNIT_MAX: return new AIScriptNumericToken(field.CalcMaxEvaluateValue(playPtn, isAlly: true)); case AIScriptTokenVariableType.ALLY_ATTACKABLE_ATK_MAX: return new AIScriptNumericToken(field.GetMaxAllyAttackableUnitAttack(playPtn, tagOwner.IsAlly)); case AIScriptTokenVariableType.ALLY_NON_ATTACKABLE_ATK_MAX: return new AIScriptNumericToken(field.GetMaxAllyNonAttackableUnitAttack(playPtn)); case AIScriptTokenVariableType.ALLY_MAX_ATTACKABLE_LIFE: return new AIScriptNumericToken(field.GetAllyMaxAttackableLife(tagOwner.IsAlly)); case AIScriptTokenVariableType.ENEMY_UNIT_MIN: return new AIScriptNumericToken(field.CalcMinEvaluateValue(EnemyAI.EmptyPlayPtn, isAlly: false)); case AIScriptTokenVariableType.ENEMY_UNIT_MAX: return new AIScriptNumericToken(field.CalcMaxEvaluateValue(EnemyAI.EmptyPlayPtn, isAlly: false)); case AIScriptTokenVariableType.HAND_COUNT_E: return new AIScriptNumericToken(field.AI.OPPONENT.HandCardList.Count); case AIScriptTokenVariableType.DECK_COUNT_E: return new AIScriptNumericToken(field.AI.PlayerPair.Opponent.DeckCardList.Count); case AIScriptTokenVariableType.PLAYPTN_COUNT: { int allPlayedCountInTurn = field.PlayedCardContainer.GetAllPlayedCountInTurn(tagOwner.IsAlly); if (playPtn != null) { return new AIScriptNumericToken(playPtn.Count + allPlayedCountInTurn + AIEvaluateBonusFromOhterUtility.GetPlayPlusCount(field, playPtn)); } return new AIScriptNumericToken(allPlayedCountInTurn); } case AIScriptTokenVariableType.MEMBER_MAX_LIFE: return new AIScriptNumericToken(field.GetMemberMaxLife(playPtn, tagOwner.IsAlly)); case AIScriptTokenVariableType.MEMBER_ATK_SUM: return new AIScriptNumericToken(field.GetMemberAtkSum(playPtn, tagOwner.IsAlly)); case AIScriptTokenVariableType.MEMBER_LIFE_SUM: return new AIScriptNumericToken(field.GetMemberLifeSum(playPtn, tagOwner.IsAlly)); case AIScriptTokenVariableType.INPLAY_ATTACK_SUM_TO_LEADER: return new AIScriptNumericToken(field.GetInplayAttackSumToLeader(tagOwner.IsAlly)); case AIScriptTokenVariableType.ATTACK_TARGET_ATK_MAX: return new AIScriptNumericToken(field.GetAttackTargetMaxAtk(tagOwner)); case AIScriptTokenVariableType.SUMMON_DRUNKEN_ATK_MAX: return new AIScriptNumericToken(field.GetSummonDrunkenAtkMax(tagOwner)); case AIScriptTokenVariableType.ENEMY_MIN_ATK: return new AIScriptNumericToken(field.GetEnemyInPlayMinAttack()); case AIScriptTokenVariableType.ENEMY_MAX_ATK: return new AIScriptNumericToken(field.GetEnemyInPlayMaxAttack()); case AIScriptTokenVariableType.ENEMY_ATK_SUM: return new AIScriptNumericToken(field.GetInplayAttackSumToLeader(isAlly: false)); case AIScriptTokenVariableType.ALLY_INPLAY_MAX_ATK: return new AIScriptNumericToken(field.GetAllyInplayMaxAttack()); case AIScriptTokenVariableType.GRAVE_COUNT: return new AIScriptNumericToken(field.VirtualCemetery.GetCemeteryCount(tagOwner.IsAlly)); case AIScriptTokenVariableType.ALLY_MAX_PP: return new AIScriptNumericToken(tagOwner.IsAlly ? field.AllyPpTotal : field.EnemyPpTotal); case AIScriptTokenVariableType.ENEMY_MAX_PP: return new AIScriptNumericToken((!tagOwner.IsAlly) ? field.AllyPpTotal : field.EnemyPpTotal); case AIScriptTokenVariableType.REST_PP: return new AIScriptNumericToken((tagOwner != null) ? field.AI.PlayPtnRecorder.GetRestPp(playPtn, field) : 0); case AIScriptTokenVariableType.NOW_REST_PP: return new AIScriptNumericToken(tagOwner.IsAlly ? field.AllyPp : field.EnemyPp); case AIScriptTokenVariableType.ALLY_EP: return new AIScriptNumericToken(tagOwner.IsAlly ? field.AllyEvolutionCount : field.EnemyEvolutionCount); case AIScriptTokenVariableType.ENEMY_EP: return new AIScriptNumericToken(tagOwner.IsAlly ? field.EnemyEvolutionCount : field.AllyEvolutionCount); case AIScriptTokenVariableType.OWN_ATK: return new AIScriptNumericToken(tagOwner.Attack); case AIScriptTokenVariableType.OWN_LIFE: return new AIScriptNumericToken(tagOwner.Life); case AIScriptTokenVariableType.OWN_COST: return new AIScriptNumericToken(tagOwner.Cost); case AIScriptTokenVariableType.OWN_BASE_ATK: return new AIScriptNumericToken(tagOwner.DefaultAttack); case AIScriptTokenVariableType.OWN_BASE_LIFE: return new AIScriptNumericToken(tagOwner.DefaultLife); case AIScriptTokenVariableType.KILLER_ATTACK_VALUE: return new AIScriptNumericToken(tagOwner.EvalKillerAttackValue(playPtn, situation)); case AIScriptTokenVariableType.ENHANCE_COST: return new AIScriptNumericToken(AIEnhanceUtility.GetEnhanceCost(tagOwner, field, playPtn)); case AIScriptTokenVariableType.PLAY_ACTOR_ENHANCE_COST: if (situation == null || situation.ActionType != AIOperationType.PLAY || situation.Actor == null) { return new AIScriptNumericToken(-1f); } return new AIScriptNumericToken(AIEnhanceUtility.GetEnhanceCost(situation.Actor, field, playPtn)); case AIScriptTokenVariableType.ACCELERATE_COST: return new AIScriptNumericToken(AIAccelerateUtility.GetAccelerateCost(tagOwner, field, playPtn)); case AIScriptTokenVariableType.CHOICE_TRANSFORM_COST: return new AIScriptNumericToken(tagOwner.GetChoiceTransformCost(field, playPtn)); case AIScriptTokenVariableType.BASE_SKILL_COUNT: return new AIScriptNumericToken(tagOwner.GetBaseSkillCount()); case AIScriptTokenVariableType.LAST_LIFE: return new AIScriptNumericToken(tagOwner.LastLife); case AIScriptTokenVariableType.MAX_ATTACKABLE_COUNT: return new AIScriptNumericToken(tagOwner.MaxAttackableCount); case AIScriptTokenVariableType.HAND_MIN_COST: if (tagOwner != null && !tagOwner.IsAlly) { return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(field.GetHandMinCost(tagOwner)); case AIScriptTokenVariableType.HAND_MAX_COST: if (!tagOwner.IsAlly) { return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(field.GetHandMaxCost(tagOwner)); case AIScriptTokenVariableType.UNION_BURST_COUNT: { int num3 = 0; if (tagOwner.HasUnionBurst) { num3 = tagOwner.UnionBurstCount; } return new AIScriptNumericToken(num3); } case AIScriptTokenVariableType.CONSUME_EP: return new AIScriptNumericToken((!tagOwner.IsNotConsumeEp) ? 1 : 0); case AIScriptTokenVariableType.LAST_HEAL_AMOUNT: return new AIScriptNumericToken(tagOwner.LastHealAmount); case AIScriptTokenVariableType.JUST_BEFORE_TURN_DAMAGE: return new AIScriptNumericToken(field.JustBeforeTurnLeaderDamage); case AIScriptTokenVariableType.RALLY_COUNT: return new AIScriptNumericToken(tagOwner.IsAlly ? field.AllyRallyCount : field.EnemyRallyCount); case AIScriptTokenVariableType.SKYBOUND_ART_COUNT: { int num2 = 0; if (tagOwner.HasSkyboundArt) { num2 = tagOwner.SkyboundArtCount; } return new AIScriptNumericToken(num2); } case AIScriptTokenVariableType.SUPER_SKYBOUND_ART_COUNT: { int num = 0; if (tagOwner.HasSuperSkyboundArt) { num = tagOwner.SuperSkyboundArtCount; } return new AIScriptNumericToken(num); } case AIScriptTokenVariableType.USED_EP_COUNT: return new AIScriptNumericToken(tagOwner.IsAlly ? field.UsedEpCount : 0); case AIScriptTokenVariableType.USED_PP_COUNT: return new AIScriptNumericToken(tagOwner.IsAlly ? field.UsedPpCount : 0); case AIScriptTokenVariableType.EARTH_RITE_COUNT: return new AIScriptNumericToken(AIGetPreprocessInformationUtility.GetEarthRiteCount(tagOwner, situation)); case AIScriptTokenVariableType.NECROMANCE_COUNT: return new AIScriptNumericToken(AIGetPreprocessInformationUtility.GetNecromanceCount(tagOwner, situation)); case AIScriptTokenVariableType.USED_STACK_COUNT: return new AIScriptNumericToken(tagOwner.IsAlly ? field.AllyGameUsedStackCount : field.EnemyGameUsedStackCount); case AIScriptTokenVariableType.DEFAULT_DAMAGE: return new AIScriptNumericToken(situation.GetCurrentProcessDefaultDamage()); case AIScriptTokenVariableType.NEXT_PLAY_PRIORITY: { AISinglePlayptnRecord bestPlayPtnRecord = field.AI.BestPlayPtnRecord; if (bestPlayPtnRecord == null) { AIConsoleUtility.LogError("NEXT_PLAY_PRIORITY: BestPlayPtnRecord is null! Wrong use timing."); return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(bestPlayPtnRecord.FirstPlayCardPriority); } case AIScriptTokenVariableType.NECROMANCED_COUNT_IN_GAME: return new AIScriptNumericToken(field.GetNecromanceCountInGame(situation, tagOwner.IsAlly)); case AIScriptTokenVariableType.IS_EVO_TURN: return new AIScriptNumericToken((field.AI.ALLY.EvolveWaitTurnCount <= 0) ? 1f : 0f); case AIScriptTokenVariableType.IS_ABLE_EVO: return new AIScriptNumericToken(tagOwner.IsAbleEvolution() ? 1f : 0f); case AIScriptTokenVariableType.IS_F_ADV: return new AIScriptNumericToken((field.AI.FieldAdvantage >= 0f) ? 1f : 0f); case AIScriptTokenVariableType.IS_F_DISADV: return new AIScriptNumericToken((field.AI.FieldAdvantage < 0f) ? 1f : 0f); case AIScriptTokenVariableType.IS_AWAKE: return new AIScriptNumericToken(SkillConditionAwake.IsAwake(tagOwner.IsAlly ? field.AllyPpTotal : field.EnemyPpTotal) ? 1f : 0f); case AIScriptTokenVariableType.IS_BERSERK: return new AIScriptNumericToken(AIBerserkUtility.IsToBeBerserk(field, null, situation, tagOwner.IsAlly) ? 1f : 0f); case AIScriptTokenVariableType.IS_TO_BE_BERSERK: return new AIScriptNumericToken(AIBerserkUtility.IsToBeBerserk(field, playPtn, situation, tagOwner.IsAlly) ? 1f : 0f); case AIScriptTokenVariableType.IS_ON_FIELD: return new AIScriptNumericToken(tagOwner.IsOnField ? 1f : 0f); case AIScriptTokenVariableType.IS_IN_HAND: return new AIScriptNumericToken(tagOwner.IsInHand ? 1f : 0f); case AIScriptTokenVariableType.IS_IN_PLAYPTN: return new AIScriptNumericToken(playPtn.Contains(field.AllyHandCards.FindIndex((AIVirtualCard c) => c.CardIndex == tagOwner.CardIndex)) ? 1f : 0f); case AIScriptTokenVariableType.IS_OWNER_TURN: return new AIScriptNumericToken(tagOwner.IsSelfTurn ? 1f : 0f); case AIScriptTokenVariableType.IS_ALLY: return new AIScriptNumericToken(tagOwner.IsAlly ? 1f : 0f); case AIScriptTokenVariableType.IS_ENEMY: return new AIScriptNumericToken(tagOwner.IsAlly ? 0f : 1f); case AIScriptTokenVariableType.IS_ALLY_FIRST: return new AIScriptNumericToken(field.AI.IsAllyFirst ? 1f : 0f); case AIScriptTokenVariableType.IS_SNEAK: return new AIScriptNumericToken(AISkillSimulationUtility.HasSkill(tagOwner, AIScriptTokenArgType.SNEAK, tagOwner.SelfField.AI, playPtn) ? 1f : 0f); case AIScriptTokenVariableType.IS_KILLER: return new AIScriptNumericToken(AISkillSimulationUtility.HasSkill(tagOwner, AIScriptTokenArgType.KILLER, tagOwner.SelfField.AI, playPtn) ? 1f : 0f); case AIScriptTokenVariableType.IS_MEDUSA: return new AIScriptNumericToken(tagOwner.IsDestroyWhenAttack ? 1f : 0f); case AIScriptTokenVariableType.IS_EVOLVED: return new AIScriptNumericToken((tagOwner.IsUseEvo || tagOwner.IsEvolution) ? 1f : 0f); case AIScriptTokenVariableType.IS_EVOLVING: return new AIScriptNumericToken(tagOwner.IsUseEvo ? 1f : 0f); case AIScriptTokenVariableType.IS_GUARD: return new AIScriptNumericToken(AISkillSimulationUtility.HasSkill(tagOwner, AIScriptTokenArgType.GUARD, tagOwner.SelfField.AI, playPtn) ? 1f : 0f); case AIScriptTokenVariableType.IS_RUSH: return new AIScriptNumericToken(AISkillSimulationUtility.HasSkill(tagOwner, AIScriptTokenArgType.RUSH, tagOwner.SelfField.AI, playPtn) ? 1f : 0f); case AIScriptTokenVariableType.IS_PLAYOUT_ATTACKER: return new AIScriptNumericToken(AttackSelectControl.IsAttackPossible(tagOwner, tagOwner.SelfField.EnemyClass, tagOwner.BaseCard.OpponentBattlePlayer) ? 1f : 0f); case AIScriptTokenVariableType.IS_ENHANCED: return new AIScriptNumericToken(tagOwner.IsEnhanced(field, playPtn, situation) ? 1f : 0f); case AIScriptTokenVariableType.IS_ACCELERATE: return new AIScriptNumericToken(tagOwner.IsAccelerated(field, playPtn, situation) ? 1f : 0f); case AIScriptTokenVariableType.IS_CRYSTALIZE: return new AIScriptNumericToken(tagOwner.IsCrystalize(field, playPtn, situation) ? 1f : 0f); case AIScriptTokenVariableType.IS_ATTACK_LEADER: if (situation != null && situation is AIVirtualAttackInfo aIVirtualAttackInfo) { return new AIScriptNumericToken((aIVirtualAttackInfo.AttackTarget != null && aIVirtualAttackInfo.AttackTarget.IsLeader) ? 1f : 0f); } return new AIScriptNumericToken(0f); case AIScriptTokenVariableType.IS_FANFARE: return new AIScriptNumericToken(field.IsEnableIgnoreFanfareBonus(playPtn) ? 0f : 1f); case AIScriptTokenVariableType.IS_SKILL_REMOVED: return new AIScriptNumericToken(tagOwner.IsSkillLost ? 1f : 0f); case AIScriptTokenVariableType.IS_BARBAROSSA: return new AIScriptNumericToken(field.AI.IsOpponentBarbarossaDestroyed ? 1f : 0f); case AIScriptTokenVariableType.IS_RESONANCE: return new AIScriptNumericToken(field.IsResonance(tagOwner.IsAlly) ? 1f : 0f); case AIScriptTokenVariableType.IS_LETHAL: return new AIScriptNumericToken(field.AI.IsLethal(tagOwner, field, playPtn, situation) ? 1f : 0f); case AIScriptTokenVariableType.IS_USED_EVO: return new AIScriptNumericToken(field.AI.ALLY.NowTurnEvol ? 0f : 1f); case AIScriptTokenVariableType.IS_FIRST_TURN: return new AIScriptNumericToken(tagOwner.IsFirstTurn ? 1f : 0f); case AIScriptTokenVariableType.IS_DAMAGED: return new AIScriptNumericToken((tagOwner.MaxLife - tagOwner.Life > 0) ? 1f : 0f); case AIScriptTokenVariableType.IS_DELAY_HEAL: return new AIScriptNumericToken(tagOwner.IsDelayHeal(field, situation) ? 1f : 0f); case AIScriptTokenVariableType.IS_NOT_ATTACK_YET: return new AIScriptNumericToken(tagOwner.IsNotAttackYet ? 1f : 0f); case AIScriptTokenVariableType.IS_LEADER: return new AIScriptNumericToken(tagOwner.IsLeader ? 1f : 0f); case AIScriptTokenVariableType.IS_GET_ON: return new AIScriptNumericToken(tagOwner.IsGetOn ? 1f : 0f); case AIScriptTokenVariableType.IS_SKILL_SUMMONED: return new AIScriptNumericToken((tagOwner.IsOnField && tagOwner.IsSkillSummoned) ? 1f : 0f); case AIScriptTokenVariableType.IS_UNTOUCHABLE: return new AIScriptNumericToken(AISkillSimulationUtility.HasSkill(tagOwner, AIScriptTokenArgType.UNTOUCHABLE, tagOwner.SelfField.AI, playPtn) ? 1f : 0f); case AIScriptTokenVariableType.IS_FORCE_TARGETING: return new AIScriptNumericToken(AISkillSimulationUtility.HasSkill(tagOwner, AIScriptTokenArgType.FORCE_TARGETING, tagOwner.SelfField.AI, playPtn) ? 1f : 0f); case AIScriptTokenVariableType.IS_QUICK: return new AIScriptNumericToken(AISkillSimulationUtility.HasSkill(tagOwner, AIScriptTokenArgType.QUICK, tagOwner.SelfField.AI, playPtn) ? 1f : 0f); case AIScriptTokenVariableType.IS_NOT_BE_ATTACKED: return new AIScriptNumericToken(((situation != null && situation.ActionType == AIOperationType.ATTACK) ? tagOwner.IsCantUnderAttack(field.ParamQuery, situation.Actor, playPtn, field) : tagOwner.IsCantUnderAnyAttack()) ? 1f : 0f); case AIScriptTokenVariableType.IS_IN_SIMULATION: return new AIScriptNumericToken(field.AI.IsInVirutalSimulation ? 1f : 0f); case AIScriptTokenVariableType.IS_IGNORE_GUARD: return new AIScriptNumericToken(AISkillSimulationUtility.HasSkill(tagOwner, AIScriptTokenArgType.IGNORE_GUARD, tagOwner.SelfField.AI, playPtn) ? 1f : 0f); case AIScriptTokenVariableType.IS_ATTACKED: return new AIScriptNumericToken(tagOwner.IsAttacked ? 1f : 0f); case AIScriptTokenVariableType.IS_ONEMORELASTWORD_TAGGED: return new AIScriptNumericToken(AIOneMoreLastwordUtility.IsHoldingOneMoreLastword(tagOwner, field) ? 1f : 0f); case AIScriptTokenVariableType.IS_DRAIN: return new AIScriptNumericToken(tagOwner.IsDrain ? 1f : 0f); default: return null; } } public static AIScriptTokenBase CalculateFunctionToken(List argList, AIScriptFunctionToken funcToken, AIVirtualField field, List playPtn, AIVirtualCard tagOwner, AISituationInfo situation) { if (argList.Count != funcToken.ArgCount) { return null; } AIVirtualCard aIVirtualCard = null; AIVirtualCard aIVirtualCard2 = null; if (situation is AIVirtualAttackInfo aIVirtualAttackInfo) { aIVirtualCard2 = aIVirtualAttackInfo.AttackTarget; aIVirtualCard = ((situation.Actor.IsAlly != tagOwner.IsAlly) ? aIVirtualAttackInfo.Actor : aIVirtualAttackInfo.AttackTarget); } switch (funcToken.FuncType) { case AIScriptTokenFuncType.MEMBER_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIFilteringUtility.MultipleFiltering(field.GetFieldCountCardList(playPtn), argList, tagOwner, playPtn, situation)?.Count ?? 0); case AIScriptTokenFuncType.POW: { float value2 = argList[1].Value; float value3 = argList[0].Value; return new AIScriptNumericToken(Mathf.Pow(value2, value3)); } case AIScriptTokenFuncType.CEILING: return new AIScriptNumericToken(Mathf.Ceil(argList[0].Value)); case AIScriptTokenFuncType.FLOOR: return new AIScriptNumericToken(Mathf.Floor(argList[0].Value)); case AIScriptTokenFuncType.EVAL_RANDOM_MULTI_DAMAGE: { argList.Reverse(); AIRandomMultiDamageEvaluator.CreateEvalRandomDamageArgList(argList, out var filters, out var damage6, out var count6); return new AIScriptNumericToken(AIRandomMultiDamageEvaluator.EvaluateRandomDamageAverage(tagOwner, field, playPtn, situation, filters, damage6, count6)); } case AIScriptTokenFuncType.EVAL_RANDOM_MULTI_DAMAGE_MAX: { argList.Reverse(); AIRandomMultiDamageEvaluator.CreateEvalRandomDamageArgList(argList, out var filters2, out var damage7, out var count7); return new AIScriptNumericToken(AIRandomMultiDamageEvaluator.EvaluateRandomDamageMax(tagOwner, field, playPtn, filters2, situation, damage7, count7)); } case AIScriptTokenFuncType.EVAL_INSTANT_ATTACK: { int attack2 = (int)argList[2].Value; int life2 = (int)argList[1].Value; int count5 = (int)argList[0].Value; return new AIScriptNumericToken(AIInstantAttackUtility.EvalInstantAttack(attack2, life2, count5, playPtn, tagOwner, situation)); } case AIScriptTokenFuncType.EVAL_RUSH: { int attack = (int)argList[2].Value; int life = (int)argList[1].Value; int count4 = (int)argList[0].Value; bool isRush = true; return new AIScriptNumericToken(AIInstantAttackUtility.EvalInstantAttack(attack, life, count4, playPtn, tagOwner, situation, isRush)); } case AIScriptTokenFuncType.INPLAY_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIFilteringUtility.MultipleFiltering(field.CardListSet.BothInplayCards, argList, tagOwner, playPtn, situation)?.Count ?? 0); case AIScriptTokenFuncType.PLAYOUT_ATTACKER_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIPlayoutAttackerCountUtility.GetPlayoutAttackerCount(field, tagOwner, playPtn, argList, situation)); case AIScriptTokenFuncType.BEFORE_PLAYPTN_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIPlayPtnUtility.GetBeforePlayPtnCount(argList, tagOwner, playPtn, situation)); case AIScriptTokenFuncType.PLAY_TOKEN_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIPlayTokenSimulationUtility.GetPlayTokenCount(argList, tagOwner, playPtn, situation)); case AIScriptTokenFuncType.EVO_COUNT_IN_GAME: return new AIScriptNumericToken(field.GetEvolutionCountInGame(tagOwner, ((AIScriptArgumentToken)argList[0]).ArgumentType)); case AIScriptTokenFuncType.EVO_COUNT_IN_PREVIOUS_TURN: return new AIScriptNumericToken(field.GetEvolutionCountInPreviousTurn(tagOwner, ((AIScriptArgumentToken)argList[0]).ArgumentType)); case AIScriptTokenFuncType.HAND_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIHandCountUtility.GetHandCount(field, argList, tagOwner, situation, playPtn)); case AIScriptTokenFuncType.HAND_NAME_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIHandCountUtility.GetHandNameCount(field, argList, tagOwner, situation, playPtn)); case AIScriptTokenFuncType.SKILL_COUNT_FROM_ID: { int iD6 = ((AIScriptIDToken)argList[0]).ID; argList.RemoveAt(0); argList.Reverse(); return new AIScriptNumericToken(AISkillCountFromIdUtility.GetSkillCountFromID(argList, iD6, tagOwner, playPtn, situation)); } case AIScriptTokenFuncType.TAG_COUNT_FROM_ID: { int iD5 = ((AIScriptIDToken)argList[0]).ID; argList.RemoveAt(0); argList.Reverse(); return new AIScriptNumericToken(AITagCountFromIdUtility.GetTagCountFromId(tagOwner, iD5, argList, field, playPtn, situation)); } case AIScriptTokenFuncType.EVAL_CHANT_COUNT_CHANGE: { int amount2 = (int)argList[0].Value; return new AIScriptNumericToken(AICountdownChangeUtility.EvalChantCountChange(tagOwner, amount2, playPtn, isSelect: true, situation)); } case AIScriptTokenFuncType.EVAL_CHANT_COUNT_CHANGE_ALL: { int amount = (int)argList[0].Value; return new AIScriptNumericToken(AICountdownChangeUtility.EvalChantCountChange(tagOwner, amount, playPtn, isSelect: false, situation)); } case AIScriptTokenFuncType.EVAL_ALL_DAMAGE: { List list19 = new List(); for (int num25 = argList.Count - 1; num25 > 0; num25--) { list19.Add(argList[num25]); } int damage8 = (int)argList[0].Value; return new AIScriptNumericToken(AIDamageSimulationUtility.EvalMultiAllDamage(tagOwner, field, list19, playPtn, situation, damage8, 1)); } case AIScriptTokenFuncType.EVAL_TARGETING_DAMAGE: { List list12 = new List(); for (int num18 = argList.Count - 1; num18 > 0; num18--) { list12.Add(argList[num18]); } int damage3 = (int)argList[0].Value; return new AIScriptNumericToken(AIDamageSimulationUtility.EvalTargetingDamage(tagOwner, field, list12, playPtn, situation, damage3)); } case AIScriptTokenFuncType.EVAL_TARGETING_AND_RANDOM_MULTI_DAMAGE: { if (argList.Count < 5) { return new AIScriptNumericToken(0f); } new List(); int num12 = 0; argList.Reverse(); for (int num13 = 1; num13 < argList.Count; num13++) { if (argList[num13] is AIScriptNumericToken) { num12 = num13; break; } } List range3 = argList.GetRange(0, num12); List range4 = argList.GetRange(num12 + 1, argList.Count - num12 - 3); int targetDamage = (int)argList[num12].Value; int randomDamage = (int)argList[argList.Count - 2].Value; int randomDamageCount = (int)argList[argList.Count - 1].Value; return new AIScriptNumericToken(AIDamageSimulationUtility.EvalTargetingDamageAndRandomMultiSelectDamage(tagOwner, field, range3, range4, playPtn, situation, targetDamage, randomDamage, randomDamageCount)); } case AIScriptTokenFuncType.EVAL_ALL_MULTI_DAMAGE: { List list2 = new List(); for (int num3 = argList.Count - 2; num3 > 0; num3--) { list2.Add(argList[num3]); } int damage = (int)argList[1].Value; int damageCount = (int)argList[0].Value; return new AIScriptNumericToken(AIDamageSimulationUtility.EvalMultiAllDamage(tagOwner, field, list2, playPtn, situation, damage, damageCount)); } case AIScriptTokenFuncType.EVAL_ALL_DESTROY: argList.Reverse(); return new AIScriptNumericToken(AIDestroySimulationUtility.EvalAllDestroy(argList, tagOwner, playPtn, situation)); case AIScriptTokenFuncType.EVAL_TARGETING_DESTROY: argList.Reverse(); return new AIScriptNumericToken(AIDestroySimulationUtility.EvalTargetingDestroy(argList, tagOwner, playPtn, situation)); case AIScriptTokenFuncType.EVAL_TARGETING_OTHER_DESTROY: { AIScriptTokenBase aIScriptTokenBase = argList[0]; argList.RemoveAt(0); int select_count = 0; if (aIScriptTokenBase is AIScriptNumericToken) { select_count = (int)(aIScriptTokenBase as AIScriptNumericToken).Value; } argList.Reverse(); int num4 = 0; int num5 = 1; while (argList != null && num5 < argList.Count) { if (argList != null && argList.Count > 0 && argList[num5] is AIScriptArgumentToken aIScriptArgumentToken6 && aIScriptArgumentToken6.IsSideArgType()) { num4 = num5; } num5++; } List range = argList.GetRange(0, num4); List range2 = argList.GetRange(num4, argList.Count - num4); return new AIScriptNumericToken(AIDestroySimulationUtility.EvalTargetingOtherDestroy(range, range2, tagOwner, playPtn, situation, select_count)); } case AIScriptTokenFuncType.EVAL_TARGETING_MULTI_DESTROY: { int num29 = 0; if (argList[0] is AIScriptNumericToken aIScriptNumericToken2) { num29 = (int)aIScriptNumericToken2.Value; } if (num29 == 0) { return new AIScriptNumericToken(0f); } argList.RemoveAt(0); argList.Reverse(); return new AIScriptNumericToken(AIDestroySimulationUtility.EvalTargetingMultiDestroy(argList, num29, tagOwner, playPtn, situation)); } case AIScriptTokenFuncType.EVAL_ALL_BOUNCE: argList.Reverse(); return new AIScriptNumericToken(field?.EvalAllBounce(argList, tagOwner, playPtn) ?? 0f); case AIScriptTokenFuncType.EVAL_TARGETING_BOUNCE: argList.Reverse(); return new AIScriptNumericToken(field?.EvalTargetingBounce(argList, tagOwner, playPtn) ?? 0f); case AIScriptTokenFuncType.EVAL_TARGETING_BANISH: argList.Reverse(); return new AIScriptNumericToken((field != null) ? AIBanishSimulationUtility.EvalTargetingBanish(argList, playPtn, field, tagOwner, situation) : 0f); case AIScriptTokenFuncType.EVAL_RANDOM_BANISH: { int count3 = (int)argList[0].Value; List list5 = new List(); for (int num9 = argList.Count - 1; num9 > 0; num9--) { list5.Add(argList[num9]); } return new AIScriptNumericToken((field != null) ? AIBanishSimulationUtility.EvalRandomBanish(list5, tagOwner, field, playPtn, count3, situation) : 0f); } case AIScriptTokenFuncType.EVAL_ALL_BANISH: argList.Reverse(); return new AIScriptNumericToken(AIBanishSimulationUtility.EvalAllBanish(argList, tagOwner, field, playPtn, situation)); case AIScriptTokenFuncType.EVAL_RANDOM_DESTROY: { int count2 = (int)argList[0].Value; argList.RemoveAt(0); argList.Reverse(); return new AIScriptNumericToken(AIDestroySimulationUtility.EvalRandomDestroy(argList, count2, tagOwner, playPtn, situation)); } case AIScriptTokenFuncType.EVAL_RANDOM_BOUNCE: { int count = (int)argList[0].Value; argList.Reverse(); return new AIScriptNumericToken(field?.EvalRandomBounce(argList.GetRange(0, argList.Count - 1), tagOwner, field, playPtn, count) ?? 0f); } case AIScriptTokenFuncType.EVAL_TARGETING_HEAL: { List list4 = new List(); for (int num7 = argList.Count - 1; num7 > 0; num7--) { list4.Add(argList[num7]); } int heal2 = (int)argList[0].Value; return new AIScriptNumericToken(AIHealSimulationUtility.EvalTargetingHeal(tagOwner, list4, playPtn, heal2)); } case AIScriptTokenFuncType.EVAL_ALL_HEAL: { List list3 = new List(); for (int num6 = argList.Count - 1; num6 > 0; num6--) { list3.Add(argList[num6]); } int heal = (int)argList[0].Value; return new AIScriptNumericToken(AIHealSimulationUtility.EvalAllHeal(tagOwner, list3, playPtn, heal)); } case AIScriptTokenFuncType.EVAL_TARGETING_METAMORPHOSE: { List list = new List(); for (int num2 = argList.Count - 1; num2 > 0; num2--) { list.Add(argList[num2]); } float value = 0f; if (argList[0] is AIScriptIDToken) { int iD = ((AIScriptIDToken)argList[0]).ID; value = AIMetamorphoseSimulationUtility.EvalTargetingMetamorphose(tagOwner, field, list, iD, playPtn, situation); } return new AIScriptNumericToken(value); } case AIScriptTokenFuncType.EVAL_RANDOM_METAMORPHOSE: { if (argList.Count < 2) { return new AIScriptNumericToken(0f); } List list18 = new List(); for (int num24 = argList.Count - 1; num24 > 1; num24--) { list18.Add(argList[num24]); } int count8 = (int)argList[0].Value; float value6 = 0f; if (argList[1] is AIScriptIDToken) { int iD4 = ((AIScriptIDToken)argList[1]).ID; value6 = AIMetamorphoseSimulationUtility.EvalRandomMetamorphose(tagOwner, field, list18, iD4, playPtn, count8, situation); } return new AIScriptNumericToken(value6); } case AIScriptTokenFuncType.EVAL_ALL_METAMORPHOSE: { List list17 = new List(); for (int num23 = argList.Count - 1; num23 > 0; num23--) { list17.Add(argList[num23]); } float value5 = 0f; if (argList[0] is AIScriptIDToken) { int iD3 = ((AIScriptIDToken)argList[0]).ID; value5 = AIMetamorphoseSimulationUtility.EvalAllMetamorphose(tagOwner, field, list17, iD3, playPtn, situation); } return new AIScriptNumericToken(value5); } case AIScriptTokenFuncType.EVAL_ALL_BUFF: return new AIScriptNumericToken(AIBuffEvaluationUtility.EvalAllBuff(tagOwner, field, argList, playPtn, situation)); case AIScriptTokenFuncType.EVAL_RANDOM_BUFF: return new AIScriptNumericToken(AIBuffEvaluationUtility.EvalRandomBuff(tagOwner, field, argList, playPtn, situation)); case AIScriptTokenFuncType.EVAL_TARGETING_BUFF: return new AIScriptNumericToken(AIBuffEvaluationUtility.EvalTargetingBuff(tagOwner, field, argList, playPtn, situation)); case AIScriptTokenFuncType.EVAL_ECHO_DAMAGE: { List list11 = new List(); for (int num17 = argList.Count - 1; num17 > 0; num17--) { list11.Add(argList[num17]); } int damage2 = (int)argList[0].Value; return new AIScriptNumericToken(AIDamageSimulationUtility.EvalEchoDamage(tagOwner, field, list11, damage2, playPtn, situation)); } case AIScriptTokenFuncType.EVAL_LEADER_DAMAGE: { int damageAmount = (int)argList[0].Value; AIScriptTokenArgType argumentType3 = ((AIScriptArgumentToken)argList[1]).ArgumentType; AIVirtualCard aIVirtualCard4 = null; switch (argumentType3) { case AIScriptTokenArgType.ENEMY_CLASS: aIVirtualCard4 = (tagOwner.IsAlly ? field.EnemyClass : field.AllyClass); break; case AIScriptTokenArgType.ALLY_CLASS: aIVirtualCard4 = (tagOwner.IsAlly ? field.AllyClass : field.EnemyClass); break; default: return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(AILeaderLifeEvaluationUtility.Evaluate(aIVirtualCard4.Life - aIVirtualCard4.SimulateDamageAmount(damageAmount, isSkillDamage: true, tagOwner.IsSpell), aIVirtualCard4.Life, aIVirtualCard4.IsAlly, tagOwner.IsAlly)); } case AIScriptTokenFuncType.EVAL_LEADER_HEAL: { int originalHealValue = (int)argList[0].Value; AIScriptTokenArgType argumentType4 = ((AIScriptArgumentToken)argList[1]).ArgumentType; AIVirtualCard aIVirtualCard5 = null; switch (argumentType4) { case AIScriptTokenArgType.ENEMY_CLASS: aIVirtualCard5 = (tagOwner.IsAlly ? field.EnemyClass : field.AllyClass); break; case AIScriptTokenArgType.ALLY_CLASS: aIVirtualCard5 = (tagOwner.IsAlly ? field.AllyClass : field.EnemyClass); break; } if (aIVirtualCard5 == null || aIVirtualCard5.Life <= 0) { return new AIScriptNumericToken(0f); } originalHealValue = AIHealSimulationUtility.CalcHealModifier(aIVirtualCard5, playPtn, situation, originalHealValue); return new AIScriptNumericToken(AILeaderLifeEvaluationUtility.Evaluate(Mathf.Min(aIVirtualCard5.Life + originalHealValue, aIVirtualCard5.MaxLife), aIVirtualCard5.Life, aIVirtualCard5.IsAlly, tagOwner.IsAlly)); } case AIScriptTokenFuncType.DECK_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIDeckSimulationUtility.GetFilteredDeck(argList, tagOwner, field, playPtn, situation)?.Count ?? 0); case AIScriptTokenFuncType.IS_CLASH_TARGET: if (aIVirtualCard == null) { return new AIScriptNumericToken(0f); } argList.Reverse(); return new AIScriptNumericToken(AIFilteringUtility.CheckMatchTargetFiltering(aIVirtualCard, null, argList, playPtn, tagOwner, situation) ? 1f : 0f); case AIScriptTokenFuncType.IS_ATTACK_TARGET: { if (aIVirtualCard2 == null) { return new AIScriptNumericToken(0f); } AIScriptArgumentToken obj = (AIScriptArgumentToken)argList[0]; AIScriptTokenArgType argumentType2 = obj.ArgumentType; _ = obj.IsNot; return new AIScriptNumericToken(AISkillSimulationUtility.HasSkill(aIVirtualCard2, argumentType2, tagOwner.SelfField.AI, playPtn) ? 1f : 0f); } case AIScriptTokenFuncType.IS_SELECTED_TARGET: { AIScriptTokenArgType aIScriptTokenArgType2 = AIScriptTokenArgType.NONE; if (argList[0] is AIScriptArgumentToken aIScriptArgumentToken10) { aIScriptTokenArgType2 = aIScriptArgumentToken10.ArgumentType; } if (aIScriptTokenArgType2 != AIScriptTokenArgType.TARGET_SELECT && aIScriptTokenArgType2 != AIScriptTokenArgType.SECOND_TARGET_SELECT) { return new AIScriptNumericToken(0f); } AISelectedTargetInfo situationTarget = situation.GetSituationTarget(aIScriptTokenArgType2); if (situationTarget == null || !situationTarget.HasTarget) { return new AIScriptNumericToken(0f); } argList.RemoveAt(0); argList.Reverse(); List targets = situationTarget.Targets; bool flag = false; for (int num26 = 0; num26 < targets.Count; num26++) { if (AIFilteringUtility.CheckMatchTargetFiltering(targets[num26], null, argList, playPtn, tagOwner, situation)) { flag = true; break; } } return new AIScriptNumericToken(flag ? 1f : 0f); } case AIScriptTokenFuncType.IS_NEXT_PLAY: if (playPtn == null || playPtn.Count <= 0) { return new AIScriptNumericToken(0f); } argList.Reverse(); return new AIScriptNumericToken(AIFilteringUtility.CheckMatchTargetFiltering(field.AllyHandCards[playPtn[0]], field.AllyHandCards, argList, playPtn, tagOwner, situation) ? 1 : 0); case AIScriptTokenFuncType.LIFE: argList.Reverse(); return new AIScriptNumericToken(AIGetStatusUtility.GetLife(tagOwner, field, playPtn, situation, argList)); case AIScriptTokenFuncType.ATTACK: argList.Reverse(); return new AIScriptNumericToken(AIGetStatusUtility.GetAttack(tagOwner, field, playPtn, situation, argList)); case AIScriptTokenFuncType.EVAL_RANDOM_MULTI_SELECT_DAMAGE: { List list16 = new List(); for (int num20 = argList.Count - 1; num20 > 0; num20--) { list16.Add(argList[num20]); } int damage5 = (int)argList[0].Value; int selectCount = (int)argList[1].Value; return new AIScriptNumericToken(AIDamageSimulationUtility.EvalRandomMultiSelectDamage(tagOwner, field, list16, playPtn, situation, damage5, selectCount)); } case AIScriptTokenFuncType.EVAL_DIVIDED_DAMAGE: { AIScriptTokenBase aIScriptTokenBase4 = argList[0]; int damage4 = (int)aIScriptTokenBase4.Value; argList.Remove(aIScriptTokenBase4); argList.Reverse(); List candidates = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, argList, tagOwner, playPtn, situation); return new AIScriptNumericToken(AIDamageSimulationUtility.EvalOldestDamage(tagOwner, candidates, field, damage4, playPtn, situation)); } case AIScriptTokenFuncType.DECK_NAME_COUNT: { argList.Reverse(); List filteredDeck2 = AIDeckSimulationUtility.GetFilteredDeck(argList, tagOwner, field, playPtn, situation); return new AIScriptNumericToken((filteredDeck2 != null) ? AIFilteringUtility.GetCardNameCountFromList(filteredDeck2, argList, tagOwner, playPtn, situation) : 0); } case AIScriptTokenFuncType.BROKEN_COUNT: { float num10 = 0f; AIScriptTokenBase aIScriptTokenBase2 = argList[0]; int num11 = (int)aIScriptTokenBase2.Value; if (num11 == 142) { argList.Remove(aIScriptTokenBase2); } argList.Reverse(); List list6 = AIFilteringUtility.MultipleFiltering(tagOwner.IsAlly ? field.CardListSet.AllyDestroyedCards : field.CardListSet.EnemyDestroyedCards, argList, tagOwner, playPtn, null, isBlockDeadCard: false); if (num11 == 142) { if (list6 != null) { foreach (AIVirtualCard item in list6) { if (item.DeadTurn) { num10 += 1f; } } } return new AIScriptNumericToken(num10); } num10 = ((list6 != null) ? ((float)list6.Count) : 0f); return new AIScriptNumericToken(num10); } case AIScriptTokenFuncType.BROKEN_NAME_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIFilteringUtility.GetCardNameCountFromList(tagOwner.IsAlly ? field.CardListSet.AllyDestroyedCards : field.CardListSet.EnemyDestroyedCards, argList, tagOwner, playPtn, situation)); case AIScriptTokenFuncType.BROKEN_COST_SUM: argList.Reverse(); return new AIScriptNumericToken(AIBrokenCostSumUtility.GetBrokenCostSum(field, tagOwner, argList, playPtn, situation)); case AIScriptTokenFuncType.LEAVE_NAME_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIFilteringUtility.GetCardNameCountFromList(tagOwner.IsAlly ? field.CardListSet.AllyLeftCards : field.CardListSet.EnemyLeftCards, argList, tagOwner, playPtn, situation)); case AIScriptTokenFuncType.LEAVE_COUNT: { AIScriptTokenBase aIScriptTokenBase5 = argList[0]; int num30 = (int)aIScriptTokenBase5.Value; if (num30 == 142) { argList.Remove(aIScriptTokenBase5); } argList.Reverse(); List targets2 = ((num30 != 142) ? (tagOwner.IsAlly ? field.CardListSet.AllyLeftCards : field.CardListSet.EnemyLeftCards) : (tagOwner.IsAlly ? field.CardListSet.AllyLeftCardsThisTurn : field.CardListSet.EnemyLeftCardsThisTurn)); return new AIScriptNumericToken(AIFilteringUtility.MultipleFiltering(targets2, argList, tagOwner, playPtn, situation, isBlockDeadCard: false)?.Count ?? 0); } case AIScriptTokenFuncType.DESTROYED_COUNT: { AIScriptIDToken aIScriptIDToken2 = argList[0] as AIScriptIDToken; float num27 = 0f; if (aIScriptIDToken2 != null) { int iD7 = aIScriptIDToken2.ID; foreach (AIVirtualCard enemyDestroyedCard in field.CardListSet.EnemyDestroyedCards) { if (!enemyDestroyedCard.IsUnit) { continue; } List destroyedBySkillList = enemyDestroyedCard.BaseCard.DestroyedBySkillList; for (int num28 = 0; num28 < destroyedBySkillList.Count; num28++) { if (destroyedBySkillList.ElementAt(num28).BaseCardId == iD7) { num27 += 1f; } } } } return new AIScriptNumericToken(num27); } case AIScriptTokenFuncType.IS_TRIBE: { AIScriptTokenArgType argumentType6 = ((AIScriptArgumentToken)argList[0]).ArgumentType; return new AIScriptNumericToken(tagOwner.IsTribe(argumentType6) ? 1f : 0f); } case AIScriptTokenFuncType.PLAYED_COUNT: argList.Reverse(); return new AIScriptNumericToken(field.PlayedCardContainer.GetPlayedCountInTurn(argList, tagOwner, playPtn, situation)); case AIScriptTokenFuncType.PLAYED_COUNT_IN_GAME: argList.Reverse(); return new AIScriptNumericToken(field.PlayedCardContainer.GetPlayedCountInGame(argList, tagOwner, playPtn, situation)); case AIScriptTokenFuncType.PLAYED_COUNT_IN_PREVIOUS_TURN: argList.Reverse(); if (argList[0] is AIScriptArgumentToken aIScriptArgumentToken9 && aIScriptArgumentToken9.IsSideArgType(includeBoth: false)) { bool isAllyList = tagOwner.IsAlly == (aIScriptArgumentToken9.ArgumentType == AIScriptTokenArgType.ALLY); return new AIScriptNumericToken(field.PlayedCardContainer.GetPlayedCountInPreviousTurn(isAllyList, argList, tagOwner, playPtn, situation)); } AIConsoleUtility.LogError("PLAYED_COUNT_IN_PREVIOUS_TURN error!! side parameter is missing"); return new AIScriptNumericToken(0f); case AIScriptTokenFuncType.PLAYED_NAME_COUNT: { AIScriptTokenArgType turnOrGame = AIScriptTokenArgType.NONE; if (argList[0] is AIScriptArgumentToken aIScriptArgumentToken8) { turnOrGame = aIScriptArgumentToken8.ArgumentType; } argList.RemoveAt(0); argList.Reverse(); return new AIScriptNumericToken(field.PlayedCardContainer.GetPlayedNameCount(argList, turnOrGame, tagOwner, playPtn, situation)); } case AIScriptTokenFuncType.RANDOM: { if (argList[0].Value == 0f) { return new AIScriptNumericToken(0f); } int num21 = field.AI.ALLY.DeckCardList.Count; for (int num22 = 0; num22 < field.AllyHandCards.Count; num22++) { num21 += field.AllyHandCards[num22].BaseCost; } return new AIScriptNumericToken((float)num21 % argList[0].Value); } case AIScriptTokenFuncType.IS_REANIMATE: { int cost = (int)argList[0].Value; return new AIScriptNumericToken(AIReanimateSimulationUtility.IsReanimate(tagOwner, cost) ? 1f : 0f); } case AIScriptTokenFuncType.DAMAGE_COUNT: { argList.Reverse(); AIScriptTokenArgType argumentType5 = ((AIScriptArgumentToken)argList[0]).ArgumentType; if (argumentType5 != AIScriptTokenArgType.TURN && argumentType5 != AIScriptTokenArgType.GAME) { return new AIScriptNumericToken(0f); } int num19 = 0; if (argList.Count == 1) { num19 = AIPlayerLifeSimulationUtility.GetAllSelfTurnDamageCount(tagOwner, field, playPtn, argumentType5); } else { switch (((AIScriptArgumentToken)argList[1]).ArgumentType) { case AIScriptTokenArgType.PLAYED: num19 = AIPlayerLifeSimulationUtility.GetSelfTurnDamageCountAtPlayed(tagOwner, field, playPtn, argumentType5); break; case AIScriptTokenArgType.PLAYPTN: num19 = AIPlayerLifeSimulationUtility.GetSelfTurnDamageCountAtPlayPtn(tagOwner, field, playPtn); break; case AIScriptTokenArgType.BEFORE_PLAYPTN: num19 = AIPlayerLifeSimulationUtility.GetSelfTurnDamageCountAtBeforePlayPtn(tagOwner, field, playPtn, argumentType5); break; } } return new AIScriptNumericToken(num19); } case AIScriptTokenFuncType.HEAL_COUNT: return new AIScriptNumericToken(AIHealCountUtility.GetHealCount(tagOwner, field, situation, playPtn, argList)); case AIScriptTokenFuncType.FORCED_EXCHANGE: { int attackLimit = (int)argList[0].Value; return new AIScriptNumericToken(field.EvalForcedExchangeVirtual(attackLimit, playPtn)); } case AIScriptTokenFuncType.TOTAL_DAMAGE: return new AIScriptNumericToken(field.GetTotalDamage(argList, tagOwner, situation)); case AIScriptTokenFuncType.EVAL_REANIMATE: return new AIScriptNumericToken(AIEvalReanimateUtility.EvalReanimate(tagOwner, playPtn, situation, argList)); case AIScriptTokenFuncType.FUSION_COUNT: return new AIScriptNumericToken(AIFusionCountUtility.GetFusionCount(tagOwner, argList, playPtn, situation)); case AIScriptTokenFuncType.NOW_FUSION_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIFusionCountUtility.GetNowFusionCount(tagOwner, argList, playPtn)); case AIScriptTokenFuncType.FUSION_COUNT_AT_ONCE: return new AIScriptNumericToken(AIFusionCountUtility.GetFusionCountAtOnce(tagOwner, argList, playPtn, situation)); case AIScriptTokenFuncType.FUSION_NAME_COUNT: return new AIScriptNumericToken(AIFusionCountUtility.GetFusionNameCount(tagOwner, argList, playPtn, situation)); case AIScriptTokenFuncType.IS_SKILL_OCCURRED: return new AIScriptNumericToken(tagOwner.IsSkillOccurred(field, playPtn, situation, argList) ? 1f : 0f); case AIScriptTokenFuncType.SKILL_ACTIVATE_COUNT: return new AIScriptNumericToken(tagOwner.GetSkillActivateCount(field, playPtn, situation, argList)); case AIScriptTokenFuncType.HAND_MAX_ATTACK: { argList.Reverse(); argList.Add(new AIScriptArgumentToken(AIScriptTokenArgType.MAX_ATTACK, isNot: false)); List list9 = AIFilteringUtility.MultipleFiltering(field.AllyHandCards, argList, tagOwner, playPtn, situation); if (list9 == null || list9.Count <= 0) { return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(list9[0].Attack); } case AIScriptTokenFuncType.DECK_MAX_COST: { argList.Reverse(); List filteredDeck = AIDeckSimulationUtility.GetFilteredDeck(argList, tagOwner, field, playPtn, situation); if (filteredDeck == null || filteredDeck.Count <= 0) { return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(filteredDeck.Max((AIVirtualCard c) => c.BaseCost)); } case AIScriptTokenFuncType.INPLAY_LARGEST_LIFE: { argList.Reverse(); List list7 = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothInplayCards, argList, tagOwner, playPtn, situation); if (list7 == null || list7.Count <= 0) { return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(list7.Max((AIVirtualCard c) => c.Life)); } case AIScriptTokenFuncType.LEADER_MAX_LIFE: { if (!(argList[0] is AIScriptArgumentToken aIScriptArgumentToken5)) { return new AIScriptNumericToken(0f); } AIVirtualCard aIVirtualCard3 = null; if (aIScriptArgumentToken5.ArgumentType == AIScriptTokenArgType.OPPONENT) { aIVirtualCard3 = (tagOwner.IsAlly ? field.EnemyClass : field.AllyClass); } else if (aIScriptArgumentToken5.ArgumentType == AIScriptTokenArgType.ALLY) { aIVirtualCard3 = (tagOwner.IsAlly ? field.AllyClass : field.EnemyClass); } if (aIVirtualCard3 == null) { return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(aIVirtualCard3.MaxLife); } case AIScriptTokenFuncType.IS_DISCARD_TARGET: argList.Reverse(); return new AIScriptNumericToken(AIDiscardUtility.IsMatchedDiscardTarget(tagOwner, argList, playPtn, situation) ? 1f : 0f); case AIScriptTokenFuncType.DISCARD_COUNT: if (!(argList[0] is AIScriptArgumentToken aIScriptArgumentToken2)) { return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(AIDiscardUtility.GetDiscardCount(aIScriptArgumentToken2.ArgumentType, tagOwner, playPtn, situation)); case AIScriptTokenFuncType.BOUNCE_COUNT: if (argList[0] is AIScriptArgumentToken { ArgumentType: var argumentType }) { return new AIScriptNumericToken(AIBounceSimulationUtility.GetBounceCount(field, situation, argumentType)); } return new AIScriptNumericToken(0f); case AIScriptTokenFuncType.EMOTE_PLAY_COUNT: { int category = (int)argList[0].Value; return new AIScriptNumericToken(field.AI.EmoteMng.GetEmotePlayCount(category)); } case AIScriptTokenFuncType.DRAW_COUNT: return GetDrawCountResultToken(argList, tagOwner, field, playPtn); case AIScriptTokenFuncType.MEMBER_MAX_ATK: argList.Reverse(); return new AIScriptNumericToken(field.GetMemberMaxAttack(tagOwner, argList, playPtn, situation)); case AIScriptTokenFuncType.IS_BURIAL_RITE: argList.Reverse(); return new AIScriptNumericToken(AIBurialUtility.IsBurialRite(situation, argList, field) ? 1f : 0f); case AIScriptTokenFuncType.BURIAL_COUNT: if (!(argList[0] is AIScriptArgumentToken aIScriptArgumentToken13)) { return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(AIBurialRiteSimulationUtility.GetBurialCount(aIScriptArgumentToken13.ArgumentType, field)); case AIScriptTokenFuncType.RESONANCE_START_COUNT: if (!(argList[0] is AIScriptArgumentToken aIScriptArgumentToken11) || !(argList[1] is AIScriptArgumentToken aIScriptArgumentToken12)) { return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(GetResonanceStartCount(tagOwner, field, aIScriptArgumentToken12.ArgumentType, aIScriptArgumentToken11.ArgumentType)); case AIScriptTokenFuncType.SUMMON_COUNT: { if (!AISummonCountUtility.ClassificateSummonCountArgument(argList, out var filters3, out var turnOrGame2, out var playedType)) { return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(AISummonCountUtility.GetSummonCount(tagOwner, filters3, turnOrGame2, playedType, playPtn, situation)); } case AIScriptTokenFuncType.BUFF_COUNT: return new AIScriptNumericToken(AIBuffCountUtility.GetBuffCount(tagOwner, field, situation, playPtn, argList)); case AIScriptTokenFuncType.IS_HOLDING_BATTLE_SKILL: if (!(argList[0] is AIScriptTextToken aIScriptTextToken2)) { return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(tagOwner.IsHoldingBattleSkill(aIScriptTextToken2.Text) ? 1 : 0); case AIScriptTokenFuncType.IS_LEADER_HOLDING_BATTLE_SKILL: if (!(argList[0] is AIScriptTextToken aIScriptTextToken)) { return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(field.AllyClass.IsHoldingBattleSkill(aIScriptTextToken.Text) ? 1 : 0); case AIScriptTokenFuncType.STACK_COUNT: { if (argList.Count <= 0 || !(argList[0] is AIScriptArgumentToken aIScriptArgumentToken7)) { return new AIScriptNumericToken(0f); } if (aIScriptArgumentToken7.ArgumentType != AIScriptTokenArgType.ALLY && aIScriptArgumentToken7.ArgumentType != AIScriptTokenArgType.OPPONENT) { return new AIScriptNumericToken(0f); } bool isAlly = tagOwner.IsAlly ^ (aIScriptArgumentToken7.ArgumentType == AIScriptTokenArgType.OPPONENT); return new AIScriptNumericToken(AIStackCountUtility.GetStackCount(field, isAlly)); } case AIScriptTokenFuncType.OWN_DESTROY_COUNT: { List ownDestroyedCards = situation.GetOwnDestroyedCards(); if (ownDestroyedCards == null) { return new AIScriptNumericToken(0f); } argList.Reverse(); return new AIScriptNumericToken(AIFilteringUtility.MultipleFiltering(ownDestroyedCards, argList, tagOwner, playPtn, situation, isBlockDeadCard: false)?.Count ?? 0); } case AIScriptTokenFuncType.IS_SELECTABLE: { float value4 = argList[0].Value; argList.RemoveAt(0); argList.Reverse(); return new AIScriptNumericToken(AIIsSelectableUtility.IsSelectable(argList, value4, tagOwner, field, playPtn, situation) ? 1 : 0); } case AIScriptTokenFuncType.IS_ENEMY_AI_ID: return new AIScriptNumericToken((argList[0].Value == (float)EnemyAI.EnemyAIID) ? 1f : 0f); case AIScriptTokenFuncType.ADD_HAND_COUNT: { AIScriptTokenBase aIScriptTokenBase3 = argList[0]; AIScriptTokenArgType aIScriptTokenArgType = (AIScriptTokenArgType)aIScriptTokenBase3.Value; if (aIScriptTokenArgType != AIScriptTokenArgType.TURN && aIScriptTokenArgType != AIScriptTokenArgType.GAME) { AIConsoleUtility.LogError("ADD_HAND_COUNT Arg Error : Last arg is only valid TURN or GAME"); return new AIScriptNumericToken(0f); } argList.Remove(aIScriptTokenBase3); argList.Reverse(); List list13 = new List(); switch (aIScriptTokenArgType) { case AIScriptTokenArgType.TURN: { List list15 = (tagOwner.IsAlly ? field.AllyTurnHandAddedCards : field.EnemyTurnHandAddedCards); if (list15 != null && list15.Count > 0) { list13.AddRange(list15); } break; } case AIScriptTokenArgType.GAME: { List list14 = (tagOwner.IsAlly ? field.AllyGameHandAddedCards : field.EnemyGameHandAddedCards); if (list14 != null && list14.Count > 0) { list13.AddRange(list14); } break; } } return new AIScriptNumericToken(AIFilteringUtility.MultipleFiltering(list13, argList, tagOwner, playPtn, situation)?.Count ?? 0); } case AIScriptTokenFuncType.BASE_COST: { argList.Reverse(); List list10 = AIFilteringUtility.MultipleFiltering(field.CardListSet.AllReferableCards, argList, tagOwner, playPtn, situation, isBlockDeadCard: false); if (list10 == null || list10.Count <= 0) { return new AIScriptNumericToken(0f); } if (list10.Count > 1) { AIConsoleUtility.LogError("BASE_COST Func : Error!!! Multiple cards have been selected"); } return new AIScriptNumericToken(list10[0].BaseCost); } case AIScriptTokenFuncType.RECEIVED_DAMAGE_SUM: { argList.Reverse(); List list8 = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, argList, tagOwner, playPtn, situation); if (list8 == null || list8.Count <= 0) { return new AIScriptNumericToken(0f); } float num14 = 0f; for (int num15 = 0; num15 < field.DamagedCardsByLastAction.Count; num15++) { Tuple tuple = field.DamagedCardsByLastAction[num15]; for (int num16 = 0; num16 < list8.Count; num16++) { AIVirtualCard card = list8[num16]; if (tuple.first.IsSameCard(card)) { num14 += (float)tuple.second; } } } return new AIScriptNumericToken(num14); } case AIScriptTokenFuncType.IS_PLAYER_CHARA_ID: if (argList == null || argList.Count <= 0) { AIConsoleUtility.LogError("IS_PLAYER_CHARA_ID error!! argList is invalid"); return new AIScriptNumericToken(0f); } if (argList[0] is AIScriptNumericToken aIScriptNumericToken) { int num8 = (int)aIScriptNumericToken.Value; return new AIScriptNumericToken((field.AI.PlayerCharaId == num8) ? 1f : 0f); } return new AIScriptNumericToken(0f); case AIScriptTokenFuncType.FUSION_COUNT_IN_GAME: argList.Reverse(); return new AIScriptNumericToken(AIFusionCountUtility.GetFusedCardCountInGame(tagOwner, argList, playPtn, situation, isWithoutSameId: false)); case AIScriptTokenFuncType.FUSION_NAME_COUNT_IN_GAME: argList.Reverse(); return new AIScriptNumericToken(AIFusionCountUtility.GetFusedCardCountInGame(tagOwner, argList, playPtn, situation, isWithoutSameId: true)); case AIScriptTokenFuncType.IS_PLAYER_ABILITY_ID: if (argList != null && argList.Count > 0 && argList[0] is AIScriptIDToken { ID: var iD2 }) { return new AIScriptNumericToken(field.AI.HasPlayerAbilityId(iD2) ? 1f : 0f); } return new AIScriptNumericToken(0f); case AIScriptTokenFuncType.BANISH_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIBanishSimulationUtility.GetInplayBanishedCount(tagOwner, field, playPtn, situation, argList)); case AIScriptTokenFuncType.HAND_BANISH_COUNT: argList.Reverse(); return new AIScriptNumericToken(AIBanishSimulationUtility.GetHandBanishedCount(tagOwner, field, playPtn, situation, argList)); case AIScriptTokenFuncType.IS_BOTH_CLASS: { if (argList == null || argList.Count <= 1) { AIConsoleUtility.LogError("IS_BOTH_CLASS error!! arg count is not enough"); return new AIScriptNumericToken(0f); } argList.Reverse(); CardBasePrm.ClanType clanType = CardBasePrm.ClanType.NONE; CardBasePrm.ClanType clanType2 = CardBasePrm.ClanType.NONE; if (argList[0] is AIScriptArgumentToken aIScriptArgumentToken3 && aIScriptArgumentToken3.IsSideArgType(includeBoth: false)) { bool num = tagOwner.IsAlly == (aIScriptArgumentToken3.ArgumentType == AIScriptTokenArgType.ALLY); clanType = (num ? field.AllyClass.Clan : field.EnemyClass.Clan); clanType2 = (num ? field.AI.AISubClassType : field.AI.PlayerSubClassType); for (int i = 1; i < argList.Count; i++) { if (argList[i] is AIScriptArgumentToken aIScriptArgumentToken4) { CardBasePrm.ClanType clanType3 = AIPlayTagInitializingUtility.ConvertTokenArgTypeToClanType(aIScriptArgumentToken4.ArgumentType); if (clanType3 != CardBasePrm.ClanType.NONE && (clanType == clanType3 || clanType2 == clanType3)) { return new AIScriptNumericToken(1f); } } } return new AIScriptNumericToken(0f); } AIConsoleUtility.LogError("IS_BOTH_CLASS error!! side parameter is invalid"); return new AIScriptNumericToken(0f); } case AIScriptTokenFuncType.EVAL_ATTACK_REMOVE: return new AIScriptNumericToken(AIEvalAttackRemoveUtility.EvalAttackRemove(tagOwner, field, playPtn, situation, argList)); case AIScriptTokenFuncType.ADDED_DECK_COUNT_IN_GAME: argList.Reverse(); return new AIScriptNumericToken(AIFilteringUtility.MultipleFiltering(tagOwner.IsAlly ? field.AllyGameAddUpdateDeckCards : field.EnemyGameAddUpdateDeckCards, argList, tagOwner, playPtn, situation)?.Count ?? 0); default: return new AIScriptNumericToken(0f); } } private static int GetResonanceStartCount(AIVirtualCard tagOwner, AIVirtualField field, AIScriptTokenArgType side, AIScriptTokenArgType gameOrTurn) { if (side != AIScriptTokenArgType.ALLY) { _ = 85; } if (gameOrTurn != AIScriptTokenArgType.GAME) { _ = 142; } if ((side == AIScriptTokenArgType.ALLY && tagOwner.IsAlly) || (side == AIScriptTokenArgType.OPPONENT && !tagOwner.IsAlly)) { if (gameOrTurn == AIScriptTokenArgType.GAME) { return field.AllyGameResonanceStartCount; } return field.AllyTurnResonanceStartCount; } if (gameOrTurn == AIScriptTokenArgType.GAME) { return field.EnemyGameResonanceStartCount; } return field.EnemyTurnResonanceStartCount; } private static AIScriptNumericToken GetDrawCountResultToken(List argList, AIVirtualCard owner, AIVirtualField field, List playPtn) { if (argList.Count <= 0 || argList.Count > 2) { AIConsoleUtility.LogError("DRAW_COUNT error!! argList.Count == " + argList.Count); return new AIScriptNumericToken(0f); } AIScriptTokenArgType aIScriptTokenArgType = AIScriptTokenArgType.NONE; AIScriptTokenArgType range = AIScriptTokenArgType.NONE; if (argList[argList.Count - 1] is AIScriptArgumentToken aIScriptArgumentToken) { aIScriptTokenArgType = aIScriptArgumentToken.ArgumentType; } if (argList.Count > 1 && argList[argList.Count - 2] is AIScriptArgumentToken aIScriptArgumentToken2) { range = aIScriptArgumentToken2.ArgumentType; } if (aIScriptTokenArgType != AIScriptTokenArgType.TURN && aIScriptTokenArgType != AIScriptTokenArgType.GAME) { AIConsoleUtility.LogError("DRAW_COUNT error!!! period == " + aIScriptTokenArgType); return new AIScriptNumericToken(0f); } return new AIScriptNumericToken(AIDrawCountUtility.GetDrawCount(owner, field, playPtn, aIScriptTokenArgType, range)); } }