From a6dbd9c058e4fe7c3764317c10e90919804b8e41 Mon Sep 17 00:00:00 2001 From: seiggy Date: Sun, 2 Aug 2015 21:36:19 -0400 Subject: [PATCH] new save system. trying to solve loading issues for legacy games. --- TLM/TLM/Configuration.cs | 11 +- TLM/TLM/CustomAI/CustomCarAI.cs | 12 +- TLM/TLM/CustomPathFind.cs | 6 +- TLM/TLM/CustomPathManager.cs | 8 +- TLM/TLM/LoadingExtension.cs | 150 ++++++++-- TLM/TLM/Log.cs | 18 +- TLM/TLM/PrioritySegment.cs | 18 +- TLM/TLM/SerializableDataExtension.cs | 323 +++++++++++++-------- TLM/TLM/TLM.csproj | 14 +- TLM/TLM/ThreadingExtension.cs | 19 +- TLM/TLM/Traffic/TrafficPriority.cs | 8 +- TLM/TLM/TrafficLight/ManualSegmentLight.cs | 4 +- TLM/TLM/TrafficLight/TrafficLightTool.cs | 8 +- TLM/TLM/TrafficManagerMod.cs | 4 +- TLM/TLM/UI/UITrafficManager.cs | 2 +- 15 files changed, 416 insertions(+), 189 deletions(-) diff --git a/TLM/TLM/Configuration.cs b/TLM/TLM/Configuration.cs index 4cf8bf92..639153ba 100644 --- a/TLM/TLM/Configuration.cs +++ b/TLM/TLM/Configuration.cs @@ -1,14 +1,17 @@ +using System; using System.Collections.Generic; using System.IO; +using System.Runtime.Serialization; using System.Xml.Serialization; namespace TrafficManager { + [Serializable] public class Configuration { - public string NodeTrafficLights; - public string NodeCrosswalk; - public string LaneFlags; + public string NodeTrafficLights = ""; + public string NodeCrosswalk = ""; + public string LaneFlags = ""; public List PrioritySegments = new List(); public List NodeDictionary = new List(); @@ -19,6 +22,7 @@ public class Configuration public List TimedNodeSteps = new List(); public List TimedNodeStepSegments = new List(); + [Obsolete("This should be replaced with memory stream write/read to save direct to the user's save file.")] public static void SaveConfigurationToFile(string filename, Configuration config) { var serializer = new XmlSerializer(typeof(Configuration)); @@ -29,6 +33,7 @@ public static void SaveConfigurationToFile(string filename, Configuration config } } + [Obsolete("This should be replaced with memory stream write/read to save direct to the user's save file.")] public static Configuration LoadConfigurationFromFile(string filename) { var serializer = new XmlSerializer(typeof(Configuration)); diff --git a/TLM/TLM/CustomAI/CustomCarAI.cs b/TLM/TLM/CustomAI/CustomCarAI.cs index d6ff6bb7..84ea64dc 100644 --- a/TLM/TLM/CustomAI/CustomCarAI.cs +++ b/TLM/TLM/CustomAI/CustomCarAI.cs @@ -39,9 +39,10 @@ private void SimulateVehicleChain(ushort vehicleId, ref Vehicle vehicleData, Vec var lodPhysics = CalculateLod(physicsLodRefPos, lastFramePosition); SimulationStep(vehicleId, ref vehicleData, vehicleId, ref vehicleData, lodPhysics); + + if (vehicleData.m_leadingVehicle != 0 || vehicleData.m_trailingVehicle == 0) + return; - // if there are vehicles behind this, simulate them - if (vehicleData.m_leadingVehicle != 0 || vehicleData.m_trailingVehicle == 0) return; var vehicleManager = Singleton.instance; var trailingVehicleId = vehicleData.m_trailingVehicle; SimulateTrailingVehicles(vehicleId, ref vehicleData, lodPhysics, trailingVehicleId, vehicleManager, @@ -424,7 +425,7 @@ public void TmCalculateSegmentPosition(ushort vehicleId, ref Vehicle vehicleData switch (prioritySegment.Type) { case PrioritySegment.PriorityType.Stop: - if (TrafficPriority.VehicleList[vehicleId].WaitTime < 25) + if (TrafficPriority.VehicleList[vehicleId].WaitTime < 75) { TrafficPriority.VehicleList[vehicleId].CarState = CarState.Stop; @@ -444,7 +445,7 @@ public void TmCalculateSegmentPosition(ushort vehicleId, ref Vehicle vehicleData return; } TrafficPriority.VehicleList[vehicleId].CarState = - CarState.Transit; + CarState.Leave; } else { @@ -482,6 +483,9 @@ public void TmCalculateSegmentPosition(ushort vehicleId, ref Vehicle vehicleData } else { + maxSpeed = vehicleData.GetLastFrameData().m_velocity.sqrMagnitude - + TrafficPriority.VehicleList[vehicleId] + .ReduceSpeedByValueToYield; return; } } diff --git a/TLM/TLM/CustomPathFind.cs b/TLM/TLM/CustomPathFind.cs index e2907b52..8177d5dd 100644 --- a/TLM/TLM/CustomPathFind.cs +++ b/TLM/TLM/CustomPathFind.cs @@ -136,7 +136,7 @@ protected virtual void Awake() if (!CustomPathFindThread.IsAlive) { //CODebugBase.Error(LogChannel.Core, "Path find thread failed to start!"); - Debug.LogError("Path find thread failed to start!", this); + Log.Error("Path find thread failed to start!"); } } @@ -1665,9 +1665,9 @@ private void PathFindThread() } catch (Exception ex) { - Debug.Log("path thread error: " + ex.Message); + Log.Error("path thread error: " + ex.Message); UIView.ForwardException(ex); - Debug.LogError("Path find error: " + ex.Message + "\n" + ex.StackTrace, this); + Log.Error("Path find error: " + ex.Message + "\n" + ex.StackTrace); var expr_1A0Cp0 = PathUnits.m_buffer; var expr_1A0Cp1 = (UIntPtr)Calculating; expr_1A0Cp0[(int)expr_1A0Cp1].m_pathFindFlags = (byte)(expr_1A0Cp0[(int)expr_1A0Cp1].m_pathFindFlags | 8); diff --git a/TLM/TLM/CustomPathManager.cs b/TLM/TLM/CustomPathManager.cs index 437eb016..ee4680dd 100644 --- a/TLM/TLM/CustomPathManager.cs +++ b/TLM/TLM/CustomPathManager.cs @@ -19,11 +19,11 @@ public class CustomPathManager : PathManager //On waking up, replace the stock pathfinders with the custom one protected new virtual void Awake() { - //Debug.Log("Waking up CustomPathManager."); + Log.Message("Waking up CustomPathManager."); var stockPathFinds = GetComponents(); var numOfStockPathFinds = stockPathFinds.Length; - //Debug.Log("Creating " + numOfStockPathFinds + " custom PathFind objects."); + Log.Message("Creating " + numOfStockPathFinds + " custom PathFind objects."); _replacementPathFinds = new CustomPathFind[numOfStockPathFinds]; for (var i = 0; i < numOfStockPathFinds; i++) { @@ -31,10 +31,10 @@ public class CustomPathManager : PathManager Destroy(stockPathFinds[i]); } - //Debug.Log("Setting _replacementPathFinds"); + Log.Message("Setting _replacementPathFinds"); var fieldInfo = typeof(PathManager).GetField("m_pathfinds", BindingFlags.NonPublic | BindingFlags.Instance); - //Debug.Log("Setting m_pathfinds to custom collection"); + Log.Message("Setting m_pathfinds to custom collection"); fieldInfo?.SetValue(this, _replacementPathFinds); } diff --git a/TLM/TLM/LoadingExtension.cs b/TLM/TLM/LoadingExtension.cs index d0ac4b23..d1464715 100644 --- a/TLM/TLM/LoadingExtension.cs +++ b/TLM/TLM/LoadingExtension.cs @@ -34,19 +34,19 @@ public override void OnCreated(ILoading loading) base.OnCreated(loading); - Debug.Log("Setting ToolMode"); + Log.Message("Setting ToolMode"); ToolMode = TrafficManagerMode.None; - Debug.Log("Init RevertMethods"); + Log.Message("Init RevertMethods"); RevertMethods = new RedirectCallsState[8]; - Debug.Log("Setting Despawn to False"); + Log.Message("Setting Despawn to False"); DespawnEnabled = true; - Debug.Log("Init DetourInited"); + Log.Message("Init DetourInited"); DetourInited = false; - Debug.Log("Init Custom PathManager"); + Log.Message("Init Custom PathManager"); CustomPathManager = new CustomPathManager(); } @@ -64,9 +64,9 @@ public override void OnReleased() public override void OnLevelLoaded(LoadMode mode) { - Debug.Log("OnLevelLoaded calling base method"); + Log.Message("OnLevelLoaded calling base method"); base.OnLevelLoaded(mode); - Debug.Log("OnLevelLoaded Returned from base, calling custom code."); + Log.Message("OnLevelLoaded Returned from base, calling custom code."); switch (mode) { @@ -82,10 +82,10 @@ public override void OnLevelLoaded(LoadMode mode) { if (Instance == null) { - Debug.Log("Instance is NULL. Set Instance to this."); + Log.Message("Instance is NULL. Set Instance to this."); if (Singleton.instance.GetType() != typeof (PathManager)) { - Debug.Log("Traffic++ Detected. Disable Pathfinder"); + Log.Message("Traffic++ Detected. Disable Pathfinder"); IsPathManagerCompatibile = false; } @@ -94,31 +94,42 @@ public override void OnLevelLoaded(LoadMode mode) if (IsPathManagerCompatibile) { - Debug.Log("Pathfinder Compatible. Setting up CustomPathManager and SimManager."); + Log.Message("Pathfinder Compatible. Setting up CustomPathManager and SimManager."); var pathManagerInstance = typeof (Singleton).GetField("sInstance", BindingFlags.Static | BindingFlags.NonPublic); var stockPathManager = PathManager.instance; + Log.Message($"Got stock PathManager instance {stockPathManager.GetName()}"); + CustomPathManager = stockPathManager.gameObject.AddComponent(); + Log.Message("Added CustomPathManager to gameObject List"); + + if (CustomPathManager == null) + { + Log.Error("CustomPathManager null. Error creating it."); + return; + } + CustomPathManager.UpdateWithPathManagerValues(stockPathManager); + Log.Message("UpdateWithPathManagerValues success"); pathManagerInstance?.SetValue(null, CustomPathManager); - Debug.Log("Getting Current SimulationManager"); + Log.Message("Getting Current SimulationManager"); var simManager = typeof (SimulationManager).GetField("m_managers", BindingFlags.Static | BindingFlags.NonPublic)? .GetValue(null) as FastList; - Debug.Log("Removing Stock PathManager"); + Log.Message("Removing Stock PathManager"); simManager?.Remove(stockPathManager); - Debug.Log("Adding Custom PathManager"); + Log.Message("Adding Custom PathManager"); simManager?.Add(CustomPathManager); Object.Destroy(stockPathManager, 10f); } - Debug.Log("Adding Controls to UI."); + Log.Message("Adding Controls to UI."); UI = ToolsModifierControl.toolController.gameObject.AddComponent(); TrafficPriority.LeftHandDrive = Singleton.instance.m_metaData.m_invertTraffic == SimulationMetaData.MetaBool.True; @@ -130,6 +141,111 @@ public override void OnLevelUnloading() // TODO: revert detours base.OnLevelUnloading(); + //if (Instance == null) + //{ + // Log.Message("Instance is NULL. Set Instance to this."); + // if (Singleton.instance.GetType() != typeof(PathManager)) + // { + // Log.Message("Traffic++ Detected. Disable Pathfinder"); + // IsPathManagerCompatibile = false; + // } + + // Instance = this; + //} + //try + //{ + // RedirectionHelper.RevertRedirect(typeof(CarAI).GetMethod("CalculateSegmentPosition", + // BindingFlags.NonPublic | BindingFlags.Instance, + // null, + // new[] + // { + // typeof (ushort), typeof (Vehicle).MakeByRefType(), typeof (PathUnit.Position), + // typeof (PathUnit.Position), typeof (uint), typeof (byte), typeof (PathUnit.Position), + // typeof (uint), typeof (byte), typeof (Vector3).MakeByRefType(), + // typeof (Vector3).MakeByRefType(), typeof (float).MakeByRefType() + // }, + // null), LoadingExtension.Instance.RevertMethods[0]); + + // RedirectionHelper.RevertRedirect(typeof (RoadBaseAI).GetMethod("SimulationStep", + // new[] {typeof (ushort), typeof (NetNode).MakeByRefType()}), + // LoadingExtension.Instance.RevertMethods[1]); + + // Log.Message("Redirecting Human AI Calls"); + // RedirectionHelper.RevertRedirect(typeof(HumanAI).GetMethod("CheckTrafficLights", + // BindingFlags.NonPublic | BindingFlags.Instance, + // null, + // new[] { typeof(ushort), typeof(ushort) }, + // null), + // LoadingExtension.Instance.RevertMethods[2]); + + // if (IsPathManagerCompatibile) + // { + // RedirectionHelper.RevertRedirect( + // typeof(CarAI).GetMethod("SimulationStep", + // new[] { + // typeof (ushort), + // typeof (Vehicle).MakeByRefType(), + // typeof (Vector3) + // }), + // Instance.RevertMethods[3]); + + // Log.Message("Redirecting PassengerCarAI Simulation Step Calls"); + // RedirectionHelper.RevertRedirect( + // typeof(PassengerCarAI).GetMethod("SimulationStep", + // new[] { typeof(ushort), typeof(Vehicle).MakeByRefType(), typeof(Vector3) }), + // Instance.RevertMethods[4]); + + // Log.Message("Redirecting CargoTruckAI Simulation Step Calls"); + // RedirectionHelper.RevertRedirect( + // typeof(CargoTruckAI).GetMethod("SimulationStep", + // new[] { typeof(ushort), typeof(Vehicle).MakeByRefType(), typeof(Vector3) }), + // Instance.RevertMethods[5]); + + // Log.Message("Redirection CarAI Calculate Segment Position calls for non-Traffic++"); + // RedirectionHelper.RevertRedirect(typeof(CarAI).GetMethod("CalculateSegmentPosition", + // BindingFlags.NonPublic | BindingFlags.Instance, + // null, + // new[] + // { + // typeof (ushort), typeof (Vehicle).MakeByRefType(), typeof (PathUnit.Position), + // typeof (uint), + // typeof (byte), typeof (Vector3).MakeByRefType(), typeof (Vector3).MakeByRefType(), + // typeof (float).MakeByRefType() + // }, + // null), + // Instance.RevertMethods[6]); + + // LoadingExtension.Instance.DetourInited = false; + // Log.Message("Pathfinder Compatible. Setting up CustomPathManager and SimManager."); + // var pathManagerInstance = typeof(Singleton).GetField("sInstance", + // BindingFlags.Static | BindingFlags.NonPublic); + + // var stockPathManager = PathManager.instance; + // CustomPathManager = stockPathManager.gameObject.GetComponent(); + // //CustomPathManager.UpdateWithPathManagerValues(stockPathManager); + + // pathManagerInstance?.SetValue(null, CustomPathManager); + + // Log.Message("Getting Current SimulationManager"); + // var simManager = + // typeof(SimulationManager).GetField("m_managers", BindingFlags.Static | BindingFlags.NonPublic)? + // .GetValue(null) as FastList; + + // Log.Message("Removing Stock PathManager"); + // simManager?.Remove(CustomPathManager); + + // Log.Message("Adding Custom PathManager"); + // simManager?.Add(stockPathManager); + // } + + //} + //catch (Exception e) + //{ + // Log.Error("Error unloading. " + e.Message); + + //} + + try { TrafficPriority.PrioritySegments.Clear(); @@ -141,19 +257,19 @@ public override void OnLevelUnloading() } catch (Exception e) { - Debug.LogError("Exception unloading mod. " + e.Message); + Log.Error("Exception unloading mod. " + e.Message); // ignored - prevents collision with other mods } } protected virtual void OnNewGame() { - Debug.Log("New Game Started"); + Log.Message("New Game Started"); } protected virtual void OnLoaded() { - Debug.Log("Loaded save game."); + Log.Message("Loaded save game."); } public void SetToolMode(TrafficManagerMode mode) diff --git a/TLM/TLM/Log.cs b/TLM/TLM/Log.cs index 6783bac3..8cd710d5 100644 --- a/TLM/TLM/Log.cs +++ b/TLM/TLM/Log.cs @@ -1,4 +1,5 @@ using System; +using UnityEngine; namespace TrafficManager { @@ -6,26 +7,35 @@ namespace TrafficManager public static class Log { const string Prefix = "TrafficLightManager: "; + private static readonly bool InGameDebug = Environment.OSVersion.Platform != PlatformID.Unix; public static void Message(object s) { - DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Message, Prefix + s.ToString()); + if(InGameDebug) + DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Message, Prefix + s.ToString()); + Debug.Log(Prefix + s.ToString()); } public static void Error(object s) { - DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Error, Prefix + s.ToString()); + if (InGameDebug) + DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Error, Prefix + s.ToString()); + Debug.LogError(Prefix + s.ToString()); } public static void Warning(object s) { - DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Warning, Prefix + s.ToString()); + if (InGameDebug) + DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Warning, Prefix + s.ToString()); + Debug.LogWarning(Prefix + s.ToString()); } internal static void Warning(InstanceType instanceType) { - DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Warning, Prefix + String.Empty.ToString()); + if (InGameDebug) + DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Warning, Prefix); + Debug.LogWarning(Prefix); } } diff --git a/TLM/TLM/PrioritySegment.cs b/TLM/TLM/PrioritySegment.cs index 33114ee7..5127eb69 100644 --- a/TLM/TLM/PrioritySegment.cs +++ b/TLM/TLM/PrioritySegment.cs @@ -70,25 +70,25 @@ private void _numCarsOnLane() var instance = Singleton.instance; var segment = instance.m_segments.m_buffer[Segmentid]; - var info = segment.Info; + var segmentInfo = segment.Info; - uint[] num2 = {segment.m_lanes}; - var num3 = 0; + uint[] laneId = {segment.m_lanes}; + var currentLane = 0; CarsOnLanes = new int[16]; - while (num3 < info.m_lanes.Length && num2[0] != 0u) + while (currentLane < segmentInfo.m_lanes.Length && laneId[0] != 0u) { - if (info.m_lanes[num3].m_laneType != NetInfo.LaneType.Pedestrian) + if (segmentInfo.m_lanes[currentLane].m_laneType != NetInfo.LaneType.Pedestrian) { - foreach (var car in Cars.Where(car => TrafficPriority.VehicleList[car].FromLaneId == num2[0])) + foreach (var car in Cars.Where(car => TrafficPriority.VehicleList[car].FromLaneId == laneId[0])) { - CarsOnLanes[num3]++; + CarsOnLanes[currentLane]++; } } - num2[0] = instance.m_lanes.m_buffer[(int)((UIntPtr)num2[0])].m_nextLane; - num3++; + laneId[0] = instance.m_lanes.m_buffer[(int)((UIntPtr)laneId[0])].m_nextLane; + currentLane++; } } } diff --git a/TLM/TLM/SerializableDataExtension.cs b/TLM/TLM/SerializableDataExtension.cs index 104713d2..9042e21a 100644 --- a/TLM/TLM/SerializableDataExtension.cs +++ b/TLM/TLM/SerializableDataExtension.cs @@ -2,9 +2,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.Serialization.Formatters.Binary; using System.Timers; using ColossalFramework; using ICities; +using NLog; using TrafficManager.CustomAI; using TrafficManager.Traffic; using TrafficManager.TrafficLight; @@ -14,25 +16,27 @@ namespace TrafficManager { - public class SerializableDataExtension : ISerializableDataExtension + public class SerializableDataExtension : SerializableDataExtensionBase { - public static string DataId = "TrafficManager_v0.9"; + public const string LegacyDataId = "TrafficManager_v0.9"; + public const string DataId = "TrafficManager_v1.0"; public static uint UniqueId; public static ISerializableData SerializableData; + private static Configuration _configuration; + public static bool ConfigLoaded = false; - private static Timer _timer; - - public void OnCreated(ISerializableData serializableData) + public override void OnCreated(ISerializableData serializableData) { UniqueId = 0u; SerializableData = serializableData; } - public void OnReleased() + public override void OnReleased() { } + [Obsolete("Part of the old save system. Will be removed eventually.")] private static void GenerateUniqueId() { UniqueId = (uint)Random.Range(1000000f, 2000000f); @@ -43,28 +47,18 @@ private static void GenerateUniqueId() } } - public void OnLoadData() + public override void OnLoadData() { - Debug.Log("Loading Mod Data."); - var data = SerializableData.LoadData(DataId); + Log.Message("Loading Mod Data"); + var data = SerializableData.LoadData(LegacyDataId) ?? SerializableData.LoadData(DataId); if (data == null) - { - GenerateUniqueId(); - } - else - { - _timer = new Timer(2000); - // Hook up the Elapsed event for the timer. - _timer.Elapsed += OnLoadDataTimed; - _timer.Enabled = true; - } + return; + DeserializeData(data); } - private static void OnLoadDataTimed(object source, ElapsedEventArgs e) + private string LoadLegacyData(byte[] data) { - var data = SerializableData.LoadData(DataId); - UniqueId = 0u; for (var i = 0; i < data.Length - 3; i++) @@ -72,176 +66,253 @@ private static void OnLoadDataTimed(object source, ElapsedEventArgs e) UniqueId = BitConverter.ToUInt32(data, i); } - Debug.Log("Loading TrafficManagerSave"); + Log.Message($"Loading TrafficManagerSave from file trafficManagerSave_{UniqueId}.xml"); var filepath = Path.Combine(Application.dataPath, "trafficManagerSave_" + UniqueId + ".xml"); - _timer.Enabled = false; - if (!File.Exists(filepath)) + if (File.Exists(filepath)) + return filepath; + + Log.Warning("Save Data doesn't exist. Expected: " + filepath); + throw new FileNotFoundException("Legacy data not present."); + } + + private void DeserializeData(byte[] data) + { + string legacyFilepath = null; + try { - Debug.LogWarning("Save Data doesn't exist. Expected: " + filepath); - return; + legacyFilepath = LoadLegacyData(data); } + catch (Exception) + { + // data isn't legacy compatible. Probably new format or missing data. + } + + if (legacyFilepath != null) + { + Log.Warning("Converting Legacy Config Data."); + _configuration = Configuration.LoadConfigurationFromFile(legacyFilepath); + } + else + { + if (data.Length == 0) + { + Log.Error("Save game data is empty! Attempting reload."); + data = SerializableData.LoadData(DataId); + } + Log.Message("Loading Data from New Load Routine! Hooray."); + var memoryStream = new MemoryStream(); + memoryStream.Write(data, 0, data.Length); + memoryStream.Position = 0; - var configuration = Configuration.LoadConfigurationFromFile(filepath); + var binaryFormatter = new BinaryFormatter(); + _configuration = (Configuration) binaryFormatter.Deserialize(memoryStream); + } + ConfigLoaded = true; + } - foreach (var segment in configuration.PrioritySegments.Where(segment => !TrafficPriority.IsPrioritySegment((ushort)segment[0], - segment[1]))) + public static void LoadDataState() + { + foreach ( + var segment in + _configuration.PrioritySegments.Where(segment => !TrafficPriority.IsPrioritySegment((ushort) segment[0], + segment[1]))) { - TrafficPriority.AddPrioritySegment((ushort)segment[0], + Log.Message($"Adding Priority Segment of type: {segment[2].ToString()}"); + TrafficPriority.AddPrioritySegment((ushort) segment[0], segment[1], - (PrioritySegment.PriorityType)segment[2]); + (PrioritySegment.PriorityType) segment[2]); } - foreach (var node in configuration.NodeDictionary.Where(node => CustomRoadAI.GetNodeSimulation((ushort)node[0]) == null)) + foreach ( + var node in _configuration.NodeDictionary.Where(node => CustomRoadAI.GetNodeSimulation((ushort) node[0]) == null) + ) { - CustomRoadAI.AddNodeToSimulation((ushort)node[0]); - var nodeDict = CustomRoadAI.GetNodeSimulation((ushort)node[0]); + try + { + CustomRoadAI.AddNodeToSimulation((ushort)node[0]); + var nodeDict = CustomRoadAI.GetNodeSimulation((ushort)node[0]); - nodeDict.ManualTrafficLights = Convert.ToBoolean(node[1]); - nodeDict.TimedTrafficLights = Convert.ToBoolean(node[2]); - nodeDict.TimedTrafficLightsActive = Convert.ToBoolean(node[3]); + nodeDict.ManualTrafficLights = Convert.ToBoolean(node[1]); + nodeDict.TimedTrafficLights = Convert.ToBoolean(node[2]); + nodeDict.TimedTrafficLightsActive = Convert.ToBoolean(node[3]); + } + catch (Exception e) + { + // if we failed, just means it's old corrupt data. Ignore it and continue. + Log.Warning("Error loading data from the NodeDictionary: " + e.Message); + } } - foreach (var segmentData in configuration.ManualSegments.Where(segmentData => !TrafficLightsManual.IsSegmentLight((ushort)segmentData[0], segmentData[1]))) + foreach ( + var segmentData in + _configuration.ManualSegments.Where( + segmentData => !TrafficLightsManual.IsSegmentLight((ushort) segmentData[0], segmentData[1]))) { - TrafficLightsManual.AddSegmentLight((ushort)segmentData[0], segmentData[1], + try + { + TrafficLightsManual.AddSegmentLight((ushort)segmentData[0], segmentData[1], RoadBaseAI.TrafficLightState.Green); - var segment = TrafficLightsManual.GetSegmentLight((ushort)segmentData[0], segmentData[1]); - segment.CurrentMode = (ManualSegmentLight.Mode)segmentData[2]; - segment.LightLeft = (RoadBaseAI.TrafficLightState)segmentData[3]; - segment.LightMain = (RoadBaseAI.TrafficLightState)segmentData[4]; - segment.LightRight = (RoadBaseAI.TrafficLightState)segmentData[5]; - segment.LightPedestrian = (RoadBaseAI.TrafficLightState)segmentData[6]; - segment.LastChange = (uint)segmentData[7]; - segment.LastChangeFrame = (uint)segmentData[8]; - segment.PedestrianEnabled = Convert.ToBoolean(segmentData[9]); + var segment = TrafficLightsManual.GetSegmentLight((ushort)segmentData[0], segmentData[1]); + segment.CurrentMode = (ManualSegmentLight.Mode)segmentData[2]; + segment.LightLeft = (RoadBaseAI.TrafficLightState)segmentData[3]; + segment.LightMain = (RoadBaseAI.TrafficLightState)segmentData[4]; + segment.LightRight = (RoadBaseAI.TrafficLightState)segmentData[5]; + segment.LightPedestrian = (RoadBaseAI.TrafficLightState)segmentData[6]; + segment.LastChange = (uint)segmentData[7]; + segment.LastChangeFrame = (uint)segmentData[8]; + segment.PedestrianEnabled = Convert.ToBoolean(segmentData[9]); + } + catch (Exception e) + { + // if we failed, just means it's old corrupt data. Ignore it and continue. + Log.Warning("Error loading data from the ManualSegments: " + e.Message); + } } var timedStepCount = 0; var timedStepSegmentCount = 0; - for (var i = 0; i < configuration.TimedNodes.Count; i++) + for (var i = 0; i < _configuration.TimedNodes.Count; i++) { - var nodeid = (ushort)configuration.TimedNodes[i][0]; - - var nodeGroup = new List(); - for (var j = 0; j < configuration.TimedNodeGroups[i].Length; j++) + try { - nodeGroup.Add(configuration.TimedNodeGroups[i][j]); - } + var nodeid = (ushort)_configuration.TimedNodes[i][0]; - if (TrafficLightsTimed.IsTimedLight(nodeid)) continue; - TrafficLightsTimed.AddTimedLight(nodeid, nodeGroup); - var timedNode = TrafficLightsTimed.GetTimedLight(nodeid); + var nodeGroup = new List(); + for (var j = 0; j < _configuration.TimedNodeGroups[i].Length; j++) + { + nodeGroup.Add(_configuration.TimedNodeGroups[i][j]); + } - timedNode.CurrentStep = configuration.TimedNodes[i][1]; + if (TrafficLightsTimed.IsTimedLight(nodeid)) continue; + TrafficLightsTimed.AddTimedLight(nodeid, nodeGroup); + var timedNode = TrafficLightsTimed.GetTimedLight(nodeid); - for (var j = 0; j < configuration.TimedNodes[i][2]; j++) - { - var cfgstep = configuration.TimedNodeSteps[timedStepCount]; + timedNode.CurrentStep = _configuration.TimedNodes[i][1]; - timedNode.AddStep(cfgstep[0]); + for (var j = 0; j < _configuration.TimedNodes[i][2]; j++) + { + var cfgstep = _configuration.TimedNodeSteps[timedStepCount]; - var step = timedNode.Steps[j]; + timedNode.AddStep(cfgstep[0]); - for (var k = 0; k < cfgstep[1]; k++) - { - step.LightLeft[k] = (RoadBaseAI.TrafficLightState)configuration.TimedNodeStepSegments[timedStepSegmentCount][0]; - step.LightMain[k] = (RoadBaseAI.TrafficLightState)configuration.TimedNodeStepSegments[timedStepSegmentCount][1]; - step.LightRight[k] = (RoadBaseAI.TrafficLightState)configuration.TimedNodeStepSegments[timedStepSegmentCount][2]; - step.LightPedestrian[k] = (RoadBaseAI.TrafficLightState)configuration.TimedNodeStepSegments[timedStepSegmentCount][3]; + var step = timedNode.Steps[j]; - timedStepSegmentCount++; + for (var k = 0; k < cfgstep[1]; k++) + { + step.LightLeft[k] = + (RoadBaseAI.TrafficLightState)_configuration.TimedNodeStepSegments[timedStepSegmentCount][0]; + step.LightMain[k] = + (RoadBaseAI.TrafficLightState)_configuration.TimedNodeStepSegments[timedStepSegmentCount][1]; + step.LightRight[k] = + (RoadBaseAI.TrafficLightState)_configuration.TimedNodeStepSegments[timedStepSegmentCount][2]; + step.LightPedestrian[k] = + (RoadBaseAI.TrafficLightState)_configuration.TimedNodeStepSegments[timedStepSegmentCount][3]; + + timedStepSegmentCount++; + } + + timedStepCount++; } - timedStepCount++; + if (Convert.ToBoolean(_configuration.TimedNodes[i][3])) + { + timedNode.Start(); + } } - - if (Convert.ToBoolean(configuration.TimedNodes[i][3])) + catch (Exception e) { - timedNode.Start(); + // ignore, as it's probably corrupt save data. it'll be culled on next save + Log.Warning("Error loading data from the TimedNodes: " + e.Message); } } var j1 = 0; for (var i1 = 0; i1 < 32768; i1++) { - if (Singleton.instance.m_nodes.m_buffer[i1].Info.m_class.m_service != ItemClass.Service.Road || - Singleton.instance.m_nodes.m_buffer[i1].m_flags == 0) continue; - var trafficLight = configuration.NodeTrafficLights[j1]; - - if (trafficLight == '1') + try { - Singleton.instance.m_nodes.m_buffer[i1].m_flags |= NetNode.Flags.TrafficLights; + if (Singleton.instance.m_nodes.m_buffer[i1].Info.m_class.m_service != ItemClass.Service.Road || + Singleton.instance.m_nodes.m_buffer[i1].m_flags == 0) + continue; + var trafficLight = _configuration.NodeTrafficLights[j1]; + + if (trafficLight == '1') + { + Singleton.instance.m_nodes.m_buffer[i1].m_flags |= NetNode.Flags.TrafficLights; + } + else + { + Singleton.instance.m_nodes.m_buffer[i1].m_flags &= ~NetNode.Flags.TrafficLights; + } } - else + catch (Exception e) { - Singleton.instance.m_nodes.m_buffer[i1].m_flags &= ~NetNode.Flags.TrafficLights; + // ignore as it's probably bad save data. + Log.Warning("Error setting the NodeTrafficLights: " + e.Message); } - j1++; } var j2 = 0; for (var i2 = 0; i2 < 32768; i2++) { - if (Singleton.instance.m_nodes.m_buffer[i2].Info.m_class.m_service != ItemClass.Service.Road || - Singleton.instance.m_nodes.m_buffer[i2].m_flags == 0) continue; - var crossWalk = configuration.NodeCrosswalk[j2]; - - if (crossWalk == '1') + try { - Singleton.instance.m_nodes.m_buffer[i2].m_flags |= NetNode.Flags.Junction; + if (Singleton.instance.m_nodes.m_buffer[i2].Info.m_class.m_service != ItemClass.Service.Road || + Singleton.instance.m_nodes.m_buffer[i2].m_flags == 0) + continue; + var crossWalk = _configuration.NodeCrosswalk[j2]; + + if (crossWalk == '1') + { + Singleton.instance.m_nodes.m_buffer[i2].m_flags |= NetNode.Flags.Junction; + } + else + { + Singleton.instance.m_nodes.m_buffer[i2].m_flags &= ~NetNode.Flags.Junction; + } } - else + catch (Exception e) { - Singleton.instance.m_nodes.m_buffer[i2].m_flags &= ~NetNode.Flags.Junction; + // bad save data. ignore + Log.Warning("Error loading data from the NodeCrosswalk: " + e.Message); } - j2++; } - var lanes = configuration.LaneFlags.Split(','); + Log.Message($"LaneFlags: {_configuration.LaneFlags}"); + var lanes = _configuration.LaneFlags.Split(','); - foreach (var split in lanes.Select(lane => lane.Split(':'))) + if (lanes.Length <= 1) + return; + foreach (var split in lanes.Select(lane => lane.Split(':')).Where(split => split.Length > 1)) { + Log.Message($"Split Data: {split[0]} , {split[1]}"); Singleton.instance.m_lanes.m_buffer[Convert.ToInt32(split[0])].m_flags = Convert.ToUInt16(split[1]); } } - public void OnSaveData() + public override void OnSaveData() { - Debug.Log("Saving Mod Data."); - var data = new FastList(); - - GenerateUniqueId(); - - Debug.Log("UniqueID: " + UniqueId); - var uniqueIdBytes = BitConverter.GetBytes(UniqueId); - - foreach (var uniqueIdByte in uniqueIdBytes) - { - data.Add(uniqueIdByte); - } - - var dataToSave = data.ToArray(); - SerializableData.SaveData(DataId, dataToSave); - - var filepath = Path.Combine(Application.dataPath, "trafficManagerSave_" + UniqueId + ".xml"); - Debug.Log("Save Location: " + filepath); + Log.Message("Saving Mod Data."); var configuration = new Configuration(); for (var i = 0; i < 32768; i++) { if (TrafficPriority.PrioritySegments.ContainsKey(i)) { + if (TrafficPriority.PrioritySegments[i].Node1 != 0) { + Log.Message($"Saving Priority Segment of type: {TrafficPriority.PrioritySegments[i].Instance1.Type}"); configuration.PrioritySegments.Add(new[] { TrafficPriority.PrioritySegments[i].Node1, i, (int)TrafficPriority.PrioritySegments[i].Instance1.Type }); } if (TrafficPriority.PrioritySegments[i].Node2 != 0) { + Log.Message($"Saving Priority Segment of type: {TrafficPriority.PrioritySegments[i].Instance2.Type}"); configuration.PrioritySegments.Add(new[] { TrafficPriority.PrioritySegments[i].Node2, i, (int)TrafficPriority.PrioritySegments[i].Instance2.Type }); } } @@ -352,7 +423,27 @@ public void OnSaveData() } } - Configuration.SaveConfigurationToFile(filepath, configuration); + var binaryFormatter = new BinaryFormatter(); + var memoryStream = new MemoryStream(); + + try + { + binaryFormatter.Serialize(memoryStream, configuration); + memoryStream.Position = 0; + Log.Message($"Save data byte length {memoryStream.Length}"); + SerializableData.SaveData(DataId, memoryStream.ToArray()); + + Log.Message("Erasing old save data."); + SerializableData.SaveData(LegacyDataId, new byte[] {}); + } + catch (Exception ex) + { + Log.Error("Unexpected error saving data: " + ex.Message); + } + finally + { + memoryStream.Close(); + } } } } diff --git a/TLM/TLM/TLM.csproj b/TLM/TLM/TLM.csproj index 5af05aa9..7582261c 100644 --- a/TLM/TLM/TLM.csproj +++ b/TLM/TLM/TLM.csproj @@ -18,7 +18,7 @@ full false bin\Debug\ - DEBUG;TRACE + DEBUG prompt 4 true @@ -33,13 +33,13 @@ - ..\..\..\..\Program Files (x86)\Steam\steamapps\common\Cities_Skylines\Cities_Data\Managed\Assembly-CSharp.dll + D:\SteamGames\steamapps\common\Cities_Skylines\Cities_Data\Managed\Assembly-CSharp.dll - ..\..\..\..\Program Files (x86)\Steam\steamapps\common\Cities_Skylines\Cities_Data\Managed\ColossalManaged.dll + D:\SteamGames\steamapps\common\Cities_Skylines\Cities_Data\Managed\ColossalManaged.dll - ..\..\..\..\Program Files (x86)\Steam\steamapps\common\Cities_Skylines\Cities_Data\Managed\ICities.dll + D:\SteamGames\steamapps\common\Cities_Skylines\Cities_Data\Managed\ICities.dll ..\packages\NLog.4.0.1\lib\net35\NLog.dll @@ -47,11 +47,11 @@ - ..\..\..\..\..\..\steamapps\common\Cities_Skylines\Cities_Data\Managed\System.Core.dll + D:\SteamGames\steamapps\common\Cities_Skylines\Managed\System.Core.dll - ..\..\..\..\Program Files (x86)\Steam\steamapps\common\Cities_Skylines\Cities_Data\Managed\UnityEngine.dll + D:\SteamGames\steamapps\common\Cities_Skylines\Cities_Data\Managed\UnityEngine.dll @@ -144,7 +144,7 @@ mkdir "%25LOCALAPPDATA%25\Colossal Order\Cities_Skylines\Addons\Mods\$(SolutionName)" del "%25LOCALAPPDATA%25\Colossal Order\Cities_Skylines\Addons\Mods\$(SolutionName)\$(TargetFileName)" xcopy /y "$(TargetPath)" "%25LOCALAPPDATA%25\Colossal Order\Cities_Skylines\Addons\Mods\$(SolutionName)" -xcopy /y "$(TargetPath)" "C:\Program Files (x86)\Steam\steamapps\workshop\content\255710\481786333" +xcopy /y "$(TargetPath)" "D:\SteamGames\steamapps\workshop\content\255710\481786333" diff --git a/TLM/TLM/ThreadingExtension.cs b/TLM/TLM/ThreadingExtension.cs index 525aec7d..658d3475 100644 --- a/TLM/TLM/ThreadingExtension.cs +++ b/TLM/TLM/ThreadingExtension.cs @@ -37,7 +37,7 @@ public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) //Debug.Log("If !DetourInited"); if (!LoadingExtension.Instance.DetourInited) { - Debug.Log("Redirecting Car AI Calculate Segment Calls"); + Log.Message("Redirecting Car AI Calculate Segment Calls"); LoadingExtension.Instance.RevertMethods[0] = RedirectionHelper.RedirectCalls( typeof (CarAI).GetMethod("CalculateSegmentPosition", BindingFlags.NonPublic | BindingFlags.Instance, @@ -52,13 +52,13 @@ public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) null), typeof (CustomCarAI).GetMethod("TmCalculateSegmentPosition")); - Debug.Log("Redirecting SimulationStep"); + Log.Message("Redirecting SimulationStep"); LoadingExtension.Instance.RevertMethods[1] = RedirectionHelper.RedirectCalls( typeof (RoadBaseAI).GetMethod("SimulationStep", new[] {typeof (ushort), typeof (NetNode).MakeByRefType()}), typeof (CustomRoadAI).GetMethod("CustomSimulationStep")); - Debug.Log("Redirecting Human AI Calls"); + Log.Message("Redirecting Human AI Calls"); LoadingExtension.Instance.RevertMethods[2] = RedirectionHelper.RedirectCalls(typeof (HumanAI).GetMethod("CheckTrafficLights", BindingFlags.NonPublic | BindingFlags.Instance, @@ -69,8 +69,8 @@ public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) if (LoadingExtension.IsPathManagerCompatibile) { - Debug.Log("Traffic++ Not detected. Loading Pathfinder."); - Debug.Log("Redirecting CarAI Simulation Step Calls"); + Log.Message("Traffic++ Not detected. Loading Pathfinder."); + Log.Message("Redirecting CarAI Simulation Step Calls"); LoadingExtension.Instance.RevertMethods[3] = RedirectionHelper.RedirectCalls( typeof (CarAI).GetMethod("SimulationStep", @@ -81,21 +81,21 @@ public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) }), typeof (CustomCarAI).GetMethod("TrafficManagerSimulationStep")); - Debug.Log("Redirecting PassengerCarAI Simulation Step Calls"); + Log.Message("Redirecting PassengerCarAI Simulation Step Calls"); LoadingExtension.Instance.RevertMethods[4] = RedirectionHelper.RedirectCalls( typeof (PassengerCarAI).GetMethod("SimulationStep", new[] {typeof (ushort), typeof (Vehicle).MakeByRefType(), typeof (Vector3)}), typeof (CustomPassengerCarAI).GetMethod("CustomSimulationStep")); - Debug.Log("Redirecting CargoTruckAI Simulation Step Calls"); + Log.Message("Redirecting CargoTruckAI Simulation Step Calls"); LoadingExtension.Instance.RevertMethods[5] = RedirectionHelper.RedirectCalls( typeof (CargoTruckAI).GetMethod("SimulationStep", new[] {typeof (ushort), typeof (Vehicle).MakeByRefType(), typeof (Vector3)}), typeof (CustomCargoTruckAI).GetMethod("CustomSimulationStep")); - Debug.Log("Redirection CarAI Calculate Segment Position calls for non-Traffic++"); + Log.Message("Redirection CarAI Calculate Segment Position calls for non-Traffic++"); LoadingExtension.Instance.RevertMethods[6] = RedirectionHelper.RedirectCalls(typeof (CarAI).GetMethod("CalculateSegmentPosition", BindingFlags.NonPublic | BindingFlags.Instance, @@ -112,6 +112,9 @@ public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) } LoadingExtension.Instance.DetourInited = true; + + if (SerializableDataExtension.ConfigLoaded) + SerializableDataExtension.LoadDataState(); } if (!LoadingExtension.Instance.NodeSimulationLoaded) diff --git a/TLM/TLM/Traffic/TrafficPriority.cs b/TLM/TLM/Traffic/TrafficPriority.cs index 5b6e517f..0055c6cb 100644 --- a/TLM/TLM/Traffic/TrafficPriority.cs +++ b/TLM/TLM/Traffic/TrafficPriority.cs @@ -20,7 +20,7 @@ public static void AddPrioritySegment(ushort nodeId, int segmentId, PrioritySegm if (PrioritySegments.ContainsKey(segmentId)) { var prioritySegment = PrioritySegments[segmentId]; - + prioritySegment.Node2 = nodeId; prioritySegment.Instance2 = new PrioritySegment(nodeId, segmentId, type); } @@ -527,7 +527,7 @@ public static bool HasLeftSegment(int segmentId, ushort nodeId, bool debug = fal { if (debug) { - Debug.Log("LEFT: " + segment + " " + GetSegmentDir(segment, nodeId)); + Log.Message("LEFT: " + segment + " " + GetSegmentDir(segment, nodeId)); } return true; } @@ -550,7 +550,7 @@ public static bool HasRightSegment(int segmentId, ushort nodeId, bool debug = fa if (debug) { - Debug.Log("RIGHT: " + segment + " " + GetSegmentDir(segment, nodeId)); + Log.Message("RIGHT: " + segment + " " + GetSegmentDir(segment, nodeId)); } return true; } @@ -571,7 +571,7 @@ public static bool HasForwardSegment(int segmentId, ushort nodeId, bool debug = if (debug) { - Debug.Log("FORWARD: " + segment + " " + GetSegmentDir(segment, nodeId)); + Log.Message("FORWARD: " + segment + " " + GetSegmentDir(segment, nodeId)); } return true; } diff --git a/TLM/TLM/TrafficLight/ManualSegmentLight.cs b/TLM/TLM/TrafficLight/ManualSegmentLight.cs index 547d2cad..1e7e018f 100644 --- a/TLM/TLM/TrafficLight/ManualSegmentLight.cs +++ b/TLM/TLM/TrafficLight/ManualSegmentLight.cs @@ -220,12 +220,12 @@ public void UpdateVisuals() LightLeft == RoadBaseAI.TrafficLightState.Red && LightRight == RoadBaseAI.TrafficLightState.Red) { - Debug.Log("Changing Light with segment Id" + Segment + " and node id " + Node + " to red."); + //Debug.Log("Changing Light with segment Id" + Segment + " and node id " + Node + " to red."); vehicleLightState = RoadBaseAI.TrafficLightState.Red; } else { - Debug.Log("Changing Light with segment Id" + Segment + " and node id " + Node + " to green."); + //Debug.Log("Changing Light with segment Id" + Segment + " and node id " + Node + " to green."); vehicleLightState = RoadBaseAI.TrafficLightState.Green; } diff --git a/TLM/TLM/TrafficLight/TrafficLightTool.cs b/TLM/TLM/TrafficLight/TrafficLightTool.cs index 667f4117..f6e5c3db 100644 --- a/TLM/TLM/TrafficLight/TrafficLightTool.cs +++ b/TLM/TLM/TrafficLight/TrafficLightTool.cs @@ -447,7 +447,6 @@ protected override void OnToolUpdate() SwitchTrafficLightToolMode(node); break; case ToolMode.AddPrioritySigns: - Debug.Log("Add Priority Signs Tool Mode"); AddPrioritySignsToolMode(node); break; case ToolMode.ManualSwitch: @@ -723,7 +722,6 @@ protected override void OnToolGUI() switch (_toolMode) { case ToolMode.AddPrioritySigns: - Debug.Log("Priority Sign OnToolGUI"); _guiPrioritySigns(); break; case ToolMode.ManualSwitch: @@ -1307,7 +1305,7 @@ private bool GetHoveredSegment(Rect myRect1, int segmentId, bool hoveredSegment, if (!myRect1.Contains(Event.current.mousePosition)) return hoveredSegment; - Debug.Log("mouse in myRect1"); + Log.Message("mouse in myRect1"); _hoveredButton[0] = segmentId; _hoveredButton[1] = -1; @@ -3343,7 +3341,7 @@ private void _guiPrioritySigns() GUI.DrawTexture(nodeBoundingBox, TrafficLightToolTextureResources.SignPriorityTexture2D); if (hoveredSegment && _uiClickedSegment) { - Debug.Log("PrioritySegment.Type = Yield"); + Log.Message("PrioritySegment.Type = Yield"); prioritySegment.Type = PrioritySegment.PriorityType.Yield; } break; @@ -3363,7 +3361,7 @@ private void _guiPrioritySigns() if(hoveredSegment && _uiClickedSegment) { - Debug.Log("PrioritySegment.Type = None"); + Log.Message("PrioritySegment.Type = None"); prioritySegment.Type = GetNumberOfMainRoads(node) >= 2 ? PrioritySegment.PriorityType.Yield : PrioritySegment.PriorityType.Main; diff --git a/TLM/TLM/TrafficManagerMod.cs b/TLM/TLM/TrafficManagerMod.cs index 903e9795..22ea170a 100644 --- a/TLM/TLM/TrafficManagerMod.cs +++ b/TLM/TLM/TrafficManagerMod.cs @@ -11,12 +11,12 @@ public class TrafficManagerMod : IUserMod public void OnEnabled() { - Debug.Log("TrafficManagerMod Enabled"); + Log.Message("TrafficManagerMod Enabled"); } public void OnDisabled() { - Debug.Log("TrafficManagerMod Disabled"); + Log.Message("TrafficManagerMod Disabled"); } } } diff --git a/TLM/TLM/UI/UITrafficManager.cs b/TLM/TLM/UI/UITrafficManager.cs index 76f9b405..d850b39d 100644 --- a/TLM/TLM/UI/UITrafficManager.cs +++ b/TLM/TLM/UI/UITrafficManager.cs @@ -134,7 +134,7 @@ private void clickSwitchTraffic(UIComponent component, UIMouseEventParameter eve private void clickAddPrioritySigns(UIComponent component, UIMouseEventParameter eventParam) { - Debug.Log("Priority Sign Clicked."); + Log.Message("Priority Sign Clicked."); if (_uiState != UIState.AddStopSign) { _uiState = UIState.AddStopSign;