Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
7fb2784
move lane connection manager to sub folder.
kianzarrin Apr 24, 2022
0967228
introduce sub manager.
kianzarrin Apr 24, 2022
9df2ccf
fix API typo
kianzarrin Apr 25, 2022
fe5e3c1
fixed GetImplementation
kianzarrin Apr 25, 2022
fd6799d
polish
kianzarrin Apr 26, 2022
c6a0ec1
create Road/Track sub managers
kianzarrin Apr 26, 2022
b87b3da
save game data
kianzarrin Apr 26, 2022
eb87b6d
lane connection record
kianzarrin Apr 26, 2022
1f49fe7
misc: use Road or Track sub manager
kianzarrin Apr 26, 2022
0cb9fa7
improve transition group support for lane connection sub managers.
kianzarrin Apr 26, 2022
a97dfa9
bugfix + arrow node markers
kianzarrin Apr 26, 2022
65cbcca
bugfix: bidirectional lane curve.
kianzarrin Apr 26, 2022
68654b1
bugfix: draw all lane connections on other nodes.
kianzarrin Apr 26, 2022
eef830e
kianzarrin Apr 26, 2022
b11a7bd
kianzarrin Apr 26, 2022
3489341
don't connect track when acute
kianzarrin Apr 27, 2022
a15dfe2
added hint/
kianzarrin Apr 27, 2022
b99bdd7
update lane arrows only on car lanes.
kianzarrin Apr 27, 2022
7f43aa4
fix regression: must not connect target to source
kianzarrin Apr 27, 2022
1546beb
polish/improve
kianzarrin Apr 27, 2022
b35a3a8
kianzarrin Apr 27, 2022
0ab91d0
improved arrow heads.
kianzarrin Apr 27, 2022
4d28a2c
use square texture to draw better triangle.
kianzarrin Apr 27, 2022
41efa23
merge
kianzarrin Apr 27, 2022
1e60387
kianzarrin Apr 28, 2022
552cbc4
use square shape without texture.
kianzarrin May 8, 2022
ae20d51
Merge branch 'master' into 354-phase3
kianzarrin May 8, 2022
1367037
do not allow connections in wrong direction.
kianzarrin May 11, 2022
5d08065
Merge branch '354-phase3' of https://github.com/CitiesSkylinesMods/TM…
kianzarrin May 11, 2022
1600a63
Merge branch 'master' into 354-phase3
kianzarrin May 11, 2022
cb66250
kianzarrin May 11, 2022
fb13a0f
regression fix: connect to avoid forward station track.
kianzarrin May 16, 2022
1c4b972
fix regression: connect car lanes to bus lanes.
kianzarrin May 16, 2022
966fa9b
fixes 1198: update all routings when creating new connection.
kianzarrin May 16, 2022
cc2e53b
direction arrow texture does not have aliasing.
kianzarrin May 16, 2022
1c9a4ee
Merge branch 'a' into 354-phase3
kianzarrin May 29, 2022
966a718
merge ext lane manager
kianzarrin May 29, 2022
819a08f
merge API update
kianzarrin May 29, 2022
ed19467
kianzarrin May 30, 2022
cdf17d2
Merge branch 'master' into 354-phase3
kianzarrin Jun 6, 2022
e70117f
Merge branch 'master' into 354-phase3
kianzarrin Jun 7, 2022
bdb3299
Merge branch 'master' into 354-phase3
kianzarrin Jun 10, 2022
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
2 changes: 1 addition & 1 deletion TLM/TLM/Manager/Impl/ExtNodeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private ExtNodeManager() {
/// <param name="nodeId">NodeId of the node to test.</param>
/// <returns></returns>
public static bool JunctionHasHighwayRules(ushort nodeId) {
return JunctionHasOnlyHighwayRoads(nodeId) && !LaneConnection.LaneConnectionManager.Instance.Sub.HasNodeConnections(nodeId);
return JunctionHasOnlyHighwayRoads(nodeId) && !LaneConnection.LaneConnectionManager.Instance.Road.HasNodeConnections(nodeId);
}

public GetNodeSegmentIdsEnumerable GetNodeSegmentIds(ushort nodeId, ClockDirection clockDirection) {
Expand Down
123 changes: 110 additions & 13 deletions TLM/TLM/Manager/Impl/LaneConnection/LaneConnectionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace TrafficManager.Manager.Impl.LaneConnection {
using TrafficManager.API.Manager;
using TrafficManager.API.Traffic.Data;
using TrafficManager.API.Traffic.Enums;
using TrafficManager.Util;
using TrafficManager.Util.Extensions;
using UnityEngine;
#if DEBUG
Expand All @@ -23,8 +24,8 @@ public class LaneConnectionManager
| VehicleInfo.VehicleType.Monorail
| VehicleInfo.VehicleType.Trolleybus;

public LaneConnectionSubManager Sub = // TODO #354 divide into Road/Track
new LaneConnectionSubManager(LaneEndTransitionGroup.Vehicle);
public LaneConnectionSubManager Road = new LaneConnectionSubManager(LaneEndTransitionGroup.Road);
public LaneConnectionSubManager Track = new LaneConnectionSubManager(LaneEndTransitionGroup.Track);

public NetInfo.LaneType LaneTypes => LANE_TYPES;

Expand All @@ -38,48 +39,141 @@ static LaneConnectionManager() {

public override void OnBeforeLoadData() {
base.OnBeforeLoadData();
Sub.OnBeforeLoadData();
Road.OnBeforeLoadData();
Track.OnBeforeLoadData();
}
public override void OnLevelUnloading() {
base.OnLevelUnloading();
Sub.OnLevelUnloading();
Road.OnLevelUnloading();
Track.OnLevelUnloading();
}

protected override void InternalPrintDebugInfo() {
base.InternalPrintDebugInfo();
Sub.PrintDebugInfo();
Road.PrintDebugInfo();
Track.PrintDebugInfo();
}

/// <summary>
/// Checks if traffic may flow from source lane to target lane according to setup lane connections
/// </summary>
/// <param name="sourceStartNode">check at start node of source lane?</param>
public bool AreLanesConnected(uint sourceLaneId, uint targetLaneId, bool sourceStartNode) {
return Sub.AreLanesConnected(sourceLaneId, targetLaneId, sourceStartNode);
return Road.AreLanesConnected(sourceLaneId, targetLaneId, sourceStartNode) ||
Track.AreLanesConnected(sourceLaneId, targetLaneId, sourceStartNode);
}

public bool AreLanesConnected(uint sourceLaneId, uint targetLaneId, bool sourceStartNode, LaneEndTransitionGroup group) {
bool ret = Road.Supports(group) &&
Road.AreLanesConnected(sourceLaneId, targetLaneId, sourceStartNode);
if (!ret) {
ret = Track.Supports(group) &&
Track.AreLanesConnected(sourceLaneId, targetLaneId, sourceStartNode);
}
return ret;
}


/// <summary>
/// Adds a lane connection between two lanes.
/// pass in <c>LaneEndTransitionGroup.All</c> to add lane connections in every sub manager that supports both lanes.
/// </summary>
/// <param name="sourceLaneId">From lane id</param>
/// <param name="targetLaneId">To lane id</param>
/// <param name="sourceStartNode">The affected node</param>
/// <param name="group">lane or track</param>
/// <returns><c>true</c> if any connection was added, <c>falsse</c> otherwise</returns>
public bool AddLaneConnection(uint sourceLaneId, uint targetLaneId, bool sourceStartNode, LaneEndTransitionGroup group) {
bool success = true;
if (Road.Supports(group)) {
success = Road.AddLaneConnection(sourceLaneId, targetLaneId, sourceStartNode);
}
if (Track.Supports(group)) {
success &= Track.AddLaneConnection(sourceLaneId, targetLaneId, sourceStartNode);
}
return success;
}

public bool RemoveLaneConnection(uint sourceLaneId, uint targetLaneId, bool sourceStartNode, LaneEndTransitionGroup group) {
bool success = true;
var sourceLaneInfo = ExtLaneManager.Instance.GetLaneInfo(sourceLaneId);
var targetLaneInfo = ExtLaneManager.Instance.GetLaneInfo(targetLaneId);
if (Road.Supports(group)) {
success = Road.RemoveLaneConnection(sourceLaneId, targetLaneId, sourceStartNode);
} else {
bool canConnect = Road.Supports(sourceLaneInfo) && Road.Supports(targetLaneInfo);
if (!canConnect)
Road.RemoveLaneConnection(sourceLaneId, targetLaneId, sourceStartNode);
}
if (Track.Supports(group)) {
success |= Track.RemoveLaneConnection(sourceLaneId, targetLaneId, sourceStartNode);
} else {
bool canConnect = Track.Supports(sourceLaneInfo) && Track.Supports(targetLaneInfo);
if (!canConnect)
Track.RemoveLaneConnection(sourceLaneId, targetLaneId, sourceStartNode);
}
return success;
}

/// <summary>
/// Determines if the given lane has incoming/outgoing connections
/// Performance note: This act as HasOutgoingConnections for uni-directional lanes but faster
/// </summary>
public bool HasConnections(uint laneId, bool startNode) =>
Sub.HasConnections(laneId, startNode);
Road.HasConnections(laneId, startNode) || Track.HasConnections(laneId, startNode);

/// <summary>
/// Determines if there exist custom lane connections at the specified node
/// </summary>
public bool HasNodeConnections(ushort nodeId) => Sub.HasNodeConnections(nodeId);
public bool HasNodeConnections(ushort nodeId) =>
Road.HasNodeConnections(nodeId) || Track.HasNodeConnections(nodeId);

// Note: Not performance critical
public bool HasUturnConnections(ushort segmentId, bool startNode) =>
Sub.HasUturnConnections(segmentId, startNode);
Road.HasUturnConnections(segmentId, startNode);

/// <summary>
/// Removes all lane connections at the specified node
/// </summary>
/// <param name="nodeId">Affected node</param>
internal void RemoveLaneConnectionsFromNode(ushort nodeId) {
Sub.RemoveLaneConnectionsFromNode(nodeId);
Road.RemoveLaneConnectionsFromNode(nodeId);
Track.RemoveLaneConnectionsFromNode(nodeId);
}


/// <summary>
/// Checks if the turning angle between two segments at the given node is within bounds.
/// </summary>
public static bool CheckSegmentsTurningAngle(ushort sourceSegmentId,
bool sourceStartNode,
ushort targetSegmentId,
bool targetStartNode) {
if (sourceSegmentId == targetSegmentId) {
return false;
}

ref NetSegment sourceSegment = ref sourceSegmentId.ToSegment();
ref NetSegment targetSegment = ref targetSegmentId.ToSegment();
float turningAngle = 0.01f - Mathf.Min(
sourceSegment.Info.m_maxTurnAngleCos,
targetSegment.Info.m_maxTurnAngleCos);

if (turningAngle < 1f) {
Vector3 sourceDirection = sourceStartNode
? sourceSegment.m_startDirection
: sourceSegment.m_endDirection;

Vector3 targetDirection = targetStartNode
? targetSegment.m_startDirection
: targetSegment.m_endDirection;

float dirDotProd = (sourceDirection.x * targetDirection.x) +
(sourceDirection.z * targetDirection.z);
return dirDotProd < turningAngle;
}

return true;
}

internal bool GetLaneEndPoint(ushort segmentId,
Expand Down Expand Up @@ -170,14 +264,17 @@ internal bool GetLaneEndPoint(ushort segmentId,
}

public bool LoadData(List<Configuration.LaneConnection> data) {
bool success = true;
bool success;
Log.Info($"Loading {data.Count} lane connections");
success = Sub.LoadData(data);
success = Road.LoadData(data);
success &= Track.LoadData(data);
return success;
}

public List<Configuration.LaneConnection> SaveData(ref bool success) {
return Sub.SaveData(ref success);
var ret = Road.SaveData(ref success);
ret.AddRange(Track.SaveData(ref success));
return ret;
}
}
}
Loading