using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyFileVersion("0.1.6.0")]
[assembly: InternalsVisibleTo("LogisticsArchitect.Tests")]
[assembly: AssemblyTitle("Logistics Architect")]
[assembly: AssemblyCompany("Loki Moon Labs")]
[assembly: AssemblyProduct("Logistics Architect")]
[assembly: AssemblyVersion("0.1.6.0")]
namespace LokiMoonLabs.LogisticsArchitect;
internal sealed class ApplyJob
{
public readonly PlanetFactory Factory;
public readonly PresetSnapshot Preset;
public readonly ICarrierStock Inventory;
public readonly ApplyResult Result = new ApplyResult();
public int Cursor = 1;
private readonly int singleId;
private readonly object expected;
private readonly int expectedEntity;
public ApplyJob(PlanetFactory factory, PresetSnapshot preset, ICarrierStock inventory, int id = 0, object expected = null)
{
Factory = factory;
Preset = preset;
Inventory = inventory;
singleId = id;
this.expected = expected;
StationComponent val = (StationComponent)((expected is StationComponent) ? expected : null);
DispenserComponent val2 = (DispenserComponent)((expected is DispenserComponent) ? expected : null);
BattleBaseComponent val3 = (BattleBaseComponent)((expected is BattleBaseComponent) ? expected : null);
expectedEntity = val?.entityId ?? val2?.entityId ?? val3?.entityId ?? 0;
}
public bool Step()
{
if (Factory == null)
{
return true;
}
int num = ((singleId > 0) ? singleId : Cursor++);
if (singleId > 0 && Cursor++ > 1)
{
return true;
}
if (Preset.Kind == Facility.Distributors)
{
PlanetTransport transport = Factory.transport;
if (transport == null || transport.dispenserPool == null || num >= Math.Min(transport.dispenserCursor, transport.dispenserPool.Length))
{
return true;
}
DispenserComponent val = transport.dispenserPool[num];
if (val != null && val.id == num && (expected == null || (object.ReferenceEquals(expected, val) && val.entityId == expectedEntity)))
{
StationService.Dispenser(Factory, val, Preset, Inventory, Result);
}
}
else if (Preset.Kind == Facility.BattleBases)
{
DefenseSystem defenseSystem = Factory.defenseSystem;
if (defenseSystem == null || defenseSystem.battleBases == null || defenseSystem.battleBases.buffer == null || num >= Math.Min(defenseSystem.battleBases.cursor, defenseSystem.battleBases.buffer.Length))
{
return true;
}
BattleBaseComponent val2 = defenseSystem.battleBases.buffer[num];
if (val2 != null && val2.id == num && (expected == null || (object.ReferenceEquals(expected, val2) && val2.entityId == expectedEntity)))
{
StationService.BattleBase(Factory, val2, Preset, Result);
}
}
else
{
PlanetTransport transport2 = Factory.transport;
if (transport2 == null || transport2.stationPool == null || num >= Math.Min(transport2.stationCursor, transport2.stationPool.Length))
{
return true;
}
StationComponent val3 = transport2.stationPool[num];
if (val3 != null && val3.id == num && StationService.Matches(val3, Preset.Kind) && (expected == null || (object.ReferenceEquals(expected, val3) && val3.entityId == expectedEntity)))
{
StationService.Station(Factory, val3, Preset, Inventory, Result);
}
}
return singleId > 0;
}
}
internal sealed class ApplyQueue
{
private readonly Queue<ApplyJob> jobs = new Queue<ApplyJob>();
private GameData data;
public string Status = "Ready. Apply buttons affect matching facilities on the current planet.";
public int Pending => jobs.Count;
public int Revision { get; private set; }
public void Enqueue(GameData game, ApplyJob job)
{
if (!object.ReferenceEquals(data, game))
{
jobs.Clear();
data = game;
}
jobs.Enqueue(job);
Status = "Applying settings…";
}
public void Clear()
{
jobs.Clear();
Status = "No pending changes.";
}
public void Tick(GameData game)
{
if (!object.ReferenceEquals(data, game))
{
Clear();
data = game;
return;
}
long timestamp = Stopwatch.GetTimestamp();
int num = 0;
while (jobs.Count > 0 && num++ < 64 && ((num & 7) != 0 || Stopwatch.GetTimestamp() - timestamp <= Stopwatch.Frequency / 2000))
{
ApplyJob applyJob = jobs.Peek();
try
{
int changed = applyJob.Result.Changed;
bool flag = applyJob.Step();
if (applyJob.Result.Changed != changed)
{
Revision++;
}
if (flag)
{
jobs.Dequeue();
Status = applyJob.Result.Summary();
}
}
catch (Exception ex)
{
jobs.Dequeue();
Status = "Apply stopped for one job: " + ex.Message;
}
}
}
}
internal sealed class ArchitectWindow : IDisposable
{
private sealed class Editor
{
public string Value;
public string Min;
public string Max;
public string Step;
public Editor(Setting s)
{
Value = Number(s.Value.Value);
Min = Number(s.Minimum.Value);
Max = Number(s.Maximum.Value);
Step = Number(s.Step.Value);
}
}
private const float ApplyButtonWidth = 100f;
private readonly Plugin plugin;
private readonly Dictionary<Setting, Editor> editors = new Dictionary<Setting, Editor>();
private Rect rect = new Rect(80f, 65f, 1000f, 720f);
private Vector2 scroll;
private bool ranges;
private int blockedThrough = -1;
private bool pointerHeld;
private bool keyboardFocused;
private GameObject shield;
private RectTransform shieldRect;
private Texture2D dark;
private Texture2D button;
private Texture2D field;
private Texture2D accent;
private Texture2D logo;
private GUIStyle panelStyle;
private GUIStyle buttonStyle;
private GUIStyle fieldStyle;
private GUIStyle headingStyle;
private GUIStyle labelStyle;
private GUIStyle sliderStyle;
private GUIStyle thumbStyle;
public bool Visible { get; private set; }
private float Scale => Mathf.Clamp((float)Screen.height / 1080f, 0.65f, 1.4f);
private bool ShieldActive
{
get
{
if (!Visible)
{
return Time.frameCount <= blockedThrough;
}
return true;
}
}
public bool KeyboardBlocking
{
get
{
if (Visible)
{
return keyboardFocused;
}
return false;
}
}
public bool Blocking
{
get
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: 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)
if (!ShieldActive)
{
return false;
}
Vector3 mousePosition = Input.mousePosition;
float scale = Scale;
bool overWindow = ((Rect)(ref rect)).Contains(new Vector2(mousePosition.x / scale, ((float)Screen.height - mousePosition.y) / scale));
return InputPolicy.Block(Visible, overWindow, pointerHeld, keyboardFocused, Time.frameCount <= blockedThrough);
}
}
public ArchitectWindow(Plugin plugin)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
this.plugin = plugin;
foreach (Preset preset in plugin.Settings.Presets)
{
foreach (Setting setting in preset.Settings)
{
editors.Add(setting, new Editor(setting));
}
}
}
public void Toggle()
{
if (Visible)
{
Close();
}
else
{
Visible = true;
}
}
public void Close()
{
Visible = false;
pointerHeld = (keyboardFocused = false);
blockedThrough = Time.frameCount + 1;
GUIUtility.keyboardControl = 0;
}
public void UpdateShield()
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Expected O, but got Unknown
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: 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_0121: 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_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0198: Unknown result type (might be due to invalid IL or missing references)
//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
if (ShieldActive && (Object)(object)shield == (Object)null)
{
shield = new GameObject("Logistics Architect modal input shield", new Type[3]
{
typeof(RectTransform),
typeof(Canvas),
typeof(GraphicRaycaster)
});
Object.DontDestroyOnLoad((Object)(object)shield);
Canvas component = shield.GetComponent<Canvas>();
component.renderMode = (RenderMode)0;
component.sortingOrder = 32760;
GameObject val = new GameObject("Window-only raycast blocker", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
val.transform.SetParent(shield.transform, false);
Image component2 = val.GetComponent<Image>();
((Graphic)component2).color = Color.clear;
((Graphic)component2).raycastTarget = true;
shieldRect = val.GetComponent<RectTransform>();
RectTransform obj = shieldRect;
RectTransform obj2 = shieldRect;
Vector2 val2 = (shieldRect.pivot = new Vector2(0f, 1f));
Vector2 anchorMin = (obj2.anchorMax = val2);
obj.anchorMin = anchorMin;
}
if ((Object)(object)shield != (Object)null && shield.activeSelf != ShieldActive)
{
shield.SetActive(ShieldActive);
}
if ((Object)(object)shieldRect != (Object)null)
{
float scale = Scale;
shieldRect.anchoredPosition = new Vector2(((Rect)(ref rect)).x * scale, (0f - ((Rect)(ref rect)).y) * scale);
shieldRect.sizeDelta = new Vector2(((Rect)(ref rect)).width * scale, ((Rect)(ref rect)).height * scale);
}
}
private static string Number(double value)
{
return value.ToString("0.########", CultureInfo.InvariantCulture);
}
private static bool Parse(string text, out double value)
{
if (double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out value))
{
return Setting.Finite(value);
}
return false;
}
private static Texture2D Solid(Color color)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Expected O, but got Unknown
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
val.SetPixel(0, 0, color);
val.Apply();
return val;
}
private static void Background(GUIStyle style, Texture2D texture)
{
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: 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)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: 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)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: 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)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
GUIStyleState normal = style.normal;
GUIStyleState hover = style.hover;
GUIStyleState active = style.active;
Texture2D val = (style.focused.background = texture);
Texture2D val3 = (active.background = val);
Texture2D background = (hover.background = val3);
normal.background = background;
GUIStyleState onNormal = style.onNormal;
GUIStyleState onHover = style.onHover;
GUIStyleState onActive = style.onActive;
Texture2D val6 = (style.onFocused.background = texture);
Texture2D val8 = (onActive.background = val6);
Texture2D background2 = (onHover.background = val8);
onNormal.background = background2;
GUIStyleState normal2 = style.normal;
GUIStyleState hover2 = style.hover;
GUIStyleState active2 = style.active;
Color val11 = (style.focused.textColor = Color.white);
Color val12 = (active2.textColor = val11);
Color textColor = (hover2.textColor = val12);
normal2.textColor = textColor;
GUIStyleState onNormal2 = style.onNormal;
GUIStyleState onHover2 = style.onHover;
GUIStyleState onActive2 = style.onActive;
Color val15 = (style.onFocused.textColor = Color.white);
Color val16 = (onActive2.textColor = val15);
Color textColor2 = (onHover2.textColor = val16);
onNormal2.textColor = textColor2;
}
private void Styles()
{
//IL_001e: 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_0066: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Expected O, but got Unknown
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Expected O, but got Unknown
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Expected O, but got Unknown
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Expected O, but got Unknown
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Expected O, but got Unknown
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Expected O, but got Unknown
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_017a: Expected O, but got Unknown
//IL_0192: Unknown result type (might be due to invalid IL or missing references)
//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: Expected O, but got Unknown
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Expected O, but got Unknown
//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
//IL_0201: Expected O, but got Unknown
if (panelStyle == null)
{
dark = Solid(new Color(0.045f, 0.065f, 0.11f, 1f));
button = Solid(new Color(0.13f, 0.18f, 0.27f, 1f));
field = Solid(new Color(0.08f, 0.1f, 0.15f, 1f));
accent = Solid(new Color(0.35f, 0.75f, 0.85f, 1f));
panelStyle = new GUIStyle(GUI.skin.window);
panelStyle.padding = new RectOffset(18, 18, 26, 16);
Background(panelStyle, dark);
buttonStyle = new GUIStyle(GUI.skin.button);
buttonStyle.fontSize = 15;
buttonStyle.padding = new RectOffset(8, 8, 6, 6);
Background(buttonStyle, button);
fieldStyle = new GUIStyle(GUI.skin.textField);
fieldStyle.fontSize = 15;
fieldStyle.padding = new RectOffset(5, 5, 5, 5);
Background(fieldStyle, field);
labelStyle = new GUIStyle(GUI.skin.label);
labelStyle.fontSize = 15;
labelStyle.normal.textColor = Color.white;
headingStyle = new GUIStyle(labelStyle);
headingStyle.fontSize = 18;
headingStyle.fontStyle = (FontStyle)1;
sliderStyle = new GUIStyle(GUI.skin.horizontalSlider);
Background(sliderStyle, button);
thumbStyle = new GUIStyle(GUI.skin.horizontalSliderThumb);
Background(thumbStyle, accent);
thumbStyle.fixedWidth = 14f;
thumbStyle.fixedHeight = 18f;
logo = Branding.LoadIcon();
}
}
public void Draw()
{
//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0204: Unknown result type (might be due to invalid IL or missing references)
//IL_020a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: 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_0020: 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_003d: 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_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: 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_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Expected O, but got Unknown
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Invalid comparison between Unknown and I4
//IL_0192: Unknown result type (might be due to invalid IL or missing references)
//IL_019b: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Invalid comparison between Unknown and I4
//IL_01be: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Invalid comparison between Unknown and I4
//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
//IL_01ab: Invalid comparison between Unknown and I4
//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
//IL_01ce: Invalid comparison between Unknown and I4
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01b5: Invalid comparison between Unknown and I4
if (!Visible)
{
return;
}
Styles();
Matrix4x4 matrix = GUI.matrix;
Color color = GUI.color;
Color backgroundColor = GUI.backgroundColor;
int depth = GUI.depth;
float scale = Scale;
try
{
GUI.matrix = Matrix4x4.Scale(new Vector3(scale, scale, 1f));
GUI.color = (GUI.backgroundColor = Color.white);
GUI.depth = -10000;
((Rect)(ref rect)).x = Mathf.Clamp(((Rect)(ref rect)).x, 0f, Mathf.Max(0f, (float)Screen.width / scale - ((Rect)(ref rect)).width));
((Rect)(ref rect)).y = Mathf.Clamp(((Rect)(ref rect)).y, 0f, Mathf.Max(0f, (float)Screen.height / scale - ((Rect)(ref rect)).height));
Event current = Event.current;
bool flag = ((Rect)(ref rect)).Contains(current.mousePosition);
bool flag2 = pointerHeld;
if ((int)current.rawType == 0)
{
if (flag)
{
pointerHeld = true;
}
else
{
GUIUtility.keyboardControl = 0;
keyboardFocused = false;
}
}
rect = GUILayout.Window(19471353, rect, new WindowFunction(Contents), "Logistics Architect — Loki Moon Labs", panelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]);
keyboardFocused = Visible && GUI.GetNameOfFocusedControl().StartsWith("LA.", StringComparison.Ordinal);
if ((int)current.rawType == 1)
{
pointerHeld = false;
}
UpdateShield();
bool flag3 = (int)current.type == 0 || (int)current.type == 1 || (int)current.type == 3 || (int)current.type == 6;
bool flag4 = (int)current.type == 4 || (int)current.type == 5;
if ((flag3 && (flag || flag2 || pointerHeld)) || (flag4 && keyboardFocused))
{
current.Use();
}
}
finally
{
GUI.matrix = matrix;
GUI.color = color;
GUI.backgroundColor = backgroundColor;
GUI.depth = depth;
}
}
private void Contents(int id)
{
//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0216: Unknown result type (might be due to invalid IL or missing references)
//IL_021b: Unknown result type (might be due to invalid IL or missing references)
//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
if ((Object)(object)logo != (Object)null)
{
GUILayout.Label((Texture)(object)logo, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Width(54f),
GUILayout.Height(54f)
});
}
GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.Label("Station auto-configuration", headingStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.Label("Apply affects the current planet. Changing presets or slider limits alone does not change existing buildings.", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.EndVertical();
if (GUILayout.Button("Close", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(65f) }))
{
Close();
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
bool flag = GUILayout.Toggle(plugin.Settings.Enabled.Value, "Enable Logistics Architect", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(215f) });
if (flag != plugin.Settings.Enabled.Value)
{
plugin.Settings.Enabled.Value = flag;
plugin.Dirty();
}
bool flag2 = GUILayout.Toggle(plugin.Settings.FillCarriers.Value, "Fill carriers from inventory", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) });
if (flag2 != plugin.Settings.FillCarriers.Value)
{
plugin.Settings.FillCarriers.Value = flag2;
plugin.Dirty();
}
ranges = GUILayout.Toggle(ranges, "Edit slider limits (min / max / step)", (GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.EndHorizontal();
GUILayout.Label(plugin.Status, labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
scroll = GUILayout.BeginScrollView(scroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(535f) });
foreach (Preset preset in plugin.Settings.Presets)
{
GUILayout.Space(10f);
GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
GUILayout.Label(preset.Name, headingStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(510f) });
bool flag3 = GUILayout.Toggle(preset.OnBuild.Value, "Configure new buildings", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
if (flag3 != preset.OnBuild.Value)
{
preset.OnBuild.Value = flag3;
plugin.Dirty();
}
GUILayout.FlexibleSpace();
bool enabled = GUI.enabled;
GUI.enabled = plugin.CanApply;
if (GUILayout.Button("Apply All", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }) && CommitAll(preset))
{
plugin.Apply(preset, null);
}
GUI.enabled = enabled;
GUILayout.EndHorizontal();
foreach (Setting setting in preset.Settings)
{
Row(preset, setting);
}
}
GUILayout.EndScrollView();
GUILayout.Label("Open with the Loki Moon Labs minimap icon • Esc closes • Carrier targets respect modded building capacities.", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]);
GUI.DragWindow(new Rect(0f, 0f, 880f, 25f));
}
private bool CommitAll(Preset preset)
{
foreach (Setting setting in preset.Settings)
{
if (!setting.Boolean && (!Parse(editors[setting].Value, out var value) || !setting.ValidValue(value)))
{
plugin.Message("Invalid value for " + setting.Label + ". Allowed: " + Number(setting.HardMin) + " to " + Number(setting.HardMax) + ".");
return false;
}
}
foreach (Setting setting2 in preset.Settings)
{
if (!setting2.Boolean)
{
Parse(editors[setting2].Value, out var value2);
setting2.SetValue(value2);
}
}
plugin.Dirty();
return true;
}
private void Row(Preset preset, Setting setting)
{
Editor editor = editors[setting];
GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
GUILayout.Label(setting.Label, labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(300f) });
if (setting.Boolean)
{
bool flag = GUILayout.Toggle(setting.Value.Value != 0.0, "Enabled", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(395f) });
if (flag != (setting.Value.Value != 0.0))
{
setting.SetValue(flag ? 1 : 0);
plugin.Dirty();
}
}
else
{
GUI.changed = false;
float num = GUILayout.HorizontalSlider((float)setting.Normalize(), 0f, 1f, sliderStyle, thumbStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(225f) });
if (GUI.changed)
{
setting.SetValue(setting.FromSlider(num));
editor.Value = Number(setting.Value.Value);
plugin.Dirty();
}
GUI.SetNextControlName(string.Concat("LA.", preset.Kind, ".", setting.Key));
editor.Value = GUILayout.TextField(editor.Value, fieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(105f) });
GUILayout.Label(setting.Unit, labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(65f) });
}
GUILayout.FlexibleSpace();
bool enabled = GUI.enabled;
GUI.enabled = plugin.CanApply;
if (GUILayout.Button("Apply", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }))
{
if (setting.Boolean || (Parse(editor.Value, out var value) && setting.SetValue(value)))
{
plugin.Dirty();
plugin.Apply(preset, setting.Key);
}
else
{
plugin.Message("Invalid " + setting.Label + ": allowed " + Number(setting.HardMin) + " to " + Number(setting.HardMax) + ".");
}
}
GUI.enabled = enabled;
GUILayout.EndHorizontal();
if (!ranges || setting.Boolean)
{
return;
}
GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
GUILayout.Space(28f);
GUILayout.Label("Min", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) });
GUI.SetNextControlName(string.Concat("LA.", preset.Kind, ".", setting.Key, ".Min"));
editor.Min = GUILayout.TextField(editor.Min, fieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
GUILayout.Label("Max", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) });
GUI.SetNextControlName(string.Concat("LA.", preset.Kind, ".", setting.Key, ".Max"));
editor.Max = GUILayout.TextField(editor.Max, fieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
GUILayout.Label("Step", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) });
GUI.SetNextControlName(string.Concat("LA.", preset.Kind, ".", setting.Key, ".Step"));
editor.Step = GUILayout.TextField(editor.Step, fieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(105f) });
if (GUILayout.Button("Save range", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) }))
{
if (Parse(editor.Min, out var value2) && Parse(editor.Max, out var value3) && Parse(editor.Step, out var value4) && setting.SetRange(value2, value3, value4))
{
plugin.Dirty();
plugin.Message("Slider range saved. Preset and existing facilities were not changed.");
}
else
{
plugin.Message("Invalid range: use finite minimum < maximum, a positive step, and the setting's physical bounds.");
}
}
GUILayout.EndHorizontal();
}
public void Dispose()
{
if ((Object)(object)shield != (Object)null)
{
Object.Destroy((Object)(object)shield);
}
Texture2D[] array = (Texture2D[])(object)new Texture2D[5] { dark, button, field, accent, logo };
foreach (Texture2D val in array)
{
if ((Object)(object)val != (Object)null)
{
Object.Destroy((Object)(object)val);
}
}
}
}
internal static class Branding
{
internal static byte[] ReadIcon()
{
using Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream("LokiMoonLabs.LogisticsArchitect.icon.png");
if (stream == null)
{
throw new InvalidOperationException("Embedded Loki Moon Labs icon is missing.");
}
using MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
internal static Texture2D LoadIcon()
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
Texture2D val = new Texture2D(2, 2);
if (!ImageConversion.LoadImage(val, ReadIcon()))
{
Object.Destroy((Object)(object)val);
throw new InvalidOperationException("Cannot load the embedded Loki Moon Labs icon.");
}
return val;
}
}
internal static class InputPolicy
{
public static bool Block(bool visible, bool overWindow, bool dragging, bool editingText, bool closingFrame)
{
if (!closingFrame)
{
if (visible)
{
if (!overWindow && !dragging)
{
return editingText;
}
return true;
}
return false;
}
return true;
}
}
internal sealed class LauncherClickGate
{
private int lastFrame = -1;
public bool Accept(int frame)
{
if (lastFrame == frame)
{
return false;
}
lastFrame = frame;
return true;
}
}
internal static class LauncherLayout
{
public static Vector2 Next(Vector2 previous, Vector2 last, float fallbackGap)
{
//IL_006e: 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)
float num = last.x - previous.x;
float num2 = last.y - previous.y;
if (num * num + num2 * num2 < 1f)
{
return new Vector2(last.x + fallbackGap * 0.075f, last.y - fallbackGap);
}
return new Vector2(last.x + Math.Abs(num) * 0.25f, last.y - Math.Abs(num2));
}
}
internal sealed class MinimapLauncher : IDisposable
{
private readonly Action toggle;
private readonly Action<string> report;
private UIPlanetGlobe owner;
private GameObject root;
private RectTransform rect;
private Image icon;
private readonly LauncherClickGate clicks = new LauncherClickGate();
public MinimapLauncher(Action toggle, Action<string> report)
{
this.toggle = toggle;
this.report = report;
}
public void Update(UIPlanetGlobe globe)
{
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Expected O, but got Unknown
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Expected O, but got Unknown
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: 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_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_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_014d: 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_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_016d: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: 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_0190: 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_0197: Unknown result type (might be due to invalid IL or missing references)
//IL_0247: Unknown result type (might be due to invalid IL or missing references)
//IL_0264: Unknown result type (might be due to invalid IL or missing references)
//IL_0269: Unknown result type (might be due to invalid IL or missing references)
//IL_026d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)owner != (Object)(object)globe || ((Object)(object)owner != (Object)null && (Object)(object)root == (Object)null))
{
Dispose();
owner = globe;
}
if ((Object)(object)globe == (Object)null || (Object)(object)globe.button3 == (Object)null || (Object)(object)globe.button2 == (Object)null)
{
return;
}
bool flag = (Object)(object)root == (Object)null;
if (flag)
{
Create(globe.button3);
}
if ((Object)(object)icon != (Object)null && (Object)(object)icon.sprite == (Object)null && (Object)(object)LDB.items != (Object)null)
{
ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(2104);
if (val != null)
{
icon.sprite = val.iconSprite;
}
}
RectTransform val2 = (RectTransform)((Component)globe.button3).transform;
RectTransform val3 = (RectTransform)((Component)globe.button2).transform;
RectTransform val4 = (((Object)(object)globe.minimap == (Object)null) ? null : ((Graphic)globe.minimap).rectTransform);
if ((Object)(object)val4 != (Object)null)
{
Rect val5 = val3.rect;
Vector2 previous = Vector2.op_Implicit(((Transform)val4).InverseTransformPoint(((Transform)val3).TransformPoint(Vector2.op_Implicit(((Rect)(ref val5)).center))));
Rect val6 = val2.rect;
Vector2 last = Vector2.op_Implicit(((Transform)val4).InverseTransformPoint(((Transform)val2).TransformPoint(Vector2.op_Implicit(((Rect)(ref val6)).center))));
Rect val7 = val2.rect;
Vector2 val8 = LauncherLayout.Next(previous, last, ((Rect)(ref val7)).height + 10f);
((Transform)rect).position = ((Transform)val4).TransformPoint(Vector2.op_Implicit(val8));
}
else
{
RectTransform obj = rect;
Rect val9 = val2.rect;
Vector2 center = ((Rect)(ref val9)).center;
Rect val10 = val2.rect;
float num = (((Rect)(ref val10)).height + 10f) * 0.075f;
Rect val11 = val2.rect;
((Transform)obj).position = ((Transform)val2).TransformPoint(Vector2.op_Implicit(center + new Vector2(num, 0f - ((Rect)(ref val11)).height - 10f)));
}
if (flag)
{
Action<string> action = report;
object[] array = new object[9]
{
"Minimap button created: active=",
root.activeInHierarchy,
", position=",
((Transform)rect).position,
", size=",
null,
null,
null,
null
};
Rect val12 = rect.rect;
array[5] = ((Rect)(ref val12)).size;
array[6] = ", parent=";
array[7] = ((Object)((Transform)rect).parent).name;
array[8] = ". Using the game's ILS icon.";
action(string.Concat(array));
}
}
private void Create(Button template)
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Expected O, but got Unknown
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Expected O, but got Unknown
//IL_011d: 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_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: Unknown result type (might be due to invalid IL or missing references)
//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Unknown result type (might be due to invalid IL or missing references)
//IL_022d: Unknown result type (might be due to invalid IL or missing references)
//IL_0234: Expected O, but got Unknown
//IL_0267: Unknown result type (might be due to invalid IL or missing references)
//IL_0292: Unknown result type (might be due to invalid IL or missing references)
//IL_0297: Unknown result type (might be due to invalid IL or missing references)
//IL_0298: Unknown result type (might be due to invalid IL or missing references)
//IL_029f: Unknown result type (might be due to invalid IL or missing references)
//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
//IL_02ca: 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_02eb: Unknown result type (might be due to invalid IL or missing references)
//IL_0320: Unknown result type (might be due to invalid IL or missing references)
//IL_0327: Expected O, but got Unknown
//IL_034a: Unknown result type (might be due to invalid IL or missing references)
//IL_0367: Unknown result type (might be due to invalid IL or missing references)
//IL_0373: Unknown result type (might be due to invalid IL or missing references)
//IL_0381: Unknown result type (might be due to invalid IL or missing references)
//IL_0386: Unknown result type (might be due to invalid IL or missing references)
//IL_0387: Unknown result type (might be due to invalid IL or missing references)
//IL_038e: Unknown result type (might be due to invalid IL or missing references)
root = Object.Instantiate<GameObject>(((Component)template).gameObject, ((Component)template).transform.parent, false);
((Object)root).name = "Logistics Architect minimap button";
rect = root.GetComponent<RectTransform>();
rect.pivot = new Vector2(0.5f, 0.5f);
Button component = root.GetComponent<Button>();
((Behaviour)component).enabled = true;
((Selectable)component).interactable = true;
root.transform.SetAsLastSibling();
component.onClick = new ButtonClickedEvent();
((UnityEvent)component.onClick).AddListener(new UnityAction(Click));
Graphic[] componentsInChildren = root.GetComponentsInChildren<Graphic>(true);
foreach (Graphic val in componentsInChildren)
{
if ((Object)(object)((Component)val).transform != (Object)(object)root.transform && ((Object)val).name.IndexOf("icon", StringComparison.OrdinalIgnoreCase) >= 0)
{
((Behaviour)val).enabled = false;
}
}
UIButton val2 = root.GetComponent<UIButton>() ?? root.AddComponent<UIButton>();
TipSettings tips = val2.tips;
((Behaviour)val2).enabled = true;
val2.button = component;
val2.eventReceiver = null;
val2.onClick += delegate
{
Click();
};
val2.tips = new TipSettings
{
tipTitle = "Logistics Architect",
tipText = "Configure logistics stations.\nClick to open or close.",
width = 260,
delay = 0.35f,
corner = tips.corner,
offset = tips.offset,
topLevel = tips.topLevel,
level = tips.level,
simpleGeneralTipPrefab = tips.simpleGeneralTipPrefab,
type = (ItemTipType)(-1)
};
val2.tipTitleFormatString = val2.tips.tipTitle;
val2.tipTextFormatString = val2.tips.tipText;
GameObject val3 = new GameObject("Interstellar Logistics Station icon", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
val3.transform.SetParent(root.transform, false);
Image val4 = (icon = val3.GetComponent<Image>());
val4.preserveAspect = true;
((Graphic)val4).color = Color.white;
((Graphic)val4).raycastTarget = true;
RectTransform rectTransform = ((Graphic)val4).rectTransform;
Vector2 val5 = (rectTransform.pivot = new Vector2(0.5f, 0.5f));
Vector2 anchorMin = (rectTransform.anchorMax = val5);
rectTransform.anchorMin = anchorMin;
Rect val8 = rect.rect;
float width = ((Rect)(ref val8)).width;
Rect val9 = rect.rect;
float num = Mathf.Min(width, ((Rect)(ref val9)).height) * 0.65f;
rectTransform.sizeDelta = new Vector2(num, num);
GameObject val10 = new GameObject("Launcher hit surface", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
val10.transform.SetParent(root.transform, false);
Image component2 = val10.GetComponent<Image>();
((Graphic)component2).color = Color.clear;
((Graphic)component2).raycastTarget = true;
RectTransform rectTransform2 = ((Graphic)component2).rectTransform;
rectTransform2.anchorMin = Vector2.zero;
rectTransform2.anchorMax = Vector2.one;
Vector2 offsetMin = (rectTransform2.offsetMax = Vector2.zero);
rectTransform2.offsetMin = offsetMin;
root.SetActive(true);
}
private void Click()
{
if (clicks.Accept(Time.frameCount))
{
report("Minimap launcher clicked; toggling Logistics Architect window.");
toggle();
}
}
public void Dispose()
{
if ((Object)(object)root != (Object)null)
{
Object.Destroy((Object)(object)root);
}
root = null;
rect = null;
icon = null;
owner = null;
}
}
internal static class OpenPanels
{
private static readonly Action<UIStationWindow> station = Bind<UIStationWindow>("OnStationIdChange");
private static readonly Action<UIDispenserWindow> dispenser = Bind<UIDispenserWindow>("OnDispenserIdChange");
private static readonly Action<UIBattleBaseWindow> battleBase = Bind<UIBattleBaseWindow>("OnBattleBaseIdChange");
private static Action<T> Bind<T>(string name)
{
return (Action<T>)Delegate.CreateDelegate(typeof(Action<T>), AccessTools.Method(typeof(T), name, (Type[])null, (Type[])null));
}
public static void Refresh()
{
UIRoot instance = UIRoot.instance;
if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.uiGame == (Object)null))
{
UIGame uiGame = instance.uiGame;
if ((Object)(object)uiGame.stationWindow != (Object)null && ((ManualBehaviour)uiGame.stationWindow).active)
{
station(uiGame.stationWindow);
}
if ((Object)(object)uiGame.dispenserWindow != (Object)null && ((ManualBehaviour)uiGame.dispenserWindow).active)
{
dispenser(uiGame.dispenserWindow);
}
if ((Object)(object)uiGame.battleBaseWindow != (Object)null && ((ManualBehaviour)uiGame.battleBaseWindow).active)
{
battleBase(uiGame.battleBaseWindow);
}
}
}
}
[BepInPlugin("LokiMoonLabs.LogisticsArchitect", "Logistics Architect", "0.1.6")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class Plugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(PlanetTransport), "NewStationComponent")]
private static class NewStation
{
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void Postfix(PlanetTransport __instance, StationComponent __result)
{
if (!((Object)(object)instance == (Object)null) && __result != null && !__result.isCollector)
{
instance.NewFacility(__instance.factory, __result.isVeinCollector ? Facility.AdvancedMiners : (__result.isStellar ? Facility.ILS : Facility.PLS), __result.id, __result);
}
}
}
[HarmonyPatch(typeof(PlanetTransport), "NewDispenserComponent")]
private static class NewDispenser
{
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void Postfix(PlanetTransport __instance, int __result)
{
if ((Object)(object)instance != (Object)null && StationService.Has(__instance.dispenserPool, __result) && __result > 0)
{
instance.NewFacility(__instance.factory, Facility.Distributors, __result, __instance.dispenserPool[__result]);
}
}
}
[HarmonyPatch(typeof(DefenseSystem), "NewBattleBaseComponent")]
private static class NewBattleBase
{
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void Postfix(DefenseSystem __instance, int __result)
{
if ((Object)(object)instance != (Object)null && __instance.battleBases != null && StationService.Has(__instance.battleBases.buffer, __result) && __result > 0)
{
instance.NewFacility(__instance.factory, Facility.BattleBases, __result, __instance.battleBases.buffer[__result]);
}
}
}
[HarmonyPatch(typeof(VFInput), "UpdateGameStates")]
private static class ModalInput
{
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void Postfix()
{
if (!((Object)(object)instance == (Object)null) && instance.window != null && instance.window.Blocking)
{
VFInput.onGUI = true;
VFInput.onGUIOperate = true;
VFInput.inScrollView = true;
if (instance.window.KeyboardBlocking)
{
VFInput.inputing = true;
}
}
}
}
public const string Guid = "LokiMoonLabs.LogisticsArchitect";
private static Plugin instance;
internal Settings Settings;
internal readonly ApplyQueue Jobs = new ApplyQueue();
private ArchitectWindow window;
private MinimapLauncher launcher;
private Harmony harmony;
private ConfigEntry<bool> uxAutoConfig;
private float saveAt;
public string Status
{
get
{
if (!Conflict)
{
return Jobs.Status;
}
return "UXAssist Auto-config logistic stations is enabled. Turn off that one UXAssist feature to use Apply or automatic configuration here.";
}
}
internal bool Conflict
{
get
{
if (uxAutoConfig != null)
{
return uxAutoConfig.Value;
}
return false;
}
}
internal bool CanApply
{
get
{
if (Settings.Enabled.Value && !Conflict && (Object)(object)GameMain.instance != (Object)null && !GameMain.instance.isMenuDemo && GameMain.data != null && GameMain.data.localPlanet != null)
{
return GameMain.data.localPlanet.factory != null;
}
return false;
}
}
private void Awake()
{
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Expected O, but got Unknown
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected O, but got Unknown
((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
Settings = new Settings(((BaseUnityPlugin)this).Config);
((BaseUnityPlugin)this).Config.Save();
if (Chainloader.PluginInfos.TryGetValue("org.soardev.uxassist", out var value) && (Object)(object)value.Instance != (Object)null)
{
value.Instance.Config.TryGetEntry<bool>(new ConfigDefinition("Factory", "AutoConfigLogistics"), ref uxAutoConfig);
}
instance = this;
window = new ArchitectWindow(this);
launcher = new MinimapLauncher(delegate
{
window.Toggle();
}, delegate(string message)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)message);
});
harmony = new Harmony("LokiMoonLabs.LogisticsArchitect");
harmony.PatchAll(typeof(Plugin).Assembly);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Logistics Architect ready. Open it with the ILS minimap button.");
}
private void Update()
{
if (window.Visible && Input.GetKeyDown((KeyCode)27))
{
window.Close();
}
window.UpdateShield();
if (launcher != null && (Object)(object)GameMain.instance != (Object)null && !GameMain.instance.isMenuDemo)
{
UIRoot val = UIRoot.instance;
launcher.Update(((Object)(object)val == (Object)null || (Object)(object)val.uiGame == (Object)null) ? null : val.uiGame.planetGlobe);
}
if (saveAt > 0f && Time.unscaledTime >= saveAt)
{
saveAt = 0f;
try
{
((BaseUnityPlugin)this).Config.Save();
}
catch (Exception ex)
{
Jobs.Status = "Could not save preset: " + ex.Message;
}
}
if (!Settings.Enabled.Value || Conflict)
{
if (Jobs.Pending > 0)
{
Jobs.Clear();
}
return;
}
int revision = Jobs.Revision;
Jobs.Tick(GameMain.data);
if (Jobs.Revision == revision)
{
return;
}
try
{
OpenPanels.Refresh();
}
catch (Exception ex2)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Settings applied, but an open panel could not refresh: " + ex2.Message));
}
}
internal void Dirty()
{
saveAt = Time.unscaledTime + 0.75f;
}
internal void Message(string text)
{
Jobs.Status = text;
}
internal void Apply(Preset preset, string only)
{
if (!CanApply)
{
Message(Conflict ? Status : "Load a planet before applying settings.");
return;
}
GameData data = GameMain.data;
PlanetFactory factory = data.localPlanet.factory;
ICarrierStock inventory = (Settings.FillCarriers.Value ? new PlayerStock(data.mainPlayer, factory.planet) : null);
Jobs.Enqueue(data, new ApplyJob(factory, preset.Snapshot(only), inventory));
}
private void NewFacility(PlanetFactory factory, Facility kind, int id, object expected)
{
if (!Settings.Enabled.Value || Conflict || factory == null || factory.gameData == null || id <= 0 || (Object)(object)GameMain.instance == (Object)null || GameMain.instance.isMenuDemo)
{
return;
}
foreach (Preset preset in Settings.Presets)
{
if (preset.Kind == kind && preset.OnBuild.Value)
{
ICarrierStock inventory = (Settings.FillCarriers.Value ? new PlayerStock(factory.gameData.mainPlayer, factory.planet) : null);
Jobs.Enqueue(factory.gameData, new ApplyJob(factory, preset.Snapshot(null), inventory, id, expected));
break;
}
}
}
private void OnGUI()
{
if (window != null)
{
window.Draw();
}
}
private void OnDestroy()
{
if (saveAt > 0f)
{
try
{
((BaseUnityPlugin)this).Config.Save();
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Could not save Logistics Architect presets: " + ex.Message));
}
}
if (harmony != null)
{
harmony.UnpatchSelf();
}
if (window != null)
{
window.Dispose();
}
if (launcher != null)
{
launcher.Dispose();
}
if ((Object)(object)instance == (Object)(object)this)
{
instance = null;
}
}
}
internal enum Facility
{
PLS,
ILS,
Distributors,
AdvancedMiners,
BattleBases
}
internal sealed class Setting
{
public readonly string Key;
public readonly string Label;
public readonly string Unit;
public readonly double HardMin;
public readonly double HardMax;
public readonly bool Integral;
public readonly bool Boolean;
public readonly ConfigEntry<double> Value;
public readonly ConfigEntry<double> Minimum;
public readonly ConfigEntry<double> Maximum;
public readonly ConfigEntry<double> Step;
public Setting(ConfigFile config, string section, string key, string label, string unit, double value, double min, double max, double step, double hardMin, double hardMax, bool integral = false, bool boolean = false)
{
Key = key;
Label = label;
Unit = unit;
HardMin = hardMin;
HardMax = hardMax;
Integral = integral;
Boolean = boolean;
Value = config.Bind<double>(section, key, value, label + ((unit.Length == 0) ? "" : (" (" + unit + ")")) + ". Saved preset; only Apply or new-building configuration changes buildings.");
Minimum = config.Bind<double>(section + ".SliderLimits", key + "Minimum", min, "Editable slider minimum. Does not change the preset or existing buildings.");
Maximum = config.Bind<double>(section + ".SliderLimits", key + "Maximum", max, "Editable slider maximum. Does not expand physical carrier arrays or change existing buildings.");
Step = config.Bind<double>(section + ".SliderLimits", key + "Step", step, "Slider increment in the displayed units.");
if (!ValidValue(Value.Value))
{
Value.Value = value;
}
if (!ValidRange(Minimum.Value, Maximum.Value, Step.Value))
{
Minimum.Value = min;
Maximum.Value = max;
Step.Value = step;
}
}
public static bool Finite(double number)
{
if (!double.IsNaN(number))
{
return !double.IsInfinity(number);
}
return false;
}
public bool ValidValue(double number)
{
if (Finite(number) && number >= HardMin && number <= HardMax)
{
if (Integral)
{
return number == Math.Round(number);
}
return true;
}
return false;
}
public bool ValidRange(double min, double max, double step)
{
if (ValidValue(min) && ValidValue(max) && min < max && Finite(step) && step > 0.0 && step <= max - min)
{
if (Integral)
{
return step == Math.Round(step);
}
return true;
}
return false;
}
public bool SetValue(double number)
{
if (!ValidValue(number))
{
return false;
}
Value.Value = number;
return true;
}
public bool SetRange(double min, double max, double step)
{
if (!ValidRange(min, max, step))
{
return false;
}
Minimum.Value = min;
Maximum.Value = max;
Step.Value = step;
return true;
}
public double Normalize()
{
return Math.Max(0.0, Math.Min(1.0, (Value.Value - Minimum.Value) / (Maximum.Value - Minimum.Value)));
}
public double FromSlider(double fraction)
{
double num = Minimum.Value + Math.Max(0.0, Math.Min(1.0, fraction)) * (Maximum.Value - Minimum.Value);
num = Minimum.Value + Math.Round((num - Minimum.Value) / Step.Value) * Step.Value;
num = Math.Max(Minimum.Value, Math.Min(Maximum.Value, num));
if (!Integral)
{
return num;
}
return Math.Round(num);
}
}
internal sealed class Preset
{
public readonly Facility Kind;
public readonly string Name;
public readonly ConfigEntry<bool> OnBuild;
public readonly List<Setting> Settings = new List<Setting>();
private readonly ConfigFile config;
public Preset(ConfigFile config, Facility kind, string name)
{
this.config = config;
Kind = kind;
Name = name;
OnBuild = config.Bind<bool>(kind.ToString(), "ConfigureNewBuildings", true, "Apply this preset when a matching facility is built. Existing facilities require Apply.");
}
public Setting Add(string key, string label, string unit, double value, double min, double max, double step, double hardMin, double hardMax, bool integral = false, bool boolean = false)
{
Setting setting = new Setting(config, Kind.ToString(), key, label, unit, value, min, max, step, hardMin, hardMax, integral, boolean);
Settings.Add(setting);
return setting;
}
public void Flag(string key, string label, bool value)
{
Add(key, label, "", value ? 1 : 0, 0.0, 1.0, 1.0, 0.0, 1.0, integral: true, boolean: true);
}
public PresetSnapshot Snapshot(string only)
{
PresetSnapshot presetSnapshot = new PresetSnapshot(Kind);
foreach (Setting setting in Settings)
{
if (setting.Key == "VesselRange")
{
presetSnapshot.VesselRangeLY = setting.Value.Value;
}
if (setting.Key == "UnlimitedVesselRange")
{
presetSnapshot.UnlimitedRange = setting.Value.Value != 0.0;
}
}
foreach (Setting setting2 in Settings)
{
if ((only == null || only == setting2.Key) && setting2.ValidValue(setting2.Value.Value))
{
presetSnapshot.Values.Add(setting2.Key, setting2.Value.Value);
}
}
return presetSnapshot;
}
}
internal sealed class PresetSnapshot
{
public readonly Facility Kind;
public double VesselRangeLY;
public bool UnlimitedRange;
public readonly Dictionary<string, double> Values = new Dictionary<string, double>();
public PresetSnapshot(Facility kind)
{
Kind = kind;
}
public bool Has(string key)
{
return Values.ContainsKey(key);
}
public double Get(string key)
{
return Values[key];
}
}
internal sealed class Settings
{
public readonly List<Preset> Presets = new List<Preset>();
public readonly ConfigEntry<bool> Enabled;
public readonly ConfigEntry<bool> FillCarriers;
public Settings(ConfigFile config)
{
Enabled = config.Bind<bool>("General", "Enabled", true, "Enable Logistics Architect.");
FillCarriers = config.Bind<bool>("General", "FillCarriersFromInventory", true, "Carrier-count Apply buttons take real bots/drones/vessels from Icarus's normal inventory on the same planet. Existing carriers are never removed.");
Preset p = Add(config, Facility.PLS, "Planetary Logistics Stations (PLS)");
Station(p, stellar: false);
Preset p2 = Add(config, Facility.ILS, "Interstellar Logistics Stations (ILS)");
Station(p2, stellar: true);
Preset preset = Add(config, Facility.Distributors, "Logistics Distributors");
Power(preset, 9.0, 0.9, 9.0, 0.3);
preset.Add("Bots", "Bots to fill", "", 10.0, 0.0, 100.0, 1.0, 0.0, 1000000.0, integral: true);
preset.Flag("AutoReplenishBots", "Native automatic bot replenishment", value: false);
Preset preset2 = Add(config, Facility.AdvancedMiners, "Advanced Mining Machines");
preset2.Add("MiningSpeed", "Collecting speed", "%", 300.0, 100.0, 1000.0, 10.0, 1.0, 1000000.0, integral: true);
Piler(preset2);
Preset p3 = Add(config, Facility.BattleBases, "Battlefield Analysis Bases");
Power(p3, 12.0, 1.2, 12.0, 0.3);
}
private Preset Add(ConfigFile file, Facility kind, string name)
{
Preset preset = new Preset(file, kind, name);
Presets.Add(preset);
return preset;
}
private static void Power(Preset p, double value, double min, double max, double step)
{
p.Add("PowerMW", "Maximum charging power", "MW", value, min, max, step, 0.0, 1000000000.0);
}
private static void Piler(Preset p)
{
p.Add("Piler", "Outgoing stack size (0 = technology)", "", 4.0, 0.0, 30.0, 1.0, 0.0, 255.0, integral: true);
}
private static void Station(Preset p, bool stellar)
{
Power(p, stellar ? 9000 : 360, stellar ? 30 : 6, stellar ? 9000 : 360, stellar ? 15 : 3);
p.Add("DroneRange", "Drone transport range", "degrees", 180.0, 1.0, 180.0, 1.0, 0.0, 180.0);
p.Add("DroneLoad", "Minimum drone load", "%", 100.0, 1.0, 100.0, 1.0, 1.0, 100.0, integral: true);
Piler(p);
p.Add("Drones", "Drones to fill", "", stellar ? 100 : 50, 0.0, stellar ? 100 : 50, 1.0, 0.0, 1000000.0, integral: true);
p.Flag("AutoReplenishDrones", "Native automatic drone replenishment", value: false);
if (stellar)
{
p.Add("VesselRange", "Vessel transport range", "LY", 60.0, 1.0, 60.0, 1.0, 0.0, 1000000000.0);
p.Flag("UnlimitedVesselRange", "Unlimited vessel transport range", value: true);
p.Add("WarpDistance", "Warp activation distance", "AU", 2.0, 0.0, 60.0, 0.5, 0.0, 1000000000.0);
p.Add("VesselLoad", "Minimum vessel load", "%", 100.0, 1.0, 100.0, 1.0, 1.0, 100.0, integral: true);
p.Add("Vessels", "Vessels to fill", "", 20.0, 0.0, 20.0, 1.0, 0.0, 1000000.0, integral: true);
p.Flag("AutoReplenishVessels", "Native automatic vessel replenishment", value: false);
p.Flag("IncludeCollectors", "Include orbital collectors", value: true);
p.Flag("RequireWarpers", "Require warpers", value: true);
p.Flag("RemoteStorage", "Set remote slot modes to Storage", value: false);
}
}
}
internal interface ICarrierStock
{
int Take(int item, int requested);
}
internal sealed class PlayerStock : ICarrierStock
{
private readonly Player player;
private readonly PlanetData planet;
public PlayerStock(Player player, PlanetData planet)
{
this.player = player;
this.planet = planet;
}
public int Take(int item, int requested)
{
if (player == null || player.package == null || !object.ReferenceEquals(player.planetData, planet) || requested <= 0)
{
return 0;
}
int num = default(int);
return player.package.TakeItem(item, requested, ref num);
}
}
internal sealed class ApplyResult
{
public int Changed;
public int Limited;
public int AddedCarriers;
public int Skipped;
public string Summary()
{
return Changed + " facilities configured; " + AddedCarriers + " carriers added; " + Limited + " carrier targets limited by building capacity; " + Skipped + " skipped.";
}
}
internal static class StationService
{
internal static bool Has<T>(T[] array, int index)
{
if (array != null && index >= 0)
{
return index < array.Length;
}
return false;
}
public static long PowerPerTick(double megawatts)
{
if (!Setting.Finite(megawatts) || megawatts < 0.0 || megawatts > 1000000000.0)
{
throw new ArgumentOutOfRangeException("megawatts");
}
return (long)Math.Round(megawatts * 1000000.0 / 60.0, MidpointRounding.AwayFromZero);
}
private static bool Power(PlanetFactory factory, int pc, double value)
{
if (factory.powerSystem == null || !Has(factory.powerSystem.consumerPool, pc) || pc <= 0 || factory.powerSystem.consumerPool[pc].id != pc)
{
return false;
}
factory.powerSystem.consumerPool[pc].workEnergyPerTick = PowerPerTick(value);
return true;
}
private static PrefabDesc Desc(PlanetFactory factory, int entity)
{
if (!Has(factory.entityPool, entity) || entity <= 0 || factory.entityPool[entity].id != entity)
{
return null;
}
int protoId = factory.entityPool[entity].protoId;
ItemProto val = ((protoId > 0) ? ((ProtoSet<ItemProto>)(object)LDB.items).Select(protoId) : null);
if (val != null && val.prefabDesc != null)
{
return val.prefabDesc;
}
int modelIndex = factory.entityPool[entity].modelIndex;
if (!Has(PlanetFactory.PrefabDescByModelIndex, modelIndex))
{
return null;
}
return PlanetFactory.PrefabDescByModelIndex[modelIndex];
}
private static int Capacity(int model, int data, int orders, int ceiling)
{
if (model <= 0 || data <= 0 || orders <= 0)
{
return 0;
}
return Math.Min(ceiling, Math.Min(model, Math.Min(data, orders)));
}
public static int DroneCapacity(PlanetFactory factory, StationComponent station)
{
PrefabDesc val = Desc(factory, station.entityId);
if (val != null)
{
return Capacity(val.stationMaxDroneCount, (station.workDroneDatas != null) ? station.workDroneDatas.Length : 0, (station.workDroneOrders != null) ? station.workDroneOrders.Length : 0, int.MaxValue);
}
return 0;
}
public static int ShipCapacity(PlanetFactory factory, StationComponent station)
{
PrefabDesc val = Desc(factory, station.entityId);
if (val != null)
{
return Capacity(val.stationMaxShipCount, (station.workShipDatas != null) ? station.workShipDatas.Length : 0, (station.workShipOrders != null) ? station.workShipOrders.Length : 0, 64);
}
return 0;
}
private static int Fill(int requested, int idle, int working, int capacity, int item, ICarrierStock inventory, ApplyResult result)
{
int num = Math.Min(Math.Max(0, requested), capacity);
if (requested > capacity)
{
result.Limited++;
}
if (idle < 0 || working < 0 || inventory == null)
{
return 0;
}
int num2 = (int)Math.Max(0L, (long)num - (long)idle - working);
if (num2 == 0)
{
return 0;
}
int num3 = inventory.Take(item, num2);
if (num3 < 0 || num3 > num2)
{
throw new InvalidOperationException("Carrier inventory returned an invalid item count.");
}
result.AddedCarriers += num3;
return num3;
}
public static bool Matches(StationComponent station, Facility kind)
{
if (station == null || station.id <= 0 || station.isCollector)
{
return false;
}
if (station.isVeinCollector)
{
return kind == Facility.AdvancedMiners;
}
return kind == (Facility)(station.isStellar ? 1 : 0);
}
public static void Station(PlanetFactory factory, StationComponent station, PresetSnapshot preset, ICarrierStock inventory, ApplyResult result)
{
//IL_0302: Unknown result type (might be due to invalid IL or missing references)
if (factory == null || !Matches(station, preset.Kind) || factory.transport == null || !Has(factory.transport.stationPool, station.id) || !object.ReferenceEquals(factory.transport.stationPool[station.id], station))
{
result.Skipped++;
return;
}
if (preset.Has("PowerMW"))
{
Power(factory, station.pcId, preset.Get("PowerMW"));
}
if (preset.Has("DroneRange"))
{
station.tripRangeDrones = Math.Cos(preset.Get("DroneRange") * Math.PI / 180.0);
}
if (preset.Has("DroneLoad"))
{
station.deliveryDrones = (int)preset.Get("DroneLoad");
}
if (preset.Has("Piler"))
{
station.pilerCount = (int)preset.Get("Piler");
}
if (preset.Has("Drones"))
{
station.idleDroneCount += Fill((int)preset.Get("Drones"), station.idleDroneCount, station.workDroneCount, DroneCapacity(factory, station), 5001, inventory, result);
}
if (preset.Has("AutoReplenishDrones"))
{
station.droneAutoReplenish = preset.Get("AutoReplenishDrones") != 0.0;
}
if (station.isStellar)
{
if (preset.Has("VesselRange") || preset.Has("UnlimitedVesselRange"))
{
station.tripRangeShips = (preset.UnlimitedRange ? 10000.0 : preset.VesselRangeLY) * 2400000.0;
}
if (preset.Has("WarpDistance"))
{
station.warpEnableDist = preset.Get("WarpDistance") * 40000.0;
}
if (preset.Has("VesselLoad"))
{
station.deliveryShips = (int)preset.Get("VesselLoad");
}
if (preset.Has("Vessels"))
{
station.idleShipCount += Fill((int)preset.Get("Vessels"), station.idleShipCount, station.workShipCount, ShipCapacity(factory, station), 5002, inventory, result);
}
if (preset.Has("AutoReplenishVessels"))
{
station.shipAutoReplenish = preset.Get("AutoReplenishVessels") != 0.0;
}
if (preset.Has("IncludeCollectors"))
{
station.includeOrbitCollector = preset.Get("IncludeCollectors") != 0.0;
}
if (preset.Has("RequireWarpers"))
{
station.warperNecessary = preset.Get("RequireWarpers") != 0.0;
}
if (preset.Has("RemoteStorage") && preset.Get("RemoteStorage") != 0.0 && station.storage != null)
{
for (int i = 0; i < station.storage.Length; i++)
{
station.storage[i].remoteLogic = (ELogisticStorage)0;
}
}
}
if (station.isVeinCollector && preset.Has("MiningSpeed"))
{
int minerId = station.minerId;
if (minerId <= 0 && Has(factory.entityPool, station.entityId))
{
minerId = factory.entityPool[station.entityId].minerId;
}
if (factory.factorySystem != null && Has(factory.factorySystem.minerPool, minerId) && minerId > 0 && factory.factorySystem.minerPool[minerId].id == minerId)
{
factory.factorySystem.minerPool[minerId].speed = (int)Math.Round(preset.Get("MiningSpeed") * 100.0);
}
}
result.Changed++;
}
public static void Dispenser(PlanetFactory factory, DispenserComponent dispenser, PresetSnapshot preset, ICarrierStock inventory, ApplyResult result)
{
if (factory == null || dispenser == null || dispenser.id <= 0 || factory.transport == null || !Has(factory.transport.dispenserPool, dispenser.id) || !object.ReferenceEquals(factory.transport.dispenserPool[dispenser.id], dispenser))
{
result.Skipped++;
return;
}
if (preset.Has("PowerMW"))
{
Power(factory, dispenser.pcId, preset.Get("PowerMW"));
}
if (preset.Has("Bots"))
{
PrefabDesc val = Desc(factory, dispenser.entityId);
int capacity = ((val != null && dispenser.workCourierDatas != null && dispenser.orders != null) ? Capacity(val.dispenserMaxCourierCount, dispenser.workCourierDatas.Length, dispenser.orders.Length, int.MaxValue) : 0);
dispenser.idleCourierCount += Fill((int)preset.Get("Bots"), dispenser.idleCourierCount, dispenser.workCourierCount, capacity, 5003, inventory, result);
}
if (preset.Has("AutoReplenishBots"))
{
dispenser.courierAutoReplenish = preset.Get("AutoReplenishBots") != 0.0;
}
result.Changed++;
}
public static void BattleBase(PlanetFactory factory, BattleBaseComponent battleBase, PresetSnapshot preset, ApplyResult result)
{
if (factory == null || battleBase == null || battleBase.id <= 0 || factory.defenseSystem == null || factory.defenseSystem.battleBases == null || !Has(factory.defenseSystem.battleBases.buffer, battleBase.id) || !object.ReferenceEquals(factory.defenseSystem.battleBases.buffer[battleBase.id], battleBase))
{
result.Skipped++;
return;
}
if (preset.Has("PowerMW"))
{
Power(factory, battleBase.pcId, preset.Get("PowerMW"));
}
result.Changed++;
}
}