Decompiled source of Upgradeable Mix Station Mod v2.0.1

Mods/UpgradeableMixStationMod.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using ScheduleOne;
using ScheduleOne.Core.Items.Framework;
using ScheduleOne.DevUtilities;
using ScheduleOne.Dialogue;
using ScheduleOne.Economy;
using ScheduleOne.Effects;
using ScheduleOne.EntityFramework;
using ScheduleOne.GameTime;
using ScheduleOne.ItemFramework;
using ScheduleOne.Map;
using ScheduleOne.Money;
using ScheduleOne.NPCs;
using ScheduleOne.ObjectScripts;
using ScheduleOne.Persistence;
using ScheduleOne.PlayerScripts;
using ScheduleOne.Product;
using ScheduleOne.Storage;
using ScheduleOne.UI.Shop;
using ScheduleOne.UI.Stations;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
using UpgradeableMixStationMod;
using UpgradeableMixStationMod.Data;
using UpgradeableMixStationMod.Items;
using UpgradeableMixStationMod.Shop;
using UpgradeableMixStationMod.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Mod), "UpgradeableMixStationMod", "2.0.0", "Dom", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("UpgradeableMixStationMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("UpgradeableMixStationMod")]
[assembly: AssemblyTitle("UpgradeableMixStationMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MyMod.Helpers
{
	public static class MelonLoggerExtensions
	{
		public static void Debug(this Instance logger, string message, bool stacktrace = true)
		{
			MelonDebug.Msg(stacktrace ? ("[" + GetCallerInfo() + "] " + message) : message);
		}

		private static string GetCallerInfo()
		{
			StackTrace stackTrace = new StackTrace();
			for (int i = 2; i < stackTrace.FrameCount; i++)
			{
				StackFrame frame = stackTrace.GetFrame(i);
				MethodBase method = frame.GetMethod();
				if (!(method?.DeclaringType == null))
				{
					return method.DeclaringType.FullName + "." + method.Name;
				}
			}
			return "unknown";
		}
	}
}
namespace UpgradeableMixStationMod
{
	public class Mod : MelonMod
	{
		private bool _injected;

		public static Mod Instance { get; private set; }

		public static UpgradeManager Upgrades { get; private set; }

		public override void OnInitializeMelon()
		{
			Instance = this;
			Upgrades = new UpgradeManager();
			((MelonBase)this).LoggerInstance.Msg("UpgradeableMixStationMod loaded.");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (sceneName == "Main" || sceneName == "Tutorial")
			{
				_injected = false;
				HookSaveSystem();
			}
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			if (_injected || (sceneName != "Main" && sceneName != "Tutorial"))
			{
				return;
			}
			try
			{
				UpgradeParts.Register();
				MelonCoroutines.Start(DelayedVendorSpawn());
				MelonCoroutines.Start(InitSpawnerDelayed());
				_injected = true;
			}
			catch (Exception arg)
			{
				((MelonBase)this).LoggerInstance.Error($"Injection failed: {arg}");
			}
		}

		private IEnumerator InitSpawnerDelayed()
		{
			yield return (object)new WaitForSeconds(4f);
			PartSpawner.Initialize();
		}

		public override void OnUpdate()
		{
		}

		private void HookSaveSystem()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			try
			{
				LoadManager instance = Singleton<LoadManager>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.onLoadComplete.AddListener(new UnityAction(OnGameLoaded));
				}
				SaveManager instance2 = Singleton<SaveManager>.Instance;
				if ((Object)(object)instance2 != (Object)null)
				{
					instance2.onSaveStart.AddListener(new UnityAction(OnGameSaving));
				}
			}
			catch
			{
				((MelonBase)this).LoggerInstance.Warning("Could not hook save system yet.");
			}
		}

		private void OnGameLoaded()
		{
			LoadManager instance = Singleton<LoadManager>.Instance;
			string text = ((instance != null) ? instance.LoadedGameFolderPath : null);
			if (!string.IsNullOrEmpty(text))
			{
				Upgrades.Load(text);
			}
		}

		private void OnGameSaving()
		{
			LoadManager instance = Singleton<LoadManager>.Instance;
			string text = ((instance != null) ? instance.LoadedGameFolderPath : null);
			if (!string.IsNullOrEmpty(text))
			{
				Upgrades.Save(text);
			}
		}

		public override void OnApplicationQuit()
		{
			try
			{
				LoadManager instance = Singleton<LoadManager>.Instance;
				string text = ((instance != null) ? instance.LoadedGameFolderPath : null);
				if (!string.IsNullOrEmpty(text))
				{
					Upgrades?.Save(text);
				}
			}
			catch
			{
			}
		}

		private IEnumerator DelayedVendorSpawn()
		{
			while (NPCManager.NPCRegistry.Count == 0)
			{
				yield return (object)new WaitForSeconds(1f);
			}
			yield return (object)new WaitForSeconds(2f);
			yield return PartsVendor.SpawnVendor();
		}
	}
}
namespace UpgradeableMixStationMod.UI
{
	public class PanelDragger : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
	{
		public RectTransform Target;

		private Vector2 _dragOffset;

		public void OnBeginDrag(PointerEventData eventData)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			Transform parent = ((Transform)Target).parent;
			Vector2 val = default(Vector2);
			RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)(object)((parent is RectTransform) ? parent : null), eventData.position, eventData.pressEventCamera, ref val);
			_dragOffset = Vector2.op_Implicit(((Transform)Target).localPosition) - val;
		}

		public void OnDrag(PointerEventData eventData)
		{
			//IL_0012: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Transform parent = ((Transform)Target).parent;
			Vector2 val = default(Vector2);
			RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)(object)((parent is RectTransform) ? parent : null), eventData.position, eventData.pressEventCamera, ref val);
			((Transform)Target).localPosition = Vector2.op_Implicit(val + _dragOffset);
		}

		public void OnEndDrag(PointerEventData eventData)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			UpgradePanel.SavePosition(Target.anchoredPosition);
		}
	}
	public static class UpgradePanel
	{
		private static GameObject _panelRoot;

		private static RectTransform _panelRect;

		private static TextMeshProUGUI _speedCurrentLabel;

		private static TextMeshProUGUI _speedNextLabel;

		private static TextMeshProUGUI _speedReqLabel;

		private static Button _speedButton;

		private static TextMeshProUGUI _speedButtonText;

		private static TextMeshProUGUI _qualityCurrentLabel;

		private static TextMeshProUGUI _qualityNextLabel;

		private static TextMeshProUGUI _qualityReqLabel;

		private static Button _qualityButton;

		private static TextMeshProUGUI _qualityButtonText;

		private static TextMeshProUGUI _statusLabel;

		private static MixingStationMk2 _currentStation;

		private static TMP_FontAsset _cachedFont;

		private static Sprite _roundedSprite;

		private static string PositionPath => Path.Combine(MelonEnvironment.UserDataDirectory, "UpgradeableMixStationMod_UIPos.txt");

		public static void Show(MixingStationCanvas canvas, MixingStationMk2 station)
		{
			_currentStation = station;
			if ((Object)(object)_cachedFont == (Object)null)
			{
				TextMeshProUGUI instructionLabel = canvas.InstructionLabel;
				_cachedFont = ((instructionLabel != null) ? ((TMP_Text)instructionLabel).font : null);
			}
			if ((Object)(object)_roundedSprite == (Object)null)
			{
				_roundedSprite = CreateRoundedSprite(12, 64);
			}
			if ((Object)(object)_panelRoot == (Object)null)
			{
				BuildPanel(((Component)canvas.Canvas).transform);
			}
			if ((Object)(object)_panelRoot.transform.parent != (Object)(object)((Component)canvas.Canvas).transform)
			{
				_panelRoot.transform.SetParent(((Component)canvas.Canvas).transform, false);
			}
			_panelRoot.SetActive(true);
			RefreshUI();
		}

		public static void Hide()
		{
			if ((Object)(object)_panelRoot != (Object)null)
			{
				_panelRoot.SetActive(false);
			}
			_currentStation = null;
		}

		public static void SavePosition(Vector2 pos)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				File.WriteAllText(PositionPath, $"{pos.x},{pos.y}");
			}
			catch
			{
			}
		}

		private static Vector2 LoadPosition()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!File.Exists(PositionPath))
				{
					return new Vector2(-20f, -10f);
				}
				string[] array = File.ReadAllText(PositionPath).Split(',');
				return new Vector2(float.Parse(array[0]), float.Parse(array[1]));
			}
			catch
			{
				return new Vector2(-20f, -10f);
			}
		}

		private static void BuildPanel(Transform canvasParent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			_panelRoot = new GameObject("MixUpgradePanel");
			_panelRoot.transform.SetParent(canvasParent, false);
			_panelRect = _panelRoot.AddComponent<RectTransform>();
			_panelRect.anchorMin = new Vector2(1f, 1f);
			_panelRect.anchorMax = new Vector2(1f, 1f);
			_panelRect.pivot = new Vector2(1f, 1f);
			_panelRect.anchoredPosition = LoadPosition();
			_panelRect.sizeDelta = new Vector2(280f, 0f);
			Image val = _panelRoot.AddComponent<Image>();
			val.sprite = _roundedSprite;
			val.type = (Type)1;
			((Graphic)val).color = new Color(0.08f, 0.08f, 0.12f, 0.92f);
			PanelDragger panelDragger = _panelRoot.AddComponent<PanelDragger>();
			panelDragger.Target = _panelRect;
			VerticalLayoutGroup val2 = _panelRoot.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)val2).padding = new RectOffset(16, 16, 16, 16);
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 8f;
			((LayoutGroup)val2).childAlignment = (TextAnchor)1;
			((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
			ContentSizeFitter val3 = _panelRoot.AddComponent<ContentSizeFitter>();
			val3.verticalFit = (FitMode)2;
			TextMeshProUGUI label = CreateLabel(_panelRoot.transform, "UPGRADES", 18f, (FontStyles)1);
			SetPreferredHeight(label, 28f);
			CreateDivider(_panelRoot.transform);
			CreateLabel(_panelRoot.transform, "SPEED", 14f, (FontStyles)1, (Color?)new Color(0.4f, 0.8f, 1f));
			_speedCurrentLabel = CreateLabel(_panelRoot.transform, "", 12f, (FontStyles)0);
			_speedNextLabel = CreateLabel(_panelRoot.transform, "", 11f, (FontStyles)2, (Color?)new Color(0.7f, 0.7f, 0.7f));
			_speedReqLabel = CreateLabel(_panelRoot.transform, "", 10f, (FontStyles)0);
			((TMP_Text)_speedReqLabel).richText = true;
			_speedButton = CreateRoundedButton(_panelRoot.transform, "Upgrade", OnSpeedClicked, out _speedButtonText);
			CreateDivider(_panelRoot.transform);
			CreateLabel(_panelRoot.transform, "QUALITY FLOOR", 14f, (FontStyles)1, (Color?)new Color(1f, 0.8f, 0.3f));
			_qualityCurrentLabel = CreateLabel(_panelRoot.transform, "", 12f, (FontStyles)0);
			_qualityNextLabel = CreateLabel(_panelRoot.transform, "", 11f, (FontStyles)2, (Color?)new Color(0.7f, 0.7f, 0.7f));
			_qualityReqLabel = CreateLabel(_panelRoot.transform, "", 10f, (FontStyles)0);
			((TMP_Text)_qualityReqLabel).richText = true;
			_qualityButton = CreateRoundedButton(_panelRoot.transform, "Upgrade", OnQualityClicked, out _qualityButtonText);
			CreateDivider(_panelRoot.transform);
			_statusLabel = CreateLabel(_panelRoot.transform, "", 11f, (FontStyles)2, (Color?)new Color(0.9f, 0.5f, 0.5f));
			SetPreferredHeight(_statusLabel, 20f);
		}

		private static void RefreshUI()
		{
			if (!((Object)(object)_currentStation == (Object)null))
			{
				StationUpgradeData data = Mod.Upgrades.GetData(((BuildableItem)_currentStation).GUID);
				((TMP_Text)_speedCurrentLabel).text = "Current: " + data.CurrentSpeedName;
				if (data.CanUpgradeSpeed)
				{
					UpgradeTier nextSpeedTier = data.NextSpeedTier;
					((TMP_Text)_speedNextLabel).text = "Next: " + nextSpeedTier.Name + " — " + nextSpeedTier.Description;
					((TMP_Text)_speedReqLabel).text = BuildRequirementsText(nextSpeedTier);
					((Component)_speedReqLabel).gameObject.SetActive(true);
					((TMP_Text)_speedButtonText).text = "Upgrade (" + MoneyManager.FormatAmount(nextSpeedTier.Cost, false, false) + ")";
					((Component)_speedButton).gameObject.SetActive(true);
					((Selectable)_speedButton).interactable = Mod.Upgrades.HasRequiredItems(nextSpeedTier);
				}
				else
				{
					((TMP_Text)_speedNextLabel).text = "MAX LEVEL";
					((Component)_speedReqLabel).gameObject.SetActive(false);
					((Component)_speedButton).gameObject.SetActive(false);
				}
				((TMP_Text)_qualityCurrentLabel).text = "Current: " + data.CurrentQualityName;
				if (data.CanUpgradeQuality)
				{
					UpgradeTier nextQualityTier = data.NextQualityTier;
					((TMP_Text)_qualityNextLabel).text = "Next: " + nextQualityTier.Name + " — " + nextQualityTier.Description;
					((TMP_Text)_qualityReqLabel).text = BuildRequirementsText(nextQualityTier);
					((Component)_qualityReqLabel).gameObject.SetActive(true);
					((TMP_Text)_qualityButtonText).text = "Upgrade (" + MoneyManager.FormatAmount(nextQualityTier.Cost, false, false) + ")";
					((Component)_qualityButton).gameObject.SetActive(true);
					((Selectable)_qualityButton).interactable = Mod.Upgrades.HasRequiredItems(nextQualityTier);
				}
				else
				{
					((TMP_Text)_qualityNextLabel).text = "MAX LEVEL";
					((Component)_qualityReqLabel).gameObject.SetActive(false);
					((Component)_qualityButton).gameObject.SetActive(false);
				}
				((TMP_Text)_statusLabel).text = "";
			}
		}

		private static string BuildRequirementsText(UpgradeTier tier)
		{
			if (tier.Items == null || tier.Items.Count == 0)
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("Requires: ");
			for (int i = 0; i < tier.Items.Count; i++)
			{
				ItemRequirement itemRequirement = tier.Items[i];
				int playerItemCount = Mod.Upgrades.GetPlayerItemCount(itemRequirement.ItemID);
				string text = ((playerItemCount >= itemRequirement.Amount) ? "#66FF66" : "#FF6666");
				if (i > 0)
				{
					stringBuilder.Append(", ");
				}
				stringBuilder.Append($"<color={text}>{itemRequirement.Amount}x {itemRequirement.DisplayName} ({playerItemCount})</color>");
			}
			return stringBuilder.ToString();
		}

		private static void OnSpeedClicked()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_currentStation == (Object)null))
			{
				if (Mod.Upgrades.TryUpgradeSpeed(((BuildableItem)_currentStation).GUID, out var failReason))
				{
					((Graphic)_statusLabel).color = new Color(0.4f, 1f, 0.4f);
					((TMP_Text)_statusLabel).text = "Speed upgraded!";
					RefreshUI();
				}
				else
				{
					((Graphic)_statusLabel).color = new Color(1f, 0.4f, 0.4f);
					((TMP_Text)_statusLabel).text = failReason;
				}
			}
		}

		private static void OnQualityClicked()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_currentStation == (Object)null))
			{
				if (Mod.Upgrades.TryUpgradeQuality(((BuildableItem)_currentStation).GUID, out var failReason))
				{
					((Graphic)_statusLabel).color = new Color(0.4f, 1f, 0.4f);
					((TMP_Text)_statusLabel).text = "Quality floor upgraded!";
					RefreshUI();
				}
				else
				{
					((Graphic)_statusLabel).color = new Color(1f, 0.4f, 0.4f);
					((TMP_Text)_statusLabel).text = failReason;
				}
			}
		}

		private static Sprite CreateRoundedSprite(int radius, int size)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			Color32[] array = (Color32[])(object)new Color32[size * size];
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num = 0f;
					float num2 = 0f;
					if (j < radius)
					{
						num = radius - j;
					}
					else if (j > size - 1 - radius)
					{
						num = j - (size - 1 - radius);
					}
					if (i < radius)
					{
						num2 = radius - i;
					}
					else if (i > size - 1 - radius)
					{
						num2 = i - (size - 1 - radius);
					}
					float num3 = Mathf.Sqrt(num * num + num2 * num2);
					byte b = (byte)((num3 <= (float)(radius - 1)) ? 255u : ((uint)((num3 <= (float)radius) ? ((byte)(255f * ((float)radius - num3))) : 0)));
					array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b);
				}
			}
			val.SetPixels32(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4((float)radius, (float)radius, (float)radius, (float)radius));
		}

		private static TextMeshProUGUI CreateLabel(Transform parent, string text, float fontSize, FontStyles style = 0, Color? color = null)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Label");
			val.transform.SetParent(parent, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val2).text = text;
			((TMP_Text)val2).fontSize = fontSize;
			((TMP_Text)val2).fontStyle = style;
			((Graphic)val2).color = (Color)(((??)color) ?? Color.white);
			((TMP_Text)val2).alignment = (TextAlignmentOptions)513;
			((TMP_Text)val2).enableWordWrapping = true;
			((TMP_Text)val2).overflowMode = (TextOverflowModes)3;
			if ((Object)(object)_cachedFont != (Object)null)
			{
				((TMP_Text)val2).font = _cachedFont;
			}
			LayoutElement val3 = val.AddComponent<LayoutElement>();
			val3.preferredHeight = fontSize + 6f;
			return val2;
		}

		private static void SetPreferredHeight(TextMeshProUGUI label, float height)
		{
			LayoutElement component = ((Component)label).GetComponent<LayoutElement>();
			if ((Object)(object)component != (Object)null)
			{
				component.preferredHeight = height;
			}
		}

		private static Button CreateRoundedButton(Transform parent, string text, Action onClick, out TextMeshProUGUI buttonLabel)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: 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_01bb: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Button");
			val.transform.SetParent(parent, false);
			val.AddComponent<LayoutElement>().preferredHeight = 34f;
			Image val2 = val.AddComponent<Image>();
			val2.sprite = _roundedSprite;
			val2.type = (Type)1;
			((Graphic)val2).color = new Color(0.2f, 0.5f, 0.3f, 1f);
			Button val3 = val.AddComponent<Button>();
			ColorBlock colors = ((Selectable)val3).colors;
			((ColorBlock)(ref colors)).normalColor = new Color(0.2f, 0.5f, 0.3f);
			((ColorBlock)(ref colors)).highlightedColor = new Color(0.25f, 0.65f, 0.35f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.15f, 0.4f, 0.2f);
			((ColorBlock)(ref colors)).disabledColor = new Color(0.2f, 0.2f, 0.2f);
			((Selectable)val3).colors = colors;
			((UnityEvent)val3.onClick).AddListener((UnityAction)delegate
			{
				onClick?.Invoke();
			});
			GameObject val4 = new GameObject("Text");
			val4.transform.SetParent(val.transform, false);
			RectTransform val5 = val4.AddComponent<RectTransform>();
			val5.anchorMin = Vector2.zero;
			val5.anchorMax = Vector2.one;
			val5.sizeDelta = Vector2.zero;
			val5.offsetMin = new Vector2(8f, 2f);
			val5.offsetMax = new Vector2(-8f, -2f);
			buttonLabel = val4.AddComponent<TextMeshProUGUI>();
			((TMP_Text)buttonLabel).text = text;
			((TMP_Text)buttonLabel).fontSize = 13f;
			((TMP_Text)buttonLabel).fontStyle = (FontStyles)1;
			((Graphic)buttonLabel).color = Color.white;
			((TMP_Text)buttonLabel).alignment = (TextAlignmentOptions)514;
			if ((Object)(object)_cachedFont != (Object)null)
			{
				((TMP_Text)buttonLabel).font = _cachedFont;
			}
			return val3;
		}

		private static void CreateDivider(Transform parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Divider");
			val.transform.SetParent(parent, false);
			LayoutElement val2 = val.AddComponent<LayoutElement>();
			val2.preferredHeight = 1f;
			val2.flexibleHeight = 0f;
			((Graphic)val.AddComponent<Image>()).color = new Color(1f, 1f, 1f, 0.15f);
		}
	}
}
namespace UpgradeableMixStationMod.Shop
{
	public static class PartsVendor
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Predicate<ShopInterface> <>9__11_0;

			public static Action <>9__14_3;

			public static UnityAction <>9__14_0;

			public static UnityAction <>9__14_1;

			public static UnityAction <>9__14_2;

			internal bool <SpawnVendor>b__11_0(ShopInterface s)
			{
				return s.ShopCode == "gas_mart_central";
			}

			internal void <SetupDialogue>b__14_0()
			{
				SetSkipBehaviourEnd();
				MelonCoroutines.Start(EndDialogueThen(delegate
				{
					OpenShop();
				}));
			}

			internal void <SetupDialogue>b__14_3()
			{
				OpenShop();
			}

			internal void <SetupDialogue>b__14_1()
			{
				<>c__DisplayClass14_0 CS$<>8__locals0 = new <>c__DisplayClass14_0();
				SetSkipBehaviourEnd();
				CS$<>8__locals0.response = GetHintResponse();
				MelonCoroutines.Start(EndDialogueThen(delegate
				{
					ShowHintBubble(CS$<>8__locals0.response);
				}));
			}

			internal void <SetupDialogue>b__14_2()
			{
				SetSkipBehaviourEnd();
				MelonCoroutines.Start(EndDialogueThen(null));
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass14_0
		{
			public string response;

			internal void <SetupDialogue>b__4()
			{
				ShowHintBubble(response);
			}
		}

		private static ShopInterface _shop;

		private static Canvas _shopCanvas;

		private static RectTransform _shopContainer;

		private static NPC _vendorNPC;

		private static Vector3 _spawnPos;

		private static Quaternion _spawnRot;

		private static bool _spawned;

		public static Vector3 VendorPosition = new Vector3(67.77f, 0f, 28.74f);

		public static Quaternion VendorRotation = Quaternion.Euler(0f, 90f, 0f);

		public static bool IsShopOpen => (Object)(object)_shopContainer != (Object)null && ((Component)_shopContainer).gameObject.activeInHierarchy;

		public static IEnumerator SpawnVendor()
		{
			if (_spawned)
			{
				yield break;
			}
			yield return (object)new WaitForSeconds(3f);
			ShopInterface sourceShop = ShopInterface.AllShops.Find((ShopInterface s) => s.ShopCode == "gas_mart_central");
			if ((Object)(object)sourceShop == (Object)null)
			{
				MelonLogger.Warning("[Shop] Could not find source shop to clone.");
				yield break;
			}
			GameObject shopGO = Object.Instantiate<GameObject>(((Component)sourceShop).gameObject);
			((Object)shopGO).name = "UpgradePartsShop";
			_shop = shopGO.GetComponent<ShopInterface>();
			_shop.ShopName = "Mix Tech Parts";
			_shop.ShopCode = "mix_tech_parts";
			_shopCanvas = shopGO.GetComponentInChildren<Canvas>(true);
			_shopContainer = _shop.Container;
			if ((Object)(object)_shop.StoreNameLabel != (Object)null)
			{
				((TMP_Text)_shop.StoreNameLabel).text = "Mix Tech Parts";
			}
			FieldInfo screenField = typeof(ShopInterface).GetField("shopScreen", BindingFlags.Instance | BindingFlags.NonPublic);
			if (screenField != null)
			{
				Component screen = shopGO.GetComponentInChildren(screenField.FieldType, true);
				if ((Object)(object)screen != (Object)null)
				{
					screenField.SetValue(_shop, screen);
				}
			}
			Cart cart = shopGO.GetComponentInChildren<Cart>(true);
			if ((Object)(object)cart != (Object)null)
			{
				cart.Shop = _shop;
			}
			RectTransform listingContainer = _shop.ListingContainer;
			if ((Object)(object)listingContainer != (Object)null)
			{
				for (int i = ((Transform)listingContainer).childCount - 1; i >= 0; i--)
				{
					Object.Destroy((Object)(object)((Component)((Transform)listingContainer).GetChild(i)).gameObject);
				}
			}
			(typeof(ShopInterface).GetField("listingUI", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(_shop) as List<ListingUI>)?.Clear();
			_shop.Listings.Clear();
			yield return null;
			if ((Object)(object)UpgradeParts.MixingGear != (Object)null)
			{
				AddListing(_shop, UpgradeParts.MixingGear, 150f);
			}
			if ((Object)(object)UpgradeParts.PrecisionComponent != (Object)null)
			{
				AddListing(_shop, UpgradeParts.PrecisionComponent, 400f);
			}
			SpawnTable();
			MelonCoroutines.Start(AddVendorMapPOI());
			MelonCoroutines.Start(SpawnNPC());
			try
			{
				TryRegisterDayPass();
			}
			catch
			{
			}
			_spawned = true;
		}

		private static void TryRegisterDayPass()
		{
			try
			{
				TimeManager instance = NetworkSingleton<TimeManager>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.onDayPass = (Action)Delegate.Combine(instance.onDayPass, new Action(OnDayPass));
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[Shop] Could not register TimeManager onDayPass: " + ex.Message);
			}
		}

		private static IEnumerator SpawnNPC()
		{
			_spawnPos = new Vector3(67.01f, 0.11f, 28.78f);
			_spawnRot = Quaternion.Euler(0f, 90f, 0f);
			NPC sourceNPC = null;
			foreach (NPC npc in NPCManager.NPCRegistry)
			{
				if ((Object)(object)npc == (Object)null || (Object)(object)npc.DialogueHandler == (Object)null || (Object)(object)((Component)npc).GetComponentInChildren<DialogueController>() == (Object)null)
				{
					continue;
				}
				sourceNPC = npc;
				break;
			}
			if ((Object)(object)sourceNPC == (Object)null)
			{
				MelonLogger.Error("[Shop] Checked NPCs, none suitable. Vendor NPC not spawned.");
				yield break;
			}
			GameObject npcGO = Object.Instantiate<GameObject>(((Component)sourceNPC).gameObject);
			((Object)npcGO).name = "Nick";
			_vendorNPC = npcGO.GetComponent<NPC>();
			_vendorNPC.FirstName = "Nick";
			_vendorNPC.hasLastName = false;
			_vendorNPC.LastName = "";
			_vendorNPC.ID = "tech_dealer_nick";
			_vendorNPC.BakedGUID = Guid.NewGuid().ToString();
			_vendorNPC.CanBeSummoned = false;
			NavMeshAgent agent = npcGO.GetComponent<NavMeshAgent>();
			if ((Object)(object)agent != (Object)null)
			{
				((Behaviour)agent).enabled = false;
			}
			if ((Object)(object)_vendorNPC.Health != (Object)null)
			{
				_vendorNPC.Health.Invincible = true;
			}
			_vendorNPC.OverrideParent = true;
			_vendorNPC.OverriddenParent = null;
			MonoBehaviour[] componentsInChildren = npcGO.GetComponentsInChildren<MonoBehaviour>();
			foreach (MonoBehaviour comp in componentsInChildren)
			{
				string typeName = ((object)comp).GetType().Name;
				if ((typeName.Contains("Schedule") || typeName.Contains("Behaviour") || typeName.Contains("Behavior")) && (Object)(object)comp != (Object)(object)_vendorNPC && !typeName.Contains("Dialogue"))
				{
					((Behaviour)comp).enabled = false;
				}
			}
			SetupDialogue(npcGO);
			yield return null;
			yield return null;
			npcGO.transform.position = _spawnPos;
			npcGO.transform.rotation = _spawnRot;
			npcGO.SetActive(true);
			_vendorNPC.SetVisible(true, false);
			Renderer[] componentsInChildren2 = npcGO.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer rend in componentsInChildren2)
			{
				if (rend is MeshRenderer && (Object)(object)((Component)rend).GetComponent<MeshFilter>() != (Object)null)
				{
					Mesh sharedMesh = ((Component)rend).GetComponent<MeshFilter>().sharedMesh;
					string meshName = ((sharedMesh != null) ? ((Object)sharedMesh).name : null) ?? "";
					if (meshName.Contains("Capsule") || meshName.Contains("Sphere") || meshName.Contains("Cube") || meshName.Contains("Cylinder"))
					{
						rend.enabled = false;
						continue;
					}
				}
				rend.enabled = true;
			}
			if ((Object)(object)_vendorNPC.Movement != (Object)null)
			{
				_vendorNPC.Movement.Stop();
				_vendorNPC.Movement.SetAgentEnabled(false);
			}
			yield return null;
			npcGO.transform.position = _spawnPos;
			npcGO.transform.rotation = _spawnRot;
			MelonCoroutines.Start(KeepInPlace());
		}

		private static void SetupDialogue(GameObject npcGO)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			//IL_00e4: 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)
			//IL_00ef: Expected O, but got Unknown
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Expected O, but got Unknown
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			DialogueController val = npcGO.GetComponent<DialogueController>() ?? npcGO.GetComponentInChildren<DialogueController>();
			if ((Object)(object)val == (Object)null)
			{
				MelonLogger.Error("[Shop] No DialogueController found on cloned NPC — dialogue will not work.");
				return;
			}
			val.Choices.Clear();
			val.GreetingOverrides.Clear();
			val.UseDialogueBehaviour = false;
			DialogueHandler val2 = npcGO.GetComponent<DialogueHandler>() ?? npcGO.GetComponentInChildren<DialogueHandler>();
			if ((Object)(object)val2 != (Object)null)
			{
				val2.DialogueEvents = (DialogueEvent[])(object)new DialogueEvent[0];
			}
			GreetingOverride val3 = new GreetingOverride();
			val3.Greeting = "What do you need?";
			val3.ShouldShow = true;
			val3.PlayVO = false;
			val.AddGreetingOverride(val3);
			DialogueChoice val4 = new DialogueChoice();
			val4.Enabled = true;
			val4.ChoiceText = "I want to buy something.";
			val4.ShowWorldspaceDialogue = true;
			val4.onChoosen = new UnityEvent();
			UnityEvent onChoosen = val4.onChoosen;
			object obj = <>c.<>9__14_0;
			if (obj == null)
			{
				UnityAction val5 = delegate
				{
					SetSkipBehaviourEnd();
					MelonCoroutines.Start(EndDialogueThen(delegate
					{
						OpenShop();
					}));
				};
				<>c.<>9__14_0 = val5;
				obj = (object)val5;
			}
			onChoosen.AddListener((UnityAction)obj);
			val.AddDialogueChoice(val4, 10);
			DialogueChoice val6 = new DialogueChoice();
			val6.Enabled = true;
			val6.ChoiceText = "Where can I find a Prototype Core?";
			val6.ShowWorldspaceDialogue = true;
			val6.onChoosen = new UnityEvent();
			UnityEvent onChoosen2 = val6.onChoosen;
			object obj2 = <>c.<>9__14_1;
			if (obj2 == null)
			{
				UnityAction val7 = delegate
				{
					SetSkipBehaviourEnd();
					string response = GetHintResponse();
					MelonCoroutines.Start(EndDialogueThen(delegate
					{
						ShowHintBubble(response);
					}));
				};
				<>c.<>9__14_1 = val7;
				obj2 = (object)val7;
			}
			onChoosen2.AddListener((UnityAction)obj2);
			val.AddDialogueChoice(val6, 5);
			DialogueChoice val8 = new DialogueChoice();
			val8.Enabled = true;
			val8.ChoiceText = "Nothing.";
			val8.ShowWorldspaceDialogue = true;
			val8.onChoosen = new UnityEvent();
			UnityEvent onChoosen3 = val8.onChoosen;
			object obj3 = <>c.<>9__14_2;
			if (obj3 == null)
			{
				UnityAction val9 = delegate
				{
					SetSkipBehaviourEnd();
					MelonCoroutines.Start(EndDialogueThen(null));
				};
				<>c.<>9__14_2 = val9;
				obj3 = (object)val9;
			}
			onChoosen3.AddListener((UnityAction)obj3);
			val.AddDialogueChoice(val8, 1);
		}

		private static IEnumerator EndDialogueThen(Action callback)
		{
			yield return null;
			yield return null;
			callback?.Invoke();
		}

		private static void SetSkipBehaviourEnd()
		{
			try
			{
				DialogueHandler val = _vendorNPC?.DialogueHandler;
				if (!((Object)(object)val == (Object)null))
				{
					FieldInfo field = typeof(DialogueHandler).GetField("skipNextDialogueBehaviourEnd", BindingFlags.Instance | BindingFlags.NonPublic);
					if (field != null)
					{
						field.SetValue(val, true);
					}
				}
			}
			catch
			{
			}
		}

		private static void ShowHintBubble(string text)
		{
			try
			{
				NPC vendorNPC = _vendorNPC;
				if (vendorNPC != null)
				{
					DialogueHandler dialogueHandler = vendorNPC.DialogueHandler;
					if (dialogueHandler != null)
					{
						dialogueHandler.ShowWorldspaceDialogue(text, 6f);
					}
				}
			}
			catch
			{
			}
		}

		private static string GetHintResponse()
		{
			if (PartSpawner.TrackedDrops.Count == 0)
			{
				return "No Prototype Cores out there today. Check back tomorrow.";
			}
			if (PartSpawner.HasGivenHintToday)
			{
				return "I already told you what I know today. Come back tomorrow.";
			}
			DeadDrop hintDrop = PartSpawner.GetHintDrop();
			if ((Object)(object)hintDrop == (Object)null)
			{
				return "I don't have any leads right now.";
			}
			string text = ((!string.IsNullOrEmpty(hintDrop.DeadDropName)) ? hintDrop.DeadDropName : "an unknown location");
			PartSpawner.MarkHintGiven();
			return "I heard there's a Prototype Core at the dead drop near \"" + text + "\". That's all I know for today.";
		}

		private static IEnumerator KeepInPlace()
		{
			while ((Object)(object)_vendorNPC != (Object)null)
			{
				if ((Object)(object)_vendorNPC.Movement != (Object)null && _vendorNPC.Movement.IsMoving)
				{
					_vendorNPC.Movement.Stop();
					_vendorNPC.Movement.SetAgentEnabled(false);
				}
				if (Vector3.Distance(((Component)_vendorNPC).transform.position, _spawnPos) > 0.3f)
				{
					((Component)_vendorNPC).transform.position = _spawnPos;
					((Component)_vendorNPC).transform.rotation = _spawnRot;
				}
				yield return (object)new WaitForSeconds(0.5f);
			}
		}

		private static void OnDayPass()
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_vendorNPC == (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)_vendorNPC.Health != (Object)null && (_vendorNPC.Health.IsDead || _vendorNPC.Health.IsKnockedOut))
				{
					Object.Destroy((Object)(object)((Component)_vendorNPC).gameObject);
					MelonCoroutines.Start(SpawnNPC());
					return;
				}
				((Component)_vendorNPC).gameObject.SetActive(true);
				_vendorNPC.SetVisible(true, false);
				((Component)_vendorNPC).transform.position = _spawnPos;
				((Component)_vendorNPC).transform.rotation = _spawnRot;
				if ((Object)(object)_vendorNPC.Movement != (Object)null)
				{
					_vendorNPC.Movement.Stop();
					_vendorNPC.Movement.SetAgentEnabled(false);
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[Shop] Respawn failed: " + ex.Message);
			}
		}

		private static void OpenShop()
		{
			if (!((Object)(object)_shop == (Object)null))
			{
				_shop.SetIsOpen(true);
				if ((Object)(object)_shopCanvas != (Object)null)
				{
					((Behaviour)_shopCanvas).enabled = true;
				}
				if ((Object)(object)_shopContainer != (Object)null)
				{
					((Component)_shopContainer).gameObject.SetActive(true);
				}
				MelonCoroutines.Start(WatchForShopClose());
			}
		}

		private static void ForceCloseShop()
		{
			if (!((Object)(object)_shop == (Object)null))
			{
				_shop.SetIsOpen(false);
				if ((Object)(object)_shopCanvas != (Object)null)
				{
					((Behaviour)_shopCanvas).enabled = false;
				}
				if ((Object)(object)_shopContainer != (Object)null)
				{
					((Component)_shopContainer).gameObject.SetActive(false);
				}
				ClearWorldspaceDialogue();
			}
		}

		private static void ClearWorldspaceDialogue()
		{
			try
			{
				NPC vendorNPC = _vendorNPC;
				if (vendorNPC != null)
				{
					DialogueHandler dialogueHandler = vendorNPC.DialogueHandler;
					if (dialogueHandler != null)
					{
						dialogueHandler.ShowWorldspaceDialogue(" ", 0f);
					}
				}
			}
			catch
			{
			}
		}

		private static IEnumerator WatchForShopClose()
		{
			yield return (object)new WaitForSeconds(0.3f);
			while ((Object)(object)_shop != (Object)null && _shop.IsOpen)
			{
				PlayerMovement player = PlayerSingleton<PlayerMovement>.Instance;
				if ((Object)(object)player != (Object)null && Vector3.Distance(((Component)player).transform.position, VendorPosition) > 8f)
				{
					ForceCloseShop();
					yield break;
				}
				yield return null;
			}
			if ((Object)(object)_shopCanvas != (Object)null)
			{
				((Behaviour)_shopCanvas).enabled = false;
			}
			if ((Object)(object)_shopContainer != (Object)null)
			{
				((Component)_shopContainer).gameObject.SetActive(false);
			}
			ClearWorldspaceDialogue();
		}

		private static void SpawnTable()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: 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_0154: 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_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Expected O, but got Unknown
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Expected O, but got Unknown
			GameObject val = new GameObject("VendorTable");
			val.transform.position = VendorPosition;
			val.transform.rotation = VendorRotation;
			Shader val2 = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard");
			GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)3);
			val3.transform.SetParent(val.transform, false);
			val3.transform.localPosition = new Vector3(0f, 0.75f, 0f);
			val3.transform.localScale = new Vector3(1.4f, 0.08f, 0.7f);
			val3.GetComponent<Renderer>().material = new Material(val2)
			{
				color = new Color(0.15f, 0.2f, 0.25f)
			};
			val3.layer = LayerMask.NameToLayer("Default");
			Material material = new Material(val2)
			{
				color = new Color(0.1f, 0.12f, 0.15f)
			};
			Vector3[] array = (Vector3[])(object)new Vector3[4]
			{
				new Vector3(0.6f, 0.37f, 0.28f),
				new Vector3(-0.6f, 0.37f, 0.28f),
				new Vector3(0.6f, 0.37f, -0.28f),
				new Vector3(-0.6f, 0.37f, -0.28f)
			};
			foreach (Vector3 localPosition in array)
			{
				GameObject val4 = GameObject.CreatePrimitive((PrimitiveType)3);
				val4.transform.SetParent(val.transform, false);
				val4.transform.localPosition = localPosition;
				val4.transform.localScale = new Vector3(0.06f, 0.7f, 0.06f);
				val4.GetComponent<Renderer>().material = material;
				val4.layer = LayerMask.NameToLayer("Default");
			}
			GameObject val5 = GameObject.CreatePrimitive((PrimitiveType)2);
			val5.transform.SetParent(val.transform, false);
			val5.transform.localPosition = new Vector3(-0.3f, 0.85f, 0f);
			val5.transform.localScale = new Vector3(0.2f, 0.04f, 0.2f);
			val5.GetComponent<Renderer>().material = new Material(val2)
			{
				color = new Color(0.5f, 0.7f, 0.9f)
			};
			Object.Destroy((Object)(object)val5.GetComponent<Collider>());
			GameObject val6 = GameObject.CreatePrimitive((PrimitiveType)3);
			val6.transform.SetParent(val.transform, false);
			val6.transform.localPosition = new Vector3(0.3f, 0.84f, 0f);
			val6.transform.localScale = new Vector3(0.15f, 0.1f, 0.15f);
			val6.GetComponent<Renderer>().material = new Material(val2)
			{
				color = new Color(0.9f, 0.6f, 0.2f)
			};
			Object.Destroy((Object)(object)val6.GetComponent<Collider>());
		}

		private static void AddListing(ShopInterface shop, PropertyItemDefinition def, float price)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			if (!((Object)(object)def == (Object)null) && !((Object)(object)shop == (Object)null))
			{
				ShopListing val = new ShopListing
				{
					name = ((BaseItemDefinition)def).Name,
					Item = (StorableItemDefinition)(object)def,
					LimitedStock = false,
					DefaultStock = -1,
					CanBeDelivered = false
				};
				typeof(ShopListing).GetField("OverridePrice", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(val, true);
				typeof(ShopListing).GetField("OverriddenPrice", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(val, price);
				shop.Listings.Add(val);
				val.Initialize(shop);
				typeof(ShopInterface).GetMethod("CreateListingUI", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(shop, new object[1] { val });
			}
		}

		public static Texture2D LoadCustomTexture(string fileName)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			try
			{
				string text = Path.Combine(MelonEnvironment.MelonBaseDirectory, "Mods", "UpgradeableMixStationMod", "Icons", fileName);
				if (!File.Exists(text))
				{
					MelonLogger.Warning("[Shop] Map icon not found at: " + text);
					return null;
				}
				byte[] array = File.ReadAllBytes(text);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				((Texture)val).filterMode = (FilterMode)1;
				ImageConversion.LoadImage(val, array);
				return val;
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[Shop] Failed to load map icon: " + ex.Message);
				return null;
			}
		}

		private static IEnumerator AddVendorMapPOI()
		{
			yield return (object)new WaitForSeconds(1f);
			POI existingPOI = Object.FindObjectOfType<POI>();
			if ((Object)(object)existingPOI == (Object)null)
			{
				MelonLogger.Warning("[Shop] Could not find an existing POI to clone for the map marker.");
				yield break;
			}
			GameObject poiAnchor = new GameObject("MixTechPartsPOI_Anchor");
			poiAnchor.transform.position = VendorPosition;
			GameObject poiGO = Object.Instantiate<GameObject>(((Component)existingPOI).gameObject, poiAnchor.transform);
			((Object)poiGO).name = "MixTechPartsPOI";
			poiGO.transform.localPosition = new Vector3(0f, 2f, 0f);
			POI poi = poiGO.GetComponent<POI>();
			poi.SetMainText("Mix Tech Parts");
			poi.onUICreated.AddListener((UnityAction)delegate
			{
				MelonCoroutines.Start(SetPOIIcon(poi));
			});
			((Behaviour)poi).enabled = true;
			poiGO.SetActive(true);
		}

		private static IEnumerator SetPOIIcon(POI poi)
		{
			yield return null;
			if ((Object)(object)poi.IconContainer == (Object)null)
			{
				MelonLogger.Warning("[Shop] POI IconContainer is null, cannot set custom icon.");
				yield break;
			}
			for (int i = ((Transform)poi.IconContainer).childCount - 1; i >= 0; i--)
			{
				Object.Destroy((Object)(object)((Component)((Transform)poi.IconContainer).GetChild(i)).gameObject);
			}
			yield return null;
			Texture2D tex = LoadCustomTexture("Supplier.png");
			if (!((Object)(object)tex == (Object)null))
			{
				GameObject iconGO = new GameObject("MixTechIcon");
				iconGO.transform.SetParent((Transform)(object)poi.IconContainer, false);
				RectTransform rect = iconGO.AddComponent<RectTransform>();
				rect.sizeDelta = new Vector2(25f, 25f);
				Image img = iconGO.AddComponent<Image>();
				img.sprite = Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(0.5f, 0.5f));
				((Graphic)img).color = Color.white;
				img.preserveAspect = true;
			}
		}
	}
}
namespace UpgradeableMixStationMod.Patches
{
	[HarmonyPatch(typeof(UIScreenManager), "get_IsBackTriggeredThisFrame")]
	public static class BlockPauseMenuForCustomShopPatch
	{
		public static void Postfix(ref bool __result)
		{
			if (PartsVendor.IsShopOpen)
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(MixingStationCanvas), "Open")]
	public static class CanvasOpenPatch
	{
		[HarmonyPostfix]
		public static void Postfix(MixingStationCanvas __instance, MixingStation station)
		{
			MixingStationMk2 val = (MixingStationMk2)(object)((station is MixingStationMk2) ? station : null);
			if (val != null)
			{
				UpgradePanel.Show(__instance, val);
			}
		}
	}
	[HarmonyPatch(typeof(MixingStationCanvas), "Close")]
	public static class CanvasClosePatch
	{
		[HarmonyPostfix]
		public static void Postfix()
		{
			UpgradePanel.Hide();
		}
	}
	[HarmonyPatch(typeof(UIScreenManager), "Update")]
	public static class CleanupGhostScreensPatch
	{
		public static void Prefix(UIScreenManager __instance)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.IsAnyScreenActive())
			{
				return;
			}
			UIScreen topScreen = __instance.TopScreen;
			if ((Object)(object)topScreen == (Object)null || !((Component)topScreen).gameObject.activeInHierarchy)
			{
				Stack<UIScreenInfo> value = Traverse.Create((object)__instance).Field("screenStack").GetValue<Stack<UIScreenInfo>>();
				if (value != null && value.Count > 0)
				{
					value.Pop();
				}
			}
		}
	}
	[HarmonyPatch(typeof(ListingUI), "Initialize")]
	public static class CustomShop_ListingUI_Patch
	{
		public static void Postfix(ListingUI __instance)
		{
			ListingUI obj = __instance;
			obj.onDropdownClicked = (Action)Delegate.Combine(obj.onDropdownClicked, (Action)delegate
			{
				//IL_00ef: 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_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_0120: Unknown result type (might be due to invalid IL or missing references)
				//IL_0125: 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)
				Canvas shopCanvas = ((Component)__instance).GetComponentInParent<Canvas>();
				if ((Object)(object)shopCanvas == (Object)null)
				{
					MelonLogger.Error("[Shop] Could not find parent Canvas!");
				}
				else
				{
					ShopAmountSelector val = ((Component)shopCanvas).GetComponentInChildren<ShopAmountSelector>(true);
					if ((Object)(object)val == (Object)null)
					{
						ShopAmountSelector val2 = Object.FindObjectOfType<ShopAmountSelector>(true);
						if ((Object)(object)val2 != (Object)null)
						{
							val = Object.Instantiate<ShopAmountSelector>(val2, ((Component)shopCanvas).transform);
							((Component)val).gameObject.SetActive(true);
							RectTransform component = ((Component)val).GetComponent<RectTransform>();
							if ((Object)(object)component != (Object)null)
							{
								((Transform)component).localScale = Vector3.one;
							}
						}
					}
					if ((Object)(object)val != (Object)null)
					{
						if ((Object)(object)__instance.DropdownAnchor != (Object)null)
						{
							((Component)val).transform.position = ((Transform)__instance.DropdownAnchor).position;
							RectTransform component2 = ((Component)val).GetComponent<RectTransform>();
							if ((Object)(object)component2 != (Object)null)
							{
								Vector2 anchoredPosition = component2.anchoredPosition;
								Rect rect = component2.rect;
								component2.anchoredPosition = anchoredPosition + new Vector2(0f, 0f - ((Rect)(ref rect)).height);
							}
						}
						((Component)val).transform.SetAsLastSibling();
						val.Open();
						((UnityEventBase)val.onSubmitted).RemoveAllListeners();
						val.onSubmitted.AddListener((UnityAction<int>)delegate(int amount)
						{
							try
							{
								Cart componentInChildren = ((Component)shopCanvas).GetComponentInChildren<Cart>(true);
								if ((Object)(object)componentInChildren != (Object)null)
								{
									componentInChildren.AddItem(__instance.Listing, amount);
								}
								else
								{
									MelonLogger.Error("[Shop] FAILED: Could not find the Cart component in this shop's UI!");
								}
							}
							catch (Exception ex)
							{
								MelonLogger.Error("[Shop] Error adding to cart: " + ex.Message);
							}
						});
					}
					else
					{
						MelonLogger.Error("[Shop] FAILED: Could not find the base game's ShopAmountSelector to clone!");
					}
				}
			});
		}
	}
	[HarmonyPatch(typeof(MixingStationCanvas), "StartMixOperation")]
	public static class QualityPatch
	{
		[HarmonyPrefix]
		public static void Prefix(MixingStationCanvas __instance, MixOperation mixOperation)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Invalid comparison between Unknown and I4
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			MixingStation mixingStation = __instance.MixingStation;
			MixingStationMk2 val = (MixingStationMk2)(object)((mixingStation is MixingStationMk2) ? mixingStation : null);
			if (val == null)
			{
				return;
			}
			StationUpgradeData data = Mod.Upgrades.GetData(((BuildableItem)val).GUID);
			if (data.QualityLevel > 0)
			{
				int qualityFloorValue = data.QualityFloorValue;
				if ((int)mixOperation.ProductQuality < qualityFloorValue)
				{
					mixOperation.ProductQuality = (EQuality)qualityFloorValue;
				}
			}
		}
	}
	[HarmonyPatch(typeof(ShopAmountSelector), "Open")]
	public static class ShopAmountSelectorOpenPatch
	{
		[HarmonyPostfix]
		public static void Postfix(ShopAmountSelector __instance)
		{
			MelonCoroutines.Start(ActivateNextFrame(__instance));
		}

		private static IEnumerator ActivateNextFrame(ShopAmountSelector selector)
		{
			yield return null;
			if ((Object)(object)selector != (Object)null && selector.IsOpen && (Object)(object)selector.InputField != (Object)null)
			{
				selector.InputField.ActivateInputField();
			}
		}
	}
	[HarmonyPatch(typeof(MixingStation), "GetMixTimeForCurrentOperation")]
	public static class SpeedPatch
	{
		[HarmonyPostfix]
		public static void Postfix(MixingStation __instance, ref int __result)
		{
			if (!(__instance is MixingStationMk2))
			{
				return;
			}
			StationUpgradeData data = Mod.Upgrades.GetData(((BuildableItem)__instance).GUID);
			if (data.SpeedLevel > 0)
			{
				if (data.IsInstantSpeed)
				{
					__result = 1;
				}
				else
				{
					__result = Mathf.Max(1, Mathf.RoundToInt((float)__result * data.SpeedMultiplier));
				}
			}
		}
	}
}
namespace UpgradeableMixStationMod.Items
{
	public static class PartSpawner
	{
		private const int SpawnsPerDay = 3;

		private static readonly List<DeadDrop> _trackedDrops = new List<DeadDrop>();

		private static bool _hooked;

		private static int _lastHintDay = -1;

		private static int _lastSpawnDay = -1;

		public static IReadOnlyList<DeadDrop> TrackedDrops => _trackedDrops;

		public static bool HasGivenHintToday => _lastHintDay == GetCurrentDay();

		public static void MarkHintGiven()
		{
			_lastHintDay = GetCurrentDay();
		}

		public static DeadDrop GetHintDrop()
		{
			if (_trackedDrops.Count == 0)
			{
				return null;
			}
			int index = GetCurrentDay() % _trackedDrops.Count;
			return _trackedDrops[index];
		}

		private static int GetCurrentDay()
		{
			try
			{
				return NetworkSingleton<TimeManager>.Instance.ElapsedDays;
			}
			catch
			{
				return 0;
			}
		}

		public static void Initialize()
		{
			if (_hooked)
			{
				return;
			}
			try
			{
				TimeManager instance = NetworkSingleton<TimeManager>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.onDayPass = (Action)Delegate.Combine(instance.onDayPass, new Action(OnNewDay));
					instance.onSleepEnd = (Action)Delegate.Combine(instance.onSleepEnd, new Action(OnNewDay));
					_hooked = true;
					OnNewDay();
				}
			}
			catch (Exception arg)
			{
				Melon<Mod>.Logger.Error($"PartSpawner init failed: {arg}");
			}
		}

		private static void OnNewDay()
		{
			int currentDay = GetCurrentDay();
			if (currentDay != _lastSpawnDay)
			{
				_lastSpawnDay = currentDay;
				CleanupOldCores();
				DistributeCores();
			}
		}

		private static void CleanupOldCores()
		{
			foreach (DeadDrop trackedDrop in _trackedDrops)
			{
				if ((Object)(object)trackedDrop == (Object)null || (Object)(object)trackedDrop.Storage == (Object)null)
				{
					continue;
				}
				try
				{
					List<ItemSlot> itemSlots = ((StorageEntity)trackedDrop.Storage).ItemSlots;
					if (itemSlots == null)
					{
						continue;
					}
					foreach (ItemSlot item in itemSlots)
					{
						if (((item != null) ? item.ItemInstance : null) != null && ((BaseItemInstance)item.ItemInstance).ID.ToLower() == "prototypecore")
						{
							item.ClearStoredInstance(false);
						}
					}
				}
				catch (Exception ex)
				{
					Melon<Mod>.Logger.Warning("Cleanup failed for drop: " + ex.Message);
				}
			}
			_trackedDrops.Clear();
		}

		private static void DistributeCores()
		{
			if ((Object)(object)UpgradeParts.PrototypeCore == (Object)null)
			{
				Melon<Mod>.Logger.Warning("PrototypeCore definition not registered yet.");
				return;
			}
			List<DeadDrop> list = DeadDrop.DeadDrops.Where((DeadDrop d) => (Object)(object)d != (Object)null && (Object)(object)d.Storage != (Object)null && ((StorageEntity)d.Storage).ItemCount == 0).ToList();
			if (list.Count == 0)
			{
				return;
			}
			for (int num = list.Count - 1; num > 0; num--)
			{
				int index = Random.Range(0, num + 1);
				DeadDrop value = list[num];
				list[num] = list[index];
				list[index] = value;
			}
			int num2 = 0;
			int num3 = Mathf.Min(3, list.Count);
			for (int i = 0; i < num3; i++)
			{
				DeadDrop val = list[i];
				try
				{
					List<ItemSlot> itemSlots = ((StorageEntity)val.Storage).ItemSlots;
					if (itemSlots != null)
					{
						ItemSlot val2 = ((IEnumerable<ItemSlot>)itemSlots).FirstOrDefault((Func<ItemSlot, bool>)((ItemSlot s) => s.ItemInstance == null));
						if (val2 != null)
						{
							ItemInstance defaultInstance = ((ItemDefinition)UpgradeParts.PrototypeCore).GetDefaultInstance(1);
							val2.SetStoredItem(defaultInstance, false);
							_trackedDrops.Add(val);
							num2++;
						}
					}
				}
				catch (Exception ex)
				{
					Melon<Mod>.Logger.Warning("Failed to place core in dead drop: " + ex.Message);
				}
			}
		}
	}
	public static class UpgradeParts
	{
		private static bool _registered;

		private static readonly string IconFolder = Path.Combine(Directory.GetCurrentDirectory(), "Mods", "UpgradeableMixStationMod", "Icons");

		public static PropertyItemDefinition MixingGear { get; private set; }

		public static PropertyItemDefinition PrecisionComponent { get; private set; }

		public static PropertyItemDefinition PrototypeCore { get; private set; }

		public static void Register()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			if (_registered)
			{
				return;
			}
			Registry instance = Singleton<Registry>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				Melon<Mod>.Logger.Error("Registry not found.");
				return;
			}
			PropertyItemDefinition item = Registry.GetItem<PropertyItemDefinition>("iodine");
			if ((Object)(object)item == (Object)null)
			{
				Melon<Mod>.Logger.Error("Could not find iodine template.");
				return;
			}
			MixingGear = CreatePart(item, instance, "mixinggear", "Mixing Gear", "MixingGear.png", new Color(0.5f, 0.7f, 0.9f));
			PrecisionComponent = CreatePart(item, instance, "precisioncomponent", "Precision Component", "PrecisionComponent.png", new Color(0.9f, 0.6f, 0.2f));
			PrototypeCore = CreatePart(item, instance, "prototypecore", "Prototype Core", "PrototypeCore.png", new Color(0.8f, 0.2f, 1f));
			_registered = true;
		}

		private static PropertyItemDefinition CreatePart(PropertyItemDefinition template, Registry registry, string id, string name, string iconFile, Color fallbackColor)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			PropertyItemDefinition val = Object.Instantiate<PropertyItemDefinition>(template);
			((Object)val).name = id;
			((BaseItemDefinition)val).Name = name;
			((BaseItemDefinition)val).ID = id;
			val.Properties = new List<Effect>();
			Sprite val2 = LoadIcon(iconFile);
			((BaseItemDefinition)val).Icon = val2 ?? GenerateFallbackIcon(fallbackColor);
			registry.AddToRegistry((ItemDefinition)(object)val);
			return val;
		}

		private static Sprite LoadIcon(string fileName)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string text = Path.Combine(IconFolder, fileName);
				if (!File.Exists(text))
				{
					Melon<Mod>.Logger.Warning("Icon not found: " + text + " — using fallback color.");
					return null;
				}
				byte[] array = File.ReadAllBytes(text);
				Texture2D val = new Texture2D(2, 2);
				ImageConversion.LoadImage(val, array);
				return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			}
			catch (Exception ex)
			{
				Melon<Mod>.Logger.Warning("Icon load failed: " + ex.Message);
				return null;
			}
		}

		private static Sprite GenerateFallbackIcon(Color color)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00de: 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)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			Color[] array = (Color[])(object)new Color[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					float num = Mathf.Abs((float)j - 31.5f);
					float num2 = Mathf.Abs((float)i - 31.5f);
					float num3 = Mathf.Sqrt(Mathf.Max(0f, num - 24f) * Mathf.Max(0f, num - 24f) + Mathf.Max(0f, num2 - 24f) * Mathf.Max(0f, num2 - 24f));
					float num4 = ((num3 <= 7f) ? 1f : 0f);
					float num5 = 0.85f + 0.15f * ((float)i / 64f);
					array[i * 64 + j] = new Color(color.r * num5, color.g * num5, color.b * num5, num4);
				}
			}
			val.SetPixels(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}
	}
}
namespace UpgradeableMixStationMod.Data
{
	[Serializable]
	public class ItemRequirement
	{
		public string ItemID;

		public int Amount;

		public string DisplayName;

		public ItemRequirement(string itemId, int amount, string displayName)
		{
			ItemID = itemId;
			Amount = amount;
			DisplayName = displayName;
		}
	}
	[Serializable]
	public class UpgradeTier
	{
		public string Name;

		public float Cost;

		public float Value;

		public string Description;

		public List<ItemRequirement> Items;

		public UpgradeTier(string name, float cost, float value, string description, List<ItemRequirement> items = null)
		{
			Name = name;
			Cost = cost;
			Value = value;
			Description = description;
			Items = items ?? new List<ItemRequirement>();
		}
	}
	public static class UpgradeConfig
	{
		public const string MixingGearID = "mixinggear";

		public const string PrecisionComponentID = "precisioncomponent";

		public const string PrototypeCoreID = "prototypecore";

		public static readonly List<UpgradeTier> SpeedTiers = new List<UpgradeTier>
		{
			new UpgradeTier("Quick Mix", 3000f, 0.8f, "80% of original time", new List<ItemRequirement>
			{
				new ItemRequirement("mixinggear", 2, "Mixing Gear")
			}),
			new UpgradeTier("Rapid Mix", 6000f, 0.6f, "60% of original time", new List<ItemRequirement>
			{
				new ItemRequirement("mixinggear", 3, "Mixing Gear"),
				new ItemRequirement("precisioncomponent", 1, "Precision Component")
			}),
			new UpgradeTier("Swift Mix", 8000f, 0.4f, "40% of original time", new List<ItemRequirement>
			{
				new ItemRequirement("mixinggear", 4, "Mixing Gear"),
				new ItemRequirement("precisioncomponent", 2, "Precision Component")
			}),
			new UpgradeTier("Blitz Mix", 10000f, 0.2f, "20% of original time", new List<ItemRequirement>
			{
				new ItemRequirement("precisioncomponent", 3, "Precision Component"),
				new ItemRequirement("prototypecore", 1, "Prototype Core")
			}),
			new UpgradeTier("Instant Mix", 20000f, 0f, "Completes in 1 minute", new List<ItemRequirement>
			{
				new ItemRequirement("precisioncomponent", 5, "Precision Component"),
				new ItemRequirement("prototypecore", 3, "Prototype Core")
			})
		};

		public static readonly List<UpgradeTier> QualityTiers = new List<UpgradeTier>
		{
			new UpgradeTier("Standard Floor", 5000f, 2f, "Minimum quality: Standard", new List<ItemRequirement>
			{
				new ItemRequirement("mixinggear", 3, "Mixing Gear"),
				new ItemRequirement("precisioncomponent", 1, "Precision Component")
			}),
			new UpgradeTier("Premium Floor", 12000f, 3f, "Minimum quality: Premium", new List<ItemRequirement>
			{
				new ItemRequirement("precisioncomponent", 4, "Precision Component"),
				new ItemRequirement("prototypecore", 1, "Prototype Core")
			}),
			new UpgradeTier("Heavenly Floor", 20000f, 4f, "Minimum quality: Heavenly", new List<ItemRequirement>
			{
				new ItemRequirement("precisioncomponent", 5, "Precision Component"),
				new ItemRequirement("prototypecore", 3, "Prototype Core")
			})
		};
	}
	[Serializable]
	public class StationUpgradeData
	{
		public int SpeedLevel;

		public int QualityLevel;

		public bool CanUpgradeSpeed => SpeedLevel < UpgradeConfig.SpeedTiers.Count;

		public bool IsInstantSpeed => SpeedLevel > 0 && UpgradeConfig.SpeedTiers[SpeedLevel - 1].Value == 0f;

		public float SpeedMultiplier => (SpeedLevel > 0) ? UpgradeConfig.SpeedTiers[SpeedLevel - 1].Value : 1f;

		public UpgradeTier NextSpeedTier => CanUpgradeSpeed ? UpgradeConfig.SpeedTiers[SpeedLevel] : null;

		public string CurrentSpeedName => (SpeedLevel > 0) ? UpgradeConfig.SpeedTiers[SpeedLevel - 1].Name : "None";

		public bool CanUpgradeQuality => QualityLevel < UpgradeConfig.QualityTiers.Count;

		public int QualityFloorValue => (QualityLevel > 0) ? ((int)UpgradeConfig.QualityTiers[QualityLevel - 1].Value) : 0;

		public UpgradeTier NextQualityTier => CanUpgradeQuality ? UpgradeConfig.QualityTiers[QualityLevel] : null;

		public string CurrentQualityName => (QualityLevel > 0) ? UpgradeConfig.QualityTiers[QualityLevel - 1].Name : "None";

		public StationUpgradeData()
		{
			SpeedLevel = 0;
			QualityLevel = 0;
		}
	}
	[Serializable]
	public class SaveFile
	{
		public Dictionary<string, StationUpgradeData> Stations = new Dictionary<string, StationUpgradeData>();
	}
	public class UpgradeManager
	{
		private const string FileName = "UpgradeableMixStationMod.json";

		private Dictionary<string, StationUpgradeData> _data = new Dictionary<string, StationUpgradeData>();

		public StationUpgradeData GetData(Guid stationGuid)
		{
			string key = stationGuid.ToString();
			if (!_data.TryGetValue(key, out var value))
			{
				value = new StationUpgradeData();
				_data[key] = value;
			}
			return value;
		}

		public bool HasRequiredItems(UpgradeTier tier)
		{
			PlayerInventory instance = PlayerSingleton<PlayerInventory>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			foreach (ItemRequirement item in tier.Items)
			{
				if (instance.GetAmountOfItem(item.ItemID) < item.Amount)
				{
					return false;
				}
			}
			return true;
		}

		public int GetPlayerItemCount(string itemID)
		{
			PlayerInventory instance = PlayerSingleton<PlayerInventory>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return 0;
			}
			return (int)instance.GetAmountOfItem(itemID);
		}

		public bool TryUpgradeSpeed(Guid stationGuid, out string failReason)
		{
			StationUpgradeData data = GetData(stationGuid);
			if (!data.CanUpgradeSpeed)
			{
				failReason = "Already at max level.";
				return false;
			}
			UpgradeTier nextSpeedTier = data.NextSpeedTier;
			if (!HasRequiredItems(nextSpeedTier))
			{
				failReason = "Missing required parts.";
				return false;
			}
			if (!TryDeductCash(nextSpeedTier.Cost, out failReason))
			{
				return false;
			}
			ConsumeItems(nextSpeedTier);
			data.SpeedLevel++;
			SaveNow();
			return true;
		}

		public bool TryUpgradeQuality(Guid stationGuid, out string failReason)
		{
			StationUpgradeData data = GetData(stationGuid);
			if (!data.CanUpgradeQuality)
			{
				failReason = "Already at max level.";
				return false;
			}
			UpgradeTier nextQualityTier = data.NextQualityTier;
			if (!HasRequiredItems(nextQualityTier))
			{
				failReason = "Missing required parts.";
				return false;
			}
			if (!TryDeductCash(nextQualityTier.Cost, out failReason))
			{
				return false;
			}
			ConsumeItems(nextQualityTier);
			data.QualityLevel++;
			SaveNow();
			return true;
		}

		private void ConsumeItems(UpgradeTier tier)
		{
			PlayerInventory instance = PlayerSingleton<PlayerInventory>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			foreach (ItemRequirement item in tier.Items)
			{
				for (int i = 0; i < item.Amount; i++)
				{
					instance.RemoveAmountOfItem(item.ItemID, 1u);
				}
			}
		}

		private bool TryDeductCash(float cost, out string failReason)
		{
			failReason = "";
			try
			{
				MoneyManager instance = NetworkSingleton<MoneyManager>.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					failReason = "Money system unavailable.";
					return false;
				}
				if (instance.cashBalance < cost)
				{
					failReason = "Not enough cash. Need " + MoneyManager.FormatAmount(cost, false, false) + ".";
					return false;
				}
				instance.ChangeCashBalance(0f - cost, true, false);
				return true;
			}
			catch (Exception arg)
			{
				failReason = "Error accessing money system.";
				Melon<Mod>.Logger.Error($"TryDeductCash failed: {arg}");
				return false;
			}
		}

		private void SaveNow()
		{
			try
			{
				LoadManager instance = Singleton<LoadManager>.Instance;
				string text = ((instance != null) ? instance.LoadedGameFolderPath : null);
				if (!string.IsNullOrEmpty(text))
				{
					Save(text);
				}
			}
			catch
			{
			}
		}

		public void Save(string saveFolderPath)
		{
			try
			{
				SaveFile saveFile = new SaveFile();
				foreach (KeyValuePair<string, StationUpgradeData> datum in _data)
				{
					if (datum.Value.SpeedLevel > 0 || datum.Value.QualityLevel > 0)
					{
						saveFile.Stations[datum.Key] = datum.Value;
					}
				}
				string path = Path.Combine(saveFolderPath, "UpgradeableMixStationMod.json");
				File.WriteAllText(path, JsonConvert.SerializeObject((object)saveFile, (Formatting)1));
			}
			catch (Exception arg)
			{
				Melon<Mod>.Logger.Error($"Failed to save: {arg}");
			}
		}

		public void Load(string saveFolderPath)
		{
			try
			{
				string path = Path.Combine(saveFolderPath, "UpgradeableMixStationMod.json");
				if (!File.Exists(path))
				{
					_data.Clear();
				}
				else
				{
					_data = JsonConvert.DeserializeObject<SaveFile>(File.ReadAllText(path))?.Stations ?? new Dictionary<string, StationUpgradeData>();
				}
			}
			catch (Exception arg)
			{
				Melon<Mod>.Logger.Error($"Failed to load: {arg}");
				_data.Clear();
			}
		}
	}
}