Skip to content

Commit

Permalink
1.9.0-alpha2:
Browse files Browse the repository at this point in the history
- Added copy & rotate feature for timed traffic lights
- Fixed several bugs related to timed traffic lights
  • Loading branch information
VictorPhilipp committed Apr 17, 2017
1 parent c815ac1 commit e413c37
Show file tree
Hide file tree
Showing 23 changed files with 711 additions and 259 deletions.
24 changes: 12 additions & 12 deletions TLM/TLM/Custom/AI/CustomTrainAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,18 +282,18 @@ public void CustomCheckNextLane(ushort vehicleID, ref Vehicle vehicleData, ref f
}
}

NetManager instance = Singleton<NetManager>.instance;
NetManager netManager = Singleton<NetManager>.instance;
Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();
Vector3 a = lastFrameData.m_position;
Vector3 a2 = lastFrameData.m_position;
Vector3 lastPos = lastFrameData.m_position;
Vector3 lastPos2 = lastFrameData.m_position;
Vector3 b = lastFrameData.m_rotation * new Vector3(0f, 0f, this.m_info.m_generatedInfo.m_wheelBase * 0.5f);
a += b;
a2 -= b;
lastPos += b;
lastPos2 -= b;
float num = 0.5f * lastFrameData.m_velocity.sqrMagnitude / this.m_info.m_braking;
float a3 = Vector3.Distance(a, bezier.a);
float b2 = Vector3.Distance(a2, bezier.a);
float a3 = Vector3.Distance(lastPos, bezier.a);
float b2 = Vector3.Distance(lastPos2, bezier.a);
if (Mathf.Min(a3, b2) >= num - 5f) {
if (!instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(1000f, vehicleID)) {
if (!netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(1000f, vehicleID)) {
maxSpeed = 0f;
return;
}
Expand All @@ -319,15 +319,15 @@ public void CustomCheckNextLane(ushort vehicleID, ref Vehicle vehicleData, ref f
//if (this.m_info.m_vehicleType != VehicleInfo.VehicleType.Monorail) { // NON-STOCK CODE
ushort targetNodeId;
if (offset < position.m_offset) {
targetNodeId = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode;
targetNodeId = netManager.m_segments.m_buffer[(int)position.m_segment].m_startNode;
} else {
targetNodeId = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode;
targetNodeId = netManager.m_segments.m_buffer[(int)position.m_segment].m_endNode;
}
ushort prevTargetNodeId;
if (prevOffset == 0) {
prevTargetNodeId = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_startNode;
prevTargetNodeId = netManager.m_segments.m_buffer[(int)prevPos.m_segment].m_startNode;
} else {
prevTargetNodeId = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_endNode;
prevTargetNodeId = netManager.m_segments.m_buffer[(int)prevPos.m_segment].m_endNode;
}
if (targetNodeId == prevTargetNodeId) {
float oldMaxSpeed = maxSpeed;
Expand Down
3 changes: 2 additions & 1 deletion TLM/TLM/Custom/PathFinding/CustomPathFind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1760,8 +1760,9 @@ private void ProcessItemMain(uint unitId, BufferItem item, ref NetSegment prevSe
totalOutgoingLanes += outgoingVehicleLanes;
}

if (explorePrevSegment && nextSegmentId == prevSegmentId)
if (explorePrevSegment && nextSegmentId == prevSegmentId) {
break;
}
} // foreach segment
#if DEBUGPF
if (debug)
Expand Down
38 changes: 36 additions & 2 deletions TLM/TLM/Geometry/SegmentEndGeometry.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using ColossalFramework;
using GenericGameBridge.Service;
using System;
using System.Collections.Generic;
using System.Linq;
Expand Down Expand Up @@ -160,13 +161,22 @@ public override string ToString() {
"\t" + $"OnlyHighways = {OnlyHighways}\n" +
"\t" + $"OutgoingOneWay = {OutgoingOneWay}\n" +
"\t" + $"IncomingOneWay = {IncomingOneWay}\n" +
"\t" + $"GetClockwiseIndex() = {GetClockwiseIndex()}\n" +
"SegmentEndGeometry]";
}

public SegmentEndGeometry(ushort segmentId, bool startNode) : base(segmentId, startNode) {

}

public static SegmentEndGeometry Get(SegmentEndId endId) {
return Get(endId.SegmentId, endId.StartNode);
}

public static SegmentEndGeometry Get(ushort segmentId, bool startNode) {
return SegmentGeometry.Get(segmentId).GetEnd(startNode);
}

internal void Cleanup() {
for (int i = 0; i < 7; ++i) {
ConnectedSegments[i] = 0;
Expand Down Expand Up @@ -276,6 +286,22 @@ public SegmentGeometry GetSegmentGeometry() {
return SegmentGeometry.Get(SegmentId);
}

public short GetClockwiseIndex() {
// calculate clockwise index
short clockwiseIndex = -1;
Constants.ServiceFactory.NetService.IterateNodeSegments(NodeId(), ClockDirection.Clockwise, delegate (ushort sId, ref NetSegment segment) {
++clockwiseIndex;
//Log._Debug($"SegmentEndGeometry.Recalculate: Setting clockwise index of seg. {sId} to {clockwiseIndex} (we are @ seg. {SegmentId})");

if (sId == SegmentId) {
return false;
}
return true;
});

return clockwiseIndex;
}

internal void Recalculate(GeometryCalculationMode calcMode) {
#if DEBUGGEO
if (GlobalConfig.Instance.DebugSwitches[5])
Expand All @@ -297,7 +323,7 @@ internal void Recalculate(GeometryCalculationMode calcMode) {
return;
}

NetManager netManager = Singleton<NetManager>.instance;
//NetManager netManager = Singleton<NetManager>.instance;

ushort nodeId = NodeId();
LastKnownNodeId = nodeId;
Expand All @@ -313,9 +339,17 @@ internal void Recalculate(GeometryCalculationMode calcMode) {

//ItemClass connectionClass = netManager.m_segments.m_buffer[SegmentId].Info.GetConnectionClass();

ushort firstClockwiseSegmentId = 0;
bool hasOtherSegments = false;
for (var s = 0; s < 8; s++) {
ushort otherSegmentId = netManager.m_nodes.m_buffer[nodeId].GetSegment(s);
ushort otherSegmentId = 0;
Constants.ServiceFactory.NetService.ProcessNode(nodeId, delegate (ushort nId, ref NetNode node) {
otherSegmentId = node.GetSegment(s);
if (s == 0) {
firstClockwiseSegmentId = otherSegmentId;
}
return true;
});
if (otherSegmentId == 0 || otherSegmentId == SegmentId || ! SegmentGeometry.IsValid(otherSegmentId))
continue;
/*ItemClass otherConnectionClass = Singleton<NetManager>.instance.m_segments.m_buffer[otherSegmentId].Info.GetConnectionClass();
Expand Down
15 changes: 7 additions & 8 deletions TLM/TLM/Geometry/SegmentGeometry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1020,13 +1020,13 @@ internal static bool calculateIsOutgoingOneWay(ushort segmentId, ushort nodeId)

var info = instance.m_segments.m_buffer[segmentId].Info;

NetInfo.Direction dir = Constants.ServiceFactory.NetService.GetSegmentEndDirection(segmentId, ref instance.m_segments.m_buffer[segmentId], instance.m_segments.m_buffer[segmentId].m_startNode == nodeId);
NetInfo.Direction dir = Constants.ServiceFactory.NetService.GetFinalSegmentEndDirection(segmentId, ref instance.m_segments.m_buffer[segmentId], instance.m_segments.m_buffer[segmentId].m_startNode == nodeId);

var laneId = instance.m_segments.m_buffer[segmentId].m_lanes;
var laneIndex = 0;
while (laneIndex < info.m_lanes.Length && laneId != 0u) {
if (info.m_lanes[laneIndex].m_laneType != NetInfo.LaneType.Pedestrian &&
((info.m_lanes[laneIndex].m_direction & dir) != NetInfo.Direction.None)) {
((info.m_lanes[laneIndex].m_finalDirection & dir) != NetInfo.Direction.None)) {
return false;
}

Expand Down Expand Up @@ -1056,12 +1056,12 @@ private static bool calculateIsOneWay(ushort segmentId) {
var laneIndex = 0;
while (laneIndex < info.m_lanes.Length && laneId != 0u) {
if (info.m_lanes[laneIndex].m_laneType != NetInfo.LaneType.Pedestrian &&
(info.m_lanes[laneIndex].m_direction == NetInfo.Direction.Forward)) {
(info.m_lanes[laneIndex].m_direction & NetInfo.Direction.Forward) != NetInfo.Direction.None) {
hasForward = true;
}

if (info.m_lanes[laneIndex].m_laneType != NetInfo.LaneType.Pedestrian &&
(info.m_lanes[laneIndex].m_direction == NetInfo.Direction.Backward)) {
(info.m_lanes[laneIndex].m_direction & NetInfo.Direction.Backward) != NetInfo.Direction.None) {
hasBackward = true;
}

Expand Down Expand Up @@ -1113,7 +1113,6 @@ internal static void calculateOneWayAtNode(ushort segmentId, ushort nodeId, out
if (instance.m_segments.m_buffer[segmentId].m_startNode == nodeId)
dir = NetInfo.Direction.Backward;
var dir2 = ((instance.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None) ? dir : NetInfo.InvertDirection(dir);
var dir3 = Constants.ServiceFactory.SimulationService.LeftHandDrive ? NetInfo.InvertDirection(dir2) : dir2;

var hasForward = false;
var hasBackward = false;
Expand All @@ -1122,17 +1121,17 @@ internal static void calculateOneWayAtNode(ushort segmentId, ushort nodeId, out
var laneIndex = 0;
while (laneIndex < info.m_lanes.Length && laneId != 0u) {
if (info.m_lanes[laneIndex].m_laneType != NetInfo.LaneType.Pedestrian &&
(info.m_lanes[laneIndex].m_direction == dir3)) {
(info.m_lanes[laneIndex].m_finalDirection & dir2) != NetInfo.Direction.None) {
isOutgoingOneWay = false;
}

if (info.m_lanes[laneIndex].m_laneType != NetInfo.LaneType.Pedestrian &&
(info.m_lanes[laneIndex].m_direction == NetInfo.Direction.Forward)) {
(info.m_lanes[laneIndex].m_direction & NetInfo.Direction.Forward) != NetInfo.Direction.None) {
hasForward = true;
}

if (info.m_lanes[laneIndex].m_laneType != NetInfo.LaneType.Pedestrian &&
(info.m_lanes[laneIndex].m_direction == NetInfo.Direction.Backward)) {
(info.m_lanes[laneIndex].m_direction & NetInfo.Direction.Backward) != NetInfo.Direction.None) {
hasBackward = true;
}

Expand Down
52 changes: 51 additions & 1 deletion TLM/TLM/Manager/CustomSegmentLightsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using TrafficManager.TrafficLight;
using TrafficManager.State;
using System.Linq;
using TrafficManager.Traffic;

namespace TrafficManager.Manager {
/// <summary>
Expand Down Expand Up @@ -102,6 +103,26 @@ public CustomSegmentLights AddSegmentLights(ushort segmentId, bool startNode, Ro
}
}

public bool SetSegmentLights(ushort nodeId, ushort segmentId, CustomSegmentLights lights) {
SegmentEndGeometry endGeo = SegmentGeometry.Get(segmentId).GetEnd(nodeId);
if (endGeo == null) {
return false;
}

CustomSegment customSegment = CustomSegments[segmentId];
if (customSegment == null) {
customSegment = new CustomSegment();
CustomSegments[segmentId] = customSegment;
}

if (endGeo.StartNode) {
customSegment.StartNodeLights = lights;
} else {
customSegment.EndNodeLights = lights;
}
return true;
}

/// <summary>
/// Add custom traffic lights at the given node
/// </summary>
Expand Down Expand Up @@ -221,6 +242,29 @@ public CustomSegmentLights GetSegmentLights(ushort segmentId, bool startNode, bo
}
}

internal void SetLightMode(ushort segmentId, bool startNode, ExtVehicleType vehicleType, CustomSegmentLight.Mode mode) {
CustomSegmentLights liveLights = GetSegmentLights(segmentId, startNode);
CustomSegmentLight liveLight = liveLights.GetCustomLight(vehicleType);
if (liveLight == null) {
Log.Error($"CustomSegmentLightsManager.SetLightMode: Cannot change light mode on seg. {segmentId} @ {startNode} for vehicle type {vehicleType} to {mode}: Vehicle light not found");
return;
}
liveLight.CurrentMode = mode;
}

internal void SetLightModes(ushort segmentId, bool startNode, CustomSegmentLights otherLights) {
CustomSegmentLights sourceLights = GetSegmentLights(segmentId, startNode);
foreach (KeyValuePair<ExtVehicleType, CustomSegmentLight> e in sourceLights.CustomLights) {
ExtVehicleType vehicleType = e.Key;
CustomSegmentLight targetLight = e.Value;

CustomSegmentLight sourceLight;
if (otherLights.CustomLights.TryGetValue(vehicleType, out sourceLight)) {
targetLight.CurrentMode = sourceLight.CurrentMode;
}
}
}

public CustomSegmentLights GetSegmentLights(ushort nodeId, ushort segmentId) {
SegmentEndGeometry endGeometry = SegmentGeometry.Get(segmentId).GetEnd(nodeId);
if (endGeometry == null) {
Expand All @@ -242,6 +286,12 @@ public override void OnLevelUnloading() {
CustomSegments = new CustomSegment[NetManager.MAX_SEGMENT_COUNT];
}


public short ClockwiseIndexOfSegmentEnd(SegmentEndId endId) {
SegmentEndGeometry endGeo = SegmentGeometry.Get(endId.SegmentId).GetEnd(endId.StartNode);
if (endGeo == null) {
return 0;
}
return endGeo.GetClockwiseIndex();
}
}
}
5 changes: 2 additions & 3 deletions TLM/TLM/Manager/VehicleRestrictionsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,8 @@ internal IDictionary<byte, ExtVehicleType> GetAllowedVehicleTypesAsDict(ushort s
while (laneIndex < numLanes && curLaneId != 0u) {
NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex];
if (laneInfo.m_vehicleType != VehicleInfo.VehicleType.None) {
ushort toNodeId = (laneInfo.m_finalDirection == dir2) ? netManager.m_segments.m_buffer[segmentId].m_endNode : netManager.m_segments.m_buffer[segmentId].m_startNode;

if (toNodeId == nodeId) {
ushort toNodeId = (laneInfo.m_finalDirection & dir2) != NetInfo.Direction.None ? netManager.m_segments.m_buffer[segmentId].m_endNode : netManager.m_segments.m_buffer[segmentId].m_startNode;
if ((laneInfo.m_finalDirection & NetInfo.Direction.Both) == NetInfo.Direction.Both || toNodeId == nodeId) {
ExtVehicleType vehicleTypes = GetAllowedVehicleTypes(segmentId, segmentInfo, laneIndex, laneInfo);
ret[(byte)laneIndex] = vehicleTypes;
}
Expand Down
2 changes: 1 addition & 1 deletion TLM/TLM/Resources/lang.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ Rotate_right Rotate right
Name Name
Apply Apply
Select_a_timed_traffic_light_program Select a timed traffic light program
The_chosen_traffic_light_program_is_incompatible_to_this_junction The chosen traffic light pattern is incompatible to this junction
The_chosen_traffic_light_program_is_incompatible_to_this_junction The chosen traffic light pattern is incompatible with this junction
Advanced_AI_cannot_be_activated Advanced AI cannot be activated
The_Advanced_Vehicle_AI_cannot_be_activated The Advanced Vehicle AI cannot be activated because you are already using another mod that modifies vehicle behavior (e.g. Improved AI or Traffic++).
Enable_dynamic_path_calculation Enable dynamic path calculation
Expand Down
3 changes: 1 addition & 2 deletions TLM/TLM/State/Flags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,6 @@ internal static bool mayHaveLaneArrows(uint laneId, bool? startNode=null) {

var dir = NetInfo.Direction.Forward;
var dir2 = ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None) ? dir : NetInfo.InvertDirection(dir);
var dir3 = Constants.ServiceFactory.SimulationService.LeftHandDrive ? NetInfo.InvertDirection(dir2) : dir2;

NetInfo segmentInfo = netManager.m_segments.m_buffer[segmentId].Info;
uint curLaneId = netManager.m_segments.m_buffer[segmentId].m_lanes;
Expand All @@ -704,7 +703,7 @@ internal static bool mayHaveLaneArrows(uint laneId, bool? startNode=null) {

if (curLaneId == laneId) {
NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex];
bool isStartNode = laneInfo.m_direction != dir3;
bool isStartNode = (laneInfo.m_finalDirection & dir2) == NetInfo.Direction.None;
if (startNode != null && isStartNode != startNode)
return false;
ushort nodeId = isStartNode ? netManager.m_segments.m_buffer[segmentId].m_startNode : netManager.m_segments.m_buffer[segmentId].m_endNode;
Expand Down
2 changes: 1 addition & 1 deletion TLM/TLM/TLM.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugGeometry|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\DebugGeometry\</OutputPath>
<DefineConstants>DEBUG;QUEUEDSTATS;DEBUGGEO;DEBUGVSTATE</DefineConstants>
<DefineConstants>DEBUG;QUEUEDSTATS;DEBUGGEO;DEBUGVSTATE;DEBUGTTL</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<WarningLevel>0</WarningLevel>
<DebugType>full</DebugType>
Expand Down
7 changes: 5 additions & 2 deletions TLM/TLM/Traffic/SegmentEnd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,11 @@ private void UnregisterAllVehicles() {
}

internal void Update() {
StartNode = Singleton<NetManager>.instance.m_segments.m_buffer[SegmentId].m_startNode == NodeId;
numLanes = Singleton<NetManager>.instance.m_segments.m_buffer[SegmentId].Info.m_lanes.Length;
Constants.ServiceFactory.NetService.ProcessSegment(SegmentId, delegate(ushort segmentId, ref NetSegment segment) {
StartNode = segment.m_startNode == NodeId;
numLanes = segment.Info.m_lanes.Length;
return true;
});
ushort[] outgoingSegmentIds = SegmentGeometry.Get(SegmentId).GetOutgoingSegments(StartNode);
numVehiclesMovingToSegmentId = new TinyDictionary<ushort, uint>[numLanes];
numVehiclesGoingToSegmentId = new TinyDictionary<ushort, uint>[numLanes];
Expand Down
Loading

0 comments on commit e413c37

Please sign in to comment.