feat(battle-engine): close the AI-simulation subsystem (verbatim)

Copied the 89 uncopied AI*SimulationUtility/extension files defining the
AIVirtualCard/AIVirtualField extension methods; the compile loop then auto-closed
the revealed type deps (~3049 files total, drift-clean). 10.0k -> 62 errors.
This commit is contained in:
gamer147
2026-06-05 20:30:59 -04:00
parent 78f310c2b3
commit 824309ec44
472 changed files with 55870 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIAccelerateUtility
{
public static bool IsAccelerate(AIVirtualCard card, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (card == null || card.AccelerateCostList == null || !card.IsInHand)
{
return false;
}
if (situation is AIVirtualActionInfo { ReservedPlayType: not PlaySimulationType.Undefined } aIVirtualActionInfo)
{
return aIVirtualActionInfo.ReservedPlayType == PlaySimulationType.Accelerate;
}
List<int> playPtn2 = (card.IsAlly ? playPtn : null);
AIVariableResultContainer valResultContainer = field.AI.ValResultContainer;
ulong hash = AIFunctionResultHashCalculator.GetHash(card, field, playPtn, null, 0uL);
if (valResultContainer.GetContainsResultValue(AIScriptTokenVariableType.IS_ACCELERATE, hash, out var getResult))
{
return getResult == 1f;
}
bool flag = field.AI.PlayPtnRecorder.IsCardPlayingSimulationType(card, field, playPtn2, situation, PlaySimulationType.Accelerate);
valResultContainer.CheckDuplicateAndAddRecord(AIScriptTokenVariableType.IS_ACCELERATE, hash, flag ? 1f : 0f, $"IsAccelerate(): Already hashed target and not equal value. CardName:[{card.CardName}] hash:[{hash}]");
return flag;
}
public static int GetAccelerateCost(AIVirtualCard card, AIVirtualField field, List<int> playPtn)
{
if (card == null || card.AccelerateCostList == null)
{
return -1;
}
List<int> playPtn2 = (card.IsAlly ? playPtn : null);
return field.AI.PlayPtnRecorder.GetCardPlaySimulationTypeCost(card, field, playPtn2, null, PlaySimulationType.Accelerate);
}
public static int GetConditionPassedAccelerateId(AIVirtualCard card, AIVirtualField field, List<int> playPtn, AISituationInfo situation, int usedCost)
{
if (card.AccelerateCostList == null || card.AccelerateCostList.Count <= 0)
{
return -1;
}
for (int i = 0; i < card.AccelerateCostList.Count; i++)
{
AIAccelerateInformation aIAccelerateInformation = card.AccelerateCostList[i];
if (aIAccelerateInformation.Cost == usedCost && aIAccelerateInformation.CheckCondition(card, field, playPtn, situation))
{
return aIAccelerateInformation.CardId;
}
}
return -1;
}
}

View File

@@ -0,0 +1,176 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIAttachTagSimulationUtility
{
public static void SimulateAttachTagToAll(List<AIVirtualCard> targets, AIVirtualCard owner, AIPlayTag tag, AIScriptTokenArgType removeTiming, AISituationInfo situation)
{
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (!aIVirtualCard.IsDead && !aIVirtualCard.IsIndependent)
{
SimulateAttachTagToSingle(aIVirtualCard, owner, tag, removeTiming, situation);
}
}
}
public static void SimulateAttachTagToTarget(AISituationInfo situation, AIVirtualCard owner, AIScriptTokenArgType whichTarget, AIPlayTag tag, AIScriptTokenArgType removeTiming)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
return;
}
List<AIVirtualCard> targets = situationTarget.Targets;
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (!aIVirtualCard.IsDead && !aIVirtualCard.IsIndependent)
{
SimulateAttachTagToSingle(aIVirtualCard, owner, tag, removeTiming, situation);
}
}
}
public static void SimulateAttachTagToSingle(AIVirtualCard target, AIVirtualCard owner, AIPlayTag tag, AIScriptTokenArgType removeTiming, AISituationInfo situation)
{
AIAttachedTagInformation info = new AIAttachedTagInformation(tag, removeTiming, owner, target);
target.TagCollectionContainer.AttachTag(info, target, situation);
RegisterAttachedTagStopPreprocess(owner, owner.SelfField, tag, removeTiming, target);
}
public static void SimulateRandomSelectAttachTag(List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AIPlayTag tag, AIScriptTokenArgType removeTiming, AISelectLogicArgumentBase selectLogic)
{
AIVirtualCardRealTargetInformation aIVirtualCardRealTargetInformation = situation.DequeueRealTargetInfo(tagOwner, field);
if (aIVirtualCardRealTargetInformation == null)
{
SimulateRandomSelectAttachTagToVirtualTarget(candidates, selectCount, tagOwner, field, playPtn, situation, tag, removeTiming, selectLogic);
}
else
{
SimulateRandomSelectAttachTagToRealTarget(aIVirtualCardRealTargetInformation, candidates, selectCount, tagOwner, situation, tag, removeTiming);
}
}
private static void SimulateRandomSelectAttachTagToVirtualTarget(List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AIPlayTag tag, AIScriptTokenArgType removeTiming, AISelectLogicArgumentBase selectLogic)
{
if (candidates == null || candidates.Count <= 0)
{
return;
}
if (selectCount >= candidates.Count)
{
SimulateAttachTagToAll(candidates, tagOwner, tag, removeTiming, situation);
return;
}
if (selectCount == 1)
{
SimulateAttachTagToSingle(selectLogic.SelectSingleTarget(candidates, tagOwner, field, playPtn, situation, AISelectTargetPattern.Worst), tagOwner, tag, removeTiming, situation);
return;
}
List<AIVirtualCard> list = selectLogic.SelectMultipleSelectedTargets(candidates, selectCount, tagOwner, field, playPtn, situation, AISelectTargetPattern.Worst);
if (list != null && list.Count > 0)
{
SimulateAttachTagToAll(list, tagOwner, tag, removeTiming, situation);
}
}
private static void SimulateRandomSelectAttachTagToRealTarget(AIVirtualCardRealTargetInformation realTargetInfo, List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AISituationInfo situation, AIPlayTag tag, AIScriptTokenArgType removeTiming)
{
List<AIVirtualCard> targetList = realTargetInfo.TargetList;
List<AIVirtualCard> list = new List<AIVirtualCard>();
int num = selectCount;
for (int i = 0; i < targetList.Count; i++)
{
AIVirtualCard item = targetList[i];
if (candidates.Contains(item))
{
list.Add(item);
num--;
if (num <= 0)
{
break;
}
}
}
SimulateAttachTagToAll(list, tagOwner, tag, removeTiming, situation);
}
private static void RegisterAttachedTagStopPreprocess(AIVirtualCard tagOwner, AIVirtualField field, AIPlayTag attachedTag, AIScriptTokenArgType removeTiming, AIVirtualCard targetCard)
{
AIAttachedTagStopPreprocessOption option = new AIAttachedTagStopPreprocessOption(targetCard)
{
TargetTag = attachedTag
};
switch (GetAttachedTagRemoveTimingForPreprocess(removeTiming, tagOwner))
{
case AIAttachedTagRemoveTiming.AllyTurnEnd:
field.TagPreprocessContainer.AppendAllyTurnEndStopInfo(option);
break;
case AIAttachedTagRemoveTiming.OpponentTurnEnd:
field.TagPreprocessContainer.AppendOpponentTurnEndStopInfo(option);
break;
case AIAttachedTagRemoveTiming.NextTurnEnd:
{
int defaultDecrementValue = (tagOwner.IsSelfTurn ? 1 : 0);
if (tagOwner.IsAlly)
{
field.TagPreprocessContainer.AppendAllyTurnEndStopInfo(option, defaultDecrementValue);
}
else
{
field.TagPreprocessContainer.AppendOpponentTurnEndStopInfo(option, defaultDecrementValue);
}
break;
}
case AIAttachedTagRemoveTiming.AllyTurnStart:
field.TagPreprocessContainer.AppendAllyTurnStartStopInfo(option);
break;
case AIAttachedTagRemoveTiming.OpponentTurnStart:
field.TagPreprocessContainer.AppendOpponentTurnStartStopInfo(option);
break;
case AIAttachedTagRemoveTiming.Leave:
field.TagPreprocessContainer.AppendLeaveStopInfo(option, tagOwner);
break;
}
}
private static AIAttachedTagRemoveTiming GetAttachedTagRemoveTimingForPreprocess(AIScriptTokenArgType srcRemoveTiming, AIVirtualCard tagOwner)
{
switch (srcRemoveTiming)
{
case AIScriptTokenArgType.WHEN_ALLY_TURNEND:
if (!tagOwner.IsAlly)
{
return AIAttachedTagRemoveTiming.OpponentTurnEnd;
}
return AIAttachedTagRemoveTiming.AllyTurnEnd;
case AIScriptTokenArgType.WHEN_OPPONENT_TURNEND:
if (!tagOwner.IsAlly)
{
return AIAttachedTagRemoveTiming.AllyTurnEnd;
}
return AIAttachedTagRemoveTiming.OpponentTurnEnd;
case AIScriptTokenArgType.WHEN_ALLY_TURNSTART:
if (!tagOwner.IsAlly)
{
return AIAttachedTagRemoveTiming.OpponentTurnStart;
}
return AIAttachedTagRemoveTiming.AllyTurnStart;
case AIScriptTokenArgType.WHEN_OPPONENT_TURNSTART:
if (!tagOwner.IsAlly)
{
return AIAttachedTagRemoveTiming.AllyTurnStart;
}
return AIAttachedTagRemoveTiming.OpponentTurnStart;
case AIScriptTokenArgType.WHEN_NEXT_TURNEND:
return AIAttachedTagRemoveTiming.NextTurnEnd;
case AIScriptTokenArgType.WHEN_LEAVE:
return AIAttachedTagRemoveTiming.Leave;
default:
return AIAttachedTagRemoveTiming.None;
}
}
}

View File

@@ -0,0 +1,12 @@
namespace Wizard;
public enum AIAttachedTagRemoveTiming
{
AllyTurnEnd,
OpponentTurnEnd,
NextTurnEnd,
AllyTurnStart,
OpponentTurnStart,
Leave,
None
}

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
using UnityEngine;
namespace Wizard;
public class AIAttackableCountSimulationUtility : MonoBehaviour
{
public static void ExecuteChangeAttackableCountAll(List<AIVirtualCard> candidates, int attackableCount)
{
if (candidates == null || candidates.Count <= 0)
{
return;
}
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
if (!aIVirtualCard.IsIndependent && !aIVirtualCard.IsDead)
{
aIVirtualCard.GiveAttackableCount(attackableCount);
}
}
}
public static void ExecuteChangeAttackableCountTargetSelect(int attackableCount, AIScriptTokenArgType whichTarget, AISituationInfo situation)
{
if (situation != null)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget != null && situationTarget.HasTarget)
{
ExecuteChangeAttackableCountAll(situationTarget.Targets, attackableCount);
}
}
}
}

View File

@@ -0,0 +1,120 @@
using System.Collections.Generic;
using Wizard.Battle.UI;
namespace Wizard;
public static class AIBanAttackSimulationUtility
{
public static void BanAttackAll(List<AIVirtualCard> candidates, CantAttackType banAttackType)
{
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
if (!aIVirtualCard.IsIndependent)
{
BanAttackSingle(aIVirtualCard, banAttackType);
}
}
}
public static void BanAttackRandom(List<AIVirtualCard> candidates, CantAttackType banAttackType, int selectCount)
{
if (selectCount <= 1)
{
AIVirtualCard aIVirtualCard = SelectTargetForBanAttack(candidates, AISelectTargetPattern.Worst);
if (aIVirtualCard != null && !aIVirtualCard.IsIndependent)
{
BanAttackSingle(aIVirtualCard, banAttackType);
}
}
else
{
BanAttackAll(SelectMultipleTargetsForBanAttack(candidates, selectCount, AISelectTargetPattern.Worst), banAttackType);
}
}
public static void BanAttackTarget(AISituationInfo situation, CantAttackType banAttackType, AIScriptTokenArgType whichTarget)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget != null && situationTarget.HasTarget)
{
BanAttackAll(situationTarget.Targets, banAttackType);
}
}
public static void BanAttackTargetPrediction(List<AIVirtualCard> candidates, CantAttackType banAttackType, int selectCount)
{
if (selectCount <= 1)
{
AIVirtualCard aIVirtualCard = SelectTargetForBanAttack(candidates, AISelectTargetPattern.Best);
if (aIVirtualCard != null && !aIVirtualCard.IsIndependent)
{
BanAttackSingle(aIVirtualCard, banAttackType);
}
}
else
{
BanAttackAll(SelectMultipleTargetsForBanAttack(candidates, selectCount, AISelectTargetPattern.Best), banAttackType);
}
}
private static void BanAttackSingle(AIVirtualCard target, CantAttackType banAttackType)
{
switch (banAttackType)
{
case CantAttackType.All:
target.IsCantAttackAll = true;
break;
case CantAttackType.Unit:
target.IsSkillCantAttackUnit = true;
break;
case CantAttackType.Class:
target.IsSkillCantAttackClass = true;
break;
case CantAttackType.NotHasGuard:
target.IsSkillCantAtkUnitNotHasGuard = true;
break;
}
}
private static AIVirtualCard SelectTargetForBanAttack(List<AIVirtualCard> candidates, AISelectTargetPattern worstOrBest)
{
int num = ((worstOrBest == AISelectTargetPattern.Worst) ? int.MaxValue : int.MinValue);
AIVirtualCard result = null;
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
if ((worstOrBest != AISelectTargetPattern.Worst) ? (aIVirtualCard.Attack > num) : (aIVirtualCard.Attack < num))
{
result = aIVirtualCard;
num = aIVirtualCard.Attack;
}
}
return result;
}
private static List<AIVirtualCard> SelectMultipleTargetsForBanAttack(List<AIVirtualCard> candidates, int selectCount, AISelectTargetPattern worstOrBest)
{
List<AIVirtualCard> list = new List<AIVirtualCard>();
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
bool flag = false;
for (int j = 0; j < list.Count; j++)
{
AIVirtualCard aIVirtualCard2 = list[j];
if ((worstOrBest != AISelectTargetPattern.Worst) ? (aIVirtualCard.Attack > aIVirtualCard2.Attack) : (aIVirtualCard.Attack < aIVirtualCard2.Attack))
{
list[j] = aIVirtualCard;
aIVirtualCard = aIVirtualCard2;
flag = true;
}
}
if (!flag && list.Count < selectCount)
{
list.Add(aIVirtualCard);
}
}
return list;
}
}

View File

@@ -0,0 +1,23 @@
using System.Collections.Generic;
namespace Wizard;
public class AIBanishSelectLogicArgument : AISelectLogicArgumentBase
{
public override AIScriptTokenArgType LogicType => AIScriptTokenArgType.BANISH_LOGIC;
public AIBanishSelectLogicArgument(List<string> args)
: base(args)
{
}
public override AIVirtualCard SelectSingleTarget(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
return AISimulationRemovalUtility.SelectRemovalTarget(candidates, tagOwner, field, playPtn, situation, worstOrBest, AIRemovalType.Banish);
}
public override List<AIVirtualCard> SelectMultipleSelectedTargets(List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
return AISimulationRemovalUtility.SelectMultipleRemovalTargets(candidates, tagOwner, field, playPtn, situation, worstOrBest, AIRemovalType.Banish, selectCount);
}
}

View File

@@ -0,0 +1,238 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public static class AIBanishSimulationUtility
{
public static float EvalTargetingBanish(List<AIScriptTokenBase> argList, List<int> playPtn, AIVirtualField field, AIVirtualCard tagOwner, AISituationInfo situation)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothInplayCards, argList, tagOwner, playPtn, null);
if (list == null || list.Count <= 0)
{
return 0f;
}
list = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(list, tagOwner, playPtn);
int num = 0;
float num2 = float.MinValue;
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (!aIVirtualCard.IsIndependent && !aIVirtualCard.IsUnbanishable && (aIVirtualCard.IsAlly == tagOwner.IsAlly || (!aIVirtualCard.IsUntouchable && !aIVirtualCard.IsSneak)))
{
num++;
float num3 = aIVirtualCard.EvaluateValueOnField(playPtn, situation, useStyle: true);
float num4 = (aIVirtualCard.IsAlly ? (0f - num3 - aIVirtualCard.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) + aIVirtualCard.GetAllBanishBonus(playPtn, useIgnoreInBattle: false) + aIVirtualCard.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false)) : (num3 + aIVirtualCard.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) - aIVirtualCard.GetAllBanishBonus(playPtn, useIgnoreInBattle: false) - aIVirtualCard.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false)));
if (num4 > num2)
{
num2 = num4;
}
}
}
if (num == 0)
{
num2 = 0f;
}
return num2;
}
public static float EvalRandomBanish(List<AIScriptTokenBase> argList, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, int count, AISituationInfo situation)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothInplayCards, argList, tagOwner, playPtn, null);
if (list != null && list.Count > 0)
{
List<float> list2 = new List<float>();
float num = 0f;
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (!aIVirtualCard.IsUnbanishable && !aIVirtualCard.IsIndependent)
{
float num2 = aIVirtualCard.EvaluateValueOnField(playPtn, situation, useStyle: true, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true);
float num3 = aIVirtualCard.EvaluateBreakValue(playPtn, useIgnoreBreak: true);
float allBanishBonus = aIVirtualCard.GetAllBanishBonus(playPtn, useIgnoreInBattle: true);
float num4 = aIVirtualCard.EvaluateLeaveValue(playPtn, useIgnoreInBattle: true);
float num5 = (aIVirtualCard.IsAlly ? (-1f) : 1f) * (num2 + num3 - allBanishBonus - num4);
list2.Add(num5);
num += num5;
}
}
if (list.Count <= count)
{
return num;
}
List<float[]> list3 = AIMathematicsLibrary.EnumerateCombinations(list2, count).ToList();
float num6 = 0f;
for (int j = 0; j < list3.Count; j++)
{
for (int k = 0; k < list3[j].Length; k++)
{
num6 += list3[j][k];
}
}
return num6 / (float)list3.Count;
}
return 0f;
}
public static float EvalAllBanish(List<AIScriptTokenBase> argList, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothInplayCards, argList, tagOwner, playPtn, null);
if (list == null || list.Count <= 0)
{
return 0f;
}
float num = 0f;
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (!aIVirtualCard.IsIndependent && !aIVirtualCard.IsUnbanishable)
{
float num2 = aIVirtualCard.EvaluateValueOnField(playPtn, situation, useStyle: true, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true);
float num3 = aIVirtualCard.EvaluateBreakValue(playPtn, useIgnoreBreak: true);
float allBanishBonus = aIVirtualCard.GetAllBanishBonus(playPtn, useIgnoreInBattle: true);
float num4 = aIVirtualCard.EvaluateLeaveValue(playPtn, useIgnoreInBattle: true);
num += (aIVirtualCard.IsAlly ? (-1f) : 1f) * (num2 + num3 - allBanishBonus - num4);
}
}
return num;
}
public static void BanishAll(List<AIVirtualCard> targetCards, AISituationInfo situation)
{
for (int i = 0; i < targetCards.Count; i++)
{
BanishSingle(targetCards[i], situation);
}
}
public static void ExecuteTargetSelectBanish(AIVirtualCard owner, List<AIVirtualCard> targets, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AIScriptTokenArgType selectType, int selectCount = 1)
{
if (situation == null)
{
AIConsoleUtility.LogError("ExecuteTargetSelectBanish() Error!! situation is null!!!!!");
}
else if (situation.IsTargetExists(selectType))
{
BanishTarget(situation, targets, selectType);
}
else
{
BanishTargetPrediction(situation, targets, owner, field, playPtn, selectType, selectCount);
}
}
private static void BanishTargetPrediction(AISituationInfo situation, List<AIVirtualCard> candidates, AIVirtualCard banishOwner, AIVirtualField field, List<int> playPtn, AIScriptTokenArgType selectType, int selectCount)
{
List<AIVirtualCard> candidates2 = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(candidates, banishOwner, playPtn);
if (selectCount <= 1)
{
AIVirtualCard target = AISimulationRemovalUtility.SelectRemovalTarget(candidates2, banishOwner, field, playPtn, situation, AISelectTargetPattern.Best, AIRemovalType.Banish);
situation.SetSingleTargetInInfo(target, TargetSelectType.Default, selectType);
BanishTarget(situation, candidates, selectType);
}
else
{
BanishAll(AISimulationRemovalUtility.SelectMultipleRemovalTargets(candidates2, banishOwner, field, playPtn, situation, AISelectTargetPattern.Best, AIRemovalType.Banish, selectCount), situation);
}
}
public static void BanishTarget(AISituationInfo situation, List<AIVirtualCard> candidates, AIScriptTokenArgType whichTarget)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
AIConsoleUtility.LogError("BanishTarget error!! No target!!!!!");
return;
}
List<AIVirtualCard> targets = situationTarget.Targets;
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (candidates.Contains(aIVirtualCard))
{
BanishSingle(aIVirtualCard, situation);
}
}
}
public static void BanishSingle(AIVirtualCard target, AISituationInfo situation)
{
if (!target.IsDead && !target.IsIndependent && !target.IsUnbanishable)
{
target.RemoveCard(situation, AIRemovalType.Banish, isFromSkill: true);
}
}
public static void BanishRandom(List<AIVirtualCard> targets, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, int selectCount = 1)
{
if (selectCount <= 1)
{
AIVirtualCard aIVirtualCard = AISimulationRemovalUtility.SelectRemovalTarget(targets, tagOwner, field, playPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Banish);
if (aIVirtualCard != null)
{
BanishSingle(aIVirtualCard, situation);
}
}
else
{
BanishAll(AISimulationRemovalUtility.SelectMultipleRemovalTargets(targets, tagOwner, field, playPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Banish, selectCount), situation);
}
}
public static int GetInplayBanishedCount(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> argList)
{
return GetFilterdBanishCardList(tagOwner, field, playPtn, situation, argList, BattleCardBase.BanishInfo.BanishPlace.Field)?.Count ?? 0;
}
public static int GetHandBanishedCount(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> argList)
{
return GetFilterdBanishCardList(tagOwner, field, playPtn, situation, argList, BattleCardBase.BanishInfo.BanishPlace.Hand)?.Count ?? 0;
}
private static List<AIVirtualCard> GetFilterdBanishCardList(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> argList, BattleCardBase.BanishInfo.BanishPlace place)
{
List<AIVirtualCard> banishedCards = field.CardListSet.BanishedCards;
if (banishedCards == null || banishedCards.Count <= 0)
{
return null;
}
SeparateArgListToFilterAndTimingArg(argList, out var filters, out var turnOrGame);
if (filters == null || filters.Count <= 0 || (turnOrGame != AIScriptTokenArgType.TURN && turnOrGame != AIScriptTokenArgType.GAME))
{
return null;
}
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(banishedCards, filters, tagOwner, playPtn, situation, isBlockDeadCard: false);
if (list == null || list.Count <= 0)
{
return null;
}
if (turnOrGame == AIScriptTokenArgType.TURN)
{
list.RemoveAll((AIVirtualCard c) => !c.IsBanishedTargetTurn(field.CurrentTurnCount));
}
list.RemoveAll((AIVirtualCard c) => c.BanishedInfo.Place != place);
return list;
}
private static void SeparateArgListToFilterAndTimingArg(List<AIScriptTokenBase> argList, out List<AIScriptTokenBase> filters, out AIScriptTokenArgType turnOrGame)
{
if (argList == null || argList.Count <= 0)
{
AIConsoleUtility.LogError("AIBanishSimulationUtility.SeparateArgListToFilterAndTimingArg() error!! argList is null!!");
filters = null;
turnOrGame = AIScriptTokenArgType.NONE;
return;
}
if (argList[argList.Count - 1] is AIScriptArgumentToken aIScriptArgumentToken)
{
turnOrGame = aIScriptArgumentToken.ArgumentType;
}
else
{
AIConsoleUtility.LogError("AIBanishSimulationUtility.SeparateArgListToFilterAndTimingArg() error!! lastToken is not ArgumentToken!!");
turnOrGame = AIScriptTokenArgType.NONE;
}
filters = argList.GetRange(0, argList.Count - 1);
}
}

View File

@@ -0,0 +1,6 @@
namespace Wizard;
public static class AIBarrierGlobal
{
public const int CLIPPING_RANGE_MAX = 9999;
}

View File

@@ -0,0 +1,180 @@
using System;
using System.Collections.Generic;
namespace Wizard;
public static class AIBasicTargetSelectUtility
{
public static AIVirtualCard SelectSingleBasicSkillTarget(List<AIVirtualCard> candidates, AIScriptTokenArgType skillType, AISelectTargetPattern worstOrBest)
{
if (candidates == null || candidates.Count <= 0)
{
return null;
}
Func<AIVirtualCard, AIVirtualCard, AISelectTargetPattern, AIVirtualCard> func = SelectCompareFunc(skillType);
if (func == null)
{
return candidates[0];
}
AIVirtualCard aIVirtualCard = null;
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard2 = candidates[i];
if (aIVirtualCard2.IsUnit && !aIVirtualCard2.IsDead)
{
aIVirtualCard = ((aIVirtualCard != null) ? func(aIVirtualCard, aIVirtualCard2, worstOrBest) : aIVirtualCard2);
}
}
return aIVirtualCard;
}
private static Func<AIVirtualCard, AIVirtualCard, AISelectTargetPattern, AIVirtualCard> SelectCompareFunc(AIScriptTokenArgType skillType)
{
switch (skillType)
{
case AIScriptTokenArgType.SNEAK:
return CompareSneakCandidates;
case AIScriptTokenArgType.QUICK:
case AIScriptTokenArgType.RUSH:
return CompareRushOrQuickCandidates;
case AIScriptTokenArgType.GUARD:
return CompareGuardCandidates;
case AIScriptTokenArgType.KILLER:
return CompareKillerCandidates;
case AIScriptTokenArgType.IGNORE_GUARD:
return CompareIgnoreGuardCandidates;
case AIScriptTokenArgType.DRAIN:
case AIScriptTokenArgType.UNTOUCHABLE:
case AIScriptTokenArgType.FORCE_TARGETING:
case AIScriptTokenArgType.UNBANISHABLE:
return null;
default:
return null;
}
}
private static AIVirtualCard CompareRushOrQuickCandidates(AIVirtualCard currentResultTarget, AIVirtualCard checkCard, AISelectTargetPattern worstOrBest)
{
int attack = currentResultTarget.Attack;
int attack2 = checkCard.Attack;
AIVirtualCard result = currentResultTarget;
switch (worstOrBest)
{
case AISelectTargetPattern.Best:
if (checkCard.IsSummonDrunkenness && !checkCard.IsCantAttackAll && attack2 > attack)
{
result = checkCard;
}
break;
case AISelectTargetPattern.Worst:
if (attack2 < attack)
{
result = checkCard;
}
break;
}
return result;
}
private static AIVirtualCard CompareGuardCandidates(AIVirtualCard currentResultTarget, AIVirtualCard checkCard, AISelectTargetPattern worstOrBest)
{
int life = currentResultTarget.Life;
int life2 = checkCard.Life;
AIVirtualCard result = currentResultTarget;
switch (worstOrBest)
{
case AISelectTargetPattern.Best:
if (life2 > life)
{
result = checkCard;
}
break;
case AISelectTargetPattern.Worst:
if (life2 < life)
{
result = checkCard;
}
break;
}
return result;
}
private static AIVirtualCard CompareSneakCandidates(AIVirtualCard currentResultTarget, AIVirtualCard checkCard, AISelectTargetPattern worstOrBest)
{
int attack = currentResultTarget.Attack;
int life = currentResultTarget.Life;
int attack2 = checkCard.Attack;
int life2 = checkCard.Life;
AIVirtualCard result = currentResultTarget;
switch (worstOrBest)
{
case AISelectTargetPattern.Best:
if (attack2 > attack)
{
result = checkCard;
}
else if (attack2 == attack && life2 > life)
{
result = checkCard;
}
break;
case AISelectTargetPattern.Worst:
if (attack2 < attack)
{
result = checkCard;
}
else if (attack2 == attack && life2 < life)
{
result = checkCard;
}
break;
}
return result;
}
private static AIVirtualCard CompareKillerCandidates(AIVirtualCard currentResultTarget, AIVirtualCard checkCard, AISelectTargetPattern worstOrBest)
{
int attack = currentResultTarget.Attack;
int attack2 = checkCard.Attack;
AIVirtualCard result = currentResultTarget;
switch (worstOrBest)
{
case AISelectTargetPattern.Best:
if (attack > attack2 || (attack == attack2 && currentResultTarget.Life < checkCard.Life))
{
result = checkCard;
}
break;
case AISelectTargetPattern.Worst:
if (attack < attack2 || (attack == attack2 && currentResultTarget.Life > checkCard.Life))
{
result = checkCard;
}
break;
}
return result;
}
private static AIVirtualCard CompareIgnoreGuardCandidates(AIVirtualCard currentResultTarget, AIVirtualCard checkCard, AISelectTargetPattern worstOrBest)
{
int attack = currentResultTarget.Attack;
int attack2 = checkCard.Attack;
AIVirtualCard result = currentResultTarget;
switch (worstOrBest)
{
case AISelectTargetPattern.Best:
if (attack2 > attack)
{
result = checkCard;
}
break;
case AISelectTargetPattern.Worst:
if (attack2 < attack)
{
result = checkCard;
}
break;
}
return result;
}
}

View File

@@ -0,0 +1,43 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIBerserkUtility
{
public static bool IsToBeBerserk(AIVirtualField field, List<int> playPtn, AISituationInfo situation, bool isAlly)
{
int num = 0;
if (isAlly && playPtn != null)
{
for (int i = 0; i < playPtn.Count; i++)
{
int index = playPtn[i];
BattleCardBase baseCard = field.AllyHandCards[index].BaseCard;
num += AIPlayOnSkillUtility.GetLifePenaltyOnPlay(baseCard, field.AI);
}
}
if (SkillConditionHalfLife.IsHalfLife((isAlly ? field.AllyClass : field.EnemyClass).Life - num) || IsForceBerserk(field, playPtn, situation, isAlly))
{
return true;
}
return false;
}
public static bool IsForceBerserk(AIVirtualField field, List<int> playPtn, AISituationInfo situation, bool isAlly)
{
List<AIVirtualCard> forceBerserkTagHolders = field.CardListSet.ForceBerserkTagHolders;
if (forceBerserkTagHolders == null || forceBerserkTagHolders.Count <= 0)
{
return false;
}
for (int i = 0; i < forceBerserkTagHolders.Count; i++)
{
AIVirtualCard aIVirtualCard = forceBerserkTagHolders[i];
if (aIVirtualCard.IsAlly == isAlly && aIVirtualCard.TagCollectionContainer.ForceBerserkTags.IsForceBerserk(aIVirtualCard, playPtn, situation))
{
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,23 @@
using System.Collections.Generic;
namespace Wizard;
public class AIBounceSelectLogicArgument : AISelectLogicArgumentBase
{
public override AIScriptTokenArgType LogicType => AIScriptTokenArgType.BOUNCE_LOGIC;
public AIBounceSelectLogicArgument(List<string> args)
: base(args)
{
}
public override AIVirtualCard SelectSingleTarget(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
return AISimulationRemovalUtility.SelectRemovalTarget(candidates, tagOwner, field, playPtn, situation, worstOrBest, AIRemovalType.Bounce);
}
public override List<AIVirtualCard> SelectMultipleSelectedTargets(List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
return AISimulationRemovalUtility.SelectMultipleRemovalTargets(candidates, tagOwner, field, playPtn, situation, worstOrBest, AIRemovalType.Bounce, selectCount);
}
}

View File

@@ -0,0 +1,134 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIBounceSimulationUtility
{
public static void BounceAll(List<AIVirtualCard> candidates, AISituationInfo situation)
{
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
if (!aIVirtualCard.IsIndependent)
{
aIVirtualCard.RemoveCard(situation, AIRemovalType.Bounce, isFromSkill: true);
BounceActivation(aIVirtualCard, situation);
}
}
}
public static void BounceRandom(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, int selectCount = 1)
{
if (selectCount <= 1)
{
AIVirtualCard aIVirtualCard = AISimulationRemovalUtility.SelectRemovalTarget(candidates, tagOwner, field, playPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Bounce);
if (aIVirtualCard != null && !aIVirtualCard.IsIndependent)
{
aIVirtualCard.RemoveCard(situation, AIRemovalType.Bounce, isFromSkill: true);
BounceActivation(aIVirtualCard, situation);
}
}
else
{
BounceAll(AISimulationRemovalUtility.SelectMultipleRemovalTargets(candidates, tagOwner, field, playPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Bounce, selectCount), situation);
}
}
public static void ExecuteTargetSelectBounce(AIVirtualCard owner, List<AIVirtualCard> targets, AISituationInfo situation, AIVirtualField field, List<int> playPtn, AIScriptTokenArgType selectType, AIRemovalType removalType, int selectCount = 1)
{
if (situation == null)
{
AIConsoleUtility.LogError("ExecuteTargetSelectDestroy() Error!! situation is null!!!!!");
return;
}
if (situation.IsTargetExists(selectType))
{
BounceTarget(situation, targets, selectType);
return;
}
situation.SelectedTargets.UpdateRemovalType(selectType, removalType);
BounceTargetPrediction(situation, targets, owner, field, playPtn, selectType, selectCount);
}
private static void BounceTargetPrediction(AISituationInfo situation, List<AIVirtualCard> candidates, AIVirtualCard bounceOwner, AIVirtualField field, List<int> playPtn, AIScriptTokenArgType selectType, int selectCount)
{
List<AIVirtualCard> candidates2 = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(candidates, bounceOwner, playPtn);
if (selectCount <= 1)
{
AIVirtualCard target = AISimulationRemovalUtility.SelectRemovalTarget(candidates2, bounceOwner, field, playPtn, situation, AISelectTargetPattern.Best, AIRemovalType.Bounce);
situation.SetSingleTargetInInfo(target, TargetSelectType.Default, selectType);
BounceTarget(situation, candidates, selectType);
}
else
{
List<AIVirtualCard> list = AISimulationRemovalUtility.SelectMultipleRemovalTargets(candidates2, bounceOwner, field, playPtn, situation, AISelectTargetPattern.Best, AIRemovalType.Bounce, selectCount);
situation.SetMultipleTargetsInInfo(list, TargetSelectType.Default, AIRemovalType.Bounce, selectType);
BounceAll(list, situation);
}
}
public static void BounceTarget(AISituationInfo situation, List<AIVirtualCard> candidates, AIScriptTokenArgType whichTarget)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
AIConsoleUtility.LogError("BounceTarget error!! No target!!!!!");
return;
}
List<AIVirtualCard> targets = situationTarget.Targets;
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (candidates.Contains(aIVirtualCard) && !aIVirtualCard.IsIndependent)
{
aIVirtualCard.RemoveCard(situation, AIRemovalType.Bounce, isFromSkill: true);
}
BounceActivation(aIVirtualCard, situation);
}
}
private static void BounceActivation(AIVirtualCard bouncedCard, AISituationInfo situation)
{
AIVirtualField selfField = situation.Actor.SelfField;
if (!selfField.CardListSet.HasBounceTagHolders)
{
return;
}
List<AIVirtualCard> bounceTagHolders = selfField.CardListSet.BounceTagHolders;
for (int i = 0; i < bounceTagHolders.Count; i++)
{
AIVirtualCard aIVirtualCard = bounceTagHolders[i];
if (!aIVirtualCard.IsDead && aIVirtualCard.IsOnField)
{
aIVirtualCard.ExecuteBounceSkills(bouncedCard, selfField, selfField.BestPlayPtn, situation);
}
}
}
public static int GetBounceCount(AIVirtualField field, AISituationInfo situation, AIScriptTokenArgType type)
{
int result = 0;
switch (type)
{
case AIScriptTokenArgType.NOW:
result = GetCurrentSituationBounceCount(situation);
break;
case AIScriptTokenArgType.TURN:
result = field.TurnBounceCount + GetCurrentSituationBounceCount(situation);
break;
case AIScriptTokenArgType.GAME:
result = field.GameBounceCount + GetCurrentSituationBounceCount(situation);
break;
}
return result;
}
private static int GetCurrentSituationBounceCount(AISituationInfo situation)
{
if (situation.BounceCardList == null)
{
return 0;
}
return situation.BounceCardList.Count;
}
}

View File

@@ -0,0 +1,21 @@
using System.Collections.Generic;
namespace Wizard;
public class AIBrokenCostSumUtility
{
public static int GetBrokenCostSum(AIVirtualField field, AIVirtualCard tagOwner, List<AIScriptTokenBase> filters, List<int> playPtn, AISituationInfo situation)
{
int num = 0;
List<AIVirtualCard> list = (tagOwner.IsAlly ? field.CardListSet.AllyDestroyedCards : field.CardListSet.EnemyDestroyedCards);
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (AIFilteringUtility.CheckMatchTargetFiltering(aIVirtualCard, list, filters, playPtn, tagOwner, situation))
{
num += aIVirtualCard.BaseCost;
}
}
return num;
}
}

View File

@@ -0,0 +1,69 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIBuffCountUtility
{
public static int GetBuffCount(AIVirtualCard owner, AIVirtualField field, AISituationInfo situation, List<int> playPtn, List<AIScriptTokenBase> argList)
{
if (argList.Count < 2)
{
return 0;
}
AIScriptTokenArgType argumentType = ((AIScriptArgumentToken)argList[0]).ArgumentType;
AIScriptTokenArgType argumentType2 = ((AIScriptArgumentToken)argList[1]).ArgumentType;
if (!IsDurationArgLegal(argumentType2) || !IsPositionArgLegal(argumentType))
{
return 0;
}
argList.RemoveRange(0, 2);
argList.Reverse();
if (argumentType == AIScriptTokenArgType.PLAYED)
{
return GetPlayedBuffCount(owner, field, argList, situation, playPtn, argumentType2);
}
return 0;
}
private static int GetPlayedBuffCount(AIVirtualCard owner, AIVirtualField field, List<AIScriptTokenBase> filters, AISituationInfo situation, List<int> playPtn, AIScriptTokenArgType duration)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothInplayCards, filters, owner, playPtn, situation);
if (list == null || list.Count <= 0)
{
return 0;
}
int num = 0;
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
switch (duration)
{
case AIScriptTokenArgType.TURN:
if (aIVirtualCard.BuffRecorderCollection != null)
{
int turn = (aIVirtualCard.IsAlly ? field.AllyTurnCount : field.EnemyTurnCount);
num += aIVirtualCard.BuffRecorderCollection.GetTurnBuffCount(turn, aIVirtualCard.IsSelfTurn);
}
break;
case AIScriptTokenArgType.GAME:
num += aIVirtualCard.BuffCount;
break;
}
}
return num;
}
private static bool IsDurationArgLegal(AIScriptTokenArgType duration)
{
if (duration != AIScriptTokenArgType.TURN)
{
return duration == AIScriptTokenArgType.GAME;
}
return true;
}
private static bool IsPositionArgLegal(AIScriptTokenArgType position)
{
return position == AIScriptTokenArgType.PLAYED;
}
}

View File

@@ -0,0 +1,241 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public static class AIBuffEvaluationUtility
{
public static readonly AIScriptTokenArgType[] LEGAL_TEMP_OR_PERM_ARGUMENTS = new AIScriptTokenArgType[2]
{
AIScriptTokenArgType.TEMP,
AIScriptTokenArgType.PERM
};
public static float EvalAllBuff(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> argList, List<int> playPtn, AISituationInfo situation)
{
if (tagOwner == null || field == null || argList == null || argList.Count <= 3)
{
return 0f;
}
CreateBuffInfoAndFilters(argList, out var filters, out var buffInfo);
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, null);
if (list == null || list.Count == 0)
{
return 0f;
}
list.RemoveAll((AIVirtualCard c) => c.IsAmulet);
return CalculateAllBuffValue(list, field, buffInfo, playPtn, situation);
}
public static float EvalRandomBuff(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> argList, List<int> playPtn, AISituationInfo situation)
{
if (tagOwner == null || field == null || argList == null || argList.Count <= 3)
{
return 0f;
}
CreateBuffInfoAndFilters(argList, out var filters, out var buffInfo);
List<AIVirtualCard> list = new List<AIVirtualCard>();
list.AddRange(field.CardListSet.BothClassAndInplayCards);
List<AIVirtualCard> list2 = AIFilteringUtility.MultipleFiltering(list, filters, tagOwner, playPtn, null);
if (list2 == null || list2.Count == 0)
{
return 0f;
}
list2.RemoveAll((AIVirtualCard c) => c.IsAmulet);
float num = 0f;
for (int num2 = 0; num2 < list2.Count; num2++)
{
AIVirtualCard target = list2[num2];
num += CalculateBuffValue(target, field, buffInfo, playPtn, situation);
}
return num / (float)list2.Count;
}
public static float EvalTargetingBuff(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> argList, List<int> playPtn, AISituationInfo situation)
{
if (tagOwner == null || field == null || argList == null || argList.Count <= 3)
{
return 0f;
}
CreateBuffInfoAndFilters(argList, out var filters, out var buffInfo);
List<AIVirtualCard> list = new List<AIVirtualCard>();
list.AddRange(field.CardListSet.BothClassAndInplayCards);
List<AIVirtualCard> list2 = AIFilteringUtility.MultipleFiltering(list, filters, tagOwner, playPtn, null);
if (list2 == null || list2.Count == 0)
{
return 0f;
}
list2.RemoveAll((AIVirtualCard c) => c.IsAmulet);
bool flag = true;
float num = float.MinValue;
for (int num2 = 0; num2 < list2.Count; num2++)
{
AIVirtualCard aIVirtualCard = list2[num2];
if (!aIVirtualCard.IsIndependent && (aIVirtualCard.IsAlly == tagOwner.IsAlly || !aIVirtualCard.CantBeFocusedSkill))
{
flag = false;
float num3 = CalculateBuffValue(aIVirtualCard, field, buffInfo, playPtn, situation);
if (num3 > num)
{
num = num3;
}
}
}
if (flag)
{
num = 0f;
}
return num;
}
private static void CreateBuffInfoAndFilters(List<AIScriptTokenBase> argList, out List<AIScriptTokenBase> filters, out AISimulationBuffInfo buffInfo)
{
int index = 0;
int index2 = 1;
int num = 2;
AIScriptArgumentToken aIScriptArgumentToken = argList[index] as AIScriptArgumentToken;
bool flag = false;
if (aIScriptArgumentToken != null)
{
flag = aIScriptArgumentToken.ArgumentType == AIScriptTokenArgType.TEMP;
}
int num2 = (int)argList[index2].Value;
int num3 = (int)argList[num].Value;
if (flag)
{
buffInfo = new AISimulationBuffInfo(num3, num2, num3, num2);
}
else
{
buffInfo = new AISimulationBuffInfo(0, 0, num3, num2);
}
filters = new List<AIScriptTokenBase>();
for (int num4 = argList.Count - 1; num4 > num; num4--)
{
filters.Add(argList[num4]);
}
}
private static float CalculateAllBuffValue(List<AIVirtualCard> targets, AIVirtualField field, AISimulationBuffInfo buffInfo, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCardStatusInfo> list = new List<AIVirtualCardStatusInfo>();
for (int i = 0; i < field.AllyInplayCards.Count; i++)
{
AIVirtualCard aIVirtualCard = field.AllyInplayCards[i];
if (aIVirtualCard.IsUnit)
{
list.Add(new AIVirtualCardStatusInfo(aIVirtualCard, aIVirtualCard.Attack, aIVirtualCard.Life));
}
}
List<AIVirtualCardStatusInfo> list2 = new List<AIVirtualCardStatusInfo>();
for (int j = 0; j < field.EnemyInplayCards.Count; j++)
{
AIVirtualCard aIVirtualCard2 = field.EnemyInplayCards[j];
if (aIVirtualCard2.IsUnit)
{
list2.Add(new AIVirtualCardStatusInfo(aIVirtualCard2, aIVirtualCard2.Attack, aIVirtualCard2.Life));
}
}
float num = 0f;
for (int k = 0; k < targets.Count; k++)
{
AIVirtualCard target = targets[k];
if (!target.IsUnit)
{
continue;
}
int attack = target.Attack + buffInfo.TotalAttackBuff;
int num2 = target.Life + buffInfo.TotalLifeBuff;
AIVirtualCardStatusInfo aIVirtualCardStatusInfo = null;
List<AIVirtualCardStatusInfo> list3 = (target.IsAlly ? list : list2);
aIVirtualCardStatusInfo = list3.FirstOrDefault((AIVirtualCardStatusInfo info) => info.BaseCard.IsSameCard(target));
if (num2 <= 0)
{
float num3 = target.EvaluateValueOnField(playPtn, situation, useStyle: true) - target.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) - target.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false);
num += num3 * (target.IsAlly ? (-1f) : 1f);
if (aIVirtualCardStatusInfo != null)
{
list3.Remove(aIVirtualCardStatusInfo);
}
}
else
{
num += (float)(buffInfo.TotalAttackBuff + buffInfo.TotalLifeBuff) * (target.IsAlly ? 1f : (-1f));
aIVirtualCardStatusInfo?.ModifyStatus(attack, num2);
}
}
if (list2 != null && list2.Count > 0 && list.Count > 0)
{
num += AISimulationUtility.EvaluateAttackValueAfterAllSkill(field, situation, list, list2, playPtn);
}
if (buffInfo.TempAttackBuff > 0)
{
for (int num4 = 0; num4 < targets.Count; num4++)
{
AIVirtualCard target2 = targets[num4];
AIVirtualCardStatusInfo aIVirtualCardStatusInfo2 = null;
aIVirtualCardStatusInfo2 = ((!target2.IsAlly) ? list2.FirstOrDefault((AIVirtualCardStatusInfo info) => info.BaseCard.IsSameCard(target2)) : list.FirstOrDefault((AIVirtualCardStatusInfo info) => info.BaseCard.IsSameCard(target2)));
if (aIVirtualCardStatusInfo2 != null && aIVirtualCardStatusInfo2.Life > 0)
{
num += (float)buffInfo.TempAttackBuff * (target2.IsAlly ? (-1f) : 1f);
}
}
}
return num;
}
private static float CalculateBuffValue(AIVirtualCard target, AIVirtualField field, AISimulationBuffInfo buffInfo, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCardStatusInfo> list = new List<AIVirtualCardStatusInfo>();
for (int i = 0; i < field.AllyInplayCards.Count; i++)
{
AIVirtualCard aIVirtualCard = field.AllyInplayCards[i];
if (aIVirtualCard.IsUnit)
{
list.Add(new AIVirtualCardStatusInfo(aIVirtualCard, aIVirtualCard.Attack, aIVirtualCard.Life));
}
}
List<AIVirtualCardStatusInfo> list2 = new List<AIVirtualCardStatusInfo>();
for (int j = 0; j < field.EnemyInplayCards.Count; j++)
{
AIVirtualCard aIVirtualCard2 = field.EnemyInplayCards[j];
if (aIVirtualCard2.IsUnit)
{
list2.Add(new AIVirtualCardStatusInfo(aIVirtualCard2, aIVirtualCard2.Attack, aIVirtualCard2.Life));
}
}
float num = 0f;
int attack = target.Attack + buffInfo.TotalAttackBuff;
int num2 = target.Life + buffInfo.TotalLifeBuff;
List<AIVirtualCardStatusInfo> list3 = (target.IsAlly ? list : list2);
AIVirtualCardStatusInfo aIVirtualCardStatusInfo = list3.FirstOrDefault((AIVirtualCardStatusInfo info) => info.BaseCard.IsSameCard(target));
if (num2 <= 0)
{
float num3 = target.EvaluateValueOnField(playPtn, situation, useStyle: true) - target.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) - target.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false);
num += num3 * (target.IsAlly ? (-1f) : 1f);
if (aIVirtualCardStatusInfo != null)
{
list3.Remove(aIVirtualCardStatusInfo);
}
}
else
{
num += (float)(buffInfo.TotalAttackBuff + buffInfo.TotalLifeBuff) * (target.IsAlly ? 1f : (-1f));
aIVirtualCardStatusInfo?.ModifyStatus(attack, num2);
}
if (list2 != null && list2.Count > 0 && list.Count > 0)
{
num += AISimulationUtility.EvaluateAttackValueAfterAllSkill(field, situation, list, list2, playPtn);
}
if (buffInfo.TempAttackBuff > 0)
{
AIVirtualCardStatusInfo aIVirtualCardStatusInfo2 = null;
aIVirtualCardStatusInfo2 = ((!target.IsAlly) ? list2.FirstOrDefault((AIVirtualCardStatusInfo info) => info.BaseCard.IsSameCard(target)) : list.FirstOrDefault((AIVirtualCardStatusInfo info) => info.BaseCard.IsSameCard(target)));
if (aIVirtualCardStatusInfo2 != null && aIVirtualCardStatusInfo2.Life > 0)
{
num += (float)buffInfo.TempAttackBuff * (target.IsAlly ? (-1f) : 1f);
}
}
return num;
}
}

View File

@@ -0,0 +1,24 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIBurialUtility
{
public static bool IsBurialRite(AISituationInfo situation, List<AIScriptTokenBase> filters, AIVirtualField field)
{
AISelectedTargetInfo burialRiteTarget = situation.GetBurialRiteTarget();
if (burialRiteTarget == null || burialRiteTarget.Type != TargetSelectType.BurialRite || !burialRiteTarget.HasTarget)
{
return false;
}
List<AIVirtualCard> targets = burialRiteTarget.Targets;
for (int i = 0; i < targets.Count; i++)
{
if (AIFilteringUtility.CheckMatchTargetFiltering(targets[i], field.AllyHandCards, filters, null, situation.Actor, situation))
{
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,28 @@
using System.Collections.Generic;
namespace Wizard;
public static class AICannotPlaySimulationUtility
{
public static bool IsCannotPlayByTag(this AIVirtualField field, AIVirtualTargetSelectAction situation, List<int> playPtn)
{
if (situation.ActionType != AIOperationType.PLAY || !situation.OriginalCard.IsAlly)
{
return false;
}
if (field.CannotPlayInformationList == null || field.CannotPlayInformationList.Count <= 0)
{
return false;
}
AIVirtualCard originalCard = situation.OriginalCard;
for (int i = 0; i < field.CannotPlayInformationList.Count; i++)
{
AICannotPlayInformation aICannotPlayInformation = field.CannotPlayInformationList[i];
if (AIFilteringUtility.CheckMatchTargetFiltering(originalCard, field.AllyHandCards, aICannotPlayInformation.Filters, playPtn, aICannotPlayInformation.Owner, situation))
{
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,31 @@
using System.Collections.Generic;
namespace Wizard;
public class AIChangeClassSimulationUtility
{
public static void ChangeClassAll(List<AIVirtualCard> candidates, CardBasePrm.ClanType classType)
{
if (candidates == null || candidates.Count <= 0)
{
return;
}
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
if (!aIVirtualCard.IsDead && !aIVirtualCard.IsIndependent)
{
aIVirtualCard.ChangeClass(classType);
}
}
}
public static void ChangeClassTarget(List<AIVirtualCard> candidates, CardBasePrm.ClanType classType, AIScriptTokenArgType whichTarget, AISituationInfo situation)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget != null && situationTarget.HasTarget)
{
ChangeClassAll(situationTarget.Targets, classType);
}
}
}

View File

@@ -0,0 +1,168 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIChangeCostSimulationUtility
{
public static void AddCostAll(int count, List<AIVirtualCard> targets)
{
if (targets != null && targets.Count > 0)
{
for (int i = 0; i < targets.Count; i++)
{
targets[i].AddCurrentCost(count);
}
}
}
public static void AddCostTarget(AIVirtualCard owner, int count, List<AIVirtualCard> candidates, List<AIVirtualCard> targets)
{
if (candidates == null || candidates.Count <= 0)
{
return;
}
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (!owner.IsSameCard(aIVirtualCard) && candidates.Contains(aIVirtualCard))
{
aIVirtualCard.AddCurrentCost(count);
}
}
}
public static void SetCostAll(int count, List<AIVirtualCard> targets)
{
if (targets != null && targets.Count > 0)
{
for (int i = 0; i < targets.Count; i++)
{
targets[i].SetCurrentCost(count);
}
}
}
public static void SetCostTarget(AIVirtualCard owner, int count, List<AIVirtualCard> candidates, List<AIVirtualCard> targets)
{
if (candidates == null || candidates.Count <= 0)
{
return;
}
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (!owner.IsSameCard(aIVirtualCard) && candidates.Contains(aIVirtualCard))
{
aIVirtualCard.SetCurrentCost(count);
}
}
}
public static AIVirtualCard SelectTargetForChangeCost(AIVirtualCard owner, List<AIVirtualCard> candidates, AISelectTargetPattern worstOrBest)
{
if (candidates == null || candidates.Count <= 0)
{
return null;
}
AIVirtualCard aIVirtualCard = candidates[0];
switch (worstOrBest)
{
case AISelectTargetPattern.Best:
{
for (int j = 1; j < candidates.Count; j++)
{
AIVirtualCard aIVirtualCard3 = candidates[j];
if (!owner.IsSameCard(aIVirtualCard3) && aIVirtualCard.Cost < aIVirtualCard3.Cost)
{
aIVirtualCard = aIVirtualCard3;
}
}
break;
}
case AISelectTargetPattern.Worst:
{
for (int i = 1; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard2 = candidates[i];
if (!owner.IsSameCard(aIVirtualCard2) && aIVirtualCard.Cost > aIVirtualCard2.Cost)
{
aIVirtualCard = aIVirtualCard2;
}
}
break;
}
}
return aIVirtualCard;
}
public static void ExecuteCostChange(AIScriptTokenArgType changeType, AIScriptTokenArgType whichTarget, int changeCost, AIVirtualCard owner, List<AIVirtualCard> candidates, AISituationInfo situation, AIVirtualField field)
{
if (candidates == null || candidates.Count <= 0)
{
return;
}
switch (whichTarget)
{
case AIScriptTokenArgType.ALL_SELECT:
ChangeCostValue(isTargetAll: true, changeType, changeCost, owner, candidates, null);
break;
case AIScriptTokenArgType.TARGET_SELECT:
case AIScriptTokenArgType.SECOND_TARGET_SELECT:
if (situation != null && situation.IsTargetExists(whichTarget))
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
AIConsoleUtility.Log("ExecuteCostChange Nothing TargetInfo");
break;
}
List<AIVirtualCard> targets2 = situationTarget.Targets;
ChangeCostValue(isTargetAll: false, changeType, changeCost, owner, candidates, targets2);
}
break;
case AIScriptTokenArgType.RANDOM_SELECT:
{
AIVirtualCard aIVirtualCard = SelectTargetForChangeCost(owner, candidates, AISelectTargetPattern.Worst);
if (aIVirtualCard != null)
{
List<AIVirtualCard> targets = new List<AIVirtualCard> { aIVirtualCard };
ChangeCostValue(isTargetAll: false, changeType, changeCost, owner, candidates, targets);
}
break;
}
default:
AIConsoleUtility.LogError("ExecuteCostChange: ilegal Target Arg type [" + whichTarget.ToString() + "]");
break;
}
}
public static void ChangeCostValue(bool isTargetAll, AIScriptTokenArgType changeType, int changeCost, AIVirtualCard owner, List<AIVirtualCard> candidates, List<AIVirtualCard> targets)
{
switch (changeType)
{
case AIScriptTokenArgType.ADD:
if (isTargetAll)
{
AddCostAll(changeCost, candidates);
}
else
{
AddCostTarget(owner, changeCost, candidates, targets);
}
break;
case AIScriptTokenArgType.SET:
if (isTargetAll)
{
SetCostAll(changeCost, candidates);
}
else
{
SetCostTarget(owner, changeCost, candidates, targets);
}
break;
default:
AIConsoleUtility.LogError("ChangeCostValue: ilegal Cost Arg type [" + changeType.ToString() + "]");
break;
}
}
}

View File

@@ -0,0 +1,41 @@
using System.Collections.Generic;
namespace Wizard;
public class AIClashHeal : AIFiltersAndSelectTypeArgument
{
private readonly int HEAL_ARG_OFFSET = 1;
private AIPolishConvertedExpression _healArg;
protected override int SELECT_TYPE_OFFSET => 2;
public AIClashHeal(string text)
: base(text)
{
}
protected override void InitExpressions(string text)
{
base.InitExpressions(text);
_healArg = _exprList[_exprList.Count - HEAL_ARG_OFFSET];
}
public override void Execute(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation = null)
{
List<AIVirtualCard> targetsFromField = GetTargetsFromField(tagOwner, field, playPtn, situation);
if (targetsFromField != null && targetsFromField.Count > 0)
{
int heal = (int)_healArg.EvalArg(tagOwner, playPtn, field, situation);
if (base.SelectType == AIScriptTokenArgType.ALL_SELECT)
{
AISkillSimulationUtility.HealAll(targetsFromField, field, heal, playPtn, situation);
}
}
}
public override List<AIVirtualCard> GetFilteredTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, bool isBlockDead = true)
{
return AIFilteringUtility.FilteringForStatusEffectiveAbility(candidates, tagOwner, base.Filters, playPtn, situation, isAttackEffective: false, isBlockDead);
}
}

View File

@@ -0,0 +1,197 @@
using System.Collections.Generic;
namespace Wizard;
public static class AICopyTagSimulationUtility
{
public static List<AIPlayTag> GetCopyTagListFromCard(AIVirtualCard target, List<AIScriptTokenArgType> timingList)
{
List<AIPlayTag> list = null;
for (int i = 0; i < timingList.Count; i++)
{
AIScriptTokenArgType timing = timingList[i];
List<AIPlayTag> copyTagOfCertainTiming = GetCopyTagOfCertainTiming(target, timing);
if (copyTagOfCertainTiming != null && copyTagOfCertainTiming.Count > 0)
{
list = AIParamQuery.AddRangeToList(copyTagOfCertainTiming, list);
}
}
return list;
}
public static void ExecuteCopyAndAttachTagToAll(AIVirtualCard tagOwner, List<AIVirtualCard> targetList, List<AIScriptTokenArgType> skillTimingList, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (targetList == null || targetList.Count <= 0)
{
return;
}
for (int i = 0; i < targetList.Count; i++)
{
List<AIPlayTag> copyTagListFromCard = GetCopyTagListFromCard(targetList[i], skillTimingList);
if (copyTagListFromCard != null)
{
AttachTagFromCopyTagList(tagOwner, tagOwner, copyTagListFromCard, situation);
}
}
}
public static void ExecuteCopyAndAttachTagToSelectedTarget(AIVirtualCard tagOwner, List<AIVirtualCard> candidates, List<AIScriptTokenArgType> skillTimingList, AIScriptTokenArgType whichTarget, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (situation != null && situation.IsTargetExists(whichTarget))
{
CopyAndAttachTagToSituationTarget(tagOwner, candidates, skillTimingList, whichTarget, field, playPtn, situation);
}
else
{
CopyAndAttachTagPrediction(tagOwner, candidates, skillTimingList, field, playPtn, situation);
}
}
private static void CopyAndAttachTagToSituationTarget(AIVirtualCard tagOwner, List<AIVirtualCard> candidates, List<AIScriptTokenArgType> skillTimingList, AIScriptTokenArgType whichTarget, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget != null && situationTarget.Targets != null)
{
ExecuteCopyAndAttachTagToAll(tagOwner, situationTarget.Targets, skillTimingList, field, playPtn, situation);
}
}
private static void CopyAndAttachTagPrediction(AIVirtualCard tagOwner, List<AIVirtualCard> candidates, List<AIScriptTokenArgType> skillTimingList, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (candidates == null || candidates.Count <= 0)
{
return;
}
AIVirtualCard aIVirtualCard = SelecteBestCopyTarget(tagOwner, candidates, field, playPtn, situation);
if (aIVirtualCard != null)
{
List<AIPlayTag> copyTagListFromCard = GetCopyTagListFromCard(aIVirtualCard, skillTimingList);
if (copyTagListFromCard != null)
{
AttachTagFromCopyTagList(tagOwner, tagOwner, copyTagListFromCard, situation);
}
}
}
private static AIVirtualCard SelecteBestCopyTarget(AIVirtualCard attachTarget, List<AIVirtualCard> candidates, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (candidates == null || candidates.Count <= 0)
{
return null;
}
AIVirtualCard result = null;
float num = float.MinValue;
for (int i = 0; i < candidates.Count; i++)
{
float num2 = 0f;
AIVirtualCard aIVirtualCard = candidates[i];
if (aIVirtualCard.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenAttack))
{
num2 += (float)aIVirtualCard.TagCollectionContainer.AttackTags.TagList.Count * 1f;
}
if (aIVirtualCard.TagCollectionContainer.HasTagCollection(TagCollectionType.Lastword))
{
num2 += (float)aIVirtualCard.TagCollectionContainer.LastwordTags.TagList.Count * 1f;
}
num2 += (aIVirtualCard.IsQuick ? 3f : 0f);
num2 += (aIVirtualCard.IsKiller ? 1f : 0f);
num2 += (aIVirtualCard.IsDrain ? 1f : 0f);
num2 += (aIVirtualCard.IsGuard ? 1f : 0f);
if (aIVirtualCard.IsRush)
{
List<AIVirtualCard> list = (attachTarget.IsAlly ? field.EnemyInplayCards : field.AllyInplayCards);
num2 += ((list != null && list.Count > 0) ? 1f : 0.5f);
}
if (num2 > num)
{
num = num2;
result = aIVirtualCard;
}
}
return result;
}
private static void AttachTagFromCopyTagList(AIVirtualCard tagOwner, AIVirtualCard attachTarget, List<AIPlayTag> copyTgList, AISituationInfo situation)
{
for (int i = 0; i < copyTgList.Count; i++)
{
AIAttachTagSimulationUtility.SimulateAttachTagToSingle(attachTarget, tagOwner, copyTgList[i], AIScriptTokenArgType.NONE, situation);
}
}
private static List<AIPlayTag> GetCopyTagOfCertainTiming(AIVirtualCard target, AIScriptTokenArgType timing)
{
switch (timing)
{
case AIScriptTokenArgType.KILLER:
case AIScriptTokenArgType.QUICK:
case AIScriptTokenArgType.RUSH:
case AIScriptTokenArgType.DRAIN:
case AIScriptTokenArgType.GUARD:
return CopyKeywordSkillTags(target, timing);
case AIScriptTokenArgType.WHEN_DESTROY:
return CopyWhenDestroyTags(target);
case AIScriptTokenArgType.WHEN_ATTACK:
return CopyWhenAttackTags(target);
case AIScriptTokenArgType.WHEN_CLASH:
return CopyWhenClashTags(target);
default:
return null;
}
}
private static List<AIPlayTag> CopyKeywordSkillTags(AIVirtualCard target, AIScriptTokenArgType skillType)
{
List<AIPlayTag> list = null;
if (target.IsHoldKeywordSkill(skillType))
{
AIPlayTag aIPlayTag = AIPlayTagInitializingUtility.CreateBasicSkillTag(skillType);
if (aIPlayTag == null)
{
return null;
}
list = AIParamQuery.AddElementToList(aIPlayTag, list);
}
return list;
}
private static List<AIPlayTag> CopyWhenDestroyTags(AIVirtualCard target)
{
List<AIPlayTag> list = null;
if (target.TagCollectionContainer.HasTagCollection(TagCollectionType.Lastword))
{
list = AIParamQuery.AddRangeToList(target.TagCollectionContainer.LastwordTags.TagList, list);
}
if (target.TagCollectionContainer.HasTag(AIPlayTagType.Break))
{
list = AIParamQuery.AddRangeToList(target.TagCollectionContainer.BreakBonusTags.TagList, list);
}
if (target.TagCollectionContainer.HasTag(AIPlayTagType.IgnoreBreak))
{
list = AIParamQuery.AddRangeToList(target.TagCollectionContainer.IgnoreBreakTags.TagList, list);
}
return list;
}
private static List<AIPlayTag> CopyWhenAttackTags(AIVirtualCard target)
{
if (target.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenAttack))
{
return target.TagCollectionContainer.AttackTags.TagList;
}
return null;
}
private static List<AIPlayTag> CopyWhenClashTags(AIVirtualCard target)
{
if (target.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenAttack))
{
AttackTagCollection attackTags = target.TagCollectionContainer.AttackTags;
if (attackTags.HasClashTag)
{
return attackTags.ClashTags;
}
}
return null;
}
}

View File

@@ -0,0 +1,122 @@
using System.Collections.Generic;
namespace Wizard;
public static class AICountdownChangeUtility
{
public static float EvalChantCountChange(AIVirtualCard actCard, int amount, List<int> playPtn, bool isSelect, AISituationInfo situation)
{
if (GetMemberChantFieldNum(actCard.SelfField, playPtn) <= 0)
{
return 0f;
}
float num = 0f;
List<AIVirtualCard> allyClassAndInplayCards = actCard.SelfField.CardListSet.AllyClassAndInplayCards;
List<AIVirtualCard> list = new List<AIVirtualCard>();
for (int i = 0; i < allyClassAndInplayCards.Count; i++)
{
AIVirtualCard aIVirtualCard = allyClassAndInplayCards[i];
if ((aIVirtualCard.CardIndex != actCard.CardIndex || aIVirtualCard.IsPlayer != actCard.IsPlayer) && aIVirtualCard.IsCountdownAmulet)
{
list.Add(aIVirtualCard);
}
}
if (playPtn != null && playPtn.Count > 0)
{
for (int j = 0; j < playPtn.Count; j++)
{
AIVirtualCard aIVirtualCard2 = actCard.SelfField.AllyHandCards[playPtn[j]];
if ((aIVirtualCard2.CardIndex != actCard.CardIndex || aIVirtualCard2.IsPlayer != actCard.IsPlayer) && aIVirtualCard2.IsCountdownAmulet)
{
list.Add(aIVirtualCard2);
}
}
}
if (isSelect)
{
int bestCandidateIndex = 0;
return CalcMaxSelectChantCountChangeBonus(amount, list, playPtn, ref bestCandidateIndex, situation);
}
return CalcAllChantCountChangeBonus(amount, list, playPtn, situation);
}
public static float CalcMaxSelectChantCountChangeBonus(int amount, List<AIVirtualCard> targets, List<int> playPtn, ref int bestCandidateIndex, AISituationInfo situation)
{
float num = 0f;
int count = targets.Count;
for (int i = 0; i < count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
float num2 = aIVirtualCard.EvaluateValueOnField(playPtn, situation, useStyle: false, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true);
AIVirtualCard aIVirtualCard2 = new AIVirtualCard(aIVirtualCard, aIVirtualCard.SelfField);
int chantCount = aIVirtualCard2.ChantCount;
chantCount = ((chantCount > amount) ? (chantCount - amount) : 0);
float num3 = 0f;
if (chantCount > 0)
{
aIVirtualCard2.ChantCount = chantCount;
num3 = aIVirtualCard2.EvaluateValueOnField(playPtn, situation, useStyle: false, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true);
}
else
{
num3 = aIVirtualCard.EvaluateBreakValue(playPtn, useIgnoreBreak: true);
}
float num4 = num3 - num2;
if (num4 > num)
{
num = num4;
bestCandidateIndex = i;
}
}
return num;
}
public static float CalcAllChantCountChangeBonus(int amount, List<AIVirtualCard> targets, List<int> playPtn, AISituationInfo situation)
{
float num = 0f;
int count = targets.Count;
for (int i = 0; i < count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
float num2 = aIVirtualCard.EvaluateValueOnField(playPtn, situation, useStyle: false, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true);
AIVirtualCard aIVirtualCard2 = new AIVirtualCard(aIVirtualCard, aIVirtualCard.SelfField);
int chantCount = aIVirtualCard2.ChantCount;
chantCount = ((chantCount > amount) ? (chantCount - amount) : 0);
float num3 = 0f;
if (chantCount > 0)
{
aIVirtualCard2.ChantCount = chantCount;
num3 = aIVirtualCard2.EvaluateValueOnField(playPtn, situation, useStyle: false, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true);
}
else
{
num3 = aIVirtualCard.EvaluateBreakValue(playPtn, useIgnoreBreak: true);
}
num += num3 - num2;
}
return num;
}
public static int GetMemberChantFieldNum(AIVirtualField field, List<int> handPtn)
{
int num = 0;
for (int i = 0; i < field.AllyInplayCards.Count; i++)
{
if (field.AllyInplayCards[i].IsCountdownAmulet)
{
num++;
}
}
if (handPtn != null)
{
for (int j = 0; j < handPtn.Count; j++)
{
if (field.AllyHandCards[handPtn[j]].IsCountdownAmulet)
{
num++;
}
}
}
return num;
}
}

View File

@@ -0,0 +1,41 @@
using System.Collections.Generic;
namespace Wizard;
public static class AICrystalizeUtility
{
public static bool IsCrystalize(AIVirtualCard card, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (card == null || card.CrystalizeCostList == null || !card.IsInHand)
{
return false;
}
AIVariableResultContainer valResultContainer = field.AI.ValResultContainer;
ulong hash = AIFunctionResultHashCalculator.GetHash(card, field, playPtn, null, 0uL);
if (valResultContainer.GetContainsResultValue(AIScriptTokenVariableType.IS_CRYSTALIZE, hash, out var getResult))
{
return getResult == 1f;
}
List<int> playPtn2 = (card.IsAlly ? playPtn : null);
bool flag = field.AI.PlayPtnRecorder.IsCardPlayingSimulationType(card, field, playPtn2, situation, PlaySimulationType.Crystalize);
valResultContainer.CheckDuplicateAndAddRecord(AIScriptTokenVariableType.IS_CRYSTALIZE, hash, flag ? 1f : 0f, $"IsCrystalize(): Already hashed target and not equal value. CardName:[{card.CardName}] hash:[{hash}]");
return flag;
}
public static int GetCrystalizeId(AIVirtualCard card, int usedCost)
{
if (card.CrystalizeCostList == null || card.CrystalizeCostList.Count <= 0)
{
return -1;
}
for (int i = 0; i < card.CrystalizeCostList.Count; i++)
{
AICrystalizeInformation aICrystalizeInformation = card.CrystalizeCostList[i];
if (aICrystalizeInformation.Cost == usedCost)
{
return aICrystalizeInformation.CardId;
}
}
return -1;
}
}

View File

@@ -0,0 +1,53 @@
using System.Collections.Generic;
using UnityEngine;
namespace Wizard;
public class AIDamageClippingInfo : AIBarrierInfoBase
{
public override AIBarrierType BarrierType => AIBarrierType.DamageClipping;
public int ClippingRange { get; protected set; } = 9999;
public AIDamageClippingInfo(int amount, int range, AIDamageType damageType, AIBarrierStopTiming stopTiming)
: base(amount, damageType, stopTiming)
{
ClippingRange = range;
UpdateHash();
}
public AIDamageClippingInfo(int amount, int range, AIDamageType damageType, List<AIBarrierStopTiming> stopTimingList)
: base(amount, damageType, stopTimingList)
{
ClippingRange = range;
UpdateHash();
}
public override AIBarrierInfoBase Clone()
{
return new AIDamageClippingInfo(base.BarrierAmount, ClippingRange, base.DamageType, base.StopTimingList);
}
public override bool IsShield()
{
if (ClippingRange == 9999)
{
return base.BarrierAmount <= 0;
}
return false;
}
protected override int CalcDamage(AIVirtualCard owner, int damage)
{
if (damage > ClippingRange)
{
return damage;
}
return Mathf.Min(damage, base.BarrierAmount);
}
protected override void UpdateHash()
{
base.Hash = AIBarrierSimulationUtility.CalculateDamageClipInfoHash(base.DamageType, BarrierType, base.StopTimingList, base.BarrierAmount, ClippingRange);
}
}

View File

@@ -0,0 +1,41 @@
using System.Collections.Generic;
using UnityEngine;
namespace Wizard;
public class AIDamageCutInfo : AIBarrierInfoBase
{
public override AIBarrierType BarrierType => AIBarrierType.DamageCut;
public AIDamageCutInfo(int amount, AIDamageType damageType, AIBarrierStopTiming stopTiming)
: base(amount, damageType, stopTiming)
{
UpdateHash();
}
public AIDamageCutInfo(int amount, AIDamageType damageType, List<AIBarrierStopTiming> stopTimingList)
: base(amount, damageType, stopTimingList)
{
UpdateHash();
}
public override AIBarrierInfoBase Clone()
{
return new AIDamageCutInfo(base.BarrierAmount, base.DamageType, base.StopTimingList);
}
public override bool IsShield()
{
return false;
}
protected override int CalcDamage(AIVirtualCard owner, int damage)
{
return Mathf.Max(0, damage - base.BarrierAmount);
}
protected override void UpdateHash()
{
base.Hash = AIBarrierSimulationUtility.CalculateDamageCutInfoHash(base.DamageType, BarrierType, base.StopTimingList, base.BarrierAmount);
}
}

View File

@@ -0,0 +1,37 @@
using System.Collections.Generic;
namespace Wizard;
public class AIDamageSelectLogicArgument : AISelectLogicArgumentBase
{
private const int DAMAGE_VALUE_ARG_INDEX = 0;
public override AIScriptTokenArgType LogicType => AIScriptTokenArgType.DAMAGE_LOGIC;
public AIDamageSelectLogicArgument(List<string> args)
: base(args)
{
}
public override AIVirtualCard SelectSingleTarget(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
int damageValue = GetDamageValue(tagOwner, field, playPtn, situation);
return AIDamageSimulationUtility.SelectDamageTarget(candidates, field, playPtn, situation, damageValue, tagOwner.IsSpell, worstOrBest);
}
public override List<AIVirtualCard> SelectMultipleSelectedTargets(List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
LogNotImplementMultipleSelect();
return null;
}
private int GetDamageValue(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (_argumentList == null || _argumentList.Count <= 0)
{
AIConsoleUtility.LogError("AIDamageSelectLogicArgument error!! _argumentList is null");
return 0;
}
return (int)_argumentList[0].EvalArg(tagOwner, playPtn, field, situation);
}
}

View File

@@ -0,0 +1,657 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Cute;
using UnityEngine;
namespace Wizard;
public static class AIDamageSimulationUtility
{
public static float EvalTargetingDamageAndRandomMultiSelectDamage(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> targetFilters, List<AIScriptTokenBase> randomFilters, List<int> playPtn, AISituationInfo situation, int targetDamage, int randomDamage, int randomDamageCount)
{
if (tagOwner == null || field == null || targetFilters == null)
{
return 0f;
}
int num = field.DamageModifierCollection.CalcModifiedDamage(field, playPtn, situation, tagOwner, targetDamage);
int damageAmount = field.DamageModifierCollection.CalcModifiedDamage(field, playPtn, situation, tagOwner, randomDamage);
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, targetFilters, tagOwner, playPtn, situation);
list.RemoveAll((AIVirtualCard c) => c.IsAmulet);
list = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(list, tagOwner, playPtn);
float num2 = float.MinValue;
int count = list.Count;
AIVirtualCard target = null;
for (int num3 = 0; num3 < count; num3++)
{
AIVirtualCard aIVirtualCard = list[num3];
if (aIVirtualCard.IsAlly == tagOwner.IsAlly || (!aIVirtualCard.IsUntouchable && !aIVirtualCard.IsSneak))
{
float num4 = 0f;
num4 = ((!aIVirtualCard.IsLeader) ? EvalDamageToCertainUnit(tagOwner, aIVirtualCard, field, num, playPtn, situation, field.AllyHandCards.Contains(tagOwner)) : AILeaderLifeEvaluationUtility.Evaluate(CalcLifeAfterDamage(aIVirtualCard, situation, num, tagOwner.IsSpell), aIVirtualCard.Life, aIVirtualCard.IsAlly, tagOwner.IsAlly));
if (num4 > num2)
{
num2 = num4;
target = aIVirtualCard;
}
}
}
if (target == null)
{
return AIRandomMultiDamageEvaluator.EvaluateRandomDamageAverage(tagOwner, field, playPtn, situation, targetFilters, damageAmount, randomDamageCount);
}
int num5 = target.SimulateDamageAmount(num, tagOwner.IsUnit, tagOwner.IsSpell);
float num6 = 0f;
int num7 = CalcLifeAfterDamage(target, situation, num, tagOwner.IsSpell);
if (num7 <= 0)
{
int num8 = target.Life - num7;
float num9 = target.EvaluateValueOnField(playPtn, situation, useStyle: true) - (target.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) + target.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false)) + (float)(num8 - target.Life) * -0.1f;
num6 = (target.IsAlly ? (0f - num9) : num9);
new List<AIVirtualCard>(field.CardListSet.BothClassAndInplayCards).RemoveAll((AIVirtualCard c) => c.Equals(target));
}
else
{
_ = field.CardListSet.BothClassAndInplayCards;
num6 = target.EvaluateValueOnField(playPtn, situation, useStyle: true);
target.Life -= num5;
num6 -= target.EvaluateValueOnField(playPtn, situation, useStyle: true);
target.Life += num5;
}
target.Life -= num5;
num6 += AIRandomMultiDamageEvaluator.EvaluateRandomDamageAverage(tagOwner, field, playPtn, situation, targetFilters, damageAmount, randomDamageCount);
target.Life += num5;
return num6;
}
public static float EvalTargetingDamage(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> filters, List<int> playPtn, AISituationInfo situation, int damage)
{
if (tagOwner == null || field == null || filters == null)
{
return 0f;
}
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, situation);
if (list == null || list.Count <= 0)
{
return 0f;
}
list.RemoveAll((AIVirtualCard c) => c.IsAmulet);
list = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(list, tagOwner, playPtn);
int damage2 = field.DamageModifierCollection.CalcModifiedDamage(field, playPtn, situation, tagOwner, damage);
float num = float.MinValue;
int count = list.Count;
if (count <= 0)
{
return 0f;
}
for (int num2 = 0; num2 < count; num2++)
{
AIVirtualCard aIVirtualCard = list[num2];
if (aIVirtualCard.IsAlly == tagOwner.IsAlly || (!aIVirtualCard.IsUntouchable && !aIVirtualCard.IsSneak))
{
float num3 = 0f;
num3 = ((!aIVirtualCard.IsLeader) ? EvalDamageToCertainUnit(tagOwner, aIVirtualCard, field, damage2, playPtn, situation, field.AllyHandCards.Contains(tagOwner)) : AILeaderLifeEvaluationUtility.Evaluate(CalcLifeAfterDamage(aIVirtualCard, situation, damage2, tagOwner.IsSpell), aIVirtualCard.Life, aIVirtualCard.IsAlly, tagOwner.IsAlly));
if (num3 > num)
{
num = num3;
}
}
}
if (num == float.MinValue)
{
num = 0f;
}
return num;
}
private static float EvalDamageToCertainUnit(AIVirtualCard tagOwner, AIVirtualCard target, AIVirtualField field, int damage, List<int> playPtn, AISituationInfo situation, bool isWhenPlaySkill)
{
float num = target.EvaluateValueOnField(playPtn, situation, useStyle: true) - (target.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) + target.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false));
int life = target.Life;
float num2 = 0f;
int num3 = CalcLifeAfterDamage(target, situation, damage, tagOwner.IsSpell);
if (num3 <= 0)
{
int num4 = life - num3;
float num5 = num + (float)(num4 - life) * -0.1f;
num2 = (target.IsAlly ? (0f - num5) : num5);
}
else
{
if (target.IsAlly)
{
return 0f;
}
if (target.IsCantUnderAnyAttack())
{
num2 += 0f;
}
else if (field.ParamQuery.GetEnemyGuardiansCount() > 0 && !target.IsGuard && !tagOwner.IsIgnoreGuard)
{
num2 += 0f;
}
else
{
AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(null, target);
List<int> list = new List<int>();
List<int> list2 = new List<int>();
List<float> list3 = new List<float>();
if (tagOwner.IsUnit && isWhenPlaySkill && tagOwner.IsAbleEvolution())
{
aIVirtualAttackInfo.SetActor(tagOwner);
list.Add(tagOwner.SimulateAttackAmount(tagOwner.Attack + tagOwner.EvoAttackPlus, aIVirtualAttackInfo));
list2.Add(tagOwner.Life + tagOwner.EvoLifePlus);
list3.Add(tagOwner.EvaluateValueOnField(playPtn, situation, useStyle: true));
}
for (int i = 0; i < field.AllyInplayCards.Count; i++)
{
AIVirtualCard aIVirtualCard = field.AllyInplayCards[i];
if (aIVirtualCard.IsUnit && !aIVirtualCard.IsDead && aIVirtualCard.IsAttackable(EnemyAI.EmptyPlayPtn))
{
aIVirtualAttackInfo.SetActor(aIVirtualCard);
list.Add(aIVirtualCard.SimulateAttackAmount(aIVirtualAttackInfo));
list2.Add(aIVirtualCard.Life);
list3.Add(aIVirtualCard.EvaluateValueOnField(playPtn, situation, useStyle: true));
}
}
int num6 = (int)Mathf.Pow(2f, list.Count);
for (int j = 0; j < num6; j++)
{
int num7 = j;
int num8 = 0;
int num9 = 0;
float num10 = 0f;
float num11 = 0f;
while (num7 > 0)
{
if (num7 % 2 == 1)
{
num9 += list[num8];
if (list2[num8] <= target.Attack)
{
num10 += list3[num8];
}
}
num8++;
num7 /= 2;
}
num9 = target.SimulateDamageAmount(num9);
num11 = ((num9 >= life) ? (num11 + 0f) : ((num9 >= num3) ? (num11 + (num - num10)) : (num11 + 0f)));
if (num2 < num11)
{
num2 = num11;
}
}
}
}
return num2;
}
public static float EvalRandomMultiSelectDamage(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> filters, List<int> playPtn, AISituationInfo situation, int damage, int selectCount)
{
if (tagOwner == null || field == null || filters == null)
{
return 0f;
}
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, null);
if (list != null && list.Count > 0)
{
list.RemoveAll((AIVirtualCard c) => c.IsAmulet);
if (list.Count <= selectCount)
{
return CalculateMultiAllDamage(tagOwner, list, field, playPtn, situation, damage, 1);
}
int num = field.DamageModifierCollection.CalcModifiedDamage(field, playPtn, situation, tagOwner, damage);
List<float> list2 = new List<float>();
List<int> list3 = new List<int>();
for (int num2 = 0; num2 < list.Count; num2++)
{
list2.Add(list[num2].EvaluateValueOnField(playPtn, situation, useStyle: true) - list[num2].GetAllBreakBonus(playPtn, useIgnoreInBattle: false) - list[num2].GetAllLeaveBonus(playPtn, useIgnoreInBattle: false));
list3.Add(num2);
}
List<int[]> list4 = AIMathematicsLibrary.EnumerateCombinations(list3, selectCount).ToList();
if (list4 == null || list4.Count == 0)
{
return 0f;
}
float num3 = 0f;
for (int num4 = 0; num4 < list4.Count; num4++)
{
int[] array = list4[num4];
float num5 = 0f;
for (int num6 = 0; num6 < array.Length; num6++)
{
int num7 = CalcLifeAfterDamage(list[array[num6]], situation, num, tagOwner.IsSpell);
num5 += ((num7 <= 0) ? list2[array[num6]] : ((float)num));
}
num3 += num5;
}
return num3 / (float)list4.Count;
}
return 0f;
}
public static int CalcLifeAfterDamage(AIVirtualCard target, AISituationInfo situation, int damage, bool isSpell)
{
int num = target.SimulateDamageAmount(damage, isSkillDamage: true, isSpell);
int num2 = target.Life - num;
int atkBuff = 0;
int lifeBuff = 0;
if (target.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenDamaged))
{
target.TagCollectionContainer.DamagedTags.GetDamagedBuffValue(target, target.SelfField, target.SelfField.BestPlayPtn, situation, out atkBuff, out lifeBuff);
num2 += lifeBuff;
}
return num2;
}
public static float EvalEchoDamage(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> filters, int damage, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothInplayCards, filters, tagOwner, playPtn, situation);
if (list == null || list.Count == 0)
{
return 0f;
}
float num = 0f;
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
float item = aIVirtualCard.EvaluateValueOnField(playPtn, situation, useStyle: true) - aIVirtualCard.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) - aIVirtualCard.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false);
List<AIVirtualCard> list2 = new List<AIVirtualCard> { aIVirtualCard };
List<float> list3 = new List<float> { item };
List<AIVirtualCard> list4 = (aIVirtualCard.IsAlly ? field.AllyInplayCards : field.EnemyInplayCards);
for (int j = 0; j < list4.Count; j++)
{
AIVirtualCard aIVirtualCard2 = list4[j];
if (!aIVirtualCard2.IsSameCard(aIVirtualCard) && aIVirtualCard2.BaseId == aIVirtualCard.BaseId)
{
list2.Add(aIVirtualCard2);
float item2 = aIVirtualCard2.EvaluateValueOnField(playPtn, situation, useStyle: true) - aIVirtualCard2.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) - aIVirtualCard2.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false);
list3.Add(item2);
}
}
float num2 = 0f;
for (int k = 0; k < list2.Count; k++)
{
AIVirtualCard aIVirtualCard3 = list2[k];
int damageAmount = field.DamageModifierCollection.CalcModifiedDamage(field, playPtn, situation, tagOwner, damage);
damageAmount = aIVirtualCard3.SimulateDamageAmount(damageAmount, isSkillDamage: true, tagOwner.IsSpell);
if (damageAmount >= aIVirtualCard3.Life)
{
num2 += list3[k];
}
}
if (EnemyAI.IsLargerThan(num2, num))
{
num = num2;
}
}
return num;
}
public static AIVirtualCard SelectDamageTarget(List<AIVirtualCard> candidates, AIVirtualField field, List<int> playPtn, AISituationInfo situation, int damage, bool isSpell, AISelectTargetPattern bestOrWorst)
{
if (candidates == null || candidates.Count <= 0)
{
AIConsoleUtility.LogError("AISimulationDamageUtility.SelectDamageTarget() : candidates is null ");
return null;
}
AIVirtualCard result = null;
float num = ((bestOrWorst == AISelectTargetPattern.Worst) ? float.MaxValue : float.MinValue);
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
if (!aIVirtualCard.IsDead)
{
float damageValueToCertainTarget = GetDamageValueToCertainTarget(aIVirtualCard, damage, situation, playPtn, isSpell);
bool flag = false;
switch (bestOrWorst)
{
case AISelectTargetPattern.Worst:
flag = num > damageValueToCertainTarget;
break;
case AISelectTargetPattern.Best:
flag = damageValueToCertainTarget > num;
break;
}
if (flag)
{
num = damageValueToCertainTarget;
result = aIVirtualCard;
}
}
}
return result;
}
public static float GetDamageValueToCertainTarget(AIVirtualCard target, int damage, AISituationInfo situation, List<int> playPtn, bool isSpell)
{
float num = 0f;
int num2 = CalcLifeAfterDamage(target, situation, damage, isSpell);
float num3 = target.EvaluateValueOnField(playPtn, situation, useStyle: true);
if (num2 <= 0)
{
num = num3 - target.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) - target.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false);
}
else
{
float num4 = 0.01f;
num = (float)(target.Life - num2) + num3 * num4;
}
return num * (target.IsAlly ? (-1f) : 1f);
}
public static float EvalOldestDamage(AIVirtualCard tagOwner, List<AIVirtualCard> candidates, AIVirtualField field, int damage, List<int> playPtn, AISituationInfo situation)
{
float num = 0f;
if (candidates == null || candidates.Count <= 0)
{
return 0f;
}
int num2 = field.DamageModifierCollection.CalcModifiedDamage(field, playPtn, situation, tagOwner, damage);
AIVirtualCard aIVirtualCard = null;
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard2 = candidates[i];
if (aIVirtualCard2.IsLeader)
{
if (aIVirtualCard == null)
{
aIVirtualCard = aIVirtualCard2;
}
else
{
AIConsoleUtility.LogError("EvalOldestDamage(): Already selected leader card! Candidate cards is illegal.");
}
}
else if (aIVirtualCard2.IsUnit)
{
int life = aIVirtualCard2.Life;
int num3 = ((num2 < life) ? num2 : life);
num += EvalDamageToCertainUnit(tagOwner, aIVirtualCard2, field, num3, playPtn, situation, field.AllyHandCards.Contains(tagOwner));
num2 -= num3;
if (num2 <= 0)
{
break;
}
}
}
if (aIVirtualCard != null && num2 > 0)
{
AIBarrierPseudoSimulationInfo aIBarrierPseudoSimulationInfo = new AIBarrierPseudoSimulationInfo(aIVirtualCard);
bool isSpell = tagOwner.IsSpell;
int num4 = aIBarrierPseudoSimulationInfo.SimulateDamageAmount(aIVirtualCard.SimulateDamageShield(damage, isSkillDamage: true, isSpell), isSpell);
num += AILeaderLifeEvaluationUtility.Evaluate(aIVirtualCard.Life - num4, aIVirtualCard.Life, aIVirtualCard.IsAlly, tagOwner.IsAlly);
}
return num;
}
public static float EvalMultiAllDamage(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> filters, List<int> playPtn, AISituationInfo situation, int damage, int damageCount)
{
if (tagOwner == null || field == null || filters == null)
{
return 0f;
}
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, null);
list.RemoveAll((AIVirtualCard c) => c.IsAmulet);
if (!list.IsNotNullOrEmpty())
{
return 0f;
}
AIFunctionResultContainer funcResultContainer = field.AI.FuncResultContainer;
ulong hash = AIFunctionResultHashCalculator.GetHash(tagOwner, field, playPtn, null, GetArgumentHash(list, damage, damageCount));
if (funcResultContainer.GetContainsResultValue(AIScriptTokenFuncType.EVAL_ALL_MULTI_DAMAGE, hash, out var getResult))
{
return getResult;
}
float result = CalculateMultiAllDamage(tagOwner, list, field, playPtn, situation, damage, damageCount);
funcResultContainer.AddRecord(AIScriptTokenFuncType.EVAL_ALL_MULTI_DAMAGE, hash, result);
return result;
}
private static float CalculateMultiAllDamage(AIVirtualCard tagOwner, List<AIVirtualCard> targetList, AIVirtualField field, List<int> playPtn, AISituationInfo situation, int damage, int damageCount)
{
float num = 0f;
List<AIVirtualCardStatusInfo> list = new List<AIVirtualCardStatusInfo>();
List<AIVirtualCardStatusInfo> list2 = new List<AIVirtualCardStatusInfo>();
int damageAmount = field.DamageModifierCollection.CalcModifiedDamage(field, playPtn, situation, tagOwner, damage);
bool isSpell = tagOwner.IsSpell;
for (int i = 0; i < targetList.Count; i++)
{
AIVirtualCard aIVirtualCard = targetList[i];
int num2 = aIVirtualCard.Life;
AIBarrierPseudoSimulationInfo aIBarrierPseudoSimulationInfo = new AIBarrierPseudoSimulationInfo(aIVirtualCard);
for (int j = 0; j < damageCount; j++)
{
int num3 = aIBarrierPseudoSimulationInfo.SimulateDamageAmount(aIVirtualCard.SimulateDamageShield(damageAmount, isSkillDamage: true, isSpell), isSpell);
num2 -= num3;
if (num2 <= 0)
{
break;
}
aIBarrierPseudoSimulationInfo.DepriveBarrier(AIBarrierStopTiming.AfterDamage);
}
if (aIVirtualCard.IsLeader)
{
num += AILeaderLifeEvaluationUtility.Evaluate(num2, aIVirtualCard.Life, aIVirtualCard.IsAlly, tagOwner.IsAlly);
}
else if (num2 <= 0)
{
float num4 = aIVirtualCard.EvaluateValueOnField(playPtn, situation, useStyle: true) - aIVirtualCard.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) - aIVirtualCard.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false);
num += num4 * (aIVirtualCard.IsAlly ? (-1f) : 1f);
}
else if (!aIVirtualCard.IsAlly || aIVirtualCard.IsAttackable(playPtn))
{
(aIVirtualCard.IsAlly ? list : list2).Add(new AIVirtualCardStatusInfo(aIVirtualCard, aIVirtualCard.Attack, num2));
}
}
if (list2.Count > 0 && list.Count > 0)
{
num += AISimulationUtility.EvaluateAttackValueAfterAllSkill(field, situation, list, list2, playPtn);
}
return num;
}
public static void DamageAll(List<AIVirtualCard> targets, AIVirtualCard damageOwner, AIVirtualField field, int damage, AISituationInfo situation)
{
int baseDamage = field.DamageModifierCollection.CalcModifiedDamage(field, field.BestPlayPtn, situation, damageOwner, damage);
for (int i = 0; i < targets.Count; i++)
{
if ((targets[i].IsUnit || targets[i].IsLeader) && !targets[i].IsDead && !targets[i].IsIndependent)
{
targets[i].AddDamage(situation, baseDamage, isSkillDamage: true);
if (targets[i].IsLeader && targets[i].IsAlly)
{
field.AllyDamageCountInGame++;
field.AllyDamageCountInTurn++;
}
}
}
for (int j = 0; j < targets.Count; j++)
{
if (targets[j].IsDead)
{
targets[j].RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: false);
}
}
}
public static void DamageRandom(List<AIVirtualCard> targets, AIVirtualCard damageOwner, AIVirtualField field, int damage, AISituationInfo situation)
{
List<int> bestPlayPtn = field.BestPlayPtn;
AIVirtualCard aIVirtualCard = SelectDamageTarget(targets, field, bestPlayPtn, situation, damage, damageOwner.IsSpell, AISelectTargetPattern.Worst);
if (aIVirtualCard != null && !aIVirtualCard.IsDead)
{
int baseDamage = field.DamageModifierCollection.CalcModifiedDamage(field, bestPlayPtn, situation, damageOwner, damage);
aIVirtualCard.AddDamage(situation, baseDamage, isSkillDamage: true);
if (aIVirtualCard.IsDead)
{
aIVirtualCard.RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: false);
}
}
}
public static void DamageTarget(AISituationInfo situation, List<AIVirtualCard> candidates, AIVirtualCard damageOwner, AIVirtualField field, AIScriptTokenArgType whichTarget, int damage, int count)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
AIConsoleUtility.LogError("DamageTarget error!! No target!!!!!");
return;
}
int baseDamage = field.DamageModifierCollection.CalcModifiedDamage(field, field.BestPlayPtn, situation, damageOwner, damage);
List<AIVirtualCard> targets = situationTarget.Targets;
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
bool flag = candidates.Contains(aIVirtualCard);
for (int j = 0; j < count; j++)
{
if (aIVirtualCard.Life <= 0)
{
break;
}
if (flag)
{
aIVirtualCard.AddDamage(situation, baseDamage, isSkillDamage: true);
}
}
}
for (int k = 0; k < targets.Count; k++)
{
if (targets[k].IsDead)
{
targets[k].RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: false);
}
}
}
public static void ExecuteTargetSelectDamage(AIVirtualCard tagOwner, List<AIVirtualCard> candidates, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AIScriptTokenArgType selectType, int damageAmount, int selectCount = 1)
{
if (situation == null)
{
AIConsoleUtility.LogError("ExecuteTargetSelectDamage() Error!! situation is null!!!!!");
}
else if (situation.IsTargetExists(selectType))
{
DamageTarget(situation, candidates, tagOwner, field, selectType, damageAmount, selectCount);
}
else
{
DamageTargetPrediction(situation, candidates, tagOwner, field, playPtn, selectType, damageAmount, selectCount);
}
}
private static void DamageTargetPrediction(AISituationInfo situation, List<AIVirtualCard> candidates, AIVirtualCard damageOwner, AIVirtualField field, List<int> playPtn, AIScriptTokenArgType whichTarget, int damage, int count)
{
if (count > 0)
{
List<AIVirtualCard> candidates2 = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(candidates, damageOwner, playPtn);
if (count == 1)
{
AIVirtualCard target = SelectDamageTarget(candidates2, field, playPtn, situation, damage, damageOwner.IsSpell, AISelectTargetPattern.Best);
situation.SetSingleTargetInInfo(target, TargetSelectType.Default, whichTarget);
DamageTarget(situation, candidates2, damageOwner, field, whichTarget, damage, count);
}
else
{
AIConsoleUtility.LogError("DamageTargetPrediction(): 複数選択ダメージのPrediction未対応");
}
}
}
public static void DamageRandomMultiSelect(List<AIVirtualCard> targets, AIVirtualCard owner, AIVirtualField field, int damage, int selectCount, AISituationInfo situation)
{
List<AIVirtualCard> list = null;
List<int> bestPlayPtn = field.BestPlayPtn;
for (int i = 0; i < selectCount; i++)
{
AIVirtualCard aIVirtualCard = SelectDamageTarget(targets, field, bestPlayPtn, situation, damage, owner.IsSpell, AISelectTargetPattern.Worst);
if (aIVirtualCard == null || aIVirtualCard.IsDead)
{
break;
}
int baseDamage = field.DamageModifierCollection.CalcModifiedDamage(field, bestPlayPtn, situation, owner, damage);
aIVirtualCard.AddDamage(situation, baseDamage, isSkillDamage: true);
targets.Remove(aIVirtualCard);
if (targets.Count <= 0)
{
break;
}
if (aIVirtualCard.IsDead)
{
list = AIParamQuery.AddElementToList(aIVirtualCard, list);
}
}
if (list != null)
{
for (int j = 0; j < list.Count; j++)
{
list[j].RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: false);
}
}
}
public static void DamageOldOrderedTargets(List<AIVirtualCard> targets, int damage, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (targets == null || targets.Count <= 0)
{
return;
}
int num = field.DamageModifierCollection.CalcModifiedDamage(field, playPtn, situation, tagOwner, damage);
AIVirtualCard aIVirtualCard = null;
List<AIVirtualCard> list = null;
for (int i = 0; i < targets.Count; i++)
{
if (num <= 0)
{
break;
}
AIVirtualCard aIVirtualCard2 = targets[i];
if (aIVirtualCard2.IsAlly != tagOwner.IsAlly && aIVirtualCard2.IsLeader)
{
aIVirtualCard = aIVirtualCard2;
continue;
}
int num2 = 0;
num2 = ((aIVirtualCard != null || i != targets.Count - 1) ? Math.Min(aIVirtualCard2.Life, num) : num);
num -= num2;
aIVirtualCard2.AddDamage(situation, num2, isSkillDamage: true);
if (aIVirtualCard2.IsDead)
{
list = AIParamQuery.AddElementToList(aIVirtualCard2, list);
}
}
if (aIVirtualCard != null && num > 0)
{
aIVirtualCard.AddDamage(situation, num, isSkillDamage: true);
if (aIVirtualCard.IsDead)
{
return;
}
}
if (list != null)
{
for (int j = 0; j < list.Count; j++)
{
list[j].RemoveCard(situation, AIRemovalType.Destroy, isFromSkill: true);
}
}
}
private static ulong GetArgumentHash(List<AIVirtualCard> targets, int damage, int damageCount)
{
ulong[] array = new ulong[12]
{
907uL, 911uL, 919uL, 929uL, 937uL, 941uL, 947uL, 953uL, 967uL, 971uL,
977uL, 983uL
};
ulong num = 0uL;
for (int i = 0; i < targets.Count; i++)
{
num += targets[i].GetHash() * array[i];
}
num += (ulong)((long)damage * 3L);
return num + (ulong)((long)damageCount * 313L);
}
}

View File

@@ -0,0 +1,21 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIDeckSimulationUtility
{
public static List<AIVirtualCard> GetFilteredDeck(List<AIScriptTokenBase> filter, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(tagOwner.IsAlly ? field.AI.AllyDeckCards : field.AI.EnemyDeckCards, filter, tagOwner, playPtn, situation);
if (list == null)
{
list = new List<AIVirtualCard>();
}
List<AIVirtualCard> list2 = AIFilteringUtility.MultipleFiltering(field.DummyDeckContainer.GetDeck(tagOwner.IsAlly), filter, tagOwner, playPtn, situation);
if (list2 != null)
{
list.AddRange(list2);
}
return list;
}
}

View File

@@ -0,0 +1,30 @@
using System.Collections.Generic;
using UnityEngine;
namespace Wizard;
public class AIDefaultSelectLogicArgument : AISelectLogicArgumentBase
{
public override AIScriptTokenArgType LogicType => AIScriptTokenArgType.DEFAULT_LOGIC;
public AIDefaultSelectLogicArgument(List<string> args)
: base(args)
{
}
public override AIVirtualCard SelectSingleTarget(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
return candidates[0];
}
public override List<AIVirtualCard> SelectMultipleSelectedTargets(List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
int num = Mathf.Min(candidates.Count, selectCount);
List<AIVirtualCard> list = new List<AIVirtualCard>();
for (int i = 0; i < num; i++)
{
list.Add(candidates[i]);
}
return list;
}
}

View File

@@ -0,0 +1,23 @@
using System.Collections.Generic;
namespace Wizard;
public class AIDestroySelectLogicArgument : AISelectLogicArgumentBase
{
public override AIScriptTokenArgType LogicType => AIScriptTokenArgType.DESTROY_LOGIC;
public AIDestroySelectLogicArgument(List<string> args)
: base(args)
{
}
public override AIVirtualCard SelectSingleTarget(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
return AISimulationRemovalUtility.SelectRemovalTarget(candidates, tagOwner, field, playPtn, situation, worstOrBest, AIRemovalType.Destroy);
}
public override List<AIVirtualCard> SelectMultipleSelectedTargets(List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
return AISimulationRemovalUtility.SelectMultipleRemovalTargets(candidates, tagOwner, field, playPtn, situation, worstOrBest, AIRemovalType.Destroy, selectCount);
}
}

View File

@@ -0,0 +1,343 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public static class AIDestroySimulationUtility
{
public static float CalcEvalDestroy(AIVirtualCard card, List<int> playPtn, AISituationInfo situation, bool useIgnoreBreak)
{
return (card.EvaluateValueOnField(playPtn, situation, useStyle: true, doesUseLostLife: true, useOthersTag: true, useIgnoreBreak) - card.GetAllBreakBonus(playPtn, useIgnoreBreak) - card.GetAllLeaveBonus(playPtn, useIgnoreBreak)) * (card.IsAlly ? (-1f) : 1f);
}
public static float EvalTargetingDestroy(List<AIScriptTokenBase> filters, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(tagOwner.SelfField.CardListSet.BothInplayCards, filters, tagOwner, playPtn, situation);
if (list == null || list.Count <= 0)
{
return 0f;
}
list = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(list, tagOwner, playPtn);
int num = 0;
float num2 = float.MinValue;
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (aIVirtualCard.IsAlly == tagOwner.IsAlly || (!aIVirtualCard.IsUntouchable && !aIVirtualCard.IsSneak))
{
num++;
float num3 = 0f;
if (!aIVirtualCard.IsIndependent && !aIVirtualCard.IsIndestructible)
{
num3 = CalcEvalDestroy(aIVirtualCard, playPtn, situation, useIgnoreBreak: false);
}
if (num3 > num2)
{
num2 = num3;
}
}
}
if (num == 0)
{
num2 = 0f;
}
return num2;
}
public static float EvalTargetingOtherDestroy(List<AIScriptTokenBase> target_filters, List<AIScriptTokenBase> destroy_filters, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, int select_count)
{
AIVirtualField selfField = tagOwner.SelfField;
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(selfField.CardListSet.BothInplayCards, target_filters, tagOwner, playPtn, situation);
if (list == null || list.Count <= 0)
{
return 0f;
}
List<AIVirtualCard> list2 = null;
List<float> list3 = new List<float>();
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (aIVirtualCard.IsUntouchable || aIVirtualCard.IsSneak)
{
if (list2 == null)
{
list2 = new List<AIVirtualCard>();
}
list2.Add(aIVirtualCard);
bool flag = AIFilteringUtility.CheckMatchTargetFiltering(aIVirtualCard, selfField.AllyHandCards, destroy_filters, playPtn, tagOwner, situation);
if (aIVirtualCard.IsIndependent || aIVirtualCard.IsIndestructible || !flag)
{
list3.Add(0f);
continue;
}
float item = CalcEvalDestroy(aIVirtualCard, playPtn, situation, useIgnoreBreak: false);
list3.Add(item);
}
}
if (list2 != null && list.Count - list2.Count < select_count)
{
return 0f;
}
List<AIVirtualCard> list4 = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(list, tagOwner, playPtn);
List<float> list5 = null;
for (int j = 0; j < list4.Count; j++)
{
if (list5 == null)
{
list5 = new List<float>();
}
AIVirtualCard aIVirtualCard2 = list4[j];
bool flag2 = AIFilteringUtility.CheckMatchTargetFiltering(aIVirtualCard2, selfField.AllyHandCards, destroy_filters, playPtn, tagOwner, situation);
if (aIVirtualCard2.IsIndependent || aIVirtualCard2.IsIndestructible || !flag2)
{
list5.Add(0f);
continue;
}
float item2 = CalcEvalDestroy(aIVirtualCard2, playPtn, situation, useIgnoreBreak: false);
list5.Add(item2);
}
list5?.Sort((float score0, float score1) => (int)(score1 - score0));
List<AIVirtualCard> list6 = new List<AIVirtualCard>();
for (int num = 0; num < list.Count; num++)
{
int num2 = 0;
for (num2 = 0; num2 < list4.Count; num2++)
{
if (list[num].Equals(list4[num2]))
{
num2 = 99999999;
break;
}
}
int num3 = 0;
num3 = 0;
while (list2 != null && num3 < list2.Count)
{
if (list[num].Equals(list2[num3]))
{
num3 = 99999999;
break;
}
num3++;
}
if (num2 != 99999999 && num3 != 99999999)
{
list6.Add(list[num]);
}
}
List<float> list7 = null;
if (list6.Count > 0)
{
list7 = new List<float>();
for (int num4 = 0; num4 < list6.Count; num4++)
{
AIVirtualCard aIVirtualCard3 = list6[num4];
bool flag3 = AIFilteringUtility.CheckMatchTargetFiltering(aIVirtualCard3, selfField.AllyHandCards, destroy_filters, playPtn, tagOwner, situation);
if (aIVirtualCard3.IsIndependent || aIVirtualCard3.IsIndestructible || !flag3)
{
list7.Add(0f);
continue;
}
float item3 = CalcEvalDestroy(aIVirtualCard3, playPtn, situation, useIgnoreBreak: false);
list7.Add(item3);
}
list7.Sort((float score0, float score1) => (int)(score1 - score0));
}
List<float> list8 = new List<float>();
if (list3 != null)
{
list8.AddRange(list3);
}
if (list7 != null)
{
list8.AddRange(list7);
}
if (list5 != null)
{
list8.AddRange(list5);
}
int num5 = list.Count - select_count;
if (num5 >= list8.Count)
{
return 0f;
}
float num6 = 0f;
for (int num7 = 0; num7 < num5; num7++)
{
num6 += list8[num7];
}
return num6;
}
public static float EvalTargetingMultiDestroy(List<AIScriptTokenBase> filter, int selectableCount, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
{
float num = 0f;
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(tagOwner.SelfField.CardListSet.BothInplayCards, filter, tagOwner, playPtn, situation);
if (list == null || list.Count <= 0)
{
return 0f;
}
list.RemoveAll((AIVirtualCard c) => c.IsAlly != tagOwner.IsAlly && (c.IsUntouchable || c.IsSneak));
if (list.Count <= selectableCount)
{
for (int num2 = 0; num2 < list.Count; num2++)
{
AIVirtualCard aIVirtualCard = list[num2];
if (!aIVirtualCard.IsIndependent && !aIVirtualCard.IsIndestructible)
{
float num3 = CalcEvalDestroy(aIVirtualCard, playPtn, situation, useIgnoreBreak: false);
num += num3;
}
}
return num;
}
List<AIVirtualCard> list2 = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(list, tagOwner, playPtn);
if (list2.Count <= selectableCount)
{
for (int num4 = 0; num4 < list2.Count; num4++)
{
AIVirtualCard aIVirtualCard2 = list2[num4];
num += CalcEvalDestroy(aIVirtualCard2, playPtn, situation, useIgnoreBreak: false);
list.Remove(aIVirtualCard2);
selectableCount--;
if (selectableCount <= 0)
{
return num;
}
}
}
else
{
list = list2;
}
Dictionary<AIVirtualCard, float> dictionary = new Dictionary<AIVirtualCard, float>();
for (int num5 = 0; num5 < list.Count; num5++)
{
AIVirtualCard aIVirtualCard3 = list[num5];
dictionary.Add(aIVirtualCard3, CalcEvalDestroy(aIVirtualCard3, playPtn, situation, useIgnoreBreak: false));
}
for (int num6 = 0; num6 < selectableCount; num6++)
{
float num7 = float.MinValue;
AIVirtualCard aIVirtualCard4 = null;
for (int num8 = 0; num8 < list.Count; num8++)
{
AIVirtualCard aIVirtualCard5 = list[num8];
float num9 = dictionary[aIVirtualCard5];
if (num9 > num7)
{
num7 = num9;
aIVirtualCard4 = aIVirtualCard5;
}
}
num += num7;
if (aIVirtualCard4 != null)
{
list.Remove(aIVirtualCard4);
dictionary.Remove(aIVirtualCard4);
}
}
return num;
}
public static float EvalAllDestroy(List<AIScriptTokenBase> argList, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(tagOwner.SelfField.CardListSet.BothInplayCards, argList, tagOwner, playPtn, situation);
if (list == null || list.Count == 0)
{
return 0f;
}
float num = 0f;
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (!aIVirtualCard.IsIndependent && !aIVirtualCard.IsIndestructible)
{
float num2 = CalcEvalDestroy(aIVirtualCard, playPtn, situation, useIgnoreBreak: false);
num += num2;
}
}
return num;
}
public static float EvalRandomDestroy(List<AIScriptTokenBase> argList, int count, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
{
AIVirtualField selfField = tagOwner.SelfField;
if (count == 0)
{
return 0f;
}
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(selfField.CardListSet.BothInplayCards, argList, tagOwner, playPtn, situation);
if (list == null || list.Count == 0)
{
return 0f;
}
float num = 0f;
if (list.Count <= count)
{
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (!aIVirtualCard.IsIndependent && !aIVirtualCard.IsIndestructible)
{
float num2 = CalcEvalDestroy(aIVirtualCard, playPtn, situation, useIgnoreBreak: false);
num += num2;
}
}
return num;
}
List<int> list2 = new List<int>();
for (int j = 0; j < list.Count; j++)
{
list2.Add(j);
}
List<int[]> list3 = AIMathematicsLibrary.EnumerateCombinations(list2, count).ToList();
for (int k = 0; k < list3.Count; k++)
{
int[] array = list3[k];
for (int l = 0; l < array.Length; l++)
{
AIVirtualCard aIVirtualCard2 = list[array[l]];
if (!aIVirtualCard2.IsIndependent && !aIVirtualCard2.IsIndestructible)
{
float num3 = CalcEvalDestroy(aIVirtualCard2, playPtn, situation, useIgnoreBreak: false);
num += num3;
}
}
}
return num / (float)list3.Count;
}
public static void ExecuteTargetSelectDestroy(AIVirtualCard owner, List<AIVirtualCard> targets, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AIScriptTokenArgType selectType, int selectCount = 1)
{
if (situation == null)
{
AIConsoleUtility.LogError("ExecuteTargetSelectDestroy() Error!! situation is null!!!!!");
}
else if (situation.IsTargetExists(selectType))
{
AISkillSimulationUtility.DestroyTarget(situation, targets, selectType);
}
else
{
DestroyTargetPrediction(owner, targets, field, playPtn, situation, selectCount, selectType);
}
}
private static void DestroyTargetPrediction(AIVirtualCard tagOwner, List<AIVirtualCard> candidates, AIVirtualField field, List<int> playPtn, AISituationInfo situation, int selectCount, AIScriptTokenArgType whichTarget)
{
AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(candidates, tagOwner, playPtn);
if (selectCount <= 1)
{
AIVirtualCard target = AISimulationRemovalUtility.SelectRemovalTarget(candidates, tagOwner, field, playPtn, situation, AISelectTargetPattern.Best, AIRemovalType.Destroy);
situation.SetSingleTargetInInfo(target, TargetSelectType.Default, whichTarget);
AISkillSimulationUtility.DestroyTarget(situation, candidates, whichTarget);
}
else
{
List<AIVirtualCard> targets = AISimulationRemovalUtility.SelectMultipleRemovalTargets(candidates, tagOwner, field, playPtn, situation, AISelectTargetPattern.Best, AIRemovalType.Destroy, selectCount);
situation.SetMultipleTargetsInInfo(targets, TargetSelectType.Default, AIRemovalType.Destroy, whichTarget);
AISkillSimulationUtility.DestroyTarget(situation, candidates, whichTarget);
}
}
}

View File

@@ -0,0 +1,52 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIDrawCountUtility
{
public static int GetDrawCount(AIVirtualCard owner, AIVirtualField field, List<int> playPtn, AIScriptTokenArgType period, AIScriptTokenArgType range)
{
int num = 0;
switch (range)
{
case AIScriptTokenArgType.PLAYPTN:
return num + GetDrawCountOfPlayptn(owner, field, playPtn);
case AIScriptTokenArgType.PLAYED:
return num + GetDrawCountOfPlayed(period, field);
default:
num += GetDrawCountOfPlayptn(owner, field, playPtn);
return num + GetDrawCountOfPlayed(period, field);
}
}
private static int GetDrawCountOfPlayptn(AIVirtualCard owner, AIVirtualField field, List<int> playPtn)
{
if (playPtn == null || playPtn.Count <= 0)
{
return 0;
}
AISinglePlayptnRecord playptnRecordOnSim = field.GetPlayptnRecordOnSim(playPtn);
if (playptnRecordOnSim == null)
{
return 0;
}
int num = 0;
List<PlayedCardInfo> playedCardList = playptnRecordOnSim.PlayedCardList;
for (int i = 0; i < playedCardList.Count && !playedCardList[i].Card.IsSameCard(owner); i++)
{
num += playedCardList[i].DrawCount;
}
return num;
}
private static int GetDrawCountOfPlayed(AIScriptTokenArgType period, AIVirtualField field)
{
int virtualDrawCount = field.VirtualDrawCount;
return period switch
{
AIScriptTokenArgType.TURN => virtualDrawCount + field.TurnDrawCount,
AIScriptTokenArgType.GAME => virtualDrawCount + field.GameDrawCount,
_ => 0,
};
}
}

View File

@@ -0,0 +1,48 @@
namespace Wizard;
public class AIEmoteCtrlNull : IAIEmoteCtrl
{
public void SetUpEmoteEvent(BattlePlayerBase self, BattlePlayerBase opponent, OperateMgr operateManager)
{
}
public AIEmoteCmd OnOpponentEmotion(ClassCharaPrm.EmotionType emoteType)
{
return null;
}
public AIEmoteCmd OnAllyTurnStart(AISituationInfo situation)
{
return null;
}
public AIEmoteCmd OnAllyTurnEnd()
{
return null;
}
public AIEmoteCmd OnOpponentTurnStart(AISituationInfo situation)
{
return null;
}
public AIEmoteCmd OnOpponentTurnEnd()
{
return null;
}
public AIEmoteCmd OnCardPlay(AISituationInfo situation)
{
return null;
}
public AIEmoteCmd OnCardDestroy(AISituationInfo situation)
{
return null;
}
public AIEmoteCmd OnAllyEvolution(AISituationInfo situation)
{
return null;
}
}

View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
namespace Wizard;
internal class AIEnemyHandTagCollectionContainer : AITagCollectionContainer
{
private readonly AIPlayTagType[] ENEMY_HAND_LEGAL_TAG_TYPES = new AIPlayTagType[19]
{
AIPlayTagType.TurnEndAttachTag,
AIPlayTagType.Enhance,
AIPlayTagType.Accelerate,
AIPlayTagType.Crystalize,
AIPlayTagType.ChoiceTransform,
AIPlayTagType.GenerateTag,
AIPlayTagType.PlayCopyTag,
AIPlayTagType.FanfareCopyTag,
AIPlayTagType.PlayAttachTag,
AIPlayTagType.FanfareAttachTag,
AIPlayTagType.PlaySelect,
AIPlayTagType.FanfareSelect,
AIPlayTagType.PlayHandSelect,
AIPlayTagType.FanfareHandSelect,
AIPlayTagType.FanfareAttachStyle,
AIPlayTagType.PlayReanimate,
AIPlayTagType.FanfareReanimate,
AIPlayTagType.PlayRemoveSkill,
AIPlayTagType.FanfareRemoveSkill
};
public AIEnemyHandTagCollectionContainer()
{
}
public AIEnemyHandTagCollectionContainer(AITagCollectionContainer container, AIVirtualCard owner)
{
if (container.Count <= 0)
{
return;
}
_holdingTagTypes = new List<AIPlayTagType>();
_holdingTagCollectionTypes = new List<TagCollectionType>();
base.TagDictionary = new List<TagCollectionWithTypeBase>();
for (int i = 0; i < container.Count; i++)
{
TagCollectionWithTypeBase tagCollectionWithTypeBase = container.TagDictionary[i];
if (IsEnemyHandLegalTagCollection(tagCollectionWithTypeBase))
{
base.TagDictionary.Add(tagCollectionWithTypeBase.Clone());
tagCollectionWithTypeBase.RegisterTypes(_holdingTagTypes);
_holdingTagCollectionTypes.Add(tagCollectionWithTypeBase.Collection.Type);
}
}
CreateFixedUseCostListWhenInit(owner, owner.SelfField);
}
public override void InitTags(AIVirtualCard owner, AIParamQuery query)
{
int tagCount = query.GetTagCount(owner);
for (int i = 0; i < tagCount; i++)
{
AIPlayTag tag = query.GetTag(owner, i);
if (Array.IndexOf(ENEMY_HAND_LEGAL_TAG_TYPES, tag.Type) >= 0)
{
AddTag(tag, owner, null);
}
}
CreateFixedUseCostListWhenInit(owner, owner.SelfField);
}
private bool IsEnemyHandLegalTagCollection(TagCollectionWithTypeBase tagCollectionWithTypes)
{
for (int i = 0; i < ENEMY_HAND_LEGAL_TAG_TYPES.Length; i++)
{
if (tagCollectionWithTypes.IsUnderManagement(ENEMY_HAND_LEGAL_TAG_TYPES[i]))
{
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,50 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIEnhanceUtility
{
public static bool IsEnhanced(AIVirtualCard card, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (card == null || card.EnhanceCostList == null)
{
return false;
}
AIVariableResultContainer valResultContainer = field.AI.ValResultContainer;
ulong hash = AIFunctionResultHashCalculator.GetHash(card, field, playPtn, null, 0uL);
if (valResultContainer.GetContainsResultValue(AIScriptTokenVariableType.IS_ENHANCED, hash, out var getResult))
{
return getResult == 1f;
}
bool flag = false;
if (card.PlayedCost < 0 && card.IsInHand)
{
List<int> playPtn2 = (card.IsAlly ? playPtn : null);
flag = field.AI.PlayPtnRecorder.IsCardPlayingSimulationType(card, field, playPtn2, situation, PlaySimulationType.Enhance);
}
else
{
flag = card.PlayedCost >= 0 && card.EnhanceCostList.Contains(card.PlayedCost);
}
valResultContainer.CheckDuplicateAndAddRecord(AIScriptTokenVariableType.IS_ENHANCED, hash, flag ? 1f : 0f, $"IsEnhanced(): Already hashed target and not equal value. CardName:[{card.CardName}] hash:[{hash}]");
return flag;
}
public static int GetEnhanceCost(AIVirtualCard card, AIVirtualField field, List<int> playPtn)
{
if (card == null || card.EnhanceCostList == null)
{
return -1;
}
if (card.PlayedCost >= 0)
{
if (card.EnhanceCostList.Contains(card.PlayedCost))
{
return card.PlayedCost;
}
return -1;
}
List<int> playPtn2 = (card.IsAlly ? playPtn : null);
return field.AI.PlayPtnRecorder.GetCardPlaySimulationTypeCost(card, field, playPtn2, null, PlaySimulationType.Enhance);
}
}

View File

@@ -0,0 +1,149 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIEvalAttackRemoveUtility
{
private const int REMOVE_TYPE_INDEX = 1;
private const int REMOVE_COUNT_INDEX = 0;
public static float EvalAttackRemove(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> argList)
{
List<AIVirtualCard> list = (tagOwner.IsAlly ? field.EnemyInplayCards : field.AllyInplayCards);
if (list.Count <= 0)
{
return 0f;
}
List<AIVirtualCard> list2 = null;
List<AIVirtualCard> list3 = null;
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (aIVirtualCard.IsUnit && !aIVirtualCard.IsCantUnderAnyAttack())
{
if (aIVirtualCard.IsGuard)
{
list2 = AIParamQuery.AddElementToList(aIVirtualCard, list2);
}
else
{
list3 = AIParamQuery.AddElementToList(aIVirtualCard, list3);
}
}
}
int num = list2?.Count ?? 0;
int num2 = list3?.Count ?? 0;
if (num + num2 <= 0)
{
return 0f;
}
int removeCount = (int)argList[0].Value;
AIScriptTokenArgType removeType = GetRemoveType(argList[1]);
List<AIVirtualCard> replacedTargetSideInplayCardList = new List<AIVirtualCard>(list);
return CalculateAttackRemoveValue(tagOwner, field, playPtn, removeCount, removeType, list2, list3, replacedTargetSideInplayCardList);
}
private static float CalculateAttackRemoveValue(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, int removeCount, AIScriptTokenArgType removeType, List<AIVirtualCard> guardList, List<AIVirtualCard> nonGuardList, List<AIVirtualCard> replacedTargetSideInplayCardList)
{
AIVirtualCard sourceCard = AIInstantAttackUtility.CreateDummyAttacker(field, tagOwner, 1, 1, 1, isEvalRush: true);
Dictionary<int, (float, bool)> dictionary = null;
if (removeCount > 1)
{
dictionary = new Dictionary<int, (float, bool)>();
}
float num = 0f;
for (int i = 0; i < removeCount; i++)
{
List<AIVirtualCard> list = ((guardList == null || guardList.Count <= 0) ? nonGuardList : guardList);
if (list == null)
{
break;
}
float num2 = float.MinValue;
AIVirtualCard aIVirtualCard = null;
bool flag = false;
for (int j = 0; j < list.Count; j++)
{
AIVirtualCard aIVirtualCard2 = list[j];
AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(sourceCard, aIVirtualCard2);
bool isRemoved = false;
if (!AIAttackSimulationUtility.IsAttackPossible(field, aIVirtualAttackInfo, replacedTargetSideInplayCardList))
{
continue;
}
float num3;
if (removeCount > 1 && dictionary.ContainsKey(aIVirtualCard2.CardIndex))
{
(num3, isRemoved) = dictionary[aIVirtualCard2.CardIndex];
}
else
{
num3 = CalculateSingleRemoveValue(aIVirtualAttackInfo, field, playPtn, removeType, ref isRemoved);
if (removeCount > 1)
{
dictionary.Add(aIVirtualCard2.CardIndex, (num3, isRemoved));
}
}
if (num3 > num2)
{
num2 = num3;
aIVirtualCard = aIVirtualCard2;
flag = isRemoved;
}
}
if (aIVirtualCard == null)
{
break;
}
num += num2;
if (flag)
{
list.Remove(aIVirtualCard);
replacedTargetSideInplayCardList.Remove(aIVirtualCard);
if (removeCount > 1)
{
dictionary.Remove(aIVirtualCard.CardIndex);
}
}
}
AIInstantAttackUtility.RemoveDummyCardFromField(field);
return num;
}
private static float CalculateSingleRemoveValue(AIVirtualAttackInfo situation, AIVirtualField field, List<int> playPtn, AIScriptTokenArgType removeType, ref bool isRemoved)
{
AIVirtualCard attackTarget = situation.AttackTarget;
isRemoved = true;
AIRemovalType removeType2;
switch (removeType)
{
case AIScriptTokenArgType.DESTROY:
removeType2 = AIRemovalType.Destroy;
isRemoved = !attackTarget.IsIndependent && !attackTarget.IsIndestructible;
break;
case AIScriptTokenArgType.BANISH:
removeType2 = AIRemovalType.Banish;
isRemoved = !attackTarget.IsIndependent && !attackTarget.IsUnbanishable;
break;
default:
AIConsoleUtility.LogError("AIEvalAttackRemoveUtility.CalculateSingleRemoveValue() error!! Not implemented removeType = " + removeType);
isRemoved = false;
return 0f;
}
if (isRemoved)
{
return AISimulationRemovalUtility.CalculateRemovalValue(attackTarget, field, playPtn, situation, removeType2, null);
}
return 0f;
}
private static AIScriptTokenArgType GetRemoveType(AIScriptTokenBase token)
{
if (token is AIScriptArgumentToken aIScriptArgumentToken)
{
return aIScriptArgumentToken.ArgumentType;
}
return AIScriptTokenArgType.NONE;
}
}

View File

@@ -0,0 +1,73 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIEvalReanimateUtility
{
private const int SIDE_INDEX = 0;
private const int REANIMATE_COST_INDEX = 1;
public static float EvalReanimate(AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> argList)
{
if (argList.Count < 2)
{
AIConsoleUtility.LogError("EVAL_REANIMATE error!!! argList count = " + argList.Count);
return 0f;
}
argList.Reverse();
if (!TryGetIsSummonToAllySide(argList[0], out var isSummonToAllySide))
{
return 0f;
}
int reanimateCost = (int)argList[1].Value;
argList.RemoveRange(0, 2);
return EvalReanimate(tagOwner, isSummonToAllySide, reanimateCost, argList, playPtn, situation);
}
private static float EvalReanimate(AIVirtualCard tagOwner, bool isSummonAllyField, int reanimateCost, List<AIScriptTokenBase> filters, List<int> playPtn, AISituationInfo situation)
{
float num = 0f;
AIVirtualField selfField = tagOwner.SelfField;
List<AIVirtualCard> list = (((tagOwner.IsAlly && isSummonAllyField) || (!tagOwner.IsAlly && !isSummonAllyField)) ? selfField.CardListSet.AllyDestroyedCards : selfField.CardListSet.EnemyDestroyedCards);
if (list == null || list.Count <= 0)
{
return 0f;
}
list = AIReanimateSimulationUtility.FilteringReanimateTargets(list, reanimateCost, tagOwner, filters, playPtn, situation);
if (list != null && list.Count > 0)
{
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard target = list[i];
num += EvalReanimateTargetValue(target, selfField, playPtn, situation);
}
num /= (float)list.Count;
}
return num * (isSummonAllyField ? 1f : (-1f));
}
public static float EvalReanimateTargetValue(AIVirtualCard target, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
return ((float)(target.DefaultAttack * target.DefaultMaxAttackableCount) + (float)target.DefaultLife + field.StyleQuery.GetUnitBonus(field, target, playPtn)) * field.StyleQuery.GetUnitRate(field, target, playPtn) * target.EvaluateAllBattleBonusRate(playPtn, useOthersTag: true, useIgnoreInBattle: false, situation) + target.GetFieldBonus(playPtn) + target.GetReanimateBonus(playPtn);
}
private static bool TryGetIsSummonToAllySide(AIScriptTokenBase sideToken, out bool isSummonToAllySide)
{
if (sideToken is AIScriptArgumentToken { ArgumentType: var argumentType })
{
switch (argumentType)
{
case AIScriptTokenArgType.ALLY:
isSummonToAllySide = true;
return true;
case AIScriptTokenArgType.OPPONENT:
isSummonToAllySide = false;
return true;
}
}
AIConsoleUtility.LogError("EVAL_REANIMATE error!!! Argument[0] is not ALLY or ENEMY");
isSummonToAllySide = true;
return false;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,102 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIFusionCountUtility
{
public static int GetFusionCount(AIVirtualCard tagOwner, List<AIScriptTokenBase> argList, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> allFusionIngredientsList = tagOwner.GetAllFusionIngredientsList(situation);
if (allFusionIngredientsList == null || allFusionIngredientsList.Count <= 0)
{
return 0;
}
argList.Reverse();
return AIFilteringUtility.MultipleFiltering(allFusionIngredientsList, argList, tagOwner, playPtn, situation)?.Count ?? 0;
}
public static int GetFusionCountAtOnce(AIVirtualCard tagOwner, List<AIScriptTokenBase> argList, List<int> playPtn, AISituationInfo situation)
{
if (situation == null || !situation.Actor.IsSameCard(tagOwner))
{
return 0;
}
List<AIVirtualCard> list = null;
if (situation is AIFusionSituationInfo || situation is AIVirtualTargetSelectAction { ActionType: AIOperationType.FUSION })
{
if (situation.IsTargetExists(AIScriptTokenArgType.TARGET_SELECT))
{
argList.Reverse();
list = AIFilteringUtility.MultipleFiltering(situation.GetSituationTarget(AIScriptTokenArgType.TARGET_SELECT).Targets, argList, tagOwner, playPtn, situation);
}
}
else
{
AIConsoleUtility.LogError("AIFusionCountUtility.GetFusionCountAtOnce(): Unexpected situation type. Not fusion situation.");
}
return list?.Count ?? 0;
}
public static int GetNowFusionCount(AIVirtualCard tagOwner, List<AIScriptTokenBase> filters, List<int> playPtn)
{
if (tagOwner.FusionIngredients == null)
{
return 0;
}
return AIFilteringUtility.MultipleFiltering(tagOwner.FusionIngredients.CardList, filters, tagOwner, playPtn, null)?.Count ?? 0;
}
public static int GetFusionNameCount(AIVirtualCard tagOwner, List<AIScriptTokenBase> argList, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> allFusionIngredientsList = tagOwner.GetAllFusionIngredientsList(situation);
if (allFusionIngredientsList == null || allFusionIngredientsList.Count <= 0)
{
return 0;
}
argList.Reverse();
return AIFilteringUtility.GetCardNameCountFromList(allFusionIngredientsList, argList, tagOwner, playPtn, situation);
}
public static int GetFusedCardCountInGame(AIVirtualCard tagOwner, List<AIScriptTokenBase> filter, List<int> playPtn, AISituationInfo situation, bool isWithoutSameId)
{
List<AIVirtualCard> list = (tagOwner.IsAlly ? tagOwner.SelfField.AllyGameFusedCards : tagOwner.SelfField.EnemyGameFusedCards);
if (list == null || list.Count <= 0)
{
return 0;
}
List<AIVirtualCard> list2 = AIFilteringUtility.MultipleFiltering(list, filter, tagOwner, playPtn, situation, isBlockDeadCard: false);
if (list2 == null)
{
return 0;
}
int count = list2.Count;
if (isWithoutSameId)
{
HashSet<int> hashSet = new HashSet<int>();
for (int i = 0; i < list2.Count; i++)
{
hashSet.Add(list2[i].BaseId);
}
count = hashSet.Count;
}
return count;
}
private static List<AIVirtualCard> GetAllFusionIngredientsList(this AIVirtualCard card, AISituationInfo situation)
{
List<AIVirtualCard> list = null;
if (card.FusionIngredients != null && card.FusionIngredients.HasFusionIngredients)
{
list = new List<AIVirtualCard>(card.FusionIngredients.CardList);
}
else if (card.BeforeTransformCard != null && card.BeforeTransformCard.FusionIngredients != null && card.BeforeTransformCard.FusionIngredients.HasFusionIngredients)
{
list = new List<AIVirtualCard>(card.BeforeTransformCard.FusionIngredients.CardList);
}
if (situation != null && situation is AIFusionSituationInfo aIFusionSituationInfo && aIFusionSituationInfo.Actor.IsSameCard(card) && aIFusionSituationInfo.IsTargetExists(AIScriptTokenArgType.TARGET_SELECT))
{
list = AIParamQuery.AddRangeToList(aIFusionSituationInfo.GetSituationTarget(AIScriptTokenArgType.TARGET_SELECT).Targets, list);
}
return list;
}
}

View File

@@ -0,0 +1,111 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIGenerateTagUtility
{
private class GenerateTagExecutingInfo
{
public AIVirtualCard Owner;
public AIVirtualCard Target;
public AIAttachedTagInformation AttachedTagInfo;
}
public static void ExecuteGenerateTag(AISituationInfo situation, AIVirtualField field, AIGenerateTagOwnerTable generateTagOwnerTable, AttachedSkillInfoReceiveDataCollection attachedInfoReceiveCollection)
{
List<GenerateTagExecutingInfo> list = CreateGeneratedTagExecutingInfoList(generateTagOwnerTable, attachedInfoReceiveCollection, field, situation);
if (list != null)
{
AttachGenerateTagOnField(list, field, situation);
}
attachedInfoReceiveCollection.Clear();
}
private static List<GenerateTagExecutingInfo> CreateGeneratedTagExecutingInfoList(AIGenerateTagOwnerTable generateTagOwnerTable, AttachedSkillInfoReceiveDataCollection attachedInfoReceiveCollection, AIVirtualField field, AISituationInfo situation)
{
List<GenerateTagExecutingInfo> list = null;
for (int i = 0; i < attachedInfoReceiveCollection.InfoList.Count; i++)
{
List<GenerateTagExecutingInfo> list2 = CreateGenerateTagExecutingInfoFromReceiveData(generateTagOwnerTable, attachedInfoReceiveCollection.InfoList[i], field, situation);
if (list2 != null)
{
list = AIParamQuery.AddRangeToList(list2, list);
}
}
return list;
}
private static List<GenerateTagExecutingInfo> CreateGenerateTagExecutingInfoFromReceiveData(AIGenerateTagOwnerTable generateTagOwnerTable, AttachedSkillInfoReceiveData attachedInfoReceiveData, AIVirtualField field, AISituationInfo situation)
{
List<GenerateTagExecutingInfo> list = null;
AIGenerateTagOwnerTable.GenerateTagOwnerInfo generateTagOwnerInfo = generateTagOwnerTable.GetGenerateTagOwnerInfo(attachedInfoReceiveData.OwnerBaseCardId, attachedInfoReceiveData.OwnerIndex, attachedInfoReceiveData.OwnerIsPlayer);
if (generateTagOwnerInfo == null || generateTagOwnerInfo.GenerateTagList == null)
{
return null;
}
List<AIPlayTag> generateTagList = generateTagOwnerInfo.GenerateTagList;
bool flag = field.AllyBattlePlayer.IsPlayer == generateTagOwnerInfo.OwnerIsPlayer;
AIVirtualCard owner = FindVirtualCard(generateTagOwnerInfo.OwnerCardIndex, flag, field);
for (int i = 0; i < attachedInfoReceiveData.TargetInfoList.Count; i++)
{
AttachedSkillInfoReceiveData.TargetInfo targetInfo = attachedInfoReceiveData.TargetInfoList[i];
bool flag2 = field.AllyBattlePlayer.IsPlayer == targetInfo.TargetIsPlayer;
AIVirtualCard aIVirtualCard = FindVirtualCard(targetInfo.TargetIndex, flag2, field);
if (aIVirtualCard == null)
{
continue;
}
for (int j = 0; j < generateTagList.Count; j++)
{
if (generateTagList[j].ArgumentExpressions is AIGenerateTag aIGenerateTag && aIGenerateTag.CheckMatchedHashList(targetInfo.SkillHashList))
{
list = AIParamQuery.AddElementToList(new GenerateTagExecutingInfo
{
Owner = owner,
Target = aIVirtualCard,
AttachedTagInfo = new AIAttachedTagInformation(aIGenerateTag.Tag, aIGenerateTag.RemoveTiming, generateTagOwnerInfo.OwnerBaseCardId, generateTagOwnerInfo.OwnerCardIndex, flag, targetInfo.TargetIndex, flag2)
}, list);
}
}
}
return list;
}
private static void AttachGenerateTagOnField(List<GenerateTagExecutingInfo> executingInfoList, AIVirtualField field, AISituationInfo situation)
{
if (executingInfoList != null)
{
for (int i = 0; i < executingInfoList.Count; i++)
{
GenerateTagExecutingInfo generateTagExecutingInfo = executingInfoList[i];
AIVirtualCard target = generateTagExecutingInfo.Target;
target.TagCollectionContainer.AttachTag(generateTagExecutingInfo.AttachedTagInfo, target, situation);
}
}
}
private static AIVirtualCard FindVirtualCard(int cardIndex, bool isAlly, AIVirtualField field)
{
AIVirtualCard aIVirtualCard = null;
aIVirtualCard = FindFromList<AIVirtualCard>(field.CardListSet.AllReferableCards);
if (aIVirtualCard != null)
{
return aIVirtualCard;
}
return FindFromList<AIVirtualCard>(field.GetEnemyHandCardList());
AIVirtualCard FindFromList<T>(List<T> _cardList) where T : AIVirtualCard
{
for (int i = 0; i < _cardList.Count; i++)
{
T val = _cardList[i];
if (val.CardIndex == cardIndex && val.IsAlly == isAlly)
{
return val;
}
}
return null;
}
}
}

View File

@@ -0,0 +1,48 @@
namespace Wizard;
public static class AIGetPreprocessInformationUtility
{
public static int GetEarthRiteCount(AIVirtualCard owner, AISituationInfo situation)
{
if (situation == null)
{
return 0;
}
if (situation.PreprocessRecorder == null || !situation.PreprocessRecorder.HasRecord)
{
return 0;
}
int num = 0;
for (int i = 0; i < situation.PreprocessRecorder.RecordList.Count; i++)
{
AISinglePreprocessRecord aISinglePreprocessRecord = situation.PreprocessRecorder.RecordList[i];
if (aISinglePreprocessRecord.RealActor.IsSameCard(owner) || aISinglePreprocessRecord.OriginalCard.IsSameCard(owner))
{
num += aISinglePreprocessRecord.EarthRiteCount;
}
}
return num;
}
public static int GetNecromanceCount(AIVirtualCard owner, AISituationInfo situation)
{
if (situation == null)
{
return 0;
}
if (situation.PreprocessRecorder == null || !situation.PreprocessRecorder.HasRecord)
{
return 0;
}
int num = 0;
for (int i = 0; i < situation.PreprocessRecorder.RecordList.Count; i++)
{
AISinglePreprocessRecord aISinglePreprocessRecord = situation.PreprocessRecorder.RecordList[i];
if (aISinglePreprocessRecord.RealActor.IsSameCard(owner) || aISinglePreprocessRecord.OriginalCard.IsSameCard(owner))
{
num += aISinglePreprocessRecord.NecromanceCount;
}
}
return num;
}
}

View File

@@ -0,0 +1,26 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIGetStatusUtility
{
public static int GetLife(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> filters)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.AllReferableCards, filters, tagOwner, playPtn, situation, isBlockDeadCard: false);
if (list == null || list.Count <= 0)
{
return 0;
}
return list[0].Life;
}
public static int GetAttack(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> filters)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.AllReferableCards, filters, tagOwner, playPtn, situation, isBlockDeadCard: false);
if (list == null || list.Count <= 0)
{
return 0;
}
return list[0].Attack;
}
}

View File

@@ -0,0 +1,143 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIHandBuffSimulationUtility
{
public static void ExecuteHandBuffAll(List<AIVirtualCard> candidates, AIBuffExecutingInfo_old buffInfo, AISituationInfo situation)
{
if (candidates == null || candidates.Count <= 0)
{
return;
}
List<AIVirtualCard> list = new List<AIVirtualCard>();
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
if (aIVirtualCard.IsInHand && aIVirtualCard.IsUnit)
{
aIVirtualCard.GiveBuff(situation, buffInfo, isTemp: false);
list.Add(aIVirtualCard);
}
}
if (list.Count > 0)
{
situation.RegisterLatestTargetList(list);
}
}
public static void ExecuteHandBuffRandom(List<AIVirtualCard> candidates, AIBuffExecutingInfo_old buffInfo, List<int> playPtn, AISituationInfo situation)
{
if (candidates != null && candidates.Count > 0)
{
AIVirtualCard aIVirtualCard = SelectHandBuffTarget(candidates, AISelectTargetPattern.Worst, playPtn, situation);
if (aIVirtualCard != null)
{
aIVirtualCard.GiveBuff(situation, buffInfo, isTemp: false);
situation.RegisterSingleLatestTarget(aIVirtualCard);
}
}
}
public static void ExecuteHandBuffTargetSelect(AIBuffExecutingInfo_old buffInfo, AIScriptTokenArgType whichTarget, AISituationInfo situation)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget != null && situationTarget.HasTarget)
{
ExecuteHandBuffAll(situationTarget.Targets, buffInfo, situation);
}
}
public static void ExecuteHandBuffBestTarget(List<AIVirtualCard> candidates, AIBuffExecutingInfo_old buffInfo, AISituationInfo situation)
{
AIVirtualCard aIVirtualCard = SelectHandBuffTarget(candidates, AISelectTargetPattern.Best, EnemyAI.EmptyPlayPtn, situation);
if (aIVirtualCard != null)
{
aIVirtualCard.GiveBuff(situation, buffInfo, isTemp: false);
situation.RegisterSingleLatestTarget(aIVirtualCard);
}
}
public static AIVirtualCard SelectHandBuffTarget(List<AIVirtualCard> candidates, AISelectTargetPattern worstOrBest, List<int> playPtn, AISituationInfo situation)
{
if (candidates == null || candidates.Count <= 0)
{
return null;
}
float num = 0f;
AIVirtualCard aIVirtualCard = null;
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard2 = candidates[i];
float handBonus = aIVirtualCard2.GetHandBonus(playPtn, situation, isIgnoreInFusion: false);
if (aIVirtualCard == null)
{
aIVirtualCard = aIVirtualCard2;
num = handBonus;
continue;
}
switch (worstOrBest)
{
case AISelectTargetPattern.Best:
if (handBonus > num)
{
num = handBonus;
aIVirtualCard = aIVirtualCard2;
}
else
{
if (handBonus < num)
{
break;
}
if (aIVirtualCard2.Cost < aIVirtualCard.Cost)
{
aIVirtualCard = aIVirtualCard2;
}
else if (aIVirtualCard2.Cost <= aIVirtualCard.Cost)
{
if (aIVirtualCard2.Attack > aIVirtualCard.Attack)
{
aIVirtualCard = aIVirtualCard2;
}
else if (aIVirtualCard2.Attack == aIVirtualCard.Attack && aIVirtualCard2.Life > aIVirtualCard.Life)
{
aIVirtualCard = aIVirtualCard2;
}
}
}
break;
case AISelectTargetPattern.Worst:
if (handBonus < num)
{
num = handBonus;
aIVirtualCard = aIVirtualCard2;
}
else
{
if (handBonus > num)
{
break;
}
if (aIVirtualCard2.Cost > aIVirtualCard.Cost)
{
aIVirtualCard = aIVirtualCard2;
}
else if (aIVirtualCard2.Cost <= aIVirtualCard.Cost)
{
if (aIVirtualCard2.Attack < aIVirtualCard.Attack)
{
aIVirtualCard = aIVirtualCard2;
}
else if (aIVirtualCard2.Attack == aIVirtualCard.Attack && aIVirtualCard2.Life < aIVirtualCard.Life)
{
aIVirtualCard = aIVirtualCard2;
}
}
}
break;
}
}
return aIVirtualCard;
}
}

View File

@@ -0,0 +1,45 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIHandCountUtility
{
public static int GetHandCount(AIVirtualField field, List<AIScriptTokenBase> filters, AIVirtualCard tagOwner, AISituationInfo situation, List<int> playPtn)
{
ReplaceIllegalFilter(filters);
int num = ((!tagOwner.IsAlly) ? AIFilteringUtility.MultipleFiltering(field.GetEnemyHandCardList(), filters, tagOwner, playPtn, situation) : AIFilteringUtility.MultipleFiltering(field.AllyHandCards, filters, tagOwner, playPtn, situation))?.Count ?? 0;
if (filters[0] is AIScriptArgumentToken { ArgumentType: AIScriptTokenArgType.ALL })
{
num += field.VirtualDrawCount;
}
return num;
}
public static int GetHandNameCount(AIVirtualField field, List<AIScriptTokenBase> filters, AIVirtualCard tagOwner, AISituationInfo situation, List<int> playPtn)
{
ReplaceIllegalFilter(filters);
return AIFilteringUtility.GetCardNameCountFromList(tagOwner.IsAlly ? field.AllyHandCards : field.GetEnemyHandCardList(), filters, tagOwner, playPtn, situation);
}
private static void ReplaceIllegalFilter(List<AIScriptTokenBase> filters)
{
for (int i = 0; i < filters.Count; i++)
{
if (filters[i] is AIScriptArgumentToken { ArgumentType: var argumentType } aIScriptArgumentToken)
{
switch (argumentType)
{
case AIScriptTokenArgType.FOLLOWER:
aIScriptArgumentToken.ArgumentType = AIScriptTokenArgType.FOLLOWER_CARD_TYPE;
break;
case AIScriptTokenArgType.BUFFED_FOLLOWER:
aIScriptArgumentToken.ArgumentType = AIScriptTokenArgType.BUFFED_FOLLOWER_CARD_TYPE;
break;
case AIScriptTokenArgType.SPELL:
aIScriptArgumentToken.ArgumentType = AIScriptTokenArgType.SPELL_CARD_TYPE;
break;
}
}
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIHealCountUtility
{
public static int GetHealCount(AIVirtualCard owner, AIVirtualField field, AISituationInfo situation, List<int> playPtn, List<AIScriptTokenBase> argList)
{
if (argList.Count < 2)
{
return 0;
}
AIScriptTokenArgType argumentType = ((AIScriptArgumentToken)argList[0]).ArgumentType;
AIScriptTokenArgType durationType;
AIScriptTokenArgType aIScriptTokenArgType;
if (argumentType == AIScriptTokenArgType.TURN || argumentType == AIScriptTokenArgType.GAME)
{
durationType = argumentType;
aIScriptTokenArgType = AIScriptTokenArgType.NONE;
argList.RemoveAt(0);
}
else
{
aIScriptTokenArgType = argumentType;
durationType = ((AIScriptArgumentToken)argList[1]).ArgumentType;
argList.RemoveRange(0, 2);
}
argList.Reverse();
if (aIScriptTokenArgType == AIScriptTokenArgType.NONE)
{
return AIHealSimulationUtility.GetSelfTurnHealCountAll(owner, field, argList, playPtn, situation, durationType);
}
return AIHealSimulationUtility.GetSelfTurnHealCountAtCountType(owner, field, argList, playPtn, situation, durationType, aIScriptTokenArgType);
}
}

View File

@@ -0,0 +1,216 @@
using System.Collections.Generic;
using UnityEngine;
namespace Wizard;
public static class AIHealSimulationUtility
{
public static int CalcHealModifier(AIVirtualCard healTarget, List<int> playPtn, AISituationInfo situation, int originalHealValue)
{
if (!healTarget.TagCollectionContainer.HasTag(AIPlayTagType.ModifyHeal))
{
return originalHealValue;
}
return healTarget.TagCollectionContainer.ModifyHealTags.GetModifiedHealValue(healTarget, healTarget, originalHealValue, playPtn, situation);
}
public static float EvalTargetingHeal(AIVirtualCard tagOwner, List<AIScriptTokenBase> filters, List<int> playPtn, int heal)
{
float num = float.MinValue;
AIVirtualField selfField = tagOwner.SelfField;
AIVirtualCard aIVirtualCard = null;
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(selfField.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, null);
if (list != null && list.Count > 0)
{
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard2 = list[i];
if (aIVirtualCard2.IsAlly == tagOwner.IsAlly || (!aIVirtualCard2.IsUntouchable && !aIVirtualCard2.IsSneak))
{
int num2 = CalcHealModifier(aIVirtualCard2, playPtn, null, heal);
float num3 = 0f;
if (aIVirtualCard2.IsUnit)
{
num3 = (float)Mathf.Min(num2, aIVirtualCard2.MaxLife - aIVirtualCard2.Life) * (aIVirtualCard2.IsAlly ? 1f : (-1f));
}
else if (aIVirtualCard2.IsLeader)
{
num3 = AILeaderLifeEvaluationUtility.Evaluate(Mathf.Min(aIVirtualCard2.MaxLife, aIVirtualCard2.Life + num2), aIVirtualCard2.Life, aIVirtualCard2.IsAlly, tagOwner.IsAlly);
}
if (num < num3)
{
num = num3;
aIVirtualCard = aIVirtualCard2;
}
float num4 = CalcEvalHealAfterAttack(aIVirtualCard2, num2);
if (num < num4)
{
num = num4;
aIVirtualCard = aIVirtualCard2;
}
}
}
}
if (aIVirtualCard != null)
{
return num;
}
return 0f;
}
public static float EvalAllHeal(AIVirtualCard tagOwner, List<AIScriptTokenBase> filters, List<int> playPtn, int heal)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(tagOwner.SelfField.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, null);
if (list == null || list.Count <= 0)
{
return 0f;
}
float num = 0f;
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (aIVirtualCard.IsAlly == tagOwner.IsAlly)
{
int num2 = CalcHealModifier(aIVirtualCard, playPtn, null, heal);
float num3 = 0f;
if (aIVirtualCard.IsUnit)
{
num3 = (float)Mathf.Min(num2, aIVirtualCard.MaxLife - aIVirtualCard.Life) * (aIVirtualCard.IsAlly ? 1f : (-1f));
}
else if (aIVirtualCard.IsLeader)
{
num3 = AILeaderLifeEvaluationUtility.Evaluate(Mathf.Min(aIVirtualCard.MaxLife, aIVirtualCard.Life + num2), aIVirtualCard.Life, aIVirtualCard.IsAlly, tagOwner.IsAlly);
}
num += num3;
}
}
return num;
}
public static float CalcEvalHealAfterAttack(AIVirtualCard healTarget, int heal)
{
AIVirtualField selfField = healTarget.SelfField;
if (!healTarget.IsUnit || !healTarget.IsAlly)
{
return 0f;
}
float num = float.MinValue;
bool flag = healTarget.IsAbleEvolution();
for (int i = 0; i < selfField.EnemyInplayCards.Count; i++)
{
AIVirtualCard aIVirtualCard = selfField.EnemyInplayCards[i];
if (aIVirtualCard.IsCantUnderAttack(selfField.ParamQuery, healTarget, EnemyAI.EmptyPlayPtn, selfField))
{
continue;
}
AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(healTarget, aIVirtualCard);
if (!(AIAttackSimulationUtility.IsAttackPossible(selfField, aIVirtualAttackInfo) || flag))
{
continue;
}
int num2 = healTarget.SimulateDamageAmount(aIVirtualCard.SimulateAttackAmount(aIVirtualAttackInfo));
if (healTarget.Life > num2)
{
int b = healTarget.MaxLife - (healTarget.Life - num2);
float num3 = Mathf.Min(heal, b);
if (num3 > num)
{
num = num3;
}
}
else if (flag && healTarget.EvolutionLife > num2)
{
int b2 = healTarget.BaseCard.BaseParameter.EvoLife - (healTarget.EvolutionLife - num2);
float num4 = Mathf.Min(heal, b2);
if (num4 > num)
{
num = num4;
}
}
}
return num;
}
public static int GetSelfTurnHealCountAll(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> filters, List<int> playPtn, AISituationInfo situation, AIScriptTokenArgType durationType)
{
return GetSelfTurnHealCountPlayed(tagOwner, field, filters, playPtn, durationType, situation) + GetSelfTurnHealCountPlayPtn(tagOwner, field, filters, playPtn, situation);
}
public static int GetSelfTurnHealCountAtCountType(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> filters, List<int> playPtn, AISituationInfo situation, AIScriptTokenArgType durationType, AIScriptTokenArgType countType)
{
return countType switch
{
AIScriptTokenArgType.PLAYED => GetSelfTurnHealCountPlayed(tagOwner, field, filters, playPtn, durationType, situation),
AIScriptTokenArgType.PLAYPTN => GetSelfTurnHealCountPlayPtn(tagOwner, field, filters, playPtn, situation),
AIScriptTokenArgType.BEFORE_PLAYPTN => GetSelfTurnHealCountBeforePlayPtn(tagOwner, field, filters, playPtn, situation, durationType),
_ => 0,
};
}
private static int GetSelfTurnHealCountPlayed(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> filters, List<int> playPtn, AIScriptTokenArgType durationType, AISituationInfo situation)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, situation);
if (list == null || list.Count <= 0)
{
return 0;
}
int turn = (tagOwner.IsAlly ? field.AllyTurnCount : field.EnemyTurnCount);
return 0 + field.HealRecorderCollection.GetTurnHealCount(turn, list, tagOwner.IsAlly);
}
private static int GetSelfTurnHealCountPlayPtn(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> filters, List<int> playPtn, AISituationInfo situation)
{
if (playPtn == null || !tagOwner.IsAlly)
{
return 0;
}
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, situation);
if (list == null || list.Count <= 0)
{
return 0;
}
int num = 0;
for (int i = 0; i < playPtn.Count; i++)
{
AIVirtualCard aIVirtualCard = field.AllyHandCards[playPtn[i]];
if (aIVirtualCard.IsSameCard(tagOwner))
{
break;
}
num += aIVirtualCard.GetWhenPlayHealCount(list, field, playPtn, situation);
}
return num;
}
private static int GetSelfTurnHealCountBeforePlayPtn(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> filters, List<int> playPtn, AISituationInfo situation, AIScriptTokenArgType durationType)
{
if (playPtn == null || !tagOwner.IsAlly)
{
return 0;
}
return GetSelfTurnHealCountPlayPtn(tagOwner, field, filters, playPtn, situation) + GetSelfTurnHealCountPlayed(tagOwner, field, filters, playPtn, durationType, situation);
}
public static AIVirtualCard SelectBestTarget(List<AIVirtualCard> targets, int healPoint)
{
float num = -1f;
AIVirtualCard result = null;
for (int i = 0; i < targets.Count; i++)
{
if (!targets[i].IsIndependent)
{
float num2 = Mathf.Min(healPoint, targets[i].MaxLife - targets[i].Life);
if (num2 > num)
{
num = num2;
result = targets[i];
}
if (num2 >= (float)healPoint)
{
break;
}
}
}
return result;
}
}

View File

@@ -0,0 +1,18 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIIsSelectableUtility
{
public static bool IsSelectable(List<AIScriptTokenBase> filters, float minSelectableCount, AIVirtualCard owner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.AllReferableCards, filters, owner, playPtn, situation);
list.RemoveAll((AIVirtualCard card) => card.IsAlly != owner.IsAlly && card.CantBeFocusedSkill);
list = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(list, owner, playPtn);
if (list == null || (float)list.Count < minSelectableCount)
{
return false;
}
return true;
}
}

View File

@@ -0,0 +1,134 @@
using System.Collections.Generic;
namespace Wizard;
public static class AILethalTargetSelectUtility
{
public class LethalTargetSelectResult
{
public AISelectedTargetInfoSet TargetSet;
public AIVirtualField ResultField;
}
public static bool LethalSelectTarget(AIVirtualField field, AIVirtualTargetSelectAction situation, AISinglePlayptnRecord playPtnRecord)
{
AIVirtualCard actor = situation.Actor;
List<AIVirtualTargetSelectInfo> list = actor.CreateAIVirtualSelectInfo(field, situation);
if (list == null || list.Count <= 0)
{
return TargetSelectAction(field, situation);
}
AISelectedTargetInfoSet preDecidedTargetSet = null;
if (situation.SelectedTargets.IsAnyTargetExists())
{
preDecidedTargetSet = situation.SelectedTargets;
}
List<AISelectedTargetInfoSet> allTargetSelectSimulationPattern = AIVirtualTargetSelectSimulator.GetAllTargetSelectSimulationPattern(list, preDecidedTargetSet, situation, field, playPtnRecord);
if (allTargetSelectSimulationPattern == null || allTargetSelectSimulationPattern.Count <= 0)
{
AIConsoleUtility.LogError("LethalSelectTarget error!! Cannot find target pattern!!!!! actor.id == " + actor.BaseId);
return TargetSelectAction(field, situation);
}
LethalTargetSelectResult lethalTargetSelectResult = new LethalTargetSelectResult
{
ResultField = field,
TargetSet = null
};
CalculateBestTargetPattern(lethalTargetSelectResult, field, situation, allTargetSelectSimulationPattern, playPtnRecord, list);
situation.SelectedTargets = lethalTargetSelectResult.TargetSet;
return TargetSelectAction(field, situation);
}
private static bool TargetSelectAction(AIVirtualField field, AIVirtualTargetSelectAction situation)
{
switch (situation.ActionType)
{
case AIOperationType.PLAY:
{
PlaySimulationInfo playSimulationInfo = AIPlayCardSimulationUtility.CreatePlaySimulationInfo(situation.Actor, situation, field);
if (playSimulationInfo != null)
{
AIVirtualPlaySimulator.PlayCard(situation, field, playSimulationInfo);
return true;
}
return false;
}
case AIOperationType.EVOLVE:
AIVirtualEvolutionSimulator.ManualEvolve(situation, field);
return true;
default:
return false;
}
}
private static void CalculateBestTargetPattern(LethalTargetSelectResult result, AIVirtualField field, AIVirtualTargetSelectAction situation, List<AISelectedTargetInfoSet> patternSet, AISinglePlayptnRecord playptnRecord, List<AIVirtualTargetSelectInfo> selectInfoList)
{
AIVirtualCard originalCard = situation.OriginalCard;
AIOperationType actionType = situation.ActionType;
int giveQuickSelectIndex = GetGiveQuickSelectIndex(selectInfoList);
bool isSecondTargetForbbidenSelectedTarget = selectInfoList.Count > 1 && selectInfoList[1].IsForbiddenSelectedTarget;
for (int i = 0; i < patternSet.Count; i++)
{
AISelectedTargetInfoSet aISelectedTargetInfoSet = patternSet[i];
if (!AIVirtualTargetSelectSimulator.IsAbleToReplaceDummyTarget(aISelectedTargetInfoSet, result.TargetSet, isSecondTargetForbbidenSelectedTarget))
{
continue;
}
if (!aISelectedTargetInfoSet.IsTargetExist(0) && aISelectedTargetInfoSet.IsTargetExist(1))
{
AIConsoleUtility.LogError("AILethalTargetSelectUtility.CalculateBestTargetPattern error!! targetPattern.firstTarget is null & secondTaget is not null");
continue;
}
AIVirtualField aIVirtualField = new AIVirtualField(field);
AISelectedTargetInfoSet similarTargetInfoSet = aISelectedTargetInfoSet.GetSimilarTargetInfoSet(aIVirtualField);
AIVirtualCard aIVirtualCard = aIVirtualField.SearchVirtualCard(originalCard);
AIVirtualCard actor = aIVirtualCard;
if (actionType == AIOperationType.PLAY)
{
actor = aIVirtualCard.FindRealActor(playptnRecord);
}
AIVirtualTargetSelectAction situation2 = new AIVirtualTargetSelectAction(actor, aIVirtualCard, actionType, similarTargetInfoSet);
TargetSelectAction(aIVirtualField, situation2);
if (giveQuickSelectIndex >= 0)
{
GiveQuickTargetSelectSimulation(similarTargetInfoSet.Get(giveQuickSelectIndex), aIVirtualField);
}
if (result.TargetSet == null || aIVirtualField.EnemyClass.Life < result.ResultField.EnemyClass.Life)
{
result.ResultField = aIVirtualField;
result.TargetSet = aISelectedTargetInfoSet.Clone();
}
}
}
private static int GetGiveQuickSelectIndex(List<AIVirtualTargetSelectInfo> selectInfoList)
{
for (int i = 0; i < selectInfoList.Count; i++)
{
AIVirtualTargetSelectInfo aIVirtualTargetSelectInfo = selectInfoList[i];
if (aIVirtualTargetSelectInfo.SelectRule != null && (aIVirtualTargetSelectInfo.SelectRule.Type == AIPlayTagType.PlayQuick || aIVirtualTargetSelectInfo.SelectRule.Type == AIPlayTagType.FanfareQuick))
{
return i;
}
}
return -1;
}
private static void GiveQuickTargetSelectSimulation(AISelectedTargetInfo receiveQuickTargets, AIVirtualField field)
{
if (!receiveQuickTargets.HasTarget)
{
return;
}
for (int i = 0; i < receiveQuickTargets.Targets.Count; i++)
{
AIVirtualCard aIVirtualCard = receiveQuickTargets.Targets[i];
AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(aIVirtualCard, field.EnemyClass);
if (AIAttackSimulationUtility.IsAttackPossible(field, aIVirtualAttackInfo) && !aIVirtualAttackInfo.WillTargetDestroyByAttackTags(field, field.BestPlayPtn, aIVirtualCard))
{
AIVirtualAttackSimulator.Attack(aIVirtualAttackInfo, field);
}
}
}
}

View File

@@ -0,0 +1,37 @@
using System.Collections.Generic;
using UnityEngine;
namespace Wizard;
public class AILifeLowerLimitInfo : AIBarrierInfoBase
{
public override AIBarrierType BarrierType => AIBarrierType.DamageClippingLifeLowerLimit;
public AILifeLowerLimitInfo(AIDamageType damageType, AIBarrierStopTiming stopTiming)
: base(0, damageType, stopTiming)
{
UpdateHash();
}
public AILifeLowerLimitInfo(AIDamageType damageType, List<AIBarrierStopTiming> stopTimingList)
: base(0, damageType, stopTimingList)
{
UpdateHash();
}
public override AIBarrierInfoBase Clone()
{
return new AILifeLowerLimitInfo(base.DamageType, base.StopTimingList);
}
public override bool IsShield()
{
return false;
}
protected override int CalcDamage(AIVirtualCard owner, int damage)
{
int b = owner.Life - 1;
return Mathf.Min(damage, b);
}
}

View File

@@ -0,0 +1,45 @@
using System.Collections.Generic;
namespace Wizard;
public class AIMaxAttackSelectLogicArgument : AISelectLogicArgumentBase
{
public override AIScriptTokenArgType LogicType => AIScriptTokenArgType.MAX_ATTACK_LOGIC;
public AIMaxAttackSelectLogicArgument(List<string> args)
: base(args)
{
}
public override AIVirtualCard SelectSingleTarget(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
AIVirtualCard aIVirtualCard = null;
int compare = 0;
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard2 = candidates[i];
if (aIVirtualCard2.IsUnit && (aIVirtualCard == null || IsWellChosenTarget(aIVirtualCard2, compare, worstOrBest)))
{
aIVirtualCard = aIVirtualCard2;
compare = aIVirtualCard2.Attack;
}
}
return aIVirtualCard;
}
public override List<AIVirtualCard> SelectMultipleSelectedTargets(List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
LogNotImplementMultipleSelect();
return null;
}
private bool IsWellChosenTarget(AIVirtualCard target, int compare, AISelectTargetPattern worstOrBest)
{
return worstOrBest switch
{
AISelectTargetPattern.Best => target.Attack > compare,
AISelectTargetPattern.Worst => target.Attack < compare,
_ => false,
};
}
}

View File

@@ -0,0 +1,53 @@
using System.Collections.Generic;
namespace Wizard;
public class AIMetamorphoseSelectLogicArgument : AISelectLogicArgumentBase
{
private const int INVALID_ID = -1;
private const int METAMORPHOSE_ID_ARG_INDEX = 0;
public override AIScriptTokenArgType LogicType => AIScriptTokenArgType.METAMORPHOSE_LOGIC;
public AIMetamorphoseSelectLogicArgument(List<string> args)
: base(args)
{
}
public override AIVirtualCard SelectSingleTarget(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
AIRemovalEvaluationOption aIRemovalEvaluationOption = CreateMetamorphoseOption(tagOwner, field);
if (aIRemovalEvaluationOption == null)
{
return null;
}
return AISimulationRemovalUtility.SelectRemovalTarget(candidates, tagOwner, field, playPtn, situation, worstOrBest, AIRemovalType.Metamorphose, aIRemovalEvaluationOption);
}
public override List<AIVirtualCard> SelectMultipleSelectedTargets(List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
AIRemovalEvaluationOption aIRemovalEvaluationOption = CreateMetamorphoseOption(tagOwner, field);
if (aIRemovalEvaluationOption == null)
{
return null;
}
return AISimulationRemovalUtility.SelectMultipleRemovalTargets(candidates, tagOwner, field, playPtn, situation, worstOrBest, AIRemovalType.Metamorphose, selectCount, aIRemovalEvaluationOption);
}
private AIRemovalEvaluationOption CreateMetamorphoseOption(AIVirtualCard tagOwner, AIVirtualField field)
{
if (_argumentList == null || _argumentList.Count <= 0)
{
AIConsoleUtility.LogError("AIMetamorphoseSelectLogicArgument error!! _argumentList is null");
return null;
}
int num = _argumentList[0].EvalID();
if (num == -1)
{
AIConsoleUtility.LogError("AIMetamorphoseSelectLogicArgument error!! tokenId is invalid");
return null;
}
return AIMetamorphoseSimulationUtility.CreateMetamorphoseEvaluationOption(tagOwner, field, num);
}
}

View File

@@ -0,0 +1,440 @@
using System.Collections.Generic;
using System.Linq;
using Cute;
namespace Wizard;
public static class AIMetamorphoseSimulationUtility
{
private struct SwappedMetamorphoseInfo
{
public AIVirtualCard TargetCard;
public AIVirtualCard TokenCard;
public List<AIVirtualCard> SwappedCardList;
public int SwappedIndex;
}
public static AIRemovalEvaluationOption CreateMetamorphoseEvaluationOption(AIVirtualCard tagOwner, AIVirtualField field, int metamorphoseId)
{
return new AIRemovalEvaluationOption
{
TagOwner = tagOwner,
MetamorphoseTokenId = metamorphoseId
};
}
public static void MetamorphoseAll(AIVirtualField field, List<AIVirtualCard> range, int metamorphoseId, AIVirtualCard actor, AISituationInfo situation)
{
for (int i = 0; i < range.Count; i++)
{
AIVirtualCard aIVirtualCard = range[i];
if (!aIVirtualCard.IsIndependent && !aIVirtualCard.IsDead)
{
ExecuteMetamorphose(aIVirtualCard, metamorphoseId, actor, field, situation);
}
}
}
public static void MetamorphoseRandom(AIVirtualField field, List<AIVirtualCard> range, int metamorphoseId, AIVirtualCard actor, List<int> playPtn, AISituationInfo situation, int selectCount = 1)
{
if (selectCount <= 0)
{
AIConsoleUtility.LogError($"AIMetamorphoseSimulationUtility.MetamorphoseRandom() error!! selectCount == {selectCount}");
return;
}
AIRemovalEvaluationOption aIRemovalEvaluationOption = CreateMetamorphoseEvaluationOption(actor, field, metamorphoseId);
if (aIRemovalEvaluationOption == null)
{
AIConsoleUtility.LogError("AIMetamorphoseSimulationUtility.MetamorphoseRandom() error!! failed create option");
return;
}
if (selectCount == 1)
{
AIVirtualCard aIVirtualCard = AISimulationRemovalUtility.SelectRemovalTarget(range, actor, field, playPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Metamorphose, aIRemovalEvaluationOption);
if (aIVirtualCard != null && !aIVirtualCard.IsIndependent)
{
ExecuteMetamorphose(aIVirtualCard, metamorphoseId, actor, field, situation);
}
return;
}
List<AIVirtualCard> list = AISimulationRemovalUtility.SelectMultipleRemovalTargets(range, actor, field, playPtn, situation, AISelectTargetPattern.Worst, AIRemovalType.Metamorphose, selectCount, aIRemovalEvaluationOption);
if (list != null && list.Count > 0)
{
for (int i = 0; i < list.Count; i++)
{
ExecuteMetamorphose(list[i], metamorphoseId, actor, field, situation);
}
}
}
public static void MetamorphoseTarget(AIVirtualField field, List<AIVirtualCard> candidates, int metamorphoseId, List<int> playPtn, AISituationInfo situation, AIScriptTokenArgType whichTarget, int count)
{
if (situation.IsTargetExists(whichTarget))
{
MetamorphoseSelectedTarget(field, metamorphoseId, situation, whichTarget);
}
else
{
MetamorphoseTargetPrediction(field, candidates, metamorphoseId, playPtn, situation, whichTarget, count);
}
}
private static void MetamorphoseSelectedTarget(AIVirtualField field, int metamorphoseId, AISituationInfo situation, AIScriptTokenArgType whichTarget)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
AIConsoleUtility.LogError("MetamorphoseSelectedTarget(): error!! No target!!!!!");
return;
}
List<AIVirtualCard> targets = situationTarget.Targets;
for (int i = 0; i < targets.Count; i++)
{
ExecuteMetamorphose(targets[i], metamorphoseId, situation.Actor, field, situation);
}
}
private static void MetamorphoseTargetPrediction(AIVirtualField field, List<AIVirtualCard> candidates, int metamorphoseId, List<int> playPtn, AISituationInfo situation, AIScriptTokenArgType whichTarget, int count)
{
if (candidates.Count < count)
{
AIConsoleUtility.LogError("MetamorphoseTargetPrediction(): Target candidates is not enough");
return;
}
AIVirtualCard actor = situation.Actor;
AIRemovalEvaluationOption aIRemovalEvaluationOption = CreateMetamorphoseEvaluationOption(actor, field, metamorphoseId);
if (aIRemovalEvaluationOption == null)
{
AIConsoleUtility.LogError("MetamorphoseTargetPrediction() error!! failed create option");
return;
}
if (count == 1)
{
AIVirtualCard aIVirtualCard = AISimulationRemovalUtility.SelectRemovalTarget(candidates, actor, field, playPtn, situation, AISelectTargetPattern.Best, AIRemovalType.Metamorphose, aIRemovalEvaluationOption);
if (aIVirtualCard != null && !aIVirtualCard.IsIndependent)
{
ExecuteMetamorphose(aIVirtualCard, metamorphoseId, actor, field, situation);
}
return;
}
List<AIVirtualCard> list = AISimulationRemovalUtility.SelectMultipleRemovalTargets(candidates, actor, field, playPtn, situation, AISelectTargetPattern.Best, AIRemovalType.Metamorphose, count, aIRemovalEvaluationOption);
if (list != null && list.Count > 0)
{
for (int i = 0; i < list.Count; i++)
{
ExecuteMetamorphose(list[i], metamorphoseId, actor, field, situation);
}
}
}
private static void ExecuteMetamorphose(AIVirtualCard target, int metamorphoseTokenId, AIVirtualCard actor, AIVirtualField field, AISituationInfo situation)
{
target.MetamorphoseLeave(situation);
MetamorphoseTokenOnVirtualField(target, metamorphoseTokenId, actor, field);
List<int> emptyPlayPtn = EnemyAI.EmptyPlayPtn;
field.ExecuteWhenChangeInplayTags(emptyPlayPtn, situation);
}
public static float EvalTargetingMetamorphose(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> filters, int tokenId, List<int> playPtn, AISituationInfo situation)
{
float num = float.MinValue;
List<AIVirtualCard> bothClassAndInplayCards = tagOwner.SelfField.CardListSet.BothClassAndInplayCards;
bothClassAndInplayCards = AIFilteringUtility.MultipleFiltering(bothClassAndInplayCards, filters, tagOwner, playPtn, situation);
bothClassAndInplayCards.RemoveAll((AIVirtualCard c) => c.IsLeader);
if (bothClassAndInplayCards == null || bothClassAndInplayCards.Count <= 0)
{
return 0f;
}
AIVirtualCard aIVirtualCard = null;
if (bothClassAndInplayCards.IsNotNullOrEmpty())
{
bothClassAndInplayCards = AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(bothClassAndInplayCards, tagOwner, playPtn);
for (int num2 = 0; num2 < bothClassAndInplayCards.Count; num2++)
{
AIVirtualCard aIVirtualCard2 = bothClassAndInplayCards[num2];
if (!aIVirtualCard2.IsIndependent && (aIVirtualCard2.IsAlly == tagOwner.IsAlly || (!aIVirtualCard2.IsUntouchable && !aIVirtualCard2.IsSneak)))
{
float num3 = EvaluateSingleMetamorphoseValue(aIVirtualCard2, tokenId, tagOwner, field, playPtn, situation);
if (num < num3)
{
num = num3;
aIVirtualCard = aIVirtualCard2;
}
}
}
}
if (aIVirtualCard == null)
{
return 0f;
}
return num;
}
public static float EvalRandomMetamorphose(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> filters, int tokenId, List<int> playPtn, int count, AISituationInfo situation)
{
List<AIVirtualCard> bothClassAndInplayCards = field.CardListSet.BothClassAndInplayCards;
bothClassAndInplayCards = AIFilteringUtility.MultipleFiltering(bothClassAndInplayCards, filters, tagOwner, playPtn, null);
if (bothClassAndInplayCards == null || bothClassAndInplayCards.Count <= 0)
{
return 0f;
}
bothClassAndInplayCards.RemoveAll((AIVirtualCard c) => c.IsLeader);
if (bothClassAndInplayCards == null || bothClassAndInplayCards.Count <= 0)
{
return 0f;
}
if (bothClassAndInplayCards.Count <= count)
{
return EvalAllMetamorphose(bothClassAndInplayCards, tokenId, tagOwner, field, playPtn, situation);
}
float num = 0f;
new List<SwappedMetamorphoseInfo>();
List<AIVirtualCard[]> list = AIMathematicsLibrary.EnumerateCombinations(bothClassAndInplayCards, count).ToList();
for (int num2 = 0; num2 < list.Count; num2++)
{
List<AIVirtualCard> targetCards = new List<AIVirtualCard>(list[num2]);
num += EvalAllMetamorphose(targetCards, tokenId, tagOwner, field, playPtn, situation);
}
return num / (float)list.Count;
}
public static float EvalAllMetamorphose(AIVirtualCard tagOwner, AIVirtualField field, List<AIScriptTokenBase> filters, int tokenId, List<int> playPtn, AISituationInfo situation)
{
return EvalAllMetamorphose(AIFilteringUtility.MultipleFiltering(tagOwner.SelfField.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, null), tokenId, tagOwner, field, playPtn, situation);
}
private static float EvalAllMetamorphose(List<AIVirtualCard> targetCards, int tokenId, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
targetCards.RemoveAll((AIVirtualCard c) => c.IsLeader);
if (targetCards == null || targetCards.Count <= 0)
{
return 0f;
}
if (targetCards == null || targetCards.Count <= 0)
{
return 0f;
}
List<SwappedMetamorphoseInfo> swappedList = new List<SwappedMetamorphoseInfo>();
float num = 0f;
List<AIVirtualCard> list = new List<AIVirtualCard>();
AIVirtualCard aIVirtualCard = null;
AIVirtualCard aIVirtualCard2 = null;
for (int num2 = 0; num2 < targetCards.Count; num2++)
{
AIVirtualCard aIVirtualCard3 = targetCards[num2];
if (aIVirtualCard3.IsIndependent)
{
continue;
}
AIVirtualCard aIVirtualCard4 = null;
if (aIVirtualCard3.IsAlly)
{
if (aIVirtualCard == null)
{
aIVirtualCard = field.AI.tokenManager.GetTokenFromId(tokenId, isAlly: true, field);
}
aIVirtualCard4 = aIVirtualCard;
}
else
{
if (aIVirtualCard2 == null)
{
aIVirtualCard2 = field.AI.tokenManager.GetTokenFromId(tokenId, isAlly: false, field);
}
aIVirtualCard4 = aIVirtualCard2;
}
if (aIVirtualCard4 == null)
{
AIConsoleUtility.LogError(string.Format("AIMetamorphosSimulationUtility.EvaluateSingleMetamorphoseValue() error!! Not found {0}: {1}", aIVirtualCard3.IsAlly ? "Ally" : "ENEMY", tokenId));
return 0f;
}
num += EvaluateMetamorphoseTargetValue(aIVirtualCard3, playPtn, situation) * ((tagOwner.IsAlly != aIVirtualCard3.IsAlly) ? 1f : (-1f));
list.Add(aIVirtualCard4);
}
for (int num3 = 0; num3 < targetCards.Count; num3++)
{
SwapInplayMetamorphoseCard(list[num3], targetCards[num3], field, ref swappedList);
}
float num4 = 0f;
for (int num5 = 0; num5 < list.Count; num5++)
{
AIVirtualCard aIVirtualCard5 = list[num5];
float num6 = EvaluateMetamorphoseTokenValue(aIVirtualCard5, playPtn, situation);
num4 += num6 * ((tagOwner.IsAlly != aIVirtualCard5.IsAlly) ? 1f : (-1f));
}
RestoreInplayMetamorphoseCard(swappedList);
list.Clear();
return (num - num4) * (tagOwner.IsAlly ? 1f : (-1f));
}
public static float EvaluateSingleMetamorphoseValue(AIVirtualCard targetCard, int afterMetamorphoseTokenId, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
float num = EvaluateMetamorphoseTargetValue(targetCard, playPtn, situation);
AIVirtualCard tokenFromId = field.AI.tokenManager.GetTokenFromId(afterMetamorphoseTokenId, targetCard.IsAlly, field);
if (tokenFromId == null)
{
AIConsoleUtility.LogError($"AIMetamorphosSimulationUtility.EvaluateSingleMetamorphoseValue() error!! Not found id == {afterMetamorphoseTokenId}");
return 0f;
}
List<SwappedMetamorphoseInfo> swappedList = new List<SwappedMetamorphoseInfo>();
SwapInplayMetamorphoseCard(tokenFromId, targetCard, field, ref swappedList);
float num2 = EvaluateMetamorphoseTokenValue(tokenFromId, playPtn, situation);
float result = (num - num2) * ((targetCard.IsAlly != tagOwner.IsAlly) ? 1f : (-1f));
RestoreInplayMetamorphoseCard(swappedList);
return result;
}
private static float EvaluateMetamorphoseTargetValue(AIVirtualCard target, List<int> playPtn, AISituationInfo situation)
{
return target.EvaluateValueOnField(playPtn, situation, useStyle: true) + (target.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) + target.GetAllBanishBonus(playPtn, useIgnoreInBattle: false) + target.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false));
}
private static float EvaluateMetamorphoseTokenValue(AIVirtualCard tokenCard, List<int> playPtn, AISituationInfo situation)
{
return tokenCard.EvaluateValueOnField(playPtn, situation, useStyle: true, doesUseLostLife: true, useOthersTag: true, useIgnoreInBattle: true) + (tokenCard.EvaluateBreakValue(playPtn, useIgnoreBreak: true) + tokenCard.EvaluateLeaveValue(playPtn, useIgnoreInBattle: true)) * EnemyAI.BREAKBONUS_RATE_IN_HAND;
}
private static void SwapInplayMetamorphoseCard(AIVirtualCard tokenCard, AIVirtualCard targetCard, AIVirtualField fieldTemp, ref List<SwappedMetamorphoseInfo> swappedList)
{
if (targetCard.IsAlly)
{
Swap(fieldTemp.AllyInplayCards, swappedList);
Swap(fieldTemp.CardListSet.AllAllyCards, swappedList);
Swap(fieldTemp.CardListSet.AllyClassAndInplayCards, swappedList);
}
else
{
Swap(fieldTemp.EnemyInplayCards, swappedList);
Swap(fieldTemp.CardListSet.EnemyClassAndInplayCards, swappedList);
}
Swap(fieldTemp.CardListSet.AllReferableCards, swappedList);
Swap(fieldTemp.CardListSet.BothClassAndInplayCards, swappedList);
Swap(fieldTemp.CardListSet.BothInplayCards, swappedList);
void Swap(List<AIVirtualCard> _cardList, List<SwappedMetamorphoseInfo> _swappedList)
{
int num = _cardList.IndexOf(targetCard);
if (num >= 0 && num < _cardList.Count)
{
_cardList.Insert(num, tokenCard);
_cardList.Remove(targetCard);
_swappedList = AIParamQuery.AddElementToList(new SwappedMetamorphoseInfo
{
TargetCard = targetCard,
TokenCard = tokenCard,
SwappedCardList = _cardList,
SwappedIndex = num
}, _swappedList);
}
}
}
private static void RestoreInplayMetamorphoseCard(List<SwappedMetamorphoseInfo> swappedList)
{
if (swappedList != null)
{
for (int i = 0; i < swappedList.Count; i++)
{
SwappedMetamorphoseInfo swappedMetamorphoseInfo = swappedList[i];
List<AIVirtualCard> swappedCardList = swappedMetamorphoseInfo.SwappedCardList;
int swappedIndex = swappedMetamorphoseInfo.SwappedIndex;
swappedCardList.Insert(swappedIndex, swappedMetamorphoseInfo.TargetCard);
swappedCardList.Remove(swappedMetamorphoseInfo.TokenCard);
}
swappedList.Clear();
}
}
public static void MetamorphoseTokenOnVirtualField(AIVirtualCard targetCard, int tokenId, AIVirtualCard tagOwner, AIVirtualField field)
{
AIVirtualCard tokenFromId = field.AI.tokenManager.GetTokenFromId(tokenId, targetCard.IsAlly, field, needsClone: true);
if (tokenFromId == null)
{
AIConsoleUtility.LogError("MetamorphoseTokenOnVirtualField: tokenCard is null");
return;
}
tokenFromId.InitAtMetamorphose(targetCard, tagOwner);
field.CardListSet.ReplaceInplayCard(targetCard.IsAlly, tokenFromId, targetCard);
targetCard.IsMetamorphosed = true;
if (targetCard.IsAlly)
{
List<AIVirtualCard> allyInplayCards = field.AllyInplayCards;
allyInplayCards.Insert(allyInplayCards.IndexOf(targetCard), tokenFromId);
allyInplayCards.Remove(targetCard);
}
else
{
List<AIVirtualCard> enemyInplayCards = field.EnemyInplayCards;
enemyInplayCards.Insert(enemyInplayCards.IndexOf(targetCard), tokenFromId);
enemyInplayCards.Remove(targetCard);
field.EnemyTokenQueue.Enqueue(new Tuple<AIVirtualCard, AIVirtualCard>(targetCard, tokenFromId));
}
}
public static void MetamorphoseHandAll(AIVirtualField field, List<AIVirtualCard> range, int metamorphoseId, AIVirtualCard actor, AISituationInfo situation)
{
for (int i = 0; i < range.Count; i++)
{
MetamorphoseHandOnVirtualField(range[i], metamorphoseId, actor, field);
}
}
public static void MetamorphoseHandRandom(AIVirtualField field, List<AIVirtualCard> range, int metamorphoseId, AIVirtualCard actor, List<int> playPtn, AISituationInfo situaion)
{
AIVirtualCard aIVirtualCard = null;
float num = float.MinValue;
for (int i = 0; i < range.Count; i++)
{
AIVirtualCard aIVirtualCard2 = range[i];
float num2 = aIVirtualCard2.EvaluatePlayValue(playPtn, situaion) + aIVirtualCard2.GetHandBonus(playPtn, situaion, isIgnoreInFusion: false);
if (num < num2)
{
aIVirtualCard = aIVirtualCard2;
num = num2;
}
}
if (aIVirtualCard != null)
{
MetamorphoseHandOnVirtualField(aIVirtualCard, metamorphoseId, actor, field);
}
}
public static void MetamorphoseHandTarget(AIVirtualField field, List<AIVirtualCard> candidates, int metamorphoseId, AISituationInfo situation, AIScriptTokenArgType whichTarget)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
AIConsoleUtility.LogError("MetamorphoseHandTarget error!! No target!!!!!");
return;
}
for (int i = 0; i < situationTarget.Targets.Count; i++)
{
AIVirtualCard aIVirtualCard = situationTarget.Targets[i];
if (candidates.Contains(aIVirtualCard))
{
MetamorphoseHandOnVirtualField(aIVirtualCard, metamorphoseId, situation.Actor, field);
}
}
}
public static void MetamorphoseHandOnVirtualField(AIVirtualCard targetCard, int tokenId, AIVirtualCard tagOwner, AIVirtualField field)
{
AIVirtualCard tokenFromId = field.AI.tokenManager.GetTokenFromId(tokenId, tagOwner.IsAlly, field, needsClone: true);
if (tokenFromId == null)
{
AIConsoleUtility.LogError("MetamorphoseHandOnVirtualField: tokenCard is null");
return;
}
tokenFromId.InitAtHandMetamorphose(targetCard, tagOwner);
targetCard.IsMetamorphosed = true;
if (targetCard.IsAlly)
{
field.CardListSet.ReplaceAllyHandCard(tokenFromId, targetCard);
}
List<AIVirtualCard> obj = (targetCard.IsAlly ? field.AllyHandCards : field.GetEnemyHandCardList());
obj.Insert(obj.IndexOf(targetCard), tokenFromId);
obj.Remove(targetCard);
}
}

View File

@@ -0,0 +1,503 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Wizard.Battle;
using Wizard.Battle.Phase;
using Wizard.Battle.Recovery;
using Wizard.Battle.View.Vfx;
using Wizard.BattleMgr;
namespace Wizard;
public class AINetworkBattleManager : NetworkBattleManagerBase
{
private AITurnControl _aiTurnControl;
private Func<VfxBase> _turnTransitionFunc;
private VfxBase _initiateGameEndFunc;
private bool _sendFinshBattleTask;
private bool _isWin;
public AIBattleInfoReceiver BattleInfoReceiver { get; protected set; }
public AINetworkBattleManager(IBattleMgrContentsCreator contentsCreator)
: base(contentsCreator)
{
_turnTransitionFunc = null;
}
protected override void NetworkBattleManagerSetup()
{
DataMgr dataMgr = GameMgr.GetIns().GetDataMgr();
dataMgr.SetDeckMaxCount(40, isSelf: true);
dataMgr.SetDeckMaxCount(40, isSelf: false);
IsShowDisconnectPanel = false;
IsShowOpponentDisconnectPanel = false;
NotReplaceCardList = new List<ReplaceReceivedCard.CardIdAndIndex>();
base.validateSkillIndexList = new List<ValidateSkillData>();
RegisterActionManager = new RegisterActionManager(this);
base.RegisterUnapprovedList = new List<RegisterUnapproved>();
base.registerSelectTypeSkillIndexList = new List<int>();
sendKeyActionDataManager = new SendKeyActionDataManager();
TouchControl = new NetworkTouchControl(this, _battleCamera, _backGround);
networkTouchControl = TouchControl as NetworkTouchControl;
JudgeResultReceiveCode = NetworkBattleReceiver.RESULT_CODE.NotFinish;
if (base.IsRecovery || GameMgr.GetIns().IsReplayBattle)
{
networkTouchControl.SetDisableTouch();
base.networkBattleData = new NetworkRecoveryBattleData(this);
networkReceiver = new NetworkReplayBattleReceiver(this);
OperateReceive = new RecoveryOperateReceive(this, RegisterActionManager, OperateMgr, base.networkBattleData);
int selfIdxSeed = (base.IsRecovery ? _contentsCreator.RecoveryManager.IdxChangeSeed : Data.ReplayBattleInfo.IdxChangeSeed);
int oppIdxSeed = (GameMgr.GetIns().IsReplayBattle ? Data.ReplayBattleInfo.OppoIdxChangeSeed : (-1));
CreateXorShift(selfIdxSeed, oppIdxSeed);
BattleEnemy.EnableEnemyAI = false;
}
else
{
base.networkBattleData = new NetworkBattleData(this);
networkReceiver = new NetworkBattleReceiver(this);
OperateReceive = new OperateReceive(this, RegisterActionManager, OperateMgr, base.networkBattleData);
}
OperateMgr.SetTouchControl(TouchControl);
networkConsistency = new NetworkConsistency(this);
_networkBattleSetupCardEventBase = new NetworkAIBattleSetupCardEvent(this, RegisterActionManager, base.networkBattleData);
operateReceiveChecker = new OperateReceiveChecker(this, base.networkBattleData);
_intervalCheckList = new List<NetworkBattleIntervalCheckerBase>();
base.opponentRecoveryToDispChecker = new OpponentRecoveryToDispChecker();
base.disconnectToDispChecker = new DisconnectToDispChecker();
_intervalCheckList.Add(base.disconnectToDispChecker);
base.disconnectToLoseChecker = new DisconnectToLoseChecker();
base.disconnectToLoseChecker.OnDisconnectLose += delegate
{
DisconnectLose();
};
base.disconnectToLoseChecker.OnBeforeDisconnectLose += delegate
{
BeforeDisconnectLose();
};
_intervalCheckList.Add(base.disconnectToLoseChecker);
base.notMulliganEndToJudgeChecker = new NullNotMulliganEndToJudgeChecker();
base.notTurnEndToLoseChecker = new NullNotTurnEndToLoseChecker(this);
base.receiveTurnEndToJudgeResult = new NullReceiveTurnEndToJudgeResult();
_intervalCheckList.Add(base.notTurnEndToLoseChecker);
base.notTurnStartToLoseChecker = new NullNotTurnStartToLoseChecker();
_intervalCheckList.Add(base.notTurnStartToLoseChecker);
SendIntervalTriggerMain = new AISendIntervalTrigger();
base.NetworkSender = new NetworkBattleSender(this, RegisterActionManager, base.RegisterUnapprovedList, networkConsistency);
_aiTurnControl = new AITurnControl();
if (!base.IsRecovery)
{
SettingOpponentAliveEvent();
IsStopIntervalCheck = false;
ToolboxGame.RealTimeNetworkAgent.StartPreparedStartTimer(DateTime.Now);
ToolboxGame.RealTimeNetworkAgent.StartRecoveryRecording();
}
}
protected override void DisconnectLose()
{
JudgeErrorDialog(isError: false);
}
public override VfxBase ChangePhase(IPhase phase)
{
if (phase is NetworkMulliganPhase || (phase is MainPhase && base.IsRecovery))
{
base.notMulliganEndToJudgeChecker.StartChecker();
base.disconnectToDispChecker.OnDisp += delegate
{
ControlDisconnectOffTouchAndView(flag: true);
};
base.disconnectToDispChecker.OnErase += delegate
{
ControlDisconnectOffTouchAndView(flag: false);
};
}
if (phase is OpeningPhase)
{
ConnectionReportTrigger.ConnectionReport(this);
}
return base.ChangePhase(phase);
}
public override void Update(float dt)
{
base.Update(dt);
if (_turnTransitionFunc != null && ToolboxGame.RealTimeNetworkAgent != null && ToolboxGame.RealTimeNetworkAgent.PlayerNetworkStatus.IsAlive)
{
base.VfxMgr.RegisterSequentialVfx(_turnTransitionFunc.GetAllFuncVfxResults());
_turnTransitionFunc = null;
}
if (_initiateGameEndFunc != null && ToolboxGame.RealTimeNetworkAgent != null && ToolboxGame.RealTimeNetworkAgent.PlayerNetworkStatus.IsAlive)
{
base.VfxMgr.RegisterSequentialVfx(_initiateGameEndFunc);
_initiateGameEndFunc = null;
}
if (ToolboxGame.RealTimeNetworkAgent != null && _turnTransitionFunc == null && !IsBattleEnd && BattleEnemy.IsSelfTurn)
{
_aiTurnControl.Update(EnemyAI);
}
}
public override void SetupBattlePlayersEvent()
{
BattlePlayer.OnSetupCardEvent += SetupCardEvent;
BattleEnemy.OnSetupCardEvent += SetupCardEvent;
BattlePlayer.OnSetupClassEvent += SetupPlayerClassEvent;
BattleEnemy.OnSetupClassEvent += SetupOpponentClassEvent;
BattlePlayer.Setup(BattleEnemy);
BattleEnemy.Setup(BattlePlayer);
BattlePlayer.OnTurnEnd += delegate
{
base.VfxMgr.Cancel();
return NullVfx.GetInstance();
};
}
protected override void SetupNetworkEvent(bool isRecovery)
{
BattlePlayer.OnPlayerActive += delegate
{
if (turnEndTimeController != null)
{
turnEndTimeController.StartCountDown("AIOnPlayerActive");
}
};
BattlePlayer battlePlayer = BattlePlayer;
battlePlayer.OnPostTurnEndComplete = (Action)Delegate.Combine(battlePlayer.OnPostTurnEndComplete, (Action)delegate
{
if (turnEndTimeController != null)
{
turnEndTimeController.EndCountDown("AIOnTurnEndComplete");
}
SendTurnEndAction();
});
BattleEnemy.OnTurnStartBeforeDraw += delegate
{
if (!IsVirtualBattle)
{
_aiTurnControl.StartTurnTimer();
}
return NullVfx.GetInstance();
};
BattleEnemy battleEnemy = BattleEnemy;
battleEnemy.OnPostTurnEndComplete = (Action)Delegate.Combine(battleEnemy.OnPostTurnEndComplete, (Action)delegate
{
if (!IsVirtualBattle)
{
_aiTurnControl.StopTurnTimer();
}
});
}
public override void InitiateGameEndSequence(bool hasWon)
{
if (ToolboxGame.RealTimeNetworkAgent != null && ToolboxGame.RealTimeNetworkAgent.PlayerNetworkStatus.IsAlive)
{
if (!_sendFinshBattleTask)
{
_sendFinshBattleTask = true;
_isWin = hasWon;
BattleFinishToEffectClear();
BattleFinishToStopIntervalChecker();
ToolboxGame.RealTimeNetworkAgent.FinishBattleTask(this);
}
}
else
{
_initiateGameEndFunc = InstantVfx.Create(delegate
{
InitiateGameEndSequence(hasWon);
});
}
}
public override void FinishBattleEffect(bool classDead)
{
classDead = !_isWin;
if (classDead)
{
BattleCardBase battleCardBase = GetBattlePlayer(classDead).Class;
if (battleCardBase.Life >= 1 && !battleCardBase.IsDead)
{
battleCardBase.FlagCardAsDestroyedByKiller();
FINISH_TYPE finishTypeByStatus = GetFinishTypeByStatus();
base.VfxMgr.RegisterSequentialVfx(DeadClass(classDead, finishTypeByStatus));
}
}
base.VfxMgr.RegisterSequentialVfx(InstantVfx.Create(delegate
{
base.InitiateGameEndSequence(!classDead);
}));
}
public override VfxBase JudgeBattleResult()
{
if (BattlePlayer.Class.IsDead && BattleEnemy.Class.IsDead)
{
return InstantVfx.Create(delegate
{
InitiateGameEndSequence(!BattlePlayer.IsSelfTurn);
});
}
if (BattlePlayer.Class.IsDead)
{
return InstantVfx.Create(delegate
{
InitiateGameEndSequence(hasWon: false);
});
}
if (BattleEnemy.Class.IsDead)
{
return InstantVfx.Create(delegate
{
InitiateGameEndSequence(hasWon: true);
});
}
return NullVfx.GetInstance();
}
protected override void SetupEvent()
{
base.SetupEvent();
BattlePlayer.OnShortageDeck += () => OnShortageDeck(BattlePlayer);
BattleEnemy.OnShortageDeck += () => OnShortageDeck(BattleEnemy);
SetUpTurnTransitionEvent();
}
private void SetUpTurnTransitionEvent()
{
BattlePlayer.OnTurnEndFinish += delegate
{
if (IsVirtualBattle || base.IsRecovery)
{
return NullVfx.GetInstance();
}
_turnTransitionFunc = null;
_turnTransitionFunc = (Func<VfxBase>)Delegate.Combine(_turnTransitionFunc, new Func<VfxBase>(base.ControlTurnStartOpponent));
return NullVfx.GetInstance();
};
BattleEnemy.OnTurnEndFinish += delegate
{
if (IsVirtualBattle || base.IsRecovery)
{
return NullVfx.GetInstance();
}
_turnTransitionFunc = null;
_turnTransitionFunc = (Func<VfxBase>)Delegate.Combine(_turnTransitionFunc, new Func<VfxBase>(base.ControlTurnStartPlayer));
return NullVfx.GetInstance();
};
}
protected override void SetupBattlePlayerRegisterEvents(BattlePlayerBase battlePlayer)
{
}
protected override void SetupNetworkActionProcessorEvent(ActionProcessor processor, bool isPlayer)
{
}
public override void SetupFieldAndHandAfterRecovery(Action onEndRecoveryCallback, RecoveryOperationInfo aiBattleRecoveryData = null)
{
if (aiBattleRecoveryData.SetupInfo.HasMulliganInfo)
{
BattlePlayer.PlayerBattleView.ClearPlayQueue();
BattleEnemy.BattleEnemyView.ClearPlayQueue();
RecreateCardViews(BattlePlayer.InPlayCards);
RecreateCardViews(BattlePlayer.HandCardList);
RecreateCardViews(BattlePlayer.DeckCardList);
RecreateCardViews(BattlePlayer.ReservedCardList);
RecreateCardViews(BattleEnemy.InPlayCards);
RecreateCardViews(BattleEnemy.HandCardList);
RecreateCardViews(BattleEnemy.DeckCardList);
RecreateCardViews(BattleEnemy.ReservedCardList);
RefreshHealthVfx refreshHealthVfx = new RefreshHealthVfx(BattlePlayer);
RefreshHealthVfx refreshHealthVfx2 = new RefreshHealthVfx(BattleEnemy);
ParallelVfxPlayer parallelVfxPlayer = ParallelVfxPlayer.Create(BattlePlayer.BattleView.Recovery(doseFirst: false), BattleEnemy.BattleView.Recovery(doseFirst: false), refreshHealthVfx, refreshHealthVfx2);
VfxBase vfxBase = (BattleEnemy.IsSelfTurn ? BattleEnemy.CreateThinkingVfx(this) : NullVfx.GetInstance());
SequentialVfxPlayer vfx = SequentialVfxPlayer.Create(RecoveryAfterMulliganPhase.RestoreUI(this), parallelVfxPlayer, HandViewBase.CreateHideCardMeshesVfx(BattleEnemy.HandCardList), vfxBase, InstantVfx.Create(delegate
{
ResetLeaderAnimation(BattlePlayer, BattleEnemy);
}));
base.VfxMgr.RegisterSequentialVfx(vfx);
}
}
public override void RecoveryEnd()
{
base.IsRecovery = false;
SettingOpponentAliveEvent();
IsStopIntervalCheck = false;
SetUpTurnTransitionEvent();
networkTouchControl.SetEnableTouch();
NetworkBattleData networkBattleData = base.networkBattleData;
base.networkBattleData = new NetworkBattleData(this);
base.networkBattleData.isPlayerMulliganEnd = networkBattleData.isPlayerMulliganEnd;
base.networkBattleData.isOppoMulliganEnd = networkBattleData.isOppoMulliganEnd;
base.networkBattleData.SetReceiveData(networkBattleData.GetReceiveData());
base.networkBattleData.isEnemyFirstTurn = networkBattleData.isEnemyFirstTurn;
_networkBattleSetupCardEventBase.OverwriteNetworkBattleData(base.networkBattleData);
SetupCreateBattleCardFunc(createCardWithoutGameObject: false);
OperateMgr operateMgr = OperateMgr;
OperateMgr = CreateOperateMgr();
OperateMgr.SetUpRecoveryEvent(operateMgr);
StartRecoveryRecording();
operateMgr = null;
OperateReceive = new OperateReceive(this, RegisterActionManager, OperateMgr, base.networkBattleData);
if (_phase is NetworkMulliganPhase)
{
(_phase as NetworkMulliganPhase).MulliganEventSetting();
}
operateReceiveChecker = new OperateReceiveChecker(this, base.networkBattleData);
networkReceiver = new NetworkBattleReceiver(this);
SetupNetworkEvent(isRecovery: true);
if (_specialWinVfx == null)
{
ClearRegisterCardList();
}
BattleEnemy.EnableEnemyAI = true;
BattlePlayer.Emotion.Enable = true;
BattleEnemy.Emotion.Enable = true;
if (BattleEnemy.IsSelfTurn)
{
EnemyAI.StopEnemyAI();
EnemyAI.ExecuteEnemyAI(useWait: true);
}
ConnectionReportTrigger.ConnectionReport(this);
}
protected override void FirstRecoverySetting()
{
if (!base.IsRecovery)
{
StartRecoveryRecording();
}
}
protected override int CreateBackgroundId()
{
if (_contentsCreator is RecoveryNetworkBattleMgrContentsCreator)
{
int backGroundId = ((RecoveryNetworkBattleMgrContentsCreator)_contentsCreator).RecoveryControllerInstance.AIBattleRecoveryData.SetupInfo.BackGroundId;
if (backGroundId >= 0)
{
return backGroundId;
}
}
return CalculationRandomStage();
}
public override void FinishBattle()
{
EnemyAI.StopEnemyAI();
}
public override void RecoveryTimeOutSetting(float extendTime, bool isMulliganEnd, long startTime = -1L)
{
if (!isMulliganEnd)
{
if (MulliganMgr != null)
{
MulliganMgr.GetMulliganInfo().SetExtendTime(extendTime);
}
return;
}
if (!BattlePlayer.IsSelfTurn)
{
if (startTime != -1)
{
_aiTurnControl.SetAndStartTurnTimer(DateTimeOffset.FromUnixTimeSeconds(startTime).LocalDateTime);
}
return;
}
if (turnEndTimeController == null)
{
TurnEndButtonUI component = SBattleLoad.m_TurnEndBtnUI.GetComponent<TurnEndButtonUI>();
turnEndTimeController = new TurnEndTimeController(this, BattlePlayer, component);
}
if (!turnEndTimeController.IsCountdownRunning())
{
turnEndTimeController.StartCountDown("SetTimeoutSetting");
}
turnEndTimeController.SetExtendTime(extendTime);
}
public void SetupMulliganLaunchCompleteEvent()
{
_contentsCreator.RecoveryRecordManager.SetupMulliganStartTimeRecorderEvent(this);
}
public override VfxBase StartBattle()
{
SequentialVfxPlayer sequentialVfxPlayer = SequentialVfxPlayer.Create();
LocalLog.SetLastTraceLogTurn(1);
sequentialVfxPlayer.Register(ChangePhase(base.PhaseCreator.CreateMainPhase()));
if (IsFirst)
{
sequentialVfxPlayer.Register(BattlePlayer.StartTurnControl("AIFirst"));
}
else
{
sequentialVfxPlayer.Register(BattleEnemy.StartTurnControl());
}
return sequentialVfxPlayer;
}
public override void SetupEnemyAI()
{
EnemyAI enemyAI = new RankMatchEnemyAI();
enemyAI.LoadBufferedBattleState();
EnemyAI = enemyAI;
BattleInfoReceiver = new AIBattleInfoReceiver(EnemyAI);
EnemyAI.InitOnGame(BattleEnemy, BattlePlayer);
if (!base.IsRecovery)
{
BattleEnemy.EnableEnemyAI = true;
}
}
public override BattleCardBase MetamorphoseCard(int cardId, bool isPlayer, int addIndex, SkillBase skill, bool isFusion = false)
{
return CreateBattleCardWithGameObject(new CardCreateInfo(cardId, isPlayer, skill.ApplyingTargetFilter is SkillTargetChosenCardsFilter, NetworkBattleDefine.NetworkCardPlaceState.None, isReferenceOpponentCard: false, skill), new IndexInfo(addIndex));
}
public override BattleCardBase CreateBattleCardWithGameObject(CardCreateInfo info, IndexInfo indexInfo, int repeatCount = -1, bool isVirtual = false, bool isActualCard = false)
{
CardParameter cardParameterFromId = CardMaster.GetInstanceForBattle().GetCardParameterFromId(info.Id);
BattlePlayerBase battlePlayer = GetBattlePlayer(info.IsPlayer);
int cardIndex = SetupCardIndex(battlePlayer, indexInfo.AddIndex);
GameObject cardGameObject = null;
if (!base.IsRecovery || !isVirtual)
{
cardGameObject = CreateBaseCardGameObject(cardParameterFromId, info.IsPlayer, cardIndex);
}
BattleCardBase battleCardBase = CreateBattleCard(info.Id, info.IsPlayer, cardGameObject, cardParameterFromId, battlePlayer, cardIndex);
if (!base.IsRecovery || !isVirtual)
{
SetupCardObjectMaterials(cardGameObject, battleCardBase);
}
return battleCardBase;
}
protected override void ControlDisconnectOffTouchAndView(bool flag)
{
if (!_sendFinshBattleTask)
{
base.ControlDisconnectOffTouchAndView(flag);
}
}
public override void PlayRetire()
{
if (RecoveryRecordManagerBase.IsExistsAINetworkRecoveryFile())
{
GameMgr.GetIns().GetDataMgr().SetRecoveryData(RecoveryOperationInfo.ReadRecoveryFile(OperationRecorderBase.RecordDirectoryPath + "recovery_ai_network.json"));
RecoveryRecordManagerBase.DeleteRecoveryFile();
}
base.PlayRetire();
}
}

View File

@@ -0,0 +1,31 @@
using System.Collections.Generic;
namespace Wizard;
public static class AINotBeAttackedSimulationUtility
{
public static void GiveNotBeAttackedToAll(List<AIVirtualCard> targets)
{
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (!aIVirtualCard.IsIndependent)
{
aIVirtualCard.NotBeAttacked();
}
}
}
public static void GiveNotBeAttackedToTargeted(AISituationInfo situation, AIScriptTokenArgType whichTarget)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
AIConsoleUtility.LogError("GiveNotBeAttackedToTargeted error! No target!");
}
else
{
GiveNotBeAttackedToAll(situationTarget.Targets);
}
}
}

View File

@@ -0,0 +1,134 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIOneMoreLastwordUtility
{
public static bool IsHoldingOneMoreLastword(AIVirtualCard tagOwner, AIVirtualField field)
{
if (!tagOwner.TagCollectionContainer.HasTag(AIPlayTagType.OneMoreLastword))
{
return false;
}
return tagOwner.TagCollectionContainer.OneMoreLastwordTags.CheckCondition(tagOwner, field);
}
private static bool IsOneMoreLastwordHolderInplay(AIVirtualField field, List<int> enemyTargets, ref int holderIndex, ref float threshold)
{
for (int i = 0; i < enemyTargets.Count; i++)
{
AIVirtualCard owner = field.EnemyInplayCards[enemyTargets[i]];
if (IsGiveTagOfOneMoreLastwordTagged(field, owner, ref threshold))
{
holderIndex = i;
return true;
}
}
return false;
}
public static void SortEnemyTargetByBreakBonus(AIVirtualField field, List<int> enemyTargets)
{
if (IsHoldingOneMoreLastword(field.EnemyClass, field))
{
SortEnemyTargetsWhenLeaderTaggedOneMoreLastword(field, enemyTargets);
return;
}
float threshold = 0f;
int holderIndex = -1;
if (IsOneMoreLastwordHolderInplay(field, enemyTargets, ref holderIndex, ref threshold))
{
SortEnemyTargetsWhenOneMoreLastwordHolderInplay(field, enemyTargets, holderIndex, threshold);
}
}
private static void SortEnemyTargetsWhenLeaderTaggedOneMoreLastword(AIVirtualField field, List<int> enemyTargets)
{
float num = float.MaxValue;
int num2 = -1;
for (int i = 0; i < enemyTargets.Count; i++)
{
AIVirtualCard aIVirtualCard = field.EnemyInplayCards[enemyTargets[i]];
if (aIVirtualCard.TagCollectionContainer.HasTagCollection(TagCollectionType.Lastword))
{
float num3 = aIVirtualCard.EvaluateBreakValue(field.BestPlayPtn, useIgnoreBreak: true);
if (num3 < num)
{
num = num3;
num2 = i;
}
}
}
if (num2 > 0)
{
int value = enemyTargets[num2];
for (int num4 = num2; num4 > 0; num4--)
{
enemyTargets[num4] = enemyTargets[num4 - 1];
}
enemyTargets[0] = value;
}
}
private static void SortEnemyTargetsWhenOneMoreLastwordHolderInplay(AIVirtualField field, List<int> enemyTargets, int holderIndex, float breakBonusThreshold)
{
List<int> list = new List<int>();
List<int> list2 = new List<int>();
float num = float.MaxValue;
for (int i = 0; i < enemyTargets.Count; i++)
{
if (i == holderIndex)
{
continue;
}
int num2 = enemyTargets[i];
AIVirtualCard aIVirtualCard = field.EnemyInplayCards[num2];
if (!aIVirtualCard.TagCollectionContainer.HasTagCollection(TagCollectionType.Lastword) && !aIVirtualCard.TagCollectionContainer.HasTag(AIPlayTagType.Break))
{
list2.Add(num2);
continue;
}
float num3 = aIVirtualCard.EvaluateBreakValue(field.BestPlayPtn, useIgnoreBreak: true);
if (num3 >= breakBonusThreshold)
{
list.Add(num2);
}
else if (num3 <= num)
{
num = num3;
list2.Insert(0, num2);
}
else
{
list2.Add(num2);
}
}
list.Add(enemyTargets[holderIndex]);
enemyTargets.Clear();
enemyTargets.AddRange(list);
enemyTargets.AddRange(list2);
}
private static bool IsGiveTagOfOneMoreLastwordTagged(AIVirtualField field, AIVirtualCard owner, ref float threshold)
{
if (!owner.TagCollectionContainer.HasTag(AIPlayTagType.LastwordAttachTag))
{
return false;
}
List<AIPlayTag> lastwordAttachTagContents = owner.TagCollectionContainer.LastwordTags.GetLastwordAttachTagContents();
if (lastwordAttachTagContents == null || lastwordAttachTagContents.Count <= 0)
{
return false;
}
for (int i = 0; i < lastwordAttachTagContents.Count; i++)
{
AIPlayTag aIPlayTag = lastwordAttachTagContents[i];
if (aIPlayTag.Type == AIPlayTagType.OneMoreLastword)
{
threshold = aIPlayTag.EvalArg(field.EnemyClass, field.BestPlayPtn, field, null);
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,19 @@
namespace Wizard;
public class AIPlayBounce : AIFiltersAndSelectTypeArgument
{
public AIPlayBounce(string text)
: base(text)
{
}
protected override void CreateLegalSelectTypes()
{
base.LegalSelectTypes = new AIScriptTokenArgType[3]
{
AIScriptTokenArgType.ALL_SELECT,
AIScriptTokenArgType.RANDOM_SELECT,
AIScriptTokenArgType.TARGET_SELECT
};
}
}

View File

@@ -0,0 +1,47 @@
using System.Collections.Generic;
namespace Wizard;
public class AIPlayReanimate : AIScriptArgumentExpressions
{
private AIPolishConvertedExpression _reanimateCostArg;
private AIPolishConvertedExpression _reanimateCountArg;
private const int REANIMATE_COST_INDEX = 0;
private const int REANIMATE_COUNT_INDEX = 1;
public AIPlayReanimate(string text)
: base(text)
{
}
protected override void InitExpressions(string text)
{
base.InitExpressions(text);
if (_exprList.Count > 1)
{
_reanimateCostArg = _exprList[0];
_reanimateCountArg = _exprList[1];
}
}
public int GetReanimateCost(AIVirtualCard tagOwner, List<int> playPtn)
{
if (_reanimateCostArg == null)
{
return -1;
}
return (int)_reanimateCostArg.EvalArg(tagOwner, playPtn, tagOwner.SelfField);
}
public int GetReanimateCount(AIVirtualCard tagOwner, List<int> playPtn)
{
if (_reanimateCountArg == null)
{
return 0;
}
return (int)_reanimateCountArg.EvalArg(tagOwner, playPtn, tagOwner.SelfField);
}
}

View File

@@ -0,0 +1,94 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public static class AIPlayerLifeSimulationUtility
{
public static int GetAllSelfTurnDamageCount(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AIScriptTokenArgType durationType)
{
return GetSelfTurnDamageCountAtPlayed(tagOwner, field, playPtn, durationType) + GetSelfTurnDamageCountAtPlayPtn(tagOwner, field, playPtn);
}
public static int GetSelfTurnDamageCountAtPlayed(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AIScriptTokenArgType durationType)
{
int num = 0;
if (!tagOwner.IsAlly)
{
_ = field.EnemyBattlePlayer;
}
else
{
_ = field.AllyBattlePlayer;
}
return durationType switch
{
AIScriptTokenArgType.TURN => field.AllyDamageCountInTurn,
AIScriptTokenArgType.GAME => tagOwner.IsAlly ? field.AllyDamageCountInGame : field.EnemyDamageCountInGame,
_ => num,
};
}
public static int GetSelfTurnDamageCountAtPlayPtn(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn)
{
if (!tagOwner.IsAlly)
{
return 0;
}
int num = 0;
IEnumerable<SkillBase> enumerable = null;
for (int i = 0; i < playPtn.Count; i++)
{
enumerable = GetSelfInjurySkillsOnPlay(field.AllyHandCards[playPtn[i]], field);
if (enumerable != null)
{
num += enumerable.Count();
}
}
return num;
}
public static int GetSelfTurnDamageCountAtBeforePlayPtn(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AIScriptTokenArgType durationType)
{
if (!tagOwner.IsAlly)
{
return 0;
}
int num = 0;
IEnumerable<SkillBase> enumerable = null;
for (int i = 0; i < playPtn.Count && !tagOwner.IsSameCard(field.AllyHandCards[playPtn[i]]); i++)
{
enumerable = GetSelfInjurySkillsOnPlay(field.AllyHandCards[playPtn[i]], field);
if (enumerable != null)
{
num += enumerable.Count();
}
}
return num + GetSelfTurnDamageCountAtPlayed(tagOwner, field, playPtn, durationType);
}
public static IEnumerable<SkillBase> GetSelfInjurySkillsOnPlay(AIVirtualCard card, AIVirtualField field)
{
foreach (SkillBase battleSkill in card.BattleSkills)
{
if (!(battleSkill is Skill_damage) || !battleSkill.IsWhenPlaySkill)
{
continue;
}
BattlePlayerReadOnlyInfoPair playerInfoPair = new BattlePlayerReadOnlyInfoPair(field.AllyBattlePlayer, field.EnemyBattlePlayer);
if (!battleSkill.CheckConditionAI(playerInfoPair, new SkillConditionCheckerOption(), isPrePlay: true))
{
continue;
}
IEnumerable<BattleCardBase> selectableCards = battleSkill.GetSelectableCards(playerInfoPair, new SkillConditionCheckerOption());
foreach (BattleCardBase item in selectableCards)
{
if (item == field.AllyBattlePlayer.Class)
{
yield return battleSkill;
break;
}
}
}
}
}

View File

@@ -0,0 +1,73 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIPlayoutAttackerCountUtility
{
public static int GetPlayoutAttackerCount(AIVirtualField field, AIVirtualCard tagOwner, List<int> playPtn, List<AIScriptTokenBase> filters, AISituationInfo situation)
{
int num = 0;
for (int i = 0; i < field.AllyInplayCards.Count; i++)
{
if (IsPlayoutAttacker(field.AllyInplayCards[i], field, filters, playPtn, tagOwner, situation))
{
num++;
}
}
AISinglePlayptnRecord playptnRecordOnSim = field.GetPlayptnRecordOnSim(playPtn);
for (int j = 0; j < playPtn.Count; j++)
{
AIVirtualCard aIVirtualCard = field.AllyHandCards[playPtn[j]];
if (aIVirtualCard == null)
{
continue;
}
if (IsPlayoutAttacker(aIVirtualCard, field, filters, playPtn, tagOwner, situation))
{
num++;
}
AIVirtualCard actor = aIVirtualCard;
if (playptnRecordOnSim != null)
{
PlayedCardInfo playedCardInfo = playptnRecordOnSim.PlayedCardList[j];
actor = ((playedCardInfo.TransformCard != null) ? playedCardInfo.TransformCard : aIVirtualCard);
}
AIVirtualTargetSelectAction aIVirtualTargetSelectAction = new AIVirtualTargetSelectAction(actor, aIVirtualCard, AIOperationType.PLAY, (AISelectedTargetInfoSet)null);
aIVirtualTargetSelectAction.forceLethalMode = true;
List<AITokenInformation> allySideTokenIdsOfPlaySituation = AIPlayTokenSimulationUtility.GetAllySideTokenIdsOfPlaySituation(field, playPtn, aIVirtualTargetSelectAction);
if (allySideTokenIdsOfPlaySituation == null || allySideTokenIdsOfPlaySituation.Count <= 0)
{
continue;
}
for (int k = 0; k < allySideTokenIdsOfPlaySituation.Count; k++)
{
if (IsPlayoutAttacker(field.AI.tokenManager.GetTokenFromId(allySideTokenIdsOfPlaySituation[k].TokenId, isAlly: true, field), field, filters, playPtn, tagOwner, situation))
{
num++;
}
}
if (num >= 6)
{
break;
}
}
return num;
}
private static bool IsPlayoutAttacker(AIVirtualCard card, AIVirtualField field, List<AIScriptTokenBase> filters, List<int> playPtn, AIVirtualCard tagOwner, AISituationInfo situation)
{
if (!card.IsAlly || !card.IsOnField)
{
return false;
}
if (!card.IsUnit || card.IsDead || !AIAttackSimulationUtility.IsAttackPossible(field, card.AttackLeaderSituation))
{
return false;
}
if (!AIFilteringUtility.CheckMatchTargetFiltering(card, field.AllyInplayCards, filters, playPtn, tagOwner, situation))
{
return false;
}
return true;
}
}

View File

@@ -0,0 +1,36 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIRallySimulationUtility
{
public static void ExecuteAppendRallyCount(AIVirtualField field, AIVirtualCard summonCard)
{
if (summonCard != null && CanAppendRallyCount(field, summonCard))
{
field.AddRallyCount(1, summonCard.IsAlly);
}
}
public static bool CanAppendRallyCount(AIVirtualField field, AIVirtualCard summonCard)
{
if (summonCard.IsUnit)
{
return true;
}
List<AIVirtualCard> tagHolders = field.CardListSet.GetTagHolders(CardListsForReference.TagHolderReferenceType.RallyCountPlus);
if (tagHolders == null)
{
return false;
}
for (int i = 0; i < tagHolders.Count; i++)
{
AIVirtualCard aIVirtualCard = tagHolders[i];
if (aIVirtualCard.TagCollectionContainer.RallyCountPlusTags.CanAppendRallyCount(aIVirtualCard, summonCard))
{
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,733 @@
using System.Collections.Generic;
using System.Linq;
using Cute;
using UnityEngine;
namespace Wizard;
public static class AIRandomMultiDamageEvaluator
{
private struct DamageSituationInfo
{
public AIVirtualCard TagOwner;
public AIVirtualField Field;
public List<int> PlayPtn;
public bool IsAlly;
public bool IsSpell;
public int DamageAmount;
public int DamageCount;
public List<AIBarrierPseudoSimulationInfo> BarrierSimList;
}
private class RandomDamageSimulationResult
{
public float BreakValue;
public List<int> RestLifeList;
public List<AIBarrierPseudoSimulationInfo> BarrierSimulationList;
}
private class CardValueInformationForEvalRandomMultiDamage
{
public float BreakValue;
public float BattleBonusRate;
}
public static void CreateEvalRandomDamageArgList(List<AIScriptTokenBase> src, out List<AIScriptTokenBase> filters, out int damage, out int count)
{
filters = src.GetRange(0, src.Count - 2);
damage = (int)src[src.Count - 2].Value;
count = (int)src[src.Count - 1].Value;
}
private static float CalcSingleTargetEvaluation(AIVirtualCard target, AIVirtualField field, List<int> playPtn, AISituationInfo situation, bool ownerIsAlly, int damageAmount, bool isSpellDamage)
{
float num = 0f;
int num2 = target.SimulateDamageAmount(damageAmount, isSkillDamage: true, isSpellDamage);
int num3 = target.Life - num2;
if (target.IsLeader)
{
return AILeaderLifeEvaluationUtility.Evaluate(num3, target.Life, target.IsAlly, ownerIsAlly);
}
if (num3 > 0)
{
float num4 = field.StyleQuery.GetUnitRate(field, target, playPtn) * target.EvaluateAllBattleBonusRate(playPtn, useOthersTag: true, useIgnoreInBattle: false, situation);
num = (float)num2 * num4;
}
else
{
num = target.EvaluateValueOnField(playPtn, situation, useStyle: true) - target.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) - target.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false, situation);
}
return num * (target.IsAlly ? (-1f) : 1f);
}
public static float EvaluateRandomDamageAverage(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> filters, int damageAmount, int damageCount)
{
if (damageCount < 0)
{
AIConsoleUtility.LogError("EvaluateRandomMultiDamageAverage() error!! damageCount < 0");
return 0f;
}
if (damageCount == 1)
{
return EvaluateSingleTargetAverage(tagOwner, field, playPtn, situation, filters, damageAmount);
}
return EvaluateMultiTargetsAverage(tagOwner, playPtn, field, filters, situation, damageAmount, damageCount);
}
private static float EvaluateSingleTargetAverage(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> filters, int damageAmount)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, situation);
if (list == null || list.Count <= 0)
{
return 0f;
}
list.RemoveAll((AIVirtualCard c) => !c.IsUnit && !c.IsLeader);
if (list.Count <= 0)
{
return 0f;
}
bool isSpellDamage = tagOwner.IsSpell || tagOwner.IsAccelerated(field, playPtn, situation);
float num = 0f;
for (int num2 = 0; num2 < list.Count; num2++)
{
float num3 = CalcSingleTargetEvaluation(list[num2], field, playPtn, situation, tagOwner.IsAlly, damageAmount, isSpellDamage);
num += num3;
}
return num / (float)list.Count;
}
private static float EvaluateMultiTargetsAverage(AIVirtualCard tagOwner, List<int> playPtn, AIVirtualField field, List<AIScriptTokenBase> filters, AISituationInfo situation, int damageAmount, int damageCount)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, null);
list.RemoveAll((AIVirtualCard c) => c.IsAmulet);
if (!list.IsNotNullOrEmpty())
{
return 0f;
}
int count = list.Count;
SeparateTargetCardBySide(list, out var allyInplays, out var enemyInplays, out var allyLeader, out var enemyLeader);
int num = damageCount / count;
int num2 = ((allyLeader != null) ? num : 0);
int num3 = ((enemyLeader != null) ? num : 0);
int num4 = ((allyInplays != null && allyInplays.Count > 0) ? ((damageCount - num2 - num3) / 2) : 0);
int num5 = ((enemyInplays != null && enemyInplays.Count > 0) ? ((damageCount - num2 - num3) / 2) : 0);
int num6 = damageCount - (num2 + num4 + num3 + num5);
if (num6 > 0)
{
if (enemyLeader != null)
{
num3 += num6;
}
else if (enemyInplays.IsNotNullOrEmpty())
{
num5 += num6;
}
else if (allyInplays.IsNotNullOrEmpty())
{
num4 += num6;
}
else if (allyLeader != null)
{
num2 += num6;
}
}
num6 = 0;
DamageSituationInfo damageSituation = new DamageSituationInfo
{
DamageAmount = field.DamageModifierCollection.CalcModifiedDamage(field, playPtn, situation, tagOwner, damageAmount),
TagOwner = tagOwner,
Field = field,
PlayPtn = playPtn,
IsSpell = (tagOwner.IsSpell || tagOwner.IsAccelerated(field, playPtn))
};
Dictionary<AIVirtualCard, CardValueInformationForEvalRandomMultiDamage> cardValueList = CreateCardValueInformationDictionary(allyInplays, field, playPtn, situation);
Dictionary<AIVirtualCard, CardValueInformationForEvalRandomMultiDamage> cardValueList2 = CreateCardValueInformationDictionary(enemyInplays, field, playPtn, situation);
List<AIBarrierPseudoSimulationInfo> barrierSimList = new List<AIBarrierPseudoSimulationInfo>(field.CardListSet.BothClassAndInplayCards.Select((AIVirtualCard c) => new AIBarrierPseudoSimulationInfo(c)));
List<AIBarrierPseudoSimulationInfo> barrierSimList2 = new List<AIBarrierPseudoSimulationInfo>(field.CardListSet.BothClassAndInplayCards.Select((AIVirtualCard c) => new AIBarrierPseudoSimulationInfo(c)));
damageSituation.IsAlly = false;
float num7 = 0f;
RandomDamageSimulationResult randomDamageSimulationResult = new RandomDamageSimulationResult();
RandomDamageSimulationResult randomDamageSimulationResult2 = new RandomDamageSimulationResult();
if (enemyInplays.IsNotNullOrEmpty())
{
damageSituation.DamageCount = num5;
damageSituation.BarrierSimList = barrierSimList2;
List<int> targetLifeList = GetTargetLifeList(enemyInplays);
randomDamageSimulationResult = EvalWorstInplayRandomDamage(enemyInplays, targetLifeList, cardValueList2, damageSituation, situation, ref num6);
if (randomDamageSimulationResult.RestLifeList.Sum() == 0)
{
randomDamageSimulationResult2.BreakValue = randomDamageSimulationResult.BreakValue;
}
else
{
randomDamageSimulationResult2 = EvalBestInplayRandomDamage(enemyInplays, targetLifeList, cardValueList2, damageSituation, situation, ref num6);
}
}
float num8 = 0f;
int restLife = enemyLeader?.Life ?? 0;
if (enemyLeader != null)
{
damageSituation.DamageCount = num3 + num6;
damageSituation.BarrierSimList = barrierSimList;
num8 = EvalRandomMultiDamageToLeader(enemyLeader, damageSituation, tagOwner.IsAlly, ref restLife, out num6);
}
damageSituation.IsAlly = true;
float num9 = 0f;
if (allyInplays.IsNotNullOrEmpty())
{
damageSituation.DamageCount = num4 + num6;
damageSituation.BarrierSimList = barrierSimList2;
List<int> targetLifeList2 = GetTargetLifeList(allyInplays);
RandomDamageSimulationResult randomDamageSimulationResult3 = EvalWorstInplayRandomDamage(allyInplays, targetLifeList2, cardValueList, damageSituation, situation, ref num6);
float breakValue = randomDamageSimulationResult3.BreakValue;
num9 = ((randomDamageSimulationResult3.RestLifeList.Sum() != 0) ? ((EvalBestInplayRandomDamage(allyInplays, targetLifeList2, cardValueList, damageSituation, situation, ref num6).BreakValue + breakValue) / 2f) : breakValue);
}
float num10 = 0f;
if (allyLeader != null)
{
int restLife2 = allyLeader.Life;
damageSituation.DamageCount = num2 + num6;
damageSituation.BarrierSimList = barrierSimList;
num10 = EvalRandomMultiDamageToLeader(allyLeader, damageSituation, tagOwner.IsAlly, ref restLife2, out num6);
}
if (num6 > 0)
{
damageSituation.IsAlly = false;
if (enemyInplays.IsNotNullOrEmpty())
{
damageSituation.DamageCount = num6;
damageSituation.BarrierSimList = randomDamageSimulationResult.BarrierSimulationList;
RandomDamageSimulationResult randomDamageSimulationResult4 = EvalWorstInplayRandomDamage(enemyInplays, randomDamageSimulationResult.RestLifeList, cardValueList2, damageSituation, situation, ref num6);
randomDamageSimulationResult.BreakValue += randomDamageSimulationResult4.BreakValue;
if (randomDamageSimulationResult4.RestLifeList.Sum() == 0)
{
randomDamageSimulationResult2.BreakValue = randomDamageSimulationResult.BreakValue;
}
else
{
damageSituation.BarrierSimList = randomDamageSimulationResult2.BarrierSimulationList;
randomDamageSimulationResult2.BreakValue += EvalBestInplayRandomDamage(enemyInplays, randomDamageSimulationResult2.RestLifeList, cardValueList2, damageSituation, situation, ref num6).BreakValue;
}
}
if (num6 > 0 && enemyLeader != null && restLife > 0)
{
damageSituation.DamageCount = num6;
damageSituation.BarrierSimList = barrierSimList;
num8 += EvalRandomMultiDamageToLeader(enemyLeader, damageSituation, tagOwner.IsAlly, ref restLife, out num6);
}
}
num7 = (randomDamageSimulationResult2.BreakValue + randomDamageSimulationResult.BreakValue) / 2f;
return num8 + num7 + num10 + num9;
}
public static float EvaluateRandomDamageMax(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, List<AIScriptTokenBase> filters, AISituationInfo situation, int damageAmount, int damageCount)
{
if (damageCount < 0)
{
AIConsoleUtility.LogError("EvaluateRandomMultiDamageAverage() error!! damageCount < 0");
return 0f;
}
if (damageCount == 1)
{
return EvaluateSingleTargetMax(tagOwner, field, playPtn, situation, filters, damageAmount);
}
return EvaluateMultiTargetsMax(tagOwner, playPtn, field, filters, situation, damageAmount, damageCount);
}
private static float EvaluateSingleTargetMax(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> filters, int damageAmount)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, situation);
if (list == null || list.Count <= 0)
{
return 0f;
}
list.RemoveAll((AIVirtualCard c) => !c.IsUnit && !c.IsLeader);
if (list.Count <= 0)
{
return 0f;
}
bool flag = false;
bool isSpellDamage = tagOwner.IsSpell || tagOwner.IsAccelerated(field, playPtn, situation);
float num = float.MinValue;
for (int num2 = 0; num2 < list.Count; num2++)
{
float num3 = CalcSingleTargetEvaluation(list[num2], field, playPtn, situation, tagOwner.IsAlly, damageAmount, isSpellDamage);
if (num3 > num)
{
num = num3;
}
flag = true;
}
if (!flag)
{
num = 0f;
}
return num;
}
private static float EvaluateMultiTargetsMax(AIVirtualCard tagOwner, List<int> playPtn, AIVirtualField field, List<AIScriptTokenBase> filters, AISituationInfo situation, int damageAmount, int damageCount)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, null);
list.RemoveAll((AIVirtualCard c) => c.IsAmulet);
if (!list.IsNotNullOrEmpty())
{
return 0f;
}
_ = list.Count;
SeparateTargetCardBySide(list, out var allyInplays, out var enemyInplays, out var allyLeader, out var enemyLeader);
DamageSituationInfo damageSituation = new DamageSituationInfo
{
DamageAmount = field.DamageModifierCollection.CalcModifiedDamage(field, playPtn, situation, tagOwner, damageAmount),
TagOwner = tagOwner,
Field = field,
PlayPtn = playPtn,
IsSpell = (tagOwner.IsSpell || tagOwner.IsAccelerated(field, playPtn))
};
Dictionary<AIVirtualCard, CardValueInformationForEvalRandomMultiDamage> cardValueList = CreateCardValueInformationDictionary(allyInplays, field, playPtn, situation);
Dictionary<AIVirtualCard, CardValueInformationForEvalRandomMultiDamage> cardValueList2 = CreateCardValueInformationDictionary(enemyInplays, field, playPtn, situation);
List<AIBarrierPseudoSimulationInfo> barrierSimList = new List<AIBarrierPseudoSimulationInfo>(field.CardListSet.BothClassAndInplayCards.Select((AIVirtualCard c) => new AIBarrierPseudoSimulationInfo(c)));
List<AIBarrierPseudoSimulationInfo> barrierSimList2 = new List<AIBarrierPseudoSimulationInfo>(field.CardListSet.BothClassAndInplayCards.Select((AIVirtualCard c) => new AIBarrierPseudoSimulationInfo(c)));
damageSituation.IsAlly = false;
float num = 0f;
int restDamageCount = damageCount;
if (enemyLeader != null)
{
int restLife = enemyLeader.Life;
damageSituation.DamageCount = restDamageCount;
damageSituation.BarrierSimList = barrierSimList;
num = EvalRandomMultiDamageToLeader(enemyLeader, damageSituation, tagOwner.IsAlly, ref restLife, out restDamageCount);
if (restLife <= 0)
{
return num;
}
}
float num2 = 0f;
int restDamageCount2 = damageCount;
if (enemyInplays != null && enemyInplays.Count > 0)
{
damageSituation.DamageCount = restDamageCount2;
damageSituation.BarrierSimList = barrierSimList2;
List<int> targetLifeList = GetTargetLifeList(enemyInplays);
RandomDamageSimulationResult randomDamageSimulationResult = EvalBestInplayRandomDamage(enemyInplays, targetLifeList, cardValueList2, damageSituation, situation, ref restDamageCount2);
num2 = randomDamageSimulationResult.BreakValue;
if (restDamageCount2 > 0 && enemyLeader != null)
{
int restLife2 = enemyLeader.Life;
damageSituation.DamageCount = restDamageCount2;
damageSituation.BarrierSimList = randomDamageSimulationResult.BarrierSimulationList;
num2 += EvalRandomMultiDamageToLeader(enemyLeader, damageSituation, tagOwner.IsAlly, ref restLife2, out restDamageCount);
if (restLife2 <= 0)
{
return num2;
}
}
}
float num3 = 0f;
if (enemyLeader != null && enemyInplays.IsNotNullOrEmpty())
{
num3 = Mathf.Max(num2, num);
}
else if (enemyLeader != null && !enemyInplays.IsNotNullOrEmpty())
{
num3 = num;
}
else if (enemyLeader == null && enemyInplays.IsNotNullOrEmpty())
{
num3 = num2;
}
if (restDamageCount2 <= 0)
{
return num3;
}
damageSituation.IsAlly = true;
int restDamageCount3 = restDamageCount2;
float num4 = 0f;
if (allyLeader != null)
{
int restLife3 = allyLeader.Life;
damageSituation.DamageCount = restDamageCount3;
damageSituation.BarrierSimList = barrierSimList;
num4 = EvalRandomMultiDamageToLeader(allyLeader, damageSituation, tagOwner.IsAlly, ref restLife3, out restDamageCount3);
}
float num5 = 0f;
int restDamageCount4 = restDamageCount2;
if (allyInplays != null && allyInplays.Count > 0)
{
damageSituation.DamageCount = restDamageCount4;
damageSituation.BarrierSimList = barrierSimList2;
List<int> targetLifeList2 = GetTargetLifeList(allyInplays);
RandomDamageSimulationResult randomDamageSimulationResult2 = EvalWorstInplayRandomDamage(allyInplays, targetLifeList2, cardValueList, damageSituation, situation, ref restDamageCount4);
num5 = randomDamageSimulationResult2.BreakValue;
if (restDamageCount4 > 0 && allyLeader != null)
{
int restLife4 = allyLeader.Life;
damageSituation.DamageCount = restDamageCount4;
damageSituation.BarrierSimList = randomDamageSimulationResult2.BarrierSimulationList;
num4 += EvalRandomMultiDamageToLeader(allyLeader, damageSituation, tagOwner.IsAlly, ref restLife4, out restDamageCount4);
}
}
float num6 = 0f;
if (allyLeader != null && allyInplays.IsNotNullOrEmpty())
{
num6 = Mathf.Max(num5, num4);
}
else if (allyLeader != null && !allyInplays.IsNotNullOrEmpty())
{
num6 = num4;
}
else if (allyLeader == null && allyInplays.IsNotNullOrEmpty())
{
num6 = num5;
}
return num3 + num6;
}
private static RandomDamageSimulationResult EvalWorstInplayRandomDamage(List<AIVirtualCard> targetCards, List<int> targetLifeList, Dictionary<AIVirtualCard, CardValueInformationForEvalRandomMultiDamage> cardValueList, DamageSituationInfo damageSituation, AISituationInfo situation, ref int restDamageCount)
{
restDamageCount = damageSituation.DamageCount;
RandomDamageSimulationResult simResult = new RandomDamageSimulationResult
{
BreakValue = 0f,
RestLifeList = new List<int>(targetLifeList),
BarrierSimulationList = new List<AIBarrierPseudoSimulationInfo>(damageSituation.BarrierSimList.Select((AIBarrierPseudoSimulationInfo info) => new AIBarrierPseudoSimulationInfo(info)))
};
List<AIVirtualCard> list = targetCards.OrderBy((AIVirtualCard c) => cardValueList[c].BreakValue).ToList();
List<int> list2 = list.Select((AIVirtualCard sortedCard) => targetCards.FindIndex((AIVirtualCard originalCard) => originalCard.IsSameCard(sortedCard))).ToList();
List<int> list3 = list2.Select((int index2) => targetLifeList[index2]).ToList();
List<int> list4 = new List<int>(list.Select((AIVirtualCard c) => 0));
List<AIBarrierPseudoSimulationInfo> list5 = list.Select((AIVirtualCard c) => simResult.BarrierSimulationList.Find((AIBarrierPseudoSimulationInfo info) => info.Owner.IsSameCard(c))).ToList();
bool isSpell = damageSituation.IsSpell;
for (int num = 0; num < damageSituation.DamageCount; num++)
{
int num2 = int.MaxValue;
int num3 = -1;
int num4 = 0;
if (list3.Count((int life) => life > 0) == 0)
{
simResult.BreakValue *= (damageSituation.IsAlly ? (-1f) : 1f);
return simResult;
}
int num5 = -1;
for (int num6 = 0; num6 < list.Count; num6++)
{
if (list3[num6] > 0)
{
if (num5 < 0)
{
num5 = num6;
}
int damage = list[num6].SimulateDamageShield(damageSituation.DamageAmount, isSkillDamage: true, isSpell);
damage = list5[num6].SimulateDamageAmount(damage, isSpell);
if (damage > 0 && list3[num6] <= damage)
{
num4++;
}
else if (damage < num2)
{
num2 = damage;
num3 = num6;
}
}
}
if (num4 == list3.Count((int life) => life > 0))
{
num3 = num5;
num2 = list[num3].SimulateDamageShield(damageSituation.DamageAmount, isSkillDamage: true, isSpell);
num2 = list5[num3].SimulateDamageAmount(num2, isSpell);
}
if (0 <= num3)
{
int index = list2[num3];
AIVirtualCard key = list[num3];
list3[num3] = Mathf.Max(0, list3[num3] - num2);
simResult.RestLifeList[index] = list3[num3];
list4[num3]++;
AIBarrierPseudoSimulationInfo targetBarrierInfo = list5[num3];
bool flag = list3[num3] <= 0;
PseudoRemoveBarrierWhenTargetGetDamaged(targetBarrierInfo, simResult.BarrierSimulationList, flag);
if (flag)
{
simResult.BreakValue += cardValueList[key].BreakValue;
}
}
restDamageCount--;
}
for (int num7 = 0; num7 < targetCards.Count; num7++)
{
AIVirtualCard aIVirtualCard = targetCards[num7];
int num8 = list4[num7];
if (aIVirtualCard.TagCollectionContainer.HasTag(AIPlayTagType.DamagedBuff) && num8 > 0 && simResult.RestLifeList[num7] > 0)
{
DamagedTagCollection damagedTags = aIVirtualCard.TagCollectionContainer.DamagedTags;
for (int num9 = 0; num9 < num8; num9++)
{
int atkBuff = 0;
int lifeBuff = 0;
damagedTags.GetDamagedBuffValue(aIVirtualCard, aIVirtualCard.SelfField, damageSituation.PlayPtn, situation, out atkBuff, out lifeBuff);
simResult.RestLifeList[num7] += lifeBuff;
if (simResult.RestLifeList[num7] <= 0)
{
simResult.BreakValue += cardValueList[aIVirtualCard].BreakValue;
break;
}
}
}
if (simResult.RestLifeList[num7] > 0)
{
simResult.BreakValue += aIVirtualCard.Life - simResult.RestLifeList[num7];
}
}
simResult.BreakValue *= (damageSituation.IsAlly ? (-1f) : 1f);
return simResult;
}
private static RandomDamageSimulationResult EvalBestInplayRandomDamage(List<AIVirtualCard> targetCards, List<int> targetLifeList, Dictionary<AIVirtualCard, CardValueInformationForEvalRandomMultiDamage> cardValueList, DamageSituationInfo damageSituation, AISituationInfo situation, ref int restDamageCount)
{
RandomDamageSimulationResult randomDamageSimulationResult = new RandomDamageSimulationResult();
randomDamageSimulationResult.BreakValue = float.MinValue;
int num = (int)Mathf.Pow(2f, targetCards.Count);
for (int i = 0; i < num; i++)
{
List<int> list = new List<int>();
List<int> list2 = new List<int>();
int num2 = i;
for (int j = 0; j < targetCards.Count; j++)
{
int num3 = (int)Mathf.Pow(2f, targetCards.Count - j - 1);
if (num2 / num3 <= 0)
{
list.Add(j);
continue;
}
list2.Add(j);
num2 -= num3;
}
float num4 = 0f;
int damageCount = damageSituation.DamageCount;
List<AIBarrierPseudoSimulationInfo> list3 = new List<AIBarrierPseudoSimulationInfo>(damageSituation.BarrierSimList.Select((AIBarrierPseudoSimulationInfo info) => new AIBarrierPseudoSimulationInfo(info)));
List<int> list4 = new List<int>(targetLifeList);
if (0 < list2.Count)
{
num4 += EvalRandomMultiDamageBreakValue(damageSituation.DamageAmount, ref damageCount, list2, damageSituation.IsSpell, targetCards, damageSituation.PlayPtn, situation, list4, cardValueList, list3);
}
if (0 < damageCount && 0 < list.Count)
{
num4 += EvalRandomMultiDamageBreakValue(damageSituation.DamageAmount, ref damageCount, list, damageSituation.IsSpell, targetCards, damageSituation.PlayPtn, situation, list4, cardValueList, list3);
}
num4 *= (damageSituation.IsAlly ? (-1f) : 1f);
if (randomDamageSimulationResult.BreakValue < num4)
{
randomDamageSimulationResult.BreakValue = num4;
randomDamageSimulationResult.BarrierSimulationList = list3;
randomDamageSimulationResult.RestLifeList = list4;
restDamageCount = damageCount;
}
}
if (randomDamageSimulationResult.RestLifeList == null)
{
randomDamageSimulationResult.RestLifeList = new List<int>(targetLifeList);
}
if (randomDamageSimulationResult.BarrierSimulationList == null)
{
randomDamageSimulationResult.BarrierSimulationList = new List<AIBarrierPseudoSimulationInfo>(damageSituation.BarrierSimList.Select((AIBarrierPseudoSimulationInfo info) => new AIBarrierPseudoSimulationInfo(info)));
}
return randomDamageSimulationResult;
}
private static float EvalRandomMultiDamageBreakValue(int damageAmount, ref int damageCount, List<int> targetIdxList, bool isSpell, List<AIVirtualCard> candidates, List<int> playPtn, AISituationInfo situation, List<int> lifeList, Dictionary<AIVirtualCard, CardValueInformationForEvalRandomMultiDamage> cardValueList, List<AIBarrierPseudoSimulationInfo> removeBarrierSimList)
{
if (lifeList.Sum() == 0)
{
return 0f;
}
float num = 0f;
int num2 = damageCount;
float num3 = 0f;
if (targetIdxList.Count > 0)
{
int num4 = -1;
for (int i = 0; i < targetIdxList.Count; i++)
{
if (lifeList[targetIdxList[i]] > 0)
{
num4 = i;
break;
}
}
if (num4 < 0 || num4 >= targetIdxList.Count)
{
return 0f;
}
int index = targetIdxList[num4];
int num5 = 0;
int num6 = lifeList[index];
AIVirtualCard target = candidates[index];
AIBarrierPseudoSimulationInfo aIBarrierPseudoSimulationInfo = removeBarrierSimList.Find((AIBarrierPseudoSimulationInfo info) => info.Owner.IsSameCard(target));
float battleBonusRate = cardValueList[target].BattleBonusRate;
while (true)
{
if (num2 <= 0)
{
damageCount = num2;
return num + num3;
}
int num7 = target.SimulateDamageShield(damageAmount, isSkillDamage: true, isSpell);
if (num7 > 0)
{
num7 = aIBarrierPseudoSimulationInfo.SimulateDamageAmount(damageAmount, isSpell);
}
num5++;
num3 += (float)num7 * battleBonusRate;
lifeList[index] -= num7;
aIBarrierPseudoSimulationInfo.DepriveBarrier(AIBarrierStopTiming.AfterDamage);
num2--;
if (target.TagCollectionContainer.HasTag(AIPlayTagType.DamagedBuff) && num5 >= num6)
{
DamagedTagCollection damagedTags = target.TagCollectionContainer.DamagedTags;
for (int num8 = 0; num8 < num5; num8++)
{
int atkBuff = 0;
int lifeBuff = 0;
damagedTags.GetDamagedBuffValue(target, target.SelfField, playPtn, situation, out atkBuff, out lifeBuff);
lifeList[index] += lifeBuff;
if (lifeList[index] <= 0)
{
break;
}
}
}
if (lifeList[index] <= 0)
{
lifeList[index] = 0;
num3 = 0f;
num5 = 0;
num += cardValueList[target].BreakValue;
num4 = targetIdxList.FindIndex((int idx) => lifeList[idx] > 0);
if (num4 < 0 || num4 >= targetIdxList.Count)
{
break;
}
index = targetIdxList[num4];
num6 = lifeList[index];
target = candidates[index];
battleBonusRate = cardValueList[target].BattleBonusRate;
aIBarrierPseudoSimulationInfo = removeBarrierSimList.Find((AIBarrierPseudoSimulationInfo info) => info.Owner.IsSameCard(target));
}
}
}
damageCount = num2;
return num + num3;
}
private static float EvalRandomMultiDamageToLeader(AIVirtualCard leader, DamageSituationInfo damageSituation, bool isAllyOwner, ref int restLife, out int restDamageCount)
{
restDamageCount = damageSituation.DamageCount;
int defaultLife = restLife;
AIBarrierPseudoSimulationInfo aIBarrierPseudoSimulationInfo = damageSituation.BarrierSimList.Find((AIBarrierPseudoSimulationInfo c) => c.Owner.IsSameCard(leader));
bool isSpell = damageSituation.IsSpell;
for (int num = 0; num < damageSituation.DamageCount; num++)
{
if (restLife <= 0)
{
restLife = 0;
break;
}
int num2 = aIBarrierPseudoSimulationInfo.SimulateDamageAmount(leader.SimulateDamageShield(damageSituation.DamageAmount, isSkillDamage: true, isSpell), isSpell);
restLife -= num2;
aIBarrierPseudoSimulationInfo.DepriveBarrier(AIBarrierStopTiming.AfterDamage);
restDamageCount--;
}
return AILeaderLifeEvaluationUtility.Evaluate(restLife, defaultLife, leader.IsAlly, isAllyOwner);
}
private static void SeparateTargetCardBySide(List<AIVirtualCard> allTargets, out List<AIVirtualCard> allyInplays, out List<AIVirtualCard> enemyInplays, out AIVirtualCard allyLeader, out AIVirtualCard enemyLeader)
{
allyInplays = null;
enemyInplays = null;
allyLeader = null;
enemyLeader = null;
if (allTargets == null)
{
return;
}
for (int i = 0; i < allTargets.Count; i++)
{
AIVirtualCard aIVirtualCard = allTargets[i];
if (aIVirtualCard.IsAlly)
{
if (aIVirtualCard.IsLeader)
{
allyLeader = aIVirtualCard;
}
else
{
allyInplays = AIParamQuery.AddElementToList(aIVirtualCard, allyInplays);
}
}
else if (aIVirtualCard.IsLeader)
{
enemyLeader = aIVirtualCard;
}
else
{
enemyInplays = AIParamQuery.AddElementToList(aIVirtualCard, enemyInplays);
}
}
}
private static List<int> GetTargetLifeList(List<AIVirtualCard> targets)
{
if (targets == null)
{
return null;
}
List<int> list = null;
for (int i = 0; i < targets.Count; i++)
{
list = AIParamQuery.AddElementToList(targets[i].Life, list);
}
return list;
}
private static Dictionary<AIVirtualCard, CardValueInformationForEvalRandomMultiDamage> CreateCardValueInformationDictionary(List<AIVirtualCard> cardList, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (cardList == null)
{
return null;
}
Dictionary<AIVirtualCard, CardValueInformationForEvalRandomMultiDamage> dictionary = new Dictionary<AIVirtualCard, CardValueInformationForEvalRandomMultiDamage>();
for (int i = 0; i < cardList.Count; i++)
{
AIVirtualCard aIVirtualCard = cardList[i];
float breakValue = aIVirtualCard.EvaluateValueOnField(playPtn, situation, useStyle: true) - (aIVirtualCard.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) + aIVirtualCard.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false));
float battleBonusRate = field.StyleQuery.GetUnitRate(field, aIVirtualCard, playPtn) * aIVirtualCard.EvaluateAllBattleBonusRate(playPtn, useOthersTag: true, useIgnoreInBattle: false, situation);
CardValueInformationForEvalRandomMultiDamage value = new CardValueInformationForEvalRandomMultiDamage
{
BreakValue = breakValue,
BattleBonusRate = battleBonusRate
};
dictionary.Add(aIVirtualCard, value);
}
return dictionary;
}
private static void PseudoRemoveBarrierWhenTargetGetDamaged(AIBarrierPseudoSimulationInfo targetBarrierInfo, List<AIBarrierPseudoSimulationInfo> otherDamageCandidateBarrierInfoList, bool isTargetLeaveFromField)
{
targetBarrierInfo.DepriveBarrier(AIBarrierStopTiming.AfterDamage);
if (isTargetLeaveFromField)
{
AIVirtualCard owner = targetBarrierInfo.Owner;
owner.SelfField.TagPreprocessContainer.LeaveStopInfoContainer?.PseudoSimulateForEvalRandomMultiDamage(otherDamageCandidateBarrierInfoList, owner);
}
}
}

View File

@@ -0,0 +1,118 @@
using System.Collections.Generic;
using System.Linq;
using Cute;
namespace Wizard;
public static class AIReanimateSimulationUtility
{
public const int NONE_REANIMATE_COST = -1;
public const int NONE_REANIMATE_ID = -1;
public static bool IsReanimate(AIVirtualCard tagOwner, int cost)
{
AIVirtualField selfField = tagOwner.SelfField;
return (tagOwner.IsAlly ? selfField.CardListSet.AllyDestroyedCards : selfField.CardListSet.EnemyDestroyedCards).Any((AIVirtualCard c) => c.IsUnit && c.Cost <= cost);
}
public static int GetReanimateTokenId(AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> filters, AIPolishConvertedExpression costExpression, AIScriptTokenArgType side, out bool isTokenAlly)
{
int num = (int)costExpression.EvalArg(tagOwner, playPtn, field, situation);
if (num < 0)
{
isTokenAlly = true;
return -1;
}
isTokenAlly = AISummonTokenUtility.GetIsTokenAlly(tagOwner, side);
return EvalReanimateTokenID(tagOwner, num, filters, isTokenAlly, playPtn, situation);
}
private static int EvalReanimateTokenID(AIVirtualCard tagOwner, int reanimateCost, List<AIScriptTokenBase> filters, bool isTokenAlly, List<int> playPtn, AISituationInfo situation)
{
if (reanimateCost == -1)
{
return -1;
}
int result = -1;
AIVirtualField selfField = tagOwner.SelfField;
List<AIVirtualCard> list = (isTokenAlly ? selfField.CardListSet.AllyDestroyedCards : selfField.CardListSet.EnemyDestroyedCards);
if (list.IsNotNullOrEmpty())
{
list = FilteringReanimateTargets(list, reanimateCost, tagOwner, filters, playPtn, situation);
if (list == null || list.Count <= 0)
{
return result;
}
Dictionary<int, int> dictionary = new Dictionary<int, int>();
for (int i = 0; i < list.Count; i++)
{
int baseId = list[i].BaseId;
if (dictionary.ContainsKey(baseId))
{
dictionary[baseId]++;
}
else
{
dictionary.Add(baseId, 1);
}
}
int maxDestroyedCount = dictionary.Max((KeyValuePair<int, int> pair) => pair.Value);
if (dictionary.Count((KeyValuePair<int, int> pair) => pair.Value == maxDestroyedCount) == 1)
{
result = dictionary.First((KeyValuePair<int, int> pair) => pair.Value == maxDestroyedCount).Key;
}
else
{
float num = float.MaxValue;
List<KeyValuePair<int, int>> maxDestroyedPair = dictionary.Where((KeyValuePair<int, int> pair) => pair.Value == maxDestroyedCount).ToList();
int i2;
for (i2 = 0; i2 < maxDestroyedPair.Count; i2++)
{
AIVirtualCard aIVirtualCard = list.First((AIVirtualCard c) => c.BaseId == maxDestroyedPair[i2].Key);
float num2 = AIEvalReanimateUtility.EvalReanimateTargetValue(aIVirtualCard, selfField, playPtn, situation);
num2 *= (isTokenAlly ? 1f : (-1f));
if (num2 < num)
{
result = aIVirtualCard.BaseId;
num = num2;
}
}
}
}
return result;
}
public static List<AIVirtualCard> FilteringReanimateTargets(List<AIVirtualCard> reanimateTargets, int reanimateCost, AIVirtualCard tagOwner, List<AIScriptTokenBase> filters, List<int> playPtn, AISituationInfo situation)
{
if (reanimateTargets == null)
{
return null;
}
int maxReanimateCost = -1;
List<AIVirtualCard> list = null;
for (int i = 0; i < reanimateTargets.Count; i++)
{
AIVirtualCard aIVirtualCard = reanimateTargets[i];
int cost = aIVirtualCard.Cost;
if (aIVirtualCard.IsUnit && cost <= reanimateCost && (filters == null || filters.Count < 0 || AIFilteringUtility.CheckMatchTargetFiltering(aIVirtualCard, reanimateTargets, filters, playPtn, tagOwner, situation)))
{
if (maxReanimateCost < cost)
{
maxReanimateCost = cost;
}
if (list == null)
{
list = new List<AIVirtualCard>();
}
list.Add(aIVirtualCard);
}
}
if (list == null)
{
return null;
}
list.RemoveAll((AIVirtualCard c) => c.Cost != maxReanimateCost);
return list;
}
}

View File

@@ -0,0 +1,121 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIRecoverAttackableCountUtility
{
public static void RecoverAttackableCountTarget(AIScriptTokenArgType targetSelectType, AISituationInfo situation)
{
if (situation != null && situation.IsTargetExists(targetSelectType))
{
RecoverAttackableCountAll(situation.GetSituationTarget(targetSelectType).Targets);
}
}
public static void RecoverAttackableCountTargetPrediction(List<AIVirtualCard> candidatis, int selectCount)
{
if (selectCount > 1)
{
List<AIVirtualCard> list = SelectMultipleTarget(candidatis, selectCount, AISelectTargetPattern.Best);
if (list != null && list.Count > 0)
{
RecoverAttackableCountAll(list);
}
}
else
{
SelectSingleTarget(candidatis, AISelectTargetPattern.Best)?.RecoverAttackableCount();
}
}
public static void RecoverAttackableCountAll(List<AIVirtualCard> targets)
{
if (targets != null)
{
for (int i = 0; i < targets.Count; i++)
{
targets[i].RecoverAttackableCount();
}
}
}
public static AIVirtualCard SelectSingleTarget(List<AIVirtualCard> candidates, AISelectTargetPattern worstOrBest)
{
if (candidates == null || candidates.Count <= 0)
{
return null;
}
AIVirtualCard result = null;
int num = ((worstOrBest == AISelectTargetPattern.Best) ? int.MinValue : int.MaxValue);
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
if (aIVirtualCard.IsUnit && aIVirtualCard.AttackableCount <= 0 && !aIVirtualCard.IsCantAttackAll)
{
int num2 = aIVirtualCard.Attack * aIVirtualCard.MaxAttackableCount;
bool flag = false;
switch (worstOrBest)
{
case AISelectTargetPattern.Best:
flag = num2 > num;
break;
case AISelectTargetPattern.Worst:
flag = num2 < num;
break;
}
if (flag)
{
result = aIVirtualCard;
num = num2;
}
}
}
return result;
}
private static List<AIVirtualCard> SelectMultipleTarget(List<AIVirtualCard> candidates, int selectCount, AISelectTargetPattern worstOrBest)
{
if (candidates == null || candidates.Count <= 0)
{
return null;
}
List<AIVirtualCard> list = null;
for (int i = 0; i < selectCount; i++)
{
if (list != null && list.Count == selectCount)
{
break;
}
AIVirtualCard aIVirtualCard = null;
int num = ((worstOrBest == AISelectTargetPattern.Best) ? int.MinValue : int.MaxValue);
for (int j = 0; j < candidates.Count; j++)
{
AIVirtualCard aIVirtualCard2 = candidates[j];
if (aIVirtualCard2.IsUnit && aIVirtualCard2.AttackableCount <= 0 && !aIVirtualCard2.IsCantAttackAll && (list == null || !list.Contains(aIVirtualCard2)))
{
int num2 = aIVirtualCard2.Attack * aIVirtualCard2.MaxAttackableCount;
bool flag = false;
switch (worstOrBest)
{
case AISelectTargetPattern.Best:
flag = num2 > num;
break;
case AISelectTargetPattern.Worst:
flag = num2 < num;
break;
}
if (flag)
{
aIVirtualCard = aIVirtualCard2;
num = num2;
}
}
}
if (aIVirtualCard != null)
{
list = AIParamQuery.AddElementToList(aIVirtualCard, list);
}
}
return list;
}
}

View File

@@ -0,0 +1,8 @@
namespace Wizard;
public class AIRemovalEvaluationOption
{
public AIVirtualCard TagOwner;
public int MetamorphoseTokenId;
}

View File

@@ -0,0 +1,60 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIRemoveSkillSimulationUtility
{
public static void RemoveSkillAll(List<AIVirtualCard> candidates, AISituationInfo situation)
{
for (int i = 0; i < candidates.Count; i++)
{
candidates[i].RemoveAllSkills(situation);
}
}
public static void RemoveSkillTargetSelect(AIScriptTokenArgType whichTarget, AISituationInfo situation)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget != null && situationTarget.HasTarget)
{
RemoveSkillAll(situationTarget.Targets, situation);
}
}
public static void RemoveSkillRandom(List<AIVirtualCard> candidates, AISituationInfo situation)
{
SelectRemoveSkillTarget(candidates, AISelectTargetPattern.Worst)?.RemoveAllSkills(situation);
}
private static AIVirtualCard SelectRemoveSkillTarget(List<AIVirtualCard> candidates, AISelectTargetPattern worstOrBest)
{
if (candidates == null || candidates.Count <= 0)
{
return null;
}
float posiOrNega = ((worstOrBest == AISelectTargetPattern.Best) ? 1f : (-1f));
float num = 0f;
AIVirtualCard aIVirtualCard = null;
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard2 = candidates[i];
if (aIVirtualCard == null)
{
num = CalcValue(aIVirtualCard2);
aIVirtualCard = aIVirtualCard2;
continue;
}
float num2 = CalcValue(aIVirtualCard2);
if (num2 > num)
{
num = num2;
aIVirtualCard = aIVirtualCard2;
}
}
return aIVirtualCard;
float CalcValue(AIVirtualCard card)
{
return (card.Value - (float)card.Attack - (float)card.Life) * posiOrNega;
}
}
}

View File

@@ -0,0 +1,39 @@
using System.Collections.Generic;
namespace Wizard;
public class AIReverseDiscardSelectLogicArgument : AISelectLogicArgumentBase
{
public AIReverseDiscardSelectLogicArgument(List<string> args)
: base(args)
{
}
public override AIVirtualCard SelectSingleTarget(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
AIReverseEvaluateValueListOrder aIReverseEvaluateValueListOrder = new AIReverseEvaluateValueListOrder();
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
float value = aIVirtualCard.GetHandBonus(playPtn, situation, isIgnoreInFusion: false) + aIVirtualCard.GetDiscardedBonus(playPtn, situation, isIgnroeInBattle: true);
aIReverseEvaluateValueListOrder.AddData(value, aIVirtualCard);
}
return aIReverseEvaluateValueListOrder.GetFirst();
}
public override List<AIVirtualCard> SelectMultipleSelectedTargets(List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
AIConsoleUtility.Log("REVERSE_DISCARD_LOGIC は複数選択に未対応です");
return null;
}
private bool IsWellTarget(float maxHandBonus, float currentHandBonus, AISelectTargetPattern worstOrBest)
{
return worstOrBest switch
{
AISelectTargetPattern.Best => maxHandBonus < currentHandBonus,
AISelectTargetPattern.Worst => maxHandBonus > currentHandBonus,
_ => false,
};
}
}

View File

@@ -0,0 +1,66 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public class AIReverseEvaluateValueListOrder
{
private List<float> evalvalues = new List<float>();
private List<AIVirtualCard> cards = new List<AIVirtualCard>();
public void AddData(float value, AIVirtualCard card)
{
if (card == null)
{
AIConsoleUtility.LogError("CompValue:AddData() Target card is null");
}
else if (evalvalues.Any())
{
bool flag = false;
for (int i = 0; i < evalvalues.Count; i++)
{
if (evalvalues[i] > value)
{
evalvalues.Insert(i, value);
cards.Insert(i, card);
flag = true;
break;
}
}
if (!flag)
{
evalvalues.Add(value);
cards.Add(card);
}
}
else
{
evalvalues.Add(value);
cards.Add(card);
}
}
public List<AIVirtualCard> GetCardList(int takeCount)
{
if (takeCount <= 0 || cards.Count < takeCount)
{
return null;
}
List<AIVirtualCard> list = new List<AIVirtualCard>();
for (int i = 0; i < takeCount; i++)
{
list.Add(cards[i]);
}
return list;
}
public AIVirtualCard GetFirst()
{
if (cards == null || cards.Count <= 0)
{
return null;
}
return cards[0];
}
}

View File

@@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Linq;
namespace Wizard;
public static class AISelectLogicSimulationUtility
{
public static AISelectLogicArgumentBase CreateSelectLogicArgument(string args)
{
List<string> list = AIPlayTagInitializingUtility.TrimAttachTagArgument(args).Replace(" ", "").Split(';')
.ToList();
AIScriptTokenArgType aIScriptTokenArgType = AIScriptTokenArgType.NONE;
if (AIScriptParser.ConvertWordToToken(list[0]) is AIScriptArgumentToken aIScriptArgumentToken)
{
aIScriptTokenArgType = aIScriptArgumentToken.ArgumentType;
}
if (aIScriptTokenArgType <= AIScriptTokenArgType.SELECT_LOGIC_TYPE_BEGIN || aIScriptTokenArgType >= AIScriptTokenArgType.SELECT_LOGIC_TYPE_END)
{
AIConsoleUtility.LogError($"CreateSelectLogicArgument error!! logicType == {aIScriptTokenArgType}");
return null;
}
list.RemoveAt(0);
return aIScriptTokenArgType switch
{
AIScriptTokenArgType.DEFAULT_LOGIC => new AIDefaultSelectLogicArgument(list),
AIScriptTokenArgType.DESTROY_LOGIC => new AIDestroySelectLogicArgument(list),
AIScriptTokenArgType.DAMAGE_LOGIC => new AIDamageSelectLogicArgument(list),
AIScriptTokenArgType.BOUNCE_LOGIC => new AIBounceSelectLogicArgument(list),
AIScriptTokenArgType.BANISH_LOGIC => new AIBanishSelectLogicArgument(list),
AIScriptTokenArgType.METAMORPHOSE_LOGIC => new AIMetamorphoseSelectLogicArgument(list),
AIScriptTokenArgType.MAX_ATTACK_LOGIC => new AIMaxAttackSelectLogicArgument(list),
AIScriptTokenArgType.TYRANT_ORDER_LOGIC => new AITyrantOrderSelectLogicArgument(list),
AIScriptTokenArgType.REVERSE_DISCARD_LOGIC => new AIReverseDiscardSelectLogicArgument(list),
AIScriptTokenArgType.WHITEFROST_WHISPER_LOGIC => new AIWhitefrostWhisperLogicArgument(list),
_ => null,
};
}
}

View File

@@ -0,0 +1,79 @@
using System.Collections.Generic;
namespace Wizard;
public static class AISetStatusSimulationUtility
{
public static bool IsNoneSetValue(AIPolishConvertedExpression expression)
{
if (expression.TokenList[0] is AIScriptArgumentToken aIScriptArgumentToken)
{
return aIScriptArgumentToken.ArgumentType == AIScriptTokenArgType.NONE;
}
return false;
}
public static void SetMaxStatusToAll(List<AIVirtualCard> targets, int attack, int life, AISituationInfo situation)
{
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (attack >= 0)
{
aIVirtualCard.SetAttack(attack);
}
if (life >= 0)
{
aIVirtualCard.SetMaxLife(situation, life);
}
}
}
public static void SetMaxStatusToTarget(AISituationInfo situation, int attack, int life, AIScriptTokenArgType whichTarget)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget != null && situationTarget.HasTarget)
{
SetMaxStatusToAll(situationTarget.Targets, attack, life, situation);
}
}
public static (AIVirtualCard allyLeader, AIVirtualCard enemyLeader) GetTargetSideLeaders(AIVirtualCard tagOwner, AIVirtualField field)
{
if (tagOwner == null)
{
return (allyLeader: null, enemyLeader: null);
}
if (!tagOwner.IsAlly)
{
return (allyLeader: field.EnemyClass, enemyLeader: field.AllyClass);
}
return (allyLeader: field.AllyClass, enemyLeader: field.EnemyClass);
}
public static void SetLeaderMaxLife(AIVirtualCard tagOwner, int maxLife, AIScriptTokenArgType sideType, AIVirtualField field, AISituationInfo situation = null)
{
(AIVirtualCard, AIVirtualCard) targetSideLeaders = GetTargetSideLeaders(tagOwner, field);
if (targetSideLeaders.Item1 == null || targetSideLeaders.Item2 == null)
{
AIConsoleUtility.LogError("AISetStatusSimulationUtility.SetLeaderMaxLife(): Failed to get the leader.");
return;
}
switch (sideType)
{
case AIScriptTokenArgType.ALLY:
targetSideLeaders.Item1.SetMaxLife(situation, maxLife);
break;
case AIScriptTokenArgType.OPPONENT:
targetSideLeaders.Item2.SetMaxLife(situation, maxLife);
break;
case AIScriptTokenArgType.BOTH:
targetSideLeaders.Item1.SetMaxLife(situation, maxLife);
targetSideLeaders.Item2.SetMaxLife(situation, maxLife);
break;
default:
AIConsoleUtility.LogError($"AISetStatusSimulationUtility.SetLeaderMaxLife(): Unexpected side type. type:{sideType}");
break;
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
namespace Wizard;
public class AIShieldInfo : AIBarrierInfoBase
{
public override AIBarrierType BarrierType => AIBarrierType.Shield;
public AIShieldInfo(AIDamageType damageType, AIBarrierStopTiming stopTiming)
: base(0, damageType, stopTiming)
{
UpdateHash();
}
public AIShieldInfo(AIDamageType damageType, List<AIBarrierStopTiming> stopTimingList)
: base(0, damageType, stopTimingList)
{
UpdateHash();
}
public override bool IsShield()
{
return true;
}
public override AIBarrierInfoBase Clone()
{
return new AIShieldInfo(base.DamageType, base.StopTimingList);
}
protected override int CalcDamage(AIVirtualCard owner, int damage)
{
return 0;
}
}

View File

@@ -0,0 +1,285 @@
using System.Collections.Generic;
namespace Wizard;
public static class AISimulationRemovalUtility
{
public static bool WillDieBySkillPrediction(AIVirtualCard card, AIVirtualField field, List<int> playPtn, AISituationInfo situation, bool isHandTagValid)
{
LifeRecord lifeRecord = new LifeRecord
{
MaxLife = card.MaxLife,
CurrentLife = card.Life
};
if (isHandTagValid && playPtn != null && playPtn.Count > 0)
{
for (int i = 0; i < playPtn.Count; i++)
{
GetRestLifeAfterCardPlay(field.AllyHandCards[playPtn[i]], card, field, playPtn, situation, lifeRecord);
if (lifeRecord.CurrentLife <= 0)
{
break;
}
}
}
return lifeRecord.CurrentLife <= 0;
}
private static void GetRestLifeAfterCardPlay(AIVirtualCard playCard, AIVirtualCard target, AIVirtualField field, List<int> playPtn, AISituationInfo situation, LifeRecord targetLife)
{
if (playCard.TagCollectionContainer.HasTagCollection(TagCollectionType.Fanfare))
{
FanfareTagCollection fanfareTags = playCard.TagCollectionContainer.FanfareTags;
if (fanfareTags.HasRemovalTags)
{
fanfareTags.RemovalPrediction(playCard, target, targetLife, field, playPtn, situation);
}
}
if (playCard.TagCollectionContainer.HasTagCollection(TagCollectionType.Play))
{
PlayTagCollection playTags = playCard.TagCollectionContainer.PlayTags;
if (playTags.HasRemovalTags)
{
playTags.RemovalPrediction(playCard, target, targetLife, field, playPtn, situation);
}
}
if (!field.CardListSet.HasOtherPlayTagHolder)
{
return;
}
for (int i = 0; i < field.CardListSet.OtherPlayTagHolders.Count; i++)
{
AIVirtualCard aIVirtualCard = field.CardListSet.OtherPlayTagHolders[i];
OtherPlayTagCollection otherPlayTags = aIVirtualCard.TagCollectionContainer.OtherPlayTags;
if (otherPlayTags.HasRemovalTags)
{
otherPlayTags.RemovalPrediction(aIVirtualCard, playCard, target, targetLife, field, playPtn, situation);
}
}
}
public static void PredictSurvivorsLifeAfterCardPlay(AIVirtualCard playCard, List<AIVirtualCard> targetList, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<LifeRecord> targetLifeList)
{
if (playCard.TagCollectionContainer.HasTagCollection(TagCollectionType.Fanfare))
{
FanfareTagCollection fanfareTags = playCard.TagCollectionContainer.FanfareTags;
if (fanfareTags.HasRemovalTags)
{
fanfareTags.MultipleRemovalPrediction(playCard, targetList, field, playPtn, situation, targetLifeList);
}
}
if (playCard.TagCollectionContainer.HasTagCollection(TagCollectionType.Play))
{
PlayTagCollection playTags = playCard.TagCollectionContainer.PlayTags;
if (playTags.HasRemovalTags)
{
playTags.MultipleRemovalPrediction(playCard, targetList, field, playPtn, situation, targetLifeList);
}
}
if (!field.CardListSet.HasOtherPlayTagHolder)
{
return;
}
for (int i = 0; i < field.CardListSet.OtherPlayTagHolders.Count; i++)
{
AIVirtualCard aIVirtualCard = field.CardListSet.OtherPlayTagHolders[i];
if (!aIVirtualCard.IsSameCard(playCard))
{
OtherPlayTagCollection otherPlayTags = aIVirtualCard.TagCollectionContainer.OtherPlayTags;
if (otherPlayTags.HasRemovalTags)
{
otherPlayTags.MultipleRemovalPrediction(aIVirtualCard, playCard, targetList, field, playPtn, situation, targetLifeList);
}
}
}
}
public static AIVirtualCard SelectRemovalTarget(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest, AIRemovalType removeType, AIRemovalEvaluationOption removalEvalOption = null)
{
if (removeType == AIRemovalType.None)
{
return null;
}
AIVirtualCard result = null;
float num = ((worstOrBest == AISelectTargetPattern.Worst) ? float.MaxValue : float.MinValue);
bool flag = worstOrBest == AISelectTargetPattern.Best;
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
bool flag2 = tagOwner.IsAlly != aIVirtualCard.IsAlly && (aIVirtualCard.IsSneak || aIVirtualCard.IsUntouchable);
if (!aIVirtualCard.IsDead && !aIVirtualCard.IsIndependent && !(flag && flag2))
{
float num2 = CalculateRemovalValue(aIVirtualCard, field, playPtn, situation, removeType, removalEvalOption);
bool flag3 = false;
switch (worstOrBest)
{
case AISelectTargetPattern.Worst:
flag3 = num2 < num;
break;
case AISelectTargetPattern.Best:
flag3 = num2 > num;
break;
}
if (flag3)
{
num = num2;
result = aIVirtualCard;
}
}
}
return result;
}
public static List<AIVirtualCard> SelectMultipleRemovalTargets(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest, AIRemovalType removeType, int count, AIRemovalEvaluationOption removalEvalOption = null)
{
if (removeType == AIRemovalType.None)
{
return null;
}
List<AIVirtualCard> list = new List<AIVirtualCard>();
float[] array = new float[count];
float num = ((worstOrBest == AISelectTargetPattern.Worst) ? float.MaxValue : float.MinValue);
bool flag = worstOrBest == AISelectTargetPattern.Best;
for (int i = 0; i < count; i++)
{
array[i] = num;
list.Add(null);
}
for (int j = 0; j < candidates.Count; j++)
{
AIVirtualCard aIVirtualCard = candidates[j];
bool flag2 = tagOwner.IsAlly != aIVirtualCard.IsAlly && (aIVirtualCard.IsSneak || aIVirtualCard.IsUntouchable);
if (aIVirtualCard.IsDead || aIVirtualCard.IsIndependent || (flag && flag2))
{
continue;
}
float num2 = CalculateRemovalValue(aIVirtualCard, field, playPtn, situation, removeType, removalEvalOption);
bool flag3 = false;
int num3 = -1;
for (int k = 0; k < list.Count; k++)
{
float num4 = array[k];
switch (worstOrBest)
{
case AISelectTargetPattern.Worst:
flag3 = num2 < num4;
break;
case AISelectTargetPattern.Best:
flag3 = num2 > num4;
break;
}
if (flag3)
{
num3 = k;
break;
}
}
if (flag3)
{
AIVirtualCard value = aIVirtualCard;
float num5 = num2;
for (int l = num3; l < list.Count; l++)
{
AIVirtualCard aIVirtualCard2 = list[l];
float num6 = array[l];
list[l] = value;
array[l] = num5;
value = aIVirtualCard2;
num5 = num6;
}
}
}
list.RemoveAll((AIVirtualCard c) => c == null);
return list;
}
public static float CalculateRemovalValue(AIVirtualCard target, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AIRemovalType removeType, AIRemovalEvaluationOption removalEvalOption)
{
float num = 0f;
switch (removeType)
{
case AIRemovalType.Destroy:
if (!target.IsIndestructible)
{
num = target.EvaluateValueOnField(playPtn, situation, useStyle: true) - target.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) - target.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false);
}
break;
case AIRemovalType.Banish:
if (!target.IsUnbanishable)
{
num = target.EvaluateValueOnField(playPtn, situation, useStyle: true) + target.GetAllBreakBonus(playPtn, useIgnoreInBattle: false) - target.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false) - target.GetAllBanishBonus(playPtn, useIgnoreInBattle: false);
}
break;
case AIRemovalType.Bounce:
{
int restPp = (target.IsAlly ? field.AI.PlayPtnRecorder.GetRestPp(playPtn, field) : field.EnemyBattlePlayer.Pp);
num = target.EvaluateBounceValue(playPtn, restPp);
num -= target.GetAllLeaveBonus(playPtn, useIgnoreInBattle: false) * (float)((!target.IsAlly) ? 1 : (-1));
break;
}
case AIRemovalType.Metamorphose:
if (removalEvalOption == null)
{
AIConsoleUtility.LogError("SelectRemovalTarget()でMetamorphoseを指定する場合はremovalEvalOptionが必要です");
return 0f;
}
num = AIMetamorphoseSimulationUtility.EvaluateSingleMetamorphoseValue(target, removalEvalOption.MetamorphoseTokenId, removalEvalOption.TagOwner, field, playPtn, situation);
break;
}
if (target.IsAlly && removeType != AIRemovalType.Bounce && removeType != AIRemovalType.Metamorphose)
{
num *= -1f;
}
return num;
}
public static AIVirtualCard SelectWorstTargetForBuff(List<AIVirtualCard> candidates, AIBuffExecutingInfo_old buffInfo)
{
AIVirtualCard result = null;
float num = float.MaxValue;
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
if (aIVirtualCard.IsUnit && !aIVirtualCard.IsDead)
{
int num2 = (aIVirtualCard.IsAttackable(aIVirtualCard.SelfField.BestPlayPtn) ? aIVirtualCard.AttackableCount : 0);
float num3 = (100f - (float)aIVirtualCard.Attack) * (float)num2;
float num4 = 100f + (float)aIVirtualCard.Attack;
int expectedAttackBuffValue = buffInfo.GetExpectedAttackBuffValue(aIVirtualCard);
int expectedLifeBuffValue = buffInfo.GetExpectedLifeBuffValue(aIVirtualCard);
float num5 = (aIVirtualCard.IsAlly ? 1f : (-1f)) * ((float)expectedAttackBuffValue * num3 + (float)expectedLifeBuffValue * num4);
if (num5 < num)
{
num = num5;
result = aIVirtualCard;
}
}
}
return result;
}
public static AIVirtualCard SelectBestTargetForBuff(List<AIVirtualCard> candidates, AIBuffExecutingInfo_old buff)
{
AIVirtualCard result = null;
float num = float.MinValue;
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
if (aIVirtualCard.IsUnit && !aIVirtualCard.IsDead)
{
int num2 = (aIVirtualCard.IsAttackable(aIVirtualCard.SelfField.BestPlayPtn) ? aIVirtualCard.AttackableCount : 0);
float num3 = (100f - (float)aIVirtualCard.Attack) * (float)num2;
float num4 = 100f + (float)aIVirtualCard.Attack;
int expectedAttackBuffValue = buff.GetExpectedAttackBuffValue(aIVirtualCard);
int expectedLifeBuffValue = buff.GetExpectedLifeBuffValue(aIVirtualCard);
float num5 = (aIVirtualCard.IsAlly ? 1f : (-1f)) * ((float)expectedAttackBuffValue * num3 + (float)expectedLifeBuffValue * num4);
if (num5 > num)
{
num = num5;
result = aIVirtualCard;
}
}
}
return result;
}
}

View File

@@ -0,0 +1,248 @@
using System.Collections.Generic;
namespace Wizard;
public static class AISituationCurrentProcessAccessExtension
{
public static AIVirtualCard GetCurrentTriggerCard(this AISituationInfo situation)
{
if (situation.IsNull())
{
return null;
}
return situation.CurrentSkillProcessInfo.TriggerInfo.TriggerCard;
}
public static bool IsSameCurrentTriggerCardAndTriggerType(this AISituationInfo situation, AIVirtualCard card, AISituationTriggerInformation.TriggerType triggerType)
{
if (situation.IsNull())
{
return false;
}
AISituationTriggerInformation triggerInfo = situation.CurrentSkillProcessInfo.TriggerInfo;
if (triggerInfo.TriggerCard == null || triggerInfo.Type != triggerType)
{
return false;
}
return triggerInfo.IsTriggerCardAndTriggerType(card, triggerType);
}
public static bool IsSameCurrentTriggerCard(this AISituationInfo situation, AIVirtualCard card)
{
if (situation.IsNull())
{
return false;
}
AISituationTriggerInformation triggerInfo = situation.CurrentSkillProcessInfo.TriggerInfo;
if (triggerInfo.TriggerCard == null)
{
return false;
}
return triggerInfo.IsTriggerCard(card);
}
public static bool IsBanishTrigger(this AISituationInfo situation)
{
if (situation.IsNull())
{
return false;
}
AISituationTriggerInformation triggerInfo = situation.CurrentSkillProcessInfo.TriggerInfo;
if (triggerInfo.Type == AISituationTriggerInformation.TriggerType.Banish)
{
return triggerInfo.TriggerCard != null;
}
return false;
}
public static bool IsOwnSummonedCard(this AISituationInfo situation, AIVirtualCard card, AIScriptTokenArgType targetCardType, bool isLatest = false)
{
if (situation.IsNull())
{
return false;
}
List<AIVirtualCard> list = (isLatest ? situation.GetOwnLatestSummonedCards() : situation.GetOwnSummonedCards());
if (list == null || list.Count <= 0)
{
return false;
}
switch (targetCardType)
{
case AIScriptTokenArgType.FOLLOWER:
if (!card.IsUnit)
{
return false;
}
break;
case AIScriptTokenArgType.AMULET:
if (!card.IsAmulet)
{
return false;
}
break;
default:
AIConsoleUtility.LogError($"IsOwnSummonedCard(): Unsupported target card type. type:{targetCardType}");
return false;
case AIScriptTokenArgType.ALL:
break;
}
for (int i = 0; i < list.Count; i++)
{
if (list[i].IsSameCard(card))
{
return true;
}
}
return false;
}
public static bool IsLatestOwnDrewCard(this AISituationInfo situation, AIVirtualCard card)
{
if (situation.IsNull())
{
return false;
}
List<AIVirtualCard> ownLatestDrewCards = situation.GetOwnLatestDrewCards();
if (ownLatestDrewCards == null || ownLatestDrewCards.Count <= 0)
{
return false;
}
for (int i = 0; i < ownLatestDrewCards.Count; i++)
{
if (ownLatestDrewCards[i].IsSameCard(card))
{
return true;
}
}
return false;
}
public static bool IsLatestTarget(this AISituationInfo situation, AIVirtualCard card)
{
List<AIVirtualCard> latestTargets = situation.GetLatestTargets();
if (latestTargets == null || latestTargets.Count <= 0)
{
AIConsoleUtility.LogError("IsLatestTarget error!! candidates is empty!!!!!");
return false;
}
for (int i = 0; i < latestTargets.Count; i++)
{
if (card.IsSameCard(latestTargets[i]))
{
return true;
}
}
return false;
}
public static List<AIVirtualCard> GetOwnDestroyedCards(this AISituationInfo situation)
{
if (situation.IsNull())
{
return null;
}
return situation.CurrentSkillProcessInfo.OwnProcessRecord.OwnDestroyedCards;
}
public static List<AIVirtualCard> GetOwnSummonedCards(this AISituationInfo situation)
{
if (situation.IsNull())
{
return null;
}
return situation.CurrentSkillProcessInfo.OwnProcessRecord.OwnSummonedCards;
}
public static List<AIVirtualCard> GetOwnLatestSummonedCards(this AISituationInfo situation)
{
if (situation.IsNull())
{
return null;
}
return situation.CurrentSkillProcessInfo.OwnProcessRecord.OwnLatestSummonedCards;
}
public static List<AIVirtualCard> GetOwnLatestDrewCards(this AISituationInfo situation)
{
if (situation.IsNull())
{
return null;
}
return situation.CurrentSkillProcessInfo.OwnProcessRecord.OwnLatestDrewCards;
}
public static List<AIVirtualCard> GetLatestTargets(this AISituationInfo situation)
{
if (situation.IsNull())
{
return null;
}
return situation.CurrentSkillProcessInfo.OwnProcessRecord.LatestTargets;
}
public static int GetCurrentProcessDefaultDamage(this AISituationInfo situation)
{
if (situation.IsNull())
{
return -1;
}
return situation.CurrentSkillProcessInfo.OwnProcessRecord.DefaultDamage;
}
public static void RegisterOwnDestroyedCard(this AISituationInfo situation, AIVirtualCard card)
{
if (!situation.IsNull())
{
situation.CurrentSkillProcessInfo.OwnProcessRecord.AddOwnDestroyedCard(card);
}
}
public static void RegisterOwnBanishedCard(this AISituationInfo situation, AIVirtualCard card)
{
if (!situation.IsNull())
{
situation.CurrentSkillProcessInfo.OwnProcessRecord.AddOwnBanishedCard(card);
}
}
public static void RegisterOwnSummonedCardList(this AISituationInfo situation, List<AIVirtualCard> cards)
{
if (!situation.IsNull() && cards != null && cards.Count > 0)
{
situation.CurrentSkillProcessInfo.OwnProcessRecord.AddOwnSummonedCards(cards);
}
}
public static void RegisterOwnDrewCardList(this AISituationInfo situation, List<AIVirtualCard> cards)
{
if (!situation.IsNull() && cards != null && cards.Count > 0)
{
situation.CurrentSkillProcessInfo.OwnProcessRecord.AddOwnDrewCards(cards);
}
}
public static void RegisterSingleLatestTarget(this AISituationInfo situation, AIVirtualCard card)
{
if (!situation.IsNull())
{
situation.CurrentSkillProcessInfo.OwnProcessRecord.RegisterSingleLatestTarget(card);
}
}
public static void RegisterLatestTargetList(this AISituationInfo situation, List<AIVirtualCard> list)
{
if (!situation.IsNull() && list != null && list.Count > 0)
{
situation.CurrentSkillProcessInfo.OwnProcessRecord.RegisterLatestTargetList(list);
}
}
private static bool IsNull(this AISituationInfo situation)
{
if (situation != null)
{
return situation.CurrentSkillProcessInfo == null;
}
return true;
}
}

View File

@@ -0,0 +1,134 @@
using System.Collections.Generic;
namespace Wizard;
public static class AISkillActivateCountUtility
{
public const int NONE_LIMIT_ACTIVATE_COUNT = -1;
public static void AllActivateCountHolderIncrement(this AIVirtualField field, AISituationInfo situation, AIPlayTagType counterType, AIVirtualCard triggerCard = null)
{
if (field.CardListSet.HasActivateCountHolder)
{
List<AIVirtualCard> activateCountHolders = field.CardListSet.ActivateCountHolders;
for (int i = 0; i < activateCountHolders.Count; i++)
{
activateCountHolders[i].Increment(situation, counterType, triggerCard);
}
}
}
public static void AllActivateCountHolderIncrement(this AIVirtualField field, AISituationInfo situation, AIPlayTagType counterType, List<AIVirtualCard> triggerCardList)
{
if (field.CardListSet.HasActivateCountHolder)
{
List<AIVirtualCard> activateCountHolders = field.CardListSet.ActivateCountHolders;
for (int i = 0; i < activateCountHolders.Count; i++)
{
activateCountHolders[i].Increment(situation, counterType, triggerCardList);
}
}
}
public static void Increment(this AIVirtualCard card, AISituationInfo situation, AIPlayTagType counterType, AIVirtualCard triggerCard = null)
{
if (card.TagCollectionContainer.HasTag(counterType) && CheckCounterTypeCommonIncrementCondition(counterType, card, situation))
{
card.TagCollectionContainer.ActivateCountTags.Increment(card, situation, counterType, triggerCard);
}
}
public static void Increment(this AIVirtualCard card, AISituationInfo situation, AIPlayTagType counterType, List<AIVirtualCard> triggerCardList)
{
if (card.TagCollectionContainer.HasTag(counterType) && CheckCounterTypeCommonIncrementCondition(counterType, card, situation))
{
card.TagCollectionContainer.ActivateCountTags.Increment(card, situation, counterType, triggerCardList);
}
}
private static bool CheckCounterTypeCommonIncrementCondition(AIPlayTagType counterType, AIVirtualCard holder, AISituationInfo situation)
{
if (counterType == AIPlayTagType.TurnEndActivateCount)
{
return holder.IsAlly == situation.Actor.IsAlly;
}
return true;
}
public static int GetSkillActivateCount(this AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> argList)
{
if (!field.CardListSet.HasActivateCountHolder)
{
return 0;
}
if (!CheckActivateCounterFilteringArgument(argList, out var filters, out var skillOwnerId, out var skillIndex))
{
return 0;
}
int num = 0;
List<AIVirtualCard> activateCountHolders = field.CardListSet.ActivateCountHolders;
for (int i = 0; i < activateCountHolders.Count; i++)
{
AIVirtualCard aIVirtualCard = activateCountHolders[i];
if (AIFilteringUtility.CheckMatchTargetFiltering(aIVirtualCard, null, filters, playPtn, tagOwner, situation))
{
num += aIVirtualCard.GetSkillActivateCountFromOneCard(skillOwnerId, skillIndex);
}
}
return num;
}
public static bool IsSkillOccurred(this AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, List<AIScriptTokenBase> argList)
{
if (!field.CardListSet.HasActivateCountHolder)
{
return false;
}
if (!CheckActivateCounterFilteringArgument(argList, out var filters, out var skillOwnerId, out var skillIndex))
{
return false;
}
List<AIVirtualCard> activateCountHolders = field.CardListSet.ActivateCountHolders;
for (int i = 0; i < activateCountHolders.Count; i++)
{
AIVirtualCard aIVirtualCard = activateCountHolders[i];
if (AIFilteringUtility.CheckMatchTargetFiltering(aIVirtualCard, null, filters, playPtn, tagOwner, situation) && !aIVirtualCard.GetIsSkillOccurredFromOneCard(skillOwnerId, skillIndex))
{
return false;
}
}
return true;
}
public static bool CheckActivateCounterFilteringArgument(List<AIScriptTokenBase> argList, out List<AIScriptTokenBase> filters, out int skillOwnerId, out int skillIndex)
{
filters = null;
skillOwnerId = -1;
skillIndex = 0;
if (!(argList[0] is AIScriptNumericToken aIScriptNumericToken))
{
return false;
}
skillIndex = (int)aIScriptNumericToken.Value;
argList.RemoveAt(0);
if (!(argList[0] is AIScriptIDToken aIScriptIDToken))
{
return false;
}
skillOwnerId = aIScriptIDToken.ID;
argList.RemoveAt(0);
argList.Reverse();
filters = argList;
return true;
}
private static int GetSkillActivateCountFromOneCard(this AIVirtualCard counterOwner, int counterSourceCardId, int counterIndex)
{
return counterOwner.TagCollectionContainer.ActivateCountTags.GetActivateCount(counterSourceCardId, counterIndex);
}
private static bool GetIsSkillOccurredFromOneCard(this AIVirtualCard counterOwner, int counterSourceCardId, int counterIndex)
{
return counterOwner.TagCollectionContainer.ActivateCountTags.IsSkillOccurred(counterSourceCardId, counterIndex);
}
}

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
namespace Wizard;
public static class AISkillCountFromIdUtility
{
public static int GetSkillCountFromID(List<AIScriptTokenBase> filters, int skillOwnerId, AIVirtualCard tagOwner, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(tagOwner.SelfField.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, situation);
if (list == null || list.Count <= 0)
{
return 0;
}
int num = 0;
for (int i = 0; i < list.Count; i++)
{
num += GetAttachedSkillCount(list[i].BaseCard, skillOwnerId);
}
return num;
}
public static int GetAttachedSkillCount(BattleCardBase targetCard, int skillOwnerId)
{
int num = 0;
List<int> ownerCardIdList = targetCard.SkillApplyInformation.AttachedSkillsInfo.OwnerCardIdList;
for (int i = 0; i < ownerCardIdList.Count; i++)
{
if (EnemyAI.GetBaseId(ownerCardIdList[i]) == skillOwnerId)
{
num++;
}
}
return num;
}
}

View File

@@ -0,0 +1,90 @@
using System.Collections.Generic;
namespace Wizard;
public static class AISpellboostSimulationUtility
{
public static void SpellboostAll(List<AIVirtualCard> targets, int count)
{
for (int i = 0; i < targets.Count; i++)
{
targets[i].Spellboost(count);
}
}
public static void SpellboostTarget(AISituationInfo situation, int count, List<AIVirtualCard> candidates, AIScriptTokenArgType whichTarget)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
return;
}
List<AIVirtualCard> targets = situationTarget.Targets;
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (candidates.Contains(aIVirtualCard))
{
aIVirtualCard.Spellboost(count);
}
}
}
public static void SpellboostWhenPlaySpellAtEvaluation(AIVirtualCard playCard, AIVirtualField field)
{
for (int i = 0; i < field.AllyHandCards.Count; i++)
{
AIVirtualCard aIVirtualCard = field.AllyHandCards[i];
if (aIVirtualCard.HasSpellboost)
{
aIVirtualCard.Spellboost(1);
}
}
}
public static void SpellboostWhenPlaySpell(AIVirtualCard playCard, AIVirtualField field)
{
if (!playCard.IsAlly)
{
return;
}
for (int i = 0; i < field.AllyHandCards.Count; i++)
{
AIVirtualCard aIVirtualCard = field.AllyHandCards[i];
if (!aIVirtualCard.IsSameCard(playCard) && aIVirtualCard.HasSpellboost)
{
aIVirtualCard.Spellboost(1);
}
}
}
public static AIVirtualCard SelectBestTargetForSpellboost(AIVirtualField field, int boostCount, List<AIVirtualCard> candidates)
{
AIVirtualCard result = null;
float num = float.MinValue;
List<int> list = new List<int>();
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
int spellboostCount = aIVirtualCard.SpellboostCount;
list.Clear();
list.Add(field.AllyHandCards.IndexOf(aIVirtualCard));
float num2 = CalculateCardValueForSpellboostEvaluation(aIVirtualCard, list);
aIVirtualCard.Spellboost(boostCount);
float num3 = CalculateCardValueForSpellboostEvaluation(aIVirtualCard, list);
aIVirtualCard.SetSpellboostCount(spellboostCount);
float num4 = num3 - num2;
if (num4 > num)
{
result = aIVirtualCard;
num = num4;
}
}
return result;
}
private static float CalculateCardValueForSpellboostEvaluation(AIVirtualCard card, List<int> playPtn)
{
return card.EvaluatePlayValue(playPtn) + card.GetHandBonus(playPtn, null, isIgnoreInFusion: false);
}
}

View File

@@ -0,0 +1,85 @@
using System.Collections.Generic;
using UnityEngine;
namespace Wizard;
public static class AISubtractCountdownSimulationUtility
{
public static void SubtractCountdownAll(List<AIVirtualCard> targetCards, int value, AISituationInfo situation)
{
for (int i = 0; i < targetCards.Count; i++)
{
SubtractCountdownSingle(targetCards[i], value, situation);
}
}
public static void ExecuteTargetSelectSubtractCountdown(AIVirtualCard tagOwner, List<AIVirtualCard> candidats, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AIScriptTokenArgType selectType, int countChange)
{
if (situation == null)
{
AIConsoleUtility.LogError("ExecuteTargetSelectSubtractCountdown() Error!! situation is null!!!!!");
}
else if (situation.IsTargetExists(selectType))
{
SubtractCountdownTarget(situation, candidats, selectType, countChange);
}
else
{
SubtractCountdownTargetPrediction(situation, candidats, tagOwner, field, playPtn, selectType, countChange);
}
}
private static void SubtractCountdownTarget(AISituationInfo situation, List<AIVirtualCard> candidates, AIScriptTokenArgType whichTarget, int value)
{
AISelectedTargetInfo situationTarget = situation.GetSituationTarget(whichTarget);
if (situationTarget == null || !situationTarget.HasTarget)
{
AIConsoleUtility.LogError("SubtractCountdownTarget error!! No target!!!!!");
return;
}
List<AIVirtualCard> targets = situationTarget.Targets;
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (candidates.Contains(aIVirtualCard))
{
SubtractCountdownSingle(aIVirtualCard, value, situation);
}
}
}
private static void SubtractCountdownTargetPrediction(AISituationInfo situation, List<AIVirtualCard> candidates, AIVirtualCard owner, AIVirtualField field, List<int> playPtn, AIScriptTokenArgType whichTarget, int countChange)
{
AIVirtualCard target = SelectBestTarget(AITargetSelectFilteringUtility.SelectCandidatesWithForceTargeting(candidates, owner, playPtn), countChange);
situation.SetSingleTargetInInfo(target, TargetSelectType.Default, whichTarget);
SubtractCountdownTarget(situation, candidates, whichTarget, countChange);
}
public static void SubtractCountdownSingle(AIVirtualCard target, int value, AISituationInfo situation)
{
if (!target.IsDead && target.IsCountdownAmulet)
{
target.ChantCountDown(situation, value);
}
}
private static AIVirtualCard SelectBestTarget(List<AIVirtualCard> candidates, int countChange)
{
AIVirtualCard result = null;
float num = float.MinValue;
List<int> emptyPlayPtn = EnemyAI.EmptyPlayPtn;
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
float num2 = aIVirtualCard.EvaluateBreakValue(emptyPlayPtn, useIgnoreBreak: false);
int num3 = Mathf.Max(0, aIVirtualCard.ChantCount - countChange);
float num4 = num2 * Mathf.Pow(0.75f, num3);
if (num4 > num)
{
result = aIVirtualCard;
num = num4;
}
}
return result;
}
}

View File

@@ -0,0 +1,89 @@
using System.Collections.Generic;
namespace Wizard;
public static class AISummonCountUtility
{
public static bool ClassificateSummonCountArgument(List<AIScriptTokenBase> argList, out List<AIScriptTokenBase> filters, out AIScriptTokenArgType turnOrGame, out AIScriptTokenArgType playedType)
{
filters = new List<AIScriptTokenBase>();
turnOrGame = AIScriptTokenArgType.NONE;
playedType = AIScriptTokenArgType.NONE;
if (argList == null || argList.Count < 2)
{
return false;
}
bool flag = false;
if (argList[0] is AIScriptArgumentToken aIScriptArgumentToken)
{
if (aIScriptArgumentToken.ArgumentType == AIScriptTokenArgType.PLAYED || aIScriptArgumentToken.ArgumentType == AIScriptTokenArgType.PLAYPTN)
{
playedType = aIScriptArgumentToken.ArgumentType;
flag = true;
}
else if (aIScriptArgumentToken.ArgumentType == AIScriptTokenArgType.TURN || aIScriptArgumentToken.ArgumentType == AIScriptTokenArgType.GAME)
{
turnOrGame = aIScriptArgumentToken.ArgumentType;
}
argList.RemoveAt(0);
if (flag)
{
if (argList[0] is AIScriptArgumentToken aIScriptArgumentToken2 && (aIScriptArgumentToken2.ArgumentType == AIScriptTokenArgType.TURN || aIScriptArgumentToken2.ArgumentType == AIScriptTokenArgType.GAME))
{
turnOrGame = aIScriptArgumentToken2.ArgumentType;
}
argList.RemoveAt(0);
}
if (turnOrGame == AIScriptTokenArgType.NONE)
{
return false;
}
argList.Reverse();
filters = argList;
return true;
}
return false;
}
public static int GetSummonCount(AIVirtualCard tagOwner, List<AIScriptTokenBase> filters, AIScriptTokenArgType turnOrGame, AIScriptTokenArgType playedType, List<int> playPtn, AISituationInfo situation)
{
if (turnOrGame != AIScriptTokenArgType.TURN && turnOrGame != AIScriptTokenArgType.GAME)
{
return 0;
}
return playedType switch
{
AIScriptTokenArgType.NONE => GetSummonCountAtPlayed(tagOwner, filters, turnOrGame, playPtn, situation) + GetSummonCountAtPlayPtn(tagOwner, filters, playPtn, situation),
AIScriptTokenArgType.PLAYED => GetSummonCountAtPlayed(tagOwner, filters, turnOrGame, playPtn, situation),
AIScriptTokenArgType.PLAYPTN => GetSummonCountAtPlayPtn(tagOwner, filters, playPtn, situation),
_ => 0,
};
}
private static int GetSummonCountAtPlayed(AIVirtualCard tagOwner, List<AIScriptTokenBase> filters, AIScriptTokenArgType turnOrGame, List<int> playPtn, AISituationInfo situation)
{
return AIFilteringUtility.MultipleFiltering(tagOwner.SelfField.SummonedCardContainer.GetSummonedList(tagOwner.IsAlly, turnOrGame == AIScriptTokenArgType.TURN), filters, tagOwner, playPtn, situation)?.Count ?? 0;
}
private static int GetSummonCountAtPlayPtn(AIVirtualCard tagOwner, List<AIScriptTokenBase> filters, List<int> playPtn, AISituationInfo situation)
{
if (!tagOwner.IsAlly || playPtn == null || playPtn.Count <= 0)
{
return 0;
}
int num = 0;
List<AIVirtualCard> allyHandCards = tagOwner.SelfField.AllyHandCards;
for (int i = 0; i < playPtn.Count; i++)
{
if (playPtn[i] < allyHandCards.Count)
{
AIVirtualCard aIVirtualCard = allyHandCards[playPtn[i]];
if ((((aIVirtualCard.IsUnit || aIVirtualCard.IsAmulet) && !aIVirtualCard.IsAccelerated(tagOwner.SelfField, playPtn, situation)) || aIVirtualCard.IsCrystalize(tagOwner.SelfField, playPtn, situation)) && AIFilteringUtility.CheckMatchTargetFiltering(aIVirtualCard, null, filters, playPtn, tagOwner, situation))
{
num++;
}
}
}
return num;
}
}

View File

@@ -0,0 +1,26 @@
using System.Collections.Generic;
namespace Wizard;
public static class AITagCountFromIdUtility
{
public static int GetTagCountFromId(AIVirtualCard tagOwner, int id, List<AIScriptTokenBase> filters, AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
List<AIVirtualCard> list = AIFilteringUtility.MultipleFiltering(field.CardListSet.BothClassAndInplayCards, filters, tagOwner, playPtn, situation);
if (list == null || list.Count <= 0)
{
return 0;
}
int num = 0;
for (int i = 0; i < list.Count; i++)
{
num += GetAttachedTagCount(list[i], id);
}
return num;
}
public static int GetAttachedTagCount(AIVirtualCard card, int id)
{
return card.TagCollectionContainer.AttachedTags?.GetAttachedTagCountFromId(id) ?? 0;
}
}

View File

@@ -0,0 +1,13 @@
namespace Wizard;
internal class AITurnEndMove : AIMove
{
public AITurnEndMove()
: base(AIOperationType.TURNEND)
{
}
public override void RunOperation(BattleManagerBase mgr, bool isPlayer)
{
}
}

View File

@@ -0,0 +1,42 @@
using System.Collections.Generic;
namespace Wizard;
public class AITyrantOrderSelectLogicArgument : AISelectLogicArgumentBase
{
public override AIScriptTokenArgType LogicType => AIScriptTokenArgType.TYRANT_ORDER_LOGIC;
public AITyrantOrderSelectLogicArgument(List<string> args)
: base(args)
{
}
public override AIVirtualCard SelectSingleTarget(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
AIConsoleUtility.LogError("AITyrantOrderSelectLogicArgument: This logic is cant use single target select");
return null;
}
public override List<AIVirtualCard> SelectMultipleSelectedTargets(List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
List<AIVirtualCard> list = new List<AIVirtualCard>(candidates);
list.RemoveAll((AIVirtualCard c) => c.IsLeader || c.IsDead || c.IsIndependent || c.IsSneak || c.IsUntouchable);
if (list.Count == selectCount)
{
return list;
}
if (list.Count < selectCount)
{
AIConsoleUtility.LogError("AITyrantOrderSelectLogicArgument:SelectMultipleSelectedTargets() - Targets dont meet the minimum number.");
return null;
}
AIReverseEvaluateValueListOrder aIReverseEvaluateValueListOrder = new AIReverseEvaluateValueListOrder();
for (int num = 0; num < list.Count; num++)
{
AIVirtualCard aIVirtualCard = list[num];
float value = ((!aIVirtualCard.IsForceTargeting) ? ((!aIVirtualCard.IsAmulet) ? AISimulationRemovalUtility.CalculateRemovalValue(aIVirtualCard, field, playPtn, situation, AIRemovalType.Destroy, null) : 0f) : float.MinValue);
aIReverseEvaluateValueListOrder.AddData(value, aIVirtualCard);
}
return aIReverseEvaluateValueListOrder.GetCardList(selectCount);
}
}

View File

@@ -0,0 +1,9 @@
namespace Wizard;
public class AIUntouchableStopPreprocessOption : AITagPreprocessCreationOptionBase
{
public AIUntouchableStopPreprocessOption(AIVirtualCard targetCard)
: base(AITagPreprocessInfoType.UNTOUCHABLE_STOP, targetCard)
{
}
}

View File

@@ -0,0 +1,120 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIVirtualCardUpdateInformationExtension
{
public static void UpdateCardInformation(this AIVirtualCard card, AIVirtualCard source)
{
card.UpdateOtherEvolveParameter(source);
card.UpdateAttachTagInformation(source);
card.UpdateRemovedTagInformation(source);
card.UpdateBarrierInfo(source);
card.UpdateWhenChangeInplayTagInformation(source);
card.UpdateRemovedAttachTagInformation(source);
card.UpdateActivateCounter(source);
card.CopyCannotAttackInfoList(source);
}
private static void UpdateOtherEvolveParameter(this AIVirtualCard card, AIVirtualCard source)
{
card.SetOtherEvolveParameterFromVirtualCard(source);
}
private static void UpdateWhenChangeInplayTagInformation(this AIVirtualCard owner, AIVirtualCard updateSource)
{
if (owner.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenChangeInplay) && updateSource.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenChangeInplay))
{
ChangeInplayTagCollection changeInplayTags = owner.TagCollectionContainer.ChangeInplayTags;
ChangeInplayTagCollection changeInplayTags2 = updateSource.TagCollectionContainer.ChangeInplayTags;
changeInplayTags.UpdateIsActivatedInformation(changeInplayTags2.TagIsActivatedList, changeInplayTags2.AddedChangeInplayActivatedInfoIncrement);
}
}
private static void UpdateAttachTagInformation(this AIVirtualCard owner, AIVirtualCard updateSource)
{
AIAttachedTagCollection attachedTags = updateSource.TagCollectionContainer.AttachedTags;
if (attachedTags == null || !attachedTags.HasAnyTag)
{
return;
}
List<ulong> list = null;
AIAttachedTagCollection attachedTags2 = owner.TagCollectionContainer.AttachedTags;
if (attachedTags2 != null && attachedTags2.HasAnyTag)
{
for (int i = 0; i < attachedTags2.AllList.Count; i++)
{
list = AIParamQuery.AddElementToList(attachedTags2.AllList[i].Hash, list);
}
}
for (int j = 0; j < attachedTags.AllList.Count; j++)
{
AIAttachedTagInformation aIAttachedTagInformation = attachedTags.AllList[j];
int num = -1;
if (list != null && list.Count > 0)
{
num = list.IndexOf(aIAttachedTagInformation.Hash);
}
if (num >= 0)
{
list.RemoveAt(num);
}
else
{
owner.TagCollectionContainer.AttachTag(aIAttachedTagInformation, owner, null);
}
}
}
private static void UpdateRemovedTagInformation(this AIVirtualCard tagOwner, AIVirtualCard updateSource)
{
AIRemovedTagCollection removedTagCollection = tagOwner.TagCollectionContainer.RemovedTagCollection;
AIRemovedTagCollection removedTagCollection2 = updateSource.TagCollectionContainer.RemovedTagCollection;
if ((removedTagCollection.AllList == null && removedTagCollection2.AllList == null) || removedTagCollection2.AllList == null || removedTagCollection2.AllList.Count <= 0)
{
return;
}
int num = ((removedTagCollection.AllList != null) ? removedTagCollection.AllList.Count : 0);
int num2 = ((removedTagCollection2.AllList != null) ? removedTagCollection2.AllList.Count : 0);
if (num < num2)
{
for (int i = num; i < removedTagCollection2.AllList.Count; i++)
{
AIRemovedTagInformation aIRemovedTagInformation = removedTagCollection2.AllList[i];
tagOwner.TagCollectionContainer.RemoveOneTagWithUpdatingFieldCardList(tagOwner, aIRemovedTagInformation.Tag, tagOwner.SelfField);
removedTagCollection.Add(aIRemovedTagInformation);
}
}
}
private static void UpdateRemovedAttachTagInformation(this AIVirtualCard owner, AIVirtualCard source)
{
AIAttachedTagCollection attachedTags = owner.TagCollectionContainer.AttachedTags;
AIAttachedTagCollection attachedTags2 = source.TagCollectionContainer.AttachedTags;
if (attachedTags != null && attachedTags.HasAnyTag && attachedTags2 != null && attachedTags2.HasRemovedInfoCaches)
{
List<AIPlayTag> removedTagCacheList = attachedTags2.RemovedTagCacheList;
for (int i = 0; i < removedTagCacheList.Count; i++)
{
AIPlayTag removingInfo = removedTagCacheList[i];
AIRemoveTagUtility.RemoveTemporaryAttachedTag(owner, owner.SelfField, removingInfo, null);
}
removedTagCacheList.Clear();
}
}
private static void UpdateBarrierInfo(this AIVirtualCard card, AIVirtualCard source)
{
card.BarrierInfoCollection = source.BarrierInfoCollection.Clone();
}
private static void UpdateActivateCounter(this AIVirtualCard card, AIVirtualCard source)
{
if (card.TagCollectionContainer.HasTagCollection(TagCollectionType.ActivateCount) && source.TagCollectionContainer.HasTagCollection(TagCollectionType.ActivateCount))
{
ActivateCountTagCollection activateCountTags = card.TagCollectionContainer.ActivateCountTags;
ActivateCountTagCollection activateCountTags2 = source.TagCollectionContainer.ActivateCountTags;
activateCountTags.UpdateCounterList(activateCountTags2.ActivateCounterList);
}
}
}

View File

@@ -0,0 +1,29 @@
namespace Wizard;
public static class AIVirtualFieldInitializeUtility
{
public static void FindBuildParameterAndApply(this AIVirtualCard self, AIVirtualFieldBuildParameterCollction fieldBuildParameter)
{
ReferableVirtualCardBuildParameterCollection referableCardBuildParameter = fieldBuildParameter.GetReferableCardBuildParameter(self);
if (referableCardBuildParameter != null)
{
self.GetInformationFromCardBuildParameter(referableCardBuildParameter);
}
}
private static void GetInformationFromCardBuildParameter(this AIVirtualCard self, ReferableVirtualCardBuildParameterCollection cardBuildParameter)
{
self.BarrierInfoCollection.GetBarrierInfoFromPreviousField(cardBuildParameter.BarrierInfoCollection);
cardBuildParameter.AttachedTags.AttachTagToReceiver(self);
cardBuildParameter.RemovedTags.RemoveTagFromCard(self);
if (self.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenChangeInplay))
{
self.TagCollectionContainer.ChangeInplayTags.UpdateIsActivatedInformation(cardBuildParameter.ChangeInplayTagIsActivatedInfoList, cardBuildParameter.AddedChangeInplayTagActivatedInfoIncrement);
}
if (self.TagCollectionContainer.HasTagCollection(TagCollectionType.ActivateCount))
{
self.TagCollectionContainer.ActivateCountTags.UpdateCounterList(cardBuildParameter.ActivateCounterList);
}
self.SetOtherEvolveParameterFromBuildParameter(cardBuildParameter);
}
}

View File

@@ -0,0 +1,232 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIVirtualFieldTagProcessExtension
{
public static void ExecuteWhenChangeInplayTags(this AIVirtualField field, List<int> playPtn, AISituationInfo situation)
{
if (!field.CardListSet.HasWhenChangeInplayHolder)
{
return;
}
List<AIVirtualCard> whenChangeInplayHolders = field.CardListSet.WhenChangeInplayHolders;
for (int i = 0; i < whenChangeInplayHolders.Count; i++)
{
AIVirtualCard aIVirtualCard = whenChangeInplayHolders[i];
if (!aIVirtualCard.IsDead)
{
aIVirtualCard.ExecuteWhenChangeInplayTag(field, playPtn, situation);
}
}
}
public static void UpdateTagInformationFromLatestAction(this AIVirtualField currentField, AIRealActionInformation latestAction, AIVirtualField beforeLatestActionField)
{
AIVirtualField aIVirtualField = new AIVirtualField(beforeLatestActionField, isLatestAction: true);
AISituationInfo aISituationInfo = latestAction.CreateSituationInfo(aIVirtualField);
if (aISituationInfo != null)
{
EnemyAI aI = currentField.AI;
List<AIVirtualCard> enemyHandCardList = currentField.GetEnemyHandCardList();
for (int i = 0; i < enemyHandCardList.Count; i++)
{
AIVirtualCard aIVirtualCard = enemyHandCardList[i];
aI.tokenManager.AddTokenFromId(aIVirtualCard.BaseId, aIVirtualCard.IsAlly);
}
aISituationInfo.SetLatestActionSimulationParameter();
SimulateLatestAction(aISituationInfo, aIVirtualField);
currentField.UpdateFieldParameterFromLatestActionField(aIVirtualField);
AIGenerateTagUtility.ExecuteGenerateTag(aISituationInfo, currentField, aI.GenerateTagOwnerTable, aI.BattleInfoReceivedData.AttachedInfoReceiveCollection);
}
}
private static AIVirtualCard FindSimilarCardFromSimulationField(AIVirtualCard card, AIVirtualField realField, AIVirtualField simulationField)
{
List<AIVirtualCard> list = null;
int num = -1;
if (card.IsInHand)
{
list = simulationField.AllyHandCards;
num = realField.AllyHandCards.IndexOf(card);
}
else if (card.IsOnField)
{
if (card.IsAlly)
{
list = simulationField.CardListSet.AllyClassAndInplayCards;
num = realField.CardListSet.AllyClassAndInplayCards.IndexOf(card);
}
else
{
list = simulationField.CardListSet.EnemyClassAndInplayCards;
num = realField.CardListSet.EnemyClassAndInplayCards.IndexOf(card);
}
}
if (list == null || num < 0 || num >= list.Count)
{
return null;
}
int num2 = 0;
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (!aIVirtualCard.IsDead)
{
if (num2 < num)
{
num2++;
}
else if (num2 == num && aIVirtualCard.BaseId == card.BaseId)
{
return aIVirtualCard;
}
}
}
return null;
}
private static AIVirtualCard FindSimilarCardFromEnemyHand(AIVirtualCard card, AIVirtualField realField, AIVirtualField simulationField)
{
List<AIVirtualCard> list = null;
int num = -1;
if (card.IsInHand)
{
list = simulationField.GetEnemyHandCardList();
num = realField.GetEnemyHandCardList().IndexOf(card);
}
if (list == null || num < 0 || num >= list.Count)
{
return null;
}
int num2 = 0;
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (num2 < num && !aIVirtualCard.IsDead)
{
num2++;
}
else if (num2 == num && aIVirtualCard.BaseId == card.BaseId)
{
return aIVirtualCard;
}
}
return null;
}
private static void SimulateLatestAction(AISituationInfo latestAction, AIVirtualField field)
{
switch (latestAction.ActionType)
{
case AIOperationType.PLAY:
{
PlaySimulationInfo playInfo = AIPlayCardSimulationUtility.CreatePlaySimulationInfo(latestAction.Actor, latestAction, field);
AIVirtualPlaySimulator.PlayCard((AIVirtualTargetSelectAction)latestAction, field, playInfo);
break;
}
case AIOperationType.EVOLVE:
AIVirtualEvolutionSimulator.ManualEvolve((AIVirtualTargetSelectAction)latestAction, field);
break;
case AIOperationType.ATTACK:
AIVirtualAttackSimulator.Attack((AIVirtualAttackInfo)latestAction, field);
break;
case AIOperationType.TURNEND:
{
AIVirtualTurnEndSimulator.TurnEnd((AIVirtualTurnEndInfo)latestAction, field);
AIVirtualTurnStartInfo aIVirtualTurnStartInfo = new AIVirtualTurnStartInfo(latestAction.Actor.IsAlly ? field.EnemyClass : field.AllyClass);
aIVirtualTurnStartInfo.SetLatestActionSimulationParameterFromPreAction(latestAction);
AIVirtualTurnStartSimulator.TurnStart(aIVirtualTurnStartInfo, field);
break;
}
case AIOperationType.FUSION:
AIVirtualFusionSimulator.Fusion((AIVirtualTargetSelectAction)latestAction, field);
break;
}
}
private static void UpdateFieldParameterFromLatestActionField(this AIVirtualField field, AIVirtualField afterLatestActionField)
{
field.UpdateFieldInformationBeforeCardUpdating(afterLatestActionField);
for (int i = 0; i < field.CardListSet.AllReferableCards.Count; i++)
{
AIVirtualCard card = field.CardListSet.AllReferableCards[i];
AIVirtualCard aIVirtualCard = FindSimilarCardFromSimulationField(card, field, afterLatestActionField);
if (aIVirtualCard != null)
{
card.UpdateCardInformation(aIVirtualCard);
}
}
for (int j = 0; j < field.GetEnemyHandCardList().Count; j++)
{
AIVirtualCard card2 = field.GetEnemyHandCardList()[j];
AIVirtualCard aIVirtualCard2 = FindSimilarCardFromEnemyHand(card2, field, afterLatestActionField);
if (aIVirtualCard2 != null)
{
card2.UpdateCardInformation(aIVirtualCard2);
}
}
field.UpdateFieldInformationAfterCardUpdating(afterLatestActionField);
}
private static void UpdateFieldInformationBeforeCardUpdating(this AIVirtualField currentField, AIVirtualField otherField)
{
currentField.SetParametersFromOtherField(otherField);
}
private static void UpdateFieldInformationAfterCardUpdating(this AIVirtualField currentField, AIVirtualField otherField)
{
currentField.TagPreprocessContainer = otherField.TagPreprocessContainer.Clone(currentField);
currentField.DamageModifierCollection = otherField.DamageModifierCollection.Clone(currentField);
currentField.IsNoInstantAttackRecheck();
}
public static void ApplyAttackBonus(this AIVirtualField field, AIVirtualAttackInfo situation)
{
if (situation.IsUsePreCheck)
{
field.SimulationExtraBonus += situation.PreCheckInformation.AttackBonus;
}
else
{
field.SimulationExtraBonus += situation.Actor.GetAttackBonus(field.BestPlayPtn, situation);
}
}
public static void ApplyClashBonus(this AIVirtualField field, AIVirtualAttackInfo situation)
{
AIVirtualCard actor = situation.Actor;
AIVirtualCard attackTarget = situation.AttackTarget;
if (attackTarget.IsUnit)
{
field.SimulationExtraBonus += actor.GetClashBonus();
field.SimulationExtraBonus += attackTarget.GetClashBonus();
}
}
public static void ApplyBuffBonus(this AIVirtualField field, AIVirtualCard buffedCard, List<int> playPtn, AISituationInfo situation)
{
field.SimulationExtraBonus += buffedCard.GetBuffBonus(playPtn, situation);
}
public static void ExecuteWhenDamageTags(this AIVirtualField field, AIVirtualCard damagedTarget, int defaultDamage, List<int> playPtn, AISituationInfo situation)
{
if (damagedTarget.Life <= 0)
{
return;
}
if (damagedTarget.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenDamaged))
{
damagedTarget.TagCollectionContainer.DamagedTags.RegisterPassedConditionTags(damagedTarget, field, playPtn, situation);
}
List<AIVirtualCard> otherDamagedTagHolders = field.CardListSet.OtherDamagedTagHolders;
if (otherDamagedTagHolders != null)
{
for (int i = 0; i < otherDamagedTagHolders.Count; i++)
{
AIVirtualCard aIVirtualCard = otherDamagedTagHolders[i];
aIVirtualCard.TagCollectionContainer.OtherDamagedTags.RegisterPassedConditionTags(aIVirtualCard, damagedTarget, defaultDamage, field, playPtn, situation);
}
}
}
}

View File

@@ -0,0 +1,45 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIVirtualFusionSimulator
{
public static void Fusion(AIVirtualTargetSelectAction situation, AIVirtualField field)
{
if (situation.ActionType != AIOperationType.FUSION)
{
AIConsoleUtility.LogError("AIVirtualFusionSimulator:Fusion() error!! situation is not [FUSION] ActionType!!!!!");
return;
}
if (!situation.IsTargetExists(AIScriptTokenArgType.TARGET_SELECT))
{
AIConsoleUtility.LogError("AIVirtualFusionSimulator:Fusion() error!! cannot find fusion ingredients!!!!!");
return;
}
FusionMoveCard(situation, field);
AIVirtualCard actor = situation.Actor;
if (actor.TagCollectionContainer.HasTag(AIPlayTagType.FusionMetamorphose))
{
actor.TagCollectionContainer.FusionMetamorphoseTags.ExecuteMetamorphose(actor, field, field.BestPlayPtn, situation);
}
}
private static void FusionMoveCard(AIVirtualTargetSelectAction situation, AIVirtualField field)
{
List<AIVirtualCard> targets = situation.GetSituationTarget(AIScriptTokenArgType.TARGET_SELECT).Targets;
bool isAlly = situation.Actor.IsAlly;
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (isAlly)
{
field.RemoveAllyHandCard(aIVirtualCard);
}
else
{
field.RemoveEnemyHandCard(aIVirtualCard);
}
situation.Actor.FusionIngredients.AddFusionIngredient(aIVirtualCard, field.CurrentTurnCount);
}
}
}

View File

@@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace Wizard;
public class AIVirtualRemovalInfo
{
public bool IsFirstTargetSelected;
public List<AIPlayTag> Tags { get; private set; }
public AIVirtualRemovalInfo(List<AIPlayTag> tags)
{
Tags = tags;
IsFirstTargetSelected = false;
}
}

View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
namespace Wizard;
public static class AIVirtualTurnStartSimulator
{
public static void TurnStart(AIVirtualTurnStartInfo situation, AIVirtualField field)
{
if (situation.ActionType != AIOperationType.TURNSTART)
{
AIConsoleUtility.LogError("AIVirtualTurnStartSimulator:TurnStart() error!! situation is not [TURNSTART] ActionType!!!!!");
return;
}
field.TurnStartFieldProcess(situation);
List<AIVirtualCard> whenChangeInplayHolders = field.CardListSet.WhenChangeInplayHolders;
if (whenChangeInplayHolders != null)
{
for (int i = 0; i < whenChangeInplayHolders.Count; i++)
{
AIVirtualCard aIVirtualCard = whenChangeInplayHolders[i];
if (!aIVirtualCard.IsDead && aIVirtualCard.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenChangeInplay))
{
aIVirtualCard.TagCollectionContainer.ChangeInplayTags.ExecuteWhenTurnStart(aIVirtualCard, field, situation);
}
}
}
List<AIVirtualCard> turnStartTagHolders = field.CardListSet.TurnStartTagHolders;
if (turnStartTagHolders != null && turnStartTagHolders.Count > 0)
{
for (int j = 0; j < turnStartTagHolders.Count; j++)
{
AIVirtualCard aIVirtualCard2 = turnStartTagHolders[j];
if (!aIVirtualCard2.IsDead && aIVirtualCard2.TagCollectionContainer.HasTagCollection(TagCollectionType.WhenTurnStart))
{
AIScriptTokenArgType turnStartSide = GetTurnStartSide(aIVirtualCard2, situation);
aIVirtualCard2.TagCollectionContainer.TurnStartTags.RegisterConditionPassedTagActions(aIVirtualCard2, situation, turnStartSide);
}
}
}
field.TagPreprocessContainer.SimulateAllTurnStartInfo(situation.Actor.IsAlly, situation);
situation.ExecuteAllSkillProcess();
}
private static AIScriptTokenArgType GetTurnStartSide(AIVirtualCard owner, AIVirtualTurnStartInfo situation)
{
if (owner.IsAlly == situation.Actor.IsAlly)
{
return AIScriptTokenArgType.ALLY;
}
return AIScriptTokenArgType.OPPONENT;
}
public static void TurnStartFieldProcess(this AIVirtualField field, AIVirtualTurnStartInfo situation)
{
field.ReverseAllCardIsSelfTurn();
field.PlayedCardContainer.ClearInTurn(situation);
if (situation.Actor.IsAlly)
{
field.AllyTurnCount++;
field.AllyPpTotal = Math.Min(field.AllyPpTotal + 1, 10);
}
else
{
field.EnemyTurnCount++;
field.EnemyPpTotal = Math.Min(field.EnemyPpTotal + 1, 10);
}
if (!field.IsLatestActionField)
{
return;
}
for (int i = 0; i < field.CardListSet.AllReferableCards.Count; i++)
{
AIVirtualCard aIVirtualCard = field.CardListSet.AllReferableCards[i];
if (aIVirtualCard.TagCollectionContainer.HasTagCollection(TagCollectionType.ActivateCount))
{
bool isOwnerTurn = aIVirtualCard.IsAlly == situation.Actor.IsAlly;
aIVirtualCard.TagCollectionContainer.ActivateCountTags.ResetAllCounter(isOwnerTurn);
}
}
}
}

View File

@@ -0,0 +1,57 @@
using System.Collections.Generic;
namespace Wizard;
public static class AIWhiteRitualSimulationUtility
{
public static void SimulateStack(AIVirtualCard stackOwner, AIVirtualField field, AISituationInfo situation, int defaultStack)
{
int num = defaultStack;
List<AIVirtualCard> list = (stackOwner.IsAlly ? field.AllyInplayCards : field.EnemyInplayCards);
if (list == null || list.Count <= 0)
{
stackOwner.SetWhiteRitual(num);
return;
}
for (int i = 0; i < list.Count; i++)
{
AIVirtualCard aIVirtualCard = list[i];
if (!aIVirtualCard.IsDead && aIVirtualCard.IsAmulet && aIVirtualCard.IsStackWhiteRitual && aIVirtualCard.WhiteRitualCount > 0 && !aIVirtualCard.IsSameCard(stackOwner))
{
aIVirtualCard.RemoveCard(situation, AIRemovalType.Banish, isFromSkill: true);
if (aIVirtualCard.IsDead)
{
num += aIVirtualCard.WhiteRitualCount;
}
}
}
stackOwner.SetWhiteRitual(num);
}
public static bool AddWhiteRitualTargetCard(int count, AIVirtualCard target)
{
if (target == null)
{
AIConsoleUtility.LogError("AddWhiteRitualTargetCard : target is missing!");
return false;
}
return target.AddWhiteRitual(count);
}
public static void AddWhiteRitualSingle(int count, List<AIVirtualCard> targets)
{
if (targets == null || targets.Count <= 0)
{
AIConsoleUtility.LogError("AddWhiteRitualSingle : target is missing!");
return;
}
for (int i = 0; i < targets.Count; i++)
{
AIVirtualCard aIVirtualCard = targets[i];
if (!aIVirtualCard.IsIndependent && aIVirtualCard.WhiteRitualCount > 0 && AddWhiteRitualTargetCard(count, aIVirtualCard))
{
break;
}
}
}
}

View File

@@ -0,0 +1,43 @@
using System.Collections.Generic;
namespace Wizard;
public class AIWhitefrostWhisperLogicArgument : AISelectLogicArgumentBase
{
private const int WHITEFROST_WHISPER_DAMAGE = 1;
public override AIScriptTokenArgType LogicType => AIScriptTokenArgType.WHITEFROST_WHISPER_LOGIC;
public AIWhitefrostWhisperLogicArgument(List<string> args)
: base(args)
{
}
public override AIVirtualCard SelectSingleTarget(List<AIVirtualCard> candidates, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
float num = float.MinValue;
AIVirtualCard result = null;
for (int i = 0; i < candidates.Count; i++)
{
AIVirtualCard aIVirtualCard = candidates[i];
if (aIVirtualCard.IsDead)
{
AIConsoleUtility.LogError("AIWhitefrostWhisperLogicArgument.SelectSingleTarget() error!! candidate is already dead!!!!!");
continue;
}
float num2 = ((aIVirtualCard.Life >= aIVirtualCard.MaxLife) ? AIDamageSimulationUtility.GetDamageValueToCertainTarget(aIVirtualCard, 1, situation, playPtn, tagOwner.IsSpell) : ((!aIVirtualCard.IsIndependent && !aIVirtualCard.IsIndestructible) ? AIDestroySimulationUtility.CalcEvalDestroy(aIVirtualCard, playPtn, situation, useIgnoreBreak: false) : 0f));
if (num2 > num)
{
num = num2;
result = aIVirtualCard;
}
}
return result;
}
public override List<AIVirtualCard> SelectMultipleSelectedTargets(List<AIVirtualCard> candidates, int selectCount, AIVirtualCard tagOwner, AIVirtualField field, List<int> playPtn, AISituationInfo situation, AISelectTargetPattern worstOrBest)
{
AIConsoleUtility.LogError("AIWhitefrostWhisperLogicArgument.SelectMultipleSelectedTargets() error!! Not implemented!!!!!");
return null;
}
}

View File

@@ -0,0 +1,9 @@
namespace Wizard;
public class AbortSoloPlayRecoveryTask : BaseTask
{
public AbortSoloPlayRecoveryTask()
{
base.type = ApiType.Type.AbortSoloPlayRecovery;
}
}

View File

@@ -0,0 +1,73 @@
namespace Wizard;
public class AcceptAgreementTask : BaseTask
{
private class Param : BaseParam
{
public int agreement_type;
public int agreement_id;
}
public enum Type
{
TOS = 1,
PrivacyPolicy,
KorAuthority
}
private Type _agreedType;
public static int _tosId;
public static int _privacyPolicyId;
public static int KorAuthorityId;
public AcceptAgreementTask()
{
base.type = ApiType.Type.AcceptAgreement;
}
public void SetParameter(Type agreedType)
{
_agreedType = agreedType;
Param param = new Param();
param.agreement_type = (int)agreedType;
switch (agreedType)
{
case Type.TOS:
param.agreement_id = _tosId;
break;
case Type.PrivacyPolicy:
param.agreement_id = _privacyPolicyId;
break;
case Type.KorAuthority:
param.agreement_id = KorAuthorityId;
break;
}
base.Params = param;
}
protected override int Parse()
{
int num = base.Parse();
if (num != 1)
{
return num;
}
switch (_agreedType)
{
case Type.TOS:
PlayerStaticData._tosAgreementState = PlayerStaticData.AgreementState.Agreed;
break;
case Type.PrivacyPolicy:
PlayerStaticData._privacyPolicyAgreementState = PlayerStaticData.AgreementState.Agreed;
break;
case Type.KorAuthority:
PlayerStaticData.KorAuthorityAgreementState = PlayerStaticData.AgreementState.Agreed;
break;
}
return num;
}
}

View File

@@ -0,0 +1,36 @@
namespace Wizard;
public class AchievementReceiveRewardTask : BaseTask
{
public class AchievementReceiveRewardTaskParam : BaseParam
{
public int achievement_type;
public int level;
}
public AchievementReceiveRewardTask()
{
base.type = ApiType.Type.AchievementReceiveReward;
}
public void SetParameter(int achievement_type, int level)
{
AchievementReceiveRewardTaskParam achievementReceiveRewardTaskParam = new AchievementReceiveRewardTaskParam();
achievementReceiveRewardTaskParam.achievement_type = achievement_type;
achievementReceiveRewardTaskParam.level = level;
base.Params = achievementReceiveRewardTaskParam;
}
protected override int Parse()
{
int num = base.Parse();
if (num != 1)
{
return num;
}
Data.MissionInfo.data = new MissionInfoDetail(base.ResponseData["data"]);
PlayerStaticData.UpdateHaveUserGoodsNumByJsonData(base.ResponseData["data"]["reward_list"]);
return num;
}
}

View File

@@ -0,0 +1,205 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Cute;
using UnityEngine;
using Wizard.ErrorDialog;
namespace Wizard;
public class ArenaCommonLobby : MonoBehaviour
{
[SerializeField]
private BoxCollider _clickProtectionCollider;
[SerializeField]
private UITexture _charaTexture;
[SerializeField]
private GameObject _mainObjectRoot;
[SerializeField]
private ArenaCommonLobbyBattleInfo _battleInfo;
[SerializeField]
private ArenaCommonLobbyTreasureBoxInfo _treasureBoxInfo;
[SerializeField]
private GameObject _buttonsRoot;
[SerializeField]
private UIButton _decisionButton;
[SerializeField]
private UILabel _decisionButtonLabel;
private const ResourcesManager.AssetLoadPathType CHARA_TEXTURE_TYPE = ResourcesManager.AssetLoadPathType.ClassCharaBase;
private const iTween.EaseType MOVE_EASE_TYPE = iTween.EaseType.easeOutExpo;
private const float CHARA_MOVE_DIST = 4.6875f;
private const float CHARA_MOVE_TIME = 0.5f;
private const float MAIN_OBJECT_MOVE_DIST = 2.8125f;
private const float MAIN_OBJECT_MOVE_TIME = 0.5f;
private const float MAIN_OBJECT_MOVE_DELAY = 0.2f;
private const float BUTTON_MOVE_DIST = 1.5625f;
private const float BUTTON_MOVE_TIME = 0.5f;
private const float BUTTON_MOVE_DELAY = 0.5f;
private List<string> _unloadAssetList = new List<string>();
private GameObject _decisionButtonEffect;
private bool _isDecisionButtonDark;
private Vector3 _charaInitPos = Vector3.zero;
private Vector3 _mainObjectInitPos = Vector3.zero;
private Vector3 _buttonInitPos = Vector3.zero;
public BoxCollider ClickProtectionCollider => _clickProtectionCollider;
public ArenaCommonLobbyTreasureBoxInfo TreasureBoxInfo => _treasureBoxInfo;
public GameObject ButtonsRoot => _buttonsRoot;
public bool IsReady { get; private set; }
public void Init(ArenaCommonLobbyInitParam initParam)
{
_clickProtectionCollider.gameObject.SetActive(value: false);
_charaInitPos = _charaTexture.transform.position;
_mainObjectInitPos = _mainObjectRoot.transform.position;
_buttonInitPos = _decisionButton.transform.position;
_charaTexture.transform.position = _charaInitPos + Vector3.right * 4.6875f;
_mainObjectRoot.transform.position = _mainObjectInitPos + Vector3.left * 2.8125f;
_decisionButton.transform.position = _buttonInitPos + Vector3.right * 1.5625f;
SystemText systemText = Data.SystemText;
int num = initParam.BattleResultList.Length;
bool battleExists = num < initParam.BattleMaxNum;
_decisionButtonLabel.text = (battleExists ? systemText.Get("Arena_0051", (num + 1).ToString()) : systemText.Get("Arena_0027"));
UIEventListener.Get(_decisionButton.gameObject).onClick = delegate
{
if (battleExists && initParam.BattleMaintenanceType.HasValue)
{
NetworkDefine.MAINTENANCE_TYPE value = initParam.BattleMaintenanceType.Value;
if (Data.MaintenanceCodeList.Contains(value))
{
Wizard.ErrorDialog.Dialog.Create((int)value);
return;
}
}
(battleExists ? initParam.BattleButtonClickCallback : initParam.RewardReceiveButtonClickCallback)();
};
List<string> loadAssetList = new List<string>();
List<Action> loadEndCallbackList = new List<Action>();
ResourcesManager resMgr = Toolbox.ResourcesManager;
string strSkinId = GameMgr.GetIns().GetDataMgr().GetCharaPrmByClassId(initParam.ClassId)
.skin_id.ToString();
loadAssetList.Add(resMgr.GetAssetTypePath(strSkinId, ResourcesManager.AssetLoadPathType.ClassCharaBase));
loadAssetList.Add(resMgr.GetAssetTypePath("cmn_ui_btn_1", ResourcesManager.AssetLoadPathType.Effect2D));
ArenaCommonLobbyLoadRequest arenaCommonLobbyLoadRequest = _battleInfo.Init(initParam, _unloadAssetList);
loadAssetList.AddRange(arenaCommonLobbyLoadRequest.LoadAssetList);
loadEndCallbackList.Add(arenaCommonLobbyLoadRequest.LoadEndCallback);
arenaCommonLobbyLoadRequest = _treasureBoxInfo.Init(initParam, _unloadAssetList);
loadAssetList.AddRange(arenaCommonLobbyLoadRequest.LoadAssetList);
loadEndCallbackList.Add(arenaCommonLobbyLoadRequest.LoadEndCallback);
StartCoroutine(resMgr.LoadAssetGroupAsync(loadAssetList, delegate
{
_unloadAssetList.AddRange(loadAssetList);
for (int i = 0; i < loadEndCallbackList.Count; i++)
{
loadEndCallbackList[i]();
}
UIManager.GetInstance().AttachAtlas(base.gameObject);
_charaTexture.mainTexture = resMgr.LoadObject<Texture>(resMgr.GetAssetTypePath(strSkinId, ResourcesManager.AssetLoadPathType.ClassCharaBase, isfetch: true));
_decisionButtonEffect = EffectUtility.CreateEffect2D(new Effect2dCreateParam
{
Parent = _decisionButton.gameObject,
EffectName = "cmn_ui_btn_1",
ColorCode = eColorCodeId.DECISION_BTN_2_COLOR,
InitActive = !_isDecisionButtonDark,
UnloadAssetList = _unloadAssetList
});
AppearAnimation();
IsReady = true;
}));
}
public void Final()
{
Toolbox.ResourcesManager.RemoveAssetGroup(_unloadAssetList);
_unloadAssetList.Clear();
}
private void AppearAnimation()
{
StartCoroutine(AppearAnimationCoroutine());
}
private IEnumerator AppearAnimationCoroutine()
{
while (UIManager.GetInstance().isFading())
{
yield return null;
}
GameMgr.GetIns().GetSoundMgr().PlaySe(Se.TYPE.SYS_WINDOW_MOVE);
iTween.MoveTo(_charaTexture.gameObject, iTween.Hash("position", _charaInitPos, "time", 0.5f, "islocal", false, "easetype", iTween.EaseType.easeOutExpo));
iTween.MoveTo(_mainObjectRoot, iTween.Hash("position", _mainObjectInitPos, "time", 0.5f, "delay", 0.2f, "islocal", false, "easetype", iTween.EaseType.easeOutExpo));
iTween.MoveTo(_decisionButton.gameObject, iTween.Hash("position", _buttonInitPos, "time", 0.5f, "delay", 0.5f, "islocal", false, "easetype", iTween.EaseType.easeOutExpo));
}
public void SetDecisionButtonToDark(bool isDark)
{
UIManager.SetObjectToGrey(_decisionButton.gameObject, isDark);
_decisionButtonEffect?.SetActive(!isDark);
_isDecisionButtonDark = isDark;
}
public static void GenerateDeckCode(GenerateDeckCodeTask.SubmitDeckType deckType, int classId, int[] cardIdList, int[] phantomCardIdList = null)
{
GenerateDeckCodeTask generateDeckCodeTask = new GenerateDeckCodeTask();
generateDeckCodeTask.SetParameter(classId, deckType, cardIdList, phantomCardIdList);
UIManager.GetInstance().StartCoroutine(Toolbox.NetworkManager.Connect(generateDeckCodeTask, delegate
{
OpenDeckCodeGenerateCompleteDialog();
}, null, null, encrypt: false));
}
private static DialogBase OpenDeckCodeGenerateCompleteDialog()
{
string deckCode = Data.GenerateDeckCode.deck_code;
SystemText text = Data.SystemText;
DialogBase dialogBase = UIManager.GetInstance().CreateDialogClose();
dialogBase.SetSize(DialogBase.Size.S);
dialogBase.SetTitleLabel(text.Get("Card_0120"));
dialogBase.SetText(text.Get("Card_0128", deckCode));
dialogBase.SetButtonLayout(DialogBase.ButtonLayout.BlueBtn_GrayBtn);
dialogBase.SetButtonText(text.Get("Card_0133"), text.Get("Common_0008"));
dialogBase.onPushButton1 = delegate
{
NativePluginWrapper.SetStringToClipboard(deckCode);
UIManager.GetInstance().CreateConfirmationDialog(text.Get("Card_0132", deckCode));
};
return dialogBase;
}
public static DialogBase OpenRetireConfirmDialog()
{
SystemText systemText = Data.SystemText;
DialogBase dialogBase = UIManager.GetInstance().CreateDialogClose();
dialogBase.SetTitleLabel(systemText.Get("Common_0051"));
dialogBase.SetText(systemText.Get("Arena_0026"));
dialogBase.SetButtonLayout(DialogBase.ButtonLayout.RedBtn_CancelBtn);
dialogBase.SetButtonText(systemText.Get("Dia_Arena_006_Button"));
return dialogBase;
}
}

View File

@@ -0,0 +1,83 @@
using System.Collections.Generic;
using Cute;
using UnityEngine;
namespace Wizard;
public class ArenaCommonLobbyBattleInfo : MonoBehaviour
{
[SerializeField]
private UIGrid _battleStateObjectsGrid;
[SerializeField]
private ArenaCommonLobbyBattleStateObject _battleStateObjectOriginal;
[SerializeField]
private UISprite _battleStateObjectsLine;
[SerializeField]
private UILabel _winNumLabel;
public ArenaCommonLobbyLoadRequest Init(ArenaCommonLobbyInitParam initParam, List<string> unloadAssetList)
{
int maxNum = initParam.BattleMaxNum;
bool[] battleResultList = initParam.BattleResultList;
int num = battleResultList.Length;
ArenaCommonLobbyBattleStateObject[] stateObjectList = new ArenaCommonLobbyBattleStateObject[maxNum];
for (int i = 0; i < maxNum; i++)
{
ArenaCommonLobbyBattleStateObject component = NGUITools.AddChild(_battleStateObjectsGrid.gameObject, _battleStateObjectOriginal.gameObject).GetComponent<ArenaCommonLobbyBattleStateObject>();
stateObjectList[i] = component;
ArenaCommonLobbyBattleStateObject.eState state = ArenaCommonLobbyBattleStateObject.eState.None;
if (i < num)
{
state = (battleResultList[i] ? ArenaCommonLobbyBattleStateObject.eState.Won : ArenaCommonLobbyBattleStateObject.eState.Lost);
}
else if (i == num)
{
state = ArenaCommonLobbyBattleStateObject.eState.Next;
}
component.ChangeState(state);
component.SetTitleText(Data.SystemText.Get("Common_0103", (i + 1).ToString()));
}
_battleStateObjectsGrid.cellWidth = _battleStateObjectsLine.width / (maxNum - 1);
_battleStateObjectsGrid.Reposition();
int battleWinNum = initParam.BattleWinNum;
_winNumLabel.text = battleWinNum.ToString();
ArenaCommonLobbyLoadRequest arenaCommonLobbyLoadRequest = new ArenaCommonLobbyLoadRequest();
bool loadExists = false;
if (battleWinNum > 0)
{
arenaCommonLobbyLoadRequest.LoadAssetList.Add(Toolbox.ResourcesManager.GetAssetTypePath("cmn_ui_orb_1", ResourcesManager.AssetLoadPathType.Effect2D));
loadExists = true;
}
if (num - battleWinNum > 0)
{
arenaCommonLobbyLoadRequest.LoadAssetList.Add(Toolbox.ResourcesManager.GetAssetTypePath("cmn_ui_orb_2", ResourcesManager.AssetLoadPathType.Effect2D));
loadExists = true;
}
arenaCommonLobbyLoadRequest.LoadEndCallback = delegate
{
if (loadExists)
{
for (int j = 0; j < maxNum; j++)
{
ArenaCommonLobbyBattleStateObject arenaCommonLobbyBattleStateObject = stateObjectList[j];
bool isWon = arenaCommonLobbyBattleStateObject.IsWon;
if (isWon || arenaCommonLobbyBattleStateObject.IsLost)
{
EffectUtility.CreateEffect2D(new Effect2dCreateParam
{
Parent = arenaCommonLobbyBattleStateObject.gameObject,
EffectName = (isWon ? "cmn_ui_orb_1" : "cmn_ui_orb_2"),
ColorCode = (isWon ? eColorCodeId.WIN_ORB_EFFECT_COLOR : eColorCodeId.LOSE_ORB_EFFECT_COLOR),
InitActive = true,
UnloadAssetList = unloadAssetList
});
}
}
}
};
return arenaCommonLobbyLoadRequest;
}
}

View File

@@ -0,0 +1,57 @@
using UnityEngine;
namespace Wizard;
public class ArenaCommonLobbyBattleStateObject : MonoBehaviour
{
public enum eState
{
None,
Won,
Lost,
Next,
Max
}
[SerializeField]
private GameObject _nextBattleMark;
[SerializeField]
private UILabel _winLabel;
[SerializeField]
private UILabel _loseLabel;
[SerializeField]
private UISprite _stateIcon;
[SerializeField]
private UILabel _titleLabel;
private readonly string[] STATE_ICON_SPRITE_NAME_TABLE = new string[4] { "orb_empty", "orb_win", "orb_lose", "orb_empty" };
private readonly int[] STATE_ICON_SPRITE_SIZE_TABLE = new int[4] { 25, 70, 70, 70 };
public eState State { get; private set; }
public bool IsWon => State == eState.Won;
public bool IsLost => State == eState.Lost;
public void ChangeState(eState state)
{
State = state;
_nextBattleMark.SetActive(state == eState.Next);
_winLabel.gameObject.SetActive(state == eState.Won);
_loseLabel.gameObject.SetActive(state == eState.Lost);
_stateIcon.spriteName = STATE_ICON_SPRITE_NAME_TABLE[(int)state];
UISprite stateIcon = _stateIcon;
int width = (_stateIcon.height = STATE_ICON_SPRITE_SIZE_TABLE[(int)state]);
stateIcon.width = width;
}
public void SetTitleText(string text)
{
_titleLabel.text = text;
}
}

View File

@@ -0,0 +1,20 @@
using System;
namespace Wizard;
public class ArenaCommonLobbyInitParam
{
public int ClassId { get; set; }
public int BattleMaxNum { get; set; }
public int BattleWinNum { get; set; }
public bool[] BattleResultList { get; set; }
public Action BattleButtonClickCallback { get; set; }
public Action RewardReceiveButtonClickCallback { get; set; }
public NetworkDefine.MAINTENANCE_TYPE? BattleMaintenanceType { get; set; }
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
namespace Wizard;
public class ArenaCommonLobbyLoadRequest
{
public List<string> LoadAssetList { get; set; }
public Action LoadEndCallback { get; set; }
public ArenaCommonLobbyLoadRequest()
{
LoadAssetList = new List<string>();
}
}

View File

@@ -0,0 +1,94 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Cute;
using UnityEngine;
namespace Wizard;
public class ArenaCommonLobbyTreasureBoxInfo : MonoBehaviour
{
[Header("現在の宝箱")]
[SerializeField]
private GameObject _nowBoxTitleRoot;
[SerializeField]
private UISprite _nowBoxSprite;
[SerializeField]
private Transform _movePos;
[Header("次の宝箱")]
[SerializeField]
private GameObject _nextBoxRoot;
[SerializeField]
private UISprite _nextBoxSprite;
private const float MOVE_TIME = 0.5f;
private const float OPEN_ANIMATION_START_TIME = 0.8f;
private const float OPEN_ANIMATION_TIME = 1.5f;
private GameObject _openEffect;
private Vector3 _backupNowBoxPos = Vector3.zero;
private bool _backupNextBoxRootActive;
public ArenaCommonLobbyLoadRequest Init(ArenaCommonLobbyInitParam initParam, List<string> unloadAssetList)
{
int battleWinNum = initParam.BattleWinNum;
_nowBoxSprite.spriteName = $"box_2pick_{battleWinNum:D2}_close";
bool flag = initParam.BattleResultList.Length < initParam.BattleMaxNum;
_nextBoxRoot.SetActive(flag);
if (flag)
{
_nextBoxSprite.spriteName = $"box_2pick_{battleWinNum + 1:D2}_close";
}
ArenaCommonLobbyLoadRequest arenaCommonLobbyLoadRequest = new ArenaCommonLobbyLoadRequest();
string effectName = $"cmn_arena_treasure_{battleWinNum + 1}";
arenaCommonLobbyLoadRequest.LoadAssetList.Add(Toolbox.ResourcesManager.GetAssetTypePath(effectName, ResourcesManager.AssetLoadPathType.Effect2D));
arenaCommonLobbyLoadRequest.LoadEndCallback = delegate
{
_openEffect = EffectUtility.CreateEffect2D(new Effect2dCreateParam
{
Parent = _nowBoxSprite.gameObject,
EffectName = effectName,
InitActive = false,
UnloadAssetList = unloadAssetList
});
};
return arenaCommonLobbyLoadRequest;
}
public void OpenBox(Action animationEndCallback = null)
{
StartCoroutine(OpenBoxCoroutine(animationEndCallback));
}
private IEnumerator OpenBoxCoroutine(Action animationEndCallback)
{
GameMgr.GetIns().GetSoundMgr().PlaySe(Se.TYPE.SYS_2PICK_BOX_OPEN);
_backupNowBoxPos = _nowBoxSprite.transform.position;
_backupNextBoxRootActive = _nextBoxRoot.activeSelf;
_nowBoxTitleRoot.SetActive(value: false);
_nextBoxRoot.SetActive(value: false);
iTween.MoveTo(_nowBoxSprite.gameObject, iTween.Hash("position", _movePos.position, "time", 0.5f, "islocal", false, "easetype", iTween.EaseType.easeOutExpo));
yield return new WaitForSeconds(0.8f);
_nowBoxSprite.enabled = false;
_openEffect.SetActive(value: true);
yield return new WaitForSeconds(1.5f);
animationEndCallback.Call();
}
public void Reset()
{
_nowBoxTitleRoot.SetActive(value: true);
_nowBoxSprite.enabled = true;
_nowBoxSprite.transform.position = _backupNowBoxPos;
_nextBoxRoot.SetActive(_backupNextBoxRootActive);
_openEffect.SetActive(value: false);
}
}

View File

@@ -0,0 +1,24 @@
namespace Wizard;
public class ArenaConfigUpdateTask : BaseTask
{
public class ArenaConfigUpdateTaskParam : BaseParam
{
public int use_challenge_two_pick_premium_card;
public long challenge_two_pick_sleeve_id;
}
public ArenaConfigUpdateTask()
{
base.type = ApiType.Type.ArenaConfigUpdate;
}
public void SetParameter(bool useChallenge2pickPremiumCard, long useChallenge2pickSleeveId)
{
ArenaConfigUpdateTaskParam arenaConfigUpdateTaskParam = new ArenaConfigUpdateTaskParam();
arenaConfigUpdateTaskParam.use_challenge_two_pick_premium_card = (useChallenge2pickPremiumCard ? 1 : 0);
arenaConfigUpdateTaskParam.challenge_two_pick_sleeve_id = useChallenge2pickSleeveId;
base.Params = arenaConfigUpdateTaskParam;
}
}

View File

@@ -0,0 +1,261 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Cute;
using UnityEngine;
using Wizard.Battle.View;
using Wizard.RoomMatch;
namespace Wizard;
public class AvatarAbilityDetailDialog : MonoBehaviour
{
private const int KEYWORD_DIALOG_DEPTH = 20;
private const int KEYWORD_PANEL_DEPTH = 25;
private const int TEXT_COLLIDER_HEIGHT_OFFSET = 22;
private const float PASSIVE_TEXT_OFFSET = 140f;
private const int DEFAULT_LABEL_HEIGHT = 60;
[SerializeField]
private UITexture _characterTexture;
[SerializeField]
private UILabel _characterName;
[SerializeField]
private UILabel _characterHBP;
[SerializeField]
private UISprite _classIcon;
[SerializeField]
private GameObject _itemRoot;
[SerializeField]
private UILabel _passiveAbilityDescLabel;
[SerializeField]
private List<UILabel> _abilityDescLabel = new List<UILabel>();
[SerializeField]
private GameObject _passiveKeyWordCollider;
[SerializeField]
private List<GameObject> _keyWordCollider = new List<GameObject>();
[SerializeField]
private List<UIWidget> _abilityItemRoot = new List<UIWidget>();
[SerializeField]
private UIWidget _passiveAbilityRoot;
[SerializeField]
private GameObject _thirdUnderLine;
[SerializeField]
private List<UILabel> _costLabel = new List<UILabel>();
[SerializeField]
private List<UILabel> _signLabel = new List<UILabel>();
[SerializeField]
private UIScrollView _scrollView;
private DeckData _deckData;
private AvatarBattleInfo _avatarBattleInfo;
private static DialogBase _avatarAbilityDialog;
private static DialogBase _keywordDialog;
private List<string> _loadList = new List<string>();
public static void Create(AvatarBattleInfo avatarBattleInfo, DeckData deck)
{
GameObject gameObject = UnityEngine.Object.Instantiate(Resources.Load("UI/layoutParts/AvatarAbilityDetailDialog")) as GameObject;
string titleLabel = Data.SystemText.Get("HeroesBattle_0006");
_avatarAbilityDialog = UIManager.GetInstance().CreateDialogClose();
_avatarAbilityDialog.SetTitleLabel(titleLabel);
_avatarAbilityDialog.SetSize(DialogBase.Size.L);
_avatarAbilityDialog.SetButtonLayout(DialogBase.ButtonLayout.CloseBtn);
_avatarAbilityDialog.SetObj(gameObject);
gameObject.GetComponent<AvatarAbilityDetailDialog>().Initialize(avatarBattleInfo, deck);
}
private void Initialize(AvatarBattleInfo avatarBattleInfo, DeckData deck)
{
_deckData = deck;
_avatarBattleInfo = avatarBattleInfo;
_itemRoot.SetActive(value: false);
RoomBase.StartDialogLoading();
UIManager.GetInstance().createInSceneCenterLoading();
StartCoroutine(LoadResources(deck.GetSkinId(), delegate
{
StartCoroutine(SetResources());
}));
}
private IEnumerator SetResources()
{
ClassCharacterMasterData charaPrmByCharaId = GameMgr.GetIns().GetDataMgr().GetCharaPrmByCharaId(_deckData.GetSkinId());
InitializeClassCharacter(_deckData.GetSkinId());
InitializeDescLabel(_avatarBattleInfo);
_characterName.text = charaPrmByCharaId.chara_name;
_characterHBP.text = _avatarBattleInfo.Bonus.BattleStartFirstPlayerTurnBp.ToString();
ClassCharaPrm.SetClassLabelSetting(_characterName, charaPrmByCharaId.clan);
_classIcon.spriteName = ClassCharaPrm.GetIconSpriteName(charaPrmByCharaId.clan);
_itemRoot.SetActive(value: true);
yield return null;
_scrollView.GetComponent<FlexibleGrid>().Reposition();
_scrollView.ResetPosition();
UIManager.GetInstance().closeInSceneCenterLoading();
RoomBase.FinishDiloagLoading();
}
private void InitializeDescLabel(AvatarBattleInfo avatarBattleInfo)
{
string allAbilityText = avatarBattleInfo.Bonus.PassiveAbilityDesc;
string[] abilityDesc = avatarBattleInfo.Bonus.AbilityDesc;
foreach (string text in abilityDesc)
{
allAbilityText += text;
}
if (avatarBattleInfo.Bonus.PassiveAbilityDesc == string.Empty)
{
_passiveAbilityRoot.gameObject.SetActive(value: false);
_passiveAbilityRoot.transform.localPosition = new Vector3(0f, 140f, 0f);
}
else
{
_passiveAbilityDescLabel.SetWrapText(BattleCardBase.ConvertSkillDescriptionText(avatarBattleInfo.Bonus.PassiveAbilityDesc));
UIEventListener.Get(_passiveAbilityDescLabel.gameObject).onClick = delegate
{
OnClickDescLabel(allAbilityText, _passiveAbilityDescLabel);
};
UIEventListener.Get(_passiveKeyWordCollider).onPress = delegate(GameObject g, bool b)
{
BattlePlayerView.PressKeyWordColorChange(_passiveAbilityDescLabel, b);
};
UIEventListener.Get(_passiveKeyWordCollider).onDragStart = delegate
{
BattlePlayerView.SetKeyWordLabelColor(_passiveAbilityDescLabel);
};
_passiveAbilityRoot.height = _passiveAbilityDescLabel.height;
_passiveAbilityDescLabel.GetComponent<BoxCollider>().size = new Vector3(_passiveAbilityRoot.localSize.x, _passiveAbilityRoot.localSize.y + 22f, 0f);
}
if (avatarBattleInfo.Bonus.AbilityCosts.Length < 3 || avatarBattleInfo.Bonus.AbilityDesc.Length < 3)
{
_abilityItemRoot[2].gameObject.SetActive(value: false);
_thirdUnderLine.SetActive(value: false);
}
for (int num = 0; num < avatarBattleInfo.Bonus.AbilityDesc.Length; num++)
{
int textNum = num;
_abilityDescLabel[textNum].SetWrapText(BattleCardBase.ConvertSkillDescriptionText(avatarBattleInfo.Bonus.AbilityDesc[textNum]));
UIEventListener.Get(_abilityDescLabel[textNum].gameObject).onClick = delegate
{
OnClickDescLabel(allAbilityText, _abilityDescLabel[textNum]);
};
UIEventListener.Get(_keyWordCollider[textNum]).onPress = delegate(GameObject g, bool b)
{
BattlePlayerView.PressKeyWordColorChange(_abilityDescLabel[textNum], b);
};
UIEventListener.Get(_keyWordCollider[textNum]).onDragStart = delegate
{
BattlePlayerView.SetKeyWordLabelColor(_abilityDescLabel[textNum]);
};
_abilityItemRoot[textNum].height = 60;
if (_abilityItemRoot[textNum].height < _abilityDescLabel[textNum].height)
{
_abilityItemRoot[textNum].height = _abilityDescLabel[textNum].height;
}
_abilityDescLabel[textNum].GetComponent<BoxCollider>().size = new Vector3(_abilityItemRoot[textNum].localSize.x, _abilityItemRoot[textNum].localSize.y + 22f, 0f);
_abilityDescLabel[textNum].GetComponent<BoxCollider>().center = new Vector3(-22f, 0f, 0f);
if (!int.TryParse(avatarBattleInfo.Bonus.AbilityCosts[textNum], out var result))
{
_signLabel[textNum].text = "-";
_costLabel[textNum].text = "X";
}
else if (result != 0)
{
_signLabel[textNum].text = ((result < 0) ? "-" : "+");
_costLabel[textNum].text = Mathf.Abs(result).ToString();
}
else
{
_signLabel[textNum].text = string.Empty;
_costLabel[textNum].text = "0";
_costLabel[textNum].transform.localPosition = new Vector3(0f, 2f, 0f);
}
}
}
private void OnClickDescLabel(string abilityText, UILabel textLabel)
{
if (HasKeyword(abilityText))
{
GameMgr.GetIns().GetSoundMgr().PlaySe(Se.TYPE.SYS_COMMON_BUTTON);
IList<string> keywords = BattleKeywordInfoListMgr.GetKeywords(abilityText);
_keywordDialog = BattlePlayerView.CreateKeyPanel(textLabel, keywords, CardMaster.CardMasterId.Default);
_keywordDialog.SetPanelDepth(20, isSetBackViewDepthImmediately: true);
_keywordDialog.GetComponentInChildren<BattleKeywordInfoListMgr>().SetPanelDepth(25);
}
}
private bool HasKeyword(string skillText)
{
IList<string> keywords = BattleKeywordInfoListMgr.GetKeywords(skillText);
bool result = false;
foreach (string item in keywords)
{
if (Data.Master.BattleKeyWordDic.ContainsKey(item))
{
result = true;
break;
}
}
return result;
}
private void OnDestroy()
{
Toolbox.ResourcesManager.RemoveAssetGroup(_loadList);
_loadList.Clear();
}
public static bool LiveDialog()
{
return _avatarAbilityDialog != null;
}
public static void CloseDialog()
{
_avatarAbilityDialog.Close();
if (_keywordDialog != null)
{
_keywordDialog.Close();
}
}
private IEnumerator LoadResources(int skinId, Action callBack)
{
_loadList.Add(GetCharacterTexturePath(skinId, isFetch: false));
yield return StartCoroutine(Toolbox.ResourcesManager.LoadAssetGroupAsync(_loadList, null));
callBack.Call();
}
private string GetCharacterTexturePath(int skinId, bool isFetch)
{
return Toolbox.ResourcesManager.GetAssetTypePath(skinId.ToString("00"), ResourcesManager.AssetLoadPathType.ClassCharaSkinThumbnail, isFetch);
}
private void InitializeClassCharacter(int skinId)
{
_characterTexture.mainTexture = Toolbox.ResourcesManager.LoadObject(GetCharacterTexturePath(skinId, isFetch: true)) as Texture;
}
}

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