Decompiled source of EquinoxsModUtils v4.1.0

plugins/EquinoxsModUtils/EquinoxsModUtils.dll

Decompiled 6 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using EquinoxsModUtils.Patches;
using FluffyUnderware.DevTools.Extensions;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("EquinoxsModUtils")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EquinoxsModUtils")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("10cac0f2-892f-4b27-9f39-3a6a47279742")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace EquinoxsModUtils
{
	internal static class MachineBuilder
	{
		internal static void buildMachine(int resId, GridInfo gridInfo, bool shouldLog, int variationIndex, int recipe, ChainData? chainData, bool reverseConveyor)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected I4, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			MachineTypeEnum machineTypeFromResID = ModUtils.GetMachineTypeFromResID(resId);
			if ((int)machineTypeFromResID == 0)
			{
				ResourceInfo resInfoFromId = SaveState.GetResInfoFromId(resId);
				string arg = (((Object)(object)resInfoFromId == (Object)null) ? "Unknown Resource" : resInfoFromId.displayName);
				ModUtils.LogEMUError($"Cannot build machine for invalid resID: {resId} - '{arg}'");
				return;
			}
			MachineTypeEnum val = machineTypeFromResID;
			MachineTypeEnum val2 = val;
			switch (val2 - 1)
			{
			case 2:
			case 7:
			case 9:
			case 15:
			case 18:
			case 20:
			case 21:
			case 23:
			case 25:
			case 31:
				doSimpleBuild(resId, gridInfo, shouldLog);
				break;
			case 0:
				if (recipe == -1)
				{
					doSimpleBuild(resId, gridInfo, shouldLog);
				}
				else
				{
					doSimpleBuildWithRecipe(resId, gridInfo, recipe, shouldLog);
				}
				break;
			case 6:
				doSimpleBuildWithRecipe(resId, gridInfo, recipe, shouldLog);
				break;
			case 3:
				doConveyorBuild(resId, gridInfo, chainData, reverseConveyor, shouldLog);
				break;
			case 4:
				doDrillBuild(resId, gridInfo);
				break;
			case 5:
				doFloorBuild(resId, gridInfo);
				break;
			case 11:
				doResearchCoreBuild(resId, gridInfo);
				break;
			case 16:
				doStairsBuild(resId, gridInfo);
				break;
			case 30:
				doStructureBuild(resId, gridInfo, variationIndex);
				break;
			default:
				ModUtils.LogEMUError($"Sorry, EMU currently doesn't support building {machineTypeFromResID}");
				break;
			}
		}

		private static void doSimpleBuild(int resID, GridInfo gridInfo, bool shouldLog)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			SimpleBuildInfo val = new SimpleBuildInfo
			{
				machineType = resID,
				rotation = gridInfo.yawRot,
				minGridPos = gridInfo.minPos
			};
			BuilderInfo val2 = (BuilderInfo)SaveState.GetResInfoFromId(resID);
			StreamedHologramData hologram = getHologram(val2, gridInfo);
			MachineInstanceDefaultBuilder val3 = (MachineInstanceDefaultBuilder)Player.instance.builder.GetBuilderForType((BuilderType)3);
			val3.newBuildInfo = (SimpleBuildInfo)((NetworkBuildInfo)val).Clone();
			val3 = (MachineInstanceDefaultBuilder)setCommonBuilderFields((ProceduralBuilder)(object)val3, val2, gridInfo, hologram);
			setPlayerBuilderPrivateFields((ProceduralBuilder)(object)val3, val2);
			doBuild((ProceduralBuilder)(object)val3, val2, -1);
			if (shouldLog)
			{
				ModUtils.LogEMUInfo($"Built {((ResourceInfo)val2).displayName} at ({gridInfo.minPos}) with yawRotation {gridInfo.yawRot}");
			}
		}

		private static void doSimpleBuildWithRecipe(int resID, GridInfo gridInfo, int recipe, bool shouldLog)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			SimpleBuildInfo newBuildInfo = new SimpleBuildInfo
			{
				machineType = resID,
				rotation = gridInfo.yawRot,
				minGridPos = gridInfo.minPos,
				recipeId = recipe
			};
			BuilderInfo val = (BuilderInfo)SaveState.GetResInfoFromId(resID);
			StreamedHologramData hologram = getHologram(val, gridInfo);
			MachineInstanceDefaultBuilder val2 = (MachineInstanceDefaultBuilder)Player.instance.builder.GetBuilderForType((BuilderType)3);
			val2.newBuildInfo = newBuildInfo;
			val2 = (MachineInstanceDefaultBuilder)setCommonBuilderFields((ProceduralBuilder)(object)val2, val, gridInfo, hologram);
			setPlayerBuilderPrivateFields((ProceduralBuilder)(object)val2, val);
			doBuild((ProceduralBuilder)(object)val2, val, recipe);
			if (shouldLog)
			{
				ModUtils.LogEMUInfo($"Built {((ResourceInfo)val).displayName} with recipe {recipe} at {gridInfo.minPos} with yawRotation {gridInfo.yawRot}");
			}
		}

		private static void doConveyorBuild(int resID, GridInfo gridInfo, ChainData? nullableChainData, bool reverseConveyor, bool shouldLog)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			if (!nullableChainData.HasValue)
			{
				ModUtils.LogEMUError("You cannot build a conveyor with null ChainData. Aborting build attempt.");
				return;
			}
			if (shouldLog)
			{
				ModUtils.LogEMUInfo("Attempting to build conveyor");
			}
			ChainData value = nullableChainData.Value;
			if (shouldLog)
			{
				ModUtils.LogEMUInfo($"chainData.count: {value.count}");
				ModUtils.LogEMUInfo($"chainData.rotation: {value.rotation}");
				ModUtils.LogEMUInfo($"chainData.shape: {value.shape}");
				ModUtils.LogEMUInfo($"chainData.start: {value.start}");
				ModUtils.LogEMUInfo($"chainData.height: {value.height}");
			}
			ConveyorBuildInfo val = new ConveyorBuildInfo
			{
				machineType = resID,
				chainData = new List<ChainData> { value },
				isReversed = reverseConveyor,
				machineIds = new List<uint>(),
				autoHubsEnabled = false
			};
			BuilderInfo val2 = (BuilderInfo)SaveState.GetResInfoFromId(resID);
			StreamedHologramData hologram = getHologram(val2, gridInfo, -1, value);
			ConveyorBuilder val3 = (ConveyorBuilder)Player.instance.builder.GetBuilderForType((BuilderType)0);
			val3.beltBuildInfo = val;
			val3 = (ConveyorBuilder)setCommonBuilderFields((ProceduralBuilder)(object)val3, val2, gridInfo, hologram);
			setPlayerBuilderPrivateFields((ProceduralBuilder)(object)val3, val2);
			((ProceduralBuilder)val3).BuildFromNetworkData((NetworkBuildInfo)(object)val, false);
			((InventoryWrapper)Player.instance.inventory).TryRemoveResources(resID, 1);
			if (shouldLog)
			{
				ModUtils.LogEMUInfo($"Built {((ResourceInfo)val2).displayName} at {gridInfo.minPos} with yawRotation {gridInfo.yawRot}");
			}
		}

		private static void doDrillBuild(int resID, GridInfo gridInfo)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			SimpleBuildInfo val = new SimpleBuildInfo
			{
				machineType = resID,
				rotation = gridInfo.yawRot,
				minGridPos = gridInfo.minPos
			};
			BuilderInfo builderInfo = (BuilderInfo)SaveState.GetResInfoFromId(resID);
			StreamedHologramData hologram = getHologram(builderInfo, gridInfo);
			DrillBuilder val2 = (DrillBuilder)Player.instance.builder.GetBuilderForType((BuilderType)1);
			val2.newBuildInfo = val;
			val2 = (DrillBuilder)setCommonBuilderFields((ProceduralBuilder)(object)val2, builderInfo, gridInfo, hologram);
			setPlayerBuilderPrivateFields((ProceduralBuilder)(object)val2, builderInfo);
			((ProceduralBuilder)val2).BuildFromNetworkData((NetworkBuildInfo)(object)val, false);
			((InventoryWrapper)Player.instance.inventory).TryRemoveResources(resID, 1);
		}

		private static void doFloorBuild(int resID, GridInfo gridInfo)
		{
		}

		private static void doResearchCoreBuild(int resID, GridInfo gridInfo)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_003f: 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_0067: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			ResearchCoreBuildInfo val = new ResearchCoreBuildInfo
			{
				machineType = resID,
				startCorner = gridInfo.minPos,
				endCorner = gridInfo.minPos,
				rotation = gridInfo.yawRot
			};
			BuilderInfo builderInfo = (BuilderInfo)SaveState.GetResInfoFromId(resID);
			StreamedHologramData hologram = getHologram(builderInfo, gridInfo);
			ResearchCoreBuilder val2 = (ResearchCoreBuilder)Player.instance.builder.GetBuilderForType((BuilderType)5);
			val2.coreBuildInfo = val;
			val2 = (ResearchCoreBuilder)setCommonBuilderFields((ProceduralBuilder)(object)val2, builderInfo, gridInfo, hologram);
			setPlayerBuilderPrivateFields((ProceduralBuilder)(object)val2, builderInfo);
			((ProceduralBuilder)val2).BuildFromNetworkData((NetworkBuildInfo)(object)val, false);
			((InventoryWrapper)Player.instance.inventory).TryRemoveResources(resID, 1);
		}

		private static void doStairsBuild(int resID, GridInfo gridInfo)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			StairsBuildInfo val = new StairsBuildInfo
			{
				machineType = resID,
				startCorner = gridInfo.minPos,
				dragDiff = Vector3Int.zero,
				rotation = gridInfo.yawRot
			};
			BuilderInfo builderInfo = (BuilderInfo)SaveState.GetResInfoFromId(resID);
			StreamedHologramData hologram = getHologram(builderInfo, gridInfo);
			StairsBuilder val2 = (StairsBuilder)Player.instance.builder.GetBuilderForType((BuilderType)6);
			val2.stairsBuildInfo = val;
			val2 = (StairsBuilder)setCommonBuilderFields((ProceduralBuilder)(object)val2, builderInfo, gridInfo, hologram);
			setPlayerBuilderPrivateFields((ProceduralBuilder)(object)val2, builderInfo);
			((ProceduralBuilder)val2).BuildFromNetworkData((NetworkBuildInfo)(object)val, false);
			((InventoryWrapper)Player.instance.inventory).TryRemoveResources(resID, 1);
		}

		private static void doStructureBuild(int resID, GridInfo gridInfo, int variationIndex)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			SimpleBuildInfo newBuildInfo = new SimpleBuildInfo
			{
				machineType = resID,
				rotation = gridInfo.yawRot,
				minGridPos = gridInfo.minPos
			};
			BuilderInfo builderInfo = (BuilderInfo)SaveState.GetResInfoFromId(resID);
			StreamedHologramData hologram = getHologram(builderInfo, gridInfo, variationIndex);
			StructureBuilder val = (StructureBuilder)Player.instance.builder.GetBuilderForType((BuilderType)11);
			((MachineInstanceDefaultBuilder)val).newBuildInfo = newBuildInfo;
			((ProceduralBuilder)val).currentVariationIndex = variationIndex;
			val = (StructureBuilder)setCommonBuilderFields((ProceduralBuilder)(object)val, builderInfo, gridInfo, hologram);
			setPlayerBuilderPrivateFields((ProceduralBuilder)(object)val, builderInfo);
			doBuild((ProceduralBuilder)(object)val, builderInfo, -1);
		}

		private static StreamedHologramData getHologram(BuilderInfo builderInfo, GridInfo gridInfo, int variationIndex = -1, ChainData? nullableChainData = null)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0011: 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_0014: Invalid comparison between Unknown and I4
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Invalid comparison between Unknown and I4
			//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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Expected I4, but got Unknown
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			StreamedHologramData val = null;
			Vector3 bottomCenter = ((GridInfo)(ref gridInfo)).BottomCenter;
			MachineTypeEnum instanceType = builderInfo.GetInstanceType();
			if ((int)instanceType == 4)
			{
				ChainData value = nullableChainData.Value;
				ConveyorInstance val2 = MachineManager.instance.Get<ConveyorInstance, ConveyorDefinition>(0, instanceType);
				StreamedHologramData obj = ((BuilderInfo)((ConveyorInstance)(ref val2)).myDef).GenerateUnbuiltHologramData();
				ConveyorHologramData val3 = (ConveyorHologramData)(object)((obj is ConveyorHologramData) ? obj : null);
				val3.buildBackwards = false;
				val3.curShape = value.shape;
				val3.numBelts = 1;
				bottomCenter.x += (float)((Vector3Int)(ref val2.gridInfo.dims)).x / 2f;
				bottomCenter.z += (float)((Vector3Int)(ref val2.gridInfo.dims)).z / 2f;
				Quaternion val4 = Quaternion.Euler(0f, (float)gridInfo.yawRot, 0f);
				((StreamedHologramData)val3).SetTransform(ref bottomCenter, ref val4, false);
				((StreamedHologramData)val3).type = builderInfo;
				return (StreamedHologramData)(object)val3;
			}
			if ((int)instanceType != 7)
			{
				bottomCenter.x += (float)((Vector3Int)(ref gridInfo.dims)).x / 2f;
				bottomCenter.z += (float)((Vector3Int)(ref gridInfo.dims)).z / 2f;
			}
			MachineTypeEnum val5 = instanceType;
			MachineTypeEnum val6 = val5;
			switch (val6 - 1)
			{
			case 0:
				val = ((BuilderInfo)(AssemblerDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 2:
				val = ((BuilderInfo)(ChestDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 4:
				val = ((BuilderInfo)(DrillDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 6:
				val = ((BuilderInfo)(InserterDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 7:
				val = ((BuilderInfo)(LightStickDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 9:
				val = ((BuilderInfo)(PlanterDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 10:
				val = ((BuilderInfo)(PowerGeneratorDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 11:
				val = ((BuilderInfo)(ResearchCoreDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 15:
				val = ((BuilderInfo)(SmelterDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 16:
				val = ((BuilderInfo)(StairsDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 18:
				val = ((BuilderInfo)(ThresherDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 20:
				val = ((BuilderInfo)(TransitDepotDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 21:
				val = ((BuilderInfo)(TransitPoleDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 22:
				val = ((BuilderInfo)(WaterWheelDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 23:
				val = ((BuilderInfo)(AccumulatorDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 24:
				val = ((BuilderInfo)(HighVoltageCableDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 25:
				val = ((BuilderInfo)(VoltageStepperDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 30:
				val = ((BuilderInfo)(StructureDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 31:
				val = ((BuilderInfo)(BlastSmelterDefinition)builderInfo).GenerateUnbuiltHologramData();
				break;
			case 5:
				Debug.Log((object)"Can't get hologram for Floor type");
				break;
			default:
				ModUtils.LogEMUWarning($"Skipped rendering hologram for unknown type: {instanceType}");
				break;
			}
			if (variationIndex != -1)
			{
				val.variationNum = variationIndex;
			}
			Quaternion val7 = Quaternion.Euler(0f, (float)gridInfo.yawRot, 0f);
			val.SetTransform(ref bottomCenter, ref val7, false);
			val.type = builderInfo;
			return val;
		}

		private static ProceduralBuilder setCommonBuilderFields(ProceduralBuilder builder, BuilderInfo builderInfo, GridInfo gridInfo, StreamedHologramData hologram)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			builder.curBuilderInfo = builderInfo;
			builder.myNewGridInfo = gridInfo;
			builder.myHolo = hologram;
			builder.recentlyBuilt = true;
			builder.OnShow();
			return builder;
		}

		private static void setPlayerBuilderPrivateFields(ProceduralBuilder builder, BuilderInfo builderInfo)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			ModUtils.SetPrivateField<PlayerBuilder>("_currentBuilder", Player.instance.builder, builder);
			ModUtils.SetPrivateField<PlayerBuilder>("_lastBuilderInfo", Player.instance.builder, builderInfo);
			ModUtils.SetPrivateField<PlayerBuilder>("_lastBuildPos", Player.instance.builder, ((GridInfo)(ref builder.curGridPlacement)).MinInt);
		}

		private static void doBuild(ProceduralBuilder builder, BuilderInfo builderInfo, int recipeID)
		{
			BuildMachineAction val = builder.GenerateNetworkData();
			val.recipeId = recipeID;
			val.resourceCostID = ((UniqueIdScriptableObject)builderInfo).uniqueId;
			val.resourceCostAmount = 1;
			NetworkMessageRelay.instance.SendNetworkAction((NetworkAction)(object)val);
		}
	}
	public class NewRecipeDetails
	{
		public CraftingMethod craftingMethod;

		public int craftTierRequired;

		public int duration;

		public List<RecipeResourceInfo> ingredients = new List<RecipeResourceInfo>();

		public List<RecipeResourceInfo> outputs = new List<RecipeResourceInfo>();

		public int sortPriority;

		public string unlockName;

		public SchematicsRecipeData ConvertToRecipe()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			SchematicsRecipeData val = (SchematicsRecipeData)ScriptableObject.CreateInstance("SchematicsRecipeData");
			val.craftingMethod = craftingMethod;
			val.craftTierRequired = craftTierRequired;
			val.duration = duration;
			val.sortPriority = sortPriority;
			val.ingQuantities = new int[ingredients.Count];
			val.ingTypes = (ResourceInfo[])(object)new ResourceInfo[ingredients.Count];
			val.outputQuantities = new int[outputs.Count];
			val.outputTypes = (ResourceInfo[])(object)new ResourceInfo[outputs.Count];
			for (int i = 0; i < ingredients.Count; i++)
			{
				val.ingQuantities[i] = ingredients[i].quantity;
				ResourceInfo resourceInfoByNameUnsafe = ModUtils.GetResourceInfoByNameUnsafe(ingredients[i].name);
				ModUtils.NullCheck(resourceInfoByNameUnsafe, "New recipe ingredient " + ingredients[i].name);
				val.ingTypes[i] = resourceInfoByNameUnsafe;
			}
			for (int j = 0; j < outputs.Count; j++)
			{
				val.outputQuantities[j] = outputs[j].quantity;
				ResourceInfo resourceInfoByNameUnsafe2 = ModUtils.GetResourceInfoByNameUnsafe(outputs[j].name);
				ModUtils.NullCheck(resourceInfoByNameUnsafe2, "New recipe output " + outputs[j].name);
				val.outputTypes[j] = resourceInfoByNameUnsafe2;
			}
			return val;
		}
	}
	public struct RecipeResourceInfo
	{
		public string name;

		public int quantity;

		public RecipeResourceInfo(string _name, int _quantity)
		{
			name = _name;
			quantity = _quantity;
		}
	}
	public class NewResourceDetails
	{
		public string parentName;

		public CraftingMethod craftingMethod;

		public int craftTierRequired;

		public string description;

		public float fuelAmount;

		public string subHeaderTitle;

		public int maxStackCount = 500;

		public int miningTierRequired;

		public GameObject model3D;

		public GameObject rawConveyorResourcePrefab;

		public string name;

		public Sprite sprite;

		public int sortPriority;

		public string unlockName;

		internal ResourceInfo ConvertToResourceInfo()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			ResourceInfo val = (ResourceInfo)ScriptableObject.CreateInstance("ResourceInfo");
			val.craftingMethod = craftingMethod;
			val.craftTierRequired = craftTierRequired;
			val.description = description;
			val.fuelAmount = fuelAmount;
			val.maxStackCount = maxStackCount;
			val.miningTierRequired = miningTierRequired;
			val.model3D = model3D;
			val.rawConveyorResourcePrefab = rawConveyorResourcePrefab;
			val.rawName = name;
			val.rawSprite = sprite;
			val.sortPriority = sortPriority;
			return val;
		}
	}
	public class NewUnlockDetails
	{
		public TechCategory category;

		public CoreType coreTypeNeeded;

		public int coreCountNeeded;

		public List<string> dependencyNames = new List<string>();

		public string description;

		public string displayName;

		public int numScansNeeded;

		public ResearchTier requiredTier;

		public Sprite sprite;

		public int treePosition;
	}
	[BepInPlugin("com.equinox.EquinoxsModUtils", "EquinoxsModUtils", "4.0.0")]
	public class ModUtils : BaseUnityPlugin
	{
		private const string MyGUID = "com.equinox.EquinoxsModUtils";

		private const string PluginName = "EquinoxsModUtils";

		private const string VersionString = "4.0.0";

		private static readonly Harmony Harmony = new Harmony("com.equinox.EquinoxsModUtils");

		public static ManualLogSource Log = new ManualLogSource("EquinoxsModUtils");

		public static bool hasGameStateLoaded = false;

		public static bool hasGameDefinesLoaded = false;

		public static bool hasMachineManagerLoaded = false;

		public static bool hasSaveStateLoaded = false;

		public static bool hasTechTreeStateLoaded = false;

		public static bool hasGameLoaded = false;

		private static bool loadingUIObserved = false;

		private static string dataFolder = Application.persistentDataPath + "/Equinox's Mod Utils";

		internal static List<NewResourceDetails> resourcesToAdd = new List<NewResourceDetails>();

		internal static List<NewRecipeDetails> recipesToAdd = new List<NewRecipeDetails>();

		internal static List<SchematicsSubHeader> subHeadersToAdd = new List<SchematicsSubHeader>();

		private static List<Unlock> unlocksToAdd = new List<Unlock>();

		private static Dictionary<string, List<string>> unlockDependencies = new Dictionary<string, List<string>>();

		private static Dictionary<string, int> resourceNameToIDMap = new Dictionary<string, int>();

		private static Dictionary<string, int> unlockNameToIDMap = new Dictionary<string, int>();

		private static Dictionary<int, Unlock> unlockCache = new Dictionary<int, Unlock>();

		public static Dictionary<string, string> hashTranslations = new Dictionary<string, string>();

		internal static List<UnlockState> unlockStatesToAdd = new List<UnlockState>();

		internal static List<string> customUnlockHashedNames = new List<string>();

		private static Dictionary<string, object> customMachineData = new Dictionary<string, object>();

		private static bool hasCustomMachineDataLoaded = false;

		private static float sSinceLastPacedLog = 0f;

		private static bool doUnlockTest = false;

		private static bool printResources = false;

		private static bool printUnlocks = false;

		public static event EventHandler GameStateLoaded;

		public static event EventHandler GameDefinesLoaded;

		public static event EventHandler MachineManagerLoaded;

		public static event EventHandler SaveStateLoaded;

		public static event EventHandler TechTreeStateLoaded;

		public static event EventHandler GameSaved;

		public static event EventHandler GameLoaded;

		private void Awake()
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			((BaseUnityPlugin)this).Logger.LogInfo((object)"PluginName: EquinoxsModUtils, VersionString: 4.0.0 is loading...");
			Harmony.PatchAll();
			CheckBepInExConfig();
			Harmony.CreateAndPatchAll(typeof(FHG_UtilsPatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(GameDefinesPatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(LocsUtilityPatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(SaveStatePatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(StringPatternsList), (string)null);
			Harmony.CreateAndPatchAll(typeof(TechActivatedSystemMessagePatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(TechTreeGridPatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(TechTreeStatePatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(UIManagerPatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(UnlockPatch), (string)null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"PluginName: EquinoxsModUtils, VersionString: 4.0.0 is loaded.");
			Log = ((BaseUnityPlugin)this).Logger;
			if (doUnlockTest)
			{
				AddNewUnlock(new NewUnlockDetails
				{
					category = (TechCategory)1,
					coreTypeNeeded = (CoreType)0,
					coreCountNeeded = 1,
					description = "Test Unlock Description",
					displayName = "Test Unlock",
					numScansNeeded = 0,
					requiredTier = (ResearchTier)2,
					treePosition = 50
				});
			}
		}

		private void Update()
		{
			if (!hasGameStateLoaded)
			{
				CheckIfGameStateLoaded();
			}
			if (!hasGameDefinesLoaded)
			{
				CheckIfGameDefinesLoaded();
			}
			if (!hasMachineManagerLoaded)
			{
				CheckIfMachineManagerLoaded();
			}
			if (!hasSaveStateLoaded)
			{
				CheckIfSaveStateLoaded();
			}
			if (!hasTechTreeStateLoaded)
			{
				CheckIfTechTreeStateLoaded();
			}
			if (!hasGameLoaded)
			{
				CheckIfGameLoaded();
			}
			sSinceLastPacedLog += Time.deltaTime;
		}

		private static void CheckBepInExConfig()
		{
			string text = Environment.CurrentDirectory + "/BepInEx/config/BepInEx.cfg";
			LogEMUInfo("Config file path: '" + text + "'");
			if (File.Exists(text))
			{
				string text2 = File.ReadAllText(text);
				if (!text2.Contains("HideManagerGameObject = true"))
				{
					LogEMUError("HideGameManagerObject has not been set to true in BepInEx.cfg");
					LogEMUError("Equinox's Mod Utils and any mods that use this library will not work if this is not enabled");
				}
				else
				{
					LogEMUInfo("HideGameManagerObject has been correctly set to true");
				}
			}
		}

		internal static void LogEMUInfo(string message)
		{
			Log.LogInfo((object)message);
		}

		internal static void LogEMUWarning(string message)
		{
			Log.LogWarning((object)message);
		}

		internal static void LogEMUError(string message)
		{
			Log.LogError((object)message);
		}

		internal static void FireGameSavedEvent(string worldName)
		{
			ModUtils.GameSaved?.Invoke(worldName, EventArgs.Empty);
		}

		private static void PrintAllResourceNames()
		{
			Debug.Log((object)"Printing all resources");
			foreach (ResourceInfo resource in GameDefines.instance.resources)
			{
				Debug.Log((object)resource.displayName);
			}
		}

		private static void PrintAllUnlockNames()
		{
			Debug.Log((object)"Printing all unlocks");
			foreach (Unlock unlock in GameDefines.instance.unlocks)
			{
				Debug.Log((object)LocsUtility.TranslateStringFromHash(unlock.displayNameHash, (string)null, (Object)null));
			}
		}

		private static void CheckIfGameStateLoaded()
		{
			if (!((Object)(object)GameLogic.instance == (Object)null) && GameState.instance != null)
			{
				hasGameStateLoaded = true;
				ModUtils.GameStateLoaded?.Invoke(GameState.instance, EventArgs.Empty);
				LogEMUInfo("GameState.intance loaded.");
			}
		}

		private static void CheckIfGameDefinesLoaded()
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Invalid comparison between Unknown and I4
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)GameLogic.instance == (Object)null || !((Object)(object)GameDefines.instance != (Object)null))
			{
				return;
			}
			hasGameDefinesLoaded = true;
			AddCustomUnlocks();
			ModUtils.GameDefinesLoaded?.Invoke(GameDefines.instance, EventArgs.Empty);
			LogEMUInfo("GameDefines.instace loaded");
			foreach (Unlock unlock in GameDefines.instance.unlocks)
			{
				string text = LocsUtility.TranslateStringFromHash(unlock.displayNameHash, (string)null, (Object)null);
				if ((int)unlock.requiredTier == 0)
				{
					LogEMUWarning("Unlock '" + text + "' has required Tier NONE, setting to Tier0");
					unlock.requiredTier = (ResearchTier)1;
				}
			}
			if (printResources)
			{
				PrintAllResourceNames();
			}
			if (printUnlocks)
			{
				PrintAllUnlockNames();
			}
		}

		private static void CheckIfSaveStateLoaded()
		{
			if (!((Object)(object)GameLogic.instance == (Object)null) && SaveState.instance != null && SaveState.instance.metadata != null && !string.IsNullOrEmpty(SaveState.instance.metadata.worldName))
			{
				hasSaveStateLoaded = true;
				LoadCustomMachineData(SaveState.instance.metadata.worldName);
				ModUtils.SaveStateLoaded?.Invoke(SaveState.instance, EventArgs.Empty);
				LogEMUInfo("SaveState.instance loaded");
			}
		}

		private static void CheckIfTechTreeStateLoaded()
		{
			if (MachineManager.instance != null && TechTreeState.instance != null)
			{
				hasTechTreeStateLoaded = true;
				ModUtils.TechTreeStateLoaded?.Invoke(TechTreeState.instance, EventArgs.Empty);
				LogEMUInfo("TechTreeState.instance loaded");
			}
		}

		private static void CheckIfMachineManagerLoaded()
		{
			if (MachineManager.instance != null)
			{
				hasMachineManagerLoaded = true;
				ModUtils.MachineManagerLoaded?.Invoke(MachineManager.instance, EventArgs.Empty);
				LogEMUInfo("MachineManager.instance loaded");
			}
		}

		private static void CheckIfGameLoaded()
		{
			if (!((Object)(object)LoadingUI.instance == (Object)null) || loadingUIObserved)
			{
				if ((Object)(object)LoadingUI.instance != (Object)null && !loadingUIObserved)
				{
					loadingUIObserved = true;
				}
				else if ((Object)(object)LoadingUI.instance == (Object)null && loadingUIObserved)
				{
					LoadUnlockStates(SaveState.instance.metadata.worldName);
					hasGameLoaded = true;
					ModUtils.GameLoaded?.Invoke(null, EventArgs.Empty);
					LogEMUInfo("Game Loaded");
				}
			}
		}

		private static void AddCustomUnlocks()
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			LogEMUInfo($"Adding {unlocksToAdd.Count} new Unlocks");
			for (int i = 0; i < unlocksToAdd.Count; i++)
			{
				Unlock unlock = unlocksToAdd[i];
				if (NullCheck(unlock, "Unlock") && FindDependencies(ref unlock))
				{
					((UniqueIdScriptableObject)unlock).uniqueId = GetNewUnlockUniqueID();
					customUnlockHashedNames.Add(unlock.displayNameHash);
					GameDefines.instance.unlocks.Add(unlock);
					LogEMUInfo($"Added new Unlock: '{((UniqueIdScriptableObject)unlock).uniqueId}'");
					unlockStatesToAdd.Add(new UnlockState
					{
						isActive = false,
						everActive = true,
						isDiscovered = true,
						scansCompleted = 0,
						scansRequired = 0,
						dependencies = new int[0],
						requirementFor = new int[0],
						tier = unlock.requiredTier,
						exists = true,
						unlockRef = unlock,
						unlockedRecipes = new List<SchematicsRecipeData>(),
						unlockedResources = new List<ResourceInfo>(),
						unlockedUpgrades = new List<UpgradeInfo>()
					});
				}
			}
		}

		private static void CleanUnlockStates()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: 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)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			LogEMUInfo("Cleaning Unlock States");
			int num = 0;
			while (num < TechTreeState.instance.unlockStates.Count())
			{
				UnlockState val = TechTreeState.instance.unlockStates[num];
				if ((Object)(object)val.unlockRef == (Object)null || GameDefines.instance.unlocks.Contains(val.unlockRef))
				{
					num++;
					continue;
				}
				ArrayExt.RemoveAt<UnlockState>(TechTreeState.instance.unlockStates, num);
				GameState.instance.acknowledgedUnlocks.Remove(((UniqueIdScriptableObject)val.unlockRef).uniqueId);
				LogEMUInfo($"Could not find Unlock for UnlockState #{num}. Removed.");
			}
			LogEMUInfo("Clearing duplicate unlock states");
			List<UnlockState> list = new List<UnlockState>();
			for (int i = 0; i < TechTreeState.instance.unlockStates.Count(); i++)
			{
				bool flag = true;
				foreach (UnlockState item in list)
				{
					if ((Object)(object)TechTreeState.instance.unlockStates[i].unlockRef == (Object)null || (Object)(object)item.unlockRef == (Object)null || ((UniqueIdScriptableObject)TechTreeState.instance.unlockStates[i].unlockRef).uniqueId != ((UniqueIdScriptableObject)item.unlockRef).uniqueId)
					{
						continue;
					}
					flag = false;
					break;
				}
				if (flag)
				{
					list.Add(TechTreeState.instance.unlockStates[i]);
				}
			}
			int num2 = TechTreeState.instance.unlockStates.Count() - list.Count;
			LogEMUInfo($"Found '{list.Count}' unique states");
			LogEMUInfo($"Removing {num2} duplicates");
			TechTreeState.instance.unlockStates = list.ToArray();
		}

		private static void CleanTechProgress()
		{
			LogEMUInfo("Cleaning Tech Progress");
			int num = 0;
			while (num < SaveState.instance.techTree.researchProgress.Count)
			{
				TechProgress val = SaveState.instance.techTree.researchProgress[num];
				if (val.techIndex >= TechTreeState.instance.unlockStates.Length)
				{
					SaveState.instance.techTree.researchProgress.RemoveAt(num);
					LogEMUInfo($"Could not find UnlockState for TechProgress #{val.techIndex}. Removed.");
				}
				else
				{
					num++;
				}
			}
		}

		internal static void AddStatesForCustomUnlocks()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0060: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			CleanUnlockStates();
			CleanTechProgress();
			LogEMUInfo($"Adding {unlocksToAdd.Count} new UnlockStates");
			foreach (UnlockState item in unlockStatesToAdd)
			{
				bool flag = false;
				for (int i = 0; i < TechTreeState.instance.unlockStates.Count(); i++)
				{
					UnlockState val = TechTreeState.instance.unlockStates[i];
					if ((Object)(object)val.unlockRef == (Object)null)
					{
						LogEMUInfo("Skipping unlock with null unlockRef");
					}
					else if (((UniqueIdScriptableObject)item.unlockRef).uniqueId == ((UniqueIdScriptableObject)val.unlockRef).uniqueId)
					{
						TechTreeState.instance.unlockStates[i] = item;
						flag = true;
						LogEMUInfo($"Updated UnlockState for Unlock #{((UniqueIdScriptableObject)item.unlockRef).uniqueId}");
						i = TechTreeState.instance.unlockStates.Count();
						LogEMUInfo("Existing tech name: " + LocsUtility.TranslateStringFromHash(val.unlockRef.displayNameHash, (string)null, (Object)null));
						break;
					}
				}
				if (!flag)
				{
					CollectionExtensions.AddItem<UnlockState>((IEnumerable<UnlockState>)TechTreeState.instance.unlockStates, item);
					LogEMUInfo($"Added UnlockState for Unlock #{((UniqueIdScriptableObject)item.unlockRef).uniqueId}");
				}
			}
		}

		private static int GetNewUnlockUniqueID()
		{
			if (!hasGameDefinesLoaded)
			{
				LogEMUInfo("Couldn't get new unlock unique ID, GameDefines not loaded yet.");
				LogEMUInfo("Check that you're calling this from an OnGameDefinesLoaded event");
				return -1;
			}
			int num = -1;
			foreach (Unlock unlock in GameDefines.instance.unlocks)
			{
				if (((UniqueIdScriptableObject)unlock).uniqueId > num)
				{
					num = ((UniqueIdScriptableObject)unlock).uniqueId;
				}
			}
			LogEMUInfo($"Found ID {num + 1} for new unlock");
			return num + 1;
		}

		private static bool FindDependencies(ref Unlock unlock)
		{
			List<Unlock> list = new List<Unlock>();
			List<string> list2 = unlockDependencies[unlock.displayNameHash];
			foreach (string item in list2)
			{
				Unlock unlockByName = GetUnlockByName(item);
				if ((Object)(object)unlockByName != (Object)null)
				{
					list.Add(unlockByName);
					continue;
				}
				LogEMUError("Could not find dependency with name '" + item + "'. Abandoning attempt to add.");
				LogEMUError("Try using a name from EquinoxsModUtils.ResourceNames");
				return false;
			}
			unlock.dependencies = list;
			if (list.Count >= 1)
			{
				unlock.dependency1 = list[0];
			}
			if (list.Count == 2)
			{
				unlock.dependency2 = list[1];
			}
			return true;
		}

		private static bool AreListIntsEqual(List<int> list1, List<int> list2, bool sort)
		{
			if (list1.Count != list2.Count)
			{
				return false;
			}
			if (sort)
			{
				list1.Sort();
				list2.Sort();
			}
			for (int i = 0; i < list1.Count; i++)
			{
				if (list1[i] != list2[i])
				{
					return false;
				}
			}
			return true;
		}

		internal static void SaveUnlockStates(string worldName)
		{
			List<string> list = new List<string>();
			foreach (string customUnlockHashedName in customUnlockHashedNames)
			{
				Unlock unlockByName = GetUnlockByName(LocsUtility.TranslateStringFromHash(customUnlockHashedName, (string)null, (Object)null));
				list.Add($"{customUnlockHashedName}|{TechTreeState.instance.IsUnlockActive(((UniqueIdScriptableObject)unlockByName).uniqueId)}");
			}
			string path = dataFolder + "/" + worldName + ".txt";
			File.WriteAllLines(path, list);
		}

		internal static void LoadUnlockStates(string worldName)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_00f2: Expected O, but got Unknown
			string path = dataFolder + "/" + worldName + ".txt";
			if (!File.Exists(path))
			{
				return;
			}
			string[] array = File.ReadAllLines(path);
			string[] array2 = array;
			foreach (string text in array2)
			{
				string text2 = text.Split(new char[1] { '|' })[0];
				if (!int.TryParse(text2, out var _))
				{
					bool flag = bool.Parse(text.Split(new char[1] { '|' })[1]);
					if (!customUnlockHashedNames.Contains(text2))
					{
						LogEMUError("Saved Unlock '" + text2 + "' is not in customUnlocksIDs");
					}
					else if (flag)
					{
						UnlockTechAction val = new UnlockTechAction
						{
							info = new UnlockTechInfo
							{
								unlockID = ((UniqueIdScriptableObject)GetUnlockByName(LocsUtility.TranslateStringFromHash(text2, (string)null, (Object)null))).uniqueId,
								drawPower = false
							}
						};
						NetworkMessageRelay.instance.SendNetworkAction((NetworkAction)(object)val);
					}
				}
			}
		}

		internal static void SaveCustomMachineData(string worldName)
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, object> customMachineDatum in customMachineData)
			{
				list.Add($"{customMachineDatum.Key}|{customMachineDatum.Value}");
			}
			string path = dataFolder + "/" + worldName + " CustomData.txt";
			File.WriteAllLines(path, list);
		}

		internal static void LoadCustomMachineData(string worldName)
		{
			string path = dataFolder + "/" + worldName + " CustomData.txt";
			if (!File.Exists(path))
			{
				LogEMUWarning("No CustomData save file found for world '" + worldName + "'");
				return;
			}
			string[] array = File.ReadAllLines(path);
			string[] array2 = array;
			foreach (string text in array2)
			{
				string[] array3 = text.Split(new char[1] { '|' });
				string text2 = array3[1];
				object obj = null;
				string text3 = array3[0];
				string[] array4 = text3.Split(new char[1] { '-' });
				string text4 = array4[2];
				switch (text4)
				{
				case "System.UInt32":
					obj = uint.Parse(text2);
					break;
				case "System.Int32":
					obj = int.Parse(text2);
					break;
				case "System.Single":
					obj = float.Parse(text2);
					break;
				case "System.Double":
					obj = double.Parse(text2);
					break;
				case "System.Boolean":
					obj = bool.Parse(text2);
					break;
				case "System.String":
					obj = text2;
					break;
				case "System.Char":
					obj = char.Parse(text2);
					break;
				default:
					LogEMUError("Cannot load custom data (key: '" + text3 + "') with unhandled type: '" + text4 + "'");
					continue;
				}
				customMachineData[text3] = obj;
			}
			hasCustomMachineDataLoaded = true;
			Log.LogInfo((object)"Loaded custom machine data");
		}

		public static ResourceInfo GetResourceInfoByName(string name, bool shouldLog = false)
		{
			if (shouldLog)
			{
				LogEMUInfo("Looking for resource with name '" + name + "'");
			}
			if (hasGameDefinesLoaded)
			{
				if (resourceNameToIDMap.ContainsKey(name))
				{
					if (shouldLog)
					{
						LogEMUInfo("Found resource in cache");
					}
					return GameDefines.instance.resources[resourceNameToIDMap[name]];
				}
				foreach (ResourceInfo resource in GameDefines.instance.resources)
				{
					if (resource.displayName == name)
					{
						if (shouldLog)
						{
							LogEMUInfo("Found resource with name '" + name + "'");
						}
						if (!resourceNameToIDMap.ContainsKey(name))
						{
							resourceNameToIDMap.Add(name, GameDefines.instance.resources.IndexOf(resource));
						}
						return resource;
					}
				}
			}
			else
			{
				LogEMUWarning("GetResourceInfoByName() was called before GameDefines.instance has loaded");
				LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking with ModUtils.hasGameDefinesLoaded");
			}
			LogEMUWarning("Could not find resource with name '" + name + "'");
			LogEMUWarning("Try using a name from EquinoxsModUtils.ResourceNames");
			return null;
		}

		public static ResourceInfo GetResourceInfoByNameUnsafe(string name, bool shouldLog = false)
		{
			if (resourceNameToIDMap.ContainsKey(name))
			{
				if (shouldLog)
				{
					LogEMUInfo("Found resource in cache");
				}
				return GameDefines.instance.resources[resourceNameToIDMap[name]];
			}
			foreach (ResourceInfo resource in GameDefines.instance.resources)
			{
				if (resource.displayName == name)
				{
					if (shouldLog)
					{
						LogEMUInfo("Found resource with name '" + name + "'");
					}
					if (!resourceNameToIDMap.ContainsKey(name))
					{
						resourceNameToIDMap.Add(name, GameDefines.instance.resources.IndexOf(resource));
					}
					return resource;
				}
			}
			LogEMUWarning("Could not find resource with name '" + name + "'");
			LogEMUWarning("Try using a name from EquinoxsModUtils.ResourceNames");
			return null;
		}

		public static int GetResourceIDByName(string name, bool shouldLog = false)
		{
			if (shouldLog)
			{
				LogEMUInfo("Looking for ID of resource with name '" + name + "'");
			}
			if (hasSaveStateLoaded)
			{
				ResourceInfo resourceInfoByName = GetResourceInfoByName(name);
				if ((Object)(object)resourceInfoByName != (Object)null)
				{
					return SaveState.GetIdForResInfo((UniqueIdScriptableObject)(object)resourceInfoByName);
				}
				return -1;
			}
			LogEMUWarning("GetResourceIDByName() was called before SaveState.instance has loaded");
			LogEMUWarning("Try using the event ModUtils.SaveState loaded or checking with ModUtils.hasSaveStateLoaded");
			return -1;
		}

		public static MachineTypeEnum GetMachineTypeFromResID(int resID)
		{
			//IL_0025: 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)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			if (!hasSaveStateLoaded)
			{
				LogEMUError("GetMachineTypeFromResID() called before SaveState.instance has loaded");
				LogEMUWarning("Try using the event ModUtils.SaveStateLoaded or checking with ModUtils.hasSaveStateLoaded");
				return (MachineTypeEnum)0;
			}
			try
			{
				return ((BuilderInfo)SaveState.GetResInfoFromId(resID)).GetInstanceType();
			}
			catch (Exception ex)
			{
				LogEMUError($"Error occurred during GetMachineTypeFromResID(resID = {resID})");
				LogEMUError(ex.Message ?? "");
				LogEMUError(ex.StackTrace ?? "");
				return (MachineTypeEnum)0;
			}
		}

		public static void AddNewResource(NewResourceDetails details)
		{
			resourcesToAdd.Add(details);
		}

		public static int GetNewResourceID(bool shouldLog = false)
		{
			int num = 0;
			foreach (ResourceInfo resource in GameDefines.instance.resources)
			{
				if (((UniqueIdScriptableObject)resource).uniqueId > num)
				{
					num = ((UniqueIdScriptableObject)resource).uniqueId;
				}
			}
			if (shouldLog)
			{
				LogEMUInfo($"Found new Resource ID: {num + 1}");
			}
			return num + 1;
		}

		public static void UpdateResourceUnlock(string resourceName, string unlockName, bool shouldLog = false)
		{
			ResourceInfo resourceInfoByName = GetResourceInfoByName(resourceName, shouldLog);
			if (!NullCheck(resourceInfoByName, resourceName))
			{
				return;
			}
			Unlock unlockByName = GetUnlockByName(unlockName, shouldLog);
			if (NullCheck(unlockByName, unlockName))
			{
				resourceInfoByName.unlock = unlockByName;
				if (shouldLog)
				{
					LogEMUInfo("Successfully set .unlock for " + resourceInfoByName.displayName + " to Unlock '" + unlockName + "'");
				}
			}
		}

		public static void UpdateResourceHeaderType(string resourceName, SchematicsSubHeader header, bool shouldLog = false)
		{
			ResourceInfo resourceInfoByName = GetResourceInfoByName(resourceName, shouldLog);
			if (NullCheck(resourceInfoByName, resourceName))
			{
				resourceInfoByName.headerType = header;
				if (shouldLog)
				{
					LogEMUInfo("Successfully set .headerType for " + resourceInfoByName.displayName);
				}
			}
		}

		public static SchematicsRecipeData FindThresherRecipeFromOutputs(string output1Name, string output2Name, bool shouldLog = false)
		{
			if (shouldLog)
			{
				LogEMUInfo("Looking for thresher recipe with outputs: '" + output1Name + "', '" + output2Name + "'");
			}
			if (!hasGameDefinesLoaded)
			{
				LogEMUWarning("FindThresherRecipeFromOutputs() called before GameDefines.instance has loaded");
				LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking with ModUtils.hasGameDefinesLoaded");
				return null;
			}
			foreach (SchematicsRecipeData schematicsRecipeEntry in GameDefines.instance.schematicsRecipeEntries)
			{
				if (schematicsRecipeEntry.outputTypes.Count() == 2 && ((schematicsRecipeEntry.outputTypes[0].displayName == output1Name && schematicsRecipeEntry.outputTypes[1].displayName == output2Name) || (schematicsRecipeEntry.outputTypes[0].displayName == output2Name && schematicsRecipeEntry.outputTypes[1].displayName == output1Name)))
				{
					if (shouldLog)
					{
						LogEMUInfo("Found thresher recipe");
					}
					return schematicsRecipeEntry;
				}
			}
			LogEMUWarning("Could not find thresher recipe");
			LogEMUWarning("Try using the resource names in EquinoxsModUtils.ResourceNames");
			return null;
		}

		public static SchematicsRecipeData TryFindThresherRecipe(int ingredientResID, bool shouldLog = false)
		{
			if (!hasGameDefinesLoaded)
			{
				LogEMUError("TryFindThresherRecipe() called before GameDefines.instance loaded");
				LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking ModUtils.hasGameDefinesLoaded.");
				return null;
			}
			if (shouldLog)
			{
				LogEMUInfo($"Attempting to find thresher recipe with ingredient #{ingredientResID}");
			}
			foreach (SchematicsRecipeData schematicsRecipeEntry in GameDefines.instance.schematicsRecipeEntries)
			{
				if (((UniqueIdScriptableObject)schematicsRecipeEntry.ingTypes[0]).uniqueId == ingredientResID)
				{
					if (shouldLog)
					{
						LogEMUInfo($"Found Thresher recipe for resource #{ingredientResID}");
					}
					return schematicsRecipeEntry;
				}
			}
			LogEMUError($"Could not find a recipe for resource #{ingredientResID}, please check this value.");
			return null;
		}

		public static SchematicsRecipeData TryFindRecipe(List<int> ingredientIDs, List<int> resultIDs, bool shouldLog = false)
		{
			if (!hasGameDefinesLoaded)
			{
				LogEMUError("TryFindRecipe() called before GameDefines.instance loaded");
				LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking ModUtils.hasGameDefinesLoaded.");
				return null;
			}
			if (shouldLog)
			{
				LogEMUInfo("Attempting to find recipe");
			}
			foreach (SchematicsRecipeData schematicsRecipeEntry in GameDefines.instance.schematicsRecipeEntries)
			{
				List<int> list = schematicsRecipeEntry.ingTypes.Select((ResourceInfo item) => ((UniqueIdScriptableObject)item).uniqueId).ToList();
				List<int> list2 = schematicsRecipeEntry.outputTypes.Select((ResourceInfo item) => ((UniqueIdScriptableObject)item).uniqueId).ToList();
				if (AreListIntsEqual(ingredientIDs, list, sort: true) && AreListIntsEqual(resultIDs, list2, sort: true))
				{
					if (shouldLog)
					{
						LogEMUInfo("Found recipe");
					}
					return schematicsRecipeEntry;
				}
			}
			LogEMUError("Could not find recipe, please check the resource IDs passed in the arguments.");
			return null;
		}

		public static void AddNewRecipe(NewRecipeDetails details, bool shouldLog = false)
		{
			if (details.ingredients.Count == 0)
			{
				LogEMUError("NewRecipeDetails has no ingredients, will not be added");
				return;
			}
			if (details.outputs.Count == 0)
			{
				LogEMUError("NweRecipeDetails has no outputs, will not be added");
				return;
			}
			recipesToAdd.Add(details);
			if (shouldLog)
			{
				LogEMUInfo("Registered NewRecipeDetails for adding to game");
			}
		}

		public static void AddNewSchematicsSubHeader(string title, string parentTitle, int priority, bool shouldLog = false)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			SchematicsSubHeader val = (SchematicsSubHeader)ScriptableObject.CreateInstance(typeof(SchematicsSubHeader));
			val.title = parentTitle + "/" + title;
			val.priority = priority;
			subHeadersToAdd.Add(val);
			if (shouldLog)
			{
				LogEMUInfo("Registered new SchematicsSubHeader '" + title + "' for adding to game");
			}
		}

		public static SchematicsHeader GetSchematicsHeaderByTitle(string title, bool shouldLog = false)
		{
			if (!NullCheck(GameDefines.instance, "GameDefines.instance"))
			{
				LogEMUError("GetSchematicsHeaderByTitle() called before GameDefines.instance has loaded");
				LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking ModUtils.hasGameDefinesLoaded.");
				return null;
			}
			foreach (SchematicsHeader schematicsHeaderEntry in GameDefines.instance.schematicsHeaderEntries)
			{
				if (schematicsHeaderEntry.title == title)
				{
					if (shouldLog)
					{
						LogEMUInfo("Found SchematicsHeader with title '" + title + "'");
					}
					return schematicsHeaderEntry;
				}
			}
			LogEMUError("Could not find SchematicsSubHeader with title '" + title + "'");
			return null;
		}

		public static SchematicsSubHeader GetSchematicsSubHeaderByTitle(string title, bool shouldLog = false)
		{
			if (!NullCheck(GameDefines.instance, "GameDefines.instance"))
			{
				LogEMUError("GetSchematicsSubHeaderByTitle() called before GameDefines.instance has loaded");
				LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking ModUtils.hasGameDefinesLoaded.");
				return null;
			}
			foreach (SchematicsSubHeader schematicsSubHeaderEntry in GameDefines.instance.schematicsSubHeaderEntries)
			{
				if (schematicsSubHeaderEntry.title == title)
				{
					if (shouldLog)
					{
						LogEMUInfo("Found SchematicsSubHeader with title '" + title + "'");
					}
					return schematicsSubHeaderEntry;
				}
			}
			LogEMUError("Could not find SchematicsSubHeader with title '" + title + "'");
			return null;
		}

		public static int GetNewRecipeID(bool shouldLog = false)
		{
			if (!NullCheck(GameDefines.instance, "GameDefines.instance"))
			{
				LogEMUError("GetNewRecipeID() called before GameDefines.instance has loaded");
				LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking ModUtils.hasGameDefinesLoaded.");
				return -1;
			}
			int num = 0;
			foreach (SchematicsRecipeData schematicsRecipeEntry in GameDefines.instance.schematicsRecipeEntries)
			{
				if (((UniqueIdScriptableObject)schematicsRecipeEntry).uniqueId > num)
				{
					num = ((UniqueIdScriptableObject)schematicsRecipeEntry).uniqueId;
				}
			}
			if (shouldLog)
			{
				LogEMUInfo($"Found new Recipe ID: {num + 1}");
			}
			return num + 1;
		}

		public static int GetNewSchematicsSubHeaderID(bool shouldLog = false)
		{
			if (!NullCheck(GameDefines.instance, "GameDefines.instance"))
			{
				LogEMUError("GetNewSchematicsSubHeaderID() called before GameDefines.instance has loaded");
				LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking ModUtils.hasGameDefinesLoaded.");
				return -1;
			}
			int num = 0;
			foreach (SchematicsSubHeader schematicsSubHeaderEntry in GameDefines.instance.schematicsSubHeaderEntries)
			{
				if (((UniqueIdScriptableObject)schematicsSubHeaderEntry).uniqueId > num)
				{
					num = ((UniqueIdScriptableObject)schematicsSubHeaderEntry).uniqueId;
				}
			}
			if (shouldLog)
			{
				LogEMUInfo($"Found new SchematicsSubHeader ID: {num + 1}");
			}
			return num + 1;
		}

		public static Unlock GetUnlockByID(int id, bool shouldLog = false)
		{
			if (shouldLog)
			{
				LogEMUInfo($"Looking for Unlock with id '{id}'");
			}
			if (!hasGameDefinesLoaded)
			{
				LogEMUWarning("GetUnlockByID() called before GameDefines has loaded");
				LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking with ModUtils.hasGameDefinesLoaded");
				return null;
			}
			if (unlockCache.ContainsKey(id))
			{
				if (shouldLog)
				{
					LogEMUInfo("Found unlock in cache");
				}
				return unlockCache[id];
			}
			for (int i = 0; i < GameDefines.instance.unlocks.Count; i++)
			{
				Unlock val = GameDefines.instance.unlocks[i];
				if (((UniqueIdScriptableObject)val).uniqueId == id)
				{
					if (shouldLog)
					{
						LogEMUInfo($"Found unlock with id '{id}'");
					}
					unlockCache.Add(id, val);
					return val;
				}
			}
			LogEMUWarning($"Couldn't find Unlock with id '{id}'");
			return null;
		}

		public static Unlock GetUnlockByName(string name, bool shouldLog = false)
		{
			if (shouldLog)
			{
				LogEMUInfo("Looking for Unlock with name '" + name + "'");
			}
			if (!hasGameDefinesLoaded)
			{
				LogEMUWarning("GetUnlockByName() called before GameDefines has loaded");
				LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking with ModUtils.hasGameDefinesLoaded");
				return null;
			}
			if (unlockNameToIDMap.ContainsKey(name) && GameDefines.instance.unlocks.Count > unlockNameToIDMap[name])
			{
				if (shouldLog)
				{
					LogEMUInfo("Found unlock in cache");
				}
				return GameDefines.instance.unlocks[unlockNameToIDMap[name]];
			}
			foreach (Unlock unlock in GameDefines.instance.unlocks)
			{
				if (unlock.displayNameHash == LocsUtility.GetHashString(name))
				{
					if (shouldLog)
					{
						LogEMUInfo("Found Unlock");
					}
					if (!unlockNameToIDMap.ContainsKey(unlock.displayNameHash))
					{
						unlockNameToIDMap.Add(unlock.displayNameHash, ((UniqueIdScriptableObject)unlock).uniqueId);
					}
					return unlock;
				}
			}
			LogEMUWarning("Couldn't find Unlock with name '" + name + "'");
			LogEMUWarning("Try using a name from EquinoxsModUtils.UnlockNames");
			return null;
		}

		public static Unlock GetUnlockByNameUnsafe(string name, bool shouldLog = false)
		{
			if (shouldLog)
			{
				LogEMUInfo("Looking for Unlock with name '" + name + "'");
			}
			if (unlockNameToIDMap.ContainsKey(name) && GameDefines.instance.unlocks.Count > unlockNameToIDMap[name])
			{
				if (shouldLog)
				{
					LogEMUInfo("Found unlock in cache");
				}
				return GameDefines.instance.unlocks[unlockNameToIDMap[name]];
			}
			foreach (Unlock unlock in GameDefines.instance.unlocks)
			{
				if (unlock.displayNameHash == LocsUtility.GetHashString(name))
				{
					if (shouldLog)
					{
						LogEMUInfo("Found Unlock");
					}
					if (!unlockNameToIDMap.ContainsKey(unlock.displayNameHash))
					{
						unlockNameToIDMap.Add(unlock.displayNameHash, ((UniqueIdScriptableObject)unlock).uniqueId);
					}
					return unlock;
				}
			}
			LogEMUWarning("Couldn't find Unlock with name '" + name + "'");
			LogEMUWarning("Try using a name from EquinoxsModUtils.UnlockNames");
			return null;
		}

		public static void AddNewUnlock(NewUnlockDetails details, bool shouldLog = false)
		{
			//IL_0035: 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_0043: Invalid comparison between Unknown and I4
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			if (details.dependencyNames.Count > 2)
			{
				LogEMUError("New Tech '" + details.displayName + "' cannot have more than 2 dependencies. Abandoning attempt to add.");
				return;
			}
			if ((int)details.coreTypeNeeded != 0 && (int)details.coreTypeNeeded != 2)
			{
				LogEMUError("New Tech '" + details.displayName + "' needs to use either Red (Purple in-game) or Green (Blue in-game) cores. Aborting attempt to add tech.");
				return;
			}
			Unlock val = ScriptableObject.CreateInstance<Unlock>();
			val.category = details.category;
			val.coresNeeded = new List<RequiredCores>
			{
				new RequiredCores
				{
					type = details.coreTypeNeeded,
					number = details.coreCountNeeded
				}
			};
			val.isCoreTech = false;
			val.isDebugTech = false;
			val.numScansNeeded = details.numScansNeeded;
			val.requiredTier = details.requiredTier;
			val.priority = 0;
			val.scanDuration = 1f;
			val.sprite = details.sprite;
			val.treePosition = details.treePosition;
			string hashString = LocsUtility.GetHashString(details.displayName);
			string hashString2 = LocsUtility.GetHashString(details.description);
			if (hashTranslations.ContainsKey(hashString))
			{
				LogEMUError("The Unlock name '" + details.displayName + "' is already in use. Abandoning attempt to add");
				return;
			}
			if (hashTranslations.ContainsKey(hashString2))
			{
				LogEMUError("The Unlock description '" + details.description + "' is already in use. Abandoning attempt to add");
				return;
			}
			hashTranslations.Add(hashString, details.displayName);
			hashTranslations.Add(hashString2, details.description);
			val.displayNameHash = hashString;
			val.descriptionHash = hashString2;
			unlockDependencies.Add(hashString, details.dependencyNames);
			unlocksToAdd.Add(val);
			if (shouldLog)
			{
				LogEMUInfo("Successfully created new Unlock '" + details.displayName + "'");
			}
		}

		public static void UpdateUnlockSprite(int unlockID, Sprite sprite, bool shouldLog = false)
		{
			if (shouldLog)
			{
				LogEMUInfo($"Trying to update sprite of Unlock with ID '{unlockID}'");
			}
			if (hasGameDefinesLoaded)
			{
				try
				{
					Unlock val = GameDefines.instance.unlocks[unlockID];
					val.sprite = sprite;
					if (shouldLog)
					{
						LogEMUInfo($"Updated sprite of Unlock with ID '{unlockID}'");
					}
					return;
				}
				catch (Exception ex)
				{
					LogEMUError($"Error occurred while trying to update sprite of Unlock with ID '{unlockID}'");
					LogEMUError(ex.Message);
					LogEMUError(ex.StackTrace);
					return;
				}
			}
			LogEMUWarning("UpdateUnlockSprite() called before GameDefines has loaded");
			LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking with ModUtils.hasGameDefinesLoaded");
		}

		public static void UpdateUnlockSprite(string displayName, Sprite sprite, bool shouldLog = false)
		{
			if (shouldLog)
			{
				LogEMUInfo("Trying to update sprite of Unlock '" + displayName + "'");
			}
			if (hasGameDefinesLoaded)
			{
				Unlock unlockByName = GetUnlockByName(displayName);
				unlockByName.sprite = sprite;
				if (shouldLog)
				{
					LogEMUInfo("Updated sprite of Unlock '" + displayName + "'");
				}
			}
			else
			{
				LogEMUWarning("UpdateUnlockSprite() called before GameDefines has loaded");
				LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking with ModUtils.hasGameDefinesLoaded");
			}
		}

		public static void UpdateUnlockTreePosition(int unlockID, float treePosition, bool shouldLog = false)
		{
			if (shouldLog)
			{
				LogEMUInfo($"Trying to update treePosition of Unlock with ID '{unlockID}'");
			}
			if (hasGameDefinesLoaded)
			{
				try
				{
					Unlock unlockByID = GetUnlockByID(unlockID);
					unlockByID.treePosition = treePosition;
					if (shouldLog)
					{
						LogEMUInfo($"Updated treePosition of Unlock with ID '{unlockID}'");
					}
					return;
				}
				catch (Exception ex)
				{
					LogEMUError($"Error occurred while trying to update treePosition of Unlock with ID '{unlockID}'");
					LogEMUError(ex.Message);
					LogEMUError(ex.StackTrace);
					return;
				}
			}
			LogEMUWarning("UpdateUnlocktreePosition() called before GameDefines has loaded");
			LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking with ModUtils.hasGameDefinesLoaded");
		}

		public static void UpdateUnlockTreePosition(string displayName, float treePosition, bool shouldLog = false)
		{
			if (shouldLog)
			{
				LogEMUInfo("Trying to update treePosition of Unlock '" + displayName + "'");
			}
			if (hasGameDefinesLoaded)
			{
				Unlock unlockByName = GetUnlockByName(displayName);
				if ((Object)(object)unlockByName != (Object)null)
				{
					unlockByName.treePosition = treePosition;
					if (shouldLog)
					{
						LogEMUInfo($"Updated treePosition of Unlock '{displayName}' to {treePosition}");
					}
				}
				else
				{
					LogEMUWarning("Could not update treePosition of unknown Unlock '" + displayName + "'");
				}
			}
			else
			{
				LogEMUWarning("UpdateUnlockTreePosition() called before GameDefines has loaded");
				LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking with ModUtils.hasGameDefinesLoaded");
			}
		}

		public static void UpdateUnlockTier(int unlockID, ResearchTier tier, bool shouldLog = false)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (shouldLog)
			{
				LogEMUInfo($"Trying to update tier of Unlock with ID '{unlockID}'");
			}
			if (hasGameDefinesLoaded)
			{
				try
				{
					Unlock unlockByID = GetUnlockByID(unlockID);
					unlockByID.requiredTier = tier;
					if (shouldLog)
					{
						LogEMUInfo($"Updated requiredTier of Unlock with ID '{unlockID}'");
					}
					return;
				}
				catch (Exception ex)
				{
					LogEMUError($"Error occurred while trying to update requiredTier of Unlock with ID '{unlockID}'");
					LogEMUError(ex.Message);
					LogEMUError(ex.StackTrace);
					return;
				}
			}
			LogEMUWarning("UpdateUnlockTier() called before GameDefines has loaded");
			LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking with ModUtils.hasGameDefinesLoaded");
		}

		public static void UpdateUnlockTier(string displayName, ResearchTier tier, bool shouldLog = false)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (shouldLog)
			{
				LogEMUInfo("Trying to update tier of Unlock '" + displayName + "'");
			}
			if (hasGameDefinesLoaded)
			{
				try
				{
					Unlock unlockByName = GetUnlockByName(displayName);
					unlockByName.requiredTier = tier;
					if (shouldLog)
					{
						LogEMUInfo("Updated requiredTier of Unlock '" + displayName + "'");
					}
					return;
				}
				catch (Exception ex)
				{
					LogEMUError("Error occurred while trying to update requiredTier of Unlock '" + displayName + "'");
					LogEMUError(ex.Message);
					LogEMUError(ex.StackTrace);
					return;
				}
			}
			LogEMUWarning("UpdateUnlockTier() called before GameDefines has loaded");
			LogEMUWarning("Try using the event ModUtils.GameDefinesLoaded or checking with ModUtils.hasGameDefinesLoaded");
		}

		public static void BuildMachine(int resId, GridInfo gridInfo, bool shouldLog = false, int variationIndex = -1, int recipe = -1, ChainData? chainData = null, bool reverseConveyor = false)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (!hasSaveStateLoaded)
			{
				LogEMUError("BuildMachine() called before SaveState.instance has loaded");
				LogEMUWarning("Try using the event ModUtils.SaveStateLoaded or checking with ModUtils.hasSaveStateLoaded");
			}
			else
			{
				MachineBuilder.buildMachine(resId, gridInfo, shouldLog, variationIndex, recipe, chainData, reverseConveyor);
			}
		}

		public static void BuildMachine(string resourceName, GridInfo gridInfo, bool shouldLog = false, int variationIndex = -1, int recipe = -1, ChainData? chainData = null, bool reverseConveyor = false)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (!hasSaveStateLoaded)
			{
				LogEMUError("BuildMachine() called before SaveState.instance has loaded");
				LogEMUWarning("Try using the event ModUtils.SaveStateLoaded or checking with ModUtils.hasSaveStateLoaded");
				return;
			}
			int resourceIDByName = GetResourceIDByName(resourceName);
			if (resourceIDByName == -1)
			{
				LogEMUError("Could not build machine '" + resourceName + "'. Couldn't find a resource matching this name.");
				LogEMUWarning("Try using the ResourceNames class for a perfect match.");
			}
			else
			{
				MachineBuilder.buildMachine(resourceIDByName, gridInfo, shouldLog, variationIndex, recipe, chainData, reverseConveyor);
			}
		}

		public static object GetPrivateField<T>(string name, T instance)
		{
			FieldInfo field = typeof(T).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
			if (field == null)
			{
				LogEMUError($"Could not find the field '{name}' under type {typeof(T)}. Aborting attempt to get value");
				return null;
			}
			return field.GetValue(instance);
		}

		public static void SetPrivateField<T>(string name, T instance, object value)
		{
			FieldInfo field = typeof(T).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
			if (field == null)
			{
				LogEMUError($"Could not find the field '{name}' under type {typeof(T)}. Aborting attempt to set value");
			}
			else
			{
				field.SetValue(instance, value);
			}
		}

		public static void SetPrivateStaticField<T>(string name, T instance, object value)
		{
			FieldInfo field = typeof(T).GetField(name, BindingFlags.Static | BindingFlags.NonPublic);
			if (field == null)
			{
				LogEMUError($"Could not find the static field '{name}' under type {typeof(T)}. Aborting attempt to set value");
			}
			else
			{
				field.SetValue(instance, value);
			}
		}

		public static bool NullCheck(object obj, string name, bool shouldLog = false)
		{
			if (obj == null)
			{
				LogEMUWarning(name + " is null");
				return false;
			}
			if (shouldLog)
			{
				LogEMUInfo(name + " is not null");
			}
			return true;
		}

		public static bool IsModInstalled(string dllName, bool shouldLog = false)
		{
			dllName = dllName.Replace(".dll", "");
			string path = AppDomain.CurrentDomain.BaseDirectory + "BepInEx/plugins";
			string[] files = Directory.GetFiles(path);
			string[] array = files;
			foreach (string text in array)
			{
				if (text.Contains(dllName))
				{
					if (shouldLog)
					{
						LogEMUInfo("Found " + dllName + ".dll, mod is installed");
					}
					return true;
				}
			}
			string[] directories = Directory.GetDirectories(path);
			string[] array2 = directories;
			foreach (string path2 in array2)
			{
				string[] files2 = Directory.GetFiles(path2);
				string[] array3 = files2;
				foreach (string text2 in array3)
				{
					if (text2.Contains(dllName))
					{
						if (shouldLog)
						{
							LogEMUInfo("Found " + dllName + ".dll, mod is installed");
						}
						return true;
					}
				}
			}
			LogEMUWarning("Could not find the file " + dllName + ".dll, mod is not installed");
			return false;
		}

		public static void CloneObject<T>(T original, ref T target)
		{
			FieldInfo[] fields = typeof(T).GetFields();
			foreach (FieldInfo fieldInfo in fields)
			{
				fieldInfo.SetValue(target, fieldInfo.GetValue(original));
			}
		}

		public static void DebugObject(object obj, string name)
		{
			if (!NullCheck(obj, name))
			{
				LogEMUError("Can't debug null object");
				return;
			}
			Dictionary<Type, string> dictionary = new Dictionary<Type, string>();
			dictionary.Add(typeof(bool), "bool");
			dictionary.Add(typeof(byte), "byte");
			dictionary.Add(typeof(sbyte), "sbyte");
			dictionary.Add(typeof(char), "char");
			dictionary.Add(typeof(short), "short");
			dictionary.Add(typeof(ushort), "ushort");
			dictionary.Add(typeof(int), "int");
			dictionary.Add(typeof(uint), "uint");
			dictionary.Add(typeof(long), "long");
			dictionary.Add(typeof(ulong), "ulong");
			dictionary.Add(typeof(float), "float");
			dictionary.Add(typeof(double), "double");
			dictionary.Add(typeof(decimal), "decimal");
			dictionary.Add(typeof(string), "string");
			Dictionary<Type, string> dictionary2 = dictionary;
			Type type = obj.GetType();
			FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			LogEMUInfo("Debugging " + type.Name + " '" + name + "':");
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				string text = fieldInfo.GetValue(obj).ToString();
				string text2 = (dictionary2.ContainsKey(fieldInfo.FieldType) ? dictionary2[fieldInfo.FieldType] : fieldInfo.FieldType.ToString());
				if (text2 == "char")
				{
					text = "'" + text + "'";
				}
				else if (text2 == "string")
				{
					text = "\"" + text + "\"";
				}
				LogEMUInfo("\t" + text2 + " " + fieldInfo.Name + " = " + text);
			}
		}

		public static void PacedLog(string message, float delaySeconds = 1f)
		{
			if (sSinceLastPacedLog > delaySeconds)
			{
				Debug.Log((object)message);
				sSinceLastPacedLog = 0f;
			}
		}

		public static void FreeCursor(bool free)
		{
			InputHandler.instance.uiInputBlocked = free;
			InputHandler.instance.playerAimStickBlocked = free;
			Cursor.lockState = (CursorLockMode)((!free) ? 1 : 0);
			Cursor.visible = free;
			UIManagerPatch.freeCursor = free;
		}

		public static void AddCustomDataForMachine<T>(uint instanceId, string name, T value)
		{
			List<string> list = new List<string>();
			list.Add(typeof(uint).ToString());
			list.Add(typeof(int).ToString());
			list.Add(typeof(float).ToString());
			list.Add(typeof(double).ToString());
			list.Add(typeof(bool).ToString());
			list.Add(typeof(string).ToString());
			list.Add(typeof(char).ToString());
			List<string> list2 = list;
			if (!list2.Contains(typeof(T).ToString()))
			{
				LogEMUError($"EMU cannot save custom data of type '{typeof(T)}', please use one of: uint, int, float, double, bool, string, char");
			}
			string key = $"{instanceId}-{name}-{typeof(T)}";
			if (!customMachineData.ContainsKey(key))
			{
				customMachineData.Add(key, value);
			}
		}

		public static void UpdateCustomDataForMachine<T>(uint instanceId, string name, T value)
		{
			List<string> list = new List<string>();
			list.Add(typeof(uint).ToString());
			list.Add(typeof(int).ToString());
			list.Add(typeof(float).ToString());
			list.Add(typeof(double).ToString());
			list.Add(typeof(bool).ToString());
			list.Add(typeof(string).ToString());
			list.Add(typeof(char).ToString());
			List<string> list2 = list;
			if (!list2.Contains(typeof(T).ToString()))
			{
				LogEMUError($"EMU cannot save custom data of type '{typeof(T)}', please use one of: uint, int, float, double, bool, string, char");
			}
			string text = $"{instanceId}-{name}-{typeof(T)}";
			if (!customMachineData.ContainsKey(text))
			{
				LogEMUWarning("Custom data with key '" + text + "' has not been added for machine yet, adding instead of updating.");
				AddCustomDataForMachine(instanceId, name, value);
			}
			else
			{
				customMachineData[text] = value;
			}
		}

		public static T GetCustomDataForMachine<T>(uint instanceId, string name)
		{
			if (!hasCustomMachineDataLoaded)
			{
				LogEMUError("GetCustomDataForMachine() called before custom data has loaded.");
				LogEMUInfo("Try using the SaveStateLoaded event or hasSaveStateLoaded variable");
				return default(T);
			}
			List<string> list = new List<string>();
			list.Add(typeof(uint).ToString());
			list.Add(typeof(int).ToString());
			list.Add(typeof(float).ToString());
			list.Add(typeof(double).ToString());
			list.Add(typeof(bool).ToString());
			list.Add(typeof(string).ToString());
			list.Add(typeof(char).ToString());
			List<string> list2 = list;
			if (!list2.Contains(typeof(T).ToString()))
			{
				LogEMUError($"EMU cannot save custom data of type '{typeof(T)}', please use one of: uint, int, float, double, bool, string, char");
			}
			string text = $"{instanceId}-{name}-{typeof(T)}";
			if (customMachineData.ContainsKey(text))
			{
				return (T)customMachineData[text];
			}
			LogEMUError("Could not find custom data with key '" + text + "'");
			return default(T);
		}

		public static bool CustomDataExistsForMachine(uint instanceId)
		{
			foreach (string key in customMachineData.Keys)
			{
				if (key.Split(new char[1] { '-' })[0] == instanceId.ToString())
				{
					return true;
				}
			}
			return false;
		}

		public static Texture2D GetImageForResource(string name, bool shouldLog = false)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			ResourceInfo resourceInfoByName = GetResourceInfoByName(name, shouldLog);
			if ((Object)(object)resourceInfoByName == (Object)null)
			{
				return null;
			}
			Sprite sprite = resourceInfoByName.sprite;
			Rect val = sprite.rect;
			if (((Rect)(ref val)).width != (float)((Texture)sprite.texture).width)
			{
				val = sprite.rect;
				int num = (int)((Rect)(ref val)).width;
				val = sprite.rect;
				Texture2D val2 = new Texture2D(num, (int)((Rect)(ref val)).height);
				Texture2D texture = sprite.texture;
				val = sprite.textureRect;
				int num2 = (int)((Rect)(ref val)).x;
				val = sprite.textureRect;
				int num3 = (int)((Rect)(ref val)).y;
				val = sprite.textureRect;
				int num4 = (int)((Rect)(ref val)).width;
				val = sprite.textureRect;
				Color[] pixels = texture.GetPixels(num2, num3, num4, (int)((Rect)(ref val)).height);
				val2.SetPixels(pixels);
				val2.Apply();
				return val2;
			}
			return sprite.texture;
		}

		public static Texture2D LoadTexture2DFromFile(string resourceName, bool shouldLog = false, Assembly assembly = null)
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			if (assembly == null)
			{
				assembly = Assembly.GetCallingAssembly();
			}
			string[] manifestResourceNames = assembly.GetManifestResourceNames();
			string text = Array.Find(manifestResourceNames, (string name) => name.EndsWith(resourceName));
			if (text == null)
			{
				LogEMUError("Could not find image resource '" + resourceName + "' in mod assembly.");
				return null;
			}
			using Stream stream = assembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				LogEMUError("Could not load image resource '" + resourceName + "' from mod assembly stream.");
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			byte[] array = memoryStream.ToArray();
			Texture2D val = new Texture2D(2, 2);
			ImageConversion.LoadImage(val, array);
			if (shouldLog)
			{
				LogEMUInfo("Created Texture2D from image resource '" + resourceName + "'");
			}
			return val;
		}

		public static Sprite LoadSpriteFromFile(string path, bool shouldLog = false)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			Texture2D val = LoadTexture2DFromFile(path, shouldLog, callingAssembly);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0f, 0f), 512f);
		}
	}
	public static class ResourceNames
	{
		public const string ConveyorBelt = "Conveyor Belt";

		public const string ConveyorBeltMKII = "Conveyor Belt MKII";

		public const string ConveyorBeltMKIII = "Conveyor Belt MKIII";

		public const string Inserter = "Inserter";

		public const string LongInserter = "Long Inserter";

		public const string FilterInserter = "Filter Inserter";

		public const string FastInserter = "Fast Inserter";

		public const string StackInserter = "Stack Inserter";

		public const string StackFilterInserter = "Stack Filter Inserter";

		public const string Container = "Container";

		public const string MonorailDepot = "Monorail Depot";

		public const string MonorailPole = "Monorail Pole";

		public const string MonorailTrack = "Monorail Track";

		public const string MiningDrill = "Mining Drill";

		public const string BlastDrill = "Blast Drill";

		public const string MiningDrillMKII = "Mining Drill MKII";

		public const string MiningCharge = "Mining Charge";

		public const string Smelter = "Smelter";

		public const string SmelterMKII = "Smelter MKII";

		public const string BlastSmelter = "Blast Smelter";

		public const string Assembler = "Assembler";

		public const string AssemblerMKII = "Assembler MKII";

		public const string Thresher = "Thresher";

		public const string ThresherMKII = "Thresher MKII";

		public const string Planter = "Planter";

		public const string CrankGenerator = "Crank Generator";

		public const string CrankGeneratorMKII = "Crank Generator MKII";

		public const string WaterWheel = "Water Wheel";

		public const string CoreComposer = "Core Composer";

		public const string ResearchCore380nmPurple = "Research Core 380nm (Purple)";

		public const string ResearchCore480nmBlue = "Research Core 480nm (Blue)";

		public const string Accumulator = "Accumulator";

		public const string VoltageStepper = "Voltage Stepper";

		public const string HighVoltageCable = "High Voltage Cable";

		public const string Beacon = "Beacon";

		public const string Biobrick = "Biobrick";

		public const string BiobrickDieselUnrefined = "Biobrick Diesel (Unrefined)";

		public const string BiobrickDieselInfusionPack = "Biobrick Diesel Infusion Pack";

		public const string BiobrickDieselImpure = "Biobrick Diesel (Impure)";

		public const string BiobrickDieselPure = "Biobrick Diesel (Pure)";

		public const string KindlevineStems = "Kindlevine Stems";

		public const string KindlevineStemsWashed = "Kindlevine Stems (Washed)";

		public const string Plantmatter = "Plantmatter";

		public const string KindlevineSeed = "Kindlevine Seed";

		public const string ShiverthornSeed = "Shiverthorn Seed";

		public const string Kindlevine = "Kindlevine";

		public const string Shiverthorn = "Shiverthorn";

		public const string ShiverthornBuds = "Shiverthorn Buds";

		public const string ShiverthornBudsNeutralized = "Shiverthorn Buds (Neutralized)";

		public const string KindlevineExtract = "Kindlevine Extract";

		public const string ShiverthornExtract = "Shiverthorn Extract";

		public const string CarbonPowder = "Carbon Powder";

		public const string Quicklime = "Quicklime";

		public const string Cement = "Cement";

		public const string AtlantumPowder = "Atlantum Powder";

		public const string Sand = "Sand";

		public const string Gravel = "Gravel";

		public const string Limestone = "Limestone";

		public const string PlantmatterFiber = "Plantmatter Fiber";

		public const string Dirt = "Dirt";

		public const string IronOre = "Iron Ore";

		public const string IronOrePowder = "Iron Ore Powder";

		public const string IronChunk = "Iron Chunk";

		public const string RefinedIronChunk = "Refined Iron Chunk";

		public const string CopperOre = "Copper Ore";

		public const string CopperOrePowder = "Copper Ore Powder";

		public const string CopperChunk = "Copper Chunk";

		public const string RefinedCopperChunk = "Refined Copper Chunk";

		public const string AtlantumOre = "Atlantum Ore";

		public const string AtlantumChunk = "Atlantum Chunk";

		public const string IronIngot = "Iron Ingot";

		public const string IronSlab = "Iron Slab";

		public const string CopperIngot = "Copper Ingot";

		public const string CopperSlab = "Copper Slab";

		public const string SteelMixture = "Steel Mixture";

		public const string SteelIngot = "Steel Ingot";

		public const string SteelSlab = "Steel Slab";

		public const string AtlantumMixture = "Atlantum Mixture";

		public const string AtlantumIngot = "Atlantum Ingot";

		public const string AtlantumSlab = "Atlantum Slab";

		public const string LimestoneBrick = "Limestone Brick";

		public const string CarbonPowderBrick = "Carbon Powder Brick";

		public const string KindlevineExtractBrick = "Kindlevine Extract Brick";

		public const string AtlantumPowderBrick = "Atlantum Powder Brick";

		public const string AtlantumMixtureBrick = "Atlantum Mixture Brick";

		public const string PlantmatterBrick = "Plantmatter Brick";

		public const string Clay = "Clay";

		public const string Concrete = "Concrete";

		public const string DecorativeConcrete = "Decorative Concrete";

		public const string Glass = "Glass";

		public const string PlantmatterFrame = "Plantmatter Frame";

		public const string CeramicParts = "Ceramic Parts";

		public const string IronFrame = "Iron Frame";

		public const string IronComponents = "Iron Components";

		public const string IronMechanism = "Iron Mechanism";

		public const string CopperWire = "Copper Wire";

		public const string CopperFrame = "Copper Frame";

		public const string CopperComponents = "Copper Components";

		public const string CopperMechanism = "Copper Mechanism";

		publ