Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of DrifterBossGrab v1.9.1
plugins/DrifterBossGrab/DrifterBossGrab.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
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.ChampRushReaper; using EntityStates.Drifter; using EntityStates.Drifter.Bag; using EntityStates.SolusHeart.PhasePreFight; 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.CharacterAI; using RoR2.HudOverlay; using RoR2.Networking; using RoR2.Projectile; using RoR2.Skills; using RoR2.SolusWeb; 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.Sprites; 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.9.1.0")] [assembly: AssemblyInformationalVersion("1.9.1")] [assembly: AssemblyProduct("DrifterBossGrab")] [assembly: AssemblyTitle("DrifterBossGrab")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.9.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 { internal static class EliteIdentity { internal static IEnumerable<EliteDef> Enumerate(CharacterBody? body) { if (!Object.op_Implicit((Object)(object)body) || BuffCatalog.eliteBuffIndices == null) { yield break; } BuffIndex[] eliteBuffIndices = BuffCatalog.eliteBuffIndices; foreach (BuffIndex val in eliteBuffIndices) { if (body.HasBuff(val)) { EliteDef val2 = BuffCatalog.GetBuffDef(val)?.eliteDef; if (Object.op_Implicit((Object)(object)val2)) { yield return val2; } } } } } public class PluginConfig { private static bool updatingEliteSelection; 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[10] { HudElementType.All, HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.WeightIcon, HudElementType.DamagePreview, HudElementType.CapacityUI, HudElementType.CardDetails, HudElementType.Cards, HudElementType.Animations, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ENABLE_HUD_EDITOR.CHECKBOX"] = new HudElementType[10] { HudElementType.All, HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.WeightIcon, HudElementType.DamagePreview, HudElementType.CapacityUI, HudElementType.CardDetails, HudElementType.Cards, HudElementType.Animations, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ENABLE_CAROUSEL_HUD.CHECKBOX"] = new HudElementType[7] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Cards, HudElementType.Animations, HudElementType.Layout, HudElementType.CardDetails, HudElementType.WeightIcon }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CAROUSEL_ORIENTATION.CHOICE"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SELECTED_CARD_POSITION.CHOICE"] = new HudElementType[4] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Cards, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.VISIBLE_CARDS.INT_FIELD"] = new HudElementType[4] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Cards, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ITEM_SPACING.FLOAT_FIELD"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CARD_RELEASE_ANIMATION.CHECKBOX"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CARD_RELEASE_DURATION.STEP_SLIDER"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CARD_RELEASE_DISTANCE.STEP_SLIDER"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CARD_DESTRUCTION_ANIMATION.CHECKBOX"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CARD_DESTRUCTION_DURATION.STEP_SLIDER"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.BREAKOUT_WARNING_STRENGTH.STEP_SLIDER"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.BREAKOUT_WARNING.CHECKBOX"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CARD_DAMAGE_WIGGLE.CHECKBOX"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CARD_DAMAGE_WIGGLE_STRENGTH.STEP_SLIDER"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ANIMATION_DURATION.FLOAT_FIELD"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ENABLE_INACTIVITY_FADE.CHECKBOX"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.INACTIVITY_FADE_DELAY_(S).FLOAT_FIELD"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.INACTIVITY_FADE_DURATION_(S).FLOAT_FIELD"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.INACTIVE_OPACITY.FLOAT_FIELD"] = new HudElementType[3] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Animations }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.MAIN_SLOT_X_OFFSET.FLOAT_FIELD"] = new HudElementType[2] { HudElementType.MainSlot, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.MAIN_SLOT_Y_OFFSET.FLOAT_FIELD"] = new HudElementType[2] { HudElementType.MainSlot, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.MAIN_SLOT_SCALE.FLOAT_FIELD"] = new HudElementType[2] { HudElementType.MainSlot, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.MAIN_SLOT_OPACITY.FLOAT_FIELD"] = new HudElementType[2] { HudElementType.MainSlot, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_ICON_(MAIN).CHECKBOX"] = new HudElementType[2] { HudElementType.MainSlot, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_BACKGROUND_(MAIN).CHECKBOX"] = new HudElementType[2] { HudElementType.MainSlot, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_WEIGHT_ICON_(MAIN).CHECKBOX"] = new HudElementType[2] { HudElementType.MainSlot, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_NAME_(MAIN).CHECKBOX"] = new HudElementType[2] { HudElementType.MainSlot, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_HEALTH_(MAIN).CHECKBOX"] = new HudElementType[2] { HudElementType.MainSlot, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_SLOT_#_(MAIN).CHECKBOX"] = new HudElementType[2] { HudElementType.MainSlot, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SIDE_SLOT_X_OFFSET.FLOAT_FIELD"] = new HudElementType[2] { HudElementType.SideSlots, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SIDE_SLOT_Y_OFFSET.FLOAT_FIELD"] = new HudElementType[2] { HudElementType.SideSlots, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SIDE_SLOT_SCALE.FLOAT_FIELD"] = new HudElementType[2] { HudElementType.SideSlots, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SIDE_SLOT_OPACITY.FLOAT_FIELD"] = new HudElementType[2] { HudElementType.SideSlots, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_ICON_(SIDE).CHECKBOX"] = new HudElementType[2] { HudElementType.SideSlots, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_BACKGROUND_(SIDE).CHECKBOX"] = new HudElementType[2] { HudElementType.SideSlots, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_WEIGHT_ICON_(SIDE).CHECKBOX"] = new HudElementType[2] { HudElementType.SideSlots, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_NAME_(SIDE).CHECKBOX"] = new HudElementType[2] { HudElementType.SideSlots, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_HEALTH_(SIDE).CHECKBOX"] = new HudElementType[2] { HudElementType.SideSlots, HudElementType.Cards }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.SHOW_SLOT_#_(SIDE).CHECKBOX"] = new HudElementType[2] { HudElementType.SideSlots, HudElementType.Cards }, ["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.ELITE_HEALTH_BAR_COLORS.CHECKBOX"] = new HudElementType[4] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Cards, HudElementType.DamagePreview }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.ELITE_HEALTH_BAR_COLOR_INTENSITY.STEP_SLIDER"] = new HudElementType[4] { HudElementType.MainSlot, HudElementType.SideSlots, HudElementType.Cards, HudElementType.DamagePreview }, ["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.CAPACITY_FILL_SMOOTHING.CHECKBOX"] = new HudElementType[1] { HudElementType.CapacityUI }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CAPACITY_FILL_SMOOTH_TIME.STEP_SLIDER"] = new HudElementType[1] { HudElementType.CapacityUI }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CAPACITY_FLASHES.CHECKBOX"] = new HudElementType[1] { HudElementType.CapacityUI }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CAPACITY_FLASH_STRENGTH.STEP_SLIDER"] = new HudElementType[1] { HudElementType.CapacityUI }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CAPACITY_FLASH_DURATION.STEP_SLIDER"] = new HudElementType[1] { HudElementType.CapacityUI }, ["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[2] { HudElementType.CapacityUI, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CAPACITY_UI_Y_POS.FLOAT_FIELD"] = new HudElementType[2] { HudElementType.CapacityUI, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CAPACITY_UI_SCALE.FLOAT_FIELD"] = new HudElementType[2] { HudElementType.CapacityUI, HudElementType.Layout }, ["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_CARD_DETAILS.CHECKBOX"] = new HudElementType[1] { HudElementType.CardDetails }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CARD_DETAILS_SCALE.FLOAT_FIELD"] = new HudElementType[2] { HudElementType.CardDetails, HudElementType.Layout }, ["COM.PWDCAT.DRIFTERBOSSGRAB.HUD.CARD_DETAILS_COLOR.COLOR"] = new HudElementType[1] { HudElementType.CardDetails } }; public static readonly Dictionary<string, BalanceSubTabType[]> BalanceSettingToSubTab = new Dictionary<string, BalanceSubTabType[]> { ["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.BREAKOUT_TIME_FORMULA.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Formulas }, ["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_FORMULA.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Formulas }, ["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.BREAKOUT_HIT_LIMIT.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Formulas }, ["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; internal ConfigEntry<string> EliteThrowEffectSelection { get; private set; } public static PluginConfig Instance => _instance ?? (_instance = new PluginConfig()); public ConfigEntry<bool> EnableBossGrabbing { get; private set; } public ConfigEntry<bool> EnableSelfGrabbing { 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<bool> EnableDebugLogs { 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<CarouselOrientation> CarouselOrientation { get; private set; } public ConfigEntry<SelectedCardPosition> SelectedCardPlacement { get; private set; } public ConfigEntry<int> VisibleCardCount { get; private set; } public ConfigEntry<float> CarouselSpacing { get; private set; } public ConfigEntry<float> CarouselAnimationDuration { get; private set; } public ConfigEntry<bool> EnableCarouselInactivityFade { get; private set; } public ConfigEntry<bool> EnableCardReleaseAnimation { get; private set; } public ConfigEntry<float> CardReleaseDuration { get; private set; } public ConfigEntry<float> CardReleaseDistance { get; private set; } public ConfigEntry<bool> EnableCardDestructionAnimation { get; private set; } public ConfigEntry<float> CardDestructionDuration { get; private set; } public ConfigEntry<float> BreakoutWarningStrength { get; private set; } public ConfigEntry<bool> EnableBreakoutWarning { get; private set; } public ConfigEntry<bool> EnableCardDamageWiggle { get; private set; } public ConfigEntry<float> CardDamageWiggleStrength { get; private set; } public ConfigEntry<float> CarouselInactivityFadeDelay { get; private set; } public ConfigEntry<float> CarouselInactivityFadeDuration { get; private set; } public ConfigEntry<float> CarouselInactivityFadeOpacity { 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> CenterSlotShowBackground { 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> SideSlotShowBackground { 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> 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<float> EliteHealthBarColorIntensity { get; private set; } public ConfigEntry<bool> EnableDamagePreview { get; private set; } public ConfigEntry<Color> DamagePreviewColor { get; private set; } public ConfigEntry<bool> SmoothCapacityFill { get; private set; } public ConfigEntry<float> CapacityFillSmoothTime { get; private set; } public ConfigEntry<bool> EnableCapacityFlashes { get; private set; } public ConfigEntry<float> CapacityFlashStrength { get; private set; } public ConfigEntry<float> CapacityFlashDuration { 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<string> BreakoutTimeFormula { get; private set; } public ConfigEntry<string> GrabRangeFormula { get; private set; } public ConfigEntry<string> MaxSmacksFormula { 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) { Instance.EnableBalance = cfg.Bind<bool>("Balance", "EnableBalance", false, "Enable bag mass limits and penalties."); Instance.MassCapacityFormula = cfg.Bind<string>("Balance", "MassCapacityFormula", "C * MC", "Set the bag's mass limit. Variables: H (Max HP), L (Level), C (Stocks), MC (Mass Cap config), S (Stage)."); Instance.MovespeedPenaltyFormula = cfg.Bind<string>("Balance", "MovespeedPenaltyFormula", "0", "Set the movement speed penalty. Variables: 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)", "Set the slam damage multiplier. Variables: BASE_COEF, MASS_SCALING, BM (Bagged Mass), MC (Mass Cap), N (Passenger Count)."); Instance.StateCalculationMode = cfg.Bind<StateCalculationMode>("Balance", "StateCalculationMode", DrifterBossGrabMod.StateCalculationMode.Current, "Use stats from the selected passenger (Current) or the whole bag (All)."); Instance.AoEDamageDistribution = cfg.Bind<AoEDamageMode>("Balance", "AoEDamageDistribution", AoEDamageMode.Full, "Choose how slams damage other passengers. Requires All stats mode. None: selected passenger only. Full: full damage to each. Split: divide damage between passengers."); Instance.OverencumbranceMax = cfg.Bind<float>("Balance", "OverencumbranceMax", 100f, "Maximum percentage over the bag's mass limit."); Instance.BreakoutTimeFormula = cfg.Bind<string>("Balance", "BreakoutTimeFormula", "", "Set the time between breakout attempts as a multiplier. H/L/C refer to Drifter; S=stage, N=passenger count, T=total mass, PM=passenger mass, PH/PL=passenger max health/level, BT=base interval in seconds. Flags such as ELITE/BOSS refer to the passenger (0 or 1). Passenger health, level and flags are 0 for objects without a character body."); Instance.GrabRangeFormula = cfg.Bind<string>("Balance", "GrabRangeFormula", "", "Set the grab range multiplier. H/L/C refer to Drifter; S=stage, N=passenger count, T=total mass. Flag variables are not supported."); Instance.MaxSmacksFormula = cfg.Bind<string>("Balance", "MaxSmacksFormula", "", "Set how many hits it takes for the selected passenger to break out. H/L/C refer to Drifter; S=stage, N=passenger count, T=total mass, PM=passenger mass, PH/PL=passenger max health/level. Flags such as ELITE/BOSS refer to the passenger (0 or 1). Passenger health, level and flags are 0 for objects without a character body. Rounded down to a whole number. INF disables hit-based breakout."); Instance.MaxLaunchSpeed = cfg.Bind<string>("Balance", "MaxLaunchSpeed", "30", "Maximum speed of passengers when they break out."); Instance.BagScaleCap = cfg.Bind<string>("Balance", "BagScaleCap", "1", "Maximum visual size of the bag."); Instance.MassCap = cfg.Bind<string>("Balance", "MassCap", "700", "Maximum mass counted for each passenger."); WireBalanceEventHandlers(); } private static void WireBalanceEventHandlers() { Instance.MassCapacityFormula.SettingChanged += delegate { string text = FormulaParser.Validate(Instance.MassCapacityFormula.Value); if (text != null) { Log.Warning("[PluginConfig] Invalid MassCapacityFormula: " + text); } DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0); foreach (DrifterBagController bagController in array) { CapacityScalingSystem.RecalculateCapacity(bagController); } }; Instance.StateCalculationMode.SettingChanged += delegate { DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0); foreach (DrifterBagController bagController in array) { CapacityScalingSystem.RecalculateState(bagController); } }; Instance.MovespeedPenaltyFormula.SettingChanged += delegate { string text = FormulaParser.Validate(Instance.MovespeedPenaltyFormula.Value); if (text != null) { Log.Warning("[PluginConfig] Invalid MovespeedPenaltyFormula: " + text); } DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0); foreach (DrifterBagController bagController in array) { CapacityScalingSystem.RecalculatePenalty(bagController); } }; Instance.BagScaleCap.SettingChanged += delegate { Instance.RefreshCachedConfigStrings(); DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0); foreach (DrifterBagController controller in array) { BagPassengerManager.ForceRecalculateMass(controller); } }; Instance.MassCap.SettingChanged += delegate { Instance.RefreshCachedConfigStrings(); DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0); foreach (DrifterBagController controller in array) { 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 InitEliteThrowEffectsConfig(ConfigFile cfg) { BalanceSettingToSubTab["COM.PWDCAT.DRIFTERBOSSGRAB.BALANCE.ELITE_EFFECTS.STRING_INPUT_FIELD"] = new BalanceSubTabType[1] { BalanceSubTabType.Formulas }; Instance.EliteThrowEffectSelection = cfg.Bind<string>("Hidden", "EliteThrowEffectSelection", "", "Elite effects on throw / grab"); Instance.EliteThrowEffectSelection.SettingChanged += delegate { if (updatingEliteSelection) { return; } updatingEliteSelection = true; try { EliteThrowEffectsAPI.ApplySelectionIds(Instance.EliteThrowEffectSelection.Value); } finally { updatingEliteSelection = false; } }; EliteThrowEffectsAPI.Initialize(cfg); } internal static void RefreshEliteThrowSelection() { if (updatingEliteSelection || Instance.EliteThrowEffectSelection == null) { return; } updatingEliteSelection = true; try { Instance.EliteThrowEffectSelection.Value = EliteThrowEffectsAPI.SelectionIds; } finally { updatingEliteSelection = false; } } 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, "Limit Repossess recharge to the remaining bag slots, using the final bag capacity. Keeps at least 1 stock available and does not raise your normal stock limit."); Instance.EnableSuccessiveGrabStockRefresh = cfg.Bind<bool>("Bottomless Bag", "EnableSuccessiveGrabStockRefresh", false, "Refresh Repossess stocks after a successful grab leaves you at 0."); Instance.CycleCooldown = cfg.Bind<float>("Bottomless Bag", "CycleCooldown", 0.2f, "Seconds between passenger switches."); Instance.PlayAnimationOnCycle = cfg.Bind<bool>("Bottomless Bag", "PlayAnimationOnCycle", false, "Play the grab animation when switching passengers."); Instance.EnableMouseWheelScrolling = cfg.Bind<bool>("Bottomless Bag", "EnableMouseWheelScrolling", true, "Switch passengers with the mouse wheel."); Instance.InverseMouseWheelScrolling = cfg.Bind<bool>("Bottomless Bag", "InverseMouseWheelScrolling", false, "Reverse the mouse wheel direction for switching passengers."); Instance.AutoPromoteMainSeat = cfg.Bind<bool>("Bottomless Bag", "AutoPromoteMainSeat", false, "Select the next passenger when the main passenger is removed."); Instance.PrioritizeMainSeat = cfg.Bind<bool>("Bottomless Bag", "PrioritizeMainSeat", false, "Make newly grabbed objects the main passenger."); Instance.SlotScalingFormula = cfg.Bind<string>("Bottomless Bag", "SlotScalingFormula", "C + 2", "Set the number of bag slots. Variables: H (Max HP), L (Level), C (Stocks), MC (Mass Cap), S (Stage). Use INF for unlimited slots."); 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 elites. Variables: 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 bosses. Variables: 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 champions. Variables: 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 players. Variables: 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 minions. Variables: 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 drones. Variables: 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 enemies. Variables: 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 enemies. Variables: 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("Mass multiplier applied to all enemies. Variables: 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 the selected flag. Variables: 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 text = FormulaParser.Validate(Instance.EliteFlagMultiplier.Value); if (text != null) { Log.Warning("[PluginConfig] Invalid EliteFlagMultiplier: " + text); } DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0); foreach (DrifterBagController controller in array) { BagPassengerManager.ForceRecalculateMass(controller); } }; Instance.BossFlagMultiplier.SettingChanged += delegate { string text = FormulaParser.Validate(Instance.BossFlagMultiplier.Value); if (text != null) { Log.Warning("[PluginConfig] Invalid BossFlagMultiplier: " + text); } DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0); foreach (DrifterBagController controller in array) { BagPassengerManager.ForceRecalculateMass(controller); } }; Instance.ChampionFlagMultiplier.SettingChanged += delegate { string text = FormulaParser.Validate(Instance.ChampionFlagMultiplier.Value); if (text != null) { Log.Warning("[PluginConfig] Invalid ChampionFlagMultiplier: " + text); } DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0); foreach (DrifterBagController controller in array) { BagPassengerManager.ForceRecalculateMass(controller); } }; Instance.PlayerFlagMultiplier.SettingChanged += delegate { string text = FormulaParser.Validate(Instance.PlayerFlagMultiplier.Value); if (text != null) { Log.Warning("[PluginConfig] Invalid PlayerFlagMultiplier: " + text); } DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0); foreach (DrifterBagController controller in array) { BagPassengerManager.ForceRecalculateMass(controller); } }; Instance.MinionFlagMultiplier.SettingChanged += delegate { string text = FormulaParser.Validate(Instance.MinionFlagMultiplier.Value); if (text != null) { Log.Warning("[PluginConfig] Invalid MinionFlagMultiplier: " + text); } DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0); foreach (DrifterBagController controller in array) { BagPassengerManager.ForceRecalculateMass(controller); } }; Instance.DroneFlagMultiplier.SettingChanged += delegate { string text = FormulaParser.Validate(Instance.DroneFlagMultiplier.Value); if (text != null) { Log.Warning("[PluginConfig] Invalid DroneFlagMultiplier: " + text); } DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0); foreach (DrifterBagController controller in array) { BagPassengerManager.ForceRecalculateMass(controller); } }; Instance.MechanicalFlagMultiplier.SettingChanged += delegate { string text = FormulaParser.Validate(Instance.MechanicalFlagMultiplier.Value); if (text != null) { Log.Warning("[PluginConfig] Invalid MechanicalFlagMultiplier: " + text); } DrifterBagController[] array = Object.FindObjectsByType<DrifterBagController>((FindObjectsSortMode)0); foreach (DrifterBagController controller in array) { BagPassengerManager.ForceRecalculateMass(controller); } }; Instance.VoidFlagMultiplier.SettingChanged += delegate { string text = FormulaParser.Validate(Instance.VoidFlagMultiplier.Value); if (text != null) { Log.Warning("[PluginConfig] Invalid VoidFlagMultiplier: " + text); } 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 value = Instance.SelectedFlag.Value; string value2 = Instance.SelectedFlagMultiplier.Value; switch (value) { case CharacterFlagType.Elite: Instance.EliteFlagMultiplier.Value = value2; break; case CharacterFlagType.Boss: Instance.BossFlagMultiplier.Value = value2; break; case CharacterFlagType.Champion: Instance.ChampionFlagMultiplier.Value = value2; break; case CharacterFlagType.Player: Instance.PlayerFlagMultiplier.Value = value2; break; case CharacterFlagType.Minion: Instance.MinionFlagMultiplier.Value = value2; break; case CharacterFlagType.Drone: Instance.DroneFlagMultiplier.Value = value2; break; case CharacterFlagType.Mechanical: Instance.MechanicalFlagMultiplier.Value = value2; break; case CharacterFlagType.Void: Instance.VoidFlagMultiplier.Value = value2; break; case CharacterFlagType.All: Instance.AllFlagMultiplier.Value = value2; 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, "Apply a preset when selected."); Instance.LastSelectedPreset = cfg.Bind<PresetType>("Hidden", "LastSelectedPreset", (PresetType)(-1), "Last applied preset."); Instance.EnableBossGrabbing = cfg.Bind<bool>("General", "EnableBossGrabbing", true, "Allow grabbing bosses."); Instance.EnableSelfGrabbing = cfg.Bind<bool>("General", "EnableSelfGrabbing", false, "Look up at least 68 degrees and double-tap Repossess within 0.3 seconds to grab yourself."); Instance.EnableNPCGrabbing = cfg.Bind<bool>("General", "EnableNPCGrabbing", false, "Allow grabbing NPCs that cannot normally be grabbed."); 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, "Choose which projectiles you can grab."); Instance.EnableDebugLogs = cfg.Bind<bool>("General", "EnableDebugLogs", false, "Write extra logs 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,GhostBladesProjectile,LunarSunProjectile", "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", "Block objects whose names contain these keywords. 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 value"); Instance.EnableConfigSync = cfg.Bind<bool>("General", "EnableConfigSync", true, "Use the host's gameplay settings for all players."); } private static void InitHudConfig(ConfigFile cfg) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Expected O, but got Unknown //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Expected O, but got Unknown //IL_063f: Unknown result type (might be due to invalid IL or missing references) //IL_0721: Unknown result type (might be due to invalid IL or missing references) //IL_072b: Expected O, but got Unknown //IL_0774: Unknown result type (might be due to invalid IL or missing references) //IL_07d6: Unknown result type (might be due to invalid IL or missing references) //IL_07e0: Expected O, but got Unknown //IL_0833: Unknown result type (might be due to invalid IL or missing references) //IL_083d: Expected O, but got Unknown //IL_0870: Unknown result type (might be due to invalid IL or missing references) //IL_087a: Expected O, but got Unknown //IL_0973: Unknown result type (might be due to invalid IL or missing references) //IL_09ab: Unknown result type (might be due to invalid IL or missing references) //IL_09e3: Unknown result type (might be due to invalid IL or missing references) //IL_0a1b: Unknown result type (might be due to invalid IL or missing references) //IL_0a53: Unknown result type (might be due to invalid IL or missing references) //IL_0a8b: Unknown result type (might be due to invalid IL or missing references) Instance.EnableCarouselHUD = cfg.Bind<bool>("Hud", "EnableCarouselHUD", false, "Show the bag carousel."); Instance.EnableCardReleaseAnimation = cfg.Bind<bool>("Hud", "EnableCardReleaseAnimation", true, "Make cards fly out when passengers leave the bag."); Instance.CardReleaseDuration = cfg.Bind<float>("Hud", "CardReleaseDuration", 0.28f, new ConfigDescription("Release animation duration in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.8f), Array.Empty<object>())); Instance.CardReleaseDistance = cfg.Bind<float>("Hud", "CardReleaseDistance", 90f, new ConfigDescription("How far released cards fly, in HUD units.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 180f), Array.Empty<object>())); Instance.EnableCardDestructionAnimation = cfg.Bind<bool>("Hud", "EnableCardDestructionAnimation", true, "Shrink and fade cards when their passenger is destroyed."); Instance.CardDestructionDuration = cfg.Bind<float>("Hud", "CardDestructionDuration", 0.18f, new ConfigDescription("Destruction animation duration in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.8f), Array.Empty<object>())); Instance.BreakoutWarningStrength = cfg.Bind<float>("Hud", "BreakoutWarningStrength", 5f, new ConfigDescription("How much portraits shake before breakout attempts. Set to 0 to disable.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); Instance.EnableBreakoutWarning = cfg.Bind<bool>("Hud", "EnableBreakoutWarning", true, "Shake passenger portraits before breakout attempts."); Instance.EnableCardDamageWiggle = cfg.Bind<bool>("Hud", "EnableCardDamageWiggle", true, "Wiggle passenger portraits when bag slams deal damage or reduce durability."); Instance.CardDamageWiggleStrength = cfg.Bind<float>("Hud", "CardDamageWiggleStrength", 1f, new ConfigDescription("How much portraits wiggle on slam damage. Set to 0 to disable.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); Instance.CarouselOrientation = cfg.Bind<CarouselOrientation>("Hud", "CarouselOrientation", DrifterBossGrabMod.CarouselOrientation.Vertical, "Arrange cards vertically or horizontally."); Instance.SelectedCardPlacement = cfg.Bind<SelectedCardPosition>("Hud", "SelectedCardPlacement", SelectedCardPosition.Center, "Selected card position: Center, Start (top/left), or End (bottom/right)."); Instance.VisibleCardCount = cfg.Bind<int>("Hud", "VisibleCardCount", 3, new ConfigDescription("Maximum number of visible carousel cards.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); Instance.CarouselSpacing = cfg.Bind<float>("Hud", "CarouselSpacing", 45f, "Space between cards."); Instance.CarouselAnimationDuration = cfg.Bind<float>("Hud", "CarouselAnimationDuration", 0.4f, "Seconds for cards to move when switching passengers."); Instance.EnableCarouselInactivityFade = cfg.Bind<bool>("Hud", "EnableCarouselInactivityFade", false, "Fade the carousel when idle."); Instance.CarouselInactivityFadeDelay = cfg.Bind<float>("Hud", "CarouselInactivityFadeDelay", 3f, "Seconds idle before the carousel starts fading."); Instance.CarouselInactivityFadeDuration = cfg.Bind<float>("Hud", "CarouselInactivityFadeDuration", 0.2f, "Seconds for the carousel to fade out."); Instance.CarouselInactivityFadeOpacity = cfg.Bind<float>("Hud", "CarouselInactivityFadeOpacity", 0f, "Carousel opacity when idle. Set to 0 to hide it."); 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.CenterSlotShowBackground = cfg.Bind<bool>("Hud", "CenterSlotShowBackground", true, "Show background 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.SideSlotShowBackground = cfg.Bind<bool>("Hud", "SideSlotShowBackground", true, "Show background 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.EnableBaggedObjectInfo = cfg.Bind<bool>("Hud", "EnableBaggedObjectInfo", false, "Show breakout time and extra bag details while holding Info/Tab. Requires Carousel HUD."); Instance.BaggedObjectInfoScale = cfg.Bind<float>("Hud", "BaggedObjectInfoScale", 1f, "Text size for card details."); Instance.BaggedObjectInfoColor = cfg.Bind<Color>("Hud", "BaggedObjectInfoColor", new Color(1f, 1f, 1f, 0.9f), "Text color for card details."); Instance.UseNewWeightIcon = cfg.Bind<bool>("Hud", "UseNewWeightIcon", false, "Use the custom weight icon."); Instance.WeightDisplayMode = cfg.Bind<WeightDisplayMode>("Hud", "WeightDisplayMode", DrifterBossGrabMod.WeightDisplayMode.Multiplier, "Choose how passenger weight is displayed."); Instance.ScaleWeightColor = cfg.Bind<bool>("Hud", "ScaleWeightColor", true, "Change the weight icon color based on 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.EliteHealthBarColorIntensity = cfg.Bind<float>("Hud", "EliteHealthBarColorIntensity", 1f, new ConfigDescription("Elite tint strength for passenger health bars and damage preview. 0 uses normal colors, 1 uses the original elite colors, and 2 strengthens the tint.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); Instance.EnableDamagePreview = cfg.Bind<bool>("Hud", "EnableDamagePreview", false, "Show how much health the next slam will remove."); Instance.DamagePreviewColor = cfg.Bind<Color>("Hud", "DamagePreviewColor", new Color(1f, 0.15f, 0.15f, 0.8f), "Color for damage preview."); Instance.SmoothCapacityFill = cfg.Bind<bool>("Hud", "SmoothCapacityFill", true, "Smooth changes to capacity and overencumbrance fill."); Instance.CapacityFillSmoothTime = cfg.Bind<float>("Hud", "CapacityFillSmoothTime", 0.1f, new ConfigDescription("Fill smoothing time in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 0.3f), Array.Empty<object>())); Instance.EnableCapacityFlashes = cfg.Bind<bool>("Hud", "EnableCapacityFlashes", true, "Highlight new fill and flash at capacity and overencumbrance limits."); Instance.CapacityFlashStrength = cfg.Bind<float>("Hud", "CapacityFlashStrength", 1f, new ConfigDescription("Flash strength relative to the default.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); Instance.CapacityFlashDuration = cfg.Bind<float>("Hud", "CapacityFlashDuration", 0.32f, new ConfigDescription("Limit flash duration in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 0.8f), Array.Empty<object>())); Instance.EnableMassCapacityUI = cfg.Bind<bool>("Hud", "EnableMassCapacityUI", false, "Show the mass capacity 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 limit markers on the mass capacity bar."); Instance.GradientIntensity = cfg.Bind<float>("Hud", "GradientIntensity", 1f, "Strength of the capacity bar gradient."); 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, "Open the HUD editor. Edit your layout in a run or use sample cards from the menus."); Instance.IsHudEditorEnabled.Value = false; WireHudEventHandlers(); } private static void WireHudEventHandlers() { Instance.EliteHealthBarColorIntensity.SettingChanged += delegate { UpdateDamagePreviewColors(); }; Instance.EnableCarouselHUD.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.CarouselOrientation.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.SelectedCardPlacement.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.VisibleCardCount.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.CarouselSpacing.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.CarouselAnimationDuration.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.EnableCarouselInactivityFade.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.CarouselInactivityFadeDelay.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.CarouselInactivityFadeDuration.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.CarouselInactivityFadeOpacity.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.CenterSlotShowIcon.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.CenterSlotShowBackground.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.CenterSlotShowWeightIcon.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.CenterSlotShowName.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.CenterSlotShowHealthBar.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.CenterSlotShowSlotNumber.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.SideSlotShowIcon.SettingChanged += delegate { UpdateBagUIToggles(); }; Instance.SideSlotShowBackground.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, "Keep bagged objects between stages."); Instance.EnableAutoGrab = cfg.Bind<bool>("Persistence", "EnableAutoGrab", false, "Automatically grab saved objects when a stage starts."); Instance.PersistBaggedBosses = cfg.Bind<bool>("Persistence", "PersistBaggedBosses", true, "Keep bagged bosses between stages."); Instance.PersistBaggedNPCs = cfg.Bind<bool>("Persistence", "PersistBaggedNPCs", true, "Keep bagged NPCs between stages."); Instance.PersistBaggedEnvironmentObjects = cfg.Bind<bool>("Persistence", "PersistBaggedEnvironmentObjects", true, "Keep bagged environment objects between stages."); Instance.PersistenceBlacklist = cfg.Bind<string>("Persistence", "PersistenceBlacklist", "", "Objects to leave behind when changing stages. Comma-separated."); Instance.AutoGrabDelay = cfg.Bind<float>("Persistence", "AutoGrabDelay", 1f, "Seconds to wait before automatically grabbing saved objects."); } 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); InitEliteThrowEffectsConfig(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> value = Instance._blacklistCache.Value; HashSet<string> hashSet = new HashSet<string>(value, StringComparer.OrdinalIgnoreCase); foreach (string item in value) { hashSet.Add(item + "(Clone)"); } return hashSet; }); 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> value = Instance._recoveryBlacklistCache.Value; HashSet<string> hashSet = new HashSet<string>(value, StringComparer.OrdinalIgnoreCase); foreach (string item2 in value) { hashSet.Add(item2 + "(Clone)"); } return hashSet; }); 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> GetSlotShowBackgroundConfig(HudElementType slot) { if (slot != HudElementType.MainSlot) { return Instance.SideSlotShowBackground; } return Instance.CenterSlotShowBackground; } 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", false, "Recover bagged objects that fall off the map."); Instance.EnemyRecoveryMode = cfg.Bind<EnemyRecoveryMode>("Recovery", "EnemyRecoveryMode", DrifterBossGrabMod.EnemyRecoveryMode.Kill, "Choose what happens to bagged enemies that fall off the map."); Instance.RecoverBaggedBosses = cfg.Bind<bool>("Recovery", "RecoverBaggedBosses", false, "Recover bagged bosses that fall off the map."); Instance.RecoverBaggedNPCs = cfg.Bind<bool>("Recovery", "RecoverBaggedNPCs", false, "Recover bagged NPCs that fall off the map."); Instance.RecoverBaggedEnvironmentObjects = cfg.Bind<bool>("Recovery", "RecoverBaggedEnvironmentObjects", false, "Recover bagged environment objects that fall off the map."); } } 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.BreakoutTimeFormula.SettingChanged += configChangedHandler; PluginConfig.Instance.GrabRangeFormula.SettingChanged += configChangedHandler; PluginConfig.Instance.MaxSmacksFormula.SettingChanged += configChangedHandler; PluginConfig.Instance.EnableBossGrabbing.SettingChanged += configChangedHandler; PluginConfig.Instance.EnableSelfGrabbing.SettingChanged += configChangedHandler; PluginConfig.Instance.EnableNPCGrabbing.SettingChanged += configChangedHandler; PluginConfig.Instance.EnableEnvironmentGrabbing.SettingChanged += configChangedHandler; PluginConfig.Instance.EnableLockedObjectGrabbing.SettingChanged += configChangedHandler; PluginConfig.Instance.ProjectileGrabbingMode.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.CarouselOrientation.SettingChanged += configChangedHandler; PluginConfig.Instance.CarouselSpacing.SettingChanged += configChangedHandler; PluginConfig.Instance.VisibleCardCount.SettingChanged += configChangedHandler; PluginConfig.Instance.SelectedCardPlacement.SettingChanged += configChangedHandler; PluginConfig.Instance.CarouselAnimationDuration.SettingChanged += configChangedHandler; PluginConfig.Instance.EnableCarouselInactivityFade.SettingChanged += configChangedHandler; PluginConfig.Instance.CarouselInactivityFadeDelay.SettingChanged += configChangedHandler; PluginConfig.Instance.CarouselInactivityFadeDuration.SettingChanged += configChangedHandler; PluginConfig.Instance.CarouselInactivityFadeOpacity.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.CenterSlotShowBackground.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.SideSlotShowBackground.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.EliteHealthBarColorIntensity.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.BreakoutTimeFormula.SettingChanged -= configChangedHandler; PluginConfig.Instance.GrabRangeFormula.SettingChanged -= configChangedHandler; PluginConfig.Instance.MaxSmacksFormula.SettingChanged -= configChangedHandler; PluginConfig.Instance.EnableBossGrabbing.SettingChanged -= configChangedHandler; PluginConfig.Instance.EnableSelfGrabbing.SettingChanged -= configChangedHandler; PluginConfig.Instance.EnableNPCGrabbing.SettingChanged -= configChangedHandler; PluginConfig.Instance.EnableEnvironmentGrabbing.SettingChanged -= configChangedHandler; PluginConfig.Instance.EnableLockedObjectGrabbing.SettingChanged -= configChangedHandler; PluginConfig.Instance.ProjectileGrabbingMode.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.CarouselOrientation.SettingChanged -= configChangedHandler; PluginConfig.Instance.CarouselSpacing.SettingChanged -= configChangedHandler; PluginConfig.Instance.VisibleCardCount.SettingChanged -= configChangedHandler; PluginConfig.Instance.SelectedCardPlacement.SettingChanged -= configChangedHandler; PluginConfig.Instance.CarouselAnimationDuration.SettingChanged -= configChangedHandler; PluginConfig.Instance.EnableCarouselInactivityFade.SettingChanged -= configChangedHandler; PluginConfig.Instance.CarouselInactivityFadeDelay.SettingChanged -= configChangedHandler; PluginConfig.Instance.CarouselInactivityFadeDuration.SettingChanged -= configChangedHandler; PluginConfig.Instance.CarouselInactivityFadeOpacity.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.CenterSlotShowBackground.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.SideSlotShowBackground.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.EliteHealthBarColorIntensity.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 SelectedCardPosition { Center, Start, End } public enum CarouselOrientation { Vertical, Horizontal } public enum HudElementType { All, MainSlot, SideSlots, WeightIcon, DamagePreview, CapacityUI, CardDetails, Cards, Animations, Layout } 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();