From 710028f571114a364e5ced5274f691d6b26eb9d8 Mon Sep 17 00:00:00 2001 From: kianzarrin Date: Fri, 9 Oct 2020 16:36:22 +0300 Subject: [PATCH] no double crossing policy (#1003) #936: no double-crossing policy --- .../Impl/JunctionRestrictionsManager.cs | 39 +++++++++++++++++++ TLM/TLM/Manager/Impl/OptionsManager.cs | 35 +++++++++-------- TLM/TLM/Resources/Translations/Options.csv | 1 + TLM/TLM/State/Options.cs | 1 + .../OptionsVehicleRestrictionsTab.cs | 11 ++++++ TLM/TLM/UI/Helpers/CheckboxOption.cs | 4 ++ TLM/TLM/Util/PriorityRoad.cs | 5 ++- TLM/TLM/Util/Shortcuts.cs | 10 ++--- 8 files changed, 84 insertions(+), 22 deletions(-) diff --git a/TLM/TLM/Manager/Impl/JunctionRestrictionsManager.cs b/TLM/TLM/Manager/Impl/JunctionRestrictionsManager.cs index 51e6ec811..026137bf2 100644 --- a/TLM/TLM/Manager/Impl/JunctionRestrictionsManager.cs +++ b/TLM/TLM/Manager/Impl/JunctionRestrictionsManager.cs @@ -668,6 +668,45 @@ public bool GetDefaultPedestrianCrossingAllowed(ushort segmentId, bool startNode return true; } + if (OptionsVehicleRestrictionsTab.NoDoubleCrossings && + node.m_flags.IsFlagSet(NetNode.Flags.Junction) && + !node.m_flags.IsFlagSet(NetNode.Flags.Untouchable) && + node.CountSegments() == 2) { + + // there are only two segments so left segment is the same as right. + ushort otherSegmentID = startNode + ? segmentId.ToSegment().m_startLeftSegment + : segmentId.ToSegment().m_endLeftSegment; + + NetInfo info1 = segmentId.ToSegment().Info; + NetInfo info2 = otherSegmentID.ToSegment().Info; + bool hasPedestrianLanes1 = info1.m_hasPedestrianLanes; + bool hasPedestrianLanes2 = info2.m_hasPedestrianLanes; + + // if only one of them has pedestrian lane then + // only the segment with pedestrian lanes need crossings + // also if neither have pedestrian lanes then none need crossing. + if (!hasPedestrianLanes1) + return false; + if (!hasPedestrianLanes2) + return true; + + float sizeDiff = info1.m_halfWidth - info2.m_halfWidth; + if (sizeDiff == 0) + return true; //if same size then both will get crossings. + + // at bridge/tunnel entracnes, pedestrian crossing is on ground road. + bool isRoad1 = info1.m_netAI is RoadAI; + bool isRoad2 = info2.m_netAI is RoadAI; + if (isRoad1 && !isRoad2) + return true; // only this segment needs pedestrian crossing. + if (isRoad2 && !isRoad1) + return false; // only the other segment needs pedestrian crossing. + + if (sizeDiff > 0) + return false; // only the smaller segment needs pedestrian crossing. + } + // crossing is allowed at junctions and at untouchable nodes (for example: spiral // underground parking) bool ret = (node.m_flags & (NetNode.Flags.Junction | NetNode.Flags.Untouchable)) != diff --git a/TLM/TLM/Manager/Impl/OptionsManager.cs b/TLM/TLM/Manager/Impl/OptionsManager.cs index 6126829b0..bafa2c760 100644 --- a/TLM/TLM/Manager/Impl/OptionsManager.cs +++ b/TLM/TLM/Manager/Impl/OptionsManager.cs @@ -240,6 +240,7 @@ int LoadBool(int idx, ILegacySerializableOption opt) { index = LoadBool(index, OptionsMassEditTab.RoundAboutQuickFix_ParkingBanMainR); index = LoadBool(index, OptionsMassEditTab.RoundAboutQuickFix_ParkingBanYieldR); + index = LoadBool(index, OptionsVehicleRestrictionsTab.NoDoubleCrossings); return true; } @@ -288,22 +289,24 @@ public byte[] SaveData(ref bool success) { (byte)(Options.allowFarTurnOnRed ? 1 : 0), (byte)(Options.automaticallyAddTrafficLightsIfApplicable ? 1 : 0), - (byte)(OptionsMassEditTab.RoundAboutQuickFix_StayInLaneMainR.Save()), - (byte)(OptionsMassEditTab.RoundAboutQuickFix_StayInLaneNearRabout.Save()), - (byte)(OptionsMassEditTab.RoundAboutQuickFix_DedicatedExitLanes.Save()), - (byte)(OptionsMassEditTab.RoundAboutQuickFix_NoCrossMainR.Save()), - (byte)(OptionsMassEditTab.RoundAboutQuickFix_NoCrossYieldR.Save()), - (byte)(OptionsMassEditTab.RoundAboutQuickFix_PrioritySigns.Save()), - - (byte)(OptionsMassEditTab.PriorityRoad_CrossMainR.Save()), - (byte)(OptionsMassEditTab.PriorityRoad_AllowLeftTurns.Save()), - (byte)(OptionsMassEditTab.PriorityRoad_EnterBlockedYeild.Save()), - (byte)(OptionsMassEditTab.PriorityRoad_StopAtEntry.Save()), - - (byte)(OptionsMassEditTab.RoundAboutQuickFix_KeepClearYieldR.Save()), - (byte)(OptionsMassEditTab.RoundAboutQuickFix_RealisticSpeedLimits.Save()), - (byte)(OptionsMassEditTab.RoundAboutQuickFix_ParkingBanMainR.Save()), - (byte)(OptionsMassEditTab.RoundAboutQuickFix_ParkingBanYieldR.Save()), + OptionsMassEditTab.RoundAboutQuickFix_StayInLaneMainR.Save(), + OptionsMassEditTab.RoundAboutQuickFix_StayInLaneNearRabout.Save(), + OptionsMassEditTab.RoundAboutQuickFix_DedicatedExitLanes.Save(), + OptionsMassEditTab.RoundAboutQuickFix_NoCrossMainR.Save(), + OptionsMassEditTab.RoundAboutQuickFix_NoCrossYieldR.Save(), + OptionsMassEditTab.RoundAboutQuickFix_PrioritySigns.Save(), + + OptionsMassEditTab.PriorityRoad_CrossMainR.Save(), + OptionsMassEditTab.PriorityRoad_AllowLeftTurns.Save(), + OptionsMassEditTab.PriorityRoad_EnterBlockedYeild.Save(), + OptionsMassEditTab.PriorityRoad_StopAtEntry.Save(), + + OptionsMassEditTab.RoundAboutQuickFix_KeepClearYieldR.Save(), + OptionsMassEditTab.RoundAboutQuickFix_RealisticSpeedLimits.Save(), + OptionsMassEditTab.RoundAboutQuickFix_ParkingBanMainR.Save(), + OptionsMassEditTab.RoundAboutQuickFix_ParkingBanYieldR.Save(), + + OptionsVehicleRestrictionsTab.NoDoubleCrossings.Save(), }; } } diff --git a/TLM/TLM/Resources/Translations/Options.csv b/TLM/TLM/Resources/Translations/Options.csv index e4f8f2032..a72896a69 100644 --- a/TLM/TLM/Resources/Translations/Options.csv +++ b/TLM/TLM/Resources/Translations/Options.csv @@ -163,3 +163,4 @@ This option is only for the purpose of adding realism to the game. ","","","","" This option is only for the purpose of adding realism to the game. ","","","","","" "Roundabout.Option:Put parking ban inside roundabouts","","Put parking ban inside roundabouts","","","","","","","","","","","","","Put parking ban inside roundabouts","","","","","" "Roundabout.Option:Put parking ban on roundabout branches","","Put parking bans on roundabout branches","","","","","","","","","","","","","Put parking bans on roundabout branches","","","","","" +"VR.Option:No double crossings","","at a segment to segment transition, only the smaller segment gets crossings.","","","","","","","","","","","","","at a segment to segment transition, only the smaller segment gets crossings.","","","","","","","" diff --git a/TLM/TLM/State/Options.cs b/TLM/TLM/State/Options.cs index 88aa75074..a981ea7ea 100644 --- a/TLM/TLM/State/Options.cs +++ b/TLM/TLM/State/Options.cs @@ -71,6 +71,7 @@ public class Options : MonoBehaviour { public static byte altLaneSelectionRatio; public static bool highwayRules; public static bool automaticallyAddTrafficLightsIfApplicable = true; + public static bool NoDoubleCrossings = false; #if DEBUG public static bool showLanes = true; #else diff --git a/TLM/TLM/State/OptionsTabs/OptionsVehicleRestrictionsTab.cs b/TLM/TLM/State/OptionsTabs/OptionsVehicleRestrictionsTab.cs index aa132d68d..782e3153e 100644 --- a/TLM/TLM/State/OptionsTabs/OptionsVehicleRestrictionsTab.cs +++ b/TLM/TLM/State/OptionsTabs/OptionsVehicleRestrictionsTab.cs @@ -24,6 +24,15 @@ public static class OptionsVehicleRestrictionsTab { private static UICheckBox _preferOuterLaneToggle; private static UICheckBox _evacBussesMayIgnoreRulesToggle; + public static CheckboxOption NoDoubleCrossings = + new CheckboxOption("NoDoubleCrossings") { + Label = "VR.Option:No double crossings", // at a segment to segment transition, only the smaller segment gets crossings + Handler = JunctionRestrictionsUpdateHandler, + }; + + static void JunctionRestrictionsUpdateHandler(bool value ) => + JunctionRestrictionsManager.Instance.UpdateAllDefaults(); + internal static void MakeSettings_VehicleRestrictions(ExtUITabstrip tabStrip) { UIHelper panelHelper = tabStrip.AddTabPage(Translation.Options.Get("Tab:Policies & Restrictions")); UIHelperBase atJunctionsGroup = panelHelper.AddGroup( @@ -120,6 +129,8 @@ internal static void MakeSettings_VehicleRestrictions(ExtUITabstrip tabStrip) { OnEvacBussesMayIgnoreRulesChanged) as UICheckBox; } + NoDoubleCrossings.AddUI(onRoadsGroup); + OptionsMassEditTab.MakePanel_MassEdit(panelHelper); } diff --git a/TLM/TLM/UI/Helpers/CheckboxOption.cs b/TLM/TLM/UI/Helpers/CheckboxOption.cs index ec081e826..e0e3a8694 100644 --- a/TLM/TLM/UI/Helpers/CheckboxOption.cs +++ b/TLM/TLM/UI/Helpers/CheckboxOption.cs @@ -9,6 +9,10 @@ public CheckboxOption(string fieldName) : base(fieldName) { public event ICities.OnCheckChanged OnValueChanged; + public OnCheckChanged Handler { + set => OnValueChanged += value; + } + public override bool Value { get => base.Value; set { diff --git a/TLM/TLM/Util/PriorityRoad.cs b/TLM/TLM/Util/PriorityRoad.cs index 5acdbae8b..9fae23f5a 100644 --- a/TLM/TLM/Util/PriorityRoad.cs +++ b/TLM/TLM/Util/PriorityRoad.cs @@ -577,10 +577,13 @@ private static void FixMinorSegmentLanes(ushort segmentId, ushort nodeId, List + /// returns a posetive value if seg1Id < seg2Id + /// internal static int CompareSegments(ushort seg1Id, ushort seg2Id) { ref NetSegment seg1 = ref GetSeg(seg1Id); ref NetSegment seg2 = ref GetSeg(seg2Id); - int diff = (int)Math.Ceiling(seg2.Info.m_halfWidth - seg1.Info.m_halfWidth); + int diff = (int)Mathf.RoundToInt(seg2.Info.m_halfWidth - seg1.Info.m_halfWidth); if (diff == 0) { diff = CountRoadVehicleLanes(seg2Id) - CountRoadVehicleLanes(seg1Id); } diff --git a/TLM/TLM/Util/Shortcuts.cs b/TLM/TLM/Util/Shortcuts.cs index 1aa94610b..a644996e4 100644 --- a/TLM/TLM/Util/Shortcuts.cs +++ b/TLM/TLM/Util/Shortcuts.cs @@ -42,11 +42,11 @@ internal static void Swap(this List list, int index1, int index2) { list[index2] = temp; } - private static NetNode[] _nodeBuffer => Singleton.instance.m_nodes.m_buffer; + private static NetNode[] _nodeBuffer = Singleton.instance.m_nodes.m_buffer; - private static NetSegment[] _segBuffer => Singleton.instance.m_segments.m_buffer; + private static NetSegment[] _segBuffer = Singleton.instance.m_segments.m_buffer; - private static NetLane[] _laneBuffer => Singleton.instance.m_lanes.m_buffer; + private static NetLane[] _laneBuffer = Singleton.instance.m_lanes.m_buffer; private static ExtSegmentEnd[] _segEndBuff => segEndMan.ExtSegmentEnds; @@ -58,13 +58,13 @@ internal static void Swap(this List list, int index1, int index2) { internal static ref NetNode GetNode(ushort nodeId) => ref _nodeBuffer[nodeId]; - internal static ref NetNode ToNode(this ushort nodeId) => ref GetNode(nodeId); + internal static ref NetNode ToNode(this ushort nodeId) => ref _nodeBuffer[nodeId]; internal static ref NetLane ToLane(this uint laneId) => ref _laneBuffer[laneId]; internal static ref NetSegment GetSeg(ushort segmentId) => ref _segBuffer[segmentId]; - internal static ref NetSegment ToSegment(this ushort segmentId) => ref GetSeg(segmentId); + internal static ref NetSegment ToSegment(this ushort segmentId) => ref _segBuffer[segmentId]; internal static NetInfo.Lane GetLaneInfo(ushort segmentId, int laneIndex) => segmentId.ToSegment().Info.m_lanes[laneIndex];