Decompiled source of Product 3 Code v0.1.3

NGA.SHPlibs.dll

Decompiled 10 months 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.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using Atlas;
using BepInEx;
using BepInEx.Logging;
using FistVR;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Sodalite.Api;
using UnityEngine;
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: AssemblyCompany("NGA")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Persistent player progression! Raid, stash loot, and deploy with seemless scene/loadout saving.")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("NGA.SHPlibs")]
[assembly: AssemblyTitle("BepInEx Plugin Title")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class BaseViewModel
{
	public event Action Changed;

	protected void NotifyListeners()
	{
		this.Changed?.Invoke();
	}

	public virtual void Initialize()
	{
	}

	public virtual void Dispose()
	{
	}
}
public class ViewModelRegistry : MonoBehaviour
{
	private static ViewModelRegistry _instance;

	private readonly Dictionary<Type, object> _map = new Dictionary<Type, object>();

	private void Awake()
	{
		if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		_instance = this;
		Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
	}

	private static void EnsureInstance()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		if (!((Object)(object)_instance != (Object)null))
		{
			GameObject val = new GameObject("ViewModelRegistry");
			_instance = val.AddComponent<ViewModelRegistry>();
			Object.DontDestroyOnLoad((Object)(object)val);
		}
	}

	public static T Get<T>() where T : BaseViewModel, new()
	{
		EnsureInstance();
		Type typeFromHandle = typeof(T);
		if (!_instance._map.TryGetValue(typeFromHandle, out var value))
		{
			T val = new T();
			val.Initialize();
			_instance._map[typeFromHandle] = val;
			value = val;
		}
		return (T)value;
	}

	public static void Prewarm<T>() where T : BaseViewModel, new()
	{
		Get<T>();
	}

	public static void Ensure()
	{
		EnsureInstance();
	}

	public static void Register<T>(T instance) where T : BaseViewModel
	{
		EnsureInstance();
		_instance._map[typeof(T)] = instance;
	}

	public static void DisposeAll()
	{
		EnsureInstance();
		foreach (KeyValuePair<Type, object> item in _instance._map)
		{
			((BaseViewModel)item.Value).Dispose();
		}
		_instance._map.Clear();
	}
}
public class UIElementAnimator
{
	public static IEnumerator AnimateRoutine(Transform rect, Transform targetTransform, float duration)
	{
		Vector3 startPos = rect.position;
		Quaternion startRot = rect.rotation;
		Vector3 targetPos = targetTransform.position;
		Quaternion targetRot = targetTransform.rotation;
		float t = 0f;
		while (t < duration)
		{
			t += Time.deltaTime;
			float lerpT = Mathf.Clamp01(t / duration);
			rect.position = Vector3.Lerp(startPos, targetPos, lerpT);
			rect.rotation = Quaternion.Lerp(startRot, targetRot, lerpT);
			yield return null;
		}
		rect.position = targetPos;
		rect.rotation = targetRot;
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string id = null, string name = null, string version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null)
		{
		}
	}
}
namespace NGA
{
	public class GiftMate : MonoBehaviour
	{
		public int refreshRate = 30;

		public float timeSinceRefresh = 0f;

		public int selectedIx = 0;

		public void Start()
		{
			drawGifts();
		}

		public void Update()
		{
			timeSinceRefresh += Time.deltaTime;
			if (timeSinceRefresh >= (float)refreshRate)
			{
				timeSinceRefresh = 0f;
				drawGifts();
			}
		}

		private void drawGifts()
		{
			SHGM.saveState.currentProfile.giftsList.giftsQueue.ForEach(delegate
			{
			});
		}

		public void BTN_SpawnSelected()
		{
			ShGiftsList giftsList = SHGM.saveState.currentProfile.giftsList;
			if (selectedIx >= 0 && selectedIx < giftsList.giftsQueue.Count)
			{
				giftsList.giftsQueue[selectedIx].idsToSpawn.ForEach(delegate
				{
				});
				giftsList.RemoveGift(giftsList.giftsQueue[selectedIx]);
				drawGifts();
			}
		}
	}
	[Serializable]
	public class ShGift
	{
		public string tinyMessage;

		public List<string> idsToSpawn;

		public ShGift(string tinyMessage, List<string> idsToSpawn)
		{
			this.tinyMessage = tinyMessage;
			this.idsToSpawn = idsToSpawn;
		}
	}
	[Serializable]
	public class ShGiftsList
	{
		public List<ShGift> giftsQueue;

		public ShGiftsList()
		{
			giftsQueue = new List<ShGift>();
		}

		public void AddGift(ShGift g)
		{
			giftsQueue.Add(g);
		}

		public void RemoveGift(ShGift g)
		{
			giftsQueue.Remove(g);
		}
	}
	[Serializable]
	public class ShLoadout
	{
		public string displayName;

		public string uid;

		public string fullFileName;

		public string lastUsedorSaved;

		public bool IsOfficialExtract;

		private ShLoadout(string displayName, bool isOfficialExtract)
		{
			uid = Guid.NewGuid().ToString();
			this.displayName = displayName;
			fullFileName = "";
			lastUsedorSaved = ShTimeCalculator.dateTimeToString(DateTime.UtcNow);
			IsOfficialExtract = isOfficialExtract;
		}

		internal static ShLoadout Create(string displayName, bool isOfficialExtract)
		{
			return new ShLoadout(displayName, isOfficialExtract);
		}

		public void UpdateLastSavedTime()
		{
			lastUsedorSaved = ShTimeCalculator.dateTimeToString(DateTime.UtcNow);
		}

		public void ChangeDisplayName(string newname)
		{
			displayName = newname;
		}
	}
	public static class ShLoadoutFactory
	{
		private const string DEFAULT_NAME = "Unnamed Loadout";

		private const string DEFAULT_EXTRACT_NAME = "Extracted Loadout";

		public static ShLoadout CreateDefault()
		{
			return ShLoadout.Create("Unnamed Loadout", isOfficialExtract: false);
		}

		public static ShLoadout CreateNamed(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				name = "Unnamed Loadout";
			}
			return ShLoadout.Create(name, isOfficialExtract: false);
		}

		public static ShLoadout CreateOfficialExtract()
		{
			return ShLoadout.Create("Extracted Loadout", isOfficialExtract: true);
		}
	}
	[Serializable]
	public class ShLoadoutRack
	{
		public List<ShLoadout> loadouts;

		public ShLoadoutRack()
		{
			Init();
		}

		public void Init()
		{
			if (loadouts == null)
			{
				loadouts = new List<ShLoadout>();
			}
		}

		public ShLoadout CreateEmptyLoadout()
		{
			if (loadouts == null)
			{
				loadouts = new List<ShLoadout>();
			}
			int num = 0;
			foreach (ShLoadout loadout in loadouts)
			{
				if (loadout != null && !loadout.IsOfficialExtract)
				{
					num++;
				}
			}
			int num2 = num + 1;
			string name = $"Loadout {num2}";
			ShLoadout shLoadout = ShLoadoutFactory.CreateNamed(name);
			loadouts.Add(shLoadout);
			return shLoadout;
		}

		public ShLoadout EnsureExtractionLoadout()
		{
			List<ShLoadout> list = new List<ShLoadout>();
			foreach (ShLoadout loadout in loadouts)
			{
				if (loadout != null && loadout.IsOfficialExtract)
				{
					list.Add(loadout);
				}
			}
			if (list.Count == 0)
			{
				ShLoadout shLoadout = ShLoadoutFactory.CreateOfficialExtract();
				loadouts.Add(shLoadout);
				return shLoadout;
			}
			if (list.Count == 1)
			{
				return list[0];
			}
			ShLoadout shLoadout2 = list[0];
			DateTime dateTime = ShTimeCalculator.stringToDateTime(shLoadout2.lastUsedorSaved);
			for (int i = 1; i < list.Count; i++)
			{
				DateTime dateTime2 = ShTimeCalculator.stringToDateTime(list[i].lastUsedorSaved);
				if (dateTime2 > dateTime)
				{
					shLoadout2 = list[i];
					dateTime = dateTime2;
				}
			}
			for (int num = loadouts.Count - 1; num >= 0; num--)
			{
				ShLoadout shLoadout3 = loadouts[num];
				if (shLoadout3 != null && shLoadout3.IsOfficialExtract && shLoadout3 != shLoadout2)
				{
					loadouts.RemoveAt(num);
				}
			}
			return shLoadout2;
		}

		public ShLoadout GetLoadout(string uid)
		{
			foreach (ShLoadout loadout in loadouts)
			{
				if (loadout.uid == uid)
				{
					return loadout;
				}
			}
			return null;
		}

		public void ConsumeLoadout(string uid)
		{
			for (int num = loadouts.Count - 1; num >= 0; num--)
			{
				ShLoadout shLoadout = loadouts[num];
				if (shLoadout != null && shLoadout.uid == uid)
				{
					loadouts.RemoveAt(num);
					break;
				}
			}
		}

		public List<ShLoadout> listLoadoutsSortedByUpdateTime()
		{
			ShLoadout item = EnsureExtractionLoadout();
			loadouts.Sort(delegate(ShLoadout a, ShLoadout b)
			{
				if (a == null && b == null)
				{
					return 0;
				}
				if (a == null)
				{
					return 1;
				}
				if (b == null)
				{
					return -1;
				}
				DateTime value = ShTimeCalculator.stringToDateTime(a.lastUsedorSaved);
				return ShTimeCalculator.stringToDateTime(b.lastUsedorSaved).CompareTo(value);
			});
			for (int num = loadouts.Count - 1; num >= 0; num--)
			{
				ShLoadout shLoadout = loadouts[num];
				if (shLoadout != null && shLoadout.IsOfficialExtract)
				{
					loadouts.RemoveAt(num);
				}
			}
			loadouts.Insert(0, item);
			return loadouts;
		}
	}
	public static class ShLoadoutsVault
	{
		private const string LOADOUTS_FOLDER = "Loadouts";

		private const string EXTR_LOADY_FILE = "ExtractionLoady.json";

		private const string LOADY_EXT = "_.json";

		public static string GetVaultProfileRoot(string profileUid)
		{
			return Path.Combine(Path.Combine(ShFileIoHandler.GetH3SaveFolder(), ShFileIoHandler.rootSaveFolder), profileUid);
		}

		public static string GetLoadoutsFolder(string profileUid)
		{
			return Path.Combine(GetVaultProfileRoot(profileUid), "Loadouts");
		}

		public static string GetExtractionLoadyFile(string profileUid)
		{
			return Path.Combine(GetLoadoutsFolder(profileUid), "ExtractionLoady.json");
		}

		public static string GetLoadyFileFromUid(string profileUid, string loadyUid)
		{
			return Path.Combine(GetLoadoutsFolder(profileUid), loadyUid + "_.json");
		}

		public static bool TrySaveExtractionLoady(string profileUid, out string error)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			error = null;
			VaultFile vf = new VaultFile();
			if (!TryScanCurrentLoadout(out vf, out error))
			{
				Debug.LogError((object)"[TrySaveExtractionLoady] Scanning quickbelt failed.");
				return false;
			}
			string extractionLoadyFile = GetExtractionLoadyFile(profileUid);
			ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(extractionLoadyFile));
			if (!ShFileIoHandler.TrySaveJson(vf, extractionLoadyFile, out error))
			{
				Debug.LogError((object)("[TrySaveExtractionLoady] Failed to save w error: " + error));
				return false;
			}
			return true;
		}

		public static VaultFile TryGetExtractionLoadyVault(string profileUid, out string error)
		{
			string extractionLoadyFile = GetExtractionLoadyFile(profileUid);
			ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(extractionLoadyFile));
			if (!ShFileIoHandler.TryLoadJson<VaultFile>(extractionLoadyFile, out VaultFile obj, out error))
			{
				Debug.LogError((object)("[TryGetExtractionLoady]: Failed to parse json w: " + error + " on file " + extractionLoadyFile));
				return null;
			}
			return obj;
		}

		public static bool TryLoadExtractionLoady(string profileUid, out string error)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			string extractionLoadyFile = GetExtractionLoadyFile(profileUid);
			ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(extractionLoadyFile));
			if (!ShFileIoHandler.TryLoadJson<VaultFile>(extractionLoadyFile, out VaultFile obj, out error))
			{
				Debug.LogError((object)("[TryLoadExtractionLoady]: Failed to parse json w: " + error + " on file " + extractionLoadyFile));
				return false;
			}
			Transform transform = ((Component)GM.CurrentPlayerBody).transform;
			return VaultSystem.SpawnObjects((VaultFileDisplayMode)1, obj, ref error, transform, Vector3.zero);
		}

		public static bool TryClearExtractionLoadyFile(string profileUid, out string error)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			VaultFile obj = new VaultFile();
			string extractionLoadyFile = GetExtractionLoadyFile(profileUid);
			ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(extractionLoadyFile));
			if (!ShFileIoHandler.TrySaveJson(obj, extractionLoadyFile, out error))
			{
				Debug.LogError((object)("[TrySaveExtractionLoady] Failed to save w error: " + error));
				return false;
			}
			return true;
		}

		public static bool TrySaveCustomLoady(string profileUid, string loadyUid, out string fullFileName, out string error)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			error = null;
			fullFileName = null;
			VaultFile vf = new VaultFile();
			if (!TryScanCurrentLoadout(out vf, out error))
			{
				Debug.LogError((object)"[TrySaveCustomLoady] Scanning quickbelt failed.");
				return false;
			}
			string loadyFileFromUid = GetLoadyFileFromUid(profileUid, loadyUid);
			ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(loadyFileFromUid));
			if (!ShFileIoHandler.TrySaveJson(vf, loadyFileFromUid, out error))
			{
				Debug.LogError((object)("[TrySaveCustomLoady] Failed to save w error: " + error));
				return false;
			}
			fullFileName = loadyFileFromUid;
			return true;
		}

		public static VaultFile TryGetCustomLoadyFile(string profileUid, string loadyUid, out string error)
		{
			string loadyFileFromUid = GetLoadyFileFromUid(profileUid, loadyUid);
			ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(loadyFileFromUid));
			if (!ShFileIoHandler.TryLoadJson<VaultFile>(loadyFileFromUid, out VaultFile obj, out error))
			{
				Debug.LogError((object)("[TryGetCustomLoadyFile]: Failed to parse json w: " + error + " on file " + loadyFileFromUid));
				return null;
			}
			return obj;
		}

		public static bool TryLoadCustomLoady(string profileUid, string loadyUid, out string error)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			string loadyFileFromUid = GetLoadyFileFromUid(profileUid, loadyUid);
			ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(loadyFileFromUid));
			if (!ShFileIoHandler.TryLoadJson<VaultFile>(loadyFileFromUid, out VaultFile obj, out error))
			{
				Debug.LogError((object)("[TryLoadCustomLoady]: Failed to parse json w: " + error + " on file " + loadyFileFromUid));
				return false;
			}
			Transform transform = ((Component)GM.CurrentPlayerBody).transform;
			return VaultSystem.SpawnObjects((VaultFileDisplayMode)1, obj, ref error, transform, Vector3.zero);
		}

		public static bool TryDeleteCustomLoady(string profileUid, string loadyUid, out string error)
		{
			error = null;
			string loadyFileFromUid = GetLoadyFileFromUid(profileUid, loadyUid);
			ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(loadyFileFromUid));
			try
			{
				if (File.Exists(loadyFileFromUid))
				{
					File.Delete(loadyFileFromUid);
				}
				return true;
			}
			catch (Exception ex)
			{
				error = ex.Message;
				Debug.LogError((object)("[TryDeleteCustomLoady]: Failed to delete w: " + error + " on file " + loadyFileFromUid));
				return false;
			}
		}

		private static bool TryScanCurrentLoadout(out VaultFile vf, out string error)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			vf = new VaultFile();
			error = null;
			if (!VaultSystem.FindAndScanObjectsInQuickbelt(vf))
			{
				error = "Loady scan failed.";
				return false;
			}
			return true;
		}
	}
	public class LootCalculator
	{
		public static List<string> GetOrderedItemsIDs(List<ObjectCategory> orderedCategories)
		{
			int count = orderedCategories?.Count ?? 0;
			List<string> result = NewBlankResultList(count);
			Dictionary<int, string> firearmAtIndex = new Dictionary<int, string>();
			string lastFirearmId = string.Empty;
			PlaceFirearms(orderedCategories, result, firearmAtIndex, ref lastFirearmId);
			FillNonFirearms(orderedCategories, result, firearmAtIndex, ref lastFirearmId);
			return result;
		}

		private static List<string> NewBlankResultList(int count)
		{
			List<string> list = new List<string>(count);
			for (int i = 0; i < count; i++)
			{
				list.Add(string.Empty);
			}
			return list;
		}

		private static void PlaceFirearms(List<ObjectCategory> cats, List<string> result, Dictionary<int, string> firearmAtIndex, ref string lastFirearmId)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			for (int i = 0; i < cats.Count; i++)
			{
				ObjectCategory val = cats[i];
				if (!IsAnyCategory(val) && (int)val == 1)
				{
					FVRObject obj = PickRandomFromCategory((ObjectCategory)1);
					string text2 = (result[i] = ToItemId(obj));
					if (!string.IsNullOrEmpty(text2))
					{
						firearmAtIndex[i] = text2;
						lastFirearmId = text2;
					}
				}
			}
		}

		private static void FillNonFirearms(List<ObjectCategory> cats, List<string> result, Dictionary<int, string> firearmAtIndex, ref string lastFirearmId)
		{
			//IL_0023: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Invalid comparison between Unknown and I4
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < cats.Count; i++)
			{
				if (!string.IsNullOrEmpty(result[i]))
				{
					continue;
				}
				ObjectCategory cat = cats[i];
				cat = ResolveAnyCategory(cat);
				if (IsAmmoCategory(cat))
				{
					result[i] = GetAmmoItemId(i, cats.Count, firearmAtIndex, ref lastFirearmId);
				}
				else if ((int)cat == 1)
				{
					FVRObject obj = PickRandomFromCategory((ObjectCategory)1);
					result[i] = ToItemId(obj);
					if (!string.IsNullOrEmpty(result[i]))
					{
						lastFirearmId = result[i];
					}
				}
				else
				{
					result[i] = ToItemId(PickRandomFromCategory(cat));
				}
			}
		}

		private static bool IsAnyCategory(ObjectCategory cat)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			return (int)cat == 0;
		}

		private static ObjectCategory ResolveAnyCategory(ObjectCategory cat)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!IsAnyCategory(cat))
			{
				return cat;
			}
			Dictionary<ObjectCategory, List<FVRObject>> odicTagCategory = ManagerSingleton<IM>.Instance.odicTagCategory;
			if (odicTagCategory == null || odicTagCategory.Count == 0)
			{
				return (ObjectCategory)0;
			}
			List<ObjectCategory> list = new List<ObjectCategory>(odicTagCategory.Keys);
			list.Remove((ObjectCategory)0);
			return list[Random.Range(0, list.Count)];
		}

		private static bool IsAmmoCategory(ObjectCategory cat)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			return (int)cat == 2 || (int)cat == 6 || (int)cat == 3 || (int)cat == 4;
		}

		private static string GetAmmoItemId(int index, int totalCount, Dictionary<int, string> firearmAtIndex, ref string lastFirearmId)
		{
			string text = ((!string.IsNullOrEmpty(lastFirearmId)) ? lastFirearmId : FindWeaponAhead(index, totalCount, firearmAtIndex));
			if (!string.IsNullOrEmpty(text))
			{
				FVRObject val = IM.OD[text];
				FVRObject randomAmmoObject = IM.OD[text].GetRandomAmmoObject(val, (List<OTagEra>)null, -1, -1, (List<OTagSet>)null);
				string text2 = ToItemId(randomAmmoObject);
				if (!string.IsNullOrEmpty(text2))
				{
					return text2;
				}
			}
			return ToItemId(PickRandomFromCategory((ObjectCategory)2));
		}

		private static string FindWeaponAhead(int idx, int totalCount, Dictionary<int, string> firearmAtIndex)
		{
			for (int i = idx + 1; i < totalCount; i++)
			{
				if (firearmAtIndex.TryGetValue(i, out var value))
				{
					return value;
				}
			}
			return string.Empty;
		}

		private static FVRObject PickRandomFromCategory(ObjectCategory cat)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<ObjectCategory, List<FVRObject>> odicTagCategory = ManagerSingleton<IM>.Instance.odicTagCategory;
			if (odicTagCategory == null)
			{
				Debug.LogError((object)"PickRandomFromCategory: failed get odicTagCategory at all");
				return null;
			}
			if (!odicTagCategory.TryGetValue(cat, out var value) || value == null || value.Count == 0)
			{
				Debug.LogError((object)("PickRandomFromCategory: failed get category " + ((object)(ObjectCategory)(ref cat)).ToString()));
				return null;
			}
			return value[Random.Range(0, value.Count)];
		}

		private static string ToItemId(FVRObject obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				Debug.LogError((object)"ToItemId: obj in put is null");
				return string.Empty;
			}
			try
			{
				if (!string.IsNullOrEmpty(obj.ItemID))
				{
					return obj.ItemID;
				}
			}
			catch
			{
				Debug.LogError((object)"ToItemId: ItemID is not present in the object");
				return string.Empty;
			}
			return string.Empty;
		}
	}
	public class ShowLootUiOnInteract : MonoBehaviour
	{
		private bool ready = false;

		private SosigLink slink;

		private SLinkLootController controller;

		public void Init(SosigLink Slink, SLinkLootController Controller)
		{
			ready = true;
			slink = Slink;
			controller = Controller;
		}

		private void Update()
		{
			if (ready)
			{
				controller.SetUiActive(((FVRInteractiveObject)slink.O).IsHeld);
			}
		}
	}
	public class SLinkLootController : MonoBehaviour
	{
		private Canvas canvas;

		private List<SpawnOnGrab> grabbies;

		public void Awake()
		{
			FindUiVariables();
		}

		private void FindUiVariables()
		{
			canvas = ((Component)((Component)this).transform).GetComponent<Canvas>();
			grabbies = new List<SpawnOnGrab>(((Component)this).GetComponentsInChildren<SpawnOnGrab>());
		}

		public static void AttachToSosig(Sosig theSosig)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)theSosig).transform.Find("Sosig_Torso");
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"AttachToSosig: could not find Sosig_Torso");
				return;
			}
			GameObject val2 = ShSpawnItems.SpawnItemFromOD("NGA_torsoLootUi");
			if ((Object)(object)val2 == (Object)null)
			{
				Debug.LogError((object)"AttachToSosig: SpawnItemFromOD returned null for torso");
				return;
			}
			val2.transform.SetParent(val);
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = new Vector3(0.007f, 0.007f, 0.007f);
			SLinkLootController component = val2.GetComponent<SLinkLootController>();
			component.EnableLooting(theSosig);
			if ((Object)(object)component == (Object)null)
			{
				Debug.LogError((object)"AttachToSosig: torso UI prefab has no SLinkLootController");
				return;
			}
			ShowLootUiOnInteract showLootUiOnInteract = ((Component)val).gameObject.AddComponent<ShowLootUiOnInteract>();
			showLootUiOnInteract.Init(((Component)val).GetComponent<SosigLink>(), component);
			Transform val3 = val.Find("UpperLink");
			if ((Object)(object)val3 == (Object)null)
			{
				Debug.LogError((object)"AttachToSosig: could not find Upper link");
				return;
			}
			GameObject val4 = ShSpawnItems.SpawnItemFromOD("NGA_waistLootUi");
			if ((Object)(object)val4 == (Object)null)
			{
				Debug.LogError((object)"AttachToSosig: SpawnItemFromOD returned null for waist");
				return;
			}
			val4.transform.SetParent(val3);
			val4.transform.localPosition = Vector3.zero;
			val4.transform.localRotation = Quaternion.identity;
			val4.transform.localScale = new Vector3(0.007f, 0.007f, 0.007f);
			SLinkLootController component2 = val4.GetComponent<SLinkLootController>();
			component2.EnableLooting(theSosig);
			if ((Object)(object)component2 == (Object)null)
			{
				Debug.LogError((object)"AttachToSosig: torso UI prefab has no SLinkLootController");
				return;
			}
			ShowLootUiOnInteract showLootUiOnInteract2 = ((Component)val3).gameObject.AddComponent<ShowLootUiOnInteract>();
			showLootUiOnInteract2.Init(((Component)val3).GetComponent<SosigLink>(), component2);
		}

		public void EnableLooting(Sosig killedSosig)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			List<ObjectCategory> list = new List<ObjectCategory>(grabbies.Count);
			foreach (SpawnOnGrab grabby in grabbies)
			{
				list.Add(grabby.itemType);
			}
			List<string> orderedItemsIDs = LootCalculator.GetOrderedItemsIDs(list);
			for (int i = 0; i < grabbies.Count; i++)
			{
				grabbies[i].SetItem(orderedItemsIDs[i]);
			}
			SetUiActive(value: false);
		}

		public void SetUiActive(bool value)
		{
			((Behaviour)canvas).enabled = value;
		}
	}
	public class SpawnOnGrab : FVRInteractiveObject
	{
		private RawImage backgroundImage;

		private RawImage itemImage;

		private readonly HashSet<FVRPhysicalObject> _inside = new HashSet<FVRPhysicalObject>();

		private readonly HashSet<FVRPhysicalObject> _waitingRelease = new HashSet<FVRPhysicalObject>();

		private Collider collectionTrigger;

		private bool destroyCollectedObject = true;

		public Color defaultColor = Color32.op_Implicit(new Color32((byte)86, (byte)70, (byte)70, (byte)128));

		public Color hoveredColor = Color32.op_Implicit(new Color32((byte)161, (byte)161, (byte)55, byte.MaxValue));

		private static readonly List<FVRPhysicalObject> _toProcess = new List<FVRPhysicalObject>(32);

		[Header("Spawner params")]
		public ObjectCategory itemType = (ObjectCategory)(-1);

		public string itemID;

		[Tooltip("How many objects can be taken from this spawner before it runs out")]
		public int currObjectCapacity;

		private FVRObject fob;

		private AnvilCallback<GameObject> itemLoader;

		public override void Awake()
		{
			((FVRInteractiveObject)this).Awake();
			FindUiVariables();
			if (!string.IsNullOrEmpty(itemID) && IM.OD.ContainsKey(itemID))
			{
				itemLoader = ((AnvilAsset)IM.OD[itemID]).GetGameObjectAsync();
			}
			if (!string.IsNullOrEmpty(itemID))
			{
				itemLoader = ((AnvilAsset)IM.OD[itemID]).GetGameObjectAsync();
			}
		}

		private void FindUiVariables()
		{
			backgroundImage = ((Component)((Component)this).transform).GetComponent<RawImage>();
			itemImage = ((Component)((Component)this).transform.Find("ItemImage")).GetComponent<RawImage>();
			collectionTrigger = ((Component)this).GetComponent<Collider>();
		}

		public void Redraw()
		{
			if (!IM.HasSpawnedID(fob.SpawnedFromId))
			{
				Debug.LogWarning((object)("SpawnedID not exist for: " + fob.ItemID));
			}
			if (currObjectCapacity > 0 && IM.HasSpawnedID(fob.SpawnedFromId))
			{
				((Behaviour)itemImage).enabled = true;
				itemImage.texture = (Texture)(object)IM.GetSpawnerID(fob.SpawnedFromId).Sprite.texture;
			}
			else
			{
				((Behaviour)itemImage).enabled = true;
			}
		}

		public override void BeginInteraction(FVRViveHand hand)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (currObjectCapacity >= 1)
			{
				((FVRInteractiveObject)this).BeginInteraction(hand);
				if (!((AnvilCallbackBase)itemLoader).IsCompleted)
				{
					((AnvilCallbackBase)itemLoader).CompleteNow();
				}
				FVRPhysicalObject component = Object.Instantiate<GameObject>(itemLoader.Result, ((Component)hand).transform.position, ((Component)hand).transform.rotation).GetComponent<FVRPhysicalObject>();
				if ((Object)(object)component != (Object)null)
				{
					hand.ForceSetInteractable((FVRInteractiveObject)(object)component);
					((FVRInteractiveObject)component).BeginInteraction(hand);
				}
				RemoveItem();
			}
		}

		public void RemoveItem()
		{
			if (currObjectCapacity >= 1)
			{
				currObjectCapacity--;
				if (currObjectCapacity < 1)
				{
					((Behaviour)itemImage).enabled = false;
				}
			}
		}

		public void AddItem(string ID, int objectAmount = 1)
		{
			if (string.IsNullOrEmpty(ID) || objectAmount < 1)
			{
				Debug.LogWarning((object)"SpawnOnGrab.AddItem: You tried to give me an empty item id or negative or zero objectAmount. Nice try.");
			}
			else if (!string.IsNullOrEmpty(itemID) && currObjectCapacity > 0)
			{
				Debug.LogWarning((object)("SpawnOnGrab.AddItem: I cant add an item if there are some already present: " + itemID + " for " + currObjectCapacity));
			}
			else if (ID == itemID)
			{
				currObjectCapacity += objectAmount;
				Redraw();
			}
			else
			{
				SetItem(ID, objectAmount);
			}
		}

		public void SetItem(string ID, int objectCapacity = 1)
		{
			if (string.IsNullOrEmpty(ID))
			{
				Debug.LogError((object)"SpawnOnGrab was given an empty or null id");
				return;
			}
			if (!IM.OD.ContainsKey(ID))
			{
				Debug.LogError((object)("SpawnOnGrab was given key that's not present in IM.OD: " + ID));
				return;
			}
			itemID = ID;
			fob = IM.OD[itemID];
			itemLoader = ((AnvilAsset)fob).GetGameObjectAsync();
			currObjectCapacity = objectCapacity;
			Redraw();
		}

		private void OnTriggerEnter(Collider other)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)other == (Object)null)
			{
				return;
			}
			((Graphic)backgroundImage).color = hoveredColor;
			FVRPhysicalObject componentInParent = ((Component)other).GetComponentInParent<FVRPhysicalObject>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				_inside.Add(componentInParent);
				if (((FVRInteractiveObject)componentInParent).IsHeld)
				{
					_waitingRelease.Add(componentInParent);
				}
			}
		}

		private void OnTriggerExit(Collider other)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)other == (Object)null))
			{
				((Graphic)backgroundImage).color = defaultColor;
				FVRPhysicalObject componentInParent = ((Component)other).GetComponentInParent<FVRPhysicalObject>();
				if (!((Object)(object)componentInParent == (Object)null))
				{
					_inside.Remove(componentInParent);
					_waitingRelease.Remove(componentInParent);
				}
			}
		}

		private void Update()
		{
			if (_inside.Count == 0)
			{
				return;
			}
			_toProcess.Clear();
			foreach (FVRPhysicalObject item in _inside)
			{
				if ((Object)(object)item != (Object)null)
				{
					_toProcess.Add(item);
				}
			}
			foreach (FVRPhysicalObject item2 in _toProcess)
			{
				if ((Object)(object)item2 == (Object)null)
				{
					continue;
				}
				if (((FVRInteractiveObject)item2).IsHeld)
				{
					_waitingRelease.Add(item2);
				}
				else
				{
					if (!_waitingRelease.Contains(item2))
					{
						continue;
					}
					FVRObject objectWrapper = item2.ObjectWrapper;
					if ((Object)(object)objectWrapper != (Object)null)
					{
						AddItem(objectWrapper.ItemID);
						if (destroyCollectedObject && (Object)(object)((Component)item2).gameObject != (Object)null)
						{
							Object.Destroy((Object)(object)((Component)item2).gameObject);
						}
					}
					_waitingRelease.Remove(item2);
					_inside.Remove(item2);
				}
			}
		}
	}
	[BepInPlugin("NGA.SafehouseProgressionMPatchy", "SafehouseProgressionMPatchy", "0.0.1")]
	[BepInDependency("nrgill28.Sodalite", "1.4.1")]
	[BepInProcess("h3vr.exe")]
	public class SafehouseProgressionMPatchy : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(GM))]
		[HarmonyPatch("Awake")]
		public class SH_GM_Initializer
		{
			private static void Postfix(GM __instance)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				if ((Object)(object)SHGM.Instance == (Object)null)
				{
					GameObject val = new GameObject("SH_GM");
					val.AddComponent<SHGM>();
					Object.DontDestroyOnLoad((Object)(object)val);
				}
			}
		}

		[HarmonyPatch(typeof(FVRSceneSettings))]
		[HarmonyPatch("LoadDefaultSceneRoutine")]
		private class FVRSceneSettingsLoadDefaultSceneRoutineHook
		{
		}

		[HarmonyPatch(typeof(Sosig), "Configure")]
		private class SosigLootAttach
		{
			private static void Postfix(Sosig __instance)
			{
			}
		}

		[HarmonyPatch(typeof(FVRWristMenu2))]
		[HarmonyPatch("Awake")]
		private class WristMenuAwakeHook
		{
			private static void Postfix(FVRWristMenu2 __instance)
			{
				if ((Object)(object)__instance == (Object)null)
				{
					Logger.LogMessage((object)"FVRWristMenu2 is null!?");
				}
				try
				{
					FVRWristMenuSection_Safehouse2 fVRWristMenuSection_Safehouse = AddWristMenuSection(__instance);
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[AddWristMenuSection] Failed with error: " + ex.Message));
				}
			}
		}

		public class SwapIconHandler : MonoBehaviour
		{
			private FVRWristMenuSectionButton b;

			private bool swapped;

			private void Awake()
			{
				b = ((Component)this).GetComponent<FVRWristMenuSectionButton>();
			}

			private void Update()
			{
				//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0247: Unknown result type (might be due to invalid IL or missing references)
				//IL_024e: Expected O, but got Unknown
				//IL_0286: Unknown result type (might be due to invalid IL or missing references)
				//IL_029d: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_021f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0224: Unknown result type (might be due to invalid IL or missing references)
				//IL_022d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0237: Unknown result type (might be due to invalid IL or missing references)
				//IL_023c: Unknown result type (might be due to invalid IL or missing references)
				if (swapped)
				{
					return;
				}
				if ((Object)(object)b == (Object)null)
				{
					b = ((Component)this).GetComponent<FVRWristMenuSectionButton>();
				}
				else
				{
					if ((Object)(object)b.ButtonText == (Object)null || !(b.ButtonText.text == "SHP3-swap"))
					{
						return;
					}
					swapped = true;
					b.ButtonText.text = "";
					Transform val = ((Component)this).transform.Find("Backing");
					if ((Object)(object)val == (Object)null)
					{
						Debug.LogError((object)"[SwapIconHandler] Could not find child named 'Backing'.");
						return;
					}
					Image component = ((Component)val).GetComponent<Image>();
					if ((Object)(object)component == (Object)null)
					{
						Debug.LogError((object)"[SwapIconHandler] 'Backing' found but it has no Image component.");
						return;
					}
					string text = Path.Combine(ShFileIoHandler.GetPluginModFolder(), "wideIcon.png");
					string text2 = Path.Combine(ShFileIoHandler.GetPluginModFolder(), "redNot.png");
					if (!File.Exists(text) || !File.Exists(text2))
					{
						Debug.LogError((object)("[SwapIconHandler] File not found: " + text));
						return;
					}
					Texture2D val2 = ShFileIoHandler.LoadTextureFromFullPath(text);
					Texture2D val3 = ShFileIoHandler.LoadTextureFromFullPath(text2);
					if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
					{
						Debug.LogError((object)"[SwapIconHandler] Loader returned null Texture2D.");
						return;
					}
					Rect val4 = default(Rect);
					((Rect)(ref val4))..ctor(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height);
					Vector2 val5 = default(Vector2);
					((Vector2)(ref val5))..ctor(0.5f, 0.5f);
					Sprite sprite = Sprite.Create(val2, val4, val5);
					component.sprite = sprite;
					if (((Graphic)component).color.a < 1f)
					{
						((Graphic)component).color = new Color(1f, 1f, 1f, 1f);
					}
					FVRPointableButton component2 = ((Component)this).GetComponent<FVRPointableButton>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.Image = component;
						component2.ColorUnselected = component2.ColorSelected;
						component2.ColorSelected *= 2f;
					}
					GameObject val6 = new GameObject("Notification");
					val6.transform.SetParent(val, false);
					RawImage val7 = val6.AddComponent<RawImage>();
					val7.texture = (Texture)(object)val3;
					RectTransform component3 = val6.GetComponent<RectTransform>();
					component3.anchorMin = new Vector2(1f, 1f);
					component3.anchorMax = new Vector2(1f, 1f);
					component3.pivot = new Vector2(1f, 1f);
					component3.anchoredPosition = Vector2.zero;
					component3.sizeDelta = new Vector2(100f, 100f);
				}
			}
		}

		public class FVRWristMenuSection_Safehouse2 : FVRWristMenuSection
		{
			public override void Enable()
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = ShSpawnItems.SpawnItemFromOD("NGA_sp3Hud");
				val.transform.Rotate(0f, -90f, 0f, (Space)1);
			}

			public override void Disable()
			{
			}

			public override void OnHide()
			{
			}
		}

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Harmony val = new Harmony("NGA.SafehouseProgressionMPatchy");
			Logger.LogMessage((object)"New harmony");
			SetUpConfigFields();
			Logger.LogMessage((object)"Setted the fields");
			val.PatchAll();
			Logger.LogMessage((object)"Hello, world! Sent from NGA.SafehouseProgressionMPatchy");
		}

		private void SetUpConfigFields()
		{
		}

		public static FVRWristMenuSection_Safehouse2 AddWristMenuSection(FVRWristMenu2 wristMenu)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Expected O, but got Unknown
			FVRWristMenuSection val = wristMenu.Sections.First((FVRWristMenuSection x) => (object)((object)x).GetType() == typeof(FVRWristMenuSection_Spawn));
			Transform transform = ((Component)val).transform;
			FVRWristMenuSection val2 = Object.Instantiate<FVRWristMenuSection>(val, transform.position, transform.rotation, transform.parent);
			GameObject gameObject = ((Component)val2).gameObject;
			GameObject gameObject2 = ((Component)gameObject.transform.parent).gameObject;
			Object.Destroy((Object)(object)val2);
			Image component = gameObject.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				string pluginModFolder = ShFileIoHandler.GetPluginModFolder();
				string absolutePath = Path.Combine(pluginModFolder, "icon.png");
				Texture2D val3 = ShFileIoHandler.LoadTextureFromFullPath(absolutePath);
				RectTransform rectTransform = ((Graphic)component).rectTransform;
				Vector2 sizeDelta = rectTransform.sizeDelta;
				Sprite sprite = Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), new Vector2(0.5f, 0.5f));
				component.sprite = sprite;
				rectTransform.sizeDelta = sizeDelta;
			}
			else
			{
				Logger.LogError((object)"No Image component found in my Section.");
			}
			FVRWristMenuSection_Safehouse2 fVRWristMenuSection_Safehouse = gameObject.AddComponent<FVRWristMenuSection_Safehouse2>();
			((FVRWristMenuSection)fVRWristMenuSection_Safehouse).ButtonText = "SHP3-swap";
			((FVRWristMenuSection)fVRWristMenuSection_Safehouse).Menu = wristMenu;
			wristMenu.Sections.Add((FVRWristMenuSection)(object)fVRWristMenuSection_Safehouse);
			wristMenu.BaseButton.AddComponent<SwapIconHandler>();
			wristMenu.RegenerateButtons();
			RectTransform val4 = (RectTransform)((Component)fVRWristMenuSection_Safehouse).transform;
			int childCount = ((Transform)val4).childCount;
			for (int num = childCount - 1; num >= 0; num--)
			{
				RectTransform val5 = (RectTransform)((Transform)val4).GetChild(num);
				Object.DestroyImmediate((Object)(object)((Component)val5).gameObject);
			}
			return fVRWristMenuSection_Safehouse;
		}
	}
	public static class ShHomesVault
	{
		private const string HOMES_FOLDER = "Homes";

		private const string OFFICIAL_FILE = "official.json";

		private const string BACKUPS_FOLDER = "Backups";

		private const string BACKUP_EXT = ".json";

		public static string GetVaultProfileRoot(string profileUid)
		{
			return Path.Combine(Path.Combine(ShFileIoHandler.GetH3SaveFolder(), ShFileIoHandler.rootSaveFolder), profileUid);
		}

		public static string GetHomeFolder(string profileUid, string sceneId)
		{
			return Path.Combine(Path.Combine(GetVaultProfileRoot(profileUid), "Homes"), sceneId);
		}

		public static string GetOfficialHomePath(string profileUid, string sceneId)
		{
			return Path.Combine(GetHomeFolder(profileUid, sceneId), "official.json");
		}

		public static string GetBackupHomeFolder(string profileUid, string sceneId)
		{
			return Path.Combine(GetHomeFolder(profileUid, sceneId), "Backups");
		}

		public static string MakeBackupHomeFilePath(string profileUid, string sceneId, DateTime when)
		{
			string text = when.ToString("yyyy-MM-dd_HH-mm-ss");
			return Path.Combine(GetBackupHomeFolder(profileUid, sceneId), text + ".json");
		}

		public static bool TrySaveOfficialHome(string profileUid, string sceneId, out string error)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			error = null;
			Scene activeScene = SceneManager.GetActiveScene();
			string name = ((Scene)(ref activeScene)).name;
			if (!string.Equals(name, sceneId, StringComparison.Ordinal))
			{
				error = "Active scene '" + name + "' does not match sceneId '" + sceneId + "'.";
				Debug.LogWarning((object)error);
				return false;
			}
			if (!TryScanCurrentScene(out var vf, out error))
			{
				Debug.LogError((object)("TrySaveOfficialHome: " + error));
				return false;
			}
			string officialHomePath = GetOfficialHomePath(profileUid, sceneId);
			ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(officialHomePath));
			if (!ShFileIoHandler.TrySaveJson(vf, officialHomePath, out error))
			{
				Debug.LogError((object)("TrySaveOfficialHome: " + error));
				return false;
			}
			return true;
		}

		public static bool TryLoadOfficialHome(string profileUid, string sceneId, out string error)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			string officialHomePath = GetOfficialHomePath(profileUid, sceneId);
			if (!ShFileIoHandler.TryLoadJson<VaultFile>(officialHomePath, out VaultFile obj, out error))
			{
				Debug.LogError((object)("TryLoadOfficialHome: Failed to parse json w: " + error + " on file " + officialHomePath));
				return false;
			}
			Transform val = null;
			return VaultSystem.SpawnObjects((VaultFileDisplayMode)2, obj, ref error, val, Vector3.zero);
		}

		public static bool TrySaveBackupHome(string profileUid, string sceneId, out string backupFileName, out string error)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			backupFileName = null;
			error = null;
			Scene activeScene = SceneManager.GetActiveScene();
			string name = ((Scene)(ref activeScene)).name;
			if (!string.Equals(name, sceneId, StringComparison.Ordinal))
			{
				error = "Active scene '" + name + "' does not match sceneId '" + sceneId + "'.";
				Debug.LogWarning((object)error);
				return false;
			}
			if (!TryScanCurrentScene(out var vf, out error))
			{
				Debug.LogError((object)("TrySaveBackupHome: " + error));
				return false;
			}
			string text = MakeBackupHomeFilePath(profileUid, sceneId, DateTime.UtcNow);
			ShFileIoHandler.EnsureDirectory(Path.GetDirectoryName(text));
			if (!ShFileIoHandler.TrySaveJson(vf, text, out error))
			{
				Debug.LogError((object)("TrySaveBackupHome: " + error));
				return false;
			}
			backupFileName = Path.GetFileName(text);
			TryPruneHomeBackups(profileUid, sceneId, 5);
			return true;
		}

		public static bool TryLoadBackupHome(string profileUid, string sceneId, string backupFileName, out string error)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			string backupHomeFolder = GetBackupHomeFolder(profileUid, sceneId);
			string text = Path.Combine(backupHomeFolder, backupFileName);
			if (!ShFileIoHandler.TryLoadJson<VaultFile>(text, out VaultFile obj, out error))
			{
				Debug.LogError((object)("TryLoadBackupHome: Failed to parse json w: " + error + " on file " + text));
				return false;
			}
			Transform val = null;
			return VaultSystem.SpawnObjects((VaultFileDisplayMode)2, obj, ref error, val, Vector3.zero);
		}

		public static List<string> ListBackupHomes(string profileUid, string sceneId)
		{
			List<string> list = new List<string>();
			string backupHomeFolder = GetBackupHomeFolder(profileUid, sceneId);
			if (!Directory.Exists(backupHomeFolder))
			{
				return list;
			}
			string[] files = Directory.GetFiles(backupHomeFolder, "*.json");
			Array.Sort(files);
			for (int i = 0; i < files.Length; i++)
			{
				list.Add(Path.GetFileName(files[i]));
			}
			return list;
		}

		public static bool TryDeleteAllForHome(string profileUid, string sceneId, out string error)
		{
			error = null;
			try
			{
				string homeFolder = GetHomeFolder(profileUid, sceneId);
				if (Directory.Exists(homeFolder))
				{
					Directory.Delete(homeFolder, recursive: true);
				}
				return true;
			}
			catch (Exception ex)
			{
				error = "DeleteAllForHome failed: " + ex.Message;
				Debug.LogError((object)error);
				return false;
			}
		}

		private static bool TryScanCurrentScene(out VaultFile vf, out string error)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			vf = new VaultFile();
			error = null;
			if (!VaultSystem.FindAndScanObjectsInScene(vf))
			{
				error = "Scene scan failed.";
				return false;
			}
			return true;
		}

		private static void TryPruneHomeBackups(string profileUid, string sceneId, int maxCount)
		{
			try
			{
				string backupHomeFolder = GetBackupHomeFolder(profileUid, sceneId);
				if (!Directory.Exists(backupHomeFolder))
				{
					return;
				}
				string[] files = Directory.GetFiles(backupHomeFolder, "*.json", SearchOption.TopDirectoryOnly);
				if (files == null || files.Length <= maxCount)
				{
					return;
				}
				Array.Sort(files, (IComparer<string>?)StringComparer.Ordinal);
				int num = files.Length - maxCount;
				for (int i = 0; i < num; i++)
				{
					try
					{
						File.Delete(files[i]);
					}
					catch (Exception ex)
					{
						Debug.LogWarning((object)("backup prune: failed to delete '" + files[i] + "': " + ex.Message));
					}
				}
			}
			catch (Exception ex2)
			{
				Debug.LogWarning((object)("backup prune error: " + ex2.Message));
			}
		}
	}
	[Serializable]
	public class ShHouseDef
	{
		public int price;

		public string sceneId;

		public string displayName;

		public string description;

		public string state;

		private readonly string _built = "Built";

		private readonly string _owned = "Owned";

		private readonly string _market = "Market";

		public string lastSavedTime;

		public string timeSpent;

		public List<string> backupFileNames { get; private set; }

		public bool canBuy()
		{
			if (state != _market)
			{
				Debug.LogWarning((object)("Attempted to buy a house that isn't on market: " + sceneId + " " + state));
				return false;
			}
			return true;
		}

		public void setBought()
		{
			state = _owned;
		}

		public bool canSell()
		{
			if (state == _market)
			{
				Debug.LogWarning((object)("Attempted to sell a house that is not owned: " + sceneId + " " + state));
				return false;
			}
			return true;
		}

		public void setMarket()
		{
			state = _market;
		}

		public bool canBuild()
		{
			if (state != _owned)
			{
				Debug.LogError((object)("Attempted to BUILD house that wasn't OWNED: " + sceneId + " " + state));
				return false;
			}
			return true;
		}

		public bool isBuilt()
		{
			return state == _built;
		}

		public void setBuilt()
		{
			state = _built;
		}

		public Texture2D getMapIcon()
		{
			foreach (CustomSceneInfo customSceneInfo in AtlasPlugin.CustomSceneInfos)
			{
				if (customSceneInfo.Identifier == sceneId)
				{
					return customSceneInfo.ThumbnailTexture;
				}
			}
			return null;
		}

		public void UpdateLastSavedTime()
		{
			lastSavedTime = ShTimeCalculator.dateTimeToString(DateTime.UtcNow);
		}

		public void UpdateStartedUsing()
		{
		}

		public bool SaveBackup(string profileUid, out string backupFileName)
		{
			backupFileName = null;
			if (state != _built)
			{
				Debug.LogWarning((object)("Attempted to save backup on a house that is not built: " + sceneId));
				return false;
			}
			if (!ShHomesVault.TrySaveBackupHome(profileUid, sceneId, out backupFileName, out var error))
			{
				Debug.LogError((object)("SaveBackup failed: " + error));
				return false;
			}
			RefreshBackupList(profileUid);
			return true;
		}

		public bool LoadBackup(string profileUid, string fileName)
		{
			if (state != _built)
			{
				Debug.LogWarning((object)("Attempted to load backup on a house that is not built: " + sceneId));
				return false;
			}
			RefreshBackupList(profileUid);
			if (backupFileNames == null || !backupFileNames.Contains(fileName))
			{
				Debug.LogWarning((object)("Attempted to load non-existent backup file: " + fileName));
				return false;
			}
			if (!ShHomesVault.TryLoadBackupHome(profileUid, sceneId, fileName, out var error))
			{
				Debug.LogError((object)("LoadBackup failed: " + error));
				return false;
			}
			return true;
		}

		public void RefreshBackupList(string profileUid)
		{
			backupFileNames = ShHomesVault.ListBackupHomes(profileUid, sceneId);
		}
	}
	[Serializable]
	public class ShHousePortfolio
	{
		public List<ShHouseDef> houseDefs;

		public ShHouseDef selectedSafehouse;

		public ShHousePortfolio()
		{
			Init();
		}

		public void SetSelectedSafehouse(string sceneId)
		{
			if (sceneId == null || sceneId == "")
			{
				Debug.LogError((object)"Attempted to set selected safehouse to null");
				return;
			}
			ShHouseDef shHouseDef = houseDefs.Find((ShHouseDef hd) => hd.sceneId == sceneId);
			if (shHouseDef == null)
			{
				Debug.LogError((object)("Attempted to set selected safehouse to one not in portfolio: " + sceneId));
			}
			else
			{
				selectedSafehouse = shHouseDef;
			}
		}

		public void Init()
		{
			if (houseDefs == null)
			{
				houseDefs = new List<ShHouseDef>();
			}
			findAndStoreAllSandboxes();
			selectedSafehouse = GetLastPlayedHouse();
		}

		public ShHouseDef getHouseDef(string sceneId)
		{
			foreach (ShHouseDef houseDef in houseDefs)
			{
				if (houseDef.sceneId == sceneId)
				{
					return houseDef;
				}
			}
			Debug.LogError((object)("Could not find house with scene id: " + sceneId));
			return null;
		}

		public void findAndStoreAllSandboxes()
		{
			foreach (CustomSceneInfo customSceneInfo in AtlasPlugin.CustomSceneInfos)
			{
				if (customSceneInfo.GameMode == "sandbox" || customSceneInfo.DisplayMode == "sandbox")
				{
					ShHouseDef houseDef = getHouseDef(customSceneInfo.Identifier);
					if (houseDef == null)
					{
						ShHouseDef item = new ShHouseDef
						{
							sceneId = customSceneInfo.Identifier,
							displayName = customSceneInfo.DisplayName,
							description = customSceneInfo.Description,
							price = 1,
							state = "Market",
							lastSavedTime = "1970-01-01T00:00:00",
							timeSpent = "0s"
						};
						houseDefs.Add(item);
					}
					else
					{
						houseDef.displayName = customSceneInfo.DisplayName;
						houseDef.description = customSceneInfo.Description;
					}
				}
			}
		}

		public ShHouseDef GetLastPlayedHouse()
		{
			if (houseDefs.Count == 0)
			{
				Debug.LogWarning((object)"No houseDefs in portfolio, no last played house.");
				return null;
			}
			ShHouseDef shHouseDef = houseDefs[0];
			foreach (ShHouseDef houseDef in houseDefs)
			{
				if (ShTimeCalculator.stringToDateTime(houseDef.lastSavedTime) > ShTimeCalculator.stringToDateTime(shHouseDef.lastSavedTime))
				{
					shHouseDef = houseDef;
				}
			}
			if (shHouseDef.canSell())
			{
				return shHouseDef;
			}
			return null;
		}
	}
	public class SceneTravelManager : MonoBehaviour
	{
		private static SceneTravelManager _instance;

		private readonly Dictionary<TravelScenario, ITravelAction> _actions = new Dictionary<TravelScenario, ITravelAction>();

		private TravelRequest? _pending;

		private int _opId;

		private Coroutine _runner;

		public event Action<TravelRequest> OnBeforeLoad;

		public event Action<TravelRequest> OnReadyToPopulate;

		public event Action<TravelRequest> OnTravelCompleted;

		public static SceneTravelManager Ensure()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if ((Object)(object)_instance != (Object)null)
			{
				return _instance;
			}
			GameObject val = new GameObject("~SceneTravelManager");
			_instance = val.AddComponent<SceneTravelManager>();
			Object.DontDestroyOnLoad((Object)(object)val);
			return _instance;
		}

		private void Awake()
		{
			if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			_instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			_actions[TravelScenario.Home] = new HomeTravelAction();
			_actions[TravelScenario.TakeAndHold] = new TakeAndHoldAction();
			_actions[TravelScenario.SupplyRaid] = new SupplyRaidAction();
			SceneManager.activeSceneChanged += OnActiveSceneChanged;
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnDestroy()
		{
			SceneManager.activeSceneChanged -= OnActiveSceneChanged;
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		public void RequestTravel(TravelRequest request)
		{
			_opId++;
			if (_runner != null)
			{
				((MonoBehaviour)this).StopCoroutine(_runner);
			}
			_pending = request;
			if (this.OnBeforeLoad != null)
			{
				this.OnBeforeLoad(request);
			}
			UnityLoadScene(request.SceneId);
			_runner = ((MonoBehaviour)this).StartCoroutine(WaitAndPopulate(_opId));
		}

		private IEnumerator WaitAndPopulate(int myOp)
		{
			Debug.Log((object)$"[Travel] ({myOp}) stage 1: waiting for active scene to match pending...");
			yield return (object)new WaitUntil((Func<bool>)delegate
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				if (!_pending.HasValue)
				{
					return false;
				}
				Scene activeScene = SceneManager.GetActiveScene();
				return ((Scene)(ref activeScene)).name == _pending.Value.SceneId;
			});
			Debug.Log((object)$"[Travel] ({myOp}) stage 1 DONE active scene is now {_pending.Value.SceneId}");
			Debug.Log((object)$"[Travel] ({myOp}) stage 2: waiting for GM.IsAsyncLoading == false");
			yield return (object)new WaitUntil((Func<bool>)(() => !GM.IsAsyncLoading));
			Debug.Log((object)$"[Travel] ({myOp}) stage 2 DONE GM async cleared");
			if (myOp != _opId)
			{
				Debug.Log((object)$"[Travel] ({myOp}) aborted newer op {_opId} detected");
				yield break;
			}
			TravelRequest req = _pending.Value;
			Debug.Log((object)$"[Travel] ({myOp}) stage 3: OnReadyToPopulate -> {req.SceneId}/{req.Scenario}");
			this.OnReadyToPopulate?.Invoke(req);
			if (_actions.TryGetValue(req.Scenario, out var action) && action != null)
			{
				Debug.Log((object)$"[Travel] ({myOp}) running scenario action: {req.Scenario}");
				TravelContext ctx = new TravelContext
				{
					SceneId = req.SceneId,
					Scenario = req.Scenario,
					ProfileUid = req.ProfileUid,
					Payload = req.Payload
				};
				yield return ((MonoBehaviour)this).StartCoroutine(action.Run(ctx));
				Debug.Log((object)$"[Travel] ({myOp}) scenario action finished: {req.Scenario}");
			}
			else
			{
				Debug.Log((object)$"[Travel] ({myOp}) no action for scenario: {req.Scenario}");
			}
			Debug.Log((object)$"[Travel] ({myOp}) stage 4: travel completed");
			this.OnTravelCompleted?.Invoke(req);
			_pending = null;
			_runner = null;
			Debug.Log((object)$"[Travel] ({myOp}) state cleared");
		}

		private static void UnityLoadScene(string sceneId)
		{
			CustomSceneInfo customScene = AtlasPlugin.GetCustomScene(sceneId);
			if (customScene != null)
			{
				AtlasPlugin.LoadCustomScene(customScene.Identifier);
			}
			else
			{
				SteamVR_LoadLevel.Begin(sceneId, false, 0.5f, 0f, 0f, 0f, 1f);
			}
		}

		private void OnActiveSceneChanged(Scene oldScene, Scene newScene)
		{
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
		}
	}
	public enum TravelScenario
	{
		None,
		Home,
		TakeAndHold,
		SupplyRaid
	}
	public class ShSceneTravel
	{
		public static void Request(string profileUid, string sceneId, TravelScenario scenario)
		{
			SceneTravelManager.Ensure().RequestTravel(new TravelRequest(sceneId, scenario, profileUid, null));
		}

		public static void Request(string profileUid, string sceneId, TravelScenario scenario, object payload)
		{
			SceneTravelManager.Ensure().RequestTravel(new TravelRequest(sceneId, scenario, profileUid, payload));
		}
	}
	public interface ITravelAction
	{
		IEnumerator Run(TravelContext ctx);
	}
	public class HomeTravelAction : ITravelAction
	{
		public IEnumerator Run(TravelContext ctx)
		{
			PopulateHome(ctx.SceneId, ctx.ProfileUid);
			yield break;
		}

		private void PopulateHome(string sceneId, string profileUid)
		{
			ShProfileState currentProfile = SHGM.saveState.currentProfile;
			if (currentProfile == null)
			{
				Debug.LogError((object)"Populate Home: No current profile selected");
				return;
			}
			ShHouseDef houseDef = currentProfile.housePortfolio.getHouseDef(sceneId);
			string error;
			if (houseDef == null)
			{
				Debug.LogError((object)("Populate Home: Housedef is null for scene id: " + sceneId));
			}
			else if (!ShHomesVault.TryLoadOfficialHome(profileUid, sceneId, out error))
			{
				Debug.LogError((object)("LoadHouse: no official save found for " + sceneId + " (" + error + ")"));
			}
			else
			{
				houseDef.UpdateStartedUsing();
			}
		}
	}
	public class TakeAndHoldAction : ITravelAction
	{
		public IEnumerator Run(TravelContext ctx)
		{
			yield break;
		}
	}
	public class SupplyRaidAction : ITravelAction
	{
		public IEnumerator Run(TravelContext ctx)
		{
			yield break;
		}
	}
	public struct TravelRequest
	{
		public readonly string SceneId;

		public readonly TravelScenario Scenario;

		public readonly string ProfileUid;

		public readonly object Payload;

		public TravelRequest(string sceneId, TravelScenario scenario, string profileUid, object payload)
		{
			SceneId = sceneId;
			Scenario = scenario;
			ProfileUid = profileUid;
			Payload = payload;
		}
	}
	public sealed class TravelContext
	{
		public string SceneId;

		public string ProfileUid;

		public TravelScenario Scenario;

		public object Payload;
	}
	public class SHGM : MonoBehaviour
	{
		public static ShMetaState saveState;

		public static SHGM Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			}
			else
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private void Start()
		{
			SceneManager.sceneLoaded += OnSceneLoaded;
			if (!GM.CurrentSceneSettings.QuitReceivers.Contains(((Component)this).gameObject))
			{
				GM.CurrentSceneSettings.QuitReceivers.Add(((Component)this).gameObject);
			}
			ViewModelRegistry.Ensure();
			ViewModelRegistry.Prewarm<ProfileViewModel>();
			ViewModelRegistry.Prewarm<PortfolioViewModel>();
			ViewModelRegistry.Prewarm<BankViewModel>();
			ViewModelRegistry.Prewarm<LoadoutsViewModel>();
			Init();
		}

		private void Init()
		{
			Debug.LogWarning((object)"-------> SH Init");
			if (ShFileIoHandler.LoadGameState(out var state))
			{
				saveState = state;
				Debug.LogWarning((object)"-------> SH Loaded existing game state.");
				return;
			}
			saveState = new ShMetaState();
			saveState.allProfiles = new List<ShProfileState>();
			saveState.currentProfile = null;
			Debug.LogWarning((object)"-------> SH Created new game state.");
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			Debug.LogWarning((object)"-------> SHGM OnSceneLoaded");
			if (!GM.CurrentSceneSettings.QuitReceivers.Contains(((Component)this).gameObject))
			{
				GM.CurrentSceneSettings.QuitReceivers.Add(((Component)this).gameObject);
			}
		}

		public void SaveGame()
		{
			if (saveState != null)
			{
				saveState.SaveMetaState();
				if (ShFileIoHandler.SaveGameState(saveState))
				{
					Debug.LogWarning((object)"-------> SHGM Game state saved successfully.");
				}
				else
				{
					Debug.LogError((object)"-------> SHGM Failed to save game state.");
				}
			}
			else
			{
				Debug.LogError((object)"-------> SHGM No game state to save.");
			}
		}

		private void QUIT()
		{
			SaveGame();
		}
	}
	[Serializable]
	public class ShMetaState
	{
		public ShProfileState currentProfile;

		public List<ShProfileState> allProfiles;

		public ShProfileState getProfileState(string uid)
		{
			foreach (ShProfileState allProfile in allProfiles)
			{
				if (allProfile.uid == uid)
				{
					return allProfile;
				}
			}
			return null;
		}

		public void SaveMetaState()
		{
			currentProfile.SaveCharacter();
		}

		public void SwapProfile(string uid)
		{
			if (string.IsNullOrEmpty(uid))
			{
				Debug.LogError((object)"SwapProfile: uid is null or empty");
				return;
			}
			ShProfileState shProfileState = allProfiles.Find((ShProfileState p) => p.uid == uid);
			if (shProfileState == null)
			{
				Debug.LogError((object)"SwapProfile: profile not found");
				return;
			}
			if (currentProfile != null)
			{
				currentProfile.SaveCharacter();
			}
			SHGM.saveState.currentProfile = shProfileState;
			currentProfile.updateSaveTimes();
		}

		public void AddProfile(ShProfileState newChar)
		{
			if (newChar == null)
			{
				Debug.LogError((object)"AddCharacter: newChar is null");
			}
			else if (allProfiles.Contains(newChar))
			{
				Debug.LogWarning((object)"AddCharacter: newChar already exists in allCharacters, skipping.");
			}
			else
			{
				allProfiles.Add(newChar);
			}
		}

		public void RemoveProfile(string uid)
		{
			if (string.IsNullOrEmpty(uid))
			{
				Debug.LogError((object)"RemoveProfile: uid is null or empty");
				return;
			}
			ShProfileState shProfileState = allProfiles.Find((ShProfileState p) => p.uid == uid);
			if (shProfileState == null)
			{
				Debug.LogWarning((object)"RemoveProfile: profile not found, skipping.");
				return;
			}
			if (currentProfile != null && currentProfile.uid == uid)
			{
				currentProfile = null;
			}
			allProfiles.Remove(shProfileState);
		}
	}
	[Serializable]
	public class ShProfileState
	{
		public string uid;

		public string faceIcon;

		public string displayName;

		public int currentRank;

		public int currentXP;

		public List<string> notificationEvents;

		public string timePlayed;

		public string lastSavedTime;

		public ShHousePortfolio housePortfolio;

		public ShLoadoutRack loadoutRack;

		public ShGiftsList giftsList;

		public ShBank bank;

		public void Init()
		{
			housePortfolio.Init();
		}

		public ShProfileState()
		{
			uid = Guid.NewGuid().ToString();
			faceIcon = "";
			displayName = "New Player";
			currentRank = 1;
			currentXP = 0;
			notificationEvents = new List<string>();
			timePlayed = "0s";
			lastSavedTime = ShTimeCalculator.dateTimeToString(DateTime.UtcNow);
			housePortfolio = new ShHousePortfolio();
			loadoutRack = new ShLoadoutRack();
			giftsList = new ShGiftsList();
			bank = new ShBank();
		}

		public static ShProfileState CreateDefaultCharacter()
		{
			ShProfileState shProfileState = new ShProfileState();
			shProfileState.displayName = "Hero";
			shProfileState.faceIcon = "";
			shProfileState.currentRank = 1;
			shProfileState.currentXP = 0;
			shProfileState.bank.IncrementPlyBalance(100);
			return shProfileState;
		}

		public void SaveCharacter()
		{
			updateTimePlayed();
			updateSaveTimes();
		}

		public void updateTimePlayed()
		{
			DateTime utcNow = DateTime.UtcNow;
			TimeSpan timeSpan = utcNow - ShTimeCalculator.stringToDateTime(lastSavedTime);
			TimeSpan duration = timeSpan + ShTimeCalculator.stringToDuration(timePlayed);
			timePlayed = ShTimeCalculator.durationToString(duration);
		}

		public void updateSaveTimes()
		{
			lastSavedTime = ShTimeCalculator.dateTimeToString(DateTime.UtcNow);
		}
	}
	public class ShBank
	{
		[Serializable]
		public class TransactionRecord
		{
			public int amount;

			public string description;

			public TransactionRecord(int amount, string description)
			{
				this.amount = amount;
				this.description = description;
			}
		}

		public int playerBalance { get; private set; }

		public List<TransactionRecord> transactions { get; private set; }

		public ShBank()
		{
			playerBalance = 0;
			transactions = new List<TransactionRecord>();
		}

		public bool TryDecrementPlyBalance(int amount)
		{
			if (playerBalance >= amount)
			{
				playerBalance -= amount;
				return true;
			}
			return false;
		}

		public void ForceDecrementPlyBalance(int amount)
		{
			playerBalance -= amount;
		}

		public void IncrementPlyBalance(int amount)
		{
			playerBalance += amount;
		}

		public bool ProcessTransaction(TransactionRecord transaction, bool forceDecrement)
		{
			if (transaction.amount < 0)
			{
				if (forceDecrement)
				{
					ForceDecrementPlyBalance(-transaction.amount);
				}
				else if (!TryDecrementPlyBalance(-transaction.amount))
				{
					return false;
				}
			}
			else
			{
				IncrementPlyBalance(transaction.amount);
			}
			transactions.Insert(0, transaction);
			return true;
		}

		public string PrintPlyBankInfo(int maxTransactions = 10)
		{
			string text = $"<b>Current balance:</b> ${playerBalance:N0}\n\n";
			text += "<b>Recent transactions:</b>\n";
			int num = 0;
			foreach (TransactionRecord transaction in transactions)
			{
				if (num++ >= maxTransactions)
				{
					break;
				}
				text += $"${transaction.amount:N0} {transaction.description}\n";
			}
			return text;
		}
	}
	public class ShCharDetailsUi : MonoBehaviour
	{
		private Transform background;

		private Transform faceIcon;

		private Transform levelProgressCircle;

		private Transform levelIcon;

		private Transform levelXpSlash;

		private Transform levelName;

		private Transform levelNumber;

		private Transform charName;

		private Transform overallDetails;

		private Transform habitsDetails;

		private Transform recordsDetails;

		private Transform nameInputField;

		private ProfileViewModel vm;

		private BankViewModel vm_bank;

		private string selectedPfpFilename = "";

		private string currentCharName = "";

		private void Awake()
		{
			FindUiVariables();
		}

		private void OnEnable()
		{
			vm = ProfileViewModel.Instance;
			vm.Changed += Redraw;
			vm_bank = BankViewModel.Instance;
			vm_bank.Changed += Redraw;
			Redraw();
		}

		private void OnDisable()
		{
			if (vm != null)
			{
				vm.Changed -= Redraw;
			}
			if (vm_bank != null)
			{
				vm_bank.Changed -= Redraw;
			}
		}

		private void FindUiVariables()
		{
			background = ((Component)this).transform.Find("Background");
			faceIcon = background.Find("FaceIcon");
			levelProgressCircle = background.Find("LevelProgressBar");
			levelIcon = background.Find("Level");
			levelXpSlash = background.Find("LevelXp");
			levelName = background.Find("LevelName");
			levelNumber = background.Find("LevelNumber");
			charName = background.Find("CharName");
			overallDetails = background.Find("OverallPanel").Find("Details");
			habitsDetails = background.Find("HabitsPanel").Find("Details");
			recordsDetails = background.Find("RecordsPanel").Find("Details");
			nameInputField = background.Find("InputField");
		}

		private void ClearDetails()
		{
			((Component)faceIcon).GetComponent<RawImage>().texture = null;
			((Component)levelProgressCircle).GetComponent<Image>().fillAmount = 0f;
			((Component)levelIcon).GetComponent<RawImage>().texture = null;
			((Component)levelXpSlash).GetComponent<Text>().text = "/ XP";
			((Component)levelName).GetComponent<Text>().text = "Level Name";
			((Component)levelNumber).GetComponent<Text>().text = "0";
			((Component)charName).GetComponent<Text>().text = "No Character Selected";
			((Component)overallDetails).GetComponent<Text>().text = "<b>Overall</b>";
			((Component)habitsDetails).GetComponent<Text>().text = "<b>Habits</b>";
			((Component)recordsDetails).GetComponent<Text>().text = "<b>Records</b>";
		}

		public void Redraw()
		{
			ShProfileState currentProfileState = vm.GetCurrentProfileState();
			if (currentProfileState == null)
			{
				AnimateToState(0);
				return;
			}
			AnimateToState(1);
			((Component)charName).GetComponent<Text>().text = currentProfileState.displayName;
			currentCharName = currentProfileState.displayName;
			selectedPfpFilename = currentProfileState.faceIcon;
			((Component)levelNumber).GetComponent<Text>().text = currentProfileState.currentRank.ToString();
			((Component)levelName).GetComponent<Text>().text = ShRankCalculator.getRankName(currentProfileState.currentRank);
			((Component)levelProgressCircle).GetComponent<Image>().fillAmount = ShRankCalculator.getRankProgressPercent(currentProfileState.currentXP, currentProfileState.currentRank);
			((Component)levelXpSlash).GetComponent<Text>().text = $"{currentProfileState.currentXP} / {ShRankCalculator.getMaxRankXP(currentProfileState.currentRank)} XP";
			((Component)faceIcon).GetComponent<RawImage>().texture = (Texture)(object)PfpManager.getTextureByFilename(currentProfileState.faceIcon);
			((Component)levelIcon).GetComponent<RawImage>().texture = (Texture)(object)ShFileIoHandler.LoadFromModTexture("NGA-SafehouseProgressionMode", ShRankCalculator.getRankIconFileName(currentProfileState.currentRank));
			((Component)overallDetails).GetComponent<Text>().text = $"<b>Overall</b>\nTime Played: {currentProfileState.timePlayed}\nCash: <color=#00FF00><b>₿{currentProfileState.bank.playerBalance}</b></color>";
			((Component)habitsDetails).GetComponent<Text>().text = "<b>Habits</b>\n- Habit details not implemented -";
			((Component)recordsDetails).GetComponent<Text>().text = "<b>Records</b>\n- Record details not implemented -";
		}

		public void BTN_NextPfp()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			SM.PlayGlobalUISound((GlobalUISound)0, ((Component)this).transform.position);
			if (vm.IsAnyProfileActive())
			{
				string filename;
				Texture2D nextPic = PfpManager.getNextPic(out filename);
				if ((Object)(object)nextPic != (Object)null)
				{
					selectedPfpFilename = filename;
					((Component)faceIcon).GetComponent<RawImage>().texture = (Texture)(object)nextPic;
				}
			}
		}

		public void BTN_PrevPfp()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			SM.PlayGlobalUISound((GlobalUISound)1, ((Component)this).transform.position);
			if (vm.IsAnyProfileActive())
			{
				string filename;
				Texture2D prevPic = PfpManager.getPrevPic(out filename);
				if ((Object)(object)prevPic != (Object)null)
				{
					selectedPfpFilename = filename;
					((Component)faceIcon).GetComponent<RawImage>().texture = (Texture)(object)prevPic;
				}
			}
		}

		public void BTN_UpdateCharacter()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			SM.PlayGlobalUISound((GlobalUISound)1, ((Component)this).transform.position);
			if (vm.IsAnyProfileActive())
			{
				vm.UpdateProfileDisplayInfo(selectedPfpFilename, currentCharName);
			}
		}

		public void BTN_SetCharacterName()
		{
			((Component)charName).GetComponent<Text>().text = ((Component)nameInputField).GetComponent<InputField>().text;
			currentCharName = ((Component)charName).GetComponent<Text>().text;
		}

		public void BTN_DeleteCharacter()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			SM.PlayGlobalUISound((GlobalUISound)1, ((Component)this).transform.position);
			vm.RemoveProfile(vm.GetCurrentProfileUid());
		}

		public void AnimateToState(int stage)
		{
			switch (stage)
			{
			case 0:
				((Component)background).gameObject.SetActive(false);
				break;
			case 1:
				((Component)background).gameObject.SetActive(true);
				break;
			default:
				Debug.LogWarning((object)$"Unknown stage: {stage}");
				break;
			}
		}
	}
	public class ShCharSelectUi : MonoBehaviour
	{
		public Color unselectedColor = Color32.op_Implicit(new Color32((byte)82, (byte)72, (byte)72, byte.MaxValue));

		public Color selectedColor = Color32.op_Implicit(new Color32((byte)72, (byte)82, (byte)72, byte.MaxValue));

		public List<Transform> locations;

		private Transform VertList;

		private Transform ExampleEntry;

		private ProfileViewModel vm;

		private BankViewModel vm_bank;

		private List<ShProfileState> currentItemsList;

		public void Awake()
		{
			FindUiVariables();
		}

		private void OnEnable()
		{
			vm = ProfileViewModel.Instance;
			vm.Changed += Redraw;
			vm_bank = BankViewModel.Instance;
			vm_bank.Changed += Redraw;
			Redraw();
		}

		private void OnDisable()
		{
			if (vm != null)
			{
				vm.Changed -= Redraw;
			}
			if (vm_bank != null)
			{
				vm_bank.Changed -= Redraw;
			}
		}

		private void FindUiVariables()
		{
			VertList = ((Component)this).transform.Find("Scroll View").Find("Viewport").Find("Content");
			ExampleEntry = ((Component)this).transform.Find("Scroll View").Find("ExampleEntry");
		}

		private Transform ConfigureEntry(ShProfileState entryData, int iterIx)
		{
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			Transform transform = Object.Instantiate<GameObject>(((Component)ExampleEntry).gameObject, VertList).transform;
			((Component)transform.Find("FaceIcon")).GetComponentInChildren<RawImage>().texture = (Texture)(object)PfpManager.getTextureByFilename(entryData.faceIcon);
			Text component = ((Component)transform.Find("CharName")).GetComponent<Text>();
			component.text = entryData.displayName;
			((Component)transform.Find("Level")).GetComponent<RawImage>().texture = (Texture)(object)((ShRankCalculator.getRankIconFileName(entryData.currentRank) == "") ? null : ShFileIoHandler.LoadFromModTexture("NGA-SafehouseProgressionMode", ShRankCalculator.getRankIconFileName(entryData.currentRank)));
			Text component2 = ((Component)transform.Find("LevelName")).GetComponent<Text>();
			component2.text = $"{ShRankCalculator.getRankName(entryData.currentRank)}\n({entryData.currentRank})";
			Text component3 = ((Component)transform.Find("Details")).GetComponent<Text>();
			component3.text = $"<color=#00FF00><b>₿{entryData.bank.playerBalance}</b></color>\nLast Played: {entryData.lastSavedTime}\nTime Played: {entryData.timePlayed}";
			int index = iterIx;
			Button component4 = ((Component)transform).GetComponent<Button>();
			((UnityEventBase)component4.onClick).RemoveAllListeners();
			((UnityEvent)component4.onClick).AddListener((UnityAction)delegate
			{
				BTN_SelectEntryBehavior(index);
			});
			((Component)transform).gameObject.SetActive(true);
			return transform;
		}

		public void Redraw()
		{
			int childCount = VertList.childCount;
			for (int num = VertList.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)VertList.GetChild(num)).gameObject);
			}
			currentItemsList = vm.listProfilesSortedByAlph();
			int num2 = -1;
			for (int i = 0; i < currentItemsList.Count; i++)
			{
				ShProfileState shProfileState = currentItemsList[i];
				if (shProfileState.uid == vm.GetCurrentProfileUid())
				{
					num2 = i;
				}
				ConfigureEntry(shProfileState, i);
			}
			if (currentItemsList.Count > 0)
			{
				HighlightOnlyEntry(num2 + childCount);
				AnimateToState(1);
			}
			else
			{
				Debug.LogWarning((object)("No uid matched: " + vm.GetCurrentProfileUid()));
				AnimateToState(0);
			}
		}

		public void BTN_SelectEntryBehavior(int i = -1)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			SM.PlayGlobalUISound((GlobalUISound)0, ((Component)this).transform.position);
			if (i < 0 || i >= VertList.childCount)
			{
				Debug.LogWarning((object)("Select Profile: Invalid index " + i));
				return;
			}
			int num = i;
			List<ShProfileState> list = currentItemsList;
			if (list.Count == 0)
			{
				Debug.LogError((object)("No character entries available to select but requested ix: " + num));
			}
			else if (num >= list.Count)
			{
				Debug.LogError((object)("Selected index out of range of items. Index: " + num + " Count: " + list.Count + "VertList count: " + VertList.childCount));
			}
			else
			{
				vm.SwapProfile(list[num].uid);
			}
		}

		private void HighlightOnlyEntry(int i)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			for (int j = 0; j < VertList.childCount; j++)
			{
				Transform child = VertList.GetChild(j);
				if (j == i)
				{
					((Graphic)((Component)child).GetComponent<Image>()).color = selectedColor;
					child.localPosition = new Vector3(child.localPosition.x, child.localPosition.y, -50f);
				}
				else
				{
					((Graphic)((Component)child).GetComponent<Image>()).color = unselectedColor;
					child.localPosition = new Vector3(child.localPosition.x, child.localPosition.y, 0f);
				}
			}
		}

		public void BTN_AddEntryBehavior()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			SM.PlayGlobalUISound((GlobalUISound)1, ((Component)this).transform.position);
			vm.AddProfile(ShProfileState.CreateDefaultCharacter());
		}

		public void AnimateToState(int stage)
		{
			if (locations == null || locations.Count <= stage)
			{
				Debug.LogError((object)("Invalid stage index or locations not set: " + stage));
			}
			else
			{
				((MonoBehaviour)this).StartCoroutine(UIElementAnimator.AnimateRoutine(((Component)this).transform, locations[stage], 0.3f));
			}
		}
	}
	public class ShHomeDetailsUi : MonoBehaviour
	{
		public ShHomeSelectUi selectUi;

		private Transform MapIcon;

		private Transform MapName;

		private Transform Description;

		private Transform LastSaved;

		private Transform State;

		private Transform BuyPrice;

		private Transform PrebuiltsPanel;

		private Transform BackupsVertList;

		private ProfileViewModel vm_prof;

		private PortfolioViewModel vm_portf;

		private void Awake()
		{
			FindUiVariables();
		}

		private void OnEnable()
		{
			vm_prof = ProfileViewModel.Instance;
			vm_prof.Changed += Redraw;
			vm_portf = PortfolioViewModel.Instance;
			vm_portf.Changed += Redraw;
			Redraw();
		}

		private void OnDisable()
		{
			if (vm_prof != null)
			{
				vm_prof.Changed -= Redraw;
			}
			if (vm_portf != null)
			{
				vm_portf.Changed -= Redraw;
			}
		}

		private void FindUiVariables()
		{
			Transform val = ((Component)this).transform.Find("Background");
			MapIcon = val.Find("MapIcon");
			MapName = val.Find("MapName");
			Description = val.Find("Description");
			LastSaved = val.Find("LastSaved");
			State = val.Find("STATE");
			BuyPrice = val.Find("Buy Price");
			PrebuiltsPanel = val.Find("PrebuiltslPanel");
			BackupsVertList = val.Find("BackupsPanel").Find("Scroll View").Find("Viewport")
				.Find("Content");
		}

		private void ClearDetails()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			((Component)MapIcon).GetComponent<RawImage>().texture = null;
			((Component)MapName).GetComponent<Text>().text = "No Safehouse Selected";
			((Component)Description).GetComponent<Text>().text = "Select a safehouse to see details.";
			((Component)LastSaved).GetComponent<Text>().text = "Last Saved: N/A";
			((Component)State).GetComponent<Text>().text = "State: N/A";
			((Component)BuyPrice).GetComponent<Text>().text = "Buy Price: N/A";
			foreach (Transform backupsVert in BackupsVertList)
			{
				Transform val = backupsVert;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		public void Redraw()
		{
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			string uiSelectedSceneId = vm_portf.uiSelectedSceneId;
			if (string.IsNullOrEmpty(uiSelectedSceneId))
			{
				Debug.LogError((object)"The UI selected scene id is null or empty.");
				ClearDetails();
				return;
			}
			ShHouseDef houseDefById = vm_portf.getHouseDefById(uiSelectedSceneId);
			if (houseDefById == null)
			{
				Debug.LogError((object)"Tried to update safehouse details pane with null entryData.");
				ClearDetails();
				return;
			}
			((Component)MapIcon).GetComponent<RawImage>().texture = (Texture)(object)houseDefById.getMapIcon();
			((Component)MapName).GetComponent<Text>().text = houseDefById.displayName;
			((Component)Description).GetComponent<Text>().text = "<b>Description:</b>" + houseDefById.description;
			((Component)LastSaved).GetComponent<Text>().text = "Last Saved: " + houseDefById.lastSavedTime;
			switch (houseDefById.state)
			{
			case "Market":
				((Component)State).GetComponent<Text>().text = "NOT BOUGHT";
				((Graphic)((Component)State).GetComponent<Text>()).color = Color.red;
				((Component)BuyPrice).GetComponent<Text>().text = "Buy price: $" + houseDefById.price;
				break;
			case "Owned":
				((Component)State).GetComponent<Text>().text = "NOT BUILT";
				((Graphic)((Component)State).GetComponent<Text>()).color = Color.yellow;
				((Component)BuyPrice).GetComponent<Text>().text = "Sell price: $" + houseDefById.price;
				break;
			case "Built":
				((Component)State).GetComponent<Text>().text = "BUILT";
				((Graphic)((Component)State).GetComponent<Text>()).color = Color.green;
				((Component)BuyPrice).GetComponent<Text>().text = "Sell price: $" + houseDefById.price;
				break;
			default:
				((Component)State).GetComponent<Text>().text = "State: Unknown";
				((Component)BuyPrice).GetComponent<Text>().text = "Price: " + houseDefById.price;
				break;
			}
		}

		public void BTN_BuyHouse()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (vm_portf.BuyHouse(vm_portf.uiSelectedSceneId))
			{
				SM.PlayGlobalUISound((GlobalUISound)0, ((Component)this).transform.position);
			}
			else
			{
				SM.PlayGlobalUISound((GlobalUISound)2, ((Component)this).transform.position);
			}
		}

		public void BTN_SellHouse()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (vm_portf.SellHouse(vm_portf.uiSelectedSceneId))
			{
				SM.PlayGlobalUISound((GlobalUISound)1, ((Component)this).transform.position);
			}
			else
			{
				SM.PlayGlobalUISound((GlobalUISound)2, ((Component)this).transform.position);
			}
		}

		public void BTN_BuildHouse()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (vm_portf.BuildHouse(vm_portf.uiSelectedSceneId))
			{
				SM.PlayGlobalUISound((GlobalUISound)1, ((Component)this).transform.position);
			}
			else
			{
				SM.PlayGlobalUISound((GlobalUISound)2, ((Component)this).transform.position);
			}
		}
	}
	public class ShHomeSelectUi : MonoBehaviour
	{
		public Color unselectedColor = Color32.op_Implicit(new Color32((byte)86, (byte)70, (byte)70, (byte)128));

		public Color selectedColor = Color32.op_Implicit(new Color32((byte)161, (byte)161, (byte)55, byte.MaxValue));

		public float selectedScale = 1.1f;

		private Transform VertList;

		private Transform ExampleEntry;

		private List<ShHouseDef> currItemList = new List<ShHouseDef>();

		private ProfileViewModel vm_prof;

		private PortfolioViewModel vm_portf;

		public void Awake()
		{
			FindUiVariables();
		}

		private void OnEnable()
		{
			vm_prof = ProfileViewModel.Instance;
			vm_prof.Changed += Redraw;
			vm_portf = PortfolioViewModel.Instance;
			vm_portf.Changed += Redraw;
			Redraw();
		}

		private void OnDisable()
		{
			if (vm_prof != null)
			{
				vm_prof.Changed -= Redraw;
			}
			if (vm_portf != null)
			{
				vm_portf.Changed -= Redraw;
			}
		}

		private void FindUiVariables()
		{
			VertList = ((Component)this).transform.Find("Scroll View").Find("Viewport").Find("Content");
			ExampleEntry = ((Component)this).transform.Find("Scroll View").Find("ExampleEntry");
		}

		private Transform ConfigureEntry(ShHouseDef entryData, int iterIx)
		{
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			Transform transform = Object.Instantiate<GameObject>(((Component)ExampleEntry).gameObject, VertList).transform;
			((Component)transform).GetComponentInChildren<RawImage>().texture = (Texture)(object)entryData.getMapIcon();
			Text component = ((Component)transform.Find("MapName")).GetComponent<Text>();
			component.text = entryData.displayName;
			string state = entryData.state;
			if (state == "Owned")
			{
				((Component)((Component)transform.Find("Unused")).transform).gameObject.SetActive(true);
				((Component)((Component)transform.Find("Locked")).transform).gameObject.SetActive(false);
			}
			else if (state == "Market")
			{
				((Component)((Component)transform.Find("Locked")).transform).gameObject.SetActive(true);
				((Component)((Component)transform.Find("Unused")).transform).gameObject.SetActive(false);
			}
			else
			{
				((Component)((Component)transform.Find("Locked")).transform).gameObject.SetActive(false);
				((Component)((Component)transform.Find("Unused")).transform).gameObject.SetActive(false);
			}
			int index = iterIx;
			Button component2 = ((Component)transform).GetComponent<Button>();
			((UnityEventBase)component2.onClick).RemoveAllListeners();
			((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
			{
				BTN_SelectEntryBehavior(index);
			});
			((Component)transform).gameObject.SetActive(true);
			return transform;
		}

		public void Redraw()
		{
			int childCount = VertList.childCount;
			for (int num = VertList.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)VertList.GetChild(num)).gameObject);
			}
			currItemList = vm_portf.listHouseDefsSortedByAlph();
			int num2 = -1;
			for (int i = 0; i < currItemList.Count; i++)
			{
				ShHouseDef shHouseDef = currItemList[i];
				if (shHouseDef.sceneId == vm_portf.GetCurrentSafehouseSceneId())
				{
					num2 = i;
				}
				Transform val = ConfigureEntry(shHouseDef, i);
			}
			if (VertList.childCount > 0)
			{
				HighlightOnlyEntry(num2 + childCount);
			}
		}

		public void BTN_SelectEntryBehavior(int i = -1)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			SM.PlayGlobalUISound((GlobalUISound)0, ((Component)this).transform.position);
			if (i >= 0 && i < VertList.childCount)
			{
				int num = i;
				List<ShHouseDef> list = currItemList;
				if (list.Count == 0)
				{
					Debug.LogError((object)("No entries available to select but requested ix: " + num));
				}
				else if (num >= list.Count)
				{
					Debug.LogError((object)("Selected index out of range of items. Index: " + num + " Count: " + list.Count + "VertList count: " + VertList.childCount));
				}
				else
				{
					vm_portf.TrySelectSafehouse(list[num].sceneId);
				}
			}
		}

		private void HighlightOnlyEntry(int i)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			for (int j = 0; j < VertList.childCount; j++)
			{
				Transform child = VertList.GetChild(j);
				if (j == i)
				{
					((Graphic)((Component)child.Find("Namebackdrop")).GetComponent<Image>()).color = selectedColor;
					child.localScale = new Vector3(selectedScale, selectedScale, selectedScale);
					child.localPosition = new Vector3(child.localPosition.x, child.localPosition.y, -50f);
				}
				else
				{
					((Graphic)((Component)child.Find("Namebackdrop")).GetComponent<Image>()).color = unselectedColor;
					child.localScale = Vector3.one;
					child.localPosition = new Vector3(child.localPosition.x, child.localPosition.y, 0f);
				}
			}
		}

		public void BTN_AddEntryBehavior()
		{
		}
	}
	public class ShLauncherPlinthUi : MonoBehaviour
	{
		private Transform plintMapIcon;

		private Transform CanvasPlinth;

		private Transform CanvasMenu;

		private Transform activateMenuBtn;

		private Transform levelUnlocks;

		private Transform manual;

		private Transform houseSelect;

		private Transform houseEdit;

		private ProfileViewModel vm_prof;

		private PortfolioViewModel vm_portf;

		private string currentTab = "Menu";

		private void Awake()
		{
			FindUiVariables();
		}

		private void OnEnable()
		{
			vm_prof = ProfileViewModel.Instance;
			vm_prof.Changed += Redraw;
			vm_portf = PortfolioViewModel.Instance;
			vm_portf.Changed += Redraw;
			Redraw();
		}

		private void OnDisable()
		{
			if (vm_prof != null)
			{
				vm_prof.Changed -= Redraw;
			}
			if (vm_portf != null)
			{
				vm_portf.Changed -= Redraw;
			}
		}

		private void FindUiVariables()
		{
			CanvasPlinth = ((Component)this).transform.Find("CanvasPlinth");
			plintMapIcon = CanvasPlinth.Find("Panel").Find("Panel (2)").Find("RawImage");
			activateMenuBtn = CanvasPlinth.Find("MenuLink");
			CanvasMenu = ((Component)this).transform.Find("CanvasMenu");
			levelUnlocks = GameObject.Find("LevelUnlocks").transform.Find("Scroll View");
			manual = GameObject.Find("LevelUnlocksDeets").transform.Find("Background");
			houseSelect = GameObject.Find("HouseSelect").transform.Find("Scroll View");
			houseEdit = GameObject.Find("HouseEdit").transform.Find("Background");
		}

		private void AllMenusOff()
		{
			((Component)activateMenuBtn).gameObject.SetActive(false);
			((Component)CanvasMenu).gameObject.SetActive(false);
			((Component)levelUnlocks).gameObject.SetActive(false);
			((Component)manual).gameObject.SetActive(false);
			((Component)houseSelect).gameObject.SetActive(false);
			((Component)houseEdit).gameObject.SetActive(false);
		}

		public void Redraw()
		{
			ShHouseDef currentSafehouseDef = vm_portf.GetCurrentSafehouseDef();
			if (currentSafehouseDef == null)
			{
				Debug.LogError((object)"Tried to update safehouse details pane with null entryData.");
				((Component)plintMapIcon).GetComponent<RawImage>().texture = null;
			}
			else
			{
				((Component)plintMapIcon).GetComponent<RawImage>().texture = (Texture)(object)currentSafehouseDef.getMapIcon();
			}
			ShProfileState currentProfileState = vm_prof.GetCurrentProfileState();
			if (currentProfileState == null)
			{
				AllMenusOff();
				return;
			}
			AllMenusOff();
			((Component)activateMenuBtn).gameObject.SetActive(true);
			switch (currentTab)
			{
			case "Manual":
				((Component)CanvasMenu).gameObject.SetActive(true);
				((Component)manual).gameObject.SetActive(true);
				break;
			case "Menu":
				((Component)CanvasMenu).gameObject.SetActive(true);
				break;
			case "Hideouts":
				((Component)houseSelect).gameObject.SetActive(true);
				((Component)houseEdit).gameObject.SetActive(true);
				break;
			case "Unlocks":
				((Component)levelUnlocks).gameObject.SetActive(true);
				((Component)manual).gameObject.SetActive(true);
				break;
			case "Difficulty":
				((Component)levelUnlocks).gameObject.SetActive(true);
				((Component)manual).gameObject.SetActive(true);
				break;
			default:
				Debug.LogError((object)("Plinth: Unexpected, tab name not known: " + currentTab));
				break;
			}
		}

		public void BTN_LaunchSafehouse()
		{
			ShHouseDef currentSafehouseDef = vm_portf.GetCurrentSafehouseDef();
			if (currentSafehouseDef == null)
			{
				Debug.LogError((object)"Plinth: No current safehouse found, can't travel to it.");
			}
			ShSceneTravel.Request(vm_prof.GetCurrentProfileState().uid, currentSafehouseDef.sceneId, TravelScenario.Home);
		}

		public void BTN_Menu()
		{
			currentTab = "Menu";
			Redraw();
		}

		public void BTN_ViewSafehouses()
		{
			currentTab = "Hideouts";
			Redraw();
		}

		public void BTN_ViewRankLevels()
		{
			currentTab = "Unlocks";
			Redraw();
		}

		public void BTN_Difficulty()
		{
			currentTab = "Difficulty";
			Redraw();
		}

		public void BTN_Manual()
		{
			currentTab = "Manual";
			Redraw();
		}

		public void BTN_Exit()
		{
			ShSceneTravel.Request("", "MainMenu3", TravelScenario.None);
		}
	}
	public class ShRankUnlocksUi : MonoBehaviour
	{
		private Transform itemList;

		private Transform ExampleEntry;

		private List<int> currItemList;

		private ProfileViewModel vm_prof;

		private PortfolioViewModel vm_portf;

		public void Awake()
		{
			FindUiVariables();
		}

		private void OnEnable()
		{
			vm_prof = ProfileViewModel.Instance;
			vm_prof.Changed += Redraw;
			vm_portf = PortfolioViewModel.Instance;
			vm_portf.Changed += Redraw;
			Redraw();
		}

		private void OnDisable()
		{
			if (vm_prof != null)
			{
				vm_prof.Changed -= Redraw;
			}
			if (vm_portf != null)
			{
				vm_portf.Changed -= Redraw;
			}
		}

		private void FindUiVariables()
		{
			itemList = ((Component)this).transform.Find("Scroll View").Find("Viewport").Find("Content");
			ExampleEntry = ((Component)this).transform.Find("Scroll View").Find("ExampleEntry");
		}

		private List<int> GetItemList()
		{
			int count = ShRankCalculator.mainRanksDef.rankNames.Count;
			currItemList = new List<int>();
			for (int i = 1; i <= count; i++)
			{
				currItemList.Add(i);
			}
			return currItemList;
		}

		private Transform ConfigureEntry(int rank, int iterIx)
		{
			Transform transform = Object.Instantiate<GameObject>(((Component)ExampleEntry).gameObject, itemList).transform;
			if ((Object)(object)transform == (Object)null)
			{
				Debug.LogError((object)("Given entry to populate is null, index: " + iterIx));
				return null;
			}
			((Component)transform.Find("Level")).GetComponentInChildren<RawImage>().texture = (Texture)(object)ShFileIoHandler.LoadFromModTexture("NGA-SafehouseProgressionMode", ShRankCalculator.getRankIconFileName(rank));
			Text component = ((Component)transform.Find("LevelNumber")).GetComponent<Text>();
			component.text = "Level " + rank;
			Text component2 = ((Component)transform.Find("LevelName")).GetComponent<Text>();
			component2.text = ShRankCalculator.getRankName(rank);
			ShProfileState currentProfileState = vm_prof.GetCurrentProfileState();
			if (rank == currentProfileState.currentRank)
			{