Decompiled source of DrifterBossGrab v1.8.0

plugins/DrifterBossGrab.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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 DrifterBossGrabMod.API;
using DrifterBossGrabMod.Balance;
using DrifterBossGrabMod.Config;
using DrifterBossGrabMod.Config.UI;
using DrifterBossGrabMod.Core;
using DrifterBossGrabMod.Features;
using DrifterBossGrabMod.Input;
using DrifterBossGrabMod.Networking;
using DrifterBossGrabMod.Patches;
using DrifterBossGrabMod.ProperSave;
using DrifterBossGrabMod.ProperSave.Core;
using DrifterBossGrabMod.ProperSave.Data;
using DrifterBossGrabMod.ProperSave.Serializers;
using DrifterBossGrabMod.ProperSave.Serializers.Plugins;
using DrifterBossGrabMod.ProperSave.Spawning;
using DrifterBossGrabMod.UI;
using EntityStates;
using EntityStates.CaptainSupplyDrop;
using EntityStates.Drifter;
using EntityStates.Drifter.Bag;
using EntityStates.SurvivorPod;
using HarmonyLib;
using KinematicCharacterController;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using Rewired;
using Rewired.Data;
using Rewired.Data.Mapping;
using RiskOfOptions;
using RiskOfOptions.Components.Options;
using RiskOfOptions.Components.Panel;
using RiskOfOptions.Components.RuntimePrefabs;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RiskOfOptions.Resources;
using RoR2;
using RoR2.HudOverlay;
using RoR2.Networking;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Rewired_Core")]
[assembly: IgnoresAccessChecksTo("RoR2")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DrifterBossGrab")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.8.0.0")]
[assembly: AssemblyInformationalVersion("1.8.0")]
[assembly: AssemblyProduct("DrifterBossGrab")]
[assembly: AssemblyTitle("DrifterBossGrab")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.8.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace DrifterBossGrabMod
{
	public class PluginConfig
	{
		private static PluginConfig _instance = null;

		public static readonly Dictionary<string, HudElementType[]> HudSettingToSubTab = new Dictionary<string, HudElementType[]>
		{
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.HUD_FILTER.CHOICE"] = new HudElementType[7]
			{
				HudElementType.All,
				HudElementType.MainSlot,
				HudElementType.SideSlots,
				HudElementType.WeightIcon,
				HudElementType.DamagePreview,
				HudElementType.CapacityUI,
				HudElementType.StatsPanel
			},
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ENABLE_HUD_EDITOR.CHECKBOX"] = new HudElementType[7]
			{
				HudElementType.All,
				HudElementType.MainSlot,
				HudElementType.SideSlots,
				HudElementType.WeightIcon,
				HudElementType.DamagePreview,
				HudElementType.CapacityUI,
				HudElementType.StatsPanel
			},
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ENABLE_CAROUSEL_HUD.CHECKBOX"] = new HudElementType[2]
			{
				HudElementType.MainSlot,
				HudElementType.SideSlots
			},
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.VERTICAL_SPACING.FLOAT_FIELD"] = new HudElementType[2]
			{
				HudElementType.MainSlot,
				HudElementType.SideSlots
			},
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ANIMATION_DURATION.FLOAT_FIELD"] = new HudElementType[2]
			{
				HudElementType.MainSlot,
				HudElementType.SideSlots
			},
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.MAIN_SLOT_X_OFFSET.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.MainSlot },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.MAIN_SLOT_Y_OFFSET.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.MainSlot },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.MAIN_SLOT_SCALE.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.MainSlot },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.MAIN_SLOT_OPACITY.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.MainSlot },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_ICON_(MAIN).CHECKBOX"] = new HudElementType[1] { HudElementType.MainSlot },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_WEIGHT_ICON_(MAIN).CHECKBOX"] = new HudElementType[1] { HudElementType.MainSlot },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_NAME_(MAIN).CHECKBOX"] = new HudElementType[1] { HudElementType.MainSlot },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_HEALTH_(MAIN).CHECKBOX"] = new HudElementType[1] { HudElementType.MainSlot },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_SLOT_#_(MAIN).CHECKBOX"] = new HudElementType[1] { HudElementType.MainSlot },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SIDE_SLOT_X_OFFSET.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.SideSlots },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SIDE_SLOT_Y_OFFSET.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.SideSlots },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SIDE_SLOT_SCALE.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.SideSlots },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SIDE_SLOT_OPACITY.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.SideSlots },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_ICON_(SIDE).CHECKBOX"] = new HudElementType[1] { HudElementType.SideSlots },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_WEIGHT_ICON_(SIDE).CHECKBOX"] = new HudElementType[1] { HudElementType.SideSlots },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_NAME_(SIDE).CHECKBOX"] = new HudElementType[1] { HudElementType.SideSlots },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_HEALTH_(SIDE).CHECKBOX"] = new HudElementType[1] { HudElementType.SideSlots },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_SLOT_#_(SIDE).CHECKBOX"] = new HudElementType[1] { HudElementType.SideSlots },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.USE_NEW_WEIGHT_ICON.CHECKBOX"] = new HudElementType[1] { HudElementType.WeightIcon },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.WEIGHT_DISPLAY_MODE.CHOICE"] = new HudElementType[1] { HudElementType.WeightIcon },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SCALE_WEIGHT_COLOR.CHECKBOX"] = new HudElementType[1] { HudElementType.WeightIcon },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_TOTAL_MASS.CHECKBOX"] = new HudElementType[1] { HudElementType.WeightIcon },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_OVERENCUMBERED_ICON.CHECKBOX"] = new HudElementType[1] { HudElementType.WeightIcon },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ENABLE_DAMAGE_PREVIEW.CHECKBOX"] = new HudElementType[1] { HudElementType.DamagePreview },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.DAMAGE_PREVIEW_COLOR.COLOR"] = new HudElementType[1] { HudElementType.DamagePreview },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ENABLE_CAPACITY_UI.CHECKBOX"] = new HudElementType[1] { HudElementType.CapacityUI },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CAPACITY_UI_X_POS.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.CapacityUI },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CAPACITY_UI_Y_POS.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.CapacityUI },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CAPACITY_UI_SCALE.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.CapacityUI },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ENABLE_SEPARATORS.CHECKBOX"] = new HudElementType[1] { HudElementType.CapacityUI },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.GRADIENT_INTENSITY.STEP_SLIDER"] = new HudElementType[1] { HudElementType.CapacityUI },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.GRADIENT_COLOR_START.COLOR"] = new HudElementType[1] { HudElementType.CapacityUI },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.GRADIENT_COLOR_MID.COLOR"] = new HudElementType[1] { HudElementType.CapacityUI },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.GRADIENT_COLOR_END.COLOR"] = new HudElementType[1] { HudElementType.CapacityUI },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.OVERENCUMBRANCE_START.COLOR"] = new HudElementType[1] { HudElementType.CapacityUI },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.OVERENCUMBRANCE_MID.COLOR"] = new HudElementType[1] { HudElementType.CapacityUI },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.OVERENCUMBRANCE_END.COLOR"] = new HudElementType[1] { HudElementType.CapacityUI },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ENABLE_STATS_PANEL.CHECKBOX"] = new HudElementType[1] { HudElementType.StatsPanel },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.STATS_PANEL_X_POS.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.StatsPanel },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.STATS_PANEL_Y_POS.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.StatsPanel },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.STATS_PANEL_SCALE.FLOAT_FIELD"] = new HudElementType[1] { HudElementType.StatsPanel },
			["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.STATS_PANEL_COLOR.COLOR"] = new HudElementType[1] { HudElementType.StatsPanel }
		};

		public static readonly Dictionary<string, BalanceSubTabType[]> BalanceSettingToSubTab = new Dictionary<string, BalanceSubTabType[]>
		{
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.MASS_CAPACITY_FORMULA.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Formulas },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.FLAG.CHOICE"] = new BalanceSubTabType[1] { BalanceSubTabType.Multipliers },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.MULTIPLIER.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Multipliers },
			["COM.PWDCAT.DRIFTERBOSSGRAB.CHARACTER_FLAGS.ALL_FLAG_MULTIPLIER.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Multipliers },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.MAX_OVERENCUMBRANCE_(%).FLOAT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Limits },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.STATE_CALCULATION.CHOICE"] = new BalanceSubTabType[1] { BalanceSubTabType.Formulas },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.MASS_MULTIPLIER_FORMULA.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Formulas },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.SPEED_PENALTY_FORMULA.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Formulas },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.BAG_VISUAL_SIZE_CAP.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Limits },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.BAGGED_ENTITY_MASS_CAP.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Limits },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.AOE_DAMAGE.CHOICE"] = new BalanceSubTabType[1] { BalanceSubTabType.Limits },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.GRAB_RANGE_MULTIPLIER.STEP_SLIDER"] = new BalanceSubTabType[1] { BalanceSubTabType.Multipliers },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.BREAKOUT_TIME_MULTIPLIER.STEP_SLIDER"] = new BalanceSubTabType[1] { BalanceSubTabType.Multipliers },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.MAX_HITS_BEFORE_BREAKOUT.INT_SLIDER"] = new BalanceSubTabType[1] { BalanceSubTabType.Limits },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.MAX_LAUNCH_SPEED.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Limits },
			["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.SLAM_DAMAGE_FORMULA.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Formulas }
		};

		internal ICachedValue<HashSet<string>> _blacklistCache;

		internal ICachedValue<HashSet<string>> _blacklistCacheWithClones;

		internal ICachedValue<HashSet<string>> _recoveryBlacklistCache;

		internal ICachedValue<HashSet<string>> _recoveryBlacklistCacheWithClones;

		internal ICachedValue<HashSet<string>> _persistenceBlacklistCache;

		internal ICachedValue<HashSet<string>> _persistenceBlacklistCacheWithClones;

		internal ICachedValue<HashSet<string>> _grabbableComponentTypesCache;

		internal ICachedValue<HashSet<string>> _grabbableKeywordBlacklistCache;

		private readonly List<IGrabbingStrategy> _grabbingStrategies = new List<IGrabbingStrategy>
		{
			new BossGrabbingStrategy(),
			new NPCGrabbingStrategy(),
			new EnvironmentGrabbingStrategy()
		};

		private bool _isBagScaleCapInfinite;

		private bool _isMassCapInfinite;

		private bool _isAddedCapacityInfinite;

		private bool _isMaxLaunchSpeedInfinite;

		private float _parsedMassCap = 700f;

		private float _parsedBagScaleCap = 1f;

		private float _parsedMaxLaunchSpeed = 30f;

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

		public ConfigEntry<bool> EnableBossGrabbing { get; private set; }

		public ConfigEntry<bool> EnableNPCGrabbing { get; private set; }

		public ConfigEntry<bool> EnableEnvironmentGrabbing { get; private set; }

		public ConfigEntry<bool> EnableLockedObjectGrabbing { get; private set; }

		public ConfigEntry<ProjectileGrabbingMode> ProjectileGrabbingMode { get; private set; }

		public ConfigEntry<string> BodyBlacklist { get; private set; }

		public ConfigEntry<string> RecoveryObjectBlacklist { get; private set; }

		public ConfigEntry<string> GrabbableComponentTypes { get; private set; }

		public ConfigEntry<string> GrabbableKeywordBlacklist { get; private set; }

		public ConfigEntry<float> SearchRadiusMultiplier { get; private set; }

		public ConfigEntry<bool> EnableDebugLogs { get; private set; }

		public ConfigEntry<bool> EnableCombatDirectorPatches { get; private set; }

		public ConfigEntry<ComponentChooserSortMode> ComponentChooserSortModeEntry { get; private set; }

		public ConfigEntry<ComponentChooserDummy> ComponentChooserDummyEntry { get; private set; }

		public ConfigEntry<bool> EnableConfigSync { get; private set; }

		public ConfigEntry<PresetType> SelectedPreset { get; private set; }

		public ConfigEntry<PresetType> LastSelectedPreset { get; private set; }

		public ConfigEntry<bool> EnableRecoveryFeature { get; private set; }

		public ConfigEntry<EnemyRecoveryMode> EnemyRecoveryMode { get; private set; }

		public ConfigEntry<bool> RecoverBaggedBosses { get; private set; }

		public ConfigEntry<bool> RecoverBaggedNPCs { get; private set; }

		public ConfigEntry<bool> RecoverBaggedEnvironmentObjects { get; private set; }

		public ConfigEntry<bool> BottomlessBagEnabled { get; private set; }

		public ConfigEntry<bool> EnableStockRefreshClamping { get; private set; }

		public ConfigEntry<bool> EnableSuccessiveGrabStockRefresh { get; private set; }

		public ConfigEntry<float> CycleCooldown { get; private set; }

		public ConfigEntry<bool> PlayAnimationOnCycle { get; private set; }

		public ConfigEntry<bool> EnableMouseWheelScrolling { get; private set; }

		public ConfigEntry<bool> InverseMouseWheelScrolling { get; private set; }

		public ConfigEntry<bool> AutoPromoteMainSeat { get; private set; }

		public ConfigEntry<bool> PrioritizeMainSeat { get; private set; }

		public ConfigEntry<bool> EnableObjectPersistence { get; private set; }

		public ConfigEntry<bool> EnableAutoGrab { get; private set; }

		public ConfigEntry<bool> PersistBaggedBosses { get; private set; }

		public ConfigEntry<bool> PersistBaggedNPCs { get; private set; }

		public ConfigEntry<bool> PersistBaggedEnvironmentObjects { get; private set; }

		public ConfigEntry<string> PersistenceBlacklist { get; private set; }

		public ConfigEntry<float> AutoGrabDelay { get; private set; }

		public ConfigEntry<bool> EnableCarouselHUD { get; private set; }

		public ConfigEntry<float> CarouselSpacing { get; private set; }

		public ConfigEntry<float> CarouselAnimationDuration { get; private set; }

		public ConfigEntry<HudElementType> SelectedHudElement { get; private set; }

		public ConfigEntry<float> CenterSlotX { get; private set; }

		public ConfigEntry<float> CenterSlotY { get; private set; }

		public ConfigEntry<float> CenterSlotScale { get; private set; }

		public ConfigEntry<float> CenterSlotOpacity { get; private set; }

		public ConfigEntry<bool> CenterSlotShowIcon { get; private set; }

		public ConfigEntry<bool> CenterSlotShowWeightIcon { get; private set; }

		public ConfigEntry<bool> CenterSlotShowName { get; private set; }

		public ConfigEntry<bool> CenterSlotShowHealthBar { get; private set; }

		public ConfigEntry<bool> CenterSlotShowSlotNumber { get; private set; }

		public ConfigEntry<float> SideSlotX { get; private set; }

		public ConfigEntry<float> SideSlotY { get; private set; }

		public ConfigEntry<float> SideSlotScale { get; private set; }

		public ConfigEntry<float> SideSlotOpacity { get; private set; }

		public ConfigEntry<bool> SideSlotShowIcon { get; private set; }

		public ConfigEntry<bool> SideSlotShowWeightIcon { get; private set; }

		public ConfigEntry<bool> SideSlotShowName { get; private set; }

		public ConfigEntry<bool> SideSlotShowHealthBar { get; private set; }

		public ConfigEntry<bool> SideSlotShowSlotNumber { get; private set; }

		public ConfigEntry<bool> EnableBaggedObjectInfo { get; private set; }

		public ConfigEntry<float> BaggedObjectInfoX { get; private set; }

		public ConfigEntry<float> BaggedObjectInfoY { get; private set; }

		public ConfigEntry<float> BaggedObjectInfoScale { get; private set; }

		public ConfigEntry<Color> BaggedObjectInfoColor { get; private set; }

		public ConfigEntry<bool> UseNewWeightIcon { get; private set; }

		public ConfigEntry<WeightDisplayMode> WeightDisplayMode { get; private set; }

		public ConfigEntry<bool> ScaleWeightColor { get; private set; }

		public ConfigEntry<bool> ShowTotalMassOnWeightIcon { get; private set; }

		public ConfigEntry<bool> ShowOverencumberIcon { get; private set; }

		public ConfigEntry<bool> EnableDamagePreview { get; private set; }

		public ConfigEntry<Color> DamagePreviewColor { get; private set; }

		public ConfigEntry<bool> EnableMassCapacityUI { get; private set; }

		public ConfigEntry<float> MassCapacityUIPositionX { get; private set; }

		public ConfigEntry<float> MassCapacityUIPositionY { get; private set; }

		public ConfigEntry<float> MassCapacityUIScale { get; private set; }

		public ConfigEntry<bool> EnableSeparators { get; private set; }

		public ConfigEntry<float> GradientIntensity { get; private set; }

		public ConfigEntry<Color> CapacityGradientColorStart { get; private set; }

		public ConfigEntry<Color> CapacityGradientColorMid { get; private set; }

		public ConfigEntry<Color> CapacityGradientColorEnd { get; private set; }

		public ConfigEntry<Color> OverencumbranceGradientColorStart { get; private set; }

		public ConfigEntry<Color> OverencumbranceGradientColorMid { get; private set; }

		public ConfigEntry<Color> OverencumbranceGradientColorEnd { get; private set; }

		public ConfigEntry<bool> IsHudEditorEnabled { get; private set; }

		public ConfigEntry<bool> EnableBalance { get; private set; }

		public ConfigEntry<AoEDamageMode> AoEDamageDistribution { get; private set; }

		public ConfigEntry<float> BreakoutTimeMultiplier { get; private set; }

		public ConfigEntry<int> MaxSmacks { get; private set; }

		public ConfigEntry<string> BagScaleCap { get; private set; }

		public ConfigEntry<string> MassCap { get; private set; }

		public ConfigEntry<string> MaxLaunchSpeed { get; private set; }

		public ConfigEntry<StateCalculationMode> StateCalculationMode { get; private set; }

		public ConfigEntry<float> OverencumbranceMax { get; private set; }

		public ConfigEntry<string> SlotScalingFormula { get; private set; }

		public ConfigEntry<string> MassCapacityFormula { get; private set; }

		public ConfigEntry<string> MovespeedPenaltyFormula { get; private set; }

		public ConfigEntry<string> SlamDamageFormula { get; private set; }

		public ConfigEntry<string> EliteFlagMultiplier { get; private set; }

		public ConfigEntry<string> BossFlagMultiplier { get; private set; }

		public ConfigEntry<string> ChampionFlagMultiplier { get; private set; }

		public ConfigEntry<string> PlayerFlagMultiplier { get; private set; }

		public ConfigEntry<string> MinionFlagMultiplier { get; private set; }

		public ConfigEntry<string> DroneFlagMultiplier { get; private set; }

		public ConfigEntry<string> MechanicalFlagMultiplier { get; private set; }

		public ConfigEntry<string> VoidFlagMultiplier { get; private set; }

		public ConfigEntry<string> AllFlagMultiplier { get; private set; }

		public ConfigEntry<CharacterFlagType> SelectedFlag { get; private set; }

		public ConfigEntry<string> SelectedFlagMultiplier { get; private set; }

		public ConfigEntry<BalanceSubTabType> SelectedBalanceSubTab { get; private set; }

		public bool IsBagScaleCapInfinite => _isBagScaleCapInfinite;

		public bool IsMassCapInfinite => _isMassCapInfinite;

		public bool IsAddedCapacityInfinite => _isAddedCapacityInfinite;

		public bool IsMaxLaunchSpeedInfinite => _isMaxLaunchSpeedInfinite;

		public float ParsedMassCap => _parsedMassCap;

		public float ParsedBagScaleCap => _parsedBagScaleCap;

		public float ParsedMaxLaunchSpeed => _parsedMaxLaunchSpeed;

		private static void InitBalanceConfig(ConfigFile cfg)
		{
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			Instance.EnableBalance = cfg.Bind<bool>("Balance", "EnableBalance", false, "Enable mass and penalty systems.");
			Instance.MassCapacityFormula = cfg.Bind<string>("Balance", "MassCapacityFormula", "C * MC", "Formula for mass capacity limit. Supported: H (Max HP), L (Level), C (Stocks), MC (Mass Cap config), S (Stage).");
			Instance.MovespeedPenaltyFormula = cfg.Bind<string>("Balance", "MovespeedPenaltyFormula", "0", "Formula for movement speed penalty. Supported: T (Total Mass), M (Mass Cap limit), C (Total Cap), H (Max HP), L (Level), MC (Mass Cap config), S (Stage).");
			Instance.SlamDamageFormula = cfg.Bind<string>("Balance", "SlamDamageFormula", "BASE_COEF + (MASS_SCALING * BM / MC)", "Formula for slam damage coefficient. Supported: BASE_COEF, MASS_SCALING, BM (Bagged Mass), MC (Mass Cap).");
			Instance.StateCalculationMode = cfg.Bind<StateCalculationMode>("Balance", "StateCalculationMode", DrifterBossGrabMod.StateCalculationMode.Current, "State calculation mode for stats.");
			Instance.AoEDamageDistribution = cfg.Bind<AoEDamageMode>("Balance", "AoEDamageDistribution", AoEDamageMode.Full, "Mode for AoE damage distribution.");
			Instance.OverencumbranceMax = cfg.Bind<float>("Balance", "OverencumbranceMax", 100f, "Maximum overencumbrance percentage.");
			Instance.BreakoutTimeMultiplier = cfg.Bind<float>("Balance", "BreakoutTimeMultiplier", 1f, "Multiplier for breakout time.");
			Instance.MaxSmacks = cfg.Bind<int>("Balance", "MaxSmacks", 3, new ConfigDescription("Hits before breakout.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			Instance.MaxLaunchSpeed = cfg.Bind<string>("Balance", "MaxLaunchSpeed", "30", "Maximum launch speed for breakout.");
			Instance.BagScaleCap = cfg.Bind<string>("Balance", "BagScaleCap", "1", "Bag visual size cap.");
			Instance.MassCap = cfg.Bind<string>("Balance", "MassCap", "700", "Mass cap for caught entities.");
			WireBalanceEventHandlers();
		}

		private static void WireBalanceEventHandlers()
		{
			Instance.MassCapacityFormula.SettingChanged += delegate
			{
				string text3 = FormulaParser.Validate(Instance.MassCapacityFormula.Value);
				if (text3 != null)
				{
					Log.Warning("[PluginConfig] Invalid MassCapacityFormula: " + text3);
				}
				DrifterBagController[] array7 = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController bagController3 in array7)
				{
					CapacityScalingSystem.RecalculateCapacity(bagController3);
				}
			};
			Instance.StateCalculationMode.SettingChanged += delegate
			{
				DrifterBagController[] array6 = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController bagController2 in array6)
				{
					CapacityScalingSystem.RecalculateState(bagController2);
				}
			};
			Instance.MovespeedPenaltyFormula.SettingChanged += delegate
			{
				string text2 = FormulaParser.Validate(Instance.MovespeedPenaltyFormula.Value);
				if (text2 != null)
				{
					Log.Warning("[PluginConfig] Invalid MovespeedPenaltyFormula: " + text2);
				}
				DrifterBagController[] array5 = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController bagController in array5)
				{
					CapacityScalingSystem.RecalculatePenalty(bagController);
				}
			};
			Instance.BagScaleCap.SettingChanged += delegate
			{
				Instance.RefreshCachedConfigStrings();
				DrifterBagController[] array4 = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController controller2 in array4)
				{
					BagPassengerManager.ForceRecalculateMass(controller2);
				}
			};
			Instance.MassCap.SettingChanged += delegate
			{
				Instance.RefreshCachedConfigStrings();
				DrifterBagController[] array3 = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController controller in array3)
				{
					BagPassengerManager.ForceRecalculateMass(controller);
				}
			};
			Instance.SlamDamageFormula.SettingChanged += delegate
			{
				string text = FormulaParser.Validate(Instance.SlamDamageFormula.Value);
				if (text != null)
				{
					Log.Warning("[PluginConfig] Invalid SlamDamageFormula: " + text);
				}
				DamagePreviewOverlay[] array = Object.FindObjectsByType<DamagePreviewOverlay>((FindObjectsSortMode)0);
				DamagePreviewOverlay[] array2 = array;
				foreach (DamagePreviewOverlay damagePreviewOverlay in array2)
				{
					damagePreviewOverlay.InvalidateCache();
				}
			};
		}

		private static void InitBottomlessBagConfig(ConfigFile cfg)
		{
			Instance.BottomlessBagEnabled = cfg.Bind<bool>("Bottomless Bag", "EnableBottomlessBag", false, "Store multiple objects and cycle through them.");
			Instance.EnableStockRefreshClamping = cfg.Bind<bool>("Bottomless Bag", "EnableStockRefreshClamping", false, "Clamp stock refresh to empty slots.");
			Instance.EnableSuccessiveGrabStockRefresh = cfg.Bind<bool>("Bottomless Bag", "EnableSuccessiveGrabStockRefresh", false, "Refresh stock only after a successful grab at 0.");
			Instance.CycleCooldown = cfg.Bind<float>("Bottomless Bag", "CycleCooldown", 0.2f, "Cooldown between passenger cycles.");
			Instance.PlayAnimationOnCycle = cfg.Bind<bool>("Bottomless Bag", "PlayAnimationOnCycle", false, "Play grab animation when cycling.");
			Instance.EnableMouseWheelScrolling = cfg.Bind<bool>("Bottomless Bag", "EnableMouseWheelScrolling", true, "Cycle passengers via mouse wheel.");
			Instance.InverseMouseWheelScrolling = cfg.Bind<bool>("Bottomless Bag", "InverseMouseWheelScrolling", false, "Invert mouse wheel cycle direction.");
			Instance.AutoPromoteMainSeat = cfg.Bind<bool>("Bottomless Bag", "AutoPromoteMainSeat", false, "Auto-promote next object when main is removed.");
			Instance.PrioritizeMainSeat = cfg.Bind<bool>("Bottomless Bag", "PrioritizeMainSeat", false, "New objects go to main seat first.");
			Instance.SlotScalingFormula = cfg.Bind<string>("Bottomless Bag", "SlotScalingFormula", "C + 2", "Formula for total bag slots. Supported: H (Max HP), L (Level), C (Stocks), MC (Mass Cap), S (Stage). Set to INF for infinite.");
			if (Instance.BottomlessBagEnabled.Value && !Instance.EnableCarouselHUD.Value)
			{
				Instance.EnableCarouselHUD.Value = true;
			}
			WireBottomlessBagEventHandlers();
		}

		private static void WireBottomlessBagEventHandlers()
		{
			Instance.BottomlessBagEnabled.SettingChanged += delegate
			{
				if (Instance.BottomlessBagEnabled.Value && !Instance.EnableCarouselHUD.Value)
				{
					Instance.EnableCarouselHUD.Value = true;
				}
			};
			Instance.SlotScalingFormula.SettingChanged += delegate
			{
				Instance.RefreshCachedConfigStrings();
				string text = FormulaParser.Validate(Instance.SlotScalingFormula.Value);
				if (text != null)
				{
					Log.Warning("[PluginConfig] Invalid SlotScalingFormula: " + text);
				}
				DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController bagController in array)
				{
					CapacityScalingSystem.RecalculateCapacity(bagController);
					CapacityScalingSystem.RecalculateState(bagController);
				}
			};
		}

		private static void InitCharacterFlagsConfig(ConfigFile cfg)
		{
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_014f: Expected O, but got Unknown
			Instance.EliteFlagMultiplier = cfg.Bind<string>("Character Flags", "EliteFlagMultiplier", "1", "Mass multiplier for Elite entities. Supported: B (Base Mass), H (Max HP), BH (Base Max HP), L (Level), C (Utility Stock Count), S (Stage Number), MC (Mass Capacity).");
			Instance.BossFlagMultiplier = cfg.Bind<string>("Character Flags", "BossFlagMultiplier", "1", "Mass multiplier for Boss entities. Supported: B (Base Mass), H (Max HP), BH (Base Max HP), L (Level), C (Utility Stock Count), S (Stage Number), MC (Mass Capacity).");
			Instance.ChampionFlagMultiplier = cfg.Bind<string>("Character Flags", "ChampionFlagMultiplier", "1", "Mass multiplier for Champion entities. Supported: B (Base Mass), H (Max HP), BH (Base Max HP), L (Level), C (Utility Stock Count), S (Stage Number), MC (Mass Capacity).");
			Instance.PlayerFlagMultiplier = cfg.Bind<string>("Character Flags", "PlayerFlagMultiplier", "1", "Mass multiplier for Player entities. Supported: B (Base Mass), H (Max HP), BH (Base Max HP), L (Level), C (Utility Stock Count), S (Stage Number), MC (Mass Capacity).");
			Instance.MinionFlagMultiplier = cfg.Bind<string>("Character Flags", "MinionFlagMultiplier", "1", "Mass multiplier for Minion entities. Supported: B (Base Mass), H (Max HP), BH (Base Max HP), L (Level), C (Utility Stock Count), S (Stage Number), MC (Mass Capacity).");
			Instance.DroneFlagMultiplier = cfg.Bind<string>("Character Flags", "DroneFlagMultiplier", "1", "Mass multiplier for Drone entities. Supported: B (Base Mass), H (Max HP), BH (Base Max HP), L (Level), C (Utility Stock Count), S (Stage Number), MC (Mass Capacity).");
			Instance.MechanicalFlagMultiplier = cfg.Bind<string>("Character Flags", "MechanicalFlagMultiplier", "1", "Mass multiplier for Mechanical entities. Supported: B (Base Mass), H (Max HP), BH (Base Max HP), L (Level), C (Utility Stock Count), S (Stage Number), MC (Mass Capacity).");
			Instance.VoidFlagMultiplier = cfg.Bind<string>("Character Flags", "VoidFlagMultiplier", "1", "Mass multiplier for Void entities. Supported: B (Base Mass), H (Max HP), BH (Base Max HP), L (Level), C (Utility Stock Count), S (Stage Number), MC (Mass Capacity).");
			Instance.AllFlagMultiplier = cfg.Bind<string>(new ConfigDefinition("Character Flags", "all Flag Multiplier"), "1", new ConfigDescription("Universal multiplier for all enemies. Supported: B (Base Mass), H (Max HP), BH (Base Max HP), L (Level), C (Utility Stock Count), S (Stage Number), MC (Mass Capacity).", (AcceptableValueBase)null, Array.Empty<object>()));
			Instance.SelectedFlag = cfg.Bind<CharacterFlagType>("Hidden", "SelectedFlag", CharacterFlagType.All, "Select which flag to modify.");
			Instance.SelectedFlagMultiplier = cfg.Bind<string>("Hidden", "FlagMultiplier", "1", "Mass multiplier for selected flag. Supported: B (Base Mass), H (Max HP), BH (Base Max HP), L (Level), C (Utility Stock Count), S (Stage Number), MC (Mass Capacity).");
			Instance.SelectedBalanceSubTab = cfg.Bind<BalanceSubTabType>("Hidden", "SelectedBalanceSubTab", BalanceSubTabType.All, "Select which Balance settings group to view.");
			CharacterFlagType value = Instance.SelectedFlag.Value;
			ConfigEntry<string> flagMultiplierConfig = GetFlagMultiplierConfig(value);
			if (flagMultiplierConfig != null)
			{
				Instance.SelectedFlagMultiplier.Value = flagMultiplierConfig.Value;
			}
			WireCharacterFlagEventHandlers();
		}

		private static void WireCharacterFlagEventHandlers()
		{
			Instance.EliteFlagMultiplier.SettingChanged += delegate
			{
				string text9 = FormulaParser.Validate(Instance.EliteFlagMultiplier.Value);
				if (text9 != null)
				{
					Log.Warning("[PluginConfig] Invalid EliteFlagMultiplier: " + text9);
				}
				DrifterBagController[] array8 = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController controller8 in array8)
				{
					BagPassengerManager.ForceRecalculateMass(controller8);
				}
			};
			Instance.BossFlagMultiplier.SettingChanged += delegate
			{
				string text8 = FormulaParser.Validate(Instance.BossFlagMultiplier.Value);
				if (text8 != null)
				{
					Log.Warning("[PluginConfig] Invalid BossFlagMultiplier: " + text8);
				}
				DrifterBagController[] array7 = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController controller7 in array7)
				{
					BagPassengerManager.ForceRecalculateMass(controller7);
				}
			};
			Instance.ChampionFlagMultiplier.SettingChanged += delegate
			{
				string text7 = FormulaParser.Validate(Instance.ChampionFlagMultiplier.Value);
				if (text7 != null)
				{
					Log.Warning("[PluginConfig] Invalid ChampionFlagMultiplier: " + text7);
				}
				DrifterBagController[] array6 = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController controller6 in array6)
				{
					BagPassengerManager.ForceRecalculateMass(controller6);
				}
			};
			Instance.PlayerFlagMultiplier.SettingChanged += delegate
			{
				string text6 = FormulaParser.Validate(Instance.PlayerFlagMultiplier.Value);
				if (text6 != null)
				{
					Log.Warning("[PluginConfig] Invalid PlayerFlagMultiplier: " + text6);
				}
				DrifterBagController[] array5 = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController controller5 in array5)
				{
					BagPassengerManager.ForceRecalculateMass(controller5);
				}
			};
			Instance.MinionFlagMultiplier.SettingChanged += delegate
			{
				string text5 = FormulaParser.Validate(Instance.MinionFlagMultiplier.Value);
				if (text5 != null)
				{
					Log.Warning("[PluginConfig] Invalid MinionFlagMultiplier: " + text5);
				}
				DrifterBagController[] array4 = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController controller4 in array4)
				{
					BagPassengerManager.ForceRecalculateMass(controller4);
				}
			};
			Instance.DroneFlagMultiplier.SettingChanged += delegate
			{
				string text4 = FormulaParser.Validate(Instance.DroneFlagMultiplier.Value);
				if (text4 != null)
				{
					Log.Warning("[PluginConfig] Invalid DroneFlagMultiplier: " + text4);
				}
				DrifterBagController[] array3 = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController controller3 in array3)
				{
					BagPassengerManager.ForceRecalculateMass(controller3);
				}
			};
			Instance.MechanicalFlagMultiplier.SettingChanged += delegate
			{
				string text3 = FormulaParser.Validate(Instance.MechanicalFlagMultiplier.Value);
				if (text3 != null)
				{
					Log.Warning("[PluginConfig] Invalid MechanicalFlagMultiplier: " + text3);
				}
				DrifterBagController[] array2 = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController controller2 in array2)
				{
					BagPassengerManager.ForceRecalculateMass(controller2);
				}
			};
			Instance.VoidFlagMultiplier.SettingChanged += delegate
			{
				string text2 = FormulaParser.Validate(Instance.VoidFlagMultiplier.Value);
				if (text2 != null)
				{
					Log.Warning("[PluginConfig] Invalid VoidFlagMultiplier: " + text2);
				}
				DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0);
				foreach (DrifterBagController controller in array)
				{
					BagPassengerManager.ForceRecalculateMass(controller);
				}
			};
			Instance.SelectedFlagMultiplier.SettingChanged += delegate
			{
				string text = FormulaParser.Validate(Instance.SelectedFlagMultiplier.Value);
				if (text != null)
				{
					Log.Warning("[PluginConfig] Invalid FlagMultiplier formula: " + text);
				}
				else
				{
					CharacterFlagType value3 = Instance.SelectedFlag.Value;
					string value4 = Instance.SelectedFlagMultiplier.Value;
					switch (value3)
					{
					case CharacterFlagType.Elite:
						Instance.EliteFlagMultiplier.Value = value4;
						break;
					case CharacterFlagType.Boss:
						Instance.BossFlagMultiplier.Value = value4;
						break;
					case CharacterFlagType.Champion:
						Instance.ChampionFlagMultiplier.Value = value4;
						break;
					case CharacterFlagType.Player:
						Instance.PlayerFlagMultiplier.Value = value4;
						break;
					case CharacterFlagType.Minion:
						Instance.MinionFlagMultiplier.Value = value4;
						break;
					case CharacterFlagType.Drone:
						Instance.DroneFlagMultiplier.Value = value4;
						break;
					case CharacterFlagType.Mechanical:
						Instance.MechanicalFlagMultiplier.Value = value4;
						break;
					case CharacterFlagType.Void:
						Instance.VoidFlagMultiplier.Value = value4;
						break;
					case CharacterFlagType.All:
						Instance.AllFlagMultiplier.Value = value4;
						break;
					}
				}
			};
			Instance.SelectedFlag.SettingChanged += delegate
			{
				CharacterFlagType value = Instance.SelectedFlag.Value;
				string value2 = "0";
				switch (value)
				{
				case CharacterFlagType.Elite:
					value2 = Instance.EliteFlagMultiplier.Value;
					break;
				case CharacterFlagType.Boss:
					value2 = Instance.BossFlagMultiplier.Value;
					break;
				case CharacterFlagType.Champion:
					value2 = Instance.ChampionFlagMultiplier.Value;
					break;
				case CharacterFlagType.Player:
					value2 = Instance.PlayerFlagMultiplier.Value;
					break;
				case CharacterFlagType.Minion:
					value2 = Instance.MinionFlagMultiplier.Value;
					break;
				case CharacterFlagType.Drone:
					value2 = Instance.DroneFlagMultiplier.Value;
					break;
				case CharacterFlagType.Mechanical:
					value2 = Instance.MechanicalFlagMultiplier.Value;
					break;
				case CharacterFlagType.Void:
					value2 = Instance.VoidFlagMultiplier.Value;
					break;
				case CharacterFlagType.All:
					value2 = Instance.AllFlagMultiplier.Value;
					break;
				}
				Instance.SelectedFlagMultiplier.Value = value2;
			};
		}

		private static void InitGeneralConfig(ConfigFile cfg)
		{
			Instance.SelectedPreset = cfg.Bind<PresetType>("General", "SelectedPreset", PresetType.Intended, "Preset to load. Changes are auto-applied.");
			Instance.LastSelectedPreset = cfg.Bind<PresetType>("Hidden", "LastSelectedPreset", PresetType.Intended, "Internal tracker of the last applied preset.");
			Instance.EnableBossGrabbing = cfg.Bind<bool>("General", "EnableBossGrabbing", true, "Allow grabbing bosses.");
			Instance.EnableNPCGrabbing = cfg.Bind<bool>("General", "EnableNPCGrabbing", false, "Allow grabbing normally-ungrabbable NPCs.");
			Instance.EnableEnvironmentGrabbing = cfg.Bind<bool>("General", "EnableEnvironmentGrabbing", false, "Allow grabbing environment objects.");
			Instance.EnableLockedObjectGrabbing = cfg.Bind<bool>("General", "EnableLockedObjectGrabbing", false, "Allow grabbing locked objects.");
			Instance.ProjectileGrabbingMode = cfg.Bind<ProjectileGrabbingMode>("General", "ProjectileGrabbingMode", DrifterBossGrabMod.ProjectileGrabbingMode.None, "Projectile grab mode.");
			Instance.EnableDebugLogs = cfg.Bind<bool>("General", "EnableDebugLogs", false, "Log grab mechanics for debugging.");
			Instance.BodyBlacklist = cfg.Bind<string>("General", "Blacklist", "HeaterPodBodyNoRespawn,ThrownObjectProjectile,ThrownObjectProjectileNoStun,GenericPickup,MultiShopTerminal,MultiShopLargeTerminal,MultiShopEquipmentTerminal,RailgunnerPistolProjectile,FMJRamping,SyringeProjectile,EngiGrenadeProjectile,CrocoSpit,CaptainTazer,LunarSpike,LunarNeedleProjectile,StickyBomb,RocketProjectile,StunAndPierceBoomerang", "Bodies and projectiles to never grab. Comma-separated.");
			Instance.RecoveryObjectBlacklist = cfg.Bind<string>("General", "RecoveryObjectBlacklist", "", "Objects to never recover from the abyss. Comma-separated.");
			Instance.GrabbableComponentTypes = cfg.Bind<string>("General", "GrabbableComponentTypes", "PurchaseInteraction,TeleporterInteraction,GenericInteraction,ProxyInteraction,DummyPingableInteraction,MealPrepController", "Component type names that make objects grabbable. Comma-separated.");
			Instance.GrabbableKeywordBlacklist = cfg.Bind<string>("General", "GrabbableKeywordBlacklist", "Master,Controller", "Keywords that prevent grabbing if found in name. Comma-separated.");
			Instance.ComponentChooserSortModeEntry = cfg.Bind<ComponentChooserSortMode>("Hidden", "ComponentChooserSortMode", ComponentChooserSortMode.ByFrequency, "How to sort components in the UI.");
			Instance.ComponentChooserDummyEntry = cfg.Bind<ComponentChooserDummy>("Hidden", "ComponentChooserDummy", ComponentChooserDummy.SelectToToggle, "Dummy setting for UI.");
			Instance.EnableConfigSync = cfg.Bind<bool>("General", "EnableConfigSync", true, "Sync configuration from host to clients.");
			Instance.SearchRadiusMultiplier = cfg.Bind<float>("Balance", "SearchRadiusMultiplier", 1f, "Multiplier for grab reach distance.");
		}

		private static void InitHudConfig(ConfigFile cfg)
		{
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0618: Unknown result type (might be due to invalid IL or missing references)
			//IL_0650: Unknown result type (might be due to invalid IL or missing references)
			//IL_0688: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c0: Unknown result type (might be due to invalid IL or missing references)
			Instance.EnableCarouselHUD = cfg.Bind<bool>("Hud", "EnableCarouselHUD", false, "Enable the custom Carousel HUD.");
			Instance.CarouselSpacing = cfg.Bind<float>("Hud", "CarouselSpacing", 45f, "Vertical spacing for carousel items.");
			Instance.CarouselAnimationDuration = cfg.Bind<float>("Hud", "CarouselAnimationDuration", 0.4f, "Duration of carousel animation.");
			Instance.CenterSlotX = cfg.Bind<float>("Hud", "CenterSlotX", 25f, "X position offset for center slot.");
			Instance.CenterSlotY = cfg.Bind<float>("Hud", "CenterSlotY", 50f, "Y position offset for center slot.");
			Instance.CenterSlotScale = cfg.Bind<float>("Hud", "CenterSlotScale", 1f, "Scale for center slot.");
			Instance.CenterSlotOpacity = cfg.Bind<float>("Hud", "CenterSlotOpacity", 1f, "Opacity for center slot.");
			Instance.CenterSlotShowIcon = cfg.Bind<bool>("Hud", "CenterSlotShowIcon", true, "Show icon in center slot.");
			Instance.CenterSlotShowWeightIcon = cfg.Bind<bool>("Hud", "CenterSlotShowWeightIcon", true, "Show weight icon in center slot.");
			Instance.CenterSlotShowName = cfg.Bind<bool>("Hud", "CenterSlotShowName", true, "Show name in center slot.");
			Instance.CenterSlotShowHealthBar = cfg.Bind<bool>("Hud", "CenterSlotShowHealthBar", true, "Show health bar in center slot.");
			Instance.CenterSlotShowSlotNumber = cfg.Bind<bool>("Hud", "CenterSlotShowSlotNumber", true, "Show slot number in center slot.");
			Instance.SideSlotX = cfg.Bind<float>("Hud", "SideSlotX", 20f, "X position offset for side slots.");
			Instance.SideSlotY = cfg.Bind<float>("Hud", "SideSlotY", 5f, "Y position offset for side slots.");
			Instance.SideSlotScale = cfg.Bind<float>("Hud", "SideSlotScale", 0.8f, "Scale for side slots.");
			Instance.SideSlotOpacity = cfg.Bind<float>("Hud", "SideSlotOpacity", 0.3f, "Opacity for side slots.");
			Instance.SideSlotShowIcon = cfg.Bind<bool>("Hud", "SideSlotShowIcon", true, "Show icon in side slots.");
			Instance.SideSlotShowWeightIcon = cfg.Bind<bool>("Hud", "SideSlotShowWeightIcon", true, "Show weight icon in side slots.");
			Instance.SideSlotShowName = cfg.Bind<bool>("Hud", "SideSlotShowName", true, "Show name in side slots.");
			Instance.SideSlotShowHealthBar = cfg.Bind<bool>("Hud", "SideSlotShowHealthBar", true, "Show health bar in side slots.");
			Instance.SideSlotShowSlotNumber = cfg.Bind<bool>("Hud", "SideSlotShowSlotNumber", true, "Show slot number in side slots.");
			Instance.SelectedHudElement = cfg.Bind<HudElementType>("Hidden", "SelectedHudElement", HudElementType.All, "Select which HUD element group to configure.");
			Instance.SelectedHudElement.Value = HudElementType.All;
			Instance.EnableBaggedObjectInfo = cfg.Bind<bool>("Hud", "EnableBaggedObjectInfo", false, "Enable the Bagged Object Info stats panel.");
			Instance.BaggedObjectInfoX = cfg.Bind<float>("Hud", "BaggedObjectInfoX", 450f, "X position offset for stats panel.");
			Instance.BaggedObjectInfoY = cfg.Bind<float>("Hud", "BaggedObjectInfoY", 85f, "Y position offset for stats panel.");
			Instance.BaggedObjectInfoScale = cfg.Bind<float>("Hud", "BaggedObjectInfoScale", 1f, "Scale for stats panel.");
			Instance.BaggedObjectInfoColor = cfg.Bind<Color>("Hud", "BaggedObjectInfoColor", new Color(1f, 1f, 1f, 0.9f), "Text color for stats panel.");
			Instance.UseNewWeightIcon = cfg.Bind<bool>("Hud", "UseNewWeightIcon", false, "Use the custom weight icon.");
			Instance.WeightDisplayMode = cfg.Bind<WeightDisplayMode>("Hud", "WeightDisplayMode", DrifterBossGrabMod.WeightDisplayMode.Multiplier, "Mode for weight display.");
			Instance.ScaleWeightColor = cfg.Bind<bool>("Hud", "ScaleWeightColor", true, "Scale weight icon color by capacity.");
			Instance.ShowTotalMassOnWeightIcon = cfg.Bind<bool>("Hud", "ShowTotalMassOnWeightIcon", false, "Show total bag mass on center slot.");
			Instance.ShowOverencumberIcon = cfg.Bind<bool>("Hud", "ShowOverencumberIcon", false, "Show overencumbrance icon.");
			Instance.EnableDamagePreview = cfg.Bind<bool>("Hud", "EnableDamagePreview", false, "Show damage preview overlay.");
			Instance.DamagePreviewColor = cfg.Bind<Color>("Hud", "DamagePreviewColor", new Color(1f, 0.15f, 0.15f, 0.8f), "Color for damage preview.");
			Instance.EnableMassCapacityUI = cfg.Bind<bool>("Hud", "EnableMassCapacityUI", false, "Enable the Mass Capacity UI bar.");
			Instance.MassCapacityUIPositionX = cfg.Bind<float>("Hud", "MassCapacityUIPositionX", -20f, "X offset for Mass Capacity UI.");
			Instance.MassCapacityUIPositionY = cfg.Bind<float>("Hud", "MassCapacityUIPositionY", 0f, "Y offset for Mass Capacity UI.");
			Instance.MassCapacityUIScale = cfg.Bind<float>("Hud", "MassCapacityUIScale", 0.8f, "Scale for Mass Capacity UI.");
			Instance.EnableSeparators = cfg.Bind<bool>("Hud", "EnableSeparators", true, "Show threshold pips on Mass Capacity UI.");
			Instance.GradientIntensity = cfg.Bind<float>("Hud", "GradientIntensity", 1f, "Intensity of the gradient color.");
			Instance.CapacityGradientColorStart = cfg.Bind<Color>("Hud", "CapacityGradientColorStart", new Color(0f, 1f, 0f, 1f), "Start color for standard capacity gradient.");
			Instance.CapacityGradientColorMid = cfg.Bind<Color>("Hud", "CapacityGradientColorMid", new Color(1f, 1f, 0f, 1f), "Mid color for standard capacity gradient.");
			Instance.CapacityGradientColorEnd = cfg.Bind<Color>("Hud", "CapacityGradientColorEnd", new Color(1f, 0f, 0f, 1f), "End color for standard capacity gradient.");
			Instance.OverencumbranceGradientColorStart = cfg.Bind<Color>("Hud", "OverencumbranceGradientColorStart", new Color(0f, 1f, 1f, 1f), "Start color for overencumbrance gradient.");
			Instance.OverencumbranceGradientColorMid = cfg.Bind<Color>("Hud", "OverencumbranceGradientColorMid", new Color(0f, 0f, 0.5f, 1f), "Mid color for overencumbrance gradient.");
			Instance.OverencumbranceGradientColorEnd = cfg.Bind<Color>("Hud", "OverencumbranceGradientColorEnd", new Color(0f, 0f, 1f, 1f), "End color for overencumbrance gradient.");
			Instance.IsHudEditorEnabled = cfg.Bind<bool>("Hidden", "IsHudEditorEnabled", false, "Toggle to enable the in-game HUD Editor. You MUST be in game for it to work.");
			Instance.IsHudEditorEnabled.Value = false;
			WireHudEventHandlers();
		}

		private static void WireHudEventHandlers()
		{
			Instance.EnableCarouselHUD.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.CenterSlotShowIcon.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.CenterSlotShowWeightIcon.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.CenterSlotShowName.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.CenterSlotShowSlotNumber.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.SideSlotShowIcon.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.SideSlotShowWeightIcon.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.SideSlotShowName.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.SideSlotShowHealthBar.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.SideSlotShowSlotNumber.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.UseNewWeightIcon.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.WeightDisplayMode.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.ScaleWeightColor.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.ShowTotalMassOnWeightIcon.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.ShowOverencumberIcon.SettingChanged += delegate
			{
				UpdateBagUIToggles();
			};
			Instance.DamagePreviewColor.SettingChanged += delegate
			{
				UpdateDamagePreviewColors();
			};
			Instance.EnableMassCapacityUI.SettingChanged += delegate
			{
				UpdateMassCapacityUIToggles();
			};
			Instance.MassCapacityUIPositionX.SettingChanged += delegate
			{
				UpdateMassCapacityUIToggles();
			};
			Instance.MassCapacityUIPositionY.SettingChanged += delegate
			{
				UpdateMassCapacityUIToggles();
			};
			Instance.MassCapacityUIScale.SettingChanged += delegate
			{
				UpdateMassCapacityUIToggles();
			};
			Instance.EnableSeparators.SettingChanged += delegate
			{
				UpdateMassCapacityUIToggles();
			};
			Instance.GradientIntensity.SettingChanged += delegate
			{
				UpdateMassCapacityUIToggles();
			};
			Instance.CapacityGradientColorStart.SettingChanged += delegate
			{
				UpdateMassCapacityUIToggles();
			};
			Instance.CapacityGradientColorMid.SettingChanged += delegate
			{
				UpdateMassCapacityUIToggles();
			};
			Instance.CapacityGradientColorEnd.SettingChanged += delegate
			{
				UpdateMassCapacityUIToggles();
			};
			Instance.OverencumbranceGradientColorStart.SettingChanged += delegate
			{
				UpdateMassCapacityUIToggles();
			};
			Instance.OverencumbranceGradientColorMid.SettingChanged += delegate
			{
				UpdateMassCapacityUIToggles();
			};
			Instance.OverencumbranceGradientColorEnd.SettingChanged += delegate
			{
				UpdateMassCapacityUIToggles();
			};
		}

		private static void InitPersistenceConfig(ConfigFile cfg)
		{
			Instance.EnableObjectPersistence = cfg.Bind<bool>("Persistence", "EnableObjectPersistence", false, "Save and restore bagged objects across stages.");
			Instance.EnableAutoGrab = cfg.Bind<bool>("Persistence", "EnableAutoGrab", false, "Auto-grab persisted objects on stage start.");
			Instance.PersistBaggedBosses = cfg.Bind<bool>("Persistence", "PersistBaggedBosses", true, "Allow bosses to persist across stages.");
			Instance.PersistBaggedNPCs = cfg.Bind<bool>("Persistence", "PersistBaggedNPCs", true, "Allow NPCs to persist across stages.");
			Instance.PersistBaggedEnvironmentObjects = cfg.Bind<bool>("Persistence", "PersistBaggedEnvironmentObjects", true, "Allow environment objects to persist across stages.");
			Instance.PersistenceBlacklist = cfg.Bind<string>("Persistence", "PersistenceBlacklist", "", "Objects to never persist. Comma-separated.");
			Instance.AutoGrabDelay = cfg.Bind<float>("Persistence", "AutoGrabDelay", 1f, "Delay before auto-grabbing persisted objects (seconds).");
		}

		public static bool IsBlacklisted(string? name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			return Instance._blacklistCacheWithClones.Value.Contains(name);
		}

		public static bool IsRecoveryBlacklisted(string? name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			return Instance._recoveryBlacklistCacheWithClones.Value.Contains(name);
		}

		public static bool IsPersistenceBlacklisted(string? name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			return Instance._persistenceBlacklistCacheWithClones.Value.Contains(name);
		}

		public static bool IsPersistenceBlacklisted(GameObject? obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return false;
			}
			if (IsPersistenceBlacklisted(((Object)obj).name))
			{
				return true;
			}
			if (Instance._persistenceBlacklistCache.Value.Contains("Teleporter") && (Object)(object)obj.GetComponent<TeleporterInteraction>() != (Object)null)
			{
				return true;
			}
			return false;
		}

		public static bool IsKeywordBlacklisted(string? name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			foreach (string item in Instance._grabbableKeywordBlacklistCache.Value)
			{
				if (name.Contains(item, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		public static bool IsGrabbable(GameObject? obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return false;
			}
			if (IsKeywordBlacklisted(((Object)obj).name))
			{
				return false;
			}
			if (IsBlacklisted(((Object)obj).name))
			{
				return false;
			}
			bool flag = false;
			foreach (string item in Instance._grabbableComponentTypesCache.Value)
			{
				Component component = obj.GetComponent(item);
				if ((Object)(object)component != (Object)null)
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return false;
			}
			foreach (IGrabbingStrategy grabbingStrategy in Instance._grabbingStrategies)
			{
				if (grabbingStrategy.CanGrab(obj))
				{
					return true;
				}
			}
			return false;
		}

		public void RefreshCachedConfigStrings()
		{
			_isBagScaleCapInfinite = string.Equals(BagScaleCap.Value, "INF", StringComparison.OrdinalIgnoreCase) || string.Equals(BagScaleCap.Value, "INFINITY", StringComparison.OrdinalIgnoreCase);
			_parsedBagScaleCap = (_isBagScaleCapInfinite ? float.MaxValue : (float.TryParse(BagScaleCap.Value, out var result) ? result : 1f));
			_isMassCapInfinite = string.Equals(MassCap.Value, "INF", StringComparison.OrdinalIgnoreCase) || string.Equals(MassCap.Value, "INFINITY", StringComparison.OrdinalIgnoreCase);
			_parsedMassCap = (_isMassCapInfinite ? float.MaxValue : (float.TryParse(MassCap.Value, out var result2) ? result2 : 700f));
			_isAddedCapacityInfinite = string.Equals(SlotScalingFormula.Value, "INF", StringComparison.OrdinalIgnoreCase) || string.Equals(SlotScalingFormula.Value, "INFINITY", StringComparison.OrdinalIgnoreCase);
			_isMaxLaunchSpeedInfinite = string.Equals(MaxLaunchSpeed.Value, "INF", StringComparison.OrdinalIgnoreCase) || string.Equals(MaxLaunchSpeed.Value, "INFINITY", StringComparison.OrdinalIgnoreCase);
			_parsedMaxLaunchSpeed = (_isMaxLaunchSpeedInfinite ? float.MaxValue : (float.TryParse(MaxLaunchSpeed.Value, out var result3) ? result3 : 30f));
		}

		public static void Init(ConfigFile cfg)
		{
			InitGeneralConfig(cfg);
			InitRecoveryConfig(cfg);
			InitPersistenceConfig(cfg);
			InitHudConfig(cfg);
			InitBottomlessBagConfig(cfg);
			InitBalanceConfig(cfg);
			InitCharacterFlagsConfig(cfg);
			InitBlacklistCaches();
			Instance.RefreshCachedConfigStrings();
		}

		private static void InitBlacklistCaches()
		{
			Instance._blacklistCache = new LazyCachedValue<HashSet<string>>(() => (!string.IsNullOrEmpty(Instance.BodyBlacklist.Value)) ? (from s in Instance.BodyBlacklist.Value.Split(',')
				select s.Trim() into s
				where !string.IsNullOrEmpty(s)
				select s).ToHashSet<string>(StringComparer.OrdinalIgnoreCase) : new HashSet<string>());
			Instance._blacklistCacheWithClones = new LazyCachedValue<HashSet<string>>(delegate
			{
				HashSet<string> value3 = Instance._blacklistCache.Value;
				HashSet<string> hashSet3 = new HashSet<string>(value3, StringComparer.OrdinalIgnoreCase);
				foreach (string item in value3)
				{
					hashSet3.Add(item + "(Clone)");
				}
				return hashSet3;
			});
			Instance._recoveryBlacklistCache = new LazyCachedValue<HashSet<string>>(() => (!string.IsNullOrEmpty(Instance.RecoveryObjectBlacklist.Value)) ? (from s in Instance.RecoveryObjectBlacklist.Value.Split(',')
				select s.Trim() into s
				where !string.IsNullOrEmpty(s)
				select s).ToHashSet<string>(StringComparer.OrdinalIgnoreCase) : new HashSet<string>());
			Instance._recoveryBlacklistCacheWithClones = new LazyCachedValue<HashSet<string>>(delegate
			{
				HashSet<string> value2 = Instance._recoveryBlacklistCache.Value;
				HashSet<string> hashSet2 = new HashSet<string>(value2, StringComparer.OrdinalIgnoreCase);
				foreach (string item2 in value2)
				{
					hashSet2.Add(item2 + "(Clone)");
				}
				return hashSet2;
			});
			Instance._grabbableComponentTypesCache = new LazyCachedValue<HashSet<string>>(() => (!string.IsNullOrEmpty(Instance.GrabbableComponentTypes.Value)) ? (from s in Instance.GrabbableComponentTypes.Value.Split(',')
				select s.Trim() into s
				where !string.IsNullOrEmpty(s)
				select s).ToHashSet<string>(StringComparer.Ordinal) : new HashSet<string>());
			Instance._grabbableKeywordBlacklistCache = new LazyCachedValue<HashSet<string>>(() => (!string.IsNullOrEmpty(Instance.GrabbableKeywordBlacklist.Value)) ? (from s in Instance.GrabbableKeywordBlacklist.Value.Split(',')
				select s.Trim() into s
				where !string.IsNullOrEmpty(s)
				select s).ToHashSet<string>(StringComparer.OrdinalIgnoreCase) : new HashSet<string>());
			Instance._persistenceBlacklistCache = new LazyCachedValue<HashSet<string>>(() => (!string.IsNullOrEmpty(Instance.PersistenceBlacklist.Value)) ? (from s in Instance.PersistenceBlacklist.Value.Split(',')
				select s.Trim() into s
				where !string.IsNullOrEmpty(s)
				select s).ToHashSet<string>(StringComparer.OrdinalIgnoreCase) : new HashSet<string>());
			Instance._persistenceBlacklistCacheWithClones = new LazyCachedValue<HashSet<string>>(delegate
			{
				HashSet<string> value = Instance._persistenceBlacklistCache.Value;
				HashSet<string> hashSet = new HashSet<string>(value, StringComparer.OrdinalIgnoreCase);
				foreach (string item3 in value)
				{
					hashSet.Add(item3 + "(Clone)");
				}
				return hashSet;
			});
			Instance.BodyBlacklist.SettingChanged += delegate
			{
				Instance._blacklistCache.Invalidate();
				Instance._blacklistCacheWithClones.Invalidate();
			};
			Instance.RecoveryObjectBlacklist.SettingChanged += delegate
			{
				Instance._recoveryBlacklistCache.Invalidate();
				Instance._recoveryBlacklistCacheWithClones.Invalidate();
			};
			Instance.PersistenceBlacklist.SettingChanged += delegate
			{
				Instance._persistenceBlacklistCache.Invalidate();
				Instance._persistenceBlacklistCacheWithClones.Invalidate();
			};
			Instance.GrabbableComponentTypes.SettingChanged += delegate
			{
				Instance._grabbableComponentTypesCache.Invalidate();
			};
			Instance.GrabbableKeywordBlacklist.SettingChanged += delegate
			{
				Instance._grabbableKeywordBlacklistCache.Invalidate();
			};
		}

		public static void RemoveEventHandlers(EventHandler debugLogsHandler, EventHandler blacklistHandler, EventHandler recoveryBlacklistHandler, EventHandler persistenceBlacklistHandler, EventHandler grabbableComponentTypesHandler, EventHandler grabbableKeywordBlacklistHandler, EventHandler bossGrabbingHandler, EventHandler npcGrabbingHandler, EventHandler environmentGrabbingHandler, EventHandler lockedObjectGrabbingHandler, EventHandler projectileGrabbingModeHandler)
		{
			Instance.EnableDebugLogs.SettingChanged -= debugLogsHandler;
			Instance.BodyBlacklist.SettingChanged -= blacklistHandler;
			Instance.RecoveryObjectBlacklist.SettingChanged -= recoveryBlacklistHandler;
			Instance.PersistenceBlacklist.SettingChanged -= persistenceBlacklistHandler;
			Instance.GrabbableComponentTypes.SettingChanged -= grabbableComponentTypesHandler;
			Instance.GrabbableKeywordBlacklist.SettingChanged -= grabbableKeywordBlacklistHandler;
			Instance.EnableBossGrabbing.SettingChanged -= bossGrabbingHandler;
			Instance.EnableNPCGrabbing.SettingChanged -= npcGrabbingHandler;
			Instance.EnableEnvironmentGrabbing.SettingChanged -= environmentGrabbingHandler;
			Instance.EnableLockedObjectGrabbing.SettingChanged -= lockedObjectGrabbingHandler;
			Instance.ProjectileGrabbingMode.SettingChanged -= projectileGrabbingModeHandler;
		}

		public static void ClearBlacklistCache()
		{
			Instance._blacklistCache.Invalidate();
			Instance._blacklistCacheWithClones.Invalidate();
		}

		public static void ClearRecoveryBlacklistCache()
		{
			Instance._recoveryBlacklistCache.Invalidate();
			Instance._recoveryBlacklistCacheWithClones.Invalidate();
		}

		public static void ClearPersistenceBlacklistCache()
		{
			Instance._persistenceBlacklistCache.Invalidate();
			Instance._persistenceBlacklistCacheWithClones.Invalidate();
		}

		public static void ClearGrabbableComponentTypesCache()
		{
			Instance._grabbableComponentTypesCache.Invalidate();
		}

		public static void ClearGrabbableKeywordBlacklistCache()
		{
			Instance._grabbableKeywordBlacklistCache.Invalidate();
		}

		public static void InvalidateAllCaches()
		{
			Instance._blacklistCache.Invalidate();
			Instance._blacklistCacheWithClones.Invalidate();
			Instance._recoveryBlacklistCache.Invalidate();
			Instance._recoveryBlacklistCacheWithClones.Invalidate();
			Instance._persistenceBlacklistCache.Invalidate();
			Instance._persistenceBlacklistCacheWithClones.Invalidate();
			Instance._grabbableComponentTypesCache.Invalidate();
			Instance._grabbableKeywordBlacklistCache.Invalidate();
		}

		public static ConfigEntry<string> GetFlagMultiplierConfig(CharacterFlagType flag)
		{
			return (ConfigEntry<string>)(flag switch
			{
				CharacterFlagType.Elite => Instance.EliteFlagMultiplier, 
				CharacterFlagType.Boss => Instance.BossFlagMultiplier, 
				CharacterFlagType.Champion => Instance.ChampionFlagMultiplier, 
				CharacterFlagType.Player => Instance.PlayerFlagMultiplier, 
				CharacterFlagType.Minion => Instance.MinionFlagMultiplier, 
				CharacterFlagType.Drone => Instance.DroneFlagMultiplier, 
				CharacterFlagType.Mechanical => Instance.MechanicalFlagMultiplier, 
				CharacterFlagType.Void => Instance.VoidFlagMultiplier, 
				CharacterFlagType.All => Instance.AllFlagMultiplier, 
				_ => Instance.AllFlagMultiplier, 
			});
		}

		public static string GetFlagDisplayName(CharacterFlagType flag)
		{
			return flag switch
			{
				CharacterFlagType.Elite => "Elite", 
				CharacterFlagType.Boss => "Boss", 
				CharacterFlagType.Champion => "Champion", 
				CharacterFlagType.Player => "Player", 
				CharacterFlagType.Minion => "Minion", 
				CharacterFlagType.Drone => "Drone", 
				CharacterFlagType.Mechanical => "Mechanical", 
				CharacterFlagType.Void => "Void", 
				CharacterFlagType.All => "All", 
				_ => "All", 
			};
		}

		public static ConfigEntry<float> GetSlotXConfig(HudElementType slot)
		{
			if (slot != HudElementType.MainSlot)
			{
				return Instance.SideSlotX;
			}
			return Instance.CenterSlotX;
		}

		public static ConfigEntry<float> GetSlotYConfig(HudElementType slot)
		{
			if (slot != HudElementType.MainSlot)
			{
				return Instance.SideSlotY;
			}
			return Instance.CenterSlotY;
		}

		public static ConfigEntry<float> GetSlotScaleConfig(HudElementType slot)
		{
			if (slot != HudElementType.MainSlot)
			{
				return Instance.SideSlotScale;
			}
			return Instance.CenterSlotScale;
		}

		public static ConfigEntry<float> GetSlotOpacityConfig(HudElementType slot)
		{
			if (slot != HudElementType.MainSlot)
			{
				return Instance.SideSlotOpacity;
			}
			return Instance.CenterSlotOpacity;
		}

		public static ConfigEntry<bool> GetSlotShowIconConfig(HudElementType slot)
		{
			if (slot != HudElementType.MainSlot)
			{
				return Instance.SideSlotShowIcon;
			}
			return Instance.CenterSlotShowIcon;
		}

		public static ConfigEntry<bool> GetSlotShowWeightIconConfig(HudElementType slot)
		{
			if (slot != HudElementType.MainSlot)
			{
				return Instance.SideSlotShowWeightIcon;
			}
			return Instance.CenterSlotShowWeightIcon;
		}

		public static ConfigEntry<bool> GetSlotShowNameConfig(HudElementType slot)
		{
			if (slot != HudElementType.MainSlot)
			{
				return Instance.SideSlotShowName;
			}
			return Instance.CenterSlotShowName;
		}

		public static ConfigEntry<bool> GetSlotShowHealthBarConfig(HudElementType slot)
		{
			if (slot != HudElementType.MainSlot)
			{
				return Instance.SideSlotShowHealthBar;
			}
			return Instance.CenterSlotShowHealthBar;
		}

		public static ConfigEntry<bool> GetSlotShowSlotNumberConfig(HudElementType slot)
		{
			if (slot != HudElementType.MainSlot)
			{
				return Instance.SideSlotShowSlotNumber;
			}
			return Instance.CenterSlotShowSlotNumber;
		}

		private static void UpdateBagUIToggles()
		{
			BaggedObjectCarousel[] array = Object.FindObjectsByType<BaggedObjectCarousel>((FindObjectsSortMode)0);
			BaggedObjectCarousel[] array2 = array;
			foreach (BaggedObjectCarousel baggedObjectCarousel in array2)
			{
				baggedObjectCarousel.UpdateToggles();
			}
		}

		private static void UpdateMassCapacityUIToggles()
		{
			MassCapacityUIController[] array = Object.FindObjectsByType<MassCapacityUIController>((FindObjectsSortMode)0);
			MassCapacityUIController[] array2 = array;
			foreach (MassCapacityUIController massCapacityUIController in array2)
			{
				massCapacityUIController.UpdateConfig();
			}
		}

		private static void UpdateDamagePreviewColors()
		{
			DamagePreviewOverlay[] array = Object.FindObjectsByType<DamagePreviewOverlay>((FindObjectsSortMode)0);
			DamagePreviewOverlay[] array2 = array;
			foreach (DamagePreviewOverlay damagePreviewOverlay in array2)
			{
				damagePreviewOverlay.UpdateColor();
			}
		}

		private static Transform? FindDeepChild(Transform parent, string name)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			foreach (Transform item in parent)
			{
				Transform val = item;
				if (((Object)val).name == name)
				{
					return val;
				}
				Transform val2 = FindDeepChild(val, name);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}

		private static void InitRecoveryConfig(ConfigFile cfg)
		{
			Instance.EnableRecoveryFeature = cfg.Bind<bool>("Recovery", "EnableRecoveryFeature", true, "Return bagged items that fall off the map.");
			Instance.EnemyRecoveryMode = cfg.Bind<EnemyRecoveryMode>("Recovery", "EnemyRecoveryMode", DrifterBossGrabMod.EnemyRecoveryMode.Recover, "Behavior for bagged enemies falling off the map.");
			Instance.RecoverBaggedBosses = cfg.Bind<bool>("Recovery", "RecoverBaggedBosses", true, "Recover bagged bosses from the abyss.");
			Instance.RecoverBaggedNPCs = cfg.Bind<bool>("Recovery", "RecoverBaggedNPCs", true, "Recover bagged NPCs from the abyss.");
			Instance.RecoverBaggedEnvironmentObjects = cfg.Bind<bool>("Recovery", "RecoverBaggedEnvironmentObjects", true, "Recover bagged environment objects from the abyss.");
		}
	}
	public static class ConfigChangeNotifier
	{
		private static readonly List<IConfigObserver> observers = new List<IConfigObserver>();

		private static readonly EventHandler configChangedHandler = OnConfigChanged;

		public static void AddObserver(IConfigObserver observer)
		{
			observers.Add(observer);
		}

		public static void RemoveObserver(IConfigObserver observer)
		{
			observers.Remove(observer);
		}

		private static void OnConfigChanged(object sender, EventArgs e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ConfigEntryBase val = (ConfigEntryBase)sender;
			NotifyObservers(val.Definition.Key, val.BoxedValue);
		}

		private static void NotifyObservers(string key, object value)
		{
			IConfigObserver[] array = observers.ToArray();
			IConfigObserver[] array2 = array;
			foreach (IConfigObserver configObserver in array2)
			{
				configObserver.OnConfigChanged(key, value);
			}
		}

		public static void Init()
		{
			PluginConfig.Instance.BreakoutTimeMultiplier.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableBossGrabbing.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableNPCGrabbing.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableEnvironmentGrabbing.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableLockedObjectGrabbing.SettingChanged += configChangedHandler;
			PluginConfig.Instance.ProjectileGrabbingMode.SettingChanged += configChangedHandler;
			PluginConfig.Instance.MaxSmacks.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableDebugLogs.SettingChanged += configChangedHandler;
			PluginConfig.Instance.BodyBlacklist.SettingChanged += configChangedHandler;
			PluginConfig.Instance.RecoveryObjectBlacklist.SettingChanged += configChangedHandler;
			PluginConfig.Instance.GrabbableComponentTypes.SettingChanged += configChangedHandler;
			PluginConfig.Instance.GrabbableKeywordBlacklist.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableObjectPersistence.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableAutoGrab.SettingChanged += configChangedHandler;
			PluginConfig.Instance.PersistBaggedBosses.SettingChanged += configChangedHandler;
			PluginConfig.Instance.PersistBaggedNPCs.SettingChanged += configChangedHandler;
			PluginConfig.Instance.PersistBaggedEnvironmentObjects.SettingChanged += configChangedHandler;
			PluginConfig.Instance.PersistenceBlacklist.SettingChanged += configChangedHandler;
			PluginConfig.Instance.BottomlessBagEnabled.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableMouseWheelScrolling.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableCarouselHUD.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CarouselSpacing.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CarouselAnimationDuration.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CenterSlotX.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CenterSlotY.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CenterSlotScale.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CenterSlotOpacity.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CenterSlotShowIcon.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CenterSlotShowWeightIcon.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CenterSlotShowName.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CenterSlotShowHealthBar.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CenterSlotShowSlotNumber.SettingChanged += configChangedHandler;
			PluginConfig.Instance.SideSlotX.SettingChanged += configChangedHandler;
			PluginConfig.Instance.SideSlotY.SettingChanged += configChangedHandler;
			PluginConfig.Instance.SideSlotScale.SettingChanged += configChangedHandler;
			PluginConfig.Instance.SideSlotOpacity.SettingChanged += configChangedHandler;
			PluginConfig.Instance.SideSlotShowIcon.SettingChanged += configChangedHandler;
			PluginConfig.Instance.SideSlotShowWeightIcon.SettingChanged += configChangedHandler;
			PluginConfig.Instance.SideSlotShowName.SettingChanged += configChangedHandler;
			PluginConfig.Instance.SideSlotShowHealthBar.SettingChanged += configChangedHandler;
			PluginConfig.Instance.SideSlotShowSlotNumber.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableDamagePreview.SettingChanged += configChangedHandler;
			PluginConfig.Instance.DamagePreviewColor.SettingChanged += configChangedHandler;
			PluginConfig.Instance.UseNewWeightIcon.SettingChanged += configChangedHandler;
			PluginConfig.Instance.WeightDisplayMode.SettingChanged += configChangedHandler;
			PluginConfig.Instance.ScaleWeightColor.SettingChanged += configChangedHandler;
			PluginConfig.Instance.ShowTotalMassOnWeightIcon.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableMassCapacityUI.SettingChanged += configChangedHandler;
			PluginConfig.Instance.MassCapacityUIPositionX.SettingChanged += configChangedHandler;
			PluginConfig.Instance.MassCapacityUIPositionY.SettingChanged += configChangedHandler;
			PluginConfig.Instance.MassCapacityUIScale.SettingChanged += configChangedHandler;
			PluginConfig.Instance.EnableSeparators.SettingChanged += configChangedHandler;
			PluginConfig.Instance.GradientIntensity.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CapacityGradientColorStart.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CapacityGradientColorMid.SettingChanged += configChangedHandler;
			PluginConfig.Instance.CapacityGradientColorEnd.SettingChanged += configChangedHandler;
			PluginConfig.Instance.OverencumbranceGradientColorStart.SettingChanged += configChangedHandler;
			PluginConfig.Instance.OverencumbranceGradientColorMid.SettingChanged += configChangedHandler;
			PluginConfig.Instance.OverencumbranceGradientColorEnd.SettingChanged += configChangedHandler;
		}

		public static void Cleanup()
		{
			PluginConfig.Instance.BreakoutTimeMultiplier.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableBossGrabbing.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableNPCGrabbing.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableEnvironmentGrabbing.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableLockedObjectGrabbing.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.ProjectileGrabbingMode.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.MaxSmacks.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableDebugLogs.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.BodyBlacklist.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.RecoveryObjectBlacklist.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.GrabbableComponentTypes.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.GrabbableKeywordBlacklist.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableObjectPersistence.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableAutoGrab.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.PersistBaggedBosses.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.PersistBaggedNPCs.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.PersistBaggedEnvironmentObjects.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.PersistenceBlacklist.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.BottomlessBagEnabled.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableMouseWheelScrolling.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableCarouselHUD.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CarouselSpacing.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CarouselAnimationDuration.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CenterSlotX.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CenterSlotY.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CenterSlotScale.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CenterSlotOpacity.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CenterSlotShowIcon.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CenterSlotShowWeightIcon.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CenterSlotShowName.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CenterSlotShowHealthBar.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CenterSlotShowSlotNumber.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.SideSlotX.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.SideSlotY.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.SideSlotScale.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.SideSlotOpacity.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.SideSlotShowIcon.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.SideSlotShowWeightIcon.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.SideSlotShowName.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.SideSlotShowHealthBar.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.SideSlotShowSlotNumber.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableDamagePreview.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.DamagePreviewColor.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.UseNewWeightIcon.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.WeightDisplayMode.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.ScaleWeightColor.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.ShowTotalMassOnWeightIcon.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableMassCapacityUI.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.MassCapacityUIPositionX.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.MassCapacityUIPositionY.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.MassCapacityUIScale.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.EnableSeparators.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.GradientIntensity.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CapacityGradientColorStart.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CapacityGradientColorMid.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.CapacityGradientColorEnd.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.OverencumbranceGradientColorStart.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.OverencumbranceGradientColorMid.SettingChanged -= configChangedHandler;
			PluginConfig.Instance.OverencumbranceGradientColorEnd.SettingChanged -= configChangedHandler;
		}
	}
	public enum EnemyRecoveryMode
	{
		Kill,
		Recover
	}
	public enum ProjectileGrabbingMode
	{
		None,
		SurvivorOnly,
		AllProjectiles
	}
	public enum WeightDisplayMode
	{
		None,
		Multiplier,
		Pounds,
		KiloGrams
	}
	public enum StateCalculationMode
	{
		Current,
		All
	}
	public enum AoEDamageMode
	{
		None,
		Full,
		Split
	}
	public enum CharacterFlagType
	{
		All,
		Elite,
		Boss,
		Champion,
		Player,
		Minion,
		Drone,
		Mechanical,
		Void
	}
	public enum HudElementType
	{
		All,
		MainSlot,
		SideSlots,
		WeightIcon,
		DamagePreview,
		CapacityUI,
		StatsPanel
	}
	public enum BalanceSubTabType
	{
		All,
		Formulas,
		Multipliers,
		Limits
	}
	public enum PresetType
	{
		Vanilla,
		Intended,
		Minimal,
		Default,
		Balance,
		Hardcore,
		Caveman,
		Custom
	}
	public interface ICachedValue<T>
	{
		T Value { get; }

		void Invalidate();
	}
	public class LazyCachedValue<T> : ICachedValue<T>
	{
		private readonly Func<T> _factory;

		private T? _value;

		private bool _isValid;

		private readonly object _lock = new object();

		public T Value
		{
			get
			{
				lock (_lock)
				{
					if (!_isValid)
					{
						_value = _factory();
						_isValid = true;
					}
					return _value;
				}
			}
		}

		public void Invalidate()
		{
			lock (_lock)
			{
				_isValid = false;
				_value = default(T);
			}
		}

		public LazyCachedValue(Func<T> factory)
		{
			_factory = factory ?? throw new ArgumentNullException("factory");
		}
	}
	public enum ComponentChooserDummy
	{
		SelectToToggle
	}
	public enum ComponentChooserSortMode
	{
		ByFrequency,
		ByProximity,
		ByRaycast
	}
	public class BodyColliderCache : MonoBehaviour
	{
		private Collider[]? _colliders;

		private bool _isInitialized;

		public Dictionary<Collider, bool> OriginalStates { get; } = new Dictionary<Collider, bool>();


		public Collider[] GetColliders()
		{
			if (!_isInitialized)
			{
				PopulateCache();
			}
			return _colliders ?? Array.Empty<Collider>();
		}

		private void PopulateCache()
		{
			Log.Debug("[BodyColliderCache] Populating collider cache for " + ((Object)((Component)this).gameObject).name);
			ModelLocator component = ((Component)this).GetComponent<ModelLocator>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.modelTransform != (Object)null)
			{
				_colliders = ((Component)component.modelTransform).GetComponentsInChildren<Collider>(true);
			}
			else
			{
				_colliders = ((Component)this).GetComponentsInChildren<Collider>(true);
			}
			Collider[]? colliders = _colliders;
			Log.Debug($"[BodyColliderCache] Found {((colliders != null) ? colliders.Length : 0)} colliders for {((Object)((Component)this).gameObject).name}");
			_isInitialized = true;
		}

		public void RefreshCache()
		{
			_isInitialized = false;
		}

		public static void DisableMovementColliders(GameObject obj, Dictionary<Collider, bool> originalStates)
		{
			BodyColliderCache bodyColliderCache = obj.GetComponent<BodyColliderCache>();
			if ((Object)(object)bodyColliderCache == (Object)null)
			{
				bodyColliderCache = obj.AddComponent<BodyColliderCache>();
			}
			IEnumerable<Collider> colliders = bodyColliderCache.GetColliders();
			if (bodyColliderCache.OriginalStates.Count > 0 && originalStates.Count == 0)
			{
				foreach (KeyValuePair<Collider, bool> originalState in bodyColliderCache.OriginalStates)
				{
					originalStates[originalState.Key] = originalState.Value;
				}
			}
			foreach (Collider item in colliders)
			{
				if ((Object)(object)item != (Object)null && item.enabled)
				{
					if (!originalStates.ContainsKey(item))
					{
						originalStates[item] = item.enabled;
					}
					if (!bodyColliderCache.OriginalStates.ContainsKey(item))
					{
						bodyColliderCache.OriginalStates[item] = item.enabled;
					}
					item.enabled = false;
				}
			}
		}

		public static void RestoreMovementColliders(Dictionary<Collider, bool> originalStates)
		{
			foreach (KeyValuePair<Collider, bool> originalState in originalStates)
			{
				if ((Object)(object)originalState.Key != (Object)null)
				{
					originalState.Key.enabled = originalState.Value;
					BodyColliderCache componentInParent = ((Component)originalState.Key).GetComponentInParent<BodyColliderCache>();
					if ((Object)(object)componentInParent != (Object)null)
					{
						componentInParent.OriginalStates.Remove(originalState.Key);
					}
				}
			}
			originalStates.Clear();
		}
	}
	internal static class Constants
	{
		public static class Timeouts
		{
			public const float SyncStateTimeout = 2f;

			public const float AutoGrabDelay = 0.5f;

			public const float OverencumbranceDebuffRemovalDelay = 1.5f;

			public const int MaxWaitFramesForPlayerBody = 120;

			public const float SyncWaitIncrement = 0.1f;
		}

		public static class Limits
		{
			public const float MaxMass = 700f;

			public const int MaxCapacity = 100;

			public const float MinimumMassPercentage = 0.1f;

			public const float MinimumMass = 1f;

			public const float PositionOffset = 0.5f;

			public const float CameraForwardOffset = 2f;

			public const float OriginYOffset = 1f;

			public const int SingleCapacity = 1;

			public const int DefaultJunkQuantity = 4;

			public const int MinDurabilityThreshold = 1;

			public const float DefaultMassPerStock = 700f;
		}

		public static class Multipliers
		{
			public const float DefaultMassMultiplier = 1f;

			public const float DefaultVelocityMultiplier = 1f;

			public const float ExponentialScalingBase = 0.5f;

			public const float WalkSpeedPenaltyMax = 0.5f;

			public const float PercentageDivisor = 100f;

			public const float CapacityRatioThreshold = 1f;

			public const float ScalingMultiplierBase = 1f;

			public const float SlamBaseDamageCoef = 2.8f;

			public const float SlamMassScaling = 5f;

			public const float DelicateWatchDamageBonus = 0.2f;

			public const float NearbyDamageBonus = 0.2f;
		}

		public static class Network
		{
			public const short BaggedObjectsPersistenceMessageType = 201;

			public const short CycleRequestMessageType = 205;

			public const short UpdateBagStateMessageType = 206;

			public const short ClientUpdateBagStateMessageType = 207;

			public const short GrabObjectMessageType = 208;

			public const short ClientPreferencesMessageType = 209;

			public const short SyncConfigMessageType = 210;

			public const short BagStateUpdatedMessageType = 211;
		}

		public const string CloneSuffix = "(Clone)";

		public const string PluginGuid = "com.pwdcat.DrifterBossGrab";

		public const string PluginName = "DrifterBossGrab";

		public const string PluginVersion = "1.8.0";
	}
	public abstract class FeatureToggleBase
	{
		private bool _isPatchesApplied;

		public abstract string FeatureName { get; }

		public abstract bool IsEnabled { get; }

		public Harmony Harmony { get; }

		protected abstract void ApplyPatches(Harmony harmony);

		protected FeatureToggleBase()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Harmony = new Harmony("com.pwdcat.DrifterBossGrab." + FeatureName.ToLowerInvariant());
		}

		public virtual void Initialize()
		{
			if (IsEnabled)
			{
				ApplyPatches(Harmony);
				_isPatchesApplied = true;
			}
		}

		public virtual void Cleanup()
		{
			Harmony.UnpatchSelf();
			_isPatchesApplied = false;
		}

		public void Enable()
		{
			if (IsEnabled && !_isPatchesApplied)
			{
				ApplyPatches(Harmony);
				_isPatchesApplied = true;
			}
		}

		public void Disable()
		{
			Cleanup();
		}

		public void Toggle(bool enable)
		{
			if (enable)
			{
				Enable();
			}
			else
			{
				Disable();
			}
		}
	}
	[BepInPlugin("com.pwdcat.DrifterBossGrab", "DrifterBossGrab", "1.8.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class DrifterBossGrabPlugin : BaseUnityPlugin, IConfigObserver
	{
		public static class Timing
		{
			public const float BatchInitializationDelay = 0.2f;

			public const float GrabbableComponentTypesUpdateDelay = 0.5f;

			public const float HudSubTabVisibilityUpdateDelay = 0.5f;

			public const float BalanceSubTabVisibilityUpdateDelay = 0.5f;
		}

		public static class BatchProcessing
		{
			public const int BatchSize = 50;
		}

		public static class UI
		{
			public const int IconTextureSize = 256;

			public const float IconRectX = 0f;

			public const float IconRectY = 0f;

			public const float IconPivotX = 0.5f;

			public const float IconPivotY = 0.5f;
		}

		[CompilerGenerated]
		private sealed class <DelayedBatchSpecialObjectAttributesInitialization>d__42 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private GameObject[] <allObjects>5__2;

			private int <i>5__3;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedBatchSpecialObjectAttributesInitialization>d__42(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<allObjects>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (!IsDrifterPresent)
					{
						return false;
					}
					<allObjects>5__2 = Object.FindObjectsByType<GameObject>((FindObjectsSortMode)0);
					<i>5__3 = 0;
					goto IL_00d9;
				case 2:
					{
						<>1__state = -1;
						goto IL_00ca;
					}
					IL_00ca:
					<i>5__3 += 50;
					goto IL_00d9;
					IL_00d9:
					if (<i>5__3 < <allObjects>5__2.Length)
					{
						int num = Mathf.Min(<i>5__3 + 50, <allObjects>5__2.Length);
						for (int i = <i>5__3; i < num; i++)
						{
							GameObject val = <allObjects>5__2[i];
							if ((Object)(object)val != (Object)null && PluginConfig.IsGrabbable(val))
							{
								GrabbableObjectPatches.AddSpecialObjectAttributesToGrabbableObject(val);
							}
						}
						if (num < <allObjects>5__2.Length)
						{
							<>2__current = null;
							<>1__state = 2;
							return true;
						}
						goto IL_00ca;
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DelayedEnsureSpecialObjectAttributes>d__41 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedEnsureSpecialObjectAttributes>d__41(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (IsDrifterPresent)
					{
						GrabbableObjectPatches.EnsureAllGrabbableObjectsHaveSpecialObjectAttributes();
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DelayedGrabbableComponentTypesUpdate>d__44 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedGrabbableComponentTypesUpdate>d__44(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					PluginConfig.ClearGrabbableComponentTypesCache();
					if (IsDrifterPresent)
					{
						GrabbableObjectPatches.EnsureAllGrabbableObjectsHaveSpecialObjectAttributes();
					}
					_grabbableComponentTypesUpdateCoroutine = null;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DelayedUpdateBalanceSubTabVisibility>d__46 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedUpdateBalanceSubTabVisibility>d__46(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)Instance != (Object)null)
					{
						Instance.UpdateBalanceSubTabVisibility();
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DelayedUpdateBottomlessBagVisibility>d__102 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedUpdateBottomlessBagVisibility>d__102(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)Instance != (Object)null)
					{
						Instance.UpdateBottomlessBagVisibility();
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DelayedUpdateDrifterPresence>d__43 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedUpdateDrifterPresence>d__43(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					IsDrifterPresent = (Object)(object)Object.FindAnyObjectByType<DrifterBagController>() != (Object)null;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DelayedUpdateHudSubTabVisibility>d__45 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedUpdateHudSubTabVisibility>d__45(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)Instance != (Object)null)
					{
						Instance.UpdateHudSubTabVisibility();
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DelayedUpdateRooVisibility>d__101 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedUpdateRooVisibility>d__101(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)Instance != (Object)null)
					{
						Instance.UpdateHudSubTabVisibility();
						Instance.UpdateBalanceSubTabVisibility();
						Instance.UpdateBottomlessBagVisibility();
						Instance.UpdateBalanceVisibility();
						Instance.UpdateHudVisibility();
						Instance.UpdateRecoveryVisibility();
						Instance.UpdatePersistenceVisibility();
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this