/*public VehiclePosition GetCurrentPosition() {
         *      LinkedListNode<VehiclePosition> firstNode = CurrentPosition;
         *      if (firstNode == null)
         *              return null;
         *      return firstNode.Value;
         * }*/

        internal void UpdatePosition(ref Vehicle vehicleData, ref PathUnit.Position curPos, ref PathUnit.Position nextPos, bool skipCheck = false)
        {
            if (!skipCheck && !CheckValidity(ref vehicleData))
            {
                return;
            }

            LastPositionUpdate = Singleton <SimulationManager> .instance.m_currentFrameIndex;

            SegmentEnd end = TrafficPriority.GetPrioritySegment(GetTransitNodeId(ref curPos, ref nextPos), curPos.m_segment);

            if (CurrentSegmentEnd != end)
            {
                if (CurrentSegmentEnd != null)
                {
                    Unlink();
                }

                WaitTime = 0;
                if (end != null)
                {
                    Link(end);
                    JunctionTransitState = VehicleJunctionTransitState.Enter;
                }
                else
                {
                    JunctionTransitState = VehicleJunctionTransitState.None;
                }
            }
        }
        private void Link(SegmentEnd end)
        {
            ushort oldFirstRegVehicleId = end.FirstRegisteredVehicleId;

            if (oldFirstRegVehicleId != 0)
            {
                VehicleStateManager._GetVehicleState(oldFirstRegVehicleId).PreviousVehicleIdOnSegment = VehicleId;
                NextVehicleIdOnSegment = oldFirstRegVehicleId;
            }
            end.FirstRegisteredVehicleId = VehicleId;
            CurrentSegmentEnd            = end;
        }
		public static void AddPrioritySegment(ushort nodeId, ushort segmentId, SegmentEnd.PriorityType type) {
			if (nodeId <= 0 || segmentId <= 0)
				return;

			Log.Info("adding PrioritySegment @ node " + nodeId + ", seg. " + segmentId + ", type " + type);

			var prioritySegment = PrioritySegments[segmentId];
			if (prioritySegment != null) { // do not replace with IsPrioritySegment!
				prioritySegment.Segment = segmentId;

				Log._Debug("Priority segment already exists. Node1=" + prioritySegment.Node1 + " Node2=" + prioritySegment.Node2);

				if (prioritySegment.Node1 == nodeId || prioritySegment.Node1 == 0) {
					Log._Debug("Updating Node1");
					prioritySegment.Node1 = nodeId;
					PrioritySegments[segmentId].Instance1 = new SegmentEnd(nodeId, segmentId, type);
					return;
				}

				if (prioritySegment.Node2 != 0) {
					// overwrite Node2
					Log.Warning("Overwriting priority segment for node " + nodeId + ", seg. " + segmentId + ", type " + type);
					prioritySegment.Node2 = nodeId;
					prioritySegment.Instance2 = new SegmentEnd(nodeId, segmentId, type);
					rebuildPriorityNodes();
				} else {
					// add Node2
					Log._Debug("Adding as Node2");
					prioritySegment.Node2 = nodeId;
					prioritySegment.Instance2 = new SegmentEnd(nodeId, segmentId, type);
				}
			} else {
				// add Node1
				Log._Debug("Adding as Node1");
				prioritySegment = new TrafficSegment();
				prioritySegment.Segment = segmentId;
				prioritySegment.Node1 = nodeId;
				prioritySegment.Instance1 = new SegmentEnd(nodeId, segmentId, type);
				PrioritySegments[segmentId] = prioritySegment;
			}
			priorityNodes.Add(nodeId);
		}
Пример #4
0
        internal void Recalculate()
        {
#if DEBUGGEO
            Log._Debug($"NodeGeometry: Recalculate @ {NodeId}");
#endif

            Cleanup();

            Flags.applyNodeTrafficLightFlag(NodeId);

            // check if node is valid
            if (!IsValid())
            {
                for (int i = 0; i < 8; ++i)
                {
                    SegmentEndGeometries[i] = null;
                }
                TrafficLightSimulation.RemoveNodeFromSimulation(NodeId, false, true);
                Flags.setNodeTrafficLight(NodeId, false);
            }
            else
            {
                NetManager netManager      = Singleton <NetManager> .instance;
                bool       hasTrafficLight = (netManager.m_nodes.m_buffer[NodeId].m_flags & NetNode.Flags.TrafficLights) != NetNode.Flags.None;
                var        nodeSim         = TrafficLightSimulation.GetNodeSimulation(NodeId);
                if (nodeSim == null)
                {
                    byte numSegmentsWithSigns = 0;
                    for (var s = 0; s < 8; s++)
                    {
                        var segmentId = netManager.m_nodes.m_buffer[NodeId].GetSegment(s);
                        if (segmentId <= 0)
                        {
                            continue;
                        }

#if DEBUGx
                        Log._Debug($"NodeGeometry.Recalculate: Housekeeping segment {segmentId}");
#endif

                        SegmentEnd prioritySegment = TrafficPriority.GetPrioritySegment(NodeId, segmentId);
                        if (prioritySegment == null)
                        {
                            continue;
                        }

                        // if node is a traffic light, it must not have priority signs
                        if (hasTrafficLight && prioritySegment.Type != SegmentEnd.PriorityType.None)
                        {
                            Log.Warning($"Housekeeping: Node {NodeId}, Segment {segmentId} is a priority sign but node has a traffic light!");
                            prioritySegment.Type = SegmentEnd.PriorityType.None;
                        }

                        // if a priority sign is set, everything is ok
                        if (prioritySegment.Type != SegmentEnd.PriorityType.None)
                        {
                            ++numSegmentsWithSigns;
                        }
                    }

                    if (numSegmentsWithSigns > 0)
                    {
                        // add priority segments for newly created segments
                        numSegmentsWithSigns += TrafficPriority.AddPriorityNode(NodeId);
                    }
                }

                // calculate node properties
                byte incomingSegments = 0;
                byte outgoingSegments = 0;
                for (int i = 0; i < 8; ++i)
                {
                    if (SegmentEndGeometries[i] == null)
                    {
                        continue;
                    }
#if DEBUGGEO
                    Log._Debug($"NodeGeometry.Recalculate: Iterating over segment end {SegmentEndGeometries[i].SegmentId} @ node {NodeId}");
#endif

                    bool startNode = SegmentEndGeometries[i].StartNode;
                    if (SegmentEndGeometries[i].GetSegmentGeometry().IsIncoming(startNode))
                    {
                        ++incomingSegments;
                    }
                    if (SegmentEndGeometries[i].GetSegmentGeometry().IsOutgoing(startNode))
                    {
                        ++outgoingSegments;
                    }
                }

                IsSimpleJunction = incomingSegments == 1 || outgoingSegments == 1;
#if DEBUGGEO
                Log._Debug($"NodeGeometry.Recalculate: Node {NodeId} has {incomingSegments} incoming and {outgoingSegments} outgoing segments.");
#endif
            }

            NotifyObservers();
        }