using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using On.RoR2; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("InteractableCreditMultiplier")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+10b9c7857b1d8b3b837207edd7035312d23a4844")] [assembly: AssemblyProduct("InteractableCreditMultiplier")] [assembly: AssemblyTitle("InteractableCreditMultiplier")] [assembly: AssemblyVersion("1.0.0.0")] public enum PrefabCategory { None, TieredChest, CategorizedChest, MultiShop, Drone, Printer } public enum PrefabType { Unknown, ChestT1, ChestT2, ChestT3, ChestCatDamage, ChestCatHealing, ChestCatUtility, ChestAdaptive, ChestCloaked, ChestLunar, BarrelMoney, BarrelMoneyVoid, BarrelEquipment, MultiShopSmall, MultiShopLarge, MultiShopEquipment, ShrineBlood, ShrineMountain, ShrineCombat, ShrineHealing, ShrineChance, ShrineOrder, ShrineShaping, ShrineCleanse, PrinterT1, PrinterT2, PrinterRedBoss, Scrapper, DroneGunner, DroneHealing, DroneTurret, DroneMissile, DroneIncinerator, DroneEmergency, DroneEquipment, DroneTC280, VoidSeed, VoidCradle, VoidTriple } namespace InteractableCreditMultiplier; public class ConfigHandler { public static ConfigEntry InteractableCreditMultiplier { get; private set; } public static ConfigEntry MaxTieredChestsTotal { get; private set; } public static ConfigEntry MaxTier1Chests { get; private set; } public static ConfigEntry MaxTier2Chests { get; private set; } public static ConfigEntry MaxTier3Chests { get; private set; } public static ConfigEntry MaxPerCategoryChests { get; private set; } public static ConfigEntry MaxAdaptiveChests { get; private set; } public static ConfigEntry MaxCloakedChests { get; private set; } public static ConfigEntry MaxLunarChests { get; private set; } public static ConfigEntry IgnoreTier3Chests { get; private set; } public static ConfigEntry IgnoreCloakedChests { get; private set; } public static ConfigEntry MaxMoneyBarrels { get; private set; } public static ConfigEntry MaxVoidCoinBarrels { get; private set; } public static ConfigEntry MaxEquipmentBarrels { get; private set; } public static ConfigEntry MaxPrinters { get; private set; } public static ConfigEntry MaxScrappers { get; private set; } public static ConfigEntry IgnoreRedAndBossPrinters { get; private set; } public static ConfigEntry MaxBloodShrines { get; private set; } public static ConfigEntry MaxCombatShrines { get; private set; } public static ConfigEntry MaxWoodlandShrines { get; private set; } public static ConfigEntry MaxMountainShrines { get; private set; } public static ConfigEntry MaxChanceShrines { get; private set; } public static ConfigEntry MaxOrderShrines { get; private set; } public static ConfigEntry MaxShapingShrines { get; private set; } public static ConfigEntry MaxCleansingPools { get; private set; } public static ConfigEntry MaxVoidSeeds { get; private set; } public static ConfigEntry MaxVoidCradles { get; private set; } public static ConfigEntry MaxVoidTriples { get; private set; } public static ConfigEntry MaxDronesTotal { get; private set; } public static ConfigEntry MaxDronesPerType { get; private set; } public static ConfigEntry MaxTotalMultishops { get; private set; } public static ConfigEntry MaxTier1Multishops { get; private set; } public static ConfigEntry MaxTier2Multishops { get; private set; } public static ConfigEntry MaxEquipmentMultishops { get; private set; } public static ConfigEntry IgnoreEquipmentMultishops { get; private set; } public static ConfigEntry EnableSoftCaps { get; private set; } public static ConfigEntry SoftCapBypassChance { get; private set; } public static ConfigEntry SoftCapScaling { get; private set; } public static ConfigEntry VerboseCreditLogging { get; private set; } public static ConfigEntry LogSpawnedPrefabs { get; private set; } public static ConfigEntry LogPreventedSpawns { get; private set; } public static ConfigEntry LogUncategorizedPrefabs { get; private set; } public static ConfigEntry DebugSpawnTracker { get; private set; } public static void InitConfig(ConfigFile config) { //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Unknown result type (might be due to invalid IL or missing references) //IL_04e3: Unknown result type (might be due to invalid IL or missing references) //IL_04f3: Expected O, but got Unknown //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_04f8: Expected O, but got Unknown //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_050a: Unknown result type (might be due to invalid IL or missing references) //IL_0517: Expected O, but got Unknown //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_051c: Expected O, but got Unknown //IL_0522: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Unknown result type (might be due to invalid IL or missing references) //IL_053b: Expected O, but got Unknown //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_0540: Expected O, but got Unknown //IL_0546: Unknown result type (might be due to invalid IL or missing references) //IL_054b: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_055f: Expected O, but got Unknown //IL_055a: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Expected O, but got Unknown //IL_056a: Unknown result type (might be due to invalid IL or missing references) //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_0576: Unknown result type (might be due to invalid IL or missing references) //IL_0583: Expected O, but got Unknown //IL_057e: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Expected O, but got Unknown //IL_058e: Unknown result type (might be due to invalid IL or missing references) //IL_0593: Unknown result type (might be due to invalid IL or missing references) //IL_059a: Unknown result type (might be due to invalid IL or missing references) //IL_05a7: Expected O, but got Unknown //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05ac: Expected O, but got Unknown //IL_05b2: Unknown result type (might be due to invalid IL or missing references) //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_05be: Unknown result type (might be due to invalid IL or missing references) //IL_05cb: Expected O, but got Unknown //IL_05c6: Unknown result type (might be due to invalid IL or missing references) //IL_05d0: Expected O, but got Unknown //IL_05d6: Unknown result type (might be due to invalid IL or missing references) //IL_05db: Unknown result type (might be due to invalid IL or missing references) //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_05ef: Expected O, but got Unknown //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05f4: Expected O, but got Unknown //IL_05fa: Unknown result type (might be due to invalid IL or missing references) //IL_05ff: Unknown result type (might be due to invalid IL or missing references) //IL_0606: Unknown result type (might be due to invalid IL or missing references) //IL_0613: Expected O, but got Unknown //IL_060e: Unknown result type (might be due to invalid IL or missing references) //IL_0618: Expected O, but got Unknown //IL_061e: Unknown result type (might be due to invalid IL or missing references) //IL_0628: Expected O, but got Unknown //IL_062e: Unknown result type (might be due to invalid IL or missing references) //IL_0638: Expected O, but got Unknown //IL_063e: Unknown result type (might be due to invalid IL or missing references) //IL_0643: Unknown result type (might be due to invalid IL or missing references) //IL_064a: Unknown result type (might be due to invalid IL or missing references) //IL_0657: Expected O, but got Unknown //IL_0652: Unknown result type (might be due to invalid IL or missing references) //IL_065c: Expected O, but got Unknown //IL_0662: Unknown result type (might be due to invalid IL or missing references) //IL_0667: Unknown result type (might be due to invalid IL or missing references) //IL_066e: Unknown result type (might be due to invalid IL or missing references) //IL_067b: Expected O, but got Unknown //IL_0676: Unknown result type (might be due to invalid IL or missing references) //IL_0680: Expected O, but got Unknown //IL_0686: Unknown result type (might be due to invalid IL or missing references) //IL_068b: Unknown result type (might be due to invalid IL or missing references) //IL_0692: Unknown result type (might be due to invalid IL or missing references) //IL_069f: Expected O, but got Unknown //IL_069a: Unknown result type (might be due to invalid IL or missing references) //IL_06a4: Expected O, but got Unknown //IL_06aa: Unknown result type (might be due to invalid IL or missing references) //IL_06af: Unknown result type (might be due to invalid IL or missing references) //IL_06b6: Unknown result type (might be due to invalid IL or missing references) //IL_06c3: Expected O, but got Unknown //IL_06be: Unknown result type (might be due to invalid IL or missing references) //IL_06c8: Expected O, but got Unknown //IL_06ce: Unknown result type (might be due to invalid IL or missing references) //IL_06d3: Unknown result type (might be due to invalid IL or missing references) //IL_06da: Unknown result type (might be due to invalid IL or missing references) //IL_06e7: Expected O, but got Unknown //IL_06e2: Unknown result type (might be due to invalid IL or missing references) //IL_06ec: Expected O, but got Unknown //IL_06f2: Unknown result type (might be due to invalid IL or missing references) //IL_06fc: Expected O, but got Unknown //IL_0702: Unknown result type (might be due to invalid IL or missing references) //IL_0707: Unknown result type (might be due to invalid IL or missing references) //IL_070e: Unknown result type (might be due to invalid IL or missing references) //IL_071b: Expected O, but got Unknown //IL_0716: Unknown result type (might be due to invalid IL or missing references) //IL_0720: Expected O, but got Unknown //IL_0726: Unknown result type (might be due to invalid IL or missing references) //IL_072b: Unknown result type (might be due to invalid IL or missing references) //IL_0732: Unknown result type (might be due to invalid IL or missing references) //IL_073f: Expected O, but got Unknown //IL_073a: Unknown result type (might be due to invalid IL or missing references) //IL_0744: Expected O, but got Unknown //IL_074a: Unknown result type (might be due to invalid IL or missing references) //IL_074f: Unknown result type (might be due to invalid IL or missing references) //IL_0756: Unknown result type (might be due to invalid IL or missing references) //IL_0763: Expected O, but got Unknown //IL_075e: Unknown result type (might be due to invalid IL or missing references) //IL_0768: Expected O, but got Unknown //IL_076e: Unknown result type (might be due to invalid IL or missing references) //IL_0773: Unknown result type (might be due to invalid IL or missing references) //IL_077a: Unknown result type (might be due to invalid IL or missing references) //IL_0787: Expected O, but got Unknown //IL_0782: Unknown result type (might be due to invalid IL or missing references) //IL_078c: Expected O, but got Unknown //IL_0792: Unknown result type (might be due to invalid IL or missing references) //IL_0797: Unknown result type (might be due to invalid IL or missing references) //IL_079e: Unknown result type (might be due to invalid IL or missing references) //IL_07ab: Expected O, but got Unknown //IL_07a6: Unknown result type (might be due to invalid IL or missing references) //IL_07b0: Expected O, but got Unknown //IL_07b6: Unknown result type (might be due to invalid IL or missing references) //IL_07bb: Unknown result type (might be due to invalid IL or missing references) //IL_07c2: Unknown result type (might be due to invalid IL or missing references) //IL_07cf: Expected O, but got Unknown //IL_07ca: Unknown result type (might be due to invalid IL or missing references) //IL_07d4: Expected O, but got Unknown //IL_07da: Unknown result type (might be due to invalid IL or missing references) //IL_07df: Unknown result type (might be due to invalid IL or missing references) //IL_07e6: Unknown result type (might be due to invalid IL or missing references) //IL_07f3: Expected O, but got Unknown //IL_07ee: Unknown result type (might be due to invalid IL or missing references) //IL_07f8: Expected O, but got Unknown //IL_07fe: Unknown result type (might be due to invalid IL or missing references) //IL_0803: Unknown result type (might be due to invalid IL or missing references) //IL_080a: Unknown result type (might be due to invalid IL or missing references) //IL_0817: Expected O, but got Unknown //IL_0812: Unknown result type (might be due to invalid IL or missing references) //IL_081c: Expected O, but got Unknown //IL_0822: Unknown result type (might be due to invalid IL or missing references) //IL_0827: Unknown result type (might be due to invalid IL or missing references) //IL_082e: Unknown result type (might be due to invalid IL or missing references) //IL_083a: Expected O, but got Unknown //IL_0835: Unknown result type (might be due to invalid IL or missing references) //IL_083f: Expected O, but got Unknown //IL_0845: Unknown result type (might be due to invalid IL or missing references) //IL_084a: Unknown result type (might be due to invalid IL or missing references) //IL_0851: Unknown result type (might be due to invalid IL or missing references) //IL_085e: Expected O, but got Unknown //IL_0859: Unknown result type (might be due to invalid IL or missing references) //IL_0863: Expected O, but got Unknown //IL_0869: Unknown result type (might be due to invalid IL or missing references) //IL_086e: Unknown result type (might be due to invalid IL or missing references) //IL_0875: Unknown result type (might be due to invalid IL or missing references) //IL_0882: Expected O, but got Unknown //IL_087d: Unknown result type (might be due to invalid IL or missing references) //IL_0887: Expected O, but got Unknown //IL_088d: Unknown result type (might be due to invalid IL or missing references) //IL_0892: Unknown result type (might be due to invalid IL or missing references) //IL_0899: Unknown result type (might be due to invalid IL or missing references) //IL_08a6: Expected O, but got Unknown //IL_08a1: Unknown result type (might be due to invalid IL or missing references) //IL_08ab: Expected O, but got Unknown //IL_08b1: Unknown result type (might be due to invalid IL or missing references) //IL_08b6: Unknown result type (might be due to invalid IL or missing references) //IL_08bd: Unknown result type (might be due to invalid IL or missing references) //IL_08ca: Expected O, but got Unknown //IL_08c5: Unknown result type (might be due to invalid IL or missing references) //IL_08cf: Expected O, but got Unknown //IL_08d5: Unknown result type (might be due to invalid IL or missing references) //IL_08da: Unknown result type (might be due to invalid IL or missing references) //IL_08e1: Unknown result type (might be due to invalid IL or missing references) //IL_08ee: Expected O, but got Unknown //IL_08e9: Unknown result type (might be due to invalid IL or missing references) //IL_08f3: Expected O, but got Unknown //IL_08f9: Unknown result type (might be due to invalid IL or missing references) //IL_08fe: Unknown result type (might be due to invalid IL or missing references) //IL_0905: Unknown result type (might be due to invalid IL or missing references) //IL_0912: Expected O, but got Unknown //IL_090d: Unknown result type (might be due to invalid IL or missing references) //IL_0917: Expected O, but got Unknown //IL_091d: Unknown result type (might be due to invalid IL or missing references) //IL_0922: Unknown result type (might be due to invalid IL or missing references) //IL_0929: Unknown result type (might be due to invalid IL or missing references) //IL_0936: Expected O, but got Unknown //IL_0931: Unknown result type (might be due to invalid IL or missing references) //IL_093b: Expected O, but got Unknown //IL_0941: Unknown result type (might be due to invalid IL or missing references) //IL_094b: Expected O, but got Unknown //IL_0951: Unknown result type (might be due to invalid IL or missing references) //IL_095b: Expected O, but got Unknown //IL_0961: Unknown result type (might be due to invalid IL or missing references) //IL_096b: Expected O, but got Unknown //IL_0971: Unknown result type (might be due to invalid IL or missing references) //IL_097b: Expected O, but got Unknown //IL_0981: Unknown result type (might be due to invalid IL or missing references) //IL_098b: Expected O, but got Unknown //IL_0991: Unknown result type (might be due to invalid IL or missing references) //IL_099b: Expected O, but got Unknown //IL_09a1: Unknown result type (might be due to invalid IL or missing references) //IL_09ab: Expected O, but got Unknown //IL_09b1: Unknown result type (might be due to invalid IL or missing references) //IL_09bb: Expected O, but got Unknown InteractableCreditMultiplier = config.Bind("General", "InteractableCreditMultiplier", 1.5f, "A fixed multiplier for your interactable credits"); MaxTieredChestsTotal = config.Bind("ChestLimits", "MaxTieredChestsTotal", 25, "Maximum total number of tiered chests allowed"); MaxTier1Chests = config.Bind("ChestLimits", "MaxTier1Chests", 15, "Maximum number of Tier 1 chests allowed"); MaxTier2Chests = config.Bind("ChestLimits", "MaxTier2Chests", 8, "Maximum number of Tier 2 chests allowed"); MaxTier3Chests = config.Bind("ChestLimits", "MaxTier3Chests", 3, "Maximum number of Tier 3 chests allowed"); MaxPerCategoryChests = config.Bind("ChestLimits", "MaxPerCategoryChests", 5, "Maximum number of categorized chests allowed per-type"); MaxAdaptiveChests = config.Bind("ChestLimits", "MaxAdaptiveChests", 5, "Maximum number of adaptive chests allowed"); MaxCloakedChests = config.Bind("ChestLimits", "MaxCloakedChests", 5, "Maximum number of cloaked chests allowed"); MaxLunarChests = config.Bind("ChestLimits", "MaxLunarChests", 2, "Maximum number of lunar chests allowed"); IgnoreTier3Chests = config.Bind("ChestLimits", "IgnoreTier3Chests", true, "If enabled, the limiter system will not count legendary chests towards total tiered chests limit"); IgnoreCloakedChests = config.Bind("ChestLimits", "IgnoreCloakedChests", true, "If enabled, the limiter system will not count cloaked chests towards total tiered chests limit"); MaxMoneyBarrels = config.Bind("BarrelLimits", "MaxMoneyBarrels", 10, "Maximum number of barrels allowed"); MaxVoidCoinBarrels = config.Bind("BarrelLimits", "MaxVoidCoinBarrels", 10, "Maximum number of void coin \"barrels\" (The ones that look like stalks) allowed"); MaxEquipmentBarrels = config.Bind("BarrelLimits", "MaxEquipmentBarrels", 3, "Maximum number of equipment barrels"); MaxPrinters = config.Bind("PrinterAndScrapperLimits", "MaxPrinters", 5, "Maximum number of printers allowed"); MaxScrappers = config.Bind("PrinterAndScrapperLimits", "MaxScrappers", 3, "Maximum number of scrappers allowed"); IgnoreRedAndBossPrinters = config.Bind("PrinterAndScrapperLimits", "IgnoreRedAndBossPrinters", true, "If enabled, the limiter system will never touch red or boss item printers"); MaxMountainShrines = config.Bind("ShrineLimits", "MaxMountainShrines", 3, "Maximum number of mountain shrines allowed"); MaxBloodShrines = config.Bind("ShrineLimits", "MaxBloodShrines", 3, "Maximum number of blood shrines allowed"); MaxCombatShrines = config.Bind("ShrineLimits", "MaxCombatShrines", 3, "Maximum number of combat shrines allowed"); MaxWoodlandShrines = config.Bind("ShrineLimits", "MaxWoodlandShrines", 3, "Maximum number of woodland shrines allowed"); MaxChanceShrines = config.Bind("ShrineLimits", "MaxChanceShrines", 3, "Maximum number of chance shrines allowed"); MaxOrderShrines = config.Bind("ShrineLimits", "MaxOrderShrines", 3, "Maximum number of order shrines allowed"); MaxShapingShrines = config.Bind("ShrineLimits", "MaxShapingShrines", 3, "Maximum number of shaping shrines allowed"); MaxCleansingPools = config.Bind("ShrineLimits", "MaxCleansingPools", 3, "Maximum number of cleansing pools allowed"); MaxVoidSeeds = config.Bind("VoidLimits", "MaxVoidSeeds", 2, "Maximum number of void seeds allowed"); MaxVoidCradles = config.Bind("VoidLimits", "MaxVoidCradles", 5, "Maximum number of void cradles allowed"); MaxVoidTriples = config.Bind("VoidLimits", "MaxVoidTriples", 5, "Maximum number of void triple cradles allowed"); MaxDronesTotal = config.Bind("DroneLimits", "MaxDronesTotal", 10, "Maximum total number of drones allowed"); MaxDronesPerType = config.Bind("DroneLimits", "MaxDronesPerType", 4, "Maximum number of drones of a single type allowed"); MaxTotalMultishops = config.Bind("ShopsLimits", "MaxTotalMultishops", 10, "Maximum total number of multishops allowed"); MaxTier1Multishops = config.Bind("ShopsLimits", "MaxTier1Multishops", 6, "Maximum number of tier 1 multishops allowed"); MaxTier2Multishops = config.Bind("ShopsLimits", "MaxTier2Multishops", 4, "Maximum number of tier 2 multishops allowed"); MaxEquipmentMultishops = config.Bind("ShopsLimits", "MaxEquipmentMultishops", 4, "Maximum number of equipment multishops allowed"); IgnoreEquipmentMultishops = config.Bind("ShopsLimits", "IgnoreEquipmentMultishops", true, "If enabled, the limiter system will not count equipment multishops towards multi-shop category max"); EnableSoftCaps = config.Bind("PitySystem", "EnableSoftCaps", true, "Enable soft caps in the pity system"); SoftCapBypassChance = config.Bind("PitySystem", "SoftCapBypassChance", 0.2f, "Chance to bypass the soft cap"); SoftCapScaling = config.Bind("PitySystem", "SoftCapScaling", true, "Scale the soft cap effect for every failed attempt, resets on success"); VerboseCreditLogging = config.Bind("Debug", "VerboseCreditLogging", false, "Enable verbose logging for credit tracking"); LogSpawnedPrefabs = config.Bind("Debug", "LogSpawnedPrefabs", false, "Log details about spawned prefabs"); LogPreventedSpawns = config.Bind("Debug", "LogPreventedSpawns", false, "Log when a spawn is forcefully prevented"); LogUncategorizedPrefabs = config.Bind("Debug", "LogUncategorizedPrefabs", false, "Log details about uncategorized prefabs"); DebugSpawnTracker = config.Bind("Debug", "DebugSpawnTracker", false, "If enabled, logs a summary of scene interactable counts after scene population."); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(InteractableCreditMultiplier, new StepSliderConfig { min = 0.5f, max = 100f, increment = 0.25f })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxTieredChestsTotal, new IntSliderConfig { min = -1, max = 100 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxTier1Chests, new IntSliderConfig { min = -1, max = 50 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxTier2Chests, new IntSliderConfig { min = -1, max = 50 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxTier3Chests, new IntSliderConfig { min = -1, max = 20 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxPerCategoryChests, new IntSliderConfig { min = -1, max = 50 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxAdaptiveChests, new IntSliderConfig { min = -1, max = 50 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxCloakedChests, new IntSliderConfig { min = -1, max = 50 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxLunarChests, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(IgnoreTier3Chests)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(IgnoreCloakedChests)); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxMoneyBarrels, new IntSliderConfig { min = -1, max = 100 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxVoidCoinBarrels, new IntSliderConfig { min = -1, max = 50 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxEquipmentBarrels, new IntSliderConfig { min = -1, max = 20 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxPrinters, new IntSliderConfig { min = -1, max = 50 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxScrappers, new IntSliderConfig { min = -1, max = 50 })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(IgnoreRedAndBossPrinters)); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxMountainShrines, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxBloodShrines, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxCombatShrines, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxWoodlandShrines, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxChanceShrines, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxOrderShrines, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxShapingShrines, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxCleansingPools, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxVoidSeeds, new IntSliderConfig { min = -1, max = 5 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxVoidCradles, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxVoidTriples, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxDronesTotal, new IntSliderConfig { min = -1, max = 100 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxDronesPerType, new IntSliderConfig { min = -1, max = 20 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxTotalMultishops, new IntSliderConfig { min = -1, max = 50 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxTier1Multishops, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxTier2Multishops, new IntSliderConfig { min = -1, max = 25 })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(EnableSoftCaps)); ModSettingsManager.AddOption((BaseOption)new SliderOption(SoftCapBypassChance)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(SoftCapScaling)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(VerboseCreditLogging)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(LogSpawnedPrefabs)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(LogPreventedSpawns)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(LogUncategorizedPrefabs)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(DebugSpawnTracker)); } } public class DebugUtils { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_PopulateScene <>9__0_0; public static Action <>9__0_1; public static Action <>9__0_2; public static hook_PlaceTeleporter <>9__0_3; internal void b__0_0(orig_PopulateScene orig, SceneDirector self) { if (ConfigHandler.VerboseCreditLogging.Value) { Main.Log.LogInfo((object)$"[InteractableCreditMultiplier] [DEBUG] Final credits: {self.interactableCredit}"); } orig.Invoke(self); } internal void b__0_1(SceneDirector self) { if (ConfigHandler.VerboseCreditLogging.Value) { Main.Log.LogInfo((object)$"[InteractableCreditMultiplier] [DEBUG] PrePopulate: {self.interactableCredit}"); } } internal void b__0_2(SceneDirector self) { if (ConfigHandler.VerboseCreditLogging.Value) { Main.Log.LogInfo((object)$"[InteractableCreditMultiplier] [DEBUG] PostPopulate: {self.interactableCredit}"); } } internal void b__0_3(orig_PlaceTeleporter orig, SceneDirector self) { if (ConfigHandler.VerboseCreditLogging.Value) { Main.Log.LogInfo((object)$"[ICM DEBUG] Before Teleporter: {self.interactableCredit}"); } orig.Invoke(self); if (ConfigHandler.VerboseCreditLogging.Value) { Main.Log.LogInfo((object)$"[ICM DEBUG] After Teleporter: {self.interactableCredit}"); } } } public static void InitDebugHooks() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { hook_PopulateScene val = delegate(orig_PopulateScene orig, SceneDirector self) { if (ConfigHandler.VerboseCreditLogging.Value) { Main.Log.LogInfo((object)$"[InteractableCreditMultiplier] [DEBUG] Final credits: {self.interactableCredit}"); } orig.Invoke(self); }; <>c.<>9__0_0 = val; obj = (object)val; } SceneDirector.PopulateScene += (hook_PopulateScene)obj; SceneDirector.onPrePopulateSceneServer += delegate(SceneDirector self) { if (ConfigHandler.VerboseCreditLogging.Value) { Main.Log.LogInfo((object)$"[InteractableCreditMultiplier] [DEBUG] PrePopulate: {self.interactableCredit}"); } }; SceneDirector.onPostPopulateSceneServer += delegate(SceneDirector self) { if (ConfigHandler.VerboseCreditLogging.Value) { Main.Log.LogInfo((object)$"[InteractableCreditMultiplier] [DEBUG] PostPopulate: {self.interactableCredit}"); } }; object obj2 = <>c.<>9__0_3; if (obj2 == null) { hook_PlaceTeleporter val2 = delegate(orig_PlaceTeleporter orig, SceneDirector self) { if (ConfigHandler.VerboseCreditLogging.Value) { Main.Log.LogInfo((object)$"[ICM DEBUG] Before Teleporter: {self.interactableCredit}"); } orig.Invoke(self); if (ConfigHandler.VerboseCreditLogging.Value) { Main.Log.LogInfo((object)$"[ICM DEBUG] After Teleporter: {self.interactableCredit}"); } }; <>c.<>9__0_3 = val2; obj2 = (object)val2; } SceneDirector.PlaceTeleporter += (hook_PlaceTeleporter)obj2; } } public class GeneralHooks { public static void InitHooks() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown SceneDirector.onPrePopulateSceneServer += OnPrePopulateSceneServer; SceneDirector.onPostPopulateSceneServer += OnPostPopulateSceneServer; DirectorCore.TrySpawnObject += new hook_TrySpawnObject(OnTrySpawnObject); } private static void OnPrePopulateSceneServer(SceneDirector self) { Main.CurrentSpawnTracker = new SceneSpawnTracker(); float value = ConfigHandler.InteractableCreditMultiplier.Value; int interactableCredit = self.interactableCredit; int num2 = (self.interactableCredit = (int)((float)interactableCredit * value)); Main.Log.LogInfo((object)$"[InteractableCreditMultiplier] Credits: {interactableCredit} -> {num2}"); } private static GameObject OnTrySpawnObject(orig_TrySpawnObject orig, DirectorCore self, DirectorSpawnRequest request) { SpawnCard spawnCard = request.spawnCard; InteractableSpawnCard val = (InteractableSpawnCard)(object)((spawnCard is InteractableSpawnCard) ? spawnCard : null); if ((Object)(object)val != (Object)null) { GameObject prefab = ((SpawnCard)val).prefab; PrefabEntry prefabEntry = PrefabHandler.GetPrefabEntry(prefab); bool flag = PrefabHandler.IsSpawnAllowed(prefabEntry); GameObject val2 = orig.Invoke(self, request); if (!flag) { if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } if (ConfigHandler.LogPreventedSpawns.Value) { Main.Log.LogInfo((object)$"Prevented spawn of {prefabEntry.Prefab} ({prefabEntry.Category})"); } return val2; } Main.CurrentSpawnTracker?.RegisterSpawn(prefab, prefabEntry.Prefab, prefabEntry.Category); return val2; } return orig.Invoke(self, request); } private static void OnPostPopulateSceneServer(SceneDirector self) { if (Main.CurrentSpawnTracker != null && ConfigHandler.DebugSpawnTracker.Value) { Main.CurrentSpawnTracker.LogTrackerResults(); } Main.CurrentSpawnTracker = null; } } [BepInPlugin("com.workes.interactablecreditmultiplier", "Interactable Credit Multiplier", "1.3.0")] public class Main : BaseUnityPlugin { public static ManualLogSource Log { get; private set; } public static SceneSpawnTracker CurrentSpawnTracker { get; set; } public void Awake() { Log = ((BaseUnityPlugin)this).Logger; ConfigHandler.InitConfig(((BaseUnityPlugin)this).Config); PrefabHandler.InitPrefabHandler(); GeneralHooks.InitHooks(); DebugUtils.InitDebugHooks(); Log.LogInfo((object)"[InteractableCreditMultiplier] Mod loaded"); } } public class PrefabEntry { public PrefabType Prefab { get; } public PrefabCategory Category { get; } public PrefabEntry(PrefabType prefab, PrefabCategory category) { Prefab = prefab; Category = category; } } public static class PrefabHandler { private static Dictionary prefabMap; private static Dictionary> individualPrefabLimiters; public static void InitPrefabHandler() { PrefabCategory category = ((!ConfigHandler.IgnoreCloakedChests.Value) ? PrefabCategory.TieredChest : PrefabCategory.None); PrefabCategory category2 = ((!ConfigHandler.IgnoreRedAndBossPrinters.Value) ? PrefabCategory.Printer : PrefabCategory.None); PrefabCategory category3 = ((!ConfigHandler.IgnoreTier3Chests.Value) ? PrefabCategory.TieredChest : PrefabCategory.None); PrefabCategory category4 = ((!ConfigHandler.IgnoreEquipmentMultishops.Value) ? PrefabCategory.MultiShop : PrefabCategory.None); prefabMap = new Dictionary { { "Chest1", new PrefabEntry(PrefabType.ChestT1, PrefabCategory.TieredChest) }, { "Chest2", new PrefabEntry(PrefabType.ChestT2, PrefabCategory.TieredChest) }, { "GoldChest", new PrefabEntry(PrefabType.ChestT3, category3) }, { "CategoryChestDamage", new PrefabEntry(PrefabType.ChestCatDamage, PrefabCategory.CategorizedChest) }, { "CategoryChest2Damage Variant", new PrefabEntry(PrefabType.ChestCatDamage, PrefabCategory.CategorizedChest) }, { "CategoryChestHealing", new PrefabEntry(PrefabType.ChestCatHealing, PrefabCategory.CategorizedChest) }, { "CategoryChest2Healing Variant", new PrefabEntry(PrefabType.ChestCatHealing, PrefabCategory.CategorizedChest) }, { "CategoryChestUtility", new PrefabEntry(PrefabType.ChestCatUtility, PrefabCategory.CategorizedChest) }, { "CategoryChest2Utility Variant", new PrefabEntry(PrefabType.ChestCatUtility, PrefabCategory.CategorizedChest) }, { "Chest1StealthedVariant", new PrefabEntry(PrefabType.ChestCloaked, category) }, { "Chest2StealthedVariant", new PrefabEntry(PrefabType.ChestCloaked, category) }, { "CasinoChest", new PrefabEntry(PrefabType.ChestAdaptive, PrefabCategory.None) }, { "LunarChest", new PrefabEntry(PrefabType.ChestLunar, PrefabCategory.None) }, { "Barrel1", new PrefabEntry(PrefabType.BarrelMoney, PrefabCategory.None) }, { "VoidCoinBarrel", new PrefabEntry(PrefabType.BarrelMoneyVoid, PrefabCategory.None) }, { "EquipmentBarrel", new PrefabEntry(PrefabType.BarrelEquipment, PrefabCategory.None) }, { "TripleShop", new PrefabEntry(PrefabType.MultiShopSmall, PrefabCategory.MultiShop) }, { "TripleShopLarge", new PrefabEntry(PrefabType.MultiShopLarge, PrefabCategory.MultiShop) }, { "TripleShopEquipment", new PrefabEntry(PrefabType.MultiShopEquipment, category4) }, { "VoidCamp", new PrefabEntry(PrefabType.VoidSeed, PrefabCategory.None) }, { "VoidChest", new PrefabEntry(PrefabType.VoidCradle, PrefabCategory.None) }, { "VoidTriple", new PrefabEntry(PrefabType.VoidTriple, PrefabCategory.None) }, { "Duplicator", new PrefabEntry(PrefabType.PrinterT1, PrefabCategory.Printer) }, { "DuplicatorLarge", new PrefabEntry(PrefabType.PrinterT2, PrefabCategory.Printer) }, { "DuplicatorMilitary", new PrefabEntry(PrefabType.PrinterRedBoss, category2) }, { "DuplicatorWild", new PrefabEntry(PrefabType.PrinterRedBoss, category2) }, { "Scrapper", new PrefabEntry(PrefabType.Scrapper, PrefabCategory.None) }, { "ShrineBlood", new PrefabEntry(PrefabType.ShrineBlood, PrefabCategory.None) }, { "ShrineBloodSandy Variant", new PrefabEntry(PrefabType.ShrineBlood, PrefabCategory.None) }, { "ShrineBloodSnowy Variant", new PrefabEntry(PrefabType.ShrineBlood, PrefabCategory.None) }, { "ShrineCombat", new PrefabEntry(PrefabType.ShrineCombat, PrefabCategory.None) }, { "ShrineCombatSandy Variant", new PrefabEntry(PrefabType.ShrineCombat, PrefabCategory.None) }, { "ShrineCombatSnowy Variant", new PrefabEntry(PrefabType.ShrineCombat, PrefabCategory.None) }, { "ShrineBoss", new PrefabEntry(PrefabType.ShrineMountain, PrefabCategory.None) }, { "ShrineBossSandy Variant", new PrefabEntry(PrefabType.ShrineMountain, PrefabCategory.None) }, { "ShrineBossSnowy Variant", new PrefabEntry(PrefabType.ShrineMountain, PrefabCategory.None) }, { "ShrineHealing", new PrefabEntry(PrefabType.ShrineHealing, PrefabCategory.None) }, { "ShrineRestack", new PrefabEntry(PrefabType.ShrineOrder, PrefabCategory.None) }, { "ShrineRestackSandy Variant", new PrefabEntry(PrefabType.ShrineOrder, PrefabCategory.None) }, { "ShrineRestackSnowy Variant", new PrefabEntry(PrefabType.ShrineOrder, PrefabCategory.None) }, { "ShrineColossusAccess", new PrefabEntry(PrefabType.ShrineShaping, PrefabCategory.None) }, { "ShrineChance", new PrefabEntry(PrefabType.ShrineChance, PrefabCategory.None) }, { "ShrineChanceSandy Variant", new PrefabEntry(PrefabType.ShrineChance, PrefabCategory.None) }, { "ShrineChanceSnowy Variant", new PrefabEntry(PrefabType.ShrineChance, PrefabCategory.None) }, { "ShrineCleanse", new PrefabEntry(PrefabType.ShrineCleanse, PrefabCategory.None) }, { "Drone1Broken", new PrefabEntry(PrefabType.DroneGunner, PrefabCategory.Drone) }, { "Drone2Broken", new PrefabEntry(PrefabType.DroneHealing, PrefabCategory.Drone) }, { "Turret1Broken", new PrefabEntry(PrefabType.DroneTurret, PrefabCategory.Drone) }, { "MissileDroneBroken", new PrefabEntry(PrefabType.DroneMissile, PrefabCategory.Drone) }, { "FlameDroneBroken", new PrefabEntry(PrefabType.DroneIncinerator, PrefabCategory.Drone) }, { "EquipmentDroneBroken", new PrefabEntry(PrefabType.DroneEquipment, PrefabCategory.Drone) }, { "EmergencyDroneBroken", new PrefabEntry(PrefabType.DroneEmergency, PrefabCategory.Drone) }, { "MegaDroneBroken", new PrefabEntry(PrefabType.DroneTC280, PrefabCategory.Drone) } }; individualPrefabLimiters = new Dictionary> { { PrefabType.ChestT1, ConfigHandler.MaxTier1Chests }, { PrefabType.ChestT2, ConfigHandler.MaxTier2Chests }, { PrefabType.ChestT3, ConfigHandler.MaxTier3Chests }, { PrefabType.ChestAdaptive, ConfigHandler.MaxAdaptiveChests }, { PrefabType.ChestCloaked, ConfigHandler.MaxCloakedChests }, { PrefabType.ChestLunar, ConfigHandler.MaxLunarChests }, { PrefabType.BarrelMoney, ConfigHandler.MaxMoneyBarrels }, { PrefabType.BarrelMoneyVoid, ConfigHandler.MaxVoidCoinBarrels }, { PrefabType.BarrelEquipment, ConfigHandler.MaxEquipmentBarrels }, { PrefabType.Scrapper, ConfigHandler.MaxScrappers }, { PrefabType.ShrineBlood, ConfigHandler.MaxBloodShrines }, { PrefabType.ShrineCombat, ConfigHandler.MaxCombatShrines }, { PrefabType.ShrineHealing, ConfigHandler.MaxWoodlandShrines }, { PrefabType.ShrineMountain, ConfigHandler.MaxMountainShrines }, { PrefabType.ShrineChance, ConfigHandler.MaxChanceShrines }, { PrefabType.ShrineOrder, ConfigHandler.MaxOrderShrines }, { PrefabType.ShrineShaping, ConfigHandler.MaxShapingShrines }, { PrefabType.ShrineCleanse, ConfigHandler.MaxCleansingPools }, { PrefabType.VoidSeed, ConfigHandler.MaxVoidSeeds }, { PrefabType.VoidCradle, ConfigHandler.MaxVoidCradles }, { PrefabType.VoidTriple, ConfigHandler.MaxVoidTriples }, { PrefabType.MultiShopSmall, ConfigHandler.MaxTier1Multishops }, { PrefabType.MultiShopLarge, ConfigHandler.MaxTier2Multishops }, { PrefabType.MultiShopEquipment, ConfigHandler.MaxEquipmentMultishops } }; } public static PrefabEntry GetPrefabEntry(GameObject go) { if ((Object)(object)go == (Object)null) { return new PrefabEntry(PrefabType.Unknown, PrefabCategory.None); } string text = ((Object)go).name; if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - "(Clone)".Length); } if (prefabMap.TryGetValue(text, out var value)) { return value; } return new PrefabEntry(PrefabType.Unknown, PrefabCategory.None); } public static bool IsSpawnAllowed(PrefabEntry entry) { switch (entry.Category) { case PrefabCategory.TieredChest: if (ConfigHandler.MaxTieredChestsTotal.Value >= 0 && GetCategoryCount(PrefabCategory.TieredChest) >= ConfigHandler.MaxTieredChestsTotal.Value) { return false; } break; case PrefabCategory.Printer: if (ConfigHandler.MaxPrinters.Value >= 0 && GetCategoryCount(PrefabCategory.Printer) >= ConfigHandler.MaxPrinters.Value) { return false; } break; case PrefabCategory.Drone: if (ConfigHandler.MaxDronesTotal.Value >= 0 && GetCategoryCount(PrefabCategory.Drone) >= ConfigHandler.MaxDronesTotal.Value) { return false; } break; } if (entry.Category == PrefabCategory.Drone && ConfigHandler.MaxDronesPerType.Value >= 0 && GetPrefabCount(entry.Prefab) >= ConfigHandler.MaxDronesPerType.Value) { return false; } if (entry.Category == PrefabCategory.CategorizedChest && ConfigHandler.MaxPerCategoryChests.Value >= 0 && GetPrefabCount(entry.Prefab) >= ConfigHandler.MaxPerCategoryChests.Value) { return false; } if (individualPrefabLimiters.ContainsKey(entry.Prefab) && individualPrefabLimiters[entry.Prefab].Value >= 0 && GetPrefabCount(entry.Prefab) >= individualPrefabLimiters[entry.Prefab].Value) { return false; } return true; } public static int GetPrefabCount(PrefabType prefab) { if (Main.CurrentSpawnTracker == null) { return -1; } if (Main.CurrentSpawnTracker.prefabCounts.TryGetValue(prefab, out var value)) { return value; } return 0; } public static int GetCategoryCount(PrefabCategory category) { if (Main.CurrentSpawnTracker == null) { return -1; } if (Main.CurrentSpawnTracker.categoryCounts.TryGetValue(category, out var value)) { return value; } return 0; } } public class SceneSpawnTracker { public Dictionary prefabCounts = new Dictionary(); public Dictionary categoryCounts = new Dictionary(); public void RegisterSpawn(GameObject prefab, PrefabType type, PrefabCategory category) { if (!prefabCounts.ContainsKey(type)) { prefabCounts[type] = 0; } prefabCounts[type]++; if (!categoryCounts.ContainsKey(category)) { categoryCounts[category] = 0; } categoryCounts[category]++; } public void Clear() { prefabCounts.Clear(); categoryCounts.Clear(); } public void LogTrackerResults() { Main.Log.LogInfo((object)"=== SceneSpawnTracker: Results After Populate ==="); foreach (KeyValuePair prefabCount in prefabCounts) { Main.Log.LogInfo((object)$"PrefabType {prefabCount.Key}: {prefabCount.Value}"); } foreach (KeyValuePair categoryCount in categoryCounts) { Main.Log.LogInfo((object)$"PrefabCategory {categoryCount.Key}: {categoryCount.Value}"); } } }