Decompiled source of BetterTrinkets v1.0.0

plugins/BetterTrinkets.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("BetterTrinkets")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BetterTrinkets")]
[assembly: AssemblyTitle("BetterTrinkets")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BetterTrinkets
{
	public static class ModConfig
	{
		public static ConfigFile TrinketConfig;

		public static ConfigEntry<bool> Enabled;

		public static ConfigEntry<bool> DoublingOnAdrenaline;

		public static ConfigEntry<bool> DebugLogging;

		public static ConfigEntry<float> HotF_PassiveHealthRegen;

		public static ConfigEntry<float> HotF_DoubledHealthRegen;

		public static ConfigEntry<float> HotF_Duration;

		public static ConfigEntry<float> BP_PassiveStaminaRegen;

		public static ConfigEntry<float> BP_DoubledStaminaRegen;

		public static ConfigEntry<float> BP_Duration;

		public static ConfigEntry<float> IB_PassiveInstantHealth;

		public static ConfigEntry<float> IB_PassiveArmor;

		public static ConfigEntry<float> IB_DoubledInstantHealth;

		public static ConfigEntry<float> IB_DoubledArmor;

		public static ConfigEntry<float> IB_Duration;

		public static ConfigEntry<float> NA_PassiveInstantStamina;

		public static ConfigEntry<float> NA_PassiveSpeed;

		public static ConfigEntry<float> NA_DoubledInstantStamina;

		public static ConfigEntry<float> NA_DoubledSpeed;

		public static ConfigEntry<float> NA_Duration;

		public static ConfigEntry<float> FoD_PassiveSwimSpeed;

		public static ConfigEntry<float> FoD_PassiveSwimStaminaReduction;

		public static ConfigEntry<float> FoD_DoubledSwimSpeed;

		public static ConfigEntry<float> FoD_DoubledSwimStaminaReduction;

		public static ConfigEntry<float> FoD_Duration;

		public static ConfigEntry<float> WS_PassiveBowSkill;

		public static ConfigEntry<float> WS_PassiveSneakSkill;

		public static ConfigEntry<float> WS_PassivePierceDamage;

		public static ConfigEntry<float> WS_DoubledBowSkill;

		public static ConfigEntry<float> WS_DoubledSneakSkill;

		public static ConfigEntry<float> WS_DoubledPierceDamage;

		public static ConfigEntry<float> WS_Duration;

		public static ConfigEntry<string> CH_PassiveResistance;

		public static ConfigEntry<string> CH_DoubledResistance;

		public static ConfigEntry<float> CH_Duration;

		public static ConfigEntry<float> BotB_PassiveInstantHealth;

		public static ConfigEntry<float> BotB_PassiveClubSkill;

		public static ConfigEntry<float> BotB_PassiveBluntDamage;

		public static ConfigEntry<float> BotB_DoubledInstantHealth;

		public static ConfigEntry<float> BotB_DoubledClubSkill;

		public static ConfigEntry<float> BotB_DoubledBluntDamage;

		public static ConfigEntry<float> BotB_Duration;

		public static ConfigEntry<float> EM_PassiveBlockStaminaReduction;

		public static ConfigEntry<float> EM_PassiveParryBonus;

		public static ConfigEntry<float> EM_PassiveDodgeSkill;

		public static ConfigEntry<float> EM_DoubledBlockStaminaReduction;

		public static ConfigEntry<float> EM_DoubledParryBonus;

		public static ConfigEntry<float> EM_DoubledDodgeSkill;

		public static ConfigEntry<float> EM_Duration;

		public static ConfigEntry<float> PE_PassiveEitrRegen;

		public static ConfigEntry<float> PE_DoubledEitrRegen;

		public static ConfigEntry<float> PE_Duration;

		public static ConfigEntry<float> RS_PassiveInstantStamina;

		public static ConfigEntry<float> RS_PassiveSlashDamage;

		public static ConfigEntry<float> RS_DoubledInstantStamina;

		public static ConfigEntry<float> RS_DoubledSlashDamage;

		public static ConfigEntry<float> RS_Duration;

		public static ConfigEntry<float> J_PassiveInstantEitr;

		public static ConfigEntry<float> J_PassiveElementalMagicSkill;

		public static ConfigEntry<float> J_PassiveBloodMagicSkill;

		public static ConfigEntry<float> J_DoubledInstantEitr;

		public static ConfigEntry<float> J_DoubledElementalMagicSkill;

		public static ConfigEntry<float> J_DoubledBloodMagicSkill;

		public static ConfigEntry<float> J_Duration;

		public static ConfigEntry<float> B_PassiveInstantHealth;

		public static ConfigEntry<float> B_PassiveInstantStamina;

		public static ConfigEntry<float> B_DoubledInstantHealth;

		public static ConfigEntry<float> B_DoubledInstantStamina;

		public static ConfigEntry<float> B_Duration;

		public static void Init()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			TrinketConfig = new ConfigFile(Path.Combine(Paths.ConfigPath, "better_trinkets.cfg"), true);
			Enabled = TrinketConfig.Bind<bool>("General", "Enabled", true, "Enable or disable the entire mod.");
			DoublingOnAdrenaline = TrinketConfig.Bind<bool>("General", "DoublingOnAdrenaline", true, "When adrenaline fills, double the trinket effect for its default duration.");
			DebugLogging = TrinketConfig.Bind<bool>("General", "DebugLogging", false, "Enable verbose logging to BepInEx log for troubleshooting.");
			HotF_PassiveHealthRegen = TrinketConfig.Bind<float>("Heart of the Forest", "PassiveHealthRegen", 1.15f, "Health regen multiplier while passively active (1.0 = no bonus, 1.15 = +15%).");
			HotF_DoubledHealthRegen = TrinketConfig.Bind<float>("Heart of the Forest", "DoubledHealthRegen", 1.3f, "Health regen multiplier during adrenaline doubling.");
			HotF_Duration = TrinketConfig.Bind<float>("Heart of the Forest", "Duration", 60f, "Duration in seconds for the doubled effect.");
			BP_PassiveStaminaRegen = TrinketConfig.Bind<float>("Bronze Pendant", "PassiveStaminaRegen", 1.15f, "Stamina regen multiplier while passively active (1.0 = no bonus, 1.15 = +15%).");
			BP_DoubledStaminaRegen = TrinketConfig.Bind<float>("Bronze Pendant", "DoubledStaminaRegen", 1.3f, "Stamina regen multiplier during adrenaline doubling.");
			BP_Duration = TrinketConfig.Bind<float>("Bronze Pendant", "Duration", 60f, "Duration in seconds for the doubled effect.");
			IB_PassiveInstantHealth = TrinketConfig.Bind<float>("Iron Brooch", "PassiveInstantHealth", 25f, "One-time health gain when trinket is equipped.");
			IB_PassiveArmor = TrinketConfig.Bind<float>("Iron Brooch", "PassiveArmor", 10f, "Bonus armor while passively active.");
			IB_DoubledInstantHealth = TrinketConfig.Bind<float>("Iron Brooch", "DoubledInstantHealth", 50f, "Health gain when adrenaline doubling activates.");
			IB_DoubledArmor = TrinketConfig.Bind<float>("Iron Brooch", "DoubledArmor", 20f, "Bonus armor during adrenaline doubling.");
			IB_Duration = TrinketConfig.Bind<float>("Iron Brooch", "Duration", 30f, "Duration in seconds for the doubled effect.");
			NA_PassiveInstantStamina = TrinketConfig.Bind<float>("Nimble Anklet", "PassiveInstantStamina", 25f, "One-time stamina gain when trinket is equipped.");
			NA_PassiveSpeed = TrinketConfig.Bind<float>("Nimble Anklet", "PassiveSpeed", 0.1f, "Movement speed modifier while passively active (0.10 = +10%).");
			NA_DoubledInstantStamina = TrinketConfig.Bind<float>("Nimble Anklet", "DoubledInstantStamina", 50f, "Stamina gain when adrenaline doubling activates.");
			NA_DoubledSpeed = TrinketConfig.Bind<float>("Nimble Anklet", "DoubledSpeed", 0.2f, "Movement speed modifier during adrenaline doubling.");
			NA_Duration = TrinketConfig.Bind<float>("Nimble Anklet", "Duration", 30f, "Duration in seconds for the doubled effect.");
			FoD_PassiveSwimSpeed = TrinketConfig.Bind<float>("Fins of Destiny", "PassiveSwimSpeed", 0.5f, "Swim speed modifier while passively active (0.50 = +50%).");
			FoD_PassiveSwimStaminaReduction = TrinketConfig.Bind<float>("Fins of Destiny", "PassiveSwimStaminaReduction", 0.8f, "Swim stamina usage reduction (0.80 = -80% stamina cost).");
			FoD_DoubledSwimSpeed = TrinketConfig.Bind<float>("Fins of Destiny", "DoubledSwimSpeed", 1f, "Swim speed modifier during adrenaline doubling.");
			FoD_DoubledSwimStaminaReduction = TrinketConfig.Bind<float>("Fins of Destiny", "DoubledSwimStaminaReduction", 0.8f, "Swim stamina usage reduction during doubling.");
			FoD_Duration = TrinketConfig.Bind<float>("Fins of Destiny", "Duration", 120f, "Duration in seconds for the doubled effect.");
			WS_PassiveBowSkill = TrinketConfig.Bind<float>("Wolf Sight", "PassiveBowSkill", 20f, "Bow skill bonus while passively active.");
			WS_PassiveSneakSkill = TrinketConfig.Bind<float>("Wolf Sight", "PassiveSneakSkill", 20f, "Sneak skill bonus while passively active.");
			WS_PassivePierceDamage = TrinketConfig.Bind<float>("Wolf Sight", "PassivePierceDamage", 0.15f, "Pierce damage modifier while passively active (0.15 = +15%).");
			WS_DoubledBowSkill = TrinketConfig.Bind<float>("Wolf Sight", "DoubledBowSkill", 40f, "Bow skill bonus during adrenaline doubling.");
			WS_DoubledSneakSkill = TrinketConfig.Bind<float>("Wolf Sight", "DoubledSneakSkill", 40f, "Sneak skill bonus during adrenaline doubling.");
			WS_DoubledPierceDamage = TrinketConfig.Bind<float>("Wolf Sight", "DoubledPierceDamage", 0.3f, "Pierce damage modifier during adrenaline doubling.");
			WS_Duration = TrinketConfig.Bind<float>("Wolf Sight", "Duration", 30f, "Duration in seconds for the doubled effect.");
			CH_PassiveResistance = TrinketConfig.Bind<string>("Crystal Heart", "PassiveResistance", "Resistant", "Damage resistance level while passively active (Normal, Resistant, VeryResistant, Immune).");
			CH_DoubledResistance = TrinketConfig.Bind<string>("Crystal Heart", "DoubledResistance", "VeryResistant", "Damage resistance level during adrenaline doubling.");
			CH_Duration = TrinketConfig.Bind<float>("Crystal Heart", "Duration", 50f, "Duration in seconds for the doubled effect.");
			BotB_PassiveInstantHealth = TrinketConfig.Bind<float>("Bracelets of the Brave", "PassiveInstantHealth", 50f, "One-time health gain when trinket is equipped.");
			BotB_PassiveClubSkill = TrinketConfig.Bind<float>("Bracelets of the Brave", "PassiveClubSkill", 20f, "Club skill bonus while passively active.");
			BotB_PassiveBluntDamage = TrinketConfig.Bind<float>("Bracelets of the Brave", "PassiveBluntDamage", 0.15f, "Blunt damage modifier while passively active (0.15 = +15%).");
			BotB_DoubledInstantHealth = TrinketConfig.Bind<float>("Bracelets of the Brave", "DoubledInstantHealth", 100f, "Health gain when adrenaline doubling activates.");
			BotB_DoubledClubSkill = TrinketConfig.Bind<float>("Bracelets of the Brave", "DoubledClubSkill", 40f, "Club skill bonus during adrenaline doubling.");
			BotB_DoubledBluntDamage = TrinketConfig.Bind<float>("Bracelets of the Brave", "DoubledBluntDamage", 0.3f, "Blunt damage modifier during adrenaline doubling.");
			BotB_Duration = TrinketConfig.Bind<float>("Bracelets of the Brave", "Duration", 60f, "Duration in seconds for the doubled effect.");
			EM_PassiveBlockStaminaReduction = TrinketConfig.Bind<float>("Evasion Mantle", "PassiveBlockStaminaReduction", 0.5f, "Block stamina cost reduction while passively active (0.50 = -50%).");
			EM_PassiveParryBonus = TrinketConfig.Bind<float>("Evasion Mantle", "PassiveParryBonus", 0.5f, "Parry bonus multiplier while passively active (0.50 = +50%).");
			EM_PassiveDodgeSkill = TrinketConfig.Bind<float>("Evasion Mantle", "PassiveDodgeSkill", 20f, "Dodge skill bonus while passively active.");
			EM_DoubledBlockStaminaReduction = TrinketConfig.Bind<float>("Evasion Mantle", "DoubledBlockStaminaReduction", 1f, "Block stamina cost reduction during adrenaline doubling (1.00 = -100%).");
			EM_DoubledParryBonus = TrinketConfig.Bind<float>("Evasion Mantle", "DoubledParryBonus", 1f, "Parry bonus multiplier during adrenaline doubling.");
			EM_DoubledDodgeSkill = TrinketConfig.Bind<float>("Evasion Mantle", "DoubledDodgeSkill", 40f, "Dodge skill bonus during adrenaline doubling.");
			EM_Duration = TrinketConfig.Bind<float>("Evasion Mantle", "Duration", 120f, "Duration in seconds for the doubled effect.");
			PE_PassiveEitrRegen = TrinketConfig.Bind<float>("Pulsating Earrings", "PassiveEitrRegen", 1.25f, "Eitr regen multiplier while passively active (1.0 = no bonus, 1.25 = +25%).");
			PE_DoubledEitrRegen = TrinketConfig.Bind<float>("Pulsating Earrings", "DoubledEitrRegen", 1.5f, "Eitr regen multiplier during adrenaline doubling.");
			PE_Duration = TrinketConfig.Bind<float>("Pulsating Earrings", "Duration", 60f, "Duration in seconds for the doubled effect.");
			RS_PassiveInstantStamina = TrinketConfig.Bind<float>("Resounding Shackle", "PassiveInstantStamina", 50f, "One-time stamina gain when trinket is equipped.");
			RS_PassiveSlashDamage = TrinketConfig.Bind<float>("Resounding Shackle", "PassiveSlashDamage", 0.15f, "Slash damage modifier while passively active (0.15 = +15%).");
			RS_DoubledInstantStamina = TrinketConfig.Bind<float>("Resounding Shackle", "DoubledInstantStamina", 100f, "Stamina gain when adrenaline doubling activates.");
			RS_DoubledSlashDamage = TrinketConfig.Bind<float>("Resounding Shackle", "DoubledSlashDamage", 0.3f, "Slash damage modifier during adrenaline doubling.");
			RS_Duration = TrinketConfig.Bind<float>("Resounding Shackle", "Duration", 60f, "Duration in seconds for the doubled effect.");
			J_PassiveInstantEitr = TrinketConfig.Bind<float>("Jormundling", "PassiveInstantEitr", 50f, "One-time eitr gain when trinket is equipped.");
			J_PassiveElementalMagicSkill = TrinketConfig.Bind<float>("Jormundling", "PassiveElementalMagicSkill", 20f, "Elemental Magic skill bonus while passively active.");
			J_PassiveBloodMagicSkill = TrinketConfig.Bind<float>("Jormundling", "PassiveBloodMagicSkill", 20f, "Blood Magic skill bonus while passively active.");
			J_DoubledInstantEitr = TrinketConfig.Bind<float>("Jormundling", "DoubledInstantEitr", 100f, "Eitr gain when adrenaline doubling activates.");
			J_DoubledElementalMagicSkill = TrinketConfig.Bind<float>("Jormundling", "DoubledElementalMagicSkill", 40f, "Elemental Magic skill bonus during adrenaline doubling.");
			J_DoubledBloodMagicSkill = TrinketConfig.Bind<float>("Jormundling", "DoubledBloodMagicSkill", 40f, "Blood Magic skill bonus during adrenaline doubling.");
			J_Duration = TrinketConfig.Bind<float>("Jormundling", "Duration", 60f, "Duration in seconds for the doubled effect.");
			B_PassiveInstantHealth = TrinketConfig.Bind<float>("Brimstone", "PassiveInstantHealth", 50f, "One-time health gain when trinket is equipped.");
			B_PassiveInstantStamina = TrinketConfig.Bind<float>("Brimstone", "PassiveInstantStamina", 50f, "One-time stamina gain when trinket is equipped.");
			B_DoubledInstantHealth = TrinketConfig.Bind<float>("Brimstone", "DoubledInstantHealth", 100f, "Health gain when adrenaline doubling activates.");
			B_DoubledInstantStamina = TrinketConfig.Bind<float>("Brimstone", "DoubledInstantStamina", 100f, "Stamina gain when adrenaline doubling activates.");
			B_Duration = TrinketConfig.Bind<float>("Brimstone", "Duration", 60f, "Duration in seconds for the doubled effect.");
		}
	}
	[BepInPlugin("com.xavie.bettertrinkets", "BetterTrinkets", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.xavie.bettertrinkets";

		public const string PluginName = "BetterTrinkets";

		public const string PluginVersion = "1.0.0";

		internal static Plugin Instance;

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Init();
			TrinketDefinitions.Init();
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.xavie.bettertrinkets");
			Log.LogInfo((object)"BetterTrinkets v1.0.0 loaded.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public class TrinketData
	{
		public string DisplayName;

		public string SEName;

		public float Duration;

		public Dictionary<string, object> PassiveFields;

		public Dictionary<string, object> DoubledFields;

		public float InstantHealth;

		public float InstantStamina;

		public float InstantEitr;

		public float DoubledInstantHealth;

		public float DoubledInstantStamina;

		public float DoubledInstantEitr;
	}
	public static class TrinketDefinitions
	{
		public static Dictionary<string, TrinketData> Effects;

		public static void Init()
		{
			Effects = new Dictionary<string, TrinketData>
			{
				["TrinketBronzeHealth"] = new TrinketData
				{
					DisplayName = "Heart of the Forest",
					SEName = "TrinketBronzeHealth",
					Duration = ModConfig.HotF_Duration.Value,
					PassiveFields = new Dictionary<string, object> { ["m_healthRegenMultiplier"] = ModConfig.HotF_PassiveHealthRegen.Value },
					DoubledFields = new Dictionary<string, object> { ["m_healthRegenMultiplier"] = ModConfig.HotF_DoubledHealthRegen.Value }
				},
				["TrinketBronzeStamina"] = new TrinketData
				{
					DisplayName = "Bronze Pendant",
					SEName = "TrinketBronzeStamina",
					Duration = ModConfig.BP_Duration.Value,
					PassiveFields = new Dictionary<string, object> { ["m_staminaRegenMultiplier"] = ModConfig.BP_PassiveStaminaRegen.Value },
					DoubledFields = new Dictionary<string, object> { ["m_staminaRegenMultiplier"] = ModConfig.BP_DoubledStaminaRegen.Value }
				},
				["TrinketIronHealth"] = new TrinketData
				{
					DisplayName = "Iron Brooch",
					SEName = "TrinketIronHealth",
					Duration = ModConfig.IB_Duration.Value,
					InstantHealth = ModConfig.IB_PassiveInstantHealth.Value,
					DoubledInstantHealth = ModConfig.IB_DoubledInstantHealth.Value,
					PassiveFields = new Dictionary<string, object> { ["m_addArmor"] = ModConfig.IB_PassiveArmor.Value },
					DoubledFields = new Dictionary<string, object> { ["m_addArmor"] = ModConfig.IB_DoubledArmor.Value }
				},
				["TrinketIronStamina"] = new TrinketData
				{
					DisplayName = "Nimble Anklet",
					SEName = "TrinketIronStamina",
					Duration = ModConfig.NA_Duration.Value,
					InstantStamina = ModConfig.NA_PassiveInstantStamina.Value,
					DoubledInstantStamina = ModConfig.NA_DoubledInstantStamina.Value,
					PassiveFields = new Dictionary<string, object> { ["m_speedModifier"] = ModConfig.NA_PassiveSpeed.Value },
					DoubledFields = new Dictionary<string, object> { ["m_speedModifier"] = ModConfig.NA_DoubledSpeed.Value }
				},
				["TrinketChitinSwim"] = new TrinketData
				{
					DisplayName = "Fins of Destiny",
					SEName = "TrinketChitinSwim",
					Duration = ModConfig.FoD_Duration.Value,
					PassiveFields = new Dictionary<string, object> { ["m_swimSpeedModifier"] = ModConfig.FoD_PassiveSwimSpeed.Value },
					DoubledFields = new Dictionary<string, object> { ["m_swimSpeedModifier"] = ModConfig.FoD_DoubledSwimSpeed.Value }
				},
				["TrinketSilverDamage"] = new TrinketData
				{
					DisplayName = "Wolf Sight",
					SEName = "TrinketSilverDamage",
					Duration = ModConfig.WS_Duration.Value,
					PassiveFields = new Dictionary<string, object>
					{
						["m_skillLevel"] = (object)(SkillType)8,
						["m_skillLevelModifier"] = ModConfig.WS_PassiveBowSkill.Value,
						["m_skillLevel2"] = (object)(SkillType)101,
						["m_skillLevelModifier2"] = ModConfig.WS_PassiveSneakSkill.Value,
						["m_damageModifier"] = ModConfig.WS_PassivePierceDamage.Value
					},
					DoubledFields = new Dictionary<string, object>
					{
						["m_skillLevel"] = (object)(SkillType)8,
						["m_skillLevelModifier"] = ModConfig.WS_DoubledBowSkill.Value,
						["m_skillLevel2"] = (object)(SkillType)101,
						["m_skillLevelModifier2"] = ModConfig.WS_DoubledSneakSkill.Value,
						["m_damageModifier"] = ModConfig.WS_DoubledPierceDamage.Value
					}
				},
				["TrinketSilverResist"] = new TrinketData
				{
					DisplayName = "Crystal Heart",
					SEName = "TrinketSilverResist",
					Duration = ModConfig.CH_Duration.Value,
					PassiveFields = new Dictionary<string, object>(),
					DoubledFields = new Dictionary<string, object>()
				},
				["TrinketBlackDamageHealth"] = new TrinketData
				{
					DisplayName = "Bracelets of the Brave",
					SEName = "TrinketBlackDamageHealth",
					Duration = ModConfig.BotB_Duration.Value,
					InstantHealth = ModConfig.BotB_PassiveInstantHealth.Value,
					DoubledInstantHealth = ModConfig.BotB_DoubledInstantHealth.Value,
					PassiveFields = new Dictionary<string, object>
					{
						["m_skillLevel"] = (object)(SkillType)3,
						["m_skillLevelModifier"] = ModConfig.BotB_PassiveClubSkill.Value,
						["m_damageModifier"] = ModConfig.BotB_PassiveBluntDamage.Value
					},
					DoubledFields = new Dictionary<string, object>
					{
						["m_skillLevel"] = (object)(SkillType)3,
						["m_skillLevelModifier"] = ModConfig.BotB_DoubledClubSkill.Value,
						["m_damageModifier"] = ModConfig.BotB_DoubledBluntDamage.Value
					}
				},
				["TrinketBlackStamina"] = new TrinketData
				{
					DisplayName = "Evasion Mantle",
					SEName = "TrinketBlackStamina",
					Duration = ModConfig.EM_Duration.Value,
					PassiveFields = new Dictionary<string, object>
					{
						["m_skillLevel"] = (object)(SkillType)108,
						["m_skillLevelModifier"] = ModConfig.EM_PassiveDodgeSkill.Value
					},
					DoubledFields = new Dictionary<string, object>
					{
						["m_skillLevel"] = (object)(SkillType)108,
						["m_skillLevelModifier"] = ModConfig.EM_DoubledDodgeSkill.Value
					}
				},
				["TrinketCarapaceEitr"] = new TrinketData
				{
					DisplayName = "Pulsating Earrings",
					SEName = "TrinketCarapaceEitr",
					Duration = ModConfig.PE_Duration.Value,
					PassiveFields = new Dictionary<string, object> { ["m_eitrRegenMultiplier"] = ModConfig.PE_PassiveEitrRegen.Value },
					DoubledFields = new Dictionary<string, object> { ["m_eitrRegenMultiplier"] = ModConfig.PE_DoubledEitrRegen.Value }
				},
				["TrinketScaleStaminaDamage"] = new TrinketData
				{
					DisplayName = "Resounding Shackle",
					SEName = "TrinketScaleStaminaDamage",
					Duration = ModConfig.RS_Duration.Value,
					InstantStamina = ModConfig.RS_PassiveInstantStamina.Value,
					DoubledInstantStamina = ModConfig.RS_DoubledInstantStamina.Value,
					PassiveFields = new Dictionary<string, object> { ["m_damageModifier"] = ModConfig.RS_PassiveSlashDamage.Value },
					DoubledFields = new Dictionary<string, object> { ["m_damageModifier"] = ModConfig.RS_DoubledSlashDamage.Value }
				},
				["TrinketFlametalEitr"] = new TrinketData
				{
					DisplayName = "Jormundling",
					SEName = "TrinketFlametalEitr",
					Duration = ModConfig.J_Duration.Value,
					InstantEitr = ModConfig.J_PassiveInstantEitr.Value,
					DoubledInstantEitr = ModConfig.J_DoubledInstantEitr.Value,
					PassiveFields = new Dictionary<string, object>
					{
						["m_skillLevel"] = (object)(SkillType)9,
						["m_skillLevelModifier"] = ModConfig.J_PassiveElementalMagicSkill.Value,
						["m_skillLevel2"] = (object)(SkillType)10,
						["m_skillLevelModifier2"] = ModConfig.J_PassiveBloodMagicSkill.Value
					},
					DoubledFields = new Dictionary<string, object>
					{
						["m_skillLevel"] = (object)(SkillType)9,
						["m_skillLevelModifier"] = ModConfig.J_DoubledElementalMagicSkill.Value,
						["m_skillLevel2"] = (object)(SkillType)10,
						["m_skillLevelModifier2"] = ModConfig.J_DoubledBloodMagicSkill.Value
					}
				},
				["TrinketFlametalStaminaHealth"] = new TrinketData
				{
					DisplayName = "Brimstone",
					SEName = "TrinketFlametalStaminaHealth",
					Duration = ModConfig.B_Duration.Value,
					InstantHealth = ModConfig.B_PassiveInstantHealth.Value,
					InstantStamina = ModConfig.B_PassiveInstantStamina.Value,
					DoubledInstantHealth = ModConfig.B_DoubledInstantHealth.Value,
					DoubledInstantStamina = ModConfig.B_DoubledInstantStamina.Value,
					PassiveFields = new Dictionary<string, object>(),
					DoubledFields = new Dictionary<string, object>()
				}
			};
		}
	}
	internal static class HashHelper
	{
		public static int GetStableHashCode(string str)
		{
			int num = 5381;
			int num2 = num;
			for (int i = 0; i < str.Length && str[i] != 0; i += 2)
			{
				num = ((num << 5) + num) ^ str[i];
				if (i == str.Length - 1 || str[i + 1] == '\0')
				{
					break;
				}
				num2 = ((num2 << 5) + num2) ^ str[i + 1];
			}
			return num + num2 * 1566083941;
		}
	}
	public class TrinketEffectManager
	{
		private static TrinketEffectManager _instance;

		private string _currentTrinketSEName;

		private StatusEffect _activePassiveSE;

		private bool _isDoubled;

		private float _doubledTimeRemaining;

		private bool _instantEffectsApplied;

		public static TrinketEffectManager Instance => _instance ?? (_instance = new TrinketEffectManager());

		public void OnPlayerUpdate(Player player)
		{
			if ((Object)(object)player != (Object)(object)Player.m_localPlayer || !ModConfig.Enabled.Value)
			{
				return;
			}
			string equippedTrinketSEName = GetEquippedTrinketSEName(player);
			SEMan sEMan = ((Character)player).GetSEMan();
			if (equippedTrinketSEName != _currentTrinketSEName)
			{
				RemovePassiveEffect(sEMan);
				_currentTrinketSEName = equippedTrinketSEName;
				_isDoubled = false;
				_doubledTimeRemaining = 0f;
				_instantEffectsApplied = false;
				if (_currentTrinketSEName != null)
				{
					ApplyPassiveEffect(player, sEMan, _currentTrinketSEName);
				}
			}
			if (_isDoubled && _doubledTimeRemaining > 0f)
			{
				_doubledTimeRemaining -= Time.deltaTime;
				if (_doubledTimeRemaining <= 0f)
				{
					_isDoubled = false;
					UpdateEffectValues(_activePassiveSE, _currentTrinketSEName, doubled: false);
					LogDebug("Doubled effect expired for " + GetDisplayName(_currentTrinketSEName) + ", reverted to passive.");
				}
			}
			if (_currentTrinketSEName != null && (Object)(object)_activePassiveSE == (Object)null)
			{
				ApplyPassiveEffect(player, sEMan, _currentTrinketSEName);
			}
		}

		public void OnAdrenalineActivated(Player player, float duration)
		{
			if (_currentTrinketSEName != null && ModConfig.DoublingOnAdrenaline.Value && TrinketDefinitions.Effects.TryGetValue(_currentTrinketSEName, out var value))
			{
				float num = ((value.Duration > 0f) ? value.Duration : duration);
				_isDoubled = true;
				_doubledTimeRemaining = num;
				UpdateEffectValues(_activePassiveSE, _currentTrinketSEName, doubled: true);
				ApplyInstantEffects(player, value, doubled: true);
				Plugin.Log.LogInfo((object)$"DOUBLED effect for {value.DisplayName} for {num}s!");
			}
		}

		public void Reset()
		{
			_currentTrinketSEName = null;
			_activePassiveSE = null;
			_isDoubled = false;
			_doubledTimeRemaining = 0f;
			_instantEffectsApplied = false;
			LogDebug("State reset.");
		}

		private string GetEquippedTrinketSEName(Player player)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return null;
			}
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if ((int)allItem.m_shared.m_itemType == 24 && ((Humanoid)player).IsItemEquiped(allItem))
				{
					StatusEffect equipStatusEffect = allItem.m_shared.m_equipStatusEffect;
					if ((Object)(object)equipStatusEffect != (Object)null)
					{
						LogDebug("Found equipped trinket: " + allItem.m_shared.m_name + ", SE: " + ((Object)equipStatusEffect).name);
						return ((Object)equipStatusEffect).name;
					}
					equipStatusEffect = allItem.m_shared.m_attackStatusEffect;
					if ((Object)(object)equipStatusEffect != (Object)null)
					{
						LogDebug("Found trinket SE via m_attackStatusEffect: " + ((Object)equipStatusEffect).name);
						return ((Object)equipStatusEffect).name;
					}
					equipStatusEffect = allItem.m_shared.m_setStatusEffect;
					if ((Object)(object)equipStatusEffect != (Object)null)
					{
						LogDebug("Found trinket SE via m_setStatusEffect: " + ((Object)equipStatusEffect).name);
						return ((Object)equipStatusEffect).name;
					}
					GameObject dropPrefab = allItem.m_dropPrefab;
					string text = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
					if (text != null && TrinketDefinitions.Effects.ContainsKey(text))
					{
						LogDebug("Matched trinket by prefab name: " + text);
						return text;
					}
					Plugin.Log.LogWarning((object)("Equipped trinket '" + allItem.m_shared.m_name + "' has no recognizable SE. Prefab: " + text));
					return null;
				}
			}
			return null;
		}

		private void ApplyPassiveEffect(Player player, SEMan seMan, string seName)
		{
			if (!TrinketDefinitions.Effects.TryGetValue(seName, out var value))
			{
				Plugin.Log.LogWarning((object)("No trinket definition for SE '" + seName + "'. Effect will not be applied."));
				return;
			}
			ObjectDB instance = ObjectDB.instance;
			if ((Object)(object)instance == (Object)null)
			{
				Plugin.Log.LogWarning((object)"ObjectDB not available yet.");
				return;
			}
			StatusEffect statusEffect = instance.GetStatusEffect(HashHelper.GetStableHashCode(seName));
			if ((Object)(object)statusEffect == (Object)null)
			{
				Plugin.Log.LogWarning((object)("SE '" + seName + "' not found in ObjectDB. Is the name correct?"));
				return;
			}
			StatusEffect statusEffect2 = seMan.GetStatusEffect(HashHelper.GetStableHashCode(seName));
			if ((Object)(object)statusEffect2 != (Object)null)
			{
				seMan.RemoveStatusEffect(statusEffect2, true);
				LogDebug("Removed existing vanilla SE '" + seName + "' before applying passive.");
			}
			StatusEffect val = Object.Instantiate<StatusEffect>(statusEffect);
			val.m_ttl = 0f;
			UpdateEffectValues(val, seName, _isDoubled);
			_activePassiveSE = seMan.AddStatusEffect(val, false, 0, 0f);
			if ((Object)(object)_activePassiveSE != (Object)null)
			{
				_activePassiveSE.m_ttl = 0f;
				Plugin.Log.LogInfo((object)("Applied passive " + value.DisplayName + " effect."));
			}
			else
			{
				Plugin.Log.LogWarning((object)("Failed to add passive SE for " + value.DisplayName + "."));
			}
			if (!_instantEffectsApplied)
			{
				ApplyInstantEffects(player, value, doubled: false);
				_instantEffectsApplied = true;
			}
		}

		private void RemovePassiveEffect(SEMan seMan)
		{
			if ((Object)(object)_activePassiveSE != (Object)null)
			{
				seMan.RemoveStatusEffect(_activePassiveSE, true);
				LogDebug("Removed passive SE '" + ((Object)_activePassiveSE).name + "'.");
				_activePassiveSE = null;
			}
		}

		private void UpdateEffectValues(StatusEffect se, string seName, bool doubled)
		{
			if ((Object)(object)se == (Object)null || !TrinketDefinitions.Effects.TryGetValue(seName, out var value))
			{
				return;
			}
			Dictionary<string, object> dictionary = (doubled ? value.DoubledFields : value.PassiveFields);
			foreach (KeyValuePair<string, object> item in dictionary)
			{
				FieldInfo fieldInfo = AccessTools.Field(((object)se).GetType(), item.Key);
				if (fieldInfo != null)
				{
					try
					{
						if (fieldInfo.FieldType == item.Value.GetType())
						{
							fieldInfo.SetValue(se, item.Value);
						}
						else
						{
							fieldInfo.SetValue(se, Convert.ChangeType(item.Value, fieldInfo.FieldType));
						}
						LogDebug($"  Set {item.Key} = {item.Value} on {((Object)se).name}");
					}
					catch (Exception ex)
					{
						Plugin.Log.LogWarning((object)("Failed to set field '" + item.Key + "' on " + ((object)se).GetType().Name + ": " + ex.Message));
					}
				}
				else
				{
					Plugin.Log.LogWarning((object)("Field '" + item.Key + "' not found on " + ((object)se).GetType().Name + ". This field may need decompiler verification."));
				}
			}
			if (seName == "TrinketSilverResist")
			{
				ApplyCrystalHeartResistance(se, doubled);
			}
		}

		private void ApplyCrystalHeartResistance(StatusEffect se, bool doubled)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			FieldInfo fieldInfo = AccessTools.Field(((object)se).GetType(), "m_mods");
			if (fieldInfo == null)
			{
				Plugin.Log.LogWarning((object)"m_mods field not found on Crystal Heart SE. Resistance effects may not work.");
				return;
			}
			string text = (doubled ? ModConfig.CH_DoubledResistance.Value : ModConfig.CH_PassiveResistance.Value);
			if (!Enum.TryParse<DamageModifier>(text, ignoreCase: true, out DamageModifier result))
			{
				Plugin.Log.LogWarning((object)("Invalid resistance level '" + text + "'. Use: Normal, Resistant, VeryResistant, Immune."));
				result = (DamageModifier)1;
			}
			List<DamageModPair> value = new List<DamageModPair>
			{
				new DamageModPair
				{
					m_type = (DamageType)1,
					m_modifier = result
				},
				new DamageModPair
				{
					m_type = (DamageType)2,
					m_modifier = result
				},
				new DamageModPair
				{
					m_type = (DamageType)4,
					m_modifier = result
				}
			};
			fieldInfo.SetValue(se, value);
			LogDebug($"  Set Crystal Heart resistance to {result}");
		}

		private void ApplyInstantEffects(Player player, TrinketData data, bool doubled)
		{
			float num = (doubled ? data.DoubledInstantHealth : data.InstantHealth);
			float num2 = (doubled ? data.DoubledInstantStamina : data.InstantStamina);
			float num3 = (doubled ? data.DoubledInstantEitr : data.InstantEitr);
			if (num > 0f)
			{
				((Character)player).Heal(num, true);
				LogDebug($"  Healed {num} HP");
			}
			if (num2 > 0f)
			{
				((Character)player).AddStamina(num2);
				LogDebug($"  Added {num2} stamina");
			}
			if (!(num3 > 0f))
			{
				return;
			}
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(Player), "AddEitr", new Type[1] { typeof(float) }, (Type[])null);
				if (methodInfo != null)
				{
					methodInfo.Invoke(player, new object[1] { num3 });
					LogDebug($"  Added {num3} eitr");
				}
				else
				{
					Plugin.Log.LogWarning((object)"Player.AddEitr method not found. Eitr gain not applied.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Failed to add eitr: " + ex.Message));
			}
		}

		private string GetDisplayName(string seName)
		{
			if (seName != null && TrinketDefinitions.Effects.TryGetValue(seName, out var value))
			{
				return value.DisplayName;
			}
			return seName ?? "None";
		}

		private void LogDebug(string message)
		{
			if (ModConfig.DebugLogging.Value)
			{
				Plugin.Log.LogInfo((object)("[Debug] " + message));
			}
		}
	}
}
namespace BetterTrinkets.Patches
{
	[HarmonyPatch(typeof(Player))]
	public static class PlayerPatches
	{
		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		public static void Update_Postfix(Player __instance)
		{
			TrinketEffectManager.Instance.OnPlayerUpdate(__instance);
		}

		[HarmonyPatch("OnDeath")]
		[HarmonyPostfix]
		public static void OnDeath_Postfix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				TrinketEffectManager.Instance.Reset();
			}
		}

		[HarmonyPatch("OnSpawned")]
		[HarmonyPostfix]
		public static void OnSpawned_Postfix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				TrinketEffectManager.Instance.OnPlayerUpdate(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(SEMan))]
	public static class SEManPatches
	{
		[HarmonyPatch("AddStatusEffect", new Type[]
		{
			typeof(StatusEffect),
			typeof(bool),
			typeof(int),
			typeof(float)
		})]
		[HarmonyPrefix]
		public static bool AddStatusEffect_SE_Prefix(SEMan __instance, StatusEffect statusEffect, ref StatusEffect __result)
		{
			if (!ModConfig.Enabled.Value)
			{
				return true;
			}
			if ((Object)(object)statusEffect == (Object)null)
			{
				return true;
			}
			string name = ((Object)statusEffect).name;
			if (name == null || !name.StartsWith("Trinket"))
			{
				return true;
			}
			if (!TrinketDefinitions.Effects.ContainsKey(name))
			{
				return true;
			}
			Character value = Traverse.Create((object)__instance).Field("m_character").GetValue<Character>();
			if ((Object)(object)value == (Object)null)
			{
				return true;
			}
			Player val = (Player)(object)((value is Player) ? value : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			float ttl = statusEffect.m_ttl;
			if (ModConfig.DebugLogging.Value)
			{
				Plugin.Log.LogInfo((object)$"[Debug] Intercepted vanilla trinket SE add: {name} (ttl={ttl}s)");
			}
			TrinketEffectManager.Instance.OnAdrenalineActivated(val, ttl);
			__result = null;
			return false;
		}

		[HarmonyPatch("AddStatusEffect", new Type[]
		{
			typeof(int),
			typeof(bool),
			typeof(int),
			typeof(float)
		})]
		[HarmonyPrefix]
		public static bool AddStatusEffect_Hash_Prefix(SEMan __instance, int nameHash, ref StatusEffect __result)
		{
			if (!ModConfig.Enabled.Value)
			{
				return true;
			}
			foreach (KeyValuePair<string, TrinketData> effect in TrinketDefinitions.Effects)
			{
				if (HashHelper.GetStableHashCode(effect.Key) == nameHash)
				{
					Character value = Traverse.Create((object)__instance).Field("m_character").GetValue<Character>();
					if ((Object)(object)value == (Object)null)
					{
						return true;
					}
					Player val = (Player)(object)((value is Player) ? value : null);
					if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
					{
						return true;
					}
					float duration = effect.Value.Duration;
					if (ModConfig.DebugLogging.Value)
					{
						Plugin.Log.LogInfo((object)$"[Debug] Intercepted hash-based trinket SE add: {effect.Key} (hash={nameHash})");
					}
					TrinketEffectManager.Instance.OnAdrenalineActivated(val, duration);
					__result = null;
					return false;
				}
			}
			return true;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}