Decompiled source of BUG CalculatorPatch v1.0.1

BUG_CalculatorPatch.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using CalculatorPatch;
using DSPCalculator;
using DSPCalculator.Compatibility;
using DSPCalculator.Logic;
using DSPCalculator.UI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;
using crecheng.DSPModSave;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class CalcFixes
{
	private static HashSet<ItemConfig> autoRaw;

	private static List<string> pendingData;

	private static List<float> pendingX;

	private static List<float> pendingY;

	private static List<bool> pendingLarge;

	private static int pendingClosed;

	public static void FitIncSwitch(UIItemNode ui)
	{
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		if (ui == null || (Object)(object)ui.incToggleObj == (Object)null || ((UINode)ui).parentCalcWindow == null || (Object)(object)((UINode)ui).parentCalcWindow.contentScrollRect == (Object)null)
		{
			return;
		}
		Transform transform = ui.incToggleObj.transform;
		Transform obj = transform.Find("inc-switch");
		RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
		Transform obj2 = transform.Find("inc-switch/switch-thumb");
		RectTransform val2 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null);
		ScrollRect contentScrollRect = ((UINode)ui).parentCalcWindow.contentScrollRect;
		RectTransform val3 = (RectTransform)(((Object)(object)contentScrollRect.viewport != (Object)null) ? ((object)contentScrollRect.viewport) : ((object)/*isinst with value type is only supported in some contexts*/));
		if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null) && !((Object)(object)transform.parent == (Object)null) && !(transform.parent.lossyScale.x <= 0f))
		{
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			val3.GetWorldCorners(array);
			float num = array[2].x;
			if ((Object)(object)contentScrollRect.verticalScrollbar != (Object)null && ((Component)contentScrollRect.verticalScrollbar).gameObject.activeInHierarchy)
			{
				((RectTransform)((Component)contentScrollRect.verticalScrollbar).transform).GetWorldCorners(array);
				num = Mathf.Min(num, array[0].x);
			}
			val.GetWorldCorners(array);
			float x = array[2].x;
			val2.GetWorldCorners(array);
			float num2 = OverflowLocal(Mathf.Max(x, array[2].x + (10f - val2.anchoredPosition.x) * ((Transform)val2).parent.lossyScale.x), num, transform.parent.lossyScale.x);
			if (num2 > 0f)
			{
				transform.localPosition -= new Vector3(num2, 0f, 0f);
			}
		}
	}

	public static float OverflowLocal(float rightWorld, float limitWorld, float scale)
	{
		if (!(scale <= 0f))
		{
			return (rightWorld - limitWorld) / scale + 8f;
		}
		return 0f;
	}

	public static void SaveWindows(BinaryWriter w)
	{
		//IL_0129: 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_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		List<UICalcWindow> list = new List<UICalcWindow>();
		if (WindowsManager.closedWindows != null)
		{
			foreach (UICalcWindow closedWindow in WindowsManager.closedWindows)
			{
				if ((Object)(object)closedWindow.windowObj != (Object)null)
				{
					list.Add(closedWindow);
				}
			}
		}
		int count = list.Count;
		if (WindowsManager.windows != null)
		{
			foreach (UICalcWindow window in WindowsManager.windows)
			{
				if ((Object)(object)window.windowObj != (Object)null)
				{
					list.Add(window);
				}
			}
		}
		List<ItemConfig> list2 = ((autoRaw == null) ? new List<ItemConfig>() : new List<ItemConfig>(autoRaw));
		foreach (ItemConfig item in list2)
		{
			item.consideredAsOre = false;
		}
		try
		{
			w.Write(1);
			w.Write(count);
			w.Write(list.Count);
			foreach (UICalcWindow item2 in list)
			{
				Vector3 localPosition = item2.windowObj.transform.localPosition;
				w.Write(item2.Copy());
				w.Write(localPosition.x);
				w.Write(localPosition.y);
				w.Write(item2.isLargeWindow);
			}
		}
		finally
		{
			foreach (ItemConfig item3 in list2)
			{
				item3.consideredAsOre = true;
			}
		}
	}

	public static void LoadWindows(BinaryReader r)
	{
		pendingData = null;
		if (r.ReadInt32() == 1)
		{
			int num = r.ReadInt32();
			int num2 = r.ReadInt32();
			List<string> list = new List<string>();
			pendingX = new List<float>();
			pendingY = new List<float>();
			pendingLarge = new List<bool>();
			for (int i = 0; i < num2; i++)
			{
				list.Add(r.ReadString());
				pendingX.Add(r.ReadSingle());
				pendingY.Add(r.ReadSingle());
				pendingLarge.Add(r.ReadBoolean());
			}
			pendingClosed = num;
			pendingData = list;
		}
	}

	public static void ClearPendingWindows()
	{
		pendingData = null;
	}

	public static void ApplyPendingWindows()
	{
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		if (pendingData == null || !GameMain.isRunning || DSPGame.IsMenuDemo || !CalcDB.inited || WindowsManager.windows == null)
		{
			return;
		}
		List<string> list = pendingData;
		pendingData = null;
		for (int num = WindowsManager.windows.Count - 1; num >= 0; num--)
		{
			WindowsManager.windows[num].CloseWindow();
		}
		foreach (UICalcWindow closedWindow in WindowsManager.closedWindows)
		{
			Object.Destroy((Object)(object)closedWindow.windowObj);
		}
		WindowsManager.closedWindows.Clear();
		for (int i = 0; i < list.Count; i++)
		{
			UICalcWindow val = WindowsManager.OpenOne(true);
			if (!val.TryPaste(list[i]))
			{
				Utils.logger.LogWarning((object)("Saved calculator window " + i + " could not be restored."));
			}
			Vector3 localPosition = val.windowObj.transform.localPosition;
			val.windowObj.transform.localPosition = new Vector3(pendingX[i], pendingY[i], localPosition.z);
			val.isLargeWindow = pendingLarge[i];
			if (i < pendingClosed)
			{
				val.CloseWindow();
			}
		}
	}

	private static bool IsRaw(UserPreference pref, int itemId)
	{
		if (!CalcDB.itemDict.TryGetValue(itemId, out var value))
		{
			return true;
		}
		bool flag = value.defaultAsOre || value.recipes.Count == 0;
		if (pref.itemConfigs.TryGetValue(itemId, out var value2))
		{
			flag = value2.consideredAsOre || flag;
			if (value2.forceNotOre && value.recipes.Count > 0)
			{
				flag = false;
			}
		}
		return flag;
	}

	private static bool MustNeed(UserPreference pref, int itemId, int target, HashSet<int> path, HashSet<int> no)
	{
		if (itemId == target)
		{
			return true;
		}
		if (no.Contains(itemId) || IsRaw(pref, itemId) || !path.Add(itemId))
		{
			return false;
		}
		bool flag;
		if (pref.itemConfigs.TryGetValue(itemId, out var value) && value.recipeID > 0 && CalcDB.recipeDict.TryGetValue(value.recipeID, out var value2))
		{
			flag = RecipeNeeds(pref, value2, target, path, no);
		}
		else
		{
			flag = true;
			foreach (NormalizedRecipe recipe in CalcDB.itemDict[itemId].recipes)
			{
				if (!RecipeNeeds(pref, recipe, target, path, no))
				{
					flag = false;
					break;
				}
			}
		}
		path.Remove(itemId);
		if (!flag)
		{
			no.Add(itemId);
		}
		return flag;
	}

	private static bool RecipeNeeds(UserPreference pref, NormalizedRecipe r, int target, HashSet<int> path, HashSet<int> no)
	{
		for (int i = 0; i < r.resources.Length; i++)
		{
			if (r.resourceCounts[i] > 0 && MustNeed(pref, r.resources[i], target, path, no))
			{
				return true;
			}
		}
		return false;
	}

	public static void SyncRecipeTimes()
	{
		if (CalcDB.recipeDict == null)
		{
			return;
		}
		foreach (NormalizedRecipe value in CalcDB.recipeDict.Values)
		{
			if (value != null && value.oriProto != null && value.ID >= 0 && value.type != NormalizedRecipe.factionateType)
			{
				int timeSpend = value.oriProto.TimeSpend;
				if (timeSpend > 0)
				{
					value.time = (double)timeSpend / 60.0;
				}
			}
		}
	}

	public static void BreakForcedLoops(SolutionTree tree)
	{
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Expected O, but got Unknown
		UserPreference userPreference = tree.userPreference;
		if (autoRaw == null)
		{
			autoRaw = new HashSet<ItemConfig>();
		}
		foreach (ItemConfig value4 in userPreference.itemConfigs.Values)
		{
			if (autoRaw.Remove(value4))
			{
				value4.consideredAsOre = false;
			}
		}
		foreach (ItemConfig item in new List<ItemConfig>(userPreference.itemConfigs.Values))
		{
			if (item.recipeID <= 0 || IsRaw(userPreference, item.ID) || !CalcDB.recipeDict.TryGetValue(item.recipeID, out var value))
			{
				continue;
			}
			List<int> list = new List<int>();
			bool flag = false;
			for (int i = 0; i < value.resources.Length; i++)
			{
				int num = value.resources[i];
				if (value.resourceCounts[i] > 0 && !IsRaw(userPreference, num) && MustNeed(userPreference, num, item.ID, new HashSet<int>(), new HashSet<int>()))
				{
					list.Add(num);
					if (userPreference.itemConfigs.TryGetValue(num, out var value2) && value2.forceNotOre)
					{
						flag = true;
					}
				}
			}
			if (list.Count == 0)
			{
				continue;
			}
			if (flag)
			{
				if (!item.forceNotOre && !IsTarget(tree, item.ID))
				{
					item.consideredAsOre = true;
					autoRaw.Add(item);
				}
				continue;
			}
			foreach (int item2 in list)
			{
				if (!userPreference.itemConfigs.TryGetValue(item2, out var value3))
				{
					value3 = new ItemConfig(item2);
					userPreference.itemConfigs[item2] = value3;
				}
				value3.consideredAsOre = true;
				autoRaw.Add(value3);
			}
		}
	}

	private static bool IsTarget(SolutionTree tree, int itemId)
	{
		foreach (ItemTarget target in tree.targets)
		{
			if (target.itemId == itemId)
			{
				return true;
			}
		}
		return false;
	}

	public static double ListedNeed(ItemNode n)
	{
		if (n.byProductRecipes.Count > 0 && n.speedFromOre <= 0.001 && n.satisfiedSpeed >= n.needSpeed - 0.001 && n.IsOre(n.solutionTree.userPreference))
		{
			return 0.0;
		}
		return n.needSpeed;
	}

	public static void MarkSharedRecipe(UIItemNode ui)
	{
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Expected O, but got Unknown
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: 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_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ui.assemblerCountText == (Object)null || ui.itemNode == null || ui.itemNode.mainRecipe == null || ((UINode)ui).parentCalcWindow == null)
		{
			return;
		}
		UIItemNode val = null;
		foreach (UIItemNode uiItemNode in ((UINode)ui).parentCalcWindow.uiItemNodes)
		{
			if (uiItemNode.itemNode != null && uiItemNode.itemNode.mainRecipe != null && uiItemNode.itemNode.mainRecipe.ID == ui.itemNode.mainRecipe.ID)
			{
				val = uiItemNode;
				break;
			}
		}
		UIButton val2 = (UIButton)ui.assemblerCountTextObj.GetComponent(typeof(UIButton));
		string text = ui.assemblerCountText.text;
		bool flag = text.StartsWith("(");
		if (val == null || val == ui)
		{
			if (flag)
			{
				ui.assemblerCountText.text = text.Substring(1, text.Length - 2);
			}
			((Graphic)ui.assemblerCountText).color = UICalcWindow.TextWhiteColor;
			return;
		}
		if (!flag)
		{
			ui.assemblerCountText.text = "(" + text + ")";
		}
		Color textWhiteColor = UICalcWindow.TextWhiteColor;
		((Graphic)ui.assemblerCountText).color = new Color(textWhiteColor.r, textWhiteColor.g, textWhiteColor.b, 0.45f);
		if ((Object)(object)val2 != (Object)null)
		{
			val2.tips.tipTitle = "Shared machines";
			val2.tips.tipText = "Same " + ((Proto)ui.itemNode.mainRecipe.recipeNorm.oriProto).name + " machines as the " + Utils.GetItemName(val.itemNode.itemId) + " row. Build them once.";
		}
	}

	private static void AddSourceCard(UICalcWindow w, int focusItem, Sprite icon, double speed, string title, string text)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: 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)
		UIItemNodeSimple val = new UIItemNodeSimple(new ItemNode(focusItem, 0.0, w.solution), false, w, false, false);
		val.outputText.text = Utils.KMG(speed);
		Transform obj = ((UINode)val).obj.transform.Find("icon");
		((Image)((Component)obj).GetComponent(typeof(Image))).sprite = icon;
		UIButton val2 = (UIButton)((Component)obj).GetComponent(typeof(UIButton));
		val2.tips.itemId = 0;
		val2.tips.tipTitle = title;
		val2.tips.tipText = text;
		val2.tips.width = 220;
		w.uiSideItemNodes.Add((UINode)(object)val);
	}

	public static void AddSourcesSection(UICalcWindow w)
	{
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Expected O, but got Unknown
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Expected O, but got Unknown
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Expected O, but got Unknown
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Expected O, but got Unknown
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Expected O, but got Unknown
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Expected O, but got Unknown
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Expected O, but got Unknown
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		//IL_027d: Expected O, but got Unknown
		if (w.solution == null || w.solution.itemNodes == null || w.uiSideItemNodes == null)
		{
			return;
		}
		bool flag = false;
		foreach (ItemNode value in w.solution.itemNodes.Values)
		{
			if (value.byProductRecipes.Count == 0)
			{
				continue;
			}
			List<RecipeInfo> list = new List<RecipeInfo>();
			if (value.mainRecipe != null && value.mainRecipe.count > 0.001)
			{
				list.Add(value.mainRecipe);
			}
			foreach (RecipeInfo byProductRecipe in value.byProductRecipes)
			{
				list.Add(byProductRecipe);
			}
			bool flag2 = value.speedFromOre > 0.001;
			if (list.Count + (flag2 ? 1 : 0) < 2)
			{
				continue;
			}
			if (!flag)
			{
				while (w.uiSideItemNodes.Count % 3 != 0)
				{
					w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("", w));
				}
				w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("Item sources", w));
				w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("", w));
				w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("", w));
				flag = true;
			}
			UIItemNodeSimple val = new UIItemNodeSimple(value, false, w, false, false);
			val.outputText.text = Utils.KMG(value.satisfiedSpeed);
			w.uiSideItemNodes.Add((UINode)(object)val);
			string itemName = Utils.GetItemName(value.itemId);
			foreach (RecipeInfo item in list)
			{
				if (w.uiSideItemNodes.Count % 3 == 0)
				{
					w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("", w));
				}
				NormalizedRecipe recipeNorm = item.recipeNorm;
				AddSourceCard(w, (recipeNorm.products.Length != 0) ? recipeNorm.products[0] : value.itemId, recipeNorm.oriProto.iconSprite, item.GetOutputSpeedByItemId(value.itemId), ((Proto)recipeNorm.oriProto).name, itemName + " from this recipe" + ((item == value.mainRecipe) ? " (main product)" : " (by-product)"));
			}
			if (flag2)
			{
				if (w.uiSideItemNodes.Count % 3 == 0)
				{
					w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("", w));
				}
				AddSourceCard(w, value.itemId, UIItemNodeSimple.oreSprite, value.speedFromOre, "Raw", itemName + " supplied from outside (Raw Resources Demands)");
			}
			while (w.uiSideItemNodes.Count % 3 != 0)
			{
				w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("", w));
			}
		}
	}

	public static void GBPreferMainOutputRecipes()
	{
		if (!CompatManager.GB)
		{
			return;
		}
		foreach (KeyValuePair<int, ItemData> item2 in CalcDB.itemDict)
		{
			List<NormalizedRecipe> recipes = item2.Value.recipes;
			if (recipes.Count < 2 || (recipes[0].products.Length != 0 && recipes[0].products[0] == item2.Key))
			{
				continue;
			}
			for (int i = 1; i < recipes.Count; i++)
			{
				if (recipes[i].products.Length != 0 && recipes[i].products[0] == item2.Key && !Patches.IsAlternative(recipes[i]))
				{
					NormalizedRecipe item = recipes[i];
					recipes.RemoveAt(i);
					recipes.Insert(0, item);
					break;
				}
			}
		}
	}

	private static bool GBFilterAccepts(int machineType, int recipeType)
	{
		switch (machineType)
		{
		case 12:
			if (recipeType != 2 && recipeType != 3 && recipeType != 4 && recipeType != 5 && recipeType != 9 && recipeType != 10 && recipeType != 15)
			{
				return recipeType == 16;
			}
			return true;
		case 17:
			if (recipeType != 2 && recipeType != 3)
			{
				return recipeType == 16;
			}
			return true;
		case 18:
			if (recipeType != 4)
			{
				return recipeType == 9;
			}
			return true;
		case 19:
			if (recipeType != 1 && recipeType != 11)
			{
				return recipeType == 13;
			}
			return true;
		default:
			return false;
		}
	}

	public static void AddGBFilterMachines()
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected I4, but got Unknown
		if (!CompatManager.GB)
		{
			return;
		}
		ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray;
		foreach (ItemProto val in dataArray)
		{
			if (val == null)
			{
				continue;
			}
			PrefabDesc val2 = ((ProtoSet<ModelProto>)(object)LDB.models).Select(val.ModelIndex)?.prefabDesc;
			if (val2 == null || !val2.isAssembler || !CalcDB.assemblerDict.TryGetValue(((Proto)val).ID, out var value))
			{
				continue;
			}
			int machineType = (int)val2.assemblerRecipeType;
			foreach (KeyValuePair<int, List<AssemblerData>> item in CalcDB.assemblerListByType)
			{
				if (GBFilterAccepts(machineType, item.Key) && !item.Value.Contains(value))
				{
					item.Value.Add(value);
				}
			}
		}
	}

	private static double Multiplier(RecipeInfo r, double baseMultiplier)
	{
		return baseMultiplier + r.bonusFactor - 1.0;
	}

	private static double BaseMultiplier(RecipeInfo r, int itemId)
	{
		double num = 1.0 + r.CalcOutputDiracInc(itemId) + r.bonusInc;
		int incLevel = r.incLevel;
		if (r.isInc && incLevel >= 0 && incLevel < Cargo.incTableMilli.Length)
		{
			num += Utils.GetIncMilli(incLevel, r.userPreference);
		}
		return num;
	}

	private static bool Inferior(RecipeInfo r, int itemId, int firstProduct)
	{
		if (r.userPreference.inferior && itemId == 1501 && firstProduct == 1501)
		{
			return !r.useIA;
		}
		return false;
	}

	public static double CalcCountByOutputSpeed(RecipeInfo r, int itemId, double speed)
	{
		if (!r.productIndices.TryGetValue(itemId, out var value))
		{
			return 0.0;
		}
		NormalizedRecipe recipeNorm = r.recipeNorm;
		if (Inferior(r, itemId, recipeNorm.products[0]))
		{
			speed = speed * (double)recipeNorm.productCounts[0] / (double)(recipeNorm.productCounts[0] + 1);
		}
		return speed / (double)recipeNorm.productCounts[value] * recipeNorm.time / Multiplier(r, BaseMultiplier(r, itemId));
	}

	public static double GetOutputSpeedByChangedCount(RecipeInfo r, int itemId, double changedCount)
	{
		if (!r.productIndices.TryGetValue(itemId, out var value))
		{
			Utils.logger.LogWarning((object)("Output requested for item " + itemId + " that recipe " + r.ID + " does not produce."));
			return 0.0;
		}
		NormalizedRecipe recipeNorm = r.recipeNorm;
		return (Inferior(r, itemId, recipeNorm.products[0]) ? ((double)(recipeNorm.productCounts[0] + 1) / (double)recipeNorm.productCounts[0]) : 1.0) * changedCount * (double)recipeNorm.productCounts[value] / recipeNorm.time * Multiplier(r, BaseMultiplier(r, itemId));
	}

	public static double GetOutputSpeedOriProto(RecipeInfo r, int index, double changedCount)
	{
		RecipeProto oriProto = r.recipeNorm.oriProto;
		int itemId = oriProto.Results[index];
		return (Inferior(r, itemId, oriProto.Results[0]) ? ((double)(oriProto.ResultCounts[0] + 1) / (double)oriProto.ResultCounts[0]) : 1.0) * changedCount * (double)oriProto.ResultCounts[index] / r.recipeNorm.time * Multiplier(r, BaseMultiplier(r, itemId));
	}
}
public static class RecipeUpdates
{
	private static readonly FieldInfo PowerFactor = typeof(RecipeProto).GetField("PowerFactor");

	public static int PickerColumns()
	{
		if (!CompatManager.GB)
		{
			return 14;
		}
		return 17;
	}

	public static int PickerRows()
	{
		if (!CompatManager.GB)
		{
			return 8;
		}
		return 7;
	}

	public static int ProliferatorCount()
	{
		return CalcDB.proliferatorItemIds.Count;
	}

	public static bool ValidRecipe(RecipeProto r)
	{
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Invalid comparison between Unknown and I4
		if (r == null || r.Items == null || r.ItemCounts == null || r.Results == null || r.ResultCounts == null || r.Items.Length != r.ItemCounts.Length || r.Results.Length != r.ResultCounts.Length || r.Results.Length == 0 || r.TimeSpend <= 0)
		{
			return false;
		}
		for (int i = 0; i < r.Items.Length; i++)
		{
			if (r.ItemCounts[i] <= 0 || ((ProtoSet<ItemProto>)(object)LDB.items).Select(r.Items[i]) == null)
			{
				return false;
			}
		}
		for (int j = 0; j < r.Results.Length; j++)
		{
			if (r.ResultCounts[j] <= 0 || ((ProtoSet<ItemProto>)(object)LDB.items).Select(r.Results[j]) == null)
			{
				return false;
			}
		}
		if ((int)r.Type == 8 && (r.Items.Length != 1 || r.Results.Length != 1 || r.ResultCounts[0] > r.ItemCounts[0] || r.Items[0] == r.Results[0]))
		{
			return false;
		}
		return true;
	}

	public static bool ContextDependent(RecipeProto r)
	{
		if (CompatManager.GB)
		{
			return ((Proto)r).ID == 429;
		}
		return false;
	}

	public static void CompleteCatalog()
	{
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Expected O, but got Unknown
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Expected I4, but got Unknown
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Invalid comparison between Unknown and I4
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Expected O, but got Unknown
		RecipeProto[] dataArray = ((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray;
		foreach (RecipeProto val in dataArray)
		{
			if (!ValidRecipe(val) || CalcDB.recipeDict.ContainsKey(((Proto)val).ID) || (val.Results.Length == 1 && val.Results[0] == 9500) || (val.Items.Length == 0 && !ContextDependent(val)))
			{
				continue;
			}
			NormalizedRecipe val2 = new NormalizedRecipe(val);
			CalcDB.recipeDict[((Proto)val).ID] = val2;
			int num = (int)val.Type;
			if (!CalcDB.assemblerListByType.ContainsKey(num))
			{
				CalcDB.assemblerListByType[num] = new List<AssemblerData>();
			}
			ItemProto[] dataArray2 = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray;
			foreach (ItemProto val3 in dataArray2)
			{
				if (val3 == null)
				{
					continue;
				}
				PrefabDesc val4 = ((ProtoSet<ModelProto>)(object)LDB.models).Select(val3.ModelIndex)?.prefabDesc;
				if (val4 != null && (val4.isFractionator || val4.isAssembler) && (int)val4.assemblerRecipeType == num)
				{
					if (!CalcDB.assemblerDict.TryGetValue(((Proto)val3).ID, out var value))
					{
						value = new AssemblerData(val3, val4);
						CalcDB.assemblerDict[((Proto)val3).ID] = value;
					}
					if (val4.isFractionator)
					{
						value.speed = CalcDB.maxBeltItemSpeedPreSec * CalcDB.maxStackSize;
					}
					CalcDB.assemblerListByType[num].Add(value);
				}
			}
			if (ContextDependent(val))
			{
				int[] products = val2.products;
				foreach (int key in products)
				{
					CalcDB.itemDict[key].defaultAsOre = true;
				}
			}
		}
		foreach (List<AssemblerData> value2 in CalcDB.assemblerListByType.Values)
		{
			HashSet<int> hashSet = new HashSet<int>();
			for (int k = 0; k < value2.Count; k++)
			{
				if (!hashSet.Add(value2[k].ID))
				{
					value2.RemoveAt(k--);
				}
			}
		}
		CalcFixes.AddGBFilterMachines();
		CalcFixes.GBPreferMainOutputRecipes();
		WriteCatalog();
	}

	public static bool ValidateSelection(SolutionTree tree)
	{
		CalcFixes.SyncRecipeTimes();
		CalcFixes.BreakForcedLoops(tree);
		foreach (ItemConfig value3 in tree.userPreference.itemConfigs.Values)
		{
			if (!value3.consideredAsOre && value3.forceNotOre && value3.recipeID > 0 && CalcDB.recipeDict.TryGetValue(value3.recipeID, out var value) && ContextDependent(value.oriProto))
			{
				UIRealtimeTip.Popup("GenesisBook material recovery depends on incoming trash, power and free inventory space; it has no fixed input ratio.", true, 0);
				return false;
			}
		}
		foreach (ItemConfig value4 in tree.userPreference.itemConfigs.Values)
		{
			if (!value4.consideredAsOre && value4.forceNotOre && value4.recipeID <= 0 && CalcDB.itemDict.TryGetValue(value4.ID, out var value2) && value2.recipes.Count != 0 && ContextDependent(value2.recipes[0].oriProto))
			{
				UIRealtimeTip.Popup("GenesisBook material recovery is a context-dependent recycling process. Supply its output externally.", true, 0);
				return false;
			}
		}
		return true;
	}

	public static double ExtraPower(RecipeInfo recipe, double existing)
	{
		if (!CompatManager.GB || recipe.useIA || PowerFactor == null)
		{
			return existing;
		}
		int num = (int)PowerFactor.GetValue(recipe.recipeNorm.oriProto);
		if (num < 2)
		{
			return existing;
		}
		ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(recipe.assemblerItemId);
		PrefabDesc val2 = ((val == null) ? null : ((ProtoSet<ModelProto>)(object)LDB.models).Select(val.ModelIndex))?.prefabDesc;
		if (val2 == null || !val2.isAssembler)
		{
			return existing;
		}
		int incLevel = recipe.incLevel;
		double num2 = ((incLevel >= 0 && incLevel < Cargo.powerTableRatio.Length) ? Utils.GetPowerRatio(incLevel, recipe.userPreference) : 1.0);
		int num3 = val2.assemblerSpeed;
		if (!recipe.isInc && incLevel >= 0 && incLevel < Cargo.accTableMilli.Length)
		{
			num3 = (int)((double)num3 * (1.0 + Utils.GetAccMilli(incLevel, recipe.userPreference)));
		}
		long num4 = (long)num3 * (long)num / 2;
		return existing + recipe.assemblerCount * (double)num4 * 60.0 * num2;
	}

	public static double FractionatorSpray(RecipeInfo recipe, double existing)
	{
		if (recipe.recipeNorm.type != NormalizedRecipe.factionateType)
		{
			return existing;
		}
		RecipeProto oriProto = recipe.recipeNorm.oriProto;
		return existing / (double)oriProto.ItemCounts[0];
	}

	private static string Join(int[] values)
	{
		string text = "";
		for (int i = 0; i < values.Length; i++)
		{
			text = text + ((i == 0) ? "" : ";") + values[i];
		}
		return text;
	}

	private static void WriteCatalog()
	{
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Expected I4, but got Unknown
		try
		{
			using StreamWriter streamWriter = new StreamWriter(Path.Combine(Path.GetDirectoryName(typeof(DSPCalculatorPlugin).Assembly.Location), "DSPCalculator-recipes.csv"), append: false, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true));
			streamWriter.WriteLine("id,name,type,seconds,input_ids,input_counts,output_ids,output_counts,productive,power_factor,in_calculator,context_dependent");
			RecipeProto[] dataArray = ((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray;
			foreach (RecipeProto val in dataArray)
			{
				if (val != null && val.Items != null && val.Results != null)
				{
					string[] array = new string[23]
					{
						((Proto)val).ID.ToString(),
						",\"",
						(((Proto)val).name ?? ((Proto)val).Name ?? "").Replace("\"", "\"\""),
						"\",",
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null
					};
					array[4] = ((int)val.Type).ToString();
					array[5] = ",";
					array[6] = ((double)val.TimeSpend / 60.0).ToString("R", CultureInfo.InvariantCulture);
					array[7] = ",";
					array[8] = Join(val.Items);
					array[9] = ",";
					array[10] = Join(val.ItemCounts ?? new int[0]);
					array[11] = ",";
					array[12] = Join(val.Results);
					array[13] = ",";
					array[14] = Join(val.ResultCounts ?? new int[0]);
					array[15] = ",";
					array[16] = val.productive.ToString();
					array[17] = ",";
					array[18] = ((!(PowerFactor == null)) ? ((int)PowerFactor.GetValue(val)) : 0).ToString();
					array[19] = ",";
					array[20] = CalcDB.recipeDict.ContainsKey(((Proto)val).ID).ToString();
					array[21] = ",";
					array[22] = ContextDependent(val).ToString();
					streamWriter.WriteLine(string.Concat(array));
				}
			}
		}
		catch (Exception ex)
		{
			Utils.logger.LogWarning((object)("Could not write recipe audit: " + ex.Message));
		}
	}
}
namespace CalculatorPatch
{
	[BepInPlugin("bug.dsp.calculatorpatch", "BUG_CalculatorPatch", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin, IModCanSave
	{
		public const string Guid = "bug.dsp.calculatorpatch";

		public const string Calculator = "com.GniMaerd.DSPCalculator";

		public const string OreEnrichment = "bug.dsp.oreenrichment";

		internal static ManualLogSource Log;

		internal static bool Active;

		private void Awake()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			if (typeof(CalcDB).Assembly.GetType("RecipeUpdates") != null)
			{
				Log.LogInfo((object)"DSPCalculator already contains these fixes, nothing patched");
				return;
			}
			PluginInfo value;
			string text = (Chainloader.PluginInfos.TryGetValue("com.GniMaerd.DSPCalculator", out value) ? value.Metadata.Version.ToString() : "?");
			Harmony val = new Harmony("bug.dsp.calculatorpatch");
			try
			{
				val.PatchAll(typeof(Patches));
				Active = true;
				Log.LogInfo((object)("DSPCalculator " + text + " patched"));
			}
			catch (Exception ex)
			{
				val.UnpatchSelf();
				Log.LogError((object)("DSPCalculator " + text + " is not the version these fixes were written for (0.5.25); it is left as it is. " + ex));
			}
		}

		public void Export(BinaryWriter w)
		{
			if (Active)
			{
				CalcFixes.SaveWindows(w);
			}
			else
			{
				w.Write(0);
			}
		}

		public void Import(BinaryReader r)
		{
			if (Active)
			{
				CalcFixes.LoadWindows(r);
			}
		}

		public void IntoOtherSave()
		{
			if (Active)
			{
				CalcFixes.ClearPendingWindows();
			}
		}
	}
	public static class Patches
	{
		[ThreadStatic]
		private static bool proliferatorLineFailed;

		internal static bool Enrichment => Chainloader.PluginInfos.ContainsKey("bug.dsp.oreenrichment");

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CalcDB), "TryInit")]
		private static void BeforeInit()
		{
			CalcDB.maxBeltItemSpeedPreSec = 0.0;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CalcDB), "TryInit")]
		private static void AfterInit()
		{
			List<int> list = (CalcDB.proliferatorItemIds = NativeProliferatorItems());
			CalcDB.proliferatorAbilitiesMap = new Dictionary<int, int>();
			CalcDB.proliferatorAbilityToId = new Dictionary<int, int>();
			foreach (int item in list)
			{
				CalcDB.proliferatorAbilitiesMap[item] = 0;
				ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(item);
				if (val != null)
				{
					if (val.Ability > 10)
					{
						CalcDB.proliferatorAbilitiesMap[item] = 10;
					}
					else if (val.Ability >= 0)
					{
						CalcDB.proliferatorAbilitiesMap[item] = val.Ability;
					}
					CalcDB.proliferatorAbilityToId[val.Ability] = ((Proto)val).ID;
				}
			}
			RecipeUpdates.CompleteCatalog();
			KeepAlternativesLast();
		}

		public static List<int> NativeProliferatorItems()
		{
			List<int> list = new List<int> { 1141, 1142, 1143 };
			HashSet<int> hashSet = new HashSet<int>();
			foreach (int item in list)
			{
				ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(item);
				if (val != null)
				{
					hashSet.Add(val.Ability);
				}
			}
			ModelProto[] dataArray = ((ProtoSet<ModelProto>)(object)LDB.models).dataArray;
			for (int i = 0; i < dataArray.Length; i++)
			{
				int[] array = dataArray[i]?.prefabDesc?.incItemId;
				if (array == null)
				{
					continue;
				}
				int[] array2 = array;
				foreach (int num in array2)
				{
					ItemProto val2 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(num);
					if (val2 != null && val2.Ability > 0 && val2.Ability <= 10 && val2.Ability < Cargo.accTableMilli.Length && val2.Ability < Cargo.incTableMilli.Length && val2.Ability < Cargo.powerTableRatio.Length && !list.Contains(num) && hashSet.Add(val2.Ability))
					{
						list.Add(num);
					}
				}
			}
			return list;
		}

		public static bool IsEnrichmentRecipe(int recipeId)
		{
			if ((recipeId <= 7000 || recipeId >= 9000) && (recipeId < 9501 || recipeId > 9547) && (recipeId < 9601 || recipeId > 9699))
			{
				if (recipeId > 10000)
				{
					return recipeId < 12000;
				}
				return false;
			}
			return true;
		}

		public static bool IsAlternative(NormalizedRecipe r)
		{
			if (Enrichment)
			{
				return IsEnrichmentRecipe(r.ID);
			}
			return false;
		}

		private static void KeepAlternativesLast()
		{
			if (!Enrichment)
			{
				return;
			}
			int num = 0;
			foreach (ItemData value in CalcDB.itemDict.Values)
			{
				List<NormalizedRecipe> list = new List<NormalizedRecipe>();
				List<NormalizedRecipe> list2 = new List<NormalizedRecipe>();
				foreach (NormalizedRecipe recipe in value.recipes)
				{
					(IsEnrichmentRecipe(recipe.ID) ? list2 : list).Add(recipe);
				}
				if (list2.Count != 0 && list.Count != 0)
				{
					bool flag = true;
					for (int i = 0; i < list.Count; i++)
					{
						flag &= value.recipes[i] == list[i];
					}
					if (!flag)
					{
						value.recipes.Clear();
						value.recipes.AddRange(list);
						value.recipes.AddRange(list2);
						num++;
					}
				}
			}
			Plugin.Log.LogInfo((object)("BUG_OreEnrichment found: its alternative recipes are listed after the normal ones (" + num + " items reordered)"));
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(RecipeInfo), "CalcCountByOutputSpeed")]
		private static bool CountByOutput(RecipeInfo __instance, int itemId, double speed, ref double __result)
		{
			__result = CalcFixes.CalcCountByOutputSpeed(__instance, itemId, speed);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(RecipeInfo), "GetOutputSpeedByChangedCount")]
		private static bool OutputByCount(RecipeInfo __instance, int itemId, double changedCount, ref double __result)
		{
			__result = CalcFixes.GetOutputSpeedByChangedCount(__instance, itemId, changedCount);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(RecipeInfo), "GetOutputSpeedOriProto")]
		private static bool OutputOriProto(RecipeInfo __instance, int index, double changedCount, ref double __result)
		{
			__result = CalcFixes.GetOutputSpeedOriProto(__instance, index, changedCount);
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RecipeInfo), "GetTotalEnergyConsumption")]
		private static void Power(RecipeInfo __instance, ref double __result)
		{
			__result = RecipeUpdates.ExtraPower(__instance, __result);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RecipeInfo), "GetProliferatorUsed")]
		private static void Spray(RecipeInfo __instance, ref double proliferatorCount)
		{
			proliferatorCount = RecipeUpdates.FractionatorSpray(__instance, proliferatorCount);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SolutionTree), "Solve")]
		private static bool BeforeSolve(SolutionTree __instance, ref bool __result)
		{
			proliferatorLineFailed = false;
			if (RecipeUpdates.ValidateSelection(__instance))
			{
				return true;
			}
			__result = false;
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SolutionTree), "CalcProliferatorInProductLine")]
		private static void ProliferatorLine(bool __result)
		{
			proliferatorLineFailed |= !__result;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SolutionTree), "Solve")]
		private static void AfterSolve(SolutionTree __instance, ref bool __result)
		{
			if (__result && proliferatorLineFailed && __instance.userPreference.solveProliferators)
			{
				__result = false;
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(SolutionTree), "CalcProliferatorInProductLine")]
		private static IEnumerable<CodeInstruction> ProliferatorCount(IEnumerable<CodeInstruction> instructions)
		{
			int found = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Ldc_I4_3)
				{
					found++;
					yield return CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(RecipeUpdates), "ProliferatorCount", (Type[])null, (Type[])null)), (IEnumerable<Label>)instruction.labels);
				}
				else
				{
					yield return instruction;
				}
			}
			if (found != 9)
			{
				throw new InvalidOperationException("proliferator matrix: " + found + " sizes instead of 9");
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(RecipePickerPatcher), "RecipePickerPrefix")]
		private static IEnumerable<CodeInstruction> PickerGrid(IEnumerable<CodeInstruction> instructions)
		{
			int rows = 0;
			int columns = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Ldc_I4_8)
				{
					rows++;
					yield return CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(RecipeUpdates), "PickerRows", (Type[])null, (Type[])null)), (IEnumerable<Label>)instruction.labels);
				}
				else if (instruction.opcode == OpCodes.Ldc_I4_S && Convert.ToInt32(instruction.operand) == 14)
				{
					columns++;
					yield return CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(RecipeUpdates), "PickerColumns", (Type[])null, (Type[])null)), (IEnumerable<Label>)instruction.labels);
				}
				else
				{
					yield return instruction;
				}
			}
			if (rows != 1 || columns != 2)
			{
				throw new InvalidOperationException("recipe picker grid: " + rows + " row and " + columns + " column sizes instead of 1 and 2");
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static IEnumerable<CodeInstruction> AssemblyButton(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			FieldInfo objB = AccessTools.Field(typeof(CompatManager), "GB");
			int num = list.FindIndex((CodeInstruction c) => c.opcode == OpCodes.Ldc_R4 && c.operand is float num4 && num4 == 415f);
			int num2 = -1;
			int num3 = num;
			while (num3 >= 0 && num2 < 0)
			{
				if (list[num3].opcode == OpCodes.Ldsfld && object.Equals(list[num3].operand, objB))
				{
					num2 = num3;
				}
				num3--;
			}
			if (num < 0 || num2 < 0 || num - num2 > 12)
			{
				throw new InvalidOperationException("interstellar assembly button placement not found");
			}
			list[num2] = CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Ldc_I4_0, (object)null), (IEnumerable<Label>)list[num2].labels);
			return list;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(UICalcWindow), "RefreshProductContent")]
		private static IEnumerable<CodeInstruction> ListedNeed(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			FieldInfo objB = AccessTools.Field(typeof(ItemNode), "needSpeed");
			int num = 0;
			for (int i = 2; i + 2 < list.Count; i++)
			{
				if ((list[i - 2].opcode == OpCodes.Brtrue_S || list[i - 2].opcode == OpCodes.Brtrue) && list[i].opcode == OpCodes.Ldfld && object.Equals(list[i].operand, objB) && list[i + 1].opcode == OpCodes.Ldc_R8 && list[i + 2].opcode == OpCodes.Cgt)
				{
					list[i] = CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(CalcFixes), "ListedNeed", (Type[])null, (Type[])null)), (IEnumerable<Label>)list[i].labels);
					num++;
				}
			}
			if (num != 2)
			{
				throw new InvalidOperationException("product list demand checks: " + num + " instead of 2");
			}
			return list;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UICalcWindow), "RefreshResourceNeedAndByProductContent")]
		private static void Sources(UICalcWindow __instance)
		{
			CalcFixes.AddSourcesSection(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static void IncSwitchInside(UIItemNode __instance)
		{
			CalcFixes.FitIncSwitch(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UIItemNode), "RefreshAssemblerDisplay")]
		private static void SharedRecipe(UIItemNode __instance)
		{
			CalcFixes.MarkSharedRecipe(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(WindowsManager), "OnUpdate")]
		private static void PendingWindows()
		{
			CalcFixes.ApplyPendingWindows();
		}
	}
}