Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of ReduceRecycler v1.3.2
plugins/ReduceRecycler/ReduceRecycler.dll
Decompiled 12 hours agousing System; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using IL.RoR2; using Mono.Cecil.Cil; using MonoMod.Cil; using On.RoR2; using R2API.Utils; using RiskOfOptions; using RiskOfOptions.Options; using RoR2; using UnityEngine; [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("ReduceRecycler")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+a9cf3e6ebb8390f4beab53127035d8f24d90abac")] [assembly: AssemblyProduct("ReduceRecycler")] [assembly: AssemblyTitle("ReduceRecycler")] [assembly: AssemblyVersion("1.0.0.0")] namespace ReduceRecycler; internal static class ConfigManager { private static ConfigFile OptionsConfig { get; set; } internal static ConfigEntry<bool> IsModEnabled { get; set; } internal static ConfigEntry<bool> EnableOnlyAfterTeleporter { get; set; } internal static ConfigEntry<ReduceRecycler.CooldownReset> CooldownReset { get; set; } internal static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown OptionsConfig = new ConfigFile(Paths.ConfigPath + "\\ReduceRecycler.cfg", true); ModSettingsManager.SetModDescription("Customize the behavior of the recycler equipment to shorten the time between uses."); IsModEnabled = OptionsConfig.Bind<bool>("Behavior", "Enable Mod", true, "Dynamically enable or disable the mod. If this is unchecked, the mod will not function until re-enabled."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(IsModEnabled)); EnableOnlyAfterTeleporter = OptionsConfig.Bind<bool>("Behavior", "Enable Only After Teleporter", false, "Enable no-cooldown only after the teleporter for the stage has been completed. For stage without a teleporter (Hidden Realms, Void Fields, Commencement), this just makes the Recycler behave as normal."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(EnableOnlyAfterTeleporter)); CooldownReset = OptionsConfig.Bind<ReduceRecycler.CooldownReset>("Behavior", "Cooldown Reset", ReduceRecycler.CooldownReset.AfterUse, "When to reset the cooldown of Recycler. AfterUse will reset immediately after use. OnDemand will reset on button press."); ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)CooldownReset)); } } internal static class Log { private static ManualLogSource Logger { get; set; } internal static void Init(ManualLogSource logger) { Logger = logger; } [Conditional("DEBUG")] internal static void Debug(object data) { Logger.LogDebug(data); } internal static void Info(object data) { Logger.LogInfo(data); } internal static void Message(object data) { Logger.LogMessage(data); } internal static void Warning(object data) { Logger.LogWarning(data); } internal static void Error(object data) { Logger.LogError(data); } internal static void Fatal(object data) { Logger.LogFatal(data); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInPlugin("quasikyo.ReduceRecycler", "ReduceRecycler", "1.3.2")] public class ReduceRecycler : BaseUnityPlugin { internal enum CooldownReset { AfterUse, OnDemand } public const string PluginGUID = "quasikyo.ReduceRecycler"; public const string PluginAuthor = "quasikyo"; public const string PluginName = "ReduceRecycler"; public const string PluginVersion = "1.3.2"; private const string finalStageSceneName = "moon2"; private const string voidFieldsStageSceneName = "arena"; public void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown Log.Init(((BaseUnityPlugin)this).Logger); Log.Info("Performing setup for ReduceRecycler"); ConfigManager.Init(); EquipmentSlot.FireRecycle += new hook_FireRecycle(ResetAfterUse); EquipmentSlot.MyFixedUpdate += new Manipulator(EquipmentActivationAllowedIfRecycler); EquipmentSlot.ExecuteIfReady += new Manipulator(ResetOnDemand); } private void EquipmentActivationAllowedIfRecycler(ILContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(context); val.GotoNext(new Func<Instruction, bool>[3] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<EquipmentSlot>(x, "get_characterBody"), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterBody>(x, "get_isEquipmentActivationAllowed") }); val.Index += 2; val.Remove(); val.EmitDelegate<Func<CharacterBody, bool>>((Func<CharacterBody, bool>)delegate(CharacterBody body) { VehicleSeat currentVehicle = body.currentVehicle; bool flag = !Object.op_Implicit((Object)(object)currentVehicle) || currentVehicle.isEquipmentActivationAllowed; return IsRecycler(body.equipmentSlot) || flag; }); } private void ResetOnDemand(ILContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(context); val.GotoNext(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<EquipmentSlot>(x, "get_stock") }); val.Remove(); val.EmitDelegate<Func<EquipmentSlot, int>>((Func<EquipmentSlot, int>)delegate(EquipmentSlot slot) { if (ConfigManager.CooldownReset.Value == CooldownReset.OnDemand) { ResetRecyclerCooldown(slot); } return slot.stock; }); } private bool ResetAfterUse(orig_FireRecycle original, EquipmentSlot slot) { bool flag = original.Invoke(slot); if (ConfigManager.CooldownReset.Value == CooldownReset.AfterUse && flag) { ((MonoBehaviour)this).StartCoroutine(ExecuteWithDelay(delegate { ResetRecyclerCooldown(slot); }, TimeSpan.FromSeconds(0.5))); } return flag; } private void ResetRecyclerCooldown(EquipmentSlot slot) { if (!ConfigManager.IsModEnabled.Value || !IsRecycler(slot)) { return; } float cooldownTimer = slot.cooldownTimer; if (float.IsInfinity(cooldownTimer)) { return; } float runStopwatch = Run.instance.GetRunStopwatch(); bool flag = StageHasTeleporter(Stage.instance.sceneDef) && TeleporterInteraction.instance.isCharged; bool flag2 = !ConfigManager.EnableOnlyAfterTeleporter.Value || flag; if (GetEquipmentCharges(slot) == 0 && flag2) { slot.characterBody.inventory.DeductActiveEquipmentCooldown(cooldownTimer); if (!Run.instance.isRunStopwatchPaused) { Run.instance.SetRunStopwatch(runStopwatch + cooldownTimer); } } } private bool StageHasTeleporter(SceneDef scene) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 bool num = (int)scene.sceneType == 1; bool flag = scene.baseSceneName.Equals("moon2"); bool flag2 = scene.baseSceneName.Equals("arena"); if (num && !flag) { return !flag2; } return false; } private bool IsRecycler(EquipmentSlot slot) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return (Object)(object)EquipmentCatalog.GetEquipmentDef((EquipmentIndex)((slot == null) ? (-1) : ((int)slot.equipmentIndex))) == (Object)(object)Equipment.Recycle; } private int GetEquipmentCharges(EquipmentSlot equipmentSlot) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = equipmentSlot.characterBody.inventory; uint activeEquipmentSlot = inventory.activeEquipmentSlot; return inventory.GetEquipment(activeEquipmentSlot).charges; } private IEnumerator ExecuteWithDelay(Action action, TimeSpan delay) { yield return (object)new WaitForSeconds((float)delay.TotalSeconds); action(); } }