Skip to content

Commit

Permalink
TMPE 1.9.4:
Browse files Browse the repository at this point in the history
- New option: Ban private cars and trucks on bus lanes
- Updated Spanish and French translation
- Optimized path-finding
- Increased path-finding cost for private cars driving on bus lanes
- Increased path-finding cost for disregarding vehicle restrictions
- Bugfix: Path-finding is unable to calculate certain paths after modifying the road network
  • Loading branch information
VictorPhilipp committed May 23, 2017
1 parent 1c0cd50 commit 9aacf99
Show file tree
Hide file tree
Showing 28 changed files with 375 additions and 257 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ A work-in-progress modification for **Cities: Skylines** to add additional traff
User manual: http://www.viathinksoft.de/tmpe

# Changelog
1.9.4, 05/23/2017
- New option: Ban private cars and trucks on bus lanes
- Updated Spanish and French translation
- Optimized path-finding
- Increased path-finding cost for private cars driving on bus lanes
- Increased path-finding cost for disregarding vehicle restrictions
- Bugfix: Path-finding is unable to calculate certain paths after modifying the road network

1.9.3, 05/22/2017
- Disabled notification of route recalculating because some players report crashes
- Removed default vehicle restrictions from bus lanes
Expand Down
115 changes: 71 additions & 44 deletions TLM/TLM/Custom/PathFinding/CustomPathFind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
using TrafficManager.Traffic;
using static TrafficManager.Manager.RoutingManager;
using CSUtil.Commons;
using static TrafficManager.Manager.TrafficMeasurementManager;
using static TrafficManager.Manager.VehicleRestrictionsManager;

namespace TrafficManager.Custom.PathFinding {
public class CustomPathFind : PathFind {
Expand Down Expand Up @@ -343,7 +345,8 @@ protected void PathFindImplementation(uint unit, ref PathUnit data) {
#if DEBUGNEWPF && DEBUG
bool debug = this._debug = _conf.DebugSwitches[0] &&
((_conf.PathFindDebugExtVehicleType == ExtVehicleType.None && (_extVehicleType == null || _extVehicleType == ExtVehicleType.None)) || (_extVehicleType != null && (_extVehicleType & _conf.PathFindDebugExtVehicleType) != ExtVehicleType.None)) &&
(_conf.PathFindDebugStartSegmentId < 0 || data.m_position00.m_segment == _conf.PathFindDebugStartSegmentId || data.m_position02.m_segment == _conf.PathFindDebugStartSegmentId)
(_conf.PathFindDebugStartSegmentId <= 0 || data.m_position00.m_segment == _conf.PathFindDebugStartSegmentId || data.m_position02.m_segment == _conf.PathFindDebugStartSegmentId) &&
(_conf.PathFindDebugVehicleId <= 0 || _vehicleId == _conf.PathFindDebugVehicleId)
;
if (debug) {
Log._Debug($"CustomPathFind.PathFindImplementation: START calculating path unit {unit}, type {_extVehicleType}");
Expand Down Expand Up @@ -540,6 +543,19 @@ protected void PathFindImplementation(uint unit, ref PathUnit data) {
if ((byte)(candidateItem.m_direction & direction) != 0 && (!flag2 || (instance.m_nodes.m_buffer[specialNodeId].m_flags & NetNode.Flags.Disabled) != NetNode.Flags.None)) {
bool isStartNode = specialNodeId == startNode2;
uint laneRoutingIndex = routingManager.GetLaneEndRoutingIndex(candidateItem.m_laneID, isStartNode);
#if DEBUGNEWPF && DEBUG
if (debug) {
Log._Debug($"CustomPathFind.PathFindImplementation: Handling special node for path unit {unit}, type {_extVehicleType}:\n" +
$"\tcandidateItem.m_position.m_segment={candidateItem.m_position.m_segment}\n" +
$"\tcandidateItem.m_position.m_lane={candidateItem.m_position.m_lane}\n" +
$"\tcandidateItem.m_laneID={candidateItem.m_laneID}\n" +
$"\tspecialNodeId={specialNodeId}\n" +
$"\tstartNode2={startNode2}\n" +
$"\tendNode2={endNode2}\n" +
$"\tlaneRoutingIndex={laneRoutingIndex}\n"
);
}
#endif
this.ProcessItemMain(unit, candidateItem, ref instance.m_segments.m_buffer[candidateItem.m_position.m_segment], ref routingManager.segmentRoutings[candidateItem.m_position.m_segment], ref routingManager.laneEndRoutings[laneRoutingIndex], specialNodeId, isStartNode, ref instance.m_nodes.m_buffer[specialNodeId], laneOffset, true);
}
specialNodeId = instance.m_nodes.m_buffer[specialNodeId].m_nextLaneNode;
Expand Down Expand Up @@ -742,7 +758,7 @@ protected void PathFindImplementation(uint unit, ref PathUnit data) {
// 1
private void ProcessItemMain(uint unitId, BufferItem item, ref NetSegment prevSegment, ref SegmentRoutingData prevSegmentRouting, ref LaneEndRoutingData prevLaneEndRouting, ushort nextNodeId, bool nextIsStartNode, ref NetNode nextNode, byte connectOffset, bool isMiddle) {
#if DEBUGNEWPF && DEBUG
bool debug = this._debug && (_conf.PathFindDebugNodeId < 0 || nextNodeId == _conf.PathFindDebugNodeId);
bool debug = this._debug && (_conf.PathFindDebugNodeId <= 0 || nextNodeId == _conf.PathFindDebugNodeId);
if (debug) {
if (! _debugPositions.ContainsKey(item.m_position.m_segment)) {
_debugPositions[item.m_position.m_segment] = new List<ushort>();
Expand Down Expand Up @@ -1028,15 +1044,15 @@ private void ProcessItemMain(uint unitId, BufferItem item, ref NetSegment prevSe

// determine if the vehicle may u-turn at the target node
bool explorePrevSegment =
nextIsEndOrOneWayOut || // stock u-turn points
_isRoadVehicle && // only road vehicles may perform u-turns
(nextIsEndOrOneWayOut || // stock u-turn points
(Options.junctionRestrictionsEnabled &&
isCustomUturnAllowed && // only do u-turns if allowed
!nextIsBeautificationNode && // no u-turns at beautification nodes
prevIsCarLane && // u-turns for road vehicles only
_isRoadVehicle && // only road vehicles may perform u-turns
!_isHeavyVehicle && // only small vehicles may perform u-turns
(nextIsTransitionOrJunction || nextIsBend) && // perform u-turns at transitions, junctions and bend nodes
!prevIsOutgoingOneWay); // do not u-turn on one-ways
!prevIsOutgoingOneWay)); // do not u-turn on one-ways

bool isStrictLaneArrowPolicyEnabled =
!nextIsBeautificationNode && // do not obey lane arrows at beautification nodes
Expand All @@ -1049,7 +1065,7 @@ private void ProcessItemMain(uint unitId, BufferItem item, ref NetSegment prevSe
#endif
(Options.relaxedBusses && _extVehicleType == ExtVehicleType.Bus)); // option: busses may ignore lane arrows

bool useRouting = prevLaneEndRouting.routed && !nextIsBeautificationNode;
//bool useRouting = prevLaneEndRouting.routed && !nextIsBeautificationNode;

bool handleStockUturn = !explorePrevSegment &&
(this._vehicleTypes & VehicleInfo.VehicleType.Tram) == VehicleInfo.VehicleType.None;
Expand All @@ -1058,7 +1074,7 @@ private void ProcessItemMain(uint unitId, BufferItem item, ref NetSegment prevSe
//LaneEndGeometry prevLaneEndGeo = prevGeometry.GetLane(item.m_position.m_lane, false)?.GetEnd(!nextIsStartNode);
#if DEBUGNEWPF
if (debug)
logBuf.Add($"item: seg. {item.m_position.m_segment}, lane {item.m_position.m_lane}, node {nextNodeId}:\n" +
logBuf.Add($"item: seg. {item.m_position.m_segment}, lane {item.m_position.m_lane}, node {nextNodeId} ({nextIsStartNode}):\n" +
"\t" + $"_extPathType={_extPathType}\n" +
"\t" + $"_vehicleTypes={_vehicleTypes}, _laneTypes={_laneTypes}\n" +
"\t" + $"_extVehicleType={_extVehicleType}\n" +
Expand Down Expand Up @@ -1127,26 +1143,37 @@ private void ProcessItemMain(uint unitId, BufferItem item, ref NetSegment prevSe
#endif

for (int i = 0; i < 8; ++i) {
ushort nextSegmentId = nextNode.GetSegment(i);
if (nextSegmentId == 0) {
LaneTransitionData[] laneTransitions = prevLaneEndRouting.GetTransitions(i);

if (laneTransitions == null) {
continue;
}

if (nextSegmentId == prevSegmentId) {
if (explorePrevSegment) {
// prevent double exploration of previous segment during this method execution
handleStockUturn = false;
} else {
#if DEBUGNEWPF
if (debug)
logBuf.Add(
$"item: seg. {item.m_position.m_segment}, lane {item.m_position.m_lane}, node {nextNodeId}:\n" +
"\t" + $"CUSTOM exploration iteration {i}\n"
);
#endif


for (int k = 0; k < laneTransitions.Length; ++k) {
ushort nextSegmentId = laneTransitions[k].segmentId;

if (nextSegmentId == 0) {
continue;
}
}

LaneTransitionData[] laneTransitions = prevLaneEndRouting.GetTransitions(i);
if (laneTransitions == null) {
continue;
}
if (nextSegmentId == prevSegmentId) {
if (explorePrevSegment) {
// prevent double exploration of previous segment during this method execution
handleStockUturn = false;
} else {
continue;
}
}

for (int k = 0; k < laneTransitions.Length; ++k) {
if (laneTransitions[k].type == LaneEndTransitionType.Invalid ||
(isStrictLaneArrowPolicyEnabled && laneTransitions[k].type == LaneEndTransitionType.Relaxed)) {
continue;
Expand All @@ -1156,9 +1183,10 @@ private void ProcessItemMain(uint unitId, BufferItem item, ref NetSegment prevSe
if (debug) {
logBuf.Add(
$"item: seg. {item.m_position.m_segment}, lane {item.m_position.m_lane}, node {nextNodeId}:\n" +
"\t" + $"-> CUSTOM exploration iteration {i}\n" +
"\t" + $"next seg={nextSegmentId}, idx={laneTransitions[k].laneIndex}, id={laneTransitions[k].laneId}, type={laneTransitions[k].type}, dist={laneTransitions[k].distance}\n"
);
"\t" + $"CUSTOM exploration iteration {i}:\n" +
"\t" + $"transition iteration {k}:\n" +
"\t" + $"{laneTransitions[k].ToString()}\n"
);
FlushMainLog(logBuf, unitId);
}
#endif
Expand Down Expand Up @@ -1461,37 +1489,36 @@ private bool ProcessItemCosts(bool debug, bool allowAdvancedAI, bool obeyStockLa
} else if (calculateTrafficStats) {
NetInfo.Direction prevFinalDir = nextIsStartNodeOfPrevSegment ? NetInfo.Direction.Forward : NetInfo.Direction.Backward;
prevFinalDir = ((prevSegment.m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None) ? prevFinalDir : NetInfo.InvertDirection(prevFinalDir);
int prevDirIndex = trafficMeasurementManager.GetDirIndex(item.m_position.m_segment, prevFinalDir);
int nextDirIndex = trafficMeasurementManager.GetDirIndex(nextSegmentId, nextFinalDir);

TrafficMeasurementManager.LaneTrafficData[] prevLanesTrafficData;
TrafficMeasurementManager.SegmentDirTrafficData prevDirTrafficData;
TrafficMeasurementManager.SegmentDirTrafficData nextDirTrafficData;
if (trafficMeasurementManager.GetTrafficData(item.m_position.m_segment, prevSegmentInfo, out prevLanesTrafficData) &&
trafficMeasurementManager.GetTrafficData(item.m_position.m_segment, prevFinalDir, out prevDirTrafficData) &&
trafficMeasurementManager.GetTrafficData(nextSegmentId, nextFinalDir, out nextDirTrafficData)
) {
if (trafficMeasurementManager.GetLaneTrafficData(item.m_position.m_segment, prevSegmentInfo, out prevLanesTrafficData)) {
float prevCongestionRatio = trafficMeasurementManager.segmentDirTrafficData[prevDirIndex].numCongestionMeasurements > 0 ? ((uint)trafficMeasurementManager.segmentDirTrafficData[prevDirIndex].numCongested * 100u) / (uint)trafficMeasurementManager.segmentDirTrafficData[prevDirIndex].numCongestionMeasurements : 0; // now in %
float nextCongestionRatio = trafficMeasurementManager.segmentDirTrafficData[nextDirIndex].numCongestionMeasurements > 0 ? ((uint)trafficMeasurementManager.segmentDirTrafficData[nextDirIndex].numCongested * 100u) / (uint)trafficMeasurementManager.segmentDirTrafficData[nextDirIndex].numCongestionMeasurements : 0; // now in %

// get the path-finding lane utilization for the previous lane
if (trafficMeasurementManager.segmentDirTrafficData[prevDirIndex].totalPathFindTrafficBuffer > 0) {
prevUsage = Mathf.Clamp(((prevLanesTrafficData[item.m_position.m_lane].lastPathFindTrafficBuffer * 100u) / trafficMeasurementManager.segmentDirTrafficData[prevDirIndex].totalPathFindTrafficBuffer), 0, 100);
} else {
prevUsage = 0;
}

// get the min. speed for the previous segment
prevTraffic = Mathf.Clamp(100 - (int)trafficMeasurementManager.segmentDirTrafficData[prevDirIndex].meanSpeed / 100, 0, 100);



// get the direction-average minimum speed for the previous segment
#if MARKCONGESTEDSEGMENTS
//int dirIndex = prevLaneInfo.m_finalDirection == NetInfo.Direction.Backward ? 1 : 0;
float prevCongestionRatio = prevDirTrafficData.numCongestionMeasurements > 0 ? ((uint)prevDirTrafficData.numCongested * 100u) / (uint)prevDirTrafficData.numCongestionMeasurements : 0; // now in %
float nextCongestionRatio = nextDirTrafficData.numCongestionMeasurements > 0 ? ((uint)nextDirTrafficData.numCongested * 100u) / (uint)nextDirTrafficData.numCongestionMeasurements : 0; // now in %

isCongested = prevCongestionRatio >= _conf.CongestionFrequencyThreshold || nextCongestionRatio >= _conf.CongestionFrequencyThreshold;
float maxCongestionRatio = Math.Max(prevCongestionRatio, nextCongestionRatio);
congestionLaneChangingCosts = 1f + maxCongestionRatio * 0.01f * _conf.CongestionLaneChangingBaseCost;
wantToChangeLane = _pathRandomizer.Int32((uint)maxCongestionRatio + _conf.RandomizedLaneChangingModulo) == 0;
#endif

// get the path-finding lane utilization for the previous lane
uint totalBuf = prevDirTrafficData.totalPathFindTrafficBuffer;
if (totalBuf > 0) {
prevUsage = Mathf.Clamp(((prevLanesTrafficData[item.m_position.m_lane].lastPathFindTrafficBuffer * 100u) / totalBuf), 0, 100);
} else {
prevUsage = 0;
}

// get the min. speed for the previous segment
prevTraffic = Mathf.Clamp(100 - (int)prevDirTrafficData.meanSpeed / 100, 0, 100);

// prevUsage, prevTraffic is now in %
#if DEBUGNEWPF
float oldUsageRand = usageRand;
Expand Down Expand Up @@ -2542,7 +2569,7 @@ protected virtual bool CanUseLane(bool debug, ushort segmentId, NetInfo segmentI
if (!Options.vehicleRestrictionsEnabled)
return true;

if (_extVehicleType == null || _extVehicleType == ExtVehicleType.None /*|| _extVehicleType == ExtVehicleType.Tram*/)
if (_extVehicleType == null || _extVehicleType == ExtVehicleType.None || _extVehicleType == ExtVehicleType.Tram)
return true;

/*if (laneInfo == null)
Expand All @@ -2551,7 +2578,7 @@ protected virtual bool CanUseLane(bool debug, ushort segmentId, NetInfo segmentI
if ((laneInfo.m_vehicleType & (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train)) == VehicleInfo.VehicleType.None)
return true;

ExtVehicleType allowedTypes = vehicleRestrictionsManager.GetAllowedVehicleTypes(segmentId, segmentInfo, laneIndex, laneInfo, false);
ExtVehicleType allowedTypes = vehicleRestrictionsManager.GetAllowedVehicleTypes(segmentId, segmentInfo, laneIndex, laneInfo, RestrictionMode.Configured);
#if DEBUGPF
if (debug) {
Log._Debug($"CanUseLane: segmentId={segmentId} laneIndex={laneIndex} _extVehicleType={_extVehicleType} _vehicleTypes={_vehicleTypes} _laneTypes={_laneTypes} _transportVehicle={_transportVehicle} _isHeavyVehicle={_isHeavyVehicle} allowedTypes={allowedTypes} res={((allowedTypes & _extVehicleType) != ExtVehicleType.None)}");
Expand Down
4 changes: 2 additions & 2 deletions TLM/TLM/Manager/AbstractSegmentGeometryObservingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ public override void OnLevelUnloading() {

public void OnUpdate(SegmentGeometry geometry) {
if (!geometry.IsValid()) {
Log._Debug($"{this.GetType().Name}.HandleInvalidSegment({geometry.SegmentId})");
//Log._Debug($"{this.GetType().Name}.HandleInvalidSegment({geometry.SegmentId})");
HandleInvalidSegment(geometry);
if (!AllowInvalidSegments) {
UnsubscribeFromSegmentGeometry(geometry.SegmentId);
}
} else {
Log._Debug($"{this.GetType().Name}.HandleValidSegment({geometry.SegmentId})");
//Log._Debug($"{this.GetType().Name}.HandleValidSegment({geometry.SegmentId})");
HandleValidSegment(geometry);
}
}
Expand Down
7 changes: 6 additions & 1 deletion TLM/TLM/Manager/OptionsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ public bool LoadData(byte[] data) {
Options.setParkingRestrictionsOverlay(data[31] == (byte)1);
}

if (data.Length >= 33) {
Options.setBanRegularTrafficOnBusLanes(data[32] == (byte)1);
}

return true;
}

Expand Down Expand Up @@ -184,7 +188,8 @@ public byte[] SaveData(ref bool success) {
(byte)(Options.evacBussesMayIgnoreRules ? 1 : 0),
(byte)(Options.instantEffects ? 1 : 0),
(byte)(Options.parkingRestrictionsEnabled ? 1 : 0),
(byte)(Options.parkingRestrictionsOverlay ? 1 : 0)
(byte)(Options.parkingRestrictionsOverlay ? 1 : 0),
(byte)(Options.banRegularTrafficOnBusLanes ? 1 : 0)
};
}
}
Expand Down
Loading

0 comments on commit 9aacf99

Please sign in to comment.