Decompiled source of PowerSystemTweak v1.0.2

PowerSystemTweak.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using PowerNetworkStructures;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PowerSystemTweek")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PowerSystemTweek")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a740d6f5-e052-4cd3-8bf3-c92ab775dac4")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace PowerSystemTweek;

[BepInPlugin("cn.chewei.dsp.power_system_tweak", "PowerSystemTweek", "1.0.0")]
[BepInProcess("DSPGAME.exe")]
public class PowerSystemTweakPlugin : BaseUnityPlugin
{
	public const string GUID = "cn.chewei.dsp.power_system_tweak";

	public const string NAME = "PowerSystemTweek";

	public const string VERSION = "1.0.0";

	public const string GAME_PROCESS = "DSPGAME.exe";

	private static ManualLogSource BepInLogger;

	private ConfigEntry<bool> configPreferCleanEnergyGenerator;

	private ConfigEntry<int> configExcDischargeEqualFuelGenerator;

	private double nextLogTime = Time.time;

	private bool showDebugUI;

	private StringBuilder debugLog = new StringBuilder(2048);

	public List<int> ListExecutionTimeIndex = new List<int>(512);

	public List<double> ListExecutionTime = new List<double>(512);

	public double ExecTimeMin;

	public double ExecTimeMax;

	public double ExecTimeMedian;

	public double ExecTimeAverage;

	public void Start()
	{
		BepInLogger = ((BaseUnityPlugin)this).Logger;
		((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
		configPreferCleanEnergyGenerator = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PreferCleanEnergyGenerator", true, "Whether enables the patch to use energy from clean energy generators before using energy generated by fuel");
		configExcDischargeEqualFuelGenerator = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ExcDischargeEqualFuelGenerator", 0, "0:Exchangers discharge as fuel generators, 1: Echangers will discharge first to save fuel, 2: Echangers will discharge last as backup energy");
		PowerSystemPatch.PowerSystemGameTickPatch = configPreferCleanEnergyGenerator.Value;
		if (configExcDischargeEqualFuelGenerator.Value >= 0 && configExcDischargeEqualFuelGenerator.Value < 3)
		{
			PowerSystemPatch.ExchangerDischargeStrategy = (EExchangerDischargeStrategy)configExcDischargeEqualFuelGenerator.Value;
		}
		if (!CheckMethodPatchInfo(typeof(PowerSystem), "GameTick"))
		{
			PowerSystemPatch.InitStopWatch();
			Harmony.CreateAndPatchAll(typeof(PowerSystemPatch), (string)null);
		}
		else
		{
			BepInLogger.LogInfo((object)"Give up Patch to avoid conflict");
		}
	}

	public void Update()
	{
		if (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305))
		{
			if (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303))
			{
				if (Input.GetKeyUp((KeyCode)121))
				{
					PowerSystemPatch.ExchangerDischargeStrategy = (EExchangerDischargeStrategy)((int)(PowerSystemPatch.ExchangerDischargeStrategy + 1) % 3);
					switch (PowerSystemPatch.ExchangerDischargeStrategy)
					{
					case EExchangerDischargeStrategy.EQUAL_AS_FUEL_GENERATOR:
						UIRealtimeTip.Popup("Exchangers discharge as fuel generator", true, 0);
						break;
					case EExchangerDischargeStrategy.DISCHARGE_FIRST:
						UIRealtimeTip.Popup("Exchangers discharge BEFORE fuel generator", true, 0);
						break;
					case EExchangerDischargeStrategy.DISCHARGE_LAST:
						UIRealtimeTip.Popup("Exchangers discharge AFTER fuel generator", true, 0);
						break;
					}
					configExcDischargeEqualFuelGenerator.Value = (int)PowerSystemPatch.ExchangerDischargeStrategy;
				}
			}
			else
			{
				if (Input.GetKeyUp((KeyCode)121))
				{
					PowerSystemPatch.PowerSystemGameTickPatch = !PowerSystemPatch.PowerSystemGameTickPatch;
					configPreferCleanEnergyGenerator.Value = PowerSystemPatch.PowerSystemGameTickPatch;
					UIRealtimeTip.Popup(PowerSystemPatch.PowerSystemGameTickPatch ? "PowerSystemTweak Enabled" : "PowerSystemTweak Disabled", true, 0);
				}
				if (Input.GetKeyUp((KeyCode)117))
				{
					showDebugUI = !showDebugUI;
				}
			}
		}
		if (showDebugUI)
		{
			UpdateExecTimeStat();
		}
	}

	public void OnGUI()
	{
		//IL_002b: 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_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		if (showDebugUI)
		{
			GUILayout.BeginArea(new Rect((float)Screen.width * 0.7f, 0f, (float)Screen.width * 0.3f, (float)Screen.height));
			GUILayout.Label(debugLog.ToString(), new GUIStyle(GUI.skin.label)
			{
				fontSize = 24
			}, Array.Empty<GUILayoutOption>());
			GUILayout.EndArea();
		}
	}

	private void UpdateExecTimeStat()
	{
		if (!GameMain.isRunning || !((double)Time.time > nextLogTime) || DSPGame.IsMenuDemo)
		{
			return;
		}
		nextLogTime = (double)Time.time + 1.0;
		ListExecutionTimeIndex.Clear();
		ListExecutionTime.Clear();
		for (int i = 0; i < GameMain.data.factoryCount; i++)
		{
			if (GameMain.data.factories[i] != null)
			{
				ListExecutionTimeIndex.Add(i);
				ListExecutionTime.Add(PowerSystemPatch.ExecuteTime[i]);
			}
		}
		ListExecutionTimeIndex.Sort((int a, int b) => Math.Sign(PowerSystemPatch.ExecuteTime[b] - PowerSystemPatch.ExecuteTime[a]));
		ListExecutionTime.Sort();
		debugLog.Clear();
		if (GameMain.localPlanet != null)
		{
			int factoryIndex = GameMain.localPlanet.factoryIndex;
			string displayName = GameMain.data.factories[factoryIndex].planet.displayName;
			PlanetFactory val = GameMain.data.factories[factoryIndex];
			debugLog.AppendFormat("Local System:{0} {1} Time:{2:N3}ms Weight{3}", factoryIndex, displayName, 1000.0 * PowerSystemPatch.ExecuteTime[factoryIndex], val.powerSystem.GetPowerSystemWeight()).AppendLine();
		}
		for (int j = 0; j < 10 && j < GameMain.data.factoryCount; j++)
		{
			string displayName2 = GameMain.data.factories[ListExecutionTimeIndex[j]].planet.displayName;
			PlanetFactory val2 = GameMain.data.factories[ListExecutionTimeIndex[j]];
			debugLog.AppendFormat("Factory Index:{0} {1} Time:{2:N3}ms Weight{3}", ListExecutionTimeIndex[j], displayName2, 1000.0 * PowerSystemPatch.ExecuteTime[ListExecutionTimeIndex[j]], val2.powerSystem.GetPowerSystemWeight()).AppendLine();
		}
		debugLog.AppendFormat("Min {0:N3}ms, Max{1:N3}ms, Avg{2:N3}ms, Median{3:N3}ms", ListExecutionTime.Min() * 1000.0, ListExecutionTime.Max() * 1000.0, ListExecutionTime.Average() * 1000.0, ListExecutionTime[ListExecutionTime.Count / 2] * 1000.0).AppendLine();
	}

	private static bool CheckMethodPatchInfo(Type typeClass, string MethodName)
	{
		Patches patchInfo = Harmony.GetPatchInfo((MethodBase)typeClass.GetMethod(MethodName));
		if (patchInfo == null)
		{
			return false;
		}
		BepInLogger.LogInfo((object)("all owners: " + patchInfo.Owners));
		foreach (Patch prefix in patchInfo.Prefixes)
		{
			ManualLogSource bepInLogger = BepInLogger;
			int index = prefix.index;
			bepInLogger.LogInfo((object)("index: " + index));
			BepInLogger.LogInfo((object)("owner: " + prefix.owner));
			BepInLogger.LogInfo((object)("patch method: " + prefix.PatchMethod));
			ManualLogSource bepInLogger2 = BepInLogger;
			index = prefix.priority;
			bepInLogger2.LogInfo((object)("priority: " + index));
			BepInLogger.LogInfo((object)("before: " + prefix.before));
			BepInLogger.LogInfo((object)("after: " + prefix.after));
		}
		return true;
	}
}
public enum EExchangerDischargeStrategy
{
	EQUAL_AS_FUEL_GENERATOR,
	DISCHARGE_FIRST,
	DISCHARGE_LAST
}
public class PowerSystemPatch
{
	public static EExchangerDischargeStrategy ExchangerDischargeStrategy = EExchangerDischargeStrategy.EQUAL_AS_FUEL_GENERATOR;

	public static bool PowerSystemGameTickPatch = true;

	public static double[] ExecuteTime = new double[512];

	public static List<HighStopwatch> StopWatchList = new List<HighStopwatch>(512);

	public static void InitStopWatch()
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		for (int i = 0; i < 512; i++)
		{
			StopWatchList.Add(new HighStopwatch());
		}
	}

	public static void SetExchangerDischargePriority(EExchangerDischargeStrategy strategy)
	{
		ExchangerDischargeStrategy = strategy;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(PowerSystem), "CalculatePowerSystemWeight")]
	private static bool CalculatePowerSystemWeightPrefix(PowerSystem __instance, ref int ___totalPowerSystemWeight)
	{
		if (!PowerSystemGameTickPatch)
		{
			return true;
		}
		___totalPowerSystemWeight = 10 + (int)(100000000.0 * ExecuteTime[__instance.planet.factoryIndex]);
		return false;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(PowerSystem), "GameTick")]
	private static bool GameTickPrefixExperimental(PowerSystem __instance, DysonSphere ___dysonSphere, long time, bool isActive, bool isMultithreadMode = false)
	{
		//IL_0093: 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_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: 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_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: 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_02f2: Invalid comparison between Unknown and I4
		//IL_0443: Unknown result type (might be due to invalid IL or missing references)
		//IL_0469: Unknown result type (might be due to invalid IL or missing references)
		//IL_0490: Unknown result type (might be due to invalid IL or missing references)
		//IL_0991: Unknown result type (might be due to invalid IL or missing references)
		//IL_0998: Unknown result type (might be due to invalid IL or missing references)
		//IL_099f: Unknown result type (might be due to invalid IL or missing references)
		if (!PowerSystemGameTickPatch)
		{
			return true;
		}
		StopWatchList[__instance.factory.index].Begin();
		FactoryProductionStat val = GameMain.statistics.production.factoryStatPool[__instance.factory.index];
		int[] productRegister = val.productRegister;
		int[] consumeRegister = val.consumeRegister;
		long num = 0L;
		long num2 = 0L;
		long num3 = 0L;
		long num4 = 0L;
		long num5 = 0L;
		float num6 = 1f / 60f;
		PlanetData planet = __instance.factory.planet;
		float windStrength = planet.windStrength;
		float luminosity = planet.luminosity;
		Vector3 normalized = ((Vector3)(ref planet.runtimeLocalSunDirection)).normalized;
		AnimData[] entityAnimPool = __instance.factory.entityAnimPool;
		SignData[] entitySignPool = __instance.factory.entitySignPool;
		if (__instance.networkServes == null || __instance.networkServes.Length != __instance.netPool.Length)
		{
			__instance.networkServes = new float[__instance.netPool.Length];
		}
		if (__instance.networkGenerates == null || __instance.networkGenerates.Length != __instance.netPool.Length)
		{
			__instance.networkGenerates = new float[__instance.netPool.Length];
		}
		bool useIonLayer = GameMain.history.useIonLayer;
		bool flag = time % 10 == 0;
		Array.Clear(__instance.currentGeneratorCapacities, 0, __instance.currentGeneratorCapacities.Length);
		Player mainPlayer = GameMain.mainPlayer;
		_ = Vector3.zero;
		Vector3 val2 = Vector3.zero;
		float num7 = 0f;
		bool flag2;
		if (mainPlayer.mecha.coreEnergyCap - mainPlayer.mecha.coreEnergy > 0.0 && mainPlayer.isAlive && mainPlayer.planetId == planet.id)
		{
			float num8 = __instance.factory.planet.realRadius + 0.2f;
			Vector3 val3 = (isMultithreadMode ? __instance.multithreadPlayerPos : mainPlayer.position);
			float magnitude = ((Vector3)(ref val3)).magnitude;
			if ((double)magnitude > 0.0)
			{
				val2 = val3 * (num8 / magnitude);
			}
			flag2 = (double)magnitude > (double)num8 - 30.0 && (double)magnitude < (double)num8 + 50.0;
		}
		else
		{
			flag2 = false;
		}
		lock (mainPlayer.mecha)
		{
			num7 = Mathf.Pow(Mathf.Clamp01((float)(1.0 - mainPlayer.mecha.coreEnergy / mainPlayer.mecha.coreEnergyCap) * 10f), 0.75f);
		}
		float num9 = ((___dysonSphere != null) ? ___dysonSphere.energyRespCoef : 0f);
		int num10 = (int)(Math.Min(Math.Abs(__instance.factory.planet.rotationPeriod), Math.Abs(__instance.factory.planet.orbitalPeriod)) * 60.0 / 2160.0);
		if (num10 < 1)
		{
			num10 = 1;
		}
		else if (num10 > 60)
		{
			num10 = 60;
		}
		if ((int)__instance.factory.planet.singularity == 1)
		{
			num10 = 60;
		}
		bool flag3 = time % num10 == 0L || GameMain.onceGameTick <= 2;
		int num11 = (int)(time % 90);
		EntityData[] entityPool = __instance.factory.entityPool;
		for (int i = 1; i < __instance.netCursor; i++)
		{
			PowerNetwork val4 = __instance.netPool[i];
			if (val4 == null || val4.id != i)
			{
				continue;
			}
			List<int> consumers = val4.consumers;
			int count = consumers.Count;
			long num12 = 0L;
			for (int j = 0; j < count; j++)
			{
				long requiredEnergy = __instance.consumerPool[consumers[j]].requiredEnergy;
				num12 += requiredEnergy;
				num2 += requiredEnergy;
			}
			foreach (Node node in val4.nodes)
			{
				int id = node.id;
				if (__instance.nodePool[id].id != id || !__instance.nodePool[id].isCharger)
				{
					continue;
				}
				if ((double)__instance.nodePool[id].coverRadius <= 20.0)
				{
					double num13 = 0.0;
					if (flag2)
					{
						double num14 = (double)__instance.nodePool[id].powerPoint.x * 0.9879999756813049 - (double)val2.x;
						float num15 = __instance.nodePool[id].powerPoint.y * 0.988f - val2.y;
						float num16 = __instance.nodePool[id].powerPoint.z * 0.988f - val2.z;
						float num17 = __instance.nodePool[id].coverRadius;
						if ((double)num17 < 9.0)
						{
							num17 += 2.01f;
						}
						else if ((double)num17 > 20.0)
						{
							num17 += 0.5f;
						}
						float num18 = (float)(num14 * num14 + (double)num15 * (double)num15 + (double)num16 * (double)num16);
						float num19 = num17 * num17;
						if ((double)num18 <= (double)num19)
						{
							double consumerRatio = val4.consumerRatio;
							float num20 = (float)(((double)num19 - (double)num18) / (3.0 * (double)num17));
							if ((double)num20 > 1.0)
							{
								num20 = 1f;
							}
							num13 = (double)num7 * consumerRatio * consumerRatio * (double)num20;
						}
					}
					double num21 = (double)__instance.nodePool[id].idleEnergyPerTick * (1.0 - num13) + (double)__instance.nodePool[id].workEnergyPerTick * num13;
					if (__instance.nodePool[id].requiredEnergy < __instance.nodePool[id].idleEnergyPerTick)
					{
						__instance.nodePool[id].requiredEnergy = __instance.nodePool[id].idleEnergyPerTick;
					}
					if ((double)__instance.nodePool[id].requiredEnergy < num21 - 0.01)
					{
						double num22 = num21 * 0.02 + (double)__instance.nodePool[id].requiredEnergy * 0.98;
						__instance.nodePool[id].requiredEnergy = (int)(num22 + 0.9999);
					}
					else if ((double)__instance.nodePool[id].requiredEnergy > num21 + 0.01)
					{
						double num23 = num21 * 0.2 + (double)__instance.nodePool[id].requiredEnergy * 0.8;
						__instance.nodePool[id].requiredEnergy = (int)num23;
					}
				}
				else
				{
					__instance.nodePool[id].requiredEnergy = __instance.nodePool[id].idleEnergyPerTick;
				}
				long num24 = __instance.nodePool[id].requiredEnergy;
				num12 += num24;
				num2 += num24;
			}
			long num25 = 0L;
			List<int> exchangers = val4.exchangers;
			int count2 = exchangers.Count;
			long num26 = 0L;
			long num27 = 0L;
			long num28 = 0L;
			long num29 = 0L;
			for (int k = 0; k < count2; k++)
			{
				int num30 = exchangers[k];
				((PowerExchangerComponent)(ref __instance.excPool[num30])).StateUpdate();
				((PowerExchangerComponent)(ref __instance.excPool[num30])).BeltUpdate(__instance.factory);
				bool flag4 = (double)__instance.excPool[num30].state >= 1.0;
				bool flag5 = (double)__instance.excPool[num30].state <= -1.0;
				if (!flag4 && !flag5)
				{
					__instance.excPool[num30].capsCurrentTick = 0L;
					__instance.excPool[num30].currEnergyPerTick = 0L;
				}
				int entityId = __instance.excPool[num30].entityId;
				float num31 = (float)(((double)__instance.excPool[num30].state + 1.0) * (double)entityAnimPool[entityId].working_length * 0.5);
				if ((double)num31 >= 3.990000009536743)
				{
					num31 = 3.99f;
				}
				entityAnimPool[entityId].time = num31;
				entityAnimPool[entityId].state = 0u;
				entityAnimPool[entityId].power = (float)__instance.excPool[num30].currPoolEnergy / (float)__instance.excPool[num30].maxPoolEnergy;
				if (flag5)
				{
					long num32 = ((PowerExchangerComponent)(ref __instance.excPool[num30])).OutputCaps();
					num28 += num32;
					num25 = num28;
					__instance.currentGeneratorCapacities[__instance.excPool[num30].subId] += num32;
				}
				else if (flag4)
				{
					num29 += ((PowerExchangerComponent)(ref __instance.excPool[num30])).InputCaps();
				}
			}
			long num33 = 0L;
			List<int> generators = val4.generators;
			int count3 = generators.Count;
			for (int l = 0; l < count3; l++)
			{
				int num34 = generators[l];
				long num35;
				if (__instance.genPool[num34].wind)
				{
					num35 = ((PowerGeneratorComponent)(ref __instance.genPool[num34])).EnergyCap_Wind(windStrength);
					num25 += num35;
					num33 += num35;
				}
				else if (__instance.genPool[num34].photovoltaic)
				{
					if (flag3)
					{
						num35 = ((PowerGeneratorComponent)(ref __instance.genPool[num34])).EnergyCap_PV(normalized.x, normalized.y, normalized.z, luminosity);
						num25 += num35;
					}
					else
					{
						num35 = __instance.genPool[num34].capacityCurrentTick;
						num25 += num35;
					}
					num33 += num35;
				}
				else if (__instance.genPool[num34].gamma)
				{
					num35 = ((PowerGeneratorComponent)(ref __instance.genPool[num34])).EnergyCap_Gamma(num9);
					num25 += num35;
					num33 += num35;
				}
				else if (__instance.genPool[num34].geothermal)
				{
					num35 = ((PowerGeneratorComponent)(ref __instance.genPool[num34])).EnergyCap_GTH();
					num25 += num35;
					num33 += num35;
				}
				else
				{
					num35 = ((PowerGeneratorComponent)(ref __instance.genPool[num34])).EnergyCap_Fuel();
					num25 += num35;
					entitySignPool[__instance.genPool[num34].entityId].signType = ((num35 <= 30) ? 8u : 0u);
				}
				__instance.currentGeneratorCapacities[__instance.genPool[num34].subId] += num35;
			}
			num += num25 - num28;
			long num36 = num25 - num12;
			long num37 = 0L;
			if (num36 > 0 && val4.exportDemandRatio > 0.0)
			{
				if (val4.exportDemandRatio > 1.0)
				{
					val4.exportDemandRatio = 1.0;
				}
				num37 = (long)((double)num36 * val4.exportDemandRatio + 0.5);
				num36 -= num37;
				num12 += num37;
			}
			val4.exportDemandRatio = 0.0;
			val4.energyStored = 0L;
			List<int> accumulators = val4.accumulators;
			int count4 = accumulators.Count;
			long num38 = 0L;
			long num39 = 0L;
			if (num36 >= 0)
			{
				for (int m = 0; m < count4; m++)
				{
					int num40 = accumulators[m];
					__instance.accPool[num40].curPower = 0L;
					long num41 = ((PowerAccumulatorComponent)(ref __instance.accPool[num40])).InputCap();
					if (num41 > 0)
					{
						long num42 = ((num41 < num36) ? num41 : num36);
						__instance.accPool[num40].curEnergy += num42;
						__instance.accPool[num40].curPower = num42;
						num36 -= num42;
						num38 += num42;
						num4 += num42;
					}
					val4.energyStored += __instance.accPool[num40].curEnergy;
					int entityId2 = __instance.accPool[num40].entityId;
					entityAnimPool[entityId2].state = ((__instance.accPool[num40].curEnergy > 0) ? 1u : 0u);
					entityAnimPool[entityId2].power = (float)__instance.accPool[num40].curEnergy / (float)__instance.accPool[num40].maxEnergy;
				}
			}
			else
			{
				long num43 = -num36;
				for (int n = 0; n < count4; n++)
				{
					int num44 = accumulators[n];
					__instance.accPool[num44].curPower = 0L;
					long num45 = ((PowerAccumulatorComponent)(ref __instance.accPool[num44])).OutputCap();
					if (num45 > 0)
					{
						long num46 = ((num45 < num43) ? num45 : num43);
						__instance.accPool[num44].curEnergy -= num46;
						__instance.accPool[num44].curPower = -num46;
						num43 -= num46;
						num39 += num46;
						num3 += num46;
					}
					val4.energyStored += __instance.accPool[num44].curEnergy;
					int entityId3 = __instance.accPool[num44].entityId;
					entityAnimPool[entityId3].state = ((__instance.accPool[num44].curEnergy > 0) ? 2u : 0u);
					entityAnimPool[entityId3].power = (float)__instance.accPool[num44].curEnergy / (float)__instance.accPool[num44].maxEnergy;
				}
			}
			num36 -= num28;
			num36 = ((num36 > 0) ? num36 : 0);
			double num47 = ((num36 < num29) ? ((double)num36 / (double)num29) : 1.0);
			for (int num48 = 0; num48 < count2; num48++)
			{
				int num49 = exchangers[num48];
				if ((double)__instance.excPool[num49].state >= 1.0 && num47 >= 0.0)
				{
					long num50 = (long)(num47 * (double)__instance.excPool[num49].capsCurrentTick + 0.99999);
					long num51 = ((num36 < num50) ? num36 : num50);
					long num52 = ((PowerExchangerComponent)(ref __instance.excPool[num49])).InputUpdate(num51, entityAnimPool, productRegister, consumeRegister);
					num36 -= num52;
					num26 += num52;
					num4 += num52;
				}
				else
				{
					__instance.excPool[num49].currEnergyPerTick = 0L;
				}
			}
			long num53 = ((num25 < num12 + num26) ? (num25 + num38 + num26) : (num12 + num38 + num26));
			double num54 = CalculateDischargeRatio(num25, num28, num33, num53);
			for (int num55 = 0; num55 < count2; num55++)
			{
				int num56 = exchangers[num55];
				if ((double)__instance.excPool[num56].state <= -1.0)
				{
					long num57 = (long)(num54 * (double)__instance.excPool[num56].capsCurrentTick + 0.99999);
					long num58 = ((num53 < num57) ? num53 : num57);
					long num59 = ((PowerExchangerComponent)(ref __instance.excPool[num56])).OutputUpdate(num58, entityAnimPool, productRegister, consumeRegister);
					num27 += num59;
					num3 += num59;
					num53 -= num59;
				}
			}
			val4.energyCapacity = num25 - num28;
			val4.energyRequired = num12 - num37;
			val4.energyExport = num37;
			val4.energyServed = ((num25 + num39 < num12) ? (num25 + num39) : num12);
			val4.energyAccumulated = num38 - num39;
			val4.energyExchanged = num26 - num27;
			val4.energyExchangedInputTotal = num26;
			val4.energyExchangedOutputTotal = num27;
			if (num37 > 0)
			{
				PlanetATField planetATField = __instance.factory.planetATField;
				planetATField.energy += num37;
				planetATField.atFieldRechargeCurrent = num37 * 60;
			}
			long num60 = num25 + num39;
			long num61 = num12 + num38;
			num5 += ((num60 >= num61) ? (num2 + num37) : num60);
			long num62 = ((num27 - num61 > 0) ? (num27 - num61) : 0);
			double num63 = ((num60 >= num61) ? 1.0 : ((double)num60 / (double)num61));
			long num64 = num61 + (num26 - num62);
			long num65 = num60 - num27;
			double num66 = ((num65 > num64) ? ((double)num64 / (double)num65) : 1.0);
			val4.consumerRatio = num63;
			val4.generaterRatio = num66;
			float num67 = ((num65 > 0 || val4.energyStored > 0 || num27 > 0) ? ((float)num63) : 0f);
			float num68 = ((num65 > 0 || val4.energyStored > 0 || num27 > 0) ? ((float)num66) : 0f);
			__instance.networkServes[i] = num67;
			__instance.networkGenerates[i] = num68;
			CalculateGeneratorLoadRatio(val4, num33, num53, out var generatorRatioClean, out var generatorRatioFuel);
			for (int num69 = 0; num69 < count3; num69++)
			{
				int num70 = generators[num69];
				long num71 = 0L;
				float num72 = 1f;
				bool flag6 = !__instance.genPool[num70].wind && !__instance.genPool[num70].photovoltaic && !__instance.genPool[num70].gamma && !__instance.genPool[num70].geothermal;
				if (flag6)
				{
					__instance.genPool[num70].currentStrength = ((num53 <= 0 || __instance.genPool[num70].capacityCurrentTick <= 0) ? 0f : 1f);
				}
				if (num53 > 0 && __instance.genPool[num70].productId == 0)
				{
					long num73 = (long)((flag6 ? generatorRatioFuel : generatorRatioClean) * (double)__instance.genPool[num70].capacityCurrentTick + 0.99999);
					num71 = ((num53 < num73) ? num53 : num73);
					if (num71 > 0)
					{
						num53 -= num71;
						if (flag6)
						{
							((PowerGeneratorComponent)(ref __instance.genPool[num70])).GenEnergyByFuel(num71, consumeRegister);
							num72 = 2f;
						}
					}
				}
				__instance.genPool[num70].generateCurrentTick = num71;
				int entityId4 = __instance.genPool[num70].entityId;
				if (__instance.genPool[num70].wind)
				{
					float num74 = 0.7f;
					((AnimData)(ref entityAnimPool[entityId4])).Step2(((double)entityAnimPool[entityId4].power > 0.10000000149011612 || num71 > 0) ? 1u : 0u, num6, windStrength, num74);
				}
				else if (__instance.genPool[num70].gamma)
				{
					bool flag7 = (num70 + num11) % 90 == 0;
					((PowerGeneratorComponent)(ref __instance.genPool[num70])).GameTick_Gamma(useIonLayer, flag, flag7, __instance.factory, productRegister, consumeRegister);
					entityAnimPool[entityId4].time += num6;
					if ((double)entityAnimPool[entityId4].time > 1.0)
					{
						entityAnimPool[entityId4].time -= 1f;
					}
					entityAnimPool[entityId4].power = (float)__instance.genPool[num70].capacityCurrentTick / (float)__instance.genPool[num70].genEnergyPerTick;
					entityAnimPool[entityId4].state = (uint)((__instance.genPool[num70].productId > 0) ? 2 : 0) + ((__instance.genPool[num70].catalystPoint > 0) ? 1u : 0u);
					entityAnimPool[entityId4].working_length = (float)((double)entityAnimPool[entityId4].working_length * 0.9900000095367432 + ((__instance.genPool[num70].catalystPoint > 0) ? 0.009999999776482582 : 0.0));
					if (isActive)
					{
						entitySignPool[entityId4].signType = ((!((double)__instance.genPool[num70].productCount < 20.0)) ? 6u : 0u);
					}
				}
				else if (__instance.genPool[num70].fuelMask > 1)
				{
					float num75 = (float)((double)entityAnimPool[entityId4].power * 0.98 + 0.02 * ((num71 > 0) ? 1.0 : 0.0));
					if (num71 > 0 && (double)num75 < 0.0)
					{
						num75 = 0f;
					}
					((AnimData)(ref entityAnimPool[entityId4])).Step2(((double)entityAnimPool[entityId4].power > 0.10000000149011612 || num71 > 0) ? 1u : 0u, num6, num75, num72);
				}
				else if (__instance.genPool[num70].geothermal)
				{
					float num76 = __instance.genPool[num70].warmup + __instance.genPool[num70].warmupSpeed;
					__instance.genPool[num70].warmup = (((double)num76 > 1.0) ? 1f : (((double)num76 < 0.0) ? 0f : num76));
					entityAnimPool[entityId4].state = ((num71 > 0) ? 1u : 0u);
					((AnimData)(ref entityAnimPool[entityId4])).Step(entityAnimPool[entityId4].state, num6, 2f, 0f);
					entityAnimPool[entityId4].working_length = __instance.genPool[num70].warmup;
					if (num71 > 0)
					{
						if ((double)entityAnimPool[entityId4].power < 1.0)
						{
							entityAnimPool[entityId4].power += num6 / 6f;
						}
					}
					else if ((double)entityAnimPool[entityId4].power > 0.0)
					{
						entityAnimPool[entityId4].power -= num6 / 6f;
					}
					entityAnimPool[entityId4].prepare_length += (float)(3.1415927410125732 * (double)num6 / 8.0);
					if ((double)entityAnimPool[entityId4].prepare_length > 6.2831854820251465)
					{
						entityAnimPool[entityId4].prepare_length -= (float)Math.PI * 2f;
					}
				}
				else
				{
					float num77 = (float)((double)entityAnimPool[entityId4].power * 0.98 + 0.02 * (double)num71 / (double)__instance.genPool[num70].genEnergyPerTick);
					if (num71 > 0 && (double)num77 < 0.20000000298023224)
					{
						num77 = 0.2f;
					}
					((AnimData)(ref entityAnimPool[entityId4])).Step2(((double)entityAnimPool[entityId4].power > 0.10000000149011612 || num71 > 0) ? 1u : 0u, num6, num77, num72);
				}
			}
		}
		lock (val)
		{
			val.powerGenRegister = num;
			val.powerConRegister = num2;
			val.powerDisRegister = num3;
			val.powerChaRegister = num4;
			val.energyConsumption += num5;
		}
		if (isActive)
		{
			for (int num78 = 0; num78 < __instance.netCursor; num78++)
			{
				PowerNetwork val5 = __instance.netPool[num78];
				if (val5 == null || val5.id != num78)
				{
					continue;
				}
				List<int> consumers2 = val5.consumers;
				int count5 = consumers2.Count;
				if (num78 == 0)
				{
					for (int num79 = 0; num79 < count5; num79++)
					{
						entitySignPool[__instance.consumerPool[consumers2[num79]].entityId].signType = 1u;
					}
				}
				else if (val5.consumerRatio < 0.10000000149011612)
				{
					for (int num80 = 0; num80 < count5; num80++)
					{
						entitySignPool[__instance.consumerPool[consumers2[num80]].entityId].signType = 2u;
					}
				}
				else if (val5.consumerRatio < 0.5)
				{
					for (int num81 = 0; num81 < count5; num81++)
					{
						entitySignPool[__instance.consumerPool[consumers2[num81]].entityId].signType = 3u;
					}
				}
				else
				{
					for (int num82 = 0; num82 < count5; num82++)
					{
						entitySignPool[__instance.consumerPool[consumers2[num82]].entityId].signType = 0u;
					}
				}
			}
		}
		for (int num83 = 1; num83 < __instance.nodeCursor; num83++)
		{
			if (__instance.nodePool[num83].id != num83)
			{
				continue;
			}
			int entityId5 = __instance.nodePool[num83].entityId;
			int networkId = __instance.nodePool[num83].networkId;
			if (__instance.nodePool[num83].isCharger)
			{
				float num84 = __instance.networkServes[networkId];
				int num85 = __instance.nodePool[num83].requiredEnergy - __instance.nodePool[num83].idleEnergyPerTick;
				if ((double)__instance.nodePool[num83].coverRadius < 20.0)
				{
					((AnimData)(ref entityAnimPool[entityId5])).StepPoweredClamped(num84, num6, (num85 <= 0) ? 1u : 2u);
				}
				else
				{
					((AnimData)(ref entityAnimPool[entityId5])).StepPoweredClamped2(num84, num6, (num85 <= 0) ? 1u : 2u);
				}
				if (num85 <= 0 || entityAnimPool[entityId5].state != 2)
				{
					continue;
				}
				lock (mainPlayer.mecha)
				{
					int num86 = (int)((double)num85 * (double)num84);
					Mecha mecha = mainPlayer.mecha;
					mecha.coreEnergy += (double)num86;
					mainPlayer.mecha.MarkEnergyChange(2, (double)num86);
					mainPlayer.mecha.AddChargerDevice(entityId5);
					if (mainPlayer.mecha.coreEnergy > mainPlayer.mecha.coreEnergyCap)
					{
						mainPlayer.mecha.coreEnergy = mainPlayer.mecha.coreEnergyCap;
					}
				}
			}
			else if (entityPool[entityId5].powerGenId == 0 && entityPool[entityId5].powerAccId == 0 && entityPool[entityId5].powerExcId == 0)
			{
				float num87 = __instance.networkServes[networkId];
				((AnimData)(ref entityAnimPool[entityId5])).Step2(((double)num87 > 0.10000000149011612) ? 1u : 0u, num6, (float)((double)entityAnimPool[entityId5].power * 0.97 + 0.03 * (double)num87), 0.4f);
			}
		}
		ExecuteTime[__instance.factory.index] = ExecuteTime[__instance.factory.index] * 0.99 + StopWatchList[__instance.factory.index].duration * 0.01;
		return false;
	}

	private static void CalculateGeneratorLoadRatio(PowerNetwork powerNetwork, long cleanEnergyGeneratorCap, long num_energy_debt, out double generatorRatioClean, out double generatorRatioFuel)
	{
		long num = powerNetwork.energyCapacity - cleanEnergyGeneratorCap;
		generatorRatioClean = 1.0;
		generatorRatioFuel = ((double)num_energy_debt - (double)cleanEnergyGeneratorCap) / ((double)num + 0.001);
		generatorRatioFuel = ((generatorRatioFuel > 1.0) ? 1.0 : generatorRatioFuel);
		if (generatorRatioFuel < 0.0)
		{
			generatorRatioFuel = 0.0;
			generatorRatioClean = (double)num_energy_debt / ((double)cleanEnergyGeneratorCap + 0.001);
			generatorRatioClean = ((generatorRatioClean > 1.0) ? 1.0 : generatorRatioClean);
		}
	}

	private static double CalculateDischargeRatio(long capGenAndExc, long capExcDischarge, long capGreenGenerator, long energyDebt)
	{
		switch (ExchangerDischargeStrategy)
		{
		default:
		{
			long num2 = capGenAndExc - capGreenGenerator;
			long num3 = energyDebt - capGreenGenerator;
			return (num2 <= 0 || num3 <= 0) ? 0.0 : ((num3 < num2) ? ((double)num3 / (double)num2) : 1.0);
		}
		case EExchangerDischargeStrategy.DISCHARGE_FIRST:
		{
			long num = energyDebt - capGreenGenerator;
			num = ((num < 0) ? 0 : num);
			return (num < capExcDischarge) ? ((double)num / (double)capExcDischarge) : 1.0;
		}
		case EExchangerDischargeStrategy.DISCHARGE_LAST:
		{
			long num = energyDebt - (capGenAndExc - capExcDischarge);
			num = ((num < 0) ? 0 : num);
			return (num < capExcDischarge) ? ((double)num / (double)capExcDischarge) : 1.0;
		}
		}
	}
}