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 ExtendedSacrifice v1.0.0
ExtendedSacrifice.dll
Decompiled 13 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ExtendedSacrifice.Compatibility; using ExtendedSacrifice.Configuration; using ExtendedSacrifice.Drops; using Microsoft.CodeAnalysis; using On.RoR2; using On.RoR2.Artifacts; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.Artifacts; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ExtendedSacrifice")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b28b33f5b9a60c2a7fd3c5364630b813641d2951")] [assembly: AssemblyProduct("ExtendedSacrifice")] [assembly: AssemblyTitle("ExtendedSacrifice")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 ExtendedSacrifice { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Irodflash.ExtendedSacrifice", "ExtendedSacrifice", "1.0.0")] public class ExtendedSacrificePlugin : BaseUnityPlugin { public const string PluginGUID = "Irodflash.ExtendedSacrifice"; public const string PluginAuthor = "Irodflash"; public const string PluginName = "ExtendedSacrifice"; public const string PluginVersion = "1.0.0"; private SacrificeDropHandler _dropHandler; public void Awake() { Log.Init(((BaseUnityPlugin)this).Logger); PluginConfig config = new PluginConfig(((BaseUnityPlugin)this).Config); if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions")) { RiskOfOptionsCompat.Register(config); } _dropHandler = new SacrificeDropHandler(config, new PityTracker()); _dropHandler.Hook(); Log.Info("Awake done."); } public void OnDestroy() { _dropHandler?.Unhook(); } } internal static class Log { private static ManualLogSource _logSource; internal static void Init(ManualLogSource logSource) { _logSource = logSource; } internal static void Debug(object data) { _logSource.LogDebug(data); } internal static void Error(object data) { _logSource.LogError(data); } internal static void Fatal(object data) { _logSource.LogFatal(data); } internal static void Info(object data) { _logSource.LogInfo(data); } internal static void Message(object data) { _logSource.LogMessage(data); } internal static void Warning(object data) { _logSource.LogWarning(data); } } } namespace ExtendedSacrifice.Drops { internal static class DropChanceCalculator { public static float Compute(PluginConfig config, CharacterBody victimBody, GameObject victimObject) { float num = config.BaseDropChance.Value * config.DropChanceMultiplier.Value; if (Object.op_Implicit((Object)(object)victimBody)) { if (victimBody.isElite) { num *= config.EliteMultiplier.Value; } if (victimBody.isBoss || victimBody.isChampion) { num *= config.BossMultiplier.Value; } } num *= 1f + GetStageBonus(config); num = Util.GetExpAdjustedDropChancePercent(num, victimObject); return Mathf.Clamp(num, 0f, config.MaxDropChance.Value); } private static float GetStageBonus(PluginConfig config) { if (!config.StageScalingEnabled.Value || !Object.op_Implicit((Object)(object)Run.instance)) { return 0f; } return Mathf.Min((float)Run.instance.stageClearCount * config.BonusPerStage.Value, config.MaxStageBonus.Value) / 100f; } } internal sealed class PityTracker { public int KillsWithoutDrop { get; private set; } public void Hook() { Run.onRunStartGlobal += OnRunStart; } public void Unhook() { Run.onRunStartGlobal -= OnRunStart; } public bool IsGuaranteed(int threshold) { return KillsWithoutDrop >= threshold; } public void RegisterMiss() { KillsWithoutDrop++; } public void RegisterDrop() { KillsWithoutDrop = 0; } private void OnRunStart(Run run) { KillsWithoutDrop = 0; } } internal sealed class SacrificeDropHandler { private readonly PluginConfig _config; private readonly PityTracker _pity; private readonly SacrificeDropRoller _roller; private readonly HashSet<HealthComponent> _rolledVictims = new HashSet<HealthComponent>(); private bool _warnedInterruptedDeath; public SacrificeDropHandler(PluginConfig config, PityTracker pity) { _config = config; _pity = pity; _roller = new SacrificeDropRoller(config, pity); } public void Hook() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown SacrificeArtifactManager.OnServerCharacterDeath += new hook_OnServerCharacterDeath(SkipVanillaRoll); HealthComponent.TakeDamageProcess += new hook_TakeDamageProcess(GuardTakeDamageProcess); GlobalEventManager.onCharacterDeathServer += OnCharacterDeathServer; Stage.onServerStageBegin += OnServerStageBegin; Stage.onStageStartGlobal += LogStageStatus; _pity.Hook(); } public void Unhook() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown SacrificeArtifactManager.OnServerCharacterDeath -= new hook_OnServerCharacterDeath(SkipVanillaRoll); HealthComponent.TakeDamageProcess -= new hook_TakeDamageProcess(GuardTakeDamageProcess); GlobalEventManager.onCharacterDeathServer -= OnCharacterDeathServer; Stage.onServerStageBegin -= OnServerStageBegin; Stage.onStageStartGlobal -= LogStageStatus; _pity.Unhook(); } private void SkipVanillaRoll(orig_OnServerCharacterDeath orig, DamageReport damageReport) { if (!_config.Enabled.Value) { orig.Invoke(damageReport); } } private void OnCharacterDeathServer(DamageReport damageReport) { if (ShouldRoll() && Object.op_Implicit((Object)(object)damageReport.victim)) { _rolledVictims.Add(damageReport.victim); SafeRoll(damageReport); } } private void GuardTakeDamageProcess(orig_TakeDamageProcess orig, HealthComponent self, DamageInfo damageInfo) { bool alive = self.alive; float combinedHealth = self.combinedHealth; try { orig.Invoke(self, damageInfo); } finally { if (alive && !self.alive) { OnDiedDuringHit(self, damageInfo, combinedHealth); } } } private void OnDiedDuringHit(HealthComponent victim, DamageInfo damageInfo, float combinedHealthBefore) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown if (!_rolledVictims.Remove(victim) && ShouldRoll()) { if (!_warnedInterruptedDeath) { _warnedInterruptedDeath = true; Log.Warning("Death of " + ((Object)victim).name + " was interrupted by another mod's error (see the stack trace above); Sacrifice drops are rolled anyway. Further occurrences are only logged with Verbose Logging."); } else if (_config.VerboseLogging.Value) { Log.Info("Death of " + ((Object)victim).name + " interrupted by another mod, rolling anyway."); } SafeRoll(new DamageReport(damageInfo, victim, damageInfo.damage, combinedHealthBefore)); } } private void OnServerStageBegin(Stage stage) { _rolledVictims.Clear(); } private void LogStageStatus(Stage stage) { SceneDef sceneDef = stage.sceneDef; Log.Info($"Stage {((sceneDef != null) ? sceneDef.cachedName : null)}: mod enabled: {_config.Enabled.Value}, host: {NetworkServer.active}, " + $"Sacrifice active: {IsSacrificeActive()} -> drops handled here: {ShouldRoll()}"); } private bool ShouldRoll() { if (_config.Enabled.Value && NetworkServer.active) { return IsSacrificeActive(); } return false; } private static bool IsSacrificeActive() { if (Object.op_Implicit((Object)(object)RunArtifactManager.instance)) { return RunArtifactManager.instance.IsArtifactEnabled(Artifacts.sacrificeArtifactDef); } return false; } private void SafeRoll(DamageReport damageReport) { try { _roller.Roll(damageReport); } catch (Exception arg) { Log.Error($"Sacrifice drop roll failed: {arg}"); } } } internal sealed class SacrificeDropRoller { private const float DropUpwardSpeed = 20f; private const float JackpotUpwardSpeed = 30f; private const float JackpotSpreadSpeed = 6f; private readonly PluginConfig _config; private readonly PityTracker _pity; private bool _warnedMissingDropTable; public SacrificeDropRoller(PluginConfig config, PityTracker pity) { _config = config; _pity = pity; } public void Roll(DamageReport damageReport) { //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) if (!IsEligible(damageReport)) { return; } CharacterBody victimBody = damageReport.victimBody; float num = DropChanceCalculator.Compute(_config, victimBody, ((Component)damageReport.victim).gameObject); bool flag = _config.PityEnabled.Value && _pity.IsGuaranteed(_config.KillsBeforeGuaranteedDrop.Value); bool flag2 = flag || Util.CheckRoll(num, 0f, (CharacterMaster)null); bool flag3 = flag2 && _config.JackpotEnabled.Value && Util.CheckRoll(_config.JackpotChance.Value, 0f, (CharacterMaster)null); if (_config.VerboseLogging.Value) { DeathRewards component = ((Component)victimBody).GetComponent<DeathRewards>(); int num2 = (Object.op_Implicit((Object)(object)component) ? component.spawnValue : 0); Log.Info($"Kill {victimBody.GetDisplayName()} (elite: {victimBody.isElite}, boss: {victimBody.isBoss || victimBody.isChampion}, " + $"spawnValue: {num2}) chance: {num:0.##}%, misses: {_pity.KillsWithoutDrop}, " + $"dropped: {flag2}, guaranteed: {flag}, jackpot: {flag3}"); } if (!flag2) { _pity.RegisterMiss(); return; } _pity.RegisterDrop(); Vector3 corePosition = victimBody.corePosition; if (flag3) { DropJackpot(corePosition, _config.JackpotItemCount.Value); } else { TryDrop(corePosition, Vector3.up * 20f); } } private static bool IsEligible(DamageReport damageReport) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)damageReport.victimMaster) || !Object.op_Implicit((Object)(object)damageReport.victimBody) || !Object.op_Implicit((Object)(object)damageReport.victim)) { return false; } if (damageReport.attackerTeamIndex == damageReport.victimTeamIndex) { return !Object.op_Implicit((Object)(object)damageReport.victimMaster.minionOwnership.ownerMaster); } return true; } private void DropJackpot(Vector3 position, int count) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) Quaternion val = Quaternion.AngleAxis(360f / (float)count, Vector3.up); Vector3 val2 = Quaternion.AngleAxis(Random.Range(0f, 360f), Vector3.up) * (Vector3.up * 30f + Vector3.forward * 6f); for (int i = 0; i < count; i++) { TryDrop(position, val2); val2 = val * val2; } } private void TryDrop(Vector3 position, Vector3 velocity) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) PickupDropTable dropTable = SacrificeArtifactManager.dropTable; if (!Object.op_Implicit((Object)(object)dropTable)) { if (!_warnedMissingDropTable) { _warnedMissingDropTable = true; Log.Warning("Sacrifice drop table is not loaded, no item can drop."); } return; } UniquePickup val = dropTable.GeneratePickup(SacrificeArtifactManager.treasureRng); if (((UniquePickup)(ref val)).isValid) { PickupDropletController.CreatePickupDroplet(val, position, velocity, false); } else if (_config.VerboseLogging.Value) { Log.Warning("Sacrifice drop table returned no valid pickup."); } } } } namespace ExtendedSacrifice.Configuration { internal sealed class PluginConfig { private const string GeneralSection = "1. General"; private const string EliteBossSection = "2. Elites and Bosses"; private const string StageScalingSection = "3. Stage Scaling"; private const string PitySection = "4. Pity"; private const string JackpotSection = "5. Jackpot"; public ConfigEntry<bool> Enabled { get; } public ConfigEntry<float> BaseDropChance { get; } public ConfigEntry<float> DropChanceMultiplier { get; } public ConfigEntry<float> MaxDropChance { get; } public ConfigEntry<bool> VerboseLogging { get; } public ConfigEntry<float> EliteMultiplier { get; } public ConfigEntry<float> BossMultiplier { get; } public ConfigEntry<bool> StageScalingEnabled { get; } public ConfigEntry<float> BonusPerStage { get; } public ConfigEntry<float> MaxStageBonus { get; } public ConfigEntry<bool> PityEnabled { get; } public ConfigEntry<int> KillsBeforeGuaranteedDrop { get; } public ConfigEntry<bool> JackpotEnabled { get; } public ConfigEntry<float> JackpotChance { get; } public ConfigEntry<int> JackpotItemCount { get; } public PluginConfig(ConfigFile file) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Expected O, but got Unknown //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Expected O, but got Unknown //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Expected O, but got Unknown //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Expected O, but got Unknown //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Expected O, but got Unknown Enabled = file.Bind<bool>("1. General", "Enabled", true, "Enable the mod. When disabled, Sacrifice uses the vanilla drop logic."); BaseDropChance = file.Bind<float>("1. General", "Base Drop Chance", 5f, new ConfigDescription("Base drop chance in percent before any multiplier. Vanilla is 5.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); DropChanceMultiplier = file.Bind<float>("1. General", "Drop Chance Multiplier", 2f, new ConfigDescription("Multiplier applied to the base drop chance. 1 = vanilla.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>())); MaxDropChance = file.Bind<float>("1. General", "Max Drop Chance", 100f, new ConfigDescription("Hard cap in percent on the final drop chance, after every bonus.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); VerboseLogging = file.Bind<bool>("1. General", "Verbose Logging", false, "Log every Sacrifice roll (monster, chance, result) to the BepInEx console. For troubleshooting."); EliteMultiplier = file.Bind<float>("2. Elites and Bosses", "Elite Multiplier", 1.5f, new ConfigDescription("Extra multiplier for elite monsters. 1 = no bonus.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); BossMultiplier = file.Bind<float>("2. Elites and Bosses", "Boss Multiplier", 2f, new ConfigDescription("Extra multiplier for bosses and champions. Stacks with the elite multiplier. 1 = no bonus.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); StageScalingEnabled = file.Bind<bool>("3. Stage Scaling", "Enabled", true, "Increase the drop chance with every stage cleared."); BonusPerStage = file.Bind<float>("3. Stage Scaling", "Bonus Per Stage", 10f, new ConfigDescription("Drop chance bonus in percent per stage cleared (10 = +10% of the chance per stage).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); MaxStageBonus = file.Bind<float>("3. Stage Scaling", "Max Stage Bonus", 100f, new ConfigDescription("Maximum total stage bonus in percent (100 = chance doubled at most).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1000f), Array.Empty<object>())); PityEnabled = file.Bind<bool>("4. Pity", "Enabled", true, "Guarantee a drop after a streak of eligible kills without any drop."); KillsBeforeGuaranteedDrop = file.Bind<int>("4. Pity", "Kills Before Guaranteed Drop", 40, new ConfigDescription("Number of consecutive kills without a drop before the next kill is guaranteed to drop.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 500), Array.Empty<object>())); JackpotEnabled = file.Bind<bool>("5. Jackpot", "Enabled", true, "Give each drop a small chance to burst into several items."); JackpotChance = file.Bind<float>("5. Jackpot", "Jackpot Chance", 2f, new ConfigDescription("Chance in percent that a drop becomes a jackpot.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); JackpotItemCount = file.Bind<int>("5. Jackpot", "Jackpot Item Count", 3, new ConfigDescription("Number of items dropped by a jackpot.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 20), Array.Empty<object>())); } } } namespace ExtendedSacrifice.Compatibility { internal static class RiskOfOptionsCompat { public const string PluginGUID = "com.rune580.riskofoptions"; [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void Register(PluginConfig config) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown ModSettingsManager.SetModDescription("More item drops from monsters when the Artifact of Sacrifice is active.\n\nMultiplayer: only the host needs the mod, and only the host's settings apply."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(config.Enabled)); ModSettingsManager.AddOption((BaseOption)new SliderOption(config.BaseDropChance, Slider(0f, 100f, "{0:0.#}%"))); ModSettingsManager.AddOption((BaseOption)new SliderOption(config.DropChanceMultiplier, Slider(0f, 20f, "x{0:0.##}"))); ModSettingsManager.AddOption((BaseOption)new SliderOption(config.MaxDropChance, Slider(0f, 100f, "{0:0.#}%"))); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(config.VerboseLogging)); ModSettingsManager.AddOption((BaseOption)new SliderOption(config.EliteMultiplier, Slider(0f, 10f, "x{0:0.##}"))); ModSettingsManager.AddOption((BaseOption)new SliderOption(config.BossMultiplier, Slider(0f, 10f, "x{0:0.##}"))); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(config.StageScalingEnabled)); ModSettingsManager.AddOption((BaseOption)new SliderOption(config.BonusPerStage, Slider(0f, 100f, "+{0:0.#}%"))); ModSettingsManager.AddOption((BaseOption)new SliderOption(config.MaxStageBonus, Slider(0f, 1000f, "+{0:0}%"))); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(config.PityEnabled)); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(config.KillsBeforeGuaranteedDrop, new IntSliderConfig { min = 1, max = 500 })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(config.JackpotEnabled)); ModSettingsManager.AddOption((BaseOption)new SliderOption(config.JackpotChance, Slider(0f, 100f, "{0:0.#}%"))); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(config.JackpotItemCount, new IntSliderConfig { min = 2, max = 20 })); } private static SliderConfig Slider(float min, float max, string format) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown return new SliderConfig { min = min, max = max, FormatString = format }; } } }