Decompiled source of OverTheCounter v1.0.4

OverTheCounter.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using HarmonyLib;
using Il2CppFishNet;
using Il2CppFishNet.Object;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne.AvatarFramework;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Economy;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Map;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.Persistence.Datas;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Product.Packaging;
using Il2CppScheduleOne.Quests;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.Compass;
using Il2CppScheduleOne.UI.Handover;
using Il2CppScheduleOne.UI.Phone.Map;
using Il2CppScheduleOne.VoiceOver;
using Il2CppSteamworks;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using OverTheCounter;
using OverTheCounter.Apps;
using OverTheCounter.Logic;
using OverTheCounter.NPCs;
using OverTheCounter.Patches;
using OverTheCounter.Quests;
using OverTheCounter.SaveData;
using OverTheCounter.UI;
using OverTheCounter.Utilities;
using S1API.Entities;
using S1API.Entities.Appearances.AccessoryFields;
using S1API.Entities.Appearances.BodyLayerFields;
using S1API.Entities.Appearances.CustomizationFields;
using S1API.Entities.Appearances.FaceLayerFields;
using S1API.Entities.Dialogue;
using S1API.Entities.Schedule;
using S1API.GameTime;
using S1API.Internal.Abstraction;
using S1API.Items;
using S1API.Messaging;
using S1API.Money;
using S1API.PhoneApp;
using S1API.Products;
using S1API.Quests;
using S1API.Quests.Identifiers;
using S1API.Saveables;
using S1API.UI;
using S1API.Utils;
using SteamNetworkLib;
using SteamNetworkLib.Sync;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "OverTheCounter", "1.0.3", "hdlmrell", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("OverTheCounter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+4fdbedd7fe3a9c7a60932d8fde5f456b84f5c1d3")]
[assembly: AssemblyProduct("OverTheCounter")]
[assembly: AssemblyTitle("OverTheCounter")]
[assembly: NeutralResourcesLanguage("en-US")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 OverTheCounter
{
	public class Core : MelonMod
	{
		private NotificationManager _notificationManager;

		private DesperationManager _desperationManager;

		public override void OnInitializeMelon()
		{
			Config.Initialize();
			ConfigSyncPatch.TryApply(((MelonBase)this).HarmonyInstance);
			((MelonBase)this).LoggerInstance.Msg("OverTheCounter Initialized.");
			ImmediateQuestWindowConfig.Register();
			ExtractIcons();
			_notificationManager = new NotificationManager(((MelonBase)this).LoggerInstance);
			_desperationManager = new DesperationManager(((MelonBase)this).LoggerInstance);
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			StaticSaveData.ResetInstance();
			VicSaveData.ResetInstance();
		}

		public override void OnLateUpdate()
		{
			try
			{
				ConfigSyncData.EnsureNetworkReady();
				ConfigSyncData.ProcessMessages();
				CustomersApp.Instance?.UpdateIconVisibility();
				_notificationManager.ProcessContractState();
				VicSaveData.Instance?.Tick();
				StaticSaveData.Instance?.Tick();
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("Error in OnLateUpdate: " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		public override void OnDeinitializeMelon()
		{
			ConfigSyncData.Cleanup();
			_notificationManager?.Cleanup();
			_desperationManager?.Cleanup();
		}

		private void ExtractIcons()
		{
			string text = Path.Combine(MelonEnvironment.UserDataDirectory, "S1API", "Icons");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			ExtractResource(text, "CustomersIcon.png");
			ExtractResource(text, "RinseCycle.png");
		}

		private void ExtractResource(string directory, string fileName)
		{
			string path = Path.Combine(directory, fileName);
			if (File.Exists(path))
			{
				return;
			}
			((MelonBase)this).LoggerInstance.Msg("Extracting " + fileName + "...");
			string text = "OverTheCounter.Resources." + fileName;
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text);
			if (stream != null)
			{
				using (FileStream destination = new FileStream(path, FileMode.Create, FileAccess.Write))
				{
					stream.CopyTo(destination);
				}
				((MelonBase)this).LoggerInstance.Msg(fileName + " extracted successfully.");
			}
			else
			{
				((MelonBase)this).LoggerInstance.Error("Could not find embedded resource '" + text + "'.");
			}
		}
	}
	public static class Config
	{
		private static MelonPreferences_Category _desperation;

		public static ConfigEntry<float> FiendAddictionThreshold;

		public static ConfigEntry<float> TriggerChancePerHour;

		public static ConfigEntry<int> MaxEventsPerDay;

		public static ConfigEntry<int> ResponseDeadlineMinutes;

		public static ConfigEntry<int> DeadlineMinutes;

		public static ConfigEntry<float> BonusMultiplier;

		public static ConfigEntry<float> RelationshipPenalty;

		public static ConfigEntry<int> CooldownMinutes;

		public static ConfigEntry<int> DayStartHour;

		public static ConfigEntry<int> DayEndHour;

		private static MelonPreferences_Category _laundering;

		public static ConfigEntry<float> VicTier1Cost;

		public static ConfigEntry<float> VicTier1Return;

		public static ConfigEntry<int> VicTier2TrustUnlock;

		public static ConfigEntry<float> VicTier2Cost;

		public static ConfigEntry<float> VicTier2Return;

		public static ConfigEntry<int> VicIntroWeedGrams;

		private static MelonPreferences_Category _subscription;

		public static ConfigEntry<float> SaasWeeklyCost;

		public static ConfigEntry<int> SaasCycleDays;

		public static ConfigEntry<float> AtmDepositTrigger;

		public static ConfigEntry<float> StaticTier1BankCost;

		public static ConfigEntry<int> StaticTier1WeedGrams;

		public static ConfigEntry<float> StaticTier2BankCost;

		public static ConfigEntry<int> StaticTier2MethGrams;

		public static ConfigEntry<float> StaticTier3BankCost;

		public static ConfigEntry<int> StaticTier3PremiumMethGrams;

		private static MelonPreferences_Category _notifications;

		public static ConfigEntry<int> ConsolidationThreshold;

		private static readonly Dictionary<string, ConfigEntry<float>> _floatEntries = new Dictionary<string, ConfigEntry<float>>();

		private static readonly Dictionary<string, ConfigEntry<int>> _intEntries = new Dictionary<string, ConfigEntry<int>>();

		private static readonly HashSet<string> _localOnlyKeys = new HashSet<string> { "ConsolidationThreshold" };

		public static void Initialize()
		{
			_desperation = MelonPreferences.CreateCategory("OverTheCounter", "Desperation System");
			FiendAddictionThreshold = Register(_desperation.CreateEntry<float>("FiendAddictionThreshold", 0.67f, "Fiend Addiction Threshold", "Addiction level required to qualify as a Fiend (0.0–1.0)", false, false, (ValueValidator)null, (string)null));
			TriggerChancePerHour = Register(_desperation.CreateEntry<float>("TriggerChancePerHour", 0.12f, "Trigger Chance Per Hour", "Probability of a desperation event each hour (0.0–1.0)", false, false, (ValueValidator)null, (string)null));
			MaxEventsPerDay = Register(_desperation.CreateEntry<int>("MaxEventsPerDay", 3, "Max Events Per Day", "Hard cap on desperation events per day", false, false, (ValueValidator)null, (string)null));
			ResponseDeadlineMinutes = Register(_desperation.CreateEntry<int>("ResponseDeadlineMinutes", 60, "Response Deadline (min)", "In-game minutes the player has to respond to a desperation offer", false, false, (ValueValidator)null, (string)null));
			DeadlineMinutes = Register(_desperation.CreateEntry<int>("DeadlineMinutes", 120, "Delivery Deadline (min)", "In-game minutes to deliver after accepting a desperation contract", false, false, (ValueValidator)null, (string)null));
			BonusMultiplier = Register(_desperation.CreateEntry<float>("BonusMultiplier", 0.45f, "Bonus Multiplier", "Extra payment multiplier for desperation deliveries (0.45 = 45%)", false, false, (ValueValidator)null, (string)null));
			RelationshipPenalty = Register(_desperation.CreateEntry<float>("RelationshipPenalty", -15f, "Relationship Penalty", "Relationship change on failed desperation event", false, false, (ValueValidator)null, (string)null));
			CooldownMinutes = Register(_desperation.CreateEntry<int>("CooldownMinutes", 1440, "Cooldown (min)", "Minutes a customer is locked out after a failed event (1440 = 24h)", false, false, (ValueValidator)null, (string)null));
			DayStartHour = Register(_desperation.CreateEntry<int>("DayStartHour", 800, "Day Start Hour", "Earliest 24h time for desperation rolls (800 = 8:00 AM)", false, false, (ValueValidator)null, (string)null));
			DayEndHour = Register(_desperation.CreateEntry<int>("DayEndHour", 2100, "Day End Hour", "Latest 24h time for desperation rolls (2100 = 9:00 PM)", false, false, (ValueValidator)null, (string)null));
			_laundering = MelonPreferences.CreateCategory("OverTheCounter_Laundering", "Vic Laundering");
			VicTier1Cost = Register(_laundering.CreateEntry<float>("VicTier1Cost", 500f, "Tier 1 Cost", "Cash required for tier-1 laundering", false, false, (ValueValidator)null, (string)null));
			VicTier1Return = Register(_laundering.CreateEntry<float>("VicTier1Return", 400f, "Tier 1 Return", "Clean money returned for tier-1 laundering", false, false, (ValueValidator)null, (string)null));
			VicTier2TrustUnlock = Register(_laundering.CreateEntry<int>("VicTier2TrustUnlock", 7, "Tier 2 Trust Unlock", "Trust level required to unlock tier-2 laundering", false, false, (ValueValidator)null, (string)null));
			VicTier2Cost = Register(_laundering.CreateEntry<float>("VicTier2Cost", 900f, "Tier 2 Cost", "Cash required for tier-2 laundering", false, false, (ValueValidator)null, (string)null));
			VicTier2Return = Register(_laundering.CreateEntry<float>("VicTier2Return", 750f, "Tier 2 Return", "Clean money returned for tier-2 laundering", false, false, (ValueValidator)null, (string)null));
			VicIntroWeedGrams = Register(_laundering.CreateEntry<int>("VicIntroWeedGrams", 40, "Intro Quest Weed Grams", "Grams of weed required to complete Vic's intro quest", false, false, (ValueValidator)null, (string)null));
			_subscription = MelonPreferences.CreateCategory("OverTheCounter_Subscription", "Static Subscription");
			SaasWeeklyCost = Register(_subscription.CreateEntry<float>("SaasWeeklyCost", 1000f, "Weekly Cost", "Bank balance deducted each billing cycle", false, false, (ValueValidator)null, (string)null));
			SaasCycleDays = Register(_subscription.CreateEntry<int>("SaasCycleDays", 7, "Cycle Days", "Number of days between subscription payments", false, false, (ValueValidator)null, (string)null));
			AtmDepositTrigger = Register(_subscription.CreateEntry<float>("AtmDepositTrigger", 5000f, "ATM Deposit Trigger", "Weekly ATM deposit sum that triggers Static's intro quest", false, false, (ValueValidator)null, (string)null));
			StaticTier1BankCost = Register(_subscription.CreateEntry<float>("StaticTier1BankCost", 3000f, "Tier 1 Bank Cost", "Bank transfer cost for the initial software package", false, false, (ValueValidator)null, (string)null));
			StaticTier1WeedGrams = Register(_subscription.CreateEntry<int>("StaticTier1WeedGrams", 20, "Tier 1 Weed Grams", "Grams of weed required for the initial package", false, false, (ValueValidator)null, (string)null));
			StaticTier2BankCost = Register(_subscription.CreateEntry<float>("StaticTier2BankCost", 6000f, "Tier 2 Bank Cost", "Bank transfer cost for the Premium upgrade", false, false, (ValueValidator)null, (string)null));
			StaticTier2MethGrams = Register(_subscription.CreateEntry<int>("StaticTier2MethGrams", 5, "Tier 2 Meth Grams", "Grams of meth required for the Premium upgrade", false, false, (ValueValidator)null, (string)null));
			StaticTier3BankCost = Register(_subscription.CreateEntry<float>("StaticTier3BankCost", 12000f, "Tier 3 Bank Cost", "Bank transfer cost for the Enterprise upgrade", false, false, (ValueValidator)null, (string)null));
			StaticTier3PremiumMethGrams = Register(_subscription.CreateEntry<int>("StaticTier3PremiumMethGrams", 10, "Tier 3 Premium Meth Grams", "Grams of premium meth required for Enterprise upgrade", false, false, (ValueValidator)null, (string)null));
			_notifications = MelonPreferences.CreateCategory("OverTheCounter_Notifications", "Contract Notifications");
			ConsolidationThreshold = Register(_notifications.CreateEntry<int>("ConsolidationThreshold", 5, "Consolidation Threshold", "Minimum contracts in a window before consolidation kicks in", false, false, (ValueValidator)null, (string)null));
		}

		private static ConfigEntry<float> Register(MelonPreferences_Entry<float> entry)
		{
			ConfigEntry<float> configEntry = new ConfigEntry<float>(entry);
			_floatEntries[((MelonPreferences_Entry)entry).Identifier] = configEntry;
			return configEntry;
		}

		private static ConfigEntry<int> Register(MelonPreferences_Entry<int> entry)
		{
			ConfigEntry<int> configEntry = new ConfigEntry<int>(entry);
			_intEntries[((MelonPreferences_Entry)entry).Identifier] = configEntry;
			return configEntry;
		}

		public static string SerializeAll()
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, ConfigEntry<float>> floatEntry in _floatEntries)
			{
				if (!_localOnlyKeys.Contains(floatEntry.Key))
				{
					list.Add(floatEntry.Key + "=" + floatEntry.Value.RawEntry.Value.ToString(CultureInfo.InvariantCulture));
				}
			}
			foreach (KeyValuePair<string, ConfigEntry<int>> intEntry in _intEntries)
			{
				if (!_localOnlyKeys.Contains(intEntry.Key))
				{
					list.Add(intEntry.Key + "=" + intEntry.Value.RawEntry.Value.ToString(CultureInfo.InvariantCulture));
				}
			}
			return string.Join("|", list);
		}

		public static void ApplyOverrides(Dictionary<string, string> data)
		{
			foreach (KeyValuePair<string, string> datum in data)
			{
				if (_localOnlyKeys.Contains(datum.Key))
				{
					continue;
				}
				ConfigEntry<int> value2;
				int result2;
				if (_floatEntries.TryGetValue(datum.Key, out var value))
				{
					if (float.TryParse(datum.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
					{
						value.SetOverride(result);
					}
				}
				else if (_intEntries.TryGetValue(datum.Key, out value2) && int.TryParse(datum.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result2))
				{
					value2.SetOverride(result2);
				}
			}
		}

		public static void ClearAllOverrides()
		{
			foreach (ConfigEntry<float> value in _floatEntries.Values)
			{
				value.ClearOverride();
			}
			foreach (ConfigEntry<int> value2 in _intEntries.Values)
			{
				value2.ClearOverride();
			}
		}
	}
}
namespace OverTheCounter.Quests
{
	public class VicIntroQuest : Quest
	{
		private static readonly Instance Logger = new Instance("VicIntroQuest");

		[SaveableField("vic_quest_stage")]
		private int _stage;

		private QuestEntry _meetVicEntry;

		private QuestEntry _bringWeedEntry;

		private static readonly Vector3 VicPosition = new Vector3(72.08f, 0.97f, 31.71f);

		protected override string Title => "Rinse Cycle";

		protected override string Description => "Help Vic with his party supplies and he'll loosen your deposit limits.";

		protected override bool AutoBegin => false;

		protected override Sprite QuestIcon => ImageUtils.LoadImage(Path.Combine(MelonEnvironment.UserDataDirectory, "S1API", "Icons", "RinseCycle.png"));

		public static VicIntroQuest Instance { get; private set; }

		public int Stage => _stage;

		private void TriggerInternalInit()
		{
			try
			{
				FieldInfo field = typeof(Quest).GetField("S1Quest", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(field == null))
				{
					object? value = field.GetValue(this);
					Quest val = (Quest)((value is Quest) ? value : null);
					if (!((Object)(object)val == (Object)null))
					{
						val.InitializeQuest(((Quest)this).Title, ((Quest)this).Description, Il2CppReferenceArray<QuestEntryData>.op_Implicit(Array.Empty<QuestEntryData>()), val.StaticGUID);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TriggerInternalInit failed: " + ex.Message);
			}
		}

		public void Initialize()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				TriggerInternalInit();
				_meetVicEntry = ((Quest)this).AddEntry("Meet Vic in the alleyway behind the bank", (Vector3?)VicPosition);
				_bringWeedEntry = ((Quest)this).AddEntry(GetWeedText(), (Vector3?)VicPosition);
			}
			catch (Exception ex)
			{
				Logger.Error("Initialize failed: " + ex.Message);
			}
		}

		private static string GetWeedText()
		{
			return $"Bring Vic {Config.VicIntroWeedGrams.Value} grams of weed";
		}

		public void RefreshEntryText()
		{
			if (_bringWeedEntry != null && _stage >= 1 && _stage < 3)
			{
				_bringWeedEntry.Title = GetWeedText();
			}
		}

		public void StartQuest()
		{
			try
			{
				_stage = 1;
				((Quest)this).Begin();
				QuestEntry meetVicEntry = _meetVicEntry;
				if (meetVicEntry != null)
				{
					meetVicEntry.Begin();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("StartQuest failed: " + ex.Message);
			}
		}

		public void CompleteObj1()
		{
			try
			{
				_stage = 2;
				QuestEntry meetVicEntry = _meetVicEntry;
				if (meetVicEntry != null)
				{
					meetVicEntry.Complete();
				}
				QuestEntry bringWeedEntry = _bringWeedEntry;
				if (bringWeedEntry != null)
				{
					bringWeedEntry.Begin();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("CompleteObj1 failed: " + ex.Message);
			}
		}

		public void CompleteObj2()
		{
			try
			{
				_stage = 3;
				QuestEntry bringWeedEntry = _bringWeedEntry;
				if (bringWeedEntry != null)
				{
					bringWeedEntry.Complete();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("CompleteObj2 failed: " + ex.Message);
			}
		}

		protected override void OnCreated()
		{
			((Registerable)this).OnCreated();
			Instance = this;
		}

		protected override void OnLoaded()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			((Saveable)this).OnLoaded();
			Instance = this;
			try
			{
				base.QuestEntries.Clear();
				_meetVicEntry = ((Quest)this).AddEntry("Meet Vic in the alleyway behind the bank", (Vector3?)VicPosition);
				_bringWeedEntry = ((Quest)this).AddEntry(GetWeedText(), (Vector3?)VicPosition);
				if (_stage >= 1)
				{
					QuestEntry meetVicEntry = _meetVicEntry;
					if (meetVicEntry != null)
					{
						meetVicEntry.Begin();
					}
				}
				if (_stage >= 2)
				{
					QuestEntry meetVicEntry2 = _meetVicEntry;
					if (meetVicEntry2 != null)
					{
						meetVicEntry2.Complete();
					}
					QuestEntry bringWeedEntry = _bringWeedEntry;
					if (bringWeedEntry != null)
					{
						bringWeedEntry.Begin();
					}
				}
				if (_stage >= 3)
				{
					QuestEntry bringWeedEntry2 = _bringWeedEntry;
					if (bringWeedEntry2 != null)
					{
						bringWeedEntry2.Complete();
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("OnLoaded rebuild failed: " + ex.Message);
			}
		}
	}
	public class StaticIntroQuest : Quest
	{
		private static readonly Instance Logger = new Instance("StaticIntroQuest");

		[SaveableField("static_quest_stage")]
		private int _stage;

		private QuestEntry _talkToStaticEntry;

		private QuestEntry _bringSuppliesEntry;

		private static readonly Vector3 StaticPosition = new Vector3(13.72f, 5.16f, 95.96f);

		protected override string Title => "Crimeware as a Service";

		protected override string Description => "Someone at the casino noticed your deposits. Find Static after 4 PM when the casino opens.";

		protected override bool AutoBegin => false;

		protected override Sprite QuestIcon => ImageUtils.LoadImage(Path.Combine(MelonEnvironment.UserDataDirectory, "S1API", "Icons", "RinseCycle.png"));

		public static StaticIntroQuest Instance { get; private set; }

		public int Stage => _stage;

		private void TriggerInternalInit()
		{
			try
			{
				FieldInfo field = typeof(Quest).GetField("S1Quest", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(field == null))
				{
					object? value = field.GetValue(this);
					Quest val = (Quest)((value is Quest) ? value : null);
					if (!((Object)(object)val == (Object)null))
					{
						val.InitializeQuest(((Quest)this).Title, ((Quest)this).Description, Il2CppReferenceArray<QuestEntryData>.op_Implicit(Array.Empty<QuestEntryData>()), val.StaticGUID);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TriggerInternalInit failed: " + ex.Message);
			}
		}

		public void Initialize()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				TriggerInternalInit();
				_talkToStaticEntry = ((Quest)this).AddEntry("Talk to Static in the casino after 4 PM", (Vector3?)StaticPosition);
				_bringSuppliesEntry = ((Quest)this).AddEntry(GetSuppliesText(), (Vector3?)StaticPosition);
			}
			catch (Exception ex)
			{
				Logger.Error("Initialize failed: " + ex.Message);
			}
		}

		private static string GetSuppliesText()
		{
			return $"Bring Static ${Config.StaticTier1BankCost.Value:N0} and {Config.StaticTier1WeedGrams.Value} grams of weed";
		}

		public void RefreshEntryText()
		{
			if (_bringSuppliesEntry != null && _stage >= 1 && _stage < 3)
			{
				_bringSuppliesEntry.Title = GetSuppliesText();
			}
		}

		public void StartQuest()
		{
			try
			{
				_stage = 1;
				((Quest)this).Begin();
				QuestEntry talkToStaticEntry = _talkToStaticEntry;
				if (talkToStaticEntry != null)
				{
					talkToStaticEntry.Begin();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("StartQuest failed: " + ex.Message);
			}
		}

		public void CompleteObj1()
		{
			try
			{
				_stage = 2;
				QuestEntry talkToStaticEntry = _talkToStaticEntry;
				if (talkToStaticEntry != null)
				{
					talkToStaticEntry.Complete();
				}
				QuestEntry bringSuppliesEntry = _bringSuppliesEntry;
				if (bringSuppliesEntry != null)
				{
					bringSuppliesEntry.Begin();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("CompleteObj1 failed: " + ex.Message);
			}
		}

		public void CompleteObj2()
		{
			try
			{
				_stage = 3;
				QuestEntry bringSuppliesEntry = _bringSuppliesEntry;
				if (bringSuppliesEntry != null)
				{
					bringSuppliesEntry.Complete();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("CompleteObj2 failed: " + ex.Message);
			}
		}

		protected override void OnCreated()
		{
			((Registerable)this).OnCreated();
			Instance = this;
		}

		protected override void OnLoaded()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			((Saveable)this).OnLoaded();
			Instance = this;
			try
			{
				base.QuestEntries.Clear();
				_talkToStaticEntry = ((Quest)this).AddEntry("Talk to Static in the casino after 4 PM", (Vector3?)StaticPosition);
				_bringSuppliesEntry = ((Quest)this).AddEntry(GetSuppliesText(), (Vector3?)StaticPosition);
				if (_stage >= 1)
				{
					QuestEntry talkToStaticEntry = _talkToStaticEntry;
					if (talkToStaticEntry != null)
					{
						talkToStaticEntry.Begin();
					}
				}
				if (_stage >= 2)
				{
					QuestEntry talkToStaticEntry2 = _talkToStaticEntry;
					if (talkToStaticEntry2 != null)
					{
						talkToStaticEntry2.Complete();
					}
					QuestEntry bringSuppliesEntry = _bringSuppliesEntry;
					if (bringSuppliesEntry != null)
					{
						bringSuppliesEntry.Begin();
					}
				}
				if (_stage >= 3)
				{
					QuestEntry bringSuppliesEntry2 = _bringSuppliesEntry;
					if (bringSuppliesEntry2 != null)
					{
						bringSuppliesEntry2.Complete();
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("OnLoaded rebuild failed: " + ex.Message);
			}
		}
	}
	public class StaticUpgrade1Quest : Quest
	{
		private static readonly Instance Logger = new Instance("StaticUpgrade1Quest");

		[SaveableField("static_upgrade1_stage")]
		private int _stage;

		private QuestEntry _bringSuppliesEntry;

		private static readonly Vector3 StaticPosition = new Vector3(13.72f, 5.16f, 95.96f);

		protected override string Title => "Premium Tier";

		protected override string Description => "Static has the premium tier upgrade available. Check your texts and bring him what he needs.";

		protected override bool AutoBegin => false;

		protected override Sprite QuestIcon => ImageUtils.LoadImage(Path.Combine(MelonEnvironment.UserDataDirectory, "S1API", "Icons", "RinseCycle.png"));

		public static StaticUpgrade1Quest Instance { get; private set; }

		public int Stage => _stage;

		private void TriggerInternalInit()
		{
			try
			{
				FieldInfo field = typeof(Quest).GetField("S1Quest", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(field == null))
				{
					object? value = field.GetValue(this);
					Quest val = (Quest)((value is Quest) ? value : null);
					if (!((Object)(object)val == (Object)null))
					{
						val.InitializeQuest(((Quest)this).Title, ((Quest)this).Description, Il2CppReferenceArray<QuestEntryData>.op_Implicit(Array.Empty<QuestEntryData>()), val.StaticGUID);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TriggerInternalInit failed: " + ex.Message);
			}
		}

		public void Initialize()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				TriggerInternalInit();
				_bringSuppliesEntry = ((Quest)this).AddEntry(GetSuppliesText(), (Vector3?)StaticPosition);
			}
			catch (Exception ex)
			{
				Logger.Error("Initialize failed: " + ex.Message);
			}
		}

		private static string GetSuppliesText()
		{
			return $"Bring Static ${Config.StaticTier2BankCost.Value:N0} and {Config.StaticTier2MethGrams.Value} grams of meth";
		}

		public void RefreshEntryText()
		{
			if (_bringSuppliesEntry != null && _stage >= 1 && _stage < 2)
			{
				_bringSuppliesEntry.Title = GetSuppliesText();
			}
		}

		public void StartQuest()
		{
			try
			{
				_stage = 1;
				((Quest)this).Begin();
				QuestEntry bringSuppliesEntry = _bringSuppliesEntry;
				if (bringSuppliesEntry != null)
				{
					bringSuppliesEntry.Begin();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("StartQuest failed: " + ex.Message);
			}
		}

		public void CompleteObj1()
		{
			try
			{
				_stage = 2;
				QuestEntry bringSuppliesEntry = _bringSuppliesEntry;
				if (bringSuppliesEntry != null)
				{
					bringSuppliesEntry.Complete();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("CompleteObj1 failed: " + ex.Message);
			}
		}

		protected override void OnCreated()
		{
			((Registerable)this).OnCreated();
			Instance = this;
		}

		protected override void OnLoaded()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			((Saveable)this).OnLoaded();
			Instance = this;
			try
			{
				base.QuestEntries.Clear();
				_bringSuppliesEntry = ((Quest)this).AddEntry(GetSuppliesText(), (Vector3?)StaticPosition);
				if (_stage >= 1)
				{
					QuestEntry bringSuppliesEntry = _bringSuppliesEntry;
					if (bringSuppliesEntry != null)
					{
						bringSuppliesEntry.Begin();
					}
				}
				if (_stage >= 2)
				{
					QuestEntry bringSuppliesEntry2 = _bringSuppliesEntry;
					if (bringSuppliesEntry2 != null)
					{
						bringSuppliesEntry2.Complete();
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("OnLoaded rebuild failed: " + ex.Message);
			}
		}
	}
	public class StaticUpgrade2Quest : Quest
	{
		private static readonly Instance Logger = new Instance("StaticUpgrade2Quest");

		[SaveableField("static_upgrade2_stage")]
		private int _stage;

		private QuestEntry _bringSuppliesEntry;

		private static readonly Vector3 StaticPosition = new Vector3(13.72f, 5.16f, 95.96f);

		protected override string Title => "Full Scale";

		protected override string Description => "Static has the final tier-3 enterprise upgrade available. Bring premium meth and go all in.";

		protected override bool AutoBegin => false;

		protected override Sprite QuestIcon => ImageUtils.LoadImage(Path.Combine(MelonEnvironment.UserDataDirectory, "S1API", "Icons", "RinseCycle.png"));

		public static StaticUpgrade2Quest Instance { get; private set; }

		public int Stage => _stage;

		private void TriggerInternalInit()
		{
			try
			{
				FieldInfo field = typeof(Quest).GetField("S1Quest", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(field == null))
				{
					object? value = field.GetValue(this);
					Quest val = (Quest)((value is Quest) ? value : null);
					if (!((Object)(object)val == (Object)null))
					{
						val.InitializeQuest(((Quest)this).Title, ((Quest)this).Description, Il2CppReferenceArray<QuestEntryData>.op_Implicit(Array.Empty<QuestEntryData>()), val.StaticGUID);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TriggerInternalInit failed: " + ex.Message);
			}
		}

		public void Initialize()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				TriggerInternalInit();
				_bringSuppliesEntry = ((Quest)this).AddEntry(GetSuppliesText(), (Vector3?)StaticPosition);
			}
			catch (Exception ex)
			{
				Logger.Error("Initialize failed: " + ex.Message);
			}
		}

		private static string GetSuppliesText()
		{
			return $"Bring Static ${Config.StaticTier3BankCost.Value:N0} and {Config.StaticTier3PremiumMethGrams.Value} grams of premium meth";
		}

		public void RefreshEntryText()
		{
			if (_bringSuppliesEntry != null && _stage >= 1 && _stage < 2)
			{
				_bringSuppliesEntry.Title = GetSuppliesText();
			}
		}

		public void StartQuest()
		{
			try
			{
				_stage = 1;
				((Quest)this).Begin();
				QuestEntry bringSuppliesEntry = _bringSuppliesEntry;
				if (bringSuppliesEntry != null)
				{
					bringSuppliesEntry.Begin();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("StartQuest failed: " + ex.Message);
			}
		}

		public void CompleteObj1()
		{
			try
			{
				_stage = 2;
				QuestEntry bringSuppliesEntry = _bringSuppliesEntry;
				if (bringSuppliesEntry != null)
				{
					bringSuppliesEntry.Complete();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("CompleteObj1 failed: " + ex.Message);
			}
		}

		protected override void OnCreated()
		{
			((Registerable)this).OnCreated();
			Instance = this;
		}

		protected override void OnLoaded()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			((Saveable)this).OnLoaded();
			Instance = this;
			try
			{
				base.QuestEntries.Clear();
				_bringSuppliesEntry = ((Quest)this).AddEntry(GetSuppliesText(), (Vector3?)StaticPosition);
				if (_stage >= 1)
				{
					QuestEntry bringSuppliesEntry = _bringSuppliesEntry;
					if (bringSuppliesEntry != null)
					{
						bringSuppliesEntry.Begin();
					}
				}
				if (_stage >= 2)
				{
					QuestEntry bringSuppliesEntry2 = _bringSuppliesEntry;
					if (bringSuppliesEntry2 != null)
					{
						bringSuppliesEntry2.Complete();
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("OnLoaded rebuild failed: " + ex.Message);
			}
		}
	}
}
namespace OverTheCounter.SaveData
{
	public class VicSaveData : Saveable
	{
		private static readonly Instance Logger = new Instance("VicSaveData");

		[SaveableField("vic_unlocked")]
		private bool _unlocked;

		[SaveableField("vic_has_been_texted")]
		private bool _hasBeenTexted;

		[SaveableField("vic_trust_level")]
		private int _trustLevel;

		[SaveableField("vic_quest_accepted")]
		private bool _questAccepted;

		[SaveableField("vic_trigger_pending_day")]
		private int _triggerPendingDay = -1;

		[SaveableField("vic_last_deposit_day")]
		private int _lastDepositDay = -1;

		[SaveableField("vic_last_trust_increment_day")]
		private int _lastTrustIncrementDay = -1;

		[SaveableField("vic_tier2_intro_shown")]
		private bool _tier2IntroShown;

		private bool _needsIntroText;

		private bool _questCreated;

		private bool _fireOnNextTick;

		private bool _staleCheckDone;

		private int _tickCounter;

		private const int TICK_INTERVAL = 300;

		private bool _positionFixed;

		private static bool _sleepEndSubscribed;

		public static VicSaveData Instance { get; private set; }

		public bool Unlocked => _unlocked;

		public bool QuestAccepted => _questAccepted;

		public int TrustLevel => _trustLevel;

		public int LastDepositDay => _lastDepositDay;

		public bool Tier2IntroShown => _tier2IntroShown;

		public bool HasBeenTexted
		{
			get
			{
				return _hasBeenTexted;
			}
			set
			{
				if (!_hasBeenTexted && value)
				{
					_hasBeenTexted = true;
					TrySendIntroText();
					CreateOrResumeQuest();
					ConfigSyncData.Instance?.PublishGameState();
					if (VicNPC.Instance != null && VicNPC.Instance.DialogueReady)
					{
						VicNPC.Instance.RefreshDialogue();
					}
				}
			}
		}

		internal static void ResetInstance()
		{
			Instance = null;
		}

		public VicSaveData()
		{
			Instance = this;
			if (!_sleepEndSubscribed)
			{
				TimeManager.OnSleepEnd = (Action<int>)Delegate.Combine(TimeManager.OnSleepEnd, (Action<int>)delegate
				{
					Instance?.OnPlayerWokeUp();
				});
				_sleepEndSubscribed = true;
			}
		}

		protected override void OnLoaded()
		{
			Instance = this;
			if (_questAccepted)
			{
				_questCreated = true;
			}
			if (_hasBeenTexted)
			{
				_questCreated = true;
			}
			else if (_triggerPendingDay < 0 && IsCleanCashQuestStarted())
			{
				_triggerPendingDay = 0;
			}
		}

		public void OnVicSpawned()
		{
			if (NetworkHelper.IsHost)
			{
				_positionFixed = false;
			}
			if (_needsIntroText)
			{
				_needsIntroText = false;
				TrySendIntroText();
			}
		}

		private void OnPlayerWokeUp()
		{
			if (NetworkHelper.IsHost)
			{
				_positionFixed = false;
				if (!_hasBeenTexted && (_triggerPendingDay >= 0 || IsCleanCashQuestStarted()))
				{
					_triggerPendingDay = 0;
					_fireOnNextTick = true;
				}
			}
		}

		public void Tick()
		{
			if (NetworkHelper.IsHost && !_staleCheckDone && _hasBeenTexted)
			{
				_staleCheckDone = true;
				if (!IsCleanCashQuestStarted())
				{
					_hasBeenTexted = false;
					_triggerPendingDay = -1;
					_questCreated = false;
					_needsIntroText = false;
					_fireOnNextTick = false;
				}
			}
			else if (_fireOnNextTick)
			{
				_fireOnNextTick = false;
				if (!_hasBeenTexted)
				{
					HasBeenTexted = true;
				}
			}
			else
			{
				if (++_tickCounter < 300)
				{
					return;
				}
				_tickCounter = 0;
				if (NetworkHelper.IsHost && !_positionFixed && VicNPC.Instance != null)
				{
					_positionFixed = true;
					try
					{
						VicNPC.Instance.WarpToSpawn();
					}
					catch (Exception)
					{
					}
				}
				if (_hasBeenTexted)
				{
					try
					{
						if (VicNPC.Instance != null && VicNPC.Instance.DialogueReady)
						{
							VicNPC.Instance.RefreshDialogue();
						}
						return;
					}
					catch (Exception)
					{
						return;
					}
				}
				if (NetworkHelper.IsHost && _triggerPendingDay < 0 && IsCleanCashQuestStarted())
				{
					_triggerPendingDay = 0;
				}
			}
		}

		public void CreateOrResumeQuest()
		{
			if (_questCreated)
			{
				return;
			}
			_questCreated = true;
			try
			{
				if (VicIntroQuest.Instance == null)
				{
					VicIntroQuest vicIntroQuest = (VicIntroQuest)(object)QuestManager.CreateQuest<VicIntroQuest>((string)null);
					if (vicIntroQuest != null)
					{
						vicIntroQuest.Initialize();
						vicIntroQuest.StartQuest();
					}
					else
					{
						Logger.Error("QuestManager.CreateQuest<VicIntroQuest> returned null.");
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("CreateOrResumeQuest failed: " + ex.Message);
			}
		}

		public void ApplyHostState(bool hasBeenTexted = false, bool questAccepted = false, bool unlocked = false, int trustLevel = -1)
		{
			bool flag = false;
			bool flag2 = unlocked;
			if (hasBeenTexted && !_hasBeenTexted)
			{
				_hasBeenTexted = true;
				if (!flag2)
				{
					CreateOrResumeQuest();
				}
				flag = true;
			}
			if (questAccepted && !_questAccepted)
			{
				_questAccepted = true;
				_questCreated = true;
				if (!flag2)
				{
					try
					{
						VicIntroQuest.Instance?.CompleteObj1();
					}
					catch (Exception ex)
					{
						Logger.Warning("Client VicIntroQuest CompleteObj1 failed: " + ex.Message);
					}
				}
				flag = true;
			}
			if (unlocked && !_unlocked)
			{
				_unlocked = true;
				try
				{
					VicIntroQuest.Instance?.CompleteObj2();
				}
				catch (Exception ex2)
				{
					Logger.Warning("Client VicIntroQuest CompleteObj2 failed: " + ex2.Message);
				}
				flag = true;
			}
			if (trustLevel >= 0 && trustLevel != _trustLevel)
			{
				_trustLevel = trustLevel;
				flag = true;
			}
			if (flag && VicNPC.Instance != null && VicNPC.Instance.DialogueReady)
			{
				VicNPC.Instance.RefreshDialogue();
			}
		}

		public void OnQuestComplete()
		{
			_unlocked = true;
			ConfigSyncData.Instance?.PublishGameState();
		}

		public void OnLaunderComplete(int currentDay)
		{
			_lastDepositDay = currentDay;
			if (_lastTrustIncrementDay < currentDay)
			{
				_lastTrustIncrementDay = currentDay;
				_trustLevel++;
			}
			ConfigSyncData.Instance?.PublishGameState();
		}

		public void HandleRemoteAction(string action)
		{
			switch (action)
			{
			case "VIC_QUEST_ACCEPTED":
				_questAccepted = true;
				_questCreated = true;
				try
				{
					VicIntroQuest.Instance?.CompleteObj1();
				}
				catch (Exception ex)
				{
					Logger.Warning("Remote VicIntroQuest CompleteObj1 failed: " + ex.Message);
				}
				break;
			case "VIC_QUEST_COMPLETE":
				_unlocked = true;
				try
				{
					VicIntroQuest.Instance?.CompleteObj2();
				}
				catch (Exception ex2)
				{
					Logger.Warning("Remote VicIntroQuest CompleteObj2 failed: " + ex2.Message);
				}
				break;
			case "VIC_LAUNDER":
			{
				int elapsedDays = TimeManager.ElapsedDays;
				if (_lastTrustIncrementDay < elapsedDays)
				{
					_lastTrustIncrementDay = elapsedDays;
					_trustLevel++;
				}
				break;
			}
			default:
				Logger.Warning("VicSaveData: unknown remote action '" + action + "'");
				return;
			}
			ConfigSyncData.Instance?.PublishGameState();
		}

		public void MarkTier2IntroShown()
		{
			_tier2IntroShown = true;
		}

		private void TrySendIntroText()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			try
			{
				NPC val = NPC.All?.FirstOrDefault((Func<NPC, bool>)((NPC n) => n.ID == "vic_bank_teller"));
				if (val != null)
				{
					val.SendTextMessage("Hey, I noticed you've been hitting your weekly deposit limits. Meet me in the alley behind the bank. I might be able to help.", (Response[])null, 1f, true);
					_needsIntroText = false;
				}
				else
				{
					Logger.Warning("Vic NPC not found — deferring intro text until spawn.");
					_needsIntroText = true;
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TrySendIntroText failed: " + ex.Message);
				_needsIntroText = true;
			}
		}

		private bool IsCleanCashQuestStarted()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Invalid comparison between Unknown and I4
			try
			{
				QuestWrapper val = QuestManager.Get<CleanCash>();
				if (val == null)
				{
					return false;
				}
				List<QuestEntry> questEntries = val.QuestEntries;
				if (questEntries == null || questEntries.Count == 0)
				{
					return false;
				}
				foreach (QuestEntry item in questEntries)
				{
					if ((int)item.State == 1 || (int)item.State == 2)
					{
						return true;
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("Could not check Clean Cash quest: " + ex.Message);
			}
			return false;
		}
	}
	public class StaticSaveData : Saveable
	{
		private static readonly Instance Logger = new Instance("StaticSaveData");

		[SaveableField("static_intro_completed")]
		private bool _introCompleted;

		[SaveableField("static_quest_triggered")]
		private bool _questTriggered;

		[SaveableField("static_crm_tier")]
		private int _crmTier;

		[SaveableField("static_saas_active")]
		private bool _saasActive;

		[SaveableField("static_saas_next_payment_day")]
		private int _saasNextPaymentDay;

		[SaveableField("static_saas_day_pass_count")]
		private int _dayPassCount;

		[SaveableField("static_upgrade_available")]
		private bool _upgradeAvailable;

		[SaveableField("static_early_visit_seen")]
		private bool _earlyVisitSeen;

		private int _tickCounter;

		private const int TICK_INTERVAL = 300;

		private bool _positionFixed;

		private bool _dialogueStale;

		private bool _questCreated;

		private bool _needsIntroText;

		private static bool _dayPassSubscribed;

		public static StaticSaveData Instance { get; private set; }

		public bool IntroCompleted => _introCompleted;

		public bool QuestTriggered => _questTriggered;

		public int CrmTier => _crmTier;

		public bool SaasActive => _saasActive;

		public int SaasNextPaymentDay => _saasNextPaymentDay;

		public int DayPassCount => _dayPassCount;

		public bool UpgradeAvailable => _upgradeAvailable;

		public bool EarlyVisitSeen => _earlyVisitSeen;

		internal static void ResetInstance()
		{
			Instance = null;
		}

		public StaticSaveData()
		{
			Instance = this;
			if (!_dayPassSubscribed)
			{
				TimeManager.OnDayPass = (Action)Delegate.Combine(TimeManager.OnDayPass, (Action)delegate
				{
					Instance?.OnDayPass();
				});
				_dayPassSubscribed = true;
			}
		}

		protected override void OnLoaded()
		{
			Instance = this;
			if (_questTriggered)
			{
				_questCreated = true;
			}
		}

		public void Tick()
		{
			if (_dialogueStale && StaticNPC.Instance != null && StaticNPC.Instance.DialogueReady && !StaticNPC.Instance.IsInDialogue)
			{
				_dialogueStale = false;
				try
				{
					StaticNPC.Instance.RefreshDialogue();
				}
				catch (Exception)
				{
				}
			}
			if (++_tickCounter < 300)
			{
				return;
			}
			_tickCounter = 0;
			if (NetworkHelper.IsHost && !_positionFixed && StaticNPC.Instance != null)
			{
				_positionFixed = true;
				try
				{
					StaticNPC.Instance.WarpToSpawn();
				}
				catch (Exception)
				{
				}
			}
			if (!_questTriggered)
			{
				try
				{
					if (ATM.WeeklyDepositSum >= Config.AtmDepositTrigger.Value)
					{
						_questTriggered = true;
						CreateOrResumeQuest();
						if (NetworkHelper.IsHost)
						{
							TrySendIntroText();
							ConfigSyncData.Instance?.PublishGameState();
						}
						else
						{
							ConfigSyncData.SendQuestAction("STATIC_ATM_TRIGGERED");
						}
					}
					return;
				}
				catch (Exception ex3)
				{
					Logger.Warning("ATM check failed: " + ex3.Message);
					return;
				}
			}
			try
			{
				if (StaticNPC.Instance != null && StaticNPC.Instance.DialogueReady)
				{
					StaticNPC.Instance.RefreshDialogue();
				}
			}
			catch (Exception)
			{
			}
		}

		public void CreateOrResumeQuest()
		{
			if (_questCreated)
			{
				return;
			}
			_questCreated = true;
			try
			{
				if (StaticIntroQuest.Instance == null)
				{
					StaticIntroQuest staticIntroQuest = (StaticIntroQuest)(object)QuestManager.CreateQuest<StaticIntroQuest>((string)null);
					if (staticIntroQuest != null)
					{
						staticIntroQuest.Initialize();
						staticIntroQuest.StartQuest();
					}
					else
					{
						Logger.Error("QuestManager.CreateQuest<StaticIntroQuest> returned null.");
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("CreateOrResumeQuest failed: " + ex.Message);
			}
		}

		public void ApplyHostState(bool questTriggered = false, bool introCompleted = false, int crmTier = -1, bool? saasActive = null, bool? upgradeAvailable = null, int saasNextPaymentDay = -1, int dayPassCount = -1)
		{
			bool flag = false;
			bool flag2 = crmTier >= 1;
			if (questTriggered && !_questTriggered)
			{
				_questTriggered = true;
				if (!flag2)
				{
					CreateOrResumeQuest();
				}
				flag = true;
			}
			if (introCompleted && !_introCompleted)
			{
				_introCompleted = true;
				if (!flag2)
				{
					try
					{
						StaticIntroQuest.Instance?.CompleteObj1();
					}
					catch (Exception ex)
					{
						Logger.Warning("Client CompleteObj1 failed: " + ex.Message);
					}
				}
				flag = true;
			}
			if (crmTier >= 0 && crmTier != _crmTier)
			{
				int crmTier2 = _crmTier;
				_crmTier = crmTier;
				if (crmTier2 == 0 && crmTier == 1)
				{
					try
					{
						StaticIntroQuest.Instance?.CompleteObj2();
					}
					catch (Exception ex2)
					{
						Logger.Warning("Client CompleteObj2 failed: " + ex2.Message);
					}
				}
				if (crmTier2 == 1 && crmTier == 2)
				{
					try
					{
						StaticUpgrade1Quest.Instance?.CompleteObj1();
					}
					catch (Exception ex3)
					{
						Logger.Warning("Client Upgrade1 CompleteObj1 failed: " + ex3.Message);
					}
				}
				if (crmTier2 == 2 && crmTier == 3)
				{
					try
					{
						StaticUpgrade2Quest.Instance?.CompleteObj1();
					}
					catch (Exception ex4)
					{
						Logger.Warning("Client Upgrade2 CompleteObj1 failed: " + ex4.Message);
					}
				}
				flag = true;
			}
			if (saasActive.HasValue && saasActive.Value != _saasActive)
			{
				_saasActive = saasActive.Value;
				flag = true;
			}
			if (upgradeAvailable.HasValue && upgradeAvailable.Value != _upgradeAvailable)
			{
				_upgradeAvailable = upgradeAvailable.Value;
				if (_upgradeAvailable)
				{
					CreateUpgradeQuest();
				}
				flag = true;
			}
			if (saasNextPaymentDay >= 0 && saasNextPaymentDay != _saasNextPaymentDay)
			{
				_saasNextPaymentDay = saasNextPaymentDay;
				flag = true;
			}
			if (dayPassCount >= 0 && dayPassCount != _dayPassCount)
			{
				_dayPassCount = dayPassCount;
				flag = true;
			}
			if (flag && StaticNPC.Instance != null && StaticNPC.Instance.DialogueReady)
			{
				StaticNPC.Instance.RefreshDialogue();
			}
		}

		public void OnStaticSpawned()
		{
			if (NetworkHelper.IsHost)
			{
				_positionFixed = false;
			}
			if (_needsIntroText)
			{
				_needsIntroText = false;
				TrySendIntroText();
			}
		}

		private void TrySendIntroText()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			try
			{
				NPC val = NPC.All?.FirstOrDefault((Func<NPC, bool>)((NPC n) => n.ID == "static_casino_fixer"));
				if (val != null)
				{
					val.SendTextMessage("[0x4E72] d1g1t4l f00tpr1nt fl4gg3d. unencrypt3d ch4nn3l. vuln: CR1T1C4L.\n\nc4s1n0. t0p fl00r. 4ft3r 4. c0m3 4l0n3.\n\n— ST4T1C", (Response[])null, 1f, true);
					_needsIntroText = false;
				}
				else
				{
					Logger.Warning("Static NPC not found — deferring intro text until spawn.");
					_needsIntroText = true;
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TrySendIntroText failed: " + ex.Message);
				_needsIntroText = true;
			}
		}

		public void OnEarlyVisitSeen()
		{
			_earlyVisitSeen = true;
		}

		public void OnIntroCompleted()
		{
			if (!_introCompleted)
			{
				_introCompleted = true;
				try
				{
					StaticIntroQuest.Instance?.CompleteObj1();
				}
				catch (Exception ex)
				{
					Logger.Error("OnIntroCompleted quest completion failed: " + ex.Message);
				}
				SendStaticText($"[0x7A3F] s0ftw4r3 p4ck4g3 r34dy. c0st: ${Config.StaticTier1BankCost.Value:N0} + {Config.StaticTier1WeedGrams.Value}g w33d.\n\nbr1ng t0 c4s1n0.\n\n— ST4T1C_SYS");
				_dialogueStale = true;
				ConfigSyncData.Instance?.PublishGameState();
			}
		}

		public void PurchaseInitial()
		{
			if (_crmTier < 1)
			{
				_crmTier = 1;
				_saasActive = true;
				_saasNextPaymentDay = _dayPassCount + Config.SaasCycleDays.Value;
				try
				{
					StaticIntroQuest.Instance?.CompleteObj2();
				}
				catch (Exception ex)
				{
					Logger.Error("PurchaseInitial quest completion failed: " + ex.Message);
				}
				_dialogueStale = true;
				ConfigSyncData.Instance?.PublishGameState();
			}
		}

		public void PurchaseUpgrade()
		{
			if (_crmTier >= 3)
			{
				return;
			}
			int crmTier = _crmTier;
			_crmTier++;
			_upgradeAvailable = false;
			try
			{
				switch (crmTier)
				{
				case 1:
					StaticUpgrade1Quest.Instance?.CompleteObj1();
					break;
				case 2:
					StaticUpgrade2Quest.Instance?.CompleteObj1();
					break;
				}
			}
			catch (Exception ex)
			{
				Logger.Error("PurchaseUpgrade quest completion failed: " + ex.Message);
			}
			_dialogueStale = true;
			ConfigSyncData.Instance?.PublishGameState();
		}

		public bool ReactivateSubscription()
		{
			try
			{
				if (Money.GetOnlineBalance() < Config.SaasWeeklyCost.Value)
				{
					return false;
				}
				Money.CreateOnlineTransaction("OTC Back-Rent", 0f - Config.SaasWeeklyCost.Value, 1f, "Static Services");
				_saasActive = true;
				_saasNextPaymentDay = _dayPassCount + Config.SaasCycleDays.Value;
				_dialogueStale = true;
				ConfigSyncData.Instance?.PublishGameState();
				return true;
			}
			catch (Exception ex)
			{
				Logger.Error("ReactivateSubscription failed: " + ex.Message);
				return false;
			}
		}

		public void CancelSubscription()
		{
			_saasActive = false;
			_upgradeAvailable = false;
			_dialogueStale = true;
			ConfigSyncData.Instance?.PublishGameState();
		}

		public void HandleRemoteAction(string action)
		{
			switch (action)
			{
			case "STATIC_ATM_TRIGGERED":
				if (!_questTriggered)
				{
					_questTriggered = true;
					TrySendIntroText();
					CreateOrResumeQuest();
				}
				break;
			case "STATIC_INTRO_COMPLETED":
				_introCompleted = true;
				try
				{
					StaticIntroQuest.Instance?.CompleteObj1();
				}
				catch (Exception ex3)
				{
					Logger.Warning("Remote CompleteObj1 failed: " + ex3.Message);
				}
				break;
			case "STATIC_PURCHASE_INITIAL":
				_crmTier = 1;
				_saasActive = true;
				_saasNextPaymentDay = _dayPassCount + Config.SaasCycleDays.Value;
				try
				{
					StaticIntroQuest.Instance?.CompleteObj2();
				}
				catch (Exception ex2)
				{
					Logger.Warning("Remote CompleteObj2 failed: " + ex2.Message);
				}
				break;
			case "STATIC_PURCHASE_UPGRADE":
			{
				if (_crmTier >= 3)
				{
					return;
				}
				int crmTier = _crmTier;
				_crmTier++;
				_upgradeAvailable = false;
				try
				{
					switch (crmTier)
					{
					case 1:
						StaticUpgrade1Quest.Instance?.CompleteObj1();
						break;
					case 2:
						StaticUpgrade2Quest.Instance?.CompleteObj1();
						break;
					}
				}
				catch (Exception ex)
				{
					Logger.Warning("Remote PurchaseUpgrade quest failed: " + ex.Message);
				}
				break;
			}
			case "STATIC_REACTIVATE":
				_saasActive = true;
				_saasNextPaymentDay = _dayPassCount + Config.SaasCycleDays.Value;
				break;
			case "STATIC_CANCEL":
				_saasActive = false;
				_upgradeAvailable = false;
				break;
			default:
				Logger.Warning("StaticSaveData: unknown remote action '" + action + "'");
				return;
			}
			ConfigSyncData.Instance?.PublishGameState();
		}

		private void OnDayPass()
		{
			if (NetworkHelper.IsHost)
			{
				_positionFixed = false;
				_dayPassCount++;
				CheckSubscriptionStatus();
			}
		}

		public void CheckSubscriptionStatus()
		{
			if (!_saasActive || _dayPassCount < _saasNextPaymentDay)
			{
				return;
			}
			try
			{
				if (Money.GetOnlineBalance() >= Config.SaasWeeklyCost.Value)
				{
					Money.CreateOnlineTransaction("OTC Server Rent", 0f - Config.SaasWeeklyCost.Value, 1f, "Static Services");
					_saasNextPaymentDay += Config.SaasCycleDays.Value;
					SendStaticText("[0x52E1] server r3nt cleared. nod3s onl1ne.\n\n— ST4T1C_SYS");
					if (_crmTier < 3 && !_upgradeAvailable)
					{
						_upgradeAvailable = true;
						SendUpgradeOfferText();
						CreateUpgradeQuest();
					}
				}
				else
				{
					_saasActive = false;
					SendStaticText("[0xDEAD] paym3nt fa1led. serv1ce suspended. r3store in p3rson.\n\n— ST4T1C_SYS");
				}
				ConfigSyncData.Instance?.PublishGameState();
			}
			catch (Exception ex)
			{
				Logger.Error("CheckSubscriptionStatus failed: " + ex.Message);
			}
		}

		private void CreateUpgradeQuest()
		{
			try
			{
				if (_crmTier == 1)
				{
					if (StaticUpgrade1Quest.Instance == null)
					{
						StaticUpgrade1Quest staticUpgrade1Quest = (StaticUpgrade1Quest)(object)QuestManager.CreateQuest<StaticUpgrade1Quest>((string)null);
						if (staticUpgrade1Quest != null)
						{
							staticUpgrade1Quest.Initialize();
							staticUpgrade1Quest.StartQuest();
						}
						else
						{
							Logger.Error("CreateQuest<StaticUpgrade1Quest> returned null.");
						}
					}
				}
				else if (_crmTier == 2 && StaticUpgrade2Quest.Instance == null)
				{
					StaticUpgrade2Quest staticUpgrade2Quest = (StaticUpgrade2Quest)(object)QuestManager.CreateQuest<StaticUpgrade2Quest>((string)null);
					if (staticUpgrade2Quest != null)
					{
						staticUpgrade2Quest.Initialize();
						staticUpgrade2Quest.StartQuest();
					}
					else
					{
						Logger.Error("CreateQuest<StaticUpgrade2Quest> returned null.");
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("CreateUpgradeQuest failed: " + ex.Message);
			}
		}

		private void SendUpgradeOfferText()
		{
			if (_crmTier == 1)
			{
				SendStaticText($"[0x9FA1] pr1v4t3 s3rv3r r34dy. c0st: ${Config.StaticTier2BankCost.Value:N0} + {Config.StaticTier2MethGrams.Value}g m3th.\nfull r3g10n c0v3r4g3. s4m3 sp0t.\n\n— ST4T1C_SYS");
			}
			else if (_crmTier == 2)
			{
				SendStaticText($"[0xB2D8] 3nt3rpr1s3 t13r. GPS tr4ck1ng. c0st: ${Config.StaticTier3BankCost.Value:N0} + {Config.StaticTier3PremiumMethGrams.Value}g pr3m1um m3th.\nl4st upgr4d3. c4s1n0.\n\n— ST4T1C_SYS");
			}
		}

		private void SendStaticText(string message)
		{
			try
			{
				NPC? obj = NPC.All?.FirstOrDefault((Func<NPC, bool>)((NPC n) => n.ID == "static_casino_fixer"));
				if (obj != null)
				{
					obj.SendTextMessage(message, (Response[])null, 1f, true);
				}
			}
			catch (Exception ex)
			{
				Logger.Error("SendStaticText failed: " + ex.Message);
			}
		}
	}
	internal class RawStringSerializer : ISyncSerializer
	{
		public string Serialize<T>(T value)
		{
			object obj = value?.ToString();
			if (obj == null)
			{
				obj = "";
			}
			return (string)obj;
		}

		public T Deserialize<T>(string data)
		{
			return (T)(object)(data ?? "");
		}

		public bool CanSerialize(Type type)
		{
			return type == typeof(string);
		}
	}
	public class ConfigSyncData : Saveable
	{
		private static readonly Instance Logger = new Instance("ConfigSync");

		[SaveableField("config_sync_payload")]
		private string _payload = "";

		private static Dictionary<string, string> _pendingGameState;

		private static bool _networkInitialized;

		private static bool _initialSyncDone;

		private static SteamNetworkClient _netClient;

		private static HostSyncVar<string> _configVar;

		private static HostSyncVar<string> _stateVar;

		private static ClientSyncVar<string> _actionVar;

		private static readonly NetworkSyncOptions _syncOptions = new NetworkSyncOptions
		{
			KeyPrefix = "OTC_",
			Serializer = (ISyncSerializer)(object)new RawStringSerializer()
		};

		private static int _actionSeq;

		private static readonly Dictionary<ulong, string> _processedActions = new Dictionary<ulong, string>();

		private static long _lastActionPollTick;

		private const long ACTION_POLL_INTERVAL_MS = 1000L;

		public static ConfigSyncData Instance { get; private set; }

		public ConfigSyncData()
		{
			Instance = this;
		}

		protected override void OnLoaded()
		{
			Instance = this;
			_pendingGameState = null;
			if (!string.IsNullOrEmpty(_payload))
			{
				Dictionary<string, string> dictionary = ParsePayload(_payload);
				Config.ApplyOverrides(dictionary);
				Logger.Msg($"Applied {dictionary.Count} config overrides from saveable payload.");
			}
			if (_configVar != null)
			{
				_configVar.Value = Config.SerializeAll();
				_stateVar.Value = SerializeGameState();
				Logger.Msg("Pushed config and game state to SyncVars.");
			}
		}

		public static void EnsureNetworkReady()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (_networkInitialized)
			{
				return;
			}
			_networkInitialized = true;
			try
			{
				_netClient = new SteamNetworkClient();
				if (!_netClient.Initialize())
				{
					Logger.Warning("SteamNetworkClient.Initialize() returned false (single-player?).");
					_netClient = null;
					return;
				}
				_configVar = _netClient.CreateHostSyncVar<string>("cfg", "", _syncOptions, (ISyncValidator<string>)null);
				_stateVar = _netClient.CreateHostSyncVar<string>("state", "", _syncOptions, (ISyncValidator<string>)null);
				_actionVar = _netClient.CreateClientSyncVar<string>("action", "", _syncOptions, (ISyncValidator<string>)null);
				_configVar.OnSyncError += delegate(Exception ex)
				{
					Logger.Warning("Config SyncVar error: " + ex.Message);
				};
				_stateVar.OnSyncError += delegate(Exception ex)
				{
					Logger.Warning("State SyncVar error: " + ex.Message);
				};
				_actionVar.OnSyncError += delegate(Exception ex)
				{
					Logger.Warning("Action SyncVar error: " + ex.Message);
				};
				_configVar.OnWriteIgnored += delegate
				{
					Logger.Warning("Config SyncVar write ignored (not lobby owner).");
				};
				_stateVar.OnWriteIgnored += delegate
				{
					Logger.Warning("State SyncVar write ignored (not lobby owner).");
				};
				_configVar.OnValueChanged += OnConfigChanged;
				_stateVar.OnValueChanged += OnStateChanged;
				_actionVar.OnValueChanged += OnActionChanged;
				Logger.Msg($"SteamNetworkLib SyncVars initialized (inLobby={_netClient.IsInLobby}).");
			}
			catch (Exception ex2)
			{
				Logger.Warning("Failed to initialize SteamNetworkLib: " + ex2.Message);
				_netClient = null;
			}
		}

		public static void ProcessMessages()
		{
			//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_01ac: 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_0243: Unknown result type (might be due to invalid IL or missing references)
			if (_netClient == null)
			{
				return;
			}
			_netClient.ProcessIncomingMessages();
			if (!_initialSyncDone && _netClient.IsInLobby)
			{
				_initialSyncDone = true;
				try
				{
					string value = Config.SerializeAll();
					if (!string.IsNullOrEmpty(value) && _configVar != null)
					{
						_configVar.Value = value;
					}
					string value2 = SerializeGameState();
					if (!string.IsNullOrEmpty(value2) && _stateVar != null)
					{
						_stateVar.Value = value2;
					}
					_configVar?.Refresh();
					_stateVar?.Refresh();
					_actionVar?.Refresh();
					Logger.Msg($"Initial SyncVar sync after lobby discovery (lobbyHost={_netClient.IsHost}).");
				}
				catch (Exception ex)
				{
					Logger.Warning("Post-lobby-discovery sync failed: " + ex.Message);
				}
			}
			if (!_netClient.IsHost || _actionVar == null || !_initialSyncDone)
			{
				return;
			}
			long tickCount = Environment.TickCount64;
			if (tickCount - _lastActionPollTick < 1000)
			{
				return;
			}
			_lastActionPollTick = tickCount;
			try
			{
				_actionVar.Refresh();
				foreach (KeyValuePair<CSteamID, string> allValue in _actionVar.GetAllValues())
				{
					if (allValue.Key.m_SteamID == _netClient.LocalPlayerId.m_SteamID)
					{
						continue;
					}
					string value3 = allValue.Value;
					if (!string.IsNullOrEmpty(value3) && (!_processedActions.TryGetValue(allValue.Key.m_SteamID, out var value4) || !(value4 == value3)))
					{
						_processedActions[allValue.Key.m_SteamID] = value3;
						int num = value3.IndexOf(':');
						if (num > 0 && num < value3.Length - 1)
						{
							string text = value3.Substring(num + 1);
							Logger.Msg($"Host received quest action '{text}' from {allValue.Key} (polled)");
							ProcessQuestAction(text);
						}
					}
				}
			}
			catch (Exception ex2)
			{
				Logger.Warning("Action poll failed: " + ex2.Message);
			}
		}

		public static void Cleanup()
		{
			try
			{
				SteamNetworkClient netClient = _netClient;
				if (netClient != null)
				{
					netClient.Dispose();
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("Cleanup failed: " + ex.Message);
			}
			_netClient = null;
			_configVar = null;
			_stateVar = null;
			_actionVar = null;
			_pendingGameState = null;
			_processedActions.Clear();
			_networkInitialized = false;
			_initialSyncDone = false;
		}

		private static void OnConfigChanged(string oldValue, string newValue)
		{
			SteamNetworkClient netClient = _netClient;
			if ((netClient != null && netClient.IsHost) || string.IsNullOrEmpty(newValue))
			{
				return;
			}
			try
			{
				Dictionary<string, string> dictionary = ParsePayload(newValue);
				Config.ApplyOverrides(dictionary);
				RefreshQuestText();
				Logger.Msg($"Client applied {dictionary.Count} config overrides from SyncVar.");
			}
			catch (Exception ex)
			{
				Logger.Warning("OnConfigChanged failed: " + ex.Message);
			}
		}

		private static void OnStateChanged(string oldValue, string newValue)
		{
			SteamNetworkClient netClient = _netClient;
			if ((netClient != null && netClient.IsHost) || string.IsNullOrEmpty(newValue))
			{
				return;
			}
			try
			{
				Dictionary<string, string> dictionary = (_pendingGameState = ParsePayload(newValue));
				ApplyGameState(dictionary);
				Logger.Msg($"Client applied {dictionary.Count} game state values from SyncVar.");
			}
			catch (Exception ex)
			{
				Logger.Warning("OnStateChanged failed: " + ex.Message);
			}
		}

		private static void OnActionChanged(CSteamID sender, string oldValue, string newValue)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			SteamNetworkClient netClient = _netClient;
			if (netClient == null || !netClient.IsHost || string.IsNullOrEmpty(newValue))
			{
				return;
			}
			ulong steamID = sender.m_SteamID;
			if (_netClient != null && steamID == _netClient.LocalPlayerId.m_SteamID)
			{
				return;
			}
			try
			{
				if (!_processedActions.TryGetValue(steamID, out var value) || !(value == newValue))
				{
					_processedActions[steamID] = newValue;
					int num = newValue.IndexOf(':');
					if (num > 0 && num < newValue.Length - 1)
					{
						string text = newValue.Substring(num + 1);
						Logger.Msg($"Host received quest action '{text}' from {sender}");
						ProcessQuestAction(text);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("OnActionChanged failed: " + ex.Message);
			}
		}

		public void RefreshFromConfig()
		{
			if (NetworkHelper.IsHost)
			{
				_payload = Config.SerializeAll();
				if (_configVar != null)
				{
					_configVar.Value = _payload;
				}
				RefreshQuestText();
			}
		}

		private static void RefreshQuestText()
		{
			try
			{
				VicIntroQuest.Instance?.RefreshEntryText();
				StaticIntroQuest.Instance?.RefreshEntryText();
				StaticUpgrade1Quest.Instance?.RefreshEntryText();
				StaticUpgrade2Quest.Instance?.RefreshEntryText();
			}
			catch (Exception ex)
			{
				Logger.Warning("RefreshQuestText failed: " + ex.Message);
			}
		}

		public void PublishGameState()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			try
			{
				string value = SerializeGameState();
				if (_stateVar != null)
				{
					_stateVar.Value = value;
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("PublishGameState failed: " + ex.Message);
			}
		}

		public static void SendQuestAction(string action)
		{
			if (NetworkHelper.IsHost)
			{
				return;
			}
			try
			{
				if (_actionVar == null)
				{
					Logger.Warning("SendQuestAction(" + action + "): SyncVar not initialized yet.");
					return;
				}
				string text = $"{++_actionSeq}:{action}";
				_actionVar.Value = text;
				Logger.Msg("Sent quest action via SyncVar: " + text);
			}
			catch (Exception ex)
			{
				Logger.Warning("SendQuestAction(" + action + ") failed: " + ex.Message);
			}
		}

		private static void ProcessQuestAction(string action)
		{
			switch (action)
			{
			case "STATIC_PURCHASE_INITIAL":
			case "STATIC_PURCHASE_UPGRADE":
			case "STATIC_ATM_TRIGGERED":
			case "STATIC_INTRO_COMPLETED":
			case "STATIC_REACTIVATE":
			case "STATIC_CANCEL":
				StaticSaveData.Instance?.HandleRemoteAction(action);
				break;
			case "VIC_QUEST_ACCEPTED":
			case "VIC_QUEST_COMPLETE":
			case "VIC_LAUNDER":
				VicSaveData.Instance?.HandleRemoteAction(action);
				break;
			default:
				Logger.Warning("Unknown quest action: " + action);
				break;
			}
		}

		public static void ApplyPendingGameState()
		{
			if (_pendingGameState != null && _pendingGameState.Count != 0)
			{
				ApplyGameState(_pendingGameState);
				Logger.Msg("Applied pending game state to newly created SaveData.");
			}
		}

		private static string SerializeGameState()
		{
			List<string> list = new List<string>();
			if (StaticSaveData.Instance != null)
			{
				list.Add("static_triggered=" + BoolToStr(StaticSaveData.Instance.QuestTriggered));
				list.Add("static_intro=" + BoolToStr(StaticSaveData.Instance.IntroCompleted));
				list.Add($"static_tier={StaticSaveData.Instance.CrmTier}");
				list.Add("static_saas=" + BoolToStr(StaticSaveData.Instance.SaasActive));
				list.Add("static_upgrade=" + BoolToStr(StaticSaveData.Instance.UpgradeAvailable));
				list.Add($"static_next_payment={StaticSaveData.Instance.SaasNextPaymentDay}");
				list.Add($"static_day_pass={StaticSaveData.Instance.DayPassCount}");
			}
			if (VicSaveData.Instance != null)
			{
				list.Add("vic_texted=" + BoolToStr(VicSaveData.Instance.HasBeenTexted));
				list.Add("vic_accepted=" + BoolToStr(VicSaveData.Instance.QuestAccepted));
				list.Add("vic_unlocked=" + BoolToStr(VicSaveData.Instance.Unlocked));
				list.Add($"vic_trust={VicSaveData.Instance.TrustLevel}");
			}
			string desperateIdsForSync = DesperationManager.GetDesperateIdsForSync();
			if (!string.IsNullOrEmpty(desperateIdsForSync))
			{
				list.Add("desp_ids=" + desperateIdsForSync);
			}
			return string.Join("|", list);
		}

		private static void ApplyGameState(Dictionary<string, string> state)
		{
			if (StaticSaveData.Instance != null)
			{
				string value;
				bool questTriggered = state.TryGetValue("static_triggered", out value) && StrToBool(value);
				string value2;
				bool introCompleted = state.TryGetValue("static_intro", out value2) && StrToBool(value2);
				string value3;
				int result;
				int crmTier = ((state.TryGetValue("static_tier", out value3) && int.TryParse(value3, out result)) ? result : (-1));
				string value4;
				bool? saasActive = (state.TryGetValue("static_saas", out value4) ? new bool?(StrToBool(value4)) : null);
				string value5;
				bool? upgradeAvailable = (state.TryGetValue("static_upgrade", out value5) ? new bool?(StrToBool(value5)) : null);
				string value6;
				int result2;
				int saasNextPaymentDay = ((state.TryGetValue("static_next_payment", out value6) && int.TryParse(value6, out result2)) ? result2 : (-1));
				string value7;
				int result3;
				int dayPassCount = ((state.TryGetValue("static_day_pass", out value7) && int.TryParse(value7, out result3)) ? result3 : (-1));
				StaticSaveData.Instance.ApplyHostState(questTriggered, introCompleted, crmTier, saasActive, upgradeAvailable, saasNextPaymentDay, dayPassCount);
			}
			if (VicSaveData.Instance != null)
			{
				string value8;
				bool hasBeenTexted = state.TryGetValue("vic_texted", out value8) && StrToBool(value8);
				string value9;
				bool questAccepted = state.TryGetValue("vic_accepted", out value9) && StrToBool(value9);
				string value10;
				bool unlocked = state.TryGetValue("vic_unlocked", out value10) && StrToBool(value10);
				string value11;
				int result4;
				int trustLevel = ((state.TryGetValue("vic_trust", out value11) && int.TryParse(value11, out result4)) ? result4 : (-1));
				VicSaveData.Instance.ApplyHostState(hasBeenTexted, questAccepted, unlocked, trustLevel);
			}
			HashSet<string> hashSet = new HashSet<string>();
			if (state.TryGetValue("desp_ids", out var value12) && !string.IsNullOrEmpty(value12))
			{
				string[] array = value12.Split(',');
				foreach (string text in array)
				{
					if (!string.IsNullOrEmpty(text))
					{
						hashSet.Add(text);
					}
				}
			}
			DesperationManager.UpdateClientDesperateIds(hashSet);
		}

		private static string BoolToStr(bool v)
		{
			if (!v)
			{
				return "0";
			}
			return "1";
		}

		private static bool StrToBool(string v)
		{
			return v == "1";
		}

		private static Dictionary<string, string> ParsePayload(string payload)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			string[] array = payload.Split('|');
			foreach (string text in array)
			{
				if (!string.IsNullOrEmpty(text))
				{
					int num = text.IndexOf('=');
					if (num > 0 && num < text.Length - 1)
					{
						string key = text.Substring(0, num);
						string value = text.Substring(num + 1);
						dictionary[key] = value;
					}
				}
			}
			return dictionary;
		}
	}
}
namespace OverTheCounter.UI
{
	public static class LocationPickerUI
	{
		private class LocationInfo
		{
			public string GUID { get; set; }

			public string Name { get; set; }

			public string Description { get; set; }
		}

		private static GameObject _pickerRoot;

		private static Action<string> _onLocationSelected;

		private static Customer _currentCustomer;

		public static void Show(Customer customer, Action<string> onSelected)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)customer == (Object)null || (Object)(object)customer.NPC == (Object)null)
			{
				MelonLogger.Error("[LocationPickerUI] Customer is null");
				return;
			}
			_currentCustomer = customer;
			_onLocationSelected = onSelected;
			List<LocationInfo> deliveryLocationsForRegion = GetDeliveryLocationsForRegion(customer.NPC.Region);
			if (deliveryLocationsForRegion.Count == 0)
			{
				MelonLogger.Warning($"[LocationPickerUI] No delivery locations found for region {customer.NPC.Region}");
			}
			else
			{
				CreatePickerUI(deliveryLocationsForRegion);
			}
		}

		private static List<LocationInfo> GetDeliveryLocationsForRegion(object region)
		{
			List<LocationInfo> list = new List<LocationInfo>();
			try
			{
				Type type = Type.GetType("Il2CppScheduleOne.Map.Map, Assembly-CSharp");
				if (type == null)
				{
					MelonLogger.Warning("[LocationPickerUI] Could not find Map type");
					return list;
				}
				object obj = typeof(Singleton<>).MakeGenericType(type).GetProperty("Instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
				if (obj == null)
				{
					MelonLogger.Warning("[LocationPickerUI] Map instance is null");
					return list;
				}
				MethodInfo method = obj.GetType().GetMethod("GetRegionData");
				if (method == null)
				{
					MelonLogger.Warning("[LocationPickerUI] Could not find GetRegionData method");
					return list;
				}
				object obj2 = method.Invoke(obj, new object[1] { region });
				if (obj2 == null)
				{
					MelonLogger.Warning($"[LocationPickerUI] No region data for {region}");
					return list;
				}
				PropertyInfo property = obj2.GetType().GetProperty("RegionDeliveryLocations");
				if (property == null)
				{
					MelonLogger.Warning("[LocationPickerUI] Could not find RegionDeliveryLocations property on " + obj2.GetType().Name);
					return list;
				}
				dynamic value = property.GetValue(obj2);
				if (value == null)
				{
					MelonLogger.Warning("[LocationPickerUI] RegionDeliveryLocations is null");
					return list;
				}
				int num = value.Length;
				for (int i = 0; i < num; i++)
				{
					dynamic val = value[i];
					if (val != null)
					{
						list.Add(new LocationInfo
						{
							GUID = val.GUID.ToString(),
							Name = val.LocationName,
							Description = (val.LocationDescription ?? "")
						});
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[LocationPickerUI] Error getting locations: " + ex.Message);
			}
			return list;
		}

		private static void CreatePickerUI(List<LocationInfo> locations)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Expected O, but got Unknown
			//IL_02da: 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_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_pickerRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_pickerRoot);
			}
			_pickerRoot = new GameObject("LocationPickerRoot");
			Canvas obj = _pickerRoot.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 90;
			_pickerRoot.AddComponent<CanvasScaler>();
			_pickerRoot.AddComponent<GraphicRaycaster>();
			((Graphic)UIFactory.Panel("Overlay", _pickerRoot.transform, new Color(0f, 0f, 0f, 0.7f), (Vector2?)null, (Vector2?)null, true).GetComponent<Image>()).raycastTarget = true;
			GameObject val = UIFactory.Panel("LocationPanel", _pickerRoot.transform, new Color(0.18f, 0.18f, 0.18f), (Vector2?)null, (Vector2?)null, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(280f, 400f);
			PositionAtTop(((Component)UIFactory.Text("Title", "<b>Select Location</b>", val.transform, 16, (TextAnchor)4, (FontStyle)0)).gameObject.GetComponent<RectTransform>(), -8f, 25f);
			Text obj2 = UIFactory.Text("Subtitle", "Where should " + _currentCustomer.NPC.FirstName + " meet you?", val.transform, 12, (TextAnchor)4, (FontStyle)0);
			((Graphic)obj2).color = new Color(0.7f, 0.7f, 0.7f);
			PositionAtTop(((Component)obj2).gameObject.GetComponent<RectTransform>(), -35f, 18f);
			ScrollRect val2 = default(ScrollRect);
			RectTransform val3 = UIFactory.ScrollableVerticalList("LocationList", val.transform, ref val2);
			RectTransform component2 = ((Component)val2).GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 0f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.offsetMin = new Vector2(8f, 45f);
			component2.offsetMax = new Vector2(-8f, -58f);
			VerticalLayoutGroup component3 = ((Component)val3).GetComponent<VerticalLayoutGroup>();
			if ((Object)(object)component3 != (Object)null)
			{
				((HorizontalOrVerticalLayoutGroup)component3).spacing = 4f;
				((LayoutGroup)component3).padding = new RectOffset(4, 4, 4, 4);
				((HorizontalOrVerticalLayoutGroup)component3).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)component3).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)component3).childForceExpandHeight = false;
				((HorizontalOrVerticalLayoutGroup)component3).childForceExpandWidth = true;
			}
			foreach (LocationInfo location in locations)
			{
				CreateLocationButton((Transform)(object)val3, location);
			}
			LayoutRebuilder.ForceRebuildLayoutImmediate(val3);
			ValueTuple<GameObject, Button, Text> valueTuple = UIFactory.RoundedButtonWithLabel("CancelBtn", "Cancel", val.transform, new Color(0.5f, 0.2f, 0.2f), 264f, 30f, 12, Color.white);
			GameObject item = valueTuple.Item1;
			Button item2 = valueTuple.Item2;
			RectTransform component4 = item.GetComponent<RectTransform>();
			component4.anchorMin = new Vector2(0.5f, 0f);
			component4.anchorMax = new Vector2(0.5f, 0f);
			component4.pivot = new Vector2(0.5f, 0f);
			component4.anchoredPosition = new Vector2(0f, 8f);
			((UnityEvent)item2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				Hide();
			}));
			_pickerRoot.SetActive(true);
		}

		private static void PositionAtTop(RectTransform rect, float yOffset, float height)
		{
			//IL_000b: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = new Vector2(0f, 1f);
			rect.anchorMax = new Vector2(1f, 1f);
			rect.pivot = new Vector2(0.5f, 1f);
			rect.anchoredPosition = new Vector2(0f, yOffset);
			rect.sizeDelta = new Vector2(0f, height);
		}

		private static void CreateLocationButton(Transform parent, LocationInfo location)
		{
			//IL_002c: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				var (val, val2, val3) = UIFactory.ButtonWithLabel("Loc_" + location.Name, location.Name, parent, new Color(0.25f, 0.42f, 0.25f), 260f, 32f);
				if ((Object)(object)val == (Object)null)
				{
					MelonLogger.Error("[LocationPickerUI] Failed to create button for " + location.Name);
					return;
				}
				LayoutElement obj = val.AddComponent<LayoutElement>();
				obj.preferredHeight = 32f;
				obj.minHeight = 32f;
				ColorBlock colors = ((Selectable)val2).colors;
				((ColorBlock)(ref colors)).normalColor = new Color(0.25f, 0.42f, 0.25f);
				((ColorBlock)(ref colors)).highlightedColor = new Color(0.35f, 0.55f, 0.35f);
				((ColorBlock)(ref colors)).pressedColor = new Color(0.2f, 0.3f, 0.2f);
				((ColorBlock)(ref colors)).selectedColor = new Color(0.25f, 0.42f, 0.25f);
				((Selectable)val2).colors = colors;
				val3.fontSize = 11;
				((Graphic)val3).color = Color.white;
				RectTransform component = ((Component)val3).GetComponent<RectTransform>();
				component.offsetMin = new Vector2(5f, 0f);
				component.offsetMax = new Vector2(-5f, 0f);
				string locGuid = location.GUID;
				((UnityEvent)val2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
				{
					Action<string> onLocationSelected = _onLocationSelected;
					Hide();
					onLocationSelected?.Invoke(locGuid);
				}));
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[LocationPickerUI] Error creating button for " + location.Name + ": " + ex.Message);
			}
		}

		public static void Hide()
		{
			if ((Object)(object)_pickerRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_pickerRoot);
				_pickerRoot = null;
			}
			_onLocationSelected = null;
			_currentCustomer = null;
		}
	}
	public static class SmartStashOverlayUI
	{
		private static GameObject _overlayRoot;

		private static Transform _listContent;

		private static bool _includeAllShifts;

		private static Text _statusText;

		private static Action _refreshAction;

		private static StorageEntity _subscribedStorageEntity;

		public static void Show()
		{
			if ((Object)(object)_overlayRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_overlayRoot);
				_overlayRoot = null;
			}
			_includeAllShifts = true;
			BuildUI();
			SubscribeToChanges();
			RefreshManifest();
		}

		public static void Hide()
		{
			UnsubscribeFromChanges();
			if ((Object)(object)_overlayRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_overlayRoot);
				_overlayRoot = null;
			}
			_listContent = null;
			_statusText = null;
		}

		private static void SubscribeToChanges()
		{
			_refreshAction = Action.op_Implicit((Action)OnInventoryChanged);
			try
			{
				StorageMenu instance = Singleton<StorageMenu>.Instance;
				if ((Object)(object)instance != (Object)null && instance.IsOpen)
				{
					StorageEntity openedStorageEntity = instance.OpenedStorageEntity;
					if ((Object)(object)openedStorageEntity != (Object)null)
					{
						openedStorageEntity.onContentsChanged += _refreshAction;
						_subscribedStorageEntity = openedStorageEntity;
					}
				}
			}
			catch (Exception ex)
			{
				Melon<Core>.Logger.Warning("[SmartStashOverlayUI] Could not subscribe to storage changes: " + ex.Message);
			}
			try
			{
				PlayerInventory instance2 = PlayerSingleton<PlayerInventory>.Instance;
				if (((instance2 != null) ? instance2.hotbarSlots : null) == null)
				{
					return;
				}
				List<HotbarSlot> hotbarSlots = instance2.hotbarSlots;
				for (int i = 0; i < hotbarSlots.Count; i++)
				{
					HotbarSlot val = hotbarSlots[i];
					if (val != null)
					{
						((ItemSlot)val).onItemDataChanged = ((ItemSlot)val).onItemDataChanged + _refreshAction;
					}
				}
			}
			catch (Exception ex2)
			{
				Melon<Core>.Logger.Warning("[SmartStashOverlayUI] Could not subscribe to hotbar changes: " + ex2.Message);
			}
		}

		private static void UnsubscribeFromChanges()
		{
			if ((Delegate)(object)_refreshAction == (Delegate)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)_subscribedStorageEntity != (Object)null)
				{
					StorageEntity subscribedStorageEntity = _subscribedStorageEntity;
					subscribedStorageEntity.onContentsChanged -= _refreshAction;
					_subscribedStorageEntity = null;
				}
			}
			catch
			{
			}
			try
			{
				PlayerInventory instance = PlayerSingleton<PlayerInventory>.Instance;
				if (((instance != null) ? instance.hotbarSlots : null) != null)
				{
					List<HotbarSlot> hotbarSlots = instance.hotbarSlots;
					for (int i = 0; i < hotbarSlots.Count; i++)
					{
						HotbarSlot val = hotbarSlots[i];
						if (val != null)
						{
							((ItemSlot)val).onItemDataChanged = ((ItemSlot)val).onItemDataChanged - _refreshAction;
						}
					}
				}
			}
			catch
			{
			}
			_refreshAction = null;
		}

		private static void OnInventoryChanged()
		{
			try
			{
				RefreshManifest();
			}
			catch (Exception ex)
			{
				Melon<Core>.Logger.Warning("[SmartStashOverlayUI] Error during auto-refresh: " + ex.Message);
			}
		}

		private static void BuildUI()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0055: 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_00b6: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Expected O, but got Unknown
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Expected O, but got Unknown
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0519: Unknown result type (might be due to invalid IL or missing references)
			//IL_052e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0543: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_0563: Unknown result type (might be due to invalid IL or missing references)
			//IL_0568: Unknown result type (might be due to invalid IL or missing references)
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0596: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_062e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0652: Unknown result type (might be due to invalid IL or missing references)
			//IL_0667: Unknown result type (might be due to invalid IL or missing references)
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0691: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a5: Unknown result type (might be due to invalid IL or missing references)
			_overlayRoot = new GameObject("SmartStashOverlayRoot");
			Canvas obj = _overlayRoot.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 80;
			_overlayRoot.AddComponent<CanvasScaler>();
			GameObject val = UIFactory.Panel("SmartStashPanel", _overlayRoot.transform, new Color(0.14f, 0.14f, 0.14f, 0.95f), (Vector2?)null, (Vector2?)null, false);
			Canvas obj2 = val.AddComponent<Canvas>();
			obj2.overrideSorting = true;
			obj2.sortingOrder = 81;
			val.AddComponent<GraphicRaycaster>();
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(1f, 0.5f);
			component.anchorMax = new Vector2(1f, 0.5f);
			component.pivot = new Vector2(1f, 0.5f);
			component.sizeDelta = new Vector2(260f, 440f);
			component.anchoredPosition = new Vector2(-10f, 0f);
			RectTransform component2 = ((Component)UIFactory.Text("Header", "<b>Delivery Manifest</b>", val.transform, 16, (TextAnchor)4, (FontStyle)0)).gameObject.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 1f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(0.5f, 1f);
			component2.anchoredPosition = new Vector2(0f, -6f);
			component2.sizeDelta = new Vector2(0f, 28f);
			GameObject val2 = new GameObject("ManifestList");
			val2.transform.SetParent(val.transform, false);
			RectTransform obj3 = val2.AddComponent<RectTransform>();
			obj3.anchorMin = new Vector2(0f, 0f);
			obj3.anchorMax = new Vector2(1f, 1f);
			obj3.offsetMin = new Vector2(12f, 100f);
			obj3.offsetMax = new Vector2(-8f, -38f);
			VerticalLayoutGroup obj4 = val2.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj4).spacing = 3f;
			((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = true;
			((LayoutGroup)obj4).childAlignment = (TextAnchor)0;
			_listContent = val2.transform;
			GameObject val3 = new GameObject("IncludeAllToggle");
			val3.transform.SetParent(val.transform, false);
			RectTransform obj5 = val3.AddComponent<RectTransform>();
			obj5.anchorMin = new Vector2(0f, 0f);
			obj5.anchorMax = new Vector2(1f, 0f);
			obj5.pivot = new Vector2(0.5f, 0f);
			obj5.anchoredPosition = new Vector2(0f, 68f);
			obj5.sizeDelta = new Vector2(0f, 24f);
			GameObject val4 = new GameObject("Background");
			val4.transform.SetParent(val3.transform, false);
			Image val5 = val4.AddComponent<Image>();
			((Graphic)val5).color = new Color(0.25f, 0.25f, 0.25f);
			RectTransform component3 = val4.GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 0.5f);
			component3.anchorMax = new Vector2(0f, 0.5f);
			component3.pivot = new Vector2(0f, 0.5f);
			component3.anchoredPosition = new Vector2(10f, 0f);
			component3.sizeDelta = new Vector2(18f, 18f);
			GameObject val6 = new GameObject("Checkmark");
			val6.transform.SetParent(val4.transform, false);
			Image val7 = val6.AddComponent<Image>();
			((Graphic)val7).color = new Color(0.4f, 0.8f, 0.4f);
			RectTransform component4 = val6.GetComponent<RectTransform>();
			component4.anchorMin = new Vector2(0.15f, 0.15f);
			component4.anchorMax = new Vector2(0.85f, 0.85f);
			component4.offsetMin = Vector2.zero;
			component4.offsetMax = Vector2.zero;
			Toggle obj6 = val3.AddComponent<Toggle>();
			obj6.isOn = true;
			obj6.graphic = (Graphic)(object)val7;
			((Selectable)obj6).targetGraphic = (Graphic)(object)val5;
			((UnityEvent<bool>)(object)obj6.onValueChanged).AddListener(UnityAction<bool>.op_Implicit((Action<bool>)OnToggleChanged));
			Text obj7 = UIFactory.Text("ToggleLabel", "Include All Shifts", val3.transform, 13, (TextAnchor)3, (FontStyle)0);
			((Graphic)obj7).color = new Color(0.8f, 0.8f, 0.8f);
			RectTransform component5 = ((Component)obj7).gameObject.GetComponent<RectTransform>();
			component5.anchorMin = new Vector2(0f, 0f);
			component5.anchorMax = new Vector2(1f, 1f);
			component5.offsetMin = new Vector2(34f, 0f);
			component5.offsetMax = new Vector2(-4f, 0f);
			ValueTuple<GameObject, Button, Text> valueTuple = UIFactory.RoundedButtonWithLabel("SmartFillBtn", "Smart Fill", val.transform, new Color(0.2f, 0.5f, 0.2f), 230f, 32f, 14, Color.white);
			GameObject item = valueTuple.Item1;
			Button item2 = valueTuple.Item2;
			RectTransform component6 = item.GetComponent<RectTransform>();
			component6.anchorMin = new Vector2(0.5f, 0f);
			component6.anchorMax = new Vector2(0.5f, 0f);
			component6.pivot = new Vector2(0.5f, 0f);
			component6.anchoredPosition = new Vector2(0f, 32f);
			ColorBlock colors = ((Selectable)item2).colors;
			((ColorBlock)(ref colors)).normalColor = new Color(0.2f, 0.5f, 0.2f);
			((ColorBlock)(ref colors)).highlightedColor = new Color(0.3f, 0.6f, 0.3f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.15f, 0.35f, 0.15f);
			((ColorBlock)(ref colors)).selectedColor = new Color(0.2f, 0.5f, 0.2f);
			((Selectable)item2).colors = colors;
			((UnityEvent)item2.onClick).AddListener(UnityAction.op_Implicit((Action)OnSmartFillClicked));
			_statusText = UIFactory.Text("StatusText", "", val.transform, 12, (TextAnchor)4, (FontStyle)0);
			((Graphic)_statusText).color = new Color(0.7f, 0.7f, 0.7f);
			RectTransform component7 = ((Component)_statusText).gameObject.GetComponent<RectTransform>();
			component7.anchorMin = new Vector2(0f, 0f);
			component7.anchorMax = new Vector2(1f, 0f);
			component7.pivot = new Vector2(0.5f, 0f);
			component7.anchoredPosition = new Vector2(0f, 6f);
			component7.sizeDelta = new Vector2(0f, 22f);
			_overlayRoot.SetActive(true);
		}

		private static void RefreshManifest()
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_listContent == (Object)null)
			{
				return;
			}
			for (int num = _listContent.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)_listContent.GetChild(num)).gameObject);
			}
			List<ManifestRequirement> list;
			try
			{
				list = ContractAggregator.CalculateManifest(_includeAllShifts);
			}
			catch (Exception ex)
			{
				Melon<Core>.Logger.Error("[SmartStashOverlayUI] Error calculating manifest: " + ex.Message);
				SetStatus("Error loading manifest");
				return;
			}
			if (list.Count == 0)
			{
				SetStatus("Nothing needed!");
				return;
			}
			SetStatus("");
			foreach (ManifestRequirement item in list)
			{
				string text = $"{item.ProductName}: {item.AmountInInventory}/{item.AmountNeeded}";
				Color color = (Color)((item.Deficit <= 0) ? new Color(0.4f, 0.8f, 0.4f) : Color.white);
				GameObject val = new GameObject("Row_" + item.ProductID);
				val.transform.SetParent(_listContent, false);
				val.AddComponent<RectTransform>().sizeDelta = new Vector2(0f, 20f);
				Text obj = val.AddComponent<Text>();
				obj.text = text;
				obj.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
				obj.fontSize = 13;
				((Graphic)obj).color = color;
				obj.alignment = (TextAnchor)3;
				obj.horizontalOverflow = (HorizontalWrapMode)0;
				obj.verticalOverflow = (VerticalWrapMode)0;
				LayoutElement obj2 = val.AddComponent<LayoutElement>();
				obj2.preferredHeight = 20f;
				obj2.minHeight = 20f;
			}
			Transform listContent = _listContent;
			LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)(object)((listContent is RectTransform) ? listContent : null));
		}

		private static void OnToggleChanged(bool value)
		{
			_includeAllShifts = value;
			RefreshManifest();
		}

		private static void OnSmartFillClicked()
		{
			try
			{
				StorageMenu instance = Singleton<StorageMenu>.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					SetStatus("Storage menu not found");
					return;
				}
				if (!instance.IsOpen)
				{
					SetStatus("Storage not open");
					return;
				}
				StorageEntity openedStorageEntity = instance.OpenedStorageEntity;
				if ((Object)(object)openedStorageEntity == (Object)null)
				{
					SetStatus("No storage entity found");
					return;
				}
				List<ItemSlot> itemSlots = openedStorageEntity.ItemSlots;
				if (itemSlots == null)
				{
					SetStatus("Cannot read storage slots");
					return;
				}
				PlayerInventory instance2 = PlayerSingleton<PlayerInventory>.Instance;
				if ((Object)(object)instance2 == (Object)null)
				{
					SetStatus("Player inventory unavailable");
					return;
				}
				List<HotbarSlot> hotbarSlots = instance2.hotbarSlots;
				if (hotbarSlots == null)
				{
					SetStatus("Hotbar unavailable");