Skip to content

Commit

Permalink
TMPE version 1.8.16:
Browse files Browse the repository at this point in the history
- Lane connections can now also be removed by pressing the backspace key
- Improved lane selection for busses if the option "Busses may ignore lane arrows" is activated
- Bugfix: The game sometimes freezes when using the timed traffic light tool
- Bugfix: Lane connections are not correctly removed after modifying/removing a junction
- Bugfix: Selecting a junction for setting up junction restrictions toggles the currently hovered junction restriction icon
  • Loading branch information
VictorPhilipp committed Mar 20, 2017
1 parent 1be0760 commit 48810a4
Show file tree
Hide file tree
Showing 9 changed files with 315 additions and 248 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ A work-in-progress modification for **Cities: Skylines** to add additional traff
User manual: http://www.viathinksoft.de/tmpe

# Changelog
1.8.16, 03/20/2017
- Lane connections can now also be removed by pressing the backspace key
- Improved lane selection for busses if the option "Busses may ignore lane arrows" is activated
- Bugfix: The game sometimes freezes when using the timed traffic light tool
- Bugfix: Lane connections are not correctly removed after modifying/removing a junction
- Bugfix: Selecting a junction for setting up junction restrictions toggles the currently hovered junction restriction icon

1.8.15, 01/27/2017
- Updated for game version 1.6.3-f1

Expand Down
394 changes: 210 additions & 184 deletions TLM/TLM/Custom/PathFinding/CustomPathFind.cs

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions TLM/TLM/Manager/LaneConnectionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,16 @@ internal void RemoveLaneConnectionsFromNode(ushort nodeId) {
/// <param name="segmentId"></param>
/// <param name="startNode"></param>
internal void RemoveLaneConnectionsFromSegment(ushort segmentId, bool startNode) {
//#if DEBUGCONN
#if DEBUGCONN
Log._Debug($"LaneConnectionManager.RemoveLaneConnectionsFromSegment({segmentId}, {startNode}) called.");
//#endif
#endif
NetManager netManager = Singleton<NetManager>.instance;

uint curLaneId = netManager.m_segments.m_buffer[segmentId].m_lanes;
while (curLaneId != 0) {
#if DEBUGCONN
Log._Debug($"LaneConnectionManager.RemoveLaneConnectionsFromSegment: Removing lane connections from segment {segmentId}, lane {curLaneId}.");
#endif
RemoveLaneConnections(curLaneId, startNode);
curLaneId = netManager.m_lanes.m_buffer[curLaneId].m_nextLane;
}
Expand All @@ -195,7 +197,7 @@ internal void RemoveLaneConnections(uint laneId, bool startNode) {

NetManager netManager = Singleton<NetManager>.instance;

for (int i = 0; i < Flags.laneConnections[laneId][nodeArrayIndex].Length; ++i) {
/*for (int i = 0; i < Flags.laneConnections[laneId][nodeArrayIndex].Length; ++i) {
uint otherLaneId = Flags.laneConnections[laneId][nodeArrayIndex][i];
if (Flags.laneConnections[otherLaneId] != null) {
if ((Flags.laneConnections[otherLaneId][0] != null && Flags.laneConnections[otherLaneId][0].Length == 1 && Flags.laneConnections[otherLaneId][0][0] == laneId && Flags.laneConnections[otherLaneId][1] == null) ||
Expand All @@ -205,7 +207,7 @@ internal void RemoveLaneConnections(uint laneId, bool startNode) {
UnsubscribeFromSegmentGeometry(otherSegmentId);
}
}
}
}*/

Flags.RemoveLaneConnections(laneId, startNode);

Expand Down
132 changes: 76 additions & 56 deletions TLM/TLM/State/Flags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using TrafficManager.Geometry;
using TrafficManager.Manager;
using TrafficManager.Traffic;
using TrafficManager.Util;

namespace TrafficManager.State {
public class Flags {
Expand Down Expand Up @@ -78,80 +79,88 @@ public enum LaneArrowChangeResult {
private static object laneAllowedVehicleTypesLock = new object();

internal static void PrintDebugInfo() {
Log._Debug("------------------------------");
Log._Debug("--- TOGGLED TRAFFIC LIGHTS ---");
Log._Debug("------------------------------");
for (uint i = 0; i < nodeTrafficLightFlag.Length; ++i) {
Log.Info("------------------------------");
Log.Info("--- TOGGLED TRAFFIC LIGHTS ---");
Log.Info("------------------------------");
for (ushort i = 0; i < nodeTrafficLightFlag.Length; ++i) {
if (nodeTrafficLightFlag[i] == null)
continue;
Log._Debug($"Node {i}: {nodeTrafficLightFlag[i]}");
Log.Info($"Node {i}: {nodeTrafficLightFlag[i]} (valid? {NetUtil.IsNodeValid(i)})");
}

Log._Debug("------------------------");
Log._Debug("--- LANE ARROW FLAGS ---");
Log._Debug("------------------------");
Log.Info("------------------------");
Log.Info("--- LANE ARROW FLAGS ---");
Log.Info("------------------------");
for (uint i = 0; i < laneArrowFlags.Length; ++i) {
if (laneArrowFlags[i] == null)
continue;
Log._Debug($"Lane {i}: {laneArrowFlags[i]}");
Log.Info($"Lane {i}: {laneArrowFlags[i]} (valid? {NetUtil.IsLaneValid(i)})");
}

Log._Debug("------------------------");
Log._Debug("--- LANE CONNECTIONS ---");
Log._Debug("------------------------");
Log.Info("------------------------");
Log.Info("--- LANE CONNECTIONS ---");
Log.Info("------------------------");
for (uint i = 0; i < laneConnections.Length; ++i) {
if (laneConnections[i] == null)
continue;

ushort segmentId = Singleton<NetManager>.instance.m_lanes.m_buffer[i].m_segment;
Log.Info($"Lane {i}: valid? {NetUtil.IsLaneValid(i)}, seg. valid? {NetUtil.IsSegmentValid(segmentId)}");
for (int x = 0; x < 2; ++x) {
if (laneConnections[i][x] == null)
continue;

ushort nodeId = x == 0 ? Singleton<NetManager>.instance.m_segments.m_buffer[segmentId].m_startNode : Singleton<NetManager>.instance.m_segments.m_buffer[segmentId].m_endNode;
Log.Info($"\tNode idx {x} ({nodeId}, seg. {segmentId}): valid? {NetUtil.IsNodeValid(nodeId)}");

for (int y = 0; y < laneConnections[i][x].Length; ++y) {
if (laneConnections[i][x][y] == 0)
continue;

Log._Debug($"Lane {i} / Node idx {x} / Entry {y}: {laneConnections[i][x][y]}");
Log.Info($"\t\tEntry {y}: {laneConnections[i][x][y]} (valid? {NetUtil.IsLaneValid(laneConnections[i][x][y])})");
}
}
}

Log._Debug("-------------------------");
Log._Debug("--- LANE SPEED LIMITS ---");
Log._Debug("-------------------------");
for (uint i = 0; i < laneSpeedLimitArray.Length; ++i) {
Log.Info("-------------------------");
Log.Info("--- LANE SPEED LIMITS ---");
Log.Info("-------------------------");
for (ushort i = 0; i < laneSpeedLimitArray.Length; ++i) {
if (laneSpeedLimitArray[i] == null)
continue;
Log.Info($"Segment {i}: valid? {NetUtil.IsSegmentValid(i)}");
for (int x = 0; x < laneSpeedLimitArray[i].Length; ++x) {
if (laneSpeedLimitArray[i][x] == null)
continue;
Log._Debug($"Segment {i} / Lane idx {x}: {laneSpeedLimitArray[i][x]}");
Log.Info($"\tLane idx {x}: {laneSpeedLimitArray[i][x]}");
}
}

Log._Debug("---------------------------------");
Log._Debug("--- LANE VEHICLE RESTRICTIONS ---");
Log._Debug("---------------------------------");
for (uint i = 0; i < laneAllowedVehicleTypesArray.Length; ++i) {
Log.Info("---------------------------------");
Log.Info("--- LANE VEHICLE RESTRICTIONS ---");
Log.Info("---------------------------------");
for (ushort i = 0; i < laneAllowedVehicleTypesArray.Length; ++i) {
if (laneAllowedVehicleTypesArray[i] == null)
continue;
Log.Info($"Segment {i}: valid? {NetUtil.IsSegmentValid(i)}");
for (int x = 0; x < laneAllowedVehicleTypesArray[i].Length; ++x) {
if (laneAllowedVehicleTypesArray[i][x] == null)
continue;
Log._Debug($"Segment {i} / Lane idx {x}: {laneAllowedVehicleTypesArray[i][x]}");
Log.Info($"\tLane idx {x}: {laneAllowedVehicleTypesArray[i][x]}");
}
}

Log._Debug("-----------------------------");
Log._Debug("--- JUNCTION RESTRICTIONS ---");
Log._Debug("-----------------------------");
for (uint i = 0; i < segmentNodeFlags.Length; ++i) {
Log.Info("-----------------------------");
Log.Info("--- JUNCTION RESTRICTIONS ---");
Log.Info("-----------------------------");
for (ushort i = 0; i < segmentNodeFlags.Length; ++i) {
if (segmentNodeFlags[i] == null)
continue;
Log.Info($"Segment {i}: valid? {NetUtil.IsSegmentValid(i)}");
for (int x = 0; x < segmentNodeFlags[i].Length; ++x) {
if (segmentNodeFlags[i][x] == null)
continue;
Log._Debug($"Segment {i} / Node idx {x}: {segmentNodeFlags[i][x]}");
Log.Info($"\tNode idx {x}: {segmentNodeFlags[i][x]}");
}
}
}
Expand Down Expand Up @@ -278,12 +287,13 @@ internal static bool RemoveLaneConnection(uint lane1Id, uint lane2Id, bool start
/// <param name="laneId"></param>
/// <param name="startNode"></param>
internal static void RemoveLaneConnections(uint laneId, bool? startNode=null) {
//Log._Debug($"Flags.RemoveLaneConnections({laneId}, {startNode}) called. laneConnections[{laneId}]={laneConnections[laneId]}");
if (laneConnections[laneId] == null)
return;

bool laneValid = CheckLane(laneId);

bool clearBothSides = startNode == null || !laneValid;
//Log._Debug($"Flags.RemoveLaneConnections({laneId}, {startNode}): laneValid={laneValid}, clearBothSides={clearBothSides}");
int? nodeArrayIndex = null;
if (!clearBothSides) {
nodeArrayIndex = (bool)startNode ? 0 : 1;
Expand All @@ -293,16 +303,23 @@ internal static void RemoveLaneConnections(uint laneId, bool? startNode=null) {
if (nodeArrayIndex != null && k != (int)nodeArrayIndex)
continue;

bool startNode1 = k == 0;

if (laneConnections[laneId][k] == null)
continue;

for (int i = 0; i < laneConnections[laneId][k].Length; ++i) {
CleanupLaneConnections(laneConnections[laneId][k][i], laneId, true);
CleanupLaneConnections(laneConnections[laneId][k][i], laneId, false);
uint otherLaneId = laneConnections[laneId][k][i];
ushort commonNodeId;
bool startNode2;
LaneConnectionManager.Instance.GetCommonNodeId(laneId, otherLaneId, startNode1, out commonNodeId, out startNode2); // TODO refactor

CleanupLaneConnections(otherLaneId, laneId, startNode2);
}

laneConnections[laneId][k] = null;
}

if (clearBothSides)
laneConnections[laneId] = null;
}
Expand Down Expand Up @@ -377,39 +394,42 @@ private static void CreateLaneConnection(uint sourceLaneId, uint targetLaneId, b
/// <param name="startNode"></param>
/// <returns></returns>
private static bool CleanupLaneConnections(uint sourceLaneId, uint targetLaneId, bool startNode) {
Log._Debug($"Flags.CleanupLaneConnections({sourceLaneId}, {targetLaneId}, {startNode}) called.");
int nodeArrayIndex = startNode ? 0 : 1;

if (laneConnections[sourceLaneId] == null || laneConnections[sourceLaneId][nodeArrayIndex] == null)
return false;

bool ret = false;
uint[] srcLaneConnections = laneConnections[sourceLaneId][nodeArrayIndex];
if (srcLaneConnections != null) {
int remainingConnections = 0;
for (int i = 0; i < srcLaneConnections.Length; ++i) {
if (srcLaneConnections[i] != targetLaneId) {
++remainingConnections;
} else {
ret = true;
srcLaneConnections[i] = 0;
}
}
if (srcLaneConnections == null) {
return false;
}

if (remainingConnections <= 0) {
laneConnections[sourceLaneId][nodeArrayIndex] = null;
if (laneConnections[sourceLaneId][1 - nodeArrayIndex] == null)
laneConnections[sourceLaneId] = null; // total cleanup
return ret;
bool ret = false;
int remainingConnections = 0;
for (int i = 0; i < srcLaneConnections.Length; ++i) {
if (srcLaneConnections[i] != targetLaneId) {
++remainingConnections;
} else {
ret = true;
srcLaneConnections[i] = 0;
}
}

if (remainingConnections != srcLaneConnections.Length) {
laneConnections[sourceLaneId][nodeArrayIndex] = new uint[remainingConnections];
int k = 0;
for (int i = 0; i < srcLaneConnections.Length; ++i) {
if (srcLaneConnections[i] == 0)
continue;
laneConnections[sourceLaneId][nodeArrayIndex][k++] = srcLaneConnections[i];
}
if (remainingConnections <= 0) {
laneConnections[sourceLaneId][nodeArrayIndex] = null;
if (laneConnections[sourceLaneId][1 - nodeArrayIndex] == null)
laneConnections[sourceLaneId] = null; // total cleanup
return ret;
}

if (remainingConnections != srcLaneConnections.Length) {
laneConnections[sourceLaneId][nodeArrayIndex] = new uint[remainingConnections];
int k = 0;
for (int i = 0; i < srcLaneConnections.Length; ++i) {
if (srcLaneConnections[i] == 0)
continue;
laneConnections[sourceLaneId][nodeArrayIndex][k++] = srcLaneConnections[i];
}
}
return ret;
Expand Down
7 changes: 6 additions & 1 deletion TLM/TLM/State/GlobalConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,12 @@ internal static void OnLevelUnloading() {
/// <summary>
/// artifical lane distance for u-turns
/// </summary>
public int UturnLaneDistance = 8;
public int UturnLaneDistance = 2;

/// <summary>
/// artifical lane distance for vehicles that change to lanes which have an incompatible lane arrow configuration
/// </summary>
public byte IncompatibleLaneDistance = 1;

/// <summary>
/// lane density random interval
Expand Down
2 changes: 1 addition & 1 deletion TLM/TLM/TrafficManagerMod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace TrafficManager {
public class TrafficManagerMod : IUserMod {

public static readonly string Version = "1.8.15";
public static readonly string Version = "1.8.16";

public static readonly uint GameVersion = 159899920u;
public static readonly uint GameVersionA = 1u;
Expand Down
1 change: 1 addition & 0 deletions TLM/TLM/UI/SubTools/JunctionRestrictionsTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ public override void OnPrimaryClickOverlay() {
return;

SelectedNodeId = HoveredNodeId;
MainTool.CheckClicked(); // prevent accidential activation of signs on node selection (TODO improve this!)
}

public override void OnSecondaryClickOverlay() {
Expand Down
2 changes: 1 addition & 1 deletion TLM/TLM/UI/SubTools/LaneConnectorTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) {
}
}

bool deleteAll = Input.GetKeyDown(KeyCode.Delete);
bool deleteAll = Input.GetKeyDown(KeyCode.Delete) || Input.GetKeyDown(KeyCode.Backspace);
bool stayInLane = Input.GetKeyDown(KeyCode.S) && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) && Singleton<NetManager>.instance.m_nodes.m_buffer[SelectedNodeId].CountSegments() == 2;
if (stayInLane)
deleteAll = true;
Expand Down
8 changes: 7 additions & 1 deletion TLM/TLM/UI/SubTools/TimedTrafficLightsTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,13 @@ private void _guiTimedControlPanel(int num) {
else
labelLayout = layoutGreen;
} else {
labelLayout = timedNodeMain.GetStep(i).IsInEndTransition() ? layoutYellow : layoutGreen;
bool inEndTransition = false;
try {
inEndTransition = timedNodeMain.GetStep(i).IsInEndTransition();
} catch (Exception e) {
Log.Error("Error while determining if timed traffic light is in end transition: " + e.ToString());
}
labelLayout = inEndTransition ? layoutYellow : layoutGreen;
}
GUILayout.Label(labelStr, labelLayout);
GUILayout.Space(5);
Expand Down

0 comments on commit 48810a4

Please sign in to comment.