using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using PlayerBacktrack; using Steamworks; using UnityEngine; using UnityEngine.AI; using UnityEngine.Localization; using UnityEngine.Localization.Tables; 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("PlayerBacktrack")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PlayerBacktrack")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("480BF3B7-3760-4887-A68B-94614B05F239")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyVersion("1.0.0.0")] namespace TMB { [BepInPlugin("com.averyocean65.pbtrack", "Player Backtrack", "1.0.0")] public class Plugin : BaseUnityPlugin { private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown Harmony val = new Harmony("com.averyocean65.pbtrack"); val.PatchAll(); SceneManager.sceneLoaded += delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)Object.FindObjectOfType())) { GameObject val2 = new GameObject("TMB Spawner"); val2.AddComponent(); } }; } } } namespace TMB.Patches { [HarmonyPatch] public class ItemAttributesPatches { private static ManualLogSource Logger = Logger.CreateLogSource("TMB IAP"); [HarmonyPatch(typeof(ItemAttributes), "GetItemNameLocalized")] [HarmonyPrefix] private static bool GetItemNameLocalizedPatch(ItemAttributes __instance, ref string __result) { if (__instance.item.itemName == "Truck Backtrack Upgrade") { __result = __instance.item.itemName; return false; } return true; } } [HarmonyPatch] public static class StatsUIPatches { private static ManualLogSource Logger = Logger.CreateLogSource("TMB StatsUI"); [HarmonyPostfix] [HarmonyPatch(typeof(StatsUI), "GetUpgradeDisplayName")] private static void UpgradeDispNamePatch(StatsUI __instance, string key, ref string __result) { if (key == "playerUpgradeTruckBacktrack") { __result = "Truck Backtrack"; } } } } namespace PlayerBacktrack { public class ItemUpgradeTruckBacktrack : MonoBehaviour { private ItemToggle _toggle; private static ManualLogSource _logger = Logger.CreateLogSource("TMB Upgrade"); private void Start() { _toggle = ((Component)this).GetComponent(); } public void Upgrade() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) int num = 0; try { num = (int)AccessTools.Field(typeof(ItemToggle), "playerTogglePhotonID").GetValue(_toggle); TmbSpawner.UpgradeTruckBacktrack(SemiFunc.PlayerGetSteamID(SemiFunc.PlayerAvatarGetFromPhotonID(num))); _logger.LogInfo((object)"Photon ID found!"); } catch { _logger.LogWarning((object)"Photon ID couldn't be found, using alternative!"); TmbSpawner.UpgradeTruckBacktrack(((object)SteamClient.SteamId/*cast due to .constrained prefix*/).ToString()); } } } public class TmbSpawner : MonoBehaviour { internal static bool PurchasedTmb = false; internal static ManualLogSource Logger; public static Dictionary playerUpgradesTruckBacktrack = new Dictionary(); private void Awake() { Logger = Logger.CreateLogSource("TMB Spawner"); Logger.LogInfo((object)"Spawned TMB Spawner!"); Object.DontDestroyOnLoad((Object)(object)this); Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } private LocalizedAsset CreateLocalizedString() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0026: Expected O, but got Unknown LocalizedAsset val = ScriptableObject.CreateInstance(); val.stringReference = new LocalizedString(TableReference.op_Implicit("TMB"), TableEntryReference.op_Implicit("TmbUpgrade")); return val; } private void Start() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown Logger.LogInfo((object)"Running TMB Spawner start!"); SortedDictionary> sortedDictionary = (SortedDictionary>)AccessTools.Field(typeof(StatsManager), "dictionaryOfDictionaries").GetValue(StatsManager.instance); Logger.LogInfo((object)"Adding Player Truck Backtrack Dictionary!"); sortedDictionary.Add("playerUpgradeTruckBacktrack", playerUpgradesTruckBacktrack); LocalizedAsset displayNameLocalized = CreateLocalizedString(); StatsManager.instance.upgradesInfo.Add("playerUpgradeTruckBacktrack", new UpgradeInfo { displayName = "Truck Backtrack", displayNameLocalized = displayNameLocalized }); Logger.LogInfo((object)"Making DDOL."); SceneManager.sceneLoaded += delegate(Scene arg0, LoadSceneMode mode) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) PurchasedTmb = playerUpgradesTruckBacktrack.Count > 0; if (PurchasedTmb) { AddTmbToScene(arg0); } }; } public static int UpgradeTruckBacktrack(string _steamID, int value = 1) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) int value2; int num = (playerUpgradesTruckBacktrack.TryGetValue(_steamID, out value2) ? value2 : 0); int num2 = Math.Max(0, num + value) - num; if (num2 == 0) { return num; } playerUpgradesTruckBacktrack[_steamID] = num + num2; Logger.LogInfo((object)$"Upgrades: {playerUpgradesTruckBacktrack[_steamID]}"); PurchasedTmb = true; if (SemiFunc.RunIsLevel()) { AddTmbToScene(SceneManager.GetActiveScene()); } return playerUpgradesTruckBacktrack[_steamID]; } private static void AddTmbToScene(Scene currentScene) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown Logger.LogInfo((object)"Adding TMB tracker to level!"); MapBacktrack val = Object.FindObjectOfType(); if (!Object.op_Implicit((Object)(object)val)) { Logger.LogWarning((object)("No MapBacktrack found in " + ((Scene)(ref currentScene)).name + "!")); return; } TruckMapBacktrack truckMapBacktrack = Object.FindObjectOfType(); if (Object.op_Implicit((Object)(object)truckMapBacktrack)) { truckMapBacktrack.amount = Mathf.FloorToInt((float)truckMapBacktrack.amount * 1.75f); return; } GameObject val2 = new GameObject("Truck Backtrack"); val2.transform.SetParent(((Component)val).transform.parent); TruckMapBacktrack truckMapBacktrack2 = val2.AddComponent(); truckMapBacktrack2.pointPrefab = val.pointPrefab; truckMapBacktrack2.amount = val.amount; truckMapBacktrack2.spacing = val.spacing * 1.2f; truckMapBacktrack2.pointWait = val.pointWait; truckMapBacktrack2.logger = Logger.CreateLogSource("TMB"); } } public class TruckMapBacktrack : MonoBehaviour { public GameObject pointPrefab; private List points = new List(); [Space] public int amount = 15; public float spacing = 0.2f; public float pointWait = 0.1f; private int currentPoint; private Vector3 currentPointPosition; private int currentPointCorner; private Vector3 truckDestination; private NavMeshPath path; private FieldInfo _lashNavmeshPos; public ManualLogSource logger; private void Start() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) logger.LogInfo((object)"Spawned TMB!"); _lashNavmeshPos = AccessTools.Field(typeof(PlayerAvatar), "LastNavmeshPosition"); path = new NavMeshPath(); for (int i = 0; i < amount; i++) { GameObject val = Object.Instantiate(pointPrefab, ((Component)this).transform); MapBacktrackPoint component = val.GetComponent(); component.spriteRenderer.color = new Color(0.79f, 0.14f, 0.25f); points.Add(component); ((Object)val.transform).name = $"Point {i}"; } ((MonoBehaviour)this).StartCoroutine(Backtrack()); } private IEnumerator Backtrack() { while (!LevelGenerator.Instance.Generated || SemiFunc.RunIsShop()) { yield return (object)new WaitForSeconds(0.1f); } yield return (object)new WaitForSeconds(0.5f); foreach (LevelPoint levelPathPoint in LevelGenerator.Instance.LevelPathPoints) { if (Object.op_Implicit((Object)(object)levelPathPoint.Room) && levelPathPoint.Room.Truck) { truckDestination = ((Component)levelPathPoint).transform.position; break; } } while (true) { Vector3 lastNavmeshPosition = (Vector3)_lashNavmeshPos.GetValue(PlayerController.instance.playerAvatarScript); Vector3 vector3 = truckDestination; bool flag1 = false; if (Map.Instance.Active && Map.Instance.GetLayerParent(lastNavmeshPosition.y + 1f).layer == Map.Instance.GetLayerParent(vector3.y + 1f).layer) { flag1 = true; } if (!Map.Instance.Active || (flag1 && (double)Vector3.Distance(lastNavmeshPosition, vector3) < 10.0)) { yield return (object)new WaitForSeconds(0.25f); continue; } NavMesh.CalculatePath(lastNavmeshPosition, vector3, -1, path); currentPoint = 0; currentPointPosition = lastNavmeshPosition; currentPointCorner = 0; while (currentPoint < points.Count) { bool flag2 = false; float spacing = this.spacing; while (!flag2 && currentPointCorner < path.corners.Length) { float num = Vector3.Distance(currentPointPosition, path.corners[currentPointCorner]); if (num < spacing) { currentPointPosition = path.corners[currentPointCorner]; spacing -= num; currentPointCorner++; continue; } currentPointPosition = Vector3.Lerp(currentPointPosition, path.corners[currentPointCorner], spacing / num); if (Map.Instance.GetLayerParent(currentPointPosition.y + 1f).layer == Map.Instance.PlayerLayer) { points[currentPoint].Show(true); } else { points[currentPoint].Show(false); } ((Component)points[currentPoint]).transform.position = new Vector3(currentPointPosition.x, 0f, currentPointPosition.z) * Map.Instance.Scale + Map.Instance.OverLayerParent.position; currentPoint++; flag2 = true; } if (currentPointCorner >= path.corners.Length) { currentPoint = points.Count; } yield return (object)new WaitForSeconds(pointWait); } foreach (MapBacktrackPoint _point in points) { while (_point.animating) { yield return (object)new WaitForSeconds(0.05f); } } yield return (object)new WaitForSeconds(pointWait); } } } }