using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[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("DSP-RecipeSlots")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+328be68d533c2fb4665ba9a6b02bb6f97ece069e")]
[assembly: AssemblyProduct("DSP-RecipeSlots")]
[assembly: AssemblyTitle("DSP-RecipeSlots")]
[assembly: AssemblyVersion("1.2.0.0")]
[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;
}
}
}
namespace DSPRecipeSlots
{
[HarmonyPatch(typeof(UIAssemblerWindow), "_OnUpdate")]
internal static class AssemblerUiPatch
{
private sealed class Slot
{
public GameObject Root;
public Image Icon;
public Text Count;
public Image Progress;
public Image ExtraProgress;
public Button Button;
public UIButton Tips;
}
private sealed class WinState
{
public readonly List<Slot> Extras = new List<Slot>();
public readonly List<Slot> GridProducts = new List<Slot>();
public readonly List<Slot> Inputs = new List<Slot>();
public int ServingCols;
public bool Multi;
}
private static readonly Dictionary<UIAssemblerWindow, WinState> Cache = new Dictionary<UIAssemblerWindow, WinState>();
private static bool _errorLogged;
private const float SlotSize = 64f;
private const float RowH = 72f;
private const int InPerRow = 6;
private const int OutPerRow = 6;
private const int MultiOutTrigger = 4;
[HarmonyPostfix]
private static void Postfix(UIAssemblerWindow __instance)
{
try
{
Update(__instance);
}
catch (Exception ex)
{
if (!_errorLogged)
{
_errorLogged = true;
Plugin.Log.LogError((object)("[ui] assembler window patch failed: " + ex));
}
}
}
private static WinState GetState(UIAssemblerWindow w)
{
if (Cache.TryGetValue(w, out var value) && value != null)
{
return value;
}
value = new WinState();
Cache[w] = value;
return value;
}
private static void Update(UIAssemblerWindow w)
{
int assemblerId = w.assemblerId;
PlanetFactory val = GameMain.localPlanet?.factory;
if (val == null || assemblerId <= 0)
{
return;
}
ref AssemblerComponent reference = ref val.factorySystem.assemblerPool[assemblerId];
if (reference.id != assemblerId)
{
return;
}
RecipeExecuteData recipeExecuteData = reference.recipeExecuteData;
if (recipeExecuteData != null)
{
int num = recipeExecuteData.products.Length;
int num2 = recipeExecuteData.requires.Length;
WinState state = GetState(w);
if (state.Multi = num2 > 6 || num > 4)
{
ApplyMulti(w, ref reference, recipeExecuteData, num2, num, state);
}
else
{
ApplySingle(w, ref reference, recipeExecuteData, num2, num, state);
}
ClampWindow(w);
}
}
private static void ApplySingle(UIAssemblerWindow w, ref AssemblerComponent a, RecipeExecuteData data, int nIn, int nOut, WinState st)
{
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_0211: Unknown result type (might be due to invalid IL or missing references)
//IL_028b: Unknown result type (might be due to invalid IL or missing references)
//IL_02af: Unknown result type (might be due to invalid IL or missing references)
//IL_02be: Unknown result type (might be due to invalid IL or missing references)
HideAll(st.GridProducts);
HideAll(st.Inputs);
if ((Object)(object)w.productGroup != (Object)null)
{
((Component)w.productGroup).gameObject.SetActive(true);
}
if ((Object)(object)w.servingGroup != (Object)null)
{
((Component)w.servingGroup).gameObject.SetActive(true);
}
if ((Object)(object)w.servingBox != (Object)null)
{
int num = Mathf.Max(1, nIn);
if (st.ServingCols != num || w.servingBox.colCount != num)
{
st.ServingCols = num;
w.servingBox.colCount = num;
w.servingBox.OnStorageSizeChanged();
}
}
if (nOut > 2)
{
EnsureSlots(w, st.Extras, nOut - 2, input: false);
}
for (int i = 0; i < st.Extras.Count; i++)
{
int num2 = i + 2;
Slot slot = st.Extras[i];
if (!((Object)(object)slot.Root == (Object)null))
{
if (nOut <= num2)
{
slot.Root.SetActive(false);
continue;
}
slot.Root.SetActive(true);
RectTransform val = (RectTransform)slot.Root.transform;
val.anchoredPosition = new Vector2(19f + 64f * (float)num2, 0f);
val.sizeDelta = new Vector2(64f, 64f);
FillProduct(slot, a, data, num2, w);
}
}
if ((Object)(object)w.productGroup != (Object)null)
{
w.productGroup.sizeDelta = new Vector2(64f * (float)Math.Max(1, nOut), 64f);
}
float num3 = 64f * (float)(Math.Max(1, nOut) - 1);
if ((Object)(object)w.speedGroup != (Object)null)
{
w.speedGroup.anchoredPosition = new Vector2(80f + num3, 0f);
}
SetArrowDirection(w, down: false);
if ((Object)(object)w.servingGroup != (Object)null)
{
w.servingGroup.anchoredPosition = new Vector2(160f + num3, 0f);
}
float num4 = 50f * (float)Math.Max(1, nIn) + 4f;
float val2 = 160f + num3 + num4 + 24f;
float num5 = Math.Max(80f + (float)(((Object)(object)w.playerInventory != (Object)null) ? w.playerInventory.colCount : 10) * 50f, val2);
if ((Object)(object)w.windowTrans != (Object)null)
{
w.windowTrans.sizeDelta = new Vector2(num5, 420f);
}
if ((Object)(object)w.playerInventoryGroup != (Object)null)
{
w.playerInventoryGroup.anchoredPosition = new Vector2(w.playerInventoryGroup.anchoredPosition.x, -180f);
}
}
private static void ApplyMulti(UIAssemblerWindow w, ref AssemblerComponent a, RecipeExecuteData data, int nIn, int nOut, WinState st)
{
//IL_020d: 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_0149: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_0186: 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_0286: Unknown result type (might be due to invalid IL or missing references)
//IL_028b: Unknown result type (might be due to invalid IL or missing references)
//IL_0296: Unknown result type (might be due to invalid IL or missing references)
//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
//IL_0358: Unknown result type (might be due to invalid IL or missing references)
//IL_037c: Unknown result type (might be due to invalid IL or missing references)
//IL_0388: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)w.productGroup != (Object)null)
{
((Component)w.productGroup).gameObject.SetActive(false);
}
if ((Object)(object)w.servingGroup != (Object)null)
{
((Component)w.servingGroup).gameObject.SetActive(false);
}
HideAll(st.Extras);
int num = Mathf.Min(6, Mathf.Max(1, nIn));
int num2 = Mathf.CeilToInt((float)nIn / (float)num);
int num3 = Mathf.Max(1, Mathf.CeilToInt((float)nOut / 6f));
float num4 = -75f;
float num5 = num4 - (float)(num2 - 1) * 72f - 32f - 40f;
float num6 = num5 - 70f;
float num7 = num6 - (float)(num3 - 1) * 72f - 32f - 64f;
float num8 = 0f - num7 + 204f + 20f;
float num9 = (float)Mathf.Min(nIn, num) * 64f;
EnsureSlots(w, st.Inputs, nIn, input: true);
for (int i = 0; i < st.Inputs.Count; i++)
{
Slot slot = st.Inputs[i];
if (!((Object)(object)slot.Root == (Object)null))
{
if (i >= nIn)
{
slot.Root.SetActive(false);
continue;
}
slot.Root.SetActive(true);
RectTransform val = (RectTransform)slot.Root.transform;
val.sizeDelta = new Vector2(64f, 64f);
float num10 = num4 - (float)(i / num) * 72f;
val.anchoredPosition = new Vector2(19f + (float)(i % num) * 64f, num10 + 100f);
FillInput(slot, a, data, i);
}
}
float num11 = (float)Mathf.Min(nOut, 6) * 64f;
float num12 = Mathf.Max(Mathf.Max(num9, num11), 120f);
float num13 = 19f + num12 * 0.5f;
if ((Object)(object)w.speedGroup != (Object)null)
{
w.speedGroup.anchoredPosition = new Vector2(num13, num5 + 100f);
SetArrowDirection(w, down: true);
}
EnsureSlots(w, st.GridProducts, nOut, input: false);
for (int j = 0; j < st.GridProducts.Count; j++)
{
Slot slot2 = st.GridProducts[j];
if (!((Object)(object)slot2.Root == (Object)null))
{
if (j >= nOut)
{
slot2.Root.SetActive(false);
continue;
}
slot2.Root.SetActive(true);
RectTransform val2 = (RectTransform)slot2.Root.transform;
val2.sizeDelta = new Vector2(64f, 64f);
float num14 = num6 - (float)(j / 6) * 72f;
val2.anchoredPosition = new Vector2(19f + (float)(j % 6) * 64f, num14 + 100f);
FillProduct(slot2, a, data, j, w);
}
}
float num15 = 19f + num12 + 40f;
float num16 = Mathf.Max(80f + (float)(((Object)(object)w.playerInventory != (Object)null) ? w.playerInventory.colCount : 10) * 50f, num15);
if ((Object)(object)w.windowTrans != (Object)null)
{
w.windowTrans.sizeDelta = new Vector2(num16, num8);
}
if ((Object)(object)w.playerInventoryGroup != (Object)null)
{
w.playerInventoryGroup.anchoredPosition = new Vector2(w.playerInventoryGroup.anchoredPosition.x, num7);
}
}
private static void SetArrowDirection(UIAssemblerWindow w, bool down)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
if (w.speedArrows == null)
{
return;
}
Quaternion val = (down ? Quaternion.Euler(0f, 0f, 90f) : Quaternion.identity);
for (int i = 0; i < w.speedArrows.Length; i++)
{
Image val2 = w.speedArrows[i];
if (!((Object)(object)val2 == (Object)null))
{
Transform transform = ((Component)val2).transform;
if (transform.localRotation != val)
{
transform.localRotation = val;
}
}
}
}
private static void FillProduct(Slot s, AssemblerComponent a, RecipeExecuteData data, int idx, UIAssemblerWindow w)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
int num = data.products[idx];
ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(num);
if ((Object)(object)s.Icon != (Object)null)
{
s.Icon.sprite = ((val != null) ? val.iconSprite : null);
}
if ((Object)(object)s.Count != (Object)null)
{
s.Count.text = a.produced[idx].ToString();
}
if ((Object)(object)s.Button != (Object)null)
{
((Selectable)s.Button).interactable = a.produced[idx] > 0;
}
if ((Object)(object)s.Tips != (Object)null && val != null)
{
s.Tips.tips.itemId = num;
s.Tips.tips.itemInc = 0;
s.Tips.tips.itemCount = 0;
s.Tips.tips.type = (ItemTipType)0;
s.Tips.tips.corner = 2;
s.Tips.tips.delay = 0.2f;
}
if ((Object)(object)s.Progress != (Object)null)
{
s.Progress.fillAmount = (((Object)(object)w.productProgress0 != (Object)null) ? w.productProgress0.fillAmount : 0f);
}
if ((Object)(object)s.ExtraProgress != (Object)null)
{
s.ExtraProgress.fillAmount = (((Object)(object)w.extraProductProgress0 != (Object)null) ? w.extraProductProgress0.fillAmount : 0f);
}
}
private static void FillInput(Slot s, AssemblerComponent a, RecipeExecuteData data, int idx)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
int num = data.requires[idx];
ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(num);
if ((Object)(object)s.Icon != (Object)null)
{
s.Icon.sprite = ((val != null) ? val.iconSprite : null);
}
int num2 = ((a.served != null && idx < a.served.Length) ? a.served[idx] : 0);
if ((Object)(object)s.Count != (Object)null)
{
s.Count.text = num2.ToString();
}
if ((Object)(object)s.Button != (Object)null)
{
((Selectable)s.Button).interactable = false;
}
if ((Object)(object)s.Tips != (Object)null && val != null)
{
int num3 = ((data.requireCounts == null || idx >= data.requireCounts.Length) ? 1 : data.requireCounts[idx]);
s.Tips.tips.itemId = num;
s.Tips.tips.itemInc = 0;
s.Tips.tips.itemCount = 0;
s.Tips.tips.type = (ItemTipType)0;
s.Tips.tips.corner = 2;
s.Tips.tips.delay = 0.2f;
s.Tips.tips.tipText = num3 + " / 次";
}
}
private static void HideAll(List<Slot> list)
{
for (int i = 0; i < list.Count; i++)
{
if (list[i] != null && (Object)(object)list[i].Root != (Object)null)
{
list[i].Root.SetActive(false);
}
}
}
private static void EnsureSlots(UIAssemblerWindow w, List<Slot> list, int need, bool input)
{
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Expected O, but got Unknown
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Expected O, but got Unknown
if ((Object)(object)w.productGroup == (Object)null)
{
return;
}
Transform parent = ((Component)w.productGroup).transform.parent;
while (list.Count < need)
{
GameObject obj = Object.Instantiate<GameObject>(((Component)w.productGroup).gameObject, parent);
((Object)obj).name = (input ? "recipeslots-input-" : "recipeslots-product-") + list.Count;
Slot slot = BuildSlot(obj, input);
if (!input)
{
int captured = list.Count;
if ((Object)(object)slot.Button != (Object)null)
{
((UnityEventBase)slot.Button.onClick).RemoveAllListeners();
((UnityEvent)slot.Button.onClick).AddListener((UnityAction)delegate
{
TakeProduct(w, captured);
});
}
}
list.Add(slot);
}
if (input)
{
return;
}
for (int num = 0; num < list.Count; num++)
{
Button button = list[num].Button;
if (!((Object)(object)button == (Object)null))
{
int captured2 = num;
((UnityEventBase)button.onClick).RemoveAllListeners();
((UnityEvent)button.onClick).AddListener((UnityAction)delegate
{
TakeProduct(w, captured2);
});
}
}
}
private static Slot BuildSlot(GameObject go, bool input)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
Slot slot = new Slot
{
Root = go
};
Transform transform = go.transform;
RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
if ((Object)(object)val != (Object)null)
{
val.sizeDelta = new Vector2(64f, 64f);
}
HideChild(transform, "product-icon-1");
HideChild(transform, "circle-fg-1");
HideChild(transform, "extra-circle-fg-1");
HideChild(transform, "cnt-text-1");
HideChild(transform, "stop-btn");
if (input)
{
HideChild(transform, "circle-fg");
HideChild(transform, "extra-circle-fg");
}
Transform val2 = transform.Find("product-icon");
if ((Object)(object)val2 != (Object)null)
{
slot.Icon = ((Component)val2).GetComponent<Image>();
slot.Button = ((Component)val2).GetComponent<Button>();
slot.Tips = ((Component)val2).GetComponent<UIButton>();
}
Transform val3 = transform.Find("cnt-text");
if ((Object)(object)val3 != (Object)null)
{
slot.Count = ((Component)val3).GetComponent<Text>();
RectTransform val4 = (RectTransform)(object)((val3 is RectTransform) ? val3 : null);
if ((Object)(object)val4 != (Object)null)
{
val4.anchorMin = new Vector2(1f, 0f);
val4.anchorMax = new Vector2(1f, 0f);
val4.pivot = new Vector2(1f, 0f);
val4.anchoredPosition = new Vector2(-9f, 7f);
if ((Object)(object)slot.Count != (Object)null)
{
slot.Count.alignment = (TextAnchor)8;
}
}
if (input && (Object)(object)slot.Button != (Object)null)
{
((Selectable)slot.Button).transition = (Transition)0;
}
}
Transform val5 = transform.Find("circle-fg");
if ((Object)(object)val5 != (Object)null)
{
slot.Progress = ((Component)val5).GetComponent<Image>();
}
Transform val6 = transform.Find("extra-circle-fg");
if ((Object)(object)val6 != (Object)null)
{
slot.ExtraProgress = ((Component)val6).GetComponent<Image>();
}
return slot;
}
private static void HideChild(Transform t, string name)
{
Transform val = t.Find(name);
if ((Object)(object)val != (Object)null)
{
((Component)val).gameObject.SetActive(false);
}
}
internal static void DumpSlots(StringBuilder o)
{
//IL_0137: 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_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
foreach (KeyValuePair<UIAssemblerWindow, WinState> item in Cache)
{
UIAssemblerWindow key = item.Key;
WinState value = item.Value;
if (!((Object)(object)key == (Object)null) && value != null)
{
o.AppendLine(" assemblerId=" + key.assemblerId + " multi=" + value.Multi);
AppendRect(o, "window", key.windowTrans);
AppendRect(o, "productGroup", key.productGroup);
AppendRect(o, "produce", key.produceGroup);
AppendRect(o, "playerStorage", key.playerInventoryGroup);
o.AppendLine(" extras=" + Describe(value.Extras));
o.AppendLine(" gridProducts=" + Describe(value.GridProducts));
o.AppendLine(" inputs=" + Describe(value.Inputs));
RectTransform val = (RectTransform)(((Object)(object)key.windowTrans != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
if ((Object)(object)val != (Object)null)
{
Rect rect = val.rect;
o.AppendLine(" windowParent rect=" + ((object)((Rect)(ref rect)).size/*cast due to .constrained prefix*/).ToString() + " pos=" + ((object)((Transform)val).position/*cast due to .constrained prefix*/).ToString());
}
}
}
}
private static string Describe(List<Slot> list)
{
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01bb: 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_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_0178: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append('[');
for (int i = 0; i < list.Count; i++)
{
Slot slot = list[i];
if (i > 0)
{
stringBuilder.Append(',');
}
if (slot == null || (Object)(object)slot.Root == (Object)null)
{
stringBuilder.Append("null");
continue;
}
Transform transform = slot.Root.transform;
RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
StringBuilder stringBuilder2 = stringBuilder.Append(((Object)slot.Root).name).Append(slot.Root.activeSelf ? "" : "(off)").Append('@');
object value;
Vector2 val2;
if (!((Object)(object)val != (Object)null))
{
value = "?";
}
else
{
val2 = val.anchoredPosition;
value = ((Vector2)(ref val2)).ToString("F0");
}
stringBuilder2.Append((string?)value);
if ((Object)(object)slot.Count != (Object)null)
{
RectTransform rectTransform = ((Graphic)slot.Count).rectTransform;
StringBuilder stringBuilder3 = stringBuilder.Append(" cnt='").Append(slot.Count.text).Append("'")
.Append(((Component)slot.Count).gameObject.activeSelf ? "" : "(off)")
.Append(" a=");
val2 = rectTransform.anchorMin;
StringBuilder stringBuilder4 = stringBuilder3.Append(((Vector2)(ref val2)).ToString("F2")).Append(" p=");
val2 = rectTransform.pivot;
StringBuilder stringBuilder5 = stringBuilder4.Append(((Vector2)(ref val2)).ToString("F2")).Append(" pos=");
val2 = rectTransform.anchoredPosition;
stringBuilder5.Append(((Vector2)(ref val2)).ToString("F0"));
}
else
{
stringBuilder.Append(" cnt=null");
}
if ((Object)(object)val != (Object)null)
{
Vector3[] array = (Vector3[])(object)new Vector3[4];
val.GetWorldCorners(array);
Vector3 val3 = array[0];
stringBuilder.Append(" scr=").Append(((Vector3)(ref val3)).ToString("F0"));
}
}
stringBuilder.Append(']');
return stringBuilder.ToString();
}
private static void AppendRect(StringBuilder o, string name, RectTransform rt)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)rt == (Object)null)
{
o.AppendLine(" " + name + "=null");
return;
}
Vector3[] array = (Vector3[])(object)new Vector3[4];
rt.GetWorldCorners(array);
string[] obj = new string[16]
{
" ", name, " pos=", null, null, null, null, null, null, null,
null, null, null, null, null, null
};
Vector2 val = rt.anchoredPosition;
obj[3] = ((Vector2)(ref val)).ToString("F0");
obj[4] = " size=";
val = rt.sizeDelta;
obj[5] = ((Vector2)(ref val)).ToString("F0");
obj[6] = " anchor=";
val = rt.anchorMin;
obj[7] = ((Vector2)(ref val)).ToString("F2");
obj[8] = "/";
val = rt.anchorMax;
obj[9] = ((Vector2)(ref val)).ToString("F2");
obj[10] = " pivot=";
val = rt.pivot;
obj[11] = ((Vector2)(ref val)).ToString("F2");
obj[12] = " wMin=";
obj[13] = ((Vector3)(ref array[0])).ToString("F0");
obj[14] = " wMax=";
obj[15] = ((Vector3)(ref array[2])).ToString("F0");
o.AppendLine(string.Concat(obj));
}
internal static void ClampWindow(UIAssemblerWindow w)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: 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_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: 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_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: 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_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_0178: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)w == (Object)null || (Object)(object)w.windowTrans == (Object)null)
{
return;
}
Transform parent = ((Transform)w.windowTrans).parent;
RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
if ((Object)(object)val == (Object)null)
{
return;
}
RectTransform windowTrans = w.windowTrans;
Rect rect = val.rect;
float width = ((Rect)(ref rect)).width;
rect = val.rect;
float height = ((Rect)(ref rect)).height;
float x = windowTrans.sizeDelta.x;
float y = windowTrans.sizeDelta.y;
if (windowTrans.anchorMin.x == windowTrans.anchorMax.x && windowTrans.anchorMin.y == windowTrans.anchorMax.y)
{
Vector2 anchoredPosition = windowTrans.anchoredPosition;
float num = (0f - width) * 0.5f + x * windowTrans.pivot.x;
float num2 = width * 0.5f - x * (1f - windowTrans.pivot.x);
float num3 = (0f - height) * 0.5f + y * windowTrans.pivot.y;
float num4 = height * 0.5f - y * (1f - windowTrans.pivot.y);
float num5 = Mathf.Clamp(anchoredPosition.x, Mathf.Min(num, num2), Mathf.Max(num, num2));
float num6 = Mathf.Clamp(anchoredPosition.y, Mathf.Min(num3, num4), Mathf.Max(num3, num4));
if (Mathf.Abs(num5 - anchoredPosition.x) > 0.5f || Mathf.Abs(num6 - anchoredPosition.y) > 0.5f)
{
windowTrans.anchoredPosition = new Vector2(num5, num6);
}
}
}
internal static bool ClickProduct(int index)
{
UIRoot instance = UIRoot.instance;
UIAssemblerWindow val = (((Object)(object)instance != (Object)null && (Object)(object)instance.uiGame != (Object)null) ? instance.uiGame.assemblerWindow : null);
if ((Object)(object)val == (Object)null)
{
return false;
}
TakeProduct(val, index);
return true;
}
private static void TakeProduct(UIAssemblerWindow w, int index)
{
PlanetFactory val = GameMain.localPlanet?.factory;
Player mainPlayer = GameMain.mainPlayer;
if (val == null || mainPlayer == null)
{
return;
}
int assemblerId = w.assemblerId;
if (assemblerId <= 0)
{
return;
}
ref AssemblerComponent reference = ref val.factorySystem.assemblerPool[assemblerId];
if (reference.id != assemblerId || reference.recipeExecuteData == null)
{
return;
}
int[] products = reference.recipeExecuteData.products;
if (index >= 0 && index < products.Length && reference.produced[index] > 0 && mainPlayer.inhandItemId <= 0)
{
int num = mainPlayer.TryAddItemToPackage(products[index], reference.produced[index], 0, false, 0, false);
val.factorySystem.assemblerPool[assemblerId].produced[index] = 0;
if (num > 0)
{
UIItemup.Up(products[index], num);
}
}
}
}
internal static class DevChannel
{
internal static void Init(ConfigFile config)
{
}
internal static void Tick()
{
}
}
internal static class LabPatches
{
[HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")]
[HarmonyPriority(0)]
internal static class LabInitPatch
{
[HarmonyPostfix]
private static void Postfix()
{
try
{
ExtendMatrices();
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[lab] ExtendMatrices failed: " + ex));
}
}
}
[HarmonyPatch(typeof(FactorySystem), "GameTickLabResearchMode")]
internal static class LabMatrixRemapTickPatch
{
[HarmonyPostfix]
private static void Postfix()
{
try
{
GameHistoryData history = GameMain.history;
RemapMatrixPoints((history != null) ? history.currentTech : 0);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[lab] remap tick: " + ex));
}
}
}
[HarmonyPatch(typeof(GameHistoryData), "Import")]
internal static class LabMatrixRemapImportPatch
{
[HarmonyPostfix]
private static void Postfix(GameHistoryData __instance)
{
try
{
RemapMatrixPoints((__instance != null) ? __instance.currentTech : 0);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[lab] remap import: " + ex));
}
}
}
[HarmonyPatch(typeof(LabComponent), "SetFunction")]
internal static class LabNeedsResizePatch
{
[HarmonyPostfix]
private static void Postfix(ref LabComponent __instance)
{
try
{
if (__instance.researchMode)
{
return;
}
RecipeExecuteData recipeExecuteData = __instance.recipeExecuteData;
if (recipeExecuteData != null && recipeExecuteData.requires != null)
{
int num = Math.Max(6, recipeExecuteData.requires.Length);
if (__instance.needs == null || __instance.needs.Length != num)
{
__instance.needs = new int[num];
}
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[m2] lab resize needs: " + ex));
}
}
}
[HarmonyPatch(typeof(LabComponent), "UpdateNeedsResearch")]
internal static class LabUpdateNeedsResearchPatch
{
[HarmonyPostfix]
private static void Postfix(ref LabComponent __instance)
{
try
{
int[] matrixIds = LabComponent.matrixIds;
int[] array = __instance.matrixServed;
int[] matrixIncServed = __instance.matrixIncServed;
if (matrixIds == null || array == null)
{
return;
}
int num = matrixIds.Length;
if (__instance.needs == null || __instance.needs.Length != num)
{
__instance.needs = new int[num];
}
if (array.Length != num)
{
int[] array2 = new int[num];
Array.Copy(array, array2, Math.Min(array.Length, num));
__instance.matrixServed = array2;
array = array2;
}
if (matrixIncServed == null || matrixIncServed.Length != num)
{
int[] array3 = new int[num];
if (matrixIncServed != null)
{
Array.Copy(matrixIncServed, array3, Math.Min(matrixIncServed.Length, num));
}
__instance.matrixIncServed = array3;
}
int[] needs = __instance.needs;
for (int i = 0; i < num; i++)
{
needs[i] = ((array[i] < 36000) ? matrixIds[i] : 0);
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[lab] UpdateNeedsResearch patch: " + ex));
}
}
}
[HarmonyPatch(typeof(LabComponent), "UpdateNeedsAssemble")]
internal static class LabUpdateNeedsAssemblePatch
{
[HarmonyPostfix]
private static void Postfix(ref LabComponent __instance)
{
RecipeExecuteData recipeExecuteData = __instance.recipeExecuteData;
if (recipeExecuteData == null)
{
return;
}
int[] requires = recipeExecuteData.requires;
int[] needs = __instance.needs;
int[] served = __instance.served;
if (requires == null || needs == null || served == null)
{
return;
}
int num = requires.Length;
if (num <= 6)
{
return;
}
int num2 = ((recipeExecuteData.timeSpend > 5400000) ? 6 : (3 * ((__instance.speedOverride + 5001) / 10000) + 3));
int num3 = needs.Length;
int i = 0;
if (num3 >= num)
{
for (int j = 0; j < num; j++)
{
needs[j] = ((j < served.Length && served[j] < num2) ? requires[j] : 0);
}
for (int k = num; k < num3; k++)
{
needs[k] = 0;
}
return;
}
int num4 = (int)(GameMain.gameTick % num);
if (num4 < 0)
{
num4 += num;
}
for (int l = 0; l < num; l++)
{
if (i >= num3)
{
break;
}
int num5 = num4 + l;
if (num5 >= num)
{
num5 -= num;
}
if (num5 < served.Length && served[num5] < num2)
{
needs[i++] = requires[num5];
}
}
for (; i < num3; i++)
{
needs[i] = 0;
}
}
}
[HarmonyPatch(typeof(LabComponent), "InternalUpdateAssemble")]
internal static class LabInternalUpdateAssemblePatch
{
private const int ShaderStateLen = 10;
[HarmonyPostfix]
private static void Postfix(ref LabComponent __instance, ref uint __result)
{
try
{
if (__result == 0)
{
return;
}
RecipeExecuteData recipeExecuteData = __instance.recipeExecuteData;
if (recipeExecuteData != null && recipeExecuteData.products != null && recipeExecuteData.products.Length != 0)
{
int num = Array.IndexOf(LabComponent.matrixIds, recipeExecuteData.products[0]);
if (num >= 0)
{
__result = (uint)(num + 1);
}
if (__result >= 10)
{
__result = 0u;
}
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[lab] InternalUpdateAssemble patch: " + ex));
}
}
}
[HarmonyPatch(typeof(LabComponent), "InternalUpdateResearch")]
internal static class LabInternalUpdateResearchPatch
{
[HarmonyPrefix]
private static bool Prefix(ref LabComponent __instance, ref uint __result)
{
try
{
int[] matrixServed = __instance.matrixServed;
int[] matrixPoints = LabComponent.matrixPoints;
if (matrixServed == null || matrixPoints == null)
{
return true;
}
int num = Math.Min(matrixServed.Length, matrixPoints.Length);
for (int i = 0; i < num; i++)
{
if (matrixPoints[i] > 0 && matrixServed[i] < matrixPoints[i])
{
__instance.replicating = false;
__result = 0u;
return false;
}
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[lab] InternalUpdateResearch patch: " + ex));
}
return true;
}
}
[HarmonyPatch(typeof(LabComponent), "UpdateOutputToNext")]
internal static class LabUpdateOutputToNextPatch
{
[HarmonyPrefix]
private static bool Prefix(ref LabComponent __instance, LabComponent[] labPool)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
try
{
int[] matrixServed = __instance.matrixServed;
if (matrixServed == null || matrixServed.Length <= 6)
{
return true;
}
int nextLabId = __instance.nextLabId;
if (nextLabId <= 0 || nextLabId >= labPool.Length)
{
return true;
}
LabComponent val = labPool[nextLabId];
if (val.id == 0 || val.id != nextLabId)
{
__instance.nextLabId = 0;
return false;
}
if (val.needs == null || __instance.recipeId != val.recipeId || __instance.techId != val.techId)
{
return false;
}
int[] matrixServed2 = val.matrixServed;
int[] matrixIncServed = __instance.matrixIncServed;
int[] matrixIncServed2 = val.matrixIncServed;
int[] matrixIds = LabComponent.matrixIds;
if (matrixServed2 == null || matrixIncServed == null || matrixIncServed2 == null || matrixIds == null)
{
return false;
}
int num = Math.Min(Math.Min(matrixServed.Length, matrixServed2.Length), Math.Min(matrixIds.Length, val.needs.Length));
lock (matrixServed)
{
lock (matrixServed2)
{
for (int i = 0; i < num; i++)
{
if (val.needs[i] == matrixIds[i] && matrixServed[i] >= 7200)
{
int num2 = (matrixServed[i] - 7200) / 3600 * 3600;
if (num2 > 36000)
{
num2 = 36000;
}
int num3 = SplitInc(ref matrixServed[i], ref matrixIncServed[i], num2);
matrixIncServed2[i] += num3;
matrixServed2[i] += num2;
}
}
}
}
return false;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[lab] UpdateOutputToNext patch: " + ex));
return true;
}
}
private static int SplitInc(ref int n, ref int m, int p)
{
int num = m / n;
int num2 = m - num * n;
n -= p;
num2 -= n;
m -= ((num2 > 0) ? (num * p + num2) : (num * p));
return num;
}
}
internal static void ExtendMatrices()
{
string value = Plugin.LabExtraMatrixIds.Value;
if (string.IsNullOrWhiteSpace(value))
{
return;
}
List<int> list = new List<int>();
string[] array = value.Split(new char[1] { ',' });
for (int i = 0; i < array.Length; i++)
{
if (int.TryParse(array[i].Trim(), out var result) && result > 0)
{
list.Add(result);
}
}
if (list.Count == 0)
{
return;
}
int[] matrixIds = LabComponent.matrixIds;
if (matrixIds == null || matrixIds.Length == 0)
{
return;
}
List<int> list2 = new List<int>();
foreach (int item in list)
{
if (Array.IndexOf(matrixIds, item) < 0 && !list2.Contains(item))
{
if (((ProtoSet<ItemProto>)(object)LDB.items).Select(item) == null)
{
Plugin.Log.LogWarning((object)("[lab] extra matrix item " + item + " not in LDB yet (will be registered later?)"));
}
list2.Add(item);
}
}
if (list2.Count != 0)
{
int num = matrixIds.Length + list2.Count;
int[] array2 = new int[num];
Array.Copy(matrixIds, array2, matrixIds.Length);
for (int j = 0; j < list2.Count; j++)
{
array2[matrixIds.Length + j] = list2[j];
}
LabComponent.matrixIds = array2;
TechProto.matrixIds = array2;
int[] matrixPoints = LabComponent.matrixPoints;
int[] array3 = new int[num];
if (matrixPoints != null)
{
Array.Copy(matrixPoints, array3, Math.Min(matrixPoints.Length, num));
}
LabComponent.matrixPoints = array3;
Plugin.Log.LogInfo((object)("[lab] matrix extended: ids=[" + string.Join(",", array2) + "] pointsLen=" + num));
}
}
internal static void RemapMatrixPoints(int techId)
{
int[] matrixIds = LabComponent.matrixIds;
int[] matrixPoints = LabComponent.matrixPoints;
if (matrixIds == null || matrixPoints == null || matrixIds.Length <= 6)
{
return;
}
Array.Clear(matrixPoints, 0, matrixPoints.Length);
if (techId <= 0)
{
return;
}
TechProto val = ((ProtoSet<TechProto>)(object)LDB.techs).Select(techId);
if (val == null || val.Items == null)
{
return;
}
for (int i = 0; i < val.Items.Length; i++)
{
int num = Array.IndexOf(matrixIds, val.Items[i]);
if (num >= 0 && num < matrixPoints.Length)
{
matrixPoints[num] = val.ItemPoints[i];
}
}
}
}
internal static class LabUiPatch
{
private sealed class Full
{
public UIButton[] Buttons;
public Image[] Icons;
public Image[] Percents;
public Text[] Counts;
public Image[] Locks;
public Image[] Incs;
}
[HarmonyPatch(typeof(UILabWindow), "_OnInit")]
internal static class OnInitPatch
{
[HarmonyPrefix]
private static void Prefix(UILabWindow __instance)
{
try
{
Ensure(__instance);
}
catch (Exception ex)
{
Log(ex);
}
}
}
[HarmonyPatch(typeof(UILabWindow), "_OnUpdate")]
internal static class OnUpdatePatch
{
[HarmonyPrefix]
private static void Prefix(UILabWindow __instance)
{
try
{
Trim(__instance);
}
catch (Exception ex)
{
Log(ex);
}
}
[HarmonyFinalizer]
private static void Finalizer(UILabWindow __instance)
{
try
{
Restore(__instance);
}
catch (Exception ex)
{
Log(ex);
}
}
[HarmonyPostfix]
private static void Postfix(UILabWindow __instance)
{
try
{
Arrange(__instance);
}
catch (Exception ex)
{
Log(ex);
}
}
}
private const int SlotCount = 9;
private static readonly Dictionary<UILabWindow, Full> Cache = new Dictionary<UILabWindow, Full>();
private static FieldInfo _protosField;
private static FieldInfo _recipesField;
private static bool _err;
private static void Log(Exception ex)
{
if (!_err)
{
_err = true;
Plugin.Log.LogError((object)("[lab-ui] " + ex));
}
}
private static void Ensure(UILabWindow w)
{
if (w.itemButtons == null || w.itemButtons.Length == 0)
{
return;
}
int[] matrixIds = LabComponent.matrixIds;
int val = ((matrixIds != null) ? matrixIds.Length : 6);
int num = Math.Max(9, val);
if (Cache.TryGetValue(w, out var value) && value != null && value.Buttons != null && value.Buttons.Length >= num)
{
return;
}
int num2 = w.itemButtons.Length;
int num3 = Math.Max(num, num2);
UIButton[] array = (UIButton[])(object)new UIButton[num3];
Image[] array2 = (Image[])(object)new Image[num3];
Image[] array3 = (Image[])(object)new Image[num3];
Text[] array4 = (Text[])(object)new Text[num3];
Image[] array5 = (Image[])(object)new Image[num3];
Image[] array6 = (Image[])(object)new Image[num3 * 3];
for (int i = 0; i < num2; i++)
{
array[i] = w.itemButtons[i];
array2[i] = Get(w.itemIcons, i);
array3[i] = Get(w.itemPercents, i);
array4[i] = ((w.itemCountTexts != null && i < w.itemCountTexts.Length) ? w.itemCountTexts[i] : null);
array5[i] = Get(w.itemLocks, i);
for (int j = 0; j < 3; j++)
{
if (w.itemIncs != null && i * 3 + j < w.itemIncs.Length)
{
array6[i * 3 + j] = w.itemIncs[i * 3 + j];
}
}
}
if (num2 > 0 && (Object)(object)w.itemButtons[0] != (Object)null)
{
Transform parent = ((Component)w.itemButtons[0]).transform.parent;
GameObject gameObject = ((Component)w.itemButtons[0]).gameObject;
for (int k = num2; k < num3; k++)
{
GameObject val2 = Object.Instantiate<GameObject>(gameObject, parent);
((Object)val2).name = "circle-ext-" + k;
array[k] = val2.GetComponent<UIButton>();
Transform transform = val2.transform;
array2[k] = ChildImage(transform, "icon");
array3[k] = ChildImage(transform, "fg");
array4[k] = ChildText(transform, "cnt-text");
array5[k] = ChildImage(transform, "locked");
for (int l = 0; l < 3; l++)
{
array6[k * 3 + l] = ChildImage(transform, "icon/inc-" + (l + 1));
}
}
}
value = new Full
{
Buttons = array,
Icons = array2,
Percents = array3,
Counts = array4,
Locks = array5,
Incs = array6
};
Cache[w] = value;
Apply(w, value);
Plugin.Log.LogInfo((object)("[lab-ui] matrix slots ready: " + num2 + " -> " + num3 + " (matrixIds=" + val + ")"));
}
private static void Apply(UILabWindow w, Full full)
{
w.itemButtons = full.Buttons;
w.itemIcons = full.Icons;
w.itemPercents = full.Percents;
w.itemCountTexts = full.Counts;
w.itemLocks = full.Locks;
w.itemIncs = full.Incs;
}
private static int VanillaBound(UILabWindow w, Full full)
{
if (_protosField == null)
{
_protosField = AccessTools.Field(typeof(UILabWindow), "matrixProtos");
}
if (_recipesField == null)
{
_recipesField = AccessTools.Field(typeof(UILabWindow), "matrixRecipes");
}
int num = 0;
if (_protosField != null && _protosField.GetValue(w) is ItemProto[] array)
{
num = array.Length;
}
if (_recipesField != null && _recipesField.GetValue(w) is RecipeProto[] array2)
{
num = ((num == 0) ? array2.Length : Math.Min(num, array2.Length));
}
if (num <= 0)
{
int[] matrixIds = LabComponent.matrixIds;
num = ((matrixIds != null) ? matrixIds.Length : 6);
}
return Math.Min(num, full.Buttons.Length);
}
private static void Trim(UILabWindow w)
{
if (Cache.TryGetValue(w, out var value) && value != null)
{
int num = VanillaBound(w, value);
if (num >= value.Buttons.Length)
{
Apply(w, value);
return;
}
UIButton[] array = (UIButton[])(object)new UIButton[num];
Image[] array2 = (Image[])(object)new Image[num];
Image[] array3 = (Image[])(object)new Image[num];
Text[] array4 = (Text[])(object)new Text[num];
Image[] array5 = (Image[])(object)new Image[num];
Image[] array6 = (Image[])(object)new Image[num * 3];
Array.Copy(value.Buttons, array, num);
Array.Copy(value.Icons, array2, num);
Array.Copy(value.Percents, array3, num);
Array.Copy(value.Counts, array4, num);
Array.Copy(value.Locks, array5, num);
Array.Copy(value.Incs, array6, num * 3);
w.itemButtons = array;
w.itemIcons = array2;
w.itemPercents = array3;
w.itemCountTexts = array4;
w.itemLocks = array5;
w.itemIncs = array6;
}
}
private static void Restore(UILabWindow w)
{
if (Cache.TryGetValue(w, out var value) && value != null)
{
Apply(w, value);
}
}
private static void Arrange(UILabWindow w)
{
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
if (!Cache.TryGetValue(w, out var value) || value == null || (Object)(object)w.windowTrans == (Object)null)
{
return;
}
int[] matrixIds = LabComponent.matrixIds;
int num = ((matrixIds != null) ? matrixIds.Length : 6);
Transform val = ((Component)w).transform.Find("matrix-group/matrix/lines");
if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf)
{
((Component)val).gameObject.SetActive(false);
}
for (int i = 0; i < value.Buttons.Length; i++)
{
UIButton val2 = value.Buttons[i];
if ((Object)(object)val2 == (Object)null)
{
continue;
}
GameObject gameObject = ((Component)val2).gameObject;
if (!gameObject.activeSelf)
{
gameObject.SetActive(true);
}
Transform transform = ((Component)val2).transform;
RectTransform val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
if ((Object)(object)val3 != (Object)null)
{
val3.anchoredPosition = new Vector2((float)(i % 3 - 1) * 96f, (float)(1 - i / 3) * 96f);
if (((Transform)val3).localScale != Vector3.one)
{
((Transform)val3).localScale = Vector3.one;
}
}
if (i < num)
{
continue;
}
if ((Object)(object)value.Icons[i] != (Object)null)
{
value.Icons[i].sprite = null;
((Behaviour)value.Icons[i]).enabled = false;
}
if ((Object)(object)value.Percents[i] != (Object)null)
{
value.Percents[i].fillAmount = 0f;
}
if ((Object)(object)value.Counts[i] != (Object)null)
{
value.Counts[i].text = "";
}
if ((Object)(object)value.Locks[i] != (Object)null)
{
((Behaviour)value.Locks[i]).enabled = true;
}
for (int j = 0; j < 3; j++)
{
if ((Object)(object)value.Incs[i * 3 + j] != (Object)null)
{
((Behaviour)value.Incs[i * 3 + j]).enabled = false;
}
}
if ((Object)(object)val2.button != (Object)null)
{
((Selectable)val2.button).interactable = false;
}
val2.tips.itemId = 0;
}
CenterGrid(w, value);
}
private static void CenterGrid(UILabWindow w, Full full)
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: 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_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: 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)
//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
//IL_02df: Unknown result type (might be due to invalid IL or missing references)
//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0304: Unknown result type (might be due to invalid IL or missing references)
//IL_0306: Unknown result type (might be due to invalid IL or missing references)
//IL_030b: Unknown result type (might be due to invalid IL or missing references)
//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_031d: Unknown result type (might be due to invalid IL or missing references)
Transform obj = ((Component)w).transform.Find("matrix-group/matrix");
RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
if ((Object)(object)val == (Object)null || full.Buttons == null || full.Buttons.Length == 0)
{
return;
}
if (((Transform)val).localScale != Vector3.one)
{
((Transform)val).localScale = Vector3.one;
}
RectTransform windowTrans = w.windowTrans;
Rect rect = windowTrans.rect;
float num = ((Rect)(ref rect)).xMax;
Transform parent = ((Transform)val).parent;
Vector3[] array = (Vector3[])(object)new Vector3[4];
for (int i = 0; i < parent.childCount; i++)
{
Transform child = parent.GetChild(i);
RectTransform val2 = (RectTransform)(object)((child is RectTransform) ? child : null);
if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2 == (Object)(object)val) && ((Component)val2).gameObject.activeInHierarchy && !(((Object)val2).name == "lines"))
{
val2.GetWorldCorners(array);
Vector3 val3 = ((Transform)windowTrans).InverseTransformPoint(array[0]);
Vector3 val4 = ((Transform)windowTrans).InverseTransformPoint(array[2]);
if (!(val4.x - val3.x < 1f) && !(val4.y - val3.y < 1f) && val3.x > ((Rect)(ref rect)).xMin + ((Rect)(ref rect)).width * 0.35f)
{
num = Mathf.Min(num, val3.x);
}
}
}
float num2 = ((Rect)(ref rect)).xMin + 18f;
float num3 = Mathf.Min(num - 16f, ((Rect)(ref rect)).xMax - 18f);
if (num3 < num2 + 60f)
{
num3 = ((Rect)(ref rect)).xMax - 18f;
}
float num4 = ((Rect)(ref rect)).yMax - 56f;
float num5 = ((Rect)(ref rect)).yMin + 14f;
float num6 = Mathf.Max(60f, num3 - num2);
float num7 = Mathf.Max(60f, num4 - num5);
float num8 = Mathf.Clamp(Mathf.Min(num6 / 3f, num7 / 3f), 46f, 96f);
float num9 = num8 * 3f;
float num10 = num8 * 3f;
float num11 = num2 + (num6 - num9) * 0.5f;
float num12 = num4 - (num7 - num10) * 0.5f;
float num13 = num8 / 96f;
Vector3 val5 = default(Vector3);
((Vector3)(ref val5))..ctor(num13, num13, 1f);
Vector3 val8 = default(Vector3);
for (int j = 0; j < full.Buttons.Length; j++)
{
UIButton val6 = full.Buttons[j];
if ((Object)(object)val6 == (Object)null)
{
continue;
}
Transform transform = ((Component)val6).transform;
RectTransform val7 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
if (!((Object)(object)val7 == (Object)null))
{
int num14 = j % 3;
int num15 = j / 3;
((Vector3)(ref val8))..ctor(num11 + ((float)num14 + 0.5f) * num8, num12 - ((float)num15 + 0.5f) * num8, 0f);
Vector3 val9 = ((Transform)windowTrans).TransformPoint(val8);
Vector3 val10 = ((Transform)val7).position - val9;
if (((Vector3)(ref val10)).sqrMagnitude > 0.25f)
{
((Transform)val7).position = val9;
}
val10 = ((Transform)val7).localScale - val5;
if (((Vector3)(ref val10)).sqrMagnitude > 1E-06f)
{
((Transform)val7).localScale = val5;
}
}
}
}
private static Image Get(Image[] arr, int i)
{
if (arr == null || i >= arr.Length)
{
return null;
}
return arr[i];
}
private static Image ChildImage(Transform t, string path)
{
Transform val = t.Find(path);
if (!((Object)(object)val != (Object)null))
{
return null;
}
return ((Component)val).GetComponent<Image>();
}
private static Text ChildText(Transform t, string path)
{
Transform val = t.Find(path);
if (!((Object)(object)val != (Object)null))
{
return null;
}
return ((Component)val).GetComponent<Text>();
}
}
internal static class NeedsUtil
{
public static bool Contains(int[] needs, int item)
{
if (needs == null)
{
return false;
}
for (int i = 0; i < needs.Length; i++)
{
if (needs[i] == item)
{
return true;
}
}
return false;
}
public static int IndexOf(int[] needs, int item)
{
if (needs == null)
{
return -1;
}
for (int i = 0; i < needs.Length; i++)
{
if (needs[i] == item)
{
return i;
}
}
return -1;
}
public static int SplitInc(ref int n, ref int m, int p)
{
if (n == 0)
{
return 0;
}
int num = m / n;
int num2 = m - num * n;
n -= p;
num2 -= n;
num = ((num2 > 0) ? (num * p + num2) : (num * p));
m -= num;
return num;
}
internal static bool Enabled()
{
try
{
return Plugin.EnableNeedsLoop == null || Plugin.EnableNeedsLoop.Value;
}
catch
{
return true;
}
}
}
[HarmonyPatch(typeof(AssemblerComponent), "SetRecipe")]
internal static class AssemblerNeedsResizePatch
{
[HarmonyPostfix]
private static void Postfix(ref AssemblerComponent __instance)
{
try
{
RecipeExecuteData recipeExecuteData = __instance.recipeExecuteData;
if (recipeExecuteData != null && recipeExecuteData.requires != null)
{
int num = Math.Max(6, recipeExecuteData.requires.Length);
if (__instance.needs == null || __instance.needs.Length != num)
{
__instance.needs = new int[num];
}
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[m2] resize needs: " + ex));
}
}
}
internal static class CargoPathFields
{
internal static readonly FieldRef<CargoPath, int> BufLen = AccessTools.FieldRefAccess<CargoPath, int>("bufferLength");
internal static readonly FieldRef<CargoPath, int> UpdLen = AccessTools.FieldRefAccess<CargoPath, int>("updateLen");
}
[HarmonyPatch]
internal static class CargoPathTryPickItemPatch
{
private static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(CargoPath), "TryPickItem", new Type[6]
{
typeof(int),
typeof(int),
typeof(int),
typeof(int[]),
typeof(byte).MakeByRefType(),
typeof(byte).MakeByRefType()
}, (Type[])null);
}
[HarmonyPrefix]
private static bool Prefix(CargoPath __instance, int index, int length, int filter, int[] needs, out byte stack, out byte inc, ref int __result)
{
stack = 1;
inc = 0;
if (needs == null || needs.Length <= 6 || !NeedsUtil.Enabled())
{
return true;
}
try
{
byte[] buffer = __instance.buffer;
CargoContainer cargoContainer = __instance.cargoContainer;
lock (buffer)
{
int num = CargoPathFields.BufLen.Invoke(__instance);
if (index < 0)
{
index = 0;
}
else if (index >= num)
{
index = num - 1;
}
int num2 = index + length;
if (num2 > num)
{
num2 = num;
}
for (int i = index; i < num2; i++)
{
if (buffer[i] < 246)
{
continue;
}
i += 250 - buffer[i];
int num3 = buffer[i + 1] - 1 + (buffer[i + 2] - 1) * 100 + (buffer[i + 3] - 1) * 10000 + (buffer[i + 4] - 1) * 1000000;
int item = cargoContainer.cargoPool[num3].item;
stack = cargoContainer.cargoPool[num3].stack;
inc = cargoContainer.cargoPool[num3].inc;
if ((filter == 0 || item == filter) && NeedsUtil.Contains(needs, item))
{
Array.Clear(buffer, i - 4, 10);
int num4 = i + 5 + 1;
if (CargoPathFields.UpdLen.Invoke(__instance) < num4)
{
CargoPathFields.UpdLen.Invoke(__instance) = num4;
}
cargoContainer.RemoveCargo(num3);
__result = item;
return false;
}
__result = 0;
return false;
}
}
__result = 0;
return false;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[m2] CargoPath.TryPickItem: " + ex));
return true;
}
}
}
[HarmonyPatch(typeof(CargoPath), "TryPickItemAtRear")]
internal static class CargoPathTryPickItemAtRearPatch
{
[HarmonyPrefix]
private static bool Prefix(CargoPath __instance, int[] needs, out int needIdx, out byte stack, out byte inc, ref int __result)
{
needIdx = -1;
stack = 1;
inc = 0;
if (needs == null || needs.Length <= 6 || !NeedsUtil.Enabled())
{
return true;
}
try
{
byte[] buffer = __instance.buffer;
CargoContainer cargoContainer = __instance.cargoContainer;
lock (buffer)
{
int num = CargoPathFields.BufLen.Invoke(__instance) - 5 - 1;
if (num >= 0 && num < buffer.Length && buffer[num] == 250)
{
int num2 = buffer[num + 1] - 1 + (buffer[num + 2] - 1) * 100 + (buffer[num + 3] - 1) * 10000 + (buffer[num + 4] - 1) * 1000000;
int item = cargoContainer.cargoPool[num2].item;
stack = cargoContainer.cargoPool[num2].stack;
inc = cargoContainer.cargoPool[num2].inc;
int num3 = NeedsUtil.IndexOf(needs, item);
if (num3 >= 0)
{
Array.Clear(buffer, num - 4, 10);
int num4 = num + 5 + 1;
if (CargoPathFields.UpdLen.Invoke(__instance) < num4)
{
CargoPathFields.UpdLen.Invoke(__instance) = num4;
}
cargoContainer.RemoveCargo(num2);
needIdx = num3;
__result = item;
return false;
}
}
}
__result = 0;
return false;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[m2] CargoPath.TryPickItemAtRear: " + ex));
return true;
}
}
}
[HarmonyPatch(typeof(CargoPath), "CanPickItemFromRear")]
internal static class CargoPathCanPickItemFromRearPatch
{
[HarmonyPrefix]
private static bool Prefix(CargoPath __instance, int[] needs, ref bool __result)
{
if (needs == null || needs.Length <= 6 || !NeedsUtil.Enabled())
{
return true;
}
try
{
byte[] buffer = __instance.buffer;
CargoContainer cargoContainer = __instance.cargoContainer;
int num = CargoPathFields.BufLen.Invoke(__instance) - 5 - 1;
if (num >= 0 && num < buffer.Length && buffer[num] == 250)
{
int num2 = buffer[num + 1] - 1 + (buffer[num + 2] - 1) * 100 + (buffer[num + 3] - 1) * 10000 + (buffer[num + 4] - 1) * 1000000;
int item = cargoContainer.cargoPool[num2].item;
if (item != 0 && NeedsUtil.Contains(needs, item))
{
__result = true;
return false;
}
}
__result = false;
return false;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[m2] CanPickItemFromRear: " + ex));
return true;
}
}
}
[HarmonyPatch]
internal static class StorageTakeTailItemsPatch
{
private static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(StorageComponent), "TakeTailItems", new Type[5]
{
typeof(int).MakeByRefType(),
typeof(int).MakeByRefType(),
typeof(int[]),
typeof(int).MakeByRefType(),
typeof(bool)
}, (Type[])null);
}
[HarmonyPrefix]
private static bool Prefix(StorageComponent __instance, ref int itemId, ref int count, int[] needs, out int inc, bool useBan, ref bool __result)
{
inc = 0;
if (needs == null || needs.Length <= 6 || !NeedsUtil.Enabled())
{
return true;
}
try
{
if (count == 0)
{
itemId = 0;
count = 0;
__result = false;
return false;
}
bool flag = false;
int num = count;
count = 0;
GRID[] grids = __instance.grids;
int num2 = (useBan ? (__instance.size - __instance.bans - 1) : (__instance.size - 1));
if (num2 >= grids.Length)
{
num2 = grids.Length - 1;
}
for (int num3 = num2; num3 >= 0; num3--)
{
if (grids[num3].itemId != 0 && grids[num3].count != 0 && (itemId == 0 || grids[num3].itemId == itemId))
{
flag = true;
if (NeedsUtil.Contains(needs, grids[num3].itemId))
{
itemId = grids[num3].itemId;
if (grids[num3].count > num)
{
inc += NeedsUtil.SplitInc(ref grids[num3].count, ref grids[num3].inc, num);
count += num;
num = 0;
break;
}
inc += grids[num3].inc;
count += grids[num3].count;
num -= grids[num3].count;
grids[num3].itemId = grids[num3].filter;
grids[num3].count = 0;
grids[num3].inc = 0;
if (grids[num3].filter == 0)
{
grids[num3].stackSize = 0;
}
}
}
}
if (count == 0)
{
itemId = 0;
count = 0;
}
else
{
__instance.lastFullItem = -1;
__instance.NotifyStorageChange();
}
__result = flag;
return false;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[m2] TakeTailItems: " + ex));
return true;
}
}
}
[HarmonyPatch]
internal static class StationTakeItemPatch
{
private static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(StationComponent), "TakeItem", new Type[4]
{
typeof(int).MakeByRefType(),
typeof(int).MakeByRefType(),
typeof(int[]),
typeof(int).MakeByRefType()
}, (Type[])null);
}
[HarmonyPrefix]
private static bool Prefix(StationComponent __instance, ref int _itemId, ref int _count, int[] _needs, out int _inc)
{
_inc = 0;
if (_needs == null || _needs.Length <= 6 || !NeedsUtil.Enabled())
{
return true;
}
try
{
if (_itemId > 0 && _count > 0 && NeedsUtil.Contains(_needs, _itemId))
{
StationStore[] storage = __instance.storage;
if (storage != null)
{
lock (storage)
{
for (int i = 0; i < storage.Length; i++)
{
if (storage[i].itemId == _itemId && storage[i].count > 0)
{
_count = ((_count < storage[i].count) ? _count : storage[i].count);
_itemId = storage[i].itemId;
_inc = NeedsUtil.SplitInc(ref storage[i].count, ref storage[i].inc, _count);
return false;
}
}
}
}
}
_itemId = 0;
_count = 0;
_inc = 0;
return false;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[m2] StationComponent.TakeItem: " + ex));
return true;
}
}
}
[HarmonyPatch]
internal static class PickFromIntM2Patch
{
private static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(PlanetFactory), "PickFrom", new Type[6]
{
typeof(int),
typeof(int),
typeof(int),
typeof(int[]),
typeof(byte).MakeByRefType(),
typeof(byte).MakeByRefType()
}, (Type[])null);
}
[HarmonyPrefix]
private static bool Prefix(PlanetFactory __instance, int entityId, int offset, int filter, int[] needs, out byte stack, out byte inc, ref int __result)
{
stack = 1;
inc = 0;
if (needs == null || needs.Length <= 6 || !NeedsUtil.Enabled())
{
return true;
}
try
{
if (entityId <= 0 || entityId >= __instance.entityCursor)
{
return true;
}
int assemblerId = __instance.entityPool[entityId].assemblerId;
int labId = __instance.entityPool[entityId].labId;
if (assemblerId <= 0 && labId <= 0)
{
return true;
}
lock (__instance.entityMutexs[entityId])
{
int[] products;
int[] produced;
if (assemblerId > 0)
{
ref AssemblerComponent reference = ref __instance.factorySystem.assemblerPool[assemblerId];
products = reference.recipeExecuteData?.products;
produced = reference.produced;
}
else
{
ref LabComponent reference2 = ref __instance.factorySystem.labPool[labId];
products = reference2.recipeExecuteData?.products;
produced = reference2.produced;
}
__result = M2Pick(products, produced, filter, needs);
return false;
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[m2] PickFrom(int): " + ex));
return true;
}
}
internal static int M2Pick(int[] products, int[] produced, int filter, int[] needs)
{
if (products == null || produced == null)
{
return 0;
}
int num = products.Length;
for (int i = 0; i < num; i++)
{
int num2 = products[i];
if (num2 > 0 && produced[i] > 0 && (filter == 0 || filter == num2) && NeedsUtil.Contains(needs, num2))
{
produced[i]--;
return num2;
}
}
return 0;
}
}
[HarmonyPatch]
internal static class PickFromUIntM2Patch
{
private const uint AssemblerTag = 33554432u;
private const uint LabTag = 117440512u;
private static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(PlanetFactory), "PickFrom", new Type[6]
{
typeof(uint),
typeof(int),
typeof(int),
typeof(int[]),
typeof(byte).MakeByRefType(),
typeof(byte).MakeByRefType()
}, (Type[])null);
}
[HarmonyPrefix]
private static bool Prefix(PlanetFactory __instance, uint ioTargetTypedId, int offset, int filter, int[] needs, out byte stack, out byte inc, ref int __result)
{
stack = 1;
inc = 0;
if (needs == null || needs.Length <= 6 || !NeedsUtil.Enabled())
{
return true;
}
try
{
uint num = ioTargetTypedId & 0xFF000000u;
if (num != 33554432 && num != 117440512)
{
return true;
}
int num2 = (int)(ioTargetTypedId & 0xFFFFFF);
if (num == 33554432)
{
if (num2 <= 0 || num2 >= __instance.factorySystem.assemblerCursor)
{
return true;
}
ref AssemblerComponent reference = ref __instance.factorySystem.assemblerPool[num2];
if (reference.id <= 0)
{
return true;
}
int[] products = reference.recipeExecuteData?.products;
int[] produced = reference.produced;
lock (__instance.entityMutexs[reference.entityId])
{
__result = PickFromIntM2Patch.M2Pick(products, produced, filter, needs);
}
}
else
{
if (num2 <= 0 || num2 >= __instance.factorySystem.labCursor)
{
return true;
}
ref LabComponent reference2 = ref __instance.factorySystem.labPool[num2];
if (reference2.id <= 0)
{
return true;
}
int[] products = reference2.recipeExecuteData?.products;
int[] produced = reference2.produced;
lock (__instance.entityMutexs[reference2.entityId])
{
__result = PickFromIntM2Patch.M2Pick(products, produced, filter, needs);
}
}
return false;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[m2] PickFrom(uint): " + ex));
return true;
}
}
}
internal static class Patches
{
[HarmonyPatch(typeof(AssemblerComponent), "UpdateNeeds")]
internal static class AssemblerUpdateNeedsPatch
{
private static long _hit;
[HarmonyPostfix]
private static void Postfix(ref AssemblerComponent __instance)
{
RecipeExecuteData recipeExecuteData = __instance.recipeExecuteData;
if (recipeExecuteData == null)
{
return;
}
int[] requires = recipeExecuteData.requires;
int[] needs = __instance.needs;
int[] served = __instance.served;
int[] requireCounts = recipeExecuteData.requireCounts;
if (requires == null || needs == null || served == null || requireCounts == null)
{
return;
}
int num = requires.Length;
if (num <= 6)
{
return;
}
int num2 = __instance.speedOverride * 180 / recipeExecuteData.timeSpend + 1;
if (num2 < 2)
{
num2 = 2;
}
int num3 = needs.Length;
if (num3 <= 0)
{
return;
}
int i = 0;
if (num3 >= num)
{
for (int j = 0; j < num; j++)
{
if (i >= num3)
{
break;
}
if (j < served.Length && j < requireCounts.Length && served[j] < requireCounts[j] * num2)
{
needs[i++] = requires[j];
}
}
}
else
{
int num4 = (int)(GameMain.gameTick % num);
if (num4 < 0)
{
num4 += num;
}
for (int k = 0; k < num; k++)
{
if (i >= num3)
{
break;
}
int num5 = num4 + k;
if (num5 >= num)
{
num5 -= num;
}
if (num5 < served.Length && num5 < requireCounts.Length && served[num5] < requireCounts[num5] * num2)
{
needs[i++] = requires[num5];
}
}
}
for (; i < num3; i++)
{
needs[i] = 0;
}
if (Plugin.Verbose.Value && _hit++ % 120 == 0L)
{
Plugin.Log.LogInfo((object)("[needs] recipe=" + __instance.recipeId + " reqLen=" + num + " needs=" + Join(needs) + " served=" + Join(served)));
}
}
}
[HarmonyPatch]
internal static class InsertIntoIntPatch
{
private static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(PlanetFactory), "InsertInto", new Type[6]
{
typeof(int),
typeof(int),
typeof(int),
typeof(byte),
typeof(byte),
typeof(byte).MakeByRefType()
}, (Type[])null);
}
[HarmonyPrefix]
private static bool Prefix(PlanetFactory __instance, int entityId, int itemId, byte itemCount, byte itemInc, out byte remainInc, ref int __result)
{
remainInc = itemInc;
if (entityId <= 0 || entityId >= __instance.entityPool.Length)
{
return true;
}
if (__instance.entityPool[entityId].beltId > 0)
{
return true;
}
int assemblerId = __instance.entityPool[entityId].assemblerId;
if (assemblerId > 0)
{
ref AssemblerComponent reference = ref __instance.factorySystem.assemblerPool[assemblerId];
if (reference.recipeExecuteData == null)
{
__result = 0;
return false;
}
int[] requires = reference.recipeExecuteData.requires;
if (requires == null || requires.Length <= 6)
{
return true;
}
lock (__instance.entityMutexs[entityId])
{
for (int i = 0; i < requires.Length; i++)
{
if (requires[i] == itemId)
{
reference.served[i] += itemCount;
reference.incServed[i] += itemInc;
remainInc = 0;
__result = itemCount;
if (Plugin.Verbose.Value)
{
Plugin.Log.LogInfo((object)("[insert-int] eid=" + entityId + " item=" + itemId + " slot=" + i + " served=" + reference.served[i]));
}
return false;
}
}
}
__result = 0;
return false;
}
int labId = __instance.entityPool[entityId].labId;
if (labId > 0)
{
return HandleLab(__instance, entityId, labId, itemId, itemCount, itemInc, out remainInc, ref __result);
}
return true;
}
}
[HarmonyPatch]
internal static class InsertIntoUIntPatch
{
private const uint AssemblerTag = 33554432u;
private const uint LabTag = 117440512u;
private static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(PlanetFactory), "InsertInto", new Type[6]
{
typeof(uint),
typeof(int),
typeof(int),
typeof(byte),
typeof(byte),
typeof(byte).MakeByRefType()
}, (Type[])null);
}
[HarmonyPrefix]
private static bool Prefix(PlanetFactory __instance, uint ioTargetTypedId, int itemId, byte itemCount, byte itemInc, out byte remainInc, ref int __result)
{
remainInc = itemInc;
switch (ioTargetTypedId & 0xFF000000u)
{
case 117440512u:
{
int num2 = (int)(ioTargetTypedId & 0xFFFFFF);
LabComponent[] array2 = ((__instance.factorySystem != null) ? __instance.factorySystem.labPool : null);
if (array2 == null || num2 <= 0 || num2 >= array2.Length)
{
__result = 0;
return false;
}
return HandleLab(__instance, array2[num2].entityId, num2, itemId, itemCount, itemInc, out remainInc, ref __result);
}
default:
return true;
case 33554432u:
{
int num = (int)(ioTargetTypedId & 0xFFFFFF);
AssemblerComponent[] array = ((__instance.factorySystem != null) ? __instance.factorySystem.assemblerPool : null);
if (array == null || num <= 0 || num >= array.Length)
{
__result = 0;
return false;
}
ref AssemblerComponent reference = ref array[num];
if (reference.id <= 0)
{
__result = 0;
return false;
}
if (reference.recipeExecuteData == null)
{
__result = 0;
return false;
}
int[] requires = reference.recipeExecuteData.requires;
if (requires == null || requires.Length <= 6)
{
return true;
}
int entityId = reference.entityId;
if (entityId <= 0 || entityId >= __instance.entityMutexs.Length)
{
return true;
}
lock (__instance.entityMutexs[entityId])
{
for (int i = 0; i < requires.Length; i++)
{
if (requires[i] == itemId)
{
reference.served[i] += itemCount;
reference.incServed[i] += itemInc;
remainInc = 0;
__result = itemCount;
if (Plugin.Verbose.Value)
{
Plugin.Log.LogInfo((object)("[insert-uint] assembler=" + num + " item=" + itemId + " slot=" + i + " served=" + reference.served[i]));
}
return false;
}
}
}
__result = 0;
return false;
}
}
}
}
private static bool HandleLab(PlanetFactory factory, int entityId, int labId, int itemId, byte itemCount, byte itemInc, out byte remainInc, ref int __result)
{
remainInc = itemInc;
LabComponent[] array = ((factory.factorySystem != null) ? factory.factorySystem.labPool : null);
if (array == null || labId >= array.Length)
{
__result = 0;
return false;
}
ref LabComponent reference = ref array[labId];
if (reference.id <= 0)
{
__result = 0;
return false;
}
lock (factory.entityMutexs[entityId])
{
if (reference.researchMode)
{
int num = Array.IndexOf(LabComponent.matrixIds, itemId);
if (num >= 0 && reference.matrixServed != null && num < reference.matrixServed.Length)
{
reference.matrixServed[num] += 3600 * itemCount;
reference.matrixIncServed[num] += 3600 * itemInc;
remainInc = 0;
__result = itemCount;
return false;
}
__result = 0;
return false;
}
int[] array2 = reference.recipeExecuteData?.requires;
if (array2 != null && array2.Length > 6 && reference.served != null)
{
for (int i = 0; i < array2.Length && i < reference.served.Length; i++)
{
if (array2[i] == itemId)
{
reference.served[i] += itemCount;
reference.incServed[i] += itemInc;
remainInc = 0;
__result = itemCount;
return false;
}
}
__result = 0;
return false;
}
}
return true;
}
[HarmonyPatch(typeof(PowerSystem), "GameTick", new Type[]
{
typeof(long),
typeof(bool),
typeof(bool),
typeof(int)
})]
private static string Join(int[] a)
{
if (a == null)
{
return "null";
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append('[');
for (int i = 0; i < a.Length; i++)
{
if (i > 0)
{
stringBuilder.Append(',');
}
stringBuilder.Append(a[i]);
}
stringBuilder.Append(']');
return stringBuilder.ToString();
}
}
[BepInPlugin("star4wish.dsp.recipeslots", "DSP-RecipeSlots", "1.2.0")]
public class Plugin : BaseUnityPlugin
{
public const string GUID = "star4wish.dsp.recipeslots";
public const string NAME = "DSP-RecipeSlots";
public const string VERSION = "1.2.0";
public static Plugin Instance;
public static ManualLogSource Log;
public static Harmony Harmony;
public static ConfigEntry<bool> Verbose;
public static ConfigEntry<string> LabExtraMatrixIds;
public static ConfigEntry<bool> EnablePatches;
public static ConfigEntry<bool> EnableNeedsLoop;
private void Awake()
{
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
EnablePatches = ((BaseUnityPlugin)this).Config.Bind<bool>("Core", "EnablePatches", true, "启用全部玩法补丁。false 时只保留调试通道,用于排查兼容性问题(区分「是不是本插件导致」)。");
EnableNeedsLoop = ((BaseUnityPlugin)this).Config.Bind<bool>("Core", "EnableNeedsLoop", true, "M2:needs 按配方长度全长填充并把取料匹配改为循环(去掉轮转占空比损失)。关闭则回退到 6 格轮转。");
Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Verbose", false, "打印补丁命中诊断日志。");
LabExtraMatrixIds = ((BaseUnityPlugin)this).Config.Bind<string>("Lab", "ExtraMatrixIds", "", "额外矩阵物品 ID(逗号分隔,必须紧接 6006 连续,如 6007)。用于研究站/科技 >6 种消耗;留空=不扩展。");
Harmony = new Harmony("star4wish.dsp.recipeslots");
Log.LogInfo((object)("[boot] awake, EnablePatches=" + EnablePatches.Value + " EnableNeedsLoop=" + EnableNeedsLoop.Value));
if (EnablePatches.Value)
{
try
{
Harmony.PatchAll();
Log.LogInfo((object)("[boot] PatchAll ok, patched=" + Harmony.GetPatchedMethods().Count()));
}
catch (Exception ex)
{
Log.LogError((object)("[boot] PatchAll FAILED: " + ex));
}
}
else
{
Log.LogWarning((object)"Core.EnablePatches=false,全部玩法补丁已跳过(仅调试通道可用)");
}
DevChannel.Init(((BaseUnityPlugin)this).Config);
Application.runInBackground = true;
Log.LogInfo((object)"DSP-RecipeSlots 1.2.0 loaded (gameTick hooks armed)");
}
private void Update()
{
DevChannel.Tick();
}
}
[HarmonyPatch(typeof(UIRecipeEntry), "SetRecipe")]
internal static class RecipeEntryPatch
{
private static bool _err;
[HarmonyPrefix]
private static bool Prefix(UIRecipeEntry __instance, RecipeProto recipe)
{
try
{
if (recipe == null)
{
return true;
}
Ensure(__instance, recipe.Results.Length + recipe.Items.Length);
Fill(__instance, recipe);
return false;
}
catch (Exception ex)
{
if (!_err)
{
_err = true;
Plugin.Log.LogError((object)("[recipe-entry] " + ex));
}
return true;
}
}
private static void Ensure(UIRecipeEntry e, int need)
{
if (e.icons == null || e.icons.Length == 0 || need <= e.icons.Length)
{
return;
}
int num = e.icons.Length;
Image[] array = (Image[])(object)new Image[need];
Text[] array2 = (Text[])(object)new Text[need];
Array.Copy(e.icons, array, num);
Array.Copy(e.countTexts, array2, Math.Min(e.countTexts.Length, num));
Image val = e.icons[0];
Transform parent = ((Component)val).transform.parent;
bool flag = e.countTexts != null && e.countTexts.Length != 0 && (Object)(object)e.countTexts[0] != (Object)null && ((Component)e.countTexts[0]).transform.IsChildOf(((Component)val).transform);
Transform val2 = ((!flag && e.countTexts != null && e.countTexts.Length != 0 && (Object)(object)e.countTexts[0] != (Object)null) ? ((Component)e.countTexts[0]).transform.parent : null);
for (int i = num; i < need; i++)
{
GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
((Object)val3).name = ((Object)((Component)val).gameObject).name + "-ext" + i;
Image val4 = val3.GetComponent<Image>();
if ((Object)(object)val4 == (Object)null)
{
val4 = val3.GetComponentInChildren<Image>(true);
}
array[i] = val4;
Text val5 = null;
if (flag)
{
val5 = val3.GetComponentInChildren<Text>(true);
}
else if ((Object)(object)val2 != (Object)null)
{
GameObject obj = Object.Instantiate<GameObject>(((Component)e.countTexts[0]).gameObject, val2);
((Object)obj).name = ((Object)((Component)e.countTexts[0]).gameObject).name + "-ext" + i;
val5 = obj.GetComponent<Text>();
}
array2[i] = val5;
val3.SetActive(false);
}
e.icons = array;
e.countTexts = array2;
}
private static void Fill(UIRecipeEntry e, RecipeProto recipe)
{
//IL_00f4: 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)
//IL_0119: Invalid comparison between Unknown and I4
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_020b: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_01d2: Invalid comparison between Unknown and I4
Image[] icons = e.icons;
Text[] countTexts = e.countTexts;
int num = 0;
float num2 = 0f;
for (int i = 0; i < recipe.Results.Length; i++)
{
if (num >= icons.Length)
{
break;
}
ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(recipe.Results[i]);
if ((Object)(object)icons[num] != (Object)null)
{
icons[num].sprite = ((val != null) ? val.iconSprite : null);
}
if (countTexts != null && num < countTexts.Length && (Object)(object)countTexts[num] != (Object)null)
{
countTexts[num].text = recipe.ResultCounts[i].ToString();
}
if ((Object)(object)icons[num] != (Object)null)
{
((Graphic)icons[num]).rectTransform.anchoredPosition = new Vector2(num2, 0f);
((Component)icons[num]).gameObject.SetActive(true);
}
num++;
num2 += 40f;
}
if ((Object)(object)e.arrow != (Object)null)
{
e.arrow.anchoredPosition = new Vector2(num2, -27f);
}
if ((Object)(object)e.timeText != (Object)null)
{
e.timeText.text = (((int)recipe.Type == 8) ? ((float)recipe.ResultCounts[0] / (float)recipe.ItemCounts[0] * 100f + "%") : ((float)recipe.TimeSpend / 60f + " s"));
}
num2 += 40f;
for (int j = 0; j < recipe.Items.Length; j++)
{
if (num >= icons.Length)
{
break;
}
ItemProto val2 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(recipe.Items[j]);
if ((Object)(object)icons[num] != (Object)null)
{
icons[num].sprite = ((val2 != null) ? val2.iconSprite : null);
}
if (countTexts != null && num < countTexts.Length && (Object)(object)countTexts[num] != (Object)null)
{
countTexts[num].text = (((int)recipe.Type == 8) ? "1" : recipe.ItemCounts[j].ToString());
}
if ((Object)(object)icons[num] != (Object)null)
{
((Graphic)icons[num]).rectTransform.anchoredPosition = new Vector2(num2, 0f);
((Component)icons[num]).gameObject.SetActive(true);
}
num++;
num2 += 40f;
}
for (int k = num; k < icons.Length; k++)
{
if ((Object)(object)icons[k] != (Object)null)
{
((Component)icons[k]).gameObject.SetActive(false);
}
}
}
}
internal static class TechUiPatch
{
[HarmonyPatch(typeof(UITechNode), "UpdateInfoComplete")]
internal static class NodePatch
{
[HarmonyPrefix]
private static void Prefix(UITechNode __instance)
{
try
{
TechProto techProto = __instance.techProto;
if (techProto != null && techProto.itemArray != null)
{
int need = techProto.itemArray.Length;
__instance.costIcons = TechUiPatch.Ensure<Image>(__instance.costIcons, need, "cost-icon");
__instance.costIconBds = TechUiPatch.Ensure<Image>(__instance.costIconBds, need, "cost-icon-bd");
__instance.costButtons = TechUiPatch.Ensure<UIButton>(__instance.costButtons, need, "cost-button");
__instance.costCountTexts = TechUiPatch.Ensure<Text>(__instance.costCountTexts, need, "cost-count");
__instance.pCostIcons = TechUiPatch.Ensure<Image>(__instance.pCostIcons, need, "pcost-icon");
__instance.pCostCountTexts = TechUiPatch.Ensure<Text>(__instance.pCostCountTexts, need, "pcost-count");
}
}
catch (Exception ex)
{
Log(ex);
}
}
[HarmonyPostfix]
private static void Postfix(UITechNode __instance)
{
try
{
TechProto techProto = __instance.techProto;
if (techProto != null && techProto.itemArray != null)
{
int num = techProto.itemArray.Length;
if (num > 6)
{
Widen(__instance.costGroup, __instance.costBg, null, num);
Widen(__instance.pCostGroup, null, null, num);
}
}
}
catch (Exception ex)
{
Log(ex);
}
}
}
[HarmonyPatch(typeof(UITechTip), "UpdateInfoComplete")]
internal static class TipPatch
{
[HarmonyPrefix]
private static void Prefix(UITechTip __instance)
{
try
{
TechProto techProto = __instance.techProto;
if (techProto != null && techProto.itemArray != null)
{
int need = techProto.itemArray.Length;
__instance.costIcons = TechUiPatch.Ensure<Image>(__instance.costIcons, need, "tip-cost-icon");
__instance.costButtons = TechUiPatch.Ensure<UIButton>(__instance.costButtons, need, "tip-cost-button");
__instance.costCountTexts = TechUiPatch.Ensure<Text>(__instance.costCountTexts, need, "tip-cost-count");
}
}
catch (Exception ex)
{
Log(ex);
}
}
[HarmonyPostfix]
private static void Postfix(UITechTip __instance)
{
try
{
TechProto techProto = __instance.techProto;
if (techProto != null && techProto.itemArray != null)
{
int num = techProto.itemArray.Length;
if (num > 6)
{
Widen(__instance.costGroup, null, __instance.panelRect, num);
}
}
}
catch (Exception ex)
{
Log(ex);
}
}
}
[HarmonyPatch(typeof(UITechTip), "UpdateLayoutDynamic")]
internal static class TipLayoutPatch
{
[HarmonyPostfix]
private static void Postfix(UITechTip __instance)
{
try
{
TechProto techProto = __instance.techProto;
if (techProto != null && techProto.itemArray != null)
{
int num = techProto.itemArray.Length;
if (num > 6)
{
Widen(__instance.costGroup, null, __instance.panelRect, num);
}
}
}
catch (Exception ex)
{
Log(ex);
}
}
}
private static bool _err;
private static T[] Ensure<T>(T[] arr, int need, string tag) where T : Component
{
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
//IL_01b6: 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)
if (arr == null || arr.Length == 0)
{
return arr;
}
if (need < arr.Length)
{
for (int i = need; i < arr.Length; i++)
{
if ((Object)(object)arr[i] != (Object)null)
{
((Component)arr[i]).gameObject.SetActive(false);
}
}
return arr;
}
if (need == arr.Length)
{
return arr;
}
int num = arr.Length;
T[] array = new T[need];
Array.Copy(arr, array, num);
T val = (((Object)(object)arr[0] != (Object)null) ? arr[0] : arr[num - 1]);
if ((Object)(object)val == (Object)null)
{
return arr;
}
Transform parent = ((Component)val).transform.parent;
Transform transform = ((Component)val).transform;
RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
Vector2 val3 = (((Object)(object)val2 != (Object)null) ? val2.anchoredPosition : Vector2.zero);
float num2 = 46f;
if (num > 1 && (Object)(object)arr[1] != (Object)null)
{
Transform transform2 = ((Component)arr[1]).transform;
RectTransform val4 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
if ((Object)(object)val4 != (Object)null)
{
num2 = val4.anchoredPosition.x - val3.x;
}
if (Mathf.Abs(num2) < 1f)
{
num2 = 46f;
}
}
for (int j = num; j < need; j++)
{
GameObject val5 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
((Object)val5).name = ((Object)((Component)val).gameObject).name + "-ext" + j;
Transform transform3 = val5.transform;
RectTransform val6 = (RectTransform)(object)((transform3 is RectTransform) ? transform3 : null);
if ((Object)(object)val6 != (Object)null)
{
val6.anchoredPosition = new Vector2(val3.x + num2 * (float)j, val3.y);
}
val5.SetActive(false);
T val7 = val5.GetComponent<T>();
if ((Object)(object)val7 == (Object)null)
{
val7 = val5.GetComponentInChildren<T>(true);
}
array[j] = val7;
if ((Object)(object)val7 == (Object)null)
{
Plugin.Log.LogWarning((object)("[tech-ui] clone " + tag + " i=" + j + " missing component " + typeof(T).Name));
}
}
return array;
}
private static void Widen(RectTransform group, RectTransform bg, RectTransform panel, int need)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
float num = 46f * (float)need + 10f;
if ((Object)(object)group != (Object)null && group.sizeDelta.x < num)
{
group.sizeDelta = new Vector2(num, group.sizeDelta.y);
}
if ((Object)(object)bg != (Object)null && bg.sizeDelta.x < num)
{
bg.sizeDelta = new Vector2(num, bg.sizeDelta.y);
}
if ((Object)(object)panel != (Object)null && panel.sizeDelta.x < num + 28f)
{
panel.sizeDelta = new Vector2(num + 28f, panel.sizeDelta.y);
}
}
private static void Log(Exception ex)
{
if (!_err)
{
_err = true;
Plugin.Log.LogError((object)("[tech-ui] " + ex));
}
}
}
}