private void _guiSpeedLimitsWindow(int num)
        {
            GUILayout.BeginHorizontal();

            Color oldColor = GUI.color;

            for (int i = 0; i < SpeedLimitManager.Instance().AvailableSpeedLimits.Count; ++i)
            {
                if (curSpeedLimitIndex != i)
                {
                    GUI.color = Color.gray;
                }
                float signSize = TrafficManagerTool.AdaptWidth(guiSpeedSignSize);
                if (GUILayout.Button(TrafficLightToolTextureResources.SpeedLimitTextures[SpeedLimitManager.Instance().AvailableSpeedLimits[i]], GUILayout.Width(signSize), GUILayout.Height(signSize)))
                {
                    curSpeedLimitIndex = i;
                }
                GUI.color = oldColor;

                if (i == 6)
                {
                    GUILayout.EndHorizontal();
                    GUILayout.BeginHorizontal();
                }
            }

            GUILayout.EndHorizontal();
            GUI.DragWindow();
        }
        protected virtual void CalculateSegPos(ushort vehicleID, ref Vehicle vehicleData, PathUnit.Position position, uint laneID, byte offset, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            NetManager instance = Singleton <NetManager> .instance;

            instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection((float)offset * 0.003921569f, out pos, out dir);
            NetInfo info = instance.m_segments.m_buffer[(int)position.m_segment].Info;

            if (info.m_lanes != null && info.m_lanes.Length > (int)position.m_lane)
            {
                var laneSpeedLimit = SpeedLimitManager.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, info.m_lanes[position.m_lane]);
                maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, laneSpeedLimit, instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve);
            }
            else
            {
                maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, 1f, 0f);
            }
        }
        public void CustomCalculateSegmentPositionPathFinder(ushort vehicleID, ref Vehicle vehicleData, PathUnit.Position position, uint laneID, byte offset, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            NetManager instance = Singleton <NetManager> .instance;

            instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection((float)offset * 0.003921569f, out pos, out dir);
            NetInfo info = instance.m_segments.m_buffer[(int)position.m_segment].Info;

            if (info.m_lanes != null && info.m_lanes.Length > (int)position.m_lane)
            {
                float speedLimit = Options.customSpeedLimitsEnabled ? SpeedLimitManager.Instance().GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, info.m_lanes[position.m_lane]) : info.m_lanes[position.m_lane].m_speedLimit;
                maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, speedLimit, instance.m_lanes.m_buffer[laneID].m_curve);
            }
            else
            {
                maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, 1f, 0f);
            }
        }
예제 #4
0
        public void CustomCalculateSegmentPositionPathFinder(ushort vehicleId, ref Vehicle vehicleData, PathUnit.Position position, uint laneId, byte offset, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            var netManager = Singleton <NetManager> .instance;

            netManager.m_lanes.m_buffer[(int)((UIntPtr)laneId)].CalculatePositionAndDirection(offset * 0.003921569f,
                                                                                              out pos, out dir);
            var info = netManager.m_segments.m_buffer[position.m_segment].Info;

            if (info.m_lanes != null && info.m_lanes.Length > position.m_lane)
            {
                var laneSpeedLimit = SpeedLimitManager.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneId, info.m_lanes[position.m_lane]);                 //info.m_lanes[position.m_lane].m_speedLimit;
                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, laneSpeedLimit, netManager.m_lanes.m_buffer[(int)((UIntPtr)laneId)].m_curve);
            }
            else
            {
                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f);
            }

            maxSpeed = CalcMaxSpeed(vehicleId, ref vehicleData, position, pos, maxSpeed, IsRecklessDriver(vehicleId, ref vehicleData));
        }
        public override void OnSaveData()
        {
            bool success = true;

            // try {
            //    Log.Info("Recalculating segment geometries");
            //    SegmentGeometry.OnBeforeSaveData();
            // }
            // catch (Exception e) {
            //    Log.Error(
            //        $"OnSaveData: Exception occurred while calling SegmentGeometry.OnBeforeSaveData: {e.ToString()}");
            //    error = true;
            // }

            foreach (ICustomManager manager in LoadingExtension.RegisteredManagers)
            {
                try {
                    Log.Info($"OnBeforeSaveData: {manager.GetType().Name}");
                    manager.OnBeforeSaveData();
                }
                catch (Exception e) {
                    Log.Error($"OnSaveData: Error while notifying {manager.GetType().Name}.OnBeforeSaveData: {e}");
                    success = false;
                }
            }

            try {
                Log.Info("Saving Mod Data.");
                var configuration = new Configuration();

                //------------------
                // Citizens
                //------------------
                configuration.ExtCitizens         = ExtCitizenManager.Instance.SaveData(ref success);
                configuration.ExtCitizenInstances = ExtCitizenInstanceManager.Instance.SaveData(ref success);

                //------------------
                // Traffic Priorities
                //------------------
                configuration.PrioritySegments = TrafficPriorityManager.AsPrioritySegmentsDM()
                                                 .SaveData(ref success);
                configuration.CustomPrioritySegments = TrafficPriorityManager.AsCustomPrioritySegmentsDM()
                                                       .SaveData(ref success);

                //------------------
                // Junction Restrictions
                //------------------
                configuration.SegmentNodeConfs = JunctionRestrictionsManager.Instance.SaveData(ref success);

                //------------------
                // Traffic Lights
                //------------------
                configuration.TimedLights = TrafficLightSimulationManager.Instance.SaveData(ref success);

                // configuration.NodeTrafficLights = ((ICustomDataManager<string>)TrafficLightManager.Instance)
                // .SaveData(ref success);
                // configuration.ToggledTrafficLights =
                // ((ICustomDataManager<List<Configuration.NodeTrafficLight>>)TrafficLightManager.Instance)
                // .SaveData(ref success);

                //------------------
                // Lane Arrows and Connections
                //------------------
                configuration.LaneFlags  = LaneArrowManager.AsLaneFlagsDM().SaveData(ref success);
                configuration.LaneArrows = LaneArrowManager.AsLaneArrowsDM().SaveData(ref success);

                configuration.LaneConnections = LaneConnectionManager.Instance.SaveData(ref success);

                //------------------
                // Speed Limits
                //------------------
                configuration.LaneSpeedLimits          = SpeedLimitManager.AsLaneSpeedLimitsDM().SaveData(ref success);
                configuration.CustomDefaultSpeedLimits = SpeedLimitManager.AsCustomDefaultSpeedLimitsDM()
                                                         .SaveData(ref success);

                //------------------
                // Vehicle and Parking Restrictions
                //------------------
                configuration.LaneAllowedVehicleTypes = VehicleRestrictionsManager.Instance.SaveData(ref success);
                configuration.ParkingRestrictions     = ParkingRestrictionsManager.Instance.SaveData(ref success);

                try {
                    // save options
                    _serializableData.SaveData("TMPE_Options", OptionsManager.Instance.SaveData(ref success));
                } catch (Exception ex) {
                    Log.Error("Unexpected error while saving options: " + ex.Message);
                    success = false;
                }

                var binaryFormatter = new BinaryFormatter();
                var memoryStream    = new MemoryStream();

                try {
                    binaryFormatter.Serialize(memoryStream, configuration);
                    memoryStream.Position = 0;
                    Log.Info($"Save data byte length {memoryStream.Length}");
                    _serializableData.SaveData(DATA_ID, memoryStream.ToArray());
                } catch (Exception ex) {
                    Log.Error("Unexpected error while saving data: " + ex);
                    success = false;
                } finally {
                    memoryStream.Close();
                }

                var reverseManagers = new List <ICustomManager>(LoadingExtension.RegisteredManagers);
                reverseManagers.Reverse();
                foreach (ICustomManager manager in reverseManagers)
                {
                    try {
                        Log.Info($"OnAfterSaveData: {manager.GetType().Name}");
                        manager.OnAfterSaveData();
                    }
                    catch (Exception e) {
                        Log.Error(
                            $"OnSaveData: Error while notifying {manager.GetType().Name}.OnAfterSaveData: {e}");
                        success = false;
                    }
                }
            } catch (Exception e) {
                success = false;
                Log.Error($"Error occurred while saving data: {e}");

                // UIView.library.ShowModal<ExceptionPanel>("ExceptionPanel")
                // .SetMessage("An error occurred while saving", "Traffic Manager: President Edition
                // detected an error while saving. To help preventing future errors, please navigate
                // to http://steamcommunity.com/sharedfiles/filedetails/?id=583429740 and follow
                // the steps under 'In case problems arise'.", true);
            }
        }
예제 #6
0
        public void CustomCalculateSegmentPosition(ushort vehicleId, ref Vehicle vehicleData, PathUnit.Position nextPosition,
                                                   PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID,
                                                   byte prevOffset, int index, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            var netManager = Singleton <NetManager> .instance;

            //var vehicleManager = Singleton<VehicleManager>.instance;
            netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection(offset * 0.003921569f, out pos, out dir);
            bool isRecklessDriver = IsRecklessDriver(vehicleId, ref vehicleData);

            var lastFrameData       = vehicleData.GetLastFrameData();
            var lastFrameVehiclePos = lastFrameData.m_position;

            var  camPos = Camera.main.transform.position;
            bool simulatePrioritySigns = (lastFrameVehiclePos - camPos).sqrMagnitude < FarLod && !isRecklessDriver;

            if (Options.simAccuracy <= 0)
            {
                if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Car)
                {
                    VehiclePosition vehiclePos = TrafficPriority.GetVehiclePosition(vehicleId);
                    if (vehiclePos.Valid && simulatePrioritySigns)                       // TODO check if this should be !vehiclePos.Valid
                    {
                        try {
                            CustomVehicleAI.HandleVehicle(vehicleId, ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleId], false, false);
                        } catch (Exception e) {
                            Log.Error("CarAI TmCalculateSegmentPosition Error: " + e.ToString());
                        }
                    }
                }
                else
                {
                    //Log._Debug($"TmCalculateSegmentPosition does not handle vehicles of type {vehicleData.Info.m_vehicleType}");
                }
            }

            // I think this is supposed to be the lane position?
            // [VN, 12/23/2015] It's the 3D car position on the Bezier curve of the lane.
            // This crazy 0.003921569f equals to 1f/255 and prevOffset is the byte value (0..255) of the car position.
            var vehiclePosOnBezier = netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].CalculatePosition(prevOffset * 0.003921569f);
            //ushort currentSegmentId = netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_segment;

            ushort destinationNodeId;
            ushort sourceNodeId;

            if (offset < position.m_offset)
            {
                destinationNodeId = netManager.m_segments.m_buffer[position.m_segment].m_startNode;
                sourceNodeId      = netManager.m_segments.m_buffer[position.m_segment].m_endNode;
            }
            else
            {
                destinationNodeId = netManager.m_segments.m_buffer[position.m_segment].m_endNode;
                sourceNodeId      = netManager.m_segments.m_buffer[position.m_segment].m_startNode;
            }
            var previousDestinationNode = prevOffset == 0 ? netManager.m_segments.m_buffer[prevPos.m_segment].m_startNode : netManager.m_segments.m_buffer[prevPos.m_segment].m_endNode;

            // this seems to be like the required braking force in order to stop the vehicle within its half length.
            var crazyValue = 0.5f * lastFrameData.m_velocity.sqrMagnitude / m_info.m_braking + m_info.m_generatedInfo.m_size.z * 0.5f;

            // Essentially, this is true if the car has enough time and space to brake (e.g. for a red traffic light)
            if (destinationNodeId == previousDestinationNode)
            {
                if (Vector3.Distance(lastFrameVehiclePos, vehiclePosOnBezier) >= crazyValue - 1f)
                {
                    var currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                    var num5 = (uint)((previousDestinationNode << 8) / 32768);
                    var num6 = currentFrameIndex - num5 & 255u;

                    var  nodeFlags        = netManager.m_nodes.m_buffer[destinationNodeId].m_flags;
                    var  prevLaneFlags    = (NetLane.Flags)netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_flags;
                    var  hasTrafficLight  = (nodeFlags & NetNode.Flags.TrafficLights) != NetNode.Flags.None;
                    var  hasCrossing      = (nodeFlags & NetNode.Flags.LevelCrossing) != NetNode.Flags.None;
                    var  isJoinedJunction = (prevLaneFlags & NetLane.Flags.JoinedJunction) != NetLane.Flags.None;
                    bool checkSpace       = !Flags.getEnterWhenBlockedAllowed(prevPos.m_segment, netManager.m_segments.m_buffer[prevPos.m_segment].m_startNode == destinationNodeId) && !isRecklessDriver;
                    //TrafficLightSimulation nodeSim = TrafficLightSimulation.GetNodeSimulation(destinationNodeId);

                    /*if (timedNode != null && timedNode.vehiclesMayEnterBlockedJunctions) {
                     *      checkSpace = false;
                     * }*/

                    if (checkSpace)
                    {
                        // check if there is enough space
                        if ((nodeFlags & (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) == NetNode.Flags.Junction &&
                            netManager.m_nodes.m_buffer[destinationNodeId].CountSegments() != 2)
                        {
                            var len = vehicleData.CalculateTotalLength(vehicleId) + 2f;
                            if (!netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(len))
                            {
                                var sufficientSpace = false;
                                if (nextPosition.m_segment != 0 &&
                                    netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_length < 30f)
                                {
                                    var flags3 = netManager.m_nodes.m_buffer[sourceNodeId].m_flags;
                                    if ((flags3 &
                                         (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) !=
                                        NetNode.Flags.Junction || netManager.m_nodes.m_buffer[sourceNodeId].CountSegments() == 2)
                                    {
                                        var laneId2 = PathManager.GetLaneID(nextPosition);
                                        if (laneId2 != 0u)
                                        {
                                            sufficientSpace = netManager.m_lanes.m_buffer[(int)((UIntPtr)laneId2)].CheckSpace(len);
                                        }
                                    }
                                }
                                if (!sufficientSpace)
                                {
                                    maxSpeed = 0f;
                                    return;
                                }
                            }
                        }
                    }

                    try {
                        VehiclePosition globalTargetPos = TrafficPriority.GetVehiclePosition(vehicleId);

                        if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == 0)
                        {
                            if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Car)
                            {
                                if (hasTrafficLight && (!isJoinedJunction || hasCrossing))
                                {
                                    var destinationInfo = netManager.m_nodes.m_buffer[destinationNodeId].Info;

                                    if (globalTargetPos.CarState == VehicleJunctionTransitState.None)
                                    {
                                        globalTargetPos.CarState = VehicleJunctionTransitState.Enter;
                                    }

                                    RoadBaseAI.TrafficLightState vehicleLightState;
                                    RoadBaseAI.TrafficLightState pedestrianLightState;
                                    bool vehicles;
                                    bool pedestrians;
                                    CustomRoadAI.GetTrafficLightState(vehicleId, ref vehicleData, destinationNodeId, prevPos.m_segment, position.m_segment, ref netManager.m_segments.m_buffer[prevPos.m_segment], currentFrameIndex - num5, out vehicleLightState, out pedestrianLightState, out vehicles, out pedestrians);

                                    if (isRecklessDriver && (destinationInfo.GetConnectionClass().m_service & ItemClass.Service.PublicTransport) == ItemClass.Service.None)                                       // no reckless driving at railroad crossings
                                    {
                                        vehicleLightState = RoadBaseAI.TrafficLightState.Green;
                                    }

                                    if (!vehicles && num6 >= 196u)
                                    {
                                        vehicles = true;
                                        RoadBaseAI.SetTrafficLightState(destinationNodeId, ref netManager.m_segments.m_buffer[prevPos.m_segment], currentFrameIndex - num5, vehicleLightState, pedestrianLightState, vehicles, pedestrians);
                                    }

                                    var stopCar = false;
                                    switch (vehicleLightState)
                                    {
                                    case RoadBaseAI.TrafficLightState.RedToGreen:
                                        if (num6 < 60u)
                                        {
                                            stopCar = true;
                                        }
                                        else
                                        {
                                            globalTargetPos.CarState = VehicleJunctionTransitState.Leave;
                                        }
                                        break;

                                    case RoadBaseAI.TrafficLightState.Red:
                                        stopCar = true;
                                        break;

                                    case RoadBaseAI.TrafficLightState.GreenToRed:
                                        if (num6 >= 30u)
                                        {
                                            stopCar = true;
                                        }
                                        else
                                        {
                                            globalTargetPos.CarState = VehicleJunctionTransitState.Leave;
                                        }
                                        break;
                                    }

                                    if ((vehicleLightState == RoadBaseAI.TrafficLightState.Green || vehicleLightState == RoadBaseAI.TrafficLightState.RedToGreen) && !Flags.getEnterWhenBlockedAllowed(prevPos.m_segment, netManager.m_segments.m_buffer[prevPos.m_segment].m_startNode == destinationNodeId))
                                    {
                                        var hasIncomingCars = TrafficPriority.HasIncomingVehiclesWithHigherPriority(vehicleId, destinationNodeId);

                                        if (hasIncomingCars)
                                        {
                                            // green light but other cars are incoming and they have priority: stop
                                            stopCar = true;
                                        }
                                    }

                                    if (stopCar)
                                    {
                                        globalTargetPos.CarState = VehicleJunctionTransitState.Stop;
                                        maxSpeed = 0f;
                                        return;
                                    }
                                }
                                else if (simulatePrioritySigns)
                                {
#if DEBUG
                                    //bool debug = destinationNodeId == 10864;
                                    //bool debug = destinationNodeId == 13531;
                                    bool debug = false;
#endif
                                    //bool debug = false;
#if DEBUG
                                    if (debug)
                                    {
                                        Log._Debug($"Vehicle {vehicleId} is arriving @ seg. {prevPos.m_segment} ({position.m_segment}, {nextPosition.m_segment}), node {destinationNodeId} which is not a traffic light.");
                                    }
#endif

                                    var prioritySegment = TrafficPriority.GetPrioritySegment(destinationNodeId, prevPos.m_segment);
                                    if (prioritySegment != null)
                                    {
#if DEBUG
                                        if (debug)
                                        {
                                            Log._Debug($"Vehicle {vehicleId} is arriving @ seg. {prevPos.m_segment} ({position.m_segment}, {nextPosition.m_segment}), node {destinationNodeId} which is not a traffic light and is a priority segment.");
                                        }
#endif
                                        if (prioritySegment.HasVehicle(vehicleId))
                                        {
#if DEBUG
                                            if (debug)
                                            {
                                                Log._Debug($"Vehicle {vehicleId}: segment target position found");
                                            }
#endif
                                            if (globalTargetPos.Valid)
                                            {
#if DEBUG
                                                if (debug)
                                                {
                                                    Log._Debug($"Vehicle {vehicleId}: global target position found. carState = {globalTargetPos.CarState.ToString()}");
                                                }
#endif
                                                var currentFrameIndex2 = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                                                var frame = currentFrameIndex2 >> 4;

                                                if (globalTargetPos.CarState == VehicleJunctionTransitState.None)
                                                {
                                                    globalTargetPos.CarState = VehicleJunctionTransitState.Enter;
                                                }

                                                if (globalTargetPos.CarState != VehicleJunctionTransitState.Leave)
                                                {
                                                    bool hasIncomingCars;
                                                    switch (prioritySegment.Type)
                                                    {
                                                    case SegmentEnd.PriorityType.Stop:
#if DEBUG
                                                        if (debug)
                                                        {
                                                            Log._Debug($"Vehicle {vehicleId}: STOP sign. waittime={globalTargetPos.WaitTime}, vel={lastFrameData.m_velocity.magnitude}");
                                                        }
#endif
                                                        if (globalTargetPos.WaitTime < MaxPriorityWaitTime)
                                                        {
                                                            globalTargetPos.CarState = VehicleJunctionTransitState.Stop;

                                                            if (lastFrameData.m_velocity.magnitude < 0.5f ||
                                                                globalTargetPos.Stopped)
                                                            {
                                                                globalTargetPos.Stopped = true;
                                                                globalTargetPos.WaitTime++;

                                                                float minStopWaitTime = Random.Range(0f, 3f);
                                                                if (globalTargetPos.WaitTime >= minStopWaitTime)
                                                                {
                                                                    hasIncomingCars = TrafficPriority.HasIncomingVehiclesWithHigherPriority(vehicleId, destinationNodeId);
#if DEBUG
                                                                    if (debug)
                                                                    {
                                                                        Log._Debug($"hasIncomingCars: {hasIncomingCars}");
                                                                    }
#endif

                                                                    if (hasIncomingCars)
                                                                    {
                                                                        maxSpeed = 0f;
                                                                        return;
                                                                    }
                                                                    globalTargetPos.CarState = VehicleJunctionTransitState.Leave;
                                                                }
                                                                else
                                                                {
                                                                    maxSpeed = 0;
                                                                    return;
                                                                }
                                                            }
                                                            else
                                                            {
                                                                maxSpeed = 0f;
                                                                return;
                                                            }
                                                        }
                                                        else
                                                        {
                                                            globalTargetPos.CarState = VehicleJunctionTransitState.Leave;
                                                        }
                                                        break;

                                                    case SegmentEnd.PriorityType.Yield:
#if DEBUG
                                                        if (debug)
                                                        {
                                                            Log._Debug($"Vehicle {vehicleId}: YIELD sign. waittime={globalTargetPos.WaitTime}");
                                                        }
#endif
                                                        if (globalTargetPos.WaitTime < MaxPriorityWaitTime)
                                                        {
                                                            globalTargetPos.WaitTime++;
                                                            globalTargetPos.CarState = VehicleJunctionTransitState.Stop;
                                                            hasIncomingCars          = TrafficPriority.HasIncomingVehiclesWithHigherPriority(vehicleId, destinationNodeId);
#if DEBUG
                                                            if (debug)
                                                            {
                                                                Log._Debug($"hasIncomingCars: {hasIncomingCars}");
                                                            }
#endif
                                                            if (hasIncomingCars)
                                                            {
                                                                if (lastFrameData.m_velocity.magnitude > 0)
                                                                {
                                                                    maxSpeed = Math.Max(0f, lastFrameData.m_velocity.magnitude - globalTargetPos.ReduceSpeedByValueToYield);
                                                                }
                                                                else
                                                                {
                                                                    maxSpeed = 0;
                                                                }
#if DEBUG
                                                                /*if (TrafficPriority.Vehicles[vehicleId].ToNode == 8621)
                                                                 *      Log.Message($"Vehicle {vehicleId} is yielding at node {destinationNodeId}. Speed: {maxSpeed}, Waiting time: {TrafficPriority.Vehicles[vehicleId].WaitTime}");*/
#endif
                                                                return;
                                                            }
                                                            else
                                                            {
#if DEBUG
                                                                /*if (TrafficPriority.Vehicles[vehicleId].ToNode == 8621)
                                                                 *      Log.Message($"Vehicle {vehicleId} is NOT yielding at node {destinationNodeId}.");*/
#endif
                                                                if (lastFrameData.m_velocity.magnitude > 0)
                                                                {
                                                                    maxSpeed = Math.Max(1f, lastFrameData.m_velocity.magnitude - globalTargetPos.ReduceSpeedByValueToYield * 0.5f);
                                                                }
                                                            }
                                                            globalTargetPos.CarState = VehicleJunctionTransitState.Leave;
                                                        }
                                                        else
                                                        {
                                                            globalTargetPos.CarState = VehicleJunctionTransitState.Leave;
                                                        }
                                                        break;

                                                    case SegmentEnd.PriorityType.Main:
#if DEBUG
                                                        if (debug)
                                                        {
                                                            Log._Debug($"Vehicle {vehicleId}: MAIN sign. waittime={globalTargetPos.WaitTime}");
                                                        }
#endif
                                                        if (globalTargetPos.WaitTime < MaxPriorityWaitTime)
                                                        {
                                                            globalTargetPos.WaitTime++;
                                                            globalTargetPos.CarState = VehicleJunctionTransitState.Stop;
                                                            maxSpeed = 0f;

                                                            hasIncomingCars = TrafficPriority.HasIncomingVehiclesWithHigherPriority(vehicleId, destinationNodeId);
#if DEBUG
                                                            if (debug)
                                                            {
                                                                Log._Debug($"hasIncomingCars: {hasIncomingCars}");
                                                            }
#endif

                                                            if (hasIncomingCars)
                                                            {
                                                                globalTargetPos.Stopped = true;
                                                                return;
                                                            }
                                                            globalTargetPos.CarState = VehicleJunctionTransitState.Leave;
                                                            globalTargetPos.Stopped  = false;
                                                        }

                                                        var info3 = netManager.m_segments.m_buffer[position.m_segment].Info;
                                                        if (info3.m_lanes != null && info3.m_lanes.Length > position.m_lane)
                                                        {
                                                            //maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, info3.m_lanes[position.m_lane].m_speedLimit, netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve) * 0.8f;
                                                            maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, SpeedLimitManager.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, info3.m_lanes[position.m_lane]), netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve);
                                                        }
                                                        else
                                                        {
                                                            maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f);
                                                        }
                                                        return;
                                                    }
                                                }
                                                else
                                                {
                                                    globalTargetPos.CarState = VehicleJunctionTransitState.Leave;
                                                }
                                            }
                                            else
                                            {
#if DEBUG
                                                if (debug)
                                                {
                                                    Log._Debug($"globalTargetPos is null! {vehicleId} @ seg. {prevPos.m_segment} @ node {destinationNodeId}");
                                                }
#endif
                                            }
                                        }
                                        else
                                        {
#if DEBUG
                                            if (debug)
                                            {
                                                Log._Debug($"targetPos is null! {vehicleId} @ seg. {prevPos.m_segment} @ node {destinationNodeId}");
                                            }
#endif
                                        }
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        Log.Error($"Error occured in TmCalculateSegmentPosition: {e.ToString()}");
                    }
                }
            }

            var info2 = netManager.m_segments.m_buffer[position.m_segment].Info;
            if (info2.m_lanes != null && info2.m_lanes.Length > position.m_lane)
            {
                var laneSpeedLimit = SpeedLimitManager.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, info2.m_lanes[position.m_lane]);                 // info2.m_lanes[position.m_lane].m_speedLimit;

#if DEBUG
                /*if (position.m_segment == 275) {
                 *      Log._Debug($"Applying lane speed limit of {laneSpeedLimit} to lane {laneID} @ seg. {position.m_segment}");
                 * }*/
#endif

                /*if (TrafficRoadRestrictions.IsSegment(position.m_segment)) {
                 *      var restrictionSegment = TrafficRoadRestrictions.GetSegment(position.m_segment);
                 *
                 *      if (restrictionSegment.SpeedLimits[position.m_lane] > 0.1f) {
                 *              laneSpeedLimit = restrictionSegment.SpeedLimits[position.m_lane];
                 *      }
                 * }*/

                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, laneSpeedLimit, netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve);
            }
            else
            {
                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f);
            }

            maxSpeed = CalcMaxSpeed(vehicleId, ref vehicleData, position, pos, maxSpeed, isRecklessDriver);
        }
        public void CustomCalculateSegmentPosition(ushort vehicleId, ref Vehicle vehicleData, PathUnit.Position nextPosition, PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID, byte prevOffset, int index, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            if ((Options.prioritySignsEnabled || Options.timedLightsEnabled) && Options.simAccuracy <= 1)
            {
                try {
                    VehicleStateManager.Instance().UpdateVehiclePos(vehicleId, ref vehicleData, ref prevPos, ref position);
                } catch (Exception e) {
                    Log.Error("TramAI CustomCalculateSegmentPosition Error: " + e.ToString());
                }
            }

            NetManager netManager = Singleton <NetManager> .instance;

            netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection((float)offset * 0.003921569f, out pos, out dir);
            Vector3 b = netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].CalculatePosition((float)prevOffset * 0.003921569f);

            Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();
            Vector3       a             = lastFrameData.m_position;
            Vector3       a2            = lastFrameData.m_position;
            Vector3       b2            = lastFrameData.m_rotation * new Vector3(0f, 0f, this.m_info.m_generatedInfo.m_wheelBase * 0.5f);

            a  += b2;
            a2 -= b2;
            float crazyValue = 0.5f * lastFrameData.m_velocity.sqrMagnitude / this.m_info.m_braking;
            float a3         = Vector3.Distance(a, b);
            float b3         = Vector3.Distance(a2, b);

            if (Mathf.Min(a3, b3) >= crazyValue - 1f)
            {
                Segment3 segment;
                segment.a = pos;
                ushort targetNodeId;
                ushort nextTargetNodeId;
                if (offset < position.m_offset)
                {
                    segment.b        = pos + dir.normalized * this.m_info.m_generatedInfo.m_size.z;
                    targetNodeId     = netManager.m_segments.m_buffer[(int)position.m_segment].m_startNode;
                    nextTargetNodeId = netManager.m_segments.m_buffer[(int)position.m_segment].m_endNode;
                }
                else
                {
                    segment.b        = pos - dir.normalized * this.m_info.m_generatedInfo.m_size.z;
                    targetNodeId     = netManager.m_segments.m_buffer[(int)position.m_segment].m_endNode;
                    nextTargetNodeId = netManager.m_segments.m_buffer[(int)position.m_segment].m_startNode;
                }
                ushort prevTargetNodeId;
                if (prevOffset == 0)
                {
                    prevTargetNodeId = netManager.m_segments.m_buffer[(int)prevPos.m_segment].m_startNode;
                }
                else
                {
                    prevTargetNodeId = netManager.m_segments.m_buffer[(int)prevPos.m_segment].m_endNode;
                }
                if (targetNodeId == prevTargetNodeId)
                {
                    if (!CustomVehicleAI.MayChangeSegment(vehicleId, ref vehicleData, ref lastFrameData, false, ref prevPos, prevTargetNodeId, prevLaneID, ref position, targetNodeId, laneID, ref nextPosition, nextTargetNodeId, out maxSpeed))
                    {
                        return;
                    }
                }
            }
            NetInfo info = netManager.m_segments.m_buffer[(int)position.m_segment].Info;

            if (info.m_lanes != null && info.m_lanes.Length > (int)position.m_lane)
            {
                float speedLimit = Options.customSpeedLimitsEnabled ? SpeedLimitManager.Instance().GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, info.m_lanes[position.m_lane]) : info.m_lanes[position.m_lane].m_speedLimit;
                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, speedLimit, netManager.m_lanes.m_buffer[laneID].m_curve);
            }
            else
            {
                maxSpeed = this.CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f);
            }
        }
        private bool drawSpeedLimitHandles(ushort segmentId, bool viewOnly)
        {
            if (!LoadingExtension.IsPathManagerCompatible)
            {
                return(false);
            }

            if (viewOnly && !Options.speedLimitsOverlay)
            {
                return(false);
            }

            // draw speedlimits over mean middle points of lane beziers
            if (!segmentCenterByDir.ContainsKey(segmentId))
            {
                segmentCenterByDir.Add(segmentId, new Dictionary <NetInfo.Direction, Vector3>());
                TrafficManagerTool.CalculateSegmentCenterByDir(segmentId, segmentCenterByDir[segmentId]);
            }

            bool hovered = false;

            foreach (KeyValuePair <NetInfo.Direction, Vector3> e in segmentCenterByDir[segmentId])
            {
                Vector3 signPos   = e.Value;
                var     screenPos = Camera.main.WorldToScreenPoint(signPos);
                screenPos.y = Screen.height - screenPos.y;
                if (screenPos.z < 0)
                {
                    return(false);
                }
                var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position;
                var diff   = signPos - camPos;

                if (diff.magnitude > TrafficManagerTool.PriorityCloseLod)
                {
                    return(false);                    // do not draw if too distant
                }
                ItemClass connectionClass = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info.GetConnectionClass();
                if (!(connectionClass.m_service == ItemClass.Service.Road ||
                      (connectionClass.m_service == ItemClass.Service.PublicTransport && connectionClass.m_subService == ItemClass.SubService.PublicTransportTrain)))
                {
                    return(false);
                }

                var  zoom          = 1.0f / diff.magnitude * 100f * MainTool.GetBaseZoom();
                var  size          = speedLimitSignSize * zoom;
                var  guiColor      = GUI.color;
                var  boundingBox   = new Rect(screenPos.x - size / 2, screenPos.y - size / 2, size, size);
                bool hoveredHandle = !viewOnly && TrafficManagerTool.IsMouseOver(boundingBox);

                if (hoveredHandle)
                {
                    // mouse hovering over sign
                    hovered    = true;
                    guiColor.a = 0.8f;
                }
                else
                {
                    guiColor.a = 0.5f;
                }

                GUI.color = guiColor;

                try {
                    GUI.DrawTexture(boundingBox, TrafficLightToolTextureResources.SpeedLimitTextures[SpeedLimitManager.GetCustomSpeedLimit(segmentId, e.Key)]);
                } catch (Exception ex) {
                    Log.Error("segment " + segmentId + " limit: " + SpeedLimitManager.GetCustomSpeedLimit(segmentId, e.Key) + ", ex: " + ex.ToString());
                }

                if (hoveredHandle && Input.GetMouseButton(0))
                {
                    // change the speed limit to the selected one
                    ushort speedLimitToSet = SpeedLimitManager.AvailableSpeedLimits[curSpeedLimitIndex];
                    //Log._Debug($"Setting speed limit of segment {segmentId}, dir {e.Key.ToString()} to {speedLimitToSet}");
                    SpeedLimitManager.SetSpeedLimit(segmentId, e.Key, speedLimitToSet);
                    //mouseClickProcessed = true;
                }

                guiColor.a = 1f;
                GUI.color  = guiColor;
            }
            return(hovered);
        }
예제 #9
0
        static TrafficLightToolTextureResources()
        {
            // simple
            RedLightTexture2D       = LoadDllResource("light_1_1.png", 103, 243);
            YellowRedLightTexture2D = LoadDllResource("light_1_2.png", 103, 243);
            GreenLightTexture2D     = LoadDllResource("light_1_3.png", 103, 243);
            // forward
            RedLightStraightTexture2D    = LoadDllResource("light_2_1.png", 103, 243);
            YellowLightStraightTexture2D = LoadDllResource("light_2_2.png", 103, 243);
            GreenLightStraightTexture2D  = LoadDllResource("light_2_3.png", 103, 243);
            // right
            RedLightRightTexture2D    = LoadDllResource("light_3_1.png", 103, 243);
            YellowLightRightTexture2D = LoadDllResource("light_3_2.png", 103, 243);
            GreenLightRightTexture2D  = LoadDllResource("light_3_3.png", 103, 243);
            // left
            RedLightLeftTexture2D    = LoadDllResource("light_4_1.png", 103, 243);
            YellowLightLeftTexture2D = LoadDllResource("light_4_2.png", 103, 243);
            GreenLightLeftTexture2D  = LoadDllResource("light_4_3.png", 103, 243);
            // forwardright
            RedLightForwardRightTexture2D    = LoadDllResource("light_5_1.png", 103, 243);
            YellowLightForwardRightTexture2D = LoadDllResource("light_5_2.png", 103, 243);
            GreenLightForwardRightTexture2D  = LoadDllResource("light_5_3.png", 103, 243);
            // forwardleft
            RedLightForwardLeftTexture2D    = LoadDllResource("light_6_1.png", 103, 243);
            YellowLightForwardLeftTexture2D = LoadDllResource("light_6_2.png", 103, 243);
            GreenLightForwardLeftTexture2D  = LoadDllResource("light_6_3.png", 103, 243);
            // yellow
            YellowLightTexture2D = LoadDllResource("light_yellow.png", 103, 243);
            // pedestrian
            PedestrianRedLightTexture2D   = LoadDllResource("pedestrian_light_1.png", 73, 123);
            PedestrianGreenLightTexture2D = LoadDllResource("pedestrian_light_2.png", 73, 123);
            // light mode
            LightModeTexture2D    = LoadDllResource(Translation.GetTranslatedFileName("light_mode.png"), 103, 95);
            LightCounterTexture2D = LoadDllResource(Translation.GetTranslatedFileName("light_counter.png"), 103, 95);
            // pedestrian mode
            PedestrianModeAutomaticTexture2D = LoadDllResource("pedestrian_mode_1.png", 73, 70);
            PedestrianModeManualTexture2D    = LoadDllResource("pedestrian_mode_2.png", 73, 73);

            // priority signs
            SignStopTexture2D     = LoadDllResource("sign_stop.png", 200, 200);
            SignYieldTexture2D    = LoadDllResource("sign_yield.png", 200, 200);
            SignPriorityTexture2D = LoadDllResource("sign_priority.png", 200, 200);
            SignNoneTexture2D     = LoadDllResource("sign_none.png", 200, 200);

            // delete priority sign
            SignRemoveTexture2D = LoadDllResource("remove_signs.png", 256, 256);
            // timer
            ClockPlayTexture2D  = LoadDllResource("clock_play.png", 512, 512);
            ClockPauseTexture2D = LoadDllResource("clock_pause.png", 512, 512);
            ClockTestTexture2D  = LoadDllResource("clock_test.png", 512, 512);

            SpeedLimitTextures = new Dictionary <ushort, Texture2D>();
            foreach (ushort speedLimit in SpeedLimitManager.Instance().AvailableSpeedLimits)
            {
                SpeedLimitTextures.Add(speedLimit, LoadDllResource(speedLimit.ToString() + ".png", 200, 200));
            }

            VehicleRestrictionTextures = new Dictionary <ExtVehicleType, Dictionary <bool, Texture2D> >();
            VehicleRestrictionTextures[ExtVehicleType.Bus]            = new Dictionary <bool, Texture2D>();
            VehicleRestrictionTextures[ExtVehicleType.CargoTrain]     = new Dictionary <bool, Texture2D>();
            VehicleRestrictionTextures[ExtVehicleType.CargoTruck]     = new Dictionary <bool, Texture2D>();
            VehicleRestrictionTextures[ExtVehicleType.Emergency]      = new Dictionary <bool, Texture2D>();
            VehicleRestrictionTextures[ExtVehicleType.PassengerCar]   = new Dictionary <bool, Texture2D>();
            VehicleRestrictionTextures[ExtVehicleType.PassengerTrain] = new Dictionary <bool, Texture2D>();
            VehicleRestrictionTextures[ExtVehicleType.Service]        = new Dictionary <bool, Texture2D>();
            VehicleRestrictionTextures[ExtVehicleType.Taxi]           = new Dictionary <bool, Texture2D>();

            foreach (KeyValuePair <ExtVehicleType, Dictionary <bool, Texture2D> > e in VehicleRestrictionTextures)
            {
                foreach (bool b in new bool[] { false, true })
                {
                    string suffix = b ? "allowed" : "forbidden";
                    e.Value[b] = LoadDllResource(e.Key.ToString().ToLower() + "_" + suffix + ".png", 200, 200);
                }
            }

            LaneChangeAllowedTexture2D   = LoadDllResource("lanechange_allowed.png", 200, 200);
            LaneChangeForbiddenTexture2D = LoadDllResource("lanechange_forbidden.png", 200, 200);

            UturnAllowedTexture2D   = LoadDllResource("uturn_allowed.png", 200, 200);
            UturnForbiddenTexture2D = LoadDllResource("uturn_forbidden.png", 200, 200);

            EnterBlockedJunctionAllowedTexture2D   = LoadDllResource("enterblocked_allowed.png", 200, 200);
            EnterBlockedJunctionForbiddenTexture2D = LoadDllResource("enterblocked_forbidden.png", 200, 200);

            PedestrianCrossingAllowedTexture2D   = LoadDllResource("crossing_allowed.png", 200, 200);
            PedestrianCrossingForbiddenTexture2D = LoadDllResource("crossing_forbidden.png", 200, 200);

            VehicleInfoSignTextures = new Dictionary <ExtVehicleType, Texture2D>();
            VehicleInfoSignTextures[ExtVehicleType.Bicycle]        = LoadDllResource("bicycle_infosign.png", 449, 411);
            VehicleInfoSignTextures[ExtVehicleType.Bus]            = LoadDllResource("bus_infosign.png", 449, 411);
            VehicleInfoSignTextures[ExtVehicleType.CargoTrain]     = LoadDllResource("cargotrain_infosign.png", 449, 411);
            VehicleInfoSignTextures[ExtVehicleType.CargoTruck]     = LoadDllResource("cargotruck_infosign.png", 449, 411);
            VehicleInfoSignTextures[ExtVehicleType.Emergency]      = LoadDllResource("emergency_infosign.png", 449, 411);
            VehicleInfoSignTextures[ExtVehicleType.PassengerCar]   = LoadDllResource("passengercar_infosign.png", 449, 411);
            VehicleInfoSignTextures[ExtVehicleType.PassengerTrain] = LoadDllResource("passengertrain_infosign.png", 449, 411);
            VehicleInfoSignTextures[ExtVehicleType.Service]        = LoadDllResource("service_infosign.png", 449, 411);
            VehicleInfoSignTextures[ExtVehicleType.Taxi]           = LoadDllResource("taxi_infosign.png", 449, 411);
            VehicleInfoSignTextures[ExtVehicleType.Tram]           = LoadDllResource("tram_infosign.png", 449, 411);
        }
        private void ShowSigns(bool viewOnly)
        {
            Quaternion camRot = Camera.main.transform.rotation;
            Vector3    camPos = Camera.main.transform.position;

            NetManager        netManager        = Singleton <NetManager> .instance;
            SpeedLimitManager speedLimitManager = SpeedLimitManager.Instance;

            if (lastCamPos == null || lastCamRot == null || !lastCamRot.Equals(camRot) || !lastCamPos.Equals(camPos))
            {
                // cache visible segments
                currentlyVisibleSegmentIds.Clear();

                for (uint segmentId = 1; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId)
                {
                    if (!Constants.ServiceFactory.NetService.IsSegmentValid((ushort)segmentId))
                    {
                        continue;
                    }

                    /*if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Untouchable) != NetSegment.Flags.None)
                     *      continue;*/

                    if ((netManager.m_segments.m_buffer[segmentId].m_bounds.center - camPos).magnitude > TrafficManagerTool.MaxOverlayDistance)
                    {
                        continue;                         // do not draw if too distant
                    }
                    Vector3 screenPos;
                    bool    visible = MainTool.WorldToScreenPoint(netManager.m_segments.m_buffer[segmentId].m_bounds.center, out screenPos);

                    if (!visible)
                    {
                        continue;
                    }

                    if (!speedLimitManager.MayHaveCustomSpeedLimits((ushort)segmentId, ref netManager.m_segments.m_buffer[segmentId]))
                    {
                        continue;
                    }

                    currentlyVisibleSegmentIds.Add((ushort)segmentId);
                }

                lastCamPos = camPos;
                lastCamRot = camRot;
            }

            bool handleHovered = false;

            foreach (ushort segmentId in currentlyVisibleSegmentIds)
            {
                Vector3 screenPos;
                bool    visible = MainTool.WorldToScreenPoint(netManager.m_segments.m_buffer[segmentId].m_bounds.center, out screenPos);

                if (!visible)
                {
                    continue;
                }

                NetInfo segmentInfo = netManager.m_segments.m_buffer[segmentId].Info;

                // draw speed limits
                if (MainTool.GetToolMode() != ToolMode.VehicleRestrictions || segmentId != SelectedSegmentId)                   // no speed limit overlay on selected segment when in vehicle restrictions mode
                {
                    if (drawSpeedLimitHandles((ushort)segmentId, ref netManager.m_segments.m_buffer[segmentId], viewOnly, ref camPos))
                    {
                        handleHovered = true;
                    }
                }
            }
            overlayHandleHovered = handleHovered;
        }
예제 #11
0
        public void CustomSegmentSimulationStep(ushort segmentID, ref NetSegment data)
        {
            if (initDone)
            {
                try {
                    TrafficPriority.segmentHousekeeping(segmentID);
                } catch (Exception e) {
                    Log.Error($"Error occured while housekeeping segment {segmentID}: " + e.ToString());
                }

                if (!Options.isStockLaneChangerUsed())
                {
                    try {
                        InStartupPhase = simStartFrame == 0 || simStartFrame >> 14 >= Singleton <SimulationManager> .instance.m_currentFrameIndex >> 14;                       // approx. 3 minutes

                        // calculate traffic density
                        uint curLaneId        = data.m_lanes;
                        int  nextNumLanes     = data.Info.m_lanes.Length;
                        uint laneIndex        = 0;
                        bool firstWithTraffic = true;
                        bool resetDensity     = false;
                        while (laneIndex < nextNumLanes && curLaneId != 0u)
                        {
                            uint buf = currentLaneTrafficBuffer[curLaneId];
                            uint currentDensities = currentLaneDensities[curLaneId];

                            //currentMeanDensity = (byte)Math.Min(100u, (uint)((currentDensities * 100u) / Math.Max(1u, maxDens))); // 0 .. 100

                            byte currentMeanSpeed = 25;
                            // we use integer division here because it's faster
                            if (buf > 0)
                            {
                                uint currentSpeeds = currentLaneSpeeds[curLaneId];

                                if (!InStartupPhase)
                                {
                                    currentMeanSpeed = (byte)Math.Min(100u, ((currentSpeeds * 100u) / buf) / ((uint)(Math.Max(SpeedLimitManager.GetLockFreeGameSpeedLimit(segmentID, laneIndex, curLaneId, data.Info.m_lanes[laneIndex]) * 8f, 1f))));                                     // 0 .. 100, m_speedLimit of highway is 2, actual max. vehicle speed on highway is 16, that's why we use x*8 == x<<3 (don't ask why CO uses different units for velocity)
                                }
                            }
                            else
                            {
                                if (!InStartupPhase)
                                {
                                    currentMeanSpeed = 100;
                                }
                            }

                            /*if (segmentID == 22980) {
                             *      Log._Debug($"Lane {curLaneId}: currentMeanSpeed={currentMeanSpeed} currentMeanDensity={currentMeanDensity}");
                             * }*/

                            if (currentMeanSpeed >= laneMeanSpeeds[curLaneId])
                            {
                                laneMeanSpeeds[curLaneId] = (byte)Math.Min((int)laneMeanSpeeds[curLaneId] + 5, currentMeanSpeed);
                            }
                            else
                            {
                                laneMeanSpeeds[curLaneId] = (byte)Math.Max((int)laneMeanSpeeds[curLaneId] - 5, 0);
                            }

                            //laneMeanDensities[curLaneId] = currentMeanDensity;

                            currentLaneTrafficBuffer[curLaneId] = 0;
                            currentLaneSpeeds[curLaneId]        = 0;

                            if (currentLaneDensities[curLaneId] > 0 && firstWithTraffic)
                            {
                                resetDensity     = (currentLaneDensities[curLaneId] > 1000000);
                                firstWithTraffic = false;
                            }

                            if (resetDensity)
                            {
                                currentLaneDensities[curLaneId] /= 2u;
                            }

                            laneIndex++;
                            curLaneId = Singleton <NetManager> .instance.m_lanes.m_buffer[curLaneId].m_nextLane;
                        }
                    } catch (Exception e) {
                        Log.Error("Error occured while calculating lane traffic density: " + e.ToString());
                    }
                }
            }
            try {
                OriginalSimulationStep(segmentID, ref data);
            } catch (Exception ex) {
                Log.Error("Error in CustomRoadAI.SimulationStep: " + ex.ToString());
            }
        }
예제 #12
0
        public void CustomCalculateSegmentPosition(ushort vehicleId, ref Vehicle vehicleData, PathUnit.Position nextPosition,
                                                   PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID,
                                                   byte prevOffset, int index, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            if ((Options.prioritySignsEnabled || Options.timedLightsEnabled) && Options.simAccuracy <= 1)
            {
                try {
                    VehicleStateManager.Instance().UpdateVehiclePos(vehicleId, ref vehicleData, ref prevPos, ref position);
                } catch (Exception e) {
                    Log.Error("CarAI CustomCalculateSegmentPosition Error: " + e.ToString());
                }
            }

            var netManager = Singleton <NetManager> .instance;

            //var vehicleManager = Singleton<VehicleManager>.instance;
            netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection(offset * 0.003921569f, out pos, out dir);

            Vehicle.Frame lastFrameData       = vehicleData.GetLastFrameData();
            Vector3       lastFrameVehiclePos = lastFrameData.m_position;

            var camPos = Camera.main.transform.position;

#if DEBUG
            //bool isEmergency = VehicleStateManager._GetVehicleState(vehicleId).VehicleType == ExtVehicleType.Emergency;
#endif

            // I think this is supposed to be the lane position?
            // [VN, 12/23/2015] It's the 3D car position on the Bezier curve of the lane.
            // This crazy 0.003921569f equals to 1f/255 and prevOffset is the byte value (0..255) of the car position.
            var vehiclePosOnBezier = netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].CalculatePosition(prevOffset * 0.003921569f);
            //ushort currentSegmentId = netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_segment;

            ushort targetNodeId;
            ushort nextTargetNodeId;
            if (offset < position.m_offset)
            {
                targetNodeId     = netManager.m_segments.m_buffer[position.m_segment].m_startNode;
                nextTargetNodeId = netManager.m_segments.m_buffer[position.m_segment].m_endNode;
            }
            else
            {
                targetNodeId     = netManager.m_segments.m_buffer[position.m_segment].m_endNode;
                nextTargetNodeId = netManager.m_segments.m_buffer[position.m_segment].m_startNode;
            }
            var prevTargetNodeId = prevOffset == 0 ? netManager.m_segments.m_buffer[prevPos.m_segment].m_startNode : netManager.m_segments.m_buffer[prevPos.m_segment].m_endNode;

            // this seems to be like the required braking force in order to stop the vehicle within its half length.
            var crazyValue = 0.5f * lastFrameData.m_velocity.sqrMagnitude / m_info.m_braking + m_info.m_generatedInfo.m_size.z * 0.5f;

            /*try {
             *      VehicleStateManager.UpdateVehiclePos(vehicleId, ref vehicleData);
             * } catch (Exception e) {
             *      Log.Error("CarAI TmCalculateSegmentPosition Error: " + e.ToString());
             * }*/

            bool isRecklessDriver = IsRecklessDriver(vehicleId, ref vehicleData);
            if (targetNodeId == prevTargetNodeId)
            {
                if (Vector3.Distance(lastFrameVehiclePos, vehiclePosOnBezier) >= crazyValue - 1f)
                {
                    if (!CustomVehicleAI.MayChangeSegment(vehicleId, ref vehicleData, ref lastFrameData, isRecklessDriver, ref prevPos, prevTargetNodeId, prevLaneID, ref position, targetNodeId, laneID, ref nextPosition, nextTargetNodeId, out maxSpeed))
                    {
                        return;
                    }
                }
            }

            var info2 = netManager.m_segments.m_buffer[position.m_segment].Info;
            if (info2.m_lanes != null && info2.m_lanes.Length > position.m_lane)
            {
                var laneSpeedLimit = Options.customSpeedLimitsEnabled ? SpeedLimitManager.Instance().GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, info2.m_lanes[position.m_lane]) : info2.m_lanes[position.m_lane].m_speedLimit;                 // info2.m_lanes[position.m_lane].m_speedLimit;

#if DEBUG
                /*if (position.m_segment == 275) {
                 *      Log._Debug($"Applying lane speed limit of {laneSpeedLimit} to lane {laneID} @ seg. {position.m_segment}");
                 * }*/
#endif
                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, laneSpeedLimit, netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve);
            }
            else
            {
                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f);
            }

            maxSpeed = CalcMaxSpeed(vehicleId, ref vehicleData, position, pos, maxSpeed, isRecklessDriver);
        }
        private bool drawSpeedLimitHandles(ushort segmentId, bool viewOnly)
        {
            if (!LoadingExtension.IsPathManagerCompatible)
            {
                return(false);
            }

            if (viewOnly && !Options.speedLimitsOverlay)
            {
                return(false);
            }

            // draw speedlimits over mean middle points of lane beziers
            if (!segmentCenterByDir.ContainsKey(segmentId))
            {
                segmentCenterByDir.Add(segmentId, new Dictionary <NetInfo.Direction, Vector3>());
                TrafficManagerTool.CalculateSegmentCenterByDir(segmentId, segmentCenterByDir[segmentId]);
            }

            bool hovered = false;

            foreach (KeyValuePair <NetInfo.Direction, Vector3> e in segmentCenterByDir[segmentId])
            {
                Vector3 signPos   = e.Value;
                var     screenPos = Camera.main.WorldToScreenPoint(signPos);
                screenPos.y = Screen.height - screenPos.y;
                if (screenPos.z < 0)
                {
                    return(false);
                }
                var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position;
                var diff   = signPos - camPos;

                if (diff.magnitude > TrafficManagerTool.PriorityCloseLod)
                {
                    return(false);                    // do not draw if too distant
                }
                ItemClass connectionClass = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info.GetConnectionClass();
                if (!(connectionClass.m_service == ItemClass.Service.Road ||
                      (connectionClass.m_service == ItemClass.Service.PublicTransport && connectionClass.m_subService == ItemClass.SubService.PublicTransportTrain)))
                {
                    return(false);
                }

                var  zoom          = 1.0f / diff.magnitude * 100f * MainTool.GetBaseZoom();
                var  size          = speedLimitSignSize * zoom;
                var  guiColor      = GUI.color;
                var  boundingBox   = new Rect(screenPos.x - size / 2, screenPos.y - size / 2, size, size);
                bool hoveredHandle = !viewOnly && TrafficManagerTool.IsMouseOver(boundingBox);

                if (hoveredHandle)
                {
                    // mouse hovering over sign
                    hovered    = true;
                    guiColor.a = 0.8f;
                }
                else
                {
                    guiColor.a = 0.5f;
                }

                GUI.color = guiColor;

                try {
                    GUI.DrawTexture(boundingBox, TrafficLightToolTextureResources.SpeedLimitTextures[SpeedLimitManager.GetCustomSpeedLimit(segmentId, e.Key)]);
                } catch (Exception ex) {
                    Log.Error("segment " + segmentId + " limit: " + SpeedLimitManager.GetCustomSpeedLimit(segmentId, e.Key) + ", ex: " + ex.ToString());
                }

                if (hoveredHandle && Input.GetMouseButton(0))
                {
                    // change the speed limit to the selected one
                    ushort speedLimitToSet = SpeedLimitManager.AvailableSpeedLimits[curSpeedLimitIndex];
                    //Log._Debug($"Setting speed limit of segment {segmentId}, dir {e.Key.ToString()} to {speedLimitToSet}");
                    SpeedLimitManager.SetSpeedLimit(segmentId, e.Key, speedLimitToSet);

                    // TODO use SegmentTraverser
                    if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
                    {
                        NetInfo         selectedSegmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info;
                        List <object[]> selectedSortedLanes = TrafficManagerTool.GetSortedVehicleLanes(segmentId, selectedSegmentInfo, null);

                        LinkedList <ushort> nodesToProcess    = new LinkedList <ushort>();
                        HashSet <ushort>    processedNodes    = new HashSet <ushort>();
                        HashSet <ushort>    processedSegments = new HashSet <ushort>();
                        processedSegments.Add(SelectedSegmentId);

                        ushort selectedStartNodeId = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_startNode;
                        ushort selectedEndNodeId   = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_endNode;

                        if (selectedStartNodeId != 0)
                        {
                            nodesToProcess.AddFirst(selectedStartNodeId);
                        }
                        if (selectedEndNodeId != 0)
                        {
                            nodesToProcess.AddFirst(selectedEndNodeId);
                        }

                        while (nodesToProcess.First != null)
                        {
                            ushort nodeId = nodesToProcess.First.Value;
                            nodesToProcess.RemoveFirst();
                            processedNodes.Add(nodeId);

                            if (Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId].CountSegments() > 2)
                            {
                                continue;                                 // junction. stop.
                            }
                            // explore segments at node
                            for (var s = 0; s < 8; s++)
                            {
                                var otherSegmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId].GetSegment(s);

                                if (otherSegmentId <= 0 || processedSegments.Contains(otherSegmentId))
                                {
                                    continue;
                                }
                                processedSegments.Add(otherSegmentId);

                                NetInfo         segmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[otherSegmentId].Info;
                                List <object[]> sortedLanes = TrafficManagerTool.GetSortedVehicleLanes(otherSegmentId, segmentInfo, null);

                                if (sortedLanes.Count == selectedSortedLanes.Count)
                                {
                                    // number of lanes matches selected segment
                                    for (int i = 0; i < sortedLanes.Count; ++i)
                                    {
                                        object[] selectedLaneData = selectedSortedLanes[i];
                                        object[] laneData         = sortedLanes[i];

                                        uint         selectedLaneId    = (uint)selectedLaneData[0];
                                        uint         selectedLaneIndex = (uint)selectedLaneData[2];
                                        NetInfo.Lane selectedLaneInfo  = segmentInfo.m_lanes[selectedLaneIndex];

                                        uint         laneId    = (uint)laneData[0];
                                        uint         laneIndex = (uint)laneData[2];
                                        NetInfo.Lane laneInfo  = segmentInfo.m_lanes[laneIndex];

                                        if (laneInfo.m_finalDirection == e.Key)
                                        {
                                            SpeedLimitManager.SetSpeedLimit(otherSegmentId, laneInfo.m_finalDirection, speedLimitToSet);
                                        }

                                        // apply restrictions of selected segment & lane
                                        //VehicleRestrictionsManager.SetAllowedVehicleTypes(otherSegmentId, segmentInfo, laneIndex, laneInfo, laneId, VehicleRestrictionsManager.GetAllowedVehicleTypes(SelectedSegmentId, selectedSegmentInfo, selectedLaneIndex, selectedLaneInfo));
                                    }

                                    // add nodes to explore
                                    ushort startNodeId = Singleton <NetManager> .instance.m_segments.m_buffer[otherSegmentId].m_startNode;
                                    ushort endNodeId   = Singleton <NetManager> .instance.m_segments.m_buffer[otherSegmentId].m_endNode;

                                    if (startNodeId != 0 && !processedNodes.Contains(startNodeId))
                                    {
                                        nodesToProcess.AddFirst(startNodeId);
                                    }
                                    if (endNodeId != 0 && !processedNodes.Contains(endNodeId))
                                    {
                                        nodesToProcess.AddFirst(endNodeId);
                                    }
                                }
                            }
                        }
                    }
                    //mouseClickProcessed = true;
                }

                guiColor.a = 1f;
                GUI.color  = guiColor;
            }
            return(hovered);
        }
예제 #14
0
        public void CustomCalculateSegmentPosition(ushort vehicleID, ref Vehicle vehicleData, PathUnit.Position nextPosition, PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID, byte prevOffset, int index, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            NetManager instance = Singleton <NetManager> .instance;

            instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection((float)offset * 0.003921569f, out pos, out dir);
            Vector3 b = instance.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].CalculatePosition((float)prevOffset * 0.003921569f);

            Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();
            Vector3       a             = lastFrameData.m_position;
            Vector3       a2            = lastFrameData.m_position;
            Vector3       b2            = lastFrameData.m_rotation * new Vector3(0f, 0f, this.m_info.m_generatedInfo.m_wheelBase * 0.5f);

            a  += b2;
            a2 -= b2;
            float num = 0.5f * lastFrameData.m_velocity.sqrMagnitude / this.m_info.m_braking;
            float a3  = Vector3.Distance(a, b);
            float b3  = Vector3.Distance(a2, b);

            if (Mathf.Min(a3, b3) >= num - 1f)
            {
                Segment3 segment;
                segment.a = pos;
                ushort num2;
                ushort num3;
                if (offset < position.m_offset)
                {
                    segment.b = pos + dir.normalized * this.m_info.m_generatedInfo.m_size.z;
                    num2      = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode;
                    num3      = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode;
                }
                else
                {
                    segment.b = pos - dir.normalized * this.m_info.m_generatedInfo.m_size.z;
                    num2      = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode;
                    num3      = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode;
                }
                ushort num4;
                if (prevOffset == 0)
                {
                    num4 = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_startNode;
                }
                else
                {
                    num4 = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_endNode;
                }
                if (num2 == num4)
                {
                    NetNode.Flags flags      = instance.m_nodes.m_buffer[(int)num2].m_flags;
                    NetLane.Flags flags2     = (NetLane.Flags)instance.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_flags;
                    bool          flag       = (flags & NetNode.Flags.TrafficLights) != NetNode.Flags.None;
                    bool          flag2      = (flags & NetNode.Flags.LevelCrossing) != NetNode.Flags.None;
                    bool          flag3      = (flags2 & NetLane.Flags.JoinedJunction) != NetLane.Flags.None;
                    bool          checkSpace = !Options.allowEnterBlockedJunctions;            // NON-STOCK CODE
                    if (checkSpace && (flags & (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) == NetNode.Flags.Junction && instance.m_nodes.m_buffer[(int)num2].CountSegments() != 2)
                    {
                        float len = vehicleData.CalculateTotalLength(vehicleID) + 2f;
                        if (!instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(len))
                        {
                            bool flag4 = false;
                            if (nextPosition.m_segment != 0 && instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_length < 30f)
                            {
                                NetNode.Flags flags3 = instance.m_nodes.m_buffer[(int)num3].m_flags;
                                if ((flags3 & (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) != NetNode.Flags.Junction || instance.m_nodes.m_buffer[(int)num3].CountSegments() == 2)
                                {
                                    uint laneID2 = PathManager.GetLaneID(nextPosition);
                                    if (laneID2 != 0u)
                                    {
                                        flag4 = instance.m_lanes.m_buffer[(int)((UIntPtr)laneID2)].CheckSpace(len);
                                    }
                                }
                            }
                            if (!flag4)
                            {
                                maxSpeed = 0f;
                                return;
                            }
                        }
                    }
                    if (flag && (!flag3 || flag2))
                    {
                        uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                        uint num5 = (uint)(((int)num4 << 8) / 32768);
                        uint num6 = currentFrameIndex - num5 & 255u;
                        RoadBaseAI.TrafficLightState vehicleLightState;
                        RoadBaseAI.TrafficLightState pedestrianLightState;
                        bool flag5;
                        bool pedestrians;
                        /// NON-STOCK CODE START ///
                        CustomRoadAI.GetTrafficLightState(vehicleID, ref vehicleData, num4, prevPos.m_segment, position.m_segment, ref instance.m_segments.m_buffer[(int)prevPos.m_segment], currentFrameIndex - num5, out vehicleLightState, out pedestrianLightState, out flag5, out pedestrians);
                        /// NON-STOCK CODE END ///
                        //RoadBaseAI.GetTrafficLightState(num4, ref instance.m_segments.m_buffer[(int)prevPos.m_segment], currentFrameIndex - num5, out vehicleLightState, out pedestrianLightState, out flag5, out pedestrians);
                        if (!flag5 && num6 >= 196u)
                        {
                            flag5 = true;
                            RoadBaseAI.SetTrafficLightState(num4, ref instance.m_segments.m_buffer[(int)prevPos.m_segment], currentFrameIndex - num5, vehicleLightState, pedestrianLightState, flag5, pedestrians);
                        }
                        switch (vehicleLightState)
                        {
                        case RoadBaseAI.TrafficLightState.RedToGreen:
                            if (num6 < 60u)
                            {
                                maxSpeed = 0f;
                                return;
                            }
                            break;

                        case RoadBaseAI.TrafficLightState.Red:
                            maxSpeed = 0f;
                            return;

                        case RoadBaseAI.TrafficLightState.GreenToRed:
                            if (num6 >= 30u)
                            {
                                maxSpeed = 0f;
                                return;
                            }
                            break;
                        }
                    }
                }
            }
            NetInfo info = instance.m_segments.m_buffer[(int)position.m_segment].Info;

            if (info.m_lanes != null && info.m_lanes.Length > (int)position.m_lane)
            {
                //maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, info.m_lanes[(int)position.m_lane].m_speedLimit, instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve);
                maxSpeed = CalculateTargetSpeed(vehicleID, ref vehicleData, SpeedLimitManager.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, info.m_lanes[position.m_lane]), instance.m_lanes.m_buffer[laneID].m_curve);
            }
            else
            {
                maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, 1f, 0f);
            }
        }
        /// <summary>
        /// Displays lane ids over lanes
        /// </summary>
        private void _guiLanes(ushort segmentId, ref NetSegment segment, ref NetInfo segmentInfo)
        {
            GUIStyle _counterStyle = new GUIStyle();
            Vector3  centerPos     = segment.m_bounds.center;
            var      screenPos     = Camera.main.WorldToScreenPoint(centerPos);

            screenPos.y = Screen.height - screenPos.y - 200;

            if (screenPos.z < 0)
            {
                return;
            }

            var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position;
            var diff   = centerPos - camPos;

            if (diff.magnitude > DebugCloseLod)
            {
                return;                 // do not draw if too distant
            }
            var zoom = 1.0f / diff.magnitude * 150f;

            _counterStyle.fontSize         = (int)(11f * zoom);
            _counterStyle.normal.textColor = new Color(1f, 1f, 0f);

            uint totalDensity = 0u;
            uint curLaneId    = segment.m_lanes;

            for (int i = 0; i < segmentInfo.m_lanes.Length; ++i)
            {
                if (curLaneId == 0)
                {
                    break;
                }

                if (CustomRoadAI.currentLaneDensities[segmentId] != null && i < CustomRoadAI.currentLaneDensities[segmentId].Length)
                {
                    totalDensity += CustomRoadAI.currentLaneDensities[segmentId][i];
                }

                curLaneId = Singleton <NetManager> .instance.m_lanes.m_buffer[curLaneId].m_nextLane;
            }

            curLaneId = segment.m_lanes;
            String labelStr = "";

            for (int i = 0; i < segmentInfo.m_lanes.Length; ++i)
            {
                if (curLaneId == 0)
                {
                    break;
                }

                NetInfo.Lane laneInfo = segmentInfo.m_lanes[i];

                labelStr += "Lane idx " + i + ", id " + curLaneId;
#if DEBUG
                labelStr += ", flags: " + ((NetLane.Flags)Singleton <NetManager> .instance.m_lanes.m_buffer[curLaneId].m_flags).ToString() + ", limit: " + SpeedLimitManager.GetCustomSpeedLimit(curLaneId) + " km/h, dir: " + laneInfo.m_direction + ", final: " + laneInfo.m_finalDirection + ", pos: " + String.Format("{0:0.##}", laneInfo.m_position) + ", sim. idx: " + laneInfo.m_similarLaneIndex + " for " + laneInfo.m_vehicleType + "/" + laneInfo.m_laneType;
#endif

                /*if (CustomRoadAI.InStartupPhase)
                 *      labelStr += ", in start-up phase";
                 * else*/
                labelStr += ", avg. speed: " + (CustomRoadAI.laneMeanSpeeds[segmentId] != null && i < CustomRoadAI.laneMeanSpeeds[segmentId].Length ? "" + CustomRoadAI.laneMeanSpeeds[segmentId][i] : "?") + " %";
                labelStr += ", rel. density: " + (CustomRoadAI.laneMeanRelDensities[segmentId] != null && i < CustomRoadAI.laneMeanRelDensities[segmentId].Length ? "" + CustomRoadAI.laneMeanRelDensities[segmentId][i] : "?") + " %";
#if ABSDENSITY
                labelStr += ", abs. density: " + (CustomRoadAI.laneMeanAbsDensities[segmentId] != null && i < CustomRoadAI.laneMeanAbsDensities[segmentId].Length ? "" + CustomRoadAI.laneMeanAbsDensities[segmentId][i] : "?") + " %";
#endif
#if DEBUG
                labelStr += " (" + (CustomRoadAI.currentLaneDensities[segmentId] != null && i < CustomRoadAI.currentLaneDensities[segmentId].Length ? "" + CustomRoadAI.currentLaneDensities[segmentId][i] : "?") + "/" + totalDensity + ")";
#endif
                labelStr += "\n";

                curLaneId = Singleton <NetManager> .instance.m_lanes.m_buffer[curLaneId].m_nextLane;
            }

            Vector2 dim       = _counterStyle.CalcSize(new GUIContent(labelStr));
            Rect    labelRect = new Rect(screenPos.x - dim.x / 2f, screenPos.y, dim.x, dim.y);

            GUI.Label(labelRect, labelStr, _counterStyle);
        }
        private void ShowSigns(bool viewOnly)
        {
            NetManager        netManager        = Singleton <NetManager> .instance;
            SpeedLimitManager speedLimitManager = SpeedLimitManager.Instance;

            var       currentCamera          = new CameraTransformValue(Camera.main);
            Transform currentCameraTransform = Camera.main.transform;
            Vector3   camPos = currentCameraTransform.position;

            if (!LastCachedCamera.Equals(currentCamera))
            {
                // cache visible segments
                LastCachedCamera = currentCamera;
                CachedVisibleSegmentIds.Clear();

                const float MAX_DIST = TrafficManagerTool.MAX_OVERLAY_DISTANCE *
                                       TrafficManagerTool.MAX_OVERLAY_DISTANCE;

                for (uint segmentId = 1; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId)
                {
                    if (!Constants.ServiceFactory.NetService.IsSegmentValid((ushort)segmentId))
                    {
                        continue;
                    }

                    // if ((netManager.m_segments.m_buffer[segmentId].m_flags &
                    // NetSegment.Flags.Untouchable) != NetSegment.Flags.None) continue;
                    Vector3 distToCamera = netManager.m_segments.m_buffer[segmentId].m_bounds.center - camPos;
                    if (distToCamera.sqrMagnitude > MAX_DIST)
                    {
                        continue; // do not draw if too distant
                    }

                    bool visible = MainTool.WorldToScreenPoint(
                        netManager.m_segments.m_buffer[segmentId].m_bounds.center,
                        out Vector3 _);

                    if (!visible)
                    {
                        continue;
                    }

                    if (!speedLimitManager.MayHaveCustomSpeedLimits(
                            (ushort)segmentId,
                            ref netManager.m_segments.m_buffer[segmentId]))
                    {
                        continue;
                    }

                    CachedVisibleSegmentIds.Add((ushort)segmentId);
                } // end for all segments
            }

            for (int segmentIdIndex = CachedVisibleSegmentIds.Size - 1;
                 segmentIdIndex >= 0;
                 segmentIdIndex--)
            {
                ushort segmentId = CachedVisibleSegmentIds.Values[segmentIdIndex];
                // draw speed limits
                if ((MainTool.GetToolMode() == ToolMode.VehicleRestrictions) &&
                    (segmentId == SelectedSegmentId))
                {
                    continue;
                }

                // no speed limit overlay on selected segment when in vehicle restrictions mode
                DrawSpeedLimitHandles(
                    segmentId,
                    ref netManager.m_segments.m_buffer[segmentId],
                    viewOnly,
                    ref camPos);
            }
        }
예제 #17
0
        /// <summary>
        /// Displays vehicle ids over vehicles
        /// </summary>
        private void _guiVehicles()
        {
            GUIStyle              _counterStyle   = new GUIStyle();
            Array16 <Vehicle>     vehicles        = Singleton <VehicleManager> .instance.m_vehicles;
            LaneConnectionManager connManager     = LaneConnectionManager.Instance();
            SimulationManager     simManager      = Singleton <SimulationManager> .instance;
            NetManager            netManager      = Singleton <NetManager> .instance;
            VehicleStateManager   vehStateManager = VehicleStateManager.Instance();

            for (int i = 1; i < vehicles.m_size; ++i)
            {
                Vehicle vehicle = vehicles.m_buffer[i];
                if (vehicle.m_flags == 0)                 // node is unused
                {
                    continue;
                }

                Vector3 vehPos    = vehicle.GetLastFramePosition();
                var     screenPos = Camera.main.WorldToScreenPoint(vehPos);
                screenPos.y = Screen.height - screenPos.y;

                if (screenPos.z < 0)
                {
                    continue;
                }

                var camPos = simManager.m_simulationView.m_position;
                var diff   = vehPos - camPos;
                if (diff.magnitude > DebugCloseLod)
                {
                    continue;                     // do not draw if too distant
                }
                var zoom = 1.0f / diff.magnitude * 150f;

                _counterStyle.fontSize         = (int)(10f * zoom);
                _counterStyle.normal.textColor = new Color(1f, 1f, 1f);
                //_counterStyle.normal.background = MakeTex(1, 1, new Color(0f, 0f, 0f, 0.4f));

                VehicleState      vState  = vehStateManager._GetVehicleState((ushort)i);
                PathUnit.Position?curPos  = vState?.GetCurrentPathPosition(ref vehicle);
                PathUnit.Position?nextPos = vState?.GetNextPathPosition(ref vehicle);
                bool?  startNode          = vState?.CurrentSegmentEnd?.StartNode;
                ushort?segmentId          = vState?.CurrentSegmentEnd?.SegmentId;
                ushort?transitNodeId      = vState?.CurrentSegmentEnd?.NodeId;

                /*float distanceToTransitNode = Single.NaN;
                 * float timeToTransitNode = Single.NaN;*/
                ushort vehSpeed = SpeedLimitManager.Instance().VehicleToCustomSpeed(vehicle.GetLastFrameVelocity().magnitude);

                Vector3?targetPos = null;
                if (transitNodeId != null)
                {
                    targetPos = netManager.m_nodes.m_buffer[(ushort)transitNodeId].m_position;
                }

                /*if (transitNodeId != null && segmentId != null && startNode != null && curPos != null) {
                 *      bool outgoing = false;
                 *      connManager.GetLaneEndPoint((ushort)segmentId, (bool)startNode, ((PathUnit.Position)curPos).m_lane, null, null, out outgoing, out targetPos);
                 * }*/

                float distanceToTransitNode = Single.NaN;
                if (targetPos != null)
                {
                    distanceToTransitNode = ((Vector3)targetPos - vehPos).magnitude;

                    /*if (vehSpeed > 0)
                     *      timeToTransitNode = distanceToTransitNode / vehSpeed;
                     * else
                     *      timeToTransitNode = Single.PositiveInfinity;*/
                }
                String labelStr = "V #" + i + " is a " + (vState.Valid ? "valid" : "invalid") + " " + vState.VehicleType + " @ ~" + vehSpeed + " km/h (" + vState.JunctionTransitState + ") dist: " + distanceToTransitNode;
#if USEPATHWAITCOUNTER
                labelStr += ", pwc: " + vState.PathWaitCounter + ", seg. " + vState.CurrentSegmentEnd?.SegmentId;
#endif
                //String labelStr = "Veh. " + i + " @ " + String.Format("{0:0.##}", vehSpeed) + "/" + (vState != null ? vState.CurrentMaxSpeed.ToString() : "-") + " (" + (vState != null ? vState.VehicleType.ToString() : "-") + ", valid? " + (vState != null ? vState.Valid.ToString() : "-") + ")" + ", len: " + (vState != null ? vState.TotalLength.ToString() : "-") + ", state: " + (vState != null ? vState.JunctionTransitState.ToString() : "-");
#if PATHRECALC
                labelStr += ", recalc: " + (vState != null ? vState.LastPathRecalculation.ToString() : "-");
#endif
                //labelStr += "\npos: " + curPos?.m_segment + "(" + curPos?.m_lane + ")->" + nextPos?.m_segment + "(" + nextPos?.m_lane + ")" /* + ", dist: " + distanceToTransitNode + ", time: " + timeToTransitNode*/ + ", last update: " + vState?.LastPositionUpdate;

                Vector2 dim       = _counterStyle.CalcSize(new GUIContent(labelStr));
                Rect    labelRect = new Rect(screenPos.x - dim.x / 2f, screenPos.y - dim.y - 50f, dim.x, dim.y);

                GUI.Box(labelRect, labelStr, _counterStyle);

                //_counterStyle.normal.background = null;
            }
        }