Decompiled source of HeimLifeTweaks v1.4.7

HeimLifeTweaks.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace HeimLifeTweaks;

[Flags]
public enum KilnWoodTypes
{
	None = 0,
	Wood = 1,
	CoreWood = 2,
	FineWood = 4,
	YggdrasilWood = 8
}
[BepInPlugin("HeimLifeTweaks.Valheim", "HeimLifeTweaks", "1.5.2")]
public class HeimLifeTweaksPlugin : BaseUnityPlugin
{
	private sealed class CircletLightOriginal
	{
		internal bool Enabled;

		internal float Range;

		internal float Intensity;

		internal float SpotAngle;

		internal Color Color;
	}

	public const string PluginGuid = "HeimLifeTweaks.Valheim";

	public const string PluginName = "HeimLifeTweaks";

	public const string PluginVersion = "1.5.2";

	internal static HeimLifeTweaksPlugin Instance;

	internal static ConfigEntry<bool> MasterEnabled;

	internal static ConfigEntry<bool> CircletEnabled;

	internal static ConfigEntry<float> CircletBrightness;

	internal static ConfigEntry<float> CircletRange;

	internal static ConfigEntry<int> CircletFocusSteps;

	internal static ConfigEntry<KeyboardShortcut> CircletNarrowKey;

	internal static ConfigEntry<KeyboardShortcut> CircletWidenKey;

	internal static ConfigEntry<KeyboardShortcut> CircletToggleKey;

	internal static ConfigEntry<bool> SkipIntroEnabled;

	internal static ConfigEntry<bool> WaterEquipmentEnabled;

	internal static ConfigEntry<bool> FermenterEnabled;

	internal static ConfigEntry<bool> FermenterShowProgress;

	internal static ConfigEntry<float> FermenterMinutes;

	internal static ConfigEntry<bool> FermenterNoCover;

	internal static ConfigEntry<bool> NoRainDamageEnabled;

	internal static ConfigEntry<bool> MapTeleportEnabled;

	internal static ConfigEntry<bool> BuildSpaceEnabled;

	internal static ConfigEntry<float> BuildRadiusMultiplier;

	internal static ConfigEntry<bool> FasterBoatsEnabled;

	internal static ConfigEntry<float> BoatWindMultiplier;

	internal static ConfigEntry<float> BoatRudderMultiplier;

	internal static ConfigEntry<bool> QuickCartEnabled;

	internal static ConfigEntry<KeyboardShortcut> QuickCartHotkey;

	internal static ConfigEntry<float> QuickCartDistance;

	internal static ConfigEntry<bool> QuickCartOutOfPlace;

	internal static ConfigEntry<bool> RegenerationEnabled;

	internal static ConfigEntry<float> StaminaCostMultiplier;

	internal static ConfigEntry<float> StaminaRegenMultiplier;

	internal static ConfigEntry<float> StaminaRegenDelayMultiplier;

	internal static ConfigEntry<float> EitrRegenRate;

	internal static ConfigEntry<float> HealthRegenMultiplier;

	internal static ConfigEntry<float> HealthRegenDelayMultiplier;

	internal static ConfigEntry<bool> AutoConsumeExtraSlotsFood;

	internal static ConfigEntry<bool> PathfinderEnabled;

	internal static ConfigEntry<bool> PathfinderDisableInDungeons;

	internal static ConfigEntry<float> LandExploreRadius;

	internal static ConfigEntry<float> SeaExploreRadius;

	internal static ConfigEntry<float> AltitudeExploreBonus;

	internal static ConfigEntry<bool> CarryWeightEnabled;

	internal static ConfigEntry<float> CarryWeightMultiplier;

	internal static ConfigEntry<bool> FastToolsEnabled;

	internal static ConfigEntry<float> PlaceDelay;

	internal static ConfigEntry<float> RemoveDelay;

	internal static ConfigEntry<float> BuildStaminaMultiplier;

	internal static ConfigEntry<bool> DigDeeperEnabled;

	internal static ConfigEntry<float> DigDepth;

	internal static ConfigEntry<float> RaiseHeight;

	internal static ConfigEntry<bool> BossPowersEnabled;

	internal static ConfigEntry<bool> BossPowersRequireDefeat;

	internal static ConfigEntry<bool> BossEikthyrEnabled;

	internal static ConfigEntry<float> EikthyrRunStaminaReduction;

	internal static ConfigEntry<float> EikthyrJumpStaminaReduction;

	internal static ConfigEntry<float> EikthyrSwimStaminaReduction;

	internal static ConfigEntry<bool> BossElderEnabled;

	internal static ConfigEntry<float> ElderChopDamage;

	internal static ConfigEntry<float> ElderPickaxeDamage;

	internal static ConfigEntry<float> ElderHealthRegen;

	internal static ConfigEntry<bool> BossBonemassEnabled;

	internal static ConfigEntry<float> BonemassBluntResistance;

	internal static ConfigEntry<float> BonemassSlashResistance;

	internal static ConfigEntry<float> BonemassPierceResistance;

	internal static ConfigEntry<float> BonemassBlockStaminaReduction;

	internal static ConfigEntry<float> BonemassStaminaReturn;

	internal static ConfigEntry<bool> BossModerEnabled;

	internal static ConfigEntry<bool> ModerTailwind;

	internal static ConfigEntry<float> ModerCarryWeight;

	internal static ConfigEntry<float> ModerMovementSpeed;

	internal static ConfigEntry<float> ModerFrostResistance;

	internal static ConfigEntry<bool> BossYagluthEnabled;

	internal static ConfigEntry<float> YagluthLightningResistance;

	internal static ConfigEntry<float> YagluthFarmingSkill;

	internal static ConfigEntry<float> YagluthDamage;

	internal static ConfigEntry<bool> BossQueenEnabled;

	internal static ConfigEntry<float> QueenEitrRegen;

	internal static ConfigEntry<float> QueenSneakStaminaReduction;

	internal static ConfigEntry<float> QueenPoisonResistance;

	internal static ConfigEntry<bool> BossFaderEnabled;

	internal static ConfigEntry<float> FaderAdrenalineGain;

	internal static ConfigEntry<float> FaderStaggerReduction;

	internal static ConfigEntry<float> FaderFireResistance;

	internal static ConfigEntry<bool> BeehiveEnabled;

	internal static ConfigEntry<float> HoneyProductionSeconds;

	internal static ConfigEntry<int> MaximumHoney;

	internal static ConfigEntry<bool> NearbyStorageEnabled;

	internal static ConfigEntry<bool> AutoSortEnabled;

	internal static ConfigEntry<KeyboardShortcut> AutoSortHotkey;

	internal static ConfigEntry<bool> CraftFromChestsEnabled;

	internal static ConfigEntry<bool> BuildFromChestsEnabled;

	internal static ConfigEntry<bool> UseItemsFromChestsEnabled;

	internal static ConfigEntry<bool> ShowHaveNeedCounts;

	internal static ConfigEntry<float> StorageRadius;

	internal static ConfigEntry<bool> RecyclingEnabled;

	internal static ConfigEntry<KeyboardShortcut> RecyclingHotkey;

	internal static ConfigEntry<bool> AutoCraftingEnabled;

	internal static ConfigEntry<bool> AutoCraftingAutoRefillLights;

	internal static ConfigEntry<float> AutoCraftingRange;

	internal static ConfigEntry<float> AutoCraftingInterval;

	internal static ConfigEntry<bool> AutoCraftingLeaveOneInput;

	internal static ConfigEntry<bool> AutoCraftingDepositOutputs;

	internal static ConfigEntry<bool> AutoCraftingWoodChests;

	internal static ConfigEntry<bool> AutoCraftingReinforcedChests;

	internal static ConfigEntry<bool> AutoCraftingBlackMetalChests;

	internal static ConfigEntry<bool> AutoCraftingPersonalChests;

	internal static ConfigEntry<bool> AutoCraftingCartContainers;

	internal static ConfigEntry<bool> AutoCraftingShipContainers;

	internal static ConfigEntry<bool> AutoCraftingOtherContainers;

	internal static ConfigEntry<int> AutoCraftingKilnCharcoalTarget;

	internal static ConfigEntry<KilnWoodTypes> AutoCraftingKilnWoodTypes;

	internal static ConfigEntry<int> AutoCraftingStationsPerTick;

	internal static ConfigEntry<float> AutoCraftingContainerCacheSeconds;

	internal static ConfigEntry<bool> AutoCraftingAutoPopCookingStations;

	internal static ConfigEntry<bool> HuntingGroundsEnabled;

	internal static ConfigEntry<float> HuntingSpawnRadius;

	internal static ConfigEntry<int> HuntingDeerCap;

	internal static ConfigEntry<int> HuntingBoarCap;

	internal static ConfigEntry<int> HuntingNeckCap;

	internal static ConfigEntry<int> HuntingOtherCap;

	internal static ConfigEntry<float> HuntingSpawnInterval;

	internal static ConfigEntry<float> HuntingPlayerRange;

	private readonly List<Harmony> _featureHarmonies = new List<Harmony>();

	private float _nextUtilityUpdate;

	private float _nextExtraSlotsFoodUpdate;

	private int _circletStep;

	private bool _circletLightOn = true;

	private Player _circletCachedPlayer;

	private Light[] _circletCachedLights;

	private float _nextCircletRescan;

	private float _nextBossPowerUpdate;

	private Player _bossHealthTrackedPlayer;

	private float _bossBaselineMaxHealth;

	private static readonly string[] ManagedBossEffects = new string[7] { "GP_Eikthyr", "GP_TheElder", "GP_Bonemass", "GP_Moder", "GP_Yagluth", "GP_Queen", "GP_Fader" };

	private readonly Dictionary<int, CircletLightOriginal> _circletOriginals = new Dictionary<int, CircletLightOriginal>();

	private void Awake()
	{
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b7f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b89: Expected O, but got Unknown
		//IL_0bd7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c78: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c82: Expected O, but got Unknown
		//IL_0cb5: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		MasterEnabled = Bind("00 - General", "Enabled", value: true, "Master switch for HeimLifeTweaks.");
		CircletEnabled = Bind("01 - Dverger Circlet", "Enabled", value: true, "Improve the Dverger Circlet light.");
		CircletBrightness = BindFloat("01 - Dverger Circlet", "Brightness", 2f, 0.25f, 5f, "Circlet light brightness.");
		CircletRange = BindFloat("01 - Dverger Circlet", "Range", 35f, 5f, 80f, "Maximum circlet beam range.");
		CircletFocusSteps = BindInt("01 - Dverger Circlet", "Focus Steps", 4, 2, 8, "Number of beam focus steps.");
		CircletNarrowKey = Bind<KeyboardShortcut>("01 - Dverger Circlet", "Narrow Beam Key", new KeyboardShortcut((KeyCode)91, (KeyCode[])(object)new KeyCode[0]), "Narrow the light beam.");
		CircletWidenKey = Bind<KeyboardShortcut>("01 - Dverger Circlet", "Widen Beam Key", new KeyboardShortcut((KeyCode)93, (KeyCode[])(object)new KeyCode[0]), "Widen the light beam.");
		CircletToggleKey = Bind<KeyboardShortcut>("01 - Dverger Circlet", "Toggle Light Key", new KeyboardShortcut((KeyCode)108, (KeyCode[])(object)new KeyCode[0]), "Toggle circlet light on or off.");
		SkipIntroEnabled = Bind("02 - Skip Intro", "Enabled", value: true, "Skip the startup intro video and logos.");
		WaterEquipmentEnabled = Bind("03 - Equipment In Water", "Enabled", value: true, "Allow equipment and tools to stay usable while swimming.");
		FermenterEnabled = Bind("04 - Fermenter", "Enabled", value: true, "Enable fermenter quality-of-life tweaks.");
		FermenterShowProgress = Bind("04 - Fermenter", "Show Progress", value: true, "Show fermentation progress while hovering.");
		FermenterMinutes = BindFloat("04 - Fermenter", "Fermentation Minutes", 40f, 1f, 120f, "Minutes required to finish fermenting.");
		FermenterNoCover = Bind("04 - Fermenter", "Work Without Cover", value: false, "Allow fermenters to work without cover.");
		NoRainDamageEnabled = Bind("05 - Rain Damage", "No Rain Damage", value: true, "Prevent uncovered structures from taking rain wear.");
		MapTeleportEnabled = Bind("06 - Map Teleport", "Enabled", value: true, "Hold Shift and press T while the large map is open to teleport to the cursor.");
		BuildSpaceEnabled = Bind("07 - Build Space", "Enabled", value: true, "Increase crafting-station build radius.");
		BuildRadiusMultiplier = BindFloat("07 - Build Space", "Build Radius Multiplier", 2f, 1f, 10f, "Multiplier for crafting-station build radius.");
		FasterBoatsEnabled = Bind("08 - Faster Boats", "Enabled", value: true, "Increase boat movement speed.");
		BoatWindMultiplier = BindFloat("08 - Faster Boats", "Wind Speed Multiplier", 2.5f, 1f, 5f, "Multiplier for wind-driven sail force.");
		BoatRudderMultiplier = BindFloat("08 - Faster Boats", "Rudder Speed Multiplier", 2.25f, 1f, 5f, "Multiplier for paddle/rudder force.");
		QuickCartEnabled = Bind("09 - Quick Cart", "Enabled", value: true, "Quickly attach or detach the nearest cart.");
		QuickCartHotkey = Bind<KeyboardShortcut>("09 - Quick Cart", "Hotkey", new KeyboardShortcut((KeyCode)118, (KeyCode[])(object)new KeyCode[0]), "Attach/detach the nearest cart.");
		QuickCartDistance = BindFloat("09 - Quick Cart", "Attach Distance", 5f, 1f, 12f, "Maximum distance to find a cart.");
		QuickCartOutOfPlace = Bind("09 - Quick Cart", "Allow Out Of Place Attach", value: true, "Allow attaching even if the cart is slightly out of its normal attach position.");
		RegenerationEnabled = Bind("10 - Regeneration", "Enabled", value: true, "Enable stamina, health, and eitr regeneration tweaks.");
		StaminaCostMultiplier = BindFloat("10 - Regeneration", "Stamina Cost Multiplier", 1f, 0f, 2f, "0 = no stamina cost, 1 = vanilla, 2 = double.");
		StaminaRegenMultiplier = BindFloat("10 - Regeneration", "Stamina Regen Multiplier", 1f, 0.1f, 5f, "Multiplier for stamina regeneration.");
		StaminaRegenDelayMultiplier = BindFloat("10 - Regeneration", "Stamina Regen Delay Multiplier", 1f, 0f, 2f, "Multiplier for stamina regeneration delay.");
		EitrRegenRate = BindFloat("10 - Regeneration", "Eitr Regen Rate", 5f, 0f, 20f, "Base eitr regeneration rate.");
		HealthRegenMultiplier = BindFloat("10 - Regeneration", "Health Regen Multiplier", 1f, 0.1f, 5f, "Multiplier for player health regeneration.");
		HealthRegenDelayMultiplier = BindFloat("10 - Regeneration", "Health Regen Delay Multiplier", 1f, 0.1f, 2f, "Multiplier for food health-regeneration delay.");
		AutoConsumeExtraSlotsFood = Bind("10 - Regeneration", "Auto Consume ExtraSlots Food", value: true, "Automatically consume food placed in ExtraSlots food slots whenever an active food slot is available.");
		PathfinderEnabled = Bind("11 - Pathfinder", "Enabled", value: true, "Increase map exploration radius.");
		PathfinderDisableInDungeons = Bind("11 - Pathfinder", "Disable In Dungeons", value: true, "Automatically suspend Pathfinder map revealing inside instanced dungeons and resume it in the overworld.");
		LandExploreRadius = BindFloat("11 - Pathfinder", "Land Explore Radius", 200f, 50f, 2000f, "Map reveal radius while travelling on land.");
		SeaExploreRadius = BindFloat("11 - Pathfinder", "Sea Explore Radius", 300f, 50f, 2000f, "Map reveal radius while attached to a ship.");
		AltitudeExploreBonus = BindFloat("11 - Pathfinder", "Altitude Bonus", 0.5f, 0f, 2f, "Additional land reveal radius per 100m of altitude, as a multiplier.");
		CarryWeightEnabled = Bind("12 - Carry Weight", "Enabled", value: true, "Modify maximum carry weight.");
		CarryWeightMultiplier = BindFloat("12 - Carry Weight", "Carry Weight Multiplier", 2f, 1f, 10f, "Multiplier for maximum carry weight.");
		FastToolsEnabled = Bind("13 - Fast Tools", "Enabled", value: true, "Speed up hammer/hoe/cultivator placement and removal.");
		PlaceDelay = BindFloat("13 - Fast Tools", "Place Delay", 0.1f, 0f, 1f, "Delay in seconds between placements. Vanilla is about 0.4.");
		RemoveDelay = BindFloat("13 - Fast Tools", "Remove Delay", 0.1f, 0f, 1f, "Delay in seconds between removals. Vanilla is about 0.25.");
		BuildStaminaMultiplier = BindFloat("13 - Fast Tools", "Build Stamina Multiplier", 1f, 0f, 2f, "Multiplier for placement-tool stamina cost.");
		DigDeeperEnabled = Bind("14 - Dig Deeper", "Enabled", value: true, "Increase terrain digging and raising limits.");
		DigDepth = BindFloat("14 - Dig Deeper", "Maximum Dig Depth", 16f, 8f, 128f, "Maximum terrain depth. Vanilla is 8.");
		RaiseHeight = BindFloat("14 - Dig Deeper", "Maximum Raise Height", 16f, 8f, 128f, "Maximum terrain raising height. Vanilla is 8.");
		BossPowersEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Keep selected unlocked Forsaken powers active passively and permanently.");
		BossPowersRequireDefeat = Bind("15 - BossPowers", "Require Boss Defeated", value: true, "Only grant a power after its boss has been defeated in this world.");
		BossEikthyrEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable Eikthyr's passive power.");
		EikthyrRunStaminaReduction = BindFloat("15 - BossPowers", "Run Stamina Reduction %", 60f, 0f, 100f, "Percent less stamina used while running.");
		EikthyrJumpStaminaReduction = BindFloat("15 - BossPowers", "Jump Stamina Reduction %", 60f, 0f, 100f, "Percent less stamina used while jumping.");
		EikthyrSwimStaminaReduction = BindFloat("15 - BossPowers", "Swim Stamina Reduction %", 60f, 0f, 100f, "Percent less stamina used while swimming.");
		BossElderEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable The Elder's passive power.");
		ElderChopDamage = BindFloat("15 - BossPowers", "Chop Damage %", 60f, 0f, 500f, "Bonus chopping damage percent.");
		ElderPickaxeDamage = BindFloat("15 - BossPowers", "Pickaxe Damage %", 60f, 0f, 500f, "Bonus pickaxe/mining damage percent.");
		ElderHealthRegen = BindFloat("15 - BossPowers", "Health Regen %", 30f, 0f, 500f, "Bonus health regeneration percent.");
		BossBonemassEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable Bonemass's passive power.");
		BonemassBluntResistance = BindFloat("15 - BossPowers", "Blunt Resistance %", 25f, 0f, 100f, "Physical resistance setting.");
		BonemassSlashResistance = BindFloat("15 - BossPowers", "Slash Resistance %", 25f, 0f, 100f, "Physical resistance setting.");
		BonemassPierceResistance = BindFloat("15 - BossPowers", "Pierce Resistance %", 25f, 0f, 100f, "Physical resistance setting.");
		BonemassBlockStaminaReduction = BindFloat("15 - BossPowers", "Block Stamina Reduction %", 100f, 0f, 100f, "Percent less stamina used when blocking.");
		BonemassStaminaReturn = BindFloat("15 - BossPowers", "Stamina Returned Per Block", 5f, 0f, 100f, "Flat stamina returned when blocking.");
		BossModerEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable Moder's passive power.");
		ModerTailwind = Bind("15 - BossPowers", "Always Tailwind", value: true, "Keep Moder's sailing tailwind effect enabled.");
		ModerCarryWeight = BindFloat("15 - BossPowers", "Carry Weight Bonus", 300f, 0f, 5000f, "Flat carry weight bonus.");
		ModerMovementSpeed = BindFloat("15 - BossPowers", "Movement Speed %", 10f, 0f, 500f, "Bonus movement speed percent.");
		ModerFrostResistance = BindFloat("15 - BossPowers", "Frost Resistance %", 50f, 0f, 100f, "Frost resistance setting.");
		BossYagluthEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable Yagluth's passive power.");
		YagluthLightningResistance = BindFloat("15 - BossPowers", "Lightning Resistance %", 50f, 0f, 100f, "Lightning resistance setting.");
		YagluthFarmingSkill = BindFloat("15 - BossPowers", "Farming Skill Bonus", 25f, 0f, 500f, "Flat Farming skill bonus.");
		YagluthDamage = BindFloat("15 - BossPowers", "Damage %", 10f, 0f, 500f, "Bonus outgoing damage percent.");
		BossQueenEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable The Queen's passive power.");
		QueenEitrRegen = BindFloat("15 - BossPowers", "Eitr Regen %", 100f, 0f, 1000f, "Bonus Eitr regeneration percent.");
		QueenSneakStaminaReduction = BindFloat("15 - BossPowers", "Sneak Stamina Reduction %", 100f, 0f, 100f, "Percent less stamina used while sneaking.");
		QueenPoisonResistance = BindFloat("15 - BossPowers", "Poison Resistance %", 50f, 0f, 100f, "Poison resistance setting.");
		BossFaderEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable Fader's passive power.");
		FaderAdrenalineGain = BindFloat("15 - BossPowers", "Adrenaline Gain %", 100f, 0f, 1000f, "Bonus Adrenaline gain percent.");
		FaderStaggerReduction = BindFloat("15 - BossPowers", "Stagger Meter Reduction %", 50f, 0f, 100f, "Percent reduction to the stagger meter modifier.");
		FaderFireResistance = BindFloat("15 - BossPowers", "Fire Resistance %", 50f, 0f, 100f, "Fire resistance setting.");
		BeehiveEnabled = Bind("16 - Beehives", "Enabled", value: true, "Enable configurable honey production.");
		HoneyProductionSeconds = BindFloat("16 - Beehives", "Honey Production Seconds", 600f, 1f, 1200f, "Seconds required to produce one honey. Vanilla is 1200. Minimum is 1 second.");
		MaximumHoney = ((BaseUnityPlugin)this).Config.Bind<int>("16 - Beehives", "Maximum Honey", 4, new ConfigDescription("Maximum honey stored in each hive. Type the number you want.", (AcceptableValueBase)null, new object[0]));
		NearbyStorageEnabled = Bind("17 - Nearby Storage", "Enabled", value: true, "Enable nearby storage quality-of-life features.");
		AutoSortEnabled = Bind("17 - Nearby Storage", "Auto Sort", value: true, "Press the hotkey to move normal backpack items into nearby chests that already contain the same item.");
		AutoSortHotkey = Bind<KeyboardShortcut>("17 - Nearby Storage", "Auto Sort Hotkey", new KeyboardShortcut((KeyCode)46, (KeyCode[])(object)new KeyCode[0]), "Hotkey for matching-chest auto sort. Default is period (.).");
		CraftFromChestsEnabled = Bind("17 - Nearby Storage", "Craft From Chests", value: true, "Crafting can count and consume materials from nearby containers.");
		BuildFromChestsEnabled = Bind("17 - Nearby Storage", "Build From Chests", value: true, "Building pieces, ships, and other placeables can count and consume materials from nearby containers.");
		UseItemsFromChestsEnabled = Bind("17 - Nearby Storage", "Use Items From Chests", value: true, "Kilns, smelters, and fireplaces can use required items from nearby containers when you interact with them.");
		ShowHaveNeedCounts = Bind("17 - Nearby Storage", "Show Have Need Counts", value: true, "Show available / required material counts using inventory plus nearby containers.");
		StorageRadius = ((BaseUnityPlugin)this).Config.Bind<float>("17 - Nearby Storage", "Storage Radius", 20f, new ConfigDescription("Radius in meters used by nearby storage features. Type any positive value you want.", (AcceptableValueBase)null, new object[0]));
		RecyclingEnabled = Bind("18 - Recycling", "Enabled", value: true, "Recycle the inventory item under the mouse cursor back into its original recipe materials. Items without a recipe are deleted.");
		RecyclingHotkey = Bind<KeyboardShortcut>("18 - Recycling", "Recycle Hotkey", new KeyboardShortcut((KeyCode)127, (KeyCode[])(object)new KeyCode[0]), "Recycle or delete the hovered inventory item. Default: Delete.");
		AutoCraftingEnabled = Bind("19 - AutoCrafting", "Enabled", value: true, "Automatically feed loaded production stations from nearby allowed containers and route finished outputs into matching containers.");
		AutoCraftingAutoRefillLights = Bind("19 - AutoCrafting", "Auto Refill Lights", value: true, "Automatically refuel Fireplace-based lights and fires from nearby allowed storage.");
		AutoCraftingRange = BindFloat("19 - AutoCrafting", "Container Range", 20f, 1f, 50f, "Maximum distance in meters from a station to pull from or deposit into containers.");
		AutoCraftingInterval = BindFloat("19 - AutoCrafting", "Refill Interval Seconds", 1f, 0.25f, 10f, "How often loaded production stations check nearby containers for inputs.");
		AutoCraftingLeaveOneInput = Bind("19 - AutoCrafting", "Leave One Input In Chest", value: true, "Keep at least one of each station input in its source chest for sorting/reference.");
		AutoCraftingDepositOutputs = Bind("19 - AutoCrafting", "Deposit Outputs Into Matching Chests", value: true, "Move station outputs into a nearby allowed chest that already contains that item. If none exists or it is full, the output drops normally.");
		AutoCraftingWoodChests = Bind("19 - AutoCrafting", "Wood Chests", value: true, "Allow basic wooden chests.");
		AutoCraftingReinforcedChests = Bind("19 - AutoCrafting", "Reinforced Chests", value: true, "Allow reinforced/iron chests.");
		AutoCraftingBlackMetalChests = Bind("19 - AutoCrafting", "Black Metal Chests", value: true, "Allow black metal chests.");
		AutoCraftingPersonalChests = Bind("19 - AutoCrafting", "Personal Chests", value: false, "Allow personal/private chests.");
		AutoCraftingCartContainers = Bind("19 - AutoCrafting", "Cart Storage", value: false, "Allow cart storage.");
		AutoCraftingShipContainers = Bind("19 - AutoCrafting", "Ship Storage", value: false, "Allow ship storage.");
		AutoCraftingOtherContainers = Bind("19 - AutoCrafting", "Other Or Modded Containers", value: false, "Allow containers that do not match a known vanilla chest/storage category.");
		AutoCraftingKilnCharcoalTarget = BindInt("19 - AutoCrafting", "Kiln Charcoal Target", 50, 0, 5000, "Stop automatically feeding wood into charcoal kilns when nearby allowed containers already contain at least this much charcoal. 0 = unlimited.");
		AutoCraftingKilnWoodTypes = ((BaseUnityPlugin)this).Config.Bind<KilnWoodTypes>("19 - AutoCrafting", "Kiln Wood Types", KilnWoodTypes.Wood, "Select which wood types AutoCrafting may feed into charcoal kilns. Default is regular Wood only. This is a multi-select flags box in Configuration Manager.");
		AutoCraftingStationsPerTick = BindInt("19 - AutoCrafting", "Stations Processed Per Tick", 2, 1, 20, "Performance control. Lower values spread AutoCrafting work across frames and reduce spikes.");
		AutoCraftingContainerCacheSeconds = BindFloat("19 - AutoCrafting", "Container Cache Seconds", 3f, 0.5f, 30f, "How long each station reuses its nearby-container list before refreshing it.");
		AutoCraftingAutoPopCookingStations = Bind("19 - AutoCrafting", "Auto Pop Cooking Stations", value: true, "Automatically eject cooked food as soon as it reaches the finished state so it cannot burn.");
		HuntingGroundsEnabled = Bind("20 - Hunting Grounds", "Enabled", value: true, "Add placeable hunting-ground spawners for vanilla mobs, labeled and grouped by biome in the hammer Misc category.");
		HuntingSpawnRadius = BindFloat("20 - Hunting Grounds", "Spawn Radius", 30f, 5f, 50f, "Animals spawn randomly between 5 meters and this radius from their spawner.");
		HuntingDeerCap = BindInt("20 - Hunting Grounds", "Deer Population Cap", 10, 1, 50, "Maximum deer maintained inside a Deer Spawner's radius.");
		HuntingBoarCap = BindInt("20 - Hunting Grounds", "Boar Population Cap", 10, 1, 50, "Maximum boars maintained inside a Boar Spawner's radius.");
		HuntingNeckCap = BindInt("20 - Hunting Grounds", "Neck Population Cap", 10, 1, 50, "Maximum necks maintained inside a Neck Spawner's radius.");
		HuntingOtherCap = BindInt("20 - Hunting Grounds", "Other Mob Population Cap", 6, 1, 50, "Population cap used by the biome mob spawner variants.");
		HuntingSpawnInterval = BindFloat("20 - Hunting Grounds", "Spawn Interval Seconds", 15f, 5f, 120f, "When below the local population cap, spawn one animal this often.");
		HuntingPlayerRange = BindFloat("20 - Hunting Grounds", "Player Activation Range", 100f, 20f, 200f, "Spawner only operates while the local player is within this distance.");
		((BaseUnityPlugin)this).Config.SettingChanged += OnAnySettingChanged;
		RefreshFeaturePatches();
		if (AutoCraftingEnabled.Value)
		{
			AutoCrafting.RefreshExistingWorldObjects();
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)"HeimLifeTweaks v1.5.2 loaded.");
	}

	private ConfigEntry<T> Bind<T>(string section, string name, T value, string description)
	{
		return ((BaseUnityPlugin)this).Config.Bind<T>(section, name, value, description);
	}

	private ConfigEntry<float> BindFloat(string section, string name, float value, float min, float max, string description)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		return ((BaseUnityPlugin)this).Config.Bind<float>(section, name, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), new object[0]));
	}

	private ConfigEntry<int> BindInt(string section, string name, int value, int min, int max, string description)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		return ((BaseUnityPlugin)this).Config.Bind<int>(section, name, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(min, max), new object[0]));
	}

	private void OnAnySettingChanged(object sender, SettingChangedEventArgs args)
	{
		try
		{
			if (args == null || args.ChangedSetting == null)
			{
				return;
			}
			string text = args.ChangedSetting.Definition.Section ?? "";
			string text2 = args.ChangedSetting.Definition.Key ?? "";
			if (text2 == "Enabled")
			{
				RefreshFeaturePatches();
			}
			if (text.StartsWith("15", StringComparison.Ordinal))
			{
				_nextBossPowerUpdate = 0f;
			}
			if (text == "19 - AutoCrafting")
			{
				AutoCrafting.InvalidateConfigCaches();
				if (AutoCraftingEnabled.Value)
				{
					AutoCrafting.RefreshExistingWorldObjects();
				}
			}
			if (text == "20 - Hunting Grounds" && HuntingGroundsEnabled.Value)
			{
				HuntingGrounds.EnsureRegistered();
			}
		}
		catch
		{
		}
	}

	private void RefreshFeaturePatches()
	{
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Expected O, but got Unknown
		for (int i = 0; i < _featureHarmonies.Count; i++)
		{
			try
			{
				_featureHarmonies[i].UnpatchSelf();
			}
			catch
			{
			}
		}
		_featureHarmonies.Clear();
		if (!MasterEnabled.Value)
		{
			return;
		}
		Type[] types = Assembly.GetExecutingAssembly().GetTypes();
		foreach (Type type in types)
		{
			object[] customAttributes = type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true);
			if (customAttributes != null && customAttributes.Length != 0 && ShouldPatchFeature(type))
			{
				try
				{
					Harmony val = new Harmony("HeimLifeTweaks.Valheim." + type.Name);
					val.PatchAll(type);
					_featureHarmonies.Add(val);
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Patch failed for " + type.Name + ": " + ex.Message));
				}
			}
		}
	}

	private bool ShouldPatchFeature(Type t)
	{
		switch (t.Name)
		{
		case "SkipIntroCoroutinePatch":
			return SkipIntroEnabled.Value;
		case "EquipmentInWaterUpdatePatch":
		case "EquipmentInWaterEquipPatch":
			return WaterEquipmentEnabled.Value;
		case "FermenterAwakePatch":
		case "FermenterHoverPatch":
		case "FermenterCoverPatch":
			return FermenterEnabled.Value;
		case "NoRainDamagePatch":
			return NoRainDamageEnabled.Value;
		case "BuildSpacePatch":
			return BuildSpaceEnabled.Value;
		case "FasterBoatWindPatch":
		case "FasterBoatRudderPatch":
			return FasterBoatsEnabled.Value;
		case "QuickCartAttachPatch":
			return QuickCartEnabled.Value;
		case "StaminaUsePatch":
		case "RegenStatsPatch":
		case "HealthRegenDelayPatch":
		case "HealthRegenAmountPatch":
			return RegenerationEnabled.Value;
		case "CarryWeightPatch":
			return CarryWeightEnabled.Value;
		case "PathfinderPatch":
			return PathfinderEnabled.Value;
		case "BuildStaminaPatch":
		case "FastToolsPlacementPatch":
			return FastToolsEnabled.Value;
		case "DigDeeperHeightmapPatch":
		case "DigDeeperApplyToHeightmapPatch":
		case "DigDeeperTerrainLevelPatch":
		case "DigDeeperTerrainRaisePatch":
			return DigDeeperEnabled.Value;
		case "BeehiveUpdatePatch":
		case "BeehiveHoverPatch":
			return BeehiveEnabled.Value;
		case "DisableGuardianPowerActivationPatch":
		case "ElderResourceDamagePatch":
			return BossPowersEnabled.Value;
		case "NearbyStorageContainerRegistryPatch":
			if (!NearbyStorageEnabled.Value)
			{
				return AutoCraftingEnabled.Value;
			}
			return true;
		case "NearbyStorageBuildCheckContextPatch":
			if (NearbyStorageEnabled.Value)
			{
				return BuildFromChestsEnabled.Value;
			}
			return false;
		case "NearbyStorageCraftCheckContextPatch":
			if (NearbyStorageEnabled.Value)
			{
				return CraftFromChestsEnabled.Value;
			}
			return false;
		case "NearbyStorageBuildActionContextPatch":
			if (NearbyStorageEnabled.Value)
			{
				return BuildFromChestsEnabled.Value;
			}
			return false;
		case "NearbyStorageCraftActionContextPatch":
			if (NearbyStorageEnabled.Value)
			{
				return CraftFromChestsEnabled.Value;
			}
			return false;
		case "NearbyStorageCountItemsPatch":
		case "NearbyStorageHaveItemPatch":
		case "NearbyStorageConsumeResourcesPatch":
			if (NearbyStorageEnabled.Value)
			{
				if (!CraftFromChestsEnabled.Value)
				{
					return BuildFromChestsEnabled.Value;
				}
				return true;
			}
			return false;
		case "NearbyStorageRequirementUiPatch":
			if (NearbyStorageEnabled.Value && ShowHaveNeedCounts.Value)
			{
				if (!CraftFromChestsEnabled.Value)
				{
					return BuildFromChestsEnabled.Value;
				}
				return true;
			}
			return false;
		case "NearbyStorageSwitchInteractPatch":
		case "NearbyStorageFireplaceInteractPatch":
			if (NearbyStorageEnabled.Value)
			{
				return UseItemsFromChestsEnabled.Value;
			}
			return false;
		case "AutoCraftingEitrRefineryRegistryPatch":
			if (AutoCraftingEnabled.Value)
			{
				return AutoCrafting.GetEitrRefineryType() != null;
			}
			return false;
		case "AutoCraftingFireplaceRegistryPatch":
		case "AutoCraftingSmelterRegistryPatch":
		case "AutoCraftingCookingStationRegistryPatch":
		case "AutoCraftingFermenterRegistryPatch":
		case "AutoCraftingOutputRoutingPatch":
		case "AutoCraftingMessageSuppressPatch":
		case "AutoCraftingCookingAutoPopPatch":
			return AutoCraftingEnabled.Value;
		case "HuntingGroundsZNetScenePatch":
		case "HuntingGroundPlacementPatch":
		case "HuntingGroundMarkerRestorePatch":
		case "HuntingGroundContainerBlockInteractPatch":
			return HuntingGroundsEnabled.Value;
		case "NoRainDamageApplyDamagePatch":
			return NoRainDamageEnabled.Value;
		default:
			return false;
		}
	}

	internal static bool On(ConfigEntry<bool> feature)
	{
		if ((Object)(object)Instance != (Object)null && MasterEnabled.Value)
		{
			return feature.Value;
		}
		return false;
	}

	private void OnDestroy()
	{
		try
		{
			((BaseUnityPlugin)this).Config.SettingChanged -= OnAnySettingChanged;
		}
		catch
		{
		}
		try
		{
			for (int i = 0; i < _featureHarmonies.Count; i++)
			{
				_featureHarmonies[i].UnpatchSelf();
			}
		}
		catch
		{
		}
		_featureHarmonies.Clear();
		try
		{
			RemoveManagedBossPowers();
		}
		catch
		{
		}
		Instance = null;
	}

	private void Update()
	{
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: 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_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Unknown result type (might be due to invalid IL or missing references)
		//IL_027b: Unknown result type (might be due to invalid IL or missing references)
		if (!MasterEnabled.Value)
		{
			RestoreCircletLights();
			return;
		}
		if (!QuickCartEnabled.Value && !MapTeleportEnabled.Value && !CircletEnabled.Value && !BossPowersEnabled.Value && (!NearbyStorageEnabled.Value || !AutoSortEnabled.Value) && !RecyclingEnabled.Value && !AutoCraftingEnabled.Value && !HuntingGroundsEnabled.Value && (!RegenerationEnabled.Value || !AutoConsumeExtraSlotsFood.Value))
		{
			return;
		}
		if (HuntingGroundsEnabled.Value)
		{
			HuntingGrounds.EnsureRegistered();
			HuntingGrounds.Tick();
		}
		if (RegenerationEnabled.Value && AutoConsumeExtraSlotsFood.Value && Time.unscaledTime >= _nextExtraSlotsFoodUpdate)
		{
			_nextExtraSlotsFoodUpdate = Time.unscaledTime + 0.75f;
			RegenerationFoodSlots.TryAutoConsume(Player.m_localPlayer);
		}
		if (AutoCraftingEnabled.Value)
		{
			AutoCrafting.Tick();
		}
		if (RecyclingEnabled.Value)
		{
			KeyboardShortcut value = RecyclingHotkey.Value;
			if (!((KeyboardShortcut)(ref value)).IsDown())
			{
				KeyboardShortcut value2 = RecyclingHotkey.Value;
				if (!Input.GetKeyDown(((KeyboardShortcut)(ref value2)).MainKey))
				{
					goto IL_014a;
				}
			}
			Recycling.TryRecycleHoveredItem(Player.m_localPlayer);
		}
		goto IL_014a;
		IL_019a:
		if (QuickCartEnabled.Value)
		{
			KeyboardShortcut value3 = QuickCartHotkey.Value;
			if (!((KeyboardShortcut)(ref value3)).IsDown())
			{
				KeyboardShortcut value4 = QuickCartHotkey.Value;
				if (!Input.GetKeyDown(((KeyboardShortcut)(ref value4)).MainKey))
				{
					goto IL_01db;
				}
			}
			TryQuickCart();
		}
		goto IL_01db;
		IL_01db:
		if (MapTeleportEnabled.Value && Minimap.IsOpen() && (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) && Input.GetKeyDown((KeyCode)116))
		{
			TryMapTeleport();
		}
		if (CircletEnabled.Value)
		{
			KeyboardShortcut value5 = CircletToggleKey.Value;
			if (((KeyboardShortcut)(ref value5)).IsDown())
			{
				_circletLightOn = !_circletLightOn;
			}
			KeyboardShortcut value6 = CircletNarrowKey.Value;
			if (((KeyboardShortcut)(ref value6)).IsDown())
			{
				_circletStep = Mathf.Max(0, _circletStep - 1);
			}
			KeyboardShortcut value7 = CircletWidenKey.Value;
			if (((KeyboardShortcut)(ref value7)).IsDown())
			{
				_circletStep = Mathf.Min(CircletFocusSteps.Value - 1, _circletStep + 1);
			}
		}
		if (CircletEnabled.Value && Time.time >= _nextUtilityUpdate)
		{
			_nextUtilityUpdate = Time.time + 0.5f;
			ApplyCircletLights();
		}
		else if (!CircletEnabled.Value && _circletCachedLights != null)
		{
			RestoreCircletLights();
			_circletCachedLights = null;
		}
		if (BossPowersEnabled.Value && Time.time >= _nextBossPowerUpdate)
		{
			_nextBossPowerUpdate = Time.time + 5f;
			MaintainBossPowers();
		}
		return;
		IL_014a:
		if (NearbyStorageEnabled.Value && AutoSortEnabled.Value)
		{
			KeyboardShortcut value8 = AutoSortHotkey.Value;
			if (!((KeyboardShortcut)(ref value8)).IsDown())
			{
				KeyboardShortcut value9 = AutoSortHotkey.Value;
				if (!Input.GetKeyDown(((KeyboardShortcut)(ref value9)).MainKey))
				{
					goto IL_019a;
				}
			}
			NearbyStorage.AutoSort(Player.m_localPlayer);
		}
		goto IL_019a;
	}

	private void MaintainBossPowers()
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
		{
			return;
		}
		TrackBossHealthBaseline(localPlayer);
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_guardianPowerCooldown");
			if (fieldInfo != null)
			{
				fieldInfo.SetValue(localPlayer, 0f);
			}
		}
		catch
		{
		}
		EnsureBossPower(localPlayer, "GP_Eikthyr", "defeated_eikthyr", BossEikthyrEnabled.Value);
		EnsureBossPower(localPlayer, "GP_TheElder", "defeated_gdking", BossElderEnabled.Value);
		EnsureBossPower(localPlayer, "GP_Bonemass", "defeated_bonemass", BossBonemassEnabled.Value);
		EnsureBossPower(localPlayer, "GP_Moder", "defeated_dragon", BossModerEnabled.Value);
		EnsureBossPower(localPlayer, "GP_Yagluth", "defeated_goblinking", BossYagluthEnabled.Value);
		EnsureBossPower(localPlayer, "GP_Queen", "defeated_queen", BossQueenEnabled.Value);
		EnsureBossPower(localPlayer, "GP_Fader", "defeated_fader", BossFaderEnabled.Value);
		RestoreBossHealthIfCorrupted(localPlayer);
	}

	private void TrackBossHealthBaseline(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		if ((Object)(object)_bossHealthTrackedPlayer != (Object)(object)player)
		{
			_bossHealthTrackedPlayer = player;
			_bossBaselineMaxHealth = 0f;
		}
		try
		{
			float maxHealth = ((Character)player).GetMaxHealth();
			if (maxHealth > _bossBaselineMaxHealth)
			{
				_bossBaselineMaxHealth = maxHealth;
			}
		}
		catch
		{
		}
	}

	private void RestoreBossHealthIfCorrupted(Player player)
	{
		if ((Object)(object)player == (Object)null || _bossBaselineMaxHealth <= 0f)
		{
			return;
		}
		float maxHealth;
		try
		{
			maxHealth = ((Character)player).GetMaxHealth();
		}
		catch
		{
			return;
		}
		if (maxHealth >= _bossBaselineMaxHealth * 0.5f)
		{
			return;
		}
		TrySetMaxHealth((Character)(object)player, _bossBaselineMaxHealth);
		try
		{
			float health = ((Character)player).GetHealth();
			if (health > _bossBaselineMaxHealth)
			{
				((Character)player).SetHealth(_bossBaselineMaxHealth);
			}
		}
		catch
		{
		}
		((BaseUnityPlugin)this).Logger.LogWarning((object)("Boss Power safety restored max health from " + maxHealth.ToString("0.##") + " to " + _bossBaselineMaxHealth.ToString("0.##") + "."));
	}

	private static void TrySetMaxHealth(Character character, float value)
	{
		if ((Object)(object)character == (Object)null || value <= 0f)
		{
			return;
		}
		try
		{
			MethodInfo[] methods = ((object)character).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name != "SetMaxHealth")
				{
					continue;
				}
				ParameterInfo[] parameters = methodInfo.GetParameters();
				if (parameters.Length < 1 || parameters[0].ParameterType != typeof(float))
				{
					continue;
				}
				object[] array = new object[parameters.Length];
				array[0] = value;
				bool flag = true;
				for (int j = 1; j < parameters.Length; j++)
				{
					Type parameterType = parameters[j].ParameterType;
					if (parameterType == typeof(bool))
					{
						array[j] = false;
						continue;
					}
					if (parameterType == typeof(float))
					{
						array[j] = 0f;
						continue;
					}
					if (parameterType == typeof(int))
					{
						array[j] = 0;
						continue;
					}
					if (!parameterType.IsValueType)
					{
						array[j] = null;
						continue;
					}
					flag = false;
					break;
				}
				if (flag)
				{
					methodInfo.Invoke(character, array);
					break;
				}
			}
		}
		catch
		{
		}
	}

	private bool HasGlobalKey(string key)
	{
		if (!BossPowersRequireDefeat.Value)
		{
			return true;
		}
		if ((Object)(object)ZoneSystem.instance == (Object)null)
		{
			return false;
		}
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(ZoneSystem), "GetGlobalKey", new Type[1] { typeof(string) }, (Type[])null);
			if (methodInfo != null)
			{
				return Convert.ToBoolean(methodInfo.Invoke(ZoneSystem.instance, new object[1] { key }));
			}
		}
		catch
		{
		}
		return false;
	}

	private void EnsureBossPower(Player player, string effectName, string globalKey, bool enabled)
	{
		if (!enabled || !HasGlobalKey(globalKey))
		{
			RemoveBossPower(player, effectName);
			return;
		}
		int stableHash = GetStableHash(effectName);
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(SEMan), "HaveStatusEffect", new Type[1] { typeof(int) }, (Type[])null);
			if (methodInfo != null && Convert.ToBoolean(methodInfo.Invoke(((Character)player).GetSEMan(), new object[1] { stableHash })))
			{
				return;
			}
		}
		catch
		{
		}
		StatusEffect val = FindStatusEffect(effectName);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Dictionary<FieldInfo, object> dictionary = new Dictionary<FieldInfo, object>();
		try
		{
			ApplyBossPowerSettings(val, effectName, dictionary);
			FieldInfo fieldInfo = AccessTools.Field(((object)val).GetType(), "m_ttl");
			if (fieldInfo != null)
			{
				if (!dictionary.ContainsKey(fieldInfo))
				{
					dictionary[fieldInfo] = fieldInfo.GetValue(val);
				}
				fieldInfo.SetValue(val, 0f);
			}
			FieldInfo fieldInfo2 = AccessTools.Field(((object)val).GetType(), "m_cooldown");
			if (fieldInfo2 != null)
			{
				if (!dictionary.ContainsKey(fieldInfo2))
				{
					dictionary[fieldInfo2] = fieldInfo2.GetValue(val);
				}
				fieldInfo2.SetValue(val, 0f);
			}
			((Character)player).GetSEMan().AddStatusEffect(stableHash, false, 0, 0f, (short)(-1));
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Boss power " + effectName + " failed: " + ex.Message));
		}
		finally
		{
			foreach (KeyValuePair<FieldInfo, object> item in dictionary)
			{
				try
				{
					item.Key.SetValue(val, item.Value);
				}
				catch
				{
				}
			}
		}
	}

	private void ApplyBossPowerSettings(StatusEffect effect, string effectName, Dictionary<FieldInfo, object> originals)
	{
		if ((Object)(object)effect == (Object)null)
		{
			return;
		}
		switch (effectName)
		{
		case "GP_Eikthyr":
			SetBossFloat(effect, originals, new string[2] { "m_runStaminaUseModifier", "m_runStaminaDrainModifier" }, (0f - EikthyrRunStaminaReduction.Value) / 100f);
			SetBossFloat(effect, originals, new string[1] { "m_jumpStaminaUseModifier" }, (0f - EikthyrJumpStaminaReduction.Value) / 100f);
			SetBossFloat(effect, originals, new string[1] { "m_swimStaminaUseModifier" }, (0f - EikthyrSwimStaminaReduction.Value) / 100f);
			break;
		case "GP_TheElder":
			SetBossFloat(effect, originals, new string[1] { "m_healthRegenMultiplier" }, 1f + ElderHealthRegen.Value / 100f);
			break;
		case "GP_Bonemass":
			SetBossFloat(effect, originals, new string[1] { "m_blockStaminaUseModifier" }, (0f - BonemassBlockStaminaReduction.Value) / 100f);
			SetKeywordFloat(effect, originals, new string[2] { "block", "stamina" }, new string[2] { "use", "modifier" }, BonemassStaminaReturn.Value);
			SetResistance(effect, "blunt", BonemassBluntResistance.Value);
			SetResistance(effect, "slash", BonemassSlashResistance.Value);
			SetResistance(effect, "pierce", BonemassPierceResistance.Value);
			break;
		case "GP_Moder":
			SetBossFloat(effect, originals, new string[1] { "m_addMaxCarryWeight" }, ModerCarryWeight.Value);
			SetBossFloat(effect, originals, new string[1] { "m_speedModifier" }, ModerMovementSpeed.Value / 100f);
			SetResistance(effect, "frost", ModerFrostResistance.Value);
			if (!ModerTailwind.Value)
			{
				ClearSailingPowerAttribute(effect, originals);
			}
			break;
		case "GP_Yagluth":
			SetResistance(effect, "lightning", YagluthLightningResistance.Value);
			SetKeywordFloat(effect, originals, new string[1] { "skill" }, null, YagluthFarmingSkill.Value);
			SetBossFloat(effect, originals, new string[1] { "m_damageModifier" }, 1f + YagluthDamage.Value / 100f);
			break;
		case "GP_Queen":
			SetBossFloat(effect, originals, new string[1] { "m_eitrRegenMultiplier" }, 1f + QueenEitrRegen.Value / 100f);
			SetBossFloat(effect, originals, new string[1] { "m_sneakStaminaUseModifier" }, (0f - QueenSneakStaminaReduction.Value) / 100f);
			SetResistance(effect, "poison", QueenPoisonResistance.Value);
			break;
		case "GP_Fader":
			SetKeywordFloat(effect, originals, new string[1] { "adrenaline" }, null, FaderAdrenalineGain.Value / 100f);
			SetBossFloat(effect, originals, new string[1] { "m_staggerModifier" }, (0f - FaderStaggerReduction.Value) / 100f);
			SetResistance(effect, "fire", FaderFireResistance.Value);
			break;
		}
	}

	private static FieldInfo FindFieldInHierarchy(Type type, string name)
	{
		while (type != null)
		{
			FieldInfo field = type.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				return field;
			}
			type = type.BaseType;
		}
		return null;
	}

	private static void SetBossFloat(StatusEffect effect, Dictionary<FieldInfo, object> originals, string[] fieldNames, float value)
	{
		for (int i = 0; i < fieldNames.Length; i++)
		{
			FieldInfo fieldInfo = FindFieldInHierarchy(((object)effect).GetType(), fieldNames[i]);
			if (!(fieldInfo == null) && !(fieldInfo.FieldType != typeof(float)))
			{
				if (!originals.ContainsKey(fieldInfo))
				{
					originals[fieldInfo] = fieldInfo.GetValue(effect);
				}
				fieldInfo.SetValue(effect, value);
			}
		}
	}

	private static void SetKeywordFloat(StatusEffect effect, Dictionary<FieldInfo, object> originals, string[] include, string[] exclude, float desiredPositiveValue)
	{
		Type type = ((object)effect).GetType();
		while (type != null)
		{
			FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (fieldInfo.FieldType != typeof(float))
				{
					continue;
				}
				string text = fieldInfo.Name.ToLowerInvariant();
				bool flag = true;
				for (int j = 0; j < include.Length; j++)
				{
					if (!text.Contains(include[j]))
					{
						flag = false;
						break;
					}
				}
				if (!flag)
				{
					continue;
				}
				if (exclude != null)
				{
					for (int k = 0; k < exclude.Length; k++)
					{
						if (text.Contains(exclude[k]))
						{
							flag = false;
							break;
						}
					}
				}
				if (!flag)
				{
					continue;
				}
				float num = Convert.ToSingle(fieldInfo.GetValue(effect));
				if (!(Math.Abs(num) < 0.0001f))
				{
					if (!originals.ContainsKey(fieldInfo))
					{
						originals[fieldInfo] = num;
					}
					fieldInfo.SetValue(effect, (num < 0f) ? (0f - Math.Abs(desiredPositiveValue)) : Math.Abs(desiredPositiveValue));
				}
			}
			type = type.BaseType;
		}
	}

	private static void SetNamedNumericValue(object root, string token, float value)
	{
		if (root == null)
		{
			return;
		}
		Type type = root.GetType();
		while (type != null)
		{
			FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			for (int i = 0; i < fields.Length; i++)
			{
				object value2;
				try
				{
					value2 = fields[i].GetValue(root);
				}
				catch
				{
					continue;
				}
				if (!(value2 is IEnumerable enumerable) || value2 is string)
				{
					continue;
				}
				foreach (object item in enumerable)
				{
					if (item == null)
					{
						continue;
					}
					FieldInfo[] fields2 = item.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					string text = item.ToString().ToLowerInvariant();
					for (int j = 0; j < fields2.Length; j++)
					{
						if (!fields2[j].FieldType.IsEnum && !(fields2[j].FieldType == typeof(string)))
						{
							continue;
						}
						try
						{
							object value3 = fields2[j].GetValue(item);
							if (value3 != null)
							{
								text = text + " " + value3.ToString().ToLowerInvariant();
							}
						}
						catch
						{
						}
					}
					if (!text.Contains(token.ToLowerInvariant()))
					{
						continue;
					}
					foreach (FieldInfo fieldInfo in fields2)
					{
						if (fieldInfo.FieldType != typeof(float))
						{
							continue;
						}
						float num;
						try
						{
							num = Convert.ToSingle(fieldInfo.GetValue(item));
						}
						catch
						{
							continue;
						}
						if (!(Math.Abs(num) < 0.0001f))
						{
							try
							{
								fieldInfo.SetValue(item, (num < 0f) ? (0f - Math.Abs(value)) : Math.Abs(value));
							}
							catch
							{
							}
						}
					}
				}
			}
			type = type.BaseType;
		}
	}

	private static void SetResistance(StatusEffect effect, string damageToken, float percent)
	{
		if ((Object)(object)effect == (Object)null)
		{
			return;
		}
		string b = ((percent <= 0.1f) ? "Normal" : ((percent < 37.5f) ? "SlightlyResistant" : ((percent < 62.5f) ? "Resistant" : ((percent < 87.5f) ? "VeryResistant" : "Immune"))));
		Type type = ((object)effect).GetType();
		while (type != null)
		{
			FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			for (int i = 0; i < fields.Length; i++)
			{
				object value;
				try
				{
					value = fields[i].GetValue(effect);
				}
				catch
				{
					continue;
				}
				if (!(value is IEnumerable enumerable) || value is string)
				{
					continue;
				}
				foreach (object item in enumerable)
				{
					if (item == null)
					{
						continue;
					}
					FieldInfo[] fields2 = item.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					bool flag = false;
					for (int j = 0; j < fields2.Length; j++)
					{
						if (!fields2[j].FieldType.IsEnum && fields2[j].FieldType != typeof(string))
						{
							continue;
						}
						try
						{
							object value2 = fields2[j].GetValue(item);
							if (value2 != null && value2.ToString().IndexOf(damageToken, StringComparison.OrdinalIgnoreCase) >= 0)
							{
								flag = true;
							}
						}
						catch
						{
						}
					}
					if (!flag)
					{
						continue;
					}
					foreach (FieldInfo fieldInfo in fields2)
					{
						if (!fieldInfo.FieldType.IsEnum)
						{
							continue;
						}
						Array values = Enum.GetValues(fieldInfo.FieldType);
						foreach (object item2 in values)
						{
							if (string.Equals(item2.ToString(), b, StringComparison.OrdinalIgnoreCase))
							{
								try
								{
									fieldInfo.SetValue(item, item2);
								}
								catch
								{
								}
								break;
							}
						}
					}
				}
			}
			type = type.BaseType;
		}
	}

	private static void ClearSailingPowerAttribute(StatusEffect effect, Dictionary<FieldInfo, object> originals)
	{
		Type type = ((object)effect).GetType();
		while (type != null)
		{
			FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!fieldInfo.FieldType.IsEnum)
				{
					continue;
				}
				object value = fieldInfo.GetValue(effect);
				if (value != null && value.ToString().IndexOf("SailingPower", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					if (!originals.ContainsKey(fieldInfo))
					{
						originals[fieldInfo] = value;
					}
					fieldInfo.SetValue(effect, Enum.ToObject(fieldInfo.FieldType, 0));
				}
			}
			type = type.BaseType;
		}
	}

	private static int GetStableHash(string text)
	{
		if (string.IsNullOrEmpty(text))
		{
			return 0;
		}
		int num = 5381;
		int num2 = 5381;
		for (int i = 0; i < text.Length; i += 2)
		{
			num = ((num << 5) + num) ^ text[i];
			if (i == text.Length - 1)
			{
				break;
			}
			num2 = ((num2 << 5) + num2) ^ text[i + 1];
		}
		return num + num2 * 1566083941;
	}

	private StatusEffect FindStatusEffect(string effectName)
	{
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(ObjectDB), "m_StatusEffects");
			IList list = ((fieldInfo == null) ? null : (fieldInfo.GetValue(ObjectDB.instance) as IList));
			if (list == null)
			{
				return null;
			}
			for (int i = 0; i < list.Count; i++)
			{
				object? obj = list[i];
				StatusEffect val = (StatusEffect)((obj is StatusEffect) ? obj : null);
				if ((Object)(object)val != (Object)null && ((Object)val).name == effectName)
				{
					return val;
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private void RemoveBossPower(Player player, string effectName)
	{
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(SEMan), "RemoveStatusEffect", new Type[2]
			{
				typeof(int),
				typeof(bool)
			}, (Type[])null);
			if (methodInfo != null)
			{
				methodInfo.Invoke(((Character)player).GetSEMan(), new object[2]
				{
					GetStableHash(effectName),
					true
				});
			}
		}
		catch
		{
		}
	}

	internal static bool IsBossPowerAvailable(ConfigEntry<bool> bossEnabled, string globalKey)
	{
		if ((Object)(object)Instance == (Object)null || MasterEnabled == null || !MasterEnabled.Value || BossPowersEnabled == null || !BossPowersEnabled.Value || bossEnabled == null || !bossEnabled.Value)
		{
			return false;
		}
		if (BossPowersRequireDefeat == null || !BossPowersRequireDefeat.Value)
		{
			return true;
		}
		if ((Object)(object)ZoneSystem.instance == (Object)null)
		{
			return false;
		}
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(ZoneSystem), "GetGlobalKey", new Type[1] { typeof(string) }, (Type[])null);
			if (methodInfo != null)
			{
				return Convert.ToBoolean(methodInfo.Invoke(ZoneSystem.instance, new object[1] { globalKey }));
			}
		}
		catch
		{
		}
		return false;
	}

	private void RemoveManagedBossPowers()
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null))
		{
			for (int i = 0; i < ManagedBossEffects.Length; i++)
			{
				RemoveBossPower(localPlayer, ManagedBossEffects[i]);
			}
		}
	}

	private void ApplyCircletLights()
	{
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return;
		}
		if (!IsDvergerCircletEquipped(localPlayer))
		{
			RestoreCircletLights();
			_circletCachedPlayer = localPlayer;
			_circletCachedLights = null;
			return;
		}
		if ((Object)(object)_circletCachedPlayer != (Object)(object)localPlayer || _circletCachedLights == null || Time.time >= _nextCircletRescan)
		{
			_circletCachedPlayer = localPlayer;
			_nextCircletRescan = Time.time + 2f;
			Light[] componentsInChildren = ((Component)localPlayer).GetComponentsInChildren<Light>(true);
			List<Light> list = new List<Light>();
			foreach (Light val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string text = GetTransformPath(((Component)val).transform).ToLowerInvariant();
				bool flag = text.IndexOf("dverger") >= 0 || text.IndexOf("circlet") >= 0 || text.IndexOf("headlamp") >= 0;
				bool flag2 = (int)val.type == 0 && ((Component)val).transform.IsChildOf(((Component)localPlayer).transform);
				if (flag || flag2)
				{
					if (!list.Contains(val))
					{
						list.Add(val);
					}
					RememberCircletOriginal(val);
				}
			}
			_circletCachedLights = list.ToArray();
		}
		if (_circletCachedLights == null || _circletCachedLights.Length == 0)
		{
			return;
		}
		int num = Mathf.Max(2, CircletFocusSteps.Value);
		_circletStep = Mathf.Clamp(_circletStep, 0, num - 1);
		float num2 = Mathf.Clamp01((float)_circletStep / (float)(num - 1));
		float range = Mathf.Lerp(CircletRange.Value * 0.55f, CircletRange.Value, num2);
		float spotAngle = Mathf.Lerp(28f, 80f, num2);
		float intensity = Mathf.Lerp(CircletBrightness.Value * 1.5f, CircletBrightness.Value * 0.7f, num2);
		for (int j = 0; j < _circletCachedLights.Length; j++)
		{
			Light val2 = _circletCachedLights[j];
			if (!((Object)(object)val2 == (Object)null))
			{
				((Behaviour)val2).enabled = _circletLightOn;
				val2.range = range;
				val2.intensity = intensity;
				val2.color = new Color(0.95f, 0.98f, 1f, 1f);
				if ((int)val2.type == 0)
				{
					val2.spotAngle = spotAngle;
				}
			}
		}
	}

	private void RememberCircletOriginal(Light light)
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)light == (Object)null))
		{
			int instanceID = ((Object)light).GetInstanceID();
			if (!_circletOriginals.ContainsKey(instanceID))
			{
				_circletOriginals[instanceID] = new CircletLightOriginal
				{
					Enabled = ((Behaviour)light).enabled,
					Range = light.range,
					Intensity = light.intensity,
					SpotAngle = light.spotAngle,
					Color = light.color
				};
			}
		}
	}

	private void RestoreCircletLights()
	{
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		if (_circletCachedLights == null)
		{
			return;
		}
		for (int i = 0; i < _circletCachedLights.Length; i++)
		{
			Light val = _circletCachedLights[i];
			if (!((Object)(object)val == (Object)null) && _circletOriginals.TryGetValue(((Object)val).GetInstanceID(), out var value) && value != null)
			{
				((Behaviour)val).enabled = value.Enabled;
				val.range = value.Range;
				val.intensity = value.Intensity;
				if ((int)val.type == 0)
				{
					val.spotAngle = value.SpotAngle;
				}
				val.color = value.Color;
			}
		}
	}

	private static bool IsDvergerCircletEquipped(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		Type type = ((object)player).GetType();
		while (type != null)
		{
			FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (typeof(ItemData).IsAssignableFrom(fieldInfo.FieldType))
				{
					ItemData item = null;
					try
					{
						object? value = fieldInfo.GetValue(player);
						item = (ItemData)((value is ItemData) ? value : null);
					}
					catch
					{
					}
					if (IsDvergerCircletItem(item))
					{
						return true;
					}
				}
			}
			type = type.BaseType;
		}
		try
		{
			Inventory inventory = ((Humanoid)player).GetInventory();
			List<ItemData> list = ((inventory == null) ? null : inventory.GetAllItems());
			if (list != null)
			{
				for (int j = 0; j < list.Count; j++)
				{
					ItemData val = list[j];
					if (!IsDvergerCircletItem(val))
					{
						continue;
					}
					bool flag = false;
					try
					{
						FieldInfo fieldInfo2 = AccessTools.Field(((object)val).GetType(), "m_equipped");
						if (fieldInfo2 != null)
						{
							flag = Convert.ToBoolean(fieldInfo2.GetValue(val));
						}
					}
					catch
					{
					}
					if (flag)
					{
						return true;
					}
				}
			}
		}
		catch
		{
		}
		return false;
	}

	private static bool IsDvergerCircletItem(ItemData item)
	{
		if (item == null || item.m_shared == null)
		{
			return false;
		}
		string text = (item.m_shared.m_name ?? "") + " " + (((Object)(object)item.m_dropPrefab == (Object)null) ? "" : (((Object)item.m_dropPrefab).name ?? ""));
		text = text.ToLowerInvariant();
		if (text.IndexOf("dverger") >= 0)
		{
			if (text.IndexOf("circlet") < 0)
			{
				return text.IndexOf("helmet") >= 0;
			}
			return true;
		}
		return false;
	}

	private static string GetTransformPath(Transform t)
	{
		string text = (((Object)(object)t == (Object)null) ? "" : ((Object)t).name);
		while ((Object)(object)t != (Object)null && (Object)(object)t.parent != (Object)null)
		{
			t = t.parent;
			text = ((Object)t).name + "/" + text;
		}
		return text;
	}

	private void TryMapTeleport()
	{
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: 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_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		Minimap instance = Minimap.instance;
		if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null)
		{
			return;
		}
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Minimap), "ScreenToWorldPoint", new Type[1] { typeof(Vector3) }, (Type[])null);
			if (methodInfo == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Map Teleport: Minimap.ScreenToWorldPoint was not found.");
				return;
			}
			Vector3 val = (Vector3)methodInfo.Invoke(instance, new object[1] { Input.mousePosition });
			if (val == Vector3.zero)
			{
				return;
			}
			if (WorldGenerator.instance != null)
			{
				val.y = WorldGenerator.instance.GetHeight(val.x, val.z) + 1.5f;
			}
			else if ((Object)(object)ZoneSystem.instance != (Object)null)
			{
				val.y = ZoneSystem.instance.GetGroundHeight(val) + 1.5f;
			}
			((Character)localPlayer).TeleportTo(val, ((Component)localPlayer).transform.rotation, true);
			try
			{
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Minimap), "SetMapMode", (Type[])null, (Type[])null);
				if (methodInfo2 != null)
				{
					ParameterInfo[] parameters = methodInfo2.GetParameters();
					if (parameters.Length == 1 && parameters[0].ParameterType.IsEnum)
					{
						object obj = Enum.ToObject(parameters[0].ParameterType, 1);
						methodInfo2.Invoke(instance, new object[1] { obj });
					}
				}
			}
			catch
			{
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Map Teleport failed: " + ex.Message));
		}
	}

	private void TryQuickCart()
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return;
		}
		float num = QuickCartDistance.Value;
		Vagon val = null;
		Vector3 val2 = ((Component)localPlayer).transform.position + Vector3.up;
		Collider[] array = Physics.OverlapSphere(val2, QuickCartDistance.Value);
		foreach (Collider val3 in array)
		{
			if ((Object)(object)val3 == (Object)null || (Object)(object)val3.attachedRigidbody == (Object)null)
			{
				continue;
			}
			Vagon component = ((Component)val3).gameObject.GetComponent<Vagon>();
			if ((Object)(object)component == (Object)null && (Object)(object)((Component)val3).transform.parent != (Object)null)
			{
				component = ((Component)((Component)val3).transform.parent).gameObject.GetComponent<Vagon>();
			}
			if ((Object)(object)component == (Object)null)
			{
				continue;
			}
			float num2 = Vector3.Distance(val3.ClosestPoint(val2), val2);
			if (!(num2 >= num) && (component.IsAttached((Character)(object)localPlayer) || !component.InUse()))
			{
				num = num2;
				if ((Object)(object)((Component)val3).transform.parent != (Object)null)
				{
					Vagon component2 = ((Component)((Component)val3).transform.parent).gameObject.GetComponent<Vagon>();
					val = (((Object)(object)component2 != (Object)null) ? component2 : component);
				}
				else
				{
					val = component;
				}
			}
		}
		if ((Object)(object)val != (Object)null)
		{
			val.Interact((Humanoid)(object)localPlayer, false, false);
		}
	}

	internal static float ComputeExploreRadius(Player player)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null)
		{
			return LandExploreRadius.Value;
		}
		bool flag = false;
		try
		{
			flag = ((Character)player).IsAttachedToShip();
		}
		catch
		{
		}
		float num = (flag ? SeaExploreRadius.Value : LandExploreRadius.Value);
		if (!flag)
		{
			float num2 = Mathf.Max(0f, ((Component)player).transform.position.y - 30f);
			num += LandExploreRadius.Value * AltitudeExploreBonus.Value * (num2 / 100f);
		}
		return Mathf.Clamp(num, 0f, 10000f);
	}
}
[HarmonyPatch]
internal static class SkipIntroCoroutinePatch
{
	private static MethodBase TargetMethod()
	{
		Type typeFromHandle = typeof(FejdStartup);
		Type[] nestedTypes = typeFromHandle.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
		for (int i = 0; i < nestedTypes.Length; i++)
		{
			string name = nestedTypes[i].Name;
			if (name.IndexOf("PlayIntroCinematic", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				MethodInfo methodInfo = AccessTools.Method(nestedTypes[i], "MoveNext", (Type[])null, (Type[])null);
				if (methodInfo != null && methodInfo.ReturnType == typeof(bool))
				{
					return methodInfo;
				}
			}
		}
		return null;
	}

	private static bool Prefix(ref bool __result)
	{
		if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.SkipIntroEnabled))
		{
			__result = false;
			return false;
		}
		return true;
	}
}
internal static class EquipmentInWaterUtil
{
	public static bool IsSwimmingForEquipment(Character character)
	{
		if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.WaterEquipmentEnabled))
		{
			return false;
		}
		return character.IsSwimming();
	}

	public static IEnumerable<CodeInstruction> ReplaceSwimmingCheck(IEnumerable<CodeInstruction> instructions)
	{
		MethodInfo swimming = AccessTools.Method(typeof(Character), "IsSwimming", (Type[])null, (Type[])null);
		MethodInfo replacement = AccessTools.Method(typeof(EquipmentInWaterUtil), "IsSwimmingForEquipment", (Type[])null, (Type[])null);
		foreach (CodeInstruction code in instructions)
		{
			if ((code.opcode == OpCodes.Call || code.opcode == OpCodes.Callvirt) && code.operand is MethodInfo && (MethodInfo)code.operand == swimming)
			{
				yield return new CodeInstruction(OpCodes.Call, (object)replacement);
			}
			else
			{
				yield return code;
			}
		}
	}
}
[HarmonyPatch(typeof(Humanoid), "UpdateEquipment")]
internal static class EquipmentInWaterUpdatePatch
{
	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		return EquipmentInWaterUtil.ReplaceSwimmingCheck(instructions);
	}
}
[HarmonyPatch(typeof(Humanoid), "EquipItem")]
internal static class EquipmentInWaterEquipPatch
{
	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		return EquipmentInWaterUtil.ReplaceSwimmingCheck(instructions);
	}
}
[HarmonyPatch(typeof(Fermenter), "Awake")]
internal static class FermenterAwakePatch
{
	private static void Postfix(Fermenter __instance)
	{
		if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FermenterEnabled))
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(Fermenter), "m_fermentationDuration");
			if (fieldInfo != null)
			{
				fieldInfo.SetValue(__instance, HeimLifeTweaksPlugin.FermenterMinutes.Value * 60f);
			}
		}
	}
}
[HarmonyPatch(typeof(Fermenter), "GetHoverText")]
internal static class FermenterHoverPatch
{
	private static void Postfix(Fermenter __instance, ref string __result)
	{
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FermenterEnabled) || !HeimLifeTweaksPlugin.FermenterShowProgress.Value)
		{
			return;
		}
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Fermenter), "GetStatus", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(Fermenter), "GetFermentationTime", (Type[])null, (Type[])null);
			if (!(methodInfo == null) && !(methodInfo2 == null))
			{
				object obj = methodInfo.Invoke(__instance, null);
				if (obj != null && obj.ToString().IndexOf("Fermenting", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					object value = methodInfo2.Invoke(__instance, null);
					float num = Convert.ToSingle(value);
					float num2 = Mathf.Max(1f, HeimLifeTweaksPlugin.FermenterMinutes.Value * 60f);
					float num3 = Mathf.Clamp01(num / num2) * 100f;
					__result = __result + "\n<color=#FFD36A>" + num3.ToString("0") + "%</color>";
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(Fermenter), "GetStatus")]
internal static class FermenterCoverPatch
{
	private static void Postfix(ref object __result)
	{
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FermenterEnabled) || !HeimLifeTweaksPlugin.FermenterNoCover.Value || __result == null)
		{
			return;
		}
		Type type = __result.GetType();
		if (!type.IsEnum)
		{
			return;
		}
		string text = __result.ToString();
		if (text.IndexOf("Cover", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Exposed", StringComparison.OrdinalIgnoreCase) < 0)
		{
			return;
		}
		try
		{
			object obj = Enum.Parse(type, "Fermenting");
			__result = obj;
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(CraftingStation), "Start")]
internal static class BuildSpacePatch
{
	private static void Postfix(CraftingStation __instance)
	{
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.BuildSpaceEnabled))
		{
			return;
		}
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(CraftingStation), "m_rangeBuild");
			if (!(fieldInfo == null))
			{
				float num = Convert.ToSingle(fieldInfo.GetValue(__instance));
				fieldInfo.SetValue(__instance, num * HeimLifeTweaksPlugin.BuildRadiusMultiplier.Value);
				FieldInfo fieldInfo2 = AccessTools.Field(typeof(CraftingStation), "m_areaMarker");
				GameObject val = (GameObject)((fieldInfo2 == null) ? null : /*isinst with value type is only supported in some contexts*/);
				if ((Object)(object)val != (Object)null)
				{
					Transform transform = val.transform;
					transform.localScale *= HeimLifeTweaksPlugin.BuildRadiusMultiplier.Value;
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(Ship), "GetSailForce")]
internal static class FasterBoatWindPatch
{
	private static void Postfix(ref Vector3 __result)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FasterBoatsEnabled))
		{
			__result *= HeimLifeTweaksPlugin.BoatWindMultiplier.Value;
		}
	}
}
[HarmonyPatch(typeof(Ship), "Awake")]
internal static class FasterBoatRudderPatch
{
	private static void Postfix(Ship __instance)
	{
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FasterBoatsEnabled))
		{
			return;
		}
		FieldInfo fieldInfo = AccessTools.Field(typeof(Ship), "m_backwardForce");
		if (fieldInfo == null)
		{
			return;
		}
		try
		{
			float num = Convert.ToSingle(fieldInfo.GetValue(__instance));
			fieldInfo.SetValue(__instance, num * HeimLifeTweaksPlugin.BoatRudderMultiplier.Value);
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(Vagon), "CanAttach")]
internal static class QuickCartAttachPatch
{
	private static bool Prefix(Vagon __instance, GameObject go, ref bool __result)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.QuickCartEnabled) || !HeimLifeTweaksPlugin.QuickCartOutOfPlace.Value || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)go != (Object)(object)((Component)Player.m_localPlayer).gameObject)
		{
			return true;
		}
		if (((Component)__instance).transform.up.y < 0.1f)
		{
			return true;
		}
		try
		{
			__result = !((Character)Player.m_localPlayer).IsTeleporting() && !((Character)Player.m_localPlayer).InDodge() && Vector3.Distance(go.transform.position + __instance.m_attachOffset, __instance.m_attachPoint.position) < HeimLifeTweaksPlugin.QuickCartDistance.Value;
			return false;
		}
		catch
		{
			return true;
		}
	}
}
[HarmonyPatch(typeof(Player), "UseStamina")]
internal static class StaminaUsePatch
{
	private static void Prefix(ref float v)
	{
		if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.RegenerationEnabled))
		{
			v *= HeimLifeTweaksPlugin.StaminaCostMultiplier.Value;
		}
	}
}
[HarmonyPatch]
internal static class RegenStatsPatch
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (MethodInfo method in methods)
		{
			if (!(method == null) && !(method.Name != "UpdateStats") && !method.IsStatic && !(method.ReturnType != typeof(void)))
			{
				ParameterInfo[] p = method.GetParameters();
				if (p.Length != 0 && !(p[0].ParameterType != typeof(float)))
				{
					yield return method;
				}
			}
		}
	}

	private static void Prefix(Player __instance, ref float __state)
	{
		__state = 0f;
		if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.RegenerationEnabled))
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_stamina");
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(Player), "m_staminaRegenTimer");
			FieldInfo fieldInfo3 = AccessTools.Field(typeof(Player), "m_eiterRegen");
			if (fieldInfo != null)
			{
				__state = Convert.ToSingle(fieldInfo.GetValue(__instance));
			}
			if (fieldInfo2 != null)
			{
				float num = Convert.ToSingle(fieldInfo2.GetValue(__instance));
				fieldInfo2.SetValue(__instance, num * HeimLifeTweaksPlugin.StaminaRegenDelayMultiplier.Value);
			}
			if (fieldInfo3 != null)
			{
				fieldInfo3.SetValue(__instance, HeimLifeTweaksPlugin.EitrRegenRate.Value);
			}
		}
	}

	private static void Postfix(Player __instance, float __state)
	{
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.RegenerationEnabled))
		{
			return;
		}
		FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_stamina");
		if (!(fieldInfo == null))
		{
			float num = Convert.ToSingle(fieldInfo.GetValue(__instance));
			if (__state > 0f && num > __state)
			{
				fieldInfo.SetValue(__instance, __state + (num - __state) * HeimLifeTweaksPlugin.StaminaRegenMultiplier.Value);
			}
		}
	}
}
[HarmonyPatch(typeof(Player), "UpdateFood")]
internal static class HealthRegenDelayPatch
{
	private static void Prefix(float dt, bool forceUpdate, ref float ___m_foodRegenTimer)
	{
		if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.RegenerationEnabled) && !forceUpdate)
		{
			float num = Mathf.Max(0.1f, HeimLifeTweaksPlugin.HealthRegenDelayMultiplier.Value);
			___m_foodRegenTimer += dt / num - dt;
		}
	}
}
[HarmonyPatch(typeof(Character), "Heal")]
internal static class HealthRegenAmountPatch
{
	private static void Prefix(Character __instance, ref float hp)
	{
		if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.RegenerationEnabled) && __instance is Player)
		{
			hp *= HeimLifeTweaksPlugin.HealthRegenMultiplier.Value;
		}
	}
}
internal static class RegenerationFoodSlots
{
	private static bool _apiResolved;

	private static MethodInfo _getFoodSlotsItems;

	private static MethodInfo _useItemMethod;

	private static MethodInfo _consumeItemMethod;

	private static MethodInfo _canConsumeItemMethod;

	private static bool _canConsumeResolved;

	internal static void TryAutoConsume(Player player)
	{
		if ((Object)(object)player == (Object)null || !HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.RegenerationEnabled) || !HeimLifeTweaksPlugin.AutoConsumeExtraSlotsFood.Value)
		{
			return;
		}
		List<ItemData> extraSlotsFoodItems = GetExtraSlotsFoodItems();
		if (extraSlotsFoodItems == null || extraSlotsFoodItems.Count == 0)
		{
			return;
		}
		int activeFoodCount = GetActiveFoodCount(player);
		for (int i = 0; i < extraSlotsFoodItems.Count; i++)
		{
			ItemData item = extraSlotsFoodItems[i];
			if (!IsValidFoodItem(item))
			{
				continue;
			}
			if (IsFoodActive(player, item))
			{
				if (!IsFoodAtBlinkStage(player, item))
				{
					continue;
				}
			}
			else if (activeFoodCount >= 3)
			{
				continue;
			}
			if (TryUseFood(player, item))
			{
				break;
			}
		}
	}

	private static bool IsValidFoodItem(ItemData item)
	{
		if (item != null && item.m_stack > 0 && item.m_shared != null)
		{
			return item.m_shared.m_food > 0f;
		}
		return false;
	}

	private static bool ResolveCanConsumeMethod(Type playerType)
	{
		if (_canConsumeResolved)
		{
			return _canConsumeItemMethod != null;
		}
		_canConsumeResolved = true;
		if (playerType == null)
		{
			return false;
		}
		try
		{
			MethodInfo[] methods = playerType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name != "CanConsumeItem" || methodInfo.ReturnType != typeof(bool))
				{
					continue;
				}
				ParameterInfo[] parameters = methodInfo.GetParameters();
				bool flag = false;
				bool flag2 = true;
				for (int j = 0; j < parameters.Length; j++)
				{
					Type parameterType = parameters[j].ParameterType;
					if (parameterType == typeof(ItemData))
					{
						flag = true;
					}
					else if (!(parameterType == typeof(bool)) && !(parameterType == typeof(Inventory)))
					{
						flag2 = false;
						break;
					}
				}
				if (flag2 && flag)
				{
					_canConsumeItemMethod = methodInfo;
					return true;
				}
			}
		}
		catch
		{
		}
		return false;
	}

	private static bool CanConsumeNow(Player player, ItemData item)
	{
		if ((Object)(object)player == (Object)null || item == null || _canConsumeItemMethod == null)
		{
			return false;
		}
		try
		{
			ParameterInfo[] parameters = _canConsumeItemMethod.GetParameters();
			object[] array = new object[parameters.Length];
			for (int i = 0; i < parameters.Length; i++)
			{
				Type parameterType = parameters[i].ParameterType;
				if (parameterType == typeof(ItemData))
				{
					array[i] = item;
					continue;
				}
				if (parameterType == typeof(bool))
				{
					array[i] = false;
					continue;
				}
				if (parameterType == typeof(Inventory))
				{
					array[i] = ((Humanoid)player).GetInventory();
					continue;
				}
				return false;
			}
			object obj = _canConsumeItemMethod.Invoke(player, array);
			return obj is bool && (bool)obj;
		}
		catch
		{
			return false;
		}
	}

	private static List<ItemData> GetExtraSlotsFoodItems()
	{
		ResolveApi();
		if (_getFoodSlotsItems == null)
		{
			return null;
		}
		try
		{
			object obj = _getFoodSlotsItems.Invoke(null, null);
			if (!(obj is IEnumerable enumerable))
			{
				return null;
			}
			List<ItemData> list = new List<ItemData>();
			foreach (object item in enumerable)
			{
				ItemData val = (ItemData)((item is ItemData) ? item : null);
				if (val != null)
				{
					list.Add(val);
				}
			}
			return list;
		}
		catch
		{
			return null;
		}
	}

	private static void ResolveApi()
	{
		if (_apiResolved)
		{
			return;
		}
		_apiResolved = true;
		try
		{
			Type type = Type.GetType("ExtraSlots.API, ExtraSlots", throwOnError: false);
			if (!(type == null))
			{
				_getFoodSlotsItems = type.GetMethod("GetFoodSlotsItems", BindingFlags.Static | BindingFlags.Public);
			}
		}
		catch
		{
		}
	}

	private static int GetActiveFoodCount(Player player)
	{
		int num = 0;
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_foods");
			IEnumerable enumerable = ((fieldInfo == null) ? null : (fieldInfo.GetValue(player) as IEnumerable));
			if (enumerable == null)
			{
				return 0;
			}
			foreach (object item in enumerable)
			{
				if (item != null)
				{
					num++;
				}
			}
		}
		catch
		{
		}
		return num;
	}

	private static bool IsFoodAtBlinkStage(Player player, ItemData item)
	{
		if ((Object)(object)player == (Object)null || item == null || item.m_shared == null)
		{
			return false;
		}
		string text = item.m_shared.m_name ?? "";
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_foods");
			IEnumerable enumerable = ((fieldInfo == null) ? null : (fieldInfo.GetValue(player) as IEnumerable));
			if (enumerable == null)
			{
				return false;
			}
			foreach (object item2 in enumerable)
			{
				if (item2 == null)
				{
					continue;
				}
				Type type = item2.GetType();
				FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				ItemData val = null;
				foreach (FieldInfo fieldInfo2 in fields)
				{
					if (typeof(ItemData).IsAssignableFrom(fieldInfo2.FieldType))
					{
						try
						{
							object? value = fieldInfo2.GetValue(item2);
							val = (ItemData)((value is ItemData) ? value : null);
						}
						catch
						{
							val = null;
						}
						if (val != null && val.m_shared != null)
						{
							break;
						}
					}
				}
				if (val != null && val.m_shared != null && !(val.m_shared.m_name != text))
				{
					float foodBurnTime = val.m_shared.m_foodBurnTime;
					if (foodBurnTime <= 0f)
					{
						foodBurnTime = item.m_shared.m_foodBurnTime;
					}
					if (foodBurnTime <= 0f)
					{
						return false;
					}
					FieldInfo field = type.GetField("m_time", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field == null || field.FieldType != typeof(float))
					{
						return false;
					}
					float num = Convert.ToSingle(field.GetValue(item2));
					return num <= foodBurnTime * 0.5f;
				}
			}
		}
		catch
		{
		}
		return false;
	}

	private static bool IsFoodActive(Player player, ItemData item)
	{
		if ((Object)(object)player == (Object)null || item == null || item.m_shared == null)
		{
			return false;
		}
		string text = item.m_shared.m_name ?? "";
		string text2 = "";
		try
		{
			text2 = (((Object)(object)item.m_dropPrefab == (Object)null) ? "" : (((Object)item.m_dropPrefab).name ?? ""));
		}
		catch
		{
		}
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_foods");
			IEnumerable enumerable = ((fieldInfo == null) ? null : (fieldInfo.GetValue(player) as IEnumerable));
			if (enumerable == null)
			{
				return false;
			}
			foreach (object item2 in enumerable)
			{
				if (item2 == null)
				{
					continue;
				}
				FieldInfo[] fields = item2.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo2 in fields)
				{
					if (typeof(ItemData).IsAssignableFrom(fieldInfo2.FieldType))
					{
						ItemData val = null;
						try
						{
							object? value = fieldInfo2.GetValue(item2);
							val = (ItemData)((value is ItemData) ? value : null);
						}
						catch
						{
						}
						if (val != null && val.m_shared != null && val.m_shared.m_name == text)
						{
							return true;
						}
					}
					else if (fieldInfo2.FieldType == typeof(string))
					{
						string text3 = null;
						try
						{
							text3 = fieldInfo2.GetValue(item2) as string;
						}
						catch
						{
						}
						if (!string.IsNullOrEmpty(text3) && (text3 == text || (!string.IsNullOrEmpty(text2) && text3 == text2)))
						{
							return true;
						}
					}
				}
			}
		}
		catch
		{
		}
		return false;
	}

	private static bool TryUseFood(Player player, ItemData item)
	{
		if ((Object)(object)player == (Object)null || item == null)
		{
			return false;
		}
		ResolveConsumeMethods(((object)player).GetType());
		Inventory inventory = ((Humanoid)player).GetInventory();
		if (_useItemMethod != null)
		{
			bool? flag = InvokeFoodMethod(_useItemMethod, player, inventory, item);
			if (flag.HasValue)
			{
				return flag.Value;
			}
		}
		if (_consumeItemMethod != null)
		{
			bool? flag2 = InvokeFoodMethod(_consumeItemMethod, player, inventory, item);
			if (flag2.HasValue)
			{
				return flag2.Value;
			}
		}
		return false;
	}

	private static void ResolveConsumeMethods(Type playerType)
	{
		if (_useItemMethod != null || _consumeItemMethod != null || playerType == null)
		{
			return;
		}
		try
		{
			MethodInfo[] methods = playerType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name != "UseItem" && methodInfo.Name != "ConsumeItem")
				{
					continue;
				}
				ParameterInfo[] parameters = methodInfo.GetParameters();
				bool flag = false;
				bool flag2 = true;
				for (int j = 0; j < parameters.Length; j++)
				{
					Type parameterType = parameters[j].ParameterType;
					if (parameterType == typeof(ItemData))
					{
						flag = true;
					}
					else if (!(parameterType == typeof(Inventory)) && !(parameterType == typeof(bool)))
					{
						flag2 = false;
						break;
					}
				}
				if (flag2 && flag)
				{
					if (methodInfo.Name == "UseItem" && _useItemMethod == null)
					{
						_useItemMethod = methodInfo;
					}
					if (methodInfo.Name == "ConsumeItem" && _consumeItemMethod == null)
					{
						_consumeItemMethod = methodInfo;
					}
				}
			}
		}
		catch
		{
		}
	}

	private static bool? InvokeFoodMethod(MethodInfo method, Player player, Inventory inventory, ItemData item)
	{
		if (method == null)
		{
			return null;
		}
		try
		{
			ParameterInfo[] parameters = method.GetParameters();
			object[] array = new object[parameters.Length];
			for (int i = 0; i < parameters.Length; i++)
			{
				Type parameterType = parameters[i].ParameterType;
				if (parameterType == typeof(ItemData))
				{
					array[i] = item;
					continue;
				}
				if (parameterType == typeof(Inventory))
				{
					array[i] = inventory;
					continue;
				}
				if (parameterType == typeof(bool))
				{
					array[i] = false;
					continue;
				}
				return null;
			}
			object value = method.Invoke(player, array);
			if (method.ReturnType == typeof(bool))
			{
				return Convert.ToBoolean(value);
			}
			return true;
		}
		catch
		{
			return false;
		}
	}
}
[HarmonyPatch(typeof(Player), "GetMaxCarryWeight")]
internal static class CarryWeightPatch
{
	private static void Postfix(ref float __result)
	{
		if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.CarryWeightEnabled))
		{
			__result *= HeimLifeTweaksPlugin.CarryWeightMultiplier.Value;
		}
	}
}
[HarmonyPatch(typeof(Minimap), "UpdateExplore")]
internal static class PathfinderPatch
{
	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		CodeInstruction previous = null;
		foreach (CodeInstruction code in instructions)
		{
			if (previous != null)
			{
				if (previous.opcode == OpCodes.Ldarg_0 && code.opcode == OpCodes.Ldfld && code.operand is FieldInfo && ((FieldInfo)code.operand).Name == "m_exploreRadius")
				{
					yield return new CodeInstruction(OpCodes.Ldarg_2, (object)null);
					yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PathfinderPatch), "GetExploreRadius", (Type[])null, (Type[])null));
					previous = null;
					continue;
				}
				yield return previous;
				previous = null;
			}
			if (code.opcode == OpCodes.Ldarg_0)
			{
				previous = code;
			}
			else
			{
				yield return code;
			}
		}
		if (previous != null)
		{
			yield return previous;
		}
	}

	public static float GetExploreRadius(Player player)
	{
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.PathfinderEnabled))
		{
			return 100f;
		}
		if (HeimLifeTweaksPlugin.PathfinderDisableInDungeons.Value && IsInsideInstancedDungeon(player))
		{
			return 0f;
		}
		return HeimLifeTweaksPlugin.ComputeExploreRadius(player);
	}

	private static bool IsInsideInstancedDungeon(Player player)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null || (Object)(object)((Component)player).transform == (Object)null)
		{
			return false;
		}
		if (((Component)player).transform.position.y > 3000f)
		{
			return true;
		}
		try
		{
			if ((Object)(object)EnvMan.instance == (Object)null)
			{
				return false;
			}
			MethodInfo method = typeof(EnvMan).GetMethod("GetCurrentEnvironment", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
			object obj = ((method == null) ? null : method.Invoke(EnvMan.instance, null));
			if (obj == null)
			{
				return false;
			}
			Type type = obj.GetType();
			string text = "";
			FieldInfo field = type.GetField("m_name", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				object value = field.GetValue(obj);
				if (value != null)
				{
					text = value.ToString();
				}
			}
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			string text2 = text.ToLowerInvariant();
			return text2.Contains("crypt") || text2.Contains("dungeon") || text2.Contains("cave") || text2.Contains("burial") || text2.Contains("trollcave") || text2.Contains("sunken");
		}
		catch
		{
			return false;
		}
	}
}
[HarmonyPatch(typeof(Player), "GetBuildStamina")]
internal static class BuildStaminaPatch
{
	private static void Postfix(ref float __result)
	{
		if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FastToolsEnabled))
		{
			__result *= HeimLifeTweaksPlugin.BuildStaminaMultiplier.Value;
		}
	}
}
[HarmonyPatch(typeof(Player), "UpdatePlacement")]
internal static class FastToolsPlacementPatch
{
	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		CodeInstruction previous = null;
		foreach (CodeInstruction code in instructions)
		{
			if (previous != null)
			{
				if (previous.opcode == OpCodes.Ldarg_0 && code.opcode == OpCodes.Ldfld && code.operand is FieldInfo)
				{
					string name = ((FieldInfo)code.operand).Name;
					if (name == "m_placeDelay")
					{
						yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(FastToolsPlacementPatch), "GetPlaceDelay", (Type[])null, (Type[])null));
						previous = null;
						continue;
					}
					if (name == "m_removeDelay")
					{
						yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(FastToolsPlacementPatch), "GetRemoveDelay", (Type[])null, (Type[])null));
						previous = null;
						continue;
					}
				}
				yield return previous;
				previous = null;
			}
			if (code.opcode == OpCodes.Ldarg_0)
			{
				previous = code;
			}
			else
			{
				yield return code;
			}
		}
		if (previous != null)
		{
			yield return previous;
		}
	}

	public static float GetPlaceDelay()
	{
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FastToolsEnabled))
		{
			return 0.4f;
		}
		return HeimLifeTweaksPlugin.PlaceDelay.Value;
	}

	public static float GetRemoveDelay()
	{
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FastToolsEnabled))
		{
			return 0.25f;
		}
		return HeimLifeTweaksPlugin.RemoveDelay.Value;
	}
}
internal static class DigDeeperTranspilerUtil
{
	internal static IEnumerable<CodeInstruction> ReplaceEight(IEnumerable<CodeInstruction> instructions, bool depth)
	{
		foreach (CodeInstruction code in instructions)
		{
			if (code.opcode == OpCodes.Ldc_R4 && code.operand is float)
			{
				float value = (float)code.operand;
				if (Math.Abs(Math.Abs(value) - 8f) < 0.0001f)
				{
					yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DigDeeperTranspilerUtil), depth ? "GetDepth" : "GetHeight", (Type[])null, (Type[])null));
					if (value < 0f)
					{
						yield return new CodeInstruction(OpCodes.Neg, (object)null);
					}
					continue;
				}
			}
			yield return code;
		}
	}

	public static float GetDepth()
	{
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.DigDeeperEnabled))
		{
			return 8f;
		}
		return HeimLifeTweaksPlugin.DigDepth.Value;
	}

	public static float GetHeight()
	{
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.DigDeeperEnabled))
		{
			return 8f;
		}
		return HeimLifeTweaksPlugin.RaiseHeight.Value;
	}
}
[HarmonyPatch(typeof(Heightmap), "LevelTerrain")]
internal static class DigDeeperHeightmapPatch
{
	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		return DigDeeperTranspilerUtil.ReplaceEight(instructions, depth: true);
	}
}
[HarmonyPatch(typeof(TerrainComp), "ApplyToHeightmap")]
internal static class DigDeeperApplyToHeightmapPatch
{
	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		return DigDeeperTranspilerUtil.ReplaceEight(instructions, depth: true);
	}
}
[HarmonyPatch(typeof(TerrainComp), "LevelTerrain")]
internal static class DigDeeperTerrainLevelPatch
{
	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		return DigDeeperTranspilerUtil.ReplaceEight(instructions, depth: true);
	}
}
[HarmonyPatch(typeof(TerrainComp), "RaiseTerrain")]
internal static class DigDeeperTerrainRaisePatch
{
	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		return DigDeeperTranspilerUtil.ReplaceEight(instructions, depth: false);
	}
}
[HarmonyPatch]
internal static class ElderResourceDamagePatch
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		Type[] types = new Type[5]
		{
			typeof(TreeBase),
			typeof(TreeLog),
			typeof(MineRock),
			typeof(MineRock5),
			typeof(Destructible)
		};
		HashSet<MethodBase> seen = new HashSet<MethodBase>();
		foreach (Type type in types)
		{
			if (type == null)
			{
				continue;
			}
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo method in methods)
			{
				if (!(method.Name != "Damage"))
				{
					ParameterInfo[] p = method.GetParameters();
					if (p.Length >= 1 && !(p[0].ParameterType != typeof(HitData)) && seen.Add(method))
					{
						yield return method;
					}
				}
			}
		}
	}

	private static void Prefix(object __instance, HitData hit)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		if (hit == null)
		{
			return;
		}
		_ = hit.m_damage;
		if (!HeimLifeTweaksPlugin.IsBossPowerAvailable(HeimLifeTweaksPlugin.BossElderEnabled, "defeated_gdking"))
		{
			return;
		}
		float num = 1f + Mathf.Max(0f, HeimLifeTweaksPlugin.ElderChopDamage.Value) / 100f;
		float num2 = 1f + Mathf.Max(0f, HeimLifeTweaksPlugin.ElderPickaxeDamage.Value) / 100f;
		try
		{
			if (hit.m_damage.m_chop > 0f)
			{
				ref DamageTypes damage = ref hit.m_damage;
				damage.m_chop *= num;
			}
			if (hit.m_damage.m_pickaxe > 0f)
			{
				ref DamageTypes damage2 = ref hit.m_damage;
				damage2.m_pickaxe *= num2;
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(Player), "ActivateGuardianPower")]
internal static class DisableGuardianPowerActivationPatch
{
	private static bool Prefix(Player __instance, ref bool __result)
	{
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.BossPowersEnabled))
		{
			return true;
		}
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_guardianPowerCooldown");
			if (fieldInfo != null)
			{
				fieldInfo.SetValue(__instance, 0f);
			}
		}
		catch
		{
		}
		__result = false;
		return false;
	}
}
[HarmonyPatch(typeof(Beehive), "UpdateBees")]
internal static class BeehiveUpdatePatch
{
	internal sealed class ProgressSnapshot
	{
		internal float Product;

		internal float UnityTime;

		internal int HoneyLevel;
	}

	internal static readonly Dictionary<int, ProgressSnapshot> Progress = new Dictionary<int, ProgressSnapshot>();

	private static void Postfix(Beehive __instance)
	{
		if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.BeehiveEnabled))
		{
			return;
		}
		try
		{
			__instance.m_secPerUnit = HeimLifeTweaksPlugin.HoneyProductionSeconds.Value;
			__instance.m_maxHoney = HeimLifeTweaksPlugin.MaximumHoney.Value;
		}
		catch
		{
		}
		int honeyLevel = GetHoneyLevel(__instance);
		ZNetView nView = GetNView(__instance);
		ZDO val = (((Object)(object)nView == (Object)null) ? null : nView.GetZDO());
		float product = 0f;
		if (val != null)
		{
			try
			{
				product = val.GetFloat(ZDOVars.s_product, 0f);
			}
			catch
			{
			}
		}
		try
		{
			int instanceID = ((Object)__instance).GetInstanceID();
			if (!Progress.TryGetValue(instanceID, out var value))
			{
				value = new ProgressSnapshot();
				Progress[instanceID] = value;
			}
			value.Product = product;
			value.UnityTime = Time.time;
			value.HoneyLevel = honeyLevel;
		}
		catch
		{
		}
	}

	internal static int GetHoneyLevel(Beehive hive)
	{
		if ((Object)(object)hive == (Object)null)
		{
			return 0;
		}
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Beehive), "GetHoneyLevel", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				return Convert.ToInt32(methodInfo.Invoke(hive, null));
			}
		}
		catch
		{
		}
		try
		{
			ZNetView nView = GetNView(hive);
			ZDO val = (((Object)(object)nView == (Object)null) ? null : nView.GetZDO());
			if (val != null)
			{
				return val.GetInt(ZDOVars.s_level, 0);
			}
		}
		catch
		{
		}
		return 0;
	}

	internal static ZNetView GetNView(Beehive hive)
	{
		if ((Object)(object)hive == (Object)null)
		{
			return null;
		}
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(Beehive), "m_nview");
			if (fieldInfo != null)
			{
				object? value = fieldInfo.GetValue(hive);
				return (ZNetView)((value is ZNetView) ? value : null);
			}
		}
		catch
		{
		}
		try
		{
			return ((Component)hive).GetComponent<ZNetView>();
		}
		catch
		{
			return null;
		}
	}

	private static Container FindNearestContainer(Vector3 position, float range)
	{
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		Container result = null;
		float num = range;
		try
		{
			Container[] array = Object.FindObjectsOfType<Container>();
			foreach (Container val in array)
			{
				if ((Object)(o