Decompiled source of TruckLoot v1.0.4

TruckLoot.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Xml.Serialization;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using ItemPersistenceMod.Patches;
using Photon.Pun;
using REPOLib.Modules;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("KeepLootInShip")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("KeepLootInShip")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1083bfd6-e88e-49d3-b763-146f4fc02662")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ItemPersistenceMod
{
	[BepInPlugin("TruckLoot", "TruckLoot", "1.0.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ItemPersistenceModBase : BaseUnityPlugin
	{
		private const string modGUID = "TruckLoot";

		private const string modName = "TruckLoot";

		private const string modVersion = "1.0.4";

		private const string repoLibGUID = "REPOLib";

		private readonly Harmony harmony = new Harmony("TruckLoot");

		internal static ItemPersistenceModBase instance;

		internal ManualLogSource mls;

		public static List<SerializedValuable> savedValuables;

		public static bool hasSavedValuables;

		public static Transform truckInteriorReference;

		private static string saveFolderPath;

		private static string currentSaveId;

		public static bool forceLoadOnNextLevel;

		public static bool repoLibAvailable;

		private float stateCheckInterval = 5f;

		private float stateCheckTimer = 0f;

		static ItemPersistenceModBase()
		{
			savedValuables = new List<SerializedValuable>();
			hasSavedValuables = false;
			truckInteriorReference = null;
			currentSaveId = "default";
			forceLoadOnNextLevel = false;
			repoLibAvailable = false;
			savedValuables = new List<SerializedValuable>();
			hasSavedValuables = false;
			currentSaveId = "default";
		}

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			mls = Logger.CreateLogSource("TruckLoot");
			mls.LogInfo((object)"TruckLoot v1.0.4 by Maflingus has Loaded!");
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				BepInPlugin metadata = pluginInfo.Value.Metadata;
				if (metadata.GUID.Equals("REPOLib"))
				{
					repoLibAvailable = true;
					mls.LogInfo((object)"Found REPOLib, enabling modded valuables support!");
					break;
				}
			}
			if (!repoLibAvailable)
			{
				mls.LogInfo((object)"REPOLib not detected - only vanilla items will be supported");
			}
			saveFolderPath = Path.Combine(Paths.ConfigPath, "ItemPersistenceMod");
			if (!Directory.Exists(saveFolderPath))
			{
				Directory.CreateDirectory(saveFolderPath);
			}
			mls.LogInfo((object)("Save folder path: " + saveFolderPath));
			LoadValuablesFromFile();
			harmony.PatchAll(typeof(ItemPersistenceModBase));
			harmony.PatchAll(typeof(GameDirectorPatch));
			harmony.PatchAll(typeof(LevelGeneratorPatch));
			harmony.PatchAll(typeof(RunManagerPatch));
			harmony.PatchAll(typeof(SaveFileDeletionPatch));
			CheckGameState();
			((MonoBehaviour)this).StartCoroutine(DelayedSceneScanner());
		}

		private void Update()
		{
			stateCheckTimer -= Time.deltaTime;
			if (stateCheckTimer <= 0f)
			{
				stateCheckTimer = stateCheckInterval;
				CheckGameState();
			}
		}

		private void OnEnable()
		{
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnDisable()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			if (!hasSavedValuables || savedValuables.Count == 0)
			{
				LoadValuablesFromFile();
			}
		}

		private void CheckGameState()
		{
			try
			{
				if (!((Object)(object)Object.FindObjectOfType<MainMenuOpen>() != (Object)null))
				{
					return;
				}
				if (!hasSavedValuables || savedValuables.Count == 0)
				{
					UpdateCurrentSaveId();
					LoadValuablesFromFile();
					if (hasSavedValuables)
					{
						forceLoadOnNextLevel = true;
					}
				}
				else
				{
					forceLoadOnNextLevel = true;
				}
			}
			catch (Exception ex)
			{
				mls.LogError((object)("Error in CheckGameState: " + ex.Message));
			}
		}

		public static void UpdateCurrentSaveId()
		{
			try
			{
				string text = currentSaveId;
				if ((Object)(object)StatsManager.instance != (Object)null)
				{
					FieldInfo fieldInfo = AccessTools.Field(typeof(StatsManager), "saveFileCurrent");
					string text2 = (string)fieldInfo.GetValue(StatsManager.instance);
					if (!string.IsNullOrEmpty(text2))
					{
						if (text2.EndsWith(".sav"))
						{
							text2 = text2.Substring(0, text2.Length - 4);
						}
						currentSaveId = text2;
						return;
					}
				}
				if (string.IsNullOrEmpty(currentSaveId))
				{
					currentSaveId = "default";
				}
			}
			catch (Exception)
			{
				if (string.IsNullOrEmpty(currentSaveId))
				{
					currentSaveId = "default";
				}
			}
		}

		public static string GetSaveFilePath(string saveId)
		{
			if (string.IsNullOrEmpty(saveId))
			{
				saveId = "default";
			}
			if (saveId.EndsWith(".sav"))
			{
				saveId = saveId.Substring(0, saveId.Length - 4);
			}
			return Path.Combine(saveFolderPath, saveId + ".xml");
		}

		public static void DeleteSaveFile(string saveId)
		{
			string saveFilePath = GetSaveFilePath(saveId);
			if (File.Exists(saveFilePath))
			{
				try
				{
					File.Delete(saveFilePath);
					instance.mls.LogInfo((object)("Deleted persistence file for save: " + saveId));
				}
				catch (Exception ex)
				{
					instance.mls.LogError((object)("Error deleting persistence file: " + ex.Message));
				}
			}
		}

		public static void SaveValuablesToFile()
		{
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)instance == (Object)null)
			{
			}
			if (!hasSavedValuables || savedValuables == null || savedValuables.Count == 0)
			{
				return;
			}
			try
			{
				string currentSaveFilePath = GetCurrentSaveFilePath();
				string directoryName = Path.GetDirectoryName(currentSaveFilePath);
				if (!Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
					Debug.Log((object)("[ItemPersistenceMod] Created directory: " + directoryName));
				}
				SaveData saveData = new SaveData();
				foreach (SerializedValuable savedValuable in savedValuables)
				{
					saveData.Items.Add(new SavedItem(savedValuable));
				}
				try
				{
					XmlSerializer xmlSerializer = new XmlSerializer(typeof(SaveData));
					using StringWriter stringWriter = new StringWriter();
					xmlSerializer.Serialize(stringWriter, saveData);
					string contents = stringWriter.ToString();
					File.WriteAllText(currentSaveFilePath, contents);
					if (File.Exists(currentSaveFilePath))
					{
						FileInfo fileInfo = new FileInfo(currentSaveFilePath);
					}
					else
					{
						Debug.LogError((object)("[ItemPersistenceMod] Failed to create save file despite no exceptions: " + currentSaveFilePath));
					}
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[ItemPersistenceMod] Error serializing save data: " + ex.Message));
					try
					{
						using (StreamWriter streamWriter = new StreamWriter(currentSaveFilePath))
						{
							streamWriter.WriteLine($"ItemPersistenceMod Save File - {DateTime.Now}");
							streamWriter.WriteLine("SaveID: " + currentSaveId);
							streamWriter.WriteLine($"Items: {savedValuables.Count}");
							streamWriter.WriteLine("------------------------------------------");
							foreach (SerializedValuable savedValuable2 in savedValuables)
							{
								streamWriter.WriteLine("Item: " + savedValuable2.prefabName);
								streamWriter.WriteLine($"  Position: {savedValuable2.relativePosition}");
								streamWriter.WriteLine($"  Rotation: {savedValuable2.rotation}");
								streamWriter.WriteLine($"  Value: ${savedValuable2.dollarValueCurrent} (Original: ${savedValuable2.dollarValueOriginal})");
								streamWriter.WriteLine("------------------------------------------");
							}
						}
						Debug.Log((object)"[ItemPersistenceMod] Fallback to text format successful");
					}
					catch (Exception ex2)
					{
						Debug.LogError((object)("[ItemPersistenceMod] Fallback save method also failed: " + ex2.Message));
					}
				}
			}
			catch (Exception ex3)
			{
				Debug.LogError((object)("[ItemPersistenceMod] Error in SaveValuablesToFile: " + ex3.Message));
			}
		}

		public static void LoadValuablesFromFile()
		{
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			UpdateCurrentSaveId();
			EnsureSaveFilesExist();
			string currentSaveFilePath = GetCurrentSaveFilePath();
			if (!File.Exists(currentSaveFilePath))
			{
				hasSavedValuables = false;
				return;
			}
			try
			{
				string text = File.ReadAllText(currentSaveFilePath);
				try
				{
					XmlSerializer xmlSerializer = new XmlSerializer(typeof(SaveData));
					SaveData saveData;
					using (StringReader textReader = new StringReader(text))
					{
						saveData = (SaveData)xmlSerializer.Deserialize(textReader);
					}
					if (saveData != null && saveData.Items != null && saveData.Items.Count > 0)
					{
						savedValuables.Clear();
						foreach (SavedItem item in saveData.Items)
						{
							savedValuables.Add(item.ToSerializedValuable());
						}
						hasSavedValuables = true;
					}
					else
					{
						hasSavedValuables = false;
					}
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[ItemPersistenceMod] Error deserializing XML: " + ex.Message + ", trying fallback format"));
					if (text.StartsWith("ItemPersistenceMod Save File"))
					{
						Debug.Log((object)"[ItemPersistenceMod] Detected simple text format - parsing...");
						savedValuables.Clear();
						string[] array = text.Split(new char[1] { '\n' });
						string text2 = null;
						Vector3 zero = Vector3.zero;
						Quaternion identity = Quaternion.identity;
						float result = 0f;
						float result2 = 0f;
						string[] array2 = array;
						foreach (string text3 in array2)
						{
							string text4 = text3.Trim();
							if (text4.StartsWith("Item: "))
							{
								text2 = text4.Substring(6);
							}
							else if (text4.StartsWith("  Position: "))
							{
								string text5 = text4.Substring(12);
								text5 = text5.Trim('(', ')', ' ');
								string[] array3 = text5.Split(new char[1] { ',' });
								if (array3.Length >= 3)
								{
									float num = float.Parse(array3[0].Trim());
									float num2 = float.Parse(array3[1].Trim());
									float num3 = float.Parse(array3[2].Trim());
									((Vector3)(ref zero))..ctor(num, num2, num3);
								}
							}
							else if (text4.StartsWith("  Rotation: "))
							{
								string text6 = text4.Substring(12);
								text6 = text6.Trim('(', ')', ' ');
								string[] array4 = text6.Split(new char[1] { ',' });
								if (array4.Length >= 4)
								{
									float num4 = float.Parse(array4[0].Trim());
									float num5 = float.Parse(array4[1].Trim());
									float num6 = float.Parse(array4[2].Trim());
									float num7 = float.Parse(array4[3].Trim());
									((Quaternion)(ref identity))..ctor(num4, num5, num6, num7);
								}
							}
							else if (text4.StartsWith("  Value: $"))
							{
								int num8 = text4.IndexOf('$');
								int num9 = text4.IndexOf('(');
								if (num8 >= 0 && num9 >= 0)
								{
									string s = text4.Substring(num8 + 1, num9 - num8 - 1).Trim();
									float.TryParse(s, out result2);
									int num10 = text4.IndexOf('$', num9);
									if (num10 >= 0)
									{
										string s2 = text4.Substring(num10 + 1).Replace(")", "").Trim();
										float.TryParse(s2, out result);
									}
								}
							}
							else if (text4.StartsWith("------------------------------------------") && text2 != null)
							{
								SerializedValuable serializedValuable = new SerializedValuable();
								serializedValuable.prefabName = text2;
								serializedValuable.relativePosition = zero;
								serializedValuable.rotation = identity;
								serializedValuable.dollarValueOriginal = result;
								serializedValuable.dollarValueCurrent = result2;
								savedValuables.Add(serializedValuable);
								text2 = null;
							}
						}
						if (savedValuables.Count > 0)
						{
							hasSavedValuables = true;
						}
						else
						{
							Debug.Log((object)"[ItemPersistenceMod] No items found in text file");
							hasSavedValuables = false;
						}
					}
					else
					{
						Debug.LogError((object)"[ItemPersistenceMod] Unknown file format - cannot load");
						hasSavedValuables = false;
					}
				}
			}
			catch (Exception ex2)
			{
				Debug.LogError((object)("[ItemPersistenceMod] Error loading valuables from file: " + ex2.Message));
				savedValuables.Clear();
				hasSavedValuables = false;
			}
			if (hasSavedValuables && savedValuables.Count > 0)
			{
				forceLoadOnNextLevel = true;
			}
		}

		public static string GetCurrentSaveFilePath()
		{
			string path = ((saveFolderPath == null) ? Path.Combine(Paths.ConfigPath, "ItemPersistenceMod") : saveFolderPath);
			return Path.Combine(path, currentSaveId + ".xml");
		}

		public static void EnsureSaveFilesExist()
		{
			string directoryName = Path.GetDirectoryName(GetCurrentSaveFilePath());
			if (Directory.Exists(directoryName))
			{
				string[] files = Directory.GetFiles(directoryName);
			}
			else
			{
				Debug.Log((object)("[ItemPersistenceMod] Save directory does not exist: " + directoryName));
			}
		}

		public static void ResetModState()
		{
			savedValuables.Clear();
			hasSavedValuables = false;
			truckInteriorReference = null;
			forceLoadOnNextLevel = false;
			string currentSaveFilePath = GetCurrentSaveFilePath();
			if (File.Exists(currentSaveFilePath))
			{
				try
				{
					File.Delete(currentSaveFilePath);
					if ((Object)(object)instance != (Object)null)
					{
						instance.mls.LogInfo((object)("Deleted save file: " + currentSaveFilePath));
					}
				}
				catch (Exception ex)
				{
					if ((Object)(object)instance != (Object)null)
					{
						instance.mls.LogError((object)("Error deleting save file: " + ex.Message));
					}
				}
			}
			if (!((Object)(object)instance != (Object)null))
			{
			}
		}

		private void OnApplicationQuit()
		{
			if (hasSavedValuables && savedValuables.Count > 0)
			{
				SaveValuablesToFile();
			}
		}

		private IEnumerator DelayedSceneScanner()
		{
			yield return (object)new WaitForSeconds(5f);
			ScanSceneForValuables();
		}

		public static void ScanSceneForValuables()
		{
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>();
			ValuableObject[] array2 = array;
			foreach (ValuableObject val in array2)
			{
				string name = ((Object)((Component)val).gameObject).name;
				float num = 0f;
				float num2 = 0f;
				try
				{
					FieldInfo field = typeof(ValuableObject).GetField("dollarValueOriginal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					FieldInfo field2 = typeof(ValuableObject).GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field != null)
					{
						num = (float)field.GetValue(val);
					}
					if (field2 != null)
					{
						num2 = (float)field2.GetValue(val);
					}
				}
				catch
				{
				}
				try
				{
					string fullPath = GetFullPath(((Component)val).transform);
				}
				catch
				{
				}
			}
			string[] array3 = new string[9] { "Valuables", "Items", "Valuables/01 Tiny", "Valuables/02 Small", "Valuables/03 Medium", "Valuables/04 Big", "Valuables/05 Wide", "Valuables/06 Tall", "Valuables/07 Very Tall" };
			string[] array4 = array3;
			foreach (string text in array4)
			{
				try
				{
					GameObject[] array5 = Resources.LoadAll<GameObject>(text);
					GameObject[] array6 = array5;
					foreach (GameObject val2 in array6)
					{
					}
				}
				catch (Exception)
				{
				}
			}
		}

		private static string GetFullPath(Transform transform)
		{
			if ((Object)(object)transform.parent == (Object)null)
			{
				return ((Object)transform).name;
			}
			return GetFullPath(transform.parent) + "/" + ((Object)transform).name;
		}
	}
	[Serializable]
	[XmlRoot("SaveData")]
	public class SaveData
	{
		[XmlElement("Items")]
		public List<SavedItem> Items { get; set; } = new List<SavedItem>();

	}
	[Serializable]
	public class SavedItem
	{
		[XmlElement("PrefabName")]
		public string PrefabName { get; set; }

		[XmlElement("PosX")]
		public float PosX { get; set; }

		[XmlElement("PosY")]
		public float PosY { get; set; }

		[XmlElement("PosZ")]
		public float PosZ { get; set; }

		[XmlElement("RotX")]
		public float RotX { get; set; }

		[XmlElement("RotY")]
		public float RotY { get; set; }

		[XmlElement("RotZ")]
		public float RotZ { get; set; }

		[XmlElement("RotW")]
		public float RotW { get; set; }

		[XmlElement("DollarValueOriginal")]
		public float DollarValueOriginal { get; set; }

		[XmlElement("DollarValueCurrent")]
		public float DollarValueCurrent { get; set; }

		public SavedItem()
		{
		}

		public SavedItem(SerializedValuable valuable)
		{
			PrefabName = valuable.prefabName;
			PosX = valuable.relativePosition.x;
			PosY = valuable.relativePosition.y;
			PosZ = valuable.relativePosition.z;
			RotX = valuable.rotation.x;
			RotY = valuable.rotation.y;
			RotZ = valuable.rotation.z;
			RotW = valuable.rotation.w;
			DollarValueOriginal = valuable.dollarValueOriginal;
			DollarValueCurrent = valuable.dollarValueCurrent;
		}

		public SerializedValuable ToSerializedValuable()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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)
			SerializedValuable serializedValuable = new SerializedValuable();
			serializedValuable.prefabName = PrefabName;
			serializedValuable.relativePosition = new Vector3(PosX, PosY, PosZ);
			serializedValuable.rotation = new Quaternion(RotX, RotY, RotZ, RotW);
			serializedValuable.dollarValueOriginal = DollarValueOriginal;
			serializedValuable.dollarValueCurrent = DollarValueCurrent;
			return serializedValuable;
		}
	}
	[Serializable]
	public class SerializedValuable
	{
		public string prefabName;

		public Vector3 relativePosition;

		public Quaternion rotation;

		public float dollarValueOriginal;

		public float dollarValueCurrent;

		public SerializedValuable()
		{
		}

		public SerializedValuable(GameObject valuableObj, Transform truckInterior)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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)
			prefabName = ((Object)valuableObj).name.Replace("(Clone)", "").Trim();
			relativePosition = truckInterior.InverseTransformPoint(valuableObj.transform.position);
			rotation = Quaternion.Inverse(truckInterior.rotation) * valuableObj.transform.rotation;
			ValuableObject component = valuableObj.GetComponent<ValuableObject>();
			if ((Object)(object)component != (Object)null)
			{
				dollarValueOriginal = component.dollarValueOriginal;
				dollarValueCurrent = component.dollarValueCurrent;
				if (dollarValueOriginal <= 0f || dollarValueCurrent <= 0f)
				{
					try
					{
						FieldInfo field = typeof(ValuableObject).GetField("dollarValueOriginal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						FieldInfo field2 = typeof(ValuableObject).GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (field != null)
						{
							dollarValueOriginal = (float)field.GetValue(component);
						}
						else
						{
							dollarValueOriginal = 100f;
						}
						if (field2 != null)
						{
							dollarValueCurrent = (float)field2.GetValue(component);
						}
						else
						{
							dollarValueCurrent = 100f;
						}
					}
					catch (Exception ex)
					{
						dollarValueOriginal = 100f;
						dollarValueCurrent = 100f;
						if ((Object)(object)ItemPersistenceModBase.instance != (Object)null)
						{
							ItemPersistenceModBase.instance.mls.LogError((object)("Error accessing valuable values: " + ex.Message));
						}
					}
				}
				if (!((Object)(object)ItemPersistenceModBase.instance != (Object)null))
				{
				}
			}
			else
			{
				dollarValueOriginal = 100f;
				dollarValueCurrent = 100f;
				if ((Object)(object)ItemPersistenceModBase.instance != (Object)null)
				{
					ItemPersistenceModBase.instance.mls.LogWarning((object)("No ValuableObject component found on " + prefabName + ", using default values"));
				}
			}
		}
	}
}
namespace ItemPersistenceMod.Patches
{
	[HarmonyPatch(typeof(StatsManager), "SaveFileDelete")]
	public class SaveFileDeletionPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(string saveFileName)
		{
			try
			{
				if (!string.IsNullOrEmpty(saveFileName))
				{
					bool flag = false;
					if ((Object)(object)RunManager.instance != (Object)null && ((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelShop || ((Object)(object)RunManager.instance.levelCurrent != (Object)(object)RunManager.instance.levelMainMenu && (Object)(object)RunManager.instance.levelCurrent != (Object)(object)RunManager.instance.levelLobbyMenu)))
					{
						flag = true;
					}
					ItemPersistenceModBase.DeleteSaveFile(saveFileName);
					FieldInfo fieldInfo = AccessTools.Field(typeof(StatsManager), "saveFileCurrent");
					if (fieldInfo != null)
					{
						string text = (string)fieldInfo.GetValue(StatsManager.instance);
						if (saveFileName == text)
						{
							ItemPersistenceModBase.savedValuables.Clear();
							ItemPersistenceModBase.hasSavedValuables = false;
						}
					}
				}
				return true;
			}
			catch (Exception ex)
			{
				ItemPersistenceModBase.instance.mls.LogError((object)("Error in SaveFileDeletionPatch: " + ex.Message));
				return true;
			}
		}
	}
	public static class GameStateCheck
	{
		public static bool IsGameplayLevel()
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Invalid comparison between Unknown and I4
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Invalid comparison between Unknown and I4
			try
			{
				if (IsArenaLevel() || isLobbyLevel())
				{
					return false;
				}
				if ((Object)(object)RunManager.instance != (Object)null)
				{
					if ((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelMainMenu || (Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelLobbyMenu)
					{
						return false;
					}
					if ((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelShop || (Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelLobby)
					{
						return true;
					}
				}
				MainMenuOpen val = Object.FindObjectOfType<MainMenuOpen>();
				if ((Object)(object)val != (Object)null)
				{
					if ((Object)(object)GameDirector.instance != (Object)null && ((int)GameDirector.instance.currentState == 2 || (int)GameDirector.instance.currentState == 3))
					{
						return true;
					}
					return false;
				}
				TruckDoor val2 = Object.FindObjectOfType<TruckDoor>();
				if ((Object)(object)val2 != (Object)null)
				{
					return true;
				}
				return true;
			}
			catch (Exception ex)
			{
				ItemPersistenceModBase.instance.mls.LogError((object)("Error in IsGameplayLevel: " + ex.Message));
				return true;
			}
		}

		public static bool isLobbyLevel()
		{
			try
			{
				if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelLobby)
				{
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				ItemPersistenceModBase.instance.mls.LogError((object)("Error in IsLobbyLevel: " + ex.Message));
				return false;
			}
		}

		public static bool IsArenaLevel()
		{
			try
			{
				if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelArena)
				{
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				ItemPersistenceModBase.instance.mls.LogError((object)("Error in IsArenaLevel: " + ex.Message));
				return false;
			}
		}

		public static bool isShopLevel()
		{
			try
			{
				if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelShop)
				{
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				ItemPersistenceModBase.instance.mls.LogError((object)("Error in IsShopLevel: " + ex.Message));
				return false;
			}
		}

		private static void DeleteSaveFileForArena()
		{
			try
			{
				ItemPersistenceModBase.UpdateCurrentSaveId();
				string currentSaveFilePath = ItemPersistenceModBase.GetCurrentSaveFilePath();
				if (File.Exists(currentSaveFilePath))
				{
					File.Delete(currentSaveFilePath);
					if (File.Exists(currentSaveFilePath))
					{
						ItemPersistenceModBase.instance.mls.LogError((object)"Failed to delete save file");
					}
				}
				ItemPersistenceModBase.savedValuables.Clear();
				ItemPersistenceModBase.hasSavedValuables = false;
			}
			catch (Exception ex)
			{
				ItemPersistenceModBase.instance.mls.LogError((object)("Error deleting save file for arena: " + ex.Message));
			}
		}

		public static bool IsTruckReady()
		{
			try
			{
				TruckDoor val = Object.FindObjectOfType<TruckDoor>();
				if ((Object)(object)val == (Object)null)
				{
					Transform val2 = GameDirectorPatch.FindTruckInterior();
					return (Object)(object)val2 != (Object)null;
				}
				return true;
			}
			catch (Exception ex)
			{
				ItemPersistenceModBase.instance.mls.LogError((object)("Error in IsTruckReady: " + ex.Message));
				return false;
			}
		}
	}
	[HarmonyPatch(typeof(GameDirector))]
	public class GameDirectorPatch
	{
		[HarmonyPatch("OutroStart")]
		[HarmonyPrefix]
		private static bool OutroStartPrefix(GameDirector __instance)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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)
			try
			{
				if (!GameStateCheck.IsGameplayLevel())
				{
					return true;
				}
				ItemPersistenceModBase.savedValuables.Clear();
				ItemPersistenceModBase.hasSavedValuables = false;
				Transform val = FindTruckInterior();
				if ((Object)(object)val == (Object)null)
				{
					return true;
				}
				ItemPersistenceModBase.truckInteriorReference = val;
				ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>();
				int num = 0;
				ValuableObject[] array2 = array;
				foreach (ValuableObject val2 in array2)
				{
					if ((Object)(object)val2 != (Object)null && IsInsideTruck(((Component)val2).gameObject, val))
					{
						SerializedValuable serializedValuable = new SerializedValuable(((Component)val2).gameObject, val);
						serializedValuable.relativePosition = LevelGeneratorPatch.GetStandardizedPosition(((Component)val2).transform.position, val);
						ItemPersistenceModBase.savedValuables.Add(serializedValuable);
						num++;
					}
				}
				if (num > 0)
				{
					ItemPersistenceModBase.hasSavedValuables = true;
					if ((Object)(object)ItemPersistenceModBase.instance != (Object)null)
					{
					}
					ItemPersistenceModBase.SaveValuablesToFile();
					string currentSaveFilePath = ItemPersistenceModBase.GetCurrentSaveFilePath();
					if (File.Exists(currentSaveFilePath))
					{
						FileInfo fileInfo = new FileInfo(currentSaveFilePath);
					}
					else
					{
						string directoryName = Path.GetDirectoryName(currentSaveFilePath);
						if (Directory.Exists(directoryName))
						{
							string[] files = Directory.GetFiles(directoryName);
							string[] array3 = files;
							foreach (string text in array3)
							{
							}
						}
					}
				}
				return true;
			}
			catch (Exception ex)
			{
				ItemPersistenceModBase.instance.mls.LogError((object)("Error in OutroStartPrefix: " + ex.Message));
				ItemPersistenceModBase.instance.mls.LogError((object)("Stack trace: " + ex.StackTrace));
				return true;
			}
		}

		public static Transform FindTruckInterior()
		{
			RoomVolume[] array = Object.FindObjectsOfType<RoomVolume>();
			RoomVolume[] array2 = array;
			foreach (RoomVolume val in array2)
			{
				if (val.Truck)
				{
					return ((Component)val).transform;
				}
			}
			GameObject[] array3 = (from go in Object.FindObjectsOfType<GameObject>()
				where ((Object)go).name.Contains("Truck") && (((Object)go).name.Contains("Interior") || ((Object)go).name.Contains("Inside") || ((Object)go).name.Contains("Room"))
				select go).ToArray();
			if (array3.Length != 0)
			{
				ItemPersistenceModBase.instance.mls.LogInfo((object)("Found truck by name: " + ((Object)array3[0]).name));
				return array3[0].transform;
			}
			TruckDoor val2 = Object.FindObjectOfType<TruckDoor>();
			if ((Object)(object)val2 != (Object)null)
			{
				return ((Component)val2).transform;
			}
			return null;
		}

		private static bool IsInsideTruck(GameObject valuableObj, Transform truckReference, float padding = 0.5f)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			Bounds val = default(Bounds);
			Collider[] componentsInChildren = ((Component)truckReference).GetComponentsInChildren<Collider>();
			if (componentsInChildren.Length != 0)
			{
				Collider[] array = componentsInChildren;
				foreach (Collider val2 in array)
				{
					if (((Bounds)(ref val)).size == Vector3.zero)
					{
						val = val2.bounds;
					}
					else
					{
						((Bounds)(ref val)).Encapsulate(val2.bounds);
					}
				}
				((Bounds)(ref val)).Expand(padding);
				if (((Bounds)(ref val)).Contains(valuableObj.transform.position))
				{
					return true;
				}
			}
			float num = Vector3.Distance(valuableObj.transform.position, truckReference.position);
			return num < 10f + padding;
		}
	}
	[HarmonyPatch(typeof(LevelGenerator))]
	public class LevelGeneratorPatch
	{
		[HarmonyPatch("GenerateDone")]
		[HarmonyPostfix]
		private static void GenerateDonePostfix(LevelGenerator __instance)
		{
			try
			{
				((MonoBehaviour)__instance).StartCoroutine(DelayedGenerateDone(__instance));
			}
			catch (Exception)
			{
			}
		}

		private static IEnumerator DelayedGenerateDone(LevelGenerator levelGenerator)
		{
			yield return null;
			ItemPersistenceModBase.LoadValuablesFromFile();
			if (!ItemPersistenceModBase.hasSavedValuables || ItemPersistenceModBase.savedValuables.Count <= 0)
			{
				yield break;
			}
			ItemPersistenceModBase.forceLoadOnNextLevel = false;
			if ((Object)(object)Object.FindObjectOfType<MainMenuOpen>() != (Object)null)
			{
				ItemPersistenceModBase.instance.mls.LogInfo((object)"Main menu detected - skipping valuable spawning");
				yield break;
			}
			float waitTime = 0f;
			while ((Object)(object)GameDirector.instance != (Object)null && (int)GameDirector.instance.currentState != 2 && waitTime < 10f)
			{
				waitTime += 0.5f;
				yield return (object)new WaitForSeconds(0.5f);
			}
			waitTime = 0f;
			bool truckFound = false;
			while (!truckFound && waitTime < 10f)
			{
				waitTime += 0.5f;
				Transform truck = GameDirectorPatch.FindTruckInterior();
				if ((Object)(object)truck != (Object)null)
				{
					truckFound = true;
				}
				yield return (object)new WaitForSeconds(0.5f);
			}
			if (!truckFound)
			{
			}
			yield return (object)new WaitForSeconds(2f);
			yield return SpawnSavedValuablesCoroutine(levelGenerator);
		}

		public static Vector3 GetStandardizedPosition(Vector3 worldPos, Transform truckTransform)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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)
			Vector3 forward = truckTransform.forward;
			forward.y = 0f;
			((Vector3)(ref forward)).Normalize();
			Vector3 right = truckTransform.right;
			right.y = 0f;
			((Vector3)(ref right)).Normalize();
			Vector3 val = worldPos - truckTransform.position;
			float num = Vector3.Dot(val, right);
			float num2 = worldPos.y - truckTransform.position.y;
			float num3 = Vector3.Dot(val, forward);
			return new Vector3(num, num2, num3);
		}

		public static Vector3 GetWorldPositionFromStandardized(Vector3 standardPos, Transform truckTransform)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			Vector3 forward = truckTransform.forward;
			forward.y = 0f;
			((Vector3)(ref forward)).Normalize();
			Vector3 right = truckTransform.right;
			right.y = 0f;
			((Vector3)(ref right)).Normalize();
			return truckTransform.position + right * standardPos.x + Vector3.up * standardPos.y + forward * standardPos.z;
		}

		private static IEnumerator SpawnSavedValuablesCoroutine(LevelGenerator levelGenerator)
		{
			ItemPersistenceModBase.instance.mls.LogInfo((object)$"Number of saved valuables: {ItemPersistenceModBase.savedValuables.Count}");
			if (!GameStateCheck.IsGameplayLevel())
			{
				yield break;
			}
			Transform truckInterior = GameDirectorPatch.FindTruckInterior();
			if ((Object)(object)truckInterior == (Object)null)
			{
				yield break;
			}
			int spawnedCount = 0;
			int failedCount = 0;
			foreach (SerializedValuable serializedValuable in ItemPersistenceModBase.savedValuables)
			{
				string prefabName = serializedValuable.prefabName.Replace("(Clone)", "").Trim();
				GameObject valuableObj = null;
				Vector3 standardizedPosition = serializedValuable.relativePosition;
				Vector3 spawnPosition = GetWorldPositionFromStandardized(standardizedPosition, truckInterior);
				spawnPosition.y += 1f;
				Quaternion spawnRotation = truckInterior.rotation * serializedValuable.rotation;
				try
				{
					bool spawnSuccessful = false;
					if (ItemPersistenceModBase.repoLibAvailable)
					{
						try
						{
							IReadOnlyList<GameObject> registeredValuables = Valuables.RegisteredValuables;
							GameObject prefab2 = ((IEnumerable<GameObject>)registeredValuables).FirstOrDefault((Func<GameObject, bool>)((GameObject go) => string.Equals(((Object)go).name.Replace("(Clone)", ""), prefabName, StringComparison.OrdinalIgnoreCase)));
							if ((Object)(object)prefab2 != (Object)null)
							{
								if (SemiFunc.IsMultiplayer())
								{
									try
									{
										string valuablePrefabPath = ResourcesHelper.GetValuablePrefabPath(prefab2);
										if (!string.IsNullOrEmpty(valuablePrefabPath))
										{
											valuableObj = PhotonNetwork.InstantiateRoomObject(valuablePrefabPath, spawnPosition, spawnRotation, (byte)0, (object[])null);
											spawnSuccessful = (Object)(object)valuableObj != (Object)null;
										}
									}
									catch (Exception)
									{
										valuableObj = Object.Instantiate<GameObject>(prefab2, spawnPosition, spawnRotation);
										spawnSuccessful = (Object)(object)valuableObj != (Object)null;
									}
								}
								else
								{
									valuableObj = Object.Instantiate<GameObject>(prefab2, spawnPosition, spawnRotation);
									spawnSuccessful = (Object)(object)valuableObj != (Object)null;
								}
							}
						}
						catch (Exception)
						{
						}
					}
					if (!spawnSuccessful)
					{
						string foundPath;
						GameObject prefab = TryLoadValuablePrefab(prefabName, out foundPath);
						if ((Object)(object)prefab != (Object)null)
						{
							if (SemiFunc.IsMultiplayer())
							{
								try
								{
									if (!string.IsNullOrEmpty(foundPath))
									{
										valuableObj = PhotonNetwork.InstantiateRoomObject(foundPath, spawnPosition, spawnRotation, (byte)0, (object[])null);
									}
								}
								catch (Exception)
								{
									valuableObj = Object.Instantiate<GameObject>(prefab, spawnPosition, spawnRotation);
								}
							}
							else
							{
								valuableObj = Object.Instantiate<GameObject>(prefab, spawnPosition, spawnRotation);
							}
						}
						foundPath = null;
					}
					if ((Object)(object)valuableObj != (Object)null)
					{
						SetValuableProperties(valuableObj, serializedValuable);
						valuableObj.GetComponent<ValuableObject>();
						PhysGrabObjectImpactDetector impactDetector = valuableObj.GetComponent<PhysGrabObjectImpactDetector>();
						impactDetector.changeInCart();
						KeepInCartState(impactDetector, 60f);
						serializedValuable.relativePosition = GetStandardizedPosition(spawnPosition, truckInterior);
						spawnedCount++;
					}
					else
					{
						failedCount++;
					}
				}
				catch (Exception)
				{
					failedCount++;
				}
			}
			if (spawnedCount > 0)
			{
				ItemPersistenceModBase.SaveValuablesToFile();
			}
		}

		private static GameObject TryLoadValuablePrefab(string searchName, out string foundPath)
		{
			foundPath = "";
			string[] array = new string[7] { "01 Tiny", "02 Small", "03 Medium", "04 Big", "05 Wide", "06 Tall", "07 Very Tall" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				string text2 = "Valuables/" + text + "/" + searchName;
				GameObject val = Resources.Load<GameObject>(text2);
				if ((Object)(object)val != (Object)null)
				{
					foundPath = text2;
					return val;
				}
			}
			string text3 = "Items/Removed Items/" + searchName;
			GameObject val2 = Resources.Load<GameObject>(text3);
			if ((Object)(object)val2 != (Object)null)
			{
				foundPath = text3;
				return val2;
			}
			string text4 = "Items/" + searchName;
			GameObject val3 = Resources.Load<GameObject>(text4);
			if ((Object)(object)val3 != (Object)null)
			{
				foundPath = text4;
				return val3;
			}
			return null;
		}

		private static GameObject FindValuablePrefab(string prefabName)
		{
			prefabName = prefabName.Replace("(Clone)", "");
			ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>();
			ValuableObject[] array2 = array;
			foreach (ValuableObject val in array2)
			{
				string text = ((Object)((Component)val).gameObject).name.Replace("(Clone)", "");
				if (text.Equals(prefabName, StringComparison.OrdinalIgnoreCase) || text.Contains(prefabName) || prefabName.Contains(text))
				{
					return ((Component)val).gameObject;
				}
			}
			GameObject[] array3 = Object.FindObjectsOfType<GameObject>();
			GameObject[] array4 = array3;
			foreach (GameObject val2 in array4)
			{
				string text2 = ((Object)val2).name.Replace("(Clone)", "");
				if ((text2.Equals(prefabName, StringComparison.OrdinalIgnoreCase) || text2.Contains(prefabName) || prefabName.Contains(text2)) && (Object)(object)val2.GetComponent<ValuableObject>() != (Object)null)
				{
					return val2;
				}
			}
			List<string> list = new List<string>();
			string text3 = prefabName.Replace("Valuable ", "").Trim();
			string[] array5 = new string[7] { "01 Tiny", "02 Small", "03 Medium", "04 Big", "05 Wide", "06 Tall", "07 Very Tall" };
			string[] array6 = new string[3] { "", "Valuable ", "Valuable_" };
			string[] array7 = array5;
			foreach (string text4 in array7)
			{
				string[] array8 = array6;
				foreach (string text5 in array8)
				{
					list.Add("Valuables/" + text4 + "/" + text5 + text3);
				}
			}
			string[] array9 = array6;
			foreach (string text6 in array9)
			{
				list.Add("Valuables/" + text6 + text3);
				list.Add("Items/" + text6 + text3);
			}
			foreach (string item in list)
			{
				try
				{
					GameObject val3 = Resources.Load<GameObject>(item);
					if ((Object)(object)val3 != (Object)null)
					{
						return val3;
					}
				}
				catch (Exception)
				{
				}
			}
			if (ItemPersistenceModBase.repoLibAvailable)
			{
				try
				{
					IReadOnlyList<GameObject> registeredValuables = Valuables.RegisteredValuables;
					foreach (GameObject item2 in registeredValuables)
					{
						if (((Object)item2).name.Contains(text3) || text3.Contains(((Object)item2).name.Replace("Valuable ", "")))
						{
							return item2;
						}
					}
				}
				catch (Exception)
				{
				}
			}
			return null;
		}

		private static IEnumerator KeepInCartState(PhysGrabObjectImpactDetector impactDetector, float duration)
		{
			for (float timer = 0f; timer < duration; timer += 0.05f)
			{
				if (!((Object)(object)impactDetector != (Object)null))
				{
					break;
				}
				impactDetector.changeInCart();
				yield return (object)new WaitForSeconds(0.05f);
			}
		}

		private static void SetValuableProperties(GameObject valuableObj, SerializedValuable serializedValuable)
		{
			ValuableObject component = valuableObj.GetComponent<ValuableObject>();
			if (!((Object)(object)component != (Object)null))
			{
				return;
			}
			try
			{
				FieldInfo field = typeof(ValuableObject).GetField("dollarValueOriginal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				FieldInfo field2 = typeof(ValuableObject).GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				FieldInfo field3 = typeof(ValuableObject).GetField("dollarValueSet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					field.SetValue(component, serializedValuable.dollarValueOriginal);
				}
				if (field2 != null)
				{
					field2.SetValue(component, serializedValuable.dollarValueCurrent);
				}
				if (field3 != null)
				{
					field3.SetValue(component, true);
				}
				else
				{
					try
					{
						MethodInfo method = typeof(ValuableObject).GetMethod("DollarValueSetLogic", BindingFlags.Instance | BindingFlags.NonPublic);
						if (method != null)
						{
							method.Invoke(component, null);
						}
					}
					catch (Exception)
					{
					}
				}
				float dollarValueOriginal = component.dollarValueOriginal;
				float dollarValueCurrent = component.dollarValueCurrent;
				try
				{
					FieldInfo field4 = typeof(ValuableObject).GetField("discovered", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field4 != null)
					{
						field4.SetValue(component, true);
					}
					component.Discover((State)0);
				}
				catch (Exception)
				{
				}
			}
			catch (Exception)
			{
			}
		}
	}
	[HarmonyPatch(typeof(RunManager))]
	public class RunManagerPatch
	{
		private static bool isGoingToMainMenu;

		[HarmonyPatch("ChangeLevel")]
		[HarmonyPrefix]
		private static void ChangeLevelPrefix(RunManager __instance, ChangeLevelType _changeLevelType)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			try
			{
				isGoingToMainMenu = (int)_changeLevelType == 4;
				if (isGoingToMainMenu && ItemPersistenceModBase.hasSavedValuables && ItemPersistenceModBase.savedValuables.Count > 0)
				{
					ItemPersistenceModBase.SaveValuablesToFile();
				}
			}
			catch (Exception ex)
			{
				ItemPersistenceModBase.instance.mls.LogError((object)("Error in ChangeLevelPrefix: " + ex.Message));
			}
		}

		[HarmonyPatch("ChangeLevel")]
		[HarmonyPostfix]
		private static void ChangeLevelPostfix(RunManager __instance, bool _completedLevel, bool _levelFailed, ChangeLevelType _changeLevelType)
		{
			try
			{
				ItemPersistenceModBase.UpdateCurrentSaveId();
			}
			catch (Exception ex)
			{
				ItemPersistenceModBase.instance.mls.LogError((object)("Error in ChangeLevelPostfix: " + ex.Message));
			}
		}

		[HarmonyPatch("UpdateLevel")]
		[HarmonyPostfix]
		private static void UpdateLevelPostfix(RunManager __instance, string _levelName, int _levelsCompleted, bool _gameOver)
		{
			try
			{
				ItemPersistenceModBase.UpdateCurrentSaveId();
			}
			catch (Exception ex)
			{
				ItemPersistenceModBase.instance.mls.LogError((object)("Error in UpdateLevelPostfix: " + ex.Message));
			}
		}

		[HarmonyPatch("ResetProgress")]
		[HarmonyPostfix]
		private static void ResetProgressPostfix(RunManager __instance)
		{
			try
			{
				if (isGoingToMainMenu)
				{
					ItemPersistenceModBase.UpdateCurrentSaveId();
				}
				else
				{
					ItemPersistenceModBase.UpdateCurrentSaveId();
				}
			}
			catch (Exception ex)
			{
				ItemPersistenceModBase.instance.mls.LogError((object)("Error in ResetProgressPostfix: " + ex.Message));
			}
		}
	}
}