using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using CalculatorPatch;
using DSPCalculator;
using DSPCalculator.Compatibility;
using DSPCalculator.Logic;
using DSPCalculator.UI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;
using crecheng.DSPModSave;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
public static class CalcFixes
{
private static HashSet<ItemConfig> autoRaw;
private static List<string> pendingData;
private static List<float> pendingX;
private static List<float> pendingY;
private static List<bool> pendingLarge;
private static int pendingClosed;
public static void FitIncSwitch(UIItemNode ui)
{
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_017a: Unknown result type (might be due to invalid IL or missing references)
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
if (ui == null || (Object)(object)ui.incToggleObj == (Object)null || ((UINode)ui).parentCalcWindow == null || (Object)(object)((UINode)ui).parentCalcWindow.contentScrollRect == (Object)null)
{
return;
}
Transform transform = ui.incToggleObj.transform;
Transform obj = transform.Find("inc-switch");
RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
Transform obj2 = transform.Find("inc-switch/switch-thumb");
RectTransform val2 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null);
ScrollRect contentScrollRect = ((UINode)ui).parentCalcWindow.contentScrollRect;
RectTransform val3 = (RectTransform)(((Object)(object)contentScrollRect.viewport != (Object)null) ? ((object)contentScrollRect.viewport) : ((object)/*isinst with value type is only supported in some contexts*/));
if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null) && !((Object)(object)transform.parent == (Object)null) && !(transform.parent.lossyScale.x <= 0f))
{
Vector3[] array = (Vector3[])(object)new Vector3[4];
val3.GetWorldCorners(array);
float num = array[2].x;
if ((Object)(object)contentScrollRect.verticalScrollbar != (Object)null && ((Component)contentScrollRect.verticalScrollbar).gameObject.activeInHierarchy)
{
((RectTransform)((Component)contentScrollRect.verticalScrollbar).transform).GetWorldCorners(array);
num = Mathf.Min(num, array[0].x);
}
val.GetWorldCorners(array);
float x = array[2].x;
val2.GetWorldCorners(array);
float num2 = OverflowLocal(Mathf.Max(x, array[2].x + (10f - val2.anchoredPosition.x) * ((Transform)val2).parent.lossyScale.x), num, transform.parent.lossyScale.x);
if (num2 > 0f)
{
transform.localPosition -= new Vector3(num2, 0f, 0f);
}
}
}
public static float OverflowLocal(float rightWorld, float limitWorld, float scale)
{
if (!(scale <= 0f))
{
return (rightWorld - limitWorld) / scale + 8f;
}
return 0f;
}
public static void SaveWindows(BinaryWriter w)
{
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
List<UICalcWindow> list = new List<UICalcWindow>();
if (WindowsManager.closedWindows != null)
{
foreach (UICalcWindow closedWindow in WindowsManager.closedWindows)
{
if ((Object)(object)closedWindow.windowObj != (Object)null)
{
list.Add(closedWindow);
}
}
}
int count = list.Count;
if (WindowsManager.windows != null)
{
foreach (UICalcWindow window in WindowsManager.windows)
{
if ((Object)(object)window.windowObj != (Object)null)
{
list.Add(window);
}
}
}
List<ItemConfig> list2 = ((autoRaw == null) ? new List<ItemConfig>() : new List<ItemConfig>(autoRaw));
foreach (ItemConfig item in list2)
{
item.consideredAsOre = false;
}
try
{
w.Write(1);
w.Write(count);
w.Write(list.Count);
foreach (UICalcWindow item2 in list)
{
Vector3 localPosition = item2.windowObj.transform.localPosition;
w.Write(item2.Copy());
w.Write(localPosition.x);
w.Write(localPosition.y);
w.Write(item2.isLargeWindow);
}
}
finally
{
foreach (ItemConfig item3 in list2)
{
item3.consideredAsOre = true;
}
}
}
public static void LoadWindows(BinaryReader r)
{
pendingData = null;
if (r.ReadInt32() == 1)
{
int num = r.ReadInt32();
int num2 = r.ReadInt32();
List<string> list = new List<string>();
pendingX = new List<float>();
pendingY = new List<float>();
pendingLarge = new List<bool>();
for (int i = 0; i < num2; i++)
{
list.Add(r.ReadString());
pendingX.Add(r.ReadSingle());
pendingY.Add(r.ReadSingle());
pendingLarge.Add(r.ReadBoolean());
}
pendingClosed = num;
pendingData = list;
}
}
public static void ClearPendingWindows()
{
pendingData = null;
}
public static void ApplyPendingWindows()
{
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
if (pendingData == null || !GameMain.isRunning || DSPGame.IsMenuDemo || !CalcDB.inited || WindowsManager.windows == null)
{
return;
}
List<string> list = pendingData;
pendingData = null;
for (int num = WindowsManager.windows.Count - 1; num >= 0; num--)
{
WindowsManager.windows[num].CloseWindow();
}
foreach (UICalcWindow closedWindow in WindowsManager.closedWindows)
{
Object.Destroy((Object)(object)closedWindow.windowObj);
}
WindowsManager.closedWindows.Clear();
for (int i = 0; i < list.Count; i++)
{
UICalcWindow val = WindowsManager.OpenOne(true);
if (!val.TryPaste(list[i]))
{
Utils.logger.LogWarning((object)("Saved calculator window " + i + " could not be restored."));
}
Vector3 localPosition = val.windowObj.transform.localPosition;
val.windowObj.transform.localPosition = new Vector3(pendingX[i], pendingY[i], localPosition.z);
val.isLargeWindow = pendingLarge[i];
if (i < pendingClosed)
{
val.CloseWindow();
}
}
}
private static bool IsRaw(UserPreference pref, int itemId)
{
if (!CalcDB.itemDict.TryGetValue(itemId, out var value))
{
return true;
}
bool flag = value.defaultAsOre || value.recipes.Count == 0;
if (pref.itemConfigs.TryGetValue(itemId, out var value2))
{
flag = value2.consideredAsOre || flag;
if (value2.forceNotOre && value.recipes.Count > 0)
{
flag = false;
}
}
return flag;
}
private static bool MustNeed(UserPreference pref, int itemId, int target, HashSet<int> path, HashSet<int> no)
{
if (itemId == target)
{
return true;
}
if (no.Contains(itemId) || IsRaw(pref, itemId) || !path.Add(itemId))
{
return false;
}
bool flag;
if (pref.itemConfigs.TryGetValue(itemId, out var value) && value.recipeID > 0 && CalcDB.recipeDict.TryGetValue(value.recipeID, out var value2))
{
flag = RecipeNeeds(pref, value2, target, path, no);
}
else
{
flag = true;
foreach (NormalizedRecipe recipe in CalcDB.itemDict[itemId].recipes)
{
if (!RecipeNeeds(pref, recipe, target, path, no))
{
flag = false;
break;
}
}
}
path.Remove(itemId);
if (!flag)
{
no.Add(itemId);
}
return flag;
}
private static bool RecipeNeeds(UserPreference pref, NormalizedRecipe r, int target, HashSet<int> path, HashSet<int> no)
{
for (int i = 0; i < r.resources.Length; i++)
{
if (r.resourceCounts[i] > 0 && MustNeed(pref, r.resources[i], target, path, no))
{
return true;
}
}
return false;
}
public static void SyncRecipeTimes()
{
if (CalcDB.recipeDict == null)
{
return;
}
foreach (NormalizedRecipe value in CalcDB.recipeDict.Values)
{
if (value != null && value.oriProto != null && value.ID >= 0 && value.type != NormalizedRecipe.factionateType)
{
int timeSpend = value.oriProto.TimeSpend;
if (timeSpend > 0)
{
value.time = (double)timeSpend / 60.0;
}
}
}
}
public static void BreakForcedLoops(SolutionTree tree)
{
//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Expected O, but got Unknown
UserPreference userPreference = tree.userPreference;
if (autoRaw == null)
{
autoRaw = new HashSet<ItemConfig>();
}
foreach (ItemConfig value4 in userPreference.itemConfigs.Values)
{
if (autoRaw.Remove(value4))
{
value4.consideredAsOre = false;
}
}
foreach (ItemConfig item in new List<ItemConfig>(userPreference.itemConfigs.Values))
{
if (item.recipeID <= 0 || IsRaw(userPreference, item.ID) || !CalcDB.recipeDict.TryGetValue(item.recipeID, out var value))
{
continue;
}
List<int> list = new List<int>();
bool flag = false;
for (int i = 0; i < value.resources.Length; i++)
{
int num = value.resources[i];
if (value.resourceCounts[i] > 0 && !IsRaw(userPreference, num) && MustNeed(userPreference, num, item.ID, new HashSet<int>(), new HashSet<int>()))
{
list.Add(num);
if (userPreference.itemConfigs.TryGetValue(num, out var value2) && value2.forceNotOre)
{
flag = true;
}
}
}
if (list.Count == 0)
{
continue;
}
if (flag)
{
if (!item.forceNotOre && !IsTarget(tree, item.ID))
{
item.consideredAsOre = true;
autoRaw.Add(item);
}
continue;
}
foreach (int item2 in list)
{
if (!userPreference.itemConfigs.TryGetValue(item2, out var value3))
{
value3 = new ItemConfig(item2);
userPreference.itemConfigs[item2] = value3;
}
value3.consideredAsOre = true;
autoRaw.Add(value3);
}
}
}
private static bool IsTarget(SolutionTree tree, int itemId)
{
foreach (ItemTarget target in tree.targets)
{
if (target.itemId == itemId)
{
return true;
}
}
return false;
}
public static double ListedNeed(ItemNode n)
{
if (n.byProductRecipes.Count > 0 && n.speedFromOre <= 0.001 && n.satisfiedSpeed >= n.needSpeed - 0.001 && n.IsOre(n.solutionTree.userPreference))
{
return 0.0;
}
return n.needSpeed;
}
public static void MarkSharedRecipe(UIItemNode ui)
{
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Expected O, but got Unknown
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)ui.assemblerCountText == (Object)null || ui.itemNode == null || ui.itemNode.mainRecipe == null || ((UINode)ui).parentCalcWindow == null)
{
return;
}
UIItemNode val = null;
foreach (UIItemNode uiItemNode in ((UINode)ui).parentCalcWindow.uiItemNodes)
{
if (uiItemNode.itemNode != null && uiItemNode.itemNode.mainRecipe != null && uiItemNode.itemNode.mainRecipe.ID == ui.itemNode.mainRecipe.ID)
{
val = uiItemNode;
break;
}
}
UIButton val2 = (UIButton)ui.assemblerCountTextObj.GetComponent(typeof(UIButton));
string text = ui.assemblerCountText.text;
bool flag = text.StartsWith("(");
if (val == null || val == ui)
{
if (flag)
{
ui.assemblerCountText.text = text.Substring(1, text.Length - 2);
}
((Graphic)ui.assemblerCountText).color = UICalcWindow.TextWhiteColor;
return;
}
if (!flag)
{
ui.assemblerCountText.text = "(" + text + ")";
}
Color textWhiteColor = UICalcWindow.TextWhiteColor;
((Graphic)ui.assemblerCountText).color = new Color(textWhiteColor.r, textWhiteColor.g, textWhiteColor.b, 0.45f);
if ((Object)(object)val2 != (Object)null)
{
val2.tips.tipTitle = "Shared machines";
val2.tips.tipText = "Same " + ((Proto)ui.itemNode.mainRecipe.recipeNorm.oriProto).name + " machines as the " + Utils.GetItemName(val.itemNode.itemId) + " row. Build them once.";
}
}
private static void AddSourceCard(UICalcWindow w, int focusItem, Sprite icon, double speed, string title, string text)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Expected O, but got Unknown
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
UIItemNodeSimple val = new UIItemNodeSimple(new ItemNode(focusItem, 0.0, w.solution), false, w, false, false);
val.outputText.text = Utils.KMG(speed);
Transform obj = ((UINode)val).obj.transform.Find("icon");
((Image)((Component)obj).GetComponent(typeof(Image))).sprite = icon;
UIButton val2 = (UIButton)((Component)obj).GetComponent(typeof(UIButton));
val2.tips.itemId = 0;
val2.tips.tipTitle = title;
val2.tips.tipText = text;
val2.tips.width = 220;
w.uiSideItemNodes.Add((UINode)(object)val);
}
public static void AddSourcesSection(UICalcWindow w)
{
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Expected O, but got Unknown
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Expected O, but got Unknown
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Expected O, but got Unknown
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Expected O, but got Unknown
//IL_0143: Unknown result type (might be due to invalid IL or missing references)
//IL_014d: Expected O, but got Unknown
//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: Expected O, but got Unknown
//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
//IL_02bd: Expected O, but got Unknown
//IL_0273: Unknown result type (might be due to invalid IL or missing references)
//IL_027d: Expected O, but got Unknown
if (w.solution == null || w.solution.itemNodes == null || w.uiSideItemNodes == null)
{
return;
}
bool flag = false;
foreach (ItemNode value in w.solution.itemNodes.Values)
{
if (value.byProductRecipes.Count == 0)
{
continue;
}
List<RecipeInfo> list = new List<RecipeInfo>();
if (value.mainRecipe != null && value.mainRecipe.count > 0.001)
{
list.Add(value.mainRecipe);
}
foreach (RecipeInfo byProductRecipe in value.byProductRecipes)
{
list.Add(byProductRecipe);
}
bool flag2 = value.speedFromOre > 0.001;
if (list.Count + (flag2 ? 1 : 0) < 2)
{
continue;
}
if (!flag)
{
while (w.uiSideItemNodes.Count % 3 != 0)
{
w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("", w));
}
w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("Item sources", w));
w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("", w));
w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("", w));
flag = true;
}
UIItemNodeSimple val = new UIItemNodeSimple(value, false, w, false, false);
val.outputText.text = Utils.KMG(value.satisfiedSpeed);
w.uiSideItemNodes.Add((UINode)(object)val);
string itemName = Utils.GetItemName(value.itemId);
foreach (RecipeInfo item in list)
{
if (w.uiSideItemNodes.Count % 3 == 0)
{
w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("", w));
}
NormalizedRecipe recipeNorm = item.recipeNorm;
AddSourceCard(w, (recipeNorm.products.Length != 0) ? recipeNorm.products[0] : value.itemId, recipeNorm.oriProto.iconSprite, item.GetOutputSpeedByItemId(value.itemId), ((Proto)recipeNorm.oriProto).name, itemName + " from this recipe" + ((item == value.mainRecipe) ? " (main product)" : " (by-product)"));
}
if (flag2)
{
if (w.uiSideItemNodes.Count % 3 == 0)
{
w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("", w));
}
AddSourceCard(w, value.itemId, UIItemNodeSimple.oreSprite, value.speedFromOre, "Raw", itemName + " supplied from outside (Raw Resources Demands)");
}
while (w.uiSideItemNodes.Count % 3 != 0)
{
w.uiSideItemNodes.Add((UINode)new UIItemNodeSimple("", w));
}
}
}
public static void GBPreferMainOutputRecipes()
{
if (!CompatManager.GB)
{
return;
}
foreach (KeyValuePair<int, ItemData> item2 in CalcDB.itemDict)
{
List<NormalizedRecipe> recipes = item2.Value.recipes;
if (recipes.Count < 2 || (recipes[0].products.Length != 0 && recipes[0].products[0] == item2.Key))
{
continue;
}
for (int i = 1; i < recipes.Count; i++)
{
if (recipes[i].products.Length != 0 && recipes[i].products[0] == item2.Key && !Patches.IsAlternative(recipes[i]))
{
NormalizedRecipe item = recipes[i];
recipes.RemoveAt(i);
recipes.Insert(0, item);
break;
}
}
}
}
private static bool GBFilterAccepts(int machineType, int recipeType)
{
switch (machineType)
{
case 12:
if (recipeType != 2 && recipeType != 3 && recipeType != 4 && recipeType != 5 && recipeType != 9 && recipeType != 10 && recipeType != 15)
{
return recipeType == 16;
}
return true;
case 17:
if (recipeType != 2 && recipeType != 3)
{
return recipeType == 16;
}
return true;
case 18:
if (recipeType != 4)
{
return recipeType == 9;
}
return true;
case 19:
if (recipeType != 1 && recipeType != 11)
{
return recipeType == 13;
}
return true;
default:
return false;
}
}
public static void AddGBFilterMachines()
{
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected I4, but got Unknown
if (!CompatManager.GB)
{
return;
}
ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray;
foreach (ItemProto val in dataArray)
{
if (val == null)
{
continue;
}
PrefabDesc val2 = ((ProtoSet<ModelProto>)(object)LDB.models).Select(val.ModelIndex)?.prefabDesc;
if (val2 == null || !val2.isAssembler || !CalcDB.assemblerDict.TryGetValue(((Proto)val).ID, out var value))
{
continue;
}
int machineType = (int)val2.assemblerRecipeType;
foreach (KeyValuePair<int, List<AssemblerData>> item in CalcDB.assemblerListByType)
{
if (GBFilterAccepts(machineType, item.Key) && !item.Value.Contains(value))
{
item.Value.Add(value);
}
}
}
}
private static double Multiplier(RecipeInfo r, double baseMultiplier)
{
return baseMultiplier + r.bonusFactor - 1.0;
}
private static double BaseMultiplier(RecipeInfo r, int itemId)
{
double num = 1.0 + r.CalcOutputDiracInc(itemId) + r.bonusInc;
int incLevel = r.incLevel;
if (r.isInc && incLevel >= 0 && incLevel < Cargo.incTableMilli.Length)
{
num += Utils.GetIncMilli(incLevel, r.userPreference);
}
return num;
}
private static bool Inferior(RecipeInfo r, int itemId, int firstProduct)
{
if (r.userPreference.inferior && itemId == 1501 && firstProduct == 1501)
{
return !r.useIA;
}
return false;
}
public static double CalcCountByOutputSpeed(RecipeInfo r, int itemId, double speed)
{
if (!r.productIndices.TryGetValue(itemId, out var value))
{
return 0.0;
}
NormalizedRecipe recipeNorm = r.recipeNorm;
if (Inferior(r, itemId, recipeNorm.products[0]))
{
speed = speed * (double)recipeNorm.productCounts[0] / (double)(recipeNorm.productCounts[0] + 1);
}
return speed / (double)recipeNorm.productCounts[value] * recipeNorm.time / Multiplier(r, BaseMultiplier(r, itemId));
}
public static double GetOutputSpeedByChangedCount(RecipeInfo r, int itemId, double changedCount)
{
if (!r.productIndices.TryGetValue(itemId, out var value))
{
Utils.logger.LogWarning((object)("Output requested for item " + itemId + " that recipe " + r.ID + " does not produce."));
return 0.0;
}
NormalizedRecipe recipeNorm = r.recipeNorm;
return (Inferior(r, itemId, recipeNorm.products[0]) ? ((double)(recipeNorm.productCounts[0] + 1) / (double)recipeNorm.productCounts[0]) : 1.0) * changedCount * (double)recipeNorm.productCounts[value] / recipeNorm.time * Multiplier(r, BaseMultiplier(r, itemId));
}
public static double GetOutputSpeedOriProto(RecipeInfo r, int index, double changedCount)
{
RecipeProto oriProto = r.recipeNorm.oriProto;
int itemId = oriProto.Results[index];
return (Inferior(r, itemId, oriProto.Results[0]) ? ((double)(oriProto.ResultCounts[0] + 1) / (double)oriProto.ResultCounts[0]) : 1.0) * changedCount * (double)oriProto.ResultCounts[index] / r.recipeNorm.time * Multiplier(r, BaseMultiplier(r, itemId));
}
}
public static class RecipeUpdates
{
private static readonly FieldInfo PowerFactor = typeof(RecipeProto).GetField("PowerFactor");
public static int PickerColumns()
{
if (!CompatManager.GB)
{
return 14;
}
return 17;
}
public static int PickerRows()
{
if (!CompatManager.GB)
{
return 8;
}
return 7;
}
public static int ProliferatorCount()
{
return CalcDB.proliferatorItemIds.Count;
}
public static bool ValidRecipe(RecipeProto r)
{
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Invalid comparison between Unknown and I4
if (r == null || r.Items == null || r.ItemCounts == null || r.Results == null || r.ResultCounts == null || r.Items.Length != r.ItemCounts.Length || r.Results.Length != r.ResultCounts.Length || r.Results.Length == 0 || r.TimeSpend <= 0)
{
return false;
}
for (int i = 0; i < r.Items.Length; i++)
{
if (r.ItemCounts[i] <= 0 || ((ProtoSet<ItemProto>)(object)LDB.items).Select(r.Items[i]) == null)
{
return false;
}
}
for (int j = 0; j < r.Results.Length; j++)
{
if (r.ResultCounts[j] <= 0 || ((ProtoSet<ItemProto>)(object)LDB.items).Select(r.Results[j]) == null)
{
return false;
}
}
if ((int)r.Type == 8 && (r.Items.Length != 1 || r.Results.Length != 1 || r.ResultCounts[0] > r.ItemCounts[0] || r.Items[0] == r.Results[0]))
{
return false;
}
return true;
}
public static bool ContextDependent(RecipeProto r)
{
if (CompatManager.GB)
{
return ((Proto)r).ID == 429;
}
return false;
}
public static void CompleteCatalog()
{
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected O, but got Unknown
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected I4, but got Unknown
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Invalid comparison between Unknown and I4
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Expected O, but got Unknown
RecipeProto[] dataArray = ((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray;
foreach (RecipeProto val in dataArray)
{
if (!ValidRecipe(val) || CalcDB.recipeDict.ContainsKey(((Proto)val).ID) || (val.Results.Length == 1 && val.Results[0] == 9500) || (val.Items.Length == 0 && !ContextDependent(val)))
{
continue;
}
NormalizedRecipe val2 = new NormalizedRecipe(val);
CalcDB.recipeDict[((Proto)val).ID] = val2;
int num = (int)val.Type;
if (!CalcDB.assemblerListByType.ContainsKey(num))
{
CalcDB.assemblerListByType[num] = new List<AssemblerData>();
}
ItemProto[] dataArray2 = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray;
foreach (ItemProto val3 in dataArray2)
{
if (val3 == null)
{
continue;
}
PrefabDesc val4 = ((ProtoSet<ModelProto>)(object)LDB.models).Select(val3.ModelIndex)?.prefabDesc;
if (val4 != null && (val4.isFractionator || val4.isAssembler) && (int)val4.assemblerRecipeType == num)
{
if (!CalcDB.assemblerDict.TryGetValue(((Proto)val3).ID, out var value))
{
value = new AssemblerData(val3, val4);
CalcDB.assemblerDict[((Proto)val3).ID] = value;
}
if (val4.isFractionator)
{
value.speed = CalcDB.maxBeltItemSpeedPreSec * CalcDB.maxStackSize;
}
CalcDB.assemblerListByType[num].Add(value);
}
}
if (ContextDependent(val))
{
int[] products = val2.products;
foreach (int key in products)
{
CalcDB.itemDict[key].defaultAsOre = true;
}
}
}
foreach (List<AssemblerData> value2 in CalcDB.assemblerListByType.Values)
{
HashSet<int> hashSet = new HashSet<int>();
for (int k = 0; k < value2.Count; k++)
{
if (!hashSet.Add(value2[k].ID))
{
value2.RemoveAt(k--);
}
}
}
CalcFixes.AddGBFilterMachines();
CalcFixes.GBPreferMainOutputRecipes();
WriteCatalog();
}
public static bool ValidateSelection(SolutionTree tree)
{
CalcFixes.SyncRecipeTimes();
CalcFixes.BreakForcedLoops(tree);
foreach (ItemConfig value3 in tree.userPreference.itemConfigs.Values)
{
if (!value3.consideredAsOre && value3.forceNotOre && value3.recipeID > 0 && CalcDB.recipeDict.TryGetValue(value3.recipeID, out var value) && ContextDependent(value.oriProto))
{
UIRealtimeTip.Popup("GenesisBook material recovery depends on incoming trash, power and free inventory space; it has no fixed input ratio.", true, 0);
return false;
}
}
foreach (ItemConfig value4 in tree.userPreference.itemConfigs.Values)
{
if (!value4.consideredAsOre && value4.forceNotOre && value4.recipeID <= 0 && CalcDB.itemDict.TryGetValue(value4.ID, out var value2) && value2.recipes.Count != 0 && ContextDependent(value2.recipes[0].oriProto))
{
UIRealtimeTip.Popup("GenesisBook material recovery is a context-dependent recycling process. Supply its output externally.", true, 0);
return false;
}
}
return true;
}
public static double ExtraPower(RecipeInfo recipe, double existing)
{
if (!CompatManager.GB || recipe.useIA || PowerFactor == null)
{
return existing;
}
int num = (int)PowerFactor.GetValue(recipe.recipeNorm.oriProto);
if (num < 2)
{
return existing;
}
ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(recipe.assemblerItemId);
PrefabDesc val2 = ((val == null) ? null : ((ProtoSet<ModelProto>)(object)LDB.models).Select(val.ModelIndex))?.prefabDesc;
if (val2 == null || !val2.isAssembler)
{
return existing;
}
int incLevel = recipe.incLevel;
double num2 = ((incLevel >= 0 && incLevel < Cargo.powerTableRatio.Length) ? Utils.GetPowerRatio(incLevel, recipe.userPreference) : 1.0);
int num3 = val2.assemblerSpeed;
if (!recipe.isInc && incLevel >= 0 && incLevel < Cargo.accTableMilli.Length)
{
num3 = (int)((double)num3 * (1.0 + Utils.GetAccMilli(incLevel, recipe.userPreference)));
}
long num4 = (long)num3 * (long)num / 2;
return existing + recipe.assemblerCount * (double)num4 * 60.0 * num2;
}
public static double FractionatorSpray(RecipeInfo recipe, double existing)
{
if (recipe.recipeNorm.type != NormalizedRecipe.factionateType)
{
return existing;
}
RecipeProto oriProto = recipe.recipeNorm.oriProto;
return existing / (double)oriProto.ItemCounts[0];
}
private static string Join(int[] values)
{
string text = "";
for (int i = 0; i < values.Length; i++)
{
text = text + ((i == 0) ? "" : ";") + values[i];
}
return text;
}
private static void WriteCatalog()
{
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Expected I4, but got Unknown
try
{
using StreamWriter streamWriter = new StreamWriter(Path.Combine(Path.GetDirectoryName(typeof(DSPCalculatorPlugin).Assembly.Location), "DSPCalculator-recipes.csv"), append: false, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true));
streamWriter.WriteLine("id,name,type,seconds,input_ids,input_counts,output_ids,output_counts,productive,power_factor,in_calculator,context_dependent");
RecipeProto[] dataArray = ((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray;
foreach (RecipeProto val in dataArray)
{
if (val != null && val.Items != null && val.Results != null)
{
string[] array = new string[23]
{
((Proto)val).ID.ToString(),
",\"",
(((Proto)val).name ?? ((Proto)val).Name ?? "").Replace("\"", "\"\""),
"\",",
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null
};
array[4] = ((int)val.Type).ToString();
array[5] = ",";
array[6] = ((double)val.TimeSpend / 60.0).ToString("R", CultureInfo.InvariantCulture);
array[7] = ",";
array[8] = Join(val.Items);
array[9] = ",";
array[10] = Join(val.ItemCounts ?? new int[0]);
array[11] = ",";
array[12] = Join(val.Results);
array[13] = ",";
array[14] = Join(val.ResultCounts ?? new int[0]);
array[15] = ",";
array[16] = val.productive.ToString();
array[17] = ",";
array[18] = ((!(PowerFactor == null)) ? ((int)PowerFactor.GetValue(val)) : 0).ToString();
array[19] = ",";
array[20] = CalcDB.recipeDict.ContainsKey(((Proto)val).ID).ToString();
array[21] = ",";
array[22] = ContextDependent(val).ToString();
streamWriter.WriteLine(string.Concat(array));
}
}
}
catch (Exception ex)
{
Utils.logger.LogWarning((object)("Could not write recipe audit: " + ex.Message));
}
}
}
namespace CalculatorPatch
{
[BepInPlugin("bug.dsp.calculatorpatch", "BUG_CalculatorPatch", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin, IModCanSave
{
public const string Guid = "bug.dsp.calculatorpatch";
public const string Calculator = "com.GniMaerd.DSPCalculator";
public const string OreEnrichment = "bug.dsp.oreenrichment";
internal static ManualLogSource Log;
internal static bool Active;
private void Awake()
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
if (typeof(CalcDB).Assembly.GetType("RecipeUpdates") != null)
{
Log.LogInfo((object)"DSPCalculator already contains these fixes, nothing patched");
return;
}
PluginInfo value;
string text = (Chainloader.PluginInfos.TryGetValue("com.GniMaerd.DSPCalculator", out value) ? value.Metadata.Version.ToString() : "?");
Harmony val = new Harmony("bug.dsp.calculatorpatch");
try
{
val.PatchAll(typeof(Patches));
Active = true;
Log.LogInfo((object)("DSPCalculator " + text + " patched"));
}
catch (Exception ex)
{
val.UnpatchSelf();
Log.LogError((object)("DSPCalculator " + text + " is not the version these fixes were written for (0.5.25); it is left as it is. " + ex));
}
}
public void Export(BinaryWriter w)
{
if (Active)
{
CalcFixes.SaveWindows(w);
}
else
{
w.Write(0);
}
}
public void Import(BinaryReader r)
{
if (Active)
{
CalcFixes.LoadWindows(r);
}
}
public void IntoOtherSave()
{
if (Active)
{
CalcFixes.ClearPendingWindows();
}
}
}
public static class Patches
{
[ThreadStatic]
private static bool proliferatorLineFailed;
internal static bool Enrichment => Chainloader.PluginInfos.ContainsKey("bug.dsp.oreenrichment");
[HarmonyPrefix]
[HarmonyPatch(typeof(CalcDB), "TryInit")]
private static void BeforeInit()
{
CalcDB.maxBeltItemSpeedPreSec = 0.0;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(CalcDB), "TryInit")]
private static void AfterInit()
{
List<int> list = (CalcDB.proliferatorItemIds = NativeProliferatorItems());
CalcDB.proliferatorAbilitiesMap = new Dictionary<int, int>();
CalcDB.proliferatorAbilityToId = new Dictionary<int, int>();
foreach (int item in list)
{
CalcDB.proliferatorAbilitiesMap[item] = 0;
ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(item);
if (val != null)
{
if (val.Ability > 10)
{
CalcDB.proliferatorAbilitiesMap[item] = 10;
}
else if (val.Ability >= 0)
{
CalcDB.proliferatorAbilitiesMap[item] = val.Ability;
}
CalcDB.proliferatorAbilityToId[val.Ability] = ((Proto)val).ID;
}
}
RecipeUpdates.CompleteCatalog();
KeepAlternativesLast();
}
public static List<int> NativeProliferatorItems()
{
List<int> list = new List<int> { 1141, 1142, 1143 };
HashSet<int> hashSet = new HashSet<int>();
foreach (int item in list)
{
ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(item);
if (val != null)
{
hashSet.Add(val.Ability);
}
}
ModelProto[] dataArray = ((ProtoSet<ModelProto>)(object)LDB.models).dataArray;
for (int i = 0; i < dataArray.Length; i++)
{
int[] array = dataArray[i]?.prefabDesc?.incItemId;
if (array == null)
{
continue;
}
int[] array2 = array;
foreach (int num in array2)
{
ItemProto val2 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(num);
if (val2 != null && val2.Ability > 0 && val2.Ability <= 10 && val2.Ability < Cargo.accTableMilli.Length && val2.Ability < Cargo.incTableMilli.Length && val2.Ability < Cargo.powerTableRatio.Length && !list.Contains(num) && hashSet.Add(val2.Ability))
{
list.Add(num);
}
}
}
return list;
}
public static bool IsEnrichmentRecipe(int recipeId)
{
if ((recipeId <= 7000 || recipeId >= 9000) && (recipeId < 9501 || recipeId > 9547) && (recipeId < 9601 || recipeId > 9699))
{
if (recipeId > 10000)
{
return recipeId < 12000;
}
return false;
}
return true;
}
public static bool IsAlternative(NormalizedRecipe r)
{
if (Enrichment)
{
return IsEnrichmentRecipe(r.ID);
}
return false;
}
private static void KeepAlternativesLast()
{
if (!Enrichment)
{
return;
}
int num = 0;
foreach (ItemData value in CalcDB.itemDict.Values)
{
List<NormalizedRecipe> list = new List<NormalizedRecipe>();
List<NormalizedRecipe> list2 = new List<NormalizedRecipe>();
foreach (NormalizedRecipe recipe in value.recipes)
{
(IsEnrichmentRecipe(recipe.ID) ? list2 : list).Add(recipe);
}
if (list2.Count != 0 && list.Count != 0)
{
bool flag = true;
for (int i = 0; i < list.Count; i++)
{
flag &= value.recipes[i] == list[i];
}
if (!flag)
{
value.recipes.Clear();
value.recipes.AddRange(list);
value.recipes.AddRange(list2);
num++;
}
}
}
Plugin.Log.LogInfo((object)("BUG_OreEnrichment found: its alternative recipes are listed after the normal ones (" + num + " items reordered)"));
}
[HarmonyPrefix]
[HarmonyPatch(typeof(RecipeInfo), "CalcCountByOutputSpeed")]
private static bool CountByOutput(RecipeInfo __instance, int itemId, double speed, ref double __result)
{
__result = CalcFixes.CalcCountByOutputSpeed(__instance, itemId, speed);
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(RecipeInfo), "GetOutputSpeedByChangedCount")]
private static bool OutputByCount(RecipeInfo __instance, int itemId, double changedCount, ref double __result)
{
__result = CalcFixes.GetOutputSpeedByChangedCount(__instance, itemId, changedCount);
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(RecipeInfo), "GetOutputSpeedOriProto")]
private static bool OutputOriProto(RecipeInfo __instance, int index, double changedCount, ref double __result)
{
__result = CalcFixes.GetOutputSpeedOriProto(__instance, index, changedCount);
return false;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(RecipeInfo), "GetTotalEnergyConsumption")]
private static void Power(RecipeInfo __instance, ref double __result)
{
__result = RecipeUpdates.ExtraPower(__instance, __result);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(RecipeInfo), "GetProliferatorUsed")]
private static void Spray(RecipeInfo __instance, ref double proliferatorCount)
{
proliferatorCount = RecipeUpdates.FractionatorSpray(__instance, proliferatorCount);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(SolutionTree), "Solve")]
private static bool BeforeSolve(SolutionTree __instance, ref bool __result)
{
proliferatorLineFailed = false;
if (RecipeUpdates.ValidateSelection(__instance))
{
return true;
}
__result = false;
return false;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(SolutionTree), "CalcProliferatorInProductLine")]
private static void ProliferatorLine(bool __result)
{
proliferatorLineFailed |= !__result;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(SolutionTree), "Solve")]
private static void AfterSolve(SolutionTree __instance, ref bool __result)
{
if (__result && proliferatorLineFailed && __instance.userPreference.solveProliferators)
{
__result = false;
}
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(SolutionTree), "CalcProliferatorInProductLine")]
private static IEnumerable<CodeInstruction> ProliferatorCount(IEnumerable<CodeInstruction> instructions)
{
int found = 0;
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Ldc_I4_3)
{
found++;
yield return CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(RecipeUpdates), "ProliferatorCount", (Type[])null, (Type[])null)), (IEnumerable<Label>)instruction.labels);
}
else
{
yield return instruction;
}
}
if (found != 9)
{
throw new InvalidOperationException("proliferator matrix: " + found + " sizes instead of 9");
}
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(RecipePickerPatcher), "RecipePickerPrefix")]
private static IEnumerable<CodeInstruction> PickerGrid(IEnumerable<CodeInstruction> instructions)
{
int rows = 0;
int columns = 0;
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Ldc_I4_8)
{
rows++;
yield return CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(RecipeUpdates), "PickerRows", (Type[])null, (Type[])null)), (IEnumerable<Label>)instruction.labels);
}
else if (instruction.opcode == OpCodes.Ldc_I4_S && Convert.ToInt32(instruction.operand) == 14)
{
columns++;
yield return CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(RecipeUpdates), "PickerColumns", (Type[])null, (Type[])null)), (IEnumerable<Label>)instruction.labels);
}
else
{
yield return instruction;
}
}
if (rows != 1 || columns != 2)
{
throw new InvalidOperationException("recipe picker grid: " + rows + " row and " + columns + " column sizes instead of 1 and 2");
}
}
[HarmonyTranspiler]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static IEnumerable<CodeInstruction> AssemblyButton(IEnumerable<CodeInstruction> instructions)
{
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
FieldInfo objB = AccessTools.Field(typeof(CompatManager), "GB");
int num = list.FindIndex((CodeInstruction c) => c.opcode == OpCodes.Ldc_R4 && c.operand is float num4 && num4 == 415f);
int num2 = -1;
int num3 = num;
while (num3 >= 0 && num2 < 0)
{
if (list[num3].opcode == OpCodes.Ldsfld && object.Equals(list[num3].operand, objB))
{
num2 = num3;
}
num3--;
}
if (num < 0 || num2 < 0 || num - num2 > 12)
{
throw new InvalidOperationException("interstellar assembly button placement not found");
}
list[num2] = CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Ldc_I4_0, (object)null), (IEnumerable<Label>)list[num2].labels);
return list;
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(UICalcWindow), "RefreshProductContent")]
private static IEnumerable<CodeInstruction> ListedNeed(IEnumerable<CodeInstruction> instructions)
{
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
FieldInfo objB = AccessTools.Field(typeof(ItemNode), "needSpeed");
int num = 0;
for (int i = 2; i + 2 < list.Count; i++)
{
if ((list[i - 2].opcode == OpCodes.Brtrue_S || list[i - 2].opcode == OpCodes.Brtrue) && list[i].opcode == OpCodes.Ldfld && object.Equals(list[i].operand, objB) && list[i + 1].opcode == OpCodes.Ldc_R8 && list[i + 2].opcode == OpCodes.Cgt)
{
list[i] = CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(CalcFixes), "ListedNeed", (Type[])null, (Type[])null)), (IEnumerable<Label>)list[i].labels);
num++;
}
}
if (num != 2)
{
throw new InvalidOperationException("product list demand checks: " + num + " instead of 2");
}
return list;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UICalcWindow), "RefreshResourceNeedAndByProductContent")]
private static void Sources(UICalcWindow __instance)
{
CalcFixes.AddSourcesSection(__instance);
}
[HarmonyPostfix]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static void IncSwitchInside(UIItemNode __instance)
{
CalcFixes.FitIncSwitch(__instance);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIItemNode), "RefreshAssemblerDisplay")]
private static void SharedRecipe(UIItemNode __instance)
{
CalcFixes.MarkSharedRecipe(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(WindowsManager), "OnUpdate")]
private static void PendingWindows()
{
CalcFixes.ApplyPendingWindows();
}
}
}