Decompiled source of KingsTweaks v2.41.3

KingsTweaks.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("KingsTweaks")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Clouduser")]
[assembly: AssemblyProduct("KingsTweaks")]
[assembly: AssemblyCopyright("Copyright © Clouduser 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("8d2599f3-d914-47ab-8365-3f90fbb2d0c3")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Craz.KingsTweaks;

[BepInPlugin("dev.craz.kingstweaks", "KingsTweaks", "2.41.3")]
public class KingsTweaksPlugin : BaseUnityPlugin
{
	public const string ModGuid = "dev.craz.kingstweaks";

	public const string ModName = "KingsTweaks";

	public const string ModVersion = "2.41.3";

	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> ModEnabled;

	internal static ConfigEntry<bool> EnforceSameVersion;

	internal static ConfigEntry<bool> ActivityFeedEnabled;

	internal static ConfigEntry<float> ActivityFeedSeconds;

	internal static ConfigEntry<float> ChestNoticeMinutes;

	internal static ConfigEntry<float> ChestNoticeRange;

	internal static ConfigEntry<bool> DyeEnabled;

	internal static ConfigEntry<bool> AutoRepairEnabled;

	internal static ConfigEntry<bool> TravelEnabled;

	internal static ConfigEntry<float> TravelCooldown;

	internal static ConfigEntry<bool> WarpsEnabled;

	internal static ConfigEntry<bool> ServerCharactersEnabled;

	internal static ConfigEntry<float> ServerCharacterSaveSeconds;

	internal static ConfigEntry<bool> ServerCharacterWipeSkills;

	internal static ConfigEntry<string> ServerCharacterMessage;

	internal static ConfigEntry<bool> SleepersEnabled;

	internal static ConfigEntry<float> SleeperRefreshSeconds;

	internal static ConfigEntry<bool> SleeperSafeFromCreatures;

	internal static ConfigEntry<float> TravelWarmup;

	internal static ConfigEntry<float> TravelCombatSeconds;

	internal static ConfigEntry<bool> TravelBlockNearEnemies;

	internal static ConfigEntry<bool> TravelBlockEncumbered;

	internal static ConfigEntry<bool> TravelAllowMetals;

	internal static ConfigEntry<float> TravelEnemyRange;

	internal static ConfigEntry<bool> RestartsEnabled;

	internal static ConfigEntry<string> RestartTimes;

	internal static ConfigEntry<bool> SignTextLimit;

	internal static ConfigEntry<int> SignCharacters;

	internal static ConfigEntry<bool> FreeBuildEnabled;

	internal static ConfigEntry<string> HiddenCommands;

	internal static ConfigEntry<bool> CommandsIgnoreCase;

	internal static ConfigEntry<bool> TeamMapPins;

	internal static ConfigEntry<bool> ClearDeathPinsButton;

	internal static ConfigEntry<bool> ProtectEmptyShips;

	internal static ConfigEntry<bool> NoPinSharing;

	internal static ConfigEntry<bool> AutoPickupSpears;

	internal static ConfigEntry<float> SpearPickupRange;

	internal static ConfigEntry<bool> CartDismantle;

	internal static ConfigEntry<bool> TorchWithTools;

	internal static ConfigEntry<bool> HideDayNumber;

	internal static ConfigEntry<bool> KeepSkillsOnDeath;

	internal static ConfigEntry<string> DisabledCommands;

	internal static ConfigEntry<bool> WhoEnabled;

	internal static ConfigEntry<bool> WhoAdminsOnly;

	internal static ConfigEntry<bool> PlaytimeEnabled;

	internal static ConfigEntry<bool> TeamsEnabled;

	internal static ConfigEntry<bool> TeamPingsOnly;

	internal static ConfigEntry<bool> TeamHud;

	internal static ConfigEntry<bool> TeamWards;

	internal static ConfigEntry<bool> AutoShield;

	internal static ConfigEntry<bool> PvpForced;

	internal static ConfigEntry<bool> PowerResetOnDeath;

	internal static ConfigEntry<bool> FirstPersonAllowed;

	internal static ConfigEntry<bool> FirstPersonForced;

	internal static ConfigEntry<bool> FirstPersonEnabled;

	internal static ConfigEntry<float> FirstPersonZoom;

	internal static ConfigEntry<float> FirstPersonForward;

	internal static ConfigEntry<float> FirstPersonHeight;

	internal static ConfigEntry<float> FirstPersonBack;

	internal static ConfigEntry<bool> FirstPersonFollowHead;

	internal static ConfigEntry<float> FirstPersonNearClip;

	internal static ConfigEntry<bool> FirstPersonShowBody;

	internal static ConfigEntry<bool> FirstPersonHideHead;

	internal static ConfigEntry<string> FirstPersonHiddenParts;

	internal static ConfigEntry<bool> FirstPersonFaceCamera;

	internal static ConfigEntry<bool> FirstPersonHeadBob;

	internal static ConfigEntry<float> FirstPersonSteadiness;

	internal static ConfigEntry<bool> FirstPersonTurnBody;

	internal static ConfigEntry<float> FirstPersonTurnAngle;

	internal static ConfigEntry<bool> NoSpawnsInWards;

	internal static ConfigEntry<bool> WardSpawnsDuringRaids;

	internal static ConfigEntry<bool> SpawnScaleEnabled;

	internal static ConfigEntry<float> CreatureSpawnMultiplier;

	internal static ConfigEntry<float> AnimalSpawnMultiplier;

	internal static ConfigEntry<bool> ChestsRespectWards;

	internal static ConfigEntry<bool> ChestNaming;

	internal static ConfigEntry<bool> SorterUsesNames;

	internal static ConfigEntry<bool> BoatPinsEnabled;

	internal static ConfigEntry<string> Motd;

	internal static ConfigEntry<bool> MotdCommandsHint;

	internal static ConfigEntry<bool> UpdateCheckEnabled;

	internal static ConfigEntry<string> UpdateVersionUrl;

	internal static ConfigEntry<bool> ShipBuildEnabled;

	internal static ConfigEntry<int> MaxPiecesPerShip;

	internal static ConfigEntry<bool> PlantingEnabled;

	internal static ConfigEntry<string> PlantList;

	internal static ConfigEntry<float> PlantGrowTime;

	internal static ConfigEntry<bool> PlantIgnoreSpacing;

	internal static ConfigEntry<bool> BlockRainWear;

	internal static ConfigEntry<bool> RequireWard;

	internal static ConfigEntry<bool> BlockWaterDamage;

	internal static ConfigEntry<bool> InfiniteTorches;

	internal static ConfigEntry<bool> InfiniteCampfires;

	internal static ConfigEntry<bool> InfiniteOtherFires;

	internal static ConfigEntry<bool> DayLengthEnabled;

	internal static ConfigEntry<float> DayMultiplier;

	internal static ConfigEntry<float> NightMultiplier;

	internal static ConfigEntry<bool> PortalRangeEnabled;

	internal static ConfigEntry<float> PortalActivationRange;

	internal static ConfigEntry<bool> TeleportEverything;

	internal static ConfigEntry<bool> PortalsBuildable;

	internal static ConfigEntry<bool> BoatHealthEnabled;

	internal static ConfigEntry<float> RaftHealth;

	internal static ConfigEntry<float> KarveHealth;

	internal static ConfigEntry<float> LongshipHealth;

	internal static ConfigEntry<float> DrakkarHealth;

	internal static ConfigEntry<float> OtherBoatHealth;

	internal static ConfigEntry<bool> BoatHammerRemoval;

	internal static ConfigEntry<bool> FloatingItems;

	internal static ConfigEntry<bool> MergeItems;

	internal static ConfigEntry<float> MergeRadius;

	internal static ConfigEntry<float> MergeInterval;

	internal static ConfigEntry<bool> ComfortEnabled;

	internal static ConfigEntry<float> ComfortRadius;

	internal static ConfigEntry<bool> CollectorEnabled;

	internal static ConfigEntry<bool> CollectorBuildable;

	internal static ConfigEntry<float> CollectorRange;

	internal static ConfigEntry<float> CollectorMinItemAge;

	internal static ConfigEntry<string> CollectorCost;

	internal static ConfigEntry<bool> TrashEnabled;

	internal static ConfigEntry<bool> TrashBuildable;

	internal static ConfigEntry<string> TrashCost;

	internal static ConfigEntry<bool> SleepInUnclaimedBeds;

	internal static ConfigEntry<float> ClaimHoldSeconds;

	internal static ConfigEntry<bool> FuelChestEnabled;

	internal static ConfigEntry<bool> FuelChestBuildable;

	internal static ConfigEntry<float> FuelChestRange;

	internal static ConfigEntry<string> FuelChestCost;

	internal static ConfigEntry<bool> RememberPasswords;

	internal static ConfigEntry<bool> UpkeepEnabled;

	internal static ConfigEntry<bool> UpkeepBuildable;

	internal static ConfigEntry<float> UpkeepRange;

	internal static ConfigEntry<float> UpkeepCostMultiplier;

	internal static ConfigEntry<string> UpkeepCost;

	internal static ConfigEntry<bool> SorterEnabled;

	internal static ConfigEntry<bool> SorterBuildable;

	internal static ConfigEntry<float> SorterRange;

	internal static ConfigEntry<string> SorterCost;

	internal static ConfigEntry<bool> CraftFromChestsEnabled;

	internal static ConfigEntry<float> CraftRange;

	internal static ConfigEntry<bool> SharedChests;

	internal static ConfigEntry<bool> WardSizeEnabled;

	internal static ConfigEntry<float> WardRadius;

	internal static ConfigEntry<bool> BuildAnywhere;

	internal static ConfigEntry<bool> TroughEnabled;

	internal static ConfigEntry<bool> TroughBuildable;

	internal static ConfigEntry<float> TroughRange;

	internal static ConfigEntry<string> TroughCost;

	internal static ConfigEntry<bool> SmelterChestEnabled;

	internal static ConfigEntry<bool> SmelterChestBuildable;

	internal static ConfigEntry<float> SmelterChestRange;

	internal static ConfigEntry<string> SmelterChestCost;

	internal static ConfigEntry<bool> DefaultShout;

	internal static ConfigEntry<KeyboardShortcut> ChatToggleKey;

	internal static ConfigEntry<bool> DeathNotifications;

	internal static ConfigEntry<bool> DeathIncludeBiome;

	internal static ConfigEntry<bool> DeathIncludeKiller;

	internal static ConfigEntry<bool> MistClearAllowed;

	internal static ConfigEntry<bool> FogClearAllowed;

	internal static ConfigEntry<bool> FogClearByDefault;

	internal static ConfigEntry<bool> EmberClearAllowed;

	internal static ConfigEntry<bool> EmberClearByDefault;

	internal static ConfigEntry<bool> FreeOverlap;

	internal static ConfigEntry<bool> PermissionsEnabled;

	internal static ConfigEntry<bool> CraftSearchButton;

	internal static ConfigEntry<bool> SizeAllowed;

	internal static ConfigEntry<bool> WhiteDeerEnabled;

	internal static ConfigEntry<float> WhiteDeerChance;

	internal static ConfigEntry<float> WhiteDeerInterval;

	internal static ConfigEntry<bool> SizeAdminsOnly;

	internal static ConfigEntry<float> SizeMin;

	internal static ConfigEntry<float> SizeMax;

	internal static ConfigEntry<string> SuperAdmins;

	internal static ConfigEntry<bool> BoatWorkstation;

	internal static ConfigEntry<float> BoatWorkstationRange;

	internal static ConfigEntry<bool> MistClearByDefault;

	internal static ConfigEntry<float> MistClearRadius;

	internal static ConfigEntry<KeyboardShortcut> MistToggleKey;

	internal static ConfigEntry<bool> UnstuckEnabled;

	internal static ConfigEntry<float> UnstuckCooldown;

	internal static ConfigEntry<bool> CompassEnabled;

	internal static ConfigEntry<bool> CompassShowPins;

	internal static ConfigEntry<bool> CompassHideCheckedPins;

	internal static ConfigEntry<bool> CompassShowDistance;

	internal static ConfigEntry<float> CompassPinRange;

	internal static ConfigEntry<bool> BackupsEnabled;

	internal static ConfigEntry<int> BackupKeep;

	internal static ConfigEntry<float> BackupMinInterval;

	internal static ConfigEntry<bool> HideShoutInWorld;

	internal static ConfigEntry<bool> HidePingInWorld;

	internal static ConfigEntry<bool> ShoutKeepCase;

	internal static ConfigEntry<bool> HoldToOpenTowards;

	internal static ConfigEntry<float> HoldSeconds;

	internal static ConfigEntry<bool> DoorsWhileBuilding;

	internal static ConfigEntry<bool> DoorLocks;

	internal static ConfigEntry<bool> ChestLocks;

	internal static ConfigEntry<bool> WardLocks;

	internal static ConfigEntry<bool> LocksOpenForOwners;

	internal static ConfigEntry<bool> HideSkyTree;

	internal static ConfigEntry<bool> RemoveStumps;

	internal static ConfigEntry<bool> StumpsDropWood;

	internal static ConfigEntry<KeyboardShortcut> MenuKey;

	internal static ConfigEntry<bool> SettingsHint;

	internal static ConfigEntry<bool> NoStaminaInWard;

	internal static ConfigEntry<bool> UpgradeFreeSpace;

	internal static ConfigEntry<float> UpgradeRange;

	internal static ConfigEntry<bool> HubEnabled;

	internal static ConfigEntry<bool> HubBuildable;

	internal static ConfigEntry<string> HubCost;

	internal static ConfigEntry<string> HubTravelCost;

	internal static ConfigEntry<float> HubWindowRange;

	internal static ConfigEntry<bool> HubEffects;

	internal static ConfigEntry<string> HubEffectColour;

	internal static ConfigEntry<float> HubTriggerRadius;

	internal static ConfigEntry<float> HubReopenDistance;

	internal static ConfigEntry<bool> TamesStayOnBoats;

	internal static ConfigEntry<bool> TameTracking;

	internal static ConfigEntry<bool> TameHealthEnabled;

	internal static ConfigEntry<float> TameHealthMultiplier;

	internal static ConfigEntry<string> TameHealthBySpecies;

	internal static ConfigEntry<bool> MinimapAllowed;

	internal static ConfigEntry<bool> FullMapAllowed;

	internal static ConfigEntry<float> MapExploreMultiplier;

	internal static ConfigEntry<bool> CompassAllowed;

	internal static ConfigEntry<bool> TamesFollowThroughPortals;

	internal static ConfigEntry<float> TameTeleportRange;

	internal static ConfigEntry<KeyboardShortcut> ShipStowKey;

	internal static ConfigEntry<float> ShipStowRange;

	internal static ConfigEntry<bool> ContinueButton;

	internal static ConfigEntry<bool> HideStoreButton;

	internal static ConfigEntry<bool> DonateButton;

	internal static ConfigEntry<string> DonateLabel;

	internal static ConfigEntry<string> DonateUrl;

	private readonly Harmony _harmony = new Harmony("dev.craz.kingstweaks");

	private volatile bool _reloadRequested;

	private FileSystemWatcher _watcher;

	internal static KingsTweaksPlugin Instance;

	private void Awake()
	{
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Expected O, but got Unknown
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Expected O, but got Unknown
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Expected O, but got Unknown
		//IL_039c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a6: Expected O, but got Unknown
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e3: Expected O, but got Unknown
		//IL_0436: Unknown result type (might be due to invalid IL or missing references)
		//IL_0440: Expected O, but got Unknown
		//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bd: Expected O, but got Unknown
		//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fa: Expected O, but got Unknown
		//IL_05d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05df: Expected O, but got Unknown
		//IL_0652: Unknown result type (might be due to invalid IL or missing references)
		//IL_065c: Expected O, but got Unknown
		//IL_07bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_07c5: Expected O, but got Unknown
		//IL_07f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0802: Expected O, but got Unknown
		//IL_0899: Unknown result type (might be due to invalid IL or missing references)
		//IL_08a3: Expected O, but got Unknown
		//IL_091a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0924: Expected O, but got Unknown
		//IL_0997: Unknown result type (might be due to invalid IL or missing references)
		//IL_09a1: Expected O, but got Unknown
		//IL_0a34: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a3e: Expected O, but got Unknown
		//IL_0ad5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0adf: Expected O, but got Unknown
		//IL_0b48: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c2a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c34: Expected O, but got Unknown
		//IL_0c59: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d7f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d89: Expected O, but got Unknown
		//IL_0dbc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0dc6: Expected O, but got Unknown
		//IL_0e39: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e43: Expected O, but got Unknown
		//IL_0e76: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e80: Expected O, but got Unknown
		//IL_0f13: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f1d: Expected O, but got Unknown
		//IL_0f90: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f9a: Expected O, but got Unknown
		//IL_0fb6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ff8: Unknown result type (might be due to invalid IL or missing references)
		//IL_1002: Expected O, but got Unknown
		//IL_1075: Unknown result type (might be due to invalid IL or missing references)
		//IL_107f: Expected O, but got Unknown
		//IL_115e: Unknown result type (might be due to invalid IL or missing references)
		//IL_1168: Expected O, but got Unknown
		//IL_11df: Unknown result type (might be due to invalid IL or missing references)
		//IL_11e9: Expected O, but got Unknown
		//IL_121c: Unknown result type (might be due to invalid IL or missing references)
		//IL_1226: Expected O, but got Unknown
		//IL_1299: Unknown result type (might be due to invalid IL or missing references)
		//IL_12a3: Expected O, but got Unknown
		//IL_12e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_1384: Unknown result type (might be due to invalid IL or missing references)
		//IL_138e: Expected O, but got Unknown
		//IL_14e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_14eb: Expected O, but got Unknown
		//IL_153e: Unknown result type (might be due to invalid IL or missing references)
		//IL_1548: Expected O, but got Unknown
		//IL_163b: Unknown result type (might be due to invalid IL or missing references)
		//IL_1645: Expected O, but got Unknown
		//IL_16f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_1702: Expected O, but got Unknown
		//IL_17ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_17d8: Expected O, but got Unknown
		//IL_180b: Unknown result type (might be due to invalid IL or missing references)
		//IL_1815: Expected O, but got Unknown
		//IL_1888: Unknown result type (might be due to invalid IL or missing references)
		//IL_1892: Expected O, but got Unknown
		//IL_18c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_18cf: Expected O, but got Unknown
		//IL_1902: Unknown result type (might be due to invalid IL or missing references)
		//IL_190c: Expected O, but got Unknown
		//IL_1a27: Unknown result type (might be due to invalid IL or missing references)
		//IL_1a31: Expected O, but got Unknown
		//IL_1a64: Unknown result type (might be due to invalid IL or missing references)
		//IL_1a6e: Expected O, but got Unknown
		//IL_1b81: Unknown result type (might be due to invalid IL or missing references)
		//IL_1b8b: Expected O, but got Unknown
		//IL_1bbe: Unknown result type (might be due to invalid IL or missing references)
		//IL_1bc8: Expected O, but got Unknown
		//IL_1bfb: Unknown result type (might be due to invalid IL or missing references)
		//IL_1c05: Expected O, but got Unknown
		//IL_1c38: Unknown result type (might be due to invalid IL or missing references)
		//IL_1c42: Expected O, but got Unknown
		//IL_1c95: Unknown result type (might be due to invalid IL or missing references)
		//IL_1c9f: Expected O, but got Unknown
		//IL_1d76: Unknown result type (might be due to invalid IL or missing references)
		//IL_1d80: Expected O, but got Unknown
		//IL_1dd3: Unknown result type (might be due to invalid IL or missing references)
		//IL_1ddd: Expected O, but got Unknown
		//IL_1ef1: Unknown result type (might be due to invalid IL or missing references)
		//IL_1efb: Expected O, but got Unknown
		//IL_2116: Unknown result type (might be due to invalid IL or missing references)
		//IL_2120: Expected O, but got Unknown
		//IL_2153: Unknown result type (might be due to invalid IL or missing references)
		//IL_215d: Expected O, but got Unknown
		//IL_21b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_21ba: Expected O, but got Unknown
		//IL_224d: Unknown result type (might be due to invalid IL or missing references)
		//IL_2257: Expected O, but got Unknown
		//IL_22ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_22f8: Expected O, but got Unknown
		//IL_236b: Unknown result type (might be due to invalid IL or missing references)
		//IL_2375: Expected O, but got Unknown
		//IL_23c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_23ca: Expected O, but got Unknown
		//IL_2441: Unknown result type (might be due to invalid IL or missing references)
		//IL_244b: Expected O, but got Unknown
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		ConfigMigration.Capture(((BaseUnityPlugin)this).Config.ConfigFilePath);
		ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("01 - General", "ModEnabled", true, "Master switch. When false, every feature below is disabled.");
		BlockRainWear = ((BaseUnityPlugin)this).Config.Bind<bool>("02 - Structures", "BlockRainWear", false, "Structures don't weather/decay from being exposed to rain without a roof.");
		RequireWard = ((BaseUnityPlugin)this).Config.Bind<bool>("02 - Structures", "RequireWard", true, "If true, rain wear protection only applies to structures inside an active (enabled) ward.");
		BlockWaterDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("02 - Structures", "BlockWaterDamage", false, "Structures take no damage from being in water (waves, tides, flooded ground). RequireWard applies to this as well.");
		InfiniteTorches = ((BaseUnityPlugin)this).Config.Bind<bool>("04 - Fires", "InfiniteTorches", false, "Standing torches, wall torches/sconces, braziers and lanterns never run out of fuel.");
		InfiniteCampfires = ((BaseUnityPlugin)this).Config.Bind<bool>("04 - Fires", "InfiniteCampfires", false, "Campfires, hearths and bonfires never run out of fuel.");
		InfiniteOtherFires = ((BaseUnityPlugin)this).Config.Bind<bool>("04 - Fires", "InfiniteOtherFires", false, "Any other fuel-burning fireplace not matched above (e.g. the hot tub).");
		DayLengthEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("05 - Time", "DayLengthEnabled", false, "Enable the day and night multipliers below.");
		DayMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("05 - Time", "DayMultiplier", 3f, new ConfigDescription("How long daytime lasts compared to vanilla. 2.0 = days twice as long, 0.5 = half as long.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 50f), Array.Empty<object>()));
		NightMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("05 - Time", "NightMultiplier", 1f, new ConfigDescription("How long nighttime lasts compared to vanilla. 2.0 = nights twice as long, 0.5 = half as long.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 50f), Array.Empty<object>()));
		PortalRangeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("12 - Portals", "PortalRangeEnabled", false, "Enable the portal activation range below.");
		PortalActivationRange = ((BaseUnityPlugin)this).Config.Bind<float>("12 - Portals", "PortalActivationRange", 15f, new ConfigDescription("Distance in meters at which a player makes a portal light up / activate.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 500f), Array.Empty<object>()));
		TeleportEverything = ((BaseUnityPlugin)this).Config.Bind<bool>("12 - Portals", "TeleportEverything", true, "Ore, metal bars and anything else normally blocked can be carried through portals.");
		PortalsBuildable = ((BaseUnityPlugin)this).Config.Bind<bool>("12 - Portals", "PortalsBuildable", true, "When false, ordinary portals are taken out of the build menu and can't be placed. Portal Hubs are unaffected, so they can be the only way to travel.");
		BoatHealthEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("07 - Boats", "BoatHealthEnabled", true, "Enable custom boat health values below. 0 = keep vanilla health for that boat.");
		RaftHealth = ((BaseUnityPlugin)this).Config.Bind<float>("07 - Boats", "RaftHealth", 800f, "Raft max health. 0 = vanilla.");
		KarveHealth = ((BaseUnityPlugin)this).Config.Bind<float>("07 - Boats", "KarveHealth", 2000f, "Karve max health. 0 = vanilla.");
		LongshipHealth = ((BaseUnityPlugin)this).Config.Bind<float>("07 - Boats", "LongshipHealth", 8000f, "Longship max health. 0 = vanilla.");
		DrakkarHealth = ((BaseUnityPlugin)this).Config.Bind<float>("07 - Boats", "DrakkarHealth", 10000f, "Drakkar max health. 0 = vanilla.");
		OtherBoatHealth = ((BaseUnityPlugin)this).Config.Bind<float>("07 - Boats", "OtherBoatHealth", 0f, "Max health for any boat not listed above (e.g. modded boats). 0 = vanilla.");
		BoatHammerRemoval = ((BaseUnityPlugin)this).Config.Bind<bool>("07 - Boats", "BoatHammerRemoval", true, "Boats can be deconstructed with the hammer (middle mouse), refunding materials like other pieces.");
		FloatingItems = ((BaseUnityPlugin)this).Config.Bind<bool>("14 - Dropped Items", "FloatingItems", true, "Dropped items float on the water surface instead of sinking.");
		MergeItems = ((BaseUnityPlugin)this).Config.Bind<bool>("14 - Dropped Items", "MergeItems", true, "Nearby dropped items of the same type are combined into one stack (up to the item's max stack size).");
		MergeRadius = ((BaseUnityPlugin)this).Config.Bind<float>("14 - Dropped Items", "MergeRadius", 3f, new ConfigDescription("How close (meters) items must be to merge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 100f), Array.Empty<object>()));
		MergeInterval = ((BaseUnityPlugin)this).Config.Bind<float>("14 - Dropped Items", "MergeInterval", 5f, new ConfigDescription("Seconds between merge passes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 600f), Array.Empty<object>()));
		ComfortEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("06 - Comfort", "ComfortEnabled", true, "Enable the custom comfort radius below.");
		ComfortRadius = ((BaseUnityPlugin)this).Config.Bind<float>("06 - Comfort", "ComfortRadius", 40f, new ConfigDescription("Radius (meters) in which comfort pieces count toward your comfort level. Vanilla is 10.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 200f), Array.Empty<object>()));
		CollectorEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("16 - Chest - Item Collector", "CollectorEnabled", true, "Item Collector chests pull in nearby dropped items. When false they act as normal chests.");
		CollectorBuildable = ((BaseUnityPlugin)this).Config.Bind<bool>("16 - Chest - Item Collector", "CollectorBuildable", true, "Item Collector appears in the hammer build menu.");
		CollectorRange = ((BaseUnityPlugin)this).Config.Bind<float>("16 - Chest - Item Collector", "CollectorRange", 50f, new ConfigDescription("Radius (meters) the Item Collector collects from.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 200f), Array.Empty<object>()));
		CollectorMinItemAge = ((BaseUnityPlugin)this).Config.Bind<float>("16 - Chest - Item Collector", "CollectorMinItemAge", 300f, new ConfigDescription("Seconds an item must have been on the ground before a collector will pick it up. 300 = 5 minutes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 86400f), Array.Empty<object>()));
		CollectorCost = ((BaseUnityPlugin)this).Config.Bind<string>("16 - Chest - Item Collector", "CollectorCost", "FineWood:50,IronNails:50,SurtlingCore:10,GreydwarfEye:4", "Build cost as PrefabName:Amount pairs separated by commas.");
		TrashEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("17 - Chest - Trash Can", "TrashEnabled", true, "Items left in a Trash Can are destroyed when you close it. When false it acts as a normal chest.");
		TrashBuildable = ((BaseUnityPlugin)this).Config.Bind<bool>("17 - Chest - Trash Can", "TrashBuildable", true, "Trash Can appears in the hammer build menu.");
		TrashCost = ((BaseUnityPlugin)this).Config.Bind<string>("17 - Chest - Trash Can", "TrashCost", "", "Build cost as PrefabName:Amount pairs separated by commas. Leave empty to use the same cost as a regular wood chest.");
		SleepInUnclaimedBeds = ((BaseUnityPlugin)this).Config.Bind<bool>("22 - Beds", "SleepInUnclaimedBeds", true, "Tap Use on an unclaimed bed to sleep in it without claiming it or changing your spawn. Hold Use to claim it (vanilla behavior). Beds you or others own work like vanilla.");
		ClaimHoldSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("22 - Beds", "ClaimHoldSeconds", 0.3f, new ConfigDescription("How long Use must be held on an unclaimed bed to claim it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
		FuelChestEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("19 - Chest - Fuel", "FuelChestEnabled", true, "Once per in-game day, Fuel Chests top up fires and torches in range using the fuel stored inside. Fires whose type has infinite fuel turned on (section 03) are skipped. When false they act as normal chests.");
		FuelChestBuildable = ((BaseUnityPlugin)this).Config.Bind<bool>("19 - Chest - Fuel", "FuelChestBuildable", true, "Fuel Chest appears in the hammer build menu.");
		FuelChestRange = ((BaseUnityPlugin)this).Config.Bind<float>("19 - Chest - Fuel", "FuelChestRange", 60f, new ConfigDescription("Radius (meters) around the Fuel Chest that gets refueled.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 200f), Array.Empty<object>()));
		FuelChestCost = ((BaseUnityPlugin)this).Config.Bind<string>("19 - Chest - Fuel", "FuelChestCost", "Wood:20,Resin:10,SurtlingCore:1", "Build cost as PrefabName:Amount pairs separated by commas. Leave empty to use the same cost as a regular wood chest.");
		RememberPasswords = ((BaseUnityPlugin)this).Config.Bind<bool>("31 - Menu and Login", "RememberPasswords", true, "Client-side. After you join a password-protected server once, the password is saved and entered automatically next time. Saved passwords are stored (lightly obfuscated, not encrypted) in BepInEx/config/dev.craz.kingstweaks.passwords.txt; delete that file to forget them all. A saved password the server rejects is removed automatically.");
		ContinueButton = ((BaseUnityPlugin)this).Config.Bind<bool>("31 - Menu and Login", "ContinueButton", true, "Adds a Continue button to the main menu that loads whatever you played last - the same character plus either that world or that server.");
		HideStoreButton = ((BaseUnityPlugin)this).Config.Bind<bool>("31 - Menu and Login", "HideStoreButton", true, "Hides the merch store button on the main menu.");
		DonateButton = ((BaseUnityPlugin)this).Config.Bind<bool>("31 - Menu and Login", "DonateButton", true, "Puts a donate button where the merch store button was. Needs the store button to exist, since it takes its place rather than adding a new one.");
		DonateLabel = ((BaseUnityPlugin)this).Config.Bind<string>("31 - Menu and Login", "DonateLabel", "Support KingsTweaks", "What the donate button says. Keep it short: it has to fit the menu's button.");
		DonateUrl = ((BaseUnityPlugin)this).Config.Bind<string>("31 - Menu and Login", "DonateUrl", "https://www.paypal.com/paypalme/CrazTK", "Where the donate button goes. It opens in your browser, outside the game.");
		UpkeepEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("20 - Chest - Upkeep", "UpkeepEnabled", true, "Once per in-game day, Upkeep Chests repair damaged structures in range using the materials stored inside. When false they act as normal chests.");
		UpkeepBuildable = ((BaseUnityPlugin)this).Config.Bind<bool>("20 - Chest - Upkeep", "UpkeepBuildable", true, "Upkeep Chest appears in the hammer build menu.");
		UpkeepRange = ((BaseUnityPlugin)this).Config.Bind<float>("20 - Chest - Upkeep", "UpkeepRange", 60f, new ConfigDescription("Radius (meters) around the Upkeep Chest that gets repaired.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 200f), Array.Empty<object>()));
		UpkeepCostMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("20 - Chest - Upkeep", "UpkeepCostMultiplier", 0.1f, new ConfigDescription("Repair cost as a share of the piece's build materials, scaled by how damaged it is. 1.0 = a piece at half health costs half its build cost. 0 = free repairs.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
		UpkeepCost = ((BaseUnityPlugin)this).Config.Bind<string>("20 - Chest - Upkeep", "UpkeepCost", "FineWood:20,Bronze:5", "Build cost as PrefabName:Amount pairs separated by commas. Leave empty to use the same cost as a regular wood chest.");
		SorterEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("18 - Chest - Sorter", "SorterEnabled", true, "Sorter Chests push their contents into nearby chests that already hold the same item. When false they act as normal chests.");
		SorterBuildable = ((BaseUnityPlugin)this).Config.Bind<bool>("18 - Chest - Sorter", "SorterBuildable", true, "Sorter Chest appears in the hammer build menu.");
		SorterRange = ((BaseUnityPlugin)this).Config.Bind<float>("18 - Chest - Sorter", "SorterRange", 40f, new ConfigDescription("Radius (meters) the Sorter Chest sorts into.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 200f), Array.Empty<object>()));
		SorterCost = ((BaseUnityPlugin)this).Config.Bind<string>("18 - Chest - Sorter", "SorterCost", "Wood:20,Copper:10", "Build cost as PrefabName:Amount pairs separated by commas. Leave empty to use the same cost as a regular wood chest.");
		CraftFromChestsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("15 - Chests", "CraftFromChestsEnabled", true, "Building and crafting can use items stored in nearby chests as well as your inventory.");
		CraftRange = ((BaseUnityPlugin)this).Config.Bind<float>("15 - Chests", "CraftRange", 60f, new ConfigDescription("Radius (meters) chests are pulled from when crafting or building.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 200f), Array.Empty<object>()));
		SharedChests = ((BaseUnityPlugin)this).Config.Bind<bool>("15 - Chests", "SharedChests", true, "More than one player can have the same chest open at once. Note: if two players move the same items at the same moment, one of those changes can be lost.");
		WardSizeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("03 - Wards", "WardSizeEnabled", true, "Enable the custom ward radius below. Wards pick up a change when they next load.");
		WardRadius = ((BaseUnityPlugin)this).Config.Bind<float>("03 - Wards", "WardRadius", 48f, new ConfigDescription("Ward protection radius in meters. Vanilla is about 32.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(4f, 500f), Array.Empty<object>()));
		BuildAnywhere = ((BaseUnityPlugin)this).Config.Bind<bool>("02 - Structures", "BuildAnywhere", true, "Removes the no-build zones inside caves, crypts, dungeons and around boss altars, and lets any piece be placed in dungeons. Pieces pick up the dungeon permission when they next load.");
		TroughEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("10 - Trough", "TroughEnabled", true, "Troughs feed tame animals in range from the food stored inside. When false it acts as a normal chest.");
		TroughBuildable = ((BaseUnityPlugin)this).Config.Bind<bool>("10 - Trough", "TroughBuildable", true, "Trough appears in the hammer build menu.");
		TroughRange = ((BaseUnityPlugin)this).Config.Bind<float>("10 - Trough", "TroughRange", 10f, new ConfigDescription("Radius (meters) the Trough feeds animals in.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 200f), Array.Empty<object>()));
		TroughCost = ((BaseUnityPlugin)this).Config.Bind<string>("10 - Trough", "TroughCost", "Wood:15,Stone:5", "Build cost as PrefabName:Amount pairs separated by commas. Leave empty to use the same cost as a regular wood chest.");
		SmelterChestEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("21 - Chest - Smelter", "SmelterChestEnabled", true, "Smelter Chests feed ore and fuel to smelters, kilns and furnaces in range, and collect what they produce. When false it acts as a normal chest.");
		SmelterChestBuildable = ((BaseUnityPlugin)this).Config.Bind<bool>("21 - Chest - Smelter", "SmelterChestBuildable", true, "Smelter Chest appears in the hammer build menu.");
		SmelterChestRange = ((BaseUnityPlugin)this).Config.Bind<float>("21 - Chest - Smelter", "SmelterChestRange", 10f, new ConfigDescription("Radius (meters) the Smelter Chest services smelters in.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 200f), Array.Empty<object>()));
		SmelterChestCost = ((BaseUnityPlugin)this).Config.Bind<string>("21 - Chest - Smelter", "SmelterChestCost", "FineWood:20,Bronze:5", "Build cost as PrefabName:Amount pairs separated by commas. Leave empty to use the same cost as a regular wood chest.");
		DefaultShout = ((BaseUnityPlugin)this).Config.Bind<bool>("24 - Chat", "DefaultShout", true, "Chat messages are sent server-wide (shout) by default instead of local say. This sets the mode you start in; the hotkey below switches it during play.");
		ChatToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("24 - Chat", "ChatToggleKey", new KeyboardShortcut((KeyCode)116, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Key that switches between server-wide and local chat.");
		DeathNotifications = ((BaseUnityPlugin)this).Config.Bind<bool>("25 - Death Notifications", "DeathNotifications", true, "When you die, a message is sent to server chat so everyone knows.");
		DeathIncludeBiome = ((BaseUnityPlugin)this).Config.Bind<bool>("25 - Death Notifications", "DeathIncludeBiome", true, "Include the biome you died in, e.g. \"died in the Black Forest\".");
		DeathIncludeKiller = ((BaseUnityPlugin)this).Config.Bind<bool>("25 - Death Notifications", "DeathIncludeKiller", true, "Include what killed you, e.g. \"was killed by a Greydwarf\".");
		MistClearAllowed = ((BaseUnityPlugin)this).Config.Bind<bool>("28 - Mist", "MistClearAllowed", true, "Allow players to clear the Mistlands fog around themselves. Each player toggles it for themselves with /mist or the hotkey below; it never affects anyone else.");
		MistClearByDefault = ((BaseUnityPlugin)this).Config.Bind<bool>("28 - Mist", "MistClearByDefault", false, "Start each session with the mist already cleared.");
		MistClearRadius = ((BaseUnityPlugin)this).Config.Bind<float>("28 - Mist", "MistClearRadius", 100f, new ConfigDescription("How far around you the mist is pushed back, in meters. The wisplight is about 10.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 2000f), Array.Empty<object>()));
		MistToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("28 - Mist", "MistToggleKey", new KeyboardShortcut((KeyCode)109, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Key that toggles the mist for you. /mist does the same thing.");
		FogClearAllowed = ((BaseUnityPlugin)this).Config.Bind<bool>("49 - Weather Effects", "FogClearAllowed", true, "Allow players to turn the biome fog off for themselves with /fog - the Plains haze, the Deep North whiteout and the rest. Each player decides for themselves and it never changes anyone else's view. /mist handles the Mistlands separately.");
		FogClearByDefault = ((BaseUnityPlugin)this).Config.Bind<bool>("49 - Weather Effects", "FogClearByDefault", false, "Start each session with the biome fog already off.");
		EmberClearAllowed = ((BaseUnityPlugin)this).Config.Bind<bool>("49 - Weather Effects", "EmberClearAllowed", true, "Allow players to stop the falling ash and embers in the Ashlands for themselves with /ember. Local to each player, like /fog.");
		EmberClearByDefault = ((BaseUnityPlugin)this).Config.Bind<bool>("49 - Weather Effects", "EmberClearByDefault", false, "Start each session with the ash and embers already stopped.");
		SuperAdmins = ((BaseUnityPlugin)this).Config.Bind<string>("51 - Permissions", "SuperAdmins", "", "Steam64 IDs, separated by commas, of the people who own this server. A superadmin has every right and is the only one who can change what other admins may do. Whoever is running a listen server is always a superadmin. Only a superadmin can change this setting, so an admin cannot promote themselves.");
		PermissionsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("51 - Permissions", "PermissionsEnabled", false, "Hold admins to the rights they have been given, rather than letting every admin do everything. Off by default so that updating takes nothing away from anyone: while it is off, every admin keeps full access exactly as before. Superadmins always have everything. Rights are set per admin from the Permissions tab of the in-game menu and kept in dev.craz.kingstweaks.permissions.txt.");
		WhiteDeerEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("54 - White Deer", "WhiteDeerEnabled", false, "Let the game's white deer appear in the world. It is already in Valheim - the prefab is Deer_White - but it isn't in any spawn list, so nobody ever sees one. This puts it in the same places ordinary deer live, very rarely. Off by default because it changes what turns up in your world.");
		WhiteDeerChance = ((BaseUnityPlugin)this).Config.Bind<float>("54 - White Deer", "WhiteDeerChance", 1f, new ConfigDescription("The chance, as a percentage, that one appears when the game considers spawning it. 1 is genuinely rare; 100 would be as common as deer.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 100f), Array.Empty<object>()));
		WhiteDeerInterval = ((BaseUnityPlugin)this).Config.Bind<float>("54 - White Deer", "WhiteDeerInterval", 1800f, new ConfigDescription("How many seconds between attempts to spawn one.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(60f, 86400f), Array.Empty<object>()));
		SizeAllowed = ((BaseUnityPlugin)this).Config.Bind<bool>("53 - Character Size", "SizeAllowed", true, "Let players change how big their character is with /size. The number is kept on the character, so everyone sees everyone else at the size they chose.");
		SizeAdminsOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("53 - Character Size", "SizeAdminsOnly", false, "Only admins may change their size.");
		SizeMin = ((BaseUnityPlugin)this).Config.Bind<float>("53 - Character Size", "SizeMin", 0.5f, new ConfigDescription("The smallest a player may be. Below about 0.5 a character starts having trouble with stairs and doorways.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), Array.Empty<object>()));
		SizeMax = ((BaseUnityPlugin)this).Config.Bind<float>("53 - Character Size", "SizeMax", 1.5f, new ConfigDescription("The largest a player may be. A bigger character has a bigger hitbox and longer reach, which is worth thinking about on a PVP server.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 4f), Array.Empty<object>()));
		CraftSearchButton = ((BaseUnityPlugin)this).Config.Bind<bool>("52 - Crafting", "CraftSearchButton", true, "Adds a search button to the crafting panel that narrows the recipe list to what you type. /find does the same thing from chat, and /find on its own clears it.");
		FreeOverlap = ((BaseUnityPlugin)this).Config.Bind<bool>("50 - Placement", "FreeOverlap", false, "Pieces may be placed inside one another - a workstation inside a table, a chest under a stair - by clearing the space each piece claims and the collision test between them. Off by default because it changes building for everyone on the server; placement is otherwise unchanged, so being out of materials, too far away or inside someone else's ward still refuses as usual.");
		BoatWorkstation = ((BaseUnityPlugin)this).Config.Bind<bool>("50 - Placement", "BoatWorkstation", false, "Boats carry a workbench, so you can repair gear and build while aboard without sailing home. It is a real copy of the workbench, minus the need for a roof or a fire.");
		BoatWorkstationRange = ((BaseUnityPlugin)this).Config.Bind<float>("50 - Placement", "BoatWorkstationRange", 20f, new ConfigDescription("How far the boat's workbench reaches, in meters. The real one is about 20.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(4f, 64f), Array.Empty<object>()));
		TamesStayOnBoats = ((BaseUnityPlugin)this).Config.Bind<bool>("09 - Tames", "TamesStayOnBoats", true, "Tame animals standing on a boat stay put instead of wandering off or jumping into deep water.");
		TamesFollowThroughPortals = ((BaseUnityPlugin)this).Config.Bind<bool>("09 - Tames", "TamesFollowThroughPortals", true, "Tames that are following you come through portals with you.");
		TameTeleportRange = ((BaseUnityPlugin)this).Config.Bind<float>("09 - Tames", "TameTeleportRange", 15f, new ConfigDescription("How close a following tame must be to come through the portal with you.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 200f), Array.Empty<object>()));
		ShipStowKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("09 - Tames", "ShipStowKey", new KeyboardShortcut((KeyCode)114, Array.Empty<KeyCode>()), "Key that puts the tame you're looking at on a nearby boat, or takes it off again.");
		ShipStowRange = ((BaseUnityPlugin)this).Config.Bind<float>("09 - Tames", "ShipStowRange", 15f, new ConfigDescription("How close a boat must be for the put on board option to appear.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 100f), Array.Empty<object>()));
		TameTracking = ((BaseUnityPlugin)this).Config.Bind<bool>("09 - Tames", "TameTracking", true, "Hold your stow key on a tame to put a marker on the map that follows it. Hold it again to stop tracking.");
		TameHealthEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("09 - Tames", "TameHealthEnabled", false, "Changes how much health tamed animals have.");
		TameHealthMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("09 - Tames", "TameHealthMultiplier", 2f, new ConfigDescription("Tamed animals get this much of their normal health, so 2 is double. Only applies while the setting above is on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 50f), Array.Empty<object>()));
		TameHealthBySpecies = ((BaseUnityPlugin)this).Config.Bind<string>("09 - Tames", "TameHealthBySpecies", "", "Per species health, as Name:Multiplier pairs separated by commas, e.g. \"Boar:2, Wolf:4, Lox:1.5\". Anything not listed uses the multiplier above. Use the creature's prefab name; only tamed animals are affected.");
		HubEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("13 - Portal Hub", "HubEnabled", true, "Portal Hubs work. When false they can't be named or travelled through.");
		HubBuildable = ((BaseUnityPlugin)this).Config.Bind<bool>("13 - Portal Hub", "HubBuildable", true, "Portal Hub appears in the hammer build menu.");
		HubCost = ((BaseUnityPlugin)this).Config.Bind<string>("13 - Portal Hub", "HubCost", "FineWood:40,SurtlingCore:6,GreydwarfEye:20", "Build cost as PrefabName:Amount pairs separated by commas. Leave empty to use the same cost as a normal portal.");
		HubTravelCost = ((BaseUnityPlugin)this).Config.Bind<string>("13 - Portal Hub", "HubTravelCost", "", "What each hub journey costs, as PrefabName:Amount, e.g. \"Coins:10\" or \"GreydwarfEye:5\". Leave empty for free travel.");
		HubWindowRange = ((BaseUnityPlugin)this).Config.Bind<float>("13 - Portal Hub", "HubWindowRange", 5f, new ConfigDescription("How far you can step from a hub before its window closes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
		HubEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("13 - Portal Hub", "HubEffects", true, "Portal Hubs show the glow and swirl a normal portal has when you come near.");
		HubEffectColour = ((BaseUnityPlugin)this).Config.Bind<string>("13 - Portal Hub", "HubEffectColour", "#c0392b", "Colour of a Portal Hub's glow, as hex or a colour name. The default is red, which sets hubs apart from the orange of an ordinary portal.");
		HubTriggerRadius = ((BaseUnityPlugin)this).Config.Bind<float>("13 - Portal Hub", "HubTriggerRadius", 1f, new ConfigDescription("How close you must be to a hub for its window to open. Lower this if it opens while you walk past.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 4f), Array.Empty<object>()));
		HubReopenDistance = ((BaseUnityPlugin)this).Config.Bind<float>("13 - Portal Hub", "HubReopenDistance", 4f, new ConfigDescription("After travelling, how far you must walk from where you landed before any hub window will open again.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>()));
		NoStaminaInWard = ((BaseUnityPlugin)this).Config.Bind<bool>("02 - Structures", "NoStaminaInWard", true, "Inside an active ward, building, deconstructing, hoeing and planting cost no stamina. Everything else, including fighting, still costs stamina as normal.");
		UpgradeFreeSpace = ((BaseUnityPlugin)this).Config.Bind<bool>("02 - Structures", "UpgradeFreeSpace", true, "Workstation upgrades (anvils, adze, tool shelf, forge cooler, chopping block and the rest) can be placed without the game asking for more space, so they can sit side by side or tucked against a wall. Everything else still needs its usual room.");
		UpgradeRange = ((BaseUnityPlugin)this).Config.Bind<float>("02 - Structures", "UpgradeRange", 10f, new ConfigDescription("How far a workstation upgrade can sit from the station it belongs to, in metres. The game's own limit is 5. 0 leaves the game's limit alone.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 64f), Array.Empty<object>()));
		SettingsHint = ((BaseUnityPlugin)this).Config.Bind<bool>("27 - In-Game Menu", "SettingsHint", true, "Tells you once, the first time you play, which key opens the settings window. Only shown to players who can actually change the settings.");
		MenuKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("27 - In-Game Menu", "MenuKey", new KeyboardShortcut((KeyCode)278, Array.Empty<KeyCode>()), "Opens the KingsTweaks settings window in game. While connected to a server the server's settings are shown and can't be changed.");
		ProtectEmptyShips = ((BaseUnityPlugin)this).Config.Bind<bool>("07 - Boats", "ProtectEmptyShips", true, "Creatures can't damage a boat with nobody aboard, so a serpent doesn't chew up the longship you left at the dock. Players can still break it, and a boat with somebody standing on it is fair game as usual.");
		NoPinSharing = ((BaseUnityPlugin)this).Config.Bind<bool>("29 - World", "NoPinSharing", true, "Using a cartography table shares the map you've explored but not your pins, so nobody hands over their base, their portals and their stashes by accident.");
		AutoPickupSpears = ((BaseUnityPlugin)this).Config.Bind<bool>("40 - Combat", "AutoPickupSpears", true, "A thrown spear comes back to you instead of being left where it landed. One you deliberately drop on the ground stays dropped.");
		SpearPickupRange = ((BaseUnityPlugin)this).Config.Bind<float>("40 - Combat", "SpearPickupRange", 60f, new ConfigDescription("How far a thrown spear can be and still come back.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 300f), Array.Empty<object>()));
		CartDismantle = ((BaseUnityPlugin)this).Config.Bind<bool>("02 - Structures", "CartDismantle", true, "Carts can be taken apart with the hammer, giving their materials back. A cart with anything in it has to be emptied first, so nothing is destroyed with it.");
		TorchWithTools = ((BaseUnityPlugin)this).Config.Bind<bool>("40 - Combat", "TorchWithTools", true, "Keeps your torch lit when you take out the hammer, hoe or cultivator, so you can build at night without working in the dark.");
		HideDayNumber = ((BaseUnityPlugin)this).Config.Bind<bool>("29 - World", "HideDayNumber", false, "Hides the \"Day 12\" message each morning.");
		KeepSkillsOnDeath = ((BaseUnityPlugin)this).Config.Bind<bool>("40 - Combat", "KeepSkillsOnDeath", false, "Dying costs you no skill progress. The rest of dying is unchanged.");
		RemoveStumps = ((BaseUnityPlugin)this).Config.Bind<bool>("29 - World", "RemoveStumps", false, "Felling a tree leaves no stump behind. Only stumps from trees cut down while this is on are affected; the ones already standing in your world, and the stumps that are part of the landscape, are left alone.");
		StumpsDropWood = ((BaseUnityPlugin)this).Config.Bind<bool>("29 - World", "StumpsDropWood", true, "A stump being removed drops what chopping it would have given, so nothing is lost. Turn this off and the stump simply disappears.");
		HideSkyTree = ((BaseUnityPlugin)this).Config.Bind<bool>("29 - World", "HideSkyTree", true, "Hides Yggdrasil, the giant tree and branch in the sky. Visual only, and each player sees their own setting unless the server syncs it.");
		MinimapAllowed = ((BaseUnityPlugin)this).Config.Bind<bool>("29 - World", "MinimapAllowed", true, "When false, the minimap in the corner is hidden for everyone on the server.");
		FullMapAllowed = ((BaseUnityPlugin)this).Config.Bind<bool>("29 - World", "FullMapAllowed", true, "When false, the full screen map can't be opened by anyone on the server.");
		MapExploreMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("29 - World", "MapExploreMultiplier", 1f, new ConfigDescription("How much of the map you uncover as you travel. 2 reveals twice as far as normal, 0.5 half as far. 1 is the game's own radius. Only changes what you discover from here on; the map you already have stays.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f), Array.Empty<object>()));
		HoldToOpenTowards = ((BaseUnityPlugin)this).Config.Bind<bool>("23 - Doors", "HoldToOpenTowards", true, "Tap Use on a door to open it away from you (vanilla). Hold Use to open it towards you. Locked doors that need a key are left alone.");
		HoldSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("23 - Doors", "HoldSeconds", 0.2f, new ConfigDescription("How long Use must be held to count as a hold rather than a tap. Lower feels snappier; too low and a slow tap counts as a hold.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2f), Array.Empty<object>()));
		DoorsWhileBuilding = ((BaseUnityPlugin)this).Config.Bind<bool>("23 - Doors", "DoorsWhileBuilding", true, "Doors can be opened with the hammer out, instead of having to put it away.");
		DoorLocks = ((BaseUnityPlugin)this).Config.Bind<bool>("23 - Doors", "DoorLocks", true, "Press the stow key on a door inside your ward to lock it. A locked door only opens for people the ward permits.");
		LocksOpenForOwners = ((BaseUnityPlugin)this).Config.Bind<bool>("23 - Doors", "LocksOpenForOwners", false, "When true, a lock only keeps other people out and anyone the ward permits can still open it. When false, locked means locked for everyone until it's unlocked.");
		ChestLocks = ((BaseUnityPlugin)this).Config.Bind<bool>("15 - Chests", "ChestLocks", true, "Press the stow key on a chest inside your ward to lock it. A locked chest only opens for people the ward permits.");
		WardLocks = ((BaseUnityPlugin)this).Config.Bind<bool>("03 - Wards", "WardLocks", true, "Press the stow key on a ward to lock it, so only people it permits can switch it off or change its list.");
		UnstuckEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("30 - Unstuck", "UnstuckEnabled", true, "Allows the /unstuck command, which moves you to solid ground nearby. Set false on a server to disable it for everyone.");
		UnstuckCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("30 - Unstuck", "UnstuckCooldown", 20f, new ConfigDescription("Seconds a player must wait between uses of /unstuck.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3600f), Array.Empty<object>()));
		CompassEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("26 - Compass", "CompassEnabled", true, "Shows a compass strip at the top of the screen.");
		CompassShowDistance = ((BaseUnityPlugin)this).Config.Bind<bool>("26 - Compass", "CompassShowDistance", true, "Shows how far away each pin is, under its name.");
		CompassHideCheckedPins = ((BaseUnityPlugin)this).Config.Bind<bool>("26 - Compass", "CompassHideCheckedPins", true, "Pins you've crossed out on the map (the checked state, shown faded) are left off the compass. Cross a pin out to hide it, un-cross it to bring it back.");
		CompassShowPins = ((BaseUnityPlugin)this).Config.Bind<bool>("26 - Compass", "CompassShowPins", true, "Map pins appear on the compass in the direction they lie.");
		CompassPinRange = ((BaseUnityPlugin)this).Config.Bind<float>("26 - Compass", "CompassPinRange", 500f, new ConfigDescription("How far away a pin can be and still show on the compass. 0 = no limit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20000f), Array.Empty<object>()));
		CompassAllowed = ((BaseUnityPlugin)this).Config.Bind<bool>("26 - Compass", "CompassAllowed", true, "When false, nobody on the server gets the compass, whatever their own setting says.");
		HideShoutInWorld = ((BaseUnityPlugin)this).Config.Bind<bool>("24 - Chat", "HideShoutInWorld", true, "Shouted messages stay in the chat window instead of appearing above players' heads. Pings are hidden the same way.");
		HidePingInWorld = ((BaseUnityPlugin)this).Config.Bind<bool>("24 - Chat", "HidePingInWorld", false, "Also hides map pings above the world. Off by default: pings are how people point things out to each other.");
		ShoutKeepCase = ((BaseUnityPlugin)this).Config.Bind<bool>("24 - Chat", "ShoutKeepCase", false, "Shows shouts as they were typed instead of IN CAPITALS. This one rewrites a game method at load, so it can clash with other chat mods: if the game stops at the loading screen, set this back to false. Takes effect on the next launch.");
		BackupsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("32 - Backups", "BackupsEnabled", true, "Server only. Copies the world files into a backups folder after the game saves.");
		BackupKeep = ((BaseUnityPlugin)this).Config.Bind<int>("32 - Backups", "BackupKeep", 12, new ConfigDescription("How many backups to keep. The oldest is deleted once there are more.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000), Array.Empty<object>()));
		BackupMinInterval = ((BaseUnityPlugin)this).Config.Bind<float>("32 - Backups", "BackupMinIntervalMinutes", 120f, new ConfigDescription("Minimum minutes between backups, so frequent saves don't fill the folder.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1440f), Array.Empty<object>()));
		EnforceSameVersion = ((BaseUnityPlugin)this).Config.Bind<bool>("33 - Compatibility", "EnforceSameVersion", true, "Server only. Players must be running the same KingsTweaks version to join. Anyone without the mod, or on a different version, is disconnected.");
		ActivityFeedEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("34 - Notifications", "ActivityFeedEnabled", true, "Shows short messages down the left side when your chests do something. Toggle in game with /uinotifications.");
		ChestNoticeMinutes = ((BaseUnityPlugin)this).Config.Bind<float>("34 - Notifications", "ChestNoticeMinutes", 5f, new ConfigDescription("How long before a chest repeats the same complaint, in minutes. It says it once when you come to it, then this often while you stay.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 120f), Array.Empty<object>()));
		ChestNoticeRange = ((BaseUnityPlugin)this).Config.Bind<float>("34 - Notifications", "ChestNoticeRange", 40f, new ConfigDescription("How close you have to be to a chest to hear about it at all.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 200f), Array.Empty<object>()));
		ActivityFeedSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("34 - Notifications", "ActivityFeedSeconds", 8f, new ConfigDescription("How long each message stays on screen.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 60f), Array.Empty<object>()));
		UpdateCheckEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("35 - Updates", "UpdateCheckEnabled", true, "Checks for a newer KingsTweaks and pulses a line on the main menu when there is one.");
		UpdateVersionUrl = ((BaseUnityPlugin)this).Config.Bind<string>("35 - Updates", "UpdateVersionUrl", "https://raw.githubusercontent.com/craztheking/KingsTweaks-/main/manifest.json", "Where to look for the latest version number: a plain text file, or a Thunderstore manifest.json, in which case version_number is read from it. That way there is only one number to update at release time. Leave empty to skip the check.");
		Motd = ((BaseUnityPlugin)this).Config.Bind<string>("36 - Server Message", "Motd", "Welcome to our server! We are using KingsTweaks Version {version}", "Shown to each player once when they join. {version} is replaced with the mod version. Leave empty for no message.");
		MotdCommandsHint = ((BaseUnityPlugin)this).Config.Bind<bool>("36 - Server Message", "MotdCommandsHint", true, "Adds \"Type /kt for all commands\" to the end of the join message, so players know the commands are there without being told.");
		NoSpawnsInWards = ((BaseUnityPlugin)this).Config.Bind<bool>("37 - Spawns", "NoSpawnsInWards", false, "Creatures don't spawn inside an active ward's radius, so mobs stop appearing in your base.");
		WardSpawnsDuringRaids = ((BaseUnityPlugin)this).Config.Bind<bool>("37 - Spawns", "WardSpawnsDuringRaids", true, "Raids ignore the rule above, so an attack on your base still happens. Turn off to keep wards clear even during a raid.");
		SpawnScaleEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("37 - Spawns", "SpawnScaleEnabled", false, "Enable the spawn multipliers below. They change how often creatures appear and how many can be around at once.");
		CreatureSpawnMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("37 - Spawns", "CreatureSpawnMultiplier", 1f, new ConfigDescription("Hostile creatures: 2 means twice as many, 0.25 means a quarter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
		AnimalSpawnMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("37 - Spawns", "AnimalSpawnMultiplier", 1f, new ConfigDescription("Passive animals such as boar, deer and birds, on the same scale.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
		ChestsRespectWards = ((BaseUnityPlugin)this).Config.Bind<bool>("03 - Wards", "ChestsRespectWards", true, "Fuel, Upkeep and craft-from-chests skip anything inside a ward you aren't permitted on, so nobody can feed off someone else's base.");
		ChestNaming = ((BaseUnityPlugin)this).Config.Bind<bool>("15 - Chests", "ChestNaming", true, "Look at a chest and press the stow key to give it a name, shown on the chest and above its window.");
		SorterUsesNames = ((BaseUnityPlugin)this).Config.Bind<bool>("18 - Chest - Sorter", "SorterUsesNames", true, "Sorter messages name the chest items went to, e.g. \"20 Stone to Stockpile\", for chests you have named.");
		BoatPinsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("38 - Boat Pins", "BoatPinsEnabled", true, "Boats you build get a map marker that follows them and disappears when the boat does.");
		FirstPersonAllowed = ((BaseUnityPlugin)this).Config.Bind<bool>("39 - Camera", "FirstPersonAllowed", true, "Server setting: when false, nobody on the server gets first person, whatever their own setting says.");
		FirstPersonForced = ((BaseUnityPlugin)this).Config.Bind<bool>("39 - Camera", "FirstPersonForced", false, "Server setting: everyone plays in first person and the camera can't be zoomed out. Players can still position the camera with the settings below.");
		FirstPersonEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("39 - Camera", "FirstPersonEnabled", true, "Zooming all the way in puts the camera at your eyes instead of over your shoulder.");
		FirstPersonZoom = ((BaseUnityPlugin)this).Config.Bind<float>("39 - Camera", "FirstPersonZoom", 0.1f, new ConfigDescription("How close to the game's minimum zoom you must be before first person kicks in, in metres. Raise it if zooming right in doesn't switch.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 3f), Array.Empty<object>()));
		FirstPersonForward = ((BaseUnityPlugin)this).Config.Bind<float>("39 - Camera", "FirstPersonForward", 0.3f, new ConfigDescription("How far ahead of your eyes the camera sits. Raise this if you see your own face.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		FirstPersonHeight = ((BaseUnityPlugin)this).Config.Bind<float>("39 - Camera", "FirstPersonHeight", 0.2f, new ConfigDescription("Moves the first person camera up or down from eye level.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.5f, 0.5f), Array.Empty<object>()));
		FirstPersonBack = ((BaseUnityPlugin)this).Config.Bind<float>("39 - Camera", "FirstPersonBack", 1.5f, new ConfigDescription("How far behind your head the camera starts when you first enter first person. Zooming in further slides it forward to your eyes, so a larger number gives you more positions to choose from.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1.5f), Array.Empty<object>()));
		FirstPersonFollowHead = ((BaseUnityPlugin)this).Config.Bind<bool>("39 - Camera", "FirstPersonFollowHead", true, "Anchors the camera to your head bone, so it ducks when you crouch, drops when you sit, and sways as you move. Turn off for a camera that only tracks eye height.");
		FirstPersonNearClip = ((BaseUnityPlugin)this).Config.Bind<float>("39 - Camera", "FirstPersonNearClip", 0.01f, new ConfigDescription("How close something can be before the camera cuts it away. Lower values keep your hands and weapon in view.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.3f), Array.Empty<object>()));
		FirstPersonShowBody = ((BaseUnityPlugin)this).Config.Bind<bool>("39 - Camera", "FirstPersonShowBody", true, "Keeps your own body and hands visible in first person. Turn off if looking down at yourself or the inside of your head bothers you.");
		FirstPersonHideHead = ((BaseUnityPlugin)this).Config.Bind<bool>("39 - Camera", "FirstPersonHideHead", true, "Hides the parts listed below while you are in first person, so they don't block the view. Your body and hands stay visible.");
		FirstPersonHiddenParts = ((BaseUnityPlugin)this).Config.Bind<string>("39 - Camera", "FirstPersonHiddenParts", "head, helmet, hair, beard", "Which parts to hide in first person, as words separated by commas. A part is hidden when its name contains one of these. Type /fpparts in game to list the names your character is actually wearing.");
		FirstPersonFaceCamera = ((BaseUnityPlugin)this).Config.Bind<bool>("39 - Camera", "FirstPersonFaceCamera", true, "Your body faces wherever the camera looks, so walking backwards steps back instead of turning you around.");
		FirstPersonHeadBob = ((BaseUnityPlugin)this).Config.Bind<bool>("39 - Camera", "FirstPersonHeadBob", false, "Lets the camera bob with your walking animation. Turn off for a steady view that still ducks when you crouch or sit.");
		FirstPersonSteadiness = ((BaseUnityPlugin)this).Config.Bind<float>("39 - Camera", "FirstPersonSteadiness", 0.02f, new ConfigDescription("With head bob off, how heavily the camera is smoothed. Higher is steadier but slower to follow crouching and sitting.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 0.5f), Array.Empty<object>()));
		FirstPersonTurnBody = ((BaseUnityPlugin)this).Config.Bind<bool>("39 - Camera", "FirstPersonTurnBody", true, "Turns your body to follow the camera once you have looked far enough to the side. Below that angle only your view moves, so you can glance around while standing still.");
		FirstPersonTurnAngle = ((BaseUnityPlugin)this).Config.Bind<float>("39 - Camera", "FirstPersonTurnAngle", 45f, new ConfigDescription("How far you can look to either side before your body follows.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(30f, 170f), Array.Empty<object>()));
		AutoShield = ((BaseUnityPlugin)this).Config.Bind<bool>("40 - Combat", "AutoShield", true, "Draws your shield automatically when you equip a one-handed weapon. Each player can toggle this with /autoshield.");
		PowerResetOnDeath = ((BaseUnityPlugin)this).Config.Bind<bool>("40 - Combat", "PowerResetOnDeath", true, "Your guardian power is ready again when you respawn, instead of carrying its cooldown through death.");
		PvpForced = ((BaseUnityPlugin)this).Config.Bind<bool>("40 - Combat", "PvpForced", false, "Server setting: everyone is flagged for PvP and can't switch it off.");
		DyeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("42 - Dye", "DyeEnabled", true, "Players can colour their gear with /dye. Put the item in the first hotbar slot and type /dye #aa3344, or /dye clear to undo it.");
		RestartsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("45 - Server", "RestartsEnabled", false, "Server only. Warns everyone, saves the world and closes the server at the times below. Something outside the game has to start it again: a restart loop in your start script, or the service set to restart on exit.");
		RestartTimes = ((BaseUnityPlugin)this).Config.Bind<string>("45 - Server", "RestartTimes", "04:00", "When to restart, as 24 hour times separated by commas, e.g. \"04:00, 16:00\".");
		SignTextLimit = ((BaseUnityPlugin)this).Config.Bind<bool>("46 - Signs", "SignTextLimit", true, "Lets signs hold more text than the game normally allows.");
		SignCharacters = ((BaseUnityPlugin)this).Config.Bind<int>("46 - Signs", "SignCharacters", 150, new ConfigDescription("How many characters a sign can hold. The game's own limit is 50. Long text still has to fit on the sign, so it gets small.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 1000), Array.Empty<object>()));
		FreeBuildEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("45 - Server", "FreeBuildEnabled", true, "Allows /freebuild, which lets an admin build without paying for materials. Turn off to disable it for everyone, admins included.");
		ClearDeathPinsButton = ((BaseUnityPlugin)this).Config.Bind<bool>("29 - World", "ClearDeathPinsButton", true, "Puts a button on the full map that clears every death marker at once.");
		TeamMapPins = ((BaseUnityPlugin)this).Config.Bind<bool>("41 - Teams", "TeamMapPins", true, "Team mates show on each other's maps even when they haven't switched their own map sharing on. Only the team sees them, so it doesn't announce anyone to the rest of the server.");
		CommandsIgnoreCase = ((BaseUnityPlugin)this).Config.Bind<bool>("34 - Notifications", "CommandsIgnoreCase", true, "Commands work however they're typed, so /Home and /HOME do the same as /home. Applies to the game's own commands as well as this mod's.");
		HiddenCommands = ((BaseUnityPlugin)this).Config.Bind<string>("45 - Server", "HiddenCommands", "", "Commands to leave out of /kt and the game's own /help, separated by commas, e.g. \"dye, fpparts\". They still work for anyone who knows them.");
		DisabledCommands = ((BaseUnityPlugin)this).Config.Bind<string>("45 - Server", "DisabledCommands", "", "Commands nobody may use, separated by commas. These are hidden as well, and anyone who tries is told the command is disabled. Write them without the slash.");
		WhoEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("45 - Server", "WhoEnabled", true, "Allows /who, which lists everyone online.");
		WhoAdminsOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("45 - Server", "WhoAdminsOnly", false, "Only admins can use /who.");
		PlaytimeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("45 - Server", "PlaytimeEnabled", true, "Keeps a running total of how long each player has been on the server, readable with /playtime.");
		TeamsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("41 - Teams", "TeamsEnabled", true, "Players can form teams: shared map pings, a team chat channel, a health list on screen and access to each other's wards.");
		TeamPingsOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("41 - Teams", "TeamPingsOnly", true, "Map pings are only seen by the pinger's own team. Players with no team see pings as normal.");
		TeamHud = ((BaseUnityPlugin)this).Config.Bind<bool>("41 - Teams", "TeamHud", true, "Shows your team mates and their health under the minimap.");
		TeamWards = ((BaseUnityPlugin)this).Config.Bind<bool>("41 - Teams", "TeamWards", true, "Wards let your team mates through without adding them by hand.");
		AutoRepairEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("43 - Repair", "AutoRepairEnabled", true, "Standing at a workbench or forge repairs everything you're carrying that the station could repair by hand.");
		TravelEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("44 - Travel", "TravelEnabled", true, "Allows /sethome, /home, /tpa and /tpr. Turn off to disable all of them.");
		TravelWarmup = ((BaseUnityPlugin)this).Config.Bind<float>("44 - Travel", "TravelWarmup", 5f, new ConfigDescription("Seconds you must stand still before a travel completes. Taking damage during the countdown cancels it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
		TravelCombatSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("44 - Travel", "TravelCombatSeconds", 15f, new ConfigDescription("You can't travel for this many seconds after being hurt. 0 allows travelling straight out of a fight.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 300f), Array.Empty<object>()));
		TravelBlockNearEnemies = ((BaseUnityPlugin)this).Config.Bind<bool>("44 - Travel", "TravelBlockNearEnemies", true, "Refuses to travel while an enemy is close by.");
		TravelEnemyRange = ((BaseUnityPlugin)this).Config.Bind<float>("44 - Travel", "TravelEnemyRange", 20f, new ConfigDescription("How close an enemy has to be to stop you travelling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 200f), Array.Empty<object>()));
		TravelBlockEncumbered = ((BaseUnityPlugin)this).Config.Bind<bool>("44 - Travel", "TravelBlockEncumbered", true, "You can't use the travel commands while over-encumbered, so a full load has to be carried or sailed home. Checked again as the journey happens, so it can't be loaded up during the countdown.");
		TravelAllowMetals = ((BaseUnityPlugin)this).Config.Bind<bool>("44 - Travel", "TravelAllowMetals", false, "Lets the travel commands carry ore, bars and anything else the game won't take through a portal. This is separate from TeleportEverything, which is about portals and Portal Hubs: a server can let portals carry metal and still refuse to let /home do it.");
		ServerCharactersEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("48 - Server Characters", "ServerCharactersEnabled", false, "The server keeps each player's belongings and skills. The first time somebody joins, their inventory is emptied and their skills set to zero, so nothing can be carried in from another world. Off by default: it wipes people's characters.");
		ServerCharacterSaveSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("48 - Server Characters", "ServerCharacterSaveSeconds", 30f, new ConfigDescription("How often a player's character is sent to the server.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 300f), Array.Empty<object>()));
		ServerCharacterWipeSkills = ((BaseUnityPlugin)this).Config.Bind<bool>("48 - Server Characters", "ServerCharacterWipeSkills", true, "Skills start at zero on a new character here. Turn off to keep whatever skills a player arrives with the first time.");
		ServerCharacterMessage = ((BaseUnityPlugin)this).Config.Bind<string>("48 - Server Characters", "ServerCharacterMessage", "Your character is kept on this server.\n\nThe first time you join, your inventory is emptied and your skills start at zero. Nothing you bring from another world comes with you.\n\nYou can't move, open your inventory or be hurt until you agree.", "What players are told before they can play. Use \\n for a new line.");
		SleepersEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("47 - Sleepers", "SleepersEnabled", false, "Logging out leaves your body behind, asleep and lootable. What's in the body is your inventory: whatever is still there when you come back is what you get. Off by default, because it changes how much a raid can cost somebody.");
		SleeperRefreshSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("47 - Sleepers", "SleeperRefreshSeconds", 10f, new ConfigDescription("How often your body is brought up to date while you play. Anything you pick up in the last few seconds before you log out may not have made it into the body yet.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 120f), Array.Empty<object>()));
		SleeperSafeFromCreatures = ((BaseUnityPlugin)this).Config.Bind<bool>("47 - Sleepers", "SleeperSafeFromCreatures", true, "Creatures ignore sleeping bodies, so nobody is robbed by a passing greydwarf. Players can still destroy them.");
		WarpsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("44 - Travel", "WarpsEnabled", true, "Admins can set up named teleport points with /addtp, which everyone can then travel to by name. Each has its own wait between uses.");
		TravelCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("44 - Travel", "TravelCooldown", 300f, new ConfigDescription("Seconds a player must wait between travels, so it can't be used to slip out of a fight.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 7200f), Array.Empty<object>()));
		ShipBuildEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("08 - Boat Building", "ShipBuildEnabled", false, "Experimental. Pieces built while you stand on a boat attach to it and sail with it. Turning this off stops new pieces attaching; ones already attached stay put.");
		MaxPiecesPerShip = ((BaseUnityPlugin)this).Config.Bind<int>("08 - Boat Building", "MaxPiecesPerShip", 5, new ConfigDescription("Maximum pieces that can be attached to one boat.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000), Array.Empty<object>()));
		PlantingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("11 - Planting", "PlantingEnabled", true, "Adds berry bushes, mushrooms and herbs to the cultivator so they can be planted.");
		PlantList = ((BaseUnityPlugin)this).Config.Bind<string>("11 - Planting", "PlantList", "RaspberryBush:Raspberry:2,BlueberryBush:Blueberries:2,CloudberryBush:Cloudberry:2,Pickable_Thistle:Thistle:1,Pickable_Mushroom:Mushroom:1,Pickable_Dandelion:Dandelion:1", "What can be planted, as GrownPrefab:SeedItem:Amount separated by commas.");
		PlantGrowTime = ((BaseUnityPlugin)this).Config.Bind<float>("11 - Planting", "PlantGrowTimeSeconds", 2000f, new ConfigDescription("How long a planted bush or herb takes to grow.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 200000f), Array.Empty<object>()));
		PlantIgnoreSpacing = ((BaseUnityPlugin)this).Config.Bind<bool>("11 - Planting", "PlantIgnoreSpacing", true, "Removes the spacing rule, so crops never say they need more room to grow and can be planted right next to each other.");
		ConfigMigration.Apply(((BaseUnityPlugin)this).Config);
		ConfigSync.MarkPersonal((ConfigEntryBase)CompassEnabled, (ConfigEntryBase)CompassShowDistance, (ConfigEntryBase)CompassHideCheckedPins, (ConfigEntryBase)ChestNoticeMinutes, (ConfigEntryBase)ChestNoticeRange, (ConfigEntryBase)CommandsIgnoreCase, (ConfigEntryBase)HideDayNumber, (ConfigEntryBase)ClearDeathPinsButton, (ConfigEntryBase)ActivityFeedEnabled, (ConfigEntryBase)ActivityFeedSeconds, (ConfigEntryBase)AutoShield, (ConfigEntryBase)SettingsHint, (ConfigEntryBase)CompassPinRange, (ConfigEntryBase)CompassShowPins, (ConfigEntryBase)MenuKey, (ConfigEntryBase)MistToggleKey, (ConfigEntryBase)ChatToggleKey, (ConfigEntryBase)ShipStowKey, (ConfigEntryBase)FirstPersonEnabled, (ConfigEntryBase)FirstPersonZoom, (ConfigEntryBase)FirstPersonForward, (ConfigEntryBase)FirstPersonHeight, (ConfigEntryBase)FirstPersonBack, (ConfigEntryBase)FirstPersonFollowHead, (ConfigEntryBase)FirstPersonNearClip, (ConfigEntryBase)FirstPersonShowBody, (ConfigEntryBase)FirstPersonHideHead, (ConfigEntryBase)FirstPersonHiddenParts, (ConfigEntryBase)FirstPersonFaceCamera, (ConfigEntryBase)TeamHud, (ConfigEntryBase)FirstPersonHeadBob, (ConfigEntryBase)FirstPersonSteadiness, (ConfigEntryBase)FirstPersonTurnBody, (ConfigEntryBase)FirstPersonTurnAngle, (ConfigEntryBase)ContinueButton, (ConfigEntryBase)RememberPasswords, (ConfigEntryBase)HideStoreButton, (ConfigEntryBase)FogClearByDefault, (ConfigEntryBase)EmberClearByDefault, (ConfigEntryBase)DonateButton, (ConfigEntryBase)DonateLabel, (ConfigEntryBase)DonateUrl);
		LocalPrefs.Apply();
		((Component)this).gameObject.AddComponent<HubWindow>();
		((Component)this).gameObject.AddComponent<TeamWindow>();
		((Component)this).gameObject.AddComponent<CharacterNotice>();
		MistControl.RegisterCommand();
		FogControl.RegisterCommand();
		EmberControl.RegisterCommand();
		Spectate.RegisterCommand();
		CraftSearch.RegisterCommand();
		Unstuck.RegisterCommand();
		Commands.RegisterAll();
		((Component)this).gameObject.AddComponent<ActivityFeed>();
		UpdateCheck.Start();
		ConfigSync.Init(((BaseUnityPlugin)this).Config);
		((BaseUnityPlugin)this).Config.SettingChanged += ConfigSync.OnSettingChanged;
		SetupWatcher();
		Stopwatch stopwatch = Stopwatch.StartNew();
		Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(KingsTweaksPlugin).Assembly);
		foreach (Type type in typesFromAssembly)
		{
			try
			{
				long elapsedMilliseconds = stopwatch.ElapsedMilliseconds;
				_harmony.CreateClassProcessor(type).Patch();
				long num = stopwatch.ElapsedMilliseconds - elapsedMilliseconds;
				if (num > 200)
				{
					Log.LogWarning((object)$"Patch {type.Name} took {num}ms.");
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Patch " + type.Name + " failed: " + ex.Message));
			}
		}
		Log.LogInfo((object)string.Format("KingsTweaks {0} ready ({1}ms patching).", "2.41.3", stopwatch.ElapsedMilliseconds));
	}

	private void SetupWatcher()
	{
		_watcher = new FileSystemWatcher(Paths.ConfigPath, Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath))
		{
			IncludeSubdirectories = false,
			NotifyFilter = (NotifyFilters.Size | NotifyFilters.LastWrite)
		};
		_watcher.Changed += delegate
		{
			_reloadRequested = true;
		};
		_watcher.Created += delegate
		{
			_reloadRequested = true;
		};
		_watcher.EnableRaisingEvents = true;
	}

	private void Update()
	{
		if (_reloadRequested)
		{
			_reloadRequested = false;
			if (!ConfigSync.IsSynced)
			{
				try
				{
					((BaseUnityPlugin)this).Config.Reload();
					LocalPrefs.Apply();
					Log.LogInfo((object)"Config reloaded from disk.");
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Failed to reload config: " + ex.Message));
				}
			}
		}
		if (ConfigSync.BroadcastPending)
		{
			ConfigSync.BroadcastPending = false;
			ConfigSync.Broadcast();
		}
		ItemMerger.Tick(Time.deltaTime);
		BedInteract.Tick();
		PasswordMemory.Tick();
		ChatMode.Tick();
		MistControl.Tick();
		FreeInWard.TellOnce();
		FogControl.Tick();
		EmberControl.Tick();
		Spectate.Tick();
		CraftSearch.Tick();
		BodySize.Tick();
		TameTeleport.Tick();
		ShipStow.Tick();
		SettingsWindow.Tick();
		SettingsHintNotice.Tick();
		DoorLocking.Tick();
		Teams.Tick();
		TeamInviteKey.Tick();
		TeamHudPanel.Tick();
		TeamPins.Tick();
		DeathPins.Tick();
		TameTracker.Tick();
		Dye.Tick();
		AutoRepair.Tick();
		Travel.Tick();
		ForcedPvp.Tick();
		Commands.Tick();
		Warps.Tick();
		Sleepers.Tick();
		Sleepers.ServerTick();
		ServerCharacters.Tick();
		ServerCharacters.WriteTick();
		MapExplore.Tick();
		ServerInfo.Tick();
		Restarts.Tick();
		DoorsInBuildMode.Tick();
		TameHealth.Tick();
		MapControl.Tick();
		AutoShieldEquip.Tick();
		if (KTUI.AnyWindowOpen && KTUI.EscapePressed())
		{
			KTUI.CloseAll();
		}
		NetRpcs.Tick();
		VersionCheck.Tick();
		ServerMessage.Tick();
		UpdateNotice.Tick();
		FejdStartup_Start_VersionLabelPatch.Refresh();
		SkyTree.Tick();
		Compass.Tick();
		DoorInteract.Tick();
		Backups.Tick();
	}

	private void OnDestroy()
	{
		_watcher?.Dispose();
		_harmony.UnpatchSelf();
	}

	internal static bool On(ConfigEntry<bool> feature)
	{
		return ModEnabled != null && feature != null && ModEnabled.Value && feature.Value;
	}

	internal static bool WardAllows(WearNTear piece)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		if (!RequireWard.Value)
		{
			return true;
		}
		return WardCheck.InsideActiveWard(((Component)piece).transform.position);
	}
}
internal static class EmptyShips
{
	private static readonly MethodInfo StandingOnShip = AccessTools.Method(typeof(Character), "GetStandingOnShip", (Type[])null, (Type[])null);

	private static readonly FieldInfo PlayersAboard = Reflect.Field(typeof(Ship), "m_players");

	internal static bool Protected(Component thing, HitData hit)
	{
		if (!KingsTweaksPlugin.On(KingsTweaksPlugin.ProtectEmptyShips) || (Object)(object)thing == (Object)null)
		{
			return false;
		}
		Ship componentInParent = thing.GetComponentInParent<Ship>();
		if ((Object)(object)componentInParent == (Object)null)
		{
			return false;
		}
		if (hit == null)
		{
			return true;
		}
		if (hit.GetAttacker() is Player)
		{
			return false;
		}
		return !Manned(componentInParent);
	}

	private static bool Manned(Ship ship)
	{
		try
		{
			if (PlayersAboard?.GetValue(ship) is ICollection collection)
			{
				return collection.Count > 0;
			}
		}
		catch
		{
		}
		if (StandingOnShip == null)
		{
			return false;
		}
		foreach (Player allPlayer in Player.GetAllPlayers())
		{
			if ((Object)(object)allPlayer == (Object)null)
			{
				continue;
			}
			try
			{
				if (StandingOnShip.Invoke(allPlayer, null) == ship)
				{
					return true;
				}
			}
			catch
			{
			}
		}
		return false;
	}
}
[HarmonyPatch(typeof(WearNTear), "Damage")]
internal static class WearNTear_Damage_ShipPatch
{
	private static bool Prepare()
	{
		return AccessTools.Method(typeof(WearNTear), "Damage", (Type[])null, (Type[])null) != null;
	}

	private static bool Prefix(WearNTear __instance, object[] __args)
	{
		object? obj = __args?.FirstOrDefault((object a) => a is HitData);
		HitData hit = (HitData)((obj is HitData) ? obj : null);
		return !EmptyShips.Protected((Component)(object)__instance, hit);
	}
}
[HarmonyPatch(typeof(Minimap), "AddSharedMapData")]
internal static class Minimap_AddSharedMapData_Patch
{
	private static readonly FieldInfo PinsField = Reflect.Field(typeof(Minimap), "m_pins");

	private static bool _told;

	private static bool Prepare()
	{
		return AccessTools.Method(typeof(Minimap), "AddSharedMapData", (Type[])null, (Type[])null) != null;
	}

	private static void Prefix(Minimap __instance, out List<object> __state)
	{
		__state = null;
		if (KingsTweaksPlugin.On(KingsTweaksPlugin.NoPinSharing))
		{
			__state = Snapshot(__instance);
		}
	}

	private static void Postfix(Minimap __instance, List<object> __state)
	{
		if (__state == null)
		{
			return;
		}
		try
		{
			List<object> list = Snapshot(__instance);
			if (list == null)
			{
				return;
			}
			MethodInfo methodInfo = null;
			int num = 0;
			foreach (object item in list)
			{
				if (item == null || __state.Contains(item))
				{
					continue;
				}
				if (methodInfo == null)
				{
					methodInfo = AccessTools.Method(typeof(Minimap), "RemovePin", new Type[1] { item.GetType() }, (Type[])null);
				}
				if (methodInfo == null)
				{
					if (!_told)
					{
						_told = true;
						KingsTweaksPlugin.Log.LogWarning((object)"Cartography: no way to take a pin back off the map on this build, so shared pins are being kept after all.");
					}
					return;
				}
				methodInfo.Invoke(__instance, new object[1] { item });
				num++;
			}
			if (num > 0)
			{
				KingsTweaksPlugin.Log.LogInfo((object)$"Cartography: kept the map, left {num} of their pins out of it.");
			}
		}
		catch (Exception ex)
		{
			KingsTweaksPlugin.Log.LogWarning((object)("Cartography: couldn't filter the shared pins: " + ex.Message));
		}
	}

	private static List<object> Snapshot(Minimap map)
	{
		try
		{
			if (!(PinsField?.GetValue(map) is IEnumerable enumerable))
			{
				return null;
			}
			List<object> list = new List<object>();
			foreach (object item in enumerable)
			{
				list.Add(item);
			}
			return list;
		}
		catch
		{
			return null;
		}
	}
}
internal static class Spears
{
	private static float _droppingUntil;

	internal static void Dropping()
	{
		_droppingUntil = Time.time + 3f;
	}

	internal static bool IsSpear(ItemData item)
	{
		string text = item?.m_shared?.m_name;
		return !string.IsNullOrEmpty(text) && text.IndexOf("spear", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	internal static void Consider(ItemDrop drop, bool loaded)
	{
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		if (!KingsTweaksPlugin.On(KingsTweaksPlugin.AutoPickupSpears) || (Object)(object)drop == (Object)null || Time.time < _droppingUntil || loaded)
		{
			return;
		}
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || !IsSpear(drop.m_itemData))
		{
			return;
		}
		float num = Mathf.Max(5f, KingsTweaksPlugin.SpearPickupRange.Value);
		Vector3 val = ((Component)drop).transform.position - ((Component)localPlayer).transform.position;
		if (((Vector3)(ref val)).sqrMagnitude > num * num)
		{
			return;
		}
		ZNetView component = ((Component)drop).GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner())
		{
			return;
		}
		try
		{
			((Humanoid)localPlayer).Pickup(((Component)drop).gameObject, true, true);
		}
		catch (Exception ex)
		{
			KingsTweaksPlugin.Log.LogWarning((object)("Spear pickup failed: " + ex.Message));
		}
	}

	internal static bool Wants()
	{
		return KingsTweaksPlugin.On(KingsTweaksPlugin.AutoPickupSpears) && (Object)(object)Player.m_localPlayer != (Object)null;
	}

	internal static bool Take(ItemDrop drop, bool loaded)
	{
		if ((Object)(object)drop == (Object)null || loaded)
		{
			return true;
		}
		if (!IsSpear(drop.m_itemData))
		{
			return true;
		}
		ZNetView component = ((Component)drop).GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null || !component.IsValid())
		{
			return false;
		}
		if (!component.IsOwner())
		{
			return true;
		}
		Consider(drop, loaded: false);
		return true;
	}
}
[HarmonyPatch]
internal static class Player_DropItem_SpearPatch
{
	private static MethodBase TargetMethod()
	{
		return AccessTools.GetDeclaredMethods(typeof(Humanoid)).FirstOrDefault((MethodInfo m) => m.Name == "DropItem") ?? AccessTools.GetDeclaredMethods(typeof(Player)).FirstOrDefault((MethodInfo m) => m.Name == "DropItem");
	}

	private static bool Prepare()
	{
		return TargetMethod() != null;
	}

	private static void Prefix(Character __instance)
	{
		if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
		{
			Spears.Dropping();
		}
	}
}
internal static class Carts
{
	private static readonly Type CartType = AccessTools.TypeByName("Vagon");

	internal static readonly bool Ready = CartType != null && AccessTools.Method(typeof(Piece), "CanBeRemoved", (Type[])null, (Type[])null) != null;

	private static readonly FieldInfo RemovableField = Reflect.Field(typeof(Piece), "m_canBeRemoved");

	internal static readonly MethodBase HoverMethod = ((CartType == null) ? null : Reflect.Method(CartType, "GetHoverText"));

	private static bool _told;

	private static readonly Dictionary<int, bool> OriginalRemovable = new Dictionary<int, bool>();

	internal static bool Enabled => Ready && KingsTweaksPlugin.On(KingsTweaksPlugin.CartDismantle);

	internal static bool IsCart(Component thing)
	{
		return CartType != null && (Object)(object)thing != (Object)null && (Object)(object)thing.GetComponentInParent(CartType) != (Object)null;
	}

	internal static bool Empty(Component thing)
	{
		Container val = (((Object)(object)thing == (Object)null) ? null : thing.GetComponentInChildren<Container>());
		Inventory val2 = (((Object)(object)val == (Object)null) ? null : val.GetInventory());
		return val2 == null || val2.NrOfItems() == 0;
	}

	internal static void Allow()
	{
		Allow(ZNetScene.instance);
	}

	internal static void Allow(ZNetScene scene)
	{
		if (!Ready || (Object)(object)scene == (Object)null || scene.m_prefabs == null || RemovableField == null)
		{
			return;
		}
		bool flag = KingsTweaksPlugin.On(KingsTweaksPlugin.CartDismantle);
		int num = 0;
		foreach (GameObject prefab in scene.m_prefabs)
		{
			if ((Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponent(CartType) == (Object)null)
			{
				continue;
			}
			Piece component = prefab.GetComponent<Piece>();
			if (!((Object)(object)component == (Object)null))
			{
				if (!OriginalRemovable.ContainsKey(((Object)component).GetInstanceID()))
				{
					OriginalRemovable[((Object)component).GetInstanceID()] = (bool)RemovableField.GetValue(component);
				}
				RemovableField.SetValue(component, flag || OriginalRemovable[((Object)component).GetInstanceID()]);
				num++;
			}
		}
		if (num != 0 && !_told && flag)
		{
			_told = true;
			KingsTweaksPlugin.Log.LogInfo((object)$"Carts: {num} of them can be taken apart with the hammer.");
			if (HoverMethod == null)
			{
				KingsTweaksPlugin.Log.LogWarning((object)"Carts: this build has no hover text on the cart, so the \"empty it first\" warning won't show. Taking a loaded one apart is still refused.");
			}
		}
	}

	internal static bool Refuse(Component thing)
	{
		return Enabled && IsCart(thing) && !Empty(thing);
	}
}
[HarmonyPatch(typeof(ZNetScene), "Awake")]
internal static class ZNetScene_Awake_CartPatch
{
	private static void Prefix(ZNetScene __instance)
	{
		try
		{
			Carts.Allow(__instance);
		}
		catch (Exception ex)
		{
			KingsTweaksPlugin.Log.LogWarning((object)("Carts: setup failed: " + ex.Message));
		}
	}
}
[HarmonyPatch(typeof(Piece), "CanBeRemoved")]
internal static class Piece_CanBeRemoved_CartPatch
{
	private static bool Prepare()
	{
		return AccessTools.Method(typeof(Piece), "CanBeRemoved", (Type[])null, (Type[])null) != null;
	}

	[HarmonyPriority(0)]
	private static void Postfix(Piece __instance, ref bool __result)
	{
		if (__result && Carts.Refuse((Component)(object)__instance))
		{
			__result = false;
		}
	}
}
[HarmonyPatch(typeof(Player), "CheckCanRemovePiece")]
internal static class Player_CheckCanRemovePiece_CartPatch
{
	private static bool Prepare()
	{
		return AccessTools.Method(typeof(Player), "CheckCanRemovePiece", (Type[])null, (Type[])null) != null;
	}

	[HarmonyPriority(0)]
	private static void Postfix(Piece __0, ref bool __result)
	{
		if (__result && Carts.Refuse((Component)(object)__0))
		{
			__result = false;
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)2, "Empty the cart first", 0, (Sprite)null, false);
			}
		}
	}
}
[HarmonyPatch]
internal static class Vagon_GetHoverText_CartPatch
{
	private static MethodBase TargetMethod()
	{
		return Carts.HoverMethod;
	}

	private static bool Prepare()
	{
		return Carts.HoverMethod != null;
	}

	private static void Postfix(Component __instance, ref string __result)
	{
		if (Carts.Enabled && !string.IsNullOrEmpty(__result) && Carts.IsCart(__instance) && !Carts.Empty(__instance))
		{
			__result += "\n<color=orange>Empty it before taking it apart</color>";
		}
	}
}
internal static class ToolTorch
{
	private static int _frame = -1;

	internal static bool Equipping => _frame == Time.frameCount;

	internal static void Allow()
	{
		_frame = Time.frameCount;
	}

	internal static void Done()
	{
		_frame = -1;
	}

	internal static bool IsBuildTool(ItemData item)
	{
		return (Object)(object)item?.m_shared?.m_buildPieces != (Object)null;
	}

	internal static MethodBase Find(string name)
	{
		return (from m in AccessTools.GetDeclaredMethods(typeof(Humanoid))
			where m.Name == name && m.GetParameters().Length >= 1 && m.GetParameters()[0].ParameterType == typeof(ItemData)
			orderby m.GetParameters().Length descending
			select m).FirstOrDefault();
	}

	internal static bool IsTorch(ItemData item)
	{
		SharedData val = item?.m_shared;
		if (val == null)
		{
			return false;
		}
		try
		{
			if (((object)Unsafe.As<ItemType, ItemType>(ref val.m_itemType)/*cast due to .constrained prefix*/).ToString().IndexOf("torch", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
		}
		catch
		{
		}
		return !string.IsNullOrEmpty(val.m_name) && val.m_name.IndexOf("torch", StringComparison.OrdinalIgnoreCase) >= 0;
	}
}
[HarmonyPatch]
internal static class Humanoid_EquipItem_TorchPatch
{
	private static MethodBase TargetMethod()
	{
		return ToolTorch.Find("EquipItem");
	}

	private static bool Prepare()
	{
		return TargetMethod() != null;
	}

	private static void Prefix(Humanoid __instance, ItemData __0)
	{
		if (KingsTweaksPlugin.On(KingsTweaksPlugin.TorchWithTools) && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && ToolTorch.IsBuildTool(__0))
		{
			ToolTorch.Allow();
		}
	}

	private static void Postfix()
	{
		ToolTorch.Done();
	}
}
[HarmonyPatch]
internal static class Humanoid_UnequipItem_TorchPatch
{
	private static MethodBase TargetMethod()
	{
		return ToolTorch.Find("UnequipItem");
	}

	private static bool Prepare()
	{
		return TargetMethod() != null;
	}

	private static bool Prefix(Humanoid __instance, ItemData __0)
	{
		if (!ToolTorch.Equipping)
		{
			return true;
		}
		if (!KingsTweaksPlugin.On(KingsTweaksPlugin.TorchWithTools))
		{
			return true;
		}
		if ((Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
		{
			return true;
		}
		return !ToolTorch.IsTorch(__0);
	}
}
[HarmonyPatch]
internal static class MessageHud_ShowMessage_DayPatch
{
	private static string _word;

	private static MethodBase TargetMethod()
	{
		return AccessTools.GetDeclaredMethods(typeof(MessageHud)).FirstOrDefault((MethodInfo m) => m.Name == "ShowMessage" && m.GetParameters().Length >= 2 && m.GetParameters()[1].ParameterType == typeof(string));
	}

	private static bool Prepare()
	{
		return TargetMethod() != null;
	}

	private static bool Prefix(string __1)
	{
		if (!KingsTweaksPlugin.On(KingsTweaksPlugin.HideDayNumber))
		{
			return true;
		}
		if (string.IsNullOrEmpty(__1))
		{
			return true;
		}
		return !IsDayCount(__1);
	}

	private static bool IsDayCount(string text)
	{
		if (text.StartsWith("$msg_day", StringComparison.OrdinalIgnoreCase))
		{
			return true;
		}
		if (_word == null)
		{
			string text2 = Loc.Localize("$msg_day");
			if (!string.IsNullOrEmpty(text2) && !text2.StartsWith("$"))
			{
				_word = text2.Trim();
			}
		}
		string text3 = _word ?? "day";
		if (!text.StartsWith(text3, StringComparison.OrdinalIgnoreCase))
		{
			return false;
		}
		string text4 = text.Substring(text3.Length).Trim();
		return text4.Length > 0 && text4.All(char.IsDigit);
	}
}
[HarmonyPatch(typeof(Skills), "OnDeath")]
internal static class Skills_OnDeath_Patch
{
	private static bool Prepare()
	{
		return AccessTools.Method(typeof(Skills), "OnDeath", (Type[])null, (Type[])null) != null;
	}

	private static bool Prefix()
	{
		return !KingsTweaksPlugin.On(KingsTweaksPlugin.KeepSkillsOnDeath);
	}
}
internal static class AdminPanel
{
	internal class Row
	{
		internal string Id = "";

		internal string Name = "";

		internal string Note = "";

		internal bool Admin;
	}

	internal static class Reasons
	{
		private static readonly Dictionary<string, string> Why = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		private static bool _loaded;

		private static string FilePath => Path.Combine(Paths.ConfigPath, "dev.craz.kingstweaks.banreasons.txt");

		internal static string For(string id)
		{
			if (!_loaded)
			{
				Load();
			}
			string value;
			return Why.TryGetValue(id ?? "", out value) ? value : "";
		}

		internal static void Set(string id, string reason)
		{
			if (!string.IsNullOrEmpty(id))
			{
				if (!_loaded)
				{
					Load();
				}
				string text = (reason ?? "").Replace('|', ' ').Trim();
				Why[id] = ((text.Length == 0) ? DateTime.Now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) : (text + " (" + DateTime.Now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) + ")"));
				Save();
			}
		}

		internal static void