Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clear all node rules #1668

Merged
merged 8 commits into from
Oct 28, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions TLM/TLM/Manager/Impl/JunctionRestrictionsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,19 @@ public bool ClearSegmentEnd(ushort segmentId, bool startNode) {
return ret;
}

public bool ClearNode(ushort nodeId) {
bool ret = false;
ref NetNode node = ref nodeId.ToNode();
for (int segmentIndex = 0; segmentIndex < Constants.MAX_SEGMENTS_OF_NODE; ++segmentIndex) {
ushort segmentId = node.GetSegment(segmentIndex);
if (segmentId != 0) {
bool startNode = segmentId.ToSegment().IsStartNode(nodeId);
ret |= ClearSegmentEnd(segmentId, startNode);
}
}
return ret;
}

private void SetSegmentJunctionRestrictions(ushort segmentId, bool startNode, JunctionRestrictions restrictions) {
if (restrictions.HasValue(JunctionRestrictionFlags.AllowUTurn)) {
SetUturnAllowed(segmentId, startNode, restrictions.GetValueOrDefault(JunctionRestrictionFlags.AllowUTurn));
Expand Down
30 changes: 30 additions & 0 deletions TLM/TLM/Manager/Impl/TrafficLightManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace TrafficManager.Manager.Impl {
using TrafficManager.Util.Extensions;
using ColossalFramework;
using TrafficManager.TrafficLight.Impl;
using TrafficManager.API.Traffic.Data;

/// <summary>
/// Manages traffic light toggling
Expand Down Expand Up @@ -129,6 +130,35 @@ public bool ToggleTrafficLight(ushort nodeId, ref NetNode node, out ToggleTraffi
return SetTrafficLight(nodeId, !HasTrafficLight(nodeId, ref node), ref node, out reason);
}

public void ResetTrafficLightAndPrioritySignsFromNode(ushort nodeId) {
if (!Shortcuts.InSimulationThread()) {
SimulationManager.instance.AddAction(() => ResetTrafficLightAndPrioritySignsFromNode(nodeId));
return;
}

ref NetNode netNode = ref nodeId.ToNode();
if (!netNode.IsValid())
return;
if (netNode.m_flags.IsFlagSet(NetNode.Flags.CustomTrafficLights) &&
(this as ITrafficLightManager).CanToggleTrafficLight(nodeId)) {
TrafficPriorityManager.Instance.RemovePrioritySignsFromNode(nodeId);

// if CustomTrafficLights is not set, UpdateNodeFlags() resets traffic lights.
netNode.m_flags &= ~NetNode.Flags.CustomTrafficLights;
NetManager.instance.UpdateNodeFlags(nodeId);

Constants.ManagerFactory.GeometryManager.MarkAsUpdated(nodeId, true);
Notifier.Instance.OnNodeModified(nodeId, this);
}
}

public bool? GetHasTrafficLight(ushort nodeId) {
NetNode.Flags flags = nodeId.ToNode().m_flags;
return flags.IsFlagSet(NetNode.Flags.CustomTrafficLights)
? HasTrafficLight(nodeId)
: null;
}

bool ITrafficLightManager.CanToggleTrafficLight(ushort nodeId) {
ref NetNode netNode = ref nodeId.ToNode();
return netNode.IsValid() &&
Expand Down
8 changes: 0 additions & 8 deletions TLM/TLM/UI/MainMenu/OSD/OnscreenDisplay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,6 @@ private static void Hide() {
}
}

/// <summary>Clear the OSD panel and display the idle hint.</summary>
public static void DisplayIdle() {
var items = new List<OsdItem>();
items.Add(new MainMenu.OSD.Label(
localizedText: Translation.Menu.Get("Onscreen.Idle:Choose a tool")));
Display(items);
}

/// <summary>
/// On Screen Display feature:
/// Clear, and hide the keybind panel.
Expand Down
21 changes: 3 additions & 18 deletions TLM/TLM/UI/RoadSelectionPanels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ internal void UpdateMassEditOverlay() {
if (tool && tool.GetToolMode() == ToolMode.None) {
if (!UI.SubTools.PrioritySigns.MassEditOverlay.IsActive) {
if (ShouldShowMassEditOverlay()) {
ShowMassEditOverlay();
RoadSelectionUtil.ShowMassEditOverlay();
}
} else {
if (!ShouldShowMassEditOverlay()) {
Expand Down Expand Up @@ -236,21 +236,6 @@ private void HideRoadAdjustPanelElements(UIPanel roadAdjustPanel) {
roadSelectSprite.isVisible = false;
}

/// <summary>
/// Enables and refreshes overlay for various traffic rules influenced by road selection panel.
/// </summary>
private void ShowMassEditOverlay() {
var tmTool = ModUI.GetTrafficManagerTool();
if (tmTool == null) {
Log.Error("ModUI.GetTrafficManagerTool() returned null");
return;
}
UI.SubTools.PrioritySigns.MassEditOverlay.Show = true;
tmTool.SetToolMode(ToolMode.None);
tmTool.InitializeSubTools();
Log._Debug("Mass edit overlay enabled");
}

private void HideMassEditOverlay() {
UI.SubTools.PrioritySigns.MassEditOverlay.Show = false;
Log._Debug("Mass edit overlay disabled");
Expand Down Expand Up @@ -452,11 +437,11 @@ protected override void OnClick(UIMouseEventParameter p) {
if (!IsActive()) {
Root.Function = this.Function;
Root.Record = Do();
Root.EnqueueAction(Root.ShowMassEditOverlay);
Root.EnqueueAction(RoadSelectionUtil.ShowMassEditOverlay);
} else {
Root.Function = FunctionModes.None;
Undo();
Root.EnqueueAction(Root.ShowMassEditOverlay);
Root.EnqueueAction(RoadSelectionUtil.ShowMassEditOverlay);
}
}
#endregion
Expand Down
12 changes: 2 additions & 10 deletions TLM/TLM/UI/SubTools/JunctionRestrictionsTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,9 @@ public JunctionRestrictionsTool(TrafficManagerTool mainTool)

public override void OnToolGUI(Event e) {
// handle delete
// TODO: #568 provide unified delete key for all managers.
if (KeybindSettingsBase.RestoreDefaultsKey.KeyDown(e)) {
ref NetNode node = ref SelectedNodeId.ToNode();

for (int segmentIndex = 0; segmentIndex < Constants.MAX_SEGMENTS_OF_NODE; ++segmentIndex) {
ushort segmentId = node.GetSegment(segmentIndex);
if (segmentId != 0) {
// TODO: #568 provide unified delete key for all managers.
bool startNode = segmentId.ToSegment().IsStartNode(SelectedNodeId);
JunctionRestrictionsManager.Instance.ClearSegmentEnd(segmentId, startNode);
}
}
JunctionRestrictionsManager.Instance.ClearNode(SelectedNodeId);
}
}

Expand Down
126 changes: 94 additions & 32 deletions TLM/TLM/UI/TrafficManagerTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public class TrafficManagerTool
// activate when we know the mechanism.
private bool ReadjustPathMode => false; //ShiftIsPressed;

private bool NodeSelectionMode => AltIsPressed;

// /// <summary>Set this to true to once call <see cref="RequestOnscreenDisplayUpdate"/>.</summary>
// public bool InvalidateOnscreenDisplayFlag { get; set; }

Expand Down Expand Up @@ -346,7 +348,7 @@ public void SetToolMode(ToolMode newToolMode) {
toolMode_ = ToolMode.None;

Log._Debug($"SetToolMode: reset because toolmode not found {newToolMode}");
OnscreenDisplay.DisplayIdle();
ScreenDisplay();
ModUI.Instance?.MainMenu?.UpdateButtons();
return;
}
Expand Down Expand Up @@ -493,10 +495,6 @@ void DefaultRenderOverlay(RenderManager.CameraInfo cameraInfo)
base.RenderOverlay(cameraInfo); // render path.
}

if (HoveredSegmentId == 0) {
return;
}

var netAdjust = NetManager.instance?.NetAdjust;

if (netAdjust == null) {
Expand All @@ -507,8 +505,14 @@ void DefaultRenderOverlay(RenderManager.CameraInfo cameraInfo)
ref NetSegment segment = ref HoveredSegmentId.ToSegment();
var color = ToolsModifierControl.toolController.m_validColorInfo;
float alpha = 1f;
NetTool.CheckOverlayAlpha(ref segment, ref alpha);
if (HoveredSegmentId != 0) {
NetTool.CheckOverlayAlpha(ref segment, ref alpha);
}

color.a *= alpha;
if (SelectedNodeId != 0) {
Highlight.DrawNodeCircle(cameraInfo, SelectedNodeId, color);
}

if (ReadjustPathMode) {
if (Input.GetMouseButton(0)) {
Expand All @@ -531,6 +535,10 @@ void DefaultRenderOverlay(RenderManager.CameraInfo cameraInfo)
importantColor: color,
nonImportantColor: color);
}
} else if (NodeSelectionMode) {
if (HoveredNodeId != SelectedNodeId && HoveredNodeId != 0) {
Highlight.DrawNodeCircle(cameraInfo, HoveredNodeId, color);
}
} else {
NetTool.RenderOverlay(cameraInfo, ref segment, color, color);
}
Expand Down Expand Up @@ -593,8 +601,11 @@ protected override void OnToolUpdate() {
if(secondaryMouseClicked) {
if(GetToolMode() == ToolMode.None) {
RoadSelectionPanels roadSelectionPanels = UIView.GetAView().GetComponent<RoadSelectionPanels>();
if(roadSelectionPanels && roadSelectionPanels.RoadWorldInfoPanelExt && roadSelectionPanels.RoadWorldInfoPanelExt.isVisible) {
if (roadSelectionPanels && roadSelectionPanels.RoadWorldInfoPanelExt && roadSelectionPanels.RoadWorldInfoPanelExt.isVisible) {
RoadSelectionPanels.RoadWorldInfoPanel.Hide();
} else if (SelectedNodeId != 0) {
SelectedNodeId = 0;
RequestOnscreenDisplayUpdate();
} else {
ModUI.Instance.CloseMainMenu();
}
Expand Down Expand Up @@ -680,37 +691,48 @@ public void OnToolGUIImpl(Event e) {
}
}

void DefaultOnToolGUI(Event e) {
private void DefaultOnToolGUI(Event e) {
if (!TMPELifecycle.PlayMode) {
return; // world info view panels are not available in edit mode
}
if (e.type == EventType.MouseDown && e.button == 0) {
bool isRoad = HoveredSegmentId != 0 && HoveredSegmentId.ToSegment().Info.m_netAI is RoadBaseAI;
if (!isRoad)
return;

if (ReadjustPathMode) {
bool isRoundabout = RoundaboutMassEdit.Instance.TraverseLoop(HoveredSegmentId, out var segmentList);
if (!isRoundabout) {
var segments = SegmentTraverser.Traverse(
HoveredSegmentId,
TraverseDirection.AnyDirection,
TraverseSide.Straight,
SegmentStopCriterion.None,
(_) => true);
segmentList = new List<ushort>(segments);
if (NodeSelectionMode) {
SelectedNodeId = HoveredNodeId;
RequestOnscreenDisplayUpdate();
} else {
bool isRoad = HoveredSegmentId != 0 && HoveredSegmentId.ToSegment().Info.m_netAI is RoadBaseAI;
if (!isRoad)
return;

if (ReadjustPathMode) {
bool isRoundabout = RoundaboutMassEdit.Instance.TraverseLoop(HoveredSegmentId, out var segmentList);
if (!isRoundabout) {
var segments = SegmentTraverser.Traverse(
HoveredSegmentId,
TraverseDirection.AnyDirection,
TraverseSide.Straight,
SegmentStopCriterion.None,
(_) => true);
segmentList = new List<ushort>(segments);
}
RoadSelectionUtil.SetRoad(HoveredSegmentId, segmentList);
}
RoadSelectionUtil.SetRoad(HoveredSegmentId, segmentList);
}

InstanceID instanceID = new InstanceID {
NetSegment = HoveredSegmentId,
};
InstanceID instanceID = new InstanceID {
NetSegment = HoveredSegmentId,
};

SimulationManager.instance.m_ThreadingWrapper.QueueMainThread(() => {
OpenWorldInfoPanel(
instanceID,
HitPos);
SimulationManager.instance.m_ThreadingWrapper.QueueMainThread(() => {
OpenWorldInfoPanel(
instanceID,
HitPos);
});
}
} else if (SelectedNodeId != 0 && KeybindSettingsBase.RestoreDefaultsKey.KeyDown(e)) {
ushort nodeId = SelectedNodeId;
SimulationManager.instance.m_ThreadingWrapper.QueueSimulationThread(() => {
PriorityRoad.EraseAllTrafficRoadsForNode(nodeId);
SimulationManager.instance.m_ThreadingWrapper.QueueMainThread(RoadSelectionUtil.ShowMassEditOverlay);
});
}
}
Expand Down Expand Up @@ -1612,9 +1634,49 @@ public void RequestOnscreenDisplayUpdate() {

if (activeOsd == null && activeLegacyOsd == null) {
// No tool hint support was available means we have to show the default
OnscreenDisplay.DisplayIdle();
ScreenDisplay();
}
}

/// <summary>Clear the OSD panel and display the idle hint.</summary>
public void ScreenDisplay() {
var items = new List<OsdItem>();
items.Add(new MainMenu.OSD.Label(
localizedText: Translation.Menu.Get("Onscreen.Idle:Choose a tool")));
items.Add(new MainMenu.OSD.HardcodedMouseShortcut(
button: ColossalFramework.UI.UIMouseButton.Left,
shift: false,
ctrl: false,
alt: false,
localizedText: "Onscreen.Default:Select a road")); // select a road to set as main road.
items.Add(new MainMenu.OSD.HardcodedMouseShortcut(
button: ColossalFramework.UI.UIMouseButton.Left,
shift: false,
ctrl: false,
alt: true,
localizedText: "Onscreen.Default:Select a node")); // select a node to erase all traffic rules.

if (SelectedNodeId != 0) {
items.Add(new MainMenu.OSD.Shortcut(
keybindSetting: KeybindSettingsBase.RestoreDefaultsKey,
localizedText: "Onscreen.Default:Erase")); // Erase all traffic rules from selected node.
items.Add(new MainMenu.OSD.HardcodedMouseShortcut(
button: ColossalFramework.UI.UIMouseButton.Right,
shift: false,
ctrl: false,
alt: false,
localizedText: "Onscreen.Default:Deselect node"));
}

items.Add(new MainMenu.OSD.HoldModifier(
shift: false,
ctrl: true,
alt: false,
localizedText: "Onscreen.Default:Show traffic rules")); // show traffic rules for high priority roads

OnscreenDisplay.Display(items);
}

public void AddUUIButton() {
try {
var hotkeys = new UUIHotKeys { ActivationKey = KeybindSettingsBase.ToggleMainMenu.Key };
Expand Down
11 changes: 11 additions & 0 deletions TLM/TLM/Util/PriorityRoad.cs
Original file line number Diff line number Diff line change
Expand Up @@ -682,5 +682,16 @@ public static IRecordable RecordRoad(List<ushort> segmentList) {
record.Record();
return record;
}

public static void EraseAllTrafficRoadsForNode(ushort nodeId) {
try {
TrafficLightManager.Instance.ResetTrafficLightAndPrioritySignsFromNode(nodeId);
LaneConnectionManager.Instance.RemoveLaneConnectionsFromNode(nodeId);
LaneArrowManager.Instance.ResetNodeLaneArrows(nodeId);
JunctionRestrictionsManager.Instance.ClearNode(nodeId);
} catch (Exception ex) {
ex.LogException();
}
}
} //end class
}
21 changes: 17 additions & 4 deletions TLM/TLM/Util/RoadSelectionUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ namespace TrafficManager.Util {
using ColossalFramework;
using ICities;
using CSUtil.Commons;
using static TrafficManager.Util.Shortcuts;
using static NetAdjust;
using static SegmentTraverser;
using TrafficManager.UI;

public class RoadSelectionUtil {
public RoadSelectionUtil() : base() {
Expand All @@ -17,6 +15,21 @@ public RoadSelectionUtil() : base() {
// instance of singleton
public static RoadSelectionUtil Instance { get; private set; }

/// <summary>
/// Enables and refreshes overlay for various traffic rules influenced by road selection panel.
/// </summary>
public static void ShowMassEditOverlay() {
var tmTool = ModUI.GetTrafficManagerTool();
if (tmTool == null) {
Log.Error("ModUI.GetTrafficManagerTool() returned null");
return;
}
UI.SubTools.PrioritySigns.MassEditOverlay.Show = true;
tmTool.SetToolMode(ToolMode.None);
tmTool.InitializeSubTools();
Log._Debug("Mass edit overlay enabled");
}

public static void Release() {
if (Instance != null) {
Instance.OnChanged = null;
Expand Down Expand Up @@ -164,7 +177,7 @@ public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) {
RoadSelectionUtil.Instance.OnChanged?.Invoke();
}
prev_segmentID = segmentID;
}catch(Exception e) {
} catch(Exception e) {
Log.Error(e.Message);
}
}
Expand Down