using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using CommonAPI;
using CommonAPI.Systems;
using CommonAPI.Systems.ModLocalization;
using HarmonyLib;
using LokiMoonLabs.HoneyIShrunkTheFactory;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
using crecheng.DSPModSave;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace LokiMoonLabs.AIOAssembler
{
internal sealed class AssemblyLine
{
private struct Slot
{
public BatchRecipe Recipe;
public int RecipeId;
public int Duration;
public int Progress;
public int Multiplier;
public float Speed;
public float RemainingWork;
}
private const int LegacySlotCount = 8;
internal const int SlotCount = 10;
internal const int InputSlotCount = 20;
internal const int OutputSlotCount = 10;
internal const int BufferedBatches = 9;
internal const int OutputSlotsPerProduct = 8;
internal readonly IngredientBuffer Ingredients = new IngredientBuffer();
private readonly Slot[] slots = new Slot[10];
private int firstSlot;
private readonly List<int> logisticsItems = new List<int>();
private bool logisticsDirty = true;
private float assemblyWorkPerTick;
private float smeltingWorkPerTick;
public int Multiplier { get; private set; }
internal bool HasPower { get; private set; }
internal float PowerServed { get; set; }
public int ConfiguredSlots
{
get
{
int num = 0;
Slot[] array = slots;
for (int i = 0; i < array.Length; i++)
{
Slot slot = array[i];
if (slot.Recipe != null)
{
num++;
}
}
return num;
}
}
public AssemblyLine()
{
Multiplier = 1;
}
public void SetMultiplier(int multiplier)
{
if (multiplier < 1 || multiplier > 1000)
{
throw new ArgumentOutOfRangeException("multiplier");
}
Multiplier = multiplier;
}
public void SetRecipe(int index, int recipeId, BatchRecipe recipe, int duration)
{
if (recipeId <= 0 || recipe == null || duration <= 0)
{
throw new ArgumentException("A slot requires a valid recipe and cycle duration.");
}
ref Slot reference = ref slots[index];
reference = new Slot
{
Recipe = recipe,
RecipeId = recipeId,
Duration = duration
};
logisticsDirty = true;
}
public void ClearRecipe(int index)
{
slots[index] = default(Slot);
logisticsDirty = true;
}
public void ClearRecipes()
{
Array.Clear(slots, 0, slots.Length);
logisticsDirty = true;
}
internal IReadOnlyList<int> LogisticsItems()
{
if (!logisticsDirty)
{
return logisticsItems;
}
logisticsItems.Clear();
Slot[] array = slots;
for (int i = 0; i < array.Length; i++)
{
Slot slot = array[i];
if (slot.Recipe == null)
{
continue;
}
BatchRecipe.IngredientChange[] changes = slot.Recipe.Changes;
for (int j = 0; j < changes.Length; j++)
{
BatchRecipe.IngredientChange ingredientChange = changes[j];
if (!logisticsItems.Contains(ingredientChange.Item))
{
logisticsItems.Add(ingredientChange.Item);
}
}
}
logisticsDirty = false;
return logisticsItems;
}
internal bool LogisticsRule(int item, out int reserve, out bool output)
{
long num = 0L;
output = false;
Slot[] array = slots;
for (int i = 0; i < array.Length; i++)
{
Slot slot = array[i];
if (slot.Recipe == null)
{
continue;
}
BatchRecipe.IngredientChange[] changes = slot.Recipe.Changes;
for (int j = 0; j < changes.Length; j++)
{
BatchRecipe.IngredientChange ingredientChange = changes[j];
if (ingredientChange.Item == item)
{
num += (long)ingredientChange.Input * (long)Math.Max(Multiplier, (slot.Progress > 0) ? slot.Multiplier : 0);
output |= ingredientChange.Output > 0;
}
}
}
reserve = (int)Math.Min(num * 9, 2147483647L);
if (reserve <= 0)
{
return output;
}
return true;
}
public int RecipeId(int index)
{
return slots[index].RecipeId;
}
internal BatchRecipe Recipe(int index)
{
return slots[index].Recipe;
}
internal int BatchMultiplier(int index)
{
if (slots[index].Progress != 0)
{
return slots[index].Multiplier;
}
return Multiplier;
}
internal bool WaitingForSpace(int index)
{
if (slots[index].Duration > 0)
{
return slots[index].Progress == slots[index].Duration;
}
return false;
}
internal long WorkingMachines(Func<BatchRecipe, int, bool> hasInputs)
{
long num = 0L;
Slot[] array = slots;
for (int i = 0; i < array.Length; i++)
{
Slot slot = array[i];
if (slot.Recipe != null && slot.Progress != slot.Duration)
{
int num2 = ((slot.Progress > 0) ? slot.Multiplier : Multiplier);
if (hasInputs(slot.Recipe, num2))
{
num += num2;
}
}
}
return num;
}
internal float CycleSeconds(int index)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Invalid comparison between Unknown and I4
Slot slot = slots[index];
if (slot.Recipe == null)
{
return 0f;
}
float num = (((int)slot.Recipe.Type == 1) ? smeltingWorkPerTick : assemblyWorkPerTick);
if (!(num > 0f))
{
return 0f;
}
return (float)slot.Duration / (60f * num * Math.Max(1f, slot.Speed));
}
internal void AdvancePowered(float speed, Func<BatchRecipe, int, bool> hasInputs, Func<BatchRecipe, int, bool> completeBatch, Func<BatchRecipe, int, float> batchSpeed = null, float smeltingSpeed = -1f)
{
HasPower = speed > 0f;
assemblyWorkPerTick = speed;
smeltingWorkPerTick = ((smeltingSpeed < 0f) ? speed : smeltingSpeed);
if (HasPower)
{
Advance(speed, completeBatch, hasInputs, batchSpeed, smeltingWorkPerTick);
}
}
public float Progress(int index)
{
Slot slot = slots[index];
if (slot.Duration != 0)
{
return (float)slot.Progress / (float)slot.Duration;
}
return 0f;
}
public void Write(BinaryWriter writer)
{
writer.Write(3);
writer.Write(Multiplier);
writer.Write(firstSlot);
Slot[] array = slots;
for (int i = 0; i < array.Length; i++)
{
Slot slot = array[i];
writer.Write(slot.RecipeId);
writer.Write(slot.Progress);
writer.Write(slot.Multiplier);
}
Ingredients.Write(writer);
}
public static AssemblyLine Read(BinaryReader reader, Func<int, BatchRecipe> resolveRecipe, Func<int, int> resolveDuration)
{
int num = reader.ReadInt32();
int num2;
switch (num)
{
default:
throw new InvalidDataException("Unsupported AIO Assembler save version.");
case 3:
num2 = 10;
break;
case 1:
case 2:
num2 = 8;
break;
}
int num3 = num2;
AssemblyLine assemblyLine = new AssemblyLine();
assemblyLine.SetMultiplier(reader.ReadInt32());
assemblyLine.firstSlot = reader.ReadInt32();
if (assemblyLine.firstSlot < 0 || assemblyLine.firstSlot >= num3)
{
throw new InvalidDataException("Invalid saved slot cursor.");
}
for (int i = 0; i < num3; i++)
{
int num4 = reader.ReadInt32();
int num5 = reader.ReadInt32();
int num6 = reader.ReadInt32();
if (num4 <= 0)
{
continue;
}
BatchRecipe batchRecipe = resolveRecipe(num4);
int num7 = ((batchRecipe != null) ? resolveDuration(num4) : 0);
if (num7 > 0)
{
assemblyLine.SetRecipe(i, num4, batchRecipe, num7);
if (num5 > 0 && num6 >= 1 && num6 <= 1000)
{
assemblyLine.slots[i].Progress = Math.Min(num5, num7);
assemblyLine.slots[i].Multiplier = num6;
}
}
}
if (num >= 2)
{
assemblyLine.Ingredients.Read(reader);
}
return assemblyLine;
}
public int Advance(int work, IReadOnlyDictionary<int, int> limits, Dictionary<int, int> stock)
{
return Advance(work, (BatchRecipe recipe, int multiplier) => recipe.TryComplete(limits, stock, multiplier));
}
private int Advance(float work, Func<BatchRecipe, int, bool> completeBatch, Func<BatchRecipe, int, bool> hasInputs = null, Func<BatchRecipe, int, float> batchSpeed = null, float smeltingWork = -1f)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Invalid comparison between Unknown and I4
if (work <= 0f)
{
return 0;
}
int num = 0;
for (int i = 0; i < 10; i++)
{
int num2 = (firstSlot + i) % 10;
Slot slot = slots[num2];
if (slot.Recipe == null)
{
continue;
}
float num3 = ((smeltingWork >= 0f && (int)slot.Recipe.Type == 1) ? smeltingWork : work);
float num4 = num3 + slot.RemainingWork;
int num5 = (int)num4;
slot.RemainingWork = num4 - (float)num5;
while (num5 > 0)
{
if (slot.Progress == 0)
{
slot.Multiplier = Multiplier;
}
if (hasInputs != null && !hasInputs(slot.Recipe, slot.Multiplier))
{
break;
}
if (slot.Progress == 0 || slot.Speed == 0f)
{
slot.Speed = batchSpeed?.Invoke(slot.Recipe, slot.Multiplier) ?? 1f;
}
int num6 = Math.Min((int)((float)num5 * slot.Speed), slot.Duration - slot.Progress);
slot.Progress += num6;
num5 -= (int)Math.Ceiling((double)num6 / (double)slot.Speed);
if (slot.Progress < slot.Duration || !completeBatch(slot.Recipe, slot.Multiplier))
{
break;
}
num++;
slot.Progress = 0;
}
slots[num2] = slot;
}
firstSlot = (firstSlot + 1) % 10;
return num;
}
}
internal sealed class BatchRecipe
{
internal struct IngredientChange
{
public int Item;
public int Input;
public int Output;
}
internal const int MaximumMultiplier = 1000;
internal readonly IngredientChange[] Changes;
internal readonly bool SpeedupOnly;
internal readonly ERecipeType Type;
internal static int DurationInTicks(int executionTime, int recipeTime)
{
if (executionTime <= 0)
{
return recipeTime;
}
return (int)(((long)executionTime + 9999L) / 10000);
}
public BatchRecipe(int[] inputs, int[] inputCounts, int[] outputs, int[] outputCounts, bool speedupOnly = false, ERecipeType type = (ERecipeType)4)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
SpeedupOnly = speedupOnly;
Type = type;
Dictionary<int, IngredientChange> dictionary = new Dictionary<int, IngredientChange>();
Add(dictionary, inputs, inputCounts, output: false);
Add(dictionary, outputs, outputCounts, output: true);
Changes = new List<IngredientChange>(dictionary.Values).ToArray();
if (!Array.Exists(Changes, (IngredientChange change) => change.Output > 0))
{
throw new ArgumentException("A recipe must produce at least one item.");
}
}
private static void Add(Dictionary<int, IngredientChange> items, int[] ids, int[] counts, bool output)
{
if (ids == null || counts == null || ids.Length != counts.Length)
{
throw new ArgumentException("Recipe IDs and counts must align.");
}
for (int i = 0; i < ids.Length; i++)
{
checked
{
if (counts[i] != 0 || ids[i] < 0)
{
if (ids[i] <= 0 || counts[i] <= 0)
{
throw new ArgumentException("Recipe items and quantities must be positive.");
}
items.TryGetValue(ids[i], out var value);
value.Item = ids[i];
if (output)
{
value.Output += counts[i];
}
else
{
value.Input += counts[i];
}
items[value.Item] = value;
}
}
}
}
public bool TryComplete(IReadOnlyDictionary<int, int> limits, Dictionary<int, int> stock, int multiplier)
{
if (multiplier < 1 || multiplier > 1000)
{
throw new ArgumentOutOfRangeException("multiplier");
}
IngredientChange[] changes = Changes;
for (int i = 0; i < changes.Length; i++)
{
IngredientChange ingredientChange = changes[i];
stock.TryGetValue(ingredientChange.Item, out var value);
long num = (long)ingredientChange.Input * (long)multiplier;
long num2 = value - num + (long)ingredientChange.Output * (long)multiplier;
if (value < num || (ingredientChange.Output > 0 && (!limits.TryGetValue(ingredientChange.Item, out var value2) || num2 > value2)))
{
return false;
}
}
IngredientChange[] changes2 = Changes;
for (int j = 0; j < changes2.Length; j++)
{
IngredientChange ingredientChange2 = changes2[j];
stock.TryGetValue(ingredientChange2.Item, out var value3);
int num3 = (int)(value3 + ((long)ingredientChange2.Output - (long)ingredientChange2.Input) * multiplier);
if (num3 == 0)
{
stock.Remove(ingredientChange2.Item);
}
else
{
stock[ingredientChange2.Item] = num3;
}
}
return true;
}
}
internal sealed class HubPanel : IDisposable
{
private const int RecipeColumns = 5;
private const int InventorySlots = 30;
private const int Width = 985;
private const int Height = 506;
private readonly Plugin plugin;
private readonly Text[] recipeLabels = (Text[])(object)new Text[10];
private readonly Image[] recipeIcons = (Image[])(object)new Image[10];
private readonly Image[] progress = (Image[])(object)new Image[10];
private readonly Button[] clear = (Button[])(object)new Button[10];
private readonly Image[] items = (Image[])(object)new Image[30];
private readonly Text[] counts = (Text[])(object)new Text[30];
private readonly UIIncArrow[] arrows = (UIIncArrow[])(object)new UIIncArrow[30];
private readonly List<int> inputs = new List<int>(20);
private readonly List<int> outputs = new List<int>(10);
private readonly Vector3[] corners = (Vector3[])(object)new Vector3[4];
private RectTransform dockedStorage;
private Vector2 storagePosition;
private bool pickingRecipe;
private float nextRefresh;
private GameObject root;
private RectTransform panel;
private CanvasGroup native;
private NativeSkin skin;
private Font font;
private Text footer;
private Text powerLabel;
private AssemblyLine line;
private StorageComponent selectedStorage;
private bool showStorage;
private bool confirmClear;
private float savedAlpha;
private bool savedRaycasts;
internal RectTransform MultiplierAnchor
{
get
{
if (!((Object)(object)root != (Object)null) || !root.activeSelf || UIRecipePicker.isOpened)
{
return null;
}
return panel;
}
}
internal bool BlocksGamePointer
{
get
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
RectTransform val = (((Object)(object)root != (Object)null && root.activeSelf) ? panel : null);
if ((Object)(object)val != (Object)null)
{
return RectTransformUtility.RectangleContainsScreenPoint(val, Vector2.op_Implicit(Input.mousePosition), (Camera)null);
}
return false;
}
}
internal int Multiplier
{
get
{
if (line != null)
{
return line.Multiplier;
}
return 1;
}
}
internal HubPanel(Plugin plugin)
{
this.plugin = plugin;
}
internal void SetMultiplier(int value)
{
if (line != null)
{
line.SetMultiplier(value);
}
}
private Image Surface(Transform parent, string name, float x, float y, float w, float h)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(name, new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
val.transform.SetParent(parent, false);
Place(val.GetComponent<RectTransform>(), x, y, w, h);
Image component = val.GetComponent<Image>();
((Graphic)component).color = new Color(0.12f, 0.22f, 0.27f, 0.98f);
return component;
}
private static void Place(RectTransform rect, float x, float y, float w, float h)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: 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)
Vector2 val = (rect.pivot = new Vector2(0f, 1f));
Vector2 anchorMin = (rect.anchorMax = val);
rect.anchorMin = anchorMin;
rect.anchoredPosition = new Vector2(x, 0f - y);
rect.sizeDelta = new Vector2(w, h);
}
private Text Label(Transform parent, string value, float x, float y, float w, float h, int size)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("Label", new Type[2]
{
typeof(RectTransform),
typeof(Text)
});
val.transform.SetParent(parent, false);
Place(val.GetComponent<RectTransform>(), x, y, w, h);
Text component = val.GetComponent<Text>();
component.font = font;
component.text = value;
component.fontSize = size;
component.alignment = (TextAnchor)3;
((Graphic)component).color = Color.white;
((Graphic)component).raycastTarget = false;
return component;
}
private Button Button(Transform parent, string label, float x, float y, float w, float h, Action action)
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
Image val = Surface(parent, label, x, y, w, h);
Button val2 = ((Component)val).gameObject.AddComponent<Button>();
((Selectable)val2).targetGraphic = (Graphic)(object)val;
skin.Button(val2);
((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
{
action();
});
Text val3 = Label(((Component)val).transform, label, 0f, 0f, w, h, (label == "×") ? 12 : 15);
val3.alignment = (TextAnchor)4;
val3.horizontalOverflow = (HorizontalWrapMode)1;
val3.verticalOverflow = (VerticalWrapMode)1;
return val2;
}
private void Create(UIGame game)
{
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_02b0: 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_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_037e: Unknown result type (might be due to invalid IL or missing references)
//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
//IL_03b8: Expected O, but got Unknown
//IL_048c: Unknown result type (might be due to invalid IL or missing references)
//IL_06e8: Unknown result type (might be due to invalid IL or missing references)
//IL_063b: Unknown result type (might be due to invalid IL or missing references)
font = game.controlPanelWindow.FONT_SAIRASB;
skin = new NativeSkin();
root = new GameObject("AIO Assembler", new Type[3]
{
typeof(RectTransform),
typeof(Canvas),
typeof(GraphicRaycaster)
});
Canvas component = root.GetComponent<Canvas>();
component.renderMode = (RenderMode)0;
component.sortingOrder = 32740;
panel = ((Graphic)Surface(root.transform, "Window", Mathf.Max(0f, (float)(Screen.width - 985) / 2f), 88f, 985f, 506f)).rectTransform;
Image component2 = ((Component)panel).GetComponent<Image>();
((Graphic)component2).color = Color.clear;
int childCount = ((Transform)panel).childCount;
skin.Frame(game.storageWindow.windowTrans, panel);
if (((Transform)panel).childCount == childCount)
{
((Graphic)component2).color = new Color(0.045f, 0.075f, 0.105f, 0.98f);
}
Image val = Surface((Transform)(object)panel, "Title bar", 25f, 27f, 935f, 35f);
((Graphic)val).color = new Color(0.041f, 0.084f, 0.11f, 0.96f);
((Component)val).gameObject.AddComponent<WindowDrag>().Window = panel;
Label(((Component)val).transform, "AIO Assembler", 12f, 0f, 180f, 35f, 19);
Button(((Component)val).transform, "Storage", 667f, 4f, 90f, 27f, delegate
{
showStorage = !showStorage;
});
Button(((Component)val).transform, "Clear Recipes", 767f, 4f, 122f, 27f, ClearAll);
Button(((Component)val).transform, "×", 898f, 4f, 30f, 27f, delegate
{
game.ShutStorageWindow();
});
Image val2 = Surface((Transform)(object)panel, "Inventory backing", 25f, 71f, 935f, 371f);
((Graphic)val2).color = new Color(0.32f, 0.58f, 0.65f, 0.32f);
((Graphic)val2).raycastTarget = false;
Image val3 = Surface((Transform)(object)panel, "Inventory inset", 26f, 72f, 933f, 369f);
((Graphic)val3).color = new Color(0.038f, 0.078f, 0.1f, 0.91f);
((Graphic)val3).raycastTarget = false;
for (int num = 0; num < recipeLabels.Length; num++)
{
int slot = num;
Image val4 = Surface((Transform)(object)panel, "Recipe", 35 + 185 * (num % 5), 81 + 97 * (num / 5), 175f, 87f);
((Graphic)val4).color = new Color(0.13f, 0.25f, 0.29f, 0.82f);
Button val5 = ((Component)val4).gameObject.AddComponent<Button>();
((Selectable)val5).targetGraphic = (Graphic)(object)val4;
((UnityEvent)val5.onClick).AddListener((UnityAction)delegate
{
Choose(slot);
});
((Component)val4).gameObject.AddComponent<RecipeInspect>().Inspect = delegate
{
Inspect(slot);
};
recipeLabels[num] = Label(((Component)val4).transform, "", 47f, 7f, 100f, 68f, 13);
recipeIcons[num] = Surface(((Component)val4).transform, "Recipe icon", 8f, 20f, 32f, 32f);
((Graphic)recipeIcons[num]).raycastTarget = false;
progress[num] = Surface(((Component)val4).transform, "Progress", 8f, 75f, 159f, 4f);
((Graphic)progress[num]).color = new Color(0.32f, 0.8f, 0.87f);
((Graphic)progress[num]).raycastTarget = false;
clear[num] = Button(((Component)val4).transform, "×", 148f, 6f, 21f, 21f, delegate
{
ClearSlot(slot);
});
}
Label((Transform)(object)panel, "Inputs", 42f, 285f, 90f, 65f, 17);
Label((Transform)(object)panel, "Outputs", 42f, 386f, 90f, 45f, 17);
UIIncArrow val6 = FindArrowTemplate();
for (int num2 = 0; num2 < items.Length; num2++)
{
int num3 = ((num2 < 20) ? (276 + 51 * (num2 / 10)) : 385);
Image val7 = Surface((Transform)(object)panel, "Inventory slot", 137 + 82 * (num2 % 10), num3, 63f, 45f);
items[num2] = Surface(((Component)val7).transform, "Item icon", 4f, 2f, 31f, 31f);
((Graphic)items[num2]).raycastTarget = false;
if ((Object)(object)val6 != (Object)null)
{
Image val8 = Surface(((Component)val7).transform, "Proliferation arrows", 58f, 3f, 23f, 13f);
NativeSkin.Copy(val8, val6.arrowImage);
val8.preserveAspect = true;
((Graphic)val8).rectTransform.pivot = new Vector2(1f, 1f);
((Graphic)val8).raycastTarget = false;
UIIncArrow val9 = (arrows[num2] = ((Component)val8).gameObject.AddComponent<UIIncArrow>());
val9.arrowImage = val8;
val9.arrowArray = val6.arrowArray;
val9.incLevel = 0;
((Behaviour)val8).enabled = false;
}
counts[num2] = Label(((Component)val7).transform, "", 3f, 27f, 54f, 14f, 12);
counts[num2].alignment = (TextAnchor)5;
((Graphic)counts[num2]).color = new Color(0.5f, 0.95f, 1f);
counts[num2].resizeTextForBestFit = true;
counts[num2].resizeTextMinSize = 8;
counts[num2].resizeTextMaxSize = 12;
}
footer = Label((Transform)(object)panel, "Click a recipe slot to choose a recipe. Right-click for details.", 29f, 448f, 624f, 37f, 15);
powerLabel = Label((Transform)(object)panel, "", 840f, 448f, 117f, 37f, 15);
powerLabel.alignment = (TextAnchor)5;
}
private static UIIncArrow FindArrowTemplate()
{
UIIncArrow[] array = Resources.FindObjectsOfTypeAll<UIIncArrow>();
foreach (UIIncArrow val in array)
{
if ((Object)(object)val.arrowImage != (Object)null && val.arrowArray != null && val.arrowArray.Length > 1 && (Object)(object)val.arrowArray[1] != (Object)null)
{
return val;
}
}
return null;
}
private void Choose(int slot)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
AssemblyLine selected = line;
pickingRecipe = true;
UIRecipePicker.Popup(new Vector2(0f, 0f), (Action<RecipeProto>)delegate(RecipeProto recipe)
{
pickingRecipe = false;
if (recipe != null && selected == line && GameMain.history.RecipeUnlocked(((Proto)recipe).ID))
{
BatchRecipe batchRecipe = Plugin.ResolveRecipe(((Proto)recipe).ID);
if (batchRecipe != null)
{
BatchRecipe recipe2 = selected.Recipe(slot);
if (selected.RecipeId(slot) != ((Proto)recipe).ID)
{
selected.SetRecipe(slot, ((Proto)recipe).ID, batchRecipe, Plugin.ResolveDuration(((Proto)recipe).ID));
ReturnSlotItems(recipe2);
}
footer.text = "Inputs show stock / delivery target (" + 9 + " batches per recipe).";
nextRefresh = 0f;
}
else
{
footer.text = "AIO Assembler cannot run this recipe: " + ((Proto)recipe).name;
}
}
}, RecipePickerFilter.Filter);
}
private void Inspect(int slot)
{
RecipeProto val = ((ProtoSet<RecipeProto>)(object)LDB.recipes).Select(line.RecipeId(slot));
footer.text = ((val == null) ? "This slot is empty." : (((Proto)val).name + " | " + line.Progress(slot).ToString("P0") + " complete" + (line.HasPower ? (" | " + line.CycleSeconds(slot).ToString("0.##") + " s per batch at current power") : "")));
}
private void ClearAll()
{
if (confirmClear && line != null)
{
HashSet<int> hashSet = new HashSet<int>(line.LogisticsItems());
hashSet.UnionWith(line.Ingredients.Items);
line.ClearRecipes();
Plugin.ReturnUnusedItems(line, selectedStorage, hashSet);
nextRefresh = 0f;
}
confirmClear = !confirmClear;
footer.text = (confirmClear ? "Click Clear Recipes again to confirm." : "All recipes cleared.");
}
private void ClearSlot(int slot)
{
if (line != null && line.Recipe(slot) != null)
{
BatchRecipe recipe = line.Recipe(slot);
line.ClearRecipe(slot);
ReturnSlotItems(recipe);
footer.text = "Recipe cleared. Items shared with other recipes stay in storage.";
nextRefresh = 0f;
}
}
private void ReturnSlotItems(BatchRecipe recipe)
{
if (recipe != null)
{
List<int> list = new List<int>(recipe.Changes.Length);
BatchRecipe.IngredientChange[] changes = recipe.Changes;
for (int i = 0; i < changes.Length; i++)
{
BatchRecipe.IngredientChange ingredientChange = changes[i];
list.Add(ingredientChange.Item);
}
Plugin.ReturnUnusedItems(line, selectedStorage, list);
}
}
internal void Update()
{
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
UIRoot instance = UIRoot.instance;
UIGame val = (((Object)(object)instance == (Object)null) ? null : instance.uiGame);
UIStorageWindow val2 = (((Object)(object)val == (Object)null) ? null : val.storageWindow);
PlanetFactory val3 = (((Object)(object)val2 == (Object)null) ? null : val2.factory);
StorageComponent[] array = val3?.factoryStorage.storagePool;
StorageComponent storage = (((Object)(object)val2 != (Object)null && ((ManualBehaviour)val2).active && array != null && val2.storageId > 0 && val2.storageId < array.Length) ? array[val2.storageId] : null);
AssemblyLine assemblyLine = plugin.Open(val3, storage);
if (assemblyLine == null)
{
RestoreNative();
RestoreStoragePosition();
if (pickingRecipe)
{
UIRecipePicker.Close();
}
if ((Object)(object)root != (Object)null)
{
root.SetActive(false);
}
line = null;
selectedStorage = null;
return;
}
if ((Object)(object)root == (Object)null)
{
Create(val);
}
selectedStorage = storage;
if (line != assemblyLine)
{
line = assemblyLine;
showStorage = false;
confirmClear = false;
nextRefresh = 0f;
}
root.SetActive(true);
if (showStorage)
{
RestoreNative();
if ((Object)(object)dockedStorage != (Object)(object)val2.windowTrans)
{
RestoreStoragePosition();
dockedStorage = val2.windowTrans;
storagePosition = dockedStorage.anchoredPosition;
}
Dock(dockedStorage, right: false);
}
else
{
RestoreStoragePosition();
HideNative(val2.windowTrans);
}
if (pickingRecipe && UIRecipePicker.isOpened)
{
Dock(val.recipePicker.pickerTrans, right: true);
}
if (!(Time.unscaledTime < nextRefresh))
{
nextRefresh = Time.unscaledTime + 0.12f;
Refresh(storage);
}
}
private void Dock(RectTransform window, bool right)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: 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_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
//IL_017e: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)window == (Object)null)
{
return;
}
Transform parent = ((Transform)window).parent;
RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
if (!((Object)(object)val == (Object)null))
{
Canvas componentInParent = ((Component)window).GetComponentInParent<Canvas>();
Camera val2 = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null);
panel.GetWorldCorners(corners);
Vector2 val3 = RectTransformUtility.WorldToScreenPoint((Camera)null, corners[(!right) ? 1 : 2]);
window.GetWorldCorners(corners);
Vector2 val4 = RectTransformUtility.WorldToScreenPoint(val2, corners[1]);
Vector2 val5 = RectTransformUtility.WorldToScreenPoint(val2, corners[2]);
Vector2 val6 = RectTransformUtility.WorldToScreenPoint(val2, corners[0]);
float num = Mathf.Abs(val5.x - val4.x);
float num2 = Mathf.Abs(val4.y - val6.y);
float num3 = (right ? (val3.x + 6f) : (val3.x - 6f - num));
Vector2 val7 = default(Vector2);
((Vector2)(ref val7))..ctor(Mathf.Clamp(num3, 0f, Mathf.Max(0f, (float)Screen.width - num)), Mathf.Clamp(val3.y, Mathf.Min(num2, (float)Screen.height), (float)Screen.height));
Vector2 val8 = default(Vector2);
Vector2 val9 = default(Vector2);
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(val, val4, val2, ref val8) && RectTransformUtility.ScreenPointToLocalPointInRectangle(val, val7, val2, ref val9))
{
window.anchoredPosition += val9 - val8;
}
}
}
private void RestoreStoragePosition()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)dockedStorage == (Object)null))
{
dockedStorage.anchoredPosition = storagePosition;
dockedStorage = null;
}
}
private void HideNative(RectTransform window)
{
if (!((Object)(object)native != (Object)null))
{
native = ((Component)window).GetComponent<CanvasGroup>();
if ((Object)(object)native == (Object)null)
{
native = ((Component)window).gameObject.AddComponent<CanvasGroup>();
}
savedAlpha = native.alpha;
savedRaycasts = native.blocksRaycasts;
native.alpha = 0f;
native.blocksRaycasts = false;
}
}
private void RestoreNative()
{
if (!((Object)(object)native == (Object)null))
{
native.alpha = savedAlpha;
native.blocksRaycasts = savedRaycasts;
native = null;
}
}
private void Refresh(StorageComponent storage)
{
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
//IL_0327: Unknown result type (might be due to invalid IL or missing references)
powerLabel.text = "Grid power " + line.PowerServed.ToString("P0");
inputs.Clear();
outputs.Clear();
for (int i = 0; i < recipeLabels.Length; i++)
{
RecipeProto val = ((ProtoSet<RecipeProto>)(object)LDB.recipes).Select(line.RecipeId(i));
BatchRecipe batchRecipe = line.Recipe(i);
int num = line.BatchMultiplier(i);
string text = ((batchRecipe == null) ? "" : ((!line.HasPower) ? "No power" : ((!NativeStorage.HasInputs(line.Ingredients, batchRecipe, num)) ? "Needs inputs" : (line.WaitingForSpace(i) ? "Output full" : (line.Progress(i).ToString("P0") + " · " + num + "x")))));
recipeLabels[i].text = "Slot " + (i + 1) + "\n" + ((val == null) ? "Empty" : (((Proto)val).name + "\n" + text));
recipeIcons[i].sprite = ((val == null) ? null : val.iconSprite);
((Behaviour)recipeIcons[i]).enabled = val != null;
((Graphic)recipeIcons[i]).color = Color.white;
((Selectable)clear[i]).interactable = val != null;
((Graphic)progress[i]).rectTransform.sizeDelta = new Vector2(159f * line.Progress(i), 4f);
if (batchRecipe == null)
{
continue;
}
BatchRecipe.IngredientChange[] changes = batchRecipe.Changes;
for (int j = 0; j < changes.Length; j++)
{
BatchRecipe.IngredientChange ingredientChange = changes[j];
if (ingredientChange.Input > 0 && !inputs.Contains(ingredientChange.Item))
{
inputs.Add(ingredientChange.Item);
}
if (ingredientChange.Output > 0 && !outputs.Contains(ingredientChange.Item))
{
outputs.Add(ingredientChange.Item);
}
}
}
for (int k = 0; k < items.Length; k++)
{
bool flag = k < 20;
List<int> list = (flag ? inputs : outputs);
int num2 = (flag ? k : (k - 20));
ItemProto val2 = ((num2 < list.Count) ? ((ProtoSet<ItemProto>)(object)LDB.items).Select(list[num2]) : null);
items[k].sprite = ((val2 == null) ? null : val2.iconSprite);
((Behaviour)items[k]).enabled = val2 != null;
((Graphic)items[k]).color = Color.white;
if (val2 == null)
{
counts[k].text = "";
SetArrows(k, 0);
continue;
}
int num3;
long points2;
if (flag)
{
num3 = line.Ingredients.Read(((Proto)val2).ID, out var points);
points2 = points;
}
else
{
num3 = NativeStorage.OutputStock(storage, ((Proto)val2).ID, out points2);
}
SetArrows(k, (int)((num3 > 0) ? Math.Max(0L, Math.Min(10L, points2 / num3)) : 0));
line.LogisticsRule(((Proto)val2).ID, out var reserve, out var _);
counts[k].text = (flag ? (num3 + "/" + reserve) : num3.ToString());
}
}
private void SetArrows(int index, int level)
{
UIIncArrow val = arrows[index];
if (!((Object)(object)val == (Object)null) && val.incLevel != level)
{
val.incLevel = level;
if (level == 0)
{
((Behaviour)val.arrowImage).enabled = false;
}
}
}
public void Dispose()
{
RestoreNative();
RestoreStoragePosition();
if ((Object)(object)root != (Object)null)
{
Object.Destroy((Object)(object)root);
}
}
}
internal sealed class RecipeInspect : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
{
internal Action Inspect;
public void OnPointerClick(PointerEventData e)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)e.button == 1 && Inspect != null)
{
Inspect();
}
}
}
internal sealed class WindowDrag : MonoBehaviour, IDragHandler, IEventSystemHandler
{
internal RectTransform Window;
public void OnDrag(PointerEventData e)
{
//IL_0006: 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_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: 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_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
Vector2 anchoredPosition = Window.anchoredPosition + e.delta;
float x = anchoredPosition.x;
float num = Screen.width;
Rect rect = Window.rect;
anchoredPosition.x = Mathf.Clamp(x, 0f, Mathf.Max(0f, num - ((Rect)(ref rect)).width));
float y = anchoredPosition.y;
Rect rect2 = Window.rect;
anchoredPosition.y = Mathf.Clamp(y, Mathf.Min(0f, ((Rect)(ref rect2)).height - (float)Screen.height), 0f);
Window.anchoredPosition = anchoredPosition;
}
}
internal sealed class IngredientBuffer
{
private struct Stack
{
public int Count;
public int Points;
}
private readonly Dictionary<int, Stack> items = new Dictionary<int, Stack>();
internal IEnumerable<int> Items => items.Keys;
internal int Read(int item, out int points)
{
items.TryGetValue(item, out var value);
points = value.Points;
return value.Count;
}
internal int Count(int item)
{
int points;
return Read(item, out points);
}
internal void Set(int item, int count, int points)
{
if (count == 0)
{
items.Remove(item);
return;
}
items[item] = new Stack
{
Count = count,
Points = points
};
}
internal int PointsFor(int item, int count)
{
int points;
int num = Read(item, out points);
if (num != 0)
{
return points / num * count + Math.Max(0, points % num - (num - count));
}
return 0;
}
internal void Consume(int item, int count)
{
Stack stack = items[item];
Set(item, stack.Count - count, stack.Points - PointsFor(item, count));
}
internal void Write(BinaryWriter writer)
{
writer.Write(items.Count);
foreach (KeyValuePair<int, Stack> item in items)
{
writer.Write(item.Key);
writer.Write(item.Value.Count);
writer.Write(item.Value.Points);
}
}
internal void Read(BinaryReader reader)
{
int num = reader.ReadInt32();
if (num < 0 || num > 65536)
{
throw new InvalidDataException("Invalid AIO ingredient buffer size.");
}
for (int i = 0; i < num; i++)
{
int num2 = reader.ReadInt32();
int num3 = reader.ReadInt32();
int num4 = reader.ReadInt32();
if (num2 <= 0 || num3 <= 0 || num4 < 0 || items.ContainsKey(num2))
{
throw new InvalidDataException("Invalid AIO ingredient buffer entry.");
}
Set(num2, num3, num4);
}
}
}
internal sealed class NativeStorage
{
private StorageComponent scratch;
internal static int OutputStock(StorageComponent storage, int item, out long points)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
long num = 0L;
points = 0L;
for (int i = 0; i < storage.size; i++)
{
GRID val = storage.grids[i];
if (val.itemId == item && val.count > 0)
{
num += val.count;
points += val.inc;
}
}
return (int)Math.Min(2147483647L, num);
}
internal static void RefillFromStorage(StorageComponent storage, AssemblyLine line)
{
IReadOnlyList<int> readOnlyList = line.LogisticsItems();
int num5 = default(int);
for (int i = 0; i < readOnlyList.Count; i++)
{
int num = readOnlyList[i];
line.LogisticsRule(num, out var reserve, out var _);
if (reserve <= 0)
{
continue;
}
int points;
int num2 = line.Ingredients.Read(num, out points);
int val = reserve - num2;
int num3 = Math.Min(val, Math.Min(storage.GetItemCount(num), (int.MaxValue - points) / 10));
if (num3 > 0)
{
int num4 = storage.TakeItem(num, num3, ref num5);
if (num4 > 0)
{
line.Ingredients.Set(num, num2 + num4, points + num5);
}
}
}
}
internal static float SpeedForBatch(IngredientBuffer buffer, BatchRecipe recipe, int multiplier)
{
if (!recipe.SpeedupOnly || Cargo.accTableMilli == null || Cargo.accTableMilli.Length == 0)
{
return 1f;
}
int num = Math.Min(10, Cargo.accTableMilli.Length - 1);
bool flag = false;
BatchRecipe.IngredientChange[] changes = recipe.Changes;
for (int i = 0; i < changes.Length; i++)
{
BatchRecipe.IngredientChange ingredientChange = changes[i];
if (ingredientChange.Input > 0)
{
long num2 = (long)ingredientChange.Input * (long)multiplier;
if (num2 > buffer.Count(ingredientChange.Item))
{
return 1f;
}
flag = true;
num = Math.Min(num, buffer.PointsFor(ingredientChange.Item, (int)num2) / (int)num2);
if (num <= 0)
{
return 1f;
}
}
}
if (!flag)
{
return 1f;
}
return 1f + (float)Cargo.accTableMilli[num];
}
internal static bool HasInputs(IngredientBuffer buffer, BatchRecipe recipe, int multiplier)
{
BatchRecipe.IngredientChange[] changes = recipe.Changes;
for (int i = 0; i < changes.Length; i++)
{
BatchRecipe.IngredientChange ingredientChange = changes[i];
if (ingredientChange.Input > 0 && buffer.Count(ingredientChange.Item) < (long)ingredientChange.Input * (long)multiplier)
{
return false;
}
}
return true;
}
public bool TryComplete(StorageComponent storage, BatchRecipe recipe, int multiplier, AssemblyLine line)
{
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Expected O, but got Unknown
//IL_010c: 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)
if (multiplier < 1 || multiplier > 1000)
{
throw new ArgumentOutOfRangeException("multiplier");
}
if (storage == null || storage.size <= 0 || storage.grids == null || storage.grids.Length < storage.size)
{
return false;
}
IngredientBuffer ingredients = line.Ingredients;
BatchRecipe.IngredientChange[] changes = recipe.Changes;
for (int i = 0; i < changes.Length; i++)
{
BatchRecipe.IngredientChange ingredientChange = changes[i];
if (StorageComponent.itemStackCount == null || ingredientChange.Item >= StorageComponent.itemStackCount.Length || (long)ingredientChange.Input * (long)multiplier > int.MaxValue || (long)ingredientChange.Output * (long)multiplier > int.MaxValue || (ingredientChange.Input > 0 && ingredients.Count(ingredientChange.Item) < ingredientChange.Input * multiplier))
{
return false;
}
}
if (scratch == null || scratch.size != storage.size)
{
scratch = new StorageComponent(storage.size);
}
scratch.type = storage.type;
scratch.bans = storage.bans;
Array.Copy(storage.grids, scratch.grids, storage.size);
BatchRecipe.IngredientChange[] changes2 = recipe.Changes;
int num2 = default(int);
for (int j = 0; j < changes2.Length; j++)
{
BatchRecipe.IngredientChange ingredientChange2 = changes2[j];
int num = ingredientChange2.Output * multiplier;
if (num <= 0)
{
continue;
}
if (scratch.AddItem(ingredientChange2.Item, num, 0, ref num2, false) != num)
{
return false;
}
int num3 = 0;
for (int k = 0; k < scratch.size; k++)
{
if (scratch.grids[k].itemId == ingredientChange2.Item && scratch.grids[k].count > 0 && ++num3 > 8)
{
return false;
}
}
}
BatchRecipe.IngredientChange[] changes3 = recipe.Changes;
for (int l = 0; l < changes3.Length; l++)
{
BatchRecipe.IngredientChange ingredientChange3 = changes3[l];
if (ingredientChange3.Input > 0)
{
ingredients.Consume(ingredientChange3.Item, ingredientChange3.Input * multiplier);
}
}
Array.Copy(scratch.grids, storage.grids, storage.size);
storage.searchStart = 0;
storage.lastEmptyItem = (storage.lastFullItem = -1);
storage.NotifyStorageChange();
return true;
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInIncompatibility("org.xcm.dsp.molecularhub")]
[CommonAPISubmoduleDependency(new string[] { "ProtoRegistry", "LocalizationModule" })]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("LokiMoonLabs.AIOAssembler", "AIO Assembler", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class Plugin : BaseUnityPlugin, IModCanSave
{
[HarmonyPatch(typeof(GameLogic), "OnFactoryFrameEnd")]
private static class FactoryEnd
{
private static void Postfix(GameLogic __instance)
{
if ((Object)(object)instance != (Object)null && (Object)(object)__instance.main != (Object)null && !__instance.main.isMenuDemo)
{
instance.Tick(__instance.data);
}
}
}
[HarmonyPatch(typeof(PlanetFactory), "RemoveEntityWithComponents")]
private static class RemoveEntity
{
private static void Prefix(PlanetFactory __instance, int __0)
{
if ((Object)(object)instance == (Object)null || GameMain.mainPlayer == null || __0 <= 0 || __0 >= __instance.entityPool.Length)
{
return;
}
StorageComponent[] storagePool = __instance.factoryStorage.storagePool;
int storageId = __instance.entityPool[__0].storageId;
if (storageId <= 0 || storageId >= storagePool.Length)
{
return;
}
AssemblyLine assemblyLine = FindLogisticsLine(__instance, storagePool[storageId]);
if (assemblyLine == null)
{
return;
}
foreach (int item in new List<int>(assemblyLine.Ingredients.Items))
{
ReturnBufferedItem(assemblyLine, GameMain.mainPlayer, __0, item);
}
}
private static void Postfix(PlanetFactory __instance, int __0)
{
if (!((Object)(object)instance == (Object)null))
{
long num = ((long)__instance.planetId << 32) | (uint)__0;
if (instance.machines.Remove(num))
{
instance.keys.Remove(num);
}
}
}
}
[HarmonyPatch(typeof(VFInput), "UpdateGameStates")]
private static class InputGuard
{
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void Postfix()
{
if (!((Object)(object)instance == (Object)null) && instance.panel != null && instance.panel.BlocksGamePointer)
{
VFInput.onGUI = true;
VFInput.onGUIOperate = true;
VFInput.inScrollView = true;
}
}
}
public const string Id = "LokiMoonLabs.AIOAssembler";
private const int ItemId = 2907;
private const int RecipeId = 1789;
private const int TechId = 1989;
private const int StorageColumns = 10;
private const int StorageRows = 10;
private static Plugin instance;
private readonly Dictionary<long, AssemblyLine> machines = new Dictionary<long, AssemblyLine>();
private readonly List<long> keys = new List<long>();
private readonly NativeStorage transfer = new NativeStorage();
private Harmony harmony;
private ItemProto item;
private ModelProto buildingModel;
private ModelProto templateModel;
private HubPanel panel;
private StorageComponent currentStorage;
private AssemblyLine currentLine;
private Func<BatchRecipe, int, bool> complete;
private Func<BatchRecipe, int, bool> hasInputs;
private Func<BatchRecipe, int, float> batchSpeed;
private float machineSpeed = 1f;
private Func<ERecipeType, int> overclock;
private void Awake()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
if (Chainloader.PluginInfos.ContainsKey("dsp.nebula-multiplayer"))
{
return;
}
harmony = new Harmony("LokiMoonLabs.AIOAssembler");
using (ProtoRegistry.StartModLoad("LokiMoonLabs.AIOAssembler"))
{
RegisterBuilding();
}
if (item == null)
{
return;
}
ProtoRegistry.onLoadingFinished += ConfigurePower;
complete = (BatchRecipe recipe, int multiplier) => transfer.TryComplete(currentStorage, recipe, multiplier, currentLine);
hasInputs = (BatchRecipe recipe, int multiplier) => NativeStorage.HasInputs(currentLine.Ingredients, recipe, multiplier);
batchSpeed = (BatchRecipe recipe, int multiplier) => NativeStorage.SpeedForBatch(currentLine.Ingredients, recipe, multiplier);
instance = this;
harmony.CreateClassProcessor(typeof(FactoryEnd)).Patch();
harmony.CreateClassProcessor(typeof(RemoveEntity)).Patch();
harmony.CreateClassProcessor(typeof(InputGuard)).Patch();
harmony.CreateClassProcessor(typeof(RecipePickerFilter)).Patch();
if (!RecipePickerFilter.Installed)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"AIO could not extend the native recipe picker. Existing smelting recipes can still run.");
}
panel = new HubPanel(this);
if (Chainloader.PluginInfos.TryGetValue("LokiMoonLabs.FastNFurious", out var value) && (Object)(object)value.Instance != (Object)null)
{
Type type = ((object)value.Instance).GetType().Assembly.GetType("LokiMoonLabs.FastNFurious.PluginConfig");
MethodInfo methodInfo = ((type == null) ? null : type.GetMethod("GetMultiplierByRecipe", new Type[1] { typeof(ERecipeType) }));
if (methodInfo != null && methodInfo.IsStatic && methodInfo.ReturnType == typeof(int))
{
overclock = (Func<ERecipeType, int>)Delegate.CreateDelegate(typeof(Func<ERecipeType, int>), methodInfo);
}
}
if (!Chainloader.PluginInfos.TryGetValue("LokiMoonLabs.HoneyIShrunkTheFactory", out var value2) || !((Object)(object)value2.Instance != (Object)null))
{
return;
}
MethodInfo method = ((object)value2.Instance).GetType().GetMethod("RegisterExternalPanel");
if (method != null)
{
method.Invoke(null, new object[3]
{
(Func<RectTransform>)(() => panel.MultiplierAnchor),
(Func<int>)(() => panel.Multiplier),
new Action<int>(panel.SetMultiplier)
});
}
}
private void RegisterBuilding()
{
//IL_02c8: 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_0318: 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)
//IL_0333: Unknown result type (might be due to invalid IL or missing references)
//IL_0338: Unknown result type (might be due to invalid IL or missing references)
//IL_0449: Unknown result type (might be due to invalid IL or missing references)
//IL_0458: Unknown result type (might be due to invalid IL or missing references)
//IL_045d: Unknown result type (might be due to invalid IL or missing references)
ModelProto val = ((ProtoSet<ModelProto>)(object)LDB.models).Select(456);
TechProto val2 = ((ProtoSet<TechProto>)(object)LDB.techs).Select(1124);
int num = ((ProtoSet<ModelProto>)(object)LDB.models).dataArray.Length + 64;
HashSet<int> hashSet = OccupiedIds((IEnumerable<Proto>)(object)((ProtoSet<ModelProto>)(object)LDB.models).dataArray, typeof(ModelProto));
int i;
for (i = 669; i < num && hashSet.Contains(i); i++)
{
}
if (i >= num)
{
i = num - 1;
while (i > 52 && hashSet.Contains(i))
{
i--;
}
}
i = ((BaseUnityPlugin)this).Config.Bind<int>("Registration", "ModelId", i, "Save identity for AIO Assembler. Keep this value after placing a building.").Value;
bool flag = hashSet.Contains(i);
int num2 = Reserve(2907, "ItemId", OccupiedIds((IEnumerable<Proto>)(object)((ProtoSet<ItemProto>)(object)LDB.items).dataArray, typeof(ItemProto)), 11999);
int num3 = Reserve(1789, "RecipeId", OccupiedIds((IEnumerable<Proto>)(object)((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray, typeof(RecipeProto)), 9999);
int num4 = Reserve(1989, "TechId", OccupiedIds((IEnumerable<Proto>)(object)((ProtoSet<TechProto>)(object)LDB.techs).dataArray, typeof(TechProto)), 9999);
if (val == null || val2 == null || i <= 52 || i >= num || flag || num2 == 0 || num3 == 0 || num4 == 0)
{
((BaseUnityPlugin)this).Logger.LogError((object)("AIO registration blocked. Assembler model present=" + (val != null) + ", model ID=" + i + ", model limit=" + num + ", model occupied=" + flag + ", item=" + num2 + ", recipe=" + num3 + ", tech=" + num4 + ", Structure Matrix present=" + (val2 != null) + "."));
return;
}
LocalizationModule.RegisterTranslation("AIOAssembler.Name", "AIO Assembler");
LocalizationModule.RegisterTranslation("AIOAssembler.Description", "Runs up to eight recipes using shared storage.");
LocalizationModule.RegisterTranslation("AIOAssembler.Unlock", "Unlocks the AIO Assembler.");
templateModel = val;
ModelProto val3 = (buildingModel = ProtoRegistry.RegisterModel(i, val.PrefabPath, (Material[])null, 0));
val3.HpMax = val.HpMax;
val3.HpRecover = val.HpRecover;
val3.HpUpgrade = val.HpUpgrade;
val3.RendererType = val.RendererType;
val3.ObjectType = val.ObjectType;
val3.RotSymmetry = val.RotSymmetry;
val3.Order = val.Order;
item = ProtoRegistry.RegisterItem(num2, "AIOAssembler.Name", "AIOAssembler.Description", "Icons/ItemRecipe/assembler-4", ProtoRegistry.GetGridIndex(2, 14, 1), 50, (EItemType)6, ProtoRegistry.GetDefaultIconDesc(Color32.op_Implicit(new Color32((byte)11, (byte)140, (byte)122, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)236, (byte)189, (byte)52, byte.MaxValue))));
ProtoRegistry.AddModelToItemProto(val3, item, new int[1] { 1 }, 810);
RecipeProto val4 = ProtoRegistry.RegisterRecipe(num3, (ERecipeType)4, 480, new int[3] { 2304, 1303, 2013 }, new int[3] { 8, 16, 20 }, new int[1] { ((Proto)item).ID }, new int[1] { 1 }, "AIOAssembler.Description", 0, item.GridIndex, "AIOAssembler.Name", "Icons/ItemRecipe/assembler-4");
ProtoRegistry.RegisterTech(num4, "AIOAssembler.Name", "AIOAssembler.Description", "AIOAssembler.Unlock", "Icons/ItemRecipe/assembler-4", new int[1] { ((Proto)val2).ID }, new int[1] { 6003 }, new int[1] { 1 }, 12000L, new int[1] { ((Proto)val4).ID }, val2.Position + new Vector2(8f, -8f));
((BaseUnityPlugin)this).Logger.LogInfo((object)("AIO IDs: item " + ((Proto)item).ID + ", model " + ((Proto)val3).ID + ", recipe " + ((Proto)val4).ID + ", tech " + num4));
}
private int Reserve(int preferred, string key, HashSet<int> occupied, int limit)
{
while (preferred <= limit && occupied.Contains(preferred))
{
preferred++;
}
ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>("Registration", key, preferred, "Save identity for AIO Assembler. Keep this value after placing a building.");
if (key == "ItemId" && val.Value == 12000 && preferred <= limit)
{
val.Value = preferred;
}
int value = val.Value;
if (value <= 0 || value > limit || occupied.Contains(value))
{
return 0;
}
return value;
}
private static HashSet<int> OccupiedIds(IEnumerable<Proto> current, Type type)
{
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Expected O, but got Unknown
HashSet<int> hashSet = new HashSet<int>();
foreach (Proto item in current)
{
if (item != null)
{
hashSet.Add(item.ID);
}
}
Type type2 = AccessTools.TypeByName("xiaoye97.LDBTool");
if (type2 == null)
{
return hashSet;
}
string[] array = new string[3] { "PreToAdd", "PostToAdd", "TotalDict" };
foreach (string text in array)
{
FieldInfo fieldInfo = AccessTools.Field(type2, text);
IEnumerable enumerable = ((fieldInfo == null) ? null : (fieldInfo.GetValue(null) as IEnumerable));
if (enumerable == null)
{
continue;
}
foreach (IEnumerable item2 in enumerable)
{
foreach (Proto item3 in item2)
{
Proto val = item3;
if (val != null && ((object)val).GetType() == type)
{
hashSet.Add(val.ID);
}
}
}
}
return hashSet;
}
private void ConfigurePower()
{
PrefabDesc prefabDesc = buildingModel.prefabDesc;
if (prefabDesc == null || object.ReferenceEquals(prefabDesc, templateModel.prefabDesc))
{
((BaseUnityPlugin)this).Logger.LogError((object)"AIO Assembler could not initialize its independent power descriptor.");
return;
}
prefabDesc.isAssembler = false;
machineSpeed = Mathf.Max(1f, (float)prefabDesc.assemblerSpeed / 10000f);
prefabDesc.isStorage = true;
prefabDesc.storageCol = 10;
prefabDesc.storageRow = 10;
prefabDesc.isPowerConsumer = true;
prefabDesc.workEnergyPerTick = 9000L;
prefabDesc.idleEnergyPerTick = 300L;
prefabDesc.multiLevel = false;
((BaseUnityPlugin)this).Logger.LogInfo((object)"AIO Assembler registered with native storage and power.");
}
internal AssemblyLine Select(PlanetFactory factory, StorageComponent storage)
{
if (!IsHub(factory, storage))
{
return null;
}
long key = ((long)factory.planetId << 32) | (uint)storage.entityId;
if (!machines.TryGetValue(key, out var value))
{
value = new AssemblyLine();
machines.Add(key, value);
}
return value;
}
public static IReadOnlyList<int> GetLogisticsItems(PlanetFactory factory, StorageComponent storage)
{
return FindLogisticsLine(factory, storage)?.LogisticsItems();
}
public static bool GetLogisticsRule(PlanetFactory factory, StorageComponent storage, int item, out int reserve, out bool output)
{
if (!GetIngredientLogisticsRule(factory, storage, item, out reserve, out output))
{
return false;
}
reserve = Math.Max(0, reserve - ReadIngredientBuffer(factory, storage, item, out var _));
if (reserve <= 0)
{
return output;
}
return true;
}
public static bool GetIngredientLogisticsRule(PlanetFactory factory, StorageComponent storage, int item, out int reserve, out bool output)
{
reserve = 0;
output = false;
return FindLogisticsLine(factory, storage)?.LogisticsRule(item, out reserve, out output) ?? false;
}
public static int ReadIngredientBuffer(PlanetFactory factory, StorageComponent storage, int item, out int points)
{
AssemblyLine assemblyLine = FindLogisticsLine(factory, storage);
points = 0;
return assemblyLine?.Ingredients.Read(item, out points) ?? 0;
}
public static void WriteIngredientBuffer(PlanetFactory factory, StorageComponent storage, int item, int count, int points)
{
FindLogisticsLine(factory, storage)?.Ingredients.Set(item, count, points);
}
private static AssemblyLine FindLogisticsLine(PlanetFactory factory, StorageComponent storage)
{
if ((Object)(object)instance == (Object)null || !instance.IsHub(factory, storage))
{
return null;
}
instance.machines.TryGetValue(((long)factory.planetId << 32) | (uint)storage.entityId, out var value);
return value;
}
private bool IsHub(PlanetFactory factory, StorageComponent storage)
{
if (factory != null && storage != null && storage.entityId > 0 && storage.entityId < factory.entityPool.Length && factory.entityPool[storage.entityId].id == storage.entityId && factory.entityPool[storage.entityId].protoId == ((Proto)item).ID)
{
return factory.entityPool[storage.entityId].storageId == storage.id;
}
return false;
}
internal static BatchRecipe ResolveRecipe(int id)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Invalid comparison between Unknown and I4
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Invalid comparison between Unknown and I4
//IL_0096: 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)
RecipeProto val = ((ProtoSet<RecipeProto>)(object)LDB.recipes).Select(id);
if (val == null || ((int)val.Type != 4 && (int)val.Type != 1) || ResolveDuration(id) <= 0)
{
return null;
}
try
{
if (RecipeProto.recipeExecuteData != null && RecipeProto.recipeExecuteData.TryGetValue(id, out var value) && value != null)
{
return new BatchRecipe(value.requires, value.requireCounts, value.products, value.productCounts, !value.productive, val.Type);
}
return new BatchRecipe(val.Items, val.ItemCounts, val.Results, val.ResultCounts, !val.productive, val.Type);
}
catch (ArgumentException)
{
return null;
}
catch (OverflowException)
{
return null;
}
}
internal static int ResolveDuration(int id)
{
RecipeProto val = ((ProtoSet<RecipeProto>)(object)LDB.recipes).Select(id);
if (val == null)
{
return 0;
}
if (RecipeProto.recipeExecuteData != null && RecipeProto.recipeExecuteData.TryGetValue(id, out var value) && value != null)
{
return BatchRecipe.DurationInTicks(value.timeSpend, val.TimeSpend);
}
return val.TimeSpend;
}
private void Tick(GameData data)
{
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
if (data == null || machines.Count == 0)
{
return;
}
int num = ((overclock == null) ? 1 : Mathf.Clamp(overclock((ERecipeType)4), 1, 20));
int num2 = ((overclock == null) ? 1 : Mathf.Clamp(overclock((ERecipeType)1), 1, 20));
foreach (long key in keys)
{
int num3 = (int)(key >> 32);
int num4 = (int)key;
PlanetFactory val = data.galaxy.PlanetById(num3)?.factory;
if (val == null || num4 <= 0 || num4 >= val.entityPool.Length)
{
continue;
}
int storageId = val.entityPool[num4].storageId;
StorageComponent[] storagePool = val.factoryStorage.storagePool;
if (storageId > 0 && storageId < storagePool.Length && IsHub(val, storagePool[storageId]))
{
AssemblyLine assemblyLine = (currentLine = machines[key]);
currentStorage = storagePool[storageId];
if (currentStorage.size < 100)
{
currentStorage.SetSize(100);
}
NativeStorage.RefillFromStorage(currentStorage, assemblyLine);
int powerConId = val.entityPool[num4].powerConId;
PowerSystem powerSystem = val.powerSystem;
if (powerConId <= 0 || powerConId >= powerSystem.consumerPool.Length)
{
assemblyLine.PowerServed = 0f;
assemblyLine.AdvancePowered(0f, hasInputs, complete);
Animate(val, num4, 0f, working: false);
continue;
}
PowerConsumerComponent val2 = powerSystem.consumerPool[powerConId];
int configuredSlots = assemblyLine.ConfiguredSlots;
int networkId = val2.networkId;
float num5 = (assemblyLine.PowerServed = ((configuredSlots > 0 && networkId > 0 && networkId < powerSystem.networkServes.Length) ? powerSystem.networkServes[networkId] : 0f));
float num7 = ((num5 < 0.1f) ? 0f : (machineSpeed * num5));
assemblyLine.AdvancePowered(num7 * (float)num, hasInputs, complete, batchSpeed, num7 * (float)num2);
long num8 = assemblyLine.WorkingMachines(hasInputs);
powerSystem.consumerPool[powerConId].requiredEnergy = ((num8 == 0) ? val2.idleEnergyPerTick : (val2.workEnergyPerTick * num8));
Animate(val, num4, num5, assemblyLine.HasPower && num8 > 0);
}
}
currentStorage = null;
currentLine = null;
}
private void Animate(PlanetFactory factory, int entity, float power, bool working)
{
AnimData[] entityAnimPool = factory.entityAnimPool;
if (entityAnimPool != null && entity < entityAnimPool.Length)
{
PrefabDesc prefabDesc = buildingModel.prefabDesc;
entityAnimPool[entity].prepare_length = prefabDesc.anim_prepare_length;
entityAnimPool[entity].working_length = prefabDesc.anim_working_length;
((AnimData)(ref entityAnimPool[entity])).Step(working ? 1u : 0u, power / 60f);
entityAnimPool[entity].power = power;
}
}
internal static void ReturnUnusedItems(AssemblyLine line, StorageComponent storage, IEnumerable<int> items)
{
Player mainPlayer = GameMain.mainPlayer;
if (storage == null || mainPlayer == null)
{
return;
}
int num2 = default(int);
foreach (int item in items)
{
int reserve;
bool output;
bool flag = line.LogisticsRule(item, out reserve, out output);
if (reserve == 0)
{
ReturnBufferedItem(line, mainPlayer, storage.entityId, item);
}
if (flag)
{
continue;
}
int itemCount = storage.GetItemCount(item);
if (itemCount <= 0)
{
continue;
}
int num = storage.TakeItem(item, itemCount, ref num2);
if (num > 0)
{
int num3 = mainPlayer.TryAddItemToPackage(item, num, num2, true, storage.entityId, false);
if (num3 > 0)
{
UIItemup.Up(item, num3);
}
}
}
}
private static void ReturnBufferedItem(AssemblyLine line, Player player, int entity, int item)
{
int points;
int num = line.Ingredients.Read(item, out points);
if (num > 0)
{
int num2 = player.TryAddItemToPackage(item, num, points, true, entity, false);
line.Ingredients.Set(item, 0, 0);
if (num2 > 0)
{
UIItemup.Up(item, num2);
}
}
}
internal AssemblyLine Open(PlanetFactory factory, StorageComponent storage)
{
AssemblyLine assemblyLine = Select(factory, storage);
if (assemblyLine != null)
{
long num = ((long)factory.planetId << 32) | (uint)storage.entityId;
if (!keys.Contains(num))
{
keys.Add(num);
}
}
return assemblyLine;
}
private void LateUpdate()
{
if (panel != null)
{
panel.Update();
}
}
private void OnDestroy()
{
ProtoRegistry.onLoadingFinished -= ConfigurePower;
if (panel != null)
{
panel.Dispose();
}
if (harmony != null)
{
harmony.UnpatchSelf();
}
if ((Object)(object)instance == (Object)(object)this)
{
instance = null;
}
}
public void Export(BinaryWriter writer)
{
writer.Write(machines.Count);
foreach (KeyValuePair<long, AssemblyLine> machine in machines)
{
writer.Write(machine.Key);
machine.Value.Write(writer);
}
}
public void Import(BinaryReader reader)
{
Dictionary<long, AssemblyLine> dictionary = new Dictionary<long, AssemblyLine>();
int num = reader.ReadInt32();
if (num < 0 || num > 1000000)
{
throw new InvalidDataException("Invalid AIO Assembler count.");
}
for (int i = 0; i < num; i++)
{
dictionary.Add(reader.ReadInt64(), AssemblyLine.Read(reader, ResolveRecipe, ResolveDuration));
}
IntoOtherSave();
foreach (KeyValuePair<long, AssemblyLine> item in dictionary)
{
machines.Add(item.Key, item.Value);
keys.Add(item.Key);
}
}
public void IntoOtherSave()
{
machines.Clear();
keys.Clear();
}
}
[HarmonyPatch(typeof(UIRecipePicker), "RefreshIcons")]
internal static class RecipePickerFilter
{
private const ERecipeType Mixed = (ERecipeType)255;
internal static bool Installed { get; private set; }
internal static ERecipeType Filter
{
get
{
if (Installed)
{
return (ERecipeType)255;
}
return (ERecipeType)4;
}
}
private static bool Matches(ERecipeType filter, ERecipeType type)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Invalid comparison between Unknown and I4
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Invalid comparison between Unknown and I4
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Invalid comparison between Unknown and I4
if ((int)filter != 255)
{
return filter == type;
}
if ((int)type != 4)
{
return (int)type == 1;
}
return true;
}
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
FieldInfo fieldInfo = AccessTools.Field(typeof(UIRecipePicker), "filter");
FieldInfo fieldInfo2 = AccessTools.Field(typeof(RecipeProto), "Type");
for (int i = 5; i + 1 < list.Count; i++)
{
CodeInstruction val = list[i + 1];
if (CodeInstructionExtensions.LoadsField(list[i - 4], fieldInfo, false) && CodeInstructionExtensions.LoadsField(list[i], fieldInfo2, false) && (!(val.opcode != OpCodes.Bne_Un) || !(val.opcode != OpCodes.Bne_Un_S)))
{
CodeInstruction val2 = new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(RecipePickerFilter), "Matches", (Type[])null, (Type[])null));
val2.labels.AddRange(val.labels);
val2.blocks.AddRange(val.blocks);
val.labels.Clear();
val.blocks.Clear();
val.opcode = OpCodes.Brfalse;
list.Insert(i + 1, val2);
Installed = true;
break;
}
}
return list;
}
}
}
namespace LokiMoonLabs.HoneyIShrunkTheFactory
{
internal sealed class NativeSkin
{
private readonly UIComboBox combo;
private readonly Button button;
private readonly Slider slider;
internal NativeSkin()
{
UIGame uiGame = UIRoot.instance.uiGame;
combo = uiGame.controlPanelWindow.filterPanel.sortFilterBox;
UIButton copyButton = uiGame.assemblerWindow.copyButton;
if ((Object)(object)copyButton != (Object)null)
{
button = copyButton.button;
}
if (!((Object)(object)uiGame.stationWindow != (Object)null))
{
return;
}
Slider[] componentsInChildren = ((Component)uiGame.stationWindow).GetComponentsInChildren<Slider>(true);
foreach (Slider val in componentsInChildren)
{
if ((Object)(object)val.handleRect != (Object)null)
{
slider = val;
break;
}
}
}
internal static void Copy(Image target, Image source)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)source == (Object)null))
{
target.sprite = source.sprite;
target.type = source.type;
((Graphic)target).material = ((Graphic)source).material;
((Graphic)target).color = ((Graphic)source).color;
target.fillCenter = source.fillCenter;
target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier;
}
}
internal void Input(Image target)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
Copy(target, ((Component)combo).GetComponent<Image>());
((Graphic)target).color = new Color(0.09f, 0.14f, 0.16f, 1f);
}
internal void Button(Button target)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected O, but got Unknown
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
Copy((Image)((Selectable)target).targetGraphic, (Image)(((Object)(object)button != (Object)null) ? ((object)/*isinst with value type is only supported in some contexts*/) : ((object)((Component)combo).GetComponent<Image>())));
if ((Object)(object)button != (Object)null)
{
((Selectable)target).colors = ((Selectable)button).colors;
((Selectable)target).transition = (Transition)1;
}
}
internal void Popup(Image target)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
Copy(target, ((Component)combo.m_DropDownList).GetComponent<Image>());
((Graphic)target).color = new Color(0.075f, 0.11f, 0.13f, 1f);
}
internal void Option(Button target)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: 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)
Image val = (Image)((Selectable)target).targetGraphic;
val.sprite = null;
((Graphic)val).material = null;
((Graphic)val).color = Color.white;
ColorBlock colors = ((Selectable)target).colors;
((ColorBlock)(ref colors)).normalColor = new Color(0.09f, 0.14f, 0.16f, 1f);
((ColorBlock)(ref colors)).highlightedColor = new Color(0.22f, 0.39f, 0.44f, 1f);
((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).highlightedColor;
((ColorBlock)(ref colors)).pressedColor = new Color(0.14f, 0.27f, 0.31f, 1f);
((Selectable)target).colors = colors;
}
internal void Scrollbar(Scrollbar target)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)combo.m_Scrollbar == (Object)null))
{
Copy(((Component)target).GetComponent<Image>(), ((Component)combo.m_Scrollbar).GetComponent<Image>());
object target2 = (object)(Image)((Selectable)target).targetGraphic;
Graphic targetGraphic = ((Selectable)combo.m_Scrollbar).targetGraphic;
Copy((Image)target2, (Image)(object)((targetGraphic is Image) ? targetGraphic : null));
((Selectable)target).colors = ((Selectable)combo.m_Scrollbar).colors;
}
}
internal void Slider(Slider target, Image background)
{
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Expected O, but got Unknown
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)slider == (Object)null)
{
return;
}
Image val = ((Component)slider).GetComponent<Image>();
if ((Object)(object)val == (Object)null)
{
Image[] componentsInChildren = ((Component)slider).GetComponentsInChildren<Image>(true);
foreach (Image val2 in componentsInChildren)
{
if ((Object)(object)((Component)val2).transform != (Object)(object)slider.handleRect && ((Object)val2).name.IndexOf("background", StringComparison.OrdinalIgnoreCase) >= 0)
{
val = val2;
break;
}
}
}
Copy(background, val);
((Graphic)background).color = new Color(0.07f, 0.12f, 0.14f, 1f);
Copy((Image)((Selectable)target).targetGraphic, ((Component)slider.handleRect).GetComponent<Image>());
((Selectable)target).colors = ((Selectable)slider).colors;
}
internal void Arrow(RectTransform parent, Font font)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: 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_0054: 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_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("Native dropdown arrow", new Type[1] { typeof(RectTransform) });
val.transform.SetParent((Transform)(object)parent, false);
RectTransform component = val.GetComponent<RectTransform>();
Vector2 val2 = (component.pivot = new Vector2(1f, 0.5f));
Vector2 anchorMin = (component.anchorMax = val2);
component.anchorMin = anchorMin;
component.anchoredPosition = new Vector2(-8f, 0f);
component.sizeDelta = new Vector2(12f, 14f);
Image[] componentsInChildren = ((Component)combo).GetComponentsInChildren<Image>(true);
foreach (Image val5 in componentsInChildren)
{
string text = ((Object)val5).name.ToLowerInvariant();
if (text.Contains("arrow") || text.Contains("down"))
{
Copy(val.AddComponent<Image>(), val5);
((Graphic)val.GetComponent<Image>()).raycastTarget = false;
return;
}
}
Text val6 = val.AddComponent<Text>();
val6.font = font;
val6.fontSize = 12;
val6.text = "▾";
val6.alignment = (TextAnchor)4;
((Graphic)val6).raycastTarget = false;
}
internal void Frame(RectTransform source, RectTransform target)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: 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_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: 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_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Expected O, but got Unknown
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_017e: Unknown result type (might be due to invalid IL or missing references)
//IL_018c: 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_0192: Unknown result type (might be due to invalid IL or missing references)
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01d2: Expected O, but got Unknown
//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
//IL_0209: Unknown result type (might be due to invalid IL or missing references)
Vector3[] array = (Vector3[])(object)new Vector3[4];
Rect rect = source.rect;
if (((Rect)(ref rect)).width <= 0f || ((Rect)(ref rect)).height <= 0f)
{
return;
}
Graphic[] componentsInChildren = ((Component)source).GetComponentsInChildren<Graphic>(true);
foreach (Graphic val in componentsInChildren)
{
if (!((Behaviour)val).enabled || (!(val is Image) && !(val is RawImage)))
{
continue;
}
val.rectTransform.GetWorldCorners(array);
Vector3 val2 = ((Transform)source).InverseTransformPoint(array[0]);
Vector3 val3 = ((Transform)source).InverseTransformPoint(array[2]);
float num = val3.x - val2.x;
float num2 = val3.y - val2.y;
if (!(num >= ((Rect)(ref rect)).width * 0.85f) || !(num2 >= ((Rect)(ref rect)).height * 0.8f))
{
continue;
}
bool flag = false;
Transform val4 = ((Component)val).transform;
while ((Object)(object)val4 != (Object)(object)source && (Object)(object)val4 != (Object)null)
{
if (!((Component)val4).gameObject.activeSelf)
{
flag = true;
break;
}
val4 = val4.parent;
}
if (!flag)
{
GameObject val5 = new GameObject("Native window " + ((Object)val).name, new Type[1] { typeof(RectTransform) });
val5.transform.SetParent((Transform)(object)target, false);
RectTransform component = val5.GetComponent<RectTransform>();
component.anchorMin = Vector2.zero;
component.anchorMax = Vector2.one;
Vector2 offsetMin = (component.offsetMax = Vector2.zero);
component.offsetMin = offsetMin;
Image val6 = (Image)(object)((val is Image) ? val : null);
Graphic val8;
if ((Object)(object)val6 != (Object)null)
{
Image val7 = val5.AddComponent<Image>();
Copy(val7, val6);
val8 = (Graphic)(object)val7;
}
else
{
RawImage val9 = (RawImage)val;
RawImage val10 = val5.AddComponent<RawImage>();
val10.texture = val9.texture;
val10.uvRect = val9.uvRect;
((Graphic)val10).material = ((Graphic)val9).material;
((Graphic)val10).color = ((Graphic)val9).color;
val8 = (Graphic)(object)val10;
}
val8.raycastTarget = false;
}
}
}
}
}