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.
658 lines
25 KiB
C#
658 lines
25 KiB
C#
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);
|
|
}
|
|
}
|