Files
SVSimServer/SVSim.BattleEngine/Engine/Wizard/AIRandomMultiDamageEvaluator.cs
gamer147 824309ec44 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.
2026-06-05 20:30:59 -04:00

734 lines
29 KiB
C#

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);
}
}
}