Decompiled source of balrond boonstone v1.0.0

plugins/BalrondBoonStone.dll

Decompiled 3 hours ago
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 System.Text.RegularExpressions;
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.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace BalrondBoonStone
{
	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;
		}
	}
	[Serializable]
	public class BoonConversion
	{
		public string m_trophyPrefabName = string.Empty;

		public string m_statusEffectName = string.Empty;

		public ItemDrop m_trophyItem;

		public StatusEffect m_statusEffect;

		public string m_runeTopicKey = string.Empty;

		public string m_runeLabelKey = string.Empty;

		public string m_runeTextKey = string.Empty;

		public string GetLocalizedBoonName()
		{
			if ((Object)(object)m_statusEffect != (Object)null && !string.IsNullOrWhiteSpace(m_statusEffect.m_name))
			{
				return Localization.instance.Localize(m_statusEffect.m_name);
			}
			return m_trophyPrefabName;
		}

		public string GetLocalizedRuneTopic()
		{
			return string.IsNullOrWhiteSpace(m_runeTopicKey) ? string.Empty : Localization.instance.Localize(m_runeTopicKey);
		}

		public string GetLocalizedRuneLabel()
		{
			return string.IsNullOrWhiteSpace(m_runeLabelKey) ? string.Empty : Localization.instance.Localize(m_runeLabelKey);
		}

		public string GetLocalizedRuneText()
		{
			return string.IsNullOrWhiteSpace(m_runeTextKey) ? string.Empty : Localization.instance.Localize(m_runeTextKey);
		}
	}
	[Serializable]
	public class BoonDamageMod
	{
		public DamageType DamageType = (DamageType)1;

		public DamageModifier Modifier = (DamageModifier)0;

		public DamageModPair ToPair()
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			DamageModPair result = default(DamageModPair);
			result.m_type = DamageType;
			result.m_modifier = Modifier;
			return result;
		}
	}
	[Serializable]
	public class BoonTuning
	{
		[Header("General")]
		public string Category = "boonstone_bal";

		[Header("Tick / periodic health")]
		public float TickInterval = 0f;

		public float HealthPerTickMinHealthPercentage = 0f;

		public float HealthPerTick = 0f;

		public HitType HitType = (HitType)0;

		[Header("Health")]
		public float HealthUpFront = 0f;

		public float HealthOverTime = 0f;

		public float HealthOverTimeDuration = 0f;

		public float HealthOverTimeInterval = 5f;

		[Header("Stamina")]
		public float StaminaUpFront = 0f;

		public float StaminaOverTime = 0f;

		public float StaminaOverTimeDuration = 0f;

		public bool StaminaOverTimeIsFraction = false;

		public float StaminaDrainPerSec = 0f;

		public float RunStaminaDrainModifier = 0f;

		public float JumpStaminaUseModifier = 0f;

		public float AttackStaminaUseModifier = 0f;

		public float BlockStaminaUseModifier = 0f;

		public float BlockStaminaUseFlatValue = 0f;

		public float DodgeStaminaUseModifier = 0f;

		public float SwimStaminaUseModifier = 0f;

		public float HomeItemStaminaUseModifier = 0f;

		public float SneakStaminaUseModifier = 0f;

		public float RunStaminaUseModifier = 0f;

		[Header("Adrenaline / stagger")]
		public float AdrenalineUpFront = 0f;

		public float AdrenalineModifier = 0f;

		public float StaggerModifier = 0f;

		public float TimedBlockBonus = 0f;

		[Header("Eitr")]
		public float EitrUpFront = 0f;

		public float EitrOverTime = 0f;

		public float EitrOverTimeDuration = 0f;

		[Header("Regen multipliers")]
		public float HealthRegenMultiplier = 1f;

		public float StaminaRegenMultiplier = 1f;

		public float EitrRegenMultiplier = 1f;

		[Header("Armor")]
		public float AddArmor = 0f;

		public float ArmorMultiplier = 0f;

		[Header("Skill raise")]
		public SkillType RaiseSkill = (SkillType)0;

		public float RaiseSkillModifier = 0f;

		[Header("Skill level modifiers")]
		public SkillType SkillLevel = (SkillType)0;

		public float SkillLevelModifier = 0f;

		public SkillType SkillLevel2 = (SkillType)0;

		public float SkillLevelModifier2 = 0f;

		[Header("Damage resist / weakness")]
		public List<BoonDamageMod> DamageMods = new List<BoonDamageMod>();

		[Header("Attack")]
		public SkillType ModifyAttackSkill = (SkillType)0;

		public float DamageModifier = 1f;

		public DamageTypes PercentageDamageModifiers = default(DamageTypes);

		[Header("Sneak")]
		public float NoiseModifier = 0f;

		public float StealthModifier = 0f;

		[Header("Carry weight")]
		public float AddMaxCarryWeight = 0f;

		[Header("Speed")]
		public float SpeedModifier = 0f;

		public float SwimSpeedModifier = 0f;

		public Vector3 JumpModifier = Vector3.zero;

		[Header("Fall")]
		public float MaxMaxFallSpeed = 0f;

		public float FallDamageModifier = 0f;

		[Header("Wind")]
		public float WindMovementModifier = 0f;

		public float WindRunStaminaModifier = 0f;

		public void Apply(SE_Stats statusEffect)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)statusEffect == (Object)null)
			{
				return;
			}
			((StatusEffect)statusEffect).m_category = Category;
			statusEffect.m_tickInterval = TickInterval;
			statusEffect.m_healthPerTickMinHealthPercentage = HealthPerTickMinHealthPercentage;
			statusEffect.m_healthPerTick = HealthPerTick;
			statusEffect.m_hitType = HitType;
			statusEffect.m_healthUpFront = HealthUpFront;
			statusEffect.m_healthOverTime = HealthOverTime;
			statusEffect.m_healthOverTimeDuration = HealthOverTimeDuration;
			statusEffect.m_healthOverTimeInterval = HealthOverTimeInterval;
			statusEffect.m_staminaUpFront = StaminaUpFront;
			statusEffect.m_staminaOverTime = StaminaOverTime;
			statusEffect.m_staminaOverTimeDuration = StaminaOverTimeDuration;
			statusEffect.m_staminaOverTimeIsFraction = StaminaOverTimeIsFraction;
			statusEffect.m_staminaDrainPerSec = StaminaDrainPerSec;
			statusEffect.m_runStaminaDrainModifier = RunStaminaDrainModifier;
			statusEffect.m_jumpStaminaUseModifier = JumpStaminaUseModifier;
			statusEffect.m_attackStaminaUseModifier = AttackStaminaUseModifier;
			statusEffect.m_blockStaminaUseModifier = BlockStaminaUseModifier;
			statusEffect.m_blockStaminaUseFlatValue = BlockStaminaUseFlatValue;
			statusEffect.m_dodgeStaminaUseModifier = DodgeStaminaUseModifier;
			statusEffect.m_swimStaminaUseModifier = SwimStaminaUseModifier;
			statusEffect.m_homeItemStaminaUseModifier = HomeItemStaminaUseModifier;
			statusEffect.m_sneakStaminaUseModifier = SneakStaminaUseModifier;
			statusEffect.m_runStaminaUseModifier = RunStaminaUseModifier;
			statusEffect.m_adrenalineUpFront = AdrenalineUpFront;
			statusEffect.m_adrenalineModifier = AdrenalineModifier;
			statusEffect.m_staggerModifier = StaggerModifier;
			statusEffect.m_timedBlockBonus = TimedBlockBonus;
			statusEffect.m_eitrUpFront = EitrUpFront;
			statusEffect.m_eitrOverTime = EitrOverTime;
			statusEffect.m_eitrOverTimeDuration = EitrOverTimeDuration;
			statusEffect.m_healthRegenMultiplier = HealthRegenMultiplier;
			statusEffect.m_staminaRegenMultiplier = StaminaRegenMultiplier;
			statusEffect.m_eitrRegenMultiplier = EitrRegenMultiplier;
			statusEffect.m_addArmor = AddArmor;
			statusEffect.m_armorMultiplier = ArmorMultiplier;
			statusEffect.m_raiseSkill = RaiseSkill;
			statusEffect.m_raiseSkillModifier = RaiseSkillModifier;
			statusEffect.m_skillLevel = SkillLevel;
			statusEffect.m_skillLevelModifier = SkillLevelModifier;
			statusEffect.m_skillLevel2 = SkillLevel2;
			statusEffect.m_skillLevelModifier2 = SkillLevelModifier2;
			statusEffect.m_mods = new List<DamageModPair>();
			if (DamageMods != null)
			{
				foreach (BoonDamageMod damageMod in DamageMods)
				{
					if (damageMod != null)
					{
						statusEffect.m_mods.Add(damageMod.ToPair());
					}
				}
			}
			statusEffect.m_modifyAttackSkill = ModifyAttackSkill;
			statusEffect.m_damageModifier = DamageModifier;
			statusEffect.m_percentigeDamageModifiers = PercentageDamageModifiers;
			statusEffect.m_noiseModifier = NoiseModifier;
			statusEffect.m_stealthModifier = StealthModifier;
			statusEffect.m_addMaxCarryWeight = AddMaxCarryWeight;
			statusEffect.m_speedModifier = SpeedModifier;
			statusEffect.m_swimSpeedModifier = SwimSpeedModifier;
			statusEffect.m_jumpModifier = JumpModifier;
			statusEffect.m_maxMaxFallSpeed = MaxMaxFallSpeed;
			statusEffect.m_fallDamageModifier = FallDamageModifier;
			statusEffect.m_windMovementModifier = WindMovementModifier;
			statusEffect.m_windRunStaminaModifier = WindRunStaminaModifier;
		}
	}
	[Serializable]
	public class BoonDefinition
	{
		public const string BoonCategory = "boonstone_bal";

		public string TrophyPrefabName;

		public string StatusEffectName;

		public string LocalizationKey;

		public string DescriptionKey;

		public string RuneTopicKey;

		public string RuneLabelKey;

		public string RuneTextKey;

		public float Duration;

		public BoonTuning Tuning;

		public ItemDrop ResolvedTrophyItem;

		public StatusEffect ResolvedStatusEffect;

		public BoonDefinition(string trophyPrefabName, float duration, BoonTuning tuning)
		{
			TrophyPrefabName = trophyPrefabName;
			StatusEffectName = BuildStatusEffectName(trophyPrefabName);
			LocalizationKey = BuildLocalizationKey(trophyPrefabName);
			DescriptionKey = LocalizationKey + "_desc";
			RuneTopicKey = BuildRuneTopicKey(trophyPrefabName);
			RuneLabelKey = BuildRuneLabelKey(trophyPrefabName);
			RuneTextKey = BuildRuneTextKey(trophyPrefabName);
			Duration = duration;
			Tuning = tuning ?? new BoonTuning();
			Tuning.Category = "boonstone_bal";
		}

		public static string BuildStatusEffectName(string trophyPrefabName)
		{
			return "SE_Boon" + trophyPrefabName;
		}

		public static string BuildLocalizationKey(string trophyPrefabName)
		{
			return "$tag_boon" + trophyPrefabName.ToLowerInvariant();
		}

		public static string BuildRuneTopicKey(string trophyPrefabName)
		{
			return "$rune_boon" + trophyPrefabName.ToLowerInvariant() + "_topic";
		}

		public static string BuildRuneLabelKey(string trophyPrefabName)
		{
			return "$rune_boon" + trophyPrefabName.ToLowerInvariant() + "_label";
		}

		public static string BuildRuneTextKey(string trophyPrefabName)
		{
			return "$rune_boon" + trophyPrefabName.ToLowerInvariant() + "_text";
		}
	}
	public static class BoonRegistry
	{
		public static readonly List<BoonDefinition> Definitions;

		public static List<BoonConversion> CreateRuntimeConversions()
		{
			List<BoonConversion> list = new List<BoonConversion>();
			foreach (BoonDefinition definition in Definitions)
			{
				if (definition == null || string.IsNullOrWhiteSpace(definition.TrophyPrefabName))
				{
					continue;
				}
				if ((Object)(object)ObjectDB.instance != (Object)null)
				{
					if ((Object)(object)definition.ResolvedStatusEffect == (Object)null && !string.IsNullOrWhiteSpace(definition.StatusEffectName))
					{
						definition.ResolvedStatusEffect = ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode(definition.StatusEffectName));
					}
					if ((Object)(object)definition.ResolvedTrophyItem == (Object)null)
					{
						GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(definition.TrophyPrefabName);
						if ((Object)(object)itemPrefab != (Object)null)
						{
							definition.ResolvedTrophyItem = itemPrefab.GetComponent<ItemDrop>();
						}
					}
				}
				list.Add(new BoonConversion
				{
					m_trophyPrefabName = definition.TrophyPrefabName,
					m_statusEffectName = definition.StatusEffectName,
					m_statusEffect = definition.ResolvedStatusEffect,
					m_trophyItem = definition.ResolvedTrophyItem,
					m_runeTopicKey = definition.RuneTopicKey,
					m_runeLabelKey = definition.RuneLabelKey,
					m_runeTextKey = definition.RuneTextKey
				});
			}
			return list;
		}

		static BoonRegistry()
		{
			//IL_00d3: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_0588: Unknown result type (might be due to invalid IL or missing references)
			//IL_058f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0620: Unknown result type (might be due to invalid IL or missing references)
			//IL_0627: Unknown result type (might be due to invalid IL or missing references)
			//IL_063e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0645: Unknown result type (might be due to invalid IL or missing references)
			//IL_068f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0696: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0744: Unknown result type (might be due to invalid IL or missing references)
			//IL_0749: Unknown result type (might be due to invalid IL or missing references)
			//IL_0788: Unknown result type (might be due to invalid IL or missing references)
			//IL_078f: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_07df: Unknown result type (might be due to invalid IL or missing references)
			//IL_081c: Unknown result type (might be due to invalid IL or missing references)
			//IL_084f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0862: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_092e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0935: Unknown result type (might be due to invalid IL or missing references)
			//IL_0947: Unknown result type (might be due to invalid IL or missing references)
			//IL_0986: Unknown result type (might be due to invalid IL or missing references)
			//IL_098d: Unknown result type (might be due to invalid IL or missing references)
			//IL_09d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a1d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a5e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a9c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aaf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b2a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bb4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c35: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c3a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c42: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c54: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c55: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c9d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cda: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d42: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d7f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dbd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dd0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e0e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e62: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e69: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e9b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ed9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0eeb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0eec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f20: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f27: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f3a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f4c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f4d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f75: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ffe: Unknown result type (might be due to invalid IL or missing references)
			//IL_1046: Unknown result type (might be due to invalid IL or missing references)
			//IL_10a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_10b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_10e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_112c: Unknown result type (might be due to invalid IL or missing references)
			//IL_1133: Unknown result type (might be due to invalid IL or missing references)
			//IL_1145: Unknown result type (might be due to invalid IL or missing references)
			//IL_1190: Unknown result type (might be due to invalid IL or missing references)
			//IL_1195: Unknown result type (might be due to invalid IL or missing references)
			//IL_11d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_1210: Unknown result type (might be due to invalid IL or missing references)
			//IL_1243: Unknown result type (might be due to invalid IL or missing references)
			//IL_128d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1294: Unknown result type (might be due to invalid IL or missing references)
			//IL_1369: Unknown result type (might be due to invalid IL or missing references)
			//IL_1385: Unknown result type (might be due to invalid IL or missing references)
			//IL_13ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_1400: Unknown result type (might be due to invalid IL or missing references)
			//IL_143f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1446: Unknown result type (might be due to invalid IL or missing references)
			//IL_1464: Unknown result type (might be due to invalid IL or missing references)
			//IL_1496: Unknown result type (might be due to invalid IL or missing references)
			//IL_14d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_14f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_14fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_1545: Unknown result type (might be due to invalid IL or missing references)
			//IL_15c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_15eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_1628: Unknown result type (might be due to invalid IL or missing references)
			//IL_1687: Unknown result type (might be due to invalid IL or missing references)
			//IL_168e: Unknown result type (might be due to invalid IL or missing references)
			//IL_16c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_1723: Unknown result type (might be due to invalid IL or missing references)
			//IL_172a: Unknown result type (might be due to invalid IL or missing references)
			//IL_1774: Unknown result type (might be due to invalid IL or missing references)
			//IL_177b: Unknown result type (might be due to invalid IL or missing references)
			//IL_1798: Unknown result type (might be due to invalid IL or missing references)
			Definitions = new List<BoonDefinition>();
			Add(B("TrophyFox_bal", new BoonTuning
			{
				StaminaRegenMultiplier = 1.08f,
				RunStaminaDrainModifier = -0.06f,
				SpeedModifier = 0.02f,
				NoiseModifier = -0.08f,
				StealthModifier = 0.06f
			}));
			Add(B("TrophyHabrok_bal", new BoonTuning
			{
				StaminaRegenMultiplier = 1.06f,
				EitrRegenMultiplier = 1.08f,
				FallDamageModifier = -0.12f,
				SpeedModifier = 0.02f,
				WindMovementModifier = 0.06f
			}));
			Add(B("TrophyHabrokBirb_bal", new BoonTuning
			{
				StaminaRegenMultiplier = 1.07f,
				RunStaminaDrainModifier = -0.04f,
				JumpModifier = new Vector3(0.04f, 0.08f, 0.04f),
				FallDamageModifier = -0.14f,
				NoiseModifier = -0.05f
			}));
			Add(B("TrophyCrow_bal", new BoonTuning
			{
				StaminaRegenMultiplier = 1.05f,
				NoiseModifier = -0.12f,
				StealthModifier = 0.08f,
				SpeedModifier = 0.01f,
				RaiseSkill = (SkillType)101,
				RaiseSkillModifier = 0.1f
			}));
			Add(B("TrophyGreywatcher_bal", new BoonTuning
			{
				HealthRegenMultiplier = 1.05f,
				StaminaRegenMultiplier = 1.04f,
				TimedBlockBonus = 0.08f,
				RaiseSkill = (SkillType)999,
				RaiseSkillModifier = 0.03f
			}));
			Add(B("TrophySouling_bal", new BoonTuning
			{
				EitrRegenMultiplier = 1.12f,
				NoiseModifier = -0.1f,
				StealthModifier = 0.05f,
				SkillLevel = (SkillType)9,
				SkillLevelModifier = 2f
			}));
			Add(B("TrophyCorpseCollector_bal", new BoonTuning
			{
				HealthRegenMultiplier = 1.06f,
				AddArmor = 4f,
				NoiseModifier = -0.04f
			}));
			Add(B("TrophyBjorn", new BoonTuning
			{
				HealthRegenMultiplier = 1.06f,
				StaminaRegenMultiplier = 1.03f,
				SkillLevel = (SkillType)11,
				SkillLevelModifier = 2f,
				NoiseModifier = -0.04f
			}));
			Add(B("TrophyBjornUndead", new BoonTuning
			{
				HealthRegenMultiplier = 1.05f,
				AddArmor = 3f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)512,
						Modifier = (DamageModifier)1
					}
				}
			}));
			Add(B("TrophyForsaken_bal", new BoonTuning
			{
				HealthRegenMultiplier = 1.04f,
				EitrRegenMultiplier = 1.08f,
				StaggerModifier = -0.06f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)512,
						Modifier = (DamageModifier)7
					}
				}
			}));
			Add(B("TrophyGoat_bal", new BoonTuning
			{
				RunStaminaDrainModifier = -0.05f,
				JumpStaminaUseModifier = -0.08f,
				JumpModifier = new Vector3(0f, 0.08f, 0.05f),
				FallDamageModifier = -0.1f
			}));
			Add(B("TrophyHaugbui_bal", new BoonTuning
			{
				AddArmor = 5f,
				HealthRegenMultiplier = 1.04f,
				SkillLevel = (SkillType)1,
				SkillLevelModifier = 3f
			}));
			Add(B("TrophyNeckBrute_bal", new BoonTuning
			{
				HealthRegenMultiplier = 1.07f,
				StaminaRegenMultiplier = 1.03f,
				SwimSpeedModifier = 0.08f,
				DamageModifier = 1.03f,
				ModifyAttackSkill = (SkillType)11
			}));
			Add(B("TrophyObsidianCrab_bal", new BoonTuning
			{
				AddArmor = 10f,
				SpeedModifier = -0.01f,
				FallDamageModifier = -0.18f
			}));
			Add(B("TrophySpectre_bal", new BoonTuning
			{
				EitrRegenMultiplier = 1.1f,
				NoiseModifier = -0.14f,
				StealthModifier = 0.06f,
				SkillLevel = (SkillType)10,
				SkillLevelModifier = 2f
			}));
			Add(B("TrophyStormdrake_bal", new BoonTuning
			{
				StaminaRegenMultiplier = 1.06f,
				RunStaminaDrainModifier = -0.05f,
				WindMovementModifier = 0.08f,
				WindRunStaminaModifier = -0.08f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)128,
						Modifier = (DamageModifier)7
					}
				}
			}));
			Add(B("TrophyShark_bal", new BoonTuning
			{
				SwimSpeedModifier = 0.15f,
				SwimStaminaUseModifier = -0.14f,
				StaminaRegenMultiplier = 1.04f,
				DamageModifier = 1.02f,
				ModifyAttackSkill = (SkillType)5
			}));
			Add(B("TrophyAbomination", new BoonTuning
			{
				HealthRegenMultiplier = 1.05f,
				AddArmor = 4f,
				SpeedModifier = -0.01f,
				DamageModifier = 1.01f
			}));
			Add(B("TrophyBlob", new BoonTuning
			{
				HealthRegenMultiplier = 1.01f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)256,
						Modifier = (DamageModifier)7
					}
				},
				NoiseModifier = -0.05f
			}));
			Add(B("TrophyBoar", new BoonTuning
			{
				HealthRegenMultiplier = 1.08f,
				StaminaRegenMultiplier = 1.03f,
				DamageModifier = 1.03f,
				ModifyAttackSkill = (SkillType)2
			}));
			Add(B("TrophyBonemass", new BoonTuning
			{
				AddArmor = 5f,
				HealthRegenMultiplier = 1.05f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)1,
						Modifier = (DamageModifier)7
					},
					new BoonDamageMod
					{
						DamageType = (DamageType)256,
						Modifier = (DamageModifier)7
					}
				}
			}));
			Add(B("TrophyCultist", new BoonTuning
			{
				SpeedModifier = 0.03f,
				AttackStaminaUseModifier = -0.1f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)32,
						Modifier = (DamageModifier)7
					}
				},
				PercentageDamageModifiers = new DamageTypes
				{
					m_fire = 0.04f
				}
			}));
			Add(B("TrophyDeathsquito", new BoonTuning
			{
				SpeedModifier = 0.05f,
				RunStaminaDrainModifier = -0.05f,
				SkillLevel = (SkillType)5,
				SkillLevelModifier = 2f,
				StealthModifier = 0.1f
			}));
			Add(B("TrophyDeer", new BoonTuning
			{
				StaminaRegenMultiplier = 1.05f,
				RunStaminaDrainModifier = -0.05f,
				JumpModifier = new Vector3(0f, 0.05f, 0.03f),
				FallDamageModifier = -0.1f
			}));
			Add(B("TrophyDragonQueen", new BoonTuning
			{
				EitrRegenMultiplier = 1.14f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)64,
						Modifier = (DamageModifier)1
					}
				},
				SkillLevel = (SkillType)9,
				SkillLevelModifier = 5f
			}));
			Add(B("TrophyDraugr", new BoonTuning
			{
				AddArmor = 3f,
				HealthRegenMultiplier = 1.04f,
				SkillLevel = (SkillType)8,
				SkillLevelModifier = 3f
			}));
			Add(B("TrophyDraugrElite", new BoonTuning
			{
				AddArmor = 4f,
				HealthRegenMultiplier = 1.05f,
				SkillLevel = (SkillType)1,
				SkillLevelModifier = 2f
			}));
			Add(B("TrophyDvergr", new BoonTuning
			{
				EitrRegenMultiplier = 1.12f,
				SkillLevel = (SkillType)9,
				SkillLevelModifier = 2f,
				SkillLevel2 = (SkillType)10,
				SkillLevelModifier2 = 3f
			}));
			Add(B("TrophyEikthyr", new BoonTuning
			{
				RunStaminaDrainModifier = -0.1f,
				JumpStaminaUseModifier = -0.1f,
				SpeedModifier = 0.04f,
				WindRunStaminaModifier = -0.04f
			}));
			Add(B("TrophyFenring", new BoonTuning
			{
				SpeedModifier = 0.03f,
				JumpModifier = new Vector3(0f, 0.08f, 0.05f),
				SkillLevel = (SkillType)11,
				SkillLevelModifier = 2f
			}));
			Add(B("TrophyFrostTroll", new BoonTuning
			{
				AddArmor = 5f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)1,
						Modifier = (DamageModifier)7
					}
				},
				SkillLevel = (SkillType)3,
				SkillLevelModifier = 2f
			}));
			Add(B("TrophyGjall", new BoonTuning
			{
				EitrRegenMultiplier = 1.1f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)32,
						Modifier = (DamageModifier)7
					}
				},
				NoiseModifier = -0.05f
			}));
			Add(B("TrophyGoblin", new BoonTuning
			{
				StaminaRegenMultiplier = 1.05f,
				SpeedModifier = 0.01f,
				SkillLevel = (SkillType)5,
				SkillLevelModifier = 3f
			}));
			Add(B("TrophyGoblinBrute", new BoonTuning
			{
				HealthRegenMultiplier = 1.06f,
				AddArmor = 4f,
				DamageModifier = 1.04f,
				ModifyAttackSkill = (SkillType)3
			}));
			Add(B("TrophyGoblinKing", new BoonTuning
			{
				HealthRegenMultiplier = 1.05f,
				StaminaRegenMultiplier = 1.05f,
				AddArmor = 3f,
				SkillLevel = (SkillType)999,
				SkillLevelModifier = 2f,
				TimedBlockBonus = 0.08f
			}));
			Add(B("TrophyGoblinShaman", new BoonTuning
			{
				EitrRegenMultiplier = 1.1f,
				SkillLevel = (SkillType)10,
				SkillLevelModifier = 2f,
				SkillLevel2 = (SkillType)9,
				SkillLevelModifier2 = 3f
			}));
			Add(B("TrophyGreydwarf", new BoonTuning
			{
				StaminaRegenMultiplier = 1.04f,
				NoiseModifier = -0.03f,
				RaiseSkill = (SkillType)13,
				RaiseSkillModifier = 0.1f
			}));
			Add(B("TrophyGreydwarfBrute", new BoonTuning
			{
				HealthRegenMultiplier = 1.05f,
				AddArmor = 3f,
				ModifyAttackSkill = (SkillType)3,
				DamageModifier = 1.03f
			}));
			Add(B("TrophyGreydwarfShaman", new BoonTuning
			{
				AddArmor = 1f,
				EitrRegenMultiplier = 1.1f,
				HealthRegenMultiplier = 1.05f
			}));
			Add(B("TrophyGrowth", new BoonTuning
			{
				HealthRegenMultiplier = 1.05f,
				SwimSpeedModifier = -0.05f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)256,
						Modifier = (DamageModifier)7
					}
				}
			}));
			Add(B("TrophyHare", new BoonTuning
			{
				SpeedModifier = 0.04f,
				RunStaminaDrainModifier = -0.1f,
				JumpStaminaUseModifier = -0.1f,
				NoiseModifier = -0.1f
			}));
			Add(B("TrophyHatchling", new BoonTuning
			{
				FallDamageModifier = -0.2f,
				JumpModifier = new Vector3(0f, 0.06f, 0.03f),
				PercentageDamageModifiers = new DamageTypes
				{
					m_frost = 0.02f
				}
			}));
			Add(B("TrophyLeech", new BoonTuning
			{
				HealthRegenMultiplier = 1.04f,
				SwimStaminaUseModifier = -0.1f,
				SwimSpeedModifier = 0.08f,
				DamageModifier = 1.02f,
				ModifyAttackSkill = (SkillType)2
			}));
			Add(B("TrophyLox", new BoonTuning
			{
				HealthRegenMultiplier = 1.06f,
				AddArmor = 4f,
				StaggerModifier = -0.08f,
				ModifyAttackSkill = (SkillType)3
			}));
			Add(B("TrophyNeck", new BoonTuning
			{
				SwimSpeedModifier = 0.1f,
				SwimStaminaUseModifier = -0.12f,
				StaminaRegenMultiplier = 1.03f
			}));
			Add(B("TrophySeeker", new BoonTuning
			{
				SpeedModifier = 0.02f,
				AttackStaminaUseModifier = -0.04f,
				SkillLevel = (SkillType)5,
				SkillLevelModifier = 3f
			}));
			Add(B("TrophySeekerBrute", new BoonTuning
			{
				AddArmor = 5f,
				DamageModifier = 1.04f,
				ModifyAttackSkill = (SkillType)3,
				StaggerModifier = -0.06f
			}));
			Add(B("TrophySeekerQueen", new BoonTuning
			{
				EitrRegenMultiplier = 1.15f,
				HealthRegenMultiplier = 1.04f,
				SkillLevel = (SkillType)9,
				SkillLevelModifier = 5f,
				SkillLevel2 = (SkillType)10,
				SkillLevelModifier2 = 5f
			}));
			Add(B("TrophySerpent", new BoonTuning
			{
				SwimSpeedModifier = 0.15f,
				SwimStaminaUseModifier = -0.15f,
				SkillLevel = (SkillType)103,
				SkillLevelModifier = 5f
			}));
			Add(B("TrophySGolem", new BoonTuning
			{
				AddArmor = 10f,
				SpeedModifier = -0.03f,
				FallDamageModifier = -0.05f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)1,
						Modifier = (DamageModifier)7
					}
				}
			}));
			Add(B("TrophySkeleton", new BoonTuning
			{
				AddArmor = 2f,
				SkillLevel = (SkillType)8,
				SkillLevelModifier = 2f
			}));
			Add(B("TrophySkeletonPoison", new BoonTuning
			{
				HealthRegenMultiplier = 1.05f,
				NoiseModifier = -0.05f,
				PercentageDamageModifiers = new DamageTypes
				{
					m_poison = 0.02f
				}
			}));
			Add(B("TrophySurtling", new BoonTuning
			{
				EitrRegenMultiplier = 1.1f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)32,
						Modifier = (DamageModifier)7
					}
				},
				PercentageDamageModifiers = new DamageTypes
				{
					m_fire = 0.02f
				}
			}));
			Add(B("TrophyTheElder", new BoonTuning
			{
				HealthRegenMultiplier = 1.05f,
				RaiseSkill = (SkillType)13,
				RaiseSkillModifier = 0.15f,
				AddArmor = 3f
			}));
			Add(B("TrophyTick", new BoonTuning
			{
				StaminaRegenMultiplier = 1.04f,
				SpeedModifier = 0.02f,
				StealthModifier = 0.05f,
				NoiseModifier = -0.05f
			}));
			Add(B("TrophyUlv", new BoonTuning
			{
				SpeedModifier = 0.03f,
				AttackStaminaUseModifier = -0.06f,
				SkillLevel = (SkillType)1,
				SkillLevelModifier = 2f,
				NoiseModifier = -0.04f
			}));
			Add(B("TrophyWolf", new BoonTuning
			{
				SpeedModifier = 0.02f,
				RunStaminaDrainModifier = -0.04f,
				SkillLevel = (SkillType)5,
				SkillLevelModifier = 3f,
				NoiseModifier = -0.04f
			}));
			Add(B("TrophyWraith", new BoonTuning
			{
				NoiseModifier = -0.15f,
				StealthModifier = 0.06f,
				EitrRegenMultiplier = 1.08f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)512,
						Modifier = (DamageModifier)7
					}
				}
			}));
			Add(B("TrophyTrollSkeleton_bal", new BoonTuning
			{
				AddArmor = 5f,
				SkillLevel = (SkillType)3,
				SkillLevelModifier = 2f,
				FallDamageModifier = -0.1f
			}));
			Add(B("TrophyTrollAshlands_bal", new BoonTuning
			{
				AddArmor = 5f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)32,
						Modifier = (DamageModifier)7
					}
				},
				ModifyAttackSkill = (SkillType)3,
				DamageModifier = 1.04f
			}));
			Add(B("TrophyStag_bal", new BoonTuning
			{
				StaminaRegenMultiplier = 1.05f,
				SpeedModifier = 0.02f,
				JumpModifier = new Vector3(0f, 0.05f, 0.03f),
				FallDamageModifier = -0.08f
			}));
			Add(B("TrophyBattleHog_bal", new BoonTuning
			{
				HealthRegenMultiplier = 1.07f,
				DamageModifier = 1.03f,
				ModifyAttackSkill = (SkillType)7,
				StaggerModifier = -0.04f
			}));
			Add(B("TrophyBear_bal", new BoonTuning
			{
				HealthRegenMultiplier = 1.08f,
				AddArmor = 4f,
				SkillLevel = (SkillType)11,
				SkillLevelModifier = 2f
			}));
			Add(B("TrophyForestTroll_bal", new BoonTuning
			{
				AddArmor = 4f,
				RaiseSkill = (SkillType)13,
				RaiseSkillModifier = 0.12f,
				FallDamageModifier = -0.1f
			}));
			Add(B("TrophyPolarBear_bal", new BoonTuning
			{
				HealthRegenMultiplier = 1.06f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)64,
						Modifier = (DamageModifier)7
					}
				},
				SpeedModifier = 0.01f
			}));
			Add(B("TrophyLeechPrimal_bal", new BoonTuning
			{
				HealthRegenMultiplier = 1.05f,
				SwimSpeedModifier = 0.08f,
				SwimStaminaUseModifier = -0.1f,
				EitrRegenMultiplier = 1.04f
			}));
			Add(B("TrophyStagGhost_bal", new BoonTuning
			{
				EitrRegenMultiplier = 1.1f,
				NoiseModifier = -0.1f,
				StealthModifier = 0.05f,
				FallDamageModifier = -0.08f
			}));
			Add(B("TrophyBonemawSerpent", new BoonTuning
			{
				SwimSpeedModifier = 0.14f,
				SwimStaminaUseModifier = -0.15f,
				DamageModifier = 1.03f,
				ModifyAttackSkill = (SkillType)5
			}));
			Add(B("TrophyCharredArcher", new BoonTuning
			{
				SkillLevel = (SkillType)8,
				SkillLevelModifier = 5f,
				StaminaRegenMultiplier = 1.04f,
				NoiseModifier = -0.04f
			}));
			Add(B("TrophyCharredMage", new BoonTuning
			{
				EitrRegenMultiplier = 1.12f,
				SkillLevel = (SkillType)9,
				SkillLevelModifier = 5f
			}));
			Add(B("TrophyCharredMelee", new BoonTuning
			{
				HealthRegenMultiplier = 1.05f,
				SkillLevel = (SkillType)1,
				SkillLevelModifier = 2f,
				AttackStaminaUseModifier = -0.05f
			}));
			Add(B("TrophyCultist_Hildir", new BoonTuning
			{
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)32,
						Modifier = (DamageModifier)7
					}
				},
				SpeedModifier = 0.02f,
				SkillLevel = (SkillType)9,
				SkillLevelModifier = 3f
			}));
			Add(B("TrophyDraugrFem", new BoonTuning
			{
				HealthRegenMultiplier = 1.04f,
				SkillLevel = (SkillType)8,
				SkillLevelModifier = 3f,
				StealthModifier = 0.04f
			}));
			Add(B("TrophyFader", new BoonTuning
			{
				EitrRegenMultiplier = 1.13f,
				SkillLevel = (SkillType)10,
				SkillLevelModifier = 5f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)512,
						Modifier = (DamageModifier)1
					}
				}
			}));
			Add(B("TrophyFallenValkyrie", new BoonTuning
			{
				SpeedModifier = 0.02f,
				FallDamageModifier = -0.16f,
				TimedBlockBonus = 0.1f,
				SkillLevel = (SkillType)1,
				SkillLevelModifier = 2f
			}));
			Add(B("TrophyGhost", new BoonTuning
			{
				NoiseModifier = -0.14f,
				StealthModifier = 0.05f,
				EitrRegenMultiplier = 1.08f
			}));
			Add(B("TrophyGoblinBruteBrosBrute", new BoonTuning
			{
				HealthRegenMultiplier = 1.06f,
				AddArmor = 4f,
				DamageModifier = 1.04f,
				ModifyAttackSkill = (SkillType)3
			}));
			Add(B("TrophyGoblinBruteBrosShaman", new BoonTuning
			{
				EitrRegenMultiplier = 1.1f,
				SkillLevel = (SkillType)10,
				SkillLevelModifier = 2f,
				HealthRegenMultiplier = 1.03f
			}));
			Add(B("TrophyKvastur", new BoonTuning
			{
				TimedBlockBonus = 0.1f,
				SkillLevel = (SkillType)1,
				SkillLevelModifier = 2f,
				AddArmor = 3f
			}));
			Add(B("TrophyMorgen", new BoonTuning
			{
				AddArmor = 6f,
				SpeedModifier = -0.02f,
				FallDamageModifier = -0.18f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)1,
						Modifier = (DamageModifier)7
					}
				}
			}));
			Add(B("TrophySkeletonHildir", new BoonTuning
			{
				AddArmor = 3f,
				SkillLevel = (SkillType)8,
				SkillLevelModifier = 2f,
				EitrRegenMultiplier = 1.04f
			}));
			Add(B("TrophyVolture", new BoonTuning
			{
				StaminaRegenMultiplier = 1.06f,
				WindMovementModifier = 0.06f,
				FallDamageModifier = -0.1f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)128,
						Modifier = (DamageModifier)7
					}
				}
			}));
			Add(B("TrophyAsksvin", new BoonTuning
			{
				HealthRegenMultiplier = 1.07f,
				StaminaRegenMultiplier = 1.03f,
				DamageMods = new List<BoonDamageMod>
				{
					new BoonDamageMod
					{
						DamageType = (DamageType)32,
						Modifier = (DamageModifier)7
					}
				},
				DamageModifier = 1.03f,
				ModifyAttackSkill = (SkillType)1
			}));
		}

		private static BoonDefinition B(string trophyPrefabName, BoonTuning tuning)
		{
			return new BoonDefinition(trophyPrefabName, 1800f, tuning);
		}

		public static string PrettyName(string trophyPrefabName)
		{
			if (string.IsNullOrWhiteSpace(trophyPrefabName))
			{
				return "Unknown";
			}
			string input = trophyPrefabName.Replace("Trophy", string.Empty).Replace("_bal", string.Empty).Replace("_", " ");
			input = Regex.Replace(input, "([a-z])([A-Z])", "$1 $2");
			input = Regex.Replace(input, "([A-Z]+)([A-Z][a-z])", "$1 $2");
			return input.Trim();
		}

		private static void Add(BoonDefinition definition)
		{
			Definitions.Add(definition);
		}
	}
	public static class BoonStatusEffectFactory
	{
		public static void RegisterAll(ObjectDB objectDb)
		{
			if ((Object)(object)objectDb == (Object)null)
			{
				return;
			}
			foreach (BoonDefinition definition in BoonRegistry.Definitions)
			{
				try
				{
					RegisterSingle(objectDb, definition);
				}
				catch (Exception arg)
				{
					Debug.LogError((object)string.Format("[{0}] Failed to register boon '{1}'\n{2}", "BalrondBoonStone", definition.TrophyPrefabName, arg));
				}
			}
		}

		private static void RegisterSingle(ObjectDB objectDb, BoonDefinition definition)
		{
			if (definition != null)
			{
				StatusEffect statusEffect = objectDb.GetStatusEffect(StringExtensionMethods.GetStableHashCode(definition.StatusEffectName));
				if ((Object)(object)statusEffect != (Object)null)
				{
					definition.ResolvedStatusEffect = statusEffect;
					TryResolveTrophy(objectDb, definition, (SE_Stats)(object)((statusEffect is SE_Stats) ? statusEffect : null));
					return;
				}
				SE_Stats val = ScriptableObject.CreateInstance<SE_Stats>();
				((Object)val).name = definition.StatusEffectName;
				((StatusEffect)val).m_name = definition.LocalizationKey;
				((StatusEffect)val).m_tooltip = definition.LocalizationKey + "_desc";
				((StatusEffect)val).m_ttl = definition.Duration;
				definition.Tuning.Apply(val);
				TryResolveTrophy(objectDb, definition, val);
				objectDb.m_StatusEffects.Add((StatusEffect)(object)val);
				definition.ResolvedStatusEffect = (StatusEffect)(object)val;
				Debug.Log((object)("[BalrondBoonStone] Registered status effect '" + definition.StatusEffectName + "'"));
			}
		}

		private static void TryResolveTrophy(ObjectDB objectDb, BoonDefinition definition, SE_Stats statusEffect)
		{
			GameObject itemPrefab = objectDb.GetItemPrefab(definition.TrophyPrefabName);
			if ((Object)(object)itemPrefab == (Object)null)
			{
				definition.ResolvedTrophyItem = null;
				return;
			}
			ItemDrop val = (definition.ResolvedTrophyItem = itemPrefab.GetComponent<ItemDrop>());
			if ((Object)(object)statusEffect != (Object)null && (Object)(object)val != (Object)null && val.m_itemData != null && val.m_itemData.m_shared != null && val.m_itemData.m_shared.m_icons != null && val.m_itemData.m_shared.m_icons.Length != 0)
			{
				((StatusEffect)statusEffect).m_icon = val.m_itemData.m_shared.m_icons[0];
			}
		}
	}
	public class BoonStone : MonoBehaviour, Hoverable, Interactable
	{
		public const string BoonCategory = "boonstone_bal";

		private const string ZdoKeyAttachedScale = "boonstone_attached_scale";

		[Header("Texts")]
		public string m_name = "$piece_boonstone_bal";

		public string m_useText = "$piece_boonstone_use";

		public string m_missingText = "$piece_boonstone_missing";

		public string m_invalidText = "$piece_boonstone_invalid";

		public string m_alreadyActiveText = "$piece_boonstone_alreadyactive";

		public string m_otherBoonActiveText = "$piece_boonstone_otheractive";

		public string m_removeText = "$piece_itemstand_take";

		public string m_readText = "$piece_boonstone_read";

		[Header("Fallback rune text")]
		public string m_defaultRuneTopic = "";

		public string m_defaultRuneLabel = "";

		[TextArea]
		public string m_defaultRuneText = "";

		[Header("References")]
		public ItemStand m_itemStand;

		public GameObject m_activeEffect;

		public EffectList m_activateStep1 = new EffectList();

		public EffectList m_activateStep2 = new EffectList();

		public EffectList m_activateStep3 = new EffectList();

		public MeshRenderer m_mesh;

		public int m_emissiveMaterialIndex;

		public Color m_activeEmissiveColor = Color.white;

		[Header("Boon mapping")]
		public List<BoonConversion> m_conversion = new List<BoonConversion>();

		[Header("Attached trophy scale")]
		public float m_scaleStep = 0.1f;

		public float m_minAttachedScale = 0.3f;

		public float m_maxAttachedScale = 2.5f;

		private bool m_visualActive;

		private string m_cachedAttachedItem = "";

		private WearNTear m_wearNTear;

		private float m_nextRefreshTime;

		private float m_nextColliderCleanupTime;

		private float m_nextScaleSyncTime;

		private float m_nextScaleInputTime;

		private float m_cachedAttachedScale = 1f;

		private readonly HashSet<int> m_itemStandOriginalChildren = new HashSet<int>();

		private Transform m_cachedAttachedVisualRoot;

		private Vector3 m_cachedAttachedVisualBaseScale = Vector3.one;

		private string m_cachedVisualItemName = "";

		private void Awake()
		{
			if ((Object)(object)m_itemStand == (Object)null)
			{
				m_itemStand = ((Component)this).GetComponentInChildren<ItemStand>(true);
			}
			CacheInitialItemStandChildren();
			EnsureRuntimeConversions();
			m_cachedAttachedScale = ReadStoredAttachedScale();
			m_wearNTear = ((Component)this).GetComponent<WearNTear>();
			if ((Object)(object)m_wearNTear != (Object)null)
			{
				WearNTear wearNTear = m_wearNTear;
				wearNTear.m_onDestroyed = (Action)Delegate.Combine(wearNTear.m_onDestroyed, new Action(OnDestroyed));
			}
		}

		private void Start()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			RefreshAttachmentCache(force: false);
			if ((Object)(object)m_mesh != (Object)null && ((Renderer)m_mesh).materials != null && ((Renderer)m_mesh).materials.Length > m_emissiveMaterialIndex && (Object)(object)((Renderer)m_mesh).materials[m_emissiveMaterialIndex] != (Object)null && ((Renderer)m_mesh).materials[m_emissiveMaterialIndex].HasProperty("_EmissionColor"))
			{
				((Renderer)m_mesh).materials[m_emissiveMaterialIndex].SetColor("_EmissionColor", Color.black);
			}
			if ((Object)(object)m_activeEffect != (Object)null)
			{
				m_activeEffect.SetActive(false);
			}
			SetActivated(HasAttachment(), triggerEffect: false);
			((MonoBehaviour)this).InvokeRepeating("RefreshState", 0.25f, 0.25f);
			((MonoBehaviour)this).InvokeRepeating("CleanupAttachmentRaycast", 0.25f, 0.5f);
			((MonoBehaviour)this).Invoke("ForceApplyAttachedScale", 0.2f);
			((MonoBehaviour)this).Invoke("ForceApplyAttachedScale", 0.6f);
			((MonoBehaviour)this).Invoke("ForceApplyAttachedScale", 1.2f);
		}

		private void Update()
		{
			SyncAttachedScaleFromZDO();
			HandleAttachedScaleInput();
		}

		private void OnDestroy()
		{
			if ((Object)(object)m_wearNTear != (Object)null)
			{
				WearNTear wearNTear = m_wearNTear;
				wearNTear.m_onDestroyed = (Action)Delegate.Remove(wearNTear.m_onDestroyed, new Action(OnDestroyed));
			}
		}

		private void RefreshState()
		{
			RefreshAttachmentCache(force: false);
			SetActivated(HasAttachment(), triggerEffect: true);
			ApplyAttachedScaleToVisual();
		}

		private void RefreshAttachmentCache(bool force)
		{
			if (!(Time.time < m_nextRefreshTime) || force)
			{
				m_nextRefreshTime = Time.time + 0.1f;
				string cachedAttachedItem = m_cachedAttachedItem;
				m_cachedAttachedItem = GetAttachedItemNameInternal();
				if (!string.Equals(cachedAttachedItem, m_cachedAttachedItem, StringComparison.Ordinal))
				{
					ResetAttachedVisualCache();
					Debug.Log((object)("[BalrondBoonStone] BoonStone '" + ((Object)this).name + "' attached item changed from '" + cachedAttachedItem + "' to '" + m_cachedAttachedItem + "'"));
				}
			}
		}

		private string GetAttachedItemNameInternal()
		{
			if ((Object)(object)m_itemStand == (Object)null)
			{
				return string.Empty;
			}
			try
			{
				string attachedItem = m_itemStand.GetAttachedItem();
				return string.IsNullOrWhiteSpace(attachedItem) ? string.Empty : attachedItem.Trim();
			}
			catch (Exception arg)
			{
				Debug.LogError((object)string.Format("[{0}] Failed reading attached item on '{1}'\n{2}", "BalrondBoonStone", ((Object)this).name, arg));
				return string.Empty;
			}
		}

		private bool HasAttachment()
		{
			return !string.IsNullOrWhiteSpace(m_cachedAttachedItem);
		}

		public string GetHoverName()
		{
			return (Localization.instance != null) ? Localization.instance.Localize(m_name) : m_name;
		}

		public string GetHoverText()
		{
			RefreshAttachmentCache(force: false);
			if (!HasAttachment())
			{
				return (Localization.instance != null) ? Localization.instance.Localize(m_name + "\n[<color=yellow><b>1-8</b></color>] $piece_itemstand_attach") : (m_name + "\nAttach trophy");
			}
			BoonConversion boonConversion = FindConversion(m_cachedAttachedItem);
			if (boonConversion == null || string.IsNullOrWhiteSpace(boonConversion.m_statusEffectName))
			{
				return (Localization.instance != null) ? Localization.instance.Localize(m_name + "\n<color=orange>" + m_invalidText + "</color>") : (m_name + "\nInvalid trophy");
			}
			string text = m_name + " (" + boonConversion.GetLocalizedBoonName() + ")\n[<color=yellow><b>$KEY_Use</b></color>] " + m_useText + "\n[<color=yellow><b>Shift+$KEY_Use</b></color>] " + m_removeText + "\n[<color=yellow><b>Alt+$KEY_Use</b></color>] " + m_readText + "\n[<color=yellow><b>- / +</b></color>] Scale trophy";
			return (Localization.instance != null) ? Localization.instance.Localize(text) : text;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			RefreshAttachmentCache(force: false);
			if (hold)
			{
				return false;
			}
			if ((Object)(object)user == (Object)null)
			{
				return false;
			}
			Player val = (Player)(object)((user is Player) ? user : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (!HasAttachment())
			{
				((Character)user).Message((MessageType)2, m_missingText, 0, (Sprite)null);
				return true;
			}
			BoonConversion boonConversion = FindConversion(m_cachedAttachedItem);
			if (boonConversion == null || string.IsNullOrWhiteSpace(boonConversion.m_statusEffectName))
			{
				((Character)user).Message((MessageType)2, m_invalidText, 0, (Sprite)null);
				return true;
			}
			if (IsAltHeld())
			{
				ShowRuneText(val, boonConversion);
				return true;
			}
			if (IsShiftHeld())
			{
				return RemoveAttachedTrophyToPlayer(val);
			}
			try
			{
				int stableHashCode = StringExtensionMethods.GetStableHashCode(boonConversion.m_statusEffectName);
				if (((Character)val).GetSEMan().HaveStatusEffect(stableHashCode))
				{
					((Character)val).Message((MessageType)2, m_alreadyActiveText, 0, (Sprite)null);
					return true;
				}
				if (HasAnyOtherBoon(val, stableHashCode))
				{
					((Character)val).Message((MessageType)2, m_otherBoonActiveText, 0, (Sprite)null);
					return true;
				}
				StatusEffect val2 = ((Character)val).GetSEMan().AddStatusEffect(stableHashCode, true, 0, 0f);
				if ((Object)(object)val2 == (Object)null)
				{
					Debug.LogWarning((object)("[BalrondBoonStone] AddStatusEffect returned null for '" + boonConversion.m_statusEffectName + "'"));
					return true;
				}
				m_activateStep1.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1);
				m_activateStep2.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1);
				m_activateStep3.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1);
				((Character)user).Message((MessageType)2, "$msg_boonstone_received " + boonConversion.GetLocalizedBoonName(), 0, (Sprite)null);
				return true;
			}
			catch (Exception arg)
			{
				Debug.LogError((object)string.Format("[{0}] Failed to apply boon from '{1}'\n{2}", "BalrondBoonStone", m_cachedAttachedItem, arg));
				return true;
			}
		}

		private void EnsureRuntimeConversions()
		{
			if (m_conversion != null && m_conversion.Count > 0)
			{
				bool flag = false;
				for (int i = 0; i < m_conversion.Count; i++)
				{
					BoonConversion boonConversion = m_conversion[i];
					if (boonConversion != null && !string.IsNullOrWhiteSpace(boonConversion.m_trophyPrefabName))
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					return;
				}
			}
			m_conversion = BoonRegistry.CreateRuntimeConversions();
			Debug.Log((object)string.Format("[{0}] Rebuilt runtime conversion list on '{1}', count={2}", "BalrondBoonStone", ((Object)this).name, m_conversion.Count));
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			RefreshAttachmentCache(force: false);
			if ((Object)(object)user == (Object)null || item == null || (Object)(object)m_itemStand == (Object)null)
			{
				return false;
			}
			if (HasAttachment())
			{
				((Character)user).Message((MessageType)2, "$msg_itsfull", 0, (Sprite)null);
				return true;
			}
			if (!IsSupportedTrophy(item))
			{
				((Character)user).Message((MessageType)2, m_invalidText, 0, (Sprite)null);
				return true;
			}
			bool flag = m_itemStand.UseItem(user, item);
			if (flag)
			{
				((MonoBehaviour)this).Invoke("ForceRefreshAfterAttach", 0.15f);
				((MonoBehaviour)this).Invoke("ForceRefreshAfterAttach", 0.5f);
				((MonoBehaviour)this).Invoke("ForceRefreshAfterAttach", 1f);
				((MonoBehaviour)this).Invoke("CleanupAttachmentRaycast", 0.2f);
				((MonoBehaviour)this).Invoke("CleanupAttachmentRaycast", 0.6f);
				((MonoBehaviour)this).Invoke("CleanupAttachmentRaycast", 1.2f);
				((MonoBehaviour)this).Invoke("ForceApplyAttachedScale", 0.2f);
				((MonoBehaviour)this).Invoke("ForceApplyAttachedScale", 0.6f);
				((MonoBehaviour)this).Invoke("ForceApplyAttachedScale", 1.2f);
			}
			return flag;
		}

		private void ForceRefreshAfterAttach()
		{
			RefreshAttachmentCache(force: true);
			SetActivated(HasAttachment(), triggerEffect: true);
		}

		private bool RemoveAttachedTrophyToPlayer(Player player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)m_itemStand == (Object)null || !HasAttachment())
			{
				return false;
			}
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				Debug.LogWarning((object)"[BalrondBoonStone] ZNetView invalid on BoonStone");
				return false;
			}
			string cachedAttachedItem = m_cachedAttachedItem;
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(cachedAttachedItem) : null);
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogWarning((object)("[BalrondBoonStone] Missing trophy prefab '" + cachedAttachedItem + "'"));
				return false;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val);
			ItemDrop component2 = val2.GetComponent<ItemDrop>();
			if ((Object)(object)component2 == (Object)null || component2.m_itemData == null)
			{
				Object.Destroy((Object)(object)val2);
				Debug.LogWarning((object)("[BalrondBoonStone] Invalid ItemDrop on trophy prefab '" + cachedAttachedItem + "'"));
				return false;
			}
			component2.LoadFromExternalZDO(component.GetZDO());
			ItemData val3 = component2.m_itemData.Clone();
			val3.m_stack = 1;
			bool flag = ((Humanoid)player).GetInventory().AddItem(val3);
			Object.Destroy((Object)(object)val2);
			if (!flag)
			{
				((Character)player).Message((MessageType)2, "$inventory_full", 0, (Sprite)null);
				return true;
			}
			((Character)player).Message((MessageType)2, "$piece_itemstand_take", 0, (Sprite)null);
			if (!component.IsOwner())
			{
				component.InvokeRPC("RPC_RequestOwn", Array.Empty<object>());
			}
			ZDO zDO = component.GetZDO();
			if (zDO != null)
			{
				zDO.Set(ZDOVars.s_item, "");
				zDO.Set(ZDOVars.s_type, 0, false);
			}
			component.InvokeRPC(ZNetView.Everybody, "SetVisualItem", new object[4] { "", 0, 0, 0 });
			ResetAttachedVisualCache();
			RefreshAttachmentCache(force: true);
			SetActivated(active: false, triggerEffect: false);
			return true;
		}

		private bool IsSupportedTrophy(ItemData item)
		{
			if (item == null || (Object)(object)item.m_dropPrefab == (Object)null)
			{
				return false;
			}
			return FindConversion(((Object)item.m_dropPrefab).name) != null;
		}

		private void SetActivated(bool active, bool triggerEffect)
		{
			if (active == m_visualActive)
			{
				return;
			}
			m_visualActive = active;
			if (triggerEffect && active)
			{
				((MonoBehaviour)this).CancelInvoke("DelayedAttachEffectsStep1");
				((MonoBehaviour)this).CancelInvoke("DelayedAttachEffectsStep2");
				((MonoBehaviour)this).CancelInvoke("DelayedAttachEffectsStep3");
				((MonoBehaviour)this).Invoke("DelayedAttachEffectsStep1", 0.2f);
				((MonoBehaviour)this).Invoke("DelayedAttachEffectsStep2", 0.6f);
				((MonoBehaviour)this).Invoke("DelayedAttachEffectsStep3", 1f);
			}
			else
			{
				if ((Object)(object)m_activeEffect != (Object)null)
				{
					m_activeEffect.SetActive(active);
				}
				((MonoBehaviour)this).StopCoroutine("FadeEmission");
				((MonoBehaviour)this).StartCoroutine("FadeEmission");
			}
		}

		private void DelayedAttachEffectsStep1()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_itemStand != (Object)null)
			{
				m_activateStep1.Create(((Component)m_itemStand).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1);
			}
		}

		private void DelayedAttachEffectsStep2()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			m_activateStep2.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1);
		}

		private void DelayedAttachEffectsStep3()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_activeEffect != (Object)null)
			{
				m_activeEffect.SetActive(true);
			}
			m_activateStep3.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1);
			((MonoBehaviour)this).StopCoroutine("FadeEmission");
			((MonoBehaviour)this).StartCoroutine("FadeEmission");
		}

		private IEnumerator FadeEmission()
		{
			if ((Object)(object)m_mesh != (Object)null && ((Renderer)m_mesh).materials != null && ((Renderer)m_mesh).materials.Length > m_emissiveMaterialIndex && (Object)(object)((Renderer)m_mesh).materials[m_emissiveMaterialIndex] != (Object)null && ((Renderer)m_mesh).materials[m_emissiveMaterialIndex].HasProperty("_EmissionColor"))
			{
				Material material = ((Renderer)m_mesh).materials[m_emissiveMaterialIndex];
				Color startColor = material.GetColor("_EmissionColor");
				Color targetColor = (m_visualActive ? m_activeEmissiveColor : Color.black);
				for (float t = 0f; t < 1f; t += Time.deltaTime)
				{
					material.SetColor("_EmissionColor", Color.Lerp(startColor, targetColor, t));
					yield return null;
				}
				material.SetColor("_EmissionColor", targetColor);
			}
		}

		private BoonConversion FindConversion(string attachedPrefabName)
		{
			if (string.IsNullOrWhiteSpace(attachedPrefabName))
			{
				return null;
			}
			for (int i = 0; i < m_conversion.Count; i++)
			{
				BoonConversion boonConversion = m_conversion[i];
				if (boonConversion != null && !string.IsNullOrWhiteSpace(boonConversion.m_trophyPrefabName) && string.Equals(boonConversion.m_trophyPrefabName.Trim(), attachedPrefabName.Trim(), StringComparison.Ordinal))
				{
					return boonConversion;
				}
			}
			return null;
		}

		private void ShowRuneText(Player player, BoonConversion conversion)
		{
			if (!((Object)(object)player == (Object)null) && conversion != null)
			{
				string text = conversion.GetLocalizedRuneTopic();
				string text2 = conversion.GetLocalizedRuneLabel();
				string text3 = conversion.GetLocalizedRuneText();
				if (string.IsNullOrWhiteSpace(text))
				{
					text = ((Localization.instance != null) ? Localization.instance.Localize(m_defaultRuneTopic) : m_defaultRuneTopic);
				}
				if (string.IsNullOrWhiteSpace(text2))
				{
					text2 = ((Localization.instance != null) ? Localization.instance.Localize(m_defaultRuneLabel) : m_defaultRuneLabel);
				}
				if (string.IsNullOrWhiteSpace(text3))
				{
					text3 = ((Localization.instance != null) ? Localization.instance.Localize(m_defaultRuneText) : m_defaultRuneText);
				}
				if (!string.IsNullOrWhiteSpace(text2) && !string.IsNullOrWhiteSpace(text3))
				{
					player.AddKnownText(text2, text3);
				}
				if (!string.IsNullOrWhiteSpace(text3) && (Object)(object)TextViewer.instance != (Object)null)
				{
					TextViewer.instance.ShowText((Style)0, text, text3, true);
				}
			}
		}

		private bool HasAnyOtherBoon(Player player, int currentHash)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			foreach (BoonDefinition definition in BoonRegistry.Definitions)
			{
				if (definition != null && !string.IsNullOrWhiteSpace(definition.StatusEffectName))
				{
					int stableHashCode = StringExtensionMethods.GetStableHashCode(definition.StatusEffectName);
					if (stableHashCode != currentHash && ((Character)player).GetSEMan().HaveStatusEffect(stableHashCode))
					{
						return true;
					}
				}
			}
			return false;
		}

		private void CleanupAttachmentRaycast()
		{
			if (Time.time < m_nextColliderCleanupTime)
			{
				return;
			}
			m_nextColliderCleanupTime = Time.time + 0.2f;
			if ((Object)(object)m_itemStand == (Object)null)
			{
				return;
			}
			int num = LayerMask.NameToLayer("Ignore Raycast");
			if (num < 0)
			{
				return;
			}
			Transform transform = ((Component)m_itemStand).transform;
			Collider[] componentsInChildren = ((Component)transform).GetComponentsInChildren<Collider>(true);
			Collider[] array = componentsInChildren;
			foreach (Collider val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					((Component)val).gameObject.layer = num;
				}
			}
		}

		private void OnDestroyed()
		{
			try
			{
				DropAttachedTrophyOnDestroy();
			}
			catch (Exception arg)
			{
				Debug.LogError((object)string.Format("[{0}] OnDestroyed failed\n{1}", "BalrondBoonStone", arg));
			}
		}

		private void DropAttachedTrophyOnDestroy()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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)
			RefreshAttachmentCache(force: false);
			if (!HasAttachment())
			{
				return;
			}
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(m_cachedAttachedItem) : null);
			if (!((Object)(object)val == (Object)null))
			{
				Transform val2 = (((Object)(object)m_itemStand != (Object)null && (Object)(object)m_itemStand.m_dropSpawnPoint != (Object)null) ? m_itemStand.m_dropSpawnPoint : ((Component)this).transform);
				GameObject val3 = Object.Instantiate<GameObject>(val, val2.position, val2.rotation);
				ItemDrop component = val3.GetComponent<ItemDrop>();
				if ((Object)(object)component != (Object)null)
				{
					ItemDrop.OnCreateNew(component);
				}
				Rigidbody component2 = val3.GetComponent<Rigidbody>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.linearVelocity = Vector3.up * 3f;
				}
			}
		}

		private void CacheInitialItemStandChildren()
		{
			m_itemStandOriginalChildren.Clear();
			if ((Object)(object)m_itemStand == (Object)null)
			{
				return;
			}
			Transform[] componentsInChildren = ((Component)m_itemStand).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					m_itemStandOriginalChildren.Add(((Object)val).GetInstanceID());
				}
			}
		}

		private void ResetAttachedVisualCache()
		{
			//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)
			m_cachedAttachedVisualRoot = null;
			m_cachedAttachedVisualBaseScale = Vector3.one;
			m_cachedVisualItemName = "";
		}

		private float ReadStoredAttachedScale()
		{
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid() || component.GetZDO() == null)
			{
				return 1f;
			}
			return Mathf.Clamp(component.GetZDO().GetFloat("boonstone_attached_scale", 1f), m_minAttachedScale, m_maxAttachedScale);
		}

		private void SyncAttachedScaleFromZDO()
		{
			if (!(Time.time < m_nextScaleSyncTime))
			{
				m_nextScaleSyncTime = Time.time + 0.15f;
				float num = ReadStoredAttachedScale();
				if (Mathf.Abs(num - m_cachedAttachedScale) > 0.001f)
				{
					m_cachedAttachedScale = num;
					ApplyAttachedScaleToVisual();
				}
				else if (HasAttachment())
				{
					ApplyAttachedScaleToVisual();
				}
			}
		}

		private void ForceApplyAttachedScale()
		{
			m_cachedAttachedScale = ReadStoredAttachedScale();
			ApplyAttachedScaleToVisual();
		}

		private void HandleAttachedScaleInput()
		{
			if (HasAttachment() && IsLocalPlayerAimingAtStone() && !(Time.time < m_nextScaleInputTime))
			{
				if (IsDecreaseScalePressed())
				{
					ChangeAttachedScale(0f - m_scaleStep);
					m_nextScaleInputTime = Time.time + 0.12f;
				}
				else if (IsIncreaseScalePressed())
				{
					ChangeAttachedScale(m_scaleStep);
					m_nextScaleInputTime = Time.time + 0.12f;
				}
			}
		}

		private void ChangeAttachedScale(float delta)
		{
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid() && component.GetZDO() != null)
			{
				if (!component.IsOwner())
				{
					component.ClaimOwnership();
				}
				float @float = component.GetZDO().GetFloat("boonstone_attached_scale", 1f);
				float num = Mathf.Clamp(@float + delta, m_minAttachedScale, m_maxAttachedScale);
				if (!(Mathf.Abs(num - @float) <= 0.0001f))
				{
					component.GetZDO().Set("boonstone_attached_scale", num);
					m_cachedAttachedScale = num;
					ApplyAttachedScaleToVisual();
				}
			}
		}

		private void ApplyAttachedScaleToVisual()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			if (!HasAttachment() || (Object)(object)m_itemStand == (Object)null)
			{
				return;
			}
			Transform val = FindAttachedVisualRoot();
			if (!((Object)(object)val == (Object)null))
			{
				if ((Object)(object)m_cachedAttachedVisualRoot != (Object)(object)val || !string.Equals(m_cachedVisualItemName, m_cachedAttachedItem, StringComparison.Ordinal))
				{
					m_cachedAttachedVisualRoot = val;
					m_cachedAttachedVisualBaseScale = val.localScale;
					m_cachedVisualItemName = m_cachedAttachedItem;
				}
				Vector3 val2 = m_cachedAttachedVisualBaseScale * m_cachedAttachedScale;
				if (val.localScale != val2)
				{
					val.localScale = val2;
				}
			}
		}

		private Transform FindAttachedVisualRoot()
		{
			if ((Object)(object)m_itemStand == (Object)null)
			{
				return null;
			}
			Transform[] componentsInChildren = ((Component)m_itemStand).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)((Component)m_itemStand).transform || m_itemStandOriginalChildren.Contains(((Object)val).GetInstanceID()))
				{
					continue;
				}
				Transform parent = val.parent;
				if ((Object)(object)parent == (Object)null || m_itemStandOriginalChildren.Contains(((Object)parent).GetInstanceID()))
				{
					Renderer[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Renderer>(true);
					if (componentsInChildren2 != null && componentsInChildren2.Length != 0)
					{
						return val;
					}
				}
			}
			return null;
		}

		private bool IsLocalPlayerAimingAtStone()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return false;
			}
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(((Component)main).transform.position, ((Component)main).transform.forward);
			RaycastHit val2 = default(RaycastHit);
			if (!Physics.Raycast(val, ref val2, 10f, -5, (QueryTriggerInteraction)1))
			{
				return false;
			}
			Transform transform = ((RaycastHit)(ref val2)).transform;
			if ((Object)(object)transform == (Object)null)
			{
				return false;
			}
			return (Object)(object)transform == (Object)(object)((Component)this).transform || transform.IsChildOf(((Component)this).transform);
		}

		private static bool IsDecreaseScalePressed()
		{
			return Input.GetKeyDown((KeyCode)45) || Input.GetKeyDown((KeyCode)269);
		}

		private static bool IsIncreaseScalePressed()
		{
			return Input.GetKeyDown((KeyCode)61) || Input.GetKeyDown((KeyCode)270);
		}

		private static bool IsShiftHeld()
		{
			return Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303);
		}

		private static bool IsAltHeld()
		{
			return Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307);
		}
	}
	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, "BalrondBoonStone-translation/");
			defaultPath = text;
		}

		public void createDefaultPath()
		{
			string configPath = Paths.ConfigPath;
			string text = Path.Combine(configPath, "BalrondBoonStone-translation/");
			if (!Directory.Exists(text))
			{
				CreateFolder(text);
			}
			else
			{
				Debug.Log((object)("BalrondBoonStone: Folder already exists: " + text));
			}
			defaultPath = text;
		}

		private string[] jsonFilePath(string folderName, string extension)
		{
			string configPath = Paths.ConfigPath;
			string text = Path.Combine(configPath, "BalrondBoonStone-translation/");
			if (!Directory.Exists(text))
			{
				CreateFolder(text);
			}
			else
			{
				Debug.Log((object)("BalrondBoonStone: Folder already exists: " + text));
			}
			string[] files = Directory.GetFiles(text, extension);
			Debug.Log((object)("BalrondBoonStone:" + folderName + " Json Files Found: " + files.Length));
			return files;
		}

		private static void CreateFolder(string path)
		{
			try
			{
				Directory.CreateDirectory(path);
				Debug.Log((object)"BalrondBoonStone: Folder created successfully.");
			}
			catch (Exception ex)
			{
				Debug.Log((object)("BalrondBoonStone: 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);
					Debug.Log((object)("BalrondBoonStone: Json Files Language: " + fileNameWithoutExtension));
					num++;
				}
				else
				{
					Debug.LogError((object)("BalrondBoonStone: Loading FAILED file: " + text));
				}
			}
			Debug.Log((object)("BalrondBoonStone: Translation JsonFiles Loaded: " + num));
		}
	}
	[BepInPlugin("balrond.astafaraios.BalrondBoonStone", "BalrondBoonStone", "1.0.0")]
	public class Launch : BaseUnityPlugin
	{
		public const string PluginGUID = "balrond.astafaraios.BalrondBoonStone";

		public const string PluginName = "BalrondBoonStone";

		public const string PluginVersion = "1.0.0";

		public static JsonLoader jsonLoader = new JsonLoader();

		public static Launch Instance { get; private set; }

		public static Harmony Harmony { get; private set; }

		public static ModResourceLoader ResourceLoader { get; private set; }

		public static AssetBundle MainAssetBundle { get; private set; }

		public static GameObject BoonStonePrefab { get; private set; }

		public static int BoonStonePrefabHash { get; private set; }

		private void Awake()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			Instance = this;
			try
			{
				jsonLoader.loadJson();
				ResourceLoader = new ModResourceLoader();
				ResourceLoader.LoadAssets();
				MainAssetBundle = ResourceLoader.assetBundle;
				BoonStonePrefab = ResourceLoader.BoonStonePrefab;
				if ((Object)(object)BoonStonePrefab == (Object)null)
				{
					throw new Exception("BoonStonePrefab is null after loading assets.");
				}
				BoonStonePrefabHash = StringExtensionMethods.GetStableHashCode(((Object)BoonStonePrefab).name);
				Harmony = new Harmony("balrond.astafaraios.BalrondBoonStone");
				Harmony.PatchAll();
				Debug.Log((object)"[BalrondBoonStone] Awake completed");
			}
			catch (Exception arg)
			{
				Debug.LogError((object)string.Format("[{0}] Awake failed\n{1}", "BalrondBoonStone", arg));
			}
		}

		private void OnDestroy()
		{
			try
			{
				Harmony harmony = Harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
				AssetBundle mainAssetBundle = MainAssetBundle;
				if (mainAssetBundle != null)
				{
					mainAssetBundle.Unload(false);
				}
			}
			catch (Exception arg)
			{
				Debug.LogError((object)string.Format("[{0}] OnDestroy failed\n{1}", "BalrondBoonStone", arg));
			}
		}
	}
	public class ModResourceLoader
	{
		public AssetBundle assetBundle;

		public GameObject BoonStonePrefab;

		private const string AssetBundleResourceName = "balrondboonstone";

		private const string BoonStonePrefabPath = "Assets/Custom/BalrondBoonStone/BoonStone_bal.prefab";

		public void LoadAssets()
		{
			assetBundle = GetAssetBundleFromResources("balrondboonstone");
			if ((Object)(object)assetBundle == (Object)null)
			{
				throw new Exception("Could not load embedded asset bundle: balrondboonstone");
			}
			BoonStonePrefab = assetBundle.LoadAsset<GameObject>("Assets/Custom/BalrondBoonStone/BoonStone_bal.prefab");
			if ((Object)(object)BoonStonePrefab == (Object)null)
			{
				string text = string.Join(", ", assetBundle.GetAllAssetNames());
				throw new Exception("Could not load prefab: Assets/Custom/BalrondBoonStone/BoonStone_bal.prefab\nAssets in bundle:\n" + text);
			}
			Debug.Log((object)"[BalrondBoonStone] Loaded prefab from bundle: Assets/Custom/BalrondBoonStone/BoonStone_bal.prefab");
		}

		private AssetBundle GetAssetBundleFromResources(string filename)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = null;
			string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
			foreach (string text2 in manifestResourceNames)
			{
				if (text2.EndsWith(filename, StringComparison.OrdinalIgnoreCase))
				{
					text = text2;
					break;
				}
			}
			if (text == null)
			{
				Debug.LogError((object)("[BalrondBoonStone] Embedded resource not found: " + filename));
				Debug.LogError((object)("[BalrondBoonStone] Available resources: " + string.Join(", ", executingAssembly.GetManifestResourceNames())));
				return null;
			}
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				Debug.LogError((object)("[BalrondBoonStone] Resource stream is null: " + text));
				return null;
			}
			return AssetBundle.LoadFromStream(stream);
		}
	}
	[HarmonyPatch]
	public static class Patches
	{
		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		private static class ZNetScene_Awake_Patch
		{
			private static void Postfix(ZNetScene __instance)
			{
				try
				{
					if (!((Object)(object)__instance == (Object)null) && !((Object)(object)Launch.BoonStonePrefab == (Object)null))
					{
						PrefabSetup.SetupAndRegisterBoonStonePrefab(__instance, Launch.BoonStonePrefab);
						PrefabSetup.TryRegisterPieceToHammer(__instance, Launch.BoonStonePrefab);
						Debug.Log((object)"[BalrondBoonStone] ZNetScene patch completed");
					}
				}
				catch (Exception arg)
				{
					Debug.LogError((object)string.Format("[{0}] ZNetScene patch failed\n{1}", "BalrondBoonStone", arg));
				}
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		[HarmonyPostfix]
		private static void ObjectDB_Awake_Postfix(ObjectDB __instance)
		{
			try
			{
				if (!((Object)(object)__instance == (Object)null))
				{
					Debug.Log((object)"[BalrondBoonStone] ObjectDB Awake detected");
					((MonoBehaviour)Launch.Instance).StartCoroutine(ObjectDBDelayedInit());
				}
			}
			catch (Exception arg)
			{
				Debug.LogError((object)string.Format("[{0}] ObjectDB patch failed\n{1}", "BalrondBoonStone", arg));
			}
		}

		private static IEnumerator ObjectDBDelayedInit()
		{
			int attempts = 0;
			while (!IsObjectDBValid())
			{
				attempts++;
				if (attempts > 50)
				{
					Debug.LogError((object)"[BalrondBoonStone] ObjectDB never became valid!");
					yield break;
				}
				yield return null;
			}
			Debug.Log((object)string.Format("[{0}] ObjectDB is valid after {1} frames", "BalrondBoonStone", attempts));
			BoonStatusEffectFactory.RegisterAll(ObjectDB.instance);
		}

		private static bool IsObjectDBValid()
		{
			ObjectDB instance = ObjectDB.instance;
			return (Object)(object)instance != (Object)null && instance.m_items != null && instance.m_items.Count != 0 && instance.m_recipes != null && instance.m_recipes.Count != 0 && (Object)(object)instance.GetItemPrefab("Amber") != (Object)null;
		}
	}
	public static class PrefabSetup
	{
		private static ZNetScene m_znetScene;

		public static void SetupAndRegisterBoonStonePrefab(ZNetScene zNetScene, GameObject prefab)
		{
			if ((Object)(object)zNetScene == (Object)null || (Object)(object)prefab == (Object)null)
			{
				Debug.LogWarning((object)"[BalrondBoonStone] SetupAndRegisterBoonStonePrefab failed: null argument");
				return;
			}
			m_znetScene = zNetScene;
			ConfigureBoonStonePrefab(zNetScene, prefab);
			if (!zNetScene.m_prefabs.Contains(prefab))
			{
				zNetScene.m_prefabs.Add(prefab);
				Debug.Log((object)("[BalrondBoonStone] Added '" + ((Object)prefab).name + "' to ZNetScene.m_prefabs"));
			}
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name);
			if (!zNetScene.m_namedPrefabs.ContainsKey(stableHashCode))
			{
				zNetScene.m_namedPrefabs.Add(stableHashCode, prefab);
				Debug.Log((object)("[BalrondBoonStone] Added '" + ((Object)prefab).name + "' to ZNetScene.m_namedPrefabs"));
			}
		}

		public static void TryRegisterPieceToHammer(ZNetScene zNetScene, GameObject piecePrefab)
		{
			if ((Object)(object)zNetScene == (Object)null || (Object)(object)piecePrefab == (Object)null)
			{
				Debug.LogWarning((object)"[BalrondBoonStone] TryRegisterPieceToHammer failed: null argument");
				return;
			}
			GameObject val = FindPrefabInZNet("Hammer", zNetScene);
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogWarning((object)"[BalrondBoonStone] Hammer prefab not found in ZNetScene");
				return;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null)
			{
				Debug.LogWarning((object)"[BalrondBoonStone] Hammer ItemDrop data missing");
				return;
			}
			PieceTable buildPieces = component.m_itemData.m_shared.m_buildPieces;
			if ((Object)(object)buildPieces == (Object)null)
			{
				Debug.LogWarning((object)"[BalrondBoonStone] Hammer PieceTable missing");
			}
			else if (!buildPieces.m_pieces.Contains(piecePrefab))
			{
				buildPieces.m_pieces.Add(piecePrefab);
				Debug.Log((object)("[BalrondBoonStone] Registered '" + ((Object)piecePrefab).name + "' to Hammer PieceTable"));
			}
		}

		public static void ConfigureBoonStonePrefab(ZNetScene zNetScene, GameObject prefab)
		{
			if (!((Object)(object)prefab == (Object)null))
			{
				Debug.Log((object)("[BalrondBoonStone] Configuring BoonStone prefab '" + ((Object)prefab).name + "'"));
				RuneStone component = prefab.GetComponent<RuneStone>();
				BoonStone boonStone = ReplaceBossStone(prefab);
				if ((Object)(object)component != (Object)null)
				{
					CopyRuneStoneFields(component, boonStone);
					Object.DestroyImmediate((Object)(object)component);
					Debug.Log((object)("[BalrondBoonStone] Removed RuneStone component from '" + ((Object)prefab).name + "'"));
				}
				ConfigureBoonStoneTexts(boonStone);
				ConfigureItemStand(prefab, boonStone);
				BuildConversions(boonStone);
				ConfigurePiece(zNetScene, prefab);
				SetupRavenGuide(prefab, zNetScene);
				ValidatePiece(prefab);
				Debug.Log((object)("[BalrondBoonStone] Finished configuring '" + ((Object)prefab).name + "'"));
			}
		}

		private static BoonStone ReplaceBossStone(GameObject prefab)
		{
			BoonStone boonStone = prefab.GetComponent<BoonStone>();
			if ((Object)(object)boonStone == (Object)null)
			{
				boonStone = prefab.AddComponent<BoonStone>();
				Debug.Log((object)("[BalrondBoonStone] Added BoonStone component to '" + ((Object)prefab).name + "'"));
			}
			BossStone component = prefab.GetComponent<BossStone>();
			if ((Object)(object)component != (Object)null)
			{
				CopyBossStoneFields(component, boonStone);
				Object.DestroyImmediate((Object)(object)component);
				Debug.Log((object)("[BalrondBoonStone] Removed BossStone component from '" + ((Object)prefab).name + "'"));
			}
			return boonStone;
		}

		private static void CopyBossStoneFields(BossStone source, BoonStone target)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null))
			{
				target.m_itemStand = source.m_itemStand;
				target.m_activeEffect = source.m_activeEffect;
				target.m_activateStep1 = source.m_activateStep1;
				target.m_activateStep2 = source.m_activateStep2;
				target.m_activateStep3 = source.m_activateStep3;
				target.m_mesh = source.m_mesh;
				target.m_emissiveMaterialIndex = source.m_emissiveMaterialIndex;
				target.m_activeEmissiveColor = source.m_activeEmissiveColor;
			}
		}

		private static void CopyRuneStoneFields(RuneStone source, BoonStone target)
		{
			if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null))
			{
				target.m_defaultRuneTopic = source.m_topic;
				target.m_defaultRuneLabel = source.m_label;
				target.m_defaultRuneText = source.m_text;
			}
		}

		private static void ConfigureBoonStoneTexts(BoonStone boonStone)
		{
			if (!((Object)(object)boonStone == (Object)null))
			{
				boonStone.m_name = "$piece_boonstone_bal";
				boonStone.m_useText = "$piece_boonstone_use";
				boonStone.m_missingText = "$piece_boonstone_missing";
				boonStone.m_invalidText = "$piece_boonstone_invalid";
				boonStone.m_alreadyActiveText = "$piece_boonstone_alreadyactive";
				boonStone.m_otherBoonActiveText = "$piece_boonstone_otheractive";
				boonStone.m_removeText = "$piece_itemstand_take";
				boonStone.m_readText = "$piece_boonstone_read";
			}
		}

		private static void ConfigureItemStand(GameObject prefab, BoonStone boonStone)
		{
			if ((Object)(object)prefab == (Object)null || (Object)(object)boonStone == (Object)null)
			{
				return;
			}
			ItemStand val = (boonStone.m_itemStand = (((Object)(object)boonStone.m_itemStand != (Object)null) ? boonStone.m_itemStand : prefab.GetComponentInChildren<ItemStand>(true)));
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogWarning((object)("[BalrondBoonStone] No ItemStand found on '" + ((Object)prefab).name + "'"));
				return;
			}
			val.m_canBeRemoved = false;
			val.m_autoAttach = false;
			val.m_supportedItems.Clear();
			int num = LayerMask.NameToLayer("Ignore Raycast");
			if (num >= 0)
			{
				Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren<Transform>(true);
				foreach (Transform val2 in componentsInChildren)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						((Component)val2).gameObject.layer = num;
					}
				}
			}
			Debug.Log((object)("[BalrondBoonStone] ItemStand configured on '" + ((Object)prefab).name + "'"));
		}

		private static void BuildConversions(BoonStone boonStone)
		{
			if ((Object)(object)boonStone == (Object)null)
			{
				return;
			}
			boonStone.m_conversion = BoonRegistry.CreateRuntimeConversions();
			ItemStand itemStand = boonStone.m_itemStand;
			if ((Object)(object)itemStand != (Object)null)
			{
				itemStand.m_supportedItems.Clear();
				for (int i = 0; i < boonStone.m_conversion.Count; i++)
				{
					BoonConversion boonConversion = boonStone.m_conversion[i];
					if (boonConversion != null && !((Object)(object)boonConversion.m_trophyItem == (Object)null) && !itemStand.m_supportedItems.Contains(boonConversion.m_trophyItem))
					{
						itemStand.m_supportedItems.Add(boonConversion.m_trophyItem);
					}
				}
			}
			Debug.Log((object)string.Format("[{0}] Built {1} conversions", "BalrondBoonStone", boonStone.m_conversion.Count));
		}

		private static GameObject GetRavenGuidePrefab(ZNetScene zNetScene)
		{
			GameObject val = FindPrefabInZNet("Ravens", zNetScene);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			GameObject val2 = FindPrefabInZNet("piece_workbench", zNetScene);
			if ((Object)(object)val2 != (Object)null)
			{
				Transform val3 = val2.transform.Find("GuidePoint");
				if ((Object)(object)val3 != (Object)null)
				{
					GuidePoint component = ((Component)val3).GetComponent<GuidePoint>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.m_ravenPrefab != (Object)null)
					{
						return component.m_ravenPrefab;
					}
				}
			}
			return null;
		}

		private static void SetupRavenGuide(GameObject prefab, ZNetScene zNetScene)
		{
			if ((Object)(object)prefab == (Object)null || (Object)(object)zNetScene == (Object)null)
			{
				return;
			}
			GuidePoint componentInChildren = prefab.GetComponentInChildren<GuidePoint>(true);
			if (!((Object)(object)componentInChildren == (Object)null))
			{
				GameObject ravenGuidePrefab = GetRavenGuidePrefab(zNetScene);
				if ((Object)(object)ravenGuidePrefab == (Object)null)
				{
					Debug.LogWarning((object)("[BalrondBoonStone] Ravens prefab not found for GuidePoint on '" + ((Object)prefab).name + "'"));
					return;
				}
				componentInChildren.m_ravenPrefab = ravenGuidePrefab;
				Debug.Log((object)("[BalrondBoonStone] Assigned Raven prefab to GuidePoint on '" + ((Object)prefab).name + "'"));
			}
		}

		private static void ConfigurePiece(ZNetScene zNetScene, GameObject prefab)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)prefab == (Object)null))
			{
				Piece component = prefab.GetComponent<Piece>();
				if ((Object)(object)component == (Object)null)
				{
					Debug.LogWarning((object)("[BalrondBoonStone] Prefab '" + ((Object)prefab).name + "' has no Piece"));
					return;
				}
				component.m_name = "$piece_boonstone_bal";
				component.m_description = "$guide_boonstone_text";
				component.m_category = (PieceCategory)0;
				SetStation(component, FindCraftingStation("piece_stonecutter", zNetScene));
				component.m_resources = (Requirement[])(object)new Requirement[0];
				AddResource(component, "Stone", 20);
				AddResource(component, "SurtlingCore", 1);
				AddResource(component, "Chain", 1, 0, recover: false);
				Debug.Log((object)string.Format("[{0}] Piece '{1}' configured with {2} resources", "BalrondBoonStone", ((Object)prefab).name, component.m_resources.Length));
			}
		}

		private static void SetStation(Piece piece, CraftingStation station)
		{
			if (!((Object)(object)piece == (Object)null))
			{
				piece.m_craftingStation = station;
			}
		}

		private static CraftingStation FindCraftingStation(string prefabName, ZNetScene zNetScene)
		{
			if ((Object)(object)zNetScene == (Object)null)
			{
				return null;
			}
			GameObject val = FindPrefabInZNet(prefabName, zNetScene);
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogWarning((object)("[BalrondBoonStone] Could not find station prefab '" + prefabName + "'"));
				return null;
			}
			CraftingStation component = val.GetComponent<CraftingStation>();
			if ((Object)(object)component == (Object)null)
			{
				Debug.LogWarning((object)("[BalrondBoonStone] Prefab '" + prefabName + "' has no CraftingStation"));
			}
			return component;
		}

		private static void AddResource(Piece piece, string itemName, int amount, int amountPerLevel = 0, bool recover = true)
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			if ((Object)(object)piece == (Object)null || (Object)(object)m_znetScene == (Object)null)
			{
				Debug.LogWarning((object)("[BalrondBoonStone] AddResource failed for '" + itemName + "'"));
				return;
			}
			List<Requirement> list = new List<Requirement>();
			if (piece.m_resources != null)
			{
				list.AddRange(piece.m_resources);
			}
			GameObject val = FindPrefabInZNet(itemName, m_znetScene);
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogWarning((object)("[BalrondBoonStone] AddResource: could not find item '" + itemName + "' in ZNetScene"));
				return;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				Debug.LogWarning((object)("[BalrondBoonStone] AddResource: item '" + itemName + "' has no ItemDrop"));
				return;
			}
			list.Add(new Requirement
			{
				m_resItem = component,
				m_amount = amount,
				m_amountPerLevel = amountPerLevel,
				m_recover = recover
			});
			piece.m_resources = list.ToArray();
		}

		private static GameObject FindPrefabInZNet(string name, ZNetScene zNetScene)
		{
			if ((Object)(object)zNetScene == (Object)null || string.IsNullOrWhiteSpace(name))
			{
				return null;
			}
			if (!zNetScene.m_namedPrefabs.TryGetValue(StringExtensionMethods.GetStableHashCode(name), out var value))
			{
				value = zNetScene.m_prefabs.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == name);
			}
			return value;
		}

		private static void ValidatePiece(GameObject prefab)
		{
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			Piece component = prefab.GetComponent<Piece>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			Debug.Log((object)("[BalrondBoonStone] ValidatePiece '" + ((Object)prefab).name + "' station=" + (((Object)(object)component.m_craftingStation != (Object)null) ? ((Object)component.m_craftingStation).name : "NULL")));
			if (component.m_resources == null)
			{
				Debug.LogWarning((object)("[BalrondBoonStone] Piece '" + ((Object)prefab).name + "' has NULL resources"));
				return;
			}
			for (int i = 0; i < component.m_resources.Length; i++)
			{
				Requirement val = component.m_resources[i];
				if (val == null || (Object)(object)val.m_resItem == (Object)null)
				{
					Debug.LogWarning((object)string.Format("[{0}] Piece '{1}' resource[{2}] invalid", "BalrondBoonStone", ((Object)prefab).name, i));
					continue;
				}
				Debug.Log((object)string.Format("[{0}] Resource[{1}] {2} x{3} recover={4}", "BalrondBoonStone", i, ((Object)val.m_resItem).name, val.m_amount, val.m_recover));
			}
		}
	}
	[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)("BalrondBoonStone: 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)"BalrondBoonStone: 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);
			}
		}
	}
}
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 ne