public static bool FindPathPosition(Vector3 position, ItemClass.Service service, NetInfo.LaneType laneType, VehicleInfo.VehicleType vehicleTypes, bool allowUnderground, bool requireConnect, float maxDistance, out PathUnit.Position pathPos, RoadManager.VehicleType vehicleType)
 {
     PathUnit.Position position2;
     float num;
     float num2;
     return CustomPathManager.FindPathPosition(position, service, laneType, vehicleTypes, allowUnderground, requireConnect, maxDistance, out pathPos, out position2, out num, out num2, vehicleType);
 }
        public RoadManager.VehicleType ToggleRestriction(RoadManager.VehicleType vehicleType)
        {
            if (!AnyLaneSelected)
                return RoadManager.VehicleType.None;

            RoadManager.VehicleType vehicleRestrictions = RoadManager.GetVehicleRestrictions(m_selectedLaneMarkers[0].m_lane);
            vehicleRestrictions ^= vehicleType;

            foreach (SegmentLaneMarker lane in m_selectedLaneMarkers)
                RoadManager.SetVehicleRestrictions(lane.m_lane, vehicleRestrictions);

            return vehicleRestrictions;
        }
 public static bool FindPathPosition(Vector3 position, ItemClass.Service service, NetInfo.LaneType laneType, VehicleInfo.VehicleType vehicleTypes, bool allowUnderground, bool requireConnect, float maxDistance, out PathUnit.Position pathPosA, out PathUnit.Position pathPosB, out float distanceSqrA, out float distanceSqrB, RoadManager.VehicleType vehicleType)
 {
     Bounds bounds = new Bounds(position, new Vector3(maxDistance * 2f, maxDistance * 2f, maxDistance * 2f));
     int num = Mathf.Max((int)((bounds.min.x - 64f) / 64f + 135f), 0);
     int num2 = Mathf.Max((int)((bounds.min.z - 64f) / 64f + 135f), 0);
     int num3 = Mathf.Min((int)((bounds.max.x + 64f) / 64f + 135f), 269);
     int num4 = Mathf.Min((int)((bounds.max.z + 64f) / 64f + 135f), 269);
     NetManager instance = Singleton<NetManager>.instance;
     pathPosA.m_segment = 0;
     pathPosA.m_lane = 0;
     pathPosA.m_offset = 0;
     distanceSqrA = 1E+10f;
     pathPosB.m_segment = 0;
     pathPosB.m_lane = 0;
     pathPosB.m_offset = 0;
     distanceSqrB = 1E+10f;
     float num5 = maxDistance * maxDistance;
     for (int i = num2; i <= num4; i++)
     {
         for (int j = num; j <= num3; j++)
         {
             ushort num6 = instance.m_segmentGrid[i * 270 + j];
             int num7 = 0;
             while (num6 != 0)
             {
                 NetInfo info = instance.m_segments.m_buffer[(int)num6].Info;
                 if (info.m_class.m_service == service && (instance.m_segments.m_buffer[(int)num6].m_flags & NetSegment.Flags.Flooded) == NetSegment.Flags.None && (allowUnderground || !info.m_netAI.IsUnderground()))
                 {
                     ushort startNode = instance.m_segments.m_buffer[(int)num6].m_startNode;
                     ushort endNode = instance.m_segments.m_buffer[(int)num6].m_endNode;
                     Vector3 position2 = instance.m_nodes.m_buffer[(int)startNode].m_position;
                     Vector3 position3 = instance.m_nodes.m_buffer[(int)endNode].m_position;
                     float num8 = Mathf.Max(Mathf.Max(bounds.min.x - 64f - position2.x, bounds.min.z - 64f - position2.z), Mathf.Max(position2.x - bounds.max.x - 64f, position2.z - bounds.max.z - 64f));
                     float num9 = Mathf.Max(Mathf.Max(bounds.min.x - 64f - position3.x, bounds.min.z - 64f - position3.z), Mathf.Max(position3.x - bounds.max.x - 64f, position3.z - bounds.max.z - 64f));
                     Vector3 b;
                     int num10;
                     float num11;
                     Vector3 b2;
                     int num12;
                     float num13;
                     if ((num8 < 0f || num9 < 0f) && instance.m_segments.m_buffer[(int)num6].m_bounds.Intersects(bounds) && CustomPathManager.GetClosestLanePosition(instance.m_segments.m_buffer[(int)num6], position, laneType, vehicleTypes, requireConnect, out b, out num10, out num11, out b2, out num12, out num13, vehicleType))
                     {
                         float num14 = Vector3.SqrMagnitude(position - b);
                         if (num14 < num5)
                         {
                             num5 = num14;
                             pathPosA.m_segment = num6;
                             pathPosA.m_lane = (byte)num10;
                             pathPosA.m_offset = (byte)Mathf.Clamp(Mathf.RoundToInt(num11 * 255f), 0, 255);
                             distanceSqrA = num14;
                             num14 = Vector3.SqrMagnitude(position - b2);
                             if (num12 == -1 || num14 >= maxDistance * maxDistance)
                             {
                                 pathPosB.m_segment = 0;
                                 pathPosB.m_lane = 0;
                                 pathPosB.m_offset = 0;
                                 distanceSqrB = 1E+10f;
                             }
                             else
                             {
                                 pathPosB.m_segment = num6;
                                 pathPosB.m_lane = (byte)num12;
                                 pathPosB.m_offset = (byte)Mathf.Clamp(Mathf.RoundToInt(num13 * 255f), 0, 255);
                                 distanceSqrB = num14;
                             }
                         }
                     }
                 }
                 num6 = instance.m_segments.m_buffer[(int)num6].m_nextGridSegment;
                 if (++num7 >= 32768)
                 {
                     CODebugBase<LogChannel>.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);
                     break;
                 }
             }
         }
     }
     return pathPosA.m_segment != 0;
 }
 public bool CreatePath(out uint unit, ref Randomizer randomizer, uint buildIndex, PathUnit.Position startPosA, PathUnit.Position startPosB, PathUnit.Position endPosA, PathUnit.Position endPosB, NetInfo.LaneType laneTypes, VehicleInfo.VehicleType vehicleTypes, float maxLength, bool isHeavyVehicle, bool ignoreBlocked, bool stablePath, bool skipQueue, RoadManager.VehicleType vehicleType)
 {
     return this.CreatePath(out unit, ref randomizer, buildIndex, startPosA, startPosB, endPosA, endPosB, default(PathUnit.Position), laneTypes, vehicleTypes, maxLength, isHeavyVehicle, ignoreBlocked, stablePath, skipQueue, vehicleType);
 }
 public bool CreatePath(out uint unit, ref Randomizer randomizer, uint buildIndex, PathUnit.Position startPosA, PathUnit.Position startPosB, PathUnit.Position endPosA, PathUnit.Position endPosB, PathUnit.Position vehiclePosition, NetInfo.LaneType laneTypes, VehicleInfo.VehicleType vehicleTypes, float maxLength, bool isHeavyVehicle, bool ignoreBlocked, bool stablePath, bool skipQueue, RoadManager.VehicleType vehicleType)
 {
     while (!Monitor.TryEnter(this.m_bufferLock, SimulationManager.SYNCHRONIZE_TIMEOUT))
     {
     }
     uint num;
     try
     {
         if (!this.m_pathUnits.CreateItem(out num, ref randomizer))
         {
             unit = 0u;
             bool result = false;
             return result;
         }
         this.m_pathUnitCount = (int)(this.m_pathUnits.ItemCount() - 1u);
     }
     finally
     {
         Monitor.Exit(this.m_bufferLock);
     }
     unit = num;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_simulationFlags = 1;
     if (isHeavyVehicle)
     {
         PathUnit[] expr_92_cp_0 = this.m_pathUnits.m_buffer;
         UIntPtr expr_92_cp_1 = (UIntPtr)unit;
         expr_92_cp_0[(int)expr_92_cp_1].m_simulationFlags = (byte)(expr_92_cp_0[(int)expr_92_cp_1].m_simulationFlags | 16);
     }
     if (ignoreBlocked)
     {
         PathUnit[] expr_BB_cp_0 = this.m_pathUnits.m_buffer;
         UIntPtr expr_BB_cp_1 = (UIntPtr)unit;
         expr_BB_cp_0[(int)expr_BB_cp_1].m_simulationFlags = (byte)(expr_BB_cp_0[(int)expr_BB_cp_1].m_simulationFlags | 32);
     }
     if (stablePath)
     {
         PathUnit[] expr_E4_cp_0 = this.m_pathUnits.m_buffer;
         UIntPtr expr_E4_cp_1 = (UIntPtr)unit;
         expr_E4_cp_0[(int)expr_E4_cp_1].m_simulationFlags = (byte)(expr_E4_cp_0[(int)expr_E4_cp_1].m_simulationFlags | 64);
     }
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_pathFindFlags = 0;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_buildIndex = buildIndex;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_position00 = startPosA;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_position01 = endPosA;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_position02 = startPosB;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_position03 = endPosB;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_position11 = vehiclePosition;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_nextPathUnit = 0u;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_laneTypes = (byte)laneTypes;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_vehicleTypes = (byte)vehicleTypes;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_length = maxLength;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_positionCount = 20;
     this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_referenceCount = 1;
     int num2 = 10000000;
     CustomPathFind pathFind = null;
     for (int i = 0; i < this.m_pathFinds.Length; i++)
     {
         CustomPathFind pathFind2 = this.m_pathFinds[i];
         if (pathFind2.IsAvailable && pathFind2.m_queuedPathFindCount < num2)
         {
             num2 = pathFind2.m_queuedPathFindCount;
             pathFind = pathFind2;
         }
     }
     if (pathFind != null && pathFind.CalculatePath(unit, skipQueue, vehicleType))
     {
         return true;
     }
     this.ReleasePath(unit);
     return false;
 }
 // NetSegment.GetClosestLane -- it's only called by the PathManager
 public static bool GetClosestLanePosition(NetSegment seg, Vector3 point, NetInfo.LaneType laneTypes, VehicleInfo.VehicleType vehicleTypes, bool requireConnect, out Vector3 positionA, out int laneIndexA, out float laneOffsetA, out Vector3 positionB, out int laneIndexB, out float laneOffsetB, RoadManager.VehicleType vehicleType)
 {
     positionA = point;
     laneIndexA = -1;
     laneOffsetA = 0f;
     positionB = point;
     laneIndexB = -1;
     laneOffsetB = 0f;
     if (seg.m_flags != NetSegment.Flags.None && seg.m_lanes != 0u)
     {
         NetInfo info = seg.Info;
         if (info.m_lanes != null)
         {
             float num = 1E+09f;
             float num2 = 1E+09f;
             uint num3 = seg.m_lanes;
             int num4 = 0;
             while (num4 < info.m_lanes.Length && num3 != 0u)
             {
                 NetInfo.Lane lane = info.m_lanes[num4];
                 if (lane.CheckType(laneTypes, vehicleTypes) && (lane.m_allowConnect || !requireConnect) && RoadManager.CanUseLane(vehicleType, num3))
                 {
                     Vector3 vector;
                     float num5;
                     Singleton<NetManager>.instance.m_lanes.m_buffer[(int)((UIntPtr)num3)].GetClosestPosition(point, out vector, out num5);
                     float num6 = Vector3.SqrMagnitude(point - vector);
                     if (lane.m_finalDirection == NetInfo.Direction.Backward || lane.m_finalDirection == NetInfo.Direction.AvoidForward)
                     {
                         if (num6 < num2)
                         {
                             num2 = num6;
                             positionB = vector;
                             laneIndexB = num4;
                             laneOffsetB = num5;
                         }
                     }
                     else if (num6 < num)
                     {
                         num = num6;
                         positionA = vector;
                         laneIndexA = num4;
                         laneOffsetA = num5;
                     }
                 }
                 num3 = Singleton<NetManager>.instance.m_lanes.m_buffer[(int)((UIntPtr)num3)].m_nextLane;
                 num4++;
             }
             if (num2 < num)
             {
                 Vector3 vector2 = positionA;
                 int num7 = laneIndexA;
                 float num8 = laneOffsetA;
                 positionA = positionB;
                 laneIndexA = laneIndexB;
                 laneOffsetA = laneOffsetB;
                 positionB = vector2;
                 laneIndexB = num7;
                 laneOffsetB = num8;
             }
             if (!info.m_canCrossLanes)
             {
                 positionB = point;
                 laneIndexB = -1;
                 laneOffsetB = 0f;
             }
         }
     }
     return laneIndexA != -1;
 }
 public bool CreatePath(out uint unit, ref Randomizer randomizer, uint buildIndex, PathUnit.Position startPosA, PathUnit.Position startPosB, PathUnit.Position endPosA, PathUnit.Position endPosB, NetInfo.LaneType laneTypes, VehicleInfo.VehicleType vehicleTypes, float maxLength, RoadManager.VehicleType vehicleType)
 {
     return this.CreatePath(out unit, ref randomizer, buildIndex, startPosA, startPosB, endPosA, endPosB, default(PathUnit.Position), laneTypes, vehicleTypes, maxLength, false, false, false, false, vehicleType);
 }
 // NetSegment.GetClosestLane -- it's only called by the PathManager
 public static bool GetClosestLanePosition(NetSegment seg, Vector3 point, NetInfo.LaneType laneTypes, VehicleInfo.VehicleType vehicleTypes, out Vector3 positionA, out int laneIndexA, out float laneOffsetA, out Vector3 positionB, out int laneIndexB, out float laneOffsetB, RoadManager.VehicleType vehicleType)
 {
     positionA   = point;
     laneIndexA  = -1;
     laneOffsetA = 0f;
     positionB   = point;
     laneIndexB  = -1;
     laneOffsetB = 0f;
     if (seg.m_flags != NetSegment.Flags.None && seg.m_lanes != 0u)
     {
         NetInfo info = seg.Info;
         if (info.m_lanes != null)
         {
             float num  = 1E+09f;
             float num2 = 1E+09f;
             uint  num3 = seg.m_lanes;
             int   num4 = 0;
             while (num4 < info.m_lanes.Length && num3 != 0u)
             {
                 NetInfo.Lane lane = info.m_lanes[num4];
                 if (lane.CheckType(laneTypes, vehicleTypes) && RoadManager.CanUseLane(vehicleType, num3))
                 {
                     Vector3 vector;
                     float   num5;
                     Singleton <NetManager> .instance.m_lanes.m_buffer[(int)((UIntPtr)num3)].GetClosestPosition(point, out vector, out num5);
                     float num6 = Vector3.SqrMagnitude(point - vector);
                     if (lane.m_finalDirection == NetInfo.Direction.Backward || lane.m_finalDirection == NetInfo.Direction.AvoidForward)
                     {
                         if (num6 < num2)
                         {
                             num2        = num6;
                             positionB   = vector;
                             laneIndexB  = num4;
                             laneOffsetB = num5;
                         }
                     }
                     else if (num6 < num)
                     {
                         num         = num6;
                         positionA   = vector;
                         laneIndexA  = num4;
                         laneOffsetA = num5;
                     }
                 }
                 num3 = Singleton <NetManager> .instance.m_lanes.m_buffer[(int)((UIntPtr)num3)].m_nextLane;
                 num4++;
             }
             if (num2 < num)
             {
                 Vector3 vector2 = positionA;
                 int     num7    = laneIndexA;
                 float   num8    = laneOffsetA;
                 positionA   = positionB;
                 laneIndexA  = laneIndexB;
                 laneOffsetA = laneOffsetB;
                 positionB   = vector2;
                 laneIndexB  = num7;
                 laneOffsetB = num8;
             }
             if (!info.m_canCrossLanes)
             {
                 positionB   = point;
                 laneIndexB  = -1;
                 laneOffsetB = 0f;
             }
         }
     }
     return(laneIndexA != -1);
 }
        void SetNodeMarkers(ushort nodeId, FastList <NodeLaneMarker> nodeMarkers)
        {
            NetNode node             = NetManager.instance.m_nodes.m_buffer[nodeId];
            int     offsetMultiplier = node.CountSegments() <= 2 ? 3 : 1;
            ushort  segmentId        = node.m_segment0;

            for (int i = 0; i < 8 && segmentId != 0; i++)
            {
                NetSegment     segment   = NetManager.instance.m_segments.m_buffer[segmentId];
                bool           isEndNode = segment.m_endNode == nodeId;
                Vector3        offset    = segment.FindDirection(segmentId, nodeId) * offsetMultiplier;
                NetInfo.Lane[] lanes     = segment.Info.m_lanes;
                uint           laneId    = segment.m_lanes;
                for (int j = 0; j < lanes.Length && laneId != 0; j++)
                {
                    //if ((lanes[j].m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) != NetInfo.LaneType.None)
                    if ((lanes[j].m_laneType & NetInfo.LaneType.Vehicle) == NetInfo.LaneType.Vehicle)
                    {
                        Vector3           pos     = Vector3.zero;
                        NetInfo.Direction laneDir = ((segment.m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None) ? lanes[j].m_finalDirection : NetInfo.InvertDirection(lanes[j].m_finalDirection);

                        bool isSource = false;
                        if (isEndNode)
                        {
                            if ((laneDir & (NetInfo.Direction.Forward | NetInfo.Direction.Avoid)) == NetInfo.Direction.Forward)
                            {
                                isSource = true;
                            }
                            pos = NetManager.instance.m_lanes.m_buffer[laneId].m_bezier.d;
                        }
                        else
                        {
                            if ((laneDir & (NetInfo.Direction.Backward | NetInfo.Direction.Avoid)) == NetInfo.Direction.Backward)
                            {
                                isSource = true;
                            }
                            pos = NetManager.instance.m_lanes.m_buffer[laneId].m_bezier.a;
                        }

                        nodeMarkers.Add(new NodeLaneMarker()
                        {
                            m_lane     = laneId,
                            m_node     = nodeId,
                            m_position = pos + offset,
                            m_color    = colors[nodeMarkers.m_size],
                            m_isSource = isSource,
                        });
                    }

                    laneId = NetManager.instance.m_lanes.m_buffer[laneId].m_nextLane;
                }

                segmentId = segment.GetRightSegment(nodeId);
                if (segmentId == node.m_segment0)
                {
                    segmentId = 0;
                }
            }

            for (int i = 0; i < nodeMarkers.m_size; i++)
            {
                if (!nodeMarkers.m_buffer[i].m_isSource)
                {
                    continue;
                }

                uint[] connections = RoadManager.GetLaneConnections(nodeMarkers.m_buffer[i].m_lane);
                if (connections == null || connections.Length == 0)
                {
                    continue;
                }

                for (int j = 0; j < nodeMarkers.m_size; j++)
                {
                    if (nodeMarkers.m_buffer[j].m_isSource)
                    {
                        continue;
                    }

                    if (connections.Contains(nodeMarkers.m_buffer[j].m_lane))
                    {
                        nodeMarkers.m_buffer[i].m_connections.Add(nodeMarkers.m_buffer[j]);
                    }
                }
            }
        }
        public bool CalculatePath(uint unit, bool skipQueue, RoadManager.VehicleType vehicleType)
        {
            if (Singleton<PathManager>.instance.AddPathReference(unit))
            {
                while (!Monitor.TryEnter(this.m_queueLock, SimulationManager.SYNCHRONIZE_TIMEOUT))
                {
                }
                try
                {
                    if (skipQueue)
                    {
                        if (this.m_queueLast == 0u)
                        {
                            this.m_queueLast = unit;
                        }
                        else
                        {
                            this.m_pathUnits.m_buffer[(int)((UIntPtr)unit)].m_nextPathUnit = this.m_queueFirst;
                        }
                        this.m_queueFirst = unit;
                    }
                    else
                    {
                        if (this.m_queueLast == 0u)
                        {
                            this.m_queueFirst = unit;
                        }
                        else
                        {
                            this.m_pathUnits.m_buffer[(int)((UIntPtr)this.m_queueLast)].m_nextPathUnit = unit;
                        }
                        this.m_queueLast = unit;
                    }

                    m_pathVehicleType[unit] = vehicleType;

                    PathUnit[] expr_BD_cp_0 = this.m_pathUnits.m_buffer;
                    UIntPtr expr_BD_cp_1 = (UIntPtr)unit;
                    expr_BD_cp_0[(int)expr_BD_cp_1].m_pathFindFlags = (byte)(expr_BD_cp_0[(int)expr_BD_cp_1].m_pathFindFlags | 1);
                    this.m_queuedPathFindCount++;
                    Monitor.Pulse(this.m_queueLock);
                }
                finally
                {
                    Monitor.Exit(this.m_queueLock);
                }
                return true;
            }
            return false;
        }
 public static bool StartPathFind(CarAI carAI, ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, RoadManager.VehicleType vehicleType)
 {
     VehicleInfo info = carAI.m_info;
     bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != Vehicle.Flags.None;
     PathUnit.Position startPosA;
     PathUnit.Position startPosB;
     float num;
     float num2;
     PathUnit.Position endPosA;
     PathUnit.Position endPosB;
     float num3;
     float num4;
     if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle, info.m_vehicleType, allowUnderground, 32f, out startPosA, out startPosB, out num, out num2, vehicleType) && CustomPathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle, info.m_vehicleType, false, 32f, out endPosA, out endPosB, out num3, out num4, vehicleType))
     {
         if (!startBothWays || num < 10f)
         {
             startPosB = default(PathUnit.Position);
         }
         if (!endBothWays || num3 < 10f)
         {
             endPosB = default(PathUnit.Position);
         }
         uint path;
         bool createPathResult;
         CustomPathManager customPathManager = Singleton<PathManager>.instance as CustomPathManager;
         if (customPathManager != null)
             createPathResult = customPathManager.CreatePath(out path, ref Singleton<SimulationManager>.instance.m_randomizer, Singleton<SimulationManager>.instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle, info.m_vehicleType, 20000f, (carAI as IVehicle).IsHeavyVehicle(), (carAI as IVehicle).IgnoreBlocked(vehicleID, ref vehicleData), false, false, vehicleType);
         else
             createPathResult = Singleton<PathManager>.instance.CreatePath(out path, ref Singleton<SimulationManager>.instance.m_randomizer, Singleton<SimulationManager>.instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle, info.m_vehicleType, 20000f, (carAI as IVehicle).IsHeavyVehicle(), (carAI as IVehicle).IgnoreBlocked(vehicleID, ref vehicleData), false, false);
         if (createPathResult)
         {
             if (vehicleData.m_path != 0u)
             {
                 Singleton<PathManager>.instance.ReleasePath(vehicleData.m_path);
             }
             vehicleData.m_path = path;
             vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
             return true;
         }
     }
     return false;
 }
Exemple #12
0
        protected override void OnToolGUI()
        {
            base.OnToolGUI();

            if (m_toolButton == null)
            {
                m_toolButton = TryCreateToolButton();
            }

            if (m_selectedLaneMarkers.Count == 0)
            {
                return;
            }

            if (screenWidth != Screen.width || screenHeight != Screen.height)
            {
                screenWidth        = Screen.width;
                screenHeight       = Screen.height;
                laneButtonsStart   = (700 * screenHeight) / 1080;
                laneButtonsWidth   = 150;                        // font doesn't scale, so width must remain the same for every resolution
                laneButtonsHeight  = (20 * screenHeight) / 1080; // only causes problems in very low resolutions
                laneButtonsSpacing = (5 * screenHeight) / 1080;
            }

            RoadManager.VehicleType vehicleRestrictions = RoadManager.GetVehicleRestrictions(m_selectedLaneMarkers[0].m_lane);
            bool apply = false;
            int  i     = 1;

            if (GUI.Button(new Rect(10, laneButtonsStart, laneButtonsWidth, laneButtonsHeight), "Ambulances: " + ((vehicleRestrictions & RoadManager.VehicleType.Ambulance) == RoadManager.VehicleType.Ambulance ? "On" : "Off")))
            {
                vehicleRestrictions ^= RoadManager.VehicleType.Ambulance;
                apply = true;
            }
            if (GUI.Button(new Rect(10, laneButtonsStart + (laneButtonsHeight + laneButtonsSpacing) * i++, laneButtonsWidth, laneButtonsHeight), "Bus: " + ((vehicleRestrictions & RoadManager.VehicleType.Bus) == RoadManager.VehicleType.Bus ? "On" : "Off")))
            {
                vehicleRestrictions ^= RoadManager.VehicleType.Bus;
                apply = true;
            }
            if (GUI.Button(new Rect(10, laneButtonsStart + (laneButtonsHeight + laneButtonsSpacing) * i++, laneButtonsWidth, laneButtonsHeight), "Cargo Trucks: " + ((vehicleRestrictions & RoadManager.VehicleType.CargoTruck) == RoadManager.VehicleType.CargoTruck ? "On" : "Off")))
            {
                vehicleRestrictions ^= RoadManager.VehicleType.CargoTruck;
                apply = true;
            }
            if (GUI.Button(new Rect(10, laneButtonsStart + (laneButtonsHeight + laneButtonsSpacing) * i++, laneButtonsWidth, laneButtonsHeight), "Fire Trucks: " + ((vehicleRestrictions & RoadManager.VehicleType.FireTruck) == RoadManager.VehicleType.FireTruck ? "On" : "Off")))
            {
                vehicleRestrictions ^= RoadManager.VehicleType.FireTruck;
                apply = true;
            }
            if (GUI.Button(new Rect(10, laneButtonsStart + (laneButtonsHeight + laneButtonsSpacing) * i++, laneButtonsWidth, laneButtonsHeight), "Garbage Trucks: " + ((vehicleRestrictions & RoadManager.VehicleType.GarbageTruck) == RoadManager.VehicleType.GarbageTruck ? "On" : "Off")))
            {
                vehicleRestrictions ^= RoadManager.VehicleType.GarbageTruck;
                apply = true;
            }
            if (GUI.Button(new Rect(10, laneButtonsStart + (laneButtonsHeight + laneButtonsSpacing) * i++, laneButtonsWidth, laneButtonsHeight), "Hearses: " + ((vehicleRestrictions & RoadManager.VehicleType.Hearse) == RoadManager.VehicleType.Hearse ? "On" : "Off")))
            {
                vehicleRestrictions ^= RoadManager.VehicleType.Hearse;
                apply = true;
            }
            if (GUI.Button(new Rect(10, laneButtonsStart + (laneButtonsHeight + laneButtonsSpacing) * i++, laneButtonsWidth, laneButtonsHeight), "Citizens: " + ((vehicleRestrictions & RoadManager.VehicleType.PassengerCar) == RoadManager.VehicleType.PassengerCar ? "On" : "Off")))
            {
                vehicleRestrictions ^= RoadManager.VehicleType.PassengerCar;
                apply = true;
            }
            if (GUI.Button(new Rect(10, laneButtonsStart + (laneButtonsHeight + laneButtonsSpacing) * i++, laneButtonsWidth, laneButtonsHeight), "Police: " + ((vehicleRestrictions & RoadManager.VehicleType.PoliceCar) == RoadManager.VehicleType.PoliceCar ? "On" : "Off")))
            {
                vehicleRestrictions ^= RoadManager.VehicleType.PoliceCar;
                apply = true;
            }
            if (GUI.Button(new Rect(10, laneButtonsStart + (laneButtonsHeight + laneButtonsSpacing) * i++, laneButtonsWidth, laneButtonsHeight), "Emergency: " + ((vehicleRestrictions & RoadManager.VehicleType.Emergency) == RoadManager.VehicleType.Emergency ? "On" : "Off")))
            {
                vehicleRestrictions ^= RoadManager.VehicleType.Emergency;
                apply = true;
            }

            if (apply)
            {
                foreach (SegmentLaneMarker lane in m_selectedLaneMarkers)
                {
                    RoadManager.SetVehicleRestrictions(lane.m_lane, vehicleRestrictions);
                }
            }
        }