Decompiled source of LethalMin v1.0.34

NoteBoxz.LethalMin.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using ElevatorMod.Patches;
using GameNetcodeStuff;
using HarmonyLib;
using Imperium.Interface.SpawningUI;
using Imperium.Patches.Objects;
using Imperium.Patches.Systems;
using LCOffice.Components;
using LethalCompanyInputUtils.Api;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalLevelLoader;
using LethalLib.Extras;
using LethalLib.Modules;
using LethalMin;
using LethalMin.ConfigPatches;
using LethalMin.HUD;
using LethalMin.Library;
using LethalMin.Patches;
using LethalMin.Patches.AI;
using LethalMin.Pikmin;
using LethalMin.Routeing;
using LethalMin.Utils;
using LethalMinLibrary;
using LethalModDataLib.Enums;
using LethalModDataLib.Features;
using LethalModDataLib.Helpers;
using LethalMon.Behaviours;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using NoteBoxz.LethalMin.NetcodePatcher;
using PiggyVarietyMod.Patches;
using PiggysVarietyMod.Hazards.TeslaGate;
using SellBodies;
using TMPro;
using Unity.AI.Navigation;
using Unity.Mathematics;
using Unity.Netcode;
using Unity.Netcode.Components;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations.Rigging;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Video;
using itolib.PlayZone;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("CodeRebirth")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("giosuel.Imperium")]
[assembly: IgnoresAccessChecksTo("itolib")]
[assembly: IgnoresAccessChecksTo("kite.ZelevatorCode")]
[assembly: IgnoresAccessChecksTo("LCOffice")]
[assembly: IgnoresAccessChecksTo("LethalCompanyInputUtils")]
[assembly: IgnoresAccessChecksTo("LethalConfig")]
[assembly: IgnoresAccessChecksTo("LethalLevelLoader")]
[assembly: IgnoresAccessChecksTo("LethalLib")]
[assembly: IgnoresAccessChecksTo("LethalMon")]
[assembly: IgnoresAccessChecksTo("MaxWasUnavailable.LethalModDataLib")]
[assembly: IgnoresAccessChecksTo("Newtonsoft.Json")]
[assembly: IgnoresAccessChecksTo("PiggysVarietyMod")]
[assembly: IgnoresAccessChecksTo("PiggyVarietyMod")]
[assembly: IgnoresAccessChecksTo("SellBodies")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: AssemblyCompany("NoteBoxz.LethalMin")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.34.0")]
[assembly: AssemblyInformationalVersion("1.0.34")]
[assembly: AssemblyProduct("LethalMin")]
[assembly: AssemblyTitle("NoteBoxz.LethalMin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.34.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class InputClassWithUtils : LcInputActions
{
	[InputAction(/*Could not decode attribute arguments.*/)]
	public InputAction Throw { get; set; } = null;


	[InputAction(/*Could not decode attribute arguments.*/)]
	public InputAction ThrowCancel { get; set; } = null;


	[InputAction(/*Could not decode attribute arguments.*/)]
	public InputAction Charge { get; set; } = null;


	[InputAction(/*Could not decode attribute arguments.*/)]
	public InputAction Whistle { get; set; } = null;


	[InputAction(/*Could not decode attribute arguments.*/)]
	public InputAction Dismiss { get; set; } = null;


	[InputAction(/*Could not decode attribute arguments.*/)]
	public InputAction SwitchWhistleAud { get; set; } = null;


	[InputAction(/*Could not decode attribute arguments.*/)]
	public InputAction SwitchLeft { get; set; } = null;


	[InputAction(/*Could not decode attribute arguments.*/)]
	public InputAction SwitchRight { get; set; } = null;


	[InputAction(/*Could not decode attribute arguments.*/)]
	public InputAction Glowmob { get; set; } = null;


	[InputAction(/*Could not decode attribute arguments.*/)]
	public InputAction OnionHudSpeed { get; set; } = null;

}
public class OnionAnimEvents : MonoBehaviour
{
	public AudioSource audio = null;

	public AudioSource audioLooped = null;

	public OnionSoundPack pack = null;

	public void OnEnable()
	{
		audioLooped.mute = true;
	}

	public void PlayAudioLooped()
	{
		audioLooped.mute = false;
		audioLooped.Play();
		global::LethalMin.LethalMin.Logger.LogInfo((object)("Playing looped audio: " + ((Object)audioLooped.clip).name));
	}

	public void StopAudioLooped()
	{
		audioLooped.Stop();
		audioLooped.mute = true;
		global::LethalMin.LethalMin.Logger.LogInfo((object)("Stopping looped audio: " + ((Object)audioLooped.clip).name));
	}

	public void PlayLandingAudio()
	{
		audio.PlayOneShot(pack.LandSound);
		global::LethalMin.LethalMin.Logger.LogInfo((object)("Playing landing audio: " + ((Object)pack.LandSound).name));
	}

	public void PlayExtendLegsAudio()
	{
		audio.PlayOneShot(pack.LegsPopOutSound);
		global::LethalMin.LethalMin.Logger.LogInfo((object)("Playing extend legs audio: " + ((Object)pack.LegsPopOutSound).name));
	}

	public void PlayRetractLegsAudio()
	{
		audio.PlayOneShot(pack.LegsPopInSound);
		global::LethalMin.LethalMin.Logger.LogInfo((object)("Playing retract legs audio: " + ((Object)pack.LegsPopInSound).name));
	}

	public void ShowOnionMesh()
	{
		Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>();
		foreach (Renderer val in componentsInChildren)
		{
			val.enabled = true;
		}
	}

	public void HideOnionMesh()
	{
		Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>();
		foreach (Renderer val in componentsInChildren)
		{
			val.enabled = false;
		}
	}
}
public enum PikminHazard
{
	Fire,
	Water,
	Electricity,
	Poison,
	Crush,
	Bullet,
	Explosive,
	Spore,
	Stab,
	Sticky,
	None
}
namespace Lethalm.Utils
{
	public class LookAtMainCamera : MonoBehaviour
	{
		private Camera mainCamera = null;

		private void Start()
		{
			mainCamera = Camera.current;
		}

		private void LateUpdate()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			mainCamera = getMainCamera();
			if ((Object)(object)mainCamera != (Object)null && 2f * ((Component)this).transform.position - ((Component)mainCamera).transform.position != Vector3.zero)
			{
				((Component)this).transform.LookAt(2f * ((Component)this).transform.position - ((Component)mainCamera).transform.position);
			}
		}

		private Camera getMainCamera()
		{
			return ((Object)(object)StartOfRound.Instance == (Object)null) ? Camera.current : StartOfRound.Instance.activeCamera;
		}
	}
}
namespace LethalMin
{
	[BepInPlugin("NoteBoxz.LethalMin", "LethalMin", "1.0.34")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class LethalMin : BaseUnityPlugin
	{
		public static Dictionary<int, OnionFuseRules> RegisteredFuseRules = new Dictionary<int, OnionFuseRules>();

		public static List<int> EnemyIDsOverridenByPiklopedia = new List<int>();

		public static LayerMask PikminColideable = LayerMask.op_Implicit(1375734017);

		public static EnemyType PikminEnemyType = null;

		public static EnemyType PuffminEnemyType = null;

		public static PikminSoundPack DefaultSoundPack = null;

		public static PikminSoundPack Pikmin2DefaultSoundPack = null;

		public static PikminSoundPack Pikmin3DefaultSoundPack = null;

		public static GameObject PikminGhostPrefab = null;

		public static GameObject SproutPrefab = null;

		public static GameObject OnionPrefab = null;

		public static GameObject DefultPikminSproutMesh = null;

		public static GameObject DefultOnionMesh = null;

		public static AnimationClip PlayerPluckAnim = null;

		public static GameObject OnionHUDSlotPrefab = null;

		public static GameObject SingleOnionHUDSlotPrefab = null;

		public static GameObject OnionItemPrefab = null;

		public static GameObject DefultOnionItemModel = null;

		public static GameObject GlowPrefab = null;

		public static GameObject PikminZapPrefab = null;

		public static GameObject PikminFirePrefab = null;

		public static GameObject PikminGasPrefab = null;

		public static GameObject PlayerSproutPrefab = null;

		public static GameObject NoticeZonePrefab = null;

		public static GameObject EnemyItemNode = null;

		public static GameObject GlowSeedPrefab = null;

		public static GameObject ItemCounterPrefab = null;

		public static GameObject GrabPosPrefab = null;

		public static OnionSoundPack DefaultOnionSoundPack = null;

		public static OnionType ShipOnionType = null;

		public static GameObject SSRenviourment = null;

		public static Vector3 enviormentStartPos = Vector3.zero;

		public const string FullEnglishAlphabetUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

		public const string FullEnglishAlphabetLower = "abcdefghijklmnopqrstuvwxyz";

		public const string FullEnglishAlhabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

		public const string FullNumbers = "0123456789";

		public static object AchivementController = null;

		public static bool InVRMode = false;

		public static List<Type> LibraryTypes = new List<Type>();

		public static List<Type> ConfigPatchTypes = new List<Type>();

		public static ConfigItem<int> MaxPikmin = null;

		public static ConfigItem<bool> FriendlyFire = null;

		public static ConfigItem<bool> FriendlyerFire = null;

		public static ConfigItem<bool> SkipPluckAnimation = null;

		public static ConfigItem<float> WhistleVolume = null;

		public static ConfigItem<bool> AllowOnionsToRevivePlayers = null;

		public static ConfigItem<bool> AllowOnionToReviveMaskeds = null;

		public static ConfigItem<bool> AllowOnionFusing = null;

		public static ConfigItem<bool> HideResultsWhenMoreThanFour = null;

		public static ConfigItem<bool> ConvertEnemyBodiesToItems = null;

		public static ConfigItem<bool> ShowOnionsInSpace = null;

		public static ConfigItem<Vector3> SpaceOnionPosition = null;

		public static ConfigItem<bool> DontUpdateSpaceOnionPosition = null;

		public static ConfigItem<bool> MakeItemsScanable = null;

		public static ConfigItem<bool> MakePikminScanable = null;

		public static ConfigItem<bool> MakeSproutsScanable = null;

		public static ConfigItem<bool> TriggerLandmines = null;

		public static ConfigItem<bool> GlobalGhostSFX = null;

		public static ConfigItem<bool> DieInPlayerDeathZone = null;

		public static ConfigItem<bool> TakeItemsFromPikmin = null;

		public static ConfigItem<bool> TeleportAroundPlayerWhenEnteringBuilding = null;

		public static ConfigItem<bool> ExcludePikminFromShotgun = null;

		public static ConfigItem<bool> ExcludePuffminFromShotgun = null;

		public static ConfigItem<float> PikminScale = null;

		public static ConfigItem<float> SproutScale = null;

		public static ConfigItem<int> CurWhistPack = null;

		public static ConfigItem<bool> BigEyesEnabled = null;

		public static ConfigItem<PikminScanNodeProperties.ScanNodeType> PikminScanNodeColorType = null;

		public static ConfigItem<PikminGeneration> DefaultGeneration = null;

		public static ConfigItem<CfgPikminGeneration> PikminModelGeneration = null;

		public static ConfigItem<CfgPikminGeneration> SoulSpriteGeneration = null;

		public static ConfigItem<CfgPikminGeneration> SproutModelGeneration = null;

		public static ConfigItem<CfgPikminGeneration> OnionModelGeneration = null;

		public static ConfigItem<CfgPikminGeneration> OnionItemModelGeneration = null;

		public static ConfigItem<CfgPikminGeneration> PikminSoundGeneration = null;

		public static ConfigItem<CfgPikminGeneration> PuffminGeneration = null;

		public static ConfigItem<string> ThrowAction = null;

		public static ConfigItem<string> ThrowCancelAction = null;

		public static ConfigItem<string> SwitchForwardAction = null;

		public static ConfigItem<string> SwitchBackwawrdsAction = null;

		public static ConfigItem<string> WhisleAction = null;

		public static ConfigItem<string> DismissAction = null;

		public static ConfigItem<string> SwitchWhistleSoundAction = null;

		public static ConfigItem<string> ChargeAction = null;

		public static ConfigItem<string> GlowmobAction = null;

		public static ConfigItem<string> OnionHudSpeedAction = null;

		public static Dictionary<string, MoonSpawnConfig> MoonSpawnConfigs = new Dictionary<string, MoonSpawnConfig>(StringComparer.OrdinalIgnoreCase);

		public static Dictionary<string, WeatherSpawnConfig> WeatherSpawnConfigs = new Dictionary<string, WeatherSpawnConfig>(StringComparer.OrdinalIgnoreCase);

		public static ConfigItem<bool> UsePowerLVForSprouts = null;

		public static ConfigItem<bool> UseLCSpawnSystem = null;

		public static ConfigItem<float> IndoorSpawnChance = null;

		public static ConfigItem<float> OutdoorSpawnChance = null;

		public static ConfigItem<float> OnionSpawnChance = null;

		public static ConfigItem<bool> UseBetaOnionSpawnSystem = null;

		public static ConfigItem<bool> AvoidWaterForOnionSpawning = null;

		public static ConfigItem<bool> AvoidBehindShipForOnionSpawning = null;

		public static ConfigItem<bool> EnableTypeSpawnFalloff = null;

		public static ConfigItem<int> TypeSpawnFalloffMaxCount = null;

		public static ConfigItem<float> TypeSpawnFalloffExponent = null;

		public static ConfigItem<float> NoOnionGroupSpawnThreshold = null;

		public static ConfigItem<bool> ScaleTypeSpawnAmountBySuppressedTypes = null;

		public static ConfigItem<float> SuppressedTypeFalloffThreshold = null;

		public static ConfigItem<float> OutdoorSpawnAmountScaleAtMaxSuppressed = null;

		public static ConfigItem<float> IndoorSpawnAmountScaleAtMaxSuppressed = null;

		public static ConfigItem<List<string>> AttackBlacklistConfig = null;

		public static ConfigItem<List<string>> ItemBlacklistConfig = null;

		public static ConfigItem<List<string>> EnemyBodyConvertBlacklistConfig = null;

		public static ConfigItem<bool> UseExitsWhenCarryingItems = null;

		public static ConfigItem<PfollowMode> PikminFollowMode = null;

		public static ConfigItem<float> TimeFallingFailSafe = null;

		public static ConfigItem<bool> CarryNonScrapItemsToCompany = null;

		public static ConfigItem<bool> IgnoreNonScrapItemsToCompany = null;

		public static ConfigItem<bool> TakeItemsToOnionOnCompany = null;

		public static ConfigItem<bool> TakeItemsToTheCar = null;

		public static ConfigItem<bool> TakeItemsToTheOnion = null;

		public static ConfigItem<bool> DisperseWhenDismissed = null;

		public static ConfigItem<bool> AllowOnBBtobeGrabed = null;

		public static ConfigItem<float> DismissWindownTime = null;

		public static ConfigItem<bool> NonWaterResistantAvoidWater = null;

		public static ConfigItem<bool> WildPikminCarry = null;

		public static ConfigItem<bool> WildPikminAttack = null;

		public static ConfigItem<bool> WildPikminAttackDamage = null;

		public static ConfigItem<bool> WildPikminNoDeath = null;

		public static ConfigItem<bool> UseConfigsForEnemies = null;

		public static ConfigItem<float> ClaySurgeon_SnipCooldown = null;

		public static ConfigItem<int> ClaySurgeon_SnipLimit = null;

		public static ConfigItem<float> Crawler_BiteCooldown = null;

		public static ConfigItem<int> Crawler_BiteLimit = null;

		public static ConfigItem<float> SandSpider_BiteCooldown = null;

		public static ConfigItem<int> SandSpider_BiteLimit = null;

		public static ConfigItem<float> HoarderBug_BiteCooldown = null;

		public static ConfigItem<int> HoarderBug_BiteLimit = null;

		public static ConfigItem<bool> HoarderBug_AggroWhenPikminTakesItem = null;

		public static ConfigItem<float> MouthDog_BiteCooldown = null;

		public static ConfigItem<int> MouthDog_BiteLimit = null;

		public static ConfigItem<bool> Blob_TrapPikmin = null;

		public static ConfigItem<bool> Blob_KillPikmin = null;

		public static ConfigItem<float> RedLocustBees_ZapCooldown = null;

		public static ConfigItem<bool> RedLocustBees_ZapPikmin = null;

		public static ConfigItem<bool> RedLocustBees_KillPikmin = null;

		public static ConfigItem<bool> CaveDweller_AllowCarry = null;

		public static ConfigItem<bool> CaveDweller_AttackAsBaby = null;

		public static ConfigItem<float> CaveDweller_BiteCooldown = null;

		public static ConfigItem<int> CaveDweller_BiteLimit = null;

		public static ConfigItem<int> RadMech_GrabLimmit = null;

		public static ConfigItem<bool> RadMech_GrabsPikmin = null;

		public static ConfigItem<int> ForestGiant_GrabLimit = null;

		public static ConfigItem<bool> ForestGiant_GrabsPikmin = null;

		public static ConfigItem<float> Jester_BiteCooldown = null;

		public static ConfigItem<int> Jester_BiteLimit = null;

		public static ConfigItem<float> ButlerEnemy_StabCooldown = null;

		public static ConfigItem<int> ButlerEnemy_StabLimit = null;

		public static ConfigItem<float> BaboonBird_BiteCooldown = null;

		public static ConfigItem<bool> Puma_HurtsPikmin = null;

		public static ConfigItem<bool> MaskedPlayerEnemy_ConvertPikmin = null;

		public static ConfigItem<bool> Puffer_CanPoisonPikmin = null;

		public static ConfigItem<bool> Company_GrabsPikmin = null;

		public static ConfigItem<bool> Company_HearsPikmin = null;

		public static ConfigItem<bool> Stingray_HeavyCarriersCanTriggerSpit = null;

		public static ConfigItem<int> Stingray_CarryStrengthNeededToTriggerSpit = null;

		public static ConfigItem<bool> Stingray_PikminCanSlipOnSlime = null;

		public static ConfigItem<bool> TurnToNormalOnDeath = null;

		public static ConfigItem<PikminHUDManager.HUDLayoutPresets> HUDPreset = null;

		public static ConfigItem<Vector3> PikminSelectionPosition = null;

		public static ConfigItem<Vector3> PikminSelectionRotation = null;

		public static ConfigItem<float> PikminSelectionScale = null;

		public static ConfigItem<float> PikminSelectionAlpha = null;

		public static ConfigItem<bool> EnableCurSlot = null;

		public static ConfigItem<bool> EnableNextSlot = null;

		public static ConfigItem<bool> EnablePreviousSlot = null;

		public static ConfigItem<Vector3> PikminCounterPosition = null;

		public static ConfigItem<Vector3> PikminCounterRotation = null;

		public static ConfigItem<float> PikminCounterScale = null;

		public static ConfigItem<float> PikminCounterAlphaActive = null;

		public static ConfigItem<float> PikminCounterAlphaIdle = null;

		public static ConfigItem<bool> EnableInExistanceCounter = null;

		public static ConfigItem<bool> EnableInSquadCounter = null;

		public static ConfigItem<bool> EnableInFieldCounter = null;

		public static ConfigItem<bool> HideSelectedWhenScanNotifcation = null;

		public static ConfigItem<bool> DontUpdateHudConfigs = null;

		public static ConfigItem<bool> GrayoutButtonsInOnionHUD = null;

		public static ConfigItem<bool> EnableCarouselEffect = null;

		public static ConfigItem<int> WhistlePriceConfig = null;

		public static ConfigItem<int> ShipOnionPriceConfig = null;

		public static ConfigItem<int> PluckaPhonePriceConfig = null;

		public static ConfigItem<int> ShipWhistlePriceConfig = null;

		public static ConfigItem<bool> IsWhistleConductive = null;

		public static ConfigItem<float> LumiknullActivateTime = null;

		public static ConfigItem<float> LumiknullActivateDistance = null;

		public static ConfigItem<float> LumiknullSpawnChance = null;

		public static ConfigItem<int> SpawnLumiknullAfterDays = null;

		public static ConfigItem<float> GlowOddsToTurnIntoSeed = null;

		public static ConfigItem<bool> GlowsUseableAtCompany = null;

		public static ConfigItem<bool> AttackOwnTamedEnemies = null;

		public static ConfigItem<bool> AttackOthersTamedEnemies = null;

		public static ConfigItem<bool> AllowMetalDetectorToZap = null;

		public static ConfigItem<bool> AddNavLinkToZeranosShip = null;

		public static ConfigItem<bool> BlockEnemiesFromEnteringZeranosShip = null;

		public static ConfigItem<bool> AddNavLinkToZeranosElevator = null;

		public static ConfigItem<bool> AutoSetHudVRPreset = null;

		public static ConfigItem<bool> DontUseInputUtilsForVR = null;

		public static ConfigItem<bool> DisableSproutInteraction = null;

		public static ConfigItem<bool> DisableWhistleFix = null;

		public static ConfigItem<float> OnionHUDZDistance = null;

		public static ConfigItem<string> ThrowVRAction = null;

		public static ConfigItem<string> ThrowCancelVRAction = null;

		public static ConfigItem<string> SecondaryThrowVRAction = null;

		public static ConfigItem<string> SwitchForwardVRAction = null;

		public static ConfigItem<string> SwitchBackwawrdsVRAction = null;

		public static ConfigItem<string> WhisleVRAction = null;

		public static ConfigItem<bool> UseMouthTriggerForWhistle = null;

		public static ConfigItem<string> DismissVRAction = null;

		public static ConfigItem<string> SwitchWhistleSoundVRAction = null;

		public static ConfigItem<string> ChargeVRAction = null;

		public static ConfigItem<string> SecondaryChargeVRAction = null;

		public static ConfigItem<bool> DisableChargeMotionBlur = null;

		public static ConfigItem<string> GlowmobVRAction = null;

		public static ConfigItem<bool> GlowmobDelay = null;

		public static ConfigItem<bool> DontDoAudibleNoiseCalcuationsForPikmin = null;

		public static ConfigItem<bool> DontResimulateOracleOnPikminDeath = null;

		public static ConfigItem<bool> RemovePuffminFromSpawnSearch = null;

		public static ConfigItem<bool> MakeCustomBoundsForWideShip = null;

		public static ConfigItem<bool> CheckNavMesh = null;

		public static ConfigItem<List<string>> NavmeshCheckBlacklistConfig = null;

		public static ConfigEntry<bool> UseCommasInVectorConfigs = null;

		public static ConfigItem<bool> GeneratePikminConfigs = null;

		public static ConfigItem<bool> UseModDataLibConfig = null;

		public static ConfigItem<bool> CleanMoonNames = null;

		public static ConfigItem<bool> GenerateMoonSpawnConfigs = null;

		public static ConfigItem<bool> GenerateWeatherSpawnConfigs = null;

		public static ConfigItem<bool> UseBetaItemWeightCalculation = null;

		public static ConfigItem<bool> WhistleMakesNoiseAtNoiceZone = null;

		public static ConfigItem<bool> DontMakeAudibleNoises = null;

		public static ConfigItem<float> PikminSignalCooldown = null;

		public static ConfigItem<bool> NoKnockBack = null;

		public static ConfigItem<bool> InvinceablePikmin = null;

		public static ConfigItem<bool> UselessBluesMode = null;

		public static ConfigItem<float> MaxWhistleZoneRadius = null;

		public static ConfigItem<float> MaxWhistleZoneDistance = null;

		public static ConfigItem<float> PlayerNoticeZoneSize = null;

		public static ConfigItem<float> PikminDamageMultipler = null;

		public static ConfigItem<float> PikminSpeedMultipler = null;

		public static ConfigItem<float> ChargeCooldown = null;

		public static ConfigItem<float> ChargeDistance = null;

		public static ConfigItem<bool> DontPurgeAfterFire = null;

		public static ConfigItem<bool> CR_ACUTargetsPikmin = null;

		public static ConfigItem<bool> CR_BulletKnockbackPikmin = null;

		public static ConfigItem<bool> CR_CraneTargetsPikmin = null;

		public static ConfigItem<bool> CR_CraneSquishPikmin = null;

		public static ConfigItem<bool> CR_FanKnockbackPikmin = null;

		public static ConfigItem<int> CR_FanKnockbackStrengthThreshold = null;

		public static ConfigItem<bool> CR_MicrowaveKnockbackPikmin = null;

		public static ConfigItem<bool> CR_FlashTurretKnockbackPikmin = null;

		public static ConfigItem<bool> CR_LaserTurretKillsPikmin = null;

		public static ConfigItem<bool> CR_TornadoPullsPikmin = null;

		public static ConfigItem<int> CR_TornadoPullStrengthThreshold = null;

		public static ConfigItem<bool> CR_TobySquishPikmin = null;

		public static ConfigItem<bool> CR_GoToSarahBeforeToby = null;

		public static ConfigItem<bool> YeetAfterLatchOn = null;

		public static ConfigItem<bool> RandomizeGenerationModels = null;

		public static ConfigItem<bool> AddCollisionToGhostSprites = null;

		public static ConfigItem<bool> FuniOnion = null;

		public static ConfigItem<bool> GiantWhistleMode = null;

		public static ConfigItem<bool> RagdollOnKnockback = null;

		public static LethalMin Instance { get; private set; } = null;


		internal static ManualLogSource Logger { get; private set; } = null;


		internal static Harmony? Harmony { get; set; }

		internal static AssetBundle assetBundle { get; private set; } = null;


		public static Dictionary<int, PikminType> RegisteredPikminTypes { get; private set; } = new Dictionary<int, PikminType>();


		public static Dictionary<int, OnionType> RegisteredOnionTypes { get; private set; } = new Dictionary<int, OnionType>();


		public static List<PikminType> NaturalSpawningTypes { get; private set; } = new List<PikminType>();


		public static Dictionary<int, PiklopediaEntry> RegisteredEntries { get; private set; } = new Dictionary<int, PiklopediaEntry>();


		public static InputClass InputClassInstace { get; private set; } = null;


		public static List<EnemyType> EnemyTypes => (from e in Resources.FindObjectsOfTypeAll<EnemyType>()
			where (Object)(object)e.enemyPrefab != (Object)null
			group e by e.enemyPrefab into g
			select g.First()).ToList();

		public static List<Item> ItemTypes => (from i in Resources.FindObjectsOfTypeAll<Item>()
			where (Object)(object)i.spawnPrefab != (Object)null
			group i by i.spawnPrefab into i
			select i.First()).ToList();

		public static List<OnionType> OnionTypes => RegisteredOnionTypes.Values.Where((OnionType ot) => ot.SpawnsIndoors || ot.SpawnsOutdoors).ToList();

		public static bool UseInputUtils => IsDependencyLoaded("com.rune580.LethalCompanyInputUtils") && (!InVRMode || !DontUseInputUtilsForVR || !InVRMode);

		public static bool UseModDataLib => IsDependencyLoaded("MaxWasUnavailable.LethalModDataLib") && UseModDataLibConfig.InternalValue;

		public static bool OnCompany => (Object)(object)RoundManager.Instance != (Object)null && (RoundManager.Instance.currentLevel.sceneName == "CompanyBuilding" || RoundManager.Instance.currentLevel.sceneName == "MusemaScene" || RoundManager.Instance.currentLevel.sceneName == "Oxyde");

		public static bool WhistleMakesNoiseAtNoticeZoneCheat => (Object)(object)PikminManager.instance != (Object)null && PikminManager.instance.Cheat_WhistleMakesNoiseAtNoticeZone.Value;

		public static bool DontMakeAudibleNoisesCheat => (Object)(object)PikminManager.instance != (Object)null && PikminManager.instance.Cheat_DontMakeAudibleNoises.Value;

		public static float PikminSignalCooldownCheat => ((Object)(object)PikminManager.instance != (Object)null) ? PikminManager.instance.Cheat_PikminSingalCooldown.Value : (-1f);

		public static bool UselessBluesCheat => (Object)(object)PikminManager.instance != (Object)null && PikminManager.instance.Cheat_UselessBluesMode.Value;

		public static bool InviciblePikminCheat => (Object)(object)PikminManager.instance != (Object)null && PikminManager.instance.Cheat_InvinceablePikmin.Value;

		public static bool NoKnockbackCheat => (Object)(object)PikminManager.instance != (Object)null && PikminManager.instance.Cheat_NoKnockback.Value;

		public static float WhistleZoneRadiusCheat => ((Object)(object)PikminManager.instance != (Object)null) ? PikminManager.instance.Cheat_MaxWhistleZoneRadius.Value : (-1f);

		public static float WhistleZoneDistanceCheat => ((Object)(object)PikminManager.instance != (Object)null) ? PikminManager.instance.Cheat_MaxWhistleZoneDistance.Value : (-1f);

		public static float PlayerNoticeZoneSizeCheat => ((Object)(object)PikminManager.instance != (Object)null) ? PikminManager.instance.Cheat_PlayerNoticeZoneSize.Value : (-1f);

		public static float PikminDamageMultiplerCheat => ((Object)(object)PikminManager.instance != (Object)null) ? PikminManager.instance.Cheat_PikminDamageMultipler.Value : (-1f);

		public static float PikminSpeedMultiplerCheat => ((Object)(object)PikminManager.instance != (Object)null) ? PikminManager.instance.Cheat_PikminSpeedMultipler.Value : (-1f);

		private void Awake()
		{
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			InputClassInstace = new InputClass();
			Logger.LogInfo((object)"LethalMin: Initializing LethalMin");
			Logger.LogInfo((object)"LethalMin: Netcode Patching");
			NetcodePatcher();
			Logger.LogInfo((object)"LethalMin: Patching");
			Patch();
			Logger.LogInfo((object)"LethalMin: Binding Configs");
			BindConfigs();
			Logger.LogInfo((object)"LethalMin: Patching Config Patches");
			PatchConfigPatches();
			Logger.LogInfo((object)"LethalMin: Loading AssetBundle");
			LoadAssetBundle();
			Logger.LogInfo((object)"LethalMin: Loading Miscellaneous Assets");
			LoadMiscAssets();
			Logger.LogInfo((object)"LethalMin: Registering Pikmin As Enemies");
			RegisterPikmin();
			Logger.LogInfo((object)"LethalMin: Registering Items");
			RegisterItems();
			Logger.LogInfo((object)"LethalMin: Registering Pikmin Types");
			RegisterPikminTypes();
			Logger.LogInfo((object)"LethalMin: Loading Default Moon Spawn Configs");
			LoadDefaultMoonConfigs();
			Logger.LogInfo((object)"LethalMin: Loading Default Weather Spawn Configs");
			LoadDefaultWeatherConfigs();
			Logger.LogInfo((object)"LethalMin: Registering Onion Types");
			RegisterOnionTypes();
			Logger.LogInfo((object)"LethalMin: Registering Onion Fuse Rules");
			RegisterFuseRules();
			Logger.LogInfo((object)"LethalMin: Registering Custom Piklopedia Entries");
			RegisterPiklopediaEntries();
			if (IsDependencyLoaded("ainavt.lc.lethalconfig"))
			{
				BindLCconfigs();
			}
			if (IsDependencyLoaded("BMX.LobbyCompatibility"))
			{
				RegisterLobbyCompat();
			}
			GameObject val = new GameObject("PikminGenerationManager");
			val.AddComponent<GenerationManager>();
			Logger.LogInfo((object)"NoteBoxz.LethalMin v1.0.34 has loaded!");
		}

		public static void RegisterItems()
		{
			Item val = assetBundle.LoadAsset<Item>("Assets/LethalMin/Whistle/WhisleItem.asset");
			val.isConductiveMetal = IsWhistleConductive;
			TerminalNode val2 = CreateTerminalNodeA("A whistle that can be used to call to your squad Pikmin easier.\n\n", val);
			Items.RegisterShopItem(val, (TerminalNode)null, (TerminalNode)null, val2, WhistlePriceConfig.InternalValue);
			UnlockableItemDef val3 = assetBundle.LoadAsset<UnlockableItemDef>("Assets/LethalMin/OnionAssets/ShipOnionDef.asset");
			TerminalNode val4 = CreateTerminalNodeB("Used to keep Purple and White Pikmin between moons.\n\n", val3);
			Unlockables.RegisterUnlockable(val3, (StoreType)1, (TerminalNode)null, (TerminalNode)null, val4, ShipOnionPriceConfig.InternalValue);
			UnlockableItemDef val5 = assetBundle.LoadAsset<UnlockableItemDef>("Assets/LethalMin/Whistle/CallBackControlDef.asset");
			float num = 300f;
			string text = $"{Mathf.FloorToInt(num / 60f):00}:{Mathf.FloorToInt(num % 60f):00}";
			TerminalNode val6 = CreateTerminalNodeB("A device that emits a large signal that calls any (non wild) pikmin to the ship. Goes on cooldown for (" + text + ") \n\n", val5);
			Unlockables.RegisterUnlockable(val5, (StoreType)1, (TerminalNode)null, (TerminalNode)null, val6, ShipWhistlePriceConfig.InternalValue);
			Item val7 = assetBundle.LoadAsset<Item>("Assets/LethalMin/Whistle/PluckAPhoneItem.asset");
			TerminalNode val8 = CreateTerminalNodeA("A more powerful whistle that can call pikmin with a bigger radius and pluck Pikmin from the ground. \n\n", val7);
			Items.RegisterShopItem(val7, (TerminalNode)null, (TerminalNode)null, val8, PluckaPhonePriceConfig.InternalValue);
			Item val9 = assetBundle.LoadAsset<Item>("Assets/LethalMin/Types/Glow Pikmin/GlowSeedItm.asset");
			Items.RegisterItem(val9);
			static TerminalNode CreateTerminalNode(string displayText, string name)
			{
				TerminalNode val10 = ScriptableObject.CreateInstance<TerminalNode>();
				((Object)val10).name = name;
				val10.clearPreviousText = true;
				val10.maxCharactersToType = 25;
				val10.displayText = displayText;
				return val10;
			}
			static TerminalNode CreateTerminalNodeA(string displayText, Item itm)
			{
				string name3 = itm.itemName.Replace(" ", "-") + "InfoNode";
				return CreateTerminalNode(displayText, name3);
			}
			static TerminalNode CreateTerminalNodeB(string displayText, UnlockableItemDef def)
			{
				string name2 = def.unlockable.unlockableName.Replace(" ", "-") + "InfoNode";
				return CreateTerminalNode(displayText, name2);
			}
		}

		public static void InitCustomDefaultSoundPacks(List<PikminSoundPack> soundPacks)
		{
			int num = 0;
			foreach (PikminSoundPack soundPack in soundPacks)
			{
				if (soundPack.IsDefaultSoundPack)
				{
					soundPack.InitalizeDict();
					num++;
				}
			}
			if (num > 0)
			{
				Logger.LogInfo((object)$"Initialized {num} custom default sound packs.");
			}
		}

		public static void InitDefaultSoundPacks()
		{
			List<PikminSoundPack> list = assetBundle.LoadAllAssets<PikminSoundPack>().ToList();
			foreach (PikminSoundPack item in list)
			{
				if (item.IsDefaultSoundPack)
				{
					item.InitalizeDict();
				}
			}
			DefaultSoundPack = assetBundle.LoadAsset<PikminSoundPack>("Assets/LethalMin/Types/DeafultSoundPack.asset");
			Pikmin2DefaultSoundPack = assetBundle.LoadAsset<PikminSoundPack>("Assets/LethalMin/Types/Pik2DeafultSoundPack.asset");
		}

		private static void RegisterTypes<T>(List<T> types, Dictionary<int, T> registry, string logName, Func<T, string> nameSelector, Action<T, int> registerAction)
		{
			Func<T, string> nameSelector2 = nameSelector;
			if (types.Count == 0)
			{
				return;
			}
			Logger.LogInfo((object)$"Registering {types.Count} {logName}");
			types.Sort((T a, T b) => string.Compare(nameSelector2(a), nameSelector2(b), StringComparison.Ordinal));
			int num = registry.Count;
			foreach (T type in types)
			{
				registerAction(type, num);
				num++;
			}
		}

		private static void RegisterTypesFromAssetBundle<T>(Dictionary<int, T> registry, string logName, Func<T, string> nameSelector, Action<T, int> registerAction) where T : ScriptableObject
		{
			List<T> types = assetBundle.LoadAllAssets<T>().ToList();
			RegisterTypes(types, registry, logName, nameSelector, registerAction);
		}

		public static void RegisterCustomPikminTypes(List<PikminType> CustomTypes)
		{
			RegisterTypes(CustomTypes, RegisteredPikminTypes, "Custom Types", (PikminType type) => type.PikminName, RegisterPikminType);
		}

		public static void RegisterPikminTypes()
		{
			InitDefaultSoundPacks();
			RegisterTypesFromAssetBundle(RegisteredPikminTypes, "Pikmin Types", (PikminType type) => type.PikminName, RegisterPikminType);
		}

		public static void RegisterPiklopediaEntries()
		{
			RegisterTypesFromAssetBundle(RegisteredEntries, "Piklopedia Entries", (PiklopediaEntry entry) => entry.EntryName, RegisterPiklopediaEntry);
		}

		public static void RegisterCustomPiklopediaEntries(List<PiklopediaEntry> loadedEntries)
		{
			RegisterTypes(loadedEntries, RegisteredEntries, "Custom Piklopedia Entries", (PiklopediaEntry entry) => entry.EntryName, RegisterPiklopediaEntry);
		}

		public static void RegisterOnionTypes()
		{
			RegisterTypesFromAssetBundle(RegisteredOnionTypes, "Onion Types", (OnionType type) => type.TypeName, RegisterOnionType);
		}

		public static void RegisterCustomOnionTypes(List<OnionType> CustomTypes)
		{
			RegisterTypes(CustomTypes, RegisteredOnionTypes, "Custom Onion Types", (OnionType type) => type.TypeName, RegisterOnionType);
		}

		public static void RegisterFuseRules()
		{
			RegisterTypesFromAssetBundle(RegisteredFuseRules, "Fuse Rules", (OnionFuseRules rules) => ((Object)rules).name, RegisterFuseRule);
		}

		public static void RegisterCustomFuseRules(List<OnionFuseRules> loadedTypes)
		{
			RegisterTypes(loadedTypes, RegisteredFuseRules, "Custom fuse rules", (OnionFuseRules rules) => ((Object)rules).name, RegisterFuseRule);
		}

		private static void RegisterPiklopediaEntry(PiklopediaEntry entry, int index)
		{
			int num = ((RegisteredEntries.Count > 0) ? (RegisteredEntries.Keys.Max() + 1) : 0);
			if (RegisteredEntries.ContainsKey(entry.PiklopediaID))
			{
				Logger.LogWarning((object)$"Piklopedia Entry: {entry.EntryName} with ID {entry.PiklopediaID} has already been registered.");
				return;
			}
			if ((Object)(object)entry.PiklopediaKeyword == (Object)null)
			{
				entry.PiklopediaKeyword = PikUtils.CreateTerminalKeyword("Piklopedia" + entry.EntryName, entry.EntryName.ToLower().Replace(" ", "") + " info", entry.PiklopediaNode);
			}
			entry.PiklopediaID = num;
			RegisteredEntries[num] = entry;
		}

		internal static void LoadAssetBundle()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			if (directoryName == null)
			{
				throw new InvalidOperationException("Unable to determine assembly location.");
			}
			string text = Path.Combine(directoryName, "lethalminassets");
			assetBundle = AssetBundle.LoadFromFile(text);
			if ((Object)(object)assetBundle == (Object)null)
			{
				throw new InvalidOperationException("Failed to load AssetBundle.");
			}
		}

		public void LoadMiscAssets()
		{
			PikminGhostPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/PikminGhost.prefab");
			SproutPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/Sprout.prefab");
			DefultPikminSproutMesh = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/Types/DefultSproutMesh.prefab");
			PlayerPluckAnim = assetBundle.LoadAsset<AnimationClip>("Assets/LethalMin/Animations/PlayerPluckNew.anim");
			OnionPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/Onion.prefab");
			DefultOnionMesh = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/OnionAssets/DefaultOnionMesh.prefab");
			OnionHUDSlotPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/OnionAssets/TypeSlot.prefab");
			SingleOnionHUDSlotPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/OnionAssets/TypeUI.prefab");
			OnionItemPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/OnionAssets/OnionGrabable.prefab");
			DefultOnionItemModel = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/OnionAssets/DefaultOnionItemMesh.prefab");
			GlowPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/IdleGlow.prefab");
			PikminZapPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/Particles/elecpikiparticle/PikminZap.prefab");
			PikminFirePrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/Particles/fixed FireGasPrefabs/PikminFire.prefab");
			PikminGasPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/Particles/fixed FireGasPrefabs/PikminGas.prefab");
			PlayerSproutPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/PlayerSprout.prefab");
			DefaultOnionSoundPack = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/OnionAssets/DefaultSoundPack.prefab").GetComponent<OnionSoundPack>();
			NoticeZonePrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/Puffmin/PuffminWhistleZone.prefab");
			EnemyItemNode = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/EnemyGrabbableItem.prefab");
			GlowSeedPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/Types/Glow Pikmin/GlowSeed.prefab");
			ItemCounterPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/PikminItemCounter.prefab");
			GrabPosPrefab = assetBundle.LoadAsset<GameObject>("Assets/LethalMin/GrabPos.prefab");
			ShipOnionType = assetBundle.LoadAsset<OnionType>("Assets/LethalMin/Types/ShipOnion.asset");
		}

		public void RegisterPikmin()
		{
			EnemyType val = assetBundle.LoadAsset<EnemyType>("Assets/LethalMin/PikminEnemyType.asset");
			TerminalNode val2 = assetBundle.LoadAsset<TerminalNode>("Assets/LethalMin/Pikmin TN.asset");
			val.spawningDisabled = ((!UseLCSpawnSystem) ? true : false);
			Enemies.RegisterEnemy(val, (Dictionary<LevelTypes, int>)null, (Dictionary<string, int>)null, val2, (TerminalKeyword)null);
			PikminEnemyType = val;
			PikminAI component = PikminEnemyType.enemyPrefab.GetComponent<PikminAI>();
			((Behaviour)component).enabled = false;
			PikminEnemyType.enemyPrefab.GetComponent<PikminTypeResolver>().PikminAIs.Add(component);
			EnemyType val3 = assetBundle.LoadAsset<EnemyType>("Assets/LethalMin/Puffmin/PuffminEnemyType.asset");
			TerminalNode val4 = assetBundle.LoadAsset<TerminalNode>("Assets/LethalMin/Puffmin/PuffminTN.asset");
			Enemies.RegisterEnemy(val3, (Dictionary<LevelTypes, int>)null, (Dictionary<string, int>)null, val4, (TerminalKeyword)null);
			PuffminEnemyType = val3;
		}

		internal static void RegisterPikminType(PikminType Ptype, int id)
		{
			Logger.LogMessage((object)("Registering Pikmin Type: " + Ptype.PikminName));
			if (RegisteredPikminTypes.ContainsKey(Ptype.PikminTypeID))
			{
				Logger.LogWarning((object)$"Pikmin Type: {Ptype.PikminName} with ID {Ptype.PikminTypeID} has already been registered.");
				return;
			}
			Ptype.MigrateOldSpawnFields();
			if ((bool)GeneratePikminConfigs && Ptype.GenerateConfigFile)
			{
				GeneratePikminTypeConfig(Ptype);
			}
			ConfigItem<bool> configItem = new ConfigItem<bool>("Pikmin", Ptype.PikminName, defaultValue: true, "Enable " + Ptype.PikminName + " Pikmin", needsRestart: true, ConfigItemAuthority.Host);
			if (!configItem)
			{
				Logger.LogWarning((object)("Pikmin Type: " + Ptype.PikminName + " is disabled in the config. Skipping registration."));
				return;
			}
			if (Ptype.DisableRegistration)
			{
				Logger.LogWarning((object)("Pikmin Type: " + Ptype.PikminName + " is set to be disabled. Skipping registration."));
				return;
			}
			if ((Object)(object)Ptype.ModelPrefab == (Object)null)
			{
				Logger.LogError((object)("Pikmin Type: " + Ptype.PikminName + " has no model prefab!"));
				return;
			}
			if ((Object)(object)Ptype.modelRefernces == (Object)null)
			{
				Logger.LogError((object)("Pikmin Type: " + Ptype.PikminName + " has no model references!"));
				return;
			}
			if ((Object)(object)Ptype.ModelPrefab.GetComponentInChildren<PikminAnimatorController>() == (Object)null)
			{
				Logger.LogWarning((object)("Pikmin Type: " + Ptype.PikminName + " has no animator controller!"));
			}
			if ((Object)(object)Ptype.PikminIcon == (Object)null)
			{
				Logger.LogWarning((object)("Pikmin Type: " + Ptype.PikminName + " has no icon!"));
			}
			if ((Object)(object)Ptype.SoundPack == (Object)null)
			{
				Ptype.SoundPack = DefaultSoundPack;
				Logger.LogWarning((object)("Pikmin Type: " + Ptype.PikminName + " has no Sound Pack! Using default."));
			}
			if ((Object)(object)Ptype.TargetOnion != (Object)null && !Ptype.TargetOnion.TypesCanHold.ToList().Contains(Ptype))
			{
				if (!Ptype.TargetOnion.AllowPikminToBeAddedToOnion)
				{
					Logger.LogWarning((object)("Pikmin Type: " + Ptype.PikminName + " has a Target Onion that does not contain this type in its TypesCanHold list! Won't add it."));
				}
				else
				{
					Logger.LogWarning((object)("Pikmin Type: " + Ptype.PikminName + " has a Target Onion that does not contain this type in its TypesCanHold list! Adding it now."));
					Array.Resize(ref Ptype.TargetOnion.TypesCanHold, Ptype.TargetOnion.TypesCanHold.Length + 1);
					Ptype.TargetOnion.TypesCanHold[Ptype.TargetOnion.TypesCanHold.Length - 1] = Ptype;
				}
			}
			else if (!Ptype.SoundPack.IsDefaultSoundPack)
			{
				Ptype.SoundPack.InitalizeDict();
			}
			if (Ptype.UsesPikminContainer && !ShipOnionType.TypesCanHold.ToList().Contains(Ptype))
			{
				Logger.LogInfo((object)("Pikmin Type: " + Ptype.PikminName + " has UsesPikminContainer set to true, adding it to the Ship Onion's TypesCanHold list."));
				Array.Resize(ref ShipOnionType.TypesCanHold, ShipOnionType.TypesCanHold.Length + 1);
				ShipOnionType.TypesCanHold[ShipOnionType.TypesCanHold.Length - 1] = Ptype;
			}
			if (Ptype.UsePiklopedia)
			{
				string text = "";
				if (Ptype.UsePresetFormatting)
				{
					string text2 = ((Ptype.piklopediaName == "") ? Ptype.PikminName : Ptype.piklopediaName);
					text = text2 + "\n\nSigurd's helpfulness level: " + Ptype.HelpfulLevel + "\n\nScientific name: " + Ptype.ScientificName + "\n\n" + Ptype.piklopediaDescription + "\n\n";
				}
				else
				{
					text = Ptype.piklopediaDescription;
				}
				if (string.IsNullOrEmpty(Ptype.piklopediaDescription))
				{
					Ptype.piklopediaDescription = $"Type Id {id}, with empty description.";
					Logger.LogWarning((object)("Pikmin Type: " + Ptype.PikminName + " has no description and uses Piklopedia!"));
				}
				TerminalNode val = null;
				if ((Object)(object)Ptype.OverridePiklopediaNode == (Object)null)
				{
					val = PikUtils.CreateTerminalNode("TerminalNode" + Ptype.PikminName, text);
					val.creatureName = (string.IsNullOrEmpty(Ptype.piklopediaName) ? Ptype.PikminName.Replace(" ", "-") : Ptype.piklopediaName);
					if (!string.IsNullOrEmpty(Ptype.piklopediaName) && string.IsNullOrWhiteSpace(Ptype.piklopediaName))
					{
						Logger.LogWarning((object)(Ptype.PikminName + " White space counts as the pikolopedia name not being empty, Pikmin name may show as empty in the terminal"));
					}
					val.displayVideo = Ptype.piklopediaVideo;
					val.loadImageSlowly = true;
				}
				else
				{
					val = Ptype.OverridePiklopediaNode;
				}
				TerminalKeyword val2 = null;
				val2 = (TerminalKeyword)((!((Object)(object)Ptype.OverridePiklopediaKeyword == (Object)null)) ? ((object)Ptype.OverridePiklopediaKeyword) : ((object)PikUtils.CreateTerminalKeyword("TerminalKeyword" + Ptype.PikminName, Ptype.PikminName.ToLower().Replace(" ", "") + " info", val)));
				PiklopediaEntry piklopediaEntry = ScriptableObject.CreateInstance<PiklopediaEntry>();
				((Object)piklopediaEntry).name = "PiklopediaEntry" + Ptype.PikminName;
				piklopediaEntry.EntryName = val.creatureName;
				Ptype.PiklopediaEntry = piklopediaEntry;
				piklopediaEntry.PiklopediaID = id;
				piklopediaEntry.PiklopediaKeyword = val2;
				piklopediaEntry.PiklopediaNode = val;
				RegisteredEntries[id] = piklopediaEntry;
			}
			for (int i = 0; i < Ptype.SoundPackGenerations.Length; i++)
			{
				PikminSoundPack pikminSoundPack = Ptype.SoundPackGenerations[i];
				if ((Object)(object)pikminSoundPack == (Object)null)
				{
					Logger.LogWarning((object)$"Pikmin Type: {Ptype.PikminName} has a null SoundPack for generation {i}! Defaulting to DefaultSoundPack.");
					Ptype.SoundPackGenerations[i] = DefaultSoundPack;
				}
				else if (!pikminSoundPack.IsDefaultSoundPack)
				{
					pikminSoundPack.InitalizeDict();
				}
			}
			if ((Object)(object)Ptype.CustomTypeScript != (Object)null)
			{
				PikminAI customTypeScript = AddCustomScriptToPikminAI(Ptype.CustomTypeScript);
				Object.Destroy((Object)(object)Ptype.CustomTypeScript);
				Ptype.CustomTypeScript = customTypeScript;
			}
			PikminAnimationPack pikminAnimationPack = Ptype.modelRefernces.AnimatorController?.AnimPack;
			if ((Object)(object)pikminAnimationPack != (Object)null)
			{
				pikminAnimationPack.AddEventsToOneshotIdleAnims();
			}
			PikminModelGeneration[] generations = Ptype.modelRefernces.Generations;
			foreach (PikminModelGeneration pikminModelGeneration in generations)
			{
				PikminAnimationPack pikminAnimationPack2 = pikminModelGeneration.AnimatorController?.AnimPack;
				if ((Object)(object)pikminAnimationPack2 != (Object)null)
				{
					pikminAnimationPack2.AddEventsToOneshotIdleAnims();
				}
			}
			Ptype.PikminTypeID = id;
			RegisteredPikminTypes[id] = Ptype;
			if (Ptype.SpawnsNaturally)
			{
				NaturalSpawningTypes.Add(Ptype);
			}
			Logger.LogMessage((object)$"Registered Pikmin Type: {Ptype.PikminName} with ID: {id}");
		}

		internal static void RegisterOnionType(OnionType Otype, int id)
		{
			Logger.LogMessage((object)("Registering Onion Type: " + Otype.TypeName));
			if (RegisteredOnionTypes.ContainsKey(id))
			{
				Logger.LogWarning((object)$"Onion Type with ID {id} has already been registered.");
				return;
			}
			int num = 0;
			PikminType[] typesCanHold = Otype.TypesCanHold;
			foreach (PikminType pikminType in typesCanHold)
			{
				if (!RegisteredPikminTypes.ContainsKey(pikminType.PikminTypeID))
				{
					Logger.LogDebug((object)("Onion Type: " + Otype.TypeName + " has a type " + pikminType.PikminName + " that is not registered! Skipping registration."));
					num++;
				}
			}
			if (num == Otype.TypesCanHold.Length)
			{
				Logger.LogWarning((object)("Onion Type: " + Otype.TypeName + " has no registered types! Skipping registration."));
				return;
			}
			Otype.OnionTypeID = id;
			RegisteredOnionTypes[id] = Otype;
			Logger.LogMessage((object)$"Registered Onion Type: {Otype.TypeName} with ID: {id}");
		}

		internal static void RegisterFuseRule(OnionFuseRules FuseR, int id)
		{
			Logger.LogMessage((object)("Registering Fuse Rules: " + ((Object)FuseR).name));
			if (RegisteredFuseRules.ContainsKey(id))
			{
				Logger.LogWarning((object)$"Fuse Rules with ID {id} has already been registered.");
				return;
			}
			FuseR.FuseRulesTypeID = id;
			RegisteredFuseRules[id] = FuseR;
			Logger.LogMessage((object)$"Registered Fuse Rules: {((Object)FuseR).name} with ID: {id}");
		}

		public void RegisterLobbyCompat()
		{
			PluginHelper.RegisterPlugin("NoteBoxz.LethalMin", new Version("1.0.34"), (CompatibilityLevel)2, (VersionStrictness)3);
		}

		public static PikminAI AddCustomScriptToPikminAI(PikminAI script)
		{
			Type type = ((object)script).GetType();
			GameObject enemyPrefab = PikminEnemyType.enemyPrefab;
			PikminAI component = enemyPrefab.GetComponent<PikminAI>();
			PikminAI pikminAI = (PikminAI)(object)enemyPrefab.AddComponent(type);
			FieldInfo[] fields = typeof(PikminAI).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				fieldInfo.SetValue(pikminAI, fieldInfo.GetValue(component));
			}
			FieldInfo[] fields2 = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			FieldInfo[] array2 = fields2;
			foreach (FieldInfo fieldInfo2 in array2)
			{
				if (!(typeof(PikminAI).GetField(fieldInfo2.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null))
				{
					fieldInfo2.SetValue(pikminAI, fieldInfo2.GetValue(script));
				}
			}
			PikminEnemyType.enemyPrefab.GetComponent<PikminTypeResolver>().PikminAIs.Add(pikminAI);
			((Behaviour)pikminAI).enabled = false;
			Logger.LogInfo((object)("Added Custom Script: " + type.Name + " to PikminAI!"));
			return pikminAI;
		}

		public static void GeneratePikminTypeConfig(PikminType pikminType)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			if ((Object)(object)pikminType == (Object)null)
			{
				Logger.LogWarning((object)"Cannot generate config for null PikminType");
				return;
			}
			Logger.LogInfo((object)("Generating config file for Pikmin Type: " + pikminType.PikminName));
			string text = Path.Combine(Paths.ConfigPath, "Pikmin");
			Directory.CreateDirectory(text);
			string path = SanitizeFileName(pikminType.PikminName) + ".cfg";
			string text2 = Path.Combine(text, path);
			ConfigFile config = new ConfigFile(text2, true);
			FieldInfo[] fields = typeof(PikminType).GetFields(BindingFlags.Instance | BindingFlags.Public);
			string section = "General";
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				IEnumerable<HeaderAttribute> customAttributes = ((MemberInfo)fieldInfo).GetCustomAttributes<HeaderAttribute>();
				HeaderAttribute val = customAttributes.LastOrDefault();
				if (val != null)
				{
					section = val.header;
				}
				else if (!ShouldSkipField(fieldInfo))
				{
					if (!IsSupportedConfigType(fieldInfo.FieldType))
					{
						Logger.LogDebug((object)$"Skipping unsupported field type: {fieldInfo.Name} ({fieldInfo.FieldType})");
						continue;
					}
					IEnumerable<TooltipAttribute> customAttributes2 = ((MemberInfo)fieldInfo).GetCustomAttributes<TooltipAttribute>();
					string description = customAttributes2.FirstOrDefault()?.tooltip ?? ("Configuration for " + fieldInfo.Name);
					object value = fieldInfo.GetValue(pikminType);
					CreateAndBindConfigEntry(config, fieldInfo, pikminType, section, description, value);
				}
			}
			string directoryName = Path.GetDirectoryName(Path.GetDirectoryName(Paths.ConfigPath));
			string relativePath = Path.GetRelativePath(directoryName, text2);
			Logger.LogInfo((object)("Config file generated for Pikmin Type: " + pikminType.PikminName + " at BepInEx/" + relativePath));
		}

		private static bool ShouldSkipField(FieldInfo field)
		{
			HashSet<string> hashSet = new HashSet<string>
			{
				"PikminTypeID", "PiklopediaEntry", "modelRefernces", "ModelPrefab", "SoundPack", "SoundPackGenerations", "PikminGhostOverrideTexture", "PikminGhostOverrideModel", "PikminSproutOverrideMaterial", "SproutOverrideModel",
				"piklopediaVideo", "OverridePiklopediaNode", "OverridePiklopediaKeyword", "CustomTypeScript", "TargetOnion", "piklopediaDescription", "FavoredMoons", "FavoredMoonTags", "FavoredWeathers", "SpawnChanceMultiplier",
				"AvoidMoons", "AvoidMoonTags", "SpawnChanceDemultiplier"
			};
			IEnumerable<HideInInspector> customAttributes = ((MemberInfo)field).GetCustomAttributes<HideInInspector>();
			return hashSet.Contains(field.Name) || customAttributes.Any();
		}

		private static bool IsSupportedConfigType(Type type)
		{
			if (type == typeof(bool) || type == typeof(int) || type == typeof(float) || type == typeof(string))
			{
				return true;
			}
			if (type.IsEnum)
			{
				return true;
			}
			if (type == typeof(Vector2) || type == typeof(Vector3) || type == typeof(Color))
			{
				return true;
			}
			if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
			{
				Type type2 = type.GetGenericArguments()[0];
				return type2 == typeof(string) || type2 == typeof(int) || type2 == typeof(float) || type2 == typeof(bool) || type2 == typeof(Color) || type2 == typeof(Vector2) || type2 == typeof(Vector3) || type2.IsEnum;
			}
			if (type.IsArray)
			{
				Type elementType = type.GetElementType();
				return elementType == typeof(string) || elementType == typeof(int) || elementType == typeof(float) || elementType == typeof(bool) || elementType == typeof(Color) || elementType == typeof(Vector2) || elementType == typeof(Vector3) || elementType.IsEnum;
			}
			return false;
		}

		private static void CreateAndBindConfigEntry(ConfigFile config, FieldInfo field, PikminType pikminType, string section, string description, object currentValue)
		{
			Type fieldType = field.FieldType;
			try
			{
				Type type = typeof(ConfigItem<>).MakeGenericType(fieldType);
				object obj = Activator.CreateInstance(type, section, field.Name, currentValue, description, true, ConfigItemAuthority.Client, config, GetItemArgs(fieldType));
				if (obj != null)
				{
					FieldInfo field2 = type.GetField("InternalValue");
					if (field2 != null)
					{
						object value = field2.GetValue(obj);
						field.SetValue(pikminType, value);
						Logger.LogDebug((object)$"{field.Name} set to {value}");
					}
				}
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"Failed to create config entry for field {field.Name}: {arg}");
			}
		}

		private static void UpdatePikminTypeField(PikminType pikminType, FieldInfo field, object newValue)
		{
			try
			{
				field.SetValue(pikminType, newValue);
				Logger.LogDebug((object)$"Updated {pikminType.PikminName}.{field.Name} to: {newValue}");
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"Failed to update field {field.Name}: {arg}");
			}
		}

		private static string GetItemArgs(Type type)
		{
			if (type == typeof(float))
			{
				return "";
			}
			if (type.IsEnum)
			{
				return "";
			}
			return "";
		}

		internal static string SanitizeFileName(string fileName)
		{
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			char[] array = invalidFileNameChars;
			foreach (char oldChar in array)
			{
				fileName = fileName.Replace(oldChar, '_');
			}
			return fileName;
		}

		public static string NormalizeMoonName(string planetName)
		{
			if (string.IsNullOrEmpty(planetName))
			{
				return planetName;
			}
			if (CleanMoonNames != null && CleanMoonNames.InternalValue)
			{
				return Regex.Replace(planetName, "^\\d+[\\s\\-]*", "").Trim();
			}
			return planetName.Trim();
		}

		public static void LoadDefaultMoonConfigs()
		{
			GetOrCreateMoonSpawnConfig("Embrion", generateFile: false);
			GetOrCreateMoonSpawnConfig("Adamance", generateFile: false);
			GetOrCreateMoonSpawnConfig("Vow", generateFile: false);
		}

		public static void LoadDefaultWeatherConfigs()
		{
			GetOrCreateWeatherSpawnConfig("Rainy", generateFile: false);
			GetOrCreateWeatherSpawnConfig("Eclipsed", generateFile: false);
		}

		public static MoonSpawnConfig GetOrCreateMoonSpawnConfig(string normalizedMoonName, bool generateFile = true)
		{
			if (MoonSpawnConfigs.TryGetValue(normalizedMoonName, out MoonSpawnConfig value))
			{
				if (!generateFile || value.HasConfigFile)
				{
					return value;
				}
				MoonSpawnConfigs.Remove(normalizedMoonName);
			}
			int defaultMaxSpawns = -1;
			float defaultBaseMultiplier = 1f;
			List<string> defaultBlockedTypes = null;
			List<string> defaultAllowedTypes = null;
			List<string> defaultTypeMultipliers = null;
			switch (normalizedMoonName.ToLower())
			{
			case "embrion":
				defaultAllowedTypes = new List<string> { "Rock Pikmin" };
				break;
			case "adamance":
				defaultBaseMultiplier = 1.5f;
				break;
			case "vow":
				defaultBaseMultiplier = 1.25f;
				break;
			case "march":
				defaultBaseMultiplier = 1.25f;
				break;
			}
			MoonSpawnConfig moonSpawnConfig = new MoonSpawnConfig(normalizedMoonName, generateFile, defaultMaxSpawns, defaultBaseMultiplier, defaultBlockedTypes, defaultAllowedTypes, defaultTypeMultipliers);
			MoonSpawnConfigs[normalizedMoonName] = moonSpawnConfig;
			return moonSpawnConfig;
		}

		public static void GenerateAllMoonSpawnConfigs()
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return;
			}
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				string text = NormalizeMoonName(val.PlanetName);
				if (!string.IsNullOrEmpty(text))
				{
					GetOrCreateMoonSpawnConfig(text);
				}
			}
			Logger.LogInfo((object)$"Generated moon spawn config files for {MoonSpawnConfigs.Count} moons.");
		}

		public static WeatherSpawnConfig GetOrCreateWeatherSpawnConfig(string weatherName, bool generateFile = true)
		{
			if (WeatherSpawnConfigs.TryGetValue(weatherName, out WeatherSpawnConfig value))
			{
				if (!generateFile || value.HasConfigFile)
				{
					return value;
				}
				WeatherSpawnConfigs.Remove(weatherName);
			}
			float defaultBaseMultiplier = 1f;
			List<string> defaultTypeMultipliers = null;
			if (weatherName.Equals("Rainy", StringComparison.OrdinalIgnoreCase))
			{
				defaultBaseMultiplier = 1.25f;
			}
			if (weatherName.Equals("Eclipsed", StringComparison.OrdinalIgnoreCase))
			{
				defaultBaseMultiplier = 0.5f;
			}
			WeatherSpawnConfig weatherSpawnConfig = new WeatherSpawnConfig(weatherName, generateFile, defaultBaseMultiplier, defaultTypeMultipliers);
			WeatherSpawnConfigs[weatherName] = weatherSpawnConfig;
			return weatherSpawnConfig;
		}

		public static void GenerateAllWeatherSpawnConfigs()
		{
			string[] names = Enum.GetNames(typeof(LevelWeatherType));
			foreach (string weatherName in names)
			{
				GetOrCreateWeatherSpawnConfig(weatherName);
			}
			Logger.LogInfo((object)$"Generated weather spawn config files for {WeatherSpawnConfigs.Count} weather types.");
		}

		public static bool IsDependencyLoaded(string pluginGUID)
		{
			return Chainloader.PluginInfos.ContainsKey(pluginGUID);
		}

		public static bool GetLeaderViaID(ulong ClientID, out Leader leader)
		{
			leader = GetLeaderViaID(ClientID);
			return (Object)(object)leader != (Object)null;
		}

		public static PikminType GetPikminTypeByName(string name)
		{
			string name2 = name;
			return RegisteredPikminTypes.Values.FirstOrDefault((PikminType t) => t.PikminName == name2);
		}

		public static PikminType GetPikminTypeByID(int ID)
		{
			PikminType value;
			return RegisteredPikminTypes.TryGetValue(ID, out value) ? value : null;
		}

		public static Leader? GetLeaderViaID(ulong ClientID)
		{
			foreach (Leader leader in PikminManager.instance.Leaders)
			{
				if (((NetworkBehaviour)leader.Controller).OwnerClientId == ClientID && PikChecks.IsPlayerConnected(leader.Controller))
				{
					return leader;
				}
			}
			return null;
		}

		public static OnionType GetOnionTypeByID(int ID)
		{
			return RegisteredOnionTypes[ID];
		}

		public static bool IsValidPikminTypeID(int ID)
		{
			return RegisteredPikminTypes.ContainsKey(ID);
		}

		internal void NetcodePatcher()
		{
			Type[] typesWithErrorHandling = GetTypesWithErrorHandling();
			Type[] array = typesWithErrorHandling;
			foreach (Type type in array)
			{
				try
				{
					MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
					MethodInfo[] array2 = methods;
					foreach (MethodInfo methodInfo in array2)
					{
						try
						{
							object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
							if (customAttributes.Length != 0)
							{
								methodInfo.Invoke(null, null);
							}
						}
						catch (FileNotFoundException arg)
						{
							Logger.LogDebug((object)$"Skipping method {methodInfo.Name} due to missing dependency: {arg}");
						}
						catch (Exception arg2)
						{
							Logger.LogWarning((object)$"Error processing method {methodInfo.Name}: {arg2}");
						}
					}
				}
				catch (Exception arg3)
				{
					Logger.LogWarning((object)$"Error processing type {type.FullName}: {arg3}");
				}
			}
		}

		internal static void Patch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("NoteBoxz.LethalMin");
			}
			Logger.LogDebug((object)"Patching...");
			try
			{
				Type[] typesWithErrorHandling = GetTypesWithErrorHandling();
				Type[] array = typesWithErrorHandling;
				foreach (Type type in array)
				{
					if (type.Namespace == "LethalMin.Library")
					{
						LibraryTypes.Add(type);
						continue;
					}
					if (type.Namespace == "LethalMin.ConfigPatches")
					{
						ConfigPatchTypes.Add(type);
						continue;
					}
					CompatClassAttribute customAttribute = type.GetCustomAttribute<CompatClassAttribute>();
					if (customAttribute != null)
					{
						string modGUID = customAttribute.ModGUID;
						if (!IsDependencyLoaded(modGUID))
						{
							continue;
						}
						Logger.LogMessage((object)(modGUID + " detected, Patching " + type.FullName));
					}
					try
					{
						Harmony.PatchAll(type);
					}
					catch (Exception ex)
					{
						Logger.LogError((object)$"Error patching type {type.FullName}: {ex}");
						if (ex.InnerException != null)
						{
							Logger.LogError((object)("Inner exception: " + ex.InnerException.Message));
						}
					}
				}
			}
			catch (Exception ex2)
			{
				Logger.LogError((object)$"Error during patching process: {ex2}");
				if (ex2.InnerException != null)
				{
					Logger.LogError((object)("Inner exception: " + ex2.InnerException.Message));
				}
			}
			Logger.LogDebug((object)"Finished patching!");
		}

		internal static void PatchConfigPatches()
		{
			Logger.LogDebug((object)"Patching config-conditional patches...");
			foreach (Type configPatchType in ConfigPatchTypes)
			{
				bool flag = false;
				if (configPatchType == typeof(ShotgunItemPatch))
				{
					flag = (bool)ExcludePikminFromShotgun || (bool)ExcludePuffminFromShotgun;
					if (!flag)
					{
						Logger.LogDebug((object)("Skipping " + configPatchType.FullName + ": no shotgun exclusion configs are enabled"));
						continue;
					}
				}
				else
				{
					flag = true;
				}
				if (!flag)
				{
					continue;
				}
				try
				{
					Harmony? harmony = Harmony;
					if (harmony != null)
					{
						harmony.PatchAll(configPatchType);
					}
					Logger.LogDebug((object)("Patched config patch: " + configPatchType.FullName));
				}
				catch (Exception ex)
				{
					Logger.LogError((object)$"Error patching config patch type {configPatchType.FullName}: {ex}");
					if (ex.InnerException != null)
					{
						Logger.LogError((object)("Inner exception: " + ex.InnerException.Message));
					}
				}
			}
			Logger.LogDebug((object)"Finished patching config-conditional patches!");
		}

		public static void PatchLibraryTypes()
		{
			Logger.LogMessage((object)"LethalMin Recived Library Call! Patching Library Types...");
			foreach (Type libraryType in LibraryTypes)
			{
				try
				{
					Harmony? harmony = Harmony;
					if (harmony != null)
					{
						harmony.PatchAll(libraryType);
					}
				}
				catch (Exception ex)
				{
					Logger.LogError((object)$"Error patching type {libraryType.FullName}: {ex}");
					if (ex.InnerException != null)
					{
						Logger.LogError((object)("Inner exception: " + ex.InnerException.Message));
					}
				}
			}
		}

		internal static Type[] GetTypesWithErrorHandling()
		{
			try
			{
				return Assembly.GetExecutingAssembly().GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				Logger.LogWarning((object)"ReflectionTypeLoadException caught while getting types. Some types will be skipped.");
				Exception[] loaderExceptions = ex.LoaderExceptions;
				foreach (Exception ex2 in loaderExceptions)
				{
					Logger.LogDebug((object)("Loader Exception: " + ex2.Message));
					if (ex2 is FileNotFoundException ex3)
					{
						Logger.LogDebug((object)("Could not load file: " + ex3.FileName));
					}
				}
				return ex.Types.Where((Type t) => t != null).ToArray();
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"Unexpected error while getting types: {arg}");
				return new Type[0];
			}
		}

		internal static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}

		public void BindConfigs()
		{
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_133d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1371: Unknown result type (might be due to invalid IL or missing references)
			//IL_1473: Unknown result type (might be due to invalid IL or missing references)
			//IL_14a7: Unknown result type (might be due to invalid IL or missing references)
			UseCommasInVectorConfigs = ((BaseUnityPlugin)this).Config.Bind<bool>("Advanced", "Use Commas In Vector Configs", false, "Whether or not to use commas in vector configs (true = x,y,z | false = x y z)");
			MaxPikmin = new ConfigItem<int>("General", "Max Pikmin", 100, "The maximun ammount of pikmin that can be spawned in at once before being despawned or sent to the onion", needsRestart: false, ConfigItemAuthority.Host);
			FriendlyFire = new ConfigItem<bool>("General", "Friendly Fire", defaultValue: false, "Allows for leaders to kill pikmin in their squad", needsRestart: false, ConfigItemAuthority.Client);
			FriendlyerFire = new ConfigItem<bool>("General", "Friendlyer Fire", defaultValue: true, "Prevents leaders from killing pikmin that are not in their squad", needsRestart: false, ConfigItemAuthority.Client);
			SkipPluckAnimation = new ConfigItem<bool>("General", "Skip Pluck Animation", defaultValue: false, "Skip the player's pluck animation when plucking a pikmin", needsRestart: false, ConfigItemAuthority.Client);
			SkipPluckAnimation.OnValueChanged += delegate
			{
				UpdateSyncedConfigs();
			};
			WhistleVolume = new ConfigItem<float>("General", "Whistle Volume", 1f, "The volume of the whistle sound effect (0.0 - 1.0)", needsRestart: false, ConfigItemAuthority.Local, "slider(0,1)");
			AllowOnionsToRevivePlayers = new ConfigItem<bool>("General", "Allow Onions To Revive Players", defaultValue: true, "Allow onions to revive players when they are killed", needsRestart: false, ConfigItemAuthority.Host);
			AllowOnionToReviveMaskeds = new ConfigItem<bool>("General", "Allow Onions To Revive Masked Players", defaultValue: true, "Allow onions to revive masked players when they are killed", needsRestart: false, ConfigItemAuthority.Host);
			AllowOnionFusing = new ConfigItem<bool>("General", "Allow Onion Fusing", defaultValue: true, "Allow onions to fuse together after a round", needsRestart: false, ConfigItemAuthority.Host);
			ConvertEnemyBodiesToItems = new ConfigItem<bool>("General", "Convert Enemy Bodies To Items", defaultValue: true, "Convert enemy bodies to items for pikmin to take to the onion", needsRestart: false, ConfigItemAuthority.Client);
			ShowOnionsInSpace = new ConfigItem<bool>("General", "Show Onions In Space", defaultValue: true, "Show onions next to the ship in space when in space (requires ship windows mod)", needsRestart: false, ConfigItemAuthority.Local);
			SpaceOnionPosition = new ConfigItem<Vector3>("General", "Space Onion Position", new Vector3(-5f, 0f, 20f), "The position of the onion in space", needsRestart: false, ConfigItemAuthority.Local);
			DontUpdateSpaceOnionPosition = new ConfigItem<bool>("General", "Dont Update Space Onion Position", defaultValue: false, "Used for debugging, dont lock the space onion position's to the config position", needsRestart: false, ConfigItemAuthority.Local);
			MakeItemsScanable = new ConfigItem<bool>("General", "Make Items Scanable", defaultValue: true, "Makes pikmin items scanable", needsRestart: false, ConfigItemAuthority.Local);
			MakePikminScanable = new ConfigItem<bool>("General", "Make Pikmin Scanable", defaultValue: true, "Makes pikmin scanable", needsRestart: false, ConfigItemAuthority.Local);
			MakeSproutsScanable = new ConfigItem<bool>("General", "Make Sprouts Scanable", defaultValue: true, "Makes sprouts scanable", needsRestart: false, ConfigItemAuthority.Local);
			TriggerLandmines = new ConfigItem<bool>("General", "Trigger Landmines", defaultValue: true, "Make pikmin trigger landmines", needsRestart: false, ConfigItemAuthority.Local);
			GlobalGhostSFX = new ConfigItem<bool>("General", "Global Ghost SFX", defaultValue: true, "When true, you will be able to hear Pikmin Ghosts no matter where you are on the moon.", needsRestart: false, ConfigItemAuthority.Local);
			HideResultsWhenMoreThanFour = new ConfigItem<bool>("General", "Hide Custom Reports With More Players", defaultValue: true, "Hide the Pikmin raised counters for every player when there are more than four players in the game. To prevent names from being covered.", needsRestart: false, ConfigItemAuthority.Local);
			DieInPlayerDeathZone = new ConfigItem<bool>("General", "Pikmin Die In Player Death Zones", defaultValue: false, "Makes it so pikmin dies when enter death zones that kill players. For example the catwalk jump pit.", needsRestart: false, ConfigItemAuthority.Client);
			TakeItemsFromPikmin = new ConfigItem<bool>("General", "Take Items From Pikmin", defaultValue: false, "Allows players to take items from pikmin", needsRestart: false, ConfigItemAuthority.Client);
			TeleportAroundPlayerWhenEnteringBuilding = new ConfigItem<bool>("General", "Teleport Pikmin Around Player When Entering Building", defaultValue: true, "Teleports pikmin around the player when entering the building to reduce lag when entering", needsRestart: false, ConfigItemAuthority.Client);
			ExcludePikminFromShotgun = new ConfigItem<bool>("General", "Exclude Pikmin From Shotgun", defaultValue: true, "Prevents Pikmin from absorbing shotgun shots", needsRestart: true, ConfigItemAuthority.Client);
			ExcludePuffminFromShotgun = new ConfigItem<bool>("General", "Exclude Puffmin From Shotgun", defaultValue: false, "Prevents Puffmin from absorbing shotgun shots", needsRestart: true, ConfigItemAuthority.Client);
			PikminScale = new ConfigItem<float>("Appearances", "Pikmin Scale", 1f, "The scale of the pikmin", needsRestart: false, ConfigItemAuthority.Local);
			SproutScale = new ConfigItem<float>("Appearances", "Sprout Scale", 1f, "The scale of the sprout", needsRestart: false, ConfigItemAuthority.Local);
			CurWhistPack = new ConfigItem<int>("Appearances", "Whistle Sound Index", 0, "press ] while holding a whistle to cycle through the available sounds (0-3)", needsRestart: false, ConfigItemAuthority.Client);
			BigEyesEnabled = new ConfigItem<bool>("Appearances", "Big Eyes Enabled", defaultValue: false, "Enables the Big Eyes from the HeyPikmin generation.", needsRestart: false, ConfigItemAuthority.Local);
			BigEyesEnabled.OnValueChanged += delegate
			{
				UpdateCurrentGeneration(1, ref PikminModelGeneration);
			};
			BigEyesEnabled.OnValueChanged += delegate
			{
				UpdateCurrentGeneration(7, ref PuffminGeneration);
			};
			PikminScanNodeColorType = new ConfigItem<PikminScanNodeProperties.ScanNodeType>("Appearances", "Pikmin Scan Node Color Type", PikminScanNodeProperties.ScanNodeType.Enemy, "The type of color to use for the scan node (Point of Intrest: Blue, Enemy: Red, Item: Green)", needsRestart: false, ConfigItemAuthority.Local);
			DefaultGeneration = new ConfigItem<PikminGeneration>("Generations", "Default Generation", PikminGeneration.Pikmin4, "The default generation to use when no specific generation is set", needsRestart: false, ConfigItemAuthority.Local);
			DefaultGeneration.OnValueChanged += delegate
			{
				UpdateDefaultGeneration();
			};
			PikminModelGeneration = new ConfigItem<CfgPikminGeneration>("Generations", "Pikmin Model Generation", CfgPikminGeneration.Default, "The generation to use for Pikmin models", needsRestart: false, ConfigItemAuthority.Local);
			PikminModelGeneration.OnValueChanged += delegate
			{
				UpdateCurrentGeneration(1, ref PikminModelGeneration);
			};
			SproutModelGeneration = new ConfigItem<CfgPikminGeneration>("Generations", "Sprout Model Generation", CfgPikminGeneration.Default, "The generation to use for Sprout models", needsRestart: false, ConfigItemAuthority.Local);
			SproutModelGeneration.OnValueChanged += delegate
			{
				UpdateCurrentGeneration(2, ref SproutModelGeneration);
			};
			PikminSoundGeneration = new ConfigItem<CfgPikminGeneration>("Generations", "Pikmin Sound Generation", CfgPikminGeneration.Default, "The generation to use for Pikmin sounds", needsRestart: false, ConfigItemAuthority.Local);
			PikminSoundGeneration.OnValueChanged += delegate
			{
				UpdateCurrentGeneration(3, ref PikminSoundGeneration);
			};
			SoulSpriteGeneration = new ConfigItem<CfgPikminGeneration>("Generations", "Soul Sprite Generation", CfgPikminGeneration.Default, "The generation to use for Pikmin Souls", needsRestart: false, ConfigItemAuthority.Local);
			SoulSpriteGeneration.OnValueChanged += delegate
			{
				UpdateCurrentGeneration(4, ref SoulSpriteGeneration);
			};
			OnionModelGeneration = new ConfigItem<CfgPikminGeneration>("Generations", "Onion Model Generation", CfgPikminGeneration.Default, "The generation to use for Onion models", needsRestart: false, ConfigItemAuthority.Local);
			OnionModelGeneration.OnValueChanged += delegate
			{
				UpdateCurrentGeneration(5, ref OnionModelGeneration);
			};
			OnionItemModelGeneration = new ConfigItem<CfgPikminGeneration>("Generations", "Onion Item Model Generation", CfgPikminGeneration.Default, "The generation to use for Onion Item models", needsRestart: false, ConfigItemAuthority.Local);
			OnionItemModelGeneration.OnValueChanged += delegate
			{
				UpdateCurrentGeneration(6, ref OnionItemModelGeneration);
			};
			PuffminGeneration = new ConfigItem<CfgPikminGeneration>("Generations", "Puffmin Generation", CfgPikminGeneration.Default, "The generation to use for Puffmin Models", needsRestart: false, ConfigItemAuthority.Local);
			PuffminGeneration.OnValueChanged += delegate
			{
				UpdateCurrentGeneration(7, ref PuffminGeneration);
			};
			ThrowAction = new ConfigItem<string>("Controls", "Throw Button", "<Keyboard>/r", "", needsRestart: true, ConfigItemAuthority.Local);
			ThrowCancelAction = new ConfigItem<string>("Controls", "Throw Cancel Button", "<Keyboard>/q", "", needsRestart: true, ConfigItemAuthority.Local);
			SwitchForwardAction = new ConfigItem<string>("Controls", "Switch Forward Button", "<Keyboard>/3", "", needsRestart: true, ConfigItemAuthority.Local);
			SwitchBackwawrdsAction = new ConfigItem<string>("Controls", "Switch Backwards Button (hold)", "<Keyboard>/2", "", needsRestart: true, ConfigItemAuthority.Local);
			WhisleAction = new ConfigItem<string>("Controls", "Whistle Button", "<Mouse>/leftButton", "", needsRestart: true, ConfigItemAuthority.Local);
			DismissAction = new ConfigItem<string>("Controls", "Dismiss Button", "<Mouse>/middleButton", "", needsRestart: true, ConfigItemAuthority.Local);
			SwitchWhistleSoundAction = new ConfigItem<string>("Controls", "Switch Whistle Sound Button", "<Keyboard>/]", "", needsRestart: true, ConfigItemAuthority.Local);
			ChargeAction = new ConfigItem<string>("Controls", "Charge Button", "<Keyboard>/4", "", needsRestart: true, ConfigItemAuthority.Local);
			GlowmobAction = new ConfigItem<string>("Controls", "Glowmob Button (hold)", "<Keyboard>/4", "", needsRestart: true, ConfigItemAuthority.Local);
			OnionHudSpeedAction = new ConfigItem<string>("Controls", "Onion Menu 10-withdraw Button", "<Keyboard>/shift", "", needsRestart: true, ConfigItemAuthority.Local);
			IndoorSpawnChance = new ConfigItem<float>("Spawning", "Indoor Pikmin Spawn Chance", 0.05f, "The odds for pikmin that spawn inside to spawn", needsRestart: false, ConfigItemAuthority.Host, "slider(0,1)");
			OutdoorSpawnChance = new ConfigItem<float>("Spawning", "Outdoor Pikmin Spawn Chance", 0.35f, "The odds for pikmin that spawn outside to spawn", needsRestart: false, ConfigItemAuthority.Host, "slider(0,1)");
			OnionSpawnChance = new ConfigItem<float>("Spawning", "Onion Spawn Chance", 0.45f, "The odds for an onion to spawn", needsRestart: false, ConfigItemAuthority.Host, "slider(0,1)");
			UseBetaOnionSpawnSystem = new ConfigItem<bool>("Spawning", "Use Beta Onion Spawn System", defaultValue: false, "Instead of calculating a spawn center and offsetting, onions are placed at the Nth closest valid outdoor AI node to the ship (1st onion = closest valid node, 2nd onion = next closest, etc.). Avoids clipping into the ship or spawning on rocks.", needsRestart: false, ConfigItemAuthority.Host);
			AvoidWaterForOnionSpawning = new ConfigItem<bool>("Spawning", "Avoid Water For Onion Spawning", defaultValue: true, "When enabled, onion spawn node candidates that sit inside a water trigger are filtered out. Has no effect on Flooded weather moons. Falls back to all nodes if no dry candidates remain.", needsRestart: false, ConfigItemAuthority.Host);
			AvoidBehindShipForOnionSpawning = new ConfigItem<bool>("Spawning", "Avoid Behind-Ship Locations For Onion Spawning", defaultValue: true, "When enabled, onion spawn node candidates that are behind the ship relative to the sun's direction are filtered out. Falls back to all nodes if no non-behind candidates remain.", needsRestart: false, ConfigItemAuthority.Host);
			UseLCSpawnSystem = new ConfigItem<bool>("Spawning", "Use LC Spawn System", defaultValue: true, "Have Pikmin be spawnable using LC's spawning system, the will result on rare occasition for pikmin to randomly spawn on the map", needsRestart: false, ConfigItemAuthority.Host);
			UsePowerLVForSprouts = new ConfigItem<bool>("Spawning", "Use Power Level For Sprouts", defaultValue: false, "Use the Power Level of a moon to determine sprout count (overrides SpawnChance configs for sprout spawning pikmin)", needsRestart: false, ConfigItemAuthority.Host, "slider(0,1)");
			EnableTypeSpawnFalloff = new ConfigItem<bool>("Spawning", "Enable Wild Spawn Falloff", defaultValue: true, "When enabled, wild pikmin spawn rates are reduced based on how many of that type are stored in onions. Types without an associated onion are not affected and may benefit from group spawning instead.", needsRestart: false, ConfigItemAuthority.Host);
			TypeSpawnFalloffMaxCount = new ConfigItem<int>("Spawning", "Wild Spawn Falloff Max Count", 100, "The number of pikmin of a given type stored in onions at which the falloff reaches 1.0 (that type stops spawning in the wild entirely). Values below this scale proportionally.", needsRestart: false, ConfigItemAuthority.Host);
			TypeSpawnFalloffExponent = new ConfigItem<float>("Spawning", "Wild Spawn Falloff Exponent", 1f, "Controls the falloff curve shape. 1.0 = linear (25 stored → 0.25 falloff), values below 1 make falloff kick in faster, values above 1 make it kick in slower.", needsRestart: false, ConfigItemAuthority.Host, "slider(0.1,3)");
			NoOnionGroupSpawnThreshold = new ConfigItem<float>("Spawning", "No-Onion Group Spawn Threshold", 0.5f, "When the average falloff of indoor (or outdoor) onion-holding pikmin types reaches this value, pikmin types without onions (bulbmin) that have CanGroupSpawnWhenFalloffHigh enabled may spawn in groups.", needsRestart: false, ConfigItemAuthority.Host, "slider(0,1)");
			ScaleTypeSpawnAmountBySuppressedTypes = new ConfigItem<bool>("Spawning", "Scale Wild Spawn Amount By Suppressed Types", defaultValue: true, "When enabled, total wild map spawn volume scales down as more onion-backed pikmin types reach high falloff. This helps avoid late-game over-abundance of a single low-falloff type.", needsRestart: false, ConfigItemAuthority.Host);
			SuppressedTypeFalloffThreshold = new ConfigItem<float>("Spawning", "Suppressed Type Falloff Threshold", 0.7f, "A type is considered suppressed when its current falloff is at or above this value. Suppressed type ratio is used to scale total spawn amount.", needsRestart: false, ConfigItemAuthority.Host, "slider(0,1)");
			OutdoorSpawnAmountScaleAtMaxSuppressed = new ConfigItem<float>("Spawning", "Outdoor Spawn Amount Scale At Max Suppressed Types", 0.25f, "Multiplier applied to outdoor map-spawn volume when all onion-backed outdoor types are suppressed. Example: 0.25 means roughly 40 becomes 10.", needsRestart: false, ConfigItemAuthority.Host, "slider(0.05,1)");
			IndoorSpawnAmountScaleAtMaxSuppressed = new ConfigItem<float>("Spawning", "Indoor Spawn Amount Scale At Max Suppressed Types", 1f, "Multiplier applied to indoor map-spawn volume when all onion-backed indoor types are suppressed. Keep at 1.0 to leave indoor/no-onion types effectively unchanged.", needsRestart: false, ConfigItemAuthority.Host, "slider(0.05,1)");
			AttackBlacklistConfig = new ConfigItem<List<string>>("Pikmin Behavior", "Attack Blacklist", new List<string>
			{
				"Docile Locust Bees", "Manticoil", "Red Locust Bees", "Blob", "Nemo", "InternNPC", "BellCrab", "Nancy", "Transporter", "Janior",
				"Peace Keeper", "Guardsman", "Tornado", "FireStorm", "Hurricane", "Cabinet"
			}, "The list of enemy names that pikmin won't attack", needsRestart: true, ConfigItemAuthority.Client);
			ItemBlacklistConfig = new ConfigItem<List<string>>("Pikmin Behavior", "Item Blacklist", new List<string>(), "The list of item names that pikmin won't pick up", needsRestart: true, ConfigItemAuthority.Client);
			EnemyBodyConvertBlacklistConfig = new ConfigItem<List<string>>("Pikmin Behavior", "Enemy Body Convert Blacklist", new List<string> { "Flowerman", "GiantKiwi" }, "The list of enemy names that the mod won't convert into items", needsRestart: true, ConfigItemAuthority.Host);
			UseExitsWhenCarryingItems = new ConfigItem<bool>("Pikmin Behavior", "Use Exits When Carrying Items", defaultValue: true, "Whether or not Pikmin can path outside directly to the ship when inside, or just leave it at an exit when inside", needsRestart: false, ConfigItemAuthority.Client);
			PikminFollowMode = new ConfigItem<PfollowMode>("Pikmin Behavior", "Follow Mode", PfollowMode.LegacyBehind, "The way pikmin follow their leader.\r\n                 New: Makes the pikmin follow the leader in a formation simular to the pikmin games\r\n                 LegacyBehind Makes the pikmin looesly follow the leader\r\n                 LegacyFollow Makes the pikmin path directly to the leader (can be buggy)", needsRestart: false, ConfigItemAuthority.Client);
			PikminFollowMode.OnValueChanged += delegate
			{
				SetFollowMode();
			};
			TimeFallingFailSafe = new ConfigItem<float>("Pikmin Behavior", "Time Falling Fail Safe", 10f, "The time it takes for a pikmin to be concitered falling infintly and teleport back into bounds", needsRestart: false, ConfigItemAuthority.Client);
			CarryNonScrapItemsToCompany = new ConfigItem<bool>("Pikmin Behavior", "Carry Non-Scrap Items To Company", defaultValue: false, "Makes it so pikmin carry Non-Scrap items (Flashlights, Keys, etc.) to the company counter instead of the ship", needsRestart: false, ConfigItemAuthority.Client);
			IgnoreNonScrapItemsToCompany = new ConfigItem<bool>("Pikmin Behavior", "Ignore Non-Scrap Items On Company", defaultValue: false, "Makes it so pikmin ignore Non-Scrap items (Flashlights, Keys, etc.) on the company entirely", needsRestart: false, ConfigItemAuthority.Client);
			TakeItemsToOnionOnCompany = new ConfigItem<bool>("Pikmin Behavior", "Take Items To Onion On Company", defaultValue: true, "Whether or not items can be taken to the onion on company", needsRestart: false, ConfigItemAuthority.Client);
			TakeItemsToTheCar = new ConfigItem<bool>("Pikmin Behavior", "Take Items To The Car", defaultValue: true, "Whether or not Pikmin can take items to the car", needsRestart: false, ConfigItemAuthority.Client);
			TakeItemsToTheOnion = new ConfigItem<bool>("Pikmin Behavior", "Take Items To The Onion", defaultValue: true, "Whether or not Pikmin can take items to the onion", needsRestart: true, ConfigItemAuthority.Client);
			DisperseWhenDismissed = new ConfigItem<bool>("Pikmin Behavior", "Disperse When Dismissed", defaultValue: false, "Whether or not Pikmin disperse into groups when dismissed", needsRestart: false, ConfigItemAuthority.Client);
			AllowOnBBtobeGrabed = new ConfigItem<bool>("Pikmin Behavior", "Allow On BoomBox to be Grabbed", defaultValue: false, "Allows Pikmin to grab the boombox when it is on", needsRestart: false, ConfigItemAuthority.Client);
			DismissWindownTime = new ConfigItem<float>("Pikmin Behavior", "Dismiss Windown Time", 2f, "The ammount of seconds to wait before pikmin can be assigned a leader again after being dismissed", needsRestart: false, ConfigItemAuthority.Client);
			NonWaterResistantAvoidWater = new ConfigItem<bool>("Pikmin Behavior", "Non-Water Resistant Pikmin Avoid Water", defaultValue: false, "Whether or not non-water resistant pikmin avoid water when pathing has no effect on flooded moons", needsRestart: false, ConfigItemAuthority.Client);
			WildPikminCarry = new ConfigItem<bool>("Pikmin Behavior", "Wild Pikmin Can Carry Items", defaultValue: false, "Whether or not wild pikmin can carry items", needsRestart: false, ConfigItemAuthority.Host);
			WildPikminAttack = new ConfigItem<bool>("Pikmin Behavior", "Wild Pikmin Can Attack Enemies", defaultValue: true, "Whether or not wild pikmin can attack enemies", needsRestart: false, ConfigItemAuthority.Host);
			WildPikminAttackDamage = new ConfigItem<bool>("Pikmin Behavior", "Wild Pikmin Attack Does Damage", defaultValue: false, "Whether or not wild pikmin's attacks do damage", needsRestart: false, ConfigItemAuthority.Host);
			WildPikminNoDeath = new ConfigItem<bool>("Pikmin Behavior", "Wild Pikmin Dont Die", defaultValue: true, "Whether or not wild pikmin can die", needsRestart: false, ConfigItemAuthority.Host);
			UseConfigsForEnemies = new ConfigItem<bool>("Enemy Behavior", "Use Enemy Configs", defaultValue: false, "Enables the use of enemy configs", needsRestart: false, ConfigItemAuthority.Client);
			ClaySurgeon_SnipCooldown = new ConfigItem<float>("Enemy Behavior", "Barber Snip Cooldown", 1f, "How long the Barber waits between snipping Pikmin (in seconds)", needsRestart: false, ConfigItemAuthority.Client);
			ClaySurgeon_SnipLimit = new ConfigItem<int>("Enemy Behavior", "Barber Snip Limit", 3, "Maximum number of Pikmin that can be snipped by a Barber at once", needsRestart: false, ConfigItemAuthority.Client);
			Crawler_BiteCooldown = new ConfigItem<float>("Enemy Behavior", "Thumper Bite Cooldown", 2f, "How long the Thumper waits between biting Pikmin (in seconds)", needsRestart: false, ConfigItemAuthority.Client);
			Crawler_BiteLimit = new ConfigItem<int>("Enemy Behavior", "Thumper Bite Limit", 3, "Maximum number of Pikmin that can be bitten by a Thumper at once", needsRestart: false, ConfigItemAuthority.Client);
			SandSpider_BiteCooldown = new ConfigItem<float>("Enemy Behavior", "Bunker Spider Bite Cooldown", 3.5f, "How long the Bunker Spider waits between biting Pikmin (in seconds)", needsRestart: false, ConfigItemAuthority.Client);
			SandSpider_BiteLimit = new ConfigItem<int>("Enemy Behavior", "Bunker Spider Bite Limit", 2, "Maximum number of Pikmin that can be bitten by a Bunker Spider at once", needsRestart: false, ConfigItemAuthority.Client);
			HoarderBug_BiteCooldown = new ConfigItem<float>("Enemy Behavior", "Hoarding Bug Bite Cooldown", 3f, "How long the Hoarding Bug waits between biting Pikmin (in seconds)", needsRestart: false, ConfigItemAuthority.Client);
			HoarderBug_BiteLimit = new ConfigItem<int>("Enemy Behavior", "Hoarding Bug Bite Limit", 1, "Maximum number of Pikmin that can be bitten by a Hoarding Bug at once", needsRestart: false, ConfigItemAuthority.Client);
			HoarderBug_AggroWhenPikminTakesItem = new ConfigItem<bool>("Enemy Behavior", "Hoarding Bug Aggro When Item Taken", defaultValue: true, "Whether Hoarding Bugs becomes aggressive when Pikmin take their items", needsRestart: false, ConfigItemAuthority.Client);
			MouthDog_BiteCooldown = new ConfigItem<float>("Enemy Behavior", "Eyeless Dog Bite Cooldown", 5.5f, "How long the Eyeless Dog waits between biting Pikmin (in seconds)", needsRestart: false, ConfigItemAuthority.Client);
			MouthDog_BiteLimit = new ConfigItem<int>("Enemy Behavior", "Eyeless Dog Bite Limit", 7, "Maximum number of Pikmin that can be bitten by a Eyeless Dog at once", needsRestart: false, ConfigItemAuthority.Client);
			Blob_TrapPikmin = new ConfigItem<bool>("Enemy Behavior", "Hydrogere Traps Pikmin", defaultValue: true, "Whether the Hydrogere can trap Pikmin inside it", needsRestart: false, ConfigItemAuthority.Client);
			Blob_KillPikmin = new ConfigItem<bool>("Enemy Behavior", "Hydrogere Kills Pikmin", defaultValue: false, "Whether the Hydrogere can kill trapped Pikmin", needsRestart: false, ConfigItemAuthority.Client);
			RedLocustBees_ZapCooldown = new ConfigItem<float>("Enemy Behavior", "Circuit Bees Zap Cooldown", 0.25f, "How long the Circuit Bees wait between zapping Pikmin (in seconds)", needsRestart: false, ConfigItemAuthority.Client);
			RedLocustBees_ZapPikmin = new ConfigItem<bool>("Enemy Behavior", "Circuit Bees Zap Pikmin", defaultValue: true, "Whether Circuit Bees can zap Pikmin", needsRestart: false, ConfigItemAuthority.Client);
			RedLocustBees_KillPikmin = new ConfigItem<bool>("Enemy Behavior", "Circuit Bees Kill Pikmin", defaultValue: false, "Whether Circuit Bees can kill Pikmin", needsRestart: false, ConfigItemAuthority.Client);
			CaveDweller_BiteCooldown = new ConfigItem<float>("Enemy Behavior", "Maneater Bite Cooldown", 1f, "How long the Maneater waits between biting Pikmin (in seconds)", needsRestart: false, ConfigItemAuthority.Client);
			CaveDweller_BiteLimit = new ConfigItem<int>("Enemy Behavior", "Maneater Bite Limit", 7, "Maximum number of Pikmin that can be bitten by a Maneater at once", needsRestart: false, ConfigItemAuthority.Client);
			CaveDweller_AllowCarry = new ConfigItem<bool>("Enemy Behavior", "Maneater Allow Carry", defaultValue: true, "Whether the Maneater can be carried by Pikmin", needsRestart: false, ConfigItemAuthority.Client);
			CaveDweller_AttackAsBaby = new ConfigItem<bool>("Enemy Behavior", "Maneater Attack As Baby", defaultValue: false, "Whether the Pikmin can attack the Maneater as a baby", needsRestart: false, ConfigItemAuthority.Client);
			RadMech_GrabLimmit = new ConfigItem<int>("Enemy Behavior", "Old Bird Grab Limit", 10, "Maximum number of Pikmin that can be grabbed by a Old Bird at once", needsRestart: false, ConfigItemAuthority.Client);
			RadMech_GrabsPikmin = new ConfigItem<bool>("Enemy Behavior", "Old Bird Grabs Pikmin", defaultValue: true, "Whether the Old Bird can grab and torch Pikmin", needsRestart: false, ConfigItemAuthority.Client);
			ForestGiant_GrabLimit = new ConfigItem<int>("Enemy Behavior", "Forest Keeper Grab Limit", 25, "Maximum number of Pikmin that can be grabbed by a Forest Keeper at once", needsRestart: false, ConfigItemAuthority.Client);
			ForestGiant_GrabsPikmin = new ConfigItem<bool>("Enemy Behavior", "Forest Keeper Grabs Pikmin", defaultValue: true, "Whether the Forest Keeper can grab and eat Pikmin", needsRestart: false, ConfigItemAuthority.Client);
			Jester_BiteCooldown = new ConfigItem<float>("Enemy Behavior", "Jester