using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Eirshy.DSP.VeinityProject.Enums;
using Eirshy.DSP.VeinityProject.Helpers;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("VeinityProject")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+0ca40dc22036dab7d8c168fab77e1da3a4afb416")]
[assembly: AssemblyProduct("VeinityProject")]
[assembly: AssemblyTitle("VeinityProject")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace Eirshy.DSP.VeinityProject
{
internal static class Config
{
public const ESourceType OceanSourceType = ESourceType.Infinite;
public static int Buffer { get; set; }
public static int WaterPumpVeinCount { get; set; }
public static bool DisableDampers { get; set; }
public static ESourceType VeinSourceType { get; set; }
public static ESourceType OilSourceType { get; set; }
public static EFiniteSourceConsumptionTarget FiniteSourceTargeting { get; set; }
public static int DiminishLimit { get; set; }
public static void Load(ConfigFile cf)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Expected O, but got Unknown
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Expected O, but got Unknown
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Expected O, but got Unknown
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Expected O, but got Unknown
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_01a4: Expected O, but got Unknown
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_01f0: Expected O, but got Unknown
//IL_0286: Unknown result type (might be due to invalid IL or missing references)
//IL_0290: Expected O, but got Unknown
//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
//IL_02e7: Expected O, but got Unknown
Buffer = cf.Bind<int>("VeinityProject", "Buffer", 50, new ConfigDescription("Internal buffer size for Miners, Oil Pumps, and Water Pumps.\nValues below 1 will be treated as 1.", (AcceptableValueBase)null, Array.Empty<object>())).Value;
if (Buffer < 1)
{
Buffer = 1;
}
WaterPumpVeinCount = cf.Bind<int>("VeinityProject", "WaterPumpVeinCount", 1, new ConfigDescription("Number of \"veins\" to pretend Water Pumps are harvesting from.\nValues below 1 will be treated as 1.", (AcceptableValueBase)null, Array.Empty<object>())).Value;
if (WaterPumpVeinCount < 1)
{
WaterPumpVeinCount = 1;
}
DisableDampers = cf.Bind<bool>("VeinityProject", "DisableDampers", false, new ConfigDescription("If true, we'll ignore the 'output is getting kinda full' damper values.", (AcceptableValueBase)null, Array.Empty<object>())).Value;
string[] array = (from s in Enum.GetNames(typeof(ESourceType))
where s != $"{ESourceType._UNSET}"
select s).ToArray();
cf.Bind<bool>("VeinityProject.SourceModes", "_OPTIONS", false, new ConfigDescription("Acceptable values for options in this group are one of the following values:\n" + string.Join(", ", array), (AcceptableValueBase)null, Array.Empty<object>()));
if (Enum.TryParse<ESourceType>(cf.Bind<string>("VeinityProject.SourceModes", "VeinSourceType", $"{ESourceType.FiniteDepleting}", new ConfigDescription("The source depletion type for Ore Veins. Default is the same as Vanilla:\nHarvested at a rate scaled to vein count until fully depleted.", (AcceptableValueBase)(object)new AcceptableValueList<string>(array), Array.Empty<object>())).Value, out var result))
{
VeinSourceType = result;
}
else
{
VeinSourceType = ESourceType.FiniteDepleting;
}
if (Enum.TryParse<ESourceType>(cf.Bind<string>("VeinityProject.SourceModes", "OilSourceType", $"{ESourceType.Diminishing}", new ConfigDescription("The source depletion type for Oil Seeps. Default is the same as Vanilla:\nHarvest at a rate scaled to vein richness, reducing it to a limit.\nSee the DiminishLimit setting for more details." + $" Use {ESourceType.InfiniteDiminished} if you want this rate, but without reduction.", (AcceptableValueBase)(object)new AcceptableValueList<string>(array), Array.Empty<object>())).Value, out var result2))
{
OilSourceType = result2;
}
else
{
OilSourceType = ESourceType.Diminishing;
}
cf.Bind<string>("VeinityProject.SourceModes", "OceanSourceType", $"{ESourceType.Infinite}", new ConfigDescription("The source depletion type for Oceans. Default is the same as Vanilla:\nHarvest at a rate scaled to the source count (default: 1).\nThis value is currently completely ignored, as there is no tracked 'remaining ocean'.", (AcceptableValueBase)null, Array.Empty<object>()));
string[] names = Enum.GetNames(typeof(EFiniteSourceConsumptionTarget));
if (Enum.TryParse<EFiniteSourceConsumptionTarget>(cf.Bind<string>("VeinityProject.SourceModes.Config", "FiniteSourceTargeting", $"{EFiniteSourceConsumptionTarget.Cyclic}", new ConfigDescription($"How {ESourceType.FiniteDepleting} picks the vein to deplete." + $" Default ({EFiniteSourceConsumptionTarget.Cyclic}) is the same as Vanilla:" + "\nIterate over the whole list of veins each tick, depleting whichver is currently selected." + $"\nOther Options: \"{EFiniteSourceConsumptionTarget.Fullest}\" depletes the fullest first," + $" \"{EFiniteSourceConsumptionTarget.Lowest}\" depletes the most empty first.", (AcceptableValueBase)(object)new AcceptableValueList<string>(names), Array.Empty<object>())).Value, out var result3))
{
FiniteSourceTargeting = result3;
}
else
{
FiniteSourceTargeting = EFiniteSourceConsumptionTarget.Cyclic;
}
DiminishLimit = cf.Bind<int>("VeinityProject.SourceModes.Config", "DiminishLimit", 2500, new ConfigDescription($"For any {ESourceType.Diminishing}-mode miners, controls how low a vein is allowed to get." + "\n2500 is roughly 0.1/s, with 25000 being roughly 1/s. Keep in mind this is per vein.\nValues below 1 will be treated as 1.", (AcceptableValueBase)null, Array.Empty<object>())).Value;
if (DiminishLimit < 1)
{
DiminishLimit = 1;
}
}
}
internal static class SmelterMinerCompat
{
private const int MapABase = 9446;
private const int MapBBase = 9447;
private const int MapCBase = 9448;
private const int SplitOffset = 20;
private const int MapOBuilding = 9469;
public static void SetUpAwake()
{
Chainloader.PluginInfos.TryGetValue("Gnimaerd.DSP.plugin.SmelterMiner", out var value);
if (value != null)
{
Type type = ((object)value.Instance).GetType();
MethodInfo method = typeof(MinerComponent).GetMethod("InternalUpdate");
MethodInfo method2 = typeof(StationComponent).GetMethod("UpdateVeinCollection");
if ((object)method != null)
{
VeinityProject.Harmony.Unpatch((MethodBase)method, type.GetMethod("InternalUpdatePatch", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
}
if ((object)method2 != null)
{
VeinityProject.Harmony.Unpatch((MethodBase)method2, type.GetMethod("UpdateVeinCollectionPatch", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
}
}
}
public static void SetUpLate()
{
//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
//IL_03e3: Invalid comparison between Unknown and I4
//IL_02da: Unknown result type (might be due to invalid IL or missing references)
Dictionary<EVeinType, int> oreMap = new Dictionary<EVeinType, int>
{
{
(EVeinType)1,
1001
},
{
(EVeinType)2,
1002
},
{
(EVeinType)3,
1003
},
{
(EVeinType)4,
1004
},
{
(EVeinType)5,
1005
},
{
(EVeinType)6,
1006
},
{
(EVeinType)7,
1007
},
{
(EVeinType)8,
1011
},
{
(EVeinType)9,
1012
},
{
(EVeinType)10,
1013
},
{
(EVeinType)11,
1117
},
{
(EVeinType)12,
1014
},
{
(EVeinType)13,
1015
},
{
(EVeinType)14,
1016
}
};
Dictionary<EVeinType, int[]> dictionary = new Dictionary<EVeinType, int[]>();
dictionary.Add((EVeinType)1, new int[3] { 1101, 1102, 0 });
dictionary.Add((EVeinType)2, new int[3] { 1104, 1104, 0 });
dictionary.Add((EVeinType)3, new int[3] { 1105, 1105, 0 });
dictionary.Add((EVeinType)4, new int[3] { 1106, 1106, 0 });
dictionary.Add((EVeinType)5, new int[3] { 1108, 1110, 0 });
dictionary.Add((EVeinType)6, new int[3] { 1109, 1109, 0 });
dictionary.Add((EVeinType)7, new int[3] { 0, 0, 1114 });
dictionary.Add((EVeinType)8, new int[3] { 0, 0, 1123 });
dictionary.Add((EVeinType)9, new int[3] { 1112, 1112, 0 });
dictionary.Add((EVeinType)10, new int[3] { 0, 0, 1113 });
dictionary.Add((EVeinType)11, new int[3]);
dictionary.Add((EVeinType)12, new int[3]);
dictionary.Add((EVeinType)13, new int[3] { 0, 0, 1124 });
dictionary.Add((EVeinType)14, new int[3]);
Dictionary<EVeinType, int[]> source = dictionary;
int[] baseIDMap = new int[3] { 9446, 9447, 9448 };
IEnumerable<(EVeinType, int, int, int)> enumerable = from vmop in source.SelectMany((KeyValuePair<EVeinType, int[]> kvp) => kvp.Value.Select((int prod, int i) => (kvp.Key, baseIDMap[i], oreMap[kvp.Key], prod)))
where vmop.prod != 0
select vmop;
bool flag = false;
foreach (var vmop2 in enumerable)
{
RecipeProto rec2 = ((IEnumerable<RecipeProto>)((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray).FirstOrDefault((Func<RecipeProto, bool>)((RecipeProto rec) => rec.Items.Contains(vmop2.Item3) && rec.Results.Contains(vmop2.Item4)));
if (rec2 == null)
{
VeinityProject.Logs.LogWarning((object)$"Missing recipe for vein {vmop2.Item1} => {vmop2.Item4}");
continue;
}
int qtyOre = rec2.ItemCounts.Where((int _, int i) => rec2.Items[i] == vmop2.Item3).First();
int qtyProduct = rec2.ResultCounts.Where((int _, int i) => rec2.Results[i] == vmop2.Item4).First();
int per = OreRemap.CalcOre2Product(qtyOre, qtyProduct);
OreRemap.Register(vmop2.Item2, vmop2.Item3, per, vmop2.Item4);
OreRemap.Register(vmop2.Item2 + 20, vmop2.Item3, per, vmop2.Item4);
if ((int)vmop2.Item1 == 7 && vmop2.Item4 == 1114 && !flag)
{
OreRemap.Register(9469, vmop2.Item3, per, vmop2.Item4);
flag = true;
}
}
}
private static IEnumerable<CodeInstruction> DisableIL_retTrue()
{
yield return new CodeInstruction(OpCodes.Ldc_I4_1, (object)null);
yield return new CodeInstruction(OpCodes.Ret, (object)null);
}
}
internal class VeinityPatcher
{
private const int ARBITRARY_LARGE_NUMBER = 500000;
private static float DiminishingMiningRateModifier { get; set; }
private static void _transcludedDependencies()
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
PlanetFactory val = null;
MinerComponent val2 = default(MinerComponent);
val.AddMiningFlagUnsafe((EVeinType)0);
val.AddVeinMiningFlagUnsafe((EVeinType)0);
((MinerComponent)(ref val2)).DetermineState();
val.factorySystem.GameTickBeforePower(0L, false);
val.factorySystem.ParallelGameTickBeforePower(0L, false, 0, 0, 0);
((MinerComponent)(ref val2)).RemoveVeinFromArray(0);
((MinerComponent)(ref val2)).GetMinimumVeinAmount(val, (VeinData[])null);
}
public static void SetUp()
{
VeinityProject.Harmony.PatchAll(typeof(VeinityPatcher));
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(StationComponent), "UpdateVeinCollection")]
private static IEnumerable<CodeInstruction> DisableIL()
{
yield return new CodeInstruction(OpCodes.Ret, (object)null);
}
private static bool DisableRO()
{
return false;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameSave), "LoadCurrentGame", new Type[] { typeof(string) })]
public static void Precalc()
{
DiminishingMiningRateModifier = GameMain.data.gameDesc.resourceMultiplier * 0.40111667f;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(MinerComponent), "SetPCState")]
public static void SetPCState(PowerConsumerComponent[] pcPool, ref MinerComponent __instance, ref bool __runOriginal)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Invalid comparison between Unknown and I4
if (__runOriginal)
{
__runOriginal = false;
_DetermineState_inline(ref __instance);
((PowerConsumerComponent)(ref pcPool[__instance.pcId])).SetRequiredEnergy(((int)__instance.workstate > 0) ? ((double)(_getupdDamper(ref __instance) * (float)__instance.speed * (float)__instance.speed) / 100000000.0) : 0.0);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void _DetermineState_inline(ref MinerComponent __instance)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected I4, but got Unknown
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: 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_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
EMinerType type = __instance.type;
switch ((int)type)
{
case 0:
break;
case 2:
case 3:
if (__instance.veinCount == 0)
{
__instance.time = 0;
__instance.workstate = (EWorkState)0;
}
else if (__instance.productCount < Config.Buffer)
{
__instance.workstate = (EWorkState)1;
}
else
{
__instance.workstate = (EWorkState)(-2);
}
break;
case 1:
if (__instance.productCount < Config.Buffer)
{
__instance.workstate = (EWorkState)1;
}
else
{
__instance.workstate = (EWorkState)(-2);
}
break;
default:
((MinerComponent)(ref __instance)).DetermineState();
break;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float _getupdDamper(ref MinerComponent __instance)
{
if (__instance.productCount >= Config.Buffer)
{
__instance.speedDamper = 0f;
}
else if (Config.DisableDampers)
{
__instance.speedDamper = 1f;
}
else if (__instance.productCount > 0)
{
float num = 2.47f - 2.45f * ((float)__instance.productCount / 50f);
num = ((num > 1f) ? 1f : ((num < 0f) ? 0f : num));
if (__instance.speedDamper == num)
{
float num2 = 2.47f - 2.45f * ((float)__instance.productCount / (float)Config.Buffer);
__instance.speedDamper = ((num2 > 1f) ? 1f : num2);
}
}
return __instance.speedDamper;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(MinerComponent), "InternalUpdate")]
public static void InternalUpdate(PlanetFactory factory, VeinData[] veinPool, float power, float miningRate, float miningSpeed, int[] productRegister, ref MinerComponent __instance, ref bool __runOriginal, ref uint __result)
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Expected I4, but got Unknown
//IL_0223: Unknown result type (might be due to invalid IL or missing references)
//IL_0229: Invalid comparison between Unknown and I4
//IL_0201: Unknown result type (might be due to invalid IL or missing references)
//IL_0205: Unknown result type (might be due to invalid IL or missing references)
//IL_0208: Invalid comparison between Unknown and I4
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_018e: Unknown result type (might be due to invalid IL or missing references)
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Unknown result type (might be due to invalid IL or missing references)
//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
//IL_054b: Unknown result type (might be due to invalid IL or missing references)
//IL_0552: Expected I4, but got Unknown
//IL_0554: Unknown result type (might be due to invalid IL or missing references)
//IL_0559: 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)
if (!__runOriginal)
{
return;
}
__runOriginal = false;
__result = 0u;
if (power < 0.1f)
{
return;
}
int veinCount = -1;
if (__instance.productCount < Config.Buffer || __instance.time < __instance.period)
{
veinCount = 0;
int veinAmountTotal = 0;
int num = int.MaxValue;
int num2 = int.MinValue;
int num3 = -1;
int num4 = -1;
EVeinType addVeinType = (EVeinType)0;
ESourceType source = ESourceType._UNSET;
int num5 = 0;
EMinerType type = __instance.type;
switch ((int)type)
{
default:
__runOriginal = true;
return;
case 0:
return;
case 1:
veinCount = ((__instance.veinCount == 0) ? Config.WaterPumpVeinCount : __instance.veinCount);
source = ESourceType.Infinite;
num5 = factory.planet.waterItemId;
break;
case 3:
source = Config.OilSourceType;
goto case 2;
case 2:
{
int veinCount2 = __instance.veinCount;
if (veinCount2 >= 0)
{
switch (veinCount2)
{
case 1:
{
int num6 = __instance.veins[0];
if (num6 > 0)
{
int amount2 = veinPool[num6].amount;
EVeinType type3 = veinPool[num6].type;
int productId2 = veinPool[num6].productId;
if (veinPool[num6].id == num6 && amount2 > 0)
{
veinCount = 1;
veinAmountTotal = amount2;
num = amount2;
num2 = amount2;
num3 = num6;
num4 = num6;
addVeinType = type3;
num5 = productId2;
}
else
{
__instance.veins[0] = 0;
}
}
break;
}
default:
{
int veinCount3 = __instance.veinCount;
while (veinCount3-- > 0)
{
int num6 = __instance.veins[veinCount3];
if (num6 <= 0)
{
continue;
}
int amount = veinPool[num6].amount;
EVeinType type2 = veinPool[num6].type;
int productId = veinPool[num6].productId;
if (veinPool[num6].id == num6 && amount > 0)
{
veinCount++;
veinAmountTotal += amount;
if (amount < num)
{
num3 = num6;
num = amount;
}
if (amount > num2)
{
num4 = num6;
num2 = amount;
}
addVeinType = type2;
num5 = productId;
}
else
{
__instance.veins[veinCount3] = 0;
}
}
break;
}
case 0:
break;
}
}
if (source == ESourceType._UNSET)
{
source = (((int)addVeinType == 0) ? ESourceType.Infinite : (((int)addVeinType != 7) ? Config.VeinSourceType : Config.OilSourceType));
}
if ((int)__instance.type != 2)
{
break;
}
switch (source)
{
case ESourceType.FiniteDepleting:
if (Config.FiniteSourceTargeting == EFiniteSourceConsumptionTarget.Fullest)
{
__instance.minimumVeinAmount = ((num4 != -1) ? num2 : 0);
}
else
{
__instance.minimumVeinAmount = ((num3 != -1) ? num : 0);
}
break;
case ESourceType.Diminishing:
__instance.minimumVeinAmount = ((veinCount > 0) ? (veinAmountTotal / veinCount) : 0);
break;
case ESourceType.Infinite:
__instance.minimumVeinAmount = ((__instance.veinCount > 0) ? 500000 : 0);
break;
default:
__instance.minimumVeinAmount = ((num3 != -1) ? num : 0);
break;
}
break;
}
}
if (veinCount > 0)
{
if (__instance.time <= __instance.period)
{
__instance.time += (int)GetSingleTickTime_inline(in source, in veinCount, in veinAmountTotal, in __instance.speed, in miningSpeed, in power, in __instance.speedDamper);
__result = 1u;
}
if (__instance.time >= __instance.period && __instance.productCount < Config.Buffer && num5 > 0)
{
int num7 = __instance.time / __instance.period;
__instance.productId = num5;
switch (source)
{
case ESourceType.Infinite:
case ESourceType.InfiniteDiminished:
__instance.productCount += num7;
Interlocked.Add(ref productRegister[num5], num7);
__instance.time -= __instance.period * num7;
break;
case ESourceType.FiniteDepleting:
{
int num6;
switch (Config.FiniteSourceTargeting)
{
default:
throw new NotImplementedException();
case EFiniteSourceConsumptionTarget.Cyclic:
{
int num10 = __instance.currentVeinIndex % __instance.veinCount;
num6 = __instance.veins[num10];
int veinCount4 = __instance.veinCount;
while (veinCount4-- > 0)
{
num10 = (num10 + 1) % __instance.veinCount;
if (num6 > 0)
{
break;
}
num6 = __instance.veins[num10];
}
__instance.currentVeinIndex = num10;
break;
}
case EFiniteSourceConsumptionTarget.Lowest:
__instance.currentVeinIndex = 0;
num6 = num3;
break;
case EFiniteSourceConsumptionTarget.Fullest:
__instance.currentVeinIndex = 0;
num6 = num4;
break;
}
ref VeinData reference2 = ref veinPool[num6];
if (reference2.amount <= 0)
{
break;
}
int realized = 0;
if (miningRate <= 0f)
{
realized = num7;
}
else
{
int consume = 0;
if (miningRate < 0.99999f)
{
uint curSeed2 = __instance.seed;
int num11 = num7;
while (num11-- > 0)
{
if (_iu_cycleSeed_inline(ref curSeed2, in miningRate))
{
if (_iu_tryConsume_inline(ref reference2, ref realized, ref consume))
{
break;
}
}
else
{
realized++;
}
}
__instance.seed = curSeed2;
}
else
{
int num12 = num7;
while (num12-- > 0 && !_iu_tryConsume_inline(ref reference2, ref realized, ref consume))
{
}
}
if (consume > 0)
{
int groupIndex = reference2.groupIndex;
long num13 = Interlocked.Add(ref factory.veinGroups[groupIndex].amount, -consume);
ref AnimData anim2 = ref factory.veinAnimPool[num6];
float newTime = ((reference2.amount >= 20000) ? 0f : (1f - (float)reference2.amount * 5E-05f));
_safeVeinAnim_largest_inline(ref anim2, in newTime);
if (num13 <= 0)
{
lock (veinPool)
{
if (reference2.id == num6)
{
int num14 = (int)reference2.type;
Vector3 pos = reference2.pos;
factory.RemoveVeinWithComponents(num6);
factory.RecalculateVeinGroup(groupIndex);
factory.NotifyVeinExhausted(num14, pos);
}
}
}
}
}
__instance.productCount += realized;
Interlocked.Add(ref productRegister[__instance.productId], realized);
_safeAddFlagsToFactory_inline(ref factory, in addVeinType);
__instance.time -= __instance.period * realized;
break;
}
case ESourceType.Diminishing:
{
float miningRate2 = miningRate * DiminishingMiningRateModifier;
if (miningRate2 > 0f && num2 > Config.DiminishLimit)
{
int reduceBy = 0;
uint curSeed = __instance.seed;
int num8 = num7;
while (num8-- > 0)
{
if (_iu_cycleSeed_inline(ref curSeed, in miningRate2))
{
reduceBy++;
}
}
__instance.seed = curSeed;
if (reduceBy > 0)
{
int num6 = num4;
ref VeinData reference = ref veinPool[num6];
int veinCount2 = Config.DiminishLimit;
int num9 = _iu_tryConsumeBulk_inline(ref reference, in reduceBy, in veinCount2);
if (num9 > 0)
{
_ = ref factory.veinGroups[reference.groupIndex];
Interlocked.Add(ref factory.veinGroups[reference.groupIndex].amount, -num9);
}
int amount3 = reference.amount;
ref AnimData anim = ref factory.veinAnimPool[num6];
float newTime = ((amount3 >= 25000) ? 0f : (1f - (float)amount3 * VeinData.oilSpeedMultiplier));
_safeVeinAnim_largest_inline(ref anim, in newTime);
}
}
__instance.productCount += num7;
Interlocked.Add(ref productRegister[num5], num7);
__instance.time -= __instance.period * num7;
break;
}
}
}
}
}
_iu_export_inline(ref __instance, ref factory, ref productRegister);
_iu_prune_inline(ref __instance, in veinCount);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float GetSingleTickTime_inline(in ESourceType source, in int veinCount, in int veinAmountTotal, in int speed, in float miningSpeed, in float power, in float speedDamper)
{
switch (source)
{
default:
throw new NotImplementedException();
case ESourceType.Infinite:
case ESourceType.FiniteDepleting:
return power * (float)speed * speedDamper * miningSpeed * (float)veinCount;
case ESourceType.InfiniteDiminished:
case ESourceType.Diminishing:
return power * (float)speed * speedDamper * miningSpeed * (float)veinAmountTotal * VeinData.oilSpeedMultiplier + (float)veinCount * 0.5f;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool _iu_cycleSeed_inline(ref uint curSeed, in float miningRate)
{
curSeed = (uint)((int)((ulong)((long)(curSeed % 2147483646 + 1) * 48271L) % 2147483647uL) - 1);
return (double)curSeed / 2147483646.0 < (double)miningRate;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool _iu_tryConsume_inline(ref VeinData vtarg, ref int realized, ref int consume)
{
int num = Interlocked.Decrement(ref vtarg.amount);
if (num >= 0)
{
if (num == 0)
{
realized++;
consume++;
return true;
}
realized++;
consume++;
return false;
}
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int _iu_tryConsumeBulk_inline(ref VeinData vd, in int reduceBy, in int minRemaining)
{
int amount;
int num;
do
{
amount = vd.amount;
if (amount <= minRemaining)
{
return 0;
}
num = amount - reduceBy;
if (num < minRemaining)
{
num = minRemaining;
}
}
while (Interlocked.CompareExchange(ref vd.amount, num, amount) != amount);
return amount - num;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void _iu_export_inline(ref MinerComponent mc, ref PlanetFactory factory, ref int[] prodReg)
{
if (mc.productCount <= 0)
{
return;
}
if (mc.insertTarget > 0)
{
byte b2 = default(byte);
if (OreRemap.HasRemap)
{
OreRemap oreRemap = OreRemap.Get(factory.entityPool[mc.entityId].protoId, mc.productId);
byte b;
if (oreRemap.IsDefault)
{
b = (byte)((mc.productCount < 4) ? ((uint)mc.productCount) : 4u);
int num = factory.InsertInto(mc.insertTarget, 0, mc.productId, b, (byte)0, ref b2);
mc.productCount -= num;
return;
}
int num2 = oreRemap.Ore2Prod(mc.productCount);
b = (byte)((num2 < 4) ? ((uint)num2) : 4u);
if (b > 0)
{
int[] consumeRegister = GameMain.statistics.production.factoryStatPool[factory.index].consumeRegister;
int num = factory.InsertInto(mc.insertTarget, 0, oreRemap.ProductID, b, (byte)0, ref b2);
int num3 = oreRemap.Prod2Ore(num);
mc.productCount -= num3;
Interlocked.Add(ref consumeRegister[mc.productId], num3);
Interlocked.Add(ref prodReg[oreRemap.ProductID], num);
}
}
else
{
byte b = (byte)((mc.productCount < 4) ? ((uint)mc.productCount) : 4u);
int num = factory.InsertInto(mc.insertTarget, 0, mc.productId, b, (byte)0, ref b2);
mc.productCount -= num;
}
return;
}
ref EntityData reference = ref factory.entityPool[mc.entityId];
if (reference.stationId <= 0)
{
return;
}
ref StationStore reference2 = ref factory.transport.stationPool[reference.stationId].storage[0];
int num4 = reference2.max - reference2.count;
if (num4 <= 0)
{
return;
}
if (OreRemap.HasRemap)
{
OreRemap oreRemap2 = OreRemap.Get(reference.protoId, mc.productId);
int num;
if (oreRemap2.IsDefault)
{
num = ((mc.productCount > num4) ? num4 : mc.productCount);
mc.productCount -= num;
Interlocked.Add(ref reference2.count, num);
reference2.itemId = mc.productId;
return;
}
int[] consumeRegister2 = GameMain.statistics.production.factoryStatPool[factory.index].consumeRegister;
int num5 = oreRemap2.Ore2Prod(mc.productCount);
num = ((num5 > num4) ? num4 : num5);
int num6 = oreRemap2.Prod2Ore(num);
mc.productCount -= num6;
Interlocked.Add(ref reference2.count, num);
Interlocked.Add(ref consumeRegister2[mc.productId], num6);
Interlocked.Add(ref prodReg[oreRemap2.ProductID], num);
reference2.itemId = oreRemap2.ProductID;
}
else
{
int num = ((mc.productCount > num4) ? num4 : mc.productCount);
mc.productCount -= num;
Interlocked.Add(ref reference2.count, num);
reference2.itemId = mc.productId;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void _iu_prune_inline(ref MinerComponent mc, in int vcnt)
{
if (vcnt >= mc.veinCount || vcnt < 0)
{
return;
}
if (vcnt == 0)
{
Array.Clear(mc.veins, 0, mc.veins.Length);
mc.veinCount = 0;
return;
}
int veinCount = mc.veinCount;
while (veinCount-- > 0)
{
if (mc.veins[veinCount] == 0)
{
for (int i = veinCount + 1; i < mc.veinCount; i++)
{
mc.veins[i - 1] = mc.veins[i];
}
mc.veinCount--;
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void _safeVeinAnim_largest_inline(ref AnimData anim, in float newTime)
{
float time;
do
{
time = anim.time;
}
while (!(time >= newTime) && Interlocked.CompareExchange(ref anim.time, newTime, time) != time);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void _safeAddFlagsToFactory_inline(ref PlanetFactory factory, in EVeinType addVeinType)
{
int num = 1 << (int)addVeinType;
int miningFlag;
do
{
miningFlag = factory._miningFlag;
}
while ((miningFlag & num) != num && Interlocked.CompareExchange(ref factory._miningFlag, miningFlag | num, miningFlag) != miningFlag);
do
{
miningFlag = factory._veinMiningFlag;
}
while ((miningFlag & num) != num && Interlocked.CompareExchange(ref factory._veinMiningFlag, miningFlag | num, miningFlag) != miningFlag);
}
}
[BepInPlugin("eirshy.dsp.VeinityProject", "VeinityProject", "0.2.6")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class VeinityProject : BaseUnityPlugin
{
public const string MODID = "VeinityProject";
public const string ROOT = "eirshy.dsp.";
public const string GUID = "eirshy.dsp.VeinityProject";
public const string VERSION = "0.2.6";
public const string NAME = "VeinityProject";
internal const string GUID_SmelterMiner = "Gnimaerd.DSP.plugin.SmelterMiner";
private static readonly Lazy<Harmony> _harmony = new Lazy<Harmony>((Func<Harmony>)(() => new Harmony("eirshy.dsp.VeinityProject")));
private static bool hasLoaded = false;
internal static Harmony Harmony => _harmony.Value;
internal static ManualLogSource Logs { get; private set; }
private void Awake()
{
Logs = ((BaseUnityPlugin)this).Logger;
((BaseUnityPlugin)this).Logger.LogMessage((object)"VeinityProject powdering up!");
Config.Load(((BaseUnityPlugin)this).Config);
SmelterMinerCompat.SetUpAwake();
VeinityPatcher.SetUp();
Harmony.PatchAll(typeof(VeinityProject));
}
[HarmonyPostfix]
[HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")]
public static void SetupLate()
{
if (!hasLoaded)
{
SmelterMinerCompat.SetUpLate();
OreRemap.Bake();
hasLoaded = true;
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "VeinityProject";
public const string PLUGIN_NAME = "VeinityProject";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace Eirshy.DSP.VeinityProject.Helpers
{
internal struct OreRemap
{
private const int PER_OUTOF = 60;
private const int SUBKEY_ANY = 65535;
public readonly int MinerID;
public readonly int OreID;
public readonly int Per;
public readonly int ProductID;
private static readonly Regex _deser = new Regex("^(\\d+)m:(\\d+)x(\\d+)=>(\\d+)x\\d+$");
private static ConcurrentDictionary<int, OreRemap> _register = new ConcurrentDictionary<int, OreRemap>();
private static Dictionary<int, OreRemap> _baked = null;
public static bool HasRemap { get; private set; }
public int Key => KeyFrom(MinerID, OreID);
public bool IsDefault => ProductID == 0;
public int Ore2Prod(int ore)
{
return ore * 60 / Per;
}
public int Prod2Ore(int product)
{
return product * Per / 60;
}
internal static int CalcOre2Product(int qtyOre, int qtyProduct)
{
return qtyOre * 60 / qtyProduct;
}
public OreRemap(int mid, int oid, int per, int prod)
{
MinerID = mid & 0xFFFF;
OreID = oid & 0xFFFF;
Per = per;
ProductID = prod;
}
private OreRemap(bool ignored)
{
MinerID = 65535;
OreID = 65535;
Per = 60;
ProductID = 0;
}
public string Serialize()
{
return $"{MinerID}m:{OreID}x{Per}=>{ProductID}x{60}";
}
public static string Serialize(OreRemap[] from)
{
return string.Join(" ", from.Select((OreRemap rm) => rm.Serialize()));
}
public static OreRemap[] Deserialize(string from)
{
return (from s in new Regex("[ .;,|-]+").Split(@from.Trim().ToLower())
select _deser.Match(s) into m
where m.Success
select new OreRemap(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value), int.Parse(m.Groups[3].Value), int.Parse(m.Groups[4].Value))).ToArray();
}
private static int KeyFrom(int MinerID, int OreID)
{
return (MinerID << 16) | OreID;
}
internal static void Register(int mid, int oid, int per, int prod)
{
if (_baked != null)
{
throw new InvalidOperationException("Remap has already been baked!");
}
HasRemap = true;
OreRemap value = new OreRemap(mid, oid, per, prod);
_register[value.Key] = value;
}
public static void Bake()
{
List<KeyValuePair<int, OreRemap>> list = _register.ToList();
_baked = new Dictionary<int, OreRemap>(list.Count);
foreach (KeyValuePair<int, OreRemap> item in list)
{
_baked.Add(item.Key, item.Value);
VeinityProject.Logs.LogMessage((object)("Baked: " + item.Value.Serialize()));
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static OreRemap Get(int MinerID, int OreID)
{
int key = KeyFrom(MinerID, OreID);
if (_baked.ContainsKey(key))
{
return _baked[key];
}
return default(OreRemap);
}
}
}
namespace Eirshy.DSP.VeinityProject.Enums
{
internal enum EFiniteSourceConsumptionTarget
{
Cyclic,
Lowest,
Fullest
}
internal enum ESourceType
{
_UNSET,
Infinite,
InfiniteDiminished,
Diminishing,
FiniteDepleting
}
}