Decompiled source of OverTheCounter v1.3.0

OverTheCounter.Il2Cpp.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
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 Il2Cpp;
using Il2CppFishNet;
using Il2CppFishNet.Connection;
using Il2CppFishNet.Managing;
using Il2CppFishNet.Managing.Object;
using Il2CppFishNet.Object;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.AvatarFramework;
using Il2CppScheduleOne.AvatarFramework.Animation;
using Il2CppScheduleOne.AvatarFramework.Equipping;
using Il2CppScheduleOne.AvatarFramework.Impostors;
using Il2CppScheduleOne.Combat;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Dialogue;
using Il2CppScheduleOne.Doors;
using Il2CppScheduleOne.Economy;
using Il2CppScheduleOne.Employees;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.Interaction;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Law;
using Il2CppScheduleOne.Management;
using Il2CppScheduleOne.Map;
using Il2CppScheduleOne.Messaging;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.NPCs.Behaviour;
using Il2CppScheduleOne.NPCs.Relation;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.Persistence.Datas;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.Police;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Product.Packaging;
using Il2CppScheduleOne.Property;
using Il2CppScheduleOne.Quests;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.Tools;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.Compass;
using Il2CppScheduleOne.UI.Handover;
using Il2CppScheduleOne.UI.Management;
using Il2CppScheduleOne.UI.Phone;
using Il2CppScheduleOne.UI.Phone.ContactsApp;
using Il2CppScheduleOne.UI.Phone.Map;
using Il2CppScheduleOne.UI.Shop;
using Il2CppScheduleOne.Variables;
using Il2CppScheduleOne.VoiceOver;
using Il2CppSteamworks;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
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.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "OverTheCounter", "1.3.0", "hdlmrell", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonOptionalDependencies(new string[] { "SteamNetworkLib" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("OverTheCounter.Il2Cpp")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+de565dbb2b56dd5e21f645dc57046918064cb34f")]
[assembly: AssemblyProduct("OverTheCounter.Il2Cpp")]
[assembly: AssemblyTitle("OverTheCounter.Il2Cpp")]
[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
{
	internal static class PrivateAccess
	{
		public static VODatabase GetDatabase(this VOEmitter emitter)
		{
			return emitter.Database;
		}

		public static CustomerData GetCustData(this Customer customer)
		{
			return customer.customerData;
		}

		public static void SetCustData(this Customer customer, CustomerData data)
		{
			customer.customerData = data;
		}

		public static string GetTitle(this Quest quest)
		{
			return quest.title;
		}

		public static void SetTitle(this Quest quest, string value)
		{
			quest.title = value;
		}

		public static DialogueHandler GetHandler(this DialogueController dc)
		{
			return dc.handler;
		}

		public static ConfigurableTypePanel[] GetConfigPanelPrefabs(this ManagementInterface mi)
		{
			return Il2CppArrayBase<ConfigurableTypePanel>.op_Implicit((Il2CppArrayBase<ConfigurableTypePanel>)(object)mi.ConfigPanelPrefabs);
		}

		public static MSGConversation GetMSGConversation(this NPC npc)
		{
			return npc.MSGConversation;
		}

		public static void SetMSGConversation(this NPC npc, MSGConversation conv)
		{
			npc.MSGConversation = conv;
		}

		public static void SetCurrentBuilding(this NPC npc, NPCEnterableBuilding building)
		{
			npc.CurrentBuilding = building;
		}

		public static void SetTimeSinceLastDealCompleted(this Customer customer, int value)
		{
			customer.TimeSinceLastDealCompleted = value;
		}

		public static void SetTimeSinceLastDealOffered(this Customer customer, int value)
		{
			customer.TimeSinceLastDealOffered = value;
		}

		public static ContractInfo GetOfferedContractInfo(this Customer customer)
		{
			return customer.OfferedContractInfo;
		}

		public static void SetOfferedContractInfo(this Customer customer, ContractInfo info)
		{
			customer.OfferedContractInfo = info;
		}

		public static NPCPoI GetPotentialCustomerPoI(this Customer customer)
		{
			return customer.potentialCustomerPoI;
		}

		public static void SetPotentialCustomerPoI(this Customer customer, NPCPoI poi)
		{
			customer.potentialCustomerPoI = poi;
		}

		public static QuestEntryHUDUI GetEntryUI(this QuestEntry entry)
		{
			return entry.entryUI;
		}

		public static void SetShouldShowCheck(this DialogueChoice choice, Func<bool, bool> func)
		{
			choice.shouldShowCheck = ShouldShowCheck.op_Implicit(func);
		}

		public static ItemSlot[] GetCustomerSlots(this HandoverScreen hs)
		{
			return Il2CppArrayBase<ItemSlot>.op_Implicit((Il2CppArrayBase<ItemSlot>)(object)hs.CustomerSlots);
		}

		public static void TrackItemAsPlayer(this HandoverScreen hs, ItemInstance item)
		{
			hs.OriginalItemLocations[item] = (EItemSource)0;
		}
	}
	public class Core : MelonMod
	{
		private NotificationManager _notificationManager;

		private DesperationManager _desperationManager;

		private DrifterManager _drifterManager;

		private ManagerController _managerManager;

		public override void OnInitializeMelon()
		{
			Config.Initialize();
			NpcTypeDiscoveryPatch.Apply(((MelonBase)this).HarmonyInstance);
			ConfigSyncPatch.TryApply(((MelonBase)this).HarmonyInstance);
			ManagerClipboardPatch.Apply(((MelonBase)this).HarmonyInstance);
			if (!ConfigSyncData.IsNetworkLibAvailable)
			{
				((MelonBase)this).LoggerInstance.Warning("SteamNetworkLib not installed — multiplayer sync disabled. Single-player works fine. Install SteamNetworkLib for co-op support.");
			}
			((MelonBase)this).LoggerInstance.Msg("OverTheCounter Initialized.");
			ImmediateQuestWindowConfig.Register();
			MinimapOverlay.Register();
			ExtractIcons();
			_notificationManager = new NotificationManager(((MelonBase)this).LoggerInstance);
			_desperationManager = new DesperationManager(((MelonBase)this).LoggerInstance);
			_drifterManager = new DrifterManager(((MelonBase)this).LoggerInstance);
			_managerManager = new ManagerController(((MelonBase)this).LoggerInstance);
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			StaticSaveData.ResetInstance();
			VicSaveData.ResetInstance();
			BellaSaveData.ResetInstance();
			StaticIntroQuest.ResetInstance();
			StaticUpgrade1Quest.ResetInstance();
			StaticUpgrade2Quest.ResetInstance();
			VicIntroQuest.ResetInstance();
			BellaProtocolQuest.ResetInstance();
			BellaSummonPatch.Reset();
			ContactsAppFix.Reset();
			DrifterInstance.CleanupAll();
			DrifterSpawner.ResetCache();
			ManagerSaveData.ResetInstance();
			ManagerInstance.CleanupAll();
			ManagerSpawner.ResetCache();
			MugshotUtility.ResetSession();
			if (!Object.op_Implicit((Object)(object)GameObject.Find("OTC_MinimapController")))
			{
				GameObject val = new GameObject("OTC_MinimapController");
				val.AddComponent<MinimapOverlay>();
				Object.DontDestroyOnLoad((Object)val);
			}
		}

		public override void OnLateUpdate()
		{
			try
			{
				ConfigSyncData.EnsureNetworkReady();
				ConfigSyncData.ProcessMessages();
				_notificationManager.ProcessContractState();
				VicSaveData.Instance?.Tick();
				StaticSaveData.Instance?.Tick();
				BellaSaveData.Instance?.Tick();
				ManagerSaveData.Instance?.Tick();
				ContactsAppFix.Tick();
				_drifterManager?.RetryPendingAdoptions();
				ManagerInstance.RetryPendingAdoptions();
				_managerManager?.CheckImmediateWages();
				foreach (ManagerInstance value in ManagerInstance.Active.Values)
				{
					value.EnsureMoving();
				}
				if (NetworkHelper.IsHost)
				{
					foreach (ManagerInstance value2 in ManagerInstance.Active.Values)
					{
						value2.SupplyBehaviour?.Tick();
						value2.DistributionBehaviour?.Tick();
					}
					if (ManagerInstance.HasPendingMessages)
					{
						ConfigSyncData.Instance?.PublishManagerMessages();
					}
					if (DrifterManager.HasPendingDrifterMessages)
					{
						ConfigSyncData.Instance?.PublishDrifterMessages();
					}
					if (ManagerInstance.StatePublishNeeded)
					{
						ManagerInstance.StatePublishNeeded = false;
						ConfigSyncData.Instance?.PublishManagerState();
					}
				}
				_drifterManager?.ClientQuestTick();
			}
			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();
			_drifterManager?.Cleanup();
			_managerManager?.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, "DrifterQuestIcon.png");
			ExtractResource(text, "DrifterProfileIcon.png");
			ExtractResource(text, "RinseCycle.png");
			ExtractResource(text, "CrimeWareQuest.png");
			ExtractResource(text, "ExecutivePrivilege.png");
			ExtractResource(text, "ManagerIcon.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<bool> DesperationEnabled;

		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<bool> ConsolidationEnabled;

		public static ConfigEntry<int> ConsolidationThreshold;

		private static MelonPreferences_Category _managers;

		public static ConfigEntry<float> ManagerDailyWage;

		public static ConfigEntry<float> ManagerSigningFee;

		public static ConfigEntry<bool> ManagerVerboseLogging;

		public static ConfigEntry<bool> AlternateHire;

		private static MelonPreferences_Category _debug;

		public static ConfigEntry<bool> VerboseLogging;

		private static MelonPreferences_Category _bella;

		public static ConfigEntry<float> BellaWeedValue;

		public static ConfigEntry<float> BellaMethValue;

		public static ConfigEntry<float> BellaCokeValue;

		private static MelonPreferences_Category _drifters;

		public static ConfigEntry<bool> DrifterEnabled;

		public static ConfigEntry<float> DrifterSpawnChancePerHour;

		public static ConfigEntry<int> MaxActiveDrifters;

		public static ConfigEntry<int> DrifterDayStartHour;

		public static ConfigEntry<int> DrifterDayEndHour;

		public static ConfigEntry<int> DrifterOfferWindowMin;

		public static ConfigEntry<int> DrifterDeliveryDeadlineMin;

		public static ConfigEntry<int> DrifterLingerMinMin;

		public static ConfigEntry<int> DrifterLingerMaxMin;

		public static ConfigEntry<float> DrifterMinDealValue;

		private static MelonPreferences_Category _minimap;

		public static ConfigEntry<bool> MinimapEnabled;

		public static ConfigEntry<int> MinimapSize;

		public static ConfigEntry<bool> MinimapRotateWithPlayer;

		public static ConfigEntry<bool> MinimapCircle;

		public static ConfigEntry<int> MinimapDefaultZoom;

		public static ConfigEntry<float> MinimapIconScale;

		public static MelonPreferences_Entry<KeyCode> MinimapToggleKey;

		public static MelonPreferences_Entry<string> MinimapPosition;

		public static MelonPreferences_Entry<Color> MinimapBorderColor;

		public static ConfigEntry<int> MinimapBorderWidth;

		public static ConfigEntry<bool> MinimapShowTime;

		public static ConfigEntry<bool> MinimapShowDay;

		public static ConfigEntry<bool> MinimapUse24HourClock;

		private static MelonPreferences_Category _minimapPoi;

		public static ConfigEntry<bool> MinimapShowPotentialCustomers;

		public static ConfigEntry<bool> MinimapShowCustomers;

		public static ConfigEntry<bool> MinimapShowDealers;

		public static ConfigEntry<bool> MinimapShowDeadDrops;

		public static ConfigEntry<bool> MinimapShowContracts;

		public static ConfigEntry<bool> MinimapShowQuests;

		public static ConfigEntry<bool> MinimapShowProperties;

		public static ConfigEntry<bool> MinimapShowManagers;

		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 Dictionary<string, ConfigEntry<bool>> _boolEntries = new Dictionary<string, ConfigEntry<bool>>();

		private static readonly HashSet<string> _localOnlyKeys = new HashSet<string>
		{
			"ConsolidationEnabled", "ConsolidationThreshold", "ManagerVerboseLogging", "VerboseLogging", "MinimapEnabled", "MinimapSize", "MinimapRotateWithPlayer", "MinimapCircle", "MinimapDefaultZoom", "MinimapIconScale",
			"MinimapBorderWidth", "MinimapShowTime", "MinimapShowDay", "MinimapUse24HourClock", "MinimapShowPotentialCustomers", "MinimapShowCustomers", "MinimapShowDealers", "MinimapShowDeadDrops", "MinimapShowContracts", "MinimapShowQuests",
			"MinimapShowProperties", "MinimapShowManagers"
		};

		public static void Initialize()
		{
			//IL_09b5: Unknown result type (might be due to invalid IL or missing references)
			_desperation = MelonPreferences.CreateCategory("OverTheCounter", "Desperation System");
			DesperationEnabled = Register(_desperation.CreateEntry<bool>("Enabled", true, "Enabled", "Enable/disable the desperation system (urgent fiend requests)", false, false, (ValueValidator)null, (string)null));
			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");
			ConsolidationEnabled = Register(_notifications.CreateEntry<bool>("Enabled", true, "Enabled", "Enable/disable contract consolidation (groups same-window deliveries into one HUD entry)", false, false, (ValueValidator)null, (string)null));
			ConsolidationThreshold = Register(_notifications.CreateEntry<int>("ConsolidationThreshold", 5, "Consolidation Threshold", "Minimum contracts in a window before consolidation kicks in", false, false, (ValueValidator)null, (string)null));
			_managers = MelonPreferences.CreateCategory("OverTheCounter_Managers", "Manager System");
			ManagerDailyWage = Register(_managers.CreateEntry<float>("ManagerDailyWage", 350f, "Base Daily Wage", "Base daily wage before upgrade fees are added", false, false, (ValueValidator)null, (string)null));
			ManagerSigningFee = Register(_managers.CreateEntry<float>("ManagerSigningFee", 3000f, "Signing Fee", "One-time fee deducted from player cash when hiring a manager", false, false, (ValueValidator)null, (string)null));
			ManagerVerboseLogging = Register(_managers.CreateEntry<bool>("ManagerVerboseLogging", false, "Verbose Logging", "Enable detailed manager logging for troubleshooting (shopping list breakdowns, per-item details)", false, false, (ValueValidator)null, (string)null));
			AlternateHire = Register(_managers.CreateEntry<bool>("AlternateHire", false, "Alternate Hire", "Show hire buttons in the OTC app instead of using Manny's dialogue. Enable if another mod conflicts with Manny.", false, false, (ValueValidator)null, (string)null));
			_debug = MelonPreferences.CreateCategory("OverTheCounter_Debug", "Debug");
			VerboseLogging = Register(_debug.CreateEntry<bool>("VerboseLogging", false, "Verbose Logging", "Enable detailed logging for troubleshooting (drifters, quests, sync, NPCs)", false, false, (ValueValidator)null, (string)null));
			_bella = MelonPreferences.CreateCategory("OverTheCounter_Bella", "Bella Protocol");
			BellaWeedValue = Register(_bella.CreateEntry<float>("BellaWeedValue", 105f, "Weed Mix Value", "Minimum base price for the weed mix Bella requires", false, false, (ValueValidator)null, (string)null));
			BellaMethValue = Register(_bella.CreateEntry<float>("BellaMethValue", 200f, "Meth Mix Value", "Minimum base price for the meth mix Bella requires", false, false, (ValueValidator)null, (string)null));
			BellaCokeValue = Register(_bella.CreateEntry<float>("BellaCokeValue", 400f, "Cocaine Mix Value", "Minimum base price for the cocaine mix Bella requires", false, false, (ValueValidator)null, (string)null));
			_drifters = MelonPreferences.CreateCategory("OverTheCounter_Drifters", "Drifter System");
			DrifterEnabled = Register(_drifters.CreateEntry<bool>("Enabled", true, "Enabled", "Enable/disable the drifter system (random street NPCs offering one-time deals)", false, false, (ValueValidator)null, (string)null));
			DrifterSpawnChancePerHour = Register(_drifters.CreateEntry<float>("DrifterSpawnChancePerHour", 0.38f, "Spawn Chance Per Hour", "Base spawn chance per hour at max regions. Scaled down by unlocked region count (0.0-1.0)", false, false, (ValueValidator)null, (string)null));
			MaxActiveDrifters = Register(_drifters.CreateEntry<int>("MaxActiveDrifters", 3, "Max Active Drifters", "Maximum number of drifters that can be active at once", false, false, (ValueValidator)null, (string)null));
			DrifterDayStartHour = Register(_drifters.CreateEntry<int>("DrifterDayStartHour", 800, "Day Start Hour", "Earliest 24h time for drifter spawns (800 = 8:00 AM)", false, false, (ValueValidator)null, (string)null));
			DrifterDayEndHour = Register(_drifters.CreateEntry<int>("DrifterDayEndHour", 2100, "Day End Hour", "Latest 24h time for drifter spawns (2100 = 9:00 PM)", false, false, (ValueValidator)null, (string)null));
			DrifterOfferWindowMin = Register(_drifters.CreateEntry<int>("DrifterOfferWindowMin", 120, "Offer Window (min)", "Minutes player has to respond to a drifter offer (120 = 2 hours)", false, false, (ValueValidator)null, (string)null));
			DrifterDeliveryDeadlineMin = Register(_drifters.CreateEntry<int>("DrifterDeliveryDeadlineMin", 240, "Delivery Deadline (min)", "Minutes to deliver after accepting a drifter deal (240 = 4 hours)", false, false, (ValueValidator)null, (string)null));
			DrifterLingerMinMin = Register(_drifters.CreateEntry<int>("DrifterLingerMinMin", 30, "Linger Min (min)", "Minimum minutes a drifter lingers after deal completion/expiry", false, false, (ValueValidator)null, (string)null));
			DrifterLingerMaxMin = Register(_drifters.CreateEntry<int>("DrifterLingerMaxMin", 60, "Linger Max (min)", "Maximum minutes a drifter lingers after deal completion/expiry", false, false, (ValueValidator)null, (string)null));
			DrifterMinDealValue = Register(_drifters.CreateEntry<float>("DrifterMinDealValue", 90f, "Min Deal Value ($)", "Soft minimum deal value - drifters ask for more quantity until the deal reaches this threshold", false, false, (ValueValidator)null, (string)null));
			_minimap = MelonPreferences.CreateCategory("OverTheCounter_Minimap", "Minimap");
			MinimapEnabled = Register(_minimap.CreateEntry<bool>("MinimapEnabled", false, "Enabled", "Show the minimap overlay", false, false, (ValueValidator)null, (string)null));
			MinimapSize = Register(_minimap.CreateEntry<int>("MinimapSize", 250, "Size (px)", "Minimap size in pixels", false, false, (ValueValidator)null, (string)null));
			MinimapRotateWithPlayer = Register(_minimap.CreateEntry<bool>("MinimapRotateWithPlayer", false, "Rotate With Player", "Rotate minimap to match player facing direction", false, false, (ValueValidator)null, (string)null));
			MinimapCircle = Register(_minimap.CreateEntry<bool>("MinimapCircle", false, "Circle Shape", "Use circular minimap shape instead of square", false, false, (ValueValidator)null, (string)null));
			MinimapDefaultZoom = Register(_minimap.CreateEntry<int>("MinimapDefaultZoom", 2, "Default Zoom", "Starting zoom level, 1=closest, 3=farthest (1-3)", false, false, (ValueValidator)null, (string)null));
			MinimapIconScale = Register(_minimap.CreateEntry<float>("MinimapIconScale", 0.7f, "Icon Scale", "POI icon scale on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapToggleKey = _minimap.CreateEntry<KeyCode>("MinimapToggleKey", (KeyCode)110, "Toggle Key", "Hotkey to cycle minimap zoom", false, false, (ValueValidator)null, (string)null);
			MinimapPosition = _minimap.CreateEntry<string>("MinimapPosition", "TopRight", "Position", "TopLeft, TopRight, BottomLeft, BottomRight", false, false, (ValueValidator)null, (string)null);
			MinimapBorderColor = _minimap.CreateEntry<Color>("MinimapBorderColor", new Color(0.2f, 0.2f, 0.2f, 0.9f), "Border Color", "Minimap border color", false, false, (ValueValidator)null, (string)null);
			MinimapBorderWidth = Register(_minimap.CreateEntry<int>("MinimapBorderWidth", 4, "Border Width", "Border thickness in pixels per side (2-10)", false, false, (ValueValidator)null, (string)null));
			MinimapShowTime = Register(_minimap.CreateEntry<bool>("MinimapShowTime", true, "Show Time", "Display the current time near the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowDay = Register(_minimap.CreateEntry<bool>("MinimapShowDay", true, "Show Day", "Display the current day near the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapUse24HourClock = Register(_minimap.CreateEntry<bool>("MinimapUse24HourClock", false, "24-Hour Clock", "Use 24-hour time format instead of 12-hour AM/PM", false, false, (ValueValidator)null, (string)null));
			_minimapPoi = MelonPreferences.CreateCategory("OverTheCounter_MinimapPOI", "Minimap POIs");
			MinimapShowPotentialCustomers = Register(_minimapPoi.CreateEntry<bool>("MinimapShowPotentialCustomers", true, "Show Potential Customers", "Show potential customer icons on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowCustomers = Register(_minimapPoi.CreateEntry<bool>("MinimapShowCustomers", false, "Show Customers", "Show unlocked customer icons on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowDealers = Register(_minimapPoi.CreateEntry<bool>("MinimapShowDealers", true, "Show Dealers", "Show dealer icons on the minimap (potential and active)", false, false, (ValueValidator)null, (string)null));
			MinimapShowDeadDrops = Register(_minimapPoi.CreateEntry<bool>("MinimapShowDeadDrops", true, "Show Dead Drops", "Show dead drop icons on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowContracts = Register(_minimapPoi.CreateEntry<bool>("MinimapShowContracts", true, "Show Contracts", "Show contract delivery icons on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowQuests = Register(_minimapPoi.CreateEntry<bool>("MinimapShowQuests", true, "Show Quests", "Show quest objective icons on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowProperties = Register(_minimapPoi.CreateEntry<bool>("MinimapShowProperties", true, "Show Properties", "Show owned property icons on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowManagers = Register(_minimapPoi.CreateEntry<bool>("MinimapShowManagers", true, "Show Managers", "Show manager icons on the minimap", 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;
		}

		private static ConfigEntry<bool> Register(MelonPreferences_Entry<bool> entry)
		{
			ConfigEntry<bool> configEntry = new ConfigEntry<bool>(entry);
			_boolEntries[((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));
				}
			}
			foreach (KeyValuePair<string, ConfigEntry<bool>> boolEntry in _boolEntries)
			{
				if (!_localOnlyKeys.Contains(boolEntry.Key))
				{
					list.Add($"{boolEntry.Key}={boolEntry.Value.RawEntry.Value}");
				}
			}
			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;
				ConfigEntry<bool> value3;
				bool result3;
				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))
				{
					if (int.TryParse(datum.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2))
					{
						value2.SetOverride(result2);
					}
				}
				else if (_boolEntries.TryGetValue(datum.Key, out value3) && bool.TryParse(datum.Value, out result3))
				{
					value3.SetOverride(result3);
				}
			}
		}

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

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

		private QuestEntry _meetVicEntry;

		private QuestEntry _bringWeedEntry;

		private static readonly Vector3 VicPosition = new Vector3(67.75f, 0.97f, 32.36f);

		protected override string Title => "Rinse Cycle";

		protected override string Description => "Help Vic with his party supplies and he'll help you clean some cash.";

		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;

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

		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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			((Saveable)this).OnLoaded();
			Instance = this;
			try
			{
				if (VicSaveData.Instance != null)
				{
					int num = (VicSaveData.Instance.Unlocked ? 3 : (VicSaveData.Instance.QuestAccepted ? 2 : (VicSaveData.Instance.HasBeenTexted ? 1 : 0)));
					if (num > _stage)
					{
						_stage = num;
					}
				}
				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("OTC: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", "CrimeWareQuest.png"));

		public static StaticIntroQuest Instance { get; private set; }

		public int Stage => _stage;

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

		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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			((Saveable)this).OnLoaded();
			Instance = this;
			try
			{
				if (StaticSaveData.Instance != null)
				{
					int num = ((StaticSaveData.Instance.CrmTier >= 1) ? 3 : (StaticSaveData.Instance.IntroCompleted ? 2 : (StaticSaveData.Instance.QuestTriggered ? 1 : 0)));
					if (num > _stage)
					{
						_stage = num;
					}
				}
				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("OTC: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", "CrimeWareQuest.png"));

		public static StaticUpgrade1Quest Instance { get; private set; }

		public int Stage => _stage;

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

		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("OTC: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", "CrimeWareQuest.png"));

		public static StaticUpgrade2Quest Instance { get; private set; }

		public int Stage => _stage;

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

		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);
			}
		}
	}
	public class DrifterDealQuest : Quest
	{
		private static readonly Instance Logger = new Instance("OTC:DrifterDealQuest");

		private string _title;

		private string _description;

		private QuestEntry _deliverEntry;

		private int _deadlineElapsedMinutes;

		protected override string Title => _title ?? "Drifter Deal";

		protected override string Description => _description ?? "Complete a deal with a drifter.";

		protected override bool AutoBegin => false;

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

		public string DrifterId { get; private set; }

		public static Dictionary<string, DrifterDealQuest> ActiveQuests { get; } = new Dictionary<string, DrifterDealQuest>();


		private Quest GetS1Quest()
		{
			object? obj = typeof(Quest).GetField("S1Quest", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(this);
			return (Quest)((obj is Quest) ? obj : null);
		}

		private void TriggerInternalInit()
		{
			try
			{
				Quest s1Quest = GetS1Quest();
				if (!((Object)(object)s1Quest == (Object)null))
				{
					s1Quest.InitializeQuest(((Quest)this).Title, ((Quest)this).Description, Il2CppReferenceArray<QuestEntryData>.op_Implicit(Array.Empty<QuestEntryData>()), s1Quest.StaticGUID);
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TriggerInternalInit failed: " + ex.Message);
			}
		}

		public void Initialize(string drifterId, string productName, int quantity, float payment, Vector3 destination, string locationDesc, int deadlineElapsedMinutes)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			DrifterId = drifterId;
			_title = "Drifter Deal";
			_description = $"Deliver {quantity} {productName} for ${payment:F0}";
			_deadlineElapsedMinutes = deadlineElapsedMinutes;
			TriggerInternalInit();
			_deliverEntry = ((Quest)this).AddEntry($"Deliver {quantity} {productName} to the drifter {locationDesc}", (Vector3?)destination);
			ActiveQuests[drifterId] = this;
		}

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

		public void UpdateTiming()
		{
			try
			{
				if (_deadlineElapsedMinutes > 0)
				{
					int currentElapsedMinutes = GetCurrentElapsedMinutes();
					int num = _deadlineElapsedMinutes - currentElapsedMinutes;
					if (num < 0)
					{
						num = 0;
					}
					int num2 = num / 60;
					int value = num % 60;
					string subtitleViaReflection = ((num >= 120) ? $"<color=green> (Expires in {num2}h {value}m)</color>" : ((num2 <= 0) ? $"<color=#ff6b6b> (Expires in {num} min)</color>" : $"<color=#ff6b6b> (Expires in {num2}h {value}m)</color>"));
					SetSubtitleViaReflection(subtitleViaReflection);
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("UpdateTiming failed: " + ex.Message);
			}
		}

		private void SetSubtitleViaReflection(string subtitle)
		{
			try
			{
				Quest s1Quest = GetS1Quest();
				if (!((Object)(object)s1Quest == (Object)null))
				{
					s1Quest.SetSubtitle(subtitle);
					if ((Object)(object)s1Quest.hudUI != (Object)null)
					{
						s1Quest.hudUI.UpdateMainLabel();
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("SetSubtitleViaReflection failed: " + ex.Message);
			}
		}

		private static int GetCurrentElapsedMinutes()
		{
			int elapsedDays = TimeManager.ElapsedDays;
			int currentTime = TimeManager.CurrentTime;
			int num = currentTime / 100;
			int num2 = currentTime % 100;
			return elapsedDays * 1440 + num * 60 + num2;
		}

		public void CompleteDeal()
		{
			try
			{
				QuestEntry deliverEntry = _deliverEntry;
				if (deliverEntry != null)
				{
					deliverEntry.Complete();
				}
				((Quest)this).Complete();
				((Quest)this).End();
				ActiveQuests.Remove(DrifterId);
			}
			catch (Exception ex)
			{
				Logger.Error("CompleteDeal failed: " + ex.Message);
			}
		}

		public void FailDeal()
		{
			try
			{
				QuestEntry deliverEntry = _deliverEntry;
				if (deliverEntry != null)
				{
					deliverEntry.Complete();
				}
				((Quest)this).Fail();
				ActiveQuests.Remove(DrifterId);
			}
			catch (Exception ex)
			{
				Logger.Error("FailDeal failed: " + ex.Message);
			}
		}

		public void CancelDeal()
		{
			try
			{
				((Quest)this).Cancel();
				ActiveQuests.Remove(DrifterId);
			}
			catch (Exception ex)
			{
				Logger.Error("CancelDeal failed: " + ex.Message);
			}
		}
	}
	public class BellaProtocolQuest : Quest
	{
		private static readonly Instance Logger = new Instance("OTC:BellaProtocolQuest");

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

		private QuestEntry _visitEntry;

		private QuestEntry _weedEntry;

		private QuestEntry _methEntry;

		private QuestEntry _cokeEntry;

		private static readonly Vector3 BellaBuilding = new Vector3(74.1f, 1f, 57.2f);

		protected override string Title => "Executive Privilege";

		protected override string Description => "Someone at the Fixer's mentioned a contact who can help with warehouse access.";

		protected override bool AutoBegin => false;

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

		public static BellaProtocolQuest Instance { get; private set; }

		public int Stage => _stage;

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

		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)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				TriggerInternalInit();
				_visitEntry = ((Quest)this).AddEntry("Visit Bella at the downtown apartment", (Vector3?)BellaBuilding);
				_weedEntry = ((Quest)this).AddEntry(GetWeedText(), (Vector3?)BellaBuilding);
				_methEntry = ((Quest)this).AddEntry(GetMethText(), (Vector3?)BellaBuilding);
				_cokeEntry = ((Quest)this).AddEntry(GetCokeText(), (Vector3?)BellaBuilding);
			}
			catch (Exception ex)
			{
				Logger.Error("Initialize failed: " + ex.Message);
			}
		}

		private static string GetWeedText()
		{
			return $"Bring Bella a weed mix worth ${Config.BellaWeedValue.Value:N0}+";
		}

		private static string GetMethText()
		{
			return $"Bring Bella a meth mix worth ${Config.BellaMethValue.Value:N0}+";
		}

		private static string GetCokeText()
		{
			return $"Bring Bella a cocaine mix worth ${Config.BellaCokeValue.Value:N0}+";
		}

		public void RefreshEntryText()
		{
			if (_weedEntry != null && _stage == 2)
			{
				_weedEntry.Title = GetWeedText();
			}
			if (_methEntry != null && _stage == 3)
			{
				_methEntry.Title = GetMethText();
			}
			if (_cokeEntry != null && _stage == 4)
			{
				_cokeEntry.Title = GetCokeText();
			}
		}

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

		public void AdvanceToWeedRequest()
		{
			try
			{
				_stage = 2;
				QuestEntry visitEntry = _visitEntry;
				if (visitEntry != null)
				{
					visitEntry.Complete();
				}
				QuestEntry weedEntry = _weedEntry;
				if (weedEntry != null)
				{
					weedEntry.Begin();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("AdvanceToWeedRequest failed: " + ex.Message);
			}
		}

		public void AdvanceToMethRequest()
		{
			try
			{
				_stage = 3;
				QuestEntry weedEntry = _weedEntry;
				if (weedEntry != null)
				{
					weedEntry.Complete();
				}
				QuestEntry methEntry = _methEntry;
				if (methEntry != null)
				{
					methEntry.Begin();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("AdvanceToMethRequest failed: " + ex.Message);
			}
		}

		public void AdvanceToCocaineRequest()
		{
			try
			{
				_stage = 4;
				QuestEntry methEntry = _methEntry;
				if (methEntry != null)
				{
					methEntry.Complete();
				}
				QuestEntry cokeEntry = _cokeEntry;
				if (cokeEntry != null)
				{
					cokeEntry.Begin();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("AdvanceToCocaineRequest failed: " + ex.Message);
			}
		}

		public void CompleteQuest()
		{
			try
			{
				_stage = 5;
				QuestEntry cokeEntry = _cokeEntry;
				if (cokeEntry != null)
				{
					cokeEntry.Complete();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("CompleteQuest failed: " + ex.Message);
			}
		}

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

		protected override void OnLoaded()
		{
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			((Saveable)this).OnLoaded();
			Instance = this;
			try
			{
				int stage = _stage;
				int value = BellaSaveData.Instance?.Stage ?? (-1);
				if (Config.VerboseLogging.Value)
				{
					Logger.Msg($"OnLoaded: save _stage={stage}, BellaSaveData.Stage={value}");
				}
				if (BellaSaveData.Instance != null && BellaSaveData.Instance.Stage > _stage)
				{
					_stage = BellaSaveData.Instance.Stage;
				}
				if (Config.VerboseLogging.Value)
				{
					Logger.Msg($"OnLoaded: rebuilding entries at _stage={_stage}");
				}
				base.QuestEntries.Clear();
				_visitEntry = ((Quest)this).AddEntry("Visit Bella at the downtown apartment", (Vector3?)BellaBuilding);
				_weedEntry = ((Quest)this).AddEntry(GetWeedText(), (Vector3?)BellaBuilding);
				_methEntry = ((Quest)this).AddEntry(GetMethText(), (Vector3?)BellaBuilding);
				_cokeEntry = ((Quest)this).AddEntry(GetCokeText(), (Vector3?)BellaBuilding);
				if (_stage >= 1)
				{
					QuestEntry visitEntry = _visitEntry;
					if (visitEntry != null)
					{
						visitEntry.Begin();
					}
				}
				if (_stage >= 2)
				{
					QuestEntry visitEntry2 = _visitEntry;
					if (visitEntry2 != null)
					{
						visitEntry2.Complete();
					}
					QuestEntry weedEntry = _weedEntry;
					if (weedEntry != null)
					{
						weedEntry.Begin();
					}
				}
				if (_stage >= 3)
				{
					QuestEntry weedEntry2 = _weedEntry;
					if (weedEntry2 != null)
					{
						weedEntry2.Complete();
					}
					QuestEntry methEntry = _methEntry;
					if (methEntry != null)
					{
						methEntry.Begin();
					}
				}
				if (_stage >= 4)
				{
					QuestEntry methEntry2 = _methEntry;
					if (methEntry2 != null)
					{
						methEntry2.Complete();
					}
					QuestEntry cokeEntry = _cokeEntry;
					if (cokeEntry != null)
					{
						cokeEntry.Begin();
					}
				}
				if (_stage >= 5)
				{
					QuestEntry cokeEntry2 = _cokeEntry;
					if (cokeEntry2 != null)
					{
						cokeEntry2.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("OTC: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 bool _needsStatePublish;

		private bool _questReconciled;

		private int _tickCounter;

		private const int TICK_INTERVAL = 300;

		private bool _positionFixed;

		internal bool _dialogueStale;

		private bool _wasInDialogue;

		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();
					_dialogueStale = true;
					ConfigSyncData.Instance?.PublishGameState();
				}
			}
		}

		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;
			}
			_dialogueStale = true;
			if (_hasBeenTexted)
			{
				_questCreated = true;
				if (NetworkHelper.IsHost)
				{
					_needsStatePublish = true;
				}
				ConfigSyncData.ApplyPendingGameState();
				ReconcileQuest();
			}
			else
			{
				ConfigSyncData.ApplyPendingGameState();
				if (_triggerPendingDay < 0 && IsCleanCashQuestStarted())
				{
					_triggerPendingDay = 0;
				}
			}
		}

		private void ReconcileQuest()
		{
			if (VicIntroQuest.Instance == null)
			{
				return;
			}
			int num = (_unlocked ? 3 : (_questAccepted ? 2 : (_hasBeenTexted ? 1 : 0)));
			if (num > VicIntroQuest.Instance.Stage)
			{
				if (num >= 2 && VicIntroQuest.Instance.Stage < 2)
				{
					VicIntroQuest.Instance.CompleteObj1();
				}
				if (num >= 3 && VicIntroQuest.Instance.Stage < 3)
				{
					VicIntroQuest.Instance.CompleteObj2();
				}
			}
		}

		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 (!_questReconciled && _hasBeenTexted && VicIntroQuest.Instance != null)
			{
				_questReconciled = true;
				int num = (_unlocked ? 3 : ((!_questAccepted) ? 1 : 2));
				if (VicIntroQuest.Instance.Stage < num)
				{
					if (Config.VerboseLogging.Value)
					{
						Logger.Msg($"Tick reconciliation: quest stage {VicIntroQuest.Instance.Stage} → {num}");
					}
					ReconcileQuest();
				}
			}
			bool flag = VicNPC.Instance != null && VicNPC.Instance.IsInDialogue;
			if (_wasInDialogue && !flag)
			{
				_dialogueStale = true;
			}
			_wasInDialogue = flag;
			if (_dialogueStale && VicNPC.Instance != null && VicNPC.Instance.DialogueReady && !flag)
			{
				_dialogueStale = false;
				try
				{
					VicNPC.Instance.RefreshDialogue();
				}
				catch (Exception)
				{
				}
			}
			if (_needsStatePublish && NetworkHelper.IsHost)
			{
				_needsStatePublish = false;
				ConfigSyncData.Instance?.PublishGameState();
			}
			if (NetworkHelper.IsHost && !_staleCheckDone && _hasBeenTexted)
			{
				_staleCheckDone = true;
				if (!_unlocked && !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)
			{
				_dialogueStale = true;
			}
		}

		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 num = (_lastDepositDay = TimeManager.ElapsedDays);
				if (_lastTrustIncrementDay < num)
				{
					_lastTrustIncrementDay = num;
					_trustLevel++;
				}
				break;
			}
			default:
				Logger.Warning("VicSaveData: unknown remote action '" + action + "'");
				return;
			}
			_dialogueStale = true;
			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("OTC: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 _wasInDialogue;

		private bool _questCreated;

		private bool _needsStatePublish;

		private bool _questReconciled;

		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;
				if (NetworkHelper.IsHost)
				{
					_needsStatePublish = true;
				}
			}
			_dialogueStale = true;
			ConfigSyncData.ApplyPendingGameState();
			ReconcileQuest();
		}

		private void ReconcileQuest()
		{
			if (StaticIntroQuest.Instance == null)
			{
				return;
			}
			int num = ((_crmTier >= 1) ? 3 : (_introCompleted ? 2 : (_questTriggered ? 1 : 0)));
			if (num > StaticIntroQuest.Instance.Stage)
			{
				if (num >= 2 && StaticIntroQuest.Instance.Stage < 2)
				{
					StaticIntroQuest.Instance.CompleteObj1();
				}
				if (num >= 3 && StaticIntroQuest.Instance.Stage < 3)
				{
					StaticIntroQuest.Instance.CompleteObj2();
				}
			}
		}

		public void Tick()
		{
			if (!_questReconciled && _questTriggered && StaticIntroQuest.Instance != null)
			{
				_questReconciled = true;
				int num = ((_crmTier >= 1) ? 3 : ((!_introCompleted) ? 1 : 2));
				if (StaticIntroQuest.Instance.Stage < num)
				{
					if (Config.VerboseLogging.Value)
					{
						Logger.Msg($"Tick reconciliation: quest stage {StaticIntroQuest.Instance.Stage} → {num}");
					}
					ReconcileQuest();
				}
			}
			bool flag = StaticNPC.Instance != null && StaticNPC.Instance.IsInDialogue;
			if (_wasInDialogue && !flag)
			{
				_dialogueStale = true;
			}
			_wasInDialogue = flag;
			if (_needsStatePublish && NetworkHelper.IsHost)
			{
				_needsStatePublish = false;
				ConfigSyncData.Instance?.PublishGameState();
			}
			if (_dialogueStale && StaticNPC.Instance != null && StaticNPC.Instance.DialogueReady && !flag)
			{
				_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);
			}
		}
	}
	public class ConfigSyncData : Saveable
	{
		private static readonly Instance Logger = new Instance("OTC:ConfigSync");

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

		private static Dictionary<string, string> _pendingGameState;

		private static int _msgSeq;

		private static int _actionSeq;

		private static bool? _networkLibAvailable;

		public static ConfigSyncData Instance { get; private set; }

		internal static bool IsNetworkLibAvailable
		{
			get
			{
				bool valueOrDefault = _networkLibAvailable.GetValueOrDefault();
				if (!_networkLibAvailable.HasValue)
				{
					valueOrDefault = AppDomain.CurrentDomain.GetAssemblies().Any((Assembly a) => a.GetName().Name.Contains("SteamNetworkLib"));
					_networkLibAvailable = valueOrDefault;
					return valueOrDefault;
				}
				return valueOrDefault;
			}
		}

		public ConfigSyncData()
		{
			Instance = this;
		}

		protected override void OnLoaded()
		{
			Instance = this;
			_pendingGameState = null;
			Config.ClearAllOverrides();
			if (IsNetworkLibAvailable)
			{
				OnLoadedNetworkPush();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void OnLoadedNetworkPush()
		{
			NetworkSyncBridge.PushOnLoaded(Config.SerializeAll(), SerializeGameState(), DrifterManager.Instance?.SerializeDrifterState() ?? "");
		}

		public static void EnsureNetworkReady()
		{
			if (IsNetworkLibAvailable)
			{
				EnsureNetworkReadyImpl();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void EnsureNetworkReadyImpl()
		{
			NetworkSyncBridge.EnsureNetworkReady();
		}

		public static void ProcessMessages()
		{
			if (IsNetworkLibAvailable)
			{
				ProcessMessagesImpl();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void ProcessMessagesImpl()
		{
			NetworkSyncBridge.ProcessMessages();
		}

		public static void Cleanup()
		{
			_pendingGameState = null;
			if (IsNetworkLibAvailable)
			{
				CleanupImpl();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void CleanupImpl()
		{
			NetworkSyncBridge.Cleanup();
		}

		public void RefreshFromConfig()
		{
			if (NetworkHelper.IsHost)
			{
				_payload = Config.SerializeAll();
				if (IsNetworkLibAvailable)
				{
					RefreshFromConfigImpl(_payload);
				}
				RefreshQuestText();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void RefreshFromConfigImpl(string payload)
		{
			NetworkSyncBridge.PushConfig(payload);
		}

		public void PublishGameState()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			try
			{
				string text = SerializeGameState();
				if (Config.VerboseLogging.Value)
				{
					Logger.Msg($"PublishGameState: payload length={text?.Length ?? 0}");
				}
				if (IsNetworkLibAvailable)
				{
					PublishGameStateImpl(text);
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("PublishGameState failed: " + ex.Message);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void PublishGameStateImpl(string payload)
		{
			NetworkSyncBridge.PushState(payload);
		}

		public void PublishDrifterState()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			try
			{
				string payload = DrifterManager.Instance?.SerializeDrifterState() ?? "";
				if (IsNetworkLibAvailable)
				{
					PublishDrifterStateImpl(payload);
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("PublishDrifterState failed: " + ex.Message);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void PublishDrifterStateImpl(string payload)
		{
			NetworkSyncBridge.PushDrifterState(payload);
		}

		public void PublishManagerState()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			ManagerSaveData.Instance?.CaptureState();
			try
			{
				if (IsNetworkLibAvailable)
				{
					PublishManagerStateImpl();
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("PublishManagerState failed: " + ex.Message);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void PublishManagerStateImpl()
		{
			ManagerInstance.PublishAllSlots();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void WriteInitialManagerSlots()
		{
			ManagerInstance.PublishAllSlots();
		}

		public void PublishManagerMessages()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			try
			{
				List<string> list = new List<string>();
				list.Add(_msgSeq++.ToString());
				foreach (ManagerInstance value in ManagerInstance.Active.Values)
				{
					if (!string.IsNullOrEmpty(value.PendingClientMessage))
					{
						list.Add(value.Id + "|" + value.PendingClientMessage);
						value.PendingClientMessage = null;
					}
				}
				ManagerInstance.HasPendingMessages = false;
				if (list.Count > 1 && IsNetworkLibAvailable)
				{
					string text = string.Join(";", list);
					PublishManagerMessagesImpl(text);
					if (Config.VerboseLogging.Value)
					{
						Logger.Msg($"PublishManagerMessages: {text.Length} chars, {list.Count - 1} messages");
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("PublishManagerMessages failed: " + ex.Message);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void PublishManagerMessagesImpl(string payload)
		{
			NetworkSyncBridge.PushManagerMessages(payload);
		}

		public void PublishDrifterMessages()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			try
			{
				List<string> list = new List<string>();
				list.Add(_msgSeq++.ToString());
				DrifterManager instance = DrifterManager.Instance;
				if (instance != null)
				{
					foreach (DrifterEvent value in instance.ActiveEvents.Values)
					{
						if (!string.IsNullOrEmpty(value.PendingClientMessage))
						{
							list.Add(value.DrifterId + "|" + value.PendingClientMessage);
							value.PendingClientMessage = null;
						}
					}
				}
				DrifterManager.HasPendingDrifterMessages = false;
				if (list.Count > 1 && IsNetworkLibAvailable)
				{
					string text = string.Join(";", list);
					PublishDrifterMessagesImpl(text);
					if (Config.VerboseLogging.Value)
					{
						Logger.Msg($"PublishDrifterMessages: {text.Length} chars, {list.Count - 1} messages");
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("PublishDrifterMessages failed: " + ex.Message);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void PublishDrifterMessagesImpl(string payload)
		{
			NetworkSyncBridge.PushDrifterMessages(payload);
		}

		public static void SendQuestAction(string action)
		{
			if (!NetworkHelper.IsHost && IsNetworkLibAvailable)
			{
				SendQuestActionImpl(action);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void SendQuestActionImpl(string action)
		{
			NetworkSyncBridge.SendAction($"{++_actionSeq}:{action}");
		}

		internal static string GetSerializedConfig()
		{
			return Config.SerializeAll();
		}

		internal static string GetSerializedGameState()
		{
			return SerializeGameState();
		}

		internal static string GetSerializedDrifterState()
		{
			return DrifterManager.Instance?.SerializeDrifterState() ?? "";
		}

		internal static void ClearOverridesForHost()
		{
			Config.ClearAllOverrides();
		}

		internal static void HandleConfigChanged(string newValue)
		{
			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("HandleConfigChanged failed: " + ex.Message);
			}
		}

		internal static void HandleStateChanged(string newValue)
		{
			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("HandleStateChanged failed: " + ex.Message);
			}
		}

		internal static void HandleDrifterStateChanged(string newValue)
		{
			try
			{
				DrifterManager.Instance?.ApplyDrifterState(newValue);
				Logger.Msg($"Client applied drifter state from SyncVar ({newValue.Length} chars).");
			}
			catch (Exception ex)
			{
				Logger.Warning("HandleDrifterStateChanged failed: " + ex.Message);
			}
		}

		internal static void HandleManagerSlotChanged(int slot, string newValue)
		{
			try
			{
				ManagerInstance.ApplyManagerSlot(slot, newValue);
				Logger.Msg($"Client applied manager slot {slot} from SyncVar ({newValue?.Length ?? 0} chars).");
			}
			catch (Exception ex)
			{
				Logger.Warning($"HandleManagerSlotChanged[{slot}] failed: {ex.Message}");
			}
		}

		internal static void HandleManagerMessageChanged(string newValue)
		{
			try
			{
				string[] array = newValue.Split(';');
				for (int i = 1; i < array.Length; i++)
				{
					string text = array[i];
					int num = text.IndexOf('|');
					if (num <= 0)
					{
						continue;
					}
					string text2 = text.Substring(0, num);
					string message = text.Substring(num + 1);
					if (ManagerInstance.Active.TryGetValue(text2, out var value))
					{
						value.SendTextMessage(m

OverTheCounter.Mono.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
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 FishNet;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Object;
using FishNet.Object;
using HarmonyLib;
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 ScheduleOne;
using ScheduleOne.AvatarFramework;
using ScheduleOne.AvatarFramework.Animation;
using ScheduleOne.AvatarFramework.Equipping;
using ScheduleOne.AvatarFramework.Impostors;
using ScheduleOne.Combat;
using ScheduleOne.DevUtilities;
using ScheduleOne.Dialogue;
using ScheduleOne.Doors;
using ScheduleOne.Economy;
using ScheduleOne.Employees;
using ScheduleOne.EntityFramework;
using ScheduleOne.GameTime;
using ScheduleOne.Interaction;
using ScheduleOne.ItemFramework;
using ScheduleOne.Law;
using ScheduleOne.Management;
using ScheduleOne.Map;
using ScheduleOne.Messaging;
using ScheduleOne.Money;
using ScheduleOne.NPCs;
using ScheduleOne.NPCs.Behaviour;
using ScheduleOne.NPCs.Relation;
using ScheduleOne.ObjectScripts;
using ScheduleOne.Persistence;
using ScheduleOne.Persistence.Datas;
using ScheduleOne.PlayerScripts;
using ScheduleOne.Police;
using ScheduleOne.Product;
using ScheduleOne.Product.Packaging;
using ScheduleOne.Property;
using ScheduleOne.Quests;
using ScheduleOne.Storage;
using ScheduleOne.Tools;
using ScheduleOne.UI;
using ScheduleOne.UI.Compass;
using ScheduleOne.UI.Handover;
using ScheduleOne.UI.Management;
using ScheduleOne.UI.Phone;
using ScheduleOne.UI.Phone.ContactsApp;
using ScheduleOne.UI.Phone.Map;
using ScheduleOne.UI.Shop;
using ScheduleOne.Variables;
using ScheduleOne.VoiceOver;
using SteamNetworkLib;
using SteamNetworkLib.Sync;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "OverTheCounter", "1.3.0", "hdlmrell", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonOptionalDependencies(new string[] { "SteamNetworkLib" })]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("OverTheCounter.Mono")]
[assembly: AssemblyConfiguration("MonoRelease")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+de565dbb2b56dd5e21f645dc57046918064cb34f")]
[assembly: AssemblyProduct("OverTheCounter.Mono")]
[assembly: AssemblyTitle("OverTheCounter.Mono")]
[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 static class Il2CppCompat
	{
		public static T TryCast<T>(this object obj) where T : class
		{
			return obj as T;
		}

		public static T Cast<T>(this object obj) where T : class
		{
			return (T)obj;
		}
	}
	public static class UnityEventCompat
	{
		public static void AddListener(this UnityEvent ev, Action action)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			ev.AddListener(new UnityAction(action.Invoke));
		}

		public static void RemoveListener(this UnityEvent ev, Action action)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			ev.RemoveListener(new UnityAction(action.Invoke));
		}

		public static void AddListener<T0>(this UnityEvent<T0> ev, Action<T0> action)
		{
			ev.AddListener((UnityAction<T0>)action.Invoke);
		}

		public static void RemoveListener<T0>(this UnityEvent<T0> ev, Action<T0> action)
		{
			ev.RemoveListener((UnityAction<T0>)action.Invoke);
		}
	}
	internal static class PrivateAccess
	{
		private static readonly FieldInfo _voeDatabase = AccessTools.Field(typeof(VOEmitter), "Database");

		private static readonly FieldInfo _customerData = AccessTools.Field(typeof(Customer), "customerData");

		private static readonly FieldInfo _questTitle = AccessTools.Field(typeof(Quest), "title");

		private static readonly FieldInfo _dcHandler = AccessTools.Field(typeof(DialogueController), "handler");

		private static readonly FieldInfo _questEntryUI = AccessTools.Field(typeof(QuestEntry), "entryUI");

		private static readonly FieldInfo _miConfigPanels = AccessTools.Field(typeof(ManagementInterface), "ConfigPanelPrefabs");

		private static readonly PropertyInfo _npcMsgConv = AccessTools.Property(typeof(NPC), "MSGConversation");

		private static readonly PropertyInfo _npcCurrentBuilding = AccessTools.Property(typeof(NPC), "CurrentBuilding");

		private static readonly PropertyInfo _custTimeDealCompleted = AccessTools.Property(typeof(Customer), "TimeSinceLastDealCompleted");

		private static readonly PropertyInfo _custTimeDealOffered = AccessTools.Property(typeof(Customer), "TimeSinceLastDealOffered");

		private static readonly PropertyInfo _custOfferedContract = AccessTools.Property(typeof(Customer), "OfferedContractInfo");

		private static readonly PropertyInfo _custPoI = AccessTools.Property(typeof(Customer), "potentialCustomerPoI");

		private static readonly FieldInfo _hsCustomerSlots = AccessTools.Field(typeof(HandoverScreen), "CustomerSlots");

		private static readonly FieldInfo _hsOriginalItemLocations = AccessTools.Field(typeof(HandoverScreen), "OriginalItemLocations");

		private static readonly Type _hsEItemSource = typeof(HandoverScreen).GetNestedType("EItemSource", BindingFlags.NonPublic);

		private static readonly object _hsEItemSourcePlayer = ((_hsEItemSource != null) ? Enum.Parse(_hsEItemSource, "Player") : null);

		public static VODatabase GetDatabase(this VOEmitter emitter)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return (VODatabase)(_voeDatabase?.GetValue(emitter));
		}

		public static CustomerData GetCustData(this Customer customer)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return (CustomerData)(_customerData?.GetValue(customer));
		}

		public static void SetCustData(this Customer customer, CustomerData data)
		{
			_customerData?.SetValue(customer, data);
		}

		public static string GetTitle(this Quest quest)
		{
			return (string)_questTitle?.GetValue(quest);
		}

		public static void SetTitle(this Quest quest, string value)
		{
			_questTitle?.SetValue(quest, value);
		}

		public static DialogueHandler GetHandler(this DialogueController dc)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return (DialogueHandler)(_dcHandler?.GetValue(dc));
		}

		public static ConfigurableTypePanel[] GetConfigPanelPrefabs(this ManagementInterface mi)
		{
			return (ConfigurableTypePanel[])_miConfigPanels?.GetValue(mi);
		}

		public static MSGConversation GetMSGConversation(this NPC npc)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return (MSGConversation)(_npcMsgConv?.GetValue(npc));
		}

		public static void SetMSGConversation(this NPC npc, MSGConversation conv)
		{
			_npcMsgConv?.SetValue(npc, conv);
		}

		public static void SetCurrentBuilding(this NPC npc, NPCEnterableBuilding building)
		{
			_npcCurrentBuilding?.SetValue(npc, building);
		}

		public static void SetTimeSinceLastDealCompleted(this Customer customer, int value)
		{
			_custTimeDealCompleted?.SetValue(customer, value);
		}

		public static void SetTimeSinceLastDealOffered(this Customer customer, int value)
		{
			_custTimeDealOffered?.SetValue(customer, value);
		}

		public static ContractInfo GetOfferedContractInfo(this Customer customer)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return (ContractInfo)(_custOfferedContract?.GetValue(customer));
		}

		public static void SetOfferedContractInfo(this Customer customer, ContractInfo info)
		{
			_custOfferedContract?.SetValue(customer, info);
		}

		public static NPCPoI GetPotentialCustomerPoI(this Customer customer)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return (NPCPoI)(_custPoI?.GetValue(customer));
		}

		public static void SetPotentialCustomerPoI(this Customer customer, NPCPoI poi)
		{
			_custPoI?.SetValue(customer, poi);
		}

		public static QuestEntryHUDUI GetEntryUI(this QuestEntry entry)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return (QuestEntryHUDUI)(_questEntryUI?.GetValue(entry));
		}

		public static void SetShouldShowCheck(this DialogueChoice choice, Func<bool, bool> func)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			choice.shouldShowCheck = new ShouldShowCheck(func.Invoke);
		}

		public static ItemSlot[] GetCustomerSlots(this HandoverScreen hs)
		{
			return (ItemSlot[])_hsCustomerSlots?.GetValue(hs);
		}

		public static void TrackItemAsPlayer(this HandoverScreen hs, ItemInstance item)
		{
			object obj = _hsOriginalItemLocations?.GetValue(hs);
			if (obj != null && _hsEItemSourcePlayer != null)
			{
				obj.GetType().GetMethod("set_Item")?.Invoke(obj, new object[2] { item, _hsEItemSourcePlayer });
			}
		}
	}
	public class Core : MelonMod
	{
		private NotificationManager _notificationManager;

		private DesperationManager _desperationManager;

		private DrifterManager _drifterManager;

		private ManagerController _managerManager;

		public override void OnInitializeMelon()
		{
			Config.Initialize();
			NpcTypeDiscoveryPatch.Apply(((MelonBase)this).HarmonyInstance);
			ConfigSyncPatch.TryApply(((MelonBase)this).HarmonyInstance);
			ManagerClipboardPatch.Apply(((MelonBase)this).HarmonyInstance);
			if (!ConfigSyncData.IsNetworkLibAvailable)
			{
				((MelonBase)this).LoggerInstance.Warning("SteamNetworkLib not installed — multiplayer sync disabled. Single-player works fine. Install SteamNetworkLib for co-op support.");
			}
			((MelonBase)this).LoggerInstance.Msg("OverTheCounter Initialized.");
			ImmediateQuestWindowConfig.Register();
			MinimapOverlay.Register();
			ExtractIcons();
			_notificationManager = new NotificationManager(((MelonBase)this).LoggerInstance);
			_desperationManager = new DesperationManager(((MelonBase)this).LoggerInstance);
			_drifterManager = new DrifterManager(((MelonBase)this).LoggerInstance);
			_managerManager = new ManagerController(((MelonBase)this).LoggerInstance);
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			StaticSaveData.ResetInstance();
			VicSaveData.ResetInstance();
			BellaSaveData.ResetInstance();
			StaticIntroQuest.ResetInstance();
			StaticUpgrade1Quest.ResetInstance();
			StaticUpgrade2Quest.ResetInstance();
			VicIntroQuest.ResetInstance();
			BellaProtocolQuest.ResetInstance();
			BellaSummonPatch.Reset();
			ContactsAppFix.Reset();
			DrifterInstance.CleanupAll();
			DrifterSpawner.ResetCache();
			ManagerSaveData.ResetInstance();
			ManagerInstance.CleanupAll();
			ManagerSpawner.ResetCache();
			MugshotUtility.ResetSession();
			if (!Object.op_Implicit((Object)(object)GameObject.Find("OTC_MinimapController")))
			{
				GameObject val = new GameObject("OTC_MinimapController");
				val.AddComponent<MinimapOverlay>();
				Object.DontDestroyOnLoad((Object)(object)val);
			}
		}

		public override void OnLateUpdate()
		{
			try
			{
				ConfigSyncData.EnsureNetworkReady();
				ConfigSyncData.ProcessMessages();
				_notificationManager.ProcessContractState();
				VicSaveData.Instance?.Tick();
				StaticSaveData.Instance?.Tick();
				BellaSaveData.Instance?.Tick();
				ManagerSaveData.Instance?.Tick();
				ContactsAppFix.Tick();
				_drifterManager?.RetryPendingAdoptions();
				ManagerInstance.RetryPendingAdoptions();
				_managerManager?.CheckImmediateWages();
				foreach (ManagerInstance value in ManagerInstance.Active.Values)
				{
					value.EnsureMoving();
				}
				if (NetworkHelper.IsHost)
				{
					foreach (ManagerInstance value2 in ManagerInstance.Active.Values)
					{
						value2.SupplyBehaviour?.Tick();
						value2.DistributionBehaviour?.Tick();
					}
					if (ManagerInstance.HasPendingMessages)
					{
						ConfigSyncData.Instance?.PublishManagerMessages();
					}
					if (DrifterManager.HasPendingDrifterMessages)
					{
						ConfigSyncData.Instance?.PublishDrifterMessages();
					}
					if (ManagerInstance.StatePublishNeeded)
					{
						ManagerInstance.StatePublishNeeded = false;
						ConfigSyncData.Instance?.PublishManagerState();
					}
				}
				_drifterManager?.ClientQuestTick();
			}
			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();
			_drifterManager?.Cleanup();
			_managerManager?.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, "DrifterQuestIcon.png");
			ExtractResource(text, "DrifterProfileIcon.png");
			ExtractResource(text, "RinseCycle.png");
			ExtractResource(text, "CrimeWareQuest.png");
			ExtractResource(text, "ExecutivePrivilege.png");
			ExtractResource(text, "ManagerIcon.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<bool> DesperationEnabled;

		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<bool> ConsolidationEnabled;

		public static ConfigEntry<int> ConsolidationThreshold;

		private static MelonPreferences_Category _managers;

		public static ConfigEntry<float> ManagerDailyWage;

		public static ConfigEntry<float> ManagerSigningFee;

		public static ConfigEntry<bool> ManagerVerboseLogging;

		public static ConfigEntry<bool> AlternateHire;

		private static MelonPreferences_Category _debug;

		public static ConfigEntry<bool> VerboseLogging;

		private static MelonPreferences_Category _bella;

		public static ConfigEntry<float> BellaWeedValue;

		public static ConfigEntry<float> BellaMethValue;

		public static ConfigEntry<float> BellaCokeValue;

		private static MelonPreferences_Category _drifters;

		public static ConfigEntry<bool> DrifterEnabled;

		public static ConfigEntry<float> DrifterSpawnChancePerHour;

		public static ConfigEntry<int> MaxActiveDrifters;

		public static ConfigEntry<int> DrifterDayStartHour;

		public static ConfigEntry<int> DrifterDayEndHour;

		public static ConfigEntry<int> DrifterOfferWindowMin;

		public static ConfigEntry<int> DrifterDeliveryDeadlineMin;

		public static ConfigEntry<int> DrifterLingerMinMin;

		public static ConfigEntry<int> DrifterLingerMaxMin;

		public static ConfigEntry<float> DrifterMinDealValue;

		private static MelonPreferences_Category _minimap;

		public static ConfigEntry<bool> MinimapEnabled;

		public static ConfigEntry<int> MinimapSize;

		public static ConfigEntry<bool> MinimapRotateWithPlayer;

		public static ConfigEntry<bool> MinimapCircle;

		public static ConfigEntry<int> MinimapDefaultZoom;

		public static ConfigEntry<float> MinimapIconScale;

		public static MelonPreferences_Entry<KeyCode> MinimapToggleKey;

		public static MelonPreferences_Entry<string> MinimapPosition;

		public static MelonPreferences_Entry<Color> MinimapBorderColor;

		public static ConfigEntry<int> MinimapBorderWidth;

		public static ConfigEntry<bool> MinimapShowTime;

		public static ConfigEntry<bool> MinimapShowDay;

		public static ConfigEntry<bool> MinimapUse24HourClock;

		private static MelonPreferences_Category _minimapPoi;

		public static ConfigEntry<bool> MinimapShowPotentialCustomers;

		public static ConfigEntry<bool> MinimapShowCustomers;

		public static ConfigEntry<bool> MinimapShowDealers;

		public static ConfigEntry<bool> MinimapShowDeadDrops;

		public static ConfigEntry<bool> MinimapShowContracts;

		public static ConfigEntry<bool> MinimapShowQuests;

		public static ConfigEntry<bool> MinimapShowProperties;

		public static ConfigEntry<bool> MinimapShowManagers;

		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 Dictionary<string, ConfigEntry<bool>> _boolEntries = new Dictionary<string, ConfigEntry<bool>>();

		private static readonly HashSet<string> _localOnlyKeys = new HashSet<string>
		{
			"ConsolidationEnabled", "ConsolidationThreshold", "ManagerVerboseLogging", "VerboseLogging", "MinimapEnabled", "MinimapSize", "MinimapRotateWithPlayer", "MinimapCircle", "MinimapDefaultZoom", "MinimapIconScale",
			"MinimapBorderWidth", "MinimapShowTime", "MinimapShowDay", "MinimapUse24HourClock", "MinimapShowPotentialCustomers", "MinimapShowCustomers", "MinimapShowDealers", "MinimapShowDeadDrops", "MinimapShowContracts", "MinimapShowQuests",
			"MinimapShowProperties", "MinimapShowManagers"
		};

		public static void Initialize()
		{
			//IL_09b6: Unknown result type (might be due to invalid IL or missing references)
			_desperation = MelonPreferences.CreateCategory("OverTheCounter", "Desperation System");
			DesperationEnabled = Register(_desperation.CreateEntry<bool>("Enabled", true, "Enabled", "Enable/disable the desperation system (urgent fiend requests)", false, false, (ValueValidator)null, (string)null));
			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");
			ConsolidationEnabled = Register(_notifications.CreateEntry<bool>("Enabled", true, "Enabled", "Enable/disable contract consolidation (groups same-window deliveries into one HUD entry)", false, false, (ValueValidator)null, (string)null));
			ConsolidationThreshold = Register(_notifications.CreateEntry<int>("ConsolidationThreshold", 5, "Consolidation Threshold", "Minimum contracts in a window before consolidation kicks in", false, false, (ValueValidator)null, (string)null));
			_managers = MelonPreferences.CreateCategory("OverTheCounter_Managers", "Manager System");
			ManagerDailyWage = Register(_managers.CreateEntry<float>("ManagerDailyWage", 350f, "Base Daily Wage", "Base daily wage before upgrade fees are added", false, false, (ValueValidator)null, (string)null));
			ManagerSigningFee = Register(_managers.CreateEntry<float>("ManagerSigningFee", 3000f, "Signing Fee", "One-time fee deducted from player cash when hiring a manager", false, false, (ValueValidator)null, (string)null));
			ManagerVerboseLogging = Register(_managers.CreateEntry<bool>("ManagerVerboseLogging", false, "Verbose Logging", "Enable detailed manager logging for troubleshooting (shopping list breakdowns, per-item details)", false, false, (ValueValidator)null, (string)null));
			AlternateHire = Register(_managers.CreateEntry<bool>("AlternateHire", false, "Alternate Hire", "Show hire buttons in the OTC app instead of using Manny's dialogue. Enable if another mod conflicts with Manny.", false, false, (ValueValidator)null, (string)null));
			_debug = MelonPreferences.CreateCategory("OverTheCounter_Debug", "Debug");
			VerboseLogging = Register(_debug.CreateEntry<bool>("VerboseLogging", false, "Verbose Logging", "Enable detailed logging for troubleshooting (drifters, quests, sync, NPCs)", false, false, (ValueValidator)null, (string)null));
			_bella = MelonPreferences.CreateCategory("OverTheCounter_Bella", "Bella Protocol");
			BellaWeedValue = Register(_bella.CreateEntry<float>("BellaWeedValue", 105f, "Weed Mix Value", "Minimum base price for the weed mix Bella requires", false, false, (ValueValidator)null, (string)null));
			BellaMethValue = Register(_bella.CreateEntry<float>("BellaMethValue", 200f, "Meth Mix Value", "Minimum base price for the meth mix Bella requires", false, false, (ValueValidator)null, (string)null));
			BellaCokeValue = Register(_bella.CreateEntry<float>("BellaCokeValue", 400f, "Cocaine Mix Value", "Minimum base price for the cocaine mix Bella requires", false, false, (ValueValidator)null, (string)null));
			_drifters = MelonPreferences.CreateCategory("OverTheCounter_Drifters", "Drifter System");
			DrifterEnabled = Register(_drifters.CreateEntry<bool>("Enabled", true, "Enabled", "Enable/disable the drifter system (random street NPCs offering one-time deals)", false, false, (ValueValidator)null, (string)null));
			DrifterSpawnChancePerHour = Register(_drifters.CreateEntry<float>("DrifterSpawnChancePerHour", 0.38f, "Spawn Chance Per Hour", "Base spawn chance per hour at max regions. Scaled down by unlocked region count (0.0-1.0)", false, false, (ValueValidator)null, (string)null));
			MaxActiveDrifters = Register(_drifters.CreateEntry<int>("MaxActiveDrifters", 3, "Max Active Drifters", "Maximum number of drifters that can be active at once", false, false, (ValueValidator)null, (string)null));
			DrifterDayStartHour = Register(_drifters.CreateEntry<int>("DrifterDayStartHour", 800, "Day Start Hour", "Earliest 24h time for drifter spawns (800 = 8:00 AM)", false, false, (ValueValidator)null, (string)null));
			DrifterDayEndHour = Register(_drifters.CreateEntry<int>("DrifterDayEndHour", 2100, "Day End Hour", "Latest 24h time for drifter spawns (2100 = 9:00 PM)", false, false, (ValueValidator)null, (string)null));
			DrifterOfferWindowMin = Register(_drifters.CreateEntry<int>("DrifterOfferWindowMin", 120, "Offer Window (min)", "Minutes player has to respond to a drifter offer (120 = 2 hours)", false, false, (ValueValidator)null, (string)null));
			DrifterDeliveryDeadlineMin = Register(_drifters.CreateEntry<int>("DrifterDeliveryDeadlineMin", 240, "Delivery Deadline (min)", "Minutes to deliver after accepting a drifter deal (240 = 4 hours)", false, false, (ValueValidator)null, (string)null));
			DrifterLingerMinMin = Register(_drifters.CreateEntry<int>("DrifterLingerMinMin", 30, "Linger Min (min)", "Minimum minutes a drifter lingers after deal completion/expiry", false, false, (ValueValidator)null, (string)null));
			DrifterLingerMaxMin = Register(_drifters.CreateEntry<int>("DrifterLingerMaxMin", 60, "Linger Max (min)", "Maximum minutes a drifter lingers after deal completion/expiry", false, false, (ValueValidator)null, (string)null));
			DrifterMinDealValue = Register(_drifters.CreateEntry<float>("DrifterMinDealValue", 90f, "Min Deal Value ($)", "Soft minimum deal value - drifters ask for more quantity until the deal reaches this threshold", false, false, (ValueValidator)null, (string)null));
			_minimap = MelonPreferences.CreateCategory("OverTheCounter_Minimap", "Minimap");
			MinimapEnabled = Register(_minimap.CreateEntry<bool>("MinimapEnabled", false, "Enabled", "Show the minimap overlay", false, false, (ValueValidator)null, (string)null));
			MinimapSize = Register(_minimap.CreateEntry<int>("MinimapSize", 250, "Size (px)", "Minimap size in pixels", false, false, (ValueValidator)null, (string)null));
			MinimapRotateWithPlayer = Register(_minimap.CreateEntry<bool>("MinimapRotateWithPlayer", false, "Rotate With Player", "Rotate minimap to match player facing direction", false, false, (ValueValidator)null, (string)null));
			MinimapCircle = Register(_minimap.CreateEntry<bool>("MinimapCircle", false, "Circle Shape", "Use circular minimap shape instead of square", false, false, (ValueValidator)null, (string)null));
			MinimapDefaultZoom = Register(_minimap.CreateEntry<int>("MinimapDefaultZoom", 2, "Default Zoom", "Starting zoom level, 1=closest, 3=farthest (1-3)", false, false, (ValueValidator)null, (string)null));
			MinimapIconScale = Register(_minimap.CreateEntry<float>("MinimapIconScale", 0.7f, "Icon Scale", "POI icon scale on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapToggleKey = _minimap.CreateEntry<KeyCode>("MinimapToggleKey", (KeyCode)110, "Toggle Key", "Hotkey to cycle minimap zoom", false, false, (ValueValidator)null, (string)null);
			MinimapPosition = _minimap.CreateEntry<string>("MinimapPosition", "TopRight", "Position", "TopLeft, TopRight, BottomLeft, BottomRight", false, false, (ValueValidator)null, (string)null);
			MinimapBorderColor = _minimap.CreateEntry<Color>("MinimapBorderColor", new Color(0.2f, 0.2f, 0.2f, 0.9f), "Border Color", "Minimap border color", false, false, (ValueValidator)null, (string)null);
			MinimapBorderWidth = Register(_minimap.CreateEntry<int>("MinimapBorderWidth", 4, "Border Width", "Border thickness in pixels per side (2-10)", false, false, (ValueValidator)null, (string)null));
			MinimapShowTime = Register(_minimap.CreateEntry<bool>("MinimapShowTime", true, "Show Time", "Display the current time near the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowDay = Register(_minimap.CreateEntry<bool>("MinimapShowDay", true, "Show Day", "Display the current day near the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapUse24HourClock = Register(_minimap.CreateEntry<bool>("MinimapUse24HourClock", false, "24-Hour Clock", "Use 24-hour time format instead of 12-hour AM/PM", false, false, (ValueValidator)null, (string)null));
			_minimapPoi = MelonPreferences.CreateCategory("OverTheCounter_MinimapPOI", "Minimap POIs");
			MinimapShowPotentialCustomers = Register(_minimapPoi.CreateEntry<bool>("MinimapShowPotentialCustomers", true, "Show Potential Customers", "Show potential customer icons on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowCustomers = Register(_minimapPoi.CreateEntry<bool>("MinimapShowCustomers", false, "Show Customers", "Show unlocked customer icons on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowDealers = Register(_minimapPoi.CreateEntry<bool>("MinimapShowDealers", true, "Show Dealers", "Show dealer icons on the minimap (potential and active)", false, false, (ValueValidator)null, (string)null));
			MinimapShowDeadDrops = Register(_minimapPoi.CreateEntry<bool>("MinimapShowDeadDrops", true, "Show Dead Drops", "Show dead drop icons on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowContracts = Register(_minimapPoi.CreateEntry<bool>("MinimapShowContracts", true, "Show Contracts", "Show contract delivery icons on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowQuests = Register(_minimapPoi.CreateEntry<bool>("MinimapShowQuests", true, "Show Quests", "Show quest objective icons on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowProperties = Register(_minimapPoi.CreateEntry<bool>("MinimapShowProperties", true, "Show Properties", "Show owned property icons on the minimap", false, false, (ValueValidator)null, (string)null));
			MinimapShowManagers = Register(_minimapPoi.CreateEntry<bool>("MinimapShowManagers", true, "Show Managers", "Show manager icons on the minimap", 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;
		}

		private static ConfigEntry<bool> Register(MelonPreferences_Entry<bool> entry)
		{
			ConfigEntry<bool> configEntry = new ConfigEntry<bool>(entry);
			_boolEntries[((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));
				}
			}
			foreach (KeyValuePair<string, ConfigEntry<bool>> boolEntry in _boolEntries)
			{
				if (!_localOnlyKeys.Contains(boolEntry.Key))
				{
					list.Add($"{boolEntry.Key}={boolEntry.Value.RawEntry.Value}");
				}
			}
			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;
				ConfigEntry<bool> value3;
				bool result3;
				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))
				{
					if (int.TryParse(datum.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2))
					{
						value2.SetOverride(result2);
					}
				}
				else if (_boolEntries.TryGetValue(datum.Key, out value3) && bool.TryParse(datum.Value, out result3))
				{
					value3.SetOverride(result3);
				}
			}
		}

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

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

		private QuestEntry _meetVicEntry;

		private QuestEntry _bringWeedEntry;

		private static readonly Vector3 VicPosition = new Vector3(67.75f, 0.97f, 32.36f);

		protected override string Title => "Rinse Cycle";

		protected override string Description => "Help Vic with his party supplies and he'll help you clean some cash.";

		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;

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

		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, Array.Empty<QuestEntryData>(), val.StaticGUID);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TriggerInternalInit failed: " + ex.Message);
			}
		}

		public void Initialize()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			((Saveable)this).OnLoaded();
			Instance = this;
			try
			{
				if (VicSaveData.Instance != null)
				{
					int num = (VicSaveData.Instance.Unlocked ? 3 : (VicSaveData.Instance.QuestAccepted ? 2 : (VicSaveData.Instance.HasBeenTexted ? 1 : 0)));
					if (num > _stage)
					{
						_stage = num;
					}
				}
				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("OTC: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", "CrimeWareQuest.png"));

		public static StaticIntroQuest Instance { get; private set; }

		public int Stage => _stage;

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

		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, Array.Empty<QuestEntryData>(), val.StaticGUID);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TriggerInternalInit failed: " + ex.Message);
			}
		}

		public void Initialize()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			((Saveable)this).OnLoaded();
			Instance = this;
			try
			{
				if (StaticSaveData.Instance != null)
				{
					int num = ((StaticSaveData.Instance.CrmTier >= 1) ? 3 : (StaticSaveData.Instance.IntroCompleted ? 2 : (StaticSaveData.Instance.QuestTriggered ? 1 : 0)));
					if (num > _stage)
					{
						_stage = num;
					}
				}
				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("OTC: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", "CrimeWareQuest.png"));

		public static StaticUpgrade1Quest Instance { get; private set; }

		public int Stage => _stage;

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

		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, Array.Empty<QuestEntryData>(), val.StaticGUID);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TriggerInternalInit failed: " + ex.Message);
			}
		}

		public void Initialize()
		{
			//IL_0010: 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_0023: 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("OTC: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", "CrimeWareQuest.png"));

		public static StaticUpgrade2Quest Instance { get; private set; }

		public int Stage => _stage;

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

		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, Array.Empty<QuestEntryData>(), val.StaticGUID);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TriggerInternalInit failed: " + ex.Message);
			}
		}

		public void Initialize()
		{
			//IL_0010: 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_0023: 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 DrifterDealQuest : Quest
	{
		private static readonly Instance Logger = new Instance("OTC:DrifterDealQuest");

		private string _title;

		private string _description;

		private QuestEntry _deliverEntry;

		private int _deadlineElapsedMinutes;

		protected override string Title => _title ?? "Drifter Deal";

		protected override string Description => _description ?? "Complete a deal with a drifter.";

		protected override bool AutoBegin => false;

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

		public string DrifterId { get; private set; }

		public static Dictionary<string, DrifterDealQuest> ActiveQuests { get; } = new Dictionary<string, DrifterDealQuest>();


		private Quest GetS1Quest()
		{
			object? obj = typeof(Quest).GetField("S1Quest", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(this);
			return (Quest)((obj is Quest) ? obj : null);
		}

		private void TriggerInternalInit()
		{
			try
			{
				Quest s1Quest = GetS1Quest();
				if (!((Object)(object)s1Quest == (Object)null))
				{
					s1Quest.InitializeQuest(((Quest)this).Title, ((Quest)this).Description, Array.Empty<QuestEntryData>(), s1Quest.StaticGUID);
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TriggerInternalInit failed: " + ex.Message);
			}
		}

		public void Initialize(string drifterId, string productName, int quantity, float payment, Vector3 destination, string locationDesc, int deadlineElapsedMinutes)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			DrifterId = drifterId;
			_title = "Drifter Deal";
			_description = $"Deliver {quantity} {productName} for ${payment:F0}";
			_deadlineElapsedMinutes = deadlineElapsedMinutes;
			TriggerInternalInit();
			_deliverEntry = ((Quest)this).AddEntry($"Deliver {quantity} {productName} to the drifter {locationDesc}", (Vector3?)destination);
			ActiveQuests[drifterId] = this;
		}

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

		public void UpdateTiming()
		{
			try
			{
				if (_deadlineElapsedMinutes > 0)
				{
					int currentElapsedMinutes = GetCurrentElapsedMinutes();
					int num = _deadlineElapsedMinutes - currentElapsedMinutes;
					if (num < 0)
					{
						num = 0;
					}
					int num2 = num / 60;
					int num3 = num % 60;
					string subtitleViaReflection = ((num >= 120) ? $"<color=green> (Expires in {num2}h {num3}m)</color>" : ((num2 <= 0) ? $"<color=#ff6b6b> (Expires in {num} min)</color>" : $"<color=#ff6b6b> (Expires in {num2}h {num3}m)</color>"));
					SetSubtitleViaReflection(subtitleViaReflection);
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("UpdateTiming failed: " + ex.Message);
			}
		}

		private void SetSubtitleViaReflection(string subtitle)
		{
			try
			{
				Quest s1Quest = GetS1Quest();
				if (!((Object)(object)s1Quest == (Object)null))
				{
					s1Quest.SetSubtitle(subtitle);
					if ((Object)(object)s1Quest.hudUI != (Object)null)
					{
						s1Quest.hudUI.UpdateMainLabel();
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("SetSubtitleViaReflection failed: " + ex.Message);
			}
		}

		private static int GetCurrentElapsedMinutes()
		{
			int elapsedDays = TimeManager.ElapsedDays;
			int currentTime = TimeManager.CurrentTime;
			int num = currentTime / 100;
			int num2 = currentTime % 100;
			return elapsedDays * 1440 + num * 60 + num2;
		}

		public void CompleteDeal()
		{
			try
			{
				QuestEntry deliverEntry = _deliverEntry;
				if (deliverEntry != null)
				{
					deliverEntry.Complete();
				}
				((Quest)this).Complete();
				((Quest)this).End();
				ActiveQuests.Remove(DrifterId);
			}
			catch (Exception ex)
			{
				Logger.Error("CompleteDeal failed: " + ex.Message);
			}
		}

		public void FailDeal()
		{
			try
			{
				QuestEntry deliverEntry = _deliverEntry;
				if (deliverEntry != null)
				{
					deliverEntry.Complete();
				}
				((Quest)this).Fail();
				ActiveQuests.Remove(DrifterId);
			}
			catch (Exception ex)
			{
				Logger.Error("FailDeal failed: " + ex.Message);
			}
		}

		public void CancelDeal()
		{
			try
			{
				((Quest)this).Cancel();
				ActiveQuests.Remove(DrifterId);
			}
			catch (Exception ex)
			{
				Logger.Error("CancelDeal failed: " + ex.Message);
			}
		}
	}
	public class BellaProtocolQuest : Quest
	{
		private static readonly Instance Logger = new Instance("OTC:BellaProtocolQuest");

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

		private QuestEntry _visitEntry;

		private QuestEntry _weedEntry;

		private QuestEntry _methEntry;

		private QuestEntry _cokeEntry;

		private static readonly Vector3 BellaBuilding = new Vector3(74.1f, 1f, 57.2f);

		protected override string Title => "Executive Privilege";

		protected override string Description => "Someone at the Fixer's mentioned a contact who can help with warehouse access.";

		protected override bool AutoBegin => false;

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

		public static BellaProtocolQuest Instance { get; private set; }

		public int Stage => _stage;

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

		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, Array.Empty<QuestEntryData>(), val.StaticGUID);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("TriggerInternalInit failed: " + ex.Message);
			}
		}

		public void Initialize()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				TriggerInternalInit();
				_visitEntry = ((Quest)this).AddEntry("Visit Bella at the downtown apartment", (Vector3?)BellaBuilding);
				_weedEntry = ((Quest)this).AddEntry(GetWeedText(), (Vector3?)BellaBuilding);
				_methEntry = ((Quest)this).AddEntry(GetMethText(), (Vector3?)BellaBuilding);
				_cokeEntry = ((Quest)this).AddEntry(GetCokeText(), (Vector3?)BellaBuilding);
			}
			catch (Exception ex)
			{
				Logger.Error("Initialize failed: " + ex.Message);
			}
		}

		private static string GetWeedText()
		{
			return $"Bring Bella a weed mix worth ${Config.BellaWeedValue.Value:N0}+";
		}

		private static string GetMethText()
		{
			return $"Bring Bella a meth mix worth ${Config.BellaMethValue.Value:N0}+";
		}

		private static string GetCokeText()
		{
			return $"Bring Bella a cocaine mix worth ${Config.BellaCokeValue.Value:N0}+";
		}

		public void RefreshEntryText()
		{
			if (_weedEntry != null && _stage == 2)
			{
				_weedEntry.Title = GetWeedText();
			}
			if (_methEntry != null && _stage == 3)
			{
				_methEntry.Title = GetMethText();
			}
			if (_cokeEntry != null && _stage == 4)
			{
				_cokeEntry.Title = GetCokeText();
			}
		}

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

		public void AdvanceToWeedRequest()
		{
			try
			{
				_stage = 2;
				QuestEntry visitEntry = _visitEntry;
				if (visitEntry != null)
				{
					visitEntry.Complete();
				}
				QuestEntry weedEntry = _weedEntry;
				if (weedEntry != null)
				{
					weedEntry.Begin();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("AdvanceToWeedRequest failed: " + ex.Message);
			}
		}

		public void AdvanceToMethRequest()
		{
			try
			{
				_stage = 3;
				QuestEntry weedEntry = _weedEntry;
				if (weedEntry != null)
				{
					weedEntry.Complete();
				}
				QuestEntry methEntry = _methEntry;
				if (methEntry != null)
				{
					methEntry.Begin();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("AdvanceToMethRequest failed: " + ex.Message);
			}
		}

		public void AdvanceToCocaineRequest()
		{
			try
			{
				_stage = 4;
				QuestEntry methEntry = _methEntry;
				if (methEntry != null)
				{
					methEntry.Complete();
				}
				QuestEntry cokeEntry = _cokeEntry;
				if (cokeEntry != null)
				{
					cokeEntry.Begin();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("AdvanceToCocaineRequest failed: " + ex.Message);
			}
		}

		public void CompleteQuest()
		{
			try
			{
				_stage = 5;
				QuestEntry cokeEntry = _cokeEntry;
				if (cokeEntry != null)
				{
					cokeEntry.Complete();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("CompleteQuest failed: " + ex.Message);
			}
		}

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

		protected override void OnLoaded()
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			((Saveable)this).OnLoaded();
			Instance = this;
			try
			{
				int stage = _stage;
				int num = BellaSaveData.Instance?.Stage ?? (-1);
				if (Config.VerboseLogging.Value)
				{
					Logger.Msg($"OnLoaded: save _stage={stage}, BellaSaveData.Stage={num}");
				}
				if (BellaSaveData.Instance != null && BellaSaveData.Instance.Stage > _stage)
				{
					_stage = BellaSaveData.Instance.Stage;
				}
				if (Config.VerboseLogging.Value)
				{
					Logger.Msg($"OnLoaded: rebuilding entries at _stage={_stage}");
				}
				base.QuestEntries.Clear();
				_visitEntry = ((Quest)this).AddEntry("Visit Bella at the downtown apartment", (Vector3?)BellaBuilding);
				_weedEntry = ((Quest)this).AddEntry(GetWeedText(), (Vector3?)BellaBuilding);
				_methEntry = ((Quest)this).AddEntry(GetMethText(), (Vector3?)BellaBuilding);
				_cokeEntry = ((Quest)this).AddEntry(GetCokeText(), (Vector3?)BellaBuilding);
				if (_stage >= 1)
				{
					QuestEntry visitEntry = _visitEntry;
					if (visitEntry != null)
					{
						visitEntry.Begin();
					}
				}
				if (_stage >= 2)
				{
					QuestEntry visitEntry2 = _visitEntry;
					if (visitEntry2 != null)
					{
						visitEntry2.Complete();
					}
					QuestEntry weedEntry = _weedEntry;
					if (weedEntry != null)
					{
						weedEntry.Begin();
					}
				}
				if (_stage >= 3)
				{
					QuestEntry weedEntry2 = _weedEntry;
					if (weedEntry2 != null)
					{
						weedEntry2.Complete();
					}
					QuestEntry methEntry = _methEntry;
					if (methEntry != null)
					{
						methEntry.Begin();
					}
				}
				if (_stage >= 4)
				{
					QuestEntry methEntry2 = _methEntry;
					if (methEntry2 != null)
					{
						methEntry2.Complete();
					}
					QuestEntry cokeEntry = _cokeEntry;
					if (cokeEntry != null)
					{
						cokeEntry.Begin();
					}
				}
				if (_stage >= 5)
				{
					QuestEntry cokeEntry2 = _cokeEntry;
					if (cokeEntry2 != null)
					{
						cokeEntry2.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("OTC: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 bool _needsStatePublish;

		private bool _questReconciled;

		private int _tickCounter;

		private const int TICK_INTERVAL = 300;

		private bool _positionFixed;

		internal bool _dialogueStale;

		private bool _wasInDialogue;

		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();
					_dialogueStale = true;
					ConfigSyncData.Instance?.PublishGameState();
				}
			}
		}

		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;
			}
			_dialogueStale = true;
			if (_hasBeenTexted)
			{
				_questCreated = true;
				if (NetworkHelper.IsHost)
				{
					_needsStatePublish = true;
				}
				ConfigSyncData.ApplyPendingGameState();
				ReconcileQuest();
			}
			else
			{
				ConfigSyncData.ApplyPendingGameState();
				if (_triggerPendingDay < 0 && IsCleanCashQuestStarted())
				{
					_triggerPendingDay = 0;
				}
			}
		}

		private void ReconcileQuest()
		{
			if (VicIntroQuest.Instance == null)
			{
				return;
			}
			int num = (_unlocked ? 3 : (_questAccepted ? 2 : (_hasBeenTexted ? 1 : 0)));
			if (num > VicIntroQuest.Instance.Stage)
			{
				if (num >= 2 && VicIntroQuest.Instance.Stage < 2)
				{
					VicIntroQuest.Instance.CompleteObj1();
				}
				if (num >= 3 && VicIntroQuest.Instance.Stage < 3)
				{
					VicIntroQuest.Instance.CompleteObj2();
				}
			}
		}

		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 (!_questReconciled && _hasBeenTexted && VicIntroQuest.Instance != null)
			{
				_questReconciled = true;
				int num = (_unlocked ? 3 : ((!_questAccepted) ? 1 : 2));
				if (VicIntroQuest.Instance.Stage < num)
				{
					if (Config.VerboseLogging.Value)
					{
						Logger.Msg($"Tick reconciliation: quest stage {VicIntroQuest.Instance.Stage} → {num}");
					}
					ReconcileQuest();
				}
			}
			bool flag = VicNPC.Instance != null && VicNPC.Instance.IsInDialogue;
			if (_wasInDialogue && !flag)
			{
				_dialogueStale = true;
			}
			_wasInDialogue = flag;
			if (_dialogueStale && VicNPC.Instance != null && VicNPC.Instance.DialogueReady && !flag)
			{
				_dialogueStale = false;
				try
				{
					VicNPC.Instance.RefreshDialogue();
				}
				catch (Exception)
				{
				}
			}
			if (_needsStatePublish && NetworkHelper.IsHost)
			{
				_needsStatePublish = false;
				ConfigSyncData.Instance?.PublishGameState();
			}
			if (NetworkHelper.IsHost && !_staleCheckDone && _hasBeenTexted)
			{
				_staleCheckDone = true;
				if (!_unlocked && !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)
			{
				_dialogueStale = true;
			}
		}

		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 num = (_lastDepositDay = TimeManager.ElapsedDays);
				if (_lastTrustIncrementDay < num)
				{
					_lastTrustIncrementDay = num;
					_trustLevel++;
				}
				break;
			}
			default:
				Logger.Warning("VicSaveData: unknown remote action '" + action + "'");
				return;
			}
			_dialogueStale = true;
			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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Invalid comparison between Unknown and I4
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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("OTC: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 _wasInDialogue;

		private bool _questCreated;

		private bool _needsStatePublish;

		private bool _questReconciled;

		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;
				if (NetworkHelper.IsHost)
				{
					_needsStatePublish = true;
				}
			}
			_dialogueStale = true;
			ConfigSyncData.ApplyPendingGameState();
			ReconcileQuest();
		}

		private void ReconcileQuest()
		{
			if (StaticIntroQuest.Instance == null)
			{
				return;
			}
			int num = ((_crmTier >= 1) ? 3 : (_introCompleted ? 2 : (_questTriggered ? 1 : 0)));
			if (num > StaticIntroQuest.Instance.Stage)
			{
				if (num >= 2 && StaticIntroQuest.Instance.Stage < 2)
				{
					StaticIntroQuest.Instance.CompleteObj1();
				}
				if (num >= 3 && StaticIntroQuest.Instance.Stage < 3)
				{
					StaticIntroQuest.Instance.CompleteObj2();
				}
			}
		}

		public void Tick()
		{
			if (!_questReconciled && _questTriggered && StaticIntroQuest.Instance != null)
			{
				_questReconciled = true;
				int num = ((_crmTier >= 1) ? 3 : ((!_introCompleted) ? 1 : 2));
				if (StaticIntroQuest.Instance.Stage < num)
				{
					if (Config.VerboseLogging.Value)
					{
						Logger.Msg($"Tick reconciliation: quest stage {StaticIntroQuest.Instance.Stage} → {num}");
					}
					ReconcileQuest();
				}
			}
			bool flag = StaticNPC.Instance != null && StaticNPC.Instance.IsInDialogue;
			if (_wasInDialogue && !flag)
			{
				_dialogueStale = true;
			}
			_wasInDialogue = flag;
			if (_needsStatePublish && NetworkHelper.IsHost)
			{
				_needsStatePublish = false;
				ConfigSyncData.Instance?.PublishGameState();
			}
			if (_dialogueStale && StaticNPC.Instance != null && StaticNPC.Instance.DialogueReady && !flag)
			{
				_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 val = NPC.All?.FirstOrDefault((Func<NPC, bool>)((NPC n) => n.ID == "static_casino_fixer"));
				if (val != null)
				{
					val.SendTextMessage(message, (Response[])null, 1f, true);
				}
			}
			catch (Exception ex)
			{
				Logger.Error("SendStaticText failed: " + ex.Message);
			}
		}
	}
	public class ConfigSyncData : Saveable
	{
		private static readonly Instance Logger = new Instance("OTC:ConfigSync");

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

		private static Dictionary<string, string> _pendingGameState;

		private static int _msgSeq;

		private static int _actionSeq;

		private static bool? _networkLibAvailable;

		public static ConfigSyncData Instance { get; private set; }

		internal static bool IsNetworkLibAvailable
		{
			get
			{
				bool valueOrDefault = _networkLibAvailable.GetValueOrDefault();
				bool result;
				if (!_networkLibAvailable.HasValue)
				{
					valueOrDefault = AppDomain.CurrentDomain.GetAssemblies().Any((Assembly a) => a.GetName().Name.Contains("SteamNetworkLib"));
					_networkLibAvailable = valueOrDefault;
					result = valueOrDefault;
				}
				else
				{
					result = valueOrDefault;
				}
				return result;
			}
		}

		public ConfigSyncData()
		{
			Instance = this;
		}

		protected override void OnLoaded()
		{
			Instance = this;
			_pendingGameState = null;
			Config.ClearAllOverrides();
			if (IsNetworkLibAvailable)
			{
				OnLoadedNetworkPush();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void OnLoadedNetworkPush()
		{
			NetworkSyncBridge.PushOnLoaded(Config.SerializeAll(), SerializeGameState(), DrifterManager.Instance?.SerializeDrifterState() ?? "");
		}

		public static void EnsureNetworkReady()
		{
			if (IsNetworkLibAvailable)
			{
				EnsureNetworkReadyImpl();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void EnsureNetworkReadyImpl()
		{
			NetworkSyncBridge.EnsureNetworkReady();
		}

		public static void ProcessMessages()
		{
			if (IsNetworkLibAvailable)
			{
				ProcessMessagesImpl();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void ProcessMessagesImpl()
		{
			NetworkSyncBridge.ProcessMessages();
		}

		public static void Cleanup()
		{
			_pendingGameState = null;
			if (IsNetworkLibAvailable)
			{
				CleanupImpl();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void CleanupImpl()
		{
			NetworkSyncBridge.Cleanup();
		}

		public void RefreshFromConfig()
		{
			if (NetworkHelper.IsHost)
			{
				_payload = Config.SerializeAll();
				if (IsNetworkLibAvailable)
				{
					RefreshFromConfigImpl(_payload);
				}
				RefreshQuestText();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void RefreshFromConfigImpl(string payload)
		{
			NetworkSyncBridge.PushConfig(payload);
		}

		public void PublishGameState()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			try
			{
				string text = SerializeGameState();
				if (Config.VerboseLogging.Value)
				{
					Logger.Msg($"PublishGameState: payload length={text?.Length ?? 0}");
				}
				if (IsNetworkLibAvailable)
				{
					PublishGameStateImpl(text);
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("PublishGameState failed: " + ex.Message);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void PublishGameStateImpl(string payload)
		{
			NetworkSyncBridge.PushState(payload);
		}

		public void PublishDrifterState()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			try
			{
				string payload = DrifterManager.Instance?.SerializeDrifterState() ?? "";
				if (IsNetworkLibAvailable)
				{
					PublishDrifterStateImpl(payload);
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("PublishDrifterState failed: " + ex.Message);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void PublishDrifterStateImpl(string payload)
		{
			NetworkSyncBridge.PushDrifterState(payload);
		}

		public void PublishManagerState()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			ManagerSaveData.Instance?.CaptureState();
			try
			{
				if (IsNetworkLibAvailable)
				{
					PublishManagerStateImpl();
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("PublishManagerState failed: " + ex.Message);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void PublishManagerStateImpl()
		{
			ManagerInstance.PublishAllSlots();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void WriteInitialManagerSlots()
		{
			ManagerInstance.PublishAllSlots();
		}

		public void PublishManagerMessages()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			try
			{
				List<string> list = new List<string>();
				list.Add(_msgSeq++.ToString());
				foreach (ManagerInstance value in ManagerInstance.Active.Values)
				{
					if (!string.IsNullOrEmpty(value.PendingClientMessage))
					{
						list.Add(value.Id + "|" + value.PendingClientMessage);
						value.PendingClientMessage = null;
					}
				}
				ManagerInstance.HasPendingMessages = false;
				if (list.Count > 1 && IsNetworkLibAvailable)
				{
					string text = string.Join(";", list);
					PublishManagerMessagesImpl(text);
					if (Config.VerboseLogging.Value)
					{
						Logger.Msg($"PublishManagerMessages: {text.Length} chars, {list.Count - 1} messages");
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("PublishManagerMessages failed: " + ex.Message);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void PublishManagerMessagesImpl(string payload)
		{
			NetworkSyncBridge.PushManagerMessages(payload);
		}

		public void PublishDrifterMessages()
		{
			if (!NetworkHelper.IsHost)
			{
				return;
			}
			try
			{
				List<string> list = new List<string>();
				list.Add(_msgSeq++.ToString());
				DrifterManager instance = DrifterManager.Instance;
				if (instance != null)
				{
					foreach (Drif