Decompiled source of Upgradeable Mix Station Mod v1.0.1

Upgradeable Mix Station Mod.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Text.RegularExpressions;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.UI.Stations;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Utils;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using UpgradeableMixStationMod;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(MixStationUpgradeMod), "Dom's Upgradeable Mix Station Mod", "1.0.0", "Dom", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonAdditionalDependencies(new string[] { "Unity.TextMeshPro" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Upgradeable Mix Station Mod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+499bca348101c88159c30d972122753e161c57e1")]
[assembly: AssemblyProduct("Upgradeable Mix Station Mod")]
[assembly: AssemblyTitle("Upgradeable Mix Station Mod")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace UpgradeableMixStationMod;

public static class BuildInfo
{
	public const string Name = "Dom's Upgradeable Mix Station Mod";

	public const string Description = "Adds upgrades to the Mixing Station Mk2";

	public const string Author = "Dom";

	public const string Version = "1.0.0";
}
public class StationUpgradeData
{
	public int Level = 1;

	public int Cost = 500;

	public bool Enhanced = false;

	public Text LevelText;

	public GameObject UpgradePanel;
}
public class GlobalUpgradeState
{
	public int Level { get; set; } = 1;


	public bool Enhanced { get; set; } = false;

}
public class MixStationUpgradeMod : MelonMod
{
	public static Dictionary<MixingStationCanvas, StationUpgradeData> stationData = new Dictionary<MixingStationCanvas, StationUpgradeData>();

	private static readonly string SavePath = Path.Combine(MelonEnvironment.UserDataDirectory, "MixStationUpgradeSave.json");

	private static GlobalUpgradeState globalState = new GlobalUpgradeState();

	public override void OnInitializeMelon()
	{
		LoadUpgradeData();
		MelonLogger.Msg("Dom's Upgradeable Mix Station Mod loaded.");
	}

	public static void SaveUpgradeData()
	{
		try
		{
			string contents = JsonSerializer.Serialize(globalState, new JsonSerializerOptions
			{
				WriteIndented = true
			});
			File.WriteAllText(SavePath, contents);
			MelonLogger.Msg("[Save] Upgrade data saved.");
		}
		catch (Exception value)
		{
			MelonLogger.Error($"[Save] Failed to save upgrade data: {value}");
		}
	}

	public static void LoadUpgradeData()
	{
		try
		{
			if (File.Exists(SavePath))
			{
				string json = File.ReadAllText(SavePath);
				globalState = JsonSerializer.Deserialize<GlobalUpgradeState>(json) ?? new GlobalUpgradeState();
				MelonLogger.Msg($"[Load] Loaded upgrade level {globalState.Level}, enhanced: {globalState.Enhanced}");
			}
			else
			{
				MelonLogger.Msg("[Load] No saved data found. Using defaults.");
			}
		}
		catch (Exception value)
		{
			MelonLogger.Error($"[Load] Failed to load upgrade data: {value}");
		}
	}

	public static void Upgrade(MixingStationCanvas stationCanvas)
	{
		if (!stationData.TryGetValue(stationCanvas, out var value))
		{
			return;
		}
		float cashBalance = NetworkSingleton<MoneyManager>.Instance.cashBalance;
		if (cashBalance < (float)value.Cost)
		{
			MelonLogger.Msg("[Upgrade] Not enough money.");
			return;
		}
		NetworkSingleton<MoneyManager>.Instance.ChangeCashBalance((float)(-value.Cost), true, true);
		value.Level++;
		globalState.Level = value.Level;
		SaveUpgradeData();
		if (value.Level == 5)
		{
			value.Cost = 30000;
			UpdateUIToEnhance(value, stationCanvas);
		}
		else
		{
			value.Cost *= 2;
			UpdateLevelText(value);
		}
		MelonLogger.Msg($"[Upgrade] Upgraded to level {value.Level}");
	}

	public static void Enhance(MixingStationCanvas stationCanvas, bool fromLoad = false)
	{
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		if (!stationData.TryGetValue(stationCanvas, out var value))
		{
			return;
		}
		if (value.Enhanced && !fromLoad)
		{
			MelonLogger.Msg("[Enhance] Already enhanced.");
			return;
		}
		value.Enhanced = true;
		globalState.Enhanced = true;
		Button componentInChildren = value.UpgradePanel.GetComponentInChildren<Button>();
		Text componentInChildren2 = ((Component)componentInChildren).GetComponentInChildren<Text>();
		if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren2 != (Object)null)
		{
			componentInChildren2.text = "Max Level";
			((Selectable)componentInChildren).interactable = false;
			Image component = ((Component)componentInChildren).GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).color = new Color(0.75f, 0.75f, 0.75f, 0.5f);
			}
		}
		if ((Object)(object)value.LevelText != (Object)null)
		{
			value.LevelText.text = "Mixing Table: Enhanced";
		}
		if (fromLoad)
		{
			SaveUpgradeData();
			MelonLogger.Msg("[Enhance] Enhancement complete (loaded state).");
		}
		else
		{
			MelonLogger.Msg("[Enhance] Enhancement complete.");
		}
	}

	public static void CreateLevelUI(MixingStationCanvas stationCanvas)
	{
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Expected O, but got Unknown
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: 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_0119: 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_0130: Expected O, but got Unknown
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Expected O, but got Unknown
		//IL_01fb: 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_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Expected O, but got Unknown
		//IL_0297: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0334: Unknown result type (might be due to invalid IL or missing references)
		if (stationData.ContainsKey(stationCanvas))
		{
			return;
		}
		StationUpgradeData stationUpgradeData = new StationUpgradeData
		{
			Level = globalState.Level,
			Enhanced = globalState.Enhanced,
			Cost = ((globalState.Level >= 5) ? 30000 : (500 * (int)Mathf.Pow(2f, (float)(globalState.Level - 1))))
		};
		Transform transform = ((Component)stationCanvas).transform;
		GameObject val = (stationUpgradeData.UpgradePanel = new GameObject("UpgradePanel"));
		val.transform.SetParent(transform, false);
		RectTransform val2 = val.AddComponent<RectTransform>();
		val2.sizeDelta = new Vector2(260f, 130f);
		((Transform)val2).localPosition = new Vector3(-400f, 0f, 0f);
		((Graphic)val.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.6f);
		((Shadow)val.AddComponent<Outline>()).effectColor = Color.white;
		GameObject val3 = new GameObject("LevelText");
		val3.transform.SetParent(val.transform, false);
		Text val4 = val3.AddComponent<Text>();
		val4.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
		val4.fontSize = 18;
		val4.alignment = (TextAnchor)4;
		stationUpgradeData.LevelText = val4;
		UpdateLevelText(stationUpgradeData);
		RectTransform component = val3.GetComponent<RectTransform>();
		component.anchoredPosition = new Vector2(0f, 30f);
		component.sizeDelta = new Vector2(240f, 50f);
		GameObject val5 = new GameObject("UpgradeButton");
		val5.transform.SetParent(val.transform, false);
		Button val6 = val5.AddComponent<Button>();
		Image val7 = val5.AddComponent<Image>();
		((Graphic)val7).color = new Color(0.85f, 0.85f, 0.85f);
		RectTransform component2 = val5.GetComponent<RectTransform>();
		component2.anchoredPosition = new Vector2(0f, -25f);
		component2.sizeDelta = new Vector2(180f, 45f);
		GameObject val8 = new GameObject("ButtonText");
		val8.transform.SetParent(val5.transform, false);
		Text val9 = val8.AddComponent<Text>();
		val9.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
		val9.fontSize = 18;
		val9.alignment = (TextAnchor)4;
		RectTransform component3 = val8.GetComponent<RectTransform>();
		component3.anchoredPosition = Vector2.zero;
		component3.sizeDelta = component2.sizeDelta;
		if (stationUpgradeData.Level == 5 && !stationUpgradeData.Enhanced)
		{
			val9.text = "Enhance";
			((UnityEvent)val6.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				Enhance(stationCanvas);
			}));
		}
		else if (stationUpgradeData.Enhanced)
		{
			val9.text = "Max Level";
			((Selectable)val6).interactable = false;
			((Graphic)val7).color = new Color(0.75f, 0.75f, 0.75f, 0.5f);
		}
		else
		{
			val9.text = "Upgrade";
			((UnityEvent)val6.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				Upgrade(stationCanvas);
			}));
		}
		stationData[stationCanvas] = stationUpgradeData;
	}

	private static void UpdateLevelText(StationUpgradeData data)
	{
		if ((Object)(object)data.LevelText != (Object)null)
		{
			data.LevelText.text = $"Mixing Table Level: {data.Level}\nNext Upgrade: ${data.Cost}";
		}
	}

	private static void UpdateUIToEnhance(StationUpgradeData data, MixingStationCanvas stationCanvas)
	{
		UpdateLevelText(data);
		Button componentInChildren = data.UpgradePanel.GetComponentInChildren<Button>();
		Text componentInChildren2 = ((Component)componentInChildren).GetComponentInChildren<Text>();
		if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren2 != (Object)null)
		{
			componentInChildren2.text = "Enhance";
			((UnityEventBase)componentInChildren.onClick).RemoveAllListeners();
			((UnityEvent)componentInChildren.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				Enhance(stationCanvas);
			}));
		}
	}
}
[HarmonyPatch(typeof(MixingStationCanvas), "Start")]
public class MixingStationCanvas_Start_Patch
{
	public static void Postfix(MixingStationCanvas __instance)
	{
		MixStationUpgradeMod.CreateLevelUI(__instance);
	}
}
[HarmonyPatch(typeof(MixingStationMk2), "MixingStart")]
public class MixingStationMk2_MixingStart_Patch
{
	public static void Postfix(MixingStationMk2 __instance)
	{
		MixingStationCanvas[] array = Il2CppArrayBase<MixingStationCanvas>.op_Implicit(Object.FindObjectsOfType<MixingStationCanvas>());
		StationUpgradeData stationUpgradeData = null;
		MixingStationCanvas[] array2 = array;
		foreach (MixingStationCanvas val in array2)
		{
			if ((Object)(object)val.MixingStation == (Object)(object)__instance && MixStationUpgradeMod.stationData.TryGetValue(val, out var value))
			{
				stationUpgradeData = value;
				break;
			}
		}
		if (stationUpgradeData == null)
		{
			MelonLogger.Warning("[MixingStart Patch] No upgrade data found. Using default timing.");
			return;
		}
		int result = 0;
		TextMeshProUGUI quantityLabel = __instance.QuantityLabel;
		string text = ((quantityLabel != null) ? ((TMP_Text)quantityLabel).text : null);
		if (!string.IsNullOrEmpty(text))
		{
			string value2 = Regex.Match(text, "\\d+").Value;
			int.TryParse(value2, out result);
		}
		if (result <= 0)
		{
			MelonLogger.Warning("[MixingStart Patch] Invalid quantity. Aborting.");
			return;
		}
		int num = Mathf.Clamp(stationUpgradeData.Level, 1, 5);
		float num2 = 3f - (float)(num - 1) * 0.5f;
		float num3 = (stationUpgradeData.Enhanced ? 1f : ((float)result * num2));
		TextMeshProUGUI progressLabel = __instance.ProgressLabel;
		if ((Object)(object)progressLabel != (Object)null)
		{
			((TMP_Text)progressLabel).text = $"{num3:0.#}s remaining";
		}
		MelonCoroutines.Start(FinishEarly(__instance, num3));
		MelonLogger.Msg($"[MixingStart Patch] Mix of {result} will finish in {num3}s (Level {num})");
	}

	private static IEnumerator FinishEarly(MixingStationMk2 station, float totalTime)
	{
		float elapsed = 0f;
		TextMeshProUGUI progressLabel = station.ProgressLabel;
		while (elapsed < totalTime)
		{
			float remaining = Mathf.Max(0f, totalTime - elapsed);
			string display = $"{remaining:0.#}s remaining";
			if ((Object)(object)progressLabel != (Object)null)
			{
				((TMP_Text)progressLabel).text = display;
			}
			elapsed += Time.deltaTime;
			yield return null;
		}
		((MixingStation)station).MixingDone();
		if ((Object)(object)progressLabel != (Object)null)
		{
			((TMP_Text)progressLabel).text = "Mixing Complete!";
		}
		MelonLogger.Msg("[MixingStart Patch] MixingDone() called early.");
	}
}