Decompiled source of AtOEndless v1.7.0
BepInEx/plugins/com.corgan.AtOEndless.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Cards; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Paradox; using Photon.Pun; using Steamworks; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")] [assembly: AssemblyCompany("com.corgan.AtOEndless")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.7.0.0")] [assembly: AssemblyInformationalVersion("1.7.0+7913b879ebbd8718f1b82b5391701b80e7f7dedc")] [assembly: AssemblyProduct("AtOEndless")] [assembly: AssemblyTitle("com.corgan.AtOEndless")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.7.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace AtOEndless { [Serializable] public class BlessingDefinition { [SerializeField] public string Id; [SerializeField] public string Name; [SerializeField] public string Rarity = "Common"; [SerializeField] public bool Enabled = true; [SerializeField] public int Tier = 0; [SerializeField] public int MinTier = 0; [SerializeField] public int MaxTier = -1; [SerializeField] public string Activation = "BeginRound"; [SerializeField] public string ItemTarget = "Self"; [SerializeField] public int RoundCycle = 0; [SerializeField] public int ExactRound = 0; [SerializeField] public int TimesPerTurn = 0; [SerializeField] public int TimesPerCombat = 0; [SerializeField] public bool ActivationOnlyOnHeroes = true; [SerializeField] public bool OnlyAddItemToNPCs = true; [SerializeField] public string CastedCardType = ""; [SerializeField] public bool EmptyHand = false; [SerializeField] public float LowerOrEqualPercentHP = 100f; [SerializeField] public bool UsedEnergy = false; [SerializeField] public string AuraCurseSetted = ""; [SerializeField] public string AuraCurseSetted2 = ""; [SerializeField] public string AuraCurseSetted3 = ""; [SerializeField] public int AuraCurseNumForOneEvent = 0; [SerializeField] public int MaxHealth = 0; [SerializeField] public string CharacterStatModified = ""; [SerializeField] public int CharacterStatModifiedValue = 0; [SerializeField] public string CharacterStatModified2 = ""; [SerializeField] public int CharacterStatModifiedValue2 = 0; [SerializeField] public string CharacterStatModified3 = ""; [SerializeField] public int CharacterStatModifiedValue3 = 0; [SerializeField] public int HealFlatBonus = 0; [SerializeField] public float HealPercentBonus = 0f; [SerializeField] public int HealReceivedFlatBonus = 0; [SerializeField] public float HealReceivedPercentBonus = 0f; [SerializeField] public float HealSelfPerDamageDonePercent = 0f; [SerializeField] public string DamageFlatBonus = ""; [SerializeField] public int DamageFlatBonusValue = 0; [SerializeField] public string DamageFlatBonus2 = ""; [SerializeField] public int DamageFlatBonusValue2 = 0; [SerializeField] public string DamageFlatBonus3 = ""; [SerializeField] public int DamageFlatBonusValue3 = 0; [SerializeField] public string DamagePercentBonus = ""; [SerializeField] public float DamagePercentBonusValue = 0f; [SerializeField] public string DamagePercentBonus2 = ""; [SerializeField] public float DamagePercentBonusValue2 = 0f; [SerializeField] public string DamagePercentBonus3 = ""; [SerializeField] public float DamagePercentBonusValue3 = 0f; [SerializeField] public string ResistModified1 = ""; [SerializeField] public int ResistModifiedValue1 = 0; [SerializeField] public string ResistModified2 = ""; [SerializeField] public int ResistModifiedValue2 = 0; [SerializeField] public string ResistModified3 = ""; [SerializeField] public int ResistModifiedValue3 = 0; [SerializeField] public string AuraCurseBonus1 = ""; [SerializeField] public int AuraCurseBonusValue1 = 0; [SerializeField] public string AuraCurseBonus2 = ""; [SerializeField] public int AuraCurseBonusValue2 = 0; [SerializeField] public string AuraCurseImmune1 = ""; [SerializeField] public string AuraCurseImmune2 = ""; [SerializeField] public int DrawCards = 0; [SerializeField] public bool DrawMultiplyByEnergyUsed = false; [SerializeField] public int HealQuantity = 0; [SerializeField] public SpecialValuesDef HealQuantitySpecialValue = null; [SerializeField] public int HealPercentQuantity = 0; [SerializeField] public int HealPercentQuantitySelf = 0; [SerializeField] public int HealBasedOnAuraCurse = 0; [SerializeField] public int EnergyQuantity = 0; [SerializeField] public string DamageToTargetType = ""; [SerializeField] public int DamageToTarget = 0; [SerializeField] public SpecialValuesDef DamageToTargetSpecialValue = null; [SerializeField] public string DamageToTargetType2 = ""; [SerializeField] public int DamageToTarget2 = 0; [SerializeField] public SpecialValuesDef DamageToTargetSpecialValue2 = null; [SerializeField] public bool DttMultiplyByEnergyUsed = false; [SerializeField] public bool DontTargetBoss = false; [SerializeField] public string AuraCurseGain1 = ""; [SerializeField] public int AuraCurseGainValue1 = 0; [SerializeField] public SpecialValuesDef AuraCurseGain1SpecialValue = null; [SerializeField] public bool ACG1MultiplyByEnergyUsed = false; [SerializeField] public string AuraCurseGain2 = ""; [SerializeField] public int AuraCurseGainValue2 = 0; [SerializeField] public SpecialValuesDef AuraCurseGain2SpecialValue = null; [SerializeField] public bool ACG2MultiplyByEnergyUsed = false; [SerializeField] public string AuraCurseGain3 = ""; [SerializeField] public int AuraCurseGainValue3 = 0; [SerializeField] public SpecialValuesDef AuraCurseGain3SpecialValue = null; [SerializeField] public bool ACG3MultiplyByEnergyUsed = false; [SerializeField] public string AuraCurseGainSelf1 = ""; [SerializeField] public int AuraCurseGainSelfValue1 = 0; [SerializeField] public string AuraCurseGainSelf2 = ""; [SerializeField] public int AuraCurseGainSelfValue2 = 0; [SerializeField] public string AuraCurseGainSelf3 = ""; [SerializeField] public int AuraCurseGainSelfValue3 = 0; [SerializeField] public string AuraCurseHeal1 = ""; [SerializeField] public string AuraCurseHeal2 = ""; [SerializeField] public string AuraCurseHeal3 = ""; [SerializeField] public bool AcHealFromTarget = false; [SerializeField] public int StealAuras = 0; [SerializeField] public int ChanceToDispel = 0; [SerializeField] public int ChanceToDispelNum = 0; [SerializeField] public int ChanceToPurge = 0; [SerializeField] public int ChanceToPurgeNum = 0; [SerializeField] public int ChanceToDispelSelf = 0; [SerializeField] public int ChanceToDispelNumSelf = 0; [SerializeField] public string CardToGain = ""; [SerializeField] public int CardNum = 0; [SerializeField] public string CardPlace = "Hand"; [SerializeField] public string CardToGainType = ""; [SerializeField] public bool CostZero = false; [SerializeField] public int CostReduction = 0; [SerializeField] public bool Vanish = false; [SerializeField] public bool Permanent = false; [SerializeField] public string EffectCaster = ""; [SerializeField] public string EffectTarget = ""; [SerializeField] public string SpriteSource = ""; [SerializeField] public BlessingUpgrade UpgradeA = null; [SerializeField] public BlessingUpgrade UpgradeB = null; [SerializeField] public BlessingUpgrade UpgradeRare = null; } [Serializable] public class SpecialValuesDef { [SerializeField] public string Name = "RuneCharges"; [SerializeField] public bool Use = false; [SerializeField] public float Multiplier = 1f; } [Serializable] public class BlessingUpgrade { public const int NOT_SET = -999; public const float NOT_SET_FLOAT = -999f; [SerializeField] public string NameSuffix = ""; [SerializeField] public int MaxHealth = -999; [SerializeField] public int CharacterStatModifiedValue = -999; [SerializeField] public int CharacterStatModifiedValue2 = -999; [SerializeField] public int DrawCards = -999; [SerializeField] public int HealQuantity = -999; [SerializeField] public int HealPercentQuantity = -999; [SerializeField] public int EnergyQuantity = -999; [SerializeField] public int DamageToTarget = -999; [SerializeField] public int DamageToTarget2 = -999; [SerializeField] public int DamageFlatBonusValue = -999; [SerializeField] public float DamagePercentBonusValue = -999f; [SerializeField] public int HealFlatBonus = -999; [SerializeField] public float HealPercentBonus = -999f; [SerializeField] public int HealReceivedFlatBonus = -999; [SerializeField] public float HealReceivedPercentBonus = -999f; [SerializeField] public int ResistModifiedValue1 = -999; [SerializeField] public int ResistModifiedValue2 = -999; [SerializeField] public int CardNum = -999; [SerializeField] public float HealSelfPerDamageDonePercent = -999f; [SerializeField] public int AuraCurseBonusValue1 = -999; [SerializeField] public int AuraCurseBonusValue2 = -999; [SerializeField] public int AuraCurseGainValue1 = -999; [SerializeField] public int AuraCurseGainValue2 = -999; [SerializeField] public int AuraCurseGainValue3 = -999; [SerializeField] public int AuraCurseGainSelfValue1 = -999; [SerializeField] public int AuraCurseGainSelfValue2 = -999; [SerializeField] public int AuraCurseGainSelfValue3 = -999; [SerializeField] public int ChanceToDispel = -999; [SerializeField] public int ChanceToDispelNum = -999; [SerializeField] public int ChanceToPurge = -999; [SerializeField] public int ChanceToPurgeNum = -999; public static bool IsSet(int value) { return value != -999; } public static bool IsSet(float value) { return Math.Abs(value - -999f) > 0.001f; } } public static class BlessingDescriptionGenerator { public static bool UseCustomDescriptions = false; private static Dictionary<string, string> generatedDescriptions = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); public static string GenerateDescription(CardData card, BlessingDefinition def) { if ((Object)(object)card == (Object)null || def == null) { return ""; } if (generatedDescriptions.TryGetValue(card.Id, out var value)) { return value; } StringBuilder stringBuilder = new StringBuilder(); ItemData item = card.Item; if ((Object)(object)item == (Object)null) { return ""; } AppendPassiveStats(stringBuilder, item, def); AppendActivationTrigger(stringBuilder, item, def); AppendFrequencyLimit(stringBuilder, item, def); AppendConditionals(stringBuilder, item, def); AppendEffects(stringBuilder, card, item, def); string description = stringBuilder.ToString(); description = FormatDescription(description); generatedDescriptions[card.Id] = description; return description; } public static void ClearCache() { generatedDescriptions.Clear(); } private static void AppendPassiveStats(StringBuilder sb, ItemData item, BlessingDefinition def) { if (item.MaxHealth != 0) { sb.Append(SpriteText("hp")); sb.Append(" "); sb.Append(GetText("cardsMaxHP")); sb.Append(NumFormat(item.MaxHealth, showPlus: true)); sb.Append("\n"); } AppendResistances(sb, item); AppendDamageBonuses(sb, item); AppendHealBonuses(sb, item); AppendCharacterStats(sb, item); AppendAuraCurseBonuses(sb, item); AppendImmunities(sb, item); } private static void AppendResistances(StringBuilder sb, ItemData item) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) List<string> list = new List<string>(); if ((int)item.ResistModified1 != 0 && item.ResistModifiedValue1 != 0) { list.Add(SpriteText(Enum.GetName(typeof(DamageType), item.ResistModified1)) + " " + NumFormat(item.ResistModifiedValue1, showPlus: true, percent: true)); } if ((int)item.ResistModified2 != 0 && item.ResistModifiedValue2 != 0) { list.Add(SpriteText(Enum.GetName(typeof(DamageType), item.ResistModified2)) + " " + NumFormat(item.ResistModifiedValue2, showPlus: true, percent: true)); } if ((int)item.ResistModified3 != 0 && item.ResistModifiedValue3 != 0) { list.Add(SpriteText(Enum.GetName(typeof(DamageType), item.ResistModified3)) + " " + NumFormat(item.ResistModifiedValue3, showPlus: true, percent: true)); } if (list.Count > 0) { sb.Append(string.Join(", ", list)); sb.Append(" resistance\n"); } } private static void AppendDamageBonuses(StringBuilder sb, ItemData item) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Invalid comparison between Unknown and I4 //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Invalid comparison between Unknown and I4 //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) if ((int)item.DamageFlatBonus == 10 && item.DamageFlatBonusValue != 0) { sb.Append(string.Format(GetText("itemAllDamages"), NumFormat(item.DamageFlatBonusValue, showPlus: true))); sb.Append("\n"); } else { List<string> list = new List<string>(); int value = 0; if ((int)item.DamageFlatBonus != 0 && (int)item.DamageFlatBonus != 10 && item.DamageFlatBonusValue != 0) { list.Add(SpriteText(Enum.GetName(typeof(DamageType), item.DamageFlatBonus))); value = item.DamageFlatBonusValue; } if ((int)item.DamageFlatBonus2 != 0 && item.DamageFlatBonusValue2 != 0) { list.Add(SpriteText(Enum.GetName(typeof(DamageType), item.DamageFlatBonus2))); } if ((int)item.DamageFlatBonus3 != 0 && item.DamageFlatBonusValue3 != 0) { list.Add(SpriteText(Enum.GetName(typeof(DamageType), item.DamageFlatBonus3))); } if (list.Count > 0) { sb.Append(string.Format(GetText("itemXDamages"), string.Join("", list), NumFormat(value, showPlus: true))); sb.Append("\n"); } } if ((int)item.DamagePercentBonus == 10 && item.DamagePercentBonusValue != 0f) { sb.Append(string.Format(GetText("itemAllDamages"), NumFormat((int)item.DamagePercentBonusValue, showPlus: true, percent: true))); sb.Append("\n"); } } private static void AppendHealBonuses(StringBuilder sb, ItemData item) { if (item.HealFlatBonus != 0) { sb.Append(SpriteText("heal")); sb.Append(" "); sb.Append(Functions.LowercaseFirst(GetText("healDone"))); sb.Append(NumFormat(item.HealFlatBonus, showPlus: true)); sb.Append("\n"); } if (item.HealPercentBonus != 0f) { sb.Append(SpriteText("heal")); sb.Append(" "); sb.Append(Functions.LowercaseFirst(GetText("healDone"))); sb.Append(NumFormat((int)item.HealPercentBonus, showPlus: true, percent: true)); sb.Append("\n"); } if (item.HealReceivedFlatBonus != 0) { sb.Append(SpriteText("heal")); sb.Append(" "); sb.Append(Functions.LowercaseFirst(GetText("healTaken"))); sb.Append(NumFormat(item.HealReceivedFlatBonus, showPlus: true)); sb.Append("\n"); } if (item.HealReceivedPercentBonus != 0f) { sb.Append(SpriteText("heal")); sb.Append(" "); sb.Append(Functions.LowercaseFirst(GetText("healTaken"))); sb.Append(NumFormat((int)item.HealReceivedPercentBonus, showPlus: true, percent: true)); sb.Append("\n"); } if (item.HealSelfPerDamageDonePercent > 0f) { sb.Append(string.Format(GetText("cardsHealSelfPerDamage"), item.HealSelfPerDamageDonePercent.ToString())); sb.Append("\n"); } } private static void AppendCharacterStats(StringBuilder sb, ItemData item) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Invalid comparison between Unknown and I4 //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Invalid comparison between Unknown and I4 if ((int)item.CharacterStatModified == 2) { sb.Append(string.Format(GetText("itemSpeed"), NumFormat(item.CharacterStatModifiedValue, showPlus: true))); sb.Append("\n"); } if ((int)item.CharacterStatModified == 4) { sb.Append(string.Format(GetText("itemEnergyRegeneration"), SpriteText("energy"), NumFormat(item.CharacterStatModifiedValue, showPlus: true))); sb.Append("\n"); } if ((int)item.CharacterStatModified2 == 2) { sb.Append(string.Format(GetText("itemSpeed"), NumFormat(item.CharacterStatModifiedValue2, showPlus: true))); sb.Append("\n"); } if ((int)item.CharacterStatModified2 == 4) { sb.Append(string.Format(GetText("itemEnergyRegeneration"), SpriteText("energy"), NumFormat(item.CharacterStatModifiedValue2, showPlus: true))); sb.Append("\n"); } } private static void AppendAuraCurseBonuses(StringBuilder sb, ItemData item) { if ((Object)(object)item.AuracurseBonus1 != (Object)null && item.AuracurseBonusValue1 > 0 && (Object)(object)item.AuracurseBonus2 != (Object)null && item.AuracurseBonusValue2 > 0 && item.AuracurseBonusValue1 == item.AuracurseBonusValue2) { string arg = SpriteText(item.AuracurseBonus1.ACName) + SpriteText(item.AuracurseBonus2.ACName); sb.Append(string.Format(GetText("itemCharges"), arg, NumFormat(item.AuracurseBonusValue1, showPlus: true))); sb.Append("\n"); return; } if ((Object)(object)item.AuracurseBonus1 != (Object)null && item.AuracurseBonusValue1 > 0) { sb.Append(string.Format(GetText("itemCharges"), SpriteText(item.AuracurseBonus1.ACName), NumFormat(item.AuracurseBonusValue1, showPlus: true))); sb.Append("\n"); } if ((Object)(object)item.AuracurseBonus2 != (Object)null && item.AuracurseBonusValue2 > 0) { sb.Append(string.Format(GetText("itemCharges"), SpriteText(item.AuracurseBonus2.ACName), NumFormat(item.AuracurseBonusValue2, showPlus: true))); sb.Append("\n"); } } private static void AppendImmunities(StringBuilder sb, ItemData item) { StringBuilder stringBuilder = new StringBuilder(); if ((Object)(object)item.AuracurseImmune1 != (Object)null) { stringBuilder.Append(ColorText("curse", SpriteText(item.AuracurseImmune1.Id))); } if ((Object)(object)item.AuracurseImmune2 != (Object)null) { stringBuilder.Append(ColorText("curse", SpriteText(item.AuracurseImmune2.Id))); } if (stringBuilder.Length > 0) { sb.Append(string.Format(GetText("cardsImmuneTo"), stringBuilder.ToString().TrimEnd(Array.Empty<char>()))); sb.Append("\n"); } } private static void AppendActivationTrigger(StringBuilder sb, ItemData item, BlessingDefinition def) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected I4, but got Unknown //IL_047a: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Invalid comparison between Unknown and I4 //IL_04a2: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) if ((int)item.Activation == 0 || (int)item.Activation == 21) { return; } if (sb.Length > 0) { sb.Append("<line-height=15%><br></line-height>"); } StringBuilder stringBuilder = new StringBuilder(); EventActivation activation = item.Activation; EventActivation val = activation; switch (val - 1) { case 0: stringBuilder.Append(GetText("itemCombatStart")); break; case 16: stringBuilder.Append(GetText("itemCombatEnd")); break; case 2: case 21: case 23: case 38: if (item.RoundCycle > 1) { stringBuilder.Append(string.Format(GetText("itemEveryNRounds"), item.RoundCycle.ToString())); } else if (item.ExactRound == 1) { stringBuilder.Append(GetText("itemFirstTurn")); } else { stringBuilder.Append(GetText("itemEveryRound")); } break; case 1: if (item.RoundCycle > 1) { stringBuilder.Append(string.Format(GetText("itemEveryRoundRoundN"), item.RoundCycle.ToString())); } else { stringBuilder.Append(GetText("itemEveryRoundRound")); } break; case 18: stringBuilder.Append(GetText("itemDamageDone")); break; case 19: if (item.LowerOrEqualPercentHP < 100f) { stringBuilder.Append(string.Format(GetText("itemWhenDamagedBelow"), item.LowerOrEqualPercentHP + "%")); } else { stringBuilder.Append(GetText("itemWhenDamaged")); } break; case 8: stringBuilder.Append(GetText("itemWhenHitted")); break; case 9: stringBuilder.Append(GetText("itemWhenBlock")); break; case 13: stringBuilder.Append(GetText("itemHealDoneAction")); break; case 14: stringBuilder.Append(GetText("itemWhenHealed")); break; case 11: stringBuilder.Append(GetText("itemWhenEvade")); break; case 12: stringBuilder.Append(GetText("itemWhenEvaded")); break; case 24: stringBuilder.Append(GetText("itemWhenKilled")); break; case 34: stringBuilder.Append("When you kill an enemy"); break; case 7: stringBuilder.Append("When you hit an enemy"); break; case 37: stringBuilder.Append(GetText("itemWhenBlockReachesZero")); break; case 5: stringBuilder.Append(GetTextOrDefault("itemWhenDrawCard", "When you draw a card")); break; case 6: case 15: case 30: if ((int)item.CastedCardType > 0) { string arg = ColorText("gold", GetText(Enum.GetName(typeof(CardType), item.CastedCardType))); stringBuilder.Append(string.Format(GetText("itemWhenYouPlay"), arg)); } else { stringBuilder.Append(string.Format(GetText("itemWhenYouPlay"), SpriteText("cards"))); } break; case 22: { if (!((Object)(object)item.AuraCurseSetted != (Object)null)) { break; } StringBuilder stringBuilder2 = new StringBuilder(); stringBuilder2.Append(SpriteText(item.AuraCurseSetted.Id)); if ((Object)(object)item.AuraCurseSetted2 != (Object)null) { stringBuilder2.Append(SpriteText(item.AuraCurseSetted2.Id)); if ((Object)(object)item.AuraCurseSetted3 != (Object)null) { stringBuilder2.Append(SpriteText(item.AuraCurseSetted3.Id)); } } stringBuilder.Append(string.Format(GetText("itemWhenYouApply"), ColorText("curse", stringBuilder2.ToString()))); break; } default: if (item.Activation == AtOEndless.blessingCombatStart) { stringBuilder.Append(GetText("itemCombatStart")); } else if (item.Activation == AtOEndless.blessingBeginRound) { stringBuilder.Append(GetText("itemEveryRoundRound")); } break; } if (stringBuilder.Length > 0) { sb.Append("<size=-.15><color=#444>["); sb.Append(stringBuilder.ToString()); sb.Append("]</color></size><br>"); } } private static void AppendFrequencyLimit(StringBuilder sb, ItemData item, BlessingDefinition def) { if (item.TimesPerTurn > 0) { StringBuilder stringBuilder = new StringBuilder(); switch (item.TimesPerTurn) { case 1: stringBuilder.Append(GetText("itemOncePerTurn")); break; case 2: stringBuilder.Append(GetText("itemTwicePerTurn")); break; case 3: stringBuilder.Append(GetText("itemThricePerTurn")); break; case 4: stringBuilder.Append(GetText("itemFourPerTurn")); break; case 5: stringBuilder.Append(GetText("itemFivePerTurn")); break; case 6: stringBuilder.Append(GetText("itemSixPerTurn")); break; case 7: stringBuilder.Append(GetText("itemSevenPerTurn")); break; case 8: stringBuilder.Append(GetText("itemEightPerTurn")); break; default: stringBuilder.Append($"{item.TimesPerTurn}x per turn"); break; } if (stringBuilder.Length > 0) { sb.Append("<size=-.15><color=#444>["); sb.Append(stringBuilder.ToString()); sb.Append("]</color></size><br>"); } } if (item.TimesPerCombat > 0) { string value = string.Format(GetTextOrDefault("itemTimesPerCombat", "{0}x per combat"), item.TimesPerCombat); sb.Append("<size=-.15><color=#444>["); sb.Append(value); sb.Append("]</color></size><br>"); } } private static void AppendConditionals(StringBuilder sb, ItemData item, BlessingDefinition def) { if (item.UsedEnergy) { sb.Append(string.Format(GetText("itemApplyForEnergyUsed"), ColorText("system", SpriteText("energy")))); sb.Append("\n"); } if (item.EmptyHand) { sb.Append(GetText("itemWhenHandEmpty")); sb.Append(":<br>"); } } private static void AppendEffects(StringBuilder sb, CardData card, ItemData item, BlessingDefinition def) { if (item.DrawCards > 0) { sb.Append(string.Format(GetText("cardsDraw"), ColorText("", NumFormat(item.DrawCards), SpriteText("card")))); sb.Append("<br>"); } AppendHealEffects(sb, item); if (item.EnergyQuantity > 0) { sb.Append(string.Format(GetText("cardsGain"), ColorText("system", NumFormat(item.EnergyQuantity), SpriteText("energy")))); sb.Append("<br>"); } AppendDamageEffects(sb, item); if (item.ChanceToDispel > 0 && item.ChanceToDispelNum != 0) { if (item.ChanceToDispel < 100) { sb.Append(string.Format(GetText("itemChanceToDispel"), ColorText("aura", NumFormat(item.ChanceToDispel, showPlus: false, percent: true)), ColorText("curse", NumFormat(item.ChanceToDispelNum)))); } else if (item.ChanceToDispelNum == -1) { sb.Append(GetText("cardsDispelAll")); } else { sb.Append(string.Format(GetText("cardsDispel"), ColorText("curse", NumFormat(item.ChanceToDispelNum)))); } sb.Append("\n"); } if (item.ChanceToPurge > 0 && item.ChanceToPurgeNum != 0) { if (item.ChanceToPurge < 100) { sb.Append(string.Format(GetText("itemChanceToPurge"), ColorText("aura", NumFormat(item.ChanceToPurge, showPlus: false, percent: true)), ColorText("curse", NumFormat(item.ChanceToPurgeNum)))); } else if (item.ChanceToPurgeNum == -1) { sb.Append(GetText("cardsPurgeAll")); } else { sb.Append(string.Format(GetText("cardsPurge"), ColorText("curse", NumFormat(item.ChanceToPurgeNum)))); } sb.Append("\n"); } AppendSpecificCurseDispel(sb, item); AppendAuraGains(sb, card, item); AppendAuraSelfGains(sb, item); AppendCardGeneration(sb, item); } private static void AppendHealEffects(StringBuilder sb, ItemData item) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (item.HealQuantity > 0) { string arg = ColorText("system", NumFormat(item.HealQuantity, showPlus: true)); string healTextForTarget = GetHealTextForTarget(item.ItemTarget, item.Activation); sb.Append(string.Format(healTextForTarget, arg)); sb.Append("<br>"); } else if (item.HealQuantity < 0) { string arg2 = ColorText("damage", NumFormat(item.HealQuantity, showPlus: true)); sb.Append(string.Format(GetText("itemLoseHPSelf"), arg2)); sb.Append("<br>"); } if (item.HealPercentQuantity > 0) { string arg3 = ColorText("system", NumFormat(item.HealPercentQuantity, showPlus: true, percent: true)); string healTextForTarget2 = GetHealTextForTarget(item.ItemTarget, item.Activation); sb.Append(string.Format(healTextForTarget2, arg3)); sb.Append("<br>"); } } private static string GetHealTextForTarget(ItemTarget target, EventActivation activation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Invalid comparison between Unknown and I4 //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 if ((int)target == 3) { return GetText("itemRecoverHeroes"); } if ((int)target == 0) { return ((int)activation == 25) ? GetText("itemResurrectHP") : GetText("itemRecoverSelf"); } if ((int)target == 4) { return GetText("itemRecoverMonsters"); } if ((int)target == 1) { return GetText("itemRecoverRandomHPHero"); } if ((int)target == 2) { return GetText("itemRecoverRandomHPMonster"); } if ((int)target == 8) { return GetText("itemRecoverLowestHPHero"); } if ((int)target == 10) { return GetText("itemRecoverLowestHPMonster"); } return GetText("itemRecoverSelf"); } private static void AppendDamageEffects(StringBuilder sb, ItemData item) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Invalid comparison between Unknown and I4 //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Invalid comparison between Unknown and I4 StringBuilder stringBuilder = new StringBuilder(); if (item.DamageToTarget1 > 0) { stringBuilder.Append(ColorText("damage", NumFormat(item.DamageToTarget1), SpriteText(Enum.GetName(typeof(DamageType), item.DamageToTargetType1)))); } if (item.DamageToTarget2 > 0) { stringBuilder.Append(ColorText("damage", NumFormat(item.DamageToTarget2), SpriteText(Enum.GetName(typeof(DamageType), item.DamageToTargetType2)))); } if (stringBuilder.Length > 0) { string key = "cardsDealDamage"; if ((int)item.ItemTarget == 4) { key = "dealDamageToAllMonsters"; } else if ((int)item.ItemTarget == 3) { key = "dealDamageToAllHeroes"; } sb.Append(string.Format(GetText(key), stringBuilder.ToString().TrimEnd(Array.Empty<char>()))); sb.Append("\n"); } } private static void AppendAuraGains(StringBuilder sb, CardData card, ItemData item) { //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Expected I4, but got Unknown //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Invalid comparison between Unknown and I4 //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Invalid comparison between Unknown and I4 //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Invalid comparison between Unknown and I4 StringBuilder stringBuilder = new StringBuilder(); bool flag = true; if ((Object)(object)item.AuracurseGain1 != (Object)null && item.AuracurseGainValue1 > 0) { bool isAura = item.AuracurseGain1.IsAura; stringBuilder.Append(ColorText(isAura ? "aura" : "curse", NumFormat(item.AuracurseGainValue1), SpriteText(item.AuracurseGain1.Id))); if (!isAura) { flag = false; } } if ((Object)(object)item.AuracurseGain2 != (Object)null && item.AuracurseGainValue2 > 0) { bool isAura2 = item.AuracurseGain2.IsAura; stringBuilder.Append(ColorText(isAura2 ? "aura" : "curse", NumFormat(item.AuracurseGainValue2), SpriteText(item.AuracurseGain2.Id))); if (!isAura2) { flag = false; } } if ((Object)(object)item.AuracurseGain3 != (Object)null && item.AuracurseGainValue3 > 0) { bool isAura3 = item.AuracurseGain3.IsAura; stringBuilder.Append(ColorText(isAura3 ? "aura" : "curse", NumFormat(item.AuracurseGainValue3), SpriteText(item.AuracurseGain3.Id))); if (!isAura3) { flag = false; } } if (stringBuilder.Length <= 0) { return; } string arg = stringBuilder.ToString().TrimEnd(Array.Empty<char>()); ItemTarget itemTarget = item.ItemTarget; ItemTarget val = itemTarget; switch ((int)val) { case 4: sb.Append(string.Format(GetText("itemApplyEnemies"), arg)); break; case 3: sb.Append(string.Format(GetText("itemApplyHeroes"), arg)); break; case 1: sb.Append(string.Format(GetText("itemApplyRandomHero"), arg)); break; case 2: sb.Append(string.Format(GetText("itemApplyRandomEnemy"), arg)); break; case 8: sb.Append(string.Format(GetText("itemApplyLowestFlatHpHero"), arg)); break; case 10: sb.Append(string.Format(GetText("itemApplyLowestFlatHpEnemy"), arg)); break; case 7: sb.Append(string.Format(GetText("itemApplyHighestFlatHpHero"), arg)); break; case 9: sb.Append(string.Format(GetText("itemApplyHighestFlatHpEnemy"), arg)); break; case 13: sb.Append(string.Format(GetTextOrDefault("itemApplyFrontEnemy", "Front enemy suffers {0}"), arg)); break; case 5: if ((int)card.TargetSide == 1 || (int)card.TargetSide == 3) { sb.Append(string.Format(GetText("cardsGrant"), arg)); } else if ((int)card.TargetSide == 0) { sb.Append(string.Format(GetText("cardsApply"), arg)); } else if (flag) { sb.Append(string.Format(GetText("cardsGrant"), arg)); } else { sb.Append(string.Format(GetText("cardsApply"), arg)); } break; default: if (flag) { sb.Append(string.Format(GetText("cardsGain"), arg)); } else { sb.Append(string.Format(GetText("cardsSuffer"), arg)); } break; } sb.Append("<br>"); } private static void AppendAuraSelfGains(StringBuilder sb, ItemData item) { StringBuilder stringBuilder = new StringBuilder(); bool flag = true; if ((Object)(object)item.AuracurseGainSelf1 != (Object)null && item.AuracurseGainSelfValue1 > 0) { bool isAura = item.AuracurseGainSelf1.IsAura; stringBuilder.Append(ColorText(isAura ? "aura" : "curse", NumFormat(item.AuracurseGainSelfValue1), SpriteText(item.AuracurseGainSelf1.Id))); if (!isAura) { flag = false; } } if ((Object)(object)item.AuracurseGainSelf2 != (Object)null && item.AuracurseGainSelfValue2 > 0) { bool isAura2 = item.AuracurseGainSelf2.IsAura; stringBuilder.Append(ColorText(isAura2 ? "aura" : "curse", NumFormat(item.AuracurseGainSelfValue2), SpriteText(item.AuracurseGainSelf2.Id))); if (!isAura2) { flag = false; } } if ((Object)(object)item.AuracurseGainSelf3 != (Object)null && item.AuracurseGainSelfValue3 > 0) { bool isAura3 = item.AuracurseGainSelf3.IsAura; stringBuilder.Append(ColorText(isAura3 ? "aura" : "curse", NumFormat(item.AuracurseGainSelfValue3), SpriteText(item.AuracurseGainSelf3.Id))); if (!isAura3) { flag = false; } } if (stringBuilder.Length > 0) { if (flag) { sb.Append(string.Format(GetText("cardsGain"), stringBuilder.ToString().TrimEnd(Array.Empty<char>()))); } else { sb.Append(string.Format(GetText("cardsSuffer"), stringBuilder.ToString().TrimEnd(Array.Empty<char>()))); } sb.Append("<br>"); } } private static void AppendCardGeneration(StringBuilder sb, ItemData item) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected I4, but got Unknown if ((Object)(object)item.CardToGain != (Object)null && item.CardNum > 0) { string text = ColorText("gold", item.CardToGain.CardName); string text2 = ""; CardPlace cardPlace = item.CardPlace; CardPlace val = cardPlace; switch ((int)val) { case 5: text2 = GetTextOrDefault("cardAddToHand", "add to hand"); break; case 1: case 2: case 3: text2 = GetTextOrDefault("cardAddToDeck", "shuffle into deck"); break; case 6: text2 = GetTextOrDefault("cardCastImmediately", "and cast it"); break; case 0: text2 = GetTextOrDefault("cardAddToDiscard", "add to discard"); break; case 4: text2 = GetTextOrDefault("cardVanish", "vanish after use"); break; } if (item.CardNum == 1) { sb.Append(string.Format(GetTextOrDefault("itemGainCard", "Gain {0} {1}"), text, text2)); } else { sb.Append(string.Format(GetTextOrDefault("itemGainCards", "Gain {0}x {1} {2}"), item.CardNum, text, text2)); } sb.Append("<br>"); } } private static void AppendSpecificCurseDispel(StringBuilder sb, ItemData item) { StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = new StringBuilder(); if ((Object)(object)item.AuracurseHeal1 != (Object)null) { if (item.AuracurseHeal1.IsAura) { stringBuilder.Append(ColorText("aura", SpriteText(item.AuracurseHeal1.Id))); } else { stringBuilder2.Append(ColorText("curse", SpriteText(item.AuracurseHeal1.Id))); } } if ((Object)(object)item.AuracurseHeal2 != (Object)null) { if (item.AuracurseHeal2.IsAura) { stringBuilder.Append(ColorText("aura", SpriteText(item.AuracurseHeal2.Id))); } else { stringBuilder2.Append(ColorText("curse", SpriteText(item.AuracurseHeal2.Id))); } } if ((Object)(object)item.AuracurseHeal3 != (Object)null) { if (item.AuracurseHeal3.IsAura) { stringBuilder.Append(ColorText("aura", SpriteText(item.AuracurseHeal3.Id))); } else { stringBuilder2.Append(ColorText("curse", SpriteText(item.AuracurseHeal3.Id))); } } if (stringBuilder.Length > 0) { sb.Append(string.Format(GetText("cardsPurge"), stringBuilder.ToString().TrimEnd(Array.Empty<char>()))); sb.Append("\n"); } if (stringBuilder2.Length > 0) { sb.Append(string.Format(GetText("cardsDispel"), stringBuilder2.ToString().TrimEnd(Array.Empty<char>()))); sb.Append("\n"); } } private static string GetText(string key) { try { return Texts.Instance.GetText(key, "") ?? key; } catch { return key; } } private static string GetTextOrDefault(string key, string defaultValue) { try { string text = Texts.Instance.GetText(key, ""); return (string.IsNullOrEmpty(text) || text == key) ? defaultValue : text; } catch { return defaultValue; } } private static string SpriteText(string spriteName) { if (string.IsNullOrEmpty(spriteName)) { return ""; } StringBuilder stringBuilder = new StringBuilder(); string text = spriteName.ToLower().Replace(" ", ""); switch (text) { case "block": case "card": stringBuilder.Append("<space=.2>"); break; case "piercing": stringBuilder.Append("<space=.4>"); break; case "bleed": case "bless": stringBuilder.Append("<space=.1>"); break; default: stringBuilder.Append("<space=.3>"); break; } stringBuilder.Append(" <space=-.2>"); stringBuilder.Append("<size=+.1><sprite name="); stringBuilder.Append(text); stringBuilder.Append("></size>"); switch (text) { case "bleed": stringBuilder.Append("<space=-.4>"); break; case "card": stringBuilder.Append("<space=-.2>"); break; case "powerful": case "fury": stringBuilder.Append("<space=-.1>"); break; default: stringBuilder.Append("<space=-.2>"); break; case "reinforce": case "fire": break; } return stringBuilder.ToString(); } private static string NumFormat(int value, bool showPlus = false, bool percent = false) { string arg = ((showPlus && value > 0) ? "+" : ""); string arg2 = (percent ? "%" : ""); return $"{arg}{value}{arg2}"; } private static string NumFormat(int value, string sprite) { return $"{value}{sprite}"; } private static string ColorText(string type, params string[] parts) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("<nobr>"); switch (type.ToLower()) { case "damage": stringBuilder.Append("<color=#B00A00>"); break; case "heal": stringBuilder.Append("<color=#1E650F>"); break; case "aura": stringBuilder.Append("<color=#263ABC>"); break; case "curse": stringBuilder.Append("<color=#720070>"); break; case "system": case "gold": stringBuilder.Append("<color=#5E3016>"); break; default: { for (int i = 0; i < parts.Length; i++) { if (i > 0) { stringBuilder.Append(" "); } stringBuilder.Append(parts[i]); } stringBuilder.Append("</nobr> "); return stringBuilder.ToString(); } } for (int j = 0; j < parts.Length; j++) { if (j > 0) { stringBuilder.Append(" "); } stringBuilder.Append(parts[j]); } stringBuilder.Append("</color></nobr> "); return stringBuilder.ToString(); } private static string FormatDescription(string description) { if (string.IsNullOrEmpty(description)) { return description; } StringBuilder stringBuilder = new StringBuilder(description); stringBuilder.Replace("<c>", "<color=#5E3016>"); stringBuilder.Replace("</c>", "</color>"); stringBuilder.Replace("<nb>", "<nobr>"); stringBuilder.Replace("</nb>", "</nobr>"); stringBuilder.Replace("<br1>", "<br><line-height=15%><br></line-height>"); stringBuilder.Replace("<br2>", "<br><line-height=30%><br></line-height>"); stringBuilder.Replace("<br3>", "<br><line-height=50%><br></line-height>"); stringBuilder.Replace("\n", "<br>"); return stringBuilder.ToString(); } } public static class BlessingDescriptionHelper { private static Dictionary<string, BlessingDefinition> cardToBlessingDef = new Dictionary<string, BlessingDefinition>(StringComparer.OrdinalIgnoreCase); private static Dictionary<string, string> customDescriptions = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); public static void RegisterBlessing(string cardId, BlessingDefinition def, BlessingUpgrade upgrade = null) { Plugin.LogInfo("[BlessingDescriptionHelper] RegisterBlessing called: cardId=" + cardId + ", def.Id=" + (def?.Id ?? "null") + ", upgrade=" + ((upgrade != null) ? "provided" : "null")); cardToBlessingDef[cardId] = def; } public static BlessingDefinition GetBlessingDef(string cardId) { if (cardToBlessingDef.TryGetValue(cardId, out var value)) { return value; } return null; } public static bool HasCustomDescription(string cardId) { return customDescriptions.ContainsKey(cardId); } public static string GetCustomDescription(string cardId) { if (customDescriptions.TryGetValue(cardId, out var value)) { return value; } return null; } public static void EnhanceDescription(CardData card) { if ((Object)(object)card == (Object)null || (Object)(object)card.Item == (Object)null) { return; } string id = card.Id; BlessingDefinition blessingDef = GetBlessingDef(id); if (blessingDef == null) { return; } Plugin.LogInfo("[BlessingDescriptionHelper] EnhanceDescription called for blessing: " + id); if (HasCustomDescription(id)) { string customDescription = GetCustomDescription(id); customDescription = (card.DescriptionNormalized = FormatCustomDescription(customDescription)); Globals.Instance.CardsDescriptionNormalized[id] = customDescription; Plugin.LogInfo("[BlessingDescriptionHelper] Applied custom description for " + id); return; } if (BlessingDescriptionGenerator.UseCustomDescriptions) { string text2 = BlessingDescriptionGenerator.GenerateDescription(card, blessingDef); if (!string.IsNullOrEmpty(text2)) { card.DescriptionNormalized = text2; Globals.Instance.CardsDescriptionNormalized[id] = text2; Plugin.LogInfo("[BlessingDescriptionHelper] Applied generated description for " + id); return; } } StringBuilder stringBuilder = new StringBuilder(); AddMissingDescriptionFragments(stringBuilder, card, blessingDef); if (stringBuilder.Length > 0) { string text3 = card.DescriptionNormalized ?? ""; string value = (card.DescriptionNormalized = text3 + stringBuilder.ToString()); Globals.Instance.CardsDescriptionNormalized[id] = value; Plugin.LogInfo($"[BlessingDescriptionHelper] Appended {stringBuilder.Length} chars to description for {id}"); } } private static string FormatCustomDescription(string description) { if (string.IsNullOrEmpty(description)) { return description; } StringBuilder stringBuilder = new StringBuilder(description); stringBuilder.Replace("<c>", "<color=#5E3016>"); stringBuilder.Replace("</c>", "</color>"); stringBuilder.Replace("<nb>", "<nobr>"); stringBuilder.Replace("</nb>", "</nobr>"); stringBuilder.Replace("<br1>", "<br><line-height=15%><br></line-height>"); stringBuilder.Replace("<br2>", "<br><line-height=30%><br></line-height>"); stringBuilder.Replace("<br3>", "<br><line-height=50%><br></line-height>"); stringBuilder.Replace("\n", "<br>"); return stringBuilder.ToString(); } private static void AddMissingDescriptionFragments(StringBuilder sb, CardData card, BlessingDefinition def) { ItemData item = card.Item; if (!((Object)(object)item == (Object)null)) { } } private static bool DescriptionContains(CardData card, string text) { if ((Object)(object)card == (Object)null || string.IsNullOrEmpty(card.DescriptionNormalized)) { return false; } return card.DescriptionNormalized.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0; } public static string SpriteText(string spriteName) { return "<sprite name=" + spriteName + ">"; } public static string DamageColor(string text) { return "<color=#B00A00>" + text + "</color>"; } public static string HealColor(string text) { return "<color=#00B000>" + text + "</color>"; } public static string AuraColor(string text) { return "<color=#5E3016>" + text + "</color>"; } public static string SystemColor(string text) { return "<color=#111111>" + text + "</color>"; } public static string FormatBonus(int value, bool showPlus = true) { if (showPlus && value > 0) { return $"+{value}"; } return value.ToString(); } public static string FormatPercent(int value, bool showPlus = true) { string arg = ((showPlus && value > 0) ? "+" : ""); return $"{arg}{value}%"; } public static void Clear() { Plugin.LogInfo($"[BlessingDescriptionHelper] Clear called - clearing {cardToBlessingDef.Count} blessing defs and {customDescriptions.Count} custom descriptions"); cardToBlessingDef.Clear(); customDescriptions.Clear(); BlessingDescriptionGenerator.ClearCache(); } } public static class BlessingPatchHelper { public static bool ShouldSkipDueToCache<TCache>(bool useCache, TCache cache, Func<TCache, bool> hasValue) { if (!AtOEndless.IsEndlessMode()) { return false; } if (Object.op_Implicit((Object)(object)MatchManager.Instance) && useCache && hasValue(cache)) { return true; } return false; } public static int ApplyIntModifierWithCache(HeroData heroData, int currentResult, bool useCache, List<int> cache, Func<ItemData, int> getModifier) { if ((Object)(object)heroData == (Object)null) { return currentResult; } bool flag = false; foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null) { int num = getModifier(cardData.Item); if (num != 0) { currentResult += num; flag = true; } } } if (Object.op_Implicit((Object)(object)MatchManager.Instance) && useCache && cache.Count > 0 && flag) { cache[0] = currentResult; } return currentResult; } public static float ApplyFloatModifierWithCache(HeroData heroData, float currentResult, bool useCache, List<float> cache, Func<ItemData, float> getModifier) { if ((Object)(object)heroData == (Object)null) { return currentResult; } bool flag = false; foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null) { float num = getModifier(cardData.Item); if (num != 0f) { currentResult += num; flag = true; } } } if (Object.op_Implicit((Object)(object)MatchManager.Instance) && useCache && cache.Count > 0 && flag) { cache[0] = currentResult; } return currentResult; } public static int ApplyTypedIntModifierWithCache<TKey>(HeroData heroData, TKey key, int currentResult, bool useCache, Dictionary<TKey, int> cache, Func<ItemData, TKey, int> getModifier) { if ((Object)(object)heroData == (Object)null) { return currentResult; } bool flag = false; foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null) { int num = getModifier(cardData.Item, key); if (num != 0) { currentResult += num; flag = true; } } } if (Object.op_Implicit((Object)(object)MatchManager.Instance) && useCache && cache.ContainsKey(key) && flag) { cache[key] = currentResult; } return currentResult; } public static float ApplyTypedFloatModifierWithCache<TKey>(HeroData heroData, TKey key, float currentResult, bool useCache, Dictionary<TKey, float> cache, Func<ItemData, TKey, float> getModifier) { if ((Object)(object)heroData == (Object)null) { return currentResult; } bool flag = false; foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null) { float num = getModifier(cardData.Item, key); if (num != 0f) { currentResult += num; flag = true; } } } if (Object.op_Implicit((Object)(object)MatchManager.Instance) && useCache && cache.ContainsKey(key) && flag) { cache[key] = currentResult; } return currentResult; } public static int GetDamageFlatBonus(ItemData item, DamageType damageType) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 int num = 0; if (item.DamageFlatBonus == damageType || (int)item.DamageFlatBonus == 10) { num += item.DamageFlatBonusValue; } if (item.DamageFlatBonus2 == damageType || (int)item.DamageFlatBonus2 == 10) { num += item.DamageFlatBonusValue2; } if (item.DamageFlatBonus3 == damageType || (int)item.DamageFlatBonus3 == 10) { num += item.DamageFlatBonusValue3; } return num; } public static float GetDamagePercentBonus(ItemData item, DamageType damageType) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Invalid comparison between Unknown and I4 float num = 0f; if (item.DamagePercentBonus == damageType || (int)item.DamagePercentBonus == 10) { num += item.DamagePercentBonusValue; } if (item.DamagePercentBonus2 == damageType || (int)item.DamagePercentBonus2 == 10) { num += item.DamagePercentBonusValue2; } if (item.DamagePercentBonus3 == damageType || (int)item.DamagePercentBonus3 == 10) { num += item.DamagePercentBonusValue3; } return num; } public static int GetResistBonus(ItemData item, DamageType damageType) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 int num = 0; if (item.ResistModified1 == damageType || (int)item.ResistModified1 == 10) { num += item.ResistModifiedValue1; } if (item.ResistModified2 == damageType || (int)item.ResistModified2 == 10) { num += item.ResistModifiedValue2; } if (item.ResistModified3 == damageType || (int)item.ResistModified3 == 10) { num += item.ResistModifiedValue3; } return num; } public static int GetStatBonus(ItemData item, CharacterStat stat) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) int num = 0; if (item.CharacterStatModified == stat) { num += item.CharacterStatModifiedValue; } if (item.CharacterStatModified2 == stat) { num += item.CharacterStatModifiedValue2; } if (item.CharacterStatModified3 == stat) { num += item.CharacterStatModifiedValue3; } return num; } public static void AddDamageDictionaryEntries(HeroData heroData, DamageType damageType, Dictionary<string, int> result, bool isPercent) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)heroData == (Object)null) { return; } foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) == (Object)null) { continue; } float num = (isPercent ? GetDamagePercentBonus(cardData.Item, damageType) : ((float)GetDamageFlatBonus(cardData.Item, damageType))); if (num != 0f) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(cardData.CardName); stringBuilder.Append("_card"); string key = stringBuilder.ToString(); if (result.ContainsKey(key)) { result[key] += (int)num; } else { result[key] = (int)num; } } } } public static void AddResistDictionaryEntries(HeroData heroData, DamageType damageType, Dictionary<string, int> result) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)heroData == (Object)null) { return; } foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) == (Object)null) { continue; } int resistBonus = GetResistBonus(cardData.Item, damageType); if (resistBonus != 0) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(cardData.CardName); stringBuilder.Append("_card"); string key = stringBuilder.ToString(); if (result.ContainsKey(key)) { result[key] += resistBonus; } else { result[key] = resistBonus; } } } } public static void ApplyAuraCurseModifiersWithCache(HeroData heroData, Dictionary<string, int> result, bool useCache, Dictionary<string, int> cache) { if ((Object)(object)heroData == (Object)null) { return; } bool flag = false; foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if (!((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null)) { continue; } if ((Object)(object)cardData.Item.AuracurseBonus1 != (Object)null) { string id = cardData.Item.AuracurseBonus1.Id; if (result.ContainsKey(id)) { result[id] += cardData.Item.AuracurseBonusValue1; } else { result[id] = cardData.Item.AuracurseBonusValue1; } flag = true; } if ((Object)(object)cardData.Item.AuracurseBonus2 != (Object)null) { string id2 = cardData.Item.AuracurseBonus2.Id; if (result.ContainsKey(id2)) { result[id2] += cardData.Item.AuracurseBonusValue2; } else { result[id2] = cardData.Item.AuracurseBonusValue2; } flag = true; } } if (!(Object.op_Implicit((Object)(object)MatchManager.Instance) && useCache && cache.Count > 0 && flag)) { return; } foreach (KeyValuePair<string, int> item in result) { cache[item.Key] = item.Value; } } } [HarmonyPatch] public static class BlessingEffectManager { public static T ApplyBlessingModifier<T>(T initialValue, HeroData heroData, Func<CardData, ItemData, T, T> modifier) { if ((Object)(object)heroData == (Object)null) { return initialValue; } T val = initialValue; foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null) { val = modifier(cardData, cardData.Item, val); } } return val; } public static bool HasBlessingImmunity(HeroData heroData, string auraCurseId) { Plugin.LogInfo($"[BlessingEffectManager] HasBlessingImmunity called. heroData={heroData}, auraCurseId={auraCurseId}", LogCategory.Blessings); if ((Object)(object)heroData == (Object)null) { return false; } foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if (!((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null)) { continue; } AuraCurseData auracurseImmune = cardData.Item.AuracurseImmune1; if (!(((auracurseImmune != null) ? auracurseImmune.Id : null) == auraCurseId)) { AuraCurseData auracurseImmune2 = cardData.Item.AuracurseImmune2; if (!(((auracurseImmune2 != null) ? auracurseImmune2.Id : null) == auraCurseId)) { continue; } } return true; } return false; } public static List<string> GetBlessingImmunities(HeroData heroData) { List<string> list = new List<string>(); if ((Object)(object)heroData == (Object)null) { return list; } foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null) { if ((Object)(object)cardData.Item.AuracurseImmune1 != (Object)null && !list.Contains(cardData.Item.AuracurseImmune1.Id)) { list.Add(cardData.Item.AuracurseImmune1.Id); } if ((Object)(object)cardData.Item.AuracurseImmune2 != (Object)null && !list.Contains(cardData.Item.AuracurseImmune2.Id)) { list.Add(cardData.Item.AuracurseImmune2.Id); } } } return list; } public static int GetMaxHPBonus(HeroData heroData) { return ApplyBlessingModifier(0, heroData, (CardData card, ItemData item, int total) => total + item.MaxHealth); } public static int GetHealFlatBonus(HeroData heroData) { return ApplyBlessingModifier(0, heroData, (CardData card, ItemData item, int total) => total + item.HealFlatBonus); } public static float GetHealPercentBonus(HeroData heroData) { return ApplyBlessingModifier(0f, heroData, (CardData card, ItemData item, float total) => total + item.HealPercentBonus); } public static int GetHealReceivedFlatBonus(HeroData heroData) { return ApplyBlessingModifier(0, heroData, (CardData card, ItemData item, int total) => total + item.HealReceivedFlatBonus); } public static float GetHealReceivedPercentBonus(HeroData heroData) { return ApplyBlessingModifier(0f, heroData, (CardData card, ItemData item, float total) => total + item.HealReceivedPercentBonus); } public static int GetDamageFlatBonus(HeroData heroData, DamageType damageType) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return ApplyBlessingModifier(0, heroData, delegate(CardData card, ItemData item, int total) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Invalid comparison between Unknown and I4 int num = 0; if (item.DamageFlatBonus == damageType || (int)item.DamageFlatBonus == 10) { num += item.DamageFlatBonusValue; } if (item.DamageFlatBonus2 == damageType || (int)item.DamageFlatBonus2 == 10) { num += item.DamageFlatBonusValue2; } if (item.DamageFlatBonus3 == damageType || (int)item.DamageFlatBonus3 == 10) { num += item.DamageFlatBonusValue3; } return total + num; }); } public static float GetDamagePercentBonus(HeroData heroData, DamageType damageType) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return ApplyBlessingModifier(0f, heroData, delegate(CardData card, ItemData item, float total) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Invalid comparison between Unknown and I4 float num = 0f; if (item.DamagePercentBonus == damageType || (int)item.DamagePercentBonus == 10) { num += item.DamagePercentBonusValue; } if (item.DamagePercentBonus2 == damageType || (int)item.DamagePercentBonus2 == 10) { num += item.DamagePercentBonusValue2; } if (item.DamagePercentBonus3 == damageType || (int)item.DamagePercentBonus3 == 10) { num += item.DamagePercentBonusValue3; } return total + num; }); } public static void AddDamageDictionaryEntries(HeroData heroData, DamageType damageType, Dictionary<string, int> result, bool isPercent) { //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Invalid comparison between Unknown and I4 //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Invalid comparison between Unknown and I4 //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Invalid comparison between Unknown and I4 //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Invalid comparison between Unknown and I4 //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Invalid comparison between Unknown and I4 //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Invalid comparison between Unknown and I4 if ((Object)(object)heroData == (Object)null) { return; } foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) == (Object)null) { continue; } float num = 0f; ItemData item = cardData.Item; if (isPercent) { if (item.DamagePercentBonus == damageType || (int)item.DamagePercentBonus == 10) { num += item.DamagePercentBonusValue; } if (item.DamagePercentBonus2 == damageType || (int)item.DamagePercentBonus2 == 10) { num += item.DamagePercentBonusValue2; } if (item.DamagePercentBonus3 == damageType || (int)item.DamagePercentBonus3 == 10) { num += item.DamagePercentBonusValue3; } } else { if (item.DamageFlatBonus == damageType || (int)item.DamageFlatBonus == 10) { num += (float)item.DamageFlatBonusValue; } if (item.DamageFlatBonus2 == damageType || (int)item.DamageFlatBonus2 == 10) { num += (float)item.DamageFlatBonusValue2; } if (item.DamageFlatBonus3 == damageType || (int)item.DamageFlatBonus3 == 10) { num += (float)item.DamageFlatBonusValue3; } } if (num != 0f) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(cardData.CardName); stringBuilder.Append("_card"); string key = stringBuilder.ToString(); if (result.ContainsKey(key)) { result[key] += (int)num; } else { result[key] = (int)num; } } } } public static int GetResistanceBonus(HeroData heroData, DamageType damageType) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return ApplyBlessingModifier(0, heroData, delegate(CardData card, ItemData item, int total) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Invalid comparison between Unknown and I4 int num = 0; if (item.ResistModified1 == damageType || (int)item.ResistModified1 == 10) { num += item.ResistModifiedValue1; } if (item.ResistModified2 == damageType || (int)item.ResistModified2 == 10) { num += item.ResistModifiedValue2; } if (item.ResistModified3 == damageType || (int)item.ResistModified3 == 10) { num += item.ResistModifiedValue3; } return total + num; }); } public static void AddResistanceDictionaryEntries(HeroData heroData, DamageType damageType, Dictionary<string, int> result) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Invalid comparison between Unknown and I4 //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Invalid comparison between Unknown and I4 if ((Object)(object)heroData == (Object)null) { return; } foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) == (Object)null) { continue; } int num = 0; ItemData item = cardData.Item; if (item.ResistModified1 == damageType || (int)item.ResistModified1 == 10) { num += item.ResistModifiedValue1; } if (item.ResistModified2 == damageType || (int)item.ResistModified2 == 10) { num += item.ResistModifiedValue2; } if (item.ResistModified3 == damageType || (int)item.ResistModified3 == 10) { num += item.ResistModifiedValue3; } if (num != 0) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(cardData.CardName); stringBuilder.Append("_card"); string key = stringBuilder.ToString(); if (result.ContainsKey(key)) { result[key] += num; } else { result[key] = num; } } } } public static Dictionary<string, int> GetAuraCurseModifiers(HeroData heroData) { Dictionary<string, int> dictionary = new Dictionary<string, int>(); if ((Object)(object)heroData == (Object)null) { return dictionary; } foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) == (Object)null) { continue; } ItemData item = cardData.Item; if ((Object)(object)item.AuracurseBonus1 != (Object)null) { string id = item.AuracurseBonus1.Id; if (dictionary.ContainsKey(id)) { dictionary[id] += item.AuracurseBonusValue1; } else { dictionary[id] = item.AuracurseBonusValue1; } } if ((Object)(object)item.AuracurseBonus2 != (Object)null) { string id2 = item.AuracurseBonus2.Id; if (dictionary.ContainsKey(id2)) { dictionary[id2] += item.AuracurseBonusValue2; } else { dictionary[id2] = item.AuracurseBonusValue2; } } } return dictionary; } public static void MergeAuraCurseModifiers(HeroData heroData, Dictionary<string, int> result) { Dictionary<string, int> auraCurseModifiers = GetAuraCurseModifiers(heroData); foreach (KeyValuePair<string, int> item in auraCurseModifiers) { if (result.ContainsKey(item.Key)) { result[item.Key] += item.Value; } else { result[item.Key] = item.Value; } } } public static int GetStatModifier(HeroData heroData, CharacterStat stat) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return ApplyBlessingModifier(0, heroData, delegate(CardData card, ItemData item, int total) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) int num = 0; if (item.CharacterStatModified == stat) { num += item.CharacterStatModifiedValue; } if (item.CharacterStatModified2 == stat) { num += item.CharacterStatModifiedValue2; } if (item.CharacterStatModified3 == stat) { num += item.CharacterStatModifiedValue3; } return total + num; }); } public static void AddHealPercentDictionaryEntries(HeroData heroData, Dictionary<string, int> result) { if ((Object)(object)heroData == (Object)null) { return; } foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null && (double)cardData.Item.HealPercentBonus != 0.0) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(cardData.CardName); stringBuilder.Append("_card"); string key = stringBuilder.ToString(); if (result.ContainsKey(key)) { result[key] += (int)cardData.Item.HealPercentBonus; } else { result[key] = (int)cardData.Item.HealPercentBonus; } } } } public static void AddHealFlatDictionaryEntries(HeroData heroData, Dictionary<string, int> result) { if ((Object)(object)heroData == (Object)null) { return; } foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, true); if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null && cardData.Item.HealFlatBonus != 0) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(cardData.CardName); stringBuilder.Append("_card"); string key = stringBuilder.ToString(); if (result.ContainsKey(key)) { result[key] += cardData.Item.HealFlatBonus; } else { result[key] = cardData.Item.HealFlatBonus; } } } } public static CardData GetRandomBlessing(List<string> ignore = null) { Plugin.LogInfo($"[Blessings] GetRandomBlessing: availableBlessings.Count = {AtOEndless.availableBlessings?.Count ?? 0}", LogCategory.Blessings); List<string> list = new List<string>(AtOEndless.availableBlessings); Plugin.LogInfo($"[Blessings] Initial pool: {list.Count} blessings", LogCategory.Blessings); foreach (string activeBlessing in AtOEndless.activeBlessings) { CardData cardData = Globals.Instance.GetCardData(activeBlessing, false); cardData = Functions.GetCardDataFromCardData(cardData, ""); if ((Object)(object)cardData != (Object)null && list.Contains(cardData.Id)) { list.Remove(cardData.Id); } } Plugin.LogInfo($"[Blessings] After removing active: {list.Count} blessings", LogCategory.Blessings); if (ignore != null) { foreach (string item in ignore) { CardData cardData2 = Globals.Instance.GetCardData(item, false); cardData2 = Functions.GetCardDataFromCardData(cardData2, ""); if ((Object)(object)cardData2 != (Object)null && list.Contains(cardData2.Id)) { list.Remove(cardData2.Id); } } } Plugin.LogInfo($"[Blessings] After removing ignored: {list.Count} blessings", LogCategory.Blessings); if (list.Count > 0) { list.Sort(); int townTier = AtOManager.Instance.GetTownTier(); string text = SelectWeightedBlessing(list, townTier); Plugin.LogInfo("[Blessings] Selected: " + text, LogCategory.Blessings); CardData val = Globals.Instance.GetCardData(text, false); Plugin.LogInfo("[Blessings] GetCardData returned: " + (((val != null) ? val.Id : null) ?? "NULL")); if (townTier == 0) { val = Functions.GetCardDataFromCardData(val, ""); if ((Object)(object)val != (Object)null) { text = val.Id; } } else if (townTier == 1) { val = Functions.GetCardDataFromCardData(val, "A"); if ((Object)(object)val != (Object)null) { text = val.Id; } } else if (townTier == 2) { val = Functions.GetCardDataFromCardData(val, "B"); if ((Object)(object)val != (Object)null) { text = val.Id; } } else if (townTier >= 3) { val = Functions.GetCardDataFromCardData(val, "RARE"); if ((Object)(object)val != (Object)null) { text = val.Id; } } if ((Object)(object)val == (Object)null) { val = Globals.Instance.GetCardData(text, false); } return val; } return null; } private static string SelectWeightedBlessing(List<string> blessingPool, int tier) { if (blessingPool == null || blessingPool.Count == 0) { return null; } if (blessingPool.Count == 1) { return blessingPool[0]; } List<int> list = new List<int>(blessingPool.Count); int num = 0; foreach (string item in blessingPool) { BlessingDefinition blessingByCardId = BlessingLoader.GetBlessingByCardId(item); float blessingWeight = BlessingLoader.GetBlessingWeight(blessingByCardId, tier); int num2 = (int)(blessingWeight * 100f); list.Add(num2); num += num2; } if (num <= 0) { int randomIntRange = MapManager.Instance.GetRandomIntRange(0, blessingPool.Count); return blessingPool[randomIntRange]; } int randomIntRange2 = MapManager.Instance.GetRandomIntRange(0, num); int num3 = 0; for (int i = 0; i < blessingPool.Count; i++) { num3 += list[i]; if (randomIntRange2 < num3) { BlessingDefinition blessingByCardId2 = BlessingLoader.GetBlessingByCardId(blessingPool[i]); Plugin.LogInfo(string.Format("[Blessings] Weighted selection: {0} (rarity={1}, weight={2}/{3}, tier={4})", blessingPool[i], blessingByCardId2?.Rarity ?? "?", list[i], num, tier)); return blessingPool[i]; } } return blessingPool[blessingPool.Count - 1]; } public static void BeginMatchBlessings() { Hero[] value = Traverse.Create((object)MatchManager.Instance).Field("TeamHero").GetValue<Hero[]>(); NPC[] value2 = Traverse.Create((object)MatchManager.Instance).Field("TeamNPC").GetValue<NPC[]>(); foreach (string item in AtOEndless.activeBlessings.ToList()) { CardData cardData = MatchManager.Instance.GetCardData(item, true); } } public static void CombatStartBlessings() { //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) Plugin.LogInfo("[BlessingEffectManager] CombatStartBlessings called.", LogCategory.Blessings); Traverse val = Traverse.Create((object)MatchManager.Instance); Hero[] value = val.Field("TeamHero").GetValue<Hero[]>(); Hero val2 = null; int num = -1; for (int i = 0; i < value.Length; i++) { if (value[i] != null && ((Character)value[i]).Alive) { val2 = value[i]; num = i; break; } } if (val2 == null) { Plugin.LogInfo("[BlessingEffectManager] CombatStartBlessings: No alive heroes, skipping all blessings", LogCategory.Blessings); return; } Hero value2 = val.Field("theHero").GetValue<Hero>(); int value3 = val.Field("heroActive").GetValue<int>(); val.Field("theHero").SetValue((object)val2); val.Field("heroActive").SetValue((object)num); Plugin.LogInfo($"[BlessingEffectManager] CombatStartBlessings: Set temporary theHero to {((Character)val2).Id}, heroActive to {num}", LogCategory.Blessings); try { foreach (string item in AtOEndless.activeBlessings.ToList()) { CardData cardData = MatchManager.Instance.GetCardData(item, true); if ((Object)(object)cardData == (Object)null) { Plugin.LogInfo("[BlessingEffectManager] CombatStartBlessings: CardData is null for blessing " + item + ", skipping", LogCategory.Blessings); } else if ((Object)(object)cardData.Item != (Object)null && cardData.Item.Activation == AtOEndless.blessingCombatStart) { Plugin.LogInfo("[BlessingEffectManager] Activating combat start blessing: " + item, LogCategory.Blessings); CardData val3 = Object.Instantiate<CardData>(cardData); val3.EnergyCost = 0; val3.Vanish = true; val3.CardClass = (CardClass)7; MatchManager.Instance.GenerateNewCard(1, item, false, (CardPlace)4, (CardData)null, (CardData)null, -1, true, 0, (CopyConfig)null); ((Character)val2).DoItem(AtOEndless.blessingCombatStart, val3, val3.Item.Id, (Character)null, 0, "", 0, (CardData)null, false); Object.Destroy((Object)(object)val3); } } } finally { val.Field("theHero").SetValue((object)value2); val.Field("heroActive").SetValue((object)value3); Plugin.LogInfo("[BlessingEffectManager] CombatStartBlessings: Restored original theHero and heroActive", LogCategory.Blessings); } } public static void BeginRoundBlessings() { //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Invalid comparison between Unknown and I4 //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Invalid comparison between Unknown and I4 //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Invalid comparison between Unknown and I4 //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Invalid comparison between Unknown and I4 //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) Plugin.LogInfo("[BlessingEffectManager] BeginRoundBlessings called.", LogCategory.Blessings); Traverse val = Traverse.Create((object)MatchManager.Instance); Hero[] value = val.Field("TeamHero").GetValue<Hero[]>(); NPC[] value2 = val.Field("TeamNPC").GetValue<NPC[]>(); Hero val2 = null; int num = -1; for (int i = 0; i < value.Length; i++) { if (value[i] != null && ((Character)value[i]).Alive) { val2 = value[i]; num = i; break; } } if (val2 == null) { Plugin.LogInfo("[BlessingEffectManager] BeginRoundBlessings: No alive heroes, skipping all blessings", LogCategory.Blessings); return; } Hero value3 = val.Field("theHero").GetValue<Hero>(); int value4 = val.Field("heroActive").GetValue<int>(); val.Field("theHero").SetValue((object)val2); val.Field("heroActive").SetValue((object)num); Plugin.LogInfo($"[BlessingEffectManager] BeginRoundBlessings: Set temporary theHero to {((Character)val2).Id}, heroActive to {num}", LogCategory.Blessings); try { foreach (string item in AtOEndless.activeBlessings.ToList()) { CardData cardData = MatchManager.Instance.GetCardData(item, true); if ((Object)(object)cardData == (Object)null) { Plugin.LogInfo("[BlessingEffectManager] BeginRoundBlessings: CardData is null for blessing " + item + ", skipping", LogCategory.Blessings); } else { if (!((Object)(object)cardData.Item != (Object)null) || cardData.Item.Activation != AtOEndless.blessingBeginRound) { continue; } if ((int)cardData.Item.ItemTarget == 0) { for (int j = 0; j < value.Length; j++) { if (value[j] != null && ((Character)value[j]).Alive) { ((Character)value[j]).DoItem(AtOEndless.blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardData)null, false); } } } else if ((int)cardData.Item.ItemTarget == 1) { List<int> list = new List<int>(); for (int k = 0; k < value.Length; k++) { if (value[k] != null && ((Character)value[k]).Alive) { list.Add(k); } } int randomIntRange = MatchManager.Instance.GetRandomIntRange(0, list.Count, "default", ""); int num2 = list[randomIntRange]; ((Character)value[num2]).DoItem(AtOEndless.blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardData)null, false); } else if ((int)cardData.Item.ItemTarget == 6) { for (int l = 0; l < value2.Length; l++) { if (value2[l] != null && ((Character)value2[l]).Alive) { ((Character)value2[l]).DoItem(AtOEndless.blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardData)null, false); } } } else if ((int)cardData.Item.ItemTarget == 2) { List<int> list2 = new List<int>(); for (int m = 0; m < value2.Length; m++) { if (value2[m] != null && ((Character)value2[m]).Alive) { list2.Add(m); } } if (list2.Count > 0) { int randomIntRange2 = MatchManager.Instance.GetRandomIntRange(0, list2.Count, "default", ""); int num3 = list2[randomIntRange2]; ((Character)val2).DoItem(AtOEndless.blessingBeginRound, cardData, cardData.Item.Id, (Character)(object)value2[num3], 0, "", 0, (CardData)null, false); } } else { ((Character)val2).DoItem(AtOEndless.blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardData)null, false); } } } } finally { val.Field("theHero").SetValue((object)value3); val.Field("heroActive").SetValue((object)value4); Plugin.LogInfo("[BlessingEffectManager] BeginRoundBlessings: Restored original theHero and heroActive", LogCategory.Blessings); } } public static void ApplyCombatStartBlessingsToNPC(NPC npc) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between Unknown and I4 //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (npc == null || !AtOEndless.IsEndlessMode()) { return; } ApplyCorruptionToNPC(npc); foreach (string activeBlessing in AtOEndless.activeBlessings) { MatchManager instance = MatchManager.Instance; CardData val = ((instance != null) ? instance.GetCardData(activeBlessing, true) : null); if (!((Object)(object)((val != null) ? val.Item : null) == (Object)null) && val.Item.Activation == AtOEndless.blessingCombatStart) { ItemTarget itemTarget = val.Item.ItemTarget; if ((int)itemTarget == 4 || (int)itemTarget == 6 || (int)itemTarget == 2) { ((Character)npc).DoItem(AtOEndless.blessingCombatStart, val, val.Item.Id, (Character)null, 0, "", 0, (CardData)null, false); } } } } public static void ApplyCorruptionToNPC(NPC npc) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 if (npc == null || (Object)(object)MatchManager.Instance == (Object)null) { return; } ItemData corruptionItem = MatchManager.Instance.corruptionItem; string corruptionCardId = MatchManager.Instance.corruptionCardId; if (!((Object)(object)corruptionItem == (Object)null) && !string.IsNullOrEmpty(corruptionCardId) && (int)corruptionItem.Activation == 27) { CardData cardData = MatchManager.Instance.GetCardData(corruptionCardId, true); if (!((Object)(object)cardData == (Object)null)) { ((Character)npc).DoItem((EventActivation)27, cardData, corruptionItem.Id, (Character)null, 0, "", 0, (CardData)null, false); NPCData npcData = ((Character)npc).NpcData; Plugin.LogInfo("Applied corruption combat start to newly spawned NPC " + ((npcData != null) ? npcData.NPCName : null), LogCategory.Blessings); } } } [HarmonyPrefix] [HarmonyPatch(typeof(CardVertical), "fMouseEnter")] public static bool CardVertical_fMouseEnter_Prefix(CardVertical __instance) { if ((Object)(object)__instance.cardData == (Object)null) { Plugin.LogInfo("[BlessingEffectManager] CardVertical.fMouseEnter skipped - cardData is null", LogCategory.Blessings); return false; } return true; } } public static class BlessingLoader { private static readonly string BlessingsFolder = "Blessings"; private static List<BlessingDefinition> loadedBlessings = new List<BlessingDefinition>(); private static Dictionary<string, BlessingDefinition> blessingLookup = new Dictionary<string, BlessingDefinition>(); private static Dictionary<string, CardData> createdCards = new Dictionary<string, CardData>(); private static List<Object> _createdScriptableObjects = new List<Object>(); public static void LoadAllBlessings() { Plugin.LogInfo("[BlessingLoader] LoadAllBlessings called", LogCategory.Blessings); loadedBlessings.Clear(); blessingLookup.Clear(); LoadEmbeddedBlessings(); LoadExternalBlessings(); Plugin.LogInfo($"Loaded {loadedBlessings.Count} total blessings ({blessingLookup.Count} unique IDs)", LogCategory.Blessings); } private static void LoadEmbeddedBlessings() { try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); Plugin.LogInfo($"[BlessingLoader] Assembly has {manifestResourceNames.Length} embedded resources:", LogCategory.Blessings); string[] array = manifestResourceNames; foreach (string text in array) { Plugin.LogInfo("[BlessingLoader] - " + text, LogCategory.Blessings); } List<string> list = manifestResourceNames.Where((string r) => r.StartsWith("AtOEndless.Data.Blessings.") && r.EndsWith(".json")).ToList(); Plugin.LogInfo($"[BlessingLoader] Found {list.Count} blessing JSON resources", LogCategory.Blessings); foreach (string item in list) { try { using Stream stream = executingAssembly.GetManifestResourceStream(item); if (stream == null) { Plugin.LogWarning("[BlessingLoader] Could not open stream for " + item); continue; } using StreamReader streamReader = new StreamReader(stream); string json = streamReader.ReadToEnd(); LoadBlessingJson(json, item); } catch (Exception ex) { Plugin.LogWarning("[BlessingLoader] Error loading " + item + ": " + ex.Message); } } Plugin.LogInfo($"[BlessingLoader] Loaded {loadedBlessings.Count} blessings from embedded resources", LogCategory.Blessings); } catch (Exception ex2) { Plugin.LogInfo("[BlessingLoader] Error loading embedded blessings: " + ex2.Message, LogCategory.Blessings); Plugin.LogInfo("[BlessingLoader] Stack trace: " + ex2.StackTrace, LogCategory.Blessings); } } private static void LoadExternalBlessings() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = Path.Combine(directoryName, BlessingsFolder); if (!Directory.Exists(text)) { Plugin.LogInfo("Blessings folder not found at " + text + ", creating it...", LogCategory.Blessings); Directory.CreateDirectory(text); return; } int count = loadedBlessings.Count; string[] files = Directory.GetFiles(text, "*.json"); foreach (string text2 in files) { try { LoadBlessingFile(text2); } catch (Exception ex) { Plugin.LogInfo("Error loading blessing file " + text2 + ": " + ex.Message, LogCategory.Blessings); } } string[] directories = Directory.GetDirectories(text); foreach (string path in directories) { string fileName = Path.GetFileName(path); Plugin.LogInfo("[BlessingLoader] Scanning subdirectory: