Decompiled source of HoneyIShrunkTheFactory v0.3.0

HoneyIShrunkTheFactory.dll

Decompiled 12 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using crecheng.DSPModSave;

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyTitle("Honey I Shrunk the Factory")]
[assembly: AssemblyCompany("Loki Moon Labs")]
[assembly: AssemblyFileVersion("0.3.0.0")]
[assembly: InternalsVisibleTo("HoneyIShrunkTheFactory.Tests")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.3.0.0")]
namespace LokiMoonLabs.HoneyIShrunkTheFactory;

internal sealed class BatchState
{
	internal int Planet;

	internal int Entity;

	internal int Proto;

	internal int Requested = 1;

	internal int Active = 1;

	internal int Recipe;

	internal bool Lab;

	internal bool Bound;

	internal bool Fractionator;

	internal bool Exchanger;

	internal int BaseInput;

	internal int BaseFluid;

	internal int BaseProduct;

	internal RecipeExecuteData Original;

	internal RecipeExecuteData Scaled;

	internal int[] OutputBefore;
}
internal sealed class BatchEngine
{
	internal readonly Dictionary<long, BatchState> States = new Dictionary<long, BatchState>();

	private readonly Dictionary<int, List<BatchState>> planets = new Dictionary<int, List<BatchState>>();

	private static ConditionalWeakTable<RecipeExecuteData, BatchState> owners = new ConditionalWeakTable<RecipeExecuteData, BatchState>();

	private void Track(BatchState state)
	{
		States.Add(Key(state.Planet, state.Entity), state);
		if (!planets.TryGetValue(state.Planet, out var value))
		{
			value = new List<BatchState>();
			planets.Add(state.Planet, value);
		}
		value.Add(state);
	}

	internal static long Key(int planet, int entity)
	{
		return ((long)planet << 32) | (uint)entity;
	}

	internal static int Multiplier(RecipeExecuteData data)
	{
		if (data == null || !owners.TryGetValue(data, out var value))
		{
			return 1;
		}
		return value.Active;
	}

	internal static BatchState Owner(RecipeExecuteData data)
	{
		if (data == null || !owners.TryGetValue(data, out var value))
		{
			return null;
		}
		return value;
	}

	internal BatchState Get(PlanetFactory factory, int entity, bool lab)
	{
		//IL_002c: 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)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		long key = Key(factory.planetId, entity);
		if (!States.TryGetValue(key, out var value))
		{
			EntityData val = factory.entityPool[entity];
			BatchState batchState = new BatchState();
			batchState.Planet = factory.planetId;
			batchState.Entity = entity;
			batchState.Proto = val.protoId;
			batchState.Lab = lab;
			batchState.Fractionator = val.fractionatorId > 0;
			batchState.Exchanger = val.powerExcId > 0;
			batchState.Recipe = ((val.fractionatorId <= 0 && val.powerExcId <= 0) ? (lab ? factory.factorySystem.labPool[val.labId].recipeId : factory.factorySystem.assemblerPool[val.assemblerId].recipeId) : 0);
			value = batchState;
			Track(value);
			if (value.Fractionator)
			{
				FractionatorComponent val2 = factory.factorySystem.fractionatorPool[val.fractionatorId];
				value.BaseInput = Math.Max(1, val2.fluidInputMax);
				value.BaseFluid = Math.Max(1, val2.fluidOutputMax);
				value.BaseProduct = Math.Max(1, val2.productOutputMax);
			}
		}
		return value;
	}

	internal void Request(PlanetFactory factory, int entity, bool lab, int count)
	{
		BatchState batchState = Get(factory, entity, lab);
		Sync(batchState, factory);
		count = BatchMath.Clamp(count);
		if (batchState.Original != null)
		{
			Make(batchState.Original, count);
		}
		batchState.Requested = count;
		Sync(batchState, factory);
	}

	internal void Remove(int planet, int entity)
	{
		if (States.TryGetValue(Key(planet, entity), out var value))
		{
			States.Remove(Key(planet, entity));
			planets[planet].Remove(value);
		}
	}

	internal BatchState FractionState(int planet, int entity)
	{
		if (!States.TryGetValue(Key(planet, entity), out var value) || !value.Fractionator)
		{
			return null;
		}
		return value;
	}

	internal void Clear()
	{
		States.Clear();
		planets.Clear();
		owners = new ConditionalWeakTable<RecipeExecuteData, BatchState>();
		FractionPowerBindings.Clear();
		ExchangerBindings.Clear();
	}

	internal void SyncFactory(PlanetFactory factory)
	{
		if (factory == null || !planets.TryGetValue(factory.planetId, out var value))
		{
			return;
		}
		foreach (BatchState item in value)
		{
			Sync(item, factory);
		}
	}

	internal void SyncAll(GameData data)
	{
		if (data == null || States.Count == 0)
		{
			return;
		}
		foreach (BatchState value in States.Values)
		{
			PlanetData val = data.galaxy.PlanetById(value.Planet);
			if (val != null && val.factory != null)
			{
				Sync(value, val.factory);
			}
		}
	}

	internal static RecipeExecuteData Make(RecipeExecuteData source, int n)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		BatchMath.Scale(source.productCounts, n);
		return new RecipeExecuteData(source.requires, BatchMath.Scale(source.requireCounts, n), source.products, source.productCounts, source.timeSpend, source.extraTimeSpend, source.productive);
	}

	private static bool UpgradeRelated(int before, int after)
	{
		ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(before);
		ItemProto val2 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(after);
		if (val == null || val2 == null)
		{
			return false;
		}
		if (val.Upgrades == null || Array.IndexOf(val.Upgrades, after) < 0)
		{
			if (val2.Upgrades != null)
			{
				return Array.IndexOf(val2.Upgrades, before) >= 0;
			}
			return false;
		}
		return true;
	}

	internal void Sync(BatchState state, PlanetFactory factory)
	{
		//IL_002b: 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_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0254: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		if (state.Entity <= 0 || state.Entity >= factory.entityPool.Length)
		{
			return;
		}
		EntityData val = factory.entityPool[state.Entity];
		if (val.id != state.Entity)
		{
			return;
		}
		if (val.protoId != state.Proto)
		{
			int num = BlueprintSettings.Kind(factory, state.Entity);
			if (state.Fractionator || state.Exchanger || num != ((!state.Lab) ? 1 : 2) || !UpgradeRelated(state.Proto, val.protoId))
			{
				return;
			}
			state.Proto = val.protoId;
		}
		FactorySystem factorySystem = factory.factorySystem;
		if (state.Exchanger)
		{
			PowerSystem powerSystem = factory.powerSystem;
			int powerExcId = val.powerExcId;
			if (powerSystem != null && powerSystem.excPool != null && powerExcId > 0 && powerExcId < powerSystem.excPool.Length && powerSystem.excPool[powerExcId].entityId == state.Entity)
			{
				state.Active = state.Requested;
				ExchangerBindings.Bind(powerSystem.excPool, powerExcId, state);
			}
		}
		else if (state.Fractionator)
		{
			int fractionatorId = val.fractionatorId;
			if (fractionatorId > 0 && fractionatorId < factorySystem.fractionatorPool.Length)
			{
				FractionatorComponent val2 = factorySystem.fractionatorPool[fractionatorId];
				if (state.BaseInput <= 0)
				{
					state.BaseInput = Math.Max(1, val2.fluidInputMax);
					state.BaseFluid = Math.Max(1, val2.fluidOutputMax);
					state.BaseProduct = Math.Max(1, val2.productOutputMax);
				}
				state.Active = state.Requested;
				factorySystem.fractionatorPool[fractionatorId].fluidInputMax = Capacity(state.BaseInput, state.Active);
				factorySystem.fractionatorPool[fractionatorId].fluidOutputMax = Capacity(state.BaseFluid, state.Active);
				factorySystem.fractionatorPool[fractionatorId].productOutputMax = Capacity(state.BaseProduct, state.Active);
				if (factory.powerSystem != null)
				{
					FractionPowerBindings.Bind(factory.powerSystem.consumerPool, val2.pcId, state);
				}
			}
		}
		else if (state.Lab)
		{
			int labId = val.labId;
			if (labId > 0 && labId < factorySystem.labPool.Length)
			{
				LabComponent val3 = factorySystem.labPool[labId];
				if (val3.researchMode)
				{
					state.Bound = false;
					state.Scaled = null;
					state.Original = null;
					state.Recipe = 0;
				}
				else
				{
					UpdateData(state, ref val3.recipeExecuteData, val3.recipeId, val3.replicating, val3.time, val3.extraTime);
					factorySystem.labPool[labId].recipeExecuteData = val3.recipeExecuteData;
				}
			}
		}
		else
		{
			int assemblerId = val.assemblerId;
			if (assemblerId > 0 && assemblerId < factorySystem.assemblerPool.Length)
			{
				AssemblerComponent val4 = factorySystem.assemblerPool[assemblerId];
				UpdateData(state, ref val4.recipeExecuteData, val4.recipeId, val4.replicating, val4.time, val4.extraTime);
				factorySystem.assemblerPool[assemblerId].recipeExecuteData = val4.recipeExecuteData;
			}
		}
	}

	private static int Capacity(int original, int n)
	{
		if (n != 1)
		{
			return Math.Max(original, (int)Math.Min(500000L, (long)original * (long)n));
		}
		return original;
	}

	private static void UpdateData(BatchState state, ref RecipeExecuteData data, int recipe, bool running, int time, int bonus)
	{
		if (data == null || recipe <= 0)
		{
			state.Bound = true;
			state.Scaled = null;
			state.Original = null;
			state.Recipe = 0;
			state.Active = state.Requested;
			return;
		}
		bool flag = state.Bound && !object.ReferenceEquals(data, state.Scaled) && !object.ReferenceEquals(data, state.Original);
		if (!state.Bound || flag)
		{
			if (state.Recipe != recipe)
			{
				state.Active = state.Requested;
			}
			state.Original = data;
			state.Recipe = recipe;
			state.Bound = true;
			state.Scaled = null;
		}
		if (state.Active != state.Requested && BatchMath.SafeToResize(running, time, bonus))
		{
			state.Active = state.Requested;
			state.Scaled = null;
		}
		if (state.Scaled == null)
		{
			RecipeExecuteData val = Make(state.Original, state.Active);
			owners.Add(val, state);
			state.Scaled = val;
		}
		data = state.Scaled;
	}

	internal void Export(BinaryWriter w)
	{
		w.Write(1212568390);
		w.Write(3);
		w.Write(States.Count);
		foreach (BatchState value in States.Values)
		{
			w.Write(value.Planet);
			w.Write(value.Entity);
			w.Write(value.Proto);
			w.Write(value.Lab);
			w.Write(value.Fractionator);
			w.Write(value.Exchanger);
			w.Write(value.Requested);
			w.Write(value.Active);
			w.Write(value.Recipe);
			w.Write(value.BaseInput);
			w.Write(value.BaseFluid);
			w.Write(value.BaseProduct);
		}
	}

	internal void Import(BinaryReader r)
	{
		int num = r.ReadInt32();
		int num2 = r.ReadInt32();
		if (num != 1212568390 || (num2 != 1 && num2 != 2 && num2 != 3))
		{
			throw new InvalidDataException("Unsupported factory batch save data.");
		}
		int num3 = r.ReadInt32();
		if (num3 < 0 || num3 > 1000000)
		{
			throw new InvalidDataException("Invalid machine count.");
		}
		Dictionary<long, BatchState> dictionary = new Dictionary<long, BatchState>();
		for (int i = 0; i < num3; i++)
		{
			BatchState batchState = new BatchState();
			batchState.Planet = r.ReadInt32();
			batchState.Entity = r.ReadInt32();
			batchState.Proto = r.ReadInt32();
			batchState.Lab = r.ReadBoolean();
			BatchState batchState2 = batchState;
			batchState2.Fractionator = num2 >= 2 && r.ReadBoolean();
			batchState2.Exchanger = num2 >= 3 && r.ReadBoolean();
			batchState2.Requested = r.ReadInt32();
			batchState2.Active = r.ReadInt32();
			batchState2.Recipe = r.ReadInt32();
			if (num2 >= 2)
			{
				batchState2.BaseInput = r.ReadInt32();
				batchState2.BaseFluid = r.ReadInt32();
				batchState2.BaseProduct = r.ReadInt32();
			}
			if (batchState2.Planet <= 0 || batchState2.Entity <= 0 || batchState2.Proto <= 0 || batchState2.Requested < 1 || batchState2.Requested > 1000 || batchState2.Active < 1 || batchState2.Active > 1000 || batchState2.Recipe < 0 || dictionary.ContainsKey(Key(batchState2.Planet, batchState2.Entity)))
			{
				throw new InvalidDataException("Invalid machine batch record.");
			}
			if (batchState2.BaseInput < 0 || batchState2.BaseFluid < 0 || batchState2.BaseProduct < 0 || (batchState2.Fractionator && (batchState2.Lab || batchState2.BaseInput == 0 || batchState2.BaseFluid == 0 || batchState2.BaseProduct == 0)))
			{
				throw new InvalidDataException("Invalid fractionator capacities.");
			}
			if (batchState2.Exchanger && (batchState2.Lab || batchState2.Fractionator || batchState2.Recipe != 0))
			{
				throw new InvalidDataException("Invalid exchanger record.");
			}
			dictionary.Add(Key(batchState2.Planet, batchState2.Entity), batchState2);
		}
		Clear();
		foreach (KeyValuePair<long, BatchState> item in dictionary)
		{
			Track(item.Value);
		}
	}
}
internal static class BatchMath
{
	internal const int HardLimit = 1000;

	internal static int Clamp(int value)
	{
		return Math.Max(1, Math.Min(1000, value));
	}

	internal static int[] Scale(int[] values, int multiplier)
	{
		int[] array = new int[values.Length];
		for (int i = 0; i < values.Length; i++)
		{
			long num = (long)values[i] * (long)multiplier;
			if (values[i] < 0 || num > 1000000)
			{
				throw new ArgumentOutOfRangeException("multiplier", "This recipe exceeds the safe batch size.");
			}
			array[i] = (int)num;
		}
		return array;
	}

	internal static long Energy(long value, int multiplier)
	{
		if (value > 0)
		{
			return Math.Min(value, 1152921504606846L) * Clamp(multiplier);
		}
		return value;
	}

	internal static bool SafeToResize(bool running, int time, int bonusTime)
	{
		if (!running && time == 0)
		{
			return bonusTime == 0;
		}
		return false;
	}
}
internal sealed class MultiplierTag
{
	internal int Kind;

	internal int Proto;

	internal int Value;

	internal int Length;

	internal int[] Source;
}
internal static class BlueprintSettings
{
	private const int Magic = 1212568397;

	private const int Version = 1;

	private const int Size = 7;

	private static readonly FieldInfo CustomComponentId = typeof(EntityData).GetField("customId");

	internal static bool Read(int[] parameters, out MultiplierTag tag)
	{
		tag = null;
		if (parameters == null || parameters.Length < 7)
		{
			return false;
		}
		int num = parameters.Length - 7;
		int num2 = parameters[num + 2];
		int num3 = parameters[num + 3];
		int num4 = parameters[num + 4];
		if (parameters[num] != 1212568397 || parameters[num + 1] != 1 || num2 < 1 || num2 > 4 || num3 <= 0 || num4 < 1 || num4 > 1000 || parameters[num + 5] != num || parameters[num + 6] != (0x4846534C ^ num2 ^ num3 ^ num4 ^ num))
		{
			return false;
		}
		tag = new MultiplierTag
		{
			Kind = num2,
			Proto = num3,
			Value = num4,
			Length = num,
			Source = parameters
		};
		return true;
	}

	internal static int[] Stamp(int[] parameters, int length, int kind, int proto, int value)
	{
		if (length < 0 || length > ((parameters != null) ? parameters.Length : 0))
		{
			throw new ArgumentOutOfRangeException("length");
		}
		if (parameters != null && length == parameters.Length && Read(parameters, out var tag))
		{
			length = tag.Length;
		}
		int[] array = new int[length + 7];
		if (length > 0)
		{
			Array.Copy(parameters, array, length);
		}
		int num = BatchMath.Clamp(value);
		array[length] = 1212568397;
		array[length + 1] = 1;
		array[length + 2] = kind;
		array[length + 3] = proto;
		array[length + 4] = num;
		array[length + 5] = length;
		array[length + 6] = 0x4846534C ^ kind ^ proto ^ num ^ length;
		return array;
	}

	internal static int Kind(PlanetFactory factory, int entity)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		if (factory == null || entity <= 0 || entity >= factory.entityPool.Length || factory.entityPool[entity].id != entity)
		{
			return 0;
		}
		EntityData val = factory.entityPool[entity];
		FactorySystem factorySystem = factory.factorySystem;
		if (factorySystem == null)
		{
			return 0;
		}
		if (CustomComponentId != null && (int)CustomComponentId.GetValue(val) > 0)
		{
			return 0;
		}
		if (val.assemblerId > 0 && val.assemblerId < factorySystem.assemblerPool.Length && factorySystem.assemblerPool[val.assemblerId].entityId == entity)
		{
			return 1;
		}
		if (val.labId > 0 && val.labId < factorySystem.labPool.Length && factorySystem.labPool[val.labId].entityId == entity && !factorySystem.labPool[val.labId].researchMode)
		{
			return 2;
		}
		if (val.fractionatorId > 0 && val.fractionatorId < factorySystem.fractionatorPool.Length && factorySystem.fractionatorPool[val.fractionatorId].entityId == entity)
		{
			return 3;
		}
		if (val.powerExcId > 0 && factory.powerSystem != null && factory.powerSystem.excPool != null && val.powerExcId < factory.powerSystem.excPool.Length && factory.powerSystem.excPool[val.powerExcId].entityId == entity)
		{
			return 4;
		}
		return 0;
	}

	internal static void Capture(BatchEngine engine, ref BuildingParameters settings, int objectId, PlanetFactory factory)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Invalid comparison between Unknown and I4
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Invalid comparison between Unknown and I4
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Invalid comparison between Unknown and I4
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Invalid comparison between Unknown and I4
		if (objectId <= 0)
		{
			return;
		}
		int num = Kind(factory, objectId);
		switch (num)
		{
		case 0:
			break;
		case 1:
			if ((int)settings.type != 5)
			{
				break;
			}
			goto default;
		default:
			if ((num != 2 || (int)settings.type == 8) && (num != 3 || (int)settings.type == 99) && (num != 4 || (int)settings.type == 13))
			{
				BatchState value2;
				int value = ((!engine.States.TryGetValue(BatchEngine.Key(factory.planetId, objectId), out value2)) ? 1 : value2.Requested);
				settings.parameters = Stamp(settings.parameters, (settings.parameters != null) ? settings.parameters.Length : 0, num, factory.entityPool[objectId].protoId, value);
			}
			break;
		}
	}

	internal static bool Compatible(ref BuildingParameters settings, MultiplierTag tag, int objectId, PlanetFactory factory, bool nativeAccepted)
	{
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Invalid comparison between Unknown and I4
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Invalid comparison between Unknown and I4
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Invalid comparison between Unknown and I4
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Invalid comparison between Unknown and I4
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Invalid comparison between Unknown and I4
		if (factory == null || objectId == 0)
		{
			return false;
		}
		if (objectId < 0)
		{
			int num = -objectId;
			if (num <= 0 || factory.prebuildPool == null || num >= factory.prebuildPool.Length || factory.prebuildPool[num].id != num)
			{
				return false;
			}
			if (!nativeAccepted)
			{
				if (tag.Kind == 3 && (int)settings.type == 99)
				{
					return factory.prebuildPool[num].protoId == tag.Proto;
				}
				return false;
			}
			return true;
		}
		int num2 = Kind(factory, objectId);
		if (num2 != tag.Kind)
		{
			return false;
		}
		switch (num2)
		{
		case 3:
			return (int)settings.type == 99;
		case 4:
			return (int)settings.type == 13;
		default:
		{
			EntityData val = factory.entityPool[objectId];
			if (num2 == 1)
			{
				if ((int)settings.type == 5)
				{
					if (!nativeAccepted)
					{
						return factory.factorySystem.assemblerPool[val.assemblerId].recipeId == settings.recipeId;
					}
					return true;
				}
				return false;
			}
			if ((int)settings.type == 8 && settings.mode0 != 2)
			{
				if (!nativeAccepted)
				{
					return factory.factorySystem.labPool[val.labId].recipeId == settings.recipeId;
				}
				return true;
			}
			return false;
		}
		}
	}

	internal static bool Paste(BatchEngine engine, ref BuildingParameters settings, int objectId, PlanetFactory factory, bool nativeAccepted)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		if (!Read(settings.parameters, out var tag) || !Compatible(ref settings, tag, objectId, factory, nativeAccepted))
		{
			return false;
		}
		if (objectId < 0)
		{
			int num = -objectId;
			PrebuildData val = factory.prebuildPool[num];
			int length = ((val.parameters != null) ? Math.Min(Math.Max(0, val.paramCount), val.parameters.Length) : 0);
			factory.prebuildPool[num].parameters = Stamp(val.parameters, length, tag.Kind, val.protoId, tag.Value);
			factory.prebuildPool[num].paramCount = factory.prebuildPool[num].parameters.Length;
			return true;
		}
		engine.Request(factory, objectId, tag.Kind == 2, tag.Value);
		return true;
	}

	internal static void ApplyBuilt(BatchEngine engine, int entityId, int[] parameters, PlanetFactory factory)
	{
		if (Read(parameters, out var tag) && Kind(factory, entityId) == tag.Kind)
		{
			engine.Request(factory, entityId, tag.Kind == 2, tag.Value);
		}
	}
}
[HarmonyPatch(typeof(BuildingParameters), "CopyFromFactoryObject")]
internal static class CaptureMultiplier
{
	[HarmonyPriority(0)]
	[HarmonyPostfix]
	internal static void Postfix(ref BuildingParameters __instance, int objectId, PlanetFactory factory, bool __result)
	{
		if (__result && !object.ReferenceEquals(Plugin.Instance, null))
		{
			BlueprintSettings.Capture(Plugin.Instance.Engine, ref __instance, objectId, factory);
		}
	}
}
[HarmonyPatch(typeof(BuildingParameters), "ToParamsArray")]
internal static class SerializeMultiplier
{
	[HarmonyPrefix]
	internal static void Prefix(ref BuildingParameters __instance, out MultiplierTag __state)
	{
		if (BlueprintSettings.Read(__instance.parameters, out __state))
		{
			__state.Source = (int[])__state.Source.Clone();
		}
	}

	[HarmonyPostfix]
	[HarmonyPriority(0)]
	internal static void Postfix(ref BuildingParameters __instance, ref int[] _parameters, ref int _paramCount, MultiplierTag __state)
	{
		if (__state != null)
		{
			int num = Math.Max(_paramCount, __state.Length);
			int[] array = new int[num];
			if (_paramCount > 0 && _parameters != null)
			{
				Array.Copy(_parameters, array, Math.Min(_paramCount, _parameters.Length));
			}
			if (__state.Length > _paramCount)
			{
				Array.Copy(__state.Source, _paramCount, array, _paramCount, __state.Length - _paramCount);
			}
			_parameters = BlueprintSettings.Stamp(array, num, __state.Kind, __state.Proto, __state.Value);
			_paramCount = _parameters.Length;
			if (!BlueprintSettings.Read(__instance.parameters, out var _))
			{
				__instance.parameters = __state.Source;
			}
		}
	}
}
[HarmonyPatch(typeof(BuildingParameters), "FromParamsArray")]
internal static class DeserializeMultiplier
{
	[HarmonyPostfix]
	[HarmonyPriority(0)]
	internal static void Postfix(ref BuildingParameters __instance, int[] _parameters)
	{
		if (BlueprintSettings.Read(_parameters, out var _))
		{
			__instance.parameters = (int[])_parameters.Clone();
		}
	}
}
[HarmonyPatch(typeof(BuildingParameters), "CopyFromBuildPreview")]
internal static class PreviewMultiplier
{
	[HarmonyPriority(0)]
	[HarmonyPostfix]
	private static void Postfix(ref BuildingParameters __instance, BuildPreview bp)
	{
		if (bp != null && BlueprintSettings.Read(bp.parameters, out var _))
		{
			__instance.parameters = (int[])bp.parameters.Clone();
		}
	}
}
[HarmonyPatch(typeof(BuildingParameters), "CanPasteToFactoryObject")]
internal static class AllowMultiplierPaste
{
	[HarmonyPostfix]
	[HarmonyPriority(0)]
	internal static void Postfix(ref BuildingParameters __instance, int objectId, PlanetFactory factory, ref bool __result)
	{
		if (!__result && BlueprintSettings.Read(__instance.parameters, out var tag))
		{
			__result = BlueprintSettings.Compatible(ref __instance, tag, objectId, factory, nativeAccepted: false);
		}
	}
}
[HarmonyPatch(typeof(BuildingParameters), "PasteToFactoryObject")]
internal static class PasteMultiplier
{
	[HarmonyPostfix]
	[HarmonyPriority(0)]
	internal static void Postfix(ref BuildingParameters __instance, int objectId, PlanetFactory factory, ref bool __result)
	{
		if (!object.ReferenceEquals(Plugin.Instance, null) && BlueprintSettings.Paste(Plugin.Instance.Engine, ref __instance, objectId, factory, __result))
		{
			__result = true;
		}
	}
}
[HarmonyPatch(typeof(BuildingParameters), "ApplyPrebuildParametersToEntity")]
internal static class FinishMultiplierBuild
{
	[HarmonyPostfix]
	[HarmonyPriority(0)]
	internal static void Postfix(int entityId, int[] parameters, PlanetFactory factory)
	{
		if (!object.ReferenceEquals(Plugin.Instance, null))
		{
			BlueprintSettings.ApplyBuilt(Plugin.Instance.Engine, entityId, parameters, factory);
		}
	}
}
internal static class ExchangerBindings
{
	private static ConditionalWeakTable<PowerExchangerComponent[], Dictionary<int, BatchState>> bindings = new ConditionalWeakTable<PowerExchangerComponent[], Dictionary<int, BatchState>>();

	[ThreadStatic]
	internal static PowerExchangerComponent[] Context;

	internal static void Bind(PowerExchangerComponent[] pool, int id, BatchState state)
	{
		Dictionary<int, BatchState> orCreateValue = bindings.GetOrCreateValue(pool);
		if (!orCreateValue.TryGetValue(id, out var value) || value != state)
		{
			orCreateValue[id] = state;
		}
	}

	internal static void Remove(PowerExchangerComponent[] pool, int id)
	{
		if (pool != null && bindings.TryGetValue(pool, out var value))
		{
			value.Remove(id);
		}
	}

	internal static int Multiplier(ref PowerExchangerComponent machine)
	{
		if (Context == null || machine.id <= 0 || !bindings.TryGetValue(Context, out var value) || !value.TryGetValue(machine.id, out var value2) || value2.Entity != machine.entityId)
		{
			return 1;
		}
		return value2.Active;
	}

	internal static void Clear()
	{
		bindings = new ConditionalWeakTable<PowerExchangerComponent[], Dictionary<int, BatchState>>();
		Context = null;
	}
}
internal static class ExchangerCharging
{
	private const long MaxRate = 8796093022207L;

	internal static long Rate(ref PowerExchangerComponent machine, int n)
	{
		int num = ((machine.emptyCount > 0) ? Math.Max(0, Math.Min(10, machine.emptyInc / machine.emptyCount)) : 0);
		double num2 = (double)Math.Max(0L, machine.energyPerTick) * (1.0 + Cargo.accTableMilli[num]) * (double)BatchMath.Clamp(n);
		if (!double.IsNaN(num2))
		{
			return (long)Math.Min(8796093022207.0, Math.Max(0.0, num2));
		}
		return 0L;
	}

	internal static int Conversions(ref PowerExchangerComponent machine)
	{
		int num = Math.Max(0, Math.Min(machine.emptyCount, 20 - machine.fullCount));
		if (machine.emptyCount > 0 && machine.emptyInc > 0)
		{
			int num2 = (machine.emptyInc + machine.emptyCount - 1) / machine.emptyCount;
			num = Math.Min(num, Math.Max(0, 32767 - machine.fullInc) / num2);
		}
		return num;
	}

	internal static long Capacity(ref PowerExchangerComponent machine, int n)
	{
		if (machine.targetState <= 0f || machine.state != 1f || machine.maxPoolEnergy <= 0 || machine.currPoolEnergy < 0 || machine.currPoolEnergy > machine.maxPoolEnergy || machine.emptyCount < 0 || machine.fullCount < 0 || machine.emptyInc < 0 || machine.fullInc < 0)
		{
			return 0L;
		}
		long num = machine.maxPoolEnergy - machine.currPoolEnergy;
		int num2 = Conversions(ref machine);
		long num3 = ((machine.maxPoolEnergy > 8796093022207L / Math.Max(1, num2)) ? 8796093022207L : (machine.maxPoolEnergy * num2));
		num = ((num > 8796093022207L - num3) ? 8796093022207L : (num + num3));
		return Math.Min(Rate(ref machine, n), num);
	}

	internal static long Process(ref PowerExchangerComponent machine, int n, long remaining, int[] products, int[] consumed)
	{
		if (machine.targetState <= 0f || machine.state != 1f || machine.maxPoolEnergy <= 0 || machine.currPoolEnergy < 0 || machine.currPoolEnergy > machine.maxPoolEnergy)
		{
			return 0L;
		}
		if (machine.emptyId <= 0 || machine.fullId <= 0 || products == null || consumed == null || machine.fullId >= products.Length || machine.emptyId >= consumed.Length)
		{
			return 0L;
		}
		long num = Math.Min(Math.Max(0L, remaining), Capacity(ref machine, n));
		if (machine.maxPoolEnergy <= 0)
		{
			return 0L;
		}
		long num2 = num / machine.maxPoolEnergy;
		long num3 = num % machine.maxPoolEnergy;
		long currPoolEnergy = machine.currPoolEnergy;
		if (num3 >= machine.maxPoolEnergy - currPoolEnergy)
		{
			num2++;
			currPoolEnergy = num3 - (machine.maxPoolEnergy - currPoolEnergy);
		}
		else
		{
			currPoolEnergy += num3;
		}
		int num4 = (int)Math.Min(num2, Conversions(ref machine));
		currPoolEnergy += (num2 - num4) * machine.maxPoolEnergy;
		if (num4 > 0)
		{
			int emptyCount = machine.emptyCount;
			int emptyInc = machine.emptyInc;
			int num5 = ((emptyCount > 0) ? (emptyInc / emptyCount) : 0);
			int num6 = emptyInc - num5 * emptyCount;
			int num7 = num5 * num4 + Math.Max(0, num6 - (emptyCount - num4));
			machine.emptyCount -= (short)num4;
			machine.emptyInc -= (short)num7;
			machine.fullCount += (short)num4;
			machine.fullInc += (short)num7;
			lock (products)
			{
				products[machine.fullId] = products[machine.fullId] + num4;
			}
			lock (consumed)
			{
				consumed[machine.emptyId] = consumed[machine.emptyId] + num4;
			}
		}
		machine.currPoolEnergy = currPoolEnergy;
		machine.currEnergyPerTick = num;
		return num;
	}
}
[HarmonyPatch(typeof(PowerSystem), "GameTick")]
internal static class ExchangerPowerContext
{
	[HarmonyPrefix]
	internal static void Prefix(PowerSystem __instance, out PowerExchangerComponent[] __state)
	{
		__state = ExchangerBindings.Context;
		ExchangerBindings.Context = __instance.excPool;
	}

	[HarmonyFinalizer]
	internal static Exception Finalizer(PowerExchangerComponent[] __state, Exception __exception)
	{
		ExchangerBindings.Context = __state;
		return __exception;
	}
}
[HarmonyPatch(typeof(UIPowerExchangerWindow), "_OnUpdate")]
internal static class ExchangerWindowContext
{
	[HarmonyPrefix]
	private static void Prefix(UIPowerExchangerWindow __instance, out PowerExchangerComponent[] __state)
	{
		__state = ExchangerBindings.Context;
		ExchangerBindings.Context = ((__instance.powerSystem == null) ? null : __instance.powerSystem.excPool);
	}

	[HarmonyFinalizer]
	private static Exception Finalizer(PowerExchangerComponent[] __state, Exception __exception)
	{
		ExchangerBindings.Context = __state;
		return __exception;
	}
}
[HarmonyPatch(typeof(PowerExchangerComponent), "CalculateActualEnergyPerTick")]
internal static class ExchangerChargeRate
{
	[HarmonyPriority(0)]
	[HarmonyAfter(new string[] { "com.marvis.energyexchangertweaks" })]
	[HarmonyPostfix]
	internal static void Postfix(ref PowerExchangerComponent __instance, bool isOutput, ref long __result)
	{
		int num = ExchangerBindings.Multiplier(ref __instance);
		if (!isOutput && __instance.targetState > 0f && num > 1)
		{
			__result = ExchangerCharging.Rate(ref __instance, num);
		}
	}
}
[HarmonyPatch(typeof(PowerExchangerComponent), "InputCaps")]
internal static class ExchangerChargeCaps
{
	[HarmonyPrefix]
	private static bool Prefix(ref PowerExchangerComponent __instance, ref long __result)
	{
		int num = ExchangerBindings.Multiplier(ref __instance);
		if (num <= 1 || __instance.targetState <= 0f)
		{
			return true;
		}
		__result = ExchangerCharging.Capacity(ref __instance, num);
		__instance.capsCurrentTick = __result;
		return false;
	}
}
[HarmonyPatch(typeof(PowerExchangerComponent), "InputUpdate")]
internal static class ExchangerChargeBatch
{
	[HarmonyPrefix]
	private static bool Prefix(ref PowerExchangerComponent __instance, long remaining, AnimData[] animPool, int[] productRegister, int[] consumeRegister, ref long __result)
	{
		int num = ExchangerBindings.Multiplier(ref __instance);
		if (num <= 1 || __instance.targetState <= 0f)
		{
			return true;
		}
		if (__instance.state != 1f)
		{
			__result = 0L;
			return false;
		}
		__result = ExchangerCharging.Process(ref __instance, num, remaining, productRegister, consumeRegister);
		if (animPool != null && __instance.entityId > 0 && __instance.entityId < animPool.Length)
		{
			long num2 = ExchangerCharging.Rate(ref __instance, num);
			animPool[__instance.entityId].state = ((num2 > 0) ? ((uint)Math.Min(100.0, (double)__result * 100.0 / (double)num2)) : 0u);
			animPool[__instance.entityId].power = ((__instance.maxPoolEnergy > 0) ? ((float)((double)__instance.currPoolEnergy / (double)__instance.maxPoolEnergy)) : 0f);
		}
		return false;
	}
}
[HarmonyPatch(typeof(PowerSystem), "RemoveExchangerComponent")]
internal static class RemoveExchanger
{
	[HarmonyPrefix]
	private static void Prefix(PowerSystem __instance, int id)
	{
		if (!object.ReferenceEquals(Plugin.Instance, null) && id > 0 && id < __instance.excPool.Length)
		{
			ExchangerBindings.Remove(__instance.excPool, id);
			Plugin.Instance.Engine.Remove(__instance.factory.planetId, __instance.excPool[id].entityId);
		}
	}
}
internal sealed class FactoryPanel : IDisposable
{
	private readonly Plugin plugin;

	private GameObject root;

	private RectTransform panel;

	private Canvas canvas;

	private Text status;

	private Text range;

	private InputField amount;

	private Slider slider;

	private PresetMenu presets;

	private NativeSkin skin;

	private Font font;

	private PlanetFactory factory;

	private int entity;

	private bool lab;

	private bool refreshing;

	private bool pointerHeld;

	private int releaseFrame = -1;

	private long selected = -1L;

	private int displayedRequested = -1;

	private readonly Vector3[] corners = (Vector3[])(object)new Vector3[4];

	private static readonly FieldInfo LabFactory = AccessTools.Field(typeof(UILabWindow), "factory");

	internal bool Editing
	{
		get
		{
			if ((Object)(object)root != (Object)null && root.activeSelf)
			{
				return amount.isFocused;
			}
			return false;
		}
	}

	internal bool Blocking
	{
		get
		{
			//IL_004b: 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)
			if ((Object)(object)root != (Object)null && root.activeSelf)
			{
				if (!Editing && !pointerHeld && !presets.Blocking && Time.frameCount > releaseFrame)
				{
					return RectTransformUtility.RectangleContainsScreenPoint(panel, Vector2.op_Implicit(Input.mousePosition), (Camera)null);
				}
				return true;
			}
			return false;
		}
	}

	internal FactoryPanel(Plugin plugin)
	{
		this.plugin = plugin;
	}

	private static RectTransform Place(GameObject go, Transform parent, float x, float y, float width, float height)
	{
		//IL_0021: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: 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_003f: 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)
		go.transform.SetParent(parent, false);
		RectTransform component = go.GetComponent<RectTransform>();
		Vector2 val = (component.pivot = new Vector2(0f, 1f));
		Vector2 anchorMin = (component.anchorMax = val);
		component.anchorMin = anchorMin;
		component.anchoredPosition = new Vector2(x, 0f - y);
		component.sizeDelta = new Vector2(width, height);
		return component;
	}

	private Text Label(Transform parent, string text, float x, float y, float width, float height, int size)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Expected O, but got Unknown
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Label", new Type[2]
		{
			typeof(RectTransform),
			typeof(Text)
		});
		Place(val, parent, x, y, width, height);
		Text component = val.GetComponent<Text>();
		component.font = font;
		component.text = text;
		component.fontSize = size;
		((Graphic)component).color = Color.white;
		((Graphic)component).raycastTarget = false;
		component.alignment = (TextAnchor)3;
		component.verticalOverflow = (VerticalWrapMode)1;
		return component;
	}

	private GameObject Surface(string name, Transform parent, float x, float y, float width, float height)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name, new Type[2]
		{
			typeof(RectTransform),
			typeof(Image)
		});
		Place(val, parent, x, y, width, height);
		Image component = val.GetComponent<Image>();
		((Graphic)component).color = new Color(0.1f, 0.21f, 0.26f, 1f);
		((Graphic)component).raycastTarget = true;
		return val;
	}

	private void Button(string title, float x, float y, float width, Action click)
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Expected O, but got Unknown
		GameObject val = Surface(title, (Transform)(object)panel, x, y, width, 30f);
		Button val2 = val.AddComponent<Button>();
		((Selectable)val2).targetGraphic = (Graphic)(object)val.GetComponent<Image>();
		skin.Button(val2);
		((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
		{
			click();
		});
		Text val3 = Label(val.transform, title, 0f, 0f, width, 30f, 16);
		val3.alignment = (TextAnchor)4;
	}

	private void Create(RectTransform nativeWindow)
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Expected O, but got Unknown
		//IL_00de: 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_02d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02df: Expected O, but got Unknown
		//IL_0344: Unknown result type (might be due to invalid IL or missing references)
		font = UIRoot.instance.uiGame.controlPanelWindow.FONT_SAIRASB;
		skin = new NativeSkin();
		root = new GameObject("Honey I Shrunk the Factory panel", new Type[3]
		{
			typeof(RectTransform),
			typeof(Canvas),
			typeof(GraphicRaycaster)
		});
		Object.DontDestroyOnLoad((Object)(object)root);
		canvas = root.GetComponent<Canvas>();
		canvas.renderMode = (RenderMode)0;
		canvas.sortingOrder = 32750;
		GameObject val = Surface("Factory batch settings", root.transform, 0f, 0f, 500f, 386f);
		panel = val.GetComponent<RectTransform>();
		((Graphic)val.GetComponent<Image>()).color = Color.clear;
		skin.Frame(nativeWindow, panel);
		Label((Transform)(object)panel, "Honey I Shrunk the Factory", 40f, 32f, 420f, 30f, 17);
		range = Label((Transform)(object)panel, "Machines in one building", 40f, 84f, 420f, 26f, 15);
		GameObject val2 = Surface("Batch amount", (Transform)(object)panel, 40f, 122f, 274f, 30f);
		amount = val2.AddComponent<InputField>();
		skin.Input(val2.GetComponent<Image>());
		Text textComponent = Label(val2.transform, "1", 8f, 0f, 258f, 30f, 15);
		amount.textComponent = textComponent;
		((Selectable)amount).targetGraphic = (Graphic)(object)val2.GetComponent<Image>();
		amount.contentType = (ContentType)2;
		amount.characterLimit = 4;
		Button("Apply", 330f, 122f, 130f, Apply);
		GameObject val3 = Surface("Multiplier", (Transform)(object)panel, 40f, 166f, 420f, 26f);
		((Graphic)val3.GetComponent<Image>()).color = Color.clear;
		slider = val3.AddComponent<Slider>();
		slider.minValue = 1f;
		slider.maxValue = plugin.Maximum.Value;
		slider.wholeNumbers = true;
		Image component = Surface("Track", val3.transform, 0f, 11f, 420f, 4f).GetComponent<Image>();
		GameObject val4 = new GameObject("Handle slide area", new Type[1] { typeof(RectTransform) });
		Place(val4, val3.transform, 6f, 4f, 408f, 18f);
		GameObject val5 = Surface("Handle", val4.transform, 0f, 0f, 12f, 0f);
		((Graphic)val5.GetComponent<Image>()).color = new Color(0.5f, 0.86f, 0.9f, 1f);
		slider.handleRect = val5.GetComponent<RectTransform>();
		((Selectable)slider).targetGraphic = (Graphic)(object)val5.GetComponent<Image>();
		skin.Slider(slider, component);
		((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float value)
		{
			if (!refreshing)
			{
				amount.text = ((int)value).ToString();
			}
		});
		presets = new PresetMenu(panel, root.transform, font, skin, Set);
		status = Label((Transform)(object)panel, "", 40f, 254f, 420f, 94f, 15);
		status.verticalOverflow = (VerticalWrapMode)0;
	}

	private void Set(int n)
	{
		amount.text = Math.Min(n, plugin.Maximum.Value).ToString();
		refreshing = true;
		slider.value = Math.Min(n, plugin.Maximum.Value);
		refreshing = false;
	}

	private void Apply()
	{
		if (!int.TryParse(amount.text, out var result) || result < 1 || result > plugin.Maximum.Value)
		{
			status.text = "Enter a whole number from 1 to " + plugin.Maximum.Value + ".";
			return;
		}
		try
		{
			plugin.Engine.Request(factory, entity, lab, result);
			UpdateStatus();
		}
		catch (Exception ex)
		{
			status.text = "Could not apply: " + ex.Message;
		}
	}

	private void UpdateStatus()
	{
		BatchState batchState = plugin.Engine.Get(factory, entity, lab);
		range.text = "Machines in one building  |  1 - " + plugin.Maximum.Value;
		if (batchState.Exchanger)
		{
			range.text = "Charging exchangers in one building  |  1 - " + plugin.Maximum.Value;
			status.text = "Charge: " + batchState.Requested + "x\nUses real grid surplus and empty accumulators. Discharge is unchanged. Above 1x, Honey replaces EnergyExchangerTweaks' charge multiplier.";
		}
		else if (batchState.Fractionator)
		{
			status.text = "Active: " + batchState.Active + "x  |  Selected: " + batchState.Requested + "x\nFractionation chance is unchanged. Unconverted input retains its spray points. Supply and power must keep up.";
		}
		else
		{
			status.text = "Active: " + batchState.Active + "x  |  Selected: " + batchState.Requested + "x\n" + ((batchState.Active != batchState.Requested) ? "Waiting for a clean batch. Clear/reselect the recipe to apply now (normal game reset)." : "Ingredients, output and power scale together. Cycle duration and existing speed boosts are retained.");
		}
	}

	internal void Update()
	{
		//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0412: Unknown result type (might be due to invalid IL or missing references)
		//IL_0417: Unknown result type (might be due to invalid IL or missing references)
		//IL_041c: Unknown result type (might be due to invalid IL or missing references)
		//IL_042c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0431: Unknown result type (might be due to invalid IL or missing references)
		//IL_0436: Unknown result type (might be due to invalid IL or missing references)
		//IL_0439: Unknown result type (might be due to invalid IL or missing references)
		//IL_043e: Unknown result type (might be due to invalid IL or missing references)
		//IL_046a: Unknown result type (might be due to invalid IL or missing references)
		//IL_046f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0529: Unknown result type (might be due to invalid IL or missing references)
		//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0272: Unknown result type (might be due to invalid IL or missing references)
		//IL_0278: Expected O, but got Unknown
		//IL_0569: Unknown result type (might be due to invalid IL or missing references)
		//IL_056e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		if (UIRecipePicker.isOpened)
		{
			if ((Object)(object)root != (Object)null)
			{
				presets.Close();
				root.SetActive(false);
			}
			pointerHeld = false;
			releaseFrame = -1;
			return;
		}
		UIRoot instance = UIRoot.instance;
		RectTransform val = null;
		PlanetFactory val2 = null;
		int num = 0;
		bool flag = false;
		if (GameMain.data != null && (Object)(object)GameMain.instance != (Object)null && !GameMain.instance.isMenuDemo && (Object)(object)instance != (Object)null && (Object)(object)instance.uiGame != (Object)null)
		{
			UIAssemblerWindow assemblerWindow = instance.uiGame.assemblerWindow;
			if ((Object)(object)assemblerWindow != (Object)null && ((ManualBehaviour)assemblerWindow).active && assemblerWindow.factory != null && assemblerWindow.assemblerId > 0 && assemblerWindow.assemblerId < assemblerWindow.factory.factorySystem.assemblerPool.Length)
			{
				val2 = assemblerWindow.factory;
				num = val2.factorySystem.assemblerPool[assemblerWindow.assemblerId].entityId;
				val = assemblerWindow.windowTrans;
			}
			else
			{
				UIFractionatorWindow fractionatorWindow = instance.uiGame.fractionatorWindow;
				if ((Object)(object)fractionatorWindow != (Object)null && ((ManualBehaviour)fractionatorWindow).active && fractionatorWindow.factory != null && fractionatorWindow.fractionatorId > 0 && fractionatorWindow.fractionatorId < fractionatorWindow.factory.factorySystem.fractionatorPool.Length)
				{
					val2 = fractionatorWindow.factory;
					num = val2.factorySystem.fractionatorPool[fractionatorWindow.fractionatorId].entityId;
					Transform transform = ((Component)fractionatorWindow).transform;
					val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				}
				UIPowerExchangerWindow exchangerWindow = instance.uiGame.exchangerWindow;
				if (val2 == null && (Object)(object)exchangerWindow != (Object)null && ((ManualBehaviour)exchangerWindow).active && exchangerWindow.factory != null && exchangerWindow.powerSystem != null && exchangerWindow.exchangerId > 0 && exchangerWindow.exchangerId < exchangerWindow.powerSystem.excPool.Length)
				{
					PowerExchangerComponent val3 = exchangerWindow.powerSystem.excPool[exchangerWindow.exchangerId];
					if (val3.targetState > 0f)
					{
						val2 = exchangerWindow.factory;
						num = val3.entityId;
						val = exchangerWindow.rectTransform;
					}
				}
				UILabWindow labWindow = instance.uiGame.labWindow;
				if (val2 == null && (Object)(object)labWindow != (Object)null && ((ManualBehaviour)labWindow).active && labWindow.labId > 0)
				{
					val2 = (PlanetFactory)LabFactory.GetValue(labWindow);
					if (val2 != null && labWindow.labId < val2.factorySystem.labPool.Length && !val2.factorySystem.labPool[labWindow.labId].researchMode)
					{
						num = val2.factorySystem.labPool[labWindow.labId].entityId;
						val = labWindow.windowTrans;
						flag = true;
					}
				}
			}
		}
		if (val2 == null || num <= 0 || (Object)(object)val == (Object)null)
		{
			if ((Object)(object)root != (Object)null)
			{
				presets.Close();
				root.SetActive(false);
			}
			pointerHeld = false;
			selected = -1L;
			return;
		}
		if ((Object)(object)root == (Object)null)
		{
			Create(val);
		}
		root.SetActive(true);
		factory = val2;
		entity = num;
		lab = flag;
		long num2 = BatchEngine.Key(val2.planetId, num);
		BatchState batchState = plugin.Engine.Get(factory, entity, lab);
		if (selected != num2 || displayedRequested != batchState.Requested)
		{
			presets.Close();
			selected = num2;
			displayedRequested = batchState.Requested;
			Set(batchState.Requested);
		}
		UpdateStatus();
		val.GetWorldCorners(corners);
		Canvas componentInParent = ((Component)val).GetComponentInParent<Canvas>();
		Camera val4 = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null);
		Vector2 val5 = RectTransformUtility.WorldToScreenPoint(val4, corners[2]);
		Vector2 val6 = RectTransformUtility.WorldToScreenPoint(val4, corners[1]);
		Rect rect = val.rect;
		float num3;
		if (!(((Rect)(ref rect)).width > 0f))
		{
			num3 = 1f;
		}
		else
		{
			float num4 = Mathf.Abs(val5.x - val6.x);
			Rect rect2 = val.rect;
			num3 = Mathf.Clamp(num4 / ((Rect)(ref rect2)).width, 0.5f, 2f);
		}
		float num5 = num3;
		canvas.scaleFactor = num5;
		float num6 = val5.x / num5 + 2f;
		float num7 = ((float)Screen.height - val5.y) / num5;
		if (num6 + 500f > (float)Screen.width / num5)
		{
			num6 = RectTransformUtility.WorldToScreenPoint(val4, corners[1]).x / num5 - 502f;
		}
		panel.anchoredPosition = new Vector2(Mathf.Clamp(num6, 0f, Mathf.Max(0f, (float)Screen.width / num5 - 500f)), 0f - num7);
		presets.Update(num5, plugin.Maximum.Value, amount.text);
		if (Input.GetMouseButtonDown(0) && RectTransformUtility.RectangleContainsScreenPoint(panel, Vector2.op_Implicit(Input.mousePosition), (Camera)null))
		{
			pointerHeld = true;
		}
		if (Input.GetMouseButtonUp(0) && pointerHeld)
		{
			pointerHeld = false;
			releaseFrame = Time.frameCount + 1;
		}
	}

	public void Dispose()
	{
		if ((Object)(object)root != (Object)null)
		{
			Object.Destroy((Object)(object)root);
		}
		root = null;
	}
}
internal static class FractionRandom
{
	internal static double Uniform(ref uint seed)
	{
		seed = (uint)((long)(seed % 2147483646 + 1) * 48271L % int.MaxValue - 1);
		return ((double)seed + 0.5) / 2147483646.0;
	}

	private static double Gamma(int shape, ref uint seed)
	{
		double num = (double)shape - 1.0 / 3.0;
		double num2 = 1.0 / Math.Sqrt(9.0 * num);
		for (int i = 0; i < 128; i++)
		{
			double num3 = Math.Sqrt(-2.0 * Math.Log(Uniform(ref seed))) * Math.Cos(Math.PI * 2.0 * Uniform(ref seed));
			double num4 = 1.0 + num2 * num3;
			if (!(num4 <= 0.0))
			{
				num4 = num4 * num4 * num4;
				double num5 = Uniform(ref seed);
				double num6 = num3 * num3;
				if (num5 < 1.0 - 0.0331 * num6 * num6 || Math.Log(num5) < num6 / 2.0 + num * (1.0 - num4 + Math.Log(num4)))
				{
					return num * num4;
				}
			}
		}
		double num7 = 0.0;
		for (int j = 0; j < shape; j++)
		{
			num7 -= Math.Log(Uniform(ref seed));
		}
		return num7;
	}

	internal static int Binomial(int count, double probability, ref uint seed)
	{
		if (count <= 0 || probability <= 0.0)
		{
			return 0;
		}
		if (probability >= 1.0)
		{
			return count;
		}
		bool flag = probability > 0.5;
		if (flag)
		{
			probability = 1.0 - probability;
		}
		int num = 0;
		int num2 = count;
		while (num2 > 32 && (double)num2 * probability > 16.0)
		{
			int num3 = num2 / 2 + 1;
			int shape = num2 - num3 + 1;
			double num4 = Gamma(num3, ref seed);
			double num5 = Gamma(shape, ref seed);
			double num6 = num4 / (num4 + num5);
			if (num6 > probability)
			{
				num2 = num3 - 1;
				probability /= num6;
			}
			else
			{
				num += num3;
				num2 -= num3;
				probability = (probability - num6) / (1.0 - num6);
			}
			if (probability <= 0.0)
			{
				num2 = 0;
				break;
			}
			if (probability >= 1.0)
			{
				num += num2;
				num2 = 0;
				break;
			}
		}
		if (num2 <= 32)
		{
			for (int i = 0; i < num2; i++)
			{
				if (Uniform(ref seed) < probability)
				{
					num++;
				}
			}
		}
		else
		{
			double num7 = ((probability < 1E-08) ? ((0.0 - probability) * (1.0 + probability / 2.0 + probability * probability / 3.0)) : Math.Log(1.0 - probability));
			long num8 = 0L;
			while (num8 < num2)
			{
				double num9 = Math.Floor(Math.Log(Uniform(ref seed)) / num7) + 1.0;
				if (num9 > (double)(num2 - num8))
				{
					break;
				}
				num8 += (long)num9;
				num++;
			}
		}
		if (!flag)
		{
			return num;
		}
		return count - num;
	}
}
internal static class Fractionation
{
	internal static Func<double> CargoLimit = () => 30.0;

	internal static void Process(ref FractionatorComponent machine, int n, float power, int[] products, int[] consumption)
	{
		if (power < 0.1f || float.IsNaN(power) || float.IsInfinity(power) || machine.fluidInputCount <= 0 || machine.fluidInputInc < 0 || machine.fluidOutputInc < 0 || machine.fluidId <= 0 || machine.productId <= 0 || machine.productId >= products.Length || machine.fluidId >= consumption.Length)
		{
			return;
		}
		int num = Math.Min(machine.productOutputMax - machine.productOutputCount, machine.fluidOutputMax - machine.fluidOutputCount);
		if (num <= 0)
		{
			machine.fractionSuccess = false;
			return;
		}
		double num2 = machine.fluidInputCargoCount;
		if (double.IsNaN(num2) || double.IsInfinity(num2) || num2 < 0.0)
		{
			return;
		}
		double num3 = ((num2 > 0.0001) ? ((double)machine.fluidInputCount / num2) : 4.0);
		double num4 = CargoLimit();
		if (double.IsNaN(num4) || double.IsInfinity(num4) || num4 < 1.0)
		{
			num4 = 30.0;
		}
		double val = (double)power * 166.66666666666666 * Math.Min(num2, num4 * (double)n) * num3 + 0.75 * (double)n;
		if (num2 <= 0.0001)
		{
			val = (double)power * 166.66666666666666 * Math.Min((double)machine.fluidInputCount / 4.0, num4 * (double)n) * 4.0 + 0.75 * (double)n;
		}
		long num5 = Math.Max(machine.progress, 100000L * (long)n);
		long num6 = Math.Min(num5, Math.Max(0L, machine.progress) + (long)Math.Min(num5, Math.Max(0.0, val)));
		int num7 = (int)Math.Min(Math.Min(num6 / 10000, machine.fluidInputCount), num);
		int num8 = (int)Math.Min(2147483647L, ((long)Math.Max(0, machine.fluidInputInc) + (long)machine.fluidInputCount - 1) / machine.fluidInputCount);
		if (num8 > 0)
		{
			num7 = Math.Min(num7, Math.Max(0, int.MaxValue - machine.fluidOutputInc) / num8);
		}
		machine.progress = (int)(num6 - (long)num7 * 10000L);
		if (num7 <= 0)
		{
			return;
		}
		int num9 = Math.Max(0, machine.fluidInputInc);
		int num10 = num9 / machine.fluidInputCount;
		int num11 = num9 % machine.fluidInputCount;
		int num12 = Math.Min(num7, machine.fluidInputCount - num11);
		int num13 = num7 - num12;
		double chance = machine.produceProb;
		int num14 = FractionRandom.Binomial(num12, Chance(chance, num10), ref machine.seed);
		int num15 = FractionRandom.Binomial(num13, Chance(chance, num10 + 1), ref machine.seed);
		int num16 = num14 + num15;
		int num17 = num7 - num16;
		long num18 = (long)num12 * (long)num10 + (long)num13 * (long)(num10 + 1);
		long num19 = (long)(num12 - num14) * (long)num10 + (long)(num13 - num15) * (long)(num10 + 1);
		machine.fluidInputCount -= num7;
		machine.fluidInputInc -= (int)num18;
		machine.fluidInputCargoCount = (float)Math.Max(0.0, num2 - (double)num7 / num3);
		if (machine.fluidInputCount == 0)
		{
			machine.fluidInputCargoCount = 0f;
			machine.fluidInputInc = 0;
		}
		machine.productOutputCount += num16;
		machine.fluidOutputCount += num17;
		machine.fluidOutputInc += (int)num19;
		machine.productOutputTotal += num16;
		machine.fluidOutputTotal += num17;
		machine.fractionSuccess = num16 > 0;
		machine.incUsed = machine.incUsed || num9 > 0;
		lock (products)
		{
			products[machine.productId] = products[machine.productId] + num16;
		}
		lock (consumption)
		{
			consumption[machine.fluidId] = consumption[machine.fluidId] + num16;
		}
	}

	private static double Chance(double chance, int level)
	{
		double num = chance * (1.0 + Cargo.accTableMilli[Math.Max(0, Math.Min(10, level))]);
		if (!double.IsNaN(num))
		{
			return Math.Max(0.0, Math.Min(1.0, num));
		}
		return 0.0;
	}
}
internal static class FractionPowerBindings
{
	private static ConditionalWeakTable<PowerConsumerComponent[], Dictionary<int, BatchState>> table = new ConditionalWeakTable<PowerConsumerComponent[], Dictionary<int, BatchState>>();

	internal static void Bind(PowerConsumerComponent[] pool, int id, BatchState state)
	{
		if (pool != null && id > 0 && id < pool.Length)
		{
			Dictionary<int, BatchState> orCreateValue = table.GetOrCreateValue(pool);
			if (!orCreateValue.TryGetValue(id, out var value) || value != state)
			{
				orCreateValue[id] = state;
			}
		}
	}

	internal static void Remove(PowerConsumerComponent[] pool, int id)
	{
		if (pool != null && table.TryGetValue(pool, out var value))
		{
			value.Remove(id);
		}
	}

	internal static int Multiplier(PowerConsumerComponent[] pool, int id)
	{
		if (pool == null || !table.TryGetValue(pool, out var value) || !value.TryGetValue(id, out var value2))
		{
			return 1;
		}
		return value2.Active;
	}

	internal static void Clear()
	{
		table = new ConditionalWeakTable<PowerConsumerComponent[], Dictionary<int, BatchState>>();
	}
}
[HarmonyPatch(typeof(FractionatorComponent), "InternalUpdate")]
internal static class FractionatorBatch
{
	internal struct Call
	{
		internal int Maximum;

		internal bool Success;
	}

	[HarmonyAfter(new string[] { "com.Valoneu.FactoryOverclock" })]
	[HarmonyPriority(0)]
	[HarmonyPrefix]
	private static void Prefix(ref FractionatorComponent __instance, PlanetFactory factory, float power, int[] productRegister, int[] consumeRegister, out Call __state)
	{
		__state = new Call
		{
			Maximum = -1
		};
		if (!object.ReferenceEquals(Plugin.Instance, null))
		{
			BatchState batchState = Plugin.Instance.Engine.FractionState(factory.planetId, __instance.entityId);
			if (batchState != null && batchState.Active > 1)
			{
				Fractionation.Process(ref __instance, batchState.Active, power, productRegister, consumeRegister);
				__state = new Call
				{
					Maximum = __instance.productOutputMax,
					Success = __instance.fractionSuccess
				};
				__instance.productOutputMax = 0;
			}
		}
	}

	[HarmonyFinalizer]
	private static Exception Finalizer(ref FractionatorComponent __instance, Call __state, float power, ref uint __result, Exception __exception)
	{
		if (__state.Maximum < 0)
		{
			return __exception;
		}
		__instance.productOutputMax = __state.Maximum;
		__instance.fractionSuccess = __state.Success;
		__instance.isWorking = __instance.fluidInputCount > 0 && __instance.productOutputCount < __instance.productOutputMax && __instance.fluidOutputCount < __instance.fluidOutputMax;
		__result = ((power >= 0.1f && __instance.isWorking) ? 1u : 0u);
		return __exception;
	}
}
[HarmonyPatch(typeof(FractionatorComponent), "SetPCState")]
internal static class FractionatorPower
{
	[HarmonyPrefix]
	internal static bool Prefix(ref FractionatorComponent __instance, PowerConsumerComponent[] pcPool)
	{
		int num = FractionPowerBindings.Multiplier(pcPool, __instance.pcId);
		if (num <= 1)
		{
			return true;
		}
		if (__instance.pcId <= 0 || __instance.pcId >= pcPool.Length)
		{
			return false;
		}
		double num2 = Math.Max(0f, __instance.fluidInputCargoCount);
		double num3 = ((num2 > 0.0001) ? ((double)__instance.fluidInputCount / num2) : 4.0);
		double num4 = Math.Max(0.0, Math.Min(num2 / (double)num, 30.0) * num3 - 30.0);
		double val = (num4 * 50.0 + 1000.0) * Cargo.powerTableRatio[((FractionatorComponent)(ref __instance)).incLevel] + 0.5;
		((PowerConsumerComponent)(ref pcPool[__instance.pcId])).SetRequiredEnergy(__instance.isWorking, (int)Math.Min(2147483647.0, val));
		pcPool[__instance.pcId].requiredEnergy = BatchMath.Energy(pcPool[__instance.pcId].requiredEnergy, num);
		return false;
	}
}
[HarmonyPatch(typeof(FactorySystem), "RemoveFractionatorComponent")]
internal static class RemoveFractionator
{
	[HarmonyPrefix]
	private static void Prefix(FactorySystem __instance, int id)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)Plugin.Instance == (Object)null) && id > 0 && id < __instance.fractionatorPool.Length)
		{
			FractionatorComponent val = __instance.fractionatorPool[id];
			if (__instance.factory.powerSystem != null)
			{
				FractionPowerBindings.Remove(__instance.factory.powerSystem.consumerPool, val.pcId);
			}
			Plugin.Instance.Engine.Remove(__instance.factory.planetId, val.entityId);
		}
	}
}
internal sealed class NativeSkin
{
	private readonly UIComboBox combo;

	private readonly Button button;

	private readonly Slider slider;

	internal NativeSkin()
	{
		UIGame uiGame = UIRoot.instance.uiGame;
		combo = uiGame.controlPanelWindow.filterPanel.sortFilterBox;
		UIButton copyButton = uiGame.assemblerWindow.copyButton;
		if ((Object)(object)copyButton != (Object)null)
		{
			button = copyButton.button;
		}
		if (!((Object)(object)uiGame.stationWindow != (Object)null))
		{
			return;
		}
		Slider[] componentsInChildren = ((Component)uiGame.stationWindow).GetComponentsInChildren<Slider>(true);
		foreach (Slider val in componentsInChildren)
		{
			if ((Object)(object)val.handleRect != (Object)null)
			{
				slider = val;
				break;
			}
		}
	}

	internal static void Copy(Image target, Image source)
	{
		//IL_0018: 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)
		if (!((Object)(object)source == (Object)null))
		{
			target.sprite = source.sprite;
			target.type = source.type;
			((Graphic)target).material = ((Graphic)source).material;
			((Graphic)target).color = ((Graphic)source).color;
			target.fillCenter = source.fillCenter;
			target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier;
		}
	}

	internal void Input(Image target)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		Copy(target, ((Component)combo).GetComponent<Image>());
		((Graphic)target).color = new Color(0.09f, 0.14f, 0.16f, 1f);
	}

	internal void Button(Button target)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Expected O, but got Unknown
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		Copy((Image)((Selectable)target).targetGraphic, (Image)(((Object)(object)button != (Object)null) ? ((object)/*isinst with value type is only supported in some contexts*/) : ((object)((Component)combo).GetComponent<Image>())));
		if ((Object)(object)button != (Object)null)
		{
			((Selectable)target).colors = ((Selectable)button).colors;
			((Selectable)target).transition = (Transition)1;
		}
	}

	internal void Popup(Image target)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		Copy(target, ((Component)combo.m_DropDownList).GetComponent<Image>());
		((Graphic)target).color = new Color(0.075f, 0.11f, 0.13f, 1f);
	}

	internal void Option(Button target)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_001b: 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_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: 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_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: 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)
		Image val = (Image)((Selectable)target).targetGraphic;
		val.sprite = null;
		((Graphic)val).material = null;
		((Graphic)val).color = Color.white;
		ColorBlock colors = ((Selectable)target).colors;
		((ColorBlock)(ref colors)).normalColor = new Color(0.09f, 0.14f, 0.16f, 1f);
		((ColorBlock)(ref colors)).highlightedColor = new Color(0.22f, 0.39f, 0.44f, 1f);
		((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).highlightedColor;
		((ColorBlock)(ref colors)).pressedColor = new Color(0.14f, 0.27f, 0.31f, 1f);
		((Selectable)target).colors = colors;
	}

	internal void Scrollbar(Scrollbar target)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Expected O, but got Unknown
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)combo.m_Scrollbar == (Object)null))
		{
			Copy(((Component)target).GetComponent<Image>(), ((Component)combo.m_Scrollbar).GetComponent<Image>());
			object target2 = (object)(Image)((Selectable)target).targetGraphic;
			Graphic targetGraphic = ((Selectable)combo.m_Scrollbar).targetGraphic;
			Copy((Image)target2, (Image)(object)((targetGraphic is Image) ? targetGraphic : null));
			((Selectable)target).colors = ((Selectable)combo.m_Scrollbar).colors;
		}
	}

	internal void Slider(Slider target, Image background)
	{
		//IL_008f: 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_00b9: Expected O, but got Unknown
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)slider == (Object)null)
		{
			return;
		}
		Image val = ((Component)slider).GetComponent<Image>();
		if ((Object)(object)val == (Object)null)
		{
			Image[] componentsInChildren = ((Component)slider).GetComponentsInChildren<Image>(true);
			foreach (Image val2 in componentsInChildren)
			{
				if ((Object)(object)((Component)val2).transform != (Object)(object)slider.handleRect && ((Object)val2).name.IndexOf("background", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					val = val2;
					break;
				}
			}
		}
		Copy(background, val);
		((Graphic)background).color = new Color(0.07f, 0.12f, 0.14f, 1f);
		Copy((Image)((Selectable)target).targetGraphic, ((Component)slider.handleRect).GetComponent<Image>());
		((Selectable)target).colors = ((Selectable)slider).colors;
	}

	internal void Arrow(RectTransform parent, Font font)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Native dropdown arrow", new Type[1] { typeof(RectTransform) });
		val.transform.SetParent((Transform)(object)parent, false);
		RectTransform component = val.GetComponent<RectTransform>();
		Vector2 val2 = (component.pivot = new Vector2(1f, 0.5f));
		Vector2 anchorMin = (component.anchorMax = val2);
		component.anchorMin = anchorMin;
		component.anchoredPosition = new Vector2(-8f, 0f);
		component.sizeDelta = new Vector2(12f, 14f);
		Image[] componentsInChildren = ((Component)combo).GetComponentsInChildren<Image>(true);
		foreach (Image val5 in componentsInChildren)
		{
			string text = ((Object)val5).name.ToLowerInvariant();
			if (text.Contains("arrow") || text.Contains("down"))
			{
				Copy(val.AddComponent<Image>(), val5);
				((Graphic)val.GetComponent<Image>()).raycastTarget = false;
				return;
			}
		}
		Text val6 = val.AddComponent<Text>();
		val6.font = font;
		val6.fontSize = 12;
		val6.text = "▾";
		val6.alignment = (TextAnchor)4;
		((Graphic)val6).raycastTarget = false;
	}

	internal void Frame(RectTransform source, RectTransform target)
	{
		//IL_0008: 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_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Expected O, but got Unknown
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Expected O, but got Unknown
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		Vector3[] array = (Vector3[])(object)new Vector3[4];
		Rect rect = source.rect;
		if (((Rect)(ref rect)).width <= 0f || ((Rect)(ref rect)).height <= 0f)
		{
			return;
		}
		Graphic[] componentsInChildren = ((Component)source).GetComponentsInChildren<Graphic>(true);
		foreach (Graphic val in componentsInChildren)
		{
			if (!((Behaviour)val).enabled || (!(val is Image) && !(val is RawImage)))
			{
				continue;
			}
			val.rectTransform.GetWorldCorners(array);
			Vector3 val2 = ((Transform)source).InverseTransformPoint(array[0]);
			Vector3 val3 = ((Transform)source).InverseTransformPoint(array[2]);
			float num = val3.x - val2.x;
			float num2 = val3.y - val2.y;
			if (!(num >= ((Rect)(ref rect)).width * 0.85f) || !(num2 >= ((Rect)(ref rect)).height * 0.8f))
			{
				continue;
			}
			bool flag = false;
			Transform val4 = ((Component)val).transform;
			while ((Object)(object)val4 != (Object)(object)source && (Object)(object)val4 != (Object)null)
			{
				if (!((Component)val4).gameObject.activeSelf)
				{
					flag = true;
					break;
				}
				val4 = val4.parent;
			}
			if (!flag)
			{
				GameObject val5 = new GameObject("Native window " + ((Object)val).name, new Type[1] { typeof(RectTransform) });
				val5.transform.SetParent((Transform)(object)target, false);
				RectTransform component = val5.GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				Vector2 offsetMin = (component.offsetMax = Vector2.zero);
				component.offsetMin = offsetMin;
				Image val6 = (Image)(object)((val is Image) ? val : null);
				Graphic val8;
				if ((Object)(object)val6 != (Object)null)
				{
					Image val7 = val5.AddComponent<Image>();
					Copy(val7, val6);
					val8 = (Graphic)(object)val7;
				}
				else
				{
					RawImage val9 = (RawImage)val;
					RawImage val10 = val5.AddComponent<RawImage>();
					val10.texture = val9.texture;
					val10.uvRect = val9.uvRect;
					((Graphic)val10).material = ((Graphic)val9).material;
					((Graphic)val10).color = ((Graphic)val9).color;
					val8 = (Graphic)(object)val10;
				}
				val8.raycastTarget = false;
			}
		}
	}
}
[HarmonyPatch(typeof(PlanetFactory), "BeforeGameTick")]
internal static class BeforeWorkers
{
	[HarmonyPostfix]
	[HarmonyPriority(0)]
	private static void Postfix(PlanetFactory __instance)
	{
		if ((Object)(object)Plugin.Instance != (Object)null)
		{
			Plugin.Instance.Engine.SyncFactory(__instance);
		}
	}
}
internal static class BatchOutput
{
	internal static bool HasRoom(RecipeExecuteData data, int[] produced)
	{
		int num = BatchEngine.Multiplier(data);
		if (num <= 1 || produced == null)
		{
			return true;
		}
		for (int i = 0; i < produced.Length; i++)
		{
			if (produced[i] + 2L * (long)data.productCounts[i] * num > int.MaxValue)
			{
				return false;
			}
		}
		return true;
	}

	internal static BatchState Begin(RecipeExecuteData data, int[] produced)
	{
		BatchState batchState = BatchEngine.Owner(data);
		if (batchState == null || batchState.Active <= 1 || produced == null)
		{
			return null;
		}
		if (batchState.OutputBefore == null || batchState.OutputBefore.Length != produced.Length)
		{
			batchState.OutputBefore = new int[produced.Length];
		}
		for (int i = 0; i < produced.Length; i++)
		{
			batchState.OutputBefore[i] = produced[i];
			produced[i] /= batchState.Active;
		}
		return batchState;
	}

	internal static void End(BatchState state, RecipeExecuteData data, int[] produced, int[] register)
	{
		if (state == null)
		{
			return;
		}
		int active = state.Active;
		for (int i = 0; i < produced.Length; i++)
		{
			int num = produced[i] - state.OutputBefore[i] / active;
			produced[i] = checked(state.OutputBefore[i] + num * active);
			if (num > 0)
			{
				lock (register)
				{
					register[data.products[i]] = register[data.products[i]] + num * (active - 1);
				}
			}
		}
	}
}
[HarmonyPatch(typeof(AssemblerComponent), "InternalUpdate")]
internal static class AssemblerBatch
{
	[HarmonyPrefix]
	[HarmonyPriority(800)]
	private static bool Prefix(ref AssemblerComponent __instance, out BatchState __state)
	{
		__state = null;
		if (!BatchOutput.HasRoom(__instance.recipeExecuteData, __instance.produced))
		{
			return false;
		}
		__state = BatchOutput.Begin(__instance.recipeExecuteData, __instance.produced);
		return true;
	}

	[HarmonyFinalizer]
	[HarmonyPriority(0)]
	private static Exception Finalizer(ref AssemblerComponent __instance, int[] productRegister, BatchState __state, Exception __exception)
	{
		BatchOutput.End(__state, __instance.recipeExecuteData, __instance.produced, productRegister);
		return __exception;
	}
}
[HarmonyPatch(typeof(LabComponent), "InternalUpdateAssemble")]
internal static class LabBatch
{
	[HarmonyPriority(800)]
	[HarmonyPrefix]
	private static bool Prefix(ref LabComponent __instance, out BatchState __state)
	{
		__state = null;
		if (!BatchOutput.HasRoom(__instance.recipeExecuteData, __instance.produced))
		{
			return false;
		}
		__state = BatchOutput.Begin(__instance.recipeExecuteData, __instance.produced);
		return true;
	}

	[HarmonyFinalizer]
	[HarmonyPriority(0)]
	private static Exception Finalizer(ref LabComponent __instance, int[] productRegister, BatchState __state, Exception __exception)
	{
		BatchOutput.End(__state, __instance.recipeExecuteData, __instance.produced, productRegister);
		return __exception;
	}
}
[HarmonyPatch(typeof(AssemblerComponent), "SetPCState")]
internal static class AssemblerPower
{
	[HarmonyPostfix]
	[HarmonyPriority(0)]
	internal static void Postfix(ref AssemblerComponent __instance, PowerConsumerComponent[] pcPool)
	{
		int num = BatchEngine.Multiplier(__instance.recipeExecuteData);
		int pcId = __instance.pcId;
		if (num > 1 && pcId > 0 && pcId < pcPool.Length)
		{
			pcPool[pcId].requiredEnergy = BatchMath.Energy(pcPool[pcId].requiredEnergy, num);
		}
	}
}
[HarmonyPatch(typeof(LabComponent), "SetPCState")]
internal static class LabPower
{
	[HarmonyPriority(0)]
	[HarmonyPostfix]
	internal static void Postfix(ref LabComponent __instance, PowerConsumerComponent[] pcPool)
	{
		int num = (__instance.researchMode ? 1 : BatchEngine.Multiplier(__instance.recipeExecuteData));
		int pcId = __instance.pcId;
		if (num > 1 && pcId > 0 && pcId < pcPool.Length)
		{
			pcPool[pcId].requiredEnergy = BatchMath.Energy(pcPool[pcId].requiredEnergy, num);
		}
	}
}
[HarmonyPatch(typeof(FactorySystem), "RemoveAssemblerComponent")]
internal static class RemoveAssembler
{
	[HarmonyPrefix]
	private static void Prefix(FactorySystem __instance, int id)
	{
		if ((Object)(object)Plugin.Instance != (Object)null && id > 0 && id < __instance.assemblerPool.Length)
		{
			Plugin.Instance.Engine.Remove(__instance.factory.planetId, __instance.assemblerPool[id].entityId);
		}
	}
}
[HarmonyPatch(typeof(FactorySystem), "RemoveLabComponent")]
internal static class RemoveLab
{
	[HarmonyPrefix]
	private static void Prefix(FactorySystem __instance, int id)
	{
		if ((Object)(object)Plugin.Instance != (Object)null && id > 0 && id < __instance.labPool.Length)
		{
			Plugin.Instance.Engine.Remove(__instance.factory.planetId, __instance.labPool[id].entityId);
		}
	}
}
[HarmonyPatch(typeof(VFInput), "UpdateGameStates")]
internal static class InputGuard
{
	[HarmonyPostfix]
	[HarmonyPriority(0)]
	private static void Postfix()
	{
		if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.Instance.Panel != null && Plugin.Instance.Panel.Blocking)
		{
			VFInput.onGUI = true;
			VFInput.onGUIOperate = true;
			VFInput.inScrollView = true;
			if (Plugin.Instance.Panel.Editing)
			{
				VFInput.inputing = true;
			}
		}
	}
}
[BepInPlugin("LokiMoonLabs.HoneyIShrunkTheFactory", "Honey I Shrunk the Factory", "0.3.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInIncompatibility("com.mandao.CondensedProduction")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class Plugin : BaseUnityPlugin, IModCanSave
{
	public const string Guid = "LokiMoonLabs.HoneyIShrunkTheFactory";

	internal static Plugin Instance;

	internal readonly BatchEngine Engine = new BatchEngine();

	internal FactoryPanel Panel;

	internal ConfigEntry<int> Maximum;

	private Harmony harmony;

	private bool failed;

	private void Awake()
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Expected O, but got Unknown
		Maximum = ((BaseUnityPlugin)this).Config.Bind<int>("Production", "MaximumMultiplier", 1000, new ConfigDescription("Maximum selectable machines per physical building. Existing paid batches retain their size until the recipe is reset. Does not change recipes globally, research speed, storage or belt stacks.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000), new object[0]));
		Instance = this;
		if (Chainloader.PluginInfos.ContainsKey("dsp.nebula-multiplayer"))
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Honey I Shrunk the Factory supports single-player only; disabled while Nebula Multiplayer is loaded.");
			return;
		}
		try
		{
			if (Chainloader.PluginInfos.TryGetValue("com.Valoneu.FactoryOverclock", out var value))
			{
				Type type = ((object)value.Instance).GetType().Assembly.GetType("FactoryOverclock.BeltPatcher");
				MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "GetFractionatorLimit", (Type[])null, (Type[])null));
				if (methodInfo == null)
				{
					throw new InvalidOperationException("FactoryOverclock fractionator adapter could not resolve its throughput limit.");
				}
				Fractionation.CargoLimit = (Func<double>)Delegate.CreateDelegate(typeof(Func<double>), methodInfo);
			}
			harmony = new Harmony("LokiMoonLabs.HoneyIShrunkTheFactory");
			harmony.PatchAll(typeof(Plugin).Assembly);
			Panel = new FactoryPanel(this);
		}
		catch (Exception ex)
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			((BaseUnityPlugin)this).Logger.LogError((object)("Batch support could not be enabled: " + ex));
			return;
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Honey I Shrunk the Factory 0.3.0 ready. Per-building batch production only; no wireless, storage or belt changes.");
	}

	private void LateUpdate()
	{
		if (Panel == null || failed)
		{
			return;
		}
		try
		{
			Panel.Update();
		}
		catch (Exception ex)
		{
			failed = true;
			Panel.Dispose();
			((BaseUnityPlugin)this).Logger.LogError((object)("Factory panel disabled: " + ex));
		}
	}

	public void Export(BinaryWriter w)
	{
		Engine.Export(w);
	}

	public void Import(BinaryReader r)
	{
		Engine.Import(r);
	}

	public void IntoOtherSave()
	{
		Engine.Clear();
	}

	private void OnDestroy()
	{
		if (Panel != null)
		{
			Panel.Dispose();
		}
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}
}
internal sealed class PresetMenu
{
	internal static readonly int[] Values = new int[22]
	{
		1, 5, 10, 15, 20, 30, 40, 50, 60, 70,
		80, 90, 100, 200, 300, 400, 500, 600, 700, 800,
		900, 1000
	};

	private readonly RectTransform header;

	private readonly RectTransform popup;

	private readonly GameObject dismiss;

	private readonly Text caption;

	private readonly float width;

	private readonly Button[] choices;

	private readonly Vector3[] corners;

	private int lastMaximum;

	private int closedThrough;

	internal bool Blocking
	{
		get
		{
			if (!((Component)popup).gameObject.activeSelf)
			{
				return Time.frameCount <= closedThrough;
			}
			return true;
		}
	}

	private static RectTransform Rect(Transform parent, string name, float width, float height)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: 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)
		GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent, false);
		RectTransform component = val.GetComponent<RectTransform>();
		Vector2 val2 = (component.pivot = new Vector2(0f, 1f));
		Vector2 anchorMin = (component.anchorMax = val2);
		component.anchorMin = anchorMin;
		component.sizeDelta = new Vector2(width, height);
		return component;
	}

	private static Image Face(RectTransform rect)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		Image val = ((Component)rect).gameObject.AddComponent<Image>();
		((Graphic)val).color = new Color(0.1f, 0.21f, 0.26f, 1f);
		return val;
	}

	private static Text Label(RectTransform parent, Font font, string text)
	{
		//IL_0007: 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)
		//IL_0033: 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)
		RectTransform val = Rect((Transform)(object)parent, "Caption", parent.sizeDelta.x - 20f, parent.sizeDelta.y);
		val.anchoredPosition = new Vector2(8f, 0f);
		Text val2 = ((Component)val).gameObject.AddComponent<Text>();
		val2.font = font;
		val2.fontSize = 14;
		val2.text = text;
		((Graphic)val2).color = Color.white;
		val2.alignment = (TextAnchor)3;
		((Graphic)val2).raycastTarget = false;
		val2.verticalOverflow = (VerticalWrapMode)1;
		return val2;
	}

	internal PresetMenu(RectTransform panel, Transform canvas, Font font, NativeSkin skin, Action<int> choose)
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Expected O, but got Unknown
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Expected O, but got Unknown
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0330: 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_0135: Expected O, but got Unknown
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0436: Unknown result type (might be due to invalid IL or missing references)
		//IL_0440: Expected O, but got Unknown
		UnityAction val = null;
		choices = (Button[])(object)new Button[Values.Length];
		corners = (Vector3[])(object)new Vector3[4];
		lastMaximum = -1;
		closedThrough = -1;
		base..ctor();
		PresetMenu presetMenu = this;
		Rect rect = panel.rect;
		width = ((Rect)(ref rect)).width - 80f;
		header = Rect((Transform)(object)panel, "Multiplier presets", width, 30f);
		header.anchoredPosition = new Vector2(40f, -206f);
		Button val2 = ((Component)header).gameObject.AddComponent<Button>();
		((Selectable)val2).targetGraphic = (Graphic)(object)Face(header);
		skin.Input((Image)((Selectable)val2).targetGraphic);
		caption = Label(header, font, "Preset: 1x");
		((Graphic)caption).rectTransform.sizeDelta = new Vector2(width - 40f, 30f);
		skin.Arrow(header, font);
		ButtonClickedEvent onClick = val2.onClick;
		if (val == null)
		{
			val = (UnityAction)delegate
			{
				if (((Component)popup).gameObject.activeSelf)
				{
					Close();
				}
				else
				{
					Open();
				}
			};
		}
		((UnityEvent)onClick).AddListener(val);
		RectTransform val3 = Rect(canvas, "Dismiss multiplier presets", 0f, 0f);
		val3.anchorMin = Vector2.zero;
		val3.anchorMax = Vector2.one;
		val3.offsetMin = (val3.offsetMax = Vector2.zero);
		Image val4 = ((Component)val3).gameObject.AddComponent<Image>();
		((Graphic)val4).color = Color.clear;
		Button val5 = ((Component)val3).gameObject.AddComponent<Button>();
		((Selectable)val5).targetGraphic = (Graphic)(object)val4;
		((UnityEvent)val5.onClick).AddListener(new UnityAction(Close));
		dismiss = ((Component)val3).gameObject;
		dismiss.SetActive(false);
		popup = Rect(canvas, "Multiplier preset list", width, 194f);
		skin.Popup(Face(popup));
		RectTransform val6 = Rect((Transform)(object)popup, "Viewport", width - 12f, 192f);
		val6.anchoredPosition = new Vector2(1f, -1f);
		((Component)val6).gameObject.AddComponent<RectMask2D>();
		RectTransform val7 = Rect((Transform)(object)val6, "Options", width - 12f, Values.Length * 24);
		ScrollRect val8 = ((Component)popup).gameObject.AddComponent<ScrollRect>();
		val8.viewport = val6;
		val8.content = val7;
		val8.horizontal = false;
		val8.vertical = true;
		val8.movementType = (MovementType)2;
		val8.scrollSensitivity = 24f;
		RectTransform val9 = Rect((Transform)(object)popup, "Scrollbar", 8f, 192f);
		val9.anchoredPosition = new Vector2(width - 9f, -1f);
		Face(val9);
		RectTransform val10 = Rect((Transform)(object)val9, "Handle", 8f, 30f);
		Image val11 = Face(val10);
		((Graphic)val11).color = new Color(0.44f, 0.76f, 0.83f, 1f);
		Scrollbar val12 = ((Component)val9).gameObject.AddComponent<Scrollbar>();
		val12.handleRect = val10;
		((Selectable)val12).targetGraphic = (Graphic)(object)val11;
		val12.direction = (Direction)2;
		val8.verticalScrollbar = val12;
		skin.Scrollbar(val12);
		for (int num = 0; num < Values.Length; num++)
		{
			int value = Values[num];
			RectTransform val13 = Rect((Transform)(object)val7, value + "x", width - 12f, 24f);
			val13.anchoredPosition = new Vector2(0f, (float)(-num * 24));
			Button val14 = ((Component)val13).gameObject.AddComponent<Button>();
			((Selectable)val14).targetGraphic = (Graphic)(object)Face(val13);
			skin.Option(val14);
			Label(val13, font, value + "x");
			((UnityEvent)val14.onClick).AddListener((UnityAction)delegate
			{
				choose(value);
				presetMenu.Close();
			});
			choices[num] = val14;
		}
		((Component)popup).gameObject.SetActive(false);
	}

	internal void Update(float scale, int maximum, string amount)
	{
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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)
		caption.text = "Preset: " + amount + "x";
		if (lastMaximum != maximum)
		{
			lastMaximum = maximum;
			for (int i = 0; i < choices.Length; i++)
			{
				((Selectable)choices[i]).interactable = Values[i] <= maximum;
				((Graphic)((Component)choices[i]).GetComponentInChildren<Text>()).color = ((Values[i] <= maximum) ? Color.white : Color.gray);
			}
		}
		if (((Component)popup).gameObject.activeSelf)
		{
			header.GetWorldCorners(corners);
			float num = corners[0].x / scale;
			float num2 = ((float)Screen.height - corners[0].y) / scale + 3f;
			if (num2 + 194f > (float)Screen.height / scale)
			{
				num2 = ((float)Screen.height - corners[1].y) / scale - 197f;
			}
			popup.anchoredPosition = new Vector2(Mathf.Clamp(num, 0f, Mathf.Max(0f, (float)Screen.width / scale - width)), 0f - Mathf.Clamp(num2, 0f, Mathf.Max(0f, (float)Screen.height / scale - 194f)));
			if (Input.GetKeyDown((KeyCode)27))
			{
				Close();
			}
		}
	}

	private void Open()
	{
		dismiss.SetActive(true);
		dismiss.transform.SetAsLastSibling();
		((Component)popup).gameObject.SetActive(true);
		((Transform)popup).SetAsLastSibling();
	}

	internal void Close()
	{
		if (((Component)popup).gameObject.activeSelf)
		{
			closedThrough = Time.frameCount + 1;
		}
		((Component)popup).gameObject.SetActive(false);
		dismiss.SetActive(false);
	}
}