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;
}
}
}
}