Decompiled source of Product 3 Code v0.1.3
NGA.SHPlibs.dll
Decompiled 10 months ago
The result has been truncated due to the large size, download it to view full contents!
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) {