diff --git a/TLM/TLM/LoadingExtension.cs b/TLM/TLM/LoadingExtension.cs index 4f2b9d3e6..bf3b4b7ac 100644 --- a/TLM/TLM/LoadingExtension.cs +++ b/TLM/TLM/LoadingExtension.cs @@ -16,10 +16,30 @@ namespace TrafficManager { using TrafficManager.State; using TrafficManager.UI.Localization; using TrafficManager.UI; + using static TrafficManager.Util.Shortcuts; + using UnityEngine; [UsedImplicitly] public class LoadingExtension : LoadingExtensionBase { private const string HARMONY_ID = "de.viathinksoft.tmpe"; + internal static LoadingExtension Instance = null; + + internal bool InGameHotReload { get; private set; } = false; + + internal static AppMode currentMode => SimulationManager.instance.m_ManagersWrapper.loading.currentMode; + + internal static bool InGame() { + try { + return currentMode == AppMode.Game; + } catch { + return false; + } + } + + FastList simManager => + typeof(SimulationManager).GetField("m_managers", BindingFlags.Static | BindingFlags.NonPublic) + ?.GetValue(null) as FastList; + public class Detour { public MethodInfo OriginalMethod; @@ -40,12 +60,6 @@ public class ManualHarmonyPatch { public HarmonyMethod postfix = null; } - // public static LoadingExtension Instance; - - public static bool IsPathManagerReplaced { - get; private set; - } - public static CustomPathManager CustomPathManager { get; set; } public static bool DetourInited { get; set; } @@ -53,8 +67,6 @@ public static bool IsPathManagerReplaced { public static List Detours { get; set; } public static HarmonyInstance HarmonyInst { get; private set; } - // public static TrafficManagerMode ToolMode { get; set; } - // public static TrafficManagerTool TrafficManagerTool { get; set; } /// /// Contains loaded languages and lookup functions for text translations @@ -261,6 +273,8 @@ private void InitDetours() { } public override void OnCreated(ILoading loading) { + Log._Debug("LoadingExtension.OnCreated() called"); + // SelfDestruct.DestructOldInstances(this); base.OnCreated(loading); @@ -270,6 +284,9 @@ public override void OnCreated(ILoading loading) { CustomPathManager = new CustomPathManager(); RegisterCustomManagers(); + + Instance = this; + InGameHotReload = InGame(); } private void RegisterCustomManagers() { @@ -304,22 +321,15 @@ private void RegisterCustomManagers() { } public override void OnReleased() { + Instance = null; base.OnReleased(); - - UIBase.ReleaseTool(); } public override void OnLevelUnloading() { Log.Info("OnLevelUnloading"); base.OnLevelUnloading(); - if (IsPathManagerReplaced) { - CustomPathManager._instance.WaitForAllPaths(); - } - // Object.Destroy(BaseUI); - // BaseUI = null; - // Object.Destroy(TransportDemandUI); - // TransportDemandUI = null; + CustomPathManager._instance.WaitForAllPaths(); try { var reverseManagers = new List(RegisteredManagers); @@ -333,21 +343,38 @@ public override void OnLevelUnloading() { Flags.OnLevelUnloading(); GlobalConfig.OnLevelUnloading(); + var gameObject = UIView.GetAView().gameObject; + void Destroy() where T : MonoBehaviour { + Object obj = (Object)gameObject.GetComponent(); + if (obj != null) { + Object.Destroy(obj); + } + } + // remove vehicle button - var removeVehicleButtonExtender = UIView - .GetAView().gameObject - .GetComponent(); - if (removeVehicleButtonExtender != null) { - Object.Destroy(removeVehicleButtonExtender, 10f); + Destroy(); + Destroy(); + + // Custom path manger is destroyed when reloading. That is why the following code + // is commented out. + //simManager?.Remove(CustomPathManager); + //Object.Destroy(CustomPathManager); + //CustomPathManager = null; + + if (TransportDemandUI != null) { + UIView uiView = UIView.GetAView(); + Object.Destroy(TransportDemandUI); + TransportDemandUI = null; } - // remove citizen instance button - var removeCitizenInstanceButtonExtender = UIView - .GetAView().gameObject - .GetComponent(); - if (removeCitizenInstanceButtonExtender != null) { - Object.Destroy(removeCitizenInstanceButtonExtender, 10f); + Log.Info("Removing Controls from UI."); + if (BaseUI != null) { + BaseUI.Close(); // Hide the UI ASAP + Object.Destroy(BaseUI); + BaseUI = null; + Log._Debug("removed UIBase instance."); } + #if TRACE Singleton.instance.OnLevelUnloading(); #endif @@ -452,63 +479,68 @@ public override void OnLevelLoaded(LoadMode mode) { } } - if (!IsPathManagerReplaced) { - try { - Log.Info("Pathfinder Compatible. Setting up CustomPathManager and SimManager."); - FieldInfo pathManagerInstance = typeof(Singleton).GetField( - "sInstance", - BindingFlags.Static | BindingFlags.NonPublic); + try { + Log.Info("Pathfinder Compatible. Setting up CustomPathManager and SimManager."); + FieldInfo pathManagerInstance = typeof(Singleton).GetField( + "sInstance", + BindingFlags.Static | BindingFlags.NonPublic); + if (pathManagerInstance == null) { + throw new Exception("pathManagerInstance is null"); + } - PathManager stockPathManager = PathManager.instance; - Log._Debug($"Got stock PathManager instance {stockPathManager.GetName()}"); - CustomPathManager = stockPathManager.gameObject.AddComponent(); - Log._Debug("Added CustomPathManager to gameObject List"); + PathManager stockPathManager = PathManager.instance; + if (stockPathManager == null) { + throw new Exception("stockPathManager is null"); + } - if (CustomPathManager == null) { - Log.Error("CustomPathManager null. Error creating it."); - return; - } + Log._Debug($"Got stock PathManager instance {stockPathManager?.GetName()}"); - CustomPathManager.UpdateWithPathManagerValues(stockPathManager); - Log._Debug("UpdateWithPathManagerValues success"); + CustomPathManager = stockPathManager.gameObject.AddComponent(); + Log._Debug("Added CustomPathManager to gameObject List"); - pathManagerInstance?.SetValue(null, CustomPathManager); + if (CustomPathManager == null) { + Log.Error("CustomPathManager null. Error creating it."); + return; + } - Log._Debug("Getting Current SimulationManager"); - var simManager = - typeof(SimulationManager).GetField( - "m_managers", - BindingFlags.Static | BindingFlags.NonPublic) - ?.GetValue(null) as FastList; + CustomPathManager.UpdateWithPathManagerValues(stockPathManager); + Log._Debug("UpdateWithPathManagerValues success"); - Log._Debug("Removing Stock PathManager"); - simManager?.Remove(stockPathManager); + pathManagerInstance.SetValue(null, CustomPathManager); - Log._Debug("Adding Custom PathManager"); - simManager?.Add(CustomPathManager); + Log._Debug("Getting Current SimulationManager"); + var simManager = this.simManager; + if (simManager == null) { + throw new Exception("simManager is null"); + } - Object.Destroy(stockPathManager, 10f); + Log._Debug("Removing Stock PathManager"); + simManager.Remove(stockPathManager); - Log._Debug("Should be custom: " + Singleton.instance.GetType()); + Log._Debug("Adding Custom PathManager"); + simManager.Add(CustomPathManager); - IsPathManagerReplaced = true; - } catch (Exception ex) { - string error = "Traffic Manager: President Edition failed to load. You can continue " + - "playing but it's NOT recommended. Traffic Manager will not work as expected."; - Log.Error(error); - Log.Error($"Path manager replacement error: {ex}"); + Object.Destroy(stockPathManager, 10f); - Singleton.instance.m_ThreadingWrapper.QueueMainThread( - () => { - UIView.library - .ShowModal("ExceptionPanel") - .SetMessage( - "TM:PE failed to load", - error, - true); - }); - } + Log._Debug("Should be custom: " + Singleton.instance.GetType()); + + } + catch (Exception ex) { + string error = "Traffic Manager: President Edition failed to load. You can continue " + + "playing but it's NOT recommended. Traffic Manager will not work as expected."; + Log.Error(error); + Log.Error($"Path manager replacement error: {ex}"); + + Singleton.instance.m_ThreadingWrapper.QueueMainThread( + () => { + UIView.library + .ShowModal("ExceptionPanel") + .SetMessage( + "TM:PE failed to load", + error, + true); + }); } Log.Info("Adding Controls to UI."); diff --git a/TLM/TLM/State/SerializableDataExtension.cs b/TLM/TLM/State/SerializableDataExtension.cs index 5268f4d1f..9a9a55fc4 100644 --- a/TLM/TLM/State/SerializableDataExtension.cs +++ b/TLM/TLM/State/SerializableDataExtension.cs @@ -1,4 +1,4 @@ -namespace TrafficManager.State { +namespace TrafficManager.State { using CSUtil.Commons; using ICities; using JetBrains.Annotations; @@ -21,6 +21,14 @@ public class SerializableDataExtension public override void OnCreated(ISerializableData serializableData) { _serializableData = serializableData; + + Log._Debug("SerializableDataExtension.OnCreated() called"); + + if (LoadingExtension.Instance.InGameHotReload) { + Log._Debug("HOT RELOAD ..."); + OnLoadData(); + LoadingExtension.Instance.OnLevelLoaded(LoadMode.LoadGame); + } } public override void OnReleased() { } diff --git a/TLM/TLM/TLM.csproj b/TLM/TLM/TLM.csproj index 19183cf39..45626244b 100644 --- a/TLM/TLM/TLM.csproj +++ b/TLM/TLM/TLM.csproj @@ -521,8 +521,22 @@ + + + + + + + + + - rem set "DEPLOYDIR=D:\Games\Steam\steamapps\workshop\content\255710\1637663252\" + + $(PostBuildEventDependsOn); + PostBuildMacros; + + +rem set "DEPLOYDIR=D:\Games\Steam\steamapps\workshop\content\255710\1637663252\" set "DEPLOYDIR=$(LOCALAPPDATA)\Colossal Order\Cities_Skylines\Addons\Mods\$(TargetName)\" del /Q "%25DEPLOYDIR%25*" @@ -534,14 +548,12 @@ xcopy /y "$(TargetDir)CSUtil.CameraControl.dll" "%25DEPLOYDIR%25" xcopy /y "$(TargetDir)TMPE.RedirectionFramework.dll" "%25DEPLOYDIR%25" xcopy /y "$(TargetDir)CSUtil.Commons.dll" "%25DEPLOYDIR%25" xcopy /y "$(TargetDir)0TMPE.Harmony.dll" "%25DEPLOYDIR%25" - -set DEPLOYDIR= - - - - +echo THE ASSEMBLY VERSION IS: @(VersionNumber) created at %25time%25 + +set DEPLOYDIR= + -