Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of balrond battle flow v0.1.0
plugins/BalrondBattleFlow.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using HarmonyLib; using LitJson2; using UnityEngine; [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 = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] namespace BalrondBattleFlow { public static class AdrenalineConstants { public const float MaxAdrenaline = 100f; public const float ZeroAdrenalineDamageMultiplier = 0.95f; public const float FullAdrenalineDamageBonus = 0.1f; public const float DefaultSecondaryAdrenalineCost = 10f; public const string SurgeStatusName = "SE_AdrenalineSurge"; public const string OverchargedStatusName = "SE_AdrenalineOvercharged"; public const float SurgeDuration = 5f; public const float OverchargedDuration = 10f; public const float OverchargedAdrenalineDrainPerSecond = 10f; } public static class AdrenalineRuntime { private static readonly Dictionary<int, StatusEffect> StatusCache = new Dictionary<int, StatusEffect>(); private static float _lastMissingStatusWarningTime; public static void ClearCache() { StatusCache.Clear(); } public static StatusEffect ResolveStatusEffect(string name) { if ((Object)(object)ObjectDB.instance == (Object)null || string.IsNullOrEmpty(name)) { return null; } EnsureStatusBootstrapsFor(name); int num = BalrondHashCompat.StableHash(name); if (StatusCache.TryGetValue(num, out var value) && (Object)(object)value != (Object)null) { return value; } StatusEffect statusEffect = ObjectDB.instance.GetStatusEffect(num); if ((Object)(object)statusEffect != (Object)null) { StatusCache[num] = statusEffect; return statusEffect; } if (ObjectDB.instance.m_StatusEffects != null) { for (int i = 0; i < ObjectDB.instance.m_StatusEffects.Count; i++) { StatusEffect val = ObjectDB.instance.m_StatusEffects[i]; if ((Object)(object)val != (Object)null && ((Object)val).name == name) { StatusCache[num] = val; return val; } } } return null; } private static void EnsureStatusBootstrapsFor(string name) { if (!((Object)(object)ObjectDB.instance == (Object)null)) { if (name == "SE_AdrenalineSurge" || name == "SE_AdrenalineOvercharged") { AdrenalineOverchargeEffectsBootstrap.Install(); } else if (name.StartsWith("SE_MinorAdren_")) { MinorAdrenEffectsBootstrap.Install(); } } } public static bool HasStatus(Player player, string statusName) { if ((Object)(object)player == (Object)null || ((Character)player).GetSEMan() == null || string.IsNullOrEmpty(statusName)) { return false; } int num = BalrondHashCompat.StableHash(statusName); return (Object)(object)((Character)player).GetSEMan().GetStatusEffect(num) != (Object)null; } public static bool AddStatus(Player player, string statusName, bool resetTime) { if ((Object)(object)player == (Object)null || ((Character)player).GetSEMan() == null || string.IsNullOrEmpty(statusName)) { return false; } StatusEffect val = ResolveStatusEffect(statusName); if ((Object)(object)val == (Object)null) { if (Time.time - _lastMissingStatusWarningTime > 2f) { _lastMissingStatusWarningTime = Time.time; BattleFlowDebug.Warning("Missing status effect " + statusName + ". ObjectDB status count=" + GetStatusCountForLog()); } return false; } ((Character)player).GetSEMan().AddStatusEffect(val.NameHash(), resetTime, 0, 0f); BattleFlowDebug.Log("Added status " + statusName + " reset=" + resetTime); return true; } public static void TryStartSurge(Player player) { if ((Object)(object)player == (Object)null || ((Character)player).GetSEMan() == null) { return; } AdrenalineOverchargeEffectsBootstrap.Install(); if (!HasStatus(player, "SE_AdrenalineSurge") && AddStatus(player, "SE_AdrenalineSurge", resetTime: false)) { Hud instance = Hud.instance; if ((Object)(object)instance != (Object)null) { instance.AdrenalineBarFlash(); } } } private static int GetStatusCountForLog() { if ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_StatusEffects == null) { return -1; } return ObjectDB.instance.m_StatusEffects.Count; } } public static class BattleFlowDebug { public static bool Enabled; public static void Log(string message) { if (Enabled) { Debug.Log((object)("BalrondBattleFlow: " + message)); } } public static void Warning(string message) { Debug.LogWarning((object)("BalrondBattleFlow: " + message)); } } public static class BattleFlowIconHelper { public static Sprite GetIcon(ObjectDB odb, params string[] prefabNames) { if ((Object)(object)odb == (Object)null || prefabNames == null) { return null; } for (int i = 0; i < prefabNames.Length; i++) { Sprite iconUnsafe = GetIconUnsafe(odb, prefabNames[i]); if ((Object)(object)iconUnsafe != (Object)null) { return iconUnsafe; } } return null; } private static Sprite GetIconUnsafe(ObjectDB odb, string prefabName) { if (string.IsNullOrEmpty(prefabName)) { return null; } GameObject itemPrefab = odb.GetItemPrefab(BalrondHashCompat.StableHash(prefabName)); if ((Object)(object)itemPrefab == (Object)null) { itemPrefab = odb.GetItemPrefab(prefabName); } if ((Object)(object)itemPrefab == (Object)null) { return null; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || component.m_itemData.m_shared == null || component.m_itemData.m_shared.m_icons == null || component.m_itemData.m_shared.m_icons.Length == 0) { return null; } return component.m_itemData.m_shared.m_icons[0]; } public static Sprite GetFallbackIcon(ObjectDB odb) { return GetIcon(odb, "TrophyEikthyr", "TrophyDeer", "Amber", "AmberPearl", "SwordBronze", "Wood"); } } public static class MinorAdrenEffectsBootstrap { private static bool _installed; public static void Install() { ObjectDB instance = ObjectDB.instance; if (!IsObjectDBReady(instance)) { BattleFlowDebug.Log("MinorAdrenEffects bootstrap skipped, ObjectDB not ready"); } else if (!_installed || !HasAll(instance)) { EnsureAll(instance); _installed = HasAll(instance); AdrenalineRuntime.ClearCache(); if (_installed) { BattleFlowDebug.Log("Minor adrenaline effects registered"); } else { BattleFlowDebug.Warning("Not all minor adrenaline effects were registered"); } } } private static bool IsObjectDBReady(ObjectDB odb) { return (Object)(object)odb != (Object)null && odb.m_StatusEffects != null && odb.m_items != null && odb.m_items.Count > 0; } private static bool HasAll(ObjectDB odb) { return HasSE(odb, "SE_MinorAdren_Sword") && HasSE(odb, "SE_MinorAdren_Axe") && HasSE(odb, "SE_MinorAdren_Mace") && HasSE(odb, "SE_MinorAdren_Knife") && HasSE(odb, "SE_MinorAdren_Spear") && HasSE(odb, "SE_MinorAdren_Polearm") && HasSE(odb, "SE_MinorAdren_Bow") && HasSE(odb, "SE_MinorAdren_Crossbow") && HasSE(odb, "SE_MinorAdren_Staff"); } public static bool HasSE(string name) { return (Object)(object)ObjectDB.instance != (Object)null && HasSE(ObjectDB.instance, name); } private static bool HasSE(ObjectDB odb, string name) { int num = BalrondHashCompat.StableHash(name); if ((Object)(object)odb.GetStatusEffect(num) != (Object)null) { return true; } if (odb.m_StatusEffects == null) { return false; } for (int i = 0; i < odb.m_StatusEffects.Count; i++) { StatusEffect val = odb.m_StatusEffects[i]; if ((Object)(object)val != (Object)null && ((Object)val).name == name) { return true; } } return false; } private static Sprite WeaponIcon(ObjectDB odb, string prefabName) { Sprite icon = BattleFlowIconHelper.GetIcon(odb, prefabName); if ((Object)(object)icon == (Object)null) { BattleFlowDebug.Warning("[MinorAdrenEffects] Missing weapon icon prefab/icon: " + prefabName); } return icon; } private static void EnsureAll(ObjectDB odb) { EnsureSE(odb, "SE_MinorAdren_Sword", WeaponIcon(odb, "SwordBronze"), 10f, "Adrenaline surge (1H Sword): +10% damage, -20% attack stamina", 1.1f, -0.2f); EnsureSE(odb, "SE_MinorAdren_Axe", WeaponIcon(odb, "AxeIron"), 10f, "Adrenaline surge (1H Axe): +10% damage, +30% stagger", 1.1f, 0f, 0f, 0f, 0.2f); EnsureSE(odb, "SE_MinorAdren_Mace", WeaponIcon(odb, "MaceIron"), 10f, "Adrenaline surge (Mace): +20% stagger, -20% block stamina", 1f, 0f, -0.2f, 0f, 0.1f); EnsureSE(odb, "SE_MinorAdren_Knife", WeaponIcon(odb, "KnifeCopper"), 10f, "Adrenaline surge (Knife): +15% move speed, +15% damage", 1.15f, 0f, 0f, 0.15f); EnsureSE(odb, "SE_MinorAdren_Spear", WeaponIcon(odb, "SpearBronze"), 10f, "Adrenaline surge (Spear): +15% move speed, -15% attack stamina", 1f, -0.15f, 0f, 0.15f); EnsureSE(odb, "SE_MinorAdren_Polearm", WeaponIcon(odb, "AtgeirBronze"), 10f, "Adrenaline surge (Atgeir): +15% damage, +15% parry bonus", 1.15f, 0f, 0f, 0f, 0f, 0.15f); EnsureSE(odb, "SE_MinorAdren_Bow", WeaponIcon(odb, "Bow"), 10f, "Adrenaline surge (Bow): -15% draw stamina, +15% move speed", 1f, -0.15f, 0f, 0.15f); EnsureSE(odb, "SE_MinorAdren_Crossbow", WeaponIcon(odb, "CrossbowArbalest"), 10f, "Adrenaline surge (Crossbow): +5% damage, +25% stagger", 1.05f, 0f, 0f, 0f, 0.25f); EnsureSE(odb, "SE_MinorAdren_Staff", WeaponIcon(odb, "StaffFireball"), 10f, "Adrenaline surge (Staff): +15% damage, +15% stamina regen", 1.15f, 0f, 0f, 0f, 0f, 0f, 0.15f); } private static void EnsureSE(ObjectDB odb, string name, Sprite icon, float ttl, string tooltip, float damage = 1f, float attackStamina = 0f, float blockStamina = 0f, float speed = 0f, float stagger = 0f, float parryBonus = 0f, float staminaRegen = 0f) { if (HasSE(odb, name)) { return; } if ((Object)(object)icon == (Object)null) { BattleFlowDebug.Warning("[MinorAdrenEffects] Status effect " + name + " missing weapon icon, skipping registration"); return; } SE_Stats val = ScriptableObject.CreateInstance<SE_Stats>(); ((Object)val).name = name; ((StatusEffect)val).m_name = "$tag_" + name + "_name_bal"; ((StatusEffect)val).m_tooltip = "$tag_" + name + "_tooltip_bal"; ((StatusEffect)val).m_icon = icon; ((StatusEffect)val).m_ttl = ttl; ((StatusEffect)val).m_flashIcon = true; if (damage != 1f) { val.m_damageModifier = damage; } if (attackStamina != 0f) { val.m_attackStaminaUseModifier = attackStamina; } if (blockStamina != 0f) { val.m_blockStaminaUseModifier = blockStamina; } if (speed != 0f) { val.m_speedModifier = speed; } if (stagger != 0f) { val.m_staggerModifier = stagger; } if (parryBonus != 0f) { val.m_timedBlockBonus = parryBonus; } if (staminaRegen != 0f) { val.m_staminaRegenMultiplier = staminaRegen; } odb.m_StatusEffects.Add((StatusEffect)(object)val); Debug.Log((object)("BalrondBattleFlow: Registered " + name + " using weapon icon")); } } public static class MinorAdrenManager { private sealed class MinorAdrenConfig { public readonly float ThresholdFraction; public readonly string EffectName; public readonly float Duration; public readonly float Cooldown; public readonly int EffectHash; public readonly float[] TierLastProcTimes = new float[4]; public MinorAdrenConfig(float fraction, string effectName, float duration, float cooldown = 20f) { ThresholdFraction = fraction; EffectName = effectName; Duration = duration; Cooldown = cooldown; EffectHash = BalrondHashCompat.StableHash(effectName); for (int i = 0; i < TierLastProcTimes.Length; i++) { TierLastProcTimes[i] = float.NegativeInfinity; } } } private static readonly Dictionary<SkillType, MinorAdrenConfig> _map = new Dictionary<SkillType, MinorAdrenConfig> { { (SkillType)1, new MinorAdrenConfig(0.25f, "SE_MinorAdren_Sword", 8f) }, { (SkillType)7, new MinorAdrenConfig(0.25f, "SE_MinorAdren_Axe", 8f) }, { (SkillType)3, new MinorAdrenConfig(0.25f, "SE_MinorAdren_Mace", 9f) }, { (SkillType)2, new MinorAdrenConfig(0.25f, "SE_MinorAdren_Knife", 7f) }, { (SkillType)5, new MinorAdrenConfig(0.25f, "SE_MinorAdren_Spear", 8f) }, { (SkillType)4, new MinorAdrenConfig(0.5f, "SE_MinorAdren_Polearm", 8f) }, { (SkillType)8, new MinorAdrenConfig(0.3f, "SE_MinorAdren_Bow", 7f) }, { (SkillType)14, new MinorAdrenConfig(0.4f, "SE_MinorAdren_Crossbow", 7f) }, { (SkillType)9, new MinorAdrenConfig(0.5f, "SE_MinorAdren_Staff", 8f) } }; public unsafe static void CheckThreshold(Player player) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); if (currentWeapon == null || currentWeapon.m_shared == null) { return; } SkillType skillType = currentWeapon.m_shared.m_skillType; if (!_map.TryGetValue(skillType, out var value)) { BattleFlowDebug.Log("Minor adrenaline no config for skill " + ((object)(*(SkillType*)(&skillType))/*cast due to .constrained prefix*/).ToString()); } else { if ((Object)(object)player.m_skills == (Object)null) { return; } Skill skill = player.m_skills.GetSkill(skillType); if (skill == null) { return; } float level = skill.m_level; if (level < 25f) { BattleFlowDebug.Log("Minor adrenaline skipped. Skill too low: " + ((object)(*(SkillType*)(&skillType))/*cast due to .constrained prefix*/).ToString() + " " + level); return; } float adrenaline = player.GetAdrenaline(); if (adrenaline < 25f) { return; } int num = 0; if (adrenaline >= 25f && level >= 75f) { num = 1; } if (adrenaline >= 50f && level >= 50f && num < 2) { num = 2; } if (adrenaline >= 75f && level >= 25f && num < 3) { num = 3; } if (num == 0) { BattleFlowDebug.Log("Minor adrenaline no tier. Skill=" + level + " adrenaline=" + adrenaline); return; } float time = Time.time; float num2 = value.TierLastProcTimes[num]; if (time - num2 < value.Cooldown) { BattleFlowDebug.Log("Minor adrenaline tier on cooldown. " + value.EffectName + " tier=" + num); return; } SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan == null) { return; } MinorAdrenEffectsBootstrap.Install(); if (!MinorAdrenEffectsBootstrap.HasSE(value.EffectName)) { BattleFlowDebug.Warning("Minor adrenaline status missing before apply: " + value.EffectName); return; } sEMan.AddStatusEffect(value.EffectHash, true, 0, 0f); value.TierLastProcTimes[num] = time; BattleFlowDebug.Log("Minor adrenaline applied " + value.EffectName + " tier=" + num + " skill=" + level + " adrenaline=" + adrenaline); Hud instance = Hud.instance; if ((Object)(object)instance != (Object)null) { instance.AdrenalineBarFlash(); } } } } public static class AdrenalineOverchargeEffectsBootstrap { private static bool _installed; public static void Install() { ObjectDB instance = ObjectDB.instance; if (!IsObjectDBReady(instance)) { BattleFlowDebug.Log("Surge/Overcharge bootstrap skipped, ObjectDB not ready"); } else if (!_installed || !HasAll(instance)) { Sprite fallbackIcon = BattleFlowIconHelper.GetFallbackIcon(instance); EnsureSurge(instance, fallbackIcon); EnsureOvercharged(instance, fallbackIcon); _installed = HasAll(instance); AdrenalineRuntime.ClearCache(); if (_installed) { BattleFlowDebug.Log("Surge/Overcharge effects registered"); } else { BattleFlowDebug.Warning("Surge/Overcharge effects were not fully registered"); } } } private static bool IsObjectDBReady(ObjectDB odb) { return (Object)(object)odb != (Object)null && odb.m_StatusEffects != null && odb.m_items != null && odb.m_items.Count > 0; } private static bool HasAll(ObjectDB odb) { return HasSE(odb, "SE_AdrenalineSurge") && HasSE(odb, "SE_AdrenalineOvercharged"); } private static bool HasSE(ObjectDB odb, string name) { if ((Object)(object)odb == (Object)null) { return false; } int num = BalrondHashCompat.StableHash(name); if ((Object)(object)odb.GetStatusEffect(num) != (Object)null) { return true; } if (odb.m_StatusEffects == null) { return false; } for (int i = 0; i < odb.m_StatusEffects.Count; i++) { StatusEffect val = odb.m_StatusEffects[i]; if ((Object)(object)val != (Object)null && ((Object)val).name == name) { return true; } } return false; } private static void EnsureSurge(ObjectDB odb, Sprite icon) { if (!HasSE(odb, "SE_AdrenalineSurge")) { SE_AdrenalineSurge sE_AdrenalineSurge = ScriptableObject.CreateInstance<SE_AdrenalineSurge>(); ((Object)sE_AdrenalineSurge).name = "SE_AdrenalineSurge"; ((StatusEffect)sE_AdrenalineSurge).m_name = "$tag_SE_AdrenalineSurge_name_bal"; ((StatusEffect)sE_AdrenalineSurge).m_tooltip = "$tag_SE_AdrenalineSurge_tooltip_bal"; ((StatusEffect)sE_AdrenalineSurge).m_icon = icon; ((StatusEffect)sE_AdrenalineSurge).m_ttl = 5f; ((StatusEffect)sE_AdrenalineSurge).m_cooldownIcon = false; ((StatusEffect)sE_AdrenalineSurge).m_flashIcon = true; odb.m_StatusEffects.Add((StatusEffect)(object)sE_AdrenalineSurge); Debug.Log((object)("BalrondBattleFlow: Registered " + ((Object)sE_AdrenalineSurge).name + " icon=" + ((Object)(object)icon != (Object)null))); } } private static void EnsureOvercharged(ObjectDB odb, Sprite icon) { if (!HasSE(odb, "SE_AdrenalineOvercharged")) { SE_AdrenalineOvercharged sE_AdrenalineOvercharged = ScriptableObject.CreateInstance<SE_AdrenalineOvercharged>(); ((Object)sE_AdrenalineOvercharged).name = "SE_AdrenalineOvercharged"; ((StatusEffect)sE_AdrenalineOvercharged).m_name = "$tag_SE_AdrenalineOvercharged_name_bal"; ((StatusEffect)sE_AdrenalineOvercharged).m_tooltip = "$tag_SE_AdrenalineOvercharged_tooltip_bal"; ((StatusEffect)sE_AdrenalineOvercharged).m_icon = icon; ((StatusEffect)sE_AdrenalineOvercharged).m_ttl = 10f; ((StatusEffect)sE_AdrenalineOvercharged).m_cooldownIcon = false; ((StatusEffect)sE_AdrenalineOvercharged).m_flashIcon = true; ((SE_Stats)sE_AdrenalineOvercharged).m_speedModifier = -0.05f; ((SE_Stats)sE_AdrenalineOvercharged).m_healthRegenMultiplier = 0.5f; ((SE_Stats)sE_AdrenalineOvercharged).m_staminaRegenMultiplier = 0.5f; ((SE_Stats)sE_AdrenalineOvercharged).m_eitrRegenMultiplier = 0.5f; ((SE_Stats)sE_AdrenalineOvercharged).m_attackStaminaUseModifier = 0.05f; odb.m_StatusEffects.Add((StatusEffect)(object)sE_AdrenalineOvercharged); Debug.Log((object)("BalrondBattleFlow: Registered " + ((Object)sE_AdrenalineOvercharged).name + " icon=" + ((Object)(object)icon != (Object)null))); } } } public sealed class SE_AdrenalineSurge : SE_Stats { public override void Stop() { Character character = ((StatusEffect)this).m_character; Player val = (Player)(object)((character is Player) ? character : null); if ((Object)(object)val != (Object)null) { float maxAdrenaline = ((Character)val).GetMaxAdrenaline(); if (maxAdrenaline > 0f && val.GetAdrenaline() >= maxAdrenaline) { AdrenalineRuntime.AddStatus(val, "SE_AdrenalineOvercharged", resetTime: true); } } ((StatusEffect)this).Stop(); } } public sealed class SE_AdrenalineOvercharged : SE_Stats { public override void UpdateStatusEffect(float dt) { ((SE_Stats)this).UpdateStatusEffect(dt); Character character = ((StatusEffect)this).m_character; Player val = (Player)(object)((character is Player) ? character : null); if (!((Object)(object)val == (Object)null)) { ((Character)val).AddAdrenaline(-10f * dt); } } } public class BalrondTranslator { public static Dictionary<string, Dictionary<string, string>> translations = new Dictionary<string, Dictionary<string, string>>(); public static Dictionary<string, string> getLanguage(string language) { if (string.IsNullOrEmpty(language)) { return null; } if (translations.TryGetValue(language, out var value)) { return value; } return null; } } public class JsonLoader { public string defaultPath = string.Empty; public void loadJson() { LoadTranslations(); justDefaultPath(); } public void justDefaultPath() { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "BalrondBattleFlow-translation/"); defaultPath = text; } public void createDefaultPath() { string configPath = Paths.ConfigPath; string path = Path.Combine(configPath, "BalrondBattleFlow-translation/"); if (!Directory.Exists(path)) { CreateFolder(path); } defaultPath = path; } private string[] jsonFilePath(string folderName, string extension) { string configPath = Paths.ConfigPath; string path = Path.Combine(configPath, "BalrondBattleFlow-translation/"); if (!Directory.Exists(path)) { CreateFolder(path); } return Directory.GetFiles(path, extension); } private static void CreateFolder(string path) { try { Directory.CreateDirectory(path); Debug.Log((object)"BalrondBattleFlow: Folder created successfully."); } catch (Exception ex) { Debug.Log((object)("BalrondBattleFlow: Error creating folder: " + ex.Message)); } } private void LoadTranslations() { int num = 0; string[] array = jsonFilePath("Translation", "*.json"); foreach (string text in array) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); string json = File.ReadAllText(text); JsonData jsonData = JsonMapper.ToObject(json); Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (string key in jsonData.Keys) { dictionary[key] = jsonData[key].ToString(); } if (dictionary != null) { BalrondTranslator.translations.Add(fileNameWithoutExtension, dictionary); num++; } else { Debug.LogError((object)("BalrondBattleFlow: Loading FAILED file: " + text)); } } } } [BepInPlugin("balrond.astafaraios.BalrondBattleFlow", "BalrondBattleFlow", "0.1.0")] public sealed class Launch : BaseUnityPlugin { public const string PluginGUID = "balrond.astafaraios.BalrondBattleFlow"; public const string PluginName = "BalrondBattleFlow"; public const string PluginVersion = "0.1.0"; public static string projectName = "BalrondBattleFlow"; public static JsonLoader jsonLoader = new JsonLoader(); private Harmony _harmony; private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown jsonLoader.loadJson(); _harmony = new Harmony("balrond.astafaraios.BalrondBattleFlow"); _harmony.PatchAll(); Debug.Log((object)"BalrondBattleFlow: loaded"); } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); _harmony = null; } } } [HarmonyPatch] internal static class AdrenalinePatches { [HarmonyPatch(typeof(Player), "AddAdrenaline")] private static class Player_AddAdrenaline_BattleFlow_Patch { private static bool Prefix(Player __instance, ref float v) { if ((Object)(object)__instance == (Object)null) { return false; } float maxAdrenaline = ((Character)__instance).GetMaxAdrenaline(); if (v > 0f && maxAdrenaline > 0f) { float num = __instance.GetAdrenaline() / maxAdrenaline; __instance.m_adrenalineDegenTimer = __instance.m_adrenalineDegenDelay.Evaluate(num); v *= Game.m_adrenalineRate; v *= __instance.m_adrenalineGainMultiplier.Evaluate(num); if (((Character)__instance).m_seman != null) { ((Character)__instance).m_seman.ModifyAdrenaline(v, ref v); } } if (v < 0f || (v > 0f && __instance.m_adrenaline < maxAdrenaline)) { __instance.m_adrenaline += v; } if (__instance.m_adrenaline < 0f) { __instance.m_adrenaline = 0f; } if (maxAdrenaline > 0f && __instance.m_adrenaline >= maxAdrenaline) { __instance.m_adrenaline = maxAdrenaline; AdrenalineRuntime.TryStartSurge(__instance); } if (v > 0f) { MinorAdrenManager.CheckThreshold(__instance); } UpdateTieredAdrenalineEffects(__instance); return false; } } [HarmonyPatch(typeof(Player), "GetMaxAdrenaline")] private static class Player_GetMaxAdrenaline_Always100_Patch { private static bool Prefix(ref float __result) { __result = 100f; return false; } } private static void UpdateTieredAdrenalineEffects(Player player) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || player.m_adrenalineEffects == null || ((Character)player).GetSEMan() == null) { return; } StatusEffect val = null; for (int num = player.m_adrenalineEffects.Count - 1; num >= 0; num--) { StatusEffectLevel val2 = player.m_adrenalineEffects[num]; if (player.m_adrenaline >= val2.m_rate) { val = val2.m_se; break; } } if (player.m_adrenalineEffects.Count <= 0 || ((!((Object)(object)val != (Object)null) || !((Object)(object)((Character)player).GetSEMan().GetStatusEffect(val.NameHash()) != (Object)(object)val)) && (!((Object)(object)val == (Object)null) || !((Object)(object)((Character)player).GetSEMan().GetStatusEffect(player.m_adrenalineEffects[0].m_se.NameHash()) != (Object)null)))) { return; } for (int i = 0; i < player.m_adrenalineEffects.Count; i++) { StatusEffectLevel val3 = player.m_adrenalineEffects[i]; if ((Object)(object)val3.m_se != (Object)null) { ((Character)player).GetSEMan().RemoveStatusEffect(val3.m_se.NameHash(), false); } } if ((Object)(object)val != (Object)null) { ((Character)player).GetSEMan().AddStatusEffect(val.NameHash(), true, 0, 0f); if ((Object)(object)Hud.instance != (Object)null) { Hud.instance.AdrenalineBarFlash(); } } } } [HarmonyPatch] internal static class CombatAdrenalinePatches { [HarmonyPatch(typeof(Character), "RPC_Damage")] private static class Character_RPC_Damage_AdrenalineScaling_Patch { [HarmonyPrefix] private static void Prefix(Character __instance, HitData hit) { if ((Object)(object)__instance == (Object)null || hit == null || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner()) { return; } Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if ((Object)(object)val == (Object)null) { return; } float num = SanitizeFloat(((Character)val).GetMaxAdrenaline(), 0f); if (!(num <= 0f)) { float num2 = SanitizeFloat(val.GetAdrenaline(), 0f); float num3 = Mathf.Clamp01(num2 / num); float value = ((num3 <= 0.0001f) ? 0.95f : (1f + 0.1f * num3)); value = SanitizeFloat(value, 1f); if (value <= 0f) { value = 1f; } ((DamageTypes)(ref hit.m_damage)).Modify(value); } } } private const float FloatEpsilon = 0.0001f; private static readonly Dictionary<SkillType, float> SpecialCosts = new Dictionary<SkillType, float> { { (SkillType)1, 5f }, { (SkillType)7, 5f }, { (SkillType)2, 5f }, { (SkillType)3, 5f }, { (SkillType)4, 5f }, { (SkillType)8, 5f }, { (SkillType)5, 5f }, { (SkillType)11, 5f }, { (SkillType)10, 5f }, { (SkillType)9, 5f } }; private static bool IsLocalPlayer(Player player) { return (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer; } private static bool TryGetPlayer(Character character, out Player player) { player = (Player)(object)((character is Player) ? character : null); return (Object)(object)player != (Object)null; } private static bool TryGetShared(ItemData item, out SharedData shared) { shared = null; if (item == null || item.m_shared == null) { return false; } shared = item.m_shared; return true; } private static float SanitizeFloat(float value, float fallback) { return (float.IsNaN(value) || float.IsInfinity(value)) ? fallback : value; } private static float GetSecondaryAdrenalineCost(ItemData weapon) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (weapon == null || weapon.m_shared == null) { return 10f; } if (!SpecialCosts.TryGetValue(weapon.m_shared.m_skillType, out var value)) { value = 10f; } if (weapon.IsTwoHanded()) { value *= 2f; } if (float.IsNaN(value) || float.IsInfinity(value) || value < 0f) { return 10f; } return value; } [HarmonyPostfix] [HarmonyPatch(typeof(Attack), "Start")] private static void Attack_Start_SecondaryAdrenalineCost(Attack __instance) { if (__instance != null && !((Object)(object)__instance.m_character == (Object)null) && TryGetPlayer((Character)(object)__instance.m_character, out var player) && IsLocalPlayer(player)) { ItemData val = __instance.m_weapon ?? ((Humanoid)player).GetCurrentWeapon(); if (TryGetShared(val, out var _) && ((Humanoid)player).m_currentAttackIsSecondary) { float num = SanitizeFloat(player.GetAdrenaline(), 0f); float secondaryAdrenalineCost = GetSecondaryAdrenalineCost(val); player.m_adrenaline = Mathf.Max(0f, num - secondaryAdrenalineCost); } } } } [HarmonyPatch] internal static class ObjectDBBattleFlowPatch { [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class ObjectDB_Awake_Patch { private static bool _awakeInitialized; public static void Postfix() { if (IsObjectDBValid()) { if (_awakeInitialized) { Debug.Log((object)"[BALROND BATTLE FLOW] ObjectDB Awake already processed — skipping duplicate setup."); return; } InitializeObjectDB(fullInit: true); _awakeInitialized = true; } } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] public static class ObjectDB_CopyOtherDB_Patch { private static bool _copyInitialized; public static void Postfix() { if (IsObjectDBValid()) { if (_copyInitialized) { Debug.Log((object)"[BALROND BATTLE FLOW] CopyOtherDB already processed — skipping duplicate setup."); return; } InitializeObjectDB(fullInit: false); _copyInitialized = true; } } } private static bool IsObjectDBValid() { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { return false; } if (instance.m_items == null || instance.m_items.Count == 0) { return false; } if (instance.m_recipes == null || instance.m_recipes.Count == 0) { return false; } if (instance.m_StatusEffects == null) { return false; } GameObject itemPrefab = instance.GetItemPrefab(BalrondHashCompat.StableHash("Amber")); if ((Object)(object)itemPrefab == (Object)null) { itemPrefab = instance.GetItemPrefab("Amber"); } if ((Object)(object)itemPrefab == (Object)null) { return false; } return true; } private static void InitializeObjectDB(bool fullInit) { Debug.Log((object)("[BALROND BATTLE FLOW] ObjectDB setup started. fullInit=" + fullInit)); MinorAdrenEffectsBootstrap.Install(); AdrenalineOverchargeEffectsBootstrap.Install(); TrinketStatusService.Initialize(); Debug.Log((object)("[BALROND BATTLE FLOW] ObjectDB setup complete. fullInit=" + fullInit)); } } [HarmonyPatch] internal static class TranslationPatches { [HarmonyPatch(typeof(FejdStartup), "SetupGui")] private class FejdStartup_SetupGUI { private static void Postfix() { string selectedLanguage = Localization.instance.GetSelectedLanguage(); Dictionary<string, string> translations = GetTranslations(selectedLanguage); AddTranslations(translations); } } [HarmonyPriority(800)] [HarmonyPatch(typeof(Localization), "SetupLanguage")] private class Translation_SetupLanguage { private static void Prefix(Localization __instance, string language) { Dictionary<string, string> translations = GetTranslations(language); AddTranslations(translations, __instance); } } [HarmonyPriority(800)] [HarmonyPatch(typeof(Localization), "LoadCSV")] private class Translation_LoadCSV { private static void Prefix(Localization __instance, string language) { Dictionary<string, string> translations = GetTranslations(language); AddTranslations(translations, __instance); } } private static Dictionary<string, string> GetTranslations(string language) { Dictionary<string, string> result = BalrondTranslator.getLanguage("English"); if (!string.Equals(language, "English", StringComparison.OrdinalIgnoreCase)) { Dictionary<string, string> language2 = BalrondTranslator.getLanguage(language); if (language2 != null) { result = language2; } else { Debug.Log((object)("BalrondBattleFlow: Did not find translation file for '" + language + "', loading English")); } } return result; } private static void AddTranslations(Dictionary<string, string> translations, Localization localizationInstance = null) { if (translations == null) { Debug.LogWarning((object)"BalrondBattleFlow: No translation file found!"); return; } if (localizationInstance != null) { foreach (KeyValuePair<string, string> translation in translations) { localizationInstance.AddWord(translation.Key, translation.Value); } return; } foreach (KeyValuePair<string, string> translation2 in translations) { Localization.instance.AddWord(translation2.Key, translation2.Value); } } } public enum TrinketScalingMode { PassiveScaling } public class SE_Stats_Scaling_Bal : SE_Stats { [Header("__Balrond Trinket Scaling__")] public TrinketScalingMode m_balMode = TrinketScalingMode.PassiveScaling; public float m_balMinAdrenaline = 0f; public float m_balMaxAdrenaline = 100f; public bool m_balShowCurrentBonus = true; public bool m_balShowScalingStats = true; private Player GetPlayer() { Character character = ((StatusEffect)this).m_character; Player val = (Player)(object)((character is Player) ? character : null); return ((Object)(object)val != (Object)null) ? val : Player.m_localPlayer; } private float GetCurrentAdrenaline() { Player player = GetPlayer(); return ((Object)(object)player != (Object)null) ? player.GetAdrenaline() : 0f; } private float GetMaxAdrenaline() { Player player = GetPlayer(); if ((Object)(object)player == (Object)null) { return 100f; } float maxAdrenaline = ((Character)player).GetMaxAdrenaline(); return (maxAdrenaline > 0f) ? maxAdrenaline : 100f; } private float GetScale() { float num = m_balMaxAdrenaline - m_balMinAdrenaline; if (Math.Abs(num) < 0.001f) { return (GetCurrentAdrenaline() >= m_balMaxAdrenaline) ? 1f : 0f; } return Mathf.Clamp01((GetCurrentAdrenaline() - m_balMinAdrenaline) / num); } private static float Round2(float value) { return Mathf.Round(value * 100f) / 100f; } private static string F(float value) { return Round2(value).ToString("0.##"); } private static string SignedF(float value) { value = Round2(value); if (value > 0f) { return "+" + value.ToString("0.##"); } return value.ToString("0.##"); } private static string SignedPercent(float value) { return SignedF(value) + "%"; } private static string L(string keyOrText) { if (string.IsNullOrEmpty(keyOrText)) { return ""; } if (!keyOrText.StartsWith("$")) { return keyOrText; } if (Localization.instance == null) { return keyOrText; } return Localization.instance.Localize(keyOrText); } private static string LocalizedLabel(string label) { switch (label) { case "Health regen": return L("$tag_battleflow_stat_health_regen"); case "Stamina regen": return L("$tag_battleflow_stat_stamina_regen"); case "Eitr regen": return L("$tag_battleflow_stat_eitr_regen"); case "Armor": return L("$tag_battleflow_stat_armor"); case "Movement speed": return L("$tag_battleflow_stat_movement_speed"); case "Swim speed": return L("$tag_battleflow_stat_swim_speed"); case "Run stamina drain": return L("$tag_battleflow_stat_run_stamina_drain"); case "Jump stamina use": return L("$tag_battleflow_stat_jump_stamina_use"); case "Attack stamina use": return L("$tag_battleflow_stat_attack_stamina_use"); case "Block stamina use": return L("$tag_battleflow_stat_block_stamina_use"); case "Dodge stamina use": return L("$tag_battleflow_stat_dodge_stamina_use"); case "Swim stamina use": return L("$tag_battleflow_stat_swim_stamina_use"); case "Home item stamina use": return L("$tag_battleflow_stat_home_item_stamina_use"); case "Sneak stamina use": return L("$tag_battleflow_stat_sneak_stamina_use"); case "Timed block bonus": return L("$tag_battleflow_stat_timed_block_bonus"); case "Adrenaline gain": return L("$tag_battleflow_stat_adrenaline_gain"); case "Stagger": return L("$tag_battleflow_stat_stagger"); case "Carry weight": return L("$tag_battleflow_stat_carry_weight"); case "Fall damage": return L("$tag_battleflow_stat_fall_damage"); case "Noise": return L("$tag_battleflow_stat_noise"); case "Stealth": return L("$tag_battleflow_stat_stealth"); case "Blunt damage": return L("$tag_battleflow_stat_blunt_damage"); case "Slash damage": return L("$tag_battleflow_stat_slash_damage"); case "Pierce damage": return L("$tag_battleflow_stat_pierce_damage"); case "Chop damage": return L("$tag_battleflow_stat_chop_damage"); case "Pickaxe damage": return L("$tag_battleflow_stat_pickaxe_damage"); case "Fire damage": return L("$tag_battleflow_stat_fire_damage"); case "Frost damage": return L("$tag_battleflow_stat_frost_damage"); case "Lightning damage": return L("$tag_battleflow_stat_lightning_damage"); case "Poison damage": return L("$tag_battleflow_stat_poison_damage"); case "Spirit damage": return L("$tag_battleflow_stat_spirit_damage"); default: if (label.StartsWith("Skill gain ")) { return L("$tag_battleflow_stat_skill_gain") + " " + label.Substring("Skill gain ".Length); } if (label.StartsWith("Skill ")) { return L("$tag_battleflow_stat_skill") + " " + label.Substring("Skill ".Length); } if (label.StartsWith("Damage ")) { return L("$tag_battleflow_stat_damage") + " " + label.Substring("Damage ".Length); } return label; } } private float ScaleFloat(float value) { return Round2(value * GetScale()); } private float ScaleMultiplier(float multiplier) { return Round2(Mathf.Lerp(1f, multiplier, GetScale())); } private void ApplyRegenMultiplier(ref float value, float targetMultiplier) { float num = ScaleMultiplier(targetMultiplier); if (num > 1f) { value += num - 1f; } else { value *= num; } value = Round2(value); } public override void ModifyHealthRegen(ref float regenMultiplier) { if (base.m_healthRegenMultiplier != 1f) { ApplyRegenMultiplier(ref regenMultiplier, base.m_healthRegenMultiplier); } } public override void ModifyStaminaRegen(ref float staminaRegen) { if (base.m_staminaRegenMultiplier != 1f) { ApplyRegenMultiplier(ref staminaRegen, base.m_staminaRegenMultiplier); } } public override void ModifyEitrRegen(ref float eitrRegen) { if (base.m_eitrRegenMultiplier != 1f) { ApplyRegenMultiplier(ref eitrRegen, base.m_eitrRegenMultiplier); } } public override void ModifyArmorMods(ref float armor) { if (base.m_addArmor != 0f) { armor += ScaleFloat(base.m_addArmor); } if (base.m_armorMultiplier != 0f) { armor *= 1f + ScaleFloat(base.m_armorMultiplier); } armor = Round2(armor); } public override void ModifySpeed(float baseSpeed, ref float speed, Character character, Vector3 dir) { float scale = GetScale(); if (base.m_speedModifier != 0f) { speed += baseSpeed * Round2(base.m_speedModifier * scale); } if (base.m_swimSpeedModifier != 0f && (Object)(object)character != (Object)null && character.IsSwimming()) { speed += baseSpeed * Round2(base.m_swimSpeedModifier * scale); } if (speed < 0f) { speed = 0f; } speed = Round2(speed); } public override void ModifyRunStaminaDrain(float baseDrain, ref float drain, Vector3 dir) { if (base.m_runStaminaDrainModifier != 0f) { drain += baseDrain * ScaleFloat(base.m_runStaminaDrainModifier); drain = Round2(drain); } } public override void ModifyJumpStaminaUsage(float baseStaminaUse, ref float staminaUse) { if (base.m_jumpStaminaUseModifier != 0f) { staminaUse += baseStaminaUse * ScaleFloat(base.m_jumpStaminaUseModifier); staminaUse = Round2(staminaUse); } } public override void ModifyAttackStaminaUsage(float baseStaminaUse, ref float staminaUse) { if (base.m_attackStaminaUseModifier != 0f) { staminaUse += baseStaminaUse * ScaleFloat(base.m_attackStaminaUseModifier); staminaUse = Round2(staminaUse); } } public override void ModifyBlockStaminaUsage(float baseStaminaUse, ref float staminaUse) { if (base.m_blockStaminaUseModifier != 0f) { staminaUse += baseStaminaUse * ScaleFloat(base.m_blockStaminaUseModifier); } if (base.m_blockStaminaUseFlatValue != 0f) { staminaUse += ScaleFloat(base.m_blockStaminaUseFlatValue); } staminaUse = Round2(staminaUse); } public override void ModifyDodgeStaminaUsage(float baseStaminaUse, ref float staminaUse) { if (base.m_dodgeStaminaUseModifier != 0f) { staminaUse += baseStaminaUse * ScaleFloat(base.m_dodgeStaminaUseModifier); staminaUse = Round2(staminaUse); } } public override void ModifySwimStaminaUsage(float baseStaminaUse, ref float staminaUse) { if (base.m_swimStaminaUseModifier != 0f) { staminaUse += baseStaminaUse * ScaleFloat(base.m_swimStaminaUseModifier); staminaUse = Round2(staminaUse); } } public override void ModifyHomeItemStaminaUsage(float baseStaminaUse, ref float staminaUse) { if (base.m_homeItemStaminaUseModifier != 0f) { staminaUse += baseStaminaUse * ScaleFloat(base.m_homeItemStaminaUseModifier); staminaUse = Round2(staminaUse); } } public override void ModifySneakStaminaUsage(float baseStaminaUse, ref float staminaUse) { if (base.m_sneakStaminaUseModifier != 0f) { staminaUse += baseStaminaUse * ScaleFloat(base.m_sneakStaminaUseModifier); staminaUse = Round2(staminaUse); } } public override void ModifyTimedBlockBonus(ref float timedBlockBonus) { if (base.m_timedBlockBonus != 0f) { timedBlockBonus *= 1f + ScaleFloat(base.m_timedBlockBonus); timedBlockBonus = Round2(timedBlockBonus); } } public override void ModifyAdrenaline(float baseValue, ref float use) { if (base.m_adrenalineModifier != 0f) { use += baseValue * ScaleFloat(base.m_adrenalineModifier); use = Round2(use); } } public override void ModifyStagger(float baseValue, ref float use) { if (base.m_staggerModifier != 0f) { use += baseValue * ScaleFloat(base.m_staggerModifier); use = Round2(use); } } public override void ModifyRaiseSkill(SkillType skill, ref float value) { //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_0014: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if ((int)base.m_raiseSkill != 0 && ((int)base.m_raiseSkill == 999 || base.m_raiseSkill == skill)) { value += ScaleFloat(base.m_raiseSkillModifier); value = Round2(value); } } public override void ModifySkillLevel(SkillType skill, ref float value) { //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_0014: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Invalid comparison between Unknown and I4 //IL_0052: 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) if ((int)base.m_skillLevel != 0 && ((int)base.m_skillLevel == 999 || base.m_skillLevel == skill)) { value += ScaleFloat(base.m_skillLevelModifier); } if ((int)base.m_skillLevel2 != 0 && ((int)base.m_skillLevel2 == 999 || base.m_skillLevel2 == skill)) { value += ScaleFloat(base.m_skillLevelModifier2); } value = Round2(value); } public override void ModifyJump(Vector3 baseJump, ref Vector3 jump) { //IL_0009: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) float scale = GetScale(); if (base.m_jumpModifier != Vector3.zero) { jump += new Vector3(baseJump.x * Round2(base.m_jumpModifier.x * scale), baseJump.y * Round2(base.m_jumpModifier.y * scale), baseJump.z * Round2(base.m_jumpModifier.z * scale)); } } public override void ModifyFallDamage(float baseDamage, ref float damage) { if (base.m_fallDamageModifier != 0f) { damage += baseDamage * ScaleFloat(base.m_fallDamageModifier); } if (damage < 0f) { damage = 0f; } damage = Round2(damage); } public override void ModifyMaxCarryWeight(float baseLimit, ref float limit) { if (base.m_addMaxCarryWeight != 0f) { limit += ScaleFloat(base.m_addMaxCarryWeight); } if (limit < 0f) { limit = 0f; } limit = Round2(limit); } public override void ModifyNoise(float baseNoise, ref float noise) { if (base.m_noiseModifier != 0f) { noise += baseNoise * ScaleFloat(base.m_noiseModifier); noise = Round2(noise); } } public override void ModifyStealth(float baseStealth, ref float stealth) { if (base.m_stealthModifier != 0f) { stealth += baseStealth * ScaleFloat(base.m_stealthModifier); stealth = Round2(stealth); } } public override void ModifyAttack(SkillType skill, ref HitData hitData) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_002d: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) if (hitData != null) { float scale = GetScale(); if ((int)base.m_modifyAttackSkill != 0 && ((int)base.m_modifyAttackSkill == 999 || base.m_modifyAttackSkill == skill)) { ((DamageTypes)(ref hitData.m_damage)).Modify(Round2(Mathf.Lerp(1f, base.m_damageModifier, scale))); } if (!IsEmptyDamageTypes(base.m_percentigeDamageModifiers)) { DamageTypes percentigeDamageModifiers = base.m_percentigeDamageModifiers; percentigeDamageModifiers.m_blunt = Round2(percentigeDamageModifiers.m_blunt * scale); percentigeDamageModifiers.m_slash = Round2(percentigeDamageModifiers.m_slash * scale); percentigeDamageModifiers.m_pierce = Round2(percentigeDamageModifiers.m_pierce * scale); percentigeDamageModifiers.m_chop = Round2(percentigeDamageModifiers.m_chop * scale); percentigeDamageModifiers.m_pickaxe = Round2(percentigeDamageModifiers.m_pickaxe * scale); percentigeDamageModifiers.m_fire = Round2(percentigeDamageModifiers.m_fire * scale); percentigeDamageModifiers.m_frost = Round2(percentigeDamageModifiers.m_frost * scale); percentigeDamageModifiers.m_lightning = Round2(percentigeDamageModifiers.m_lightning * scale); percentigeDamageModifiers.m_poison = Round2(percentigeDamageModifiers.m_poison * scale); percentigeDamageModifiers.m_spirit = Round2(percentigeDamageModifiers.m_spirit * scale); ((DamageTypes)(ref hitData.m_damage)).Modify(percentigeDamageModifiers); } } } private static bool IsEmptyDamageTypes(DamageTypes damage) { //IL_0001: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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) //IL_0042: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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) return damage.m_blunt == 0f && damage.m_slash == 0f && damage.m_pierce == 0f && damage.m_chop == 0f && damage.m_pickaxe == 0f && damage.m_fire == 0f && damage.m_frost == 0f && damage.m_lightning == 0f && damage.m_poison == 0f && damage.m_spirit == 0f; } public override void ModifyDamageMods(ref DamageModifiers modifiers) { } public override string GetTooltipString() { StringBuilder stringBuilder = new StringBuilder(1024); if (!string.IsNullOrEmpty(((StatusEffect)this).m_tooltip)) { stringBuilder.Append(L(((StatusEffect)this).m_tooltip)); stringBuilder.Append("\n\n"); } stringBuilder.Append("<color=orange>"); stringBuilder.Append(L("$tag_battleflow_scaling_header")); stringBuilder.Append("</color>\n"); stringBuilder.Append(L("$tag_battleflow_scaling_description")); stringBuilder.Append("\n"); if (m_balShowCurrentBonus) { float currentAdrenaline = GetCurrentAdrenaline(); float maxAdrenaline = GetMaxAdrenaline(); float value = GetScale() * 100f; stringBuilder.Append(L("$tag_battleflow_current_adrenaline")); stringBuilder.Append(": <color=orange>"); stringBuilder.Append(F(currentAdrenaline)); stringBuilder.Append("/"); stringBuilder.Append(F(maxAdrenaline)); stringBuilder.Append("</color>\n"); stringBuilder.Append(L("$tag_battleflow_current_power")); stringBuilder.Append(": <color=orange>"); stringBuilder.Append(F(value)); stringBuilder.Append("%</color>\n"); } if (m_balShowScalingStats) { stringBuilder.Append("\n"); AppendScalingStats(stringBuilder); } return stringBuilder.ToString(); } private void AppendScalingStats(StringBuilder sb) { //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Invalid comparison between Unknown and I4 //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Invalid comparison between Unknown and I4 //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Invalid comparison between Unknown and I4 //IL_02da: Unknown result type (might be due to invalid IL or missing references) AppendPercentCurrentRangeIfNotDefault(sb, "Health regen", base.m_healthRegenMultiplier, 1f); AppendPercentCurrentRangeIfNotDefault(sb, "Stamina regen", base.m_staminaRegenMultiplier, 1f); AppendPercentCurrentRangeIfNotDefault(sb, "Eitr regen", base.m_eitrRegenMultiplier, 1f); AppendFlatCurrentRangeIfNotZero(sb, "Armor", base.m_addArmor); AppendPercentCurrentRangeIfNotZero(sb, "Armor", base.m_armorMultiplier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Movement speed", base.m_speedModifier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Swim speed", base.m_swimSpeedModifier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Run stamina drain", base.m_runStaminaDrainModifier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Jump stamina use", base.m_jumpStaminaUseModifier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Attack stamina use", base.m_attackStaminaUseModifier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Block stamina use", base.m_blockStaminaUseModifier * 100f); AppendFlatCurrentRangeIfNotZero(sb, "Block stamina use", base.m_blockStaminaUseFlatValue); AppendPercentCurrentRangeIfNotZero(sb, "Dodge stamina use", base.m_dodgeStaminaUseModifier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Swim stamina use", base.m_swimStaminaUseModifier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Home item stamina use", base.m_homeItemStaminaUseModifier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Sneak stamina use", base.m_sneakStaminaUseModifier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Timed block bonus", base.m_timedBlockBonus * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Adrenaline gain", base.m_adrenalineModifier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Stagger", base.m_staggerModifier * 100f); AppendFlatCurrentRangeIfNotZero(sb, "Carry weight", base.m_addMaxCarryWeight); AppendPercentCurrentRangeIfNotZero(sb, "Fall damage", base.m_fallDamageModifier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Noise", base.m_noiseModifier * 100f); AppendPercentCurrentRangeIfNotZero(sb, "Stealth", base.m_stealthModifier * 100f); if ((int)base.m_skillLevel > 0) { AppendFlatCurrentRangeIfNotZero(sb, "Skill " + ((object)Unsafe.As<SkillType, SkillType>(ref base.m_skillLevel)/*cast due to .constrained prefix*/).ToString(), base.m_skillLevelModifier); } if ((int)base.m_skillLevel2 > 0) { AppendFlatCurrentRangeIfNotZero(sb, "Skill " + ((object)Unsafe.As<SkillType, SkillType>(ref base.m_skillLevel2)/*cast due to .constrained prefix*/).ToString(), base.m_skillLevelModifier2); } if ((int)base.m_raiseSkill > 0) { AppendPercentCurrentRangeIfNotZero(sb, "Skill gain " + ((object)Unsafe.As<SkillType, SkillType>(ref base.m_raiseSkill)/*cast due to .constrained prefix*/).ToString(), base.m_raiseSkillModifier * 100f); } if ((int)base.m_modifyAttackSkill != 0 && base.m_damageModifier != 1f) { AppendPercentCurrentRangeIfNotZero(sb, "Damage " + ((object)Unsafe.As<SkillType, SkillType>(ref base.m_modifyAttackSkill)/*cast due to .constrained prefix*/).ToString(), (base.m_damageModifier - 1f) * 100f); } AppendDamageTypeRange(sb, "Blunt damage", base.m_percentigeDamageModifiers.m_blunt); AppendDamageTypeRange(sb, "Slash damage", base.m_percentigeDamageModifiers.m_slash); AppendDamageTypeRange(sb, "Pierce damage", base.m_percentigeDamageModifiers.m_pierce); AppendDamageTypeRange(sb, "Chop damage", base.m_percentigeDamageModifiers.m_chop); AppendDamageTypeRange(sb, "Pickaxe damage", base.m_percentigeDamageModifiers.m_pickaxe); AppendDamageTypeRange(sb, "Fire damage", base.m_percentigeDamageModifiers.m_fire); AppendDamageTypeRange(sb, "Frost damage", base.m_percentigeDamageModifiers.m_frost); AppendDamageTypeRange(sb, "Lightning damage", base.m_percentigeDamageModifiers.m_lightning); AppendDamageTypeRange(sb, "Poison damage", base.m_percentigeDamageModifiers.m_poison); AppendDamageTypeRange(sb, "Spirit damage", base.m_percentigeDamageModifiers.m_spirit); } private void AppendDamageTypeRange(StringBuilder sb, string label, float value) { if (value != 0f) { AppendPercentCurrentRangeIfNotZero(sb, label, value * 100f); } } private void AppendPercentCurrentRangeIfNotDefault(StringBuilder sb, string label, float multiplier, float defaultValue) { if (multiplier != defaultValue) { AppendPercentCurrentRangeIfNotZero(sb, label, (multiplier - defaultValue) * 100f); } } private void AppendFlatCurrentRangeIfNotZero(StringBuilder sb, string label, float max) { if (max != 0f) { float value = Round2(max * GetScale()); sb.Append(LocalizedLabel(label)); sb.Append(": <color=orange>"); sb.Append(SignedF(value)); sb.Append(" / "); sb.Append(SignedF(max)); sb.Append("</color>\n"); } } private void AppendPercentCurrentRangeIfNotZero(StringBuilder sb, string label, float maxPercent) { if (maxPercent != 0f) { float value = Round2(maxPercent * GetScale()); sb.Append(LocalizedLabel(label)); sb.Append(": <color=orange>"); sb.Append(SignedPercent(value)); sb.Append(" / "); sb.Append(SignedPercent(maxPercent)); sb.Append("</color>\n"); } } } public enum TrinketEffectSlot { EquipStatusEffect } public enum TrinketStatusBuildMode { CopyExistingSanitized, BuildFromDefinition } public sealed class TrinketStatusDefinition { public string ItemPrefab = ""; public string SourceStatusName = ""; public string NewStatusName = ""; public string DisplayName = ""; public string Tooltip = ""; public TrinketStatusBuildMode BuildMode = TrinketStatusBuildMode.BuildFromDefinition; public TrinketEffectSlot Slot = TrinketEffectSlot.EquipStatusEffect; public float MinAdrenaline = 0f; public float MaxAdrenaline = 100f; public bool ClearItemAdrenalineFields = true; public bool ClearFullAdrenalineStatus = true; public bool ClearCopiedResistances = true; public bool ClearCopiedUpFrontValues = true; public float HealthRegenMultiplier = 1f; public float StaminaRegenMultiplier = 1f; public float EitrRegenMultiplier = 1f; public float AddArmor = 0f; public float ArmorMultiplier = 0f; public float SpeedModifier = 0f; public float SwimSpeedModifier = 0f; public float SwimStaminaUseModifier = 0f; public float DodgeStaminaUseModifier = 0f; public float RunStaminaDrainModifier = 0f; public float JumpStaminaUseModifier = 0f; public float AttackStaminaUseModifier = 0f; public float BlockStaminaUseModifier = 0f; public float BlockStaminaUseFlatValue = 0f; public float HomeItemStaminaUseModifier = 0f; public float SneakStaminaUseModifier = 0f; public float RunStaminaUseModifier = 0f; public float TimedBlockBonus = 0f; public float AdrenalineModifier = 0f; public float StaggerModifier = 0f; public float AddMaxCarryWeight = 0f; public float FallDamageModifier = 0f; public Vector3 JumpModifier = Vector3.zero; public SkillType RaiseSkill = (SkillType)0; public float RaiseSkillModifier = 0f; public SkillType SkillLevel = (SkillType)0; public float SkillLevelModifier = 0f; public SkillType SkillLevel2 = (SkillType)0; public float SkillLevelModifier2 = 0f; public SkillType ModifyAttackSkill = (SkillType)0; public float DamageModifier = 1f; public DamageTypes PercentageDamageModifiers = default(DamageTypes); } public static class TrinketStatusRegistry { private static readonly List<TrinketStatusDefinition> _definitions = new List<TrinketStatusDefinition>(); private static bool _built; public static List<TrinketStatusDefinition> GetDefinitions() { EnsureBuilt(); return _definitions; } public static void Rebuild() { _built = false; _definitions.Clear(); EnsureBuilt(); } private static void EnsureBuilt() { if (!_built) { _definitions.Clear(); RegisterDefinitions(GetVanillaReworks()); RegisterDefinitions(GetCustomTrinkets()); _built = true; } } private static void RegisterDefinitions(IEnumerable<TrinketStatusDefinition> definitions) { foreach (TrinketStatusDefinition definition in definitions) { Register(definition); } } private static void Register(TrinketStatusDefinition definition) { if (definition != null && !string.IsNullOrEmpty(definition.ItemPrefab) && !string.IsNullOrEmpty(definition.NewStatusName)) { ForceTrinketDefaults(definition); _definitions.Add(definition); } } private static void ForceTrinketDefaults(TrinketStatusDefinition definition) { definition.BuildMode = TrinketStatusBuildMode.BuildFromDefinition; definition.Slot = TrinketEffectSlot.EquipStatusEffect; definition.MinAdrenaline = 0f; definition.MaxAdrenaline = 100f; definition.ClearItemAdrenalineFields = true; definition.ClearFullAdrenalineStatus = true; definition.ClearCopiedResistances = true; definition.ClearCopiedUpFrontValues = true; if (string.IsNullOrEmpty(definition.DisplayName)) { definition.DisplayName = "$tag_" + definition.NewStatusName + "_name_bal"; } if (string.IsNullOrEmpty(definition.Tooltip)) { definition.Tooltip = "$tag_" + definition.NewStatusName + "_tooltip_bal"; } } private static TrinketStatusDefinition BuildNew(string itemPrefab, string newStatusName) { TrinketStatusDefinition trinketStatusDefinition = new TrinketStatusDefinition { ItemPrefab = itemPrefab, NewStatusName = newStatusName, DisplayName = "$tag_" + newStatusName + "_name_bal", Tooltip = "$tag_" + newStatusName + "_tooltip_bal", BuildMode = TrinketStatusBuildMode.BuildFromDefinition }; ForceTrinketDefaults(trinketStatusDefinition); return trinketStatusDefinition; } private static DamageTypes Damage(float blunt = 0f, float slash = 0f, float pierce = 0f, float chop = 0f, float pickaxe = 0f, float fire = 0f, float frost = 0f, float lightning = 0f, float poison = 0f, float spirit = 0f) { //IL_0003: 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_0060: 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) return new DamageTypes { m_blunt = blunt, m_slash = slash, m_pierce = pierce, m_chop = chop, m_pickaxe = pickaxe, m_fire = fire, m_frost = frost, m_lightning = lightning, m_poison = poison, m_spirit = spirit }; } private static IEnumerable<TrinketStatusDefinition> GetVanillaReworks() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: 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_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) TrinketStatusDefinition trinketStatusDefinition = BuildNew("TrinketBronzeHealth", "SE_TrinketBronzeHealth_SCALING"); trinketStatusDefinition.HealthRegenMultiplier = 1.1f; TrinketStatusDefinition trinketStatusDefinition2 = BuildNew("TrinketBronzeStamina", "SE_TrinketBronzeStamina_SCALING"); trinketStatusDefinition2.StaminaRegenMultiplier = 1.1f; TrinketStatusDefinition trinketStatusDefinition3 = BuildNew("TrinketIronHealth", "SE_TrinketIronHealth_SCALING"); trinketStatusDefinition3.AddArmor = 10f; trinketStatusDefinition3.HealthRegenMultiplier = 1.05f; TrinketStatusDefinition trinketStatusDefinition4 = BuildNew("TrinketIronStamina", "SE_TrinketIronStamina_SCALING"); trinketStatusDefinition4.SpeedModifier = 0.05f; trinketStatusDefinition4.RunStaminaDrainModifier = -0.1f; TrinketStatusDefinition trinketStatusDefinition5 = BuildNew("TrinketChitinSwim", "SE_TrinketChitinSwim_SCALING"); trinketStatusDefinition5.SwimSpeedModifier = 0.5f; trinketStatusDefinition5.SwimStaminaUseModifier = -0.5f; TrinketStatusDefinition trinketStatusDefinition6 = BuildNew("TrinketSilverDamage", "SE_TrinketSilverDamage_SCALING"); trinketStatusDefinition6.SkillLevel = (SkillType)8; trinketStatusDefinition6.SkillLevelModifier = 10f; trinketStatusDefinition6.SkillLevel2 = (SkillType)5; trinketStatusDefinition6.SkillLevelModifier2 = 10f; trinketStatusDefinition6.PercentageDamageModifiers = Damage(0f, 0f, 0.05f); TrinketStatusDefinition trinketStatusDefinition7 = BuildNew("TrinketSilverResist", "SE_TrinketSilverResist_SCALING"); trinketStatusDefinition7.AddArmor = 10f; trinketStatusDefinition7.BlockStaminaUseModifier = -0.05f; trinketStatusDefinition7.TimedBlockBonus = 0.05f; TrinketStatusDefinition trinketStatusDefinition8 = BuildNew("TrinketBlackDamageHealth", "SE_TrinketBlackDamageHealth_SCALING"); trinketStatusDefinition8.SkillLevel = (SkillType)3; trinketStatusDefinition8.SkillLevelModifier = 10f; trinketStatusDefinition8.PercentageDamageModifiers = Damage(0.05f); trinketStatusDefinition8.HealthRegenMultiplier = 1.05f; TrinketStatusDefinition trinketStatusDefinition9 = BuildNew("TrinketBlackStamina", "SE_TrinketBlackStamina_SCALING"); trinketStatusDefinition9.BlockStaminaUseModifier = -0.15f; trinketStatusDefinition9.DodgeStaminaUseModifier = -0.15f; trinketStatusDefinition9.TimedBlockBonus = 0.15f; TrinketStatusDefinition trinketStatusDefinition10 = BuildNew("TrinketCarapaceEitr", "SE_TrinketCarapaceEitr_SCALING"); trinketStatusDefinition10.EitrRegenMultiplier = 1.1f; trinketStatusDefinition10.HealthRegenMultiplier = 1.1f; TrinketStatusDefinition trinketStatusDefinition11 = BuildNew("TrinketScaleStaminaDamage", "SE_TrinketScaleStaminaDamage_SCALING"); trinketStatusDefinition11.StaminaRegenMultiplier = 1.1f; trinketStatusDefinition11.AttackStaminaUseModifier = -0.1f; trinketStatusDefinition11.PercentageDamageModifiers = Damage(0f, 0.05f); TrinketStatusDefinition trinketStatusDefinition12 = BuildNew("TrinketFlametalEitr", "SE_TrinketFlametalEitr_SCALING"); trinketStatusDefinition12.EitrRegenMultiplier = 1.1f; trinketStatusDefinition12.SkillLevel = (SkillType)9; trinketStatusDefinition12.SkillLevelModifier = 10f; trinketStatusDefinition12.SkillLevel2 = (SkillType)10; trinketStatusDefinition12.SkillLevelModifier2 = 10f; TrinketStatusDefinition trinketStatusDefinition13 = BuildNew("TrinketFlametalStaminaHealth", "SE_TrinketFlametalStaminaHealth_SCALING"); trinketStatusDefinition13.HealthRegenMultiplier = 1.1f; trinketStatusDefinition13.StaminaRegenMultiplier = 1.1f; trinketStatusDefinition13.AddArmor = 10f; return new TrinketStatusDefinition[13] { trinketStatusDefinition, trinketStatusDefinition2, trinketStatusDefinition3, trinketStatusDefinition4, trinketStatusDefinition5, trinketStatusDefinition6, trinketStatusDefinition7, trinketStatusDefinition8, trinketStatusDefinition9, trinketStatusDefinition10, trinketStatusDefinition11, trinketStatusDefinition12, trinketStatusDefinition13 }; } private static IEnumerable<TrinketStatusDefinition> GetCustomTrinkets() { TrinketStatusDefinition trinketStatusDefinition = BuildNew("TrinketEmeraldCore_bal", "SE_TrinketEmeraldCore_bal_SCALING"); trinketStatusDefinition.HealthRegenMultiplier = 1.04f; trinketStatusDefinition.EitrRegenMultiplier = 1.1f; trinketStatusDefinition.AddArmor = 4f; trinketStatusDefinition.SpeedModifier = 0.02f; trinketStatusDefinition.DodgeStaminaUseModifier = -0.04f; trinketStatusDefinition.RunStaminaDrainModifier = -0.04f; trinketStatusDefinition.AttackStaminaUseModifier = -0.04f; return new TrinketStatusDefinition[1] { trinketStatusDefinition }; } } public static class TrinketStatusService { private static bool _initialized; public static void Initialize() { if (_initialized) { return; } if ((Object)(object)ObjectDB.instance == (Object)null) { Debug.LogWarning((object)"BalrondBattleFlow: TrinketStatusService skipped - ObjectDB is null"); return; } List<TrinketStatusDefinition> definitions = TrinketStatusRegistry.GetDefinitions(); int num = 0; for (int i = 0; i < definitions.Count; i++) { if (ApplyDefinition(definitions[i])) { num++; } } _initialized = true; Debug.Log((object)("BalrondBattleFlow: TrinketStatusService initialized. Applied statuses: " + num + "/" + definitions.Count)); } public static void Reset() { _initialized = false; TrinketStatusRegistry.Rebuild(); } private static bool ApplyDefinition(TrinketStatusDefinition def) { if (def == null) { return false; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(def.ItemPrefab); if ((Object)(object)itemPrefab == (Object)null) { itemPrefab = ObjectDB.instance.GetItemPrefab(BalrondHashCompat.StableHash(def.ItemPrefab)); } if ((Object)(object)itemPrefab == (Object)null) { Debug.LogWarning((object)("BalrondBattleFlow: Trinket item prefab not found - " + def.ItemPrefab)); return false; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || component.m_itemData.m_shared == null) { Debug.LogWarning((object)("BalrondBattleFlow: ItemDrop/shared missing on trinket - " + def.ItemPrefab)); return false; } SE_Stats_Scaling_Bal sE_Stats_Scaling_Bal = CreateStatus(def, component); if ((Object)(object)sE_Stats_Scaling_Bal == (Object)null) { Debug.LogWarning((object)("BalrondBattleFlow: Failed to create status for " + def.ItemPrefab)); return false; } RegisterStatusEffect((StatusEffect)(object)sE_Stats_Scaling_Bal); AssignStatusToItem(def, component, (StatusEffect)(object)sE_Stats_Scaling_Bal); Debug.Log((object)("BalrondBattleFlow: Applied " + ((Object)sE_Stats_Scaling_Bal).name + " to " + def.ItemPrefab)); return true; } private static SE_Stats_Scaling_Bal CreateStatus(TrinketStatusDefinition def, ItemDrop itemDrop) { SE_Stats_Scaling_Bal sE_Stats_Scaling_Bal = ScriptableObject.CreateInstance<SE_Stats_Scaling_Bal>(); if (def.BuildMode == TrinketStatusBuildMode.CopyExistingSanitized) { SE_Stats val = FindSourceStatus(def, itemDrop); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("BalrondBattleFlow: Source SE_Stats not found for " + def.ItemPrefab + " / " + def.SourceStatusName)); return null; } CopySEStats(val, sE_Stats_Scaling_Bal, def); } else { BuildSEStatsFromDefinition(def, sE_Stats_Scaling_Bal, itemDrop); } ApplyCommonDefinition(def, sE_Stats_Scaling_Bal, itemDrop); return sE_Stats_Scaling_Bal; } private static SE_Stats FindSourceStatus(TrinketStatusDefinition def, ItemDrop itemDrop) { StatusEffect equipStatusEffect = itemDrop.m_itemData.m_shared.m_equipStatusEffect; if (equipStatusEffect is SE_Stats) { return (SE_Stats)(object)((equipStatusEffect is SE_Stats) ? equipStatusEffect : null); } StatusEffect fullAdrenalineSE = itemDrop.m_itemData.m_shared.m_fullAdrenalineSE; if (fullAdrenalineSE is SE_Stats) { return (SE_Stats)(object)((fullAdrenalineSE is SE_Stats) ? fullAdrenalineSE : null); } if (ObjectDB.instance.m_StatusEffects == null) { return null; } for (int i = 0; i < ObjectDB.instance.m_StatusEffects.Count; i++) { StatusEffect val = ObjectDB.instance.m_StatusEffects[i]; if (!((Object)(object)val == (Object)null) && (((Object)val).name == def.SourceStatusName || val.m_name == def.SourceStatusName)) { return (SE_Stats)(object)((val is SE_Stats) ? val : null); } } return null; } private static void AssignStatusToItem(TrinketStatusDefinition def, ItemDrop itemDrop, StatusEffect status) { SharedData shared = itemDrop.m_itemData.m_shared; if (def.ClearItemAdrenalineFields) { ClearSharedAdrenalineFields(shared); } if (def.ClearFullAdrenalineStatus) { shared.m_fullAdrenalineSE = null; } shared.m_equipStatusEffect = status; } private static void ClearSharedAdrenalineFields(SharedData shared) { if (shared == null) { return; } shared.m_fullAdrenalineSE = null; FieldInfo[] fields = typeof(SharedData).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { string text = fieldInfo.Name.ToLowerInvariant(); if (text.Contains("adrenaline")) { if (fieldInfo.FieldType == typeof(StatusEffect)) { fieldInfo.SetValue(shared, null); } else if (fieldInfo.FieldType == typeof(float)) { fieldInfo.SetValue(shared, 0f); } else if (fieldInfo.FieldType == typeof(int)) { fieldInfo.SetValue(shared, 0); } else if (fieldInfo.FieldType == typeof(bool)) { fieldInfo.SetValue(shared, false); } } } } private static void ApplyCommonDefinition(TrinketStatusDefinition def, SE_Stats_Scaling_Bal status, ItemDrop itemDrop) { ((Object)status).name = def.NewStatusName; ((StatusEffect)status).m_name = ((!string.IsNullOrEmpty(def.DisplayName)) ? def.DisplayName : ("$tag_" + def.NewStatusName + "_name_bal")); ((StatusEffect)status).m_tooltip = ((!string.IsNullOrEmpty(def.Tooltip)) ? def.Tooltip : ("$tag_" + def.NewStatusName + "_tooltip_bal")); if (itemDrop.m_itemData.m_shared.m_icons != null && itemDrop.m_itemData.m_shared.m_icons.Length != 0) { ((StatusEffect)status).m_icon = itemDrop.m_itemData.m_shared.m_icons[0]; } status.m_balMode = TrinketScalingMode.PassiveScaling; status.m_balMinAdrenaline = def.MinAdrenaline; status.m_balMaxAdrenaline = def.MaxAdrenaline; ((StatusEffect)status).m_ttl = 0f; ((StatusEffect)status).m_cooldown = 0f; ((StatusEffect)status).m_startMessage = ""; ((StatusEffect)status).m_stopMessage = ""; ((StatusEffect)status).m_repeatMessage = ""; ((StatusEffect)status).m_repeatInterval = 0f; } private static void BuildSEStatsFromDefinition(TrinketStatusDefinition def, SE_Stats_Scaling_Bal status, ItemDrop itemDrop) { ((StatusEffect)status).m_name = ((!string.IsNullOrEmpty(def.DisplayName)) ? def.DisplayName : ("$tag_" + def.NewStatusName + "_name_bal")); ((StatusEffect)status).m_tooltip = ((!string.IsNullOrEmpty(def.Tooltip)) ? def.Tooltip : ("$tag_" + def.NewStatusName + "_tooltip_bal")); if (itemDrop.m_itemData.m_shared.m_icons != null && itemDrop.m_itemData.m_shared.m_icons.Length != 0) { ((StatusEffect)status).m_icon = itemDrop.m_itemData.m_shared.m_icons[0]; } ApplyDefinitionStats(def, status); } private static void ApplyDefinitionStats(TrinketStatusDefinition def, SE_Stats_Scaling_Bal status) { //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) ((SE_Stats)status).m_healthRegenMultiplier = def.HealthRegenMultiplier; ((SE_Stats)status).m_staminaRegenMultiplier = def.StaminaRegenMultiplier; ((SE_Stats)status).m_eitrRegenMultiplier = def.EitrRegenMultiplier; ((SE_Stats)status).m_healthUpFront = 0f; ((SE_Stats)status).m_staminaUpFront = 0f; ((SE_Stats)status).m_eitrUpFront = 0f; ((SE_Stats)status).m_adrenalineUpFront = 0f; ((SE_Stats)status).m_addArmor = def.AddArmor; ((SE_Stats)status).m_armorMultiplier = def.ArmorMultiplier; ((SE_Stats)status).m_speedModifier = def.SpeedModifier; ((SE_Stats)status).m_swimSpeedModifier = def.SwimSpeedModifier; ((SE_Stats)status).m_swimStaminaUseModifier = def.SwimStaminaUseModifier; ((SE_Stats)status).m_dodgeStaminaUseModifier = def.DodgeStaminaUseModifier; ((SE_Stats)status).m_runStaminaDrainModifier = def.RunStaminaDrainModifier; ((SE_Stats)status).m_jumpStaminaUseModifier = def.JumpStaminaUseModifier; ((SE_Stats)status).m_attackStaminaUseModifier = def.AttackStaminaUseModifier; ((SE_Stats)status).m_blockStaminaUseModifier = def.BlockStaminaUseModifier; ((SE_Stats)status).m_blockStaminaUseFlatValue = def.BlockStaminaUseFlatValue; ((SE_Stats)status).m_homeItemStaminaUseModifier = def.HomeItemStaminaUseModifier; ((SE_Stats)status).m_sneakStaminaUseModifier = def.SneakStaminaUseModifier; ((SE_Stats)status).m_runStaminaUseModifier = def.RunStaminaUseModifier; ((SE_Stats)status).m_timedBlockBonus = def.TimedBlockBonus; ((SE_Stats)status).m_adrenalineModifier = def.AdrenalineModifier; ((SE_Stats)status).m_staggerModifier = def.StaggerModifier; ((SE_Stats)status).m_addMaxCarryWeight = def.AddMaxCarryWeight; ((SE_Stats)status).m_fallDamageModifier = def.FallDamageModifier; ((SE_Stats)status).m_jumpModifier = def.JumpModifier; ((SE_Stats)status).m_raiseSkill = def.RaiseSkill; ((SE_Stats)status).m_raiseSkillModifier = def.RaiseSkillModifier; ((SE_Stats)status).m_skillLevel = def.SkillLevel; ((SE_Stats)status).m_skillLevelModifier = def.SkillLevelModifier; ((SE_Stats)status).m_skillLevel2 = def.SkillLevel2; ((SE_Stats)status).m_skillLevelModifier2 = def.SkillLevelModifier2; ((SE_Stats)status).m_modifyAttackSkill = def.ModifyAttackSkill; ((SE_Stats)status).m_damageModifier = def.DamageModifier; ((SE_Stats)status).m_percentigeDamageModifiers = def.PercentageDamageModifiers; ((SE_Stats)status).m_mods = new List<DamageModPair>(); } private static void RegisterStatusEffect(StatusEffect status) { if ((Object)(object)status == (Object)null) { return; } if (ObjectDB.instance.m_StatusEffects == null) { ObjectDB.instance.m_StatusEffects = new List<StatusEffect>(); } for (int i = 0; i < ObjectDB.instance.m_StatusEffects.Count; i++) { StatusEffect val = ObjectDB.instance.m_StatusEffects[i]; if ((Object)(object)val != (Object)null && ((Object)val).name == ((Object)status).name) { ObjectDB.instance.m_StatusEffects[i] = status; return; } } ObjectDB.instance.m_StatusEffects.Add(status); } private static void CopyStatusEffect(StatusEffect src, StatusEffect dst) { //IL_004b: 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) dst.m_name = src.m_name; dst.m_category = src.m_category; dst.m_icon = src.m_icon; dst.m_flashIcon = src.m_flashIcon; dst.m_cooldownIcon = src.m_cooldownIcon; dst.m_tooltip = src.m_tooltip; dst.m_attributes = src.m_attributes; dst.m_startEffects = src.m_startEffects; dst.m_stopEffects = src.m_stopEffects; dst.m_activationAnimation = src.m_activationAnimation; } private static void CopySEStats(SE_Stats src, SE_Stats_Scaling_Bal dst, TrinketStatusDefinition def) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) CopyStatusEffect((StatusEffect)(object)src, (StatusEffect)(object)dst); ((SE_Stats)dst).m_runStaminaDrainModifier = src.m_runStaminaDrainModifier; ((SE_Stats)dst).m_jumpStaminaUseModifier = src.m_jumpStaminaUseModifier; ((SE_Stats)dst).m_attackStaminaUseModifier = src.m_attackStaminaUseModifier; ((SE_Stats)dst).m_blockStaminaUseModifier = src.m_blockStaminaUseModifier; ((SE_Stats)dst).m_blockStaminaUseFlatValue = src.m_blockStaminaUseFlatValue; ((SE_Stats)dst).m_dodgeStaminaUseModifier = src.m_dodgeStaminaUseModifier; ((SE_Stats)dst).m_swimStaminaUseModifier = src.m_swimStaminaUseModifier; ((SE_Stats)dst).m_homeItemStaminaUseModifier = src.m_homeItemStaminaUseModifier; ((SE_Stats)dst).m_sneakStaminaUseModifier = src.m_sneakStaminaUseModifier; ((SE_Stats)dst).m_runStaminaUseModifier = src.m_runStaminaUseModifier; ((SE_Stats)dst).m_adrenalineModifier = src.m_adrenalineModifier; ((SE_Stats)dst).m_staggerModifier = src.m_staggerModifier; ((SE_Stats)dst).m_timedBlockBonus = src.m_timedBlockBonus; ((SE_Stats)dst).m_healthRegenMultiplier = src.m_healthRegenMultiplier; ((SE_Stats)dst).m_staminaRegenMultiplier = src.m_staminaRegenMultiplier; ((SE_Stats)dst).m_eitrRegenMultiplier = src.m_eitrRegenMultiplier; ((SE_Stats)dst).m_addArmor = src.m_addArmor; ((SE_Stats)dst).m_armorMultiplier = src.m_armorMultiplier; ((SE_Stats)dst).m_raiseSkill = src.m_raiseSkill; ((SE_Stats)dst).m_raiseSkillModifier = src.m_raiseSkillModifier; ((SE_Stats)dst).m_skillLevel = src.m_skillLevel; ((SE_Stats)dst).m_skillLevelModifier = src.m_skillLevelModifier; ((SE_Stats)dst).m_skillLevel2 = src.m_skillLevel2; ((SE_Stats)dst).m_skillLevelModifier2 = src.m_skillLevelModifier2; ((SE_Stats)dst).m_modifyAttackSkill = src.m_modifyAttackSkill; ((SE_Stats)dst).m_damageModifier = src.m_damageModifier; ((SE_Stats)dst).m_percentigeDamageModifiers = src.m_percentigeDamageModifiers; ((SE_Stats)dst).m_noiseModifier = src.m_noiseModifier; ((SE_Stats)dst).m_stealthModifier = src.m_stealthModifier; ((SE_Stats)dst).m_addMaxCarryWeight = src.m_addMaxCarryWeight; ((SE_Stats)dst).m_speedModifier = src.m_speedModifier; ((SE_Stats)dst).m_swimSpeedModifier = src.m_swimSpeedModifier; ((SE_Stats)dst).m_jumpModifier = src.m_jumpModifier; ((SE_Stats)dst).m_maxMaxFallSpeed = src.m_maxMaxFallSpeed; ((SE_Stats)dst).m_fallDamageModifier = src.m_fallDamageModifier; if (def.ClearCopiedUpFrontValues) { ((SE_Stats)dst).m_healthUpFront = 0f; ((SE_Stats)dst).m_staminaUpFront = 0f; ((SE_Stats)dst).m_eitrUpFront = 0f; ((SE_Stats)dst).m_adrenalineUpFront = 0f; } else { ((SE_Stats)dst).m_healthUpFront = src.m_healthUpFront; ((SE_Stats)dst).m_staminaUpFront = src.m_staminaUpFront; ((SE_Stats)dst).m_eitrUpFront = src.m_eitrUpFront; ((SE_Stats)dst).m_adrenalineUpFront = src.m_adrenalineUpFront; } ((SE_Stats)dst).m_mods = (def.ClearCopiedResistances ? new List<DamageModPair>() : ((src.m_mods != null) ? new List<DamageModPair>(src.m_mods) : new List<DamageModPair>())); } } public static class BalrondHashCompat { private static readonly MethodInfo _getStableHashCodeStringBool; private static readonly MethodInfo _getStableHashCodeString; static BalrondHashCompat() { try { Type typeFromHandle = typeof(StringExtensionMethods); _getStableHashCodeStringBool = typeFromHandle.GetMethod("GetStableHashCode", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(string), typeof(bool) }, null); _getStableHashCodeString = typeFromHandle.GetMethod("GetStableHashCode", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); } catch { _getStableHashCodeStringBool = null; _getStableHashCodeString = null; } } public static int StableHash(string value) { if (value == null) { return 0; } try { if (_getStableHashCodeStringBool != null) { return (int)_getStableHashCodeStringBool.Invoke(null, new object[2] { value, false }); } if (_getStableHashCodeString != null) { return (int)_getStableHashCodeString.Invoke(null, new object[1] { value }); } } catch { } return FallbackStableHash(value); } private static int FallbackStableHash(string value) { int num = 5381; int num2 = num; for (int i = 0; i < value.Length; i += 2) { num = ((num << 5) + num) ^ value[i]; if (i == value.Length - 1) { break; } num2 = ((num2 << 5) + num2) ^ value[i + 1]; } return num + num2 * 1566083941; } } } namespace LitJson2 { internal enum JsonType { None, Object, Array, String, Int, Long, Double, Boolean } internal interface IJsonWrapper : IList, IOrderedDictionary, IDictionary, ICollection, IEnumerable { bool IsArray { get; } bool IsBoolean { get; } bool IsDouble { get; } bool IsInt { get; } bool IsLong { get; } bool IsObject { get; } bool IsString { get; } bool GetBoolean(); double GetDouble(); int GetInt(); JsonType GetJsonType(); long GetLong(); string GetString(); void SetBoolean(bool val); void SetDouble(double val); void SetInt(int val); void SetJsonType(JsonType type); void SetLong(long val); void SetString(string val); string ToJson(); void ToJson(JsonWriter writer); } internal class JsonData : IJsonWrapper, IList, IOrderedDictionary, IDictionary, ICollection, IEnumerable, IEquatable<JsonData> { private IList<JsonData> inst_array; private bool inst_boolean; private double inst_double; private int inst_int; private long inst_long; private IDictionary<string, JsonData> inst_object; private string inst_string; private string json; private JsonType type; private IList<KeyValuePair<string, JsonData>> object_list; public int Count => EnsureCollection().Count; public bool IsArray => type == JsonType.Array; public bool IsBoolean => type == JsonType.Boolean; public bool IsDouble => type == JsonType.Double; public bool IsInt => type == JsonType.Int; public bool IsLong => type == JsonType.Long; public bool IsObject => type == JsonType.Object; public bool IsString => type == JsonType.String; public ICollection<string> Keys { get { EnsureDictionary(); return inst_object.Keys; } } int ICollection.Count => Count; bool ICollection.IsSynchronized => EnsureCollection().IsSynchronized; object ICollection.SyncRoot => EnsureCollection().SyncRoot; bool IDictionary.IsFixedSize => EnsureDictionary().IsFixedSize; bool IDictionary.IsReadOnly => EnsureDictionary().IsReadOnly; ICollection IDictionary.Keys { get { EnsureDictionary(); IList<string> list = new List<string>(); foreach (KeyValuePair<string, JsonData> item in object_list) { list.Add(item.Key); } return (ICollection)list; } } ICollection IDictionary.Values { get { EnsureDictionary(); IList<JsonData> list = new List<JsonData>(); foreach (KeyValuePair<string, JsonData> item in object_list) { list.Add(item.Value); } return (ICollection)list; } } bool IJsonWrapper.IsArray => IsArray; bool IJsonWrapper.IsBoolean => IsBoolean; bool IJsonWrapper.IsDouble => IsDouble; bool IJsonWrapper.IsInt => IsInt; bool IJsonWrapper.IsLong => IsLong; bool IJsonWrapper.IsObject => IsObject; bool IJsonWrapper.IsString => IsString; bool IList.IsFixedSize => EnsureList().IsFixedSize; bool IList.IsReadOnly => EnsureList().IsReadOnly; object IDictionary.this[object key] { get { return EnsureDictionary()[key]; } set { if (!(key is string)) { throw new ArgumentException("The key has to be a string"); } JsonData value2 = ToJsonData(value); this[(string)key] = value2; } } object IOrderedDictionary.this[int idx] { get { EnsureDictionary(); return object_list[idx].Value; } set { EnsureDictionary(); JsonData value2 = ToJsonData(value); KeyValuePair<string, JsonData> keyValuePair = object_list[idx]; inst_object[keyValuePair.Key] = value2; KeyValuePair<string, JsonData> value3 = new KeyValuePair<string, JsonData>(keyValuePair.Key, value2); object_list[idx] = value3; } } object IList.this[int index] { get { return EnsureList()[index]; } set { EnsureList(); JsonData value2 = ToJsonData(value); this[index] = value2; } } public JsonData this[string prop_name] { get { EnsureDictionary(); return inst_object[prop_name]; } set { EnsureDictionary(); KeyValuePair<string, JsonData> keyValuePair = new KeyValuePair<string, JsonData>(prop_name, value); if (inst_object.ContainsKey(prop_name)) { for (int i = 0; i < object_list.Count; i++) { if (object_list[i].Key == prop_name) { object_list[i] = keyValuePair; break; } } } else { object_list.Add(keyValuePair); } inst_object[prop_name] = value; json = null; } } public JsonData this[int index] { get { EnsureCollection(); if (type == JsonType.Array) { return inst_array[index]; } return object_list[index].Value; } set { EnsureCollection(); if (type == JsonType.Array) { inst_array[index] = value; } else { KeyValuePair<string, JsonData> keyValuePair = object_list[index]; KeyValuePair<string, JsonData> value2 = new KeyValuePair<string, JsonData>(keyValuePair.Key, value); object_list[index] = value2; inst_object[keyValuePair.Key] = value; } json = null; } } public JsonData() { } public JsonData(bool boolean) { type = JsonType.Boolean; inst_boolean = boolean; } public JsonData(double number) { type = JsonType.Double; inst_double = number; } public JsonData(int number) { type = JsonType.Int; inst_int = number; } public JsonData(long number) { type = JsonType.Long; inst_long = number; } public JsonData(object obj) { if (obj is bool) { type = JsonType.Boolean; inst_boolean = (bool)obj; return; } if (obj is double) { type = JsonType.Double; inst_double = (double)obj; return; } if (obj is int) { type = JsonType.Int; inst_int = (int)obj; return; } if (obj is long) { type = JsonType.Long; inst_long = (long)obj; return; } if (obj is string) { type = JsonType.String; inst_string = (string)obj; return; } throw new ArgumentException("Unable to wrap the given object with JsonData"); } public JsonData(string str) { type = JsonType.String; inst_string = str; } public static implicit operator JsonData(bool data) { return new JsonData(data); } public static implicit operator JsonData(double data) { return new JsonData(data); } public static implicit operator JsonData(int data) { return new JsonData(data); } public static implicit operator JsonData(long data) { return new JsonData(data); } public static implicit operator JsonData(string data) { return new JsonData(data); } public static explicit operator bool(JsonData data) { if (data.type != JsonType.Boolean) { throw new InvalidCastException("Instance of JsonData doesn't hold a double"); } return data.inst_boolean; } public static explicit operator double(JsonData data) { if (data.type != JsonType.Double) { throw new InvalidCastException("Instance of JsonData doesn't hold a double"); } return data.inst_double; } public static explicit operator int(JsonData data) { if (data.type != JsonType.Int) { throw new InvalidCastException("Instance of JsonData doesn't hold an int"); } return data.inst_int; } public static explicit operator long(JsonData data) { if (data.type != JsonType.Long) { throw new InvalidCastException("Instance of JsonData doesn't hold an int"); } return data.inst_long; } public static explicit operator string(JsonData data) { if (data.type != JsonType.String) { throw new InvalidCastException("Instance of JsonData doesn't hold a string"); } return data.inst_string; } void ICollection.CopyTo(Array array, int index) { EnsureCollection().CopyTo(array, index); } void IDictionary.Add(object key, object value) { JsonData value2 = ToJsonData(value); EnsureDictionary().Add(key, value2); KeyValuePair<string, JsonData> item = new KeyValuePair<string, JsonData>((string)key, value2); object_list.Add(item); json = null; } void IDictionary.Clear() { EnsureDictionary().Clear(); object_list.Clear(); json = null; } bool IDictionary.Contains(object key) { return EnsureDictionary().Contains(key); } IDictionaryEnumerator IDictionary.GetEnumerator() { return ((IOrderedDictionary)this).GetEnumerator(); } void IDictionary.Remove(object key) { EnsureDictionary().Remove(key); for (int i = 0; i < object_list.Count; i++) { if (object_list[i].Key == (string)key) { object_list.RemoveAt(i); break; } } json = null; } IEnumerator IEnumerable.GetEnumerator() { return EnsureCollection().GetEnumerator(); } bool IJsonWrapper.GetBoolean() { if (type != JsonType.Boolean) { throw new InvalidOperationException("JsonData instance doesn't hold a boolean"); } return inst_boolean; } double IJsonWrapper.GetDouble() { if (type != JsonType.Double) { throw new InvalidOperationException("JsonData instance doesn't hold a double"); } return inst_double; } int IJsonWrapper.GetInt() { if (type != JsonType.Int) { throw new InvalidOperationException("JsonData instance doesn't hold an int"); } return inst_int; } long IJsonWrapper.GetLong() { if (type != JsonType.Long) { throw new InvalidOperationException("JsonData instance doesn't hold a long"); } return inst_long; } string IJsonWrapper.GetString() { if (type != JsonType.String) { throw new InvalidOperationException("JsonData instance doesn't hold a string"); } return inst_string; } void IJsonWrapper.SetBoolean(bool val) { type = JsonType.Boolean; inst_boolean = val; json = null; } void IJsonWrapper.SetDouble(double val) { type = JsonType.Double; inst_double = val; json = null; } void IJsonWrapper.SetInt(int val) { type = JsonType.Int; inst_int = val; json = null; } void IJsonWrapper.SetLong(long val) { type = JsonType.Long; inst_long = val; json = null; } void IJsonWrapper.SetString(string val) { type = JsonType.String; inst_string = val; json = null; } string IJsonWrapper.ToJson() { return ToJson(); } void IJsonWrapper.ToJson(JsonWriter writer) { ToJson(writer); } int IList.Add(object value) { return Add(value); } void IList.Clear() { EnsureList().Clear(); json = null; } bool IList.Contains(object value) { return EnsureList().Contains(value); } int IList.IndexOf(object value) { return EnsureList().IndexOf(value); } void IList.Insert(int index, object value) { EnsureList().Insert(index, value); json = null; } void IList.Remove(object value) { EnsureList().Remove(value); json = null; } void IList.RemoveAt(int index) { EnsureList().RemoveAt(index); json = null; } IDictionaryEnumerator IOrderedDictionary.GetEnumerator() { EnsureDictionary(); return new OrderedDictionaryEnumerator(object_list.GetEnumerator()); } void IOrderedDictionary.Insert(int idx, object key, object value) { string text = (string)key; JsonData value2 = (this[text] = ToJsonData(value)); KeyValuePair<string, JsonData> item = new KeyValuePair<string, JsonData>(text, value2); object_list.Insert(idx, item); } void IOrderedDictionary.RemoveAt(int idx) { EnsureDictionary(); inst_object.Remove(object_list[idx].Key); object_list.RemoveAt(idx); } private ICollection EnsureCollection() { if (type == JsonType.Array) { return (ICollection)inst_array; } if (type == JsonType.Object) { return (IC