Decompiled source of CrusherPerformanceFix v1.1.1

plugins/CrusherPerformanceFix/CrusherPerformanceFix.dll

Decompiled 3 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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("CrusherPerformanceFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CrusherPerformanceFix")]
[assembly: AssemblyTitle("CrusherPerformanceFix")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
}
namespace StackLimits
{
	[BepInPlugin("CrusherPerformanceFix", "Crusher Performance Fix", "1.1.1")]
	public class CrusherPerformanceFix : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(CrusherInstance), "UpdateCrafting")]
		private static class CrusherUpdateCraftingDelay
		{
			private static bool Prefix(float dt, ref CrusherInstance __instance)
			{
				if (!__instance.isCrafting)
				{
					__instance.progress += dt * notCraftingDelayCrusher;
					if (__instance.progress <= 1f)
					{
						return false;
					}
					__instance.progress = 0f;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(ThresherInstance), "UpdateCrafting")]
		private static class ThresherUpdateCraftingDelay
		{
			private static bool Prefix(float dt, ref ThresherInstance __instance)
			{
				if (!__instance.isCrafting)
				{
					__instance.progress += dt * notCraftingDelayThresher;
					if (__instance.progress <= 1f)
					{
						return false;
					}
					__instance.progress = 0f;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(AssemblerInstance), "UpdateCrafting")]
		private static class AssemblerUpdateCraftingDelay
		{
			private static bool Prefix(float dt, ref AssemblerInstance __instance)
			{
				if (!__instance.isCrafting)
				{
					__instance.timeCrafting += dt * notCraftingDelayAssembler;
					if (__instance.timeCrafting <= 1f)
					{
						return false;
					}
					__instance.timeCrafting = 0f;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(GridManager), "GetChunkArrayIndexFromId")]
		private static class GetChunkArrayIndexFromIdWarningRemoval
		{
			public static void Prefix(in int chunkId, ref bool warnOutOfBounds)
			{
				warnOutOfBounds = false;
			}
		}

		[HarmonyPatch(typeof(CrusherInstance), "ValidateAddResources")]
		private static class CrusherInstanceValidateAddResources
		{
			public static bool Prefix(ref CrusherInstance me, int resId, int inventoryIndex, out int slotNum, AddResourceValidationType validationType, ref bool __result)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Invalid comparison between Unknown and I4
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Invalid comparison between Unknown and I4
				slotNum = -1;
				if (inventoryIndex != 1)
				{
					__result = (int)validationType == 3;
					return false;
				}
				if ((int)validationType != 2)
				{
					__result = true;
					return false;
				}
				ref Inventory inputInventory = ref ((CrusherInstance)(ref me)).GetInputInventory();
				int num = default(int);
				int firstSlotWithResource = ((Inventory)(ref inputInventory)).GetFirstSlotWithResource(resId, ref num);
				__result = firstSlotWithResource == -1 || num < inputInventory.myStacks[firstSlotWithResource].maxStack;
				return false;
			}
		}

		[HarmonyPatch(typeof(CrusherInstance), "ValidateAddResources")]
		private static class CrusherInstanceValidateAddResourcesAlt
		{
			public static bool Prefix(ref CrusherInstance me, int resId, int inventoryIndex, out int slotNum, AddResourceValidationType validationType, ref bool __result)
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Invalid comparison between Unknown and I4
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Invalid comparison between Unknown and I4
				slotNum = -1;
				if (inventoryIndex == 1 && GameDefines.instance.IsResourceCrushable(resId))
				{
					if ((int)validationType != 2)
					{
						__result = true;
						return false;
					}
					ref Inventory inputInventory = ref ((CrusherInstance)(ref me)).GetInputInventory();
					int num = default(int);
					int firstSlotWithResource = ((Inventory)(ref inputInventory)).GetFirstSlotWithResource(resId, ref num);
					__result = firstSlotWithResource == -1 || num < inputInventory.myStacks[firstSlotWithResource].maxStack;
				}
				else
				{
					__result = (int)validationType == 3;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(CrusherInstance), "TakeResourcesToCraft")]
		private static class CrusherInstanceTakeResourcesToCraft
		{
			private static bool Prefix(ref CrusherInstance __instance, ref bool __result)
			{
				//IL_0012: 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)
				if ((Object)(object)__instance.previousRecipe != (Object)null && Traverse.Create((object)__instance).Method("HasResourcesToCraftRecipe", new object[1] { __instance.previousRecipe }).GetValue<bool>(new object[1] { __instance.previousRecipe }) && Traverse.Create((object)__instance).Method("CanAddResources", new object[1] { __instance.previousRecipe }).GetValue<bool>(new object[1] { __instance.previousRecipe }))
				{
					ref Inventory inputInventory = ref ((CrusherInstance)(ref __instance)).GetInputInventory();
					__instance.isCrafting = true;
					__instance.currentRecipe = __instance.previousRecipe;
					__instance.cycleAmount++;
					for (int i = 0; i < __instance.previousRecipe.ingTypes.Length; i++)
					{
						((Inventory)(ref inputInventory)).TryRemoveResources(((UniqueIdScriptableObject)__instance.previousRecipe.ingTypes[i]).uniqueId, __instance.previousRecipe.ingQuantities[i]);
					}
					__result = true;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(CrusherDefinition), "UpdateStreamedVisuals")]
		private static class CrusherDefinitionUpdateStreamedVisualsInput
		{
			public static bool Prefix(ref CrusherInstance inst, Span<Matrix4x4> dynamicLocalMatrices, ref StreamedMachineData<CrusherInstance, CrusherDefinition> streamedData, float dt)
			{
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				//IL_0103: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				CrusherDefinition type = streamedData.type;
				streamedData.ToggleOnOff(((CrusherInstance)(ref inst)).isOn);
				streamedData.RefreshAudioState();
				streamedData.RunAnims(((BuilderInfo)type).rawBuilderPrefab.anims, dt, ((CrusherInstance)(ref inst)).isOn, dynamicLocalMatrices);
				((MachineParticleState)(ref streamedData.commonData.particles[0])).UpdateParticleState(((CrusherInstance)(ref inst)).isOn, (ParticleSystemStopBehavior)1);
				if (inst.queuedEnergyDischarge)
				{
					inst.queuedEnergyDischarge = false;
					((MachineParticleState)(ref streamedData.commonData.particles[1])).PlayOneShot();
				}
				((IStreamedMachineInstance)streamedData.streamedInstance).UpdateMaterialPropVariations(ref streamedData.commonData);
				ResourceInfo val = null;
				if ((Object)(object)inst.currentRecipe != (Object)null)
				{
					val = inst.currentRecipe.ingTypes[0];
				}
				else if ((Object)(object)inst.previousRecipe != (Object)null)
				{
					val = inst.previousRecipe.ingTypes[0];
				}
				MachineStatus val2 = (((Object)(object)val != (Object)null && !inst.powerInfo.showPowerWarning) ? ((MachineStatus)(((CrusherInstance)(ref inst)).isOn ? 2 : 9)) : (inst.powerInfo.showPowerWarning ? ((MachineStatus)4) : ((!((Object)(object)val == (Object)null)) ? ((MachineStatus)1) : ((MachineStatus)1))));
				streamedData.RefreshOverlayMode(val2, val);
				return false;
			}
		}

		[HarmonyPatch(typeof(CrusherDefinition), "UpdateStreamedVisuals")]
		private static class CrusherDefinitionUpdateStreamedVisualsOutput
		{
			public static bool Prefix(ref CrusherInstance inst, Span<Matrix4x4> dynamicLocalMatrices, ref StreamedMachineData<CrusherInstance, CrusherDefinition> streamedData, float dt)
			{
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				//IL_0103: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				CrusherDefinition type = streamedData.type;
				streamedData.ToggleOnOff(((CrusherInstance)(ref inst)).isOn);
				streamedData.RefreshAudioState();
				streamedData.RunAnims(((BuilderInfo)type).rawBuilderPrefab.anims, dt, ((CrusherInstance)(ref inst)).isOn, dynamicLocalMatrices);
				((MachineParticleState)(ref streamedData.commonData.particles[0])).UpdateParticleState(((CrusherInstance)(ref inst)).isOn, (ParticleSystemStopBehavior)1);
				if (inst.queuedEnergyDischarge)
				{
					inst.queuedEnergyDischarge = false;
					((MachineParticleState)(ref streamedData.commonData.particles[1])).PlayOneShot();
				}
				((IStreamedMachineInstance)streamedData.streamedInstance).UpdateMaterialPropVariations(ref streamedData.commonData);
				ResourceInfo val = null;
				if ((Object)(object)inst.currentRecipe != (Object)null)
				{
					val = inst.currentRecipe.outputTypes[0];
				}
				else if ((Object)(object)inst.previousRecipe != (Object)null)
				{
					val = inst.previousRecipe.outputTypes[0];
				}
				MachineStatus val2 = (((Object)(object)val != (Object)null && !inst.powerInfo.showPowerWarning) ? ((MachineStatus)(((CrusherInstance)(ref inst)).isOn ? 2 : 9)) : (inst.powerInfo.showPowerWarning ? ((MachineStatus)4) : ((!((Object)(object)val == (Object)null)) ? ((MachineStatus)1) : ((MachineStatus)1))));
				streamedData.RefreshOverlayMode(val2, val);
				return false;
			}
		}

		[HarmonyPatch(typeof(CrusherInspector), "Set")]
		private static class CrusherInspectorSet
		{
			public static void Prefix(ref CrusherInstance inst)
			{
				if ((Object)(object)inst.currentRecipe == (Object)null && (Object)(object)inst.previousRecipe != (Object)null)
				{
					inst.currentRecipe = inst.previousRecipe;
				}
			}
		}

		private const string PluginName = "Crusher Performance Fix";

		private const string pluginGuid = "CrusherPerformanceFix";

		private const string VersionString = "1.1.1";

		private Harmony harmony = new Harmony("Crusher Performance Fix");

		public static float notCraftingDelayCrusher;

		public static float notCraftingDelayAssembler;

		public static float notCraftingDelayThresher;

		private void Awake()
		{
			if (((BaseUnityPlugin)this).Config.Bind<bool>("General", "RemoveLogSpamNearEdge", true, "Prevent the game from spamming 'Chunk out of range: (90, 90, 330)@0 out of range with offsets (3, 3, 11)@0/(11, 9, 11)' when you try to build near the edge of a level. ").Value)
			{
				harmony.PatchAll(typeof(GetChunkArrayIndexFromIdWarningRemoval));
			}
			if (((BaseUnityPlugin)this).Config.Bind<bool>("Crusher", "DelayActive", true, "Apply the delay for crushers. Strongly recommended to keep this on true as this is the main performance improvement of the mod.").Value)
			{
				harmony.PatchAll(typeof(CrusherUpdateCraftingDelay));
			}
			if (((BaseUnityPlugin)this).Config.Bind<bool>("Crusher", "AllowAnyResourceInput", false, "Allows to input one stack of any resource into crushers. As this strongly simplifies what inserters need to calculate, this also gives a huge performance boost. Also fixes inserters getting invalid input display when crusher is full. It will just wait patiently like on all other machines.").Value)
			{
				harmony.PatchAll(typeof(CrusherInstanceValidateAddResources));
			}
			else
			{
				harmony.PatchAll(typeof(CrusherInstanceValidateAddResourcesAlt));
			}
			if (((BaseUnityPlugin)this).Config.Bind<bool>("Crusher", "LockInRecipe", false, "Locks in the first recipe each crusher ever produces permanently. This means that after the first production cycle, each crusher will only ever attempt to continue producing this recipe. With default mod settings this doesn't give much of a performance increase but it can be used as an alternative to 'DelayActive'. I also find it useful to prevent crushers from going into recipes that where not intended (crushing sesamite sand when there are not enough stems for example).").Value)
			{
				harmony.PatchAll(typeof(CrusherInstanceTakeResourcesToCraft));
			}
			if (!((BaseUnityPlugin)this).Config.Bind<bool>("Crusher", "VanillaDisplay", false, "If set, the vanilla behavior of showing the first item in the input inventory is applied when you press 'alt'. This means that nothing might be shown while the crusher is actually working. Not recommended.").Value)
			{
				if (((BaseUnityPlugin)this).Config.Bind<bool>("Crusher", "DisplayOutput", false, "If set, the first output product rather than the first input product is shown on crushers when you press 'alt' (like with all other machines)").Value)
				{
					harmony.PatchAll(typeof(CrusherDefinitionUpdateStreamedVisualsOutput));
				}
				else
				{
					harmony.PatchAll(typeof(CrusherDefinitionUpdateStreamedVisualsInput));
				}
			}
			if (((BaseUnityPlugin)this).Config.Bind<bool>("Crusher", "DisplayPreviousRecipe", true, "If there is no current crafting being done, displays the last crafted recipe in the inspector.").Value)
			{
				harmony.PatchAll(typeof(CrusherInspectorSet));
			}
			if (((BaseUnityPlugin)this).Config.Bind<bool>("Assembler", "DelayActive", false, "Apply the delay for assemblers.").Value)
			{
				harmony.PatchAll(typeof(AssemblerUpdateCraftingDelay));
			}
			if (((BaseUnityPlugin)this).Config.Bind<bool>("Thresher", "DelayActive", false, "Apply the delay for threshers.").Value)
			{
				harmony.PatchAll(typeof(ThresherUpdateCraftingDelay));
			}
			notCraftingDelayCrusher = 1f / ((BaseUnityPlugin)this).Config.Bind<float>("Crusher", "CheckDelay", 1f, "Time until next check is performed when machine stopped due to lack of input. Number needs to be larger than 0.02 for this mod to make any sense. Only applied is DelayActive is set for this machine.").Value;
			notCraftingDelayAssembler = 1f / ((BaseUnityPlugin)this).Config.Bind<float>("Assembler", "CheckDelay", 1f, "Time until next check is performed when machine stopped due to lack of input. Number needs to be larger than 0.02 for this mod to make any sense. Only applied is DelayActive is set for this machine.").Value;
			notCraftingDelayThresher = 1f / ((BaseUnityPlugin)this).Config.Bind<float>("Thresher", "CheckDelay", 1f, "Time until next check is performed when machine stopped due to lack of input. Number needs to be larger than 0.02 for this mod to make any sense. Only applied is DelayActive is set for this machine.").Value;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Crusher Performance Fix Version 1.1.1 has loaded.");
		}
	}
}