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 BalancedFasterInteractables v1.4.1
BalancedFasterInteractables.dll
Decompiled 6 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using EntityStates; using EntityStates.Barrel; using EntityStates.DroneCombiner; using EntityStates.DroneScrapper; using EntityStates.Duplicator; using EntityStates.MealPrep; using EntityStates.Scrapper; using HarmonyLib; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using RoR2; using RoR2.AsyncManagement; using RoR2.EntityLogic; using UnityEngine; using UnityEngine.Events; 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: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.4.1.0")] [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 BalancedFasterInteractables { [BepInPlugin("com.riskofresources.fast.interactable", "BalancedFasterInteractables", "1.4.1")] [BepInIncompatibility("riskofresources.FasterInteractableBalancer")] [BepInIncompatibility("FlyingComputer.ExchangeChanges")] [BepInIncompatibility("Felda.ActuallyFaster")] internal class Plugin : BaseUnityPlugin { private class PurchaseDelay : MonoBehaviour { private ArgumentCache delay; private float original; internal static void Set(PurchaseInteraction interaction, float multiplier, bool timed) { IEnumerable<PurchaseDelay> enumerable = ((Component)interaction).GetComponents<PurchaseDelay>(); if (!enumerable.Any()) { enumerable = Initialize(interaction); } float num = 0f; foreach (PurchaseDelay item in enumerable) { item.Update(multiplier); num = Mathf.Max(item.original, num); } if (timed) { UpdateStopwatch(num - num * multiplier); } ((UnityEventBase)interaction.onPurchase).DirtyPersistentCalls(); } internal static void Remove(PurchaseInteraction interaction) { PurchaseDelay[] components = ((Component)interaction).gameObject.GetComponents<PurchaseDelay>(); foreach (PurchaseDelay obj in components) { ((UnityEventBase)interaction.onPurchase).DirtyPersistentCalls(); obj.Reset(); Object.Destroy((Object)(object)obj); } } private void Update(float multiplier) { delay.floatArgument = original * multiplier; } private void Reset() { delay.floatArgument = original; } private static IEnumerable<PurchaseDelay> Initialize(PurchaseInteraction interaction) { foreach (PersistentCall call in ((UnityEventBase)interaction.onPurchase).m_PersistentCalls.m_Calls) { if (call.target is DelayedEvent && call.methodName == "CallDelayed") { PurchaseDelay purchaseDelay = ((Component)interaction).gameObject.AddComponent<PurchaseDelay>(); purchaseDelay.delay = call.arguments; purchaseDelay.original = purchaseDelay.delay.floatArgument; yield return purchaseDelay; } } } } public const string version = "1.4.1"; public const string identifier = "com.riskofresources.fast.interactable"; private static ConfigEntry<bool> teleporter; private static ConfigEntry<bool> penalty; internal static ConfigEntry<float> speed; private static ConfigEntry<bool> printer; private static ConfigEntry<bool> shrine; private static ConfigEntry<bool> chest; private static ConfigEntry<bool> cradle; private static ConfigEntry<bool> pool; private static ConfigEntry<bool> cauldron; internal static ConfigEntry<bool> scrapper; internal static ConfigEntry<bool> upgrade; internal static ConfigEntry<bool> craft; public static bool Idle { get { if (teleporter.Value) { TeleporterInteraction instance = TeleporterInteraction.instance; if (!(((instance != null) ? instance.currentState : null) is ChargedState)) { return CombatDirector.instancesList.Any(); } } return false; } } protected void Awake() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown teleporter = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Only After Teleporter", true, "By default, this plugin will only take effect after the teleporter has been charged, or all combat directors have deactivated."); penalty = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Time Penalty", true, "Any time taken off the activation will be directly added to the game stopwatch."); speed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Speed", 75f, new ConfigDescription("Time to complete each interaction is reduced by this percentage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); printer = interactable("Printer"); scrapper = interactable("Scrapper"); shrine = interactable("Shrine of Chance"); chest = interactable("Chest"); cradle = interactable("Void Cradle"); pool = interactable("Cleansing Pool"); cauldron = interactable("Lunar Cauldron"); upgrade = interactable("Drone Combiner Station"); craft = interactable("Wandering CHEF"); Harmony.CreateAndPatchAll(typeof(Plugin), (string)null); Harmony.CreateAndPatchAll(typeof(Update), (string)null); ConfigEntry<bool> interactable(string key) { return ((BaseUnityPlugin)this).Config.Bind<bool>("Interactables", key, true, ""); } } [HarmonyPatch(typeof(Duplicating), "OnEnter")] [HarmonyPostfix] private static void PrintFaster(Duplicating __instance) { DelayedEvent val = default(DelayedEvent); if (((Component)((EntityState)__instance).outer).TryGetComponent<DelayedEvent>(ref val)) { ((Behaviour)val).enabled = false; } int num; float num2; if (printer.Value) { num = (Idle ? 1 : 0); if (num == 0) { num2 = speed.Value / 100f; goto IL_0044; } } else { num = 1; } num2 = 0f; goto IL_0044; IL_0044: float num3 = num2; ((EntityState)__instance).GetComponent<PurchaseInteraction>().SetUnavailableTemporarily(Time.fixedDeltaTime + 3f * (1f - num3)); if (num == 0) { num3 *= Duplicating.initialDelayDuration + Duplicating.timeBetweenStartAndDropDroplet; ((EntityState)__instance).fixedAge = ((EntityState)__instance).fixedAge + num3; UpdateStopwatch(num3); } } [HarmonyPatch(typeof(Duplicating), "BeginCooking")] [HarmonyPostfix] private static void ScaleAnimation(Duplicating __instance) { if (printer.Value && !Idle) { ((EntityState)__instance).GetModelAnimator().speed = 125f / (125f - speed.Value); } } [HarmonyPatch(typeof(Duplicating), "OnExit")] [HarmonyILManipulator] private static void ApplyCooldown(ILContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(context); ILLabel val2 = val.DefineLabel(); if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCall<PurchaseInteraction>(i, "SetAvailable") })) { val.Emit(OpCodes.Ldc_I4_1); val.Emit(OpCodes.Brtrue, (object)val2); int index = val.Index + 1; val.Index = index; val.Emit(OpCodes.Ldnull); val.Emit(OpCodes.Ldc_I4_0); val.MarkLabel(val2); val.Emit(OpCodes.Pop); val.Emit(OpCodes.Pop); } else { Debug.LogError((object)"Unable to apply cooldown on printer."); } } [HarmonyPatch(typeof(ScrapperBaseState), "OnEnter")] [HarmonyPostfix] private static void ScrapQuickly(ScrapperBaseState __instance) { if (!scrapper.Value || Idle) { return; } float num = speed.Value / 100f; if (!(__instance is WaitToBeginScrapping)) { if (!(__instance is Scrapping)) { if (!(__instance is ScrappingToIdle)) { return; } num *= ScrappingToIdle.duration * 0.5f; } else { num *= Scrapping.duration; } } else { num *= WaitToBeginScrapping.duration; } ((EntityState)__instance).fixedAge = ((EntityState)__instance).fixedAge + num; UpdateStopwatch(num); } [HarmonyPatch(typeof(ShrineChanceBehavior), "AddShrineStack")] [HarmonyPostfix] private static void SpeedUpShrine(ShrineChanceBehavior __instance) { if (shrine.Value && !Idle) { float num = speed.Value / 100f * __instance.refreshTimer; __instance.refreshTimer -= num; UpdateStopwatch(num); } } [HarmonyPatch(typeof(Opening), "OnEnter")] [HarmonyPostfix] private static void OpenChest(EntityState __instance) { if (chest.Value && !Idle && __instance.GetComponent<ChestBehavior>() != null) { float num = speed.Value / 100f; UpdateStopwatch(0.45f * Opening.duration * num); num = ((num != 1f) ? (1f / (1f - num)) : float.MaxValue); __instance.GetModelAnimator().speed = num; } } [HarmonyPatch(typeof(OpeningLunar), "OnEnter")] [HarmonyPostfix] private static void CrackThatSuckerOpen(BaseState __instance) { if (cradle.Value && !Idle) { float num = speed.Value / 100f; float num2 = 1f - num; if (!Object.op_Implicit((Object)(object)((EntityState)__instance).GetComponent<ScriptedCombatEncounter>())) { num *= 0.125f; num2 += num; } num *= OpeningLunar.duration; num2 = ((num2 == 0f) ? float.MaxValue : (1f / num2)); ((EntityState)__instance).fixedAge = ((EntityState)__instance).fixedAge + num; UpdateStopwatch(num); ((EntityState)__instance).GetModelAnimator().speed = num2; } } [HarmonyPatch(typeof(PurchaseInteraction), "OnInteractionBegin")] [HarmonyPrefix] private static void TryToInfest(PurchaseInteraction __instance) { if (Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<ScriptedCombatEncounter>())) { if (!cradle.Value || Idle) { PurchaseDelay.Remove(__instance); } else { PurchaseDelay.Set(__instance, 1f - speed.Value / 95f, timed: false); } } } [HarmonyPatch(typeof(PurchaseInteraction), "OnInteractionBegin")] [HarmonyPrefix] private static void CleanseRapidly(PurchaseInteraction __instance) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if (__instance.isShrine && (int)__instance.costType == 9) { if (!pool.Value || Idle) { PurchaseDelay.Remove(__instance); } else { PurchaseDelay.Set(__instance, 1f - speed.Value / 100f, timed: true); } } } [HarmonyPatch(typeof(PurchaseInteraction), "OnInteractionBegin")] [HarmonyPrefix] private static void CookSoup(PurchaseInteraction __instance) { if (__instance.contextToken == "BAZAAR_CAULDRON_CONTEXT") { if (!cauldron.Value || Idle) { PurchaseDelay.Remove(__instance); } else { PurchaseDelay.Set(__instance, 1f - speed.Value / 100f, timed: true); } } } internal static void UpdateStopwatch(float time) { Run instance = Run.instance; if (penalty.Value) { bool? flag = ((instance != null) ? new bool?(instance.isRunStopwatchPaused) : ((bool?)null)); if (flag.HasValue && flag != true && NetworkServer.active) { instance.SetRunStopwatch(instance.GetRunStopwatch() + time); } } } } internal class Update { [HarmonyPatch(typeof(WaitToBeginScrappingDrone), "FixedUpdate")] [HarmonyPatch(typeof(DroneScrapping), "OnEnter")] [HarmonyPatch(typeof(DroneScrapping), "FixedUpdate")] [HarmonyPatch(typeof(DroneScrappingToIdle), "FixedUpdate")] [HarmonyILManipulator] private static void DestroyImmediate(ILContext context, MethodBase __originalMethod) { SetDuration(__originalMethod, context, Plugin.scrapper); } [HarmonyPatch(typeof(DroneScrapping), "OnEnter")] [HarmonyPrefix] private static void ScaleEffect() { object value = typeof(DroneScrapping).GetField("scrapVFXPrefab").GetValue(null); float num = 1f - Plugin.speed.Value / 115f; object obj = value; GameObject effect = (GameObject)((obj is GameObject) ? obj : null); if (effect == null) { get(); } if (!Plugin.scrapper.Value || Plugin.Idle) { num = 1f; } effect.GetComponent<DestroyOnTimer>().duration = 3.5f * num; effect.GetComponent<VFXAttributes>().DoNotPool = true; [MethodImpl(MethodImplOptions.NoInlining)] void get() { ref GameObject reference = ref effect; object obj2 = value; reference = EntityStateGameObject.op_Implicit((EntityStateGameObject)((obj2 is EntityStateGameObject) ? obj2 : null)); } } [HarmonyPatch(typeof(DroneCombinerCombining), "OnEnter")] [HarmonyPostfix] private static void Coalescence(DroneCombinerCombining __instance) { float speed; float cooldown; if (Plugin.upgrade.Value && !Plugin.Idle) { speed = Plugin.speed.Value / 100f; cooldown = 0f; update(ref __instance.initialTimer); cooldown = 0.5f * DroneCombinerCombining.fadeOutDuration; update(ref __instance.absorbTimer); update(ref __instance.animationTimer); } void update(ref float value) { float num = speed * (value - cooldown); value -= num; Plugin.UpdateStopwatch(num); } } [HarmonyPatch(typeof(DroneCombinerController), "ShouldDisplayHologram")] [HarmonyILManipulator] private static void AlwaysDisplayHologram(ILContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0048: 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) ILCursor val = new ILCursor(context); if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchLdfld<DroneCombinerController>(i, "_isBusy") })) { int index = val.Index + 1; val.Index = index; val.Emit(OpCodes.Pop); val.Emit(OpCodes.Ldc_I4_0); } else { Debug.LogError((object)"Unable to display hologram."); } } [HarmonyPatch(typeof(WaitToBeginCooking), "OnEnter")] [HarmonyPatch(typeof(WaitToBeginCooking), "FixedUpdate")] [HarmonyPatch(typeof(Cooking), "OnEnter")] [HarmonyPatch(typeof(Cooking), "FixedUpdate")] [HarmonyPatch(typeof(CookingToIdle), "OnEnter")] [HarmonyPatch(typeof(CookingToIdle), "FixedUpdate")] [HarmonyILManipulator] private static void CraftingTable(ILContext context, MethodBase __originalMethod) { SetDuration(__originalMethod, context, Plugin.craft); } private static void SetDuration(MethodBase method, ILContext context, ConfigEntry<bool> enabled) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown ILCursor val = new ILCursor(context); FieldInfo field = method.DeclaringType.GetField("duration", AccessTools.all); while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchLdsfld(i, field) })) { val.EmitDelegate<Func<float, float>>((Func<float, float>)delegate(float duration) { if (!enabled.Value || Plugin.Idle) { return duration; } float num = duration * Plugin.speed.Value / 105f; if (method.Name == "OnEnter") { Plugin.UpdateStopwatch(num); } return duration - num; }); context = null; } if (context != null) { Debug.LogError((object)("Unable to modify duration for `" + method.DeclaringType.Name + "::" + method.Name + "`.")); } } } }