// TODO clean up restrictions (currently we do not check if restrictions are equal with the base type)
        public bool HasSegmentRestrictions(ushort segmentId)
        {
            bool ret = false;

            Services.NetService.IterateSegmentLanes(
                segmentId,
                (uint laneId,
                 ref NetLane lane,
                 NetInfo.Lane laneInfo,
                 ushort segId,
                 ref NetSegment segment,
                 byte laneIndex) =>
            {
                ExtVehicleType defaultMask = GetDefaultAllowedVehicleTypes(
                    laneInfo,
                    VehicleRestrictionsMode.Unrestricted);

                ExtVehicleType currentMask = GetAllowedVehicleTypes(
                    segmentId,
                    segment.Info,
                    laneIndex,
                    laneInfo,
                    VehicleRestrictionsMode.Configured);

                if (defaultMask != currentMask)
                {
                    ret = true;
                    return(false);
                }

                return(true);
            });

            return(ret);
        }
        /// <summary>
        /// Sets the allowed vehicle types for the given segment and lane.
        /// </summary>
        /// <param name="segmentId"></param>
        /// <param name="laneIndex"></param>
        /// <param name="laneId"></param>
        /// <param name="allowedTypes"></param>
        /// <returns></returns>
        internal bool SetAllowedVehicleTypes(ushort segmentId,
                                             NetInfo segmentInfo,
                                             uint laneIndex,
                                             NetInfo.Lane laneInfo,
                                             uint laneId,
                                             ExtVehicleType allowedTypes)
        {
            if (!Services.NetService.IsLaneValid(laneId))
            {
                return(false);
            }

            if (!Services.NetService.IsSegmentValid(segmentId))
            {
                // TODO we do not need the segmentId given here. Lane is enough
                return(false);
            }

            allowedTypes &= GetBaseMask(
                segmentInfo.m_lanes[laneIndex],
                VehicleRestrictionsMode.Configured); // ensure default base mask
            Flags.setLaneAllowedVehicleTypes(segmentId, laneIndex, laneId, allowedTypes);

            NotifyStartEndNode(segmentId);

            if (OptionsManager.Instance.MayPublishSegmentChanges())
            {
                Services.NetService.PublishSegmentChanges(segmentId);
            }

            return(true);
        }
 public void ToggleAllowedType(ushort segmentId,
                               NetInfo segmentInfo,
                               uint laneIndex,
                               uint laneId,
                               NetInfo.Lane laneInfo,
                               ExtVehicleType vehicleType,
                               bool add)
 {
     if (add)
     {
         AddAllowedType(segmentId, segmentInfo, laneIndex, laneId, laneInfo, vehicleType);
     }
     else
     {
         RemoveAllowedType(segmentId, segmentInfo, laneIndex, laneId, laneInfo, vehicleType);
     }
 }
        public bool LoadData(List <Configuration.LaneVehicleTypes> data)
        {
            bool success = true;

            Log.Info($"Loading lane vehicle restriction data. {data.Count} elements");

            foreach (Configuration.LaneVehicleTypes laneVehicleTypes in data)
            {
                try {
                    if (!Services.NetService.IsLaneValid(laneVehicleTypes.laneId))
                    {
                        continue;
                    }

                    ExtVehicleType baseMask = GetBaseMask(
                        laneVehicleTypes.laneId,
                        VehicleRestrictionsMode.Configured);
                    ExtVehicleType maskedType = laneVehicleTypes.ApiVehicleTypes & baseMask;
#if DEBUGLOAD
                    Log._Debug($"Loading lane vehicle restriction: lane {laneVehicleTypes.laneId} = " +
                               $"{laneVehicleTypes.vehicleTypes}, masked = {maskedType}");
#endif
                    if (maskedType != baseMask)
                    {
                        Flags.setLaneAllowedVehicleTypes(laneVehicleTypes.laneId, maskedType);
                    }
                    else
                    {
#if DEBUGLOAD
                        Log._Debug($"Masked type does not differ from base type. Ignoring.");
#endif
                    }
                }
                catch (Exception e) {
                    // ignore, as it's probably corrupt save data. it'll be culled on next save
                    Log.Warning("Error loading data from vehicle restrictions: " + e);
                    success = false;
                }
            }

            return(success);
        }
        /// <summary>
        /// Determines if a vehicle may use the given lane.
        /// </summary>
        /// <param name="debug"></param>
        /// <param name="segmentId"></param>
        /// <param name="laneIndex"></param>
        /// <param name="laneId"></param>
        /// <param name="laneInfo"></param>
        /// <returns></returns>
        public bool MayUseLane(ExtVehicleType type,
                               ushort segmentId,
                               byte laneIndex,
                               NetInfo segmentInfo)
        {
            if (type == ExtVehicleType.None /* || type == ExtVehicleType.Tram*/)
            {
                return(true);
            }

            // if (laneInfo == null)
            // laneInfo = Singleton<NetManager>.instance.m_segments.m_buffer[segmentId].Info.m_lanes[laneIndex];*/

            if (segmentInfo == null || laneIndex >= segmentInfo.m_lanes.Length)
            {
                return(true);
            }

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

            if ((laneInfo.m_vehicleType &
                 (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train)) ==
                VehicleInfo.VehicleType.None)
            {
                return(true);
            }

            if (!Options.vehicleRestrictionsEnabled)
            {
                return((GetDefaultAllowedVehicleTypes(
                            laneInfo,
                            VehicleRestrictionsMode.Configured) & type) != ExtVehicleType.None);
            }

            return((GetAllowedVehicleTypes(
                        segmentId,
                        segmentInfo,
                        laneIndex,
                        laneInfo,
                        VehicleRestrictionsMode.Configured) & type) != ExtVehicleType.None);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Removes the given vehicle type from the set of allowed vehicles at the specified lane
        /// </summary>
        /// <param name="segmentId"></param>
        /// <param name="laneIndex"></param>
        /// <param name="laneId"></param>
        /// <param name="laneInfo"></param>
        /// <param name="road"></param>
        /// <param name="vehicleType"></param>
        public void RemoveAllowedType(ushort segmentId,
                                      NetInfo segmentInfo,
                                      uint laneIndex,
                                      uint laneId,
                                      NetInfo.Lane laneInfo,
                                      ExtVehicleType vehicleType)
        {
            if (!Services.NetService.IsLaneAndItsSegmentValid(laneId))
            {
                return;
            }

            if (!Services.NetService.IsSegmentValid(segmentId))
            {
                // TODO we do not need the segmentId given here. Lane is enough
                return;
            }

            ExtVehicleType allowedTypes = GetAllowedVehicleTypes(
                segmentId,
                segmentInfo,
                laneIndex,
                laneInfo,
                VehicleRestrictionsMode.Configured);

            allowedTypes &= ~vehicleType;
            allowedTypes &= GetBaseMask(
                segmentInfo.m_lanes[laneIndex],
                VehicleRestrictionsMode.Configured); // ensure default base mask
            Flags.SetLaneAllowedVehicleTypes(segmentId, laneIndex, laneId, allowedTypes);
            NotifyStartEndNode(segmentId);

            if (OptionsManager.Instance.MayPublishSegmentChanges())
            {
                Services.NetService.PublishSegmentChanges(segmentId);
            }
        }
        /// <summary>
        /// Determines the allowed vehicle types that may approach the given node from the given segment (lane-wise).
        /// </summary>
        /// <param name="segmentId"></param>
        /// <param name="nodeId"></param>
        /// <returns></returns>
        public IDictionary <byte, ExtVehicleType> GetAllowedVehicleTypesAsDict(
            ushort segmentId,
            ushort nodeId,
            VehicleRestrictionsMode busLaneMode)
        {
            IDictionary <byte, ExtVehicleType> ret = new TinyDictionary <byte, ExtVehicleType>();
            NetManager netManager = Singleton <NetManager> .instance;

            if (segmentId == 0 ||
                (netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Created)
                == NetSegment.Flags.None ||
                nodeId == 0 ||
                (netManager.m_nodes.m_buffer[nodeId].m_flags & NetNode.Flags.Created)
                == NetNode.Flags.None)
            {
                return(ret);
            }

            const NetInfo.Direction DIR = NetInfo.Direction.Forward;

            NetInfo.Direction dir2 =
                ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Invert)
                 == NetSegment.Flags.None)
                    ? DIR
                    : NetInfo.InvertDirection(DIR);

            NetInfo segmentInfo = netManager.m_segments.m_buffer[segmentId].Info;
            uint    curLaneId   = netManager.m_segments.m_buffer[segmentId].m_lanes;
            int     numLanes    = segmentInfo.m_lanes.Length;
            uint    laneIndex   = 0;

            while (laneIndex < numLanes && curLaneId != 0u)
            {
                NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex];

                if (laneInfo.m_laneType == NetInfo.LaneType.Vehicle ||
                    laneInfo.m_laneType == NetInfo.LaneType.TransportVehicle)
                {
                    if ((laneInfo.m_vehicleType & VEHICLE_TYPES) != VehicleInfo.VehicleType.None)
                    {
                        ushort toNodeId =
                            (laneInfo.m_finalDirection & dir2) != NetInfo.Direction.None
                                ? netManager.m_segments.m_buffer[segmentId].m_endNode
                                : netManager.m_segments.m_buffer[segmentId].m_startNode;

                        if ((laneInfo.m_finalDirection & NetInfo.Direction.Both) ==
                            NetInfo.Direction.Both || toNodeId == nodeId)
                        {
                            ExtVehicleType vehicleTypes = GetAllowedVehicleTypes(
                                segmentId,
                                segmentInfo,
                                laneIndex,
                                laneInfo,
                                busLaneMode);
                            ret[(byte)laneIndex] = vehicleTypes;
                        }
                    }
                }

                curLaneId = netManager.m_lanes.m_buffer[curLaneId].m_nextLane;
                ++laneIndex;
            }

            return(ret);
        }
 public bool IsAllowed(ExtVehicleType?allowedTypes, ExtVehicleType vehicleType)
 {
     return(allowedTypes == null ||
            ((ExtVehicleType)allowedTypes & vehicleType) != ExtVehicleType.None);
 }