diff --git a/NodeControllerRenewal/Manager/Extensions/SerializableDataExtension.cs b/NodeControllerRenewal/Manager/Extensions/SerializableDataExtension.cs index 09157295..2441c30d 100644 --- a/NodeControllerRenewal/Manager/Extensions/SerializableDataExtension.cs +++ b/NodeControllerRenewal/Manager/Extensions/SerializableDataExtension.cs @@ -31,7 +31,7 @@ public override void OnLoadData() SingletonMod.Logger.Debug($"Import NC2 data"); WasImported = true; - var state = BackwardÑompatibility.Loader.Load(data); + var state = BackwardCompatibility.Loader.Load(data); var config = state.ToXml(); SetLoadData(config); } diff --git a/NodeControllerRenewal/Manager/SegmentEndData.cs b/NodeControllerRenewal/Manager/SegmentEndData.cs index 9cf328d7..fe3eed34 100644 --- a/NodeControllerRenewal/Manager/SegmentEndData.cs +++ b/NodeControllerRenewal/Manager/SegmentEndData.cs @@ -765,7 +765,7 @@ public void Render(OverlayData contourData, OverlayData outterData, OverlayData { var data = SingletonManager.Instance[NodeId]; - RenderÑontour(contourData); + RenderContour(contourData); if (data.IsMoveableEnds && IsChangeable) { RenderEnd(contourData, LengthXZ(LeftSide.Position - Position) + CircleRadius, 0f); @@ -788,7 +788,7 @@ public void Render(OverlayData contourData, OverlayData outterData, OverlayData } public void RenderAlign(OverlayData contourData, OverlayData? leftData = null, OverlayData? rightData = null) { - RenderÑontour(contourData); + RenderContour(contourData); RenderEnd(contourData); if (leftData != null) @@ -813,7 +813,7 @@ public void RenderEnd(OverlayData data, float? leftCut = null, float? rightCut = line = line.Cut(startT, 1 - endT); line.Render(data); } - public void RenderÑontour(OverlayData data) + public void RenderContour(OverlayData data) { RenderSide(LeftSide, data); RenderSide(RightSide, data); diff --git a/NodeControllerRenewal/Mod.cs b/NodeControllerRenewal/Mod.cs index 452fc4aa..d526f9e9 100644 --- a/NodeControllerRenewal/Mod.cs +++ b/NodeControllerRenewal/Mod.cs @@ -335,13 +335,12 @@ private void PatchHideCrosswalk(ref bool success) private void PatchTMPE(ref bool success) { + var jrHook = TrafficManager.API.Implementations.HookFactory.JunctionRestrictionsHook; + + jrHook.GetConfigurableHook += ExternalModPatches.GetConfigurableHook; + jrHook.GetDefaultsHook += ExternalModPatches.GetDefaultsHook; + success &= Patch_TrafficLightManager_CanToggleTrafficLight(); - success &= Patch_JunctionRestrictionsManager_GetDefaultEnteringBlockedJunctionAllowed(); - success &= Patch_JunctionRestrictionsManager_GetDefaultPedestrianCrossingAllowed(); - success &= Patch_JunctionRestrictionsManager_GetDefaultUturnAllowed(); - success &= Patch_JunctionRestrictionsManager_IsEnteringBlockedJunctionAllowedConfigurable(); - success &= Patch_JunctionRestrictionsManager_IsPedestrianCrossingAllowedConfigurable(); - success &= Patch_JunctionRestrictionsManager_IsUturnAllowedConfigurable(); if ((Type.GetType("TrafficManager.TrafficManagerMod") ?? Type.GetType("TrafficManager.Lifecycle.TrafficManagerMod")) is Type tmpeMod) { @@ -360,30 +359,6 @@ private bool Patch_TrafficLightManager_CanToggleTrafficLight() { return AddPrefix(typeof(ExternalModPatches), nameof(ExternalModPatches.CanToggleTrafficLightPrefix), typeof(TrafficLightManager), nameof(TrafficLightManager.CanToggleTrafficLight)); } - private bool Patch_JunctionRestrictionsManager_GetDefaultEnteringBlockedJunctionAllowed() - { - return AddPrefix(typeof(ExternalModPatches), nameof(ExternalModPatches.GetDefaultEnteringBlockedJunctionAllowedPrefix), typeof(JunctionRestrictionsManager), nameof(JunctionRestrictionsManager.GetDefaultEnteringBlockedJunctionAllowed)); - } - private bool Patch_JunctionRestrictionsManager_GetDefaultPedestrianCrossingAllowed() - { - return AddPrefix(typeof(ExternalModPatches), nameof(ExternalModPatches.GetDefaultPedestrianCrossingAllowedPrefix), typeof(JunctionRestrictionsManager), nameof(JunctionRestrictionsManager.GetDefaultPedestrianCrossingAllowed)); - } - private bool Patch_JunctionRestrictionsManager_GetDefaultUturnAllowed() - { - return AddPrefix(typeof(ExternalModPatches), nameof(ExternalModPatches.GetDefaultUturnAllowedPrefix), typeof(JunctionRestrictionsManager), nameof(JunctionRestrictionsManager.GetDefaultUturnAllowed)); - } - private bool Patch_JunctionRestrictionsManager_IsEnteringBlockedJunctionAllowedConfigurable() - { - return AddPrefix(typeof(ExternalModPatches), nameof(ExternalModPatches.IsEnteringBlockedJunctionAllowedConfigurablePrefix), typeof(JunctionRestrictionsManager), nameof(JunctionRestrictionsManager.IsEnteringBlockedJunctionAllowedConfigurable)); - } - private bool Patch_JunctionRestrictionsManager_IsPedestrianCrossingAllowedConfigurable() - { - return AddPrefix(typeof(ExternalModPatches), nameof(ExternalModPatches.IsPedestrianCrossingAllowedConfigurablePrefix), typeof(JunctionRestrictionsManager), nameof(JunctionRestrictionsManager.IsPedestrianCrossingAllowedConfigurable)); - } - private bool Patch_JunctionRestrictionsManager_IsUturnAllowedConfigurable() - { - return AddPrefix(typeof(ExternalModPatches), nameof(ExternalModPatches.IsUturnAllowedConfigurablePrefix), typeof(JunctionRestrictionsManager), nameof(JunctionRestrictionsManager.IsUturnAllowedConfigurable)); - } #endregion diff --git a/NodeControllerRenewal/NodeControllerRenewal.csproj b/NodeControllerRenewal/NodeControllerRenewal.csproj index 2d3ac6f3..515f2a3e 100644 --- a/NodeControllerRenewal/NodeControllerRenewal.csproj +++ b/NodeControllerRenewal/NodeControllerRenewal.csproj @@ -131,7 +131,7 @@ - + @@ -254,7 +254,7 @@ - + diff --git a/NodeControllerRenewal/Patches/ExternalModPatches.cs b/NodeControllerRenewal/Patches/ExternalModPatches.cs index dbb23227..a44c5abb 100644 --- a/NodeControllerRenewal/Patches/ExternalModPatches.cs +++ b/NodeControllerRenewal/Patches/ExternalModPatches.cs @@ -1,12 +1,52 @@ using ColossalFramework; using ModsCommon; using ModsCommon.Utilities; +using System; using TrafficManager.API.Traffic.Enums; +using static TrafficManager.API.Hook.IJunctionRestrictionsHook; namespace NodeController.Patches { public static class ExternalModPatches { + public static void UpdateFlag(FlagsHookArgs args, JunctionRestrictionsFlags flag, Func func) + { + if (args.Mask.IsFlagSet(flag)) + { + var value = func(); + if (value.HasValue) + args.Result = args.Result.SetFlags(flag, value.Value); + } + } + + public static void GetConfigurableHook(FlagsHookArgs args) + { + ushort nodeID = args.StartNode ? args.SegmentId.GetSegment().m_startNode : args.SegmentId.GetSegment().m_endNode; + var node = SingletonManager.Instance[nodeID]; + + if (node == null) + UpdateFlag(args, JunctionRestrictionsFlags.AllowEnterWhenBlocked, () => IsEnteringBlockedJunctionAllowedConfigurable(args.SegmentId, nodeID)); + else + { + UpdateFlag(args, JunctionRestrictionsFlags.AllowUTurn, () => IsUturnAllowedConfigurable(node)); + UpdateFlag(args, JunctionRestrictionsFlags.AllowPedestrianCrossing, () => IsPedestrianCrossingAllowedConfigurable(node)); + UpdateFlag(args, JunctionRestrictionsFlags.AllowEnterWhenBlocked, () => IsEnteringBlockedJunctionAllowedConfigurable(node)); + } + } + + public static void GetDefaultsHook(FlagsHookArgs args) + { + ushort nodeID = args.StartNode ? args.SegmentId.GetSegment().m_startNode : args.SegmentId.GetSegment().m_endNode; + var node = SingletonManager.Instance[nodeID]; + + if (node != null) + { + UpdateFlag(args, JunctionRestrictionsFlags.AllowUTurn, () => IsDefaultUturnAllowed(node)); + UpdateFlag(args, JunctionRestrictionsFlags.AllowPedestrianCrossing, () => IsDefaultPedestrianCrossingAllowed(node)); + UpdateFlag(args, JunctionRestrictionsFlags.AllowEnterWhenBlocked, () => IsDefaultEnteringBlockedJunctionAllowed(node)); + } + } + private static bool? IsUturnAllowedConfigurable(NodeData node) => node?.Type switch { NodeStyleType.Crossing or NodeStyleType.Stretch or NodeStyleType.Middle or NodeStyleType.Bend => false,// always off @@ -64,52 +104,14 @@ public static bool CanToggleTrafficLightPrefix(ref bool __result, ushort nodeId, var nodeData = SingletonManager.Instance[nodeId]; return HandleNullBool(CanHaveTrafficLights(nodeData, out reason), ref __result); } - public static bool GetDefaultEnteringBlockedJunctionAllowedPrefix(ushort segmentId, bool startNode, ref bool __result) - { - ushort nodeID = startNode ? segmentId.GetSegment().m_startNode : segmentId.GetSegment().m_endNode; - var data = SingletonManager.Instance[nodeID]; - return HandleNullBool(IsDefaultEnteringBlockedJunctionAllowed(data), ref __result); - } - public static bool GetDefaultPedestrianCrossingAllowedPrefix(ushort segmentId, bool startNode, ref bool __result) - { - ushort nodeID = startNode ? segmentId.GetSegment().m_startNode : segmentId.GetSegment().m_endNode; - NodeData data = SingletonManager.Instance[nodeID]; - return HandleNullBool(IsDefaultPedestrianCrossingAllowed(data), ref __result); - } - public static bool GetDefaultUturnAllowedPrefix(ushort segmentId, bool startNode, ref bool __result) - { - ushort nodeID = startNode ? segmentId.GetSegment().m_startNode : segmentId.GetSegment().m_endNode; - var data = SingletonManager.Instance[nodeID]; - return HandleNullBool(IsDefaultUturnAllowed(data), ref __result); - } - public static bool IsEnteringBlockedJunctionAllowedConfigurablePrefix(ushort segmentId, bool startNode, ref bool __result) - { - ushort nodeID = startNode ? segmentId.GetSegment().m_startNode : segmentId.GetSegment().m_endNode; - var data = SingletonManager.Instance[nodeID]; - if (data == null) - { - var flags = nodeID.GetNode().m_flags; - bool oneway = flags.IsFlagSet(NetNode.Flags.OneWayIn) & flags.IsFlagSet(NetNode.Flags.OneWayOut); - if (oneway & !segmentId.GetSegment().Info.m_hasPedestrianLanes) - { - __result = false; - return false; - } - } - return HandleNullBool(IsEnteringBlockedJunctionAllowedConfigurable(data), ref __result); - } - public static bool IsPedestrianCrossingAllowedConfigurablePrefix(ushort segmentId, bool startNode, ref bool __result) - { - ushort nodeID = startNode ? segmentId.GetSegment().m_startNode : segmentId.GetSegment().m_endNode; - var data = SingletonManager.Instance[nodeID]; - return HandleNullBool(IsPedestrianCrossingAllowedConfigurable(data), ref __result); - } - public static bool IsUturnAllowedConfigurablePrefix(ushort segmentId, bool startNode, ref bool __result) + private static bool? IsEnteringBlockedJunctionAllowedConfigurable(ushort segmentId, ushort nodeID) { - ushort nodeID = startNode ? segmentId.GetSegment().m_startNode : segmentId.GetSegment().m_endNode; - var data = SingletonManager.Instance[nodeID]; - return HandleNullBool(IsUturnAllowedConfigurable(data), ref __result); + var flags = nodeID.GetNode().m_flags; + bool oneway = flags.IsFlagSet(NetNode.Flags.OneWayIn) & flags.IsFlagSet(NetNode.Flags.OneWayOut); + return oneway && !segmentId.GetSegment().Info.m_hasPedestrianLanes + ? true + : null; } public static bool ShouldHideCrossingPrefix(ushort nodeID, ushort segmentID, ref bool __result) diff --git a/NodeControllerRenewal/ToolModes/AlignSegmentEnds.cs b/NodeControllerRenewal/ToolModes/AlignSegmentEnds.cs index 035757ed..81d7ef0e 100644 --- a/NodeControllerRenewal/ToolModes/AlignSegmentEnds.cs +++ b/NodeControllerRenewal/ToolModes/AlignSegmentEnds.cs @@ -167,7 +167,7 @@ public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) foreach (var segmentData in Tool.Data.SegmentEndDatas) { var defaultColor = new OverlayData(cameraInfo) { Color = segmentData.OverlayColor, RenderLimit = underground }; - segmentData.RenderСontour(defaultColor); + segmentData.RenderContour(defaultColor); segmentData.RenderEnd(defaultColor); } diff --git a/NodeControllerRenewal/ToolModes/DragCorner.cs b/NodeControllerRenewal/ToolModes/DragCorner.cs index 334a6a42..472bf48e 100644 --- a/NodeControllerRenewal/ToolModes/DragCorner.cs +++ b/NodeControllerRenewal/ToolModes/DragCorner.cs @@ -50,7 +50,7 @@ public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) var forbidden = new OverlayData(cameraInfo) { Color = Colors.Red, RenderLimit = underground }; SegmentEnd[Corner].Render(allow, forbidden, allow); - SegmentEnd.RenderСontour(new OverlayData(cameraInfo) { Color = SegmentEnd.OverlayColor, RenderLimit = underground }); + SegmentEnd.RenderContour(new OverlayData(cameraInfo) { Color = SegmentEnd.OverlayColor, RenderLimit = underground }); SegmentEnd.RenderEnd(new OverlayData(cameraInfo) { Color = SegmentEnd.OverlayColor, RenderLimit = underground }); SegmentEnd[Corner].RenderCircle(new OverlayData(cameraInfo) { Color = Colors.Yellow, RenderLimit = underground }); } diff --git "a/NodeControllerRenewal/Utilities/Backward\320\241ompatibility.cs" b/NodeControllerRenewal/Utilities/BackwardCompatibility.cs similarity index 99% rename from "NodeControllerRenewal/Utilities/Backward\320\241ompatibility.cs" rename to NodeControllerRenewal/Utilities/BackwardCompatibility.cs index f8bd381f..5aca16ec 100644 --- "a/NodeControllerRenewal/Utilities/Backward\320\241ompatibility.cs" +++ b/NodeControllerRenewal/Utilities/BackwardCompatibility.cs @@ -10,7 +10,7 @@ using System.Xml.Linq; using UnityEngine; -namespace NodeController.BackwardСompatibility +namespace NodeController.BackwardCompatibility { public static class Loader {