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);
 }
Exemple #2
0
        public static NetInfo[] GetSubPrefabs(NetInfo prefab)
        {
            var subPrefabs = new NetInfo[NET_TYPE_NAMES.Length];

            if (prefab.m_netAI is TrainTrackAI)
            {
                var netAI = (TrainTrackAI) prefab.m_netAI;
                subPrefabs[(int)NetType.Tunnel] = netAI.m_tunnelInfo;
                subPrefabs[(int)NetType.Ground] = netAI.m_info;
                subPrefabs[(int)NetType.Elevated] = netAI.m_elevatedInfo;
                subPrefabs[(int)NetType.Bridge] = netAI.m_bridgeInfo;
            }
            else if (prefab.m_netAI is RoadAI)
            {
                var netAI = (RoadAI) prefab.m_netAI;
                subPrefabs[(int)NetType.Tunnel] = netAI.m_tunnelInfo;
                subPrefabs[(int)NetType.Ground] = netAI.m_info;
                subPrefabs[(int)NetType.Elevated] = netAI.m_elevatedInfo;
                subPrefabs[(int)NetType.Bridge] = netAI.m_bridgeInfo;
            }
            else if (prefab.m_netAI is PedestrianPathAI)
            {
                var netAI = (PedestrianPathAI) prefab.m_netAI;
                subPrefabs[(int)NetType.Tunnel] = netAI.m_tunnelInfo;
                subPrefabs[(int)NetType.Ground] = netAI.m_info;
                subPrefabs[(int)NetType.Elevated] = netAI.m_elevatedInfo;
                subPrefabs[(int)NetType.Bridge] = netAI.m_bridgeInfo;
            }
            return subPrefabs;
        }
		/// <summary>
		/// Determines 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="laneInfo"></param>
		/// <returns></returns>
		internal static ExtVehicleType GetAllowedVehicleTypes(ushort segmentId, uint laneIndex, uint laneId, NetInfo.Lane laneInfo) {
			if (Flags.IsInitDone()) {
				ExtVehicleType?[] fastArray = Flags.laneAllowedVehicleTypesArray[segmentId];
				if (fastArray != null && fastArray.Length > laneIndex && fastArray[laneIndex] != null) {
					return (ExtVehicleType)fastArray[laneIndex];
				}
			}

			ExtVehicleType ret = ExtVehicleType.None;
			if ((laneInfo.m_vehicleType & VehicleInfo.VehicleType.Bicycle) != VehicleInfo.VehicleType.None)
				ret |= ExtVehicleType.Bicycle;
			if ((laneInfo.m_vehicleType & VehicleInfo.VehicleType.Tram) != VehicleInfo.VehicleType.None)
				ret |= ExtVehicleType.Tram;
			if ((laneInfo.m_laneType & NetInfo.LaneType.TransportVehicle) != NetInfo.LaneType.None)
				ret |= ExtVehicleType.RoadPublicTransport | ExtVehicleType.Emergency;
			else if ((laneInfo.m_vehicleType & VehicleInfo.VehicleType.Car) != VehicleInfo.VehicleType.None)
				ret |= ExtVehicleType.RoadVehicle;
			if ((laneInfo.m_vehicleType & (VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Metro)) != VehicleInfo.VehicleType.None)
				ret |= ExtVehicleType.RailVehicle;
			if ((laneInfo.m_vehicleType & VehicleInfo.VehicleType.Ship) != VehicleInfo.VehicleType.None)
				ret |= ExtVehicleType.Ship;
			if ((laneInfo.m_vehicleType & VehicleInfo.VehicleType.Plane) != VehicleInfo.VehicleType.None)
				ret |= ExtVehicleType.Plane;

			return ret;
		}
        public new 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, ItemClass.Service vehicleService)
        {
            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;

            byte simulationFlags = createSimulationFlag(isHeavyVehicle, ignoreBlocked, stablePath, vehicleService);
            assignPathProperties(unit, buildIndex, startPosA, startPosB, endPosA, endPosB, vehiclePosition, laneTypes, vehicleTypes, maxLength, simulationFlags);

            return findShortestPath(unit, skipQueue);
        }
		/// <summary>
		/// Determines the currently set speed limit for the given segment and lane direction in terms of discrete speed limit levels.
		/// An in-game speed limit of 2.0 (e.g. on highway) is hereby translated into a discrete speed limit value of 100 (km/h).
		/// </summary>
		/// <param name="segmentId"></param>
		/// <param name="dir"></param>
		/// <returns></returns>
		public static ushort GetCustomSpeedLimit(ushort segmentId, NetInfo.Direction dir) {
			// calculate the currently set mean speed limit
			if (segmentId == 0)
				return 0;
			if ((Singleton<NetManager>.instance.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Created) == NetSegment.Flags.None)
				return 0;

			var segmentInfo = Singleton<NetManager>.instance.m_segments.m_buffer[segmentId].Info;
			uint curLaneId = Singleton<NetManager>.instance.m_segments.m_buffer[segmentId].m_lanes;
			int laneIndex = 0;
			float meanSpeedLimit = 0f;
			uint validLanes = 0;
			while (laneIndex < segmentInfo.m_lanes.Length && curLaneId != 0u) {
				NetInfo.Direction d = segmentInfo.m_lanes[laneIndex].m_direction;
				if ((segmentInfo.m_lanes[laneIndex].m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) == NetInfo.LaneType.None || d != dir)
					goto nextIter;

				ushort? setSpeedLimit = Flags.getLaneSpeedLimit(curLaneId);
				if (setSpeedLimit != null)
					meanSpeedLimit += ToGameSpeedLimit((ushort)setSpeedLimit); // custom speed limit
				else
					meanSpeedLimit += segmentInfo.m_lanes[laneIndex].m_speedLimit; // game default
				++validLanes;

				nextIter:
				curLaneId = Singleton<NetManager>.instance.m_lanes.m_buffer[curLaneId].m_nextLane;
				laneIndex++;
			}

			if (validLanes > 0)
				meanSpeedLimit /= (float)validLanes;
			return ToCustomSpeedLimit(meanSpeedLimit);
		}
        public static bool CreateSegment(NetManager _this, out ushort segmentID, ref Randomizer randomizer, NetInfo info, ushort startNode, ushort endNode, Vector3 startDirection, Vector3 endDirection, uint buildIndex, uint modifiedIndex, bool invert)
        {
            var ai = info.m_netAI as RoadAI;
            if (ai != null && ai.m_enableZoning)
            {
                var caller = new System.Diagnostics.StackFrame(1).GetMethod().Name;

                switch (caller)
                {
                    case "MoveMiddleNode": // segment that was modified because user added network, apply style of previous segment
                        newBlockColumnCount = MoveMiddleNode_releasedColumnCount >= 0 ?
                            MoveMiddleNode_releasedColumnCount : InputThreadingExtension.userSelectedColumnCount;
                        break;

                    case "SplitSegment": // segment that was split by new node, apply style of previous segment
                        newBlockColumnCount = SplitSegment_releasedColumnCount >= 0 ?
                            SplitSegment_releasedColumnCount : InputThreadingExtension.userSelectedColumnCount;
                        break;

                    default: // unknown caller (e.g. new road placed), set to depth selected by user
                        newBlockColumnCount = InputThreadingExtension.userSelectedColumnCount;
                        SplitSegment_releasedColumnCount = -1;
                        MoveMiddleNode_releasedColumnCount = -1;
                        break;
                }
            }

            // Call original method
            CreateSegmentRedirector.Revert();
            var success = _this.CreateSegment(out segmentID, ref randomizer, info, startNode, endNode, startDirection, endDirection, buildIndex, modifiedIndex, invert);
            CreateSegmentRedirector.Apply();

            return success;
        }
        public void BuildUp(NetInfo info, NetInfoVersion version)
        {
            ///////////////////////////
            // Texturing             //
            ///////////////////////////
            SetupTextures(info, version);

            ///////////////////////////
            // Set up                //
            ///////////////////////////
            info.m_createGravel = false;
            info.m_createPavement = true;
            info.m_setVehicleFlags = 0;

            ///////////////////////////
            // AI                    //
            ///////////////////////////
            var playerNetAI = info.GetComponent<PlayerNetAI>();

            if (playerNetAI != null)
            {
                playerNetAI.m_constructionCost = playerNetAI.m_constructionCost * 3 / 2;
                playerNetAI.m_maintenanceCost = playerNetAI.m_maintenanceCost * 3 / 2;
            }
        }
 // from CitizenAI
 public static bool FindPathPosition(ushort instanceID, ref CitizenInstance citizenData, Vector3 pos, NetInfo.LaneType laneTypes, VehicleInfo.VehicleType vehicleTypes, bool allowUnderground, out PathUnit.Position position)
 {
     position = default(PathUnit.Position);
     float num = 1E+10f;
     PathUnit.Position position2;
     PathUnit.Position position3;
     float num2;
     float num3;
     if (CustomPathManager.FindPathPosition(pos, ItemClass.Service.Road, laneTypes, vehicleTypes, allowUnderground, 32f, out position2, out position3, out num2, out num3, RoadManager.VehicleType.PassengerCar) && num2 < num)
     {
         num = num2;
         position = position2;
     }
     PathUnit.Position position4;
     PathUnit.Position position5;
     float num4;
     float num5;
     if (CustomPathManager.FindPathPosition(pos, ItemClass.Service.Beautification, laneTypes, vehicleTypes, allowUnderground, 32f, out position4, out position5, out num4, out num5, RoadManager.VehicleType.PassengerCar) && num4 < num)
     {
         num = num4;
         position = position4;
     }
     PathUnit.Position position6;
     PathUnit.Position position7;
     float num6;
     float num7;
     if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None && CustomPathManager.FindPathPosition(pos, ItemClass.Service.PublicTransport, laneTypes, vehicleTypes, allowUnderground, 32f, out position6, out position7, out num6, out num7, RoadManager.VehicleType.PassengerCar) && num6 < num)
     {
         position = position6;
     }
     return position.m_segment != 0;
 }
        public float GetActiveTreeDistance(NetInfo prefab, LanePosition position)
        {
            var segmentData = SegmentDataManager.Instance.GetActiveOptions(prefab);

            var result = 0f;
            if (segmentData != null && segmentData.Features.IsFlagSet(SegmentData.FeatureFlags.RepeatDistances))
            {
                switch (position)
                {
                    case LanePosition.Left:
                        result = segmentData.RepeatDistances.x;
                        break;
                    case LanePosition.Middle:
                        result = segmentData.RepeatDistances.y;
                        break;
                    case LanePosition.Right:
                        result = segmentData.RepeatDistances.z;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException(nameof(position));
                }
            }

            return result > 0f ? result : GetDefaultTreeDistance(prefab, position);
        }
        //Test
        public static void AdjustElevation(ushort startNode, Vector3 vector, NetInfo netInfo)
        {
            NetManager nm = NetManager.instance;
            var node = nm.m_nodes.m_buffer[startNode];
            float elevation = NetSegment.SampleTerrainHeight(netInfo, vector, false);
            byte ele = (byte)Mathf.Clamp(Mathf.RoundToInt(Math.Max(node.m_elevation, elevation)), 0, 255);
            float terrain = TerrainManager.instance.SampleRawHeightSmoothWithWater(node.m_position, false, 0f);
            node.m_elevation = ele;
            node.m_position = new Vector3(node.m_position.x, ele + terrain, node.m_position.z);
            if (elevation < 11f)
            {
                node.m_flags |= NetNode.Flags.OnGround;
            }
            else
            {
                node.m_flags &= ~NetNode.Flags.OnGround;
                UpdateSegment(node.m_segment0, elevation);
                UpdateSegment(node.m_segment1, elevation);
                UpdateSegment(node.m_segment2, elevation);
                UpdateSegment(node.m_segment3, elevation);
                UpdateSegment(node.m_segment4, elevation);
                UpdateSegment(node.m_segment5, elevation);
                UpdateSegment(node.m_segment6, elevation);
                UpdateSegment(node.m_segment7, elevation);

            }
            nm.m_nodes.m_buffer[startNode] = node;
            //Singleton<NetManager>.instance.UpdateNode(startNode);
        }
        public SegmentData GetActiveOptions(NetInfo prefab)
        {
            var options = _assetMode ? _assetSegmentOptions : _selectedSegmentOptions;

            SegmentData segmentData;
            options.TryGetValue(prefab, out segmentData);
            return segmentData;
        }
Exemple #12
0
 public bool Populate(NetInfo prefab)
 {
     Populating = true;
     SelectedPrefab = prefab;
     var result = PopulateImpl();
     Populating = false;
     return result;
 }
 protected override bool IsServiceValid(NetInfo info)
 {
     if (info.GetService() == this.service)
       return true;
     if (this.isMapEditor)
       return info.GetService() == ItemClass.Service.PublicTransport;
     return false;
 }
        public static void CalculateGuideLines(NetInfo netInfo, NetTool.ControlPoint startPoint, NetTool.ControlPoint endPoint,
			IList<GuideLine> resultList)
        {
            lock (SegmentCache) {

                var startPosition = startPoint.m_position;
                var endPosition = endPoint.m_position;

                //var segments = NetManager.instance.m_segments;
                //NetManager.instance.GetClosestSegments(endPosition, SegmentCache, out _segmentCacheCount);

                NetUtil.GetClosestSegments(netInfo, endPosition, SegmentCache, out _segmentCacheCount);
                SnapController.DebugPrint = String.Format("Closest Segment Count: {0}", _segmentCacheCount);

                var c = _segmentCacheCount;
                for (ushort i = 0; i < c; i++) {

                    var segmentId = SegmentCache[i];

                    var s = NetManager.instance.m_segments.m_buffer[segmentId];

                    // Ensure they are part of the same network
                    if (!NetUtil.AreSimilarClass(s.Info, netInfo))
                        continue;

                    if (
                        Vector3Extensions.DistanceSquared(NetManager.instance.m_nodes.m_buffer[s.m_startNode].m_position, endPosition) >
                        Settings.MaxGuideLineQueryDistanceSqr)
                        continue;

                    // Test the start and end of the segment

                    // Check if the node can branch in the guide direction (angles less than 45deg or so should be discarded)
                    if (CanNodeBranchInDirection(s.m_endNode, s.m_startDirection)) {

                        var endNode = NetManager.instance.m_nodes.m_buffer[s.m_endNode];

                        TestLine(s.Info, startPosition, endPosition,
                            endNode.m_position,
                            endNode.m_position + s.m_startDirection.Flatten(),
                            resultList, segmentId, s.m_endNode);

                    }

                    if (CanNodeBranchInDirection(s.m_startNode, s.m_endDirection)) {

                        var startNode = NetManager.instance.m_nodes.m_buffer[s.m_startNode];

                        TestLine(s.Info, startPosition, endPosition,
                            startNode.m_position,
                            startNode.m_position + s.m_endDirection.Flatten(),
                            resultList, segmentId, s.m_startNode);

                    }
                }

            }
        }
        public static bool AreSimilarClass(NetInfo i1, NetInfo i2)
        {
            if (i1 == i2)
                return true;

            if (i1 != null && i2 != null && i1.m_class.m_service == i2.m_class.m_service)
                return true;

            return false;
        }
 public static void CreatePavement(NetInfo prefab)
 {
     if (prefab == null)
     {
         return;
     }
     prefab.m_createGravel = false;
     prefab.m_createRuining = false;
     prefab.m_createPavement = true;
 }
 public static NetInfo ClonePrefab(NetInfo originalPrefab, string newName, Transform parentTransform)
 {
     var instance = Object.Instantiate(originalPrefab.gameObject);
     instance.name = newName;
     instance.transform.SetParent(parentTransform);
     instance.transform.localPosition = new Vector3(-7500, -7500, -7500);
     var newPrefab = instance.GetComponent<NetInfo>();
     instance.SetActive(false);
     newPrefab.m_prefabInitialized = false;
     return newPrefab;
 }
 public static void MakePedestrianLanesNarrow(NetInfo prefab)
 {
     if (prefab?.m_lanes == null)
     {
         return;
     }
     foreach (var lane in prefab.m_lanes.Where(lane => lane != null && lane.m_laneType == NetInfo.LaneType.Pedestrian))
     {
         lane.m_width = 2;
         lane.m_position = Math.Sign(lane.m_position) * (4 + .5f * lane.m_width);
     }
 }
        public static void SetHighwayProps(this NetInfo info, NetInfo highwayInfoTemplate)
        {
            var leftHwLane = highwayInfoTemplate
                .m_lanes
                .Where(l => l != null && l.m_laneProps != null && l.m_laneProps.name != null && l.m_laneProps.m_props != null)
                .FirstOrDefault(l => l.m_laneProps.name.ToLower().Contains("left"));

            var rightHwLane = highwayInfoTemplate
                .m_lanes
                .Where(l => l != null && l.m_laneProps != null && l.m_laneProps.name != null && l.m_laneProps.m_props != null)
                .FirstOrDefault(l => l.m_laneProps.name.ToLower().Contains("right"));

            foreach (var lane in info.m_lanes)
            {
                if (lane.m_laneProps != null && lane.m_laneProps.name != null)
                {
                    if (leftHwLane != null)
                    {
                        if (lane.m_laneProps.name.ToLower().Contains("left"))
                        {
                            var newProps = ScriptableObject.CreateInstance<NetLaneProps>();
                            newProps.name = "Highway6L Left Props";

                            newProps.m_props = leftHwLane
                                .m_laneProps
                                .m_props
                                .Select(p => p.ShallowClone())
                                .ToArray();

                            lane.m_laneProps = newProps;
                        }
                    }

                    if (rightHwLane != null)
                    {
                        if (lane.m_laneProps.name.ToLower().Contains("right"))
                        {
                            var newProps = ScriptableObject.CreateInstance<NetLaneProps>();
                            newProps.name = "Highway6L Right Props";

                            newProps.m_props = rightHwLane
                                .m_laneProps
                                .m_props
                                .Select(p => p.ShallowClone())
                                .ToArray();

                            lane.m_laneProps = newProps;
                        }
                    }
                }
            }
        }
        public PropInfo GetActiveStreetLight(NetInfo prefab)
        {
            var segmentData = SegmentDataManager.Instance.GetActiveOptions(prefab);

            if (segmentData == null || !segmentData.Features.IsFlagSet(SegmentData.FeatureFlags.StreetLight))
            {
                return GetDefaultStreetLight(prefab);
            }
            else
            {
                return segmentData.StreetLightPrefab;
            }
        }
        public float GetActiveStreetLightDistance(NetInfo prefab)
        {
            var segmentData = SegmentDataManager.Instance.GetActiveOptions(prefab);

            if (segmentData != null && segmentData.Features.IsFlagSet(SegmentData.FeatureFlags.RepeatDistances) && segmentData.RepeatDistances.w > 0f)
            {
                return segmentData.RepeatDistances.w;
            }
            else
            {
                return GetDefaultStreetLightDistance(prefab);
            }
        }
        public void BuildUp(NetInfo info, NetInfoVersion version)
        {
            ///////////////////////////
            // 3DModeling            //
            ///////////////////////////
            info.Setup8mNoSwWoodMesh(version);

            ///////////////////////////
            // Texturing             //
            ///////////////////////////
            if (version == NetInfoVersion.Ground)
            {
                info.SetupGroundNakedTextures(version);
            }
            else
            {
                info.SetupElevatedBoardWalkTextures(version);
            }

            ///////////////////////////
            // Set up                //
            ///////////////////////////
            info.m_createGravel = true;
            info.m_createPavement = false;
            info.SetupTinyPed(version);

            if (version == NetInfoVersion.Ground)
            {
                info.m_setVehicleFlags = Vehicle.Flags.OnGravel;
            }

            ///////////////////////////
            // AI                    //
            ///////////////////////////
            var pedestrianVanilla = Prefabs.Find<NetInfo>(NetInfos.Vanilla.PED_PAVEMENT);
            switch (version)
            {
                case NetInfoVersion.Ground:
                    {
                        var vanillaplayerNetAI = pedestrianVanilla.GetComponent<PlayerNetAI>();
                        var playerNetAI = info.GetComponent<PlayerNetAI>();

                        if (playerNetAI != null)
                        {
                            playerNetAI.m_constructionCost = vanillaplayerNetAI.m_constructionCost;
                            playerNetAI.m_maintenanceCost = vanillaplayerNetAI.m_maintenanceCost;
                        }
                    }
                    break;
            }
        }
 private bool IsRoadEligibleToPublicTransport(NetInfo info)
 {
     if (this.category == "PublicTransportTrain" && (info.m_vehicleTypes & VehicleInfo.VehicleType.Train) != VehicleInfo.VehicleType.None || this.category == "PublicTransportMetro" && (info.m_vehicleTypes & VehicleInfo.VehicleType.Metro) != VehicleInfo.VehicleType.None || this.category == "PublicTransportBus" && (info.m_laneTypes & NetInfo.LaneType.TransportVehicle) != NetInfo.LaneType.None)
         return true;
     if (this.category == "PublicTransportTram")
         return (info.m_vehicleTypes & VehicleInfo.VehicleType.Tram) != VehicleInfo.VehicleType.None;
     //begin mod
     if (this.category == "PublicTransportPlane")
         return (info.m_vehicleTypes & VehicleInfo.VehicleType.Plane) != VehicleInfo.VehicleType.None;
     if (this.category == "PublicTransportShip")
         return (info.m_vehicleTypes & VehicleInfo.VehicleType.Ship) != VehicleInfo.VehicleType.None;
     //end mod
     return false;
 }
        public static NetInfo.Lane FindLane(this NetInfo info, NetInfo.LaneType predicate, bool crashOnNotFound = true)
        {
            var lane = info
                .m_lanes
                .FirstOrDefault(l => l.m_laneType == NetInfo.LaneType.Vehicle);

            if (lane == null)
            {
                if (crashOnNotFound)
                {
                    throw new Exception("TFW: Lane not found");
                }
            }

            return lane;
        }
Exemple #25
0
 void CopyAttributes(NetInfo.Lane lane)
 {
     this.m_position = lane.m_position;
     this.m_width = lane.m_width;
     this.m_verticalOffset = lane.m_verticalOffset;
     this.m_stopOffset = lane.m_stopOffset;
     this.m_speedLimit = lane.m_speedLimit;
     this.m_direction = lane.m_direction;
     this.m_laneType = lane.m_laneType;
     this.m_vehicleType = lane.m_vehicleType;
     this.m_laneProps = lane.m_laneProps;
     this.m_allowStop = lane.m_allowStop;
     this.m_useTerrainHeight = lane.m_useTerrainHeight;
     this.m_finalDirection = lane.m_finalDirection;
     this.m_similarLaneIndex = lane.m_similarLaneIndex;
     this.m_similarLaneCount = lane.m_similarLaneCount;
 }
		/// <summary>
		/// Determines the average default speed limit for a given NetInfo object in terms of discrete speed limit levels.
		/// An in-game speed limit of 2.0 (e.g. on highway) is hereby translated into a discrete speed limit value of 100 (km/h).
		/// </summary>
		/// <param name="segmentInfo"></param>
		/// <param name="dir"></param>
		/// <returns></returns>
		public static ushort GetAverageDefaultCustomSpeedLimit(NetInfo segmentInfo, NetInfo.Direction? dir=null) {
			// calculate the currently set mean speed limit
			float meanSpeedLimit = 0f;
			uint validLanes = 0;
			for (int i = 0; i < segmentInfo.m_lanes.Length; ++i) {
				NetInfo.Direction d = segmentInfo.m_lanes[i].m_direction;
				if ((segmentInfo.m_lanes[i].m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) == NetInfo.LaneType.None || (dir != null && d != dir))
					continue;

				meanSpeedLimit += segmentInfo.m_lanes[i].m_speedLimit;
				++validLanes;
			}

			if (validLanes > 0)
				meanSpeedLimit /= (float)validLanes;
			return ToCustomSpeedLimit(meanSpeedLimit);
		}
        public TreeInfo GetActiveTree(NetInfo prefab, LanePosition position)
        {
            var segmentData = SegmentDataManager.Instance.GetActiveOptions(prefab);

            if (segmentData == null || !segmentData.Features.IsFlagSet(position.ToTreeFeatureFlag()))
            {
                return GetDefaultTree(prefab, position);
            }
            else
            {
                switch (position)
                {
                    case LanePosition.Left: return segmentData.TreeLeftPrefab;
                    case LanePosition.Middle: return segmentData.TreeMiddlePrefab;
                    case LanePosition.Right: return segmentData.TreeRightPrefab;
                    default: throw new ArgumentOutOfRangeException(nameof(position));
                }
            }
        }
 public static void HandleAsymComplementarySegmentsFlags(NetInfo.Segment fSegment, NetInfo.Segment bSegment, LanesLayoutStyle lanesLayoutStyle)
 {
     switch (lanesLayoutStyle)
     {
         case LanesLayoutStyle.AsymL1R2:
         case LanesLayoutStyle.AsymL1R3:
             fSegment.m_forwardForbidden |= NetSegment.Flags.Invert;
             fSegment.m_backwardRequired |= NetSegment.Flags.Invert;
             bSegment.m_forwardRequired |= NetSegment.Flags.Invert;
             bSegment.m_backwardForbidden |= NetSegment.Flags.Invert;
             break;
         case LanesLayoutStyle.AsymL3R1:
             fSegment.m_forwardRequired |= NetSegment.Flags.Invert;
             fSegment.m_backwardForbidden |= NetSegment.Flags.Invert;
             bSegment.m_forwardForbidden |= NetSegment.Flags.Invert;
             bSegment.m_backwardRequired |= NetSegment.Flags.Invert;
             break;
     }
 }
        private static void SetupTextures(NetInfo info, NetInfoVersion version)
        {
            switch (version)
            {
                case NetInfoVersion.Ground:
                    info.SetAllSegmentsTexture(
                        new TextureSet
                           (null,
                            @"Roads\Common\Textures\Plain\Ground_Segment__AlphaMap.png"),
                        new LODTextureSet
                           (@"Roads\Common\Textures\Plain\Ground_Segment_LOD__MainTex.png",
                            @"Roads\Common\Textures\Plain\Ground_Segment_LOD__AlphaMap.png",
                            @"Roads\Common\Textures\Plain\Ground_Segment_LOD__XYSMap.png"));

                    foreach (var node in info.m_nodes)
                    {
                        if (node.m_flagsRequired == NetNode.Flags.Transition)
                        {
                            node.SetTextures(
                                new TextureSet
                                   (null,
                                    @"Roads\Common\Textures\Plain\Ground_Trans__AlphaMap.png"),
                                new LODTextureSet
                                   (@"Roads\Common\Textures\Plain\Ground_Trans_LOD__MainTex.png",
                                    @"Roads\Common\Textures\Plain\Ground_Trans_LOD__AlphaMap.png",
                                    @"Roads\Common\Textures\Plain\Ground_Trans_LOD__XYSMap.png"));
                        }
                        else
                        {
                            node.SetTextures(
                                new TextureSet
                                   (null,
                                    @"Roads\Common\Textures\Plain\Ground_Segment__AlphaMap.png"),
                                new LODTextureSet
                                   (@"Roads\Common\Textures\Plain\Ground_Node_LOD__MainTex.png",
                                    @"Roads\Common\Textures\Plain\Ground_Node_LOD__AlphaMap.png",
                                    @"Roads\Common\Textures\Plain\Ground_Node_LOD__XYSMap.png"));
                        }
                    }
                    break;
            }
        }
        public void Update()
        {
            var prefab = GetToolPrefab();
            var alwaysVisible = Options.OptionsHolder.Options.alwaysVisible;
            if (prefab == null && !alwaysVisible)
            {
                NoPillarsUI.Hide();
                if (currentPrefab == null && currentAlwaysVisible == alwaysVisible)
                {
                    return;
                }
                Reset();
                currentPrefab = null;
                if (Options.OptionsHolder.Options.resetOnHide)
                {
                    NoPillarsUI.Reset();
                }
                currentAlwaysVisible = alwaysVisible;
            }
            else {
                currentAlwaysVisible = alwaysVisible;
                NoPillarsUI.Show();
                var collide = NoPillarsUI.Collide;
                var pillars = NoPillarsUI.Pillars;
                if (currentCollide == collide && currentPillars == pillars)
                {
                    return;
                }
                Reset();
                currentPrefab = prefab;
                currentPillars = pillars;
                currentCollide = collide;
                savedMetadata = new List<NetInfoExtensions.Metadata>();

                foreach (var prefabToModify in Util.GetAllPrefabs())
                {
                    savedMetadata.Add(prefabToModify.GetMetadata());
                    prefabToModify.SetMetadata(collide, pillars);
                }
            }
        }
        public static void HideCrossings0(Material material, Material segMaterial, NetInfo info, bool lod = false)
        {
            if (material == null)
            {
                throw new ArgumentNullException("material");
            }
            //if (segMaterial == null) throw new ArgumentNullException("segMaterial");
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            Texture2D tex, tex2;
            bool      dump = false;

#if DEBUG
            dump = false;
#endif
            if (dump)
            {
                DumpUtils.Dump(info);
            }

            tex = material.TryGetTexture2D(ID_Defuse);
            Log.Debug($"material={material} tex={tex} h={tex?.height} w={tex?.width}");
            if (tex != null)
            {
                if (dump)
                {
                    DumpUtils.Dump(tex, info);
                }
                if (TextureCache.Contains(tex))
                {
                    tex = TextureCache[tex] as Texture2D;
                    Log.Info("Texture cache hit: " + tex.name);
                }
                else
                {
                    Log.Info("processing Defuse texture for " + tex.name);
                    tex = tex.GetReadableCopy();
                    tex.CropAndStrech(); if (dump)
                    {
                        DumpUtils.Dump(tex, info);
                    }
                    tex.Finalize(lod);
                    TextureCache[material.GetTexture(ID_Defuse)] = tex;
                }
                if (dump)
                {
                    DumpUtils.Dump(tex, info);
                }
                material.SetTexture(ID_Defuse, tex);
                //Log.Info($"material={material} tex={tex} h={tex.height} w={tex.width}");
                if (dump)
                {
                    DumpUtils.Dump(tex, DumpUtils.GetFilePath(ID_Defuse, "node-processed", info));
                }
            }

            tex = material.TryGetTexture2D(ID_APRMap);

            if (tex != null && tex.name != "RoadSmallNode-default-apr" && tex.name != "BasicRoad2_Junction-apr")
            {
                segMaterial = segMaterial ?? GetSegmentMaterial(info, ID_APRMap);
                tex2        = segMaterial?.TryGetTexture2D(ID_APRMap);
                if (tex != null && tex2 != null)
                {
                    if (dump)
                    {
                        DumpUtils.Dump(tex, info);
                    }
                    if (dump)
                    {
                        DumpUtils.Dump(tex2, info);
                    }
                    if (TextureCache.Contains(tex))
                    {
                        tex = TextureCache[tex] as Texture2D;
                        Log.Info("Texture cache hit: " + tex.name);
                    }
                    else
                    {
                        Log.Info("processing APR texture for " + tex.name);
                        bool linear = lod && !info.IsNExt();
                        tex  = tex.GetReadableCopy(linear: linear);
                        tex2 = tex2.GetReadableCopy(linear: linear);
                        if (tex2.width == tex.width * 2)
                        {
                            tex2 = TextureUtils.CutToSize(tex2, tex.width, tex.height);
                            if (dump)
                            {
                                DumpUtils.Dump(tex2, info);
                            }
                        }

                        tex.CropAndStrech(); if (dump)
                        {
                            DumpUtils.Dump(tex, info);
                        }
                        if (info.m_netAI is RoadAI)
                        {
                            if (info.isAsym() && !info.isOneWay())
                            {
                                tex2.Mirror();
                                if (dump)
                                {
                                    DumpUtils.Dump(tex2, info);
                                }
                            }
                            tex2.Scale(info.ScaleRatio());
                            if (info.ScaleRatio() != 1f && dump)
                            {
                                DumpUtils.Dump(tex2, info);
                            }
                        }
                        tex.MeldDiff(tex2); if (dump)
                        {
                            DumpUtils.Dump(tex, info);
                        }

                        tex.Finalize(lod);
                        TextureCache[material.GetTexture(ID_APRMap)] = tex;
                    }
                    material.SetTexture(ID_APRMap, tex);
                    if (dump)
                    {
                        DumpUtils.Dump(tex, DumpUtils.GetFilePath(ID_APRMap, "node-processed", info));
                    }
                } // end if cache
            }     // end if tex
        }         // end if category
Exemple #32
0
        /// <summary>
        ///     This methods skips our detour by calling the original method from the game, allowing the creation of the needed
        ///     segment.
        /// </summary>
        /// <param name="segment"></param>
        /// <param name="randomizer"></param>
        /// <param name="info"></param>
        /// <param name="startNode"></param>
        /// <param name="endNode"></param>
        /// <param name="startDirection"></param>
        /// <param name="endDirection"></param>
        /// <param name="buildIndex"></param>
        /// <param name="modifiedIndex"></param>
        /// <param name="invert"></param>
        /// <returns></returns>
        private static bool CreateSegmentOriginal(out ushort segment, ref Randomizer randomizer, NetInfo info,
                                                  ushort startNode, ushort endNode, Vector3 startDirection, Vector3 endDirection, uint buildIndex,
                                                  uint modifiedIndex, bool invert)
        {
            Revert();

            var result = NetManager.instance.CreateSegment(out segment, ref randomizer, info, startNode, endNode,
                                                           startDirection, endDirection, buildIndex, modifiedIndex, invert);

            Deploy();

            return(result);
        }
        public static Material HideCrossings(Material material, Material segMaterial, NetInfo info, bool lod = false)
        {
            try {
                if (MaterialCache == null)
                {
                    return(material); // program is loading/unloading
                }
                if (MaterialCache.Contains(material))
                {
                    return((Material)MaterialCache[material]);
                }

                var      ticks = System.Diagnostics.Stopwatch.StartNew();
                Material ret   = new Material(material);
                HideCrossings0(ret, segMaterial, info, lod);
                MaterialCache[material] = ret;
                Log.Info($"Cached new texture for {info.name} ticks=" + ticks.ElapsedTicks.ToString("E2"));
                return(ret);
            }
            catch (Exception e) {
                material.GetHashCode();
                Log.Info(e.ToString());
                MaterialCache[material] = material; // do not repeat the same mistake!
                return(material);
            }
        }
        public static void TrimNonHighwayProps(this NetInfo info, bool removeRightStreetLights = false, bool removeLeftStreetLights = true)
        {
            var randomProp    = Prefabs.Find <PropInfo>("Random Street Prop", false);
            var streetLight   = Prefabs.Find <PropInfo>("New Street Light", false);
            var streetLightHw = Prefabs.Find <PropInfo>("New Street Light Highway", false);
            var manhole       = Prefabs.Find <PropInfo>("Manhole", false);

            foreach (var laneProps in info.m_lanes.Select(l => l.m_laneProps).Where(lpi => lpi != null))
            {
                var remainingProp = new List <NetLaneProps.Prop>();

                foreach (var prop in laneProps.m_props.Where(p => p.m_prop != null))
                {
                    var newProp = prop.ShallowClone();
                    if (prop.m_prop == randomProp)
                    {
                        continue;
                    }

                    if (prop.m_prop == manhole)
                    {
                        continue;
                    }

                    if (removeLeftStreetLights)
                    {
                        if (prop.m_prop == streetLight &&
                            laneProps.name.Contains("Left"))
                        {
                            prop.m_probability = 0;
                            //continue;
                        }

                        if (prop.m_prop == streetLightHw &&
                            laneProps.name.Contains("Left"))
                        {
                            prop.m_probability = 0;
                            //continue;
                        }
                    }

                    if (removeRightStreetLights)
                    {
                        if (prop.m_prop == streetLight &&
                            laneProps.name.Contains("Right"))
                        {
                            prop.m_probability = 0;
                            //continue;
                        }

                        if (prop.m_prop == streetLightHw &&
                            laneProps.name.Contains("Right"))
                        {
                            prop.m_probability = 0;
                            //continue;
                        }
                    }

                    remainingProp.Add(prop);
                }

                laneProps.m_props = remainingProp.ToArray();
            }
        }
Exemple #35
0
        protected override void EndRenderingImpl(RenderManager.CameraInfo cameraInfo)
        {
            FastList <RenderGroup> renderedGroups = Singleton <RenderManager> .instance.m_renderedGroups;

            this.m_nameInstanceBuffer.Clear();
            this.m_visibleRoadNameSegment  = 0;
            this.m_visibleTrafficLightNode = 0;
            for (int groupIndex = 0; groupIndex < renderedGroups.m_size; groupIndex++)
            {
                RenderGroup renderGroup = renderedGroups.m_buffer[groupIndex];
                if (renderGroup.m_instanceMask != 0)
                {
                    const int resolutionRatio = NODEGRID_RESOLUTION / RenderManager.GROUP_RESOLUTION; // = 270/45 = 6
                    int       net_x0          = renderGroup.m_x * resolutionRatio;
                    int       net_z0          = renderGroup.m_z * resolutionRatio;
                    int       net_x1          = (renderGroup.m_x + 1) * resolutionRatio - 1; // = net_x + 5
                    int       net_z1          = (renderGroup.m_z + 1) * resolutionRatio - 1; // = net_z + 5
                    for (int net_z = net_z0; net_z <= net_z1; net_z++)
                    {
                        for (int net_x = net_x0; net_x <= net_x1; net_x++)
                        {
                            int    gridIndex = net_z * NODEGRID_RESOLUTION + net_x;
                            ushort nodeID    = this.m_nodeGrid[gridIndex];
                            int    watchdog  = 0;
                            while (nodeID != 0)
                            {
                                nodeID.ToNode().RenderInstance(cameraInfo, nodeID, renderGroup.m_instanceMask);
                                nodeID = nodeID.ToNode().m_nextGridNode;
                                if (++watchdog >= 32768)
                                {
                                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                                    break;
                                }
                            }
                        }
                    }
                    for (int net_z = net_z0; net_z <= net_z1; net_z++)
                    {
                        for (int net_x = net_x0; net_x <= net_x1; net_x++)
                        {
                            int    gridIndex = net_z * 270 + net_x;
                            ushort segmentID = this.m_segmentGrid[gridIndex];
                            int    watchdog  = 0;
                            while (segmentID != 0)
                            {
                                this.m_segments.m_buffer[(int)segmentID].RenderInstance(cameraInfo, segmentID, renderGroup.m_instanceMask);
                                segmentID = this.m_segments.m_buffer[(int)segmentID].m_nextGridSegment;
                                if (++watchdog >= 36864)
                                {
                                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                                    break;
                                }
                            }
                        }
                    }
                }
            }
            this.m_lastVisibleRoadNameSegment  = this.m_visibleRoadNameSegment;
            this.m_lastVisibleTrafficLightNode = this.m_visibleTrafficLightNode;
            int num11 = PrefabCollection <NetInfo> .PrefabCount();

            for (int n = 0; n < num11; n++)
            {
                NetInfo prefab = PrefabCollection <NetInfo> .GetPrefab((uint)n);

                if (prefab != null)
                {
                    if (prefab.m_segments != null)
                    {
                        for (int num12 = 0; num12 < prefab.m_segments.Length; num12++)
                        {
                            NetInfo.Segment  segment     = prefab.m_segments[num12];
                            NetInfo.LodValue combinedLod = segment.m_combinedLod;
                            if (combinedLod != null && combinedLod.m_lodCount != 0)
                            {
                                NetSegment.RenderLod(cameraInfo, combinedLod);
                            }
                        }
                    }
                    if (prefab.m_nodes != null)
                    {
                        for (int num13 = 0; num13 < prefab.m_nodes.Length; num13++)
                        {
                            NetInfo.Node     node         = prefab.m_nodes[num13];
                            NetInfo.LodValue combinedLod2 = node.m_combinedLod;
                            if (combinedLod2 != null && combinedLod2.m_lodCount != 0)
                            {
                                if (node.m_directConnect)
                                {
                                    NetSegment.RenderLod(cameraInfo, combinedLod2);
                                }
                                else
                                {
                                    NetNode.RenderLod(cameraInfo, combinedLod2);
                                }
                            }
                        }
                    }
                }
            }
        }
Exemple #36
0
        protected override void OnToolUpdate()
        {
            base.OnToolUpdate();
            Ray          ray   = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastInput input = new RaycastInput(ray, Camera.main.farClipPlane);

            input.m_ignoreSegmentFlags       = NetSegment.Flags.None;
            input.m_ignoreNodeFlags          = NetNode.Flags.All;
            input.m_ignoreParkFlags          = DistrictPark.Flags.All;
            input.m_ignorePropFlags          = PropInstance.Flags.All;
            input.m_ignoreTreeFlags          = TreeInstance.Flags.All;
            input.m_ignoreCitizenFlags       = CitizenInstance.Flags.All;
            input.m_ignoreVehicleFlags       = Vehicle.Flags.Created;
            input.m_ignoreBuildingFlags      = Building.Flags.All;
            input.m_ignoreDisasterFlags      = DisasterData.Flags.All;
            input.m_ignoreTransportFlags     = TransportLine.Flags.All;
            input.m_ignoreParkedVehicleFlags = VehicleParked.Flags.All;
            input.m_ignoreTerrain            = true;
            RayCast(input, out RaycastOutput output);
            m_hover = output.m_netSegment;

            if (Input.GetKeyDown(KeyCode.Escape))
            {
                enabled = false;
                ToolsModifierControl.SetTool <DefaultTool>();
            }

            if (m_hover != 0)
            {
                m_netInfo = GetSegment(m_hover).Info;
                if (Input.GetMouseButtonUp(0))
                {
                    instance.enabled = false;
                    if (Singleton <UnlockManager> .instance.Unlocked(m_netInfo.m_UnlockMilestone))
                    {
                        // you know when you make a bugfix just to mess with people? well this is that bugfix. enjoy.
                        UIView.Find("E2A").Unfocus();

                        UIView.Find("TSCloseButton").SimulateClick();

                        enabled = false;

                        m_netTool = ToolsModifierControl.SetTool <NetTool>();

                        m_netInfo = FindDefaultElevation(m_netInfo);

                        // If we don't load UI, stuff happens, whatever.
                        List <UIComponent>        reveal = null;
                        ElektrixModsConfiguration config = Configuration <ElektrixModsConfiguration> .Load();

                        if (config.NP_OpenUI)
                        {
                            reveal = FindRoadInPanel(m_netInfo.name);
                        }

                        m_netTool.Prefab = m_netInfo;
                        if (reveal != null)
                        {
                            UIView.Find("TSCloseButton").SimulateClick();
                            Db.l("[Net Picker] Attempting to open panel " + reveal[1].parent.parent.parent.parent.name.Replace("Panel", ""));
                            UIButton rb = UIView.Find("MainToolstrip").Find <UIButton>(reveal[1].parent.parent.parent.parent.name.Replace("Panel", ""));
                            rb.SimulateClick();
                            reveal[0].SimulateClick();
                            reveal[1].SimulateClick();
                            if (!UIView.Find("TSCloseButton").isVisible)
                            {
                                Db.l("Failed");
                            }
                        }
                        else if (config.NP_OpenUI)
                        {
                            ThrowError("This net type is hidden and won't work properly if used by non-advanced users. In order to use this net, disable 'open ui' in Net Picker settings. If this net *isn't* actually hidden, please tweet your net type (and what menu it can be found in) to @cosigncosine. Thanks!");
                            ToolsModifierControl.SetTool <DefaultTool>();
                            UIView.Find("ElectricityPanel").Hide();
                        }
                        m_fakeNetTool = true;

                        //Debug.LogError(NetworkSkins.modPath);
                        ushort  segmentId = m_hover;
                        NetInfo prefab    = m_netInfo;

                        try
                        {
                            Type     segmentDataManagerType  = Type.GetType("NetworkSkins.Data.SegmentDataManager, NetworkSkins");
                            object   segmentDataManager      = segmentDataManagerType.GetField("Instance").GetValue(null);
                            object[] SegmentToSegmentDataMap = (object[])segmentDataManagerType.GetField("SegmentToSegmentDataMap").GetValue(segmentDataManager);

                            var segmentData = SegmentToSegmentDataMap[segmentId];
                            segmentDataManagerType.GetMethod("SetActiveOptions").Invoke(segmentDataManager, new object[] { prefab, segmentData });
                        }
                        catch (Exception e) { Debug.Log("Network skins isn't installed."); }

                        if (config.CloseWindow)
                        {
                            UIView.Find("ElektrixModsPanel").Hide();
                        }
                    }
                    else
                    {
                        ThrowError("This net type isn't unlocked yet! Wait until this unlock/milestone: " + m_netInfo.m_UnlockMilestone.m_name);
                    }
                }
            }
            else
            {
                m_netInfo = default(NetInfo);
            }
        }
Exemple #37
0
        public static NetInfo Setup16m3mSW3mBikelaneMesh(this NetInfo info, NetInfoVersion version, LanesLayoutStyle lanesLayoutStyle = LanesLayoutStyle.Symmetrical)
        {
            var highwayInfo      = Prefabs.Find <NetInfo>(NetInfos.Vanilla.HIGHWAY_3L);
            var highwaySlopeInfo = Prefabs.Find <NetInfo>(NetInfos.Vanilla.HIGHWAY_3L_SLOPE);
            var defaultMaterial  = highwayInfo.m_nodes[0].m_material;

            switch (version)
            {
            case NetInfoVersion.Ground:
            case NetInfoVersion.GroundGrass:
            case NetInfoVersion.GroundTrees:
            {
                var segment0 = info.m_segments[0].ShallowClone();
                var segment1 = info.m_segments[1].ShallowClone();
                var segment2 = info.m_segments[2].ShallowClone();
                var segment3 = info.m_segments[1].ShallowClone();

                var node0 = info.m_nodes[0].ShallowClone();

                segment0
                .SetMeshes
                    (@"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Ground.obj",
                    @"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Ground_LOD.obj");
                segment1
                .SetMeshes
                    (@"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Ground.obj",
                    @"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Ground_LOD.obj");
                segment2
                .SetMeshes
                    (@"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Ground.obj",
                    @"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Ground_LOD.obj");
                segment3
                .SetMeshes
                    (@"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Ground.obj",
                    @"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Ground_LOD.obj");
                node0
                .SetMeshes
                    (@"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Ground_Node.obj",
                    @"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Ground_Node_LOD.obj");

                RoadHelper.HandleAsymSegmentFlags(segment0);
                RoadHelper.HandleAsymSegmentFlags(segment2);

                info.m_segments = new[] { segment0, segment1, segment2, segment3 };
                info.m_nodes    = new[] { node0 };

                break;
            }

            case NetInfoVersion.Elevated:
            case NetInfoVersion.Bridge:
            {
                var segment0 = info.m_segments[0].ShallowClone();
                var node0    = info.m_nodes[0].ShallowClone();

                segment0
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Elevated.obj",
                    @"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Elevated_LOD.obj");

                node0.
                SetMeshes
                    (@"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Elevated_Node.obj",
                    @"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Elevated_Node_LOD.obj");

                RoadHelper.HandleAsymSegmentFlags(segment0);
                info.m_segments = new[] { segment0 };
                info.m_nodes    = new[] { node0 };
                break;
            }

            case NetInfoVersion.Slope:
            {
                var segment0 = info.m_segments[0].ShallowClone();
                var segment1 = highwaySlopeInfo.m_segments[1].ShallowClone();
                var segment2 = info.m_segments[1].ShallowClone();

                var node0 = info.m_nodes[0].ShallowClone();
                var node1 = info.m_nodes[1].ShallowClone();
                var node2 = node0.ShallowClone();
                //segment0
                //    .SetFlagsDefault()
                //    **ToDo

                segment2
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Slope.obj",
                    @"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Slope_LOD.obj");

                node1
                .SetMeshes
                    (@"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Slope_Node.obj",
                    @"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Slope_Node_LOD.obj");

                node2
                .SetFlags(NetNode.Flags.Underground, NetNode.Flags.None)
                .SetMeshes
                    (@"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Slope_U_Node.obj",
                    @"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Slope_U_Node_LOD.obj");

                RoadHelper.HandleAsymSegmentFlags(segment2);
                node2.m_material = defaultMaterial;

                info.m_segments = new[] { segment0, segment1, segment2 };
                info.m_nodes    = new[] { node0, node1, node2 };

                break;
            }

            case NetInfoVersion.Tunnel:
            {
                var segment0 = info.m_segments[0].ShallowClone();
                var segment1 = segment0.ShallowClone();

                var node0 = info.m_nodes[0].ShallowClone();
                var node1 = node0.ShallowClone();

                segment1
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Tunnel.obj",
                    @"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Tunnel_LOD.obj");

                node1
                .SetFlags(NetNode.Flags.None, NetNode.Flags.None)
                .SetMeshes
                    (@"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Tunnel_Node.obj",
                    @"Roads\Common\Meshes\16m\3mSW3mBikeLanes\Tunnel_Node_LOD.obj");

                RoadHelper.HandleAsymSegmentFlags(segment1);
                segment1.m_material = defaultMaterial;
                node1.m_material    = defaultMaterial;

                info.m_segments = new[] { segment0, segment1 };
                info.m_nodes    = new[] { node0, node1 };

                break;
            }
            }
            return(info);
        }
        public static NetInfo Setup32m3mSW2mMdnMesh(this NetInfo info, NetInfoVersion version)
        {
            var highwayInfo     = Prefabs.Find <NetInfo>(NetInfos.Vanilla.ROAD_6L);
            var slopeInfo       = Prefabs.Find <NetInfo>(NetInfos.Vanilla.ROAD_4L_SLOPE);
            var defaultMaterial = highwayInfo.m_nodes[0].m_material;

            switch (version)
            {
            case NetInfoVersion.Ground:
            {
                var segments0 = info.m_segments[0];
                var nodes0    = info.m_nodes[0];

                segments0
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Common\Meshes\32m\3mSW2mMdn\Ground.obj");

                nodes0.SetMeshes
                    (@"Roads\Common\Meshes\32m\3mSW2mMdn\Ground_Node.obj");

                info.m_segments = new[] { segments0 };
                info.m_nodes    = new[] { nodes0 };
                break;
            }

            case NetInfoVersion.Elevated:
            {
                var segments0 = info.m_segments[0];
                var nodes0    = info.m_nodes[0];

                segments0
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Common\Meshes\32m\3mSW2mMdn\Elevated.obj",
                    @"Roads\Common\Meshes\32m\3mSW2mMdn\Elevated_LOD.obj");

                nodes0
                .SetMeshes
                    (@"Roads\Common\Meshes\32m\3mSW2mMdn\Elevated_Node.obj",
                    @"Roads\Common\Meshes\32m\3mSW2mMdn\Elevated_Node_LOD.obj");

                info.m_segments = new[] { segments0 };
                info.m_nodes    = new[] { nodes0 };
                break;
            }

            case NetInfoVersion.Bridge:
            {
                var segments0 = info.m_segments[0];
                var segments1 = info.m_segments[1];
                var nodes0    = info.m_nodes[0];

                segments0
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Common\Meshes\32m\3mSW2mMdn\Elevated.obj",
                    @"Roads\Common\Meshes\32m\3mSW2mMdn\Elevated_LOD.obj");

                segments1
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Common\Meshes\32m\3mSW2mMdn\Bridge_Cables.obj",
                    @"Roads\Common\Meshes\32m\3mSW2mMdn\Bridge_Cables_LOD.obj");

                nodes0
                .SetMeshes
                    (@"Roads\Common\Meshes\32m\3mSW2mMdn\Elevated_Node.obj",
                    @"Roads\Common\Meshes\32m\3mSW2mMdn\Elevated_Node_LOD.obj");

                info.m_segments = new[] { segments0, segments1 };
                info.m_nodes    = new[] { nodes0 };
                break;
            }

            case NetInfoVersion.Slope:
            {
                var segment0 = info.m_segments[0];
                var segment1 = slopeInfo.m_segments[1].ShallowClone();
                var segment2 = info.m_segments[1];

                var node0 = info.m_nodes[0];
                var node1 = info.m_nodes[1];
                var node2 = node0.ShallowClone();
                //segment0
                //    .SetFlagsDefault()
                //    **ToDo

                segment2
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Common\Meshes\32m\3mSW2mMdn\Slope.obj",
                    @"Roads\Common\Meshes\32m\3mSW2mMdn\Slope_LOD.obj");

                node1
                .SetMeshes
                    (@"Roads\Common\Meshes\32m\3mSW2mMdn\Slope_Node.obj",
                    @"Roads\Common\Meshes\32m\3mSW2mMdn\Slope_Node_LOD.obj");

                node2
                .SetMeshes
                    (@"Roads\Common\Meshes\32m\3mSW2mMdn\Slope_U_Node.obj",
                    @"Roads\Common\Meshes\32m\3mSW2mMdn\Slope_U_Node_LOD.obj");

                node2.m_material = defaultMaterial;

                info.m_segments = new[] { segment0, segment1, segment2 };
                info.m_nodes    = new[] { node0, node1, node2 };

                break;
            }

            case NetInfoVersion.Tunnel:
            {
                var segment0 = info.m_segments[0];
                var segment1 = segment0.ShallowClone();

                var node0 = info.m_nodes[0];
                var node1 = node0.ShallowClone();

                segment1
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Common\Meshes\32m\3mSW2mMdn\Tunnel.obj",
                    @"Roads\Common\Meshes\32m\3mSW2mMdn\Tunnel_LOD.obj");

                node1
                .SetFlags(NetNode.Flags.None, NetNode.Flags.None)
                .SetMeshes
                    (@"Roads\Common\Meshes\32m\3mSW2mMdn\Tunnel_Node.obj",
                    @"Roads\Common\Meshes\32m\3mSW2mMdn\Tunnel_Node_LOD.obj");

                segment1.m_material = defaultMaterial;
                node1.m_material    = defaultMaterial;

                info.m_segments = new[] { segment0, segment1 };
                info.m_nodes    = new[] { node0, node1 };

                break;
            }
            }
            return(info);
        }
Exemple #39
0
        /// <summary>
        /// Determines the average custom speed limit for a given NetInfo object in terms of discrete speed limit levels.
        /// An in-game speed limit of 2.0 (e.g. on highway) is hereby translated into a discrete speed limit value of 100 (km/h).
        /// </summary>
        /// <param name="segmentInfo"></param>
        /// <param name="finalDir"></param>
        /// <returns></returns>
        public ushort GetAverageCustomSpeedLimit(ushort segmentId, ref NetSegment segment, NetInfo segmentInfo, NetInfo.Direction?finalDir = null)
        {
            // calculate the currently set mean speed limit
            float meanSpeedLimit = 0f;
            uint  validLanes     = 0;
            uint  curLaneId      = segment.m_lanes;

            for (byte laneIndex = 0; laneIndex < segmentInfo.m_lanes.Length; ++laneIndex)
            {
                NetInfo.Lane      laneInfo = segmentInfo.m_lanes[laneIndex];
                NetInfo.Direction d        = laneInfo.m_finalDirection;
                if (finalDir != null && d != finalDir)
                {
                    continue;
                }
                if (!MayHaveCustomSpeedLimits(laneInfo))
                {
                    continue;
                }

                meanSpeedLimit += GetLockFreeGameSpeedLimit(segmentId, laneIndex, curLaneId, laneInfo);
                curLaneId       = Singleton <NetManager> .instance.m_lanes.m_buffer[curLaneId].m_nextLane;
                ++validLanes;
            }

            if (validLanes > 0)
            {
                meanSpeedLimit /= (float)validLanes;
            }
            return((ushort)Mathf.Round(meanSpeedLimit));
        }
        public static bool segmentIsIncomingOneWay(int segmentid, ushort nodeID)
        {
            NetManager instance = Singleton <NetManager> .instance;

            var segment = instance.m_segments.m_buffer[segmentid];
            var info    = segment.Info;

            uint num2 = segment.m_lanes;
            int  num3 = 0;

            NetInfo.Direction dir = NetInfo.Direction.Forward;
            if (segment.m_startNode == nodeID)
            {
                dir = NetInfo.Direction.Backward;
            }
            var dir2 = ((segment.m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None) ? dir : NetInfo.InvertDirection(dir);
            var dir3 = TrafficPriority.leftHandDrive ? NetInfo.InvertDirection(dir2) : dir2;

            var isOneWay = true;

            while (num3 < info.m_lanes.Length && num2 != 0u)
            {
                if (info.m_lanes[num3].m_laneType != NetInfo.LaneType.Pedestrian &&
                    (info.m_lanes[num3].m_direction == dir3))
                {
                    isOneWay = false;
                }

                num2 = instance.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_nextLane;
                num3++;
            }

            return(isOneWay);
        }
        public override void RenderOverlay(RenderManager.CameraInfo cameraInfo, Color toolColor, Color despawnColor)
        {
            if (!isValid)
            {
                return;
            }

            ushort  segment = id.NetSegment;
            NetInfo netInfo = segmentBuffer[segment].Info;

            ushort startNode = segmentBuffer[segment].m_startNode;
            ushort endNode   = segmentBuffer[segment].m_endNode;

            bool smoothStart = ((nodeBuffer[startNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None);
            bool smoothEnd   = ((nodeBuffer[endNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None);

            Bezier3 bezier;

            bezier.a = nodeBuffer[startNode].m_position;
            bezier.d = nodeBuffer[endNode].m_position;
            // NON-STOCK CODE STARTS
            if (MoveItTool.IsCSUROffset(netInfo))
            {
                var tmpDir = segmentBuffer[segment].m_startDirection;
                if ((segmentBuffer[segment].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None)
                {
                    tmpDir = -tmpDir;
                }
                tmpDir   = new Vector3(tmpDir.z, tmpDir.y, -tmpDir.x);
                bezier.a = tmpDir * (netInfo.m_halfWidth + netInfo.m_pavementWidth) / 2f + bezier.a;

                tmpDir = segmentBuffer[segment].m_endDirection;
                if ((segmentBuffer[segment].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None)
                {
                    tmpDir = -tmpDir;
                }
                tmpDir   = new Vector3(-tmpDir.z, tmpDir.y, tmpDir.x);
                bezier.d = tmpDir * (netInfo.m_halfWidth + netInfo.m_pavementWidth) / 2f + bezier.d;
            }
            // NON-STOCK CODE ENDS

            NetSegment.CalculateMiddlePoints(
                bezier.a, segmentBuffer[segment].m_startDirection,
                bezier.d, segmentBuffer[segment].m_endDirection,
                smoothStart, smoothEnd, out bezier.b, out bezier.c);

            // NON-STOCK CODE STARTS
            if (MoveItTool.IsCSUROffset(netInfo))
            {
                RenderManager.instance.OverlayEffect.DrawBezier(cameraInfo, toolColor, bezier, (netInfo.m_halfWidth - netInfo.m_pavementWidth) * 4f / 3f, 100000f, -100000f, -1f, 1280f, false, true);
            }
            else
            {
                RenderManager.instance.OverlayEffect.DrawBezier(cameraInfo, toolColor, bezier, netInfo.m_halfWidth * 4f / 3f, 100000f, -100000f, -1f, 1280f, false, true);
            }
            // NON-STOCK CODE ENDS

            Segment3 segment1, segment2;

            segment1.a = nodeBuffer[startNode].m_position;
            segment2.a = nodeBuffer[endNode].m_position;

            segment1.b = GetControlPoint(segment);
            segment2.b = segment1.b;

            // NON-STOCK CODE STARTS
            if (MoveItTool.IsCSUROffset(netInfo))
            {
                var tmpDir = segmentBuffer[segment].m_startDirection;
                if ((segmentBuffer[segment].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None)
                {
                    tmpDir = -tmpDir;
                }
                tmpDir     = new Vector3(tmpDir.z, tmpDir.y, -tmpDir.x);
                segment1.a = tmpDir * (netInfo.m_halfWidth + netInfo.m_pavementWidth) / 2f + segment1.a;

                tmpDir = segmentBuffer[segment].m_endDirection;
                if ((segmentBuffer[segment].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None)
                {
                    tmpDir = -tmpDir;
                }
                tmpDir     = new Vector3(-tmpDir.z, tmpDir.y, tmpDir.x);
                segment2.a = tmpDir * (netInfo.m_halfWidth + netInfo.m_pavementWidth) / 2f + segment2.a;

                tmpDir = (segmentBuffer[segment].m_startDirection - segmentBuffer[segment].m_endDirection) / 2;
                if ((segmentBuffer[segment].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None)
                {
                    tmpDir = -tmpDir;
                }
                tmpDir     = new Vector3(tmpDir.z, tmpDir.y, -tmpDir.x);
                segment1.b = tmpDir * (netInfo.m_halfWidth + netInfo.m_pavementWidth) / 2f + segment1.b;
                segment2.b = segment1.b;
            }
            // NON-STOCK CODE ENDS
            toolColor.a = toolColor.a / 2;

            RenderManager.instance.OverlayEffect.DrawSegment(cameraInfo, toolColor, segment1, segment2, 0, 10f, -1f, 1280f, false, true);
            // NON-STOCK CODE STARTS
            if (MoveItTool.IsCSUROffset(netInfo))
            {
                RenderManager.instance.OverlayEffect.DrawCircle(cameraInfo, toolColor, segment1.b, (netInfo.m_halfWidth - netInfo.m_pavementWidth) / 2f, -1f, 1280f, false, true);
            }
            else
            {
                RenderManager.instance.OverlayEffect.DrawCircle(cameraInfo, toolColor, segment1.b, netInfo.m_halfWidth / 2f, -1f, 1280f, false, true);
            }
            // NON-STOCK CODE ENDS
        }
Exemple #42
0
        public void OnBeforeSimulationStep(ushort segmentId, ref NetSegment segment)
        {
            GlobalConfig conf = GlobalConfig.Instance;

            // calculate traffic density
            NetInfo segmentInfo = segment.Info;
            int     numLanes    = segmentInfo.m_lanes.Length;

            if (LaneTrafficData[segmentId] == null || LaneTrafficData[segmentId].Length < numLanes)
            {
                LaneTrafficData[segmentId] = new LaneTrafficData[numLanes];
                for (int i = 0; i < numLanes; ++i)
                {
                    // laneTrafficData[segmentId][i] = new LaneTrafficData();
                    LaneTrafficData[segmentId][i].meanSpeed = REF_REL_SPEED;
                }
            }

            // calculate max./min. lane speed
            for (var i = 0; i < 2; ++i)
            {
                meanSpeeds[i]     = 0;
                meanSpeedLanes[i] = 0;
            }

            uint curLaneId = segment.m_lanes;

            byte laneIndex = 0;

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

                if ((laneInfo.m_laneType & LANE_TYPES) != NetInfo.LaneType.None &&
                    (laneInfo.m_vehicleType & VEHICLE_TYPES) != VehicleInfo.VehicleType.None)
                {
                    int dirIndex = GetDirIndex(laneInfo.m_finalDirection);

                    // calculate reported mean speed
                    ushort newRelSpeed = CalcLaneRelativeMeanSpeed(
                        segmentId,
                        laneIndex,
                        curLaneId,
                        segment.Info.m_lanes[laneIndex]);

                    meanSpeeds[dirIndex] += newRelSpeed;
                    ++meanSpeedLanes[dirIndex];

                    LaneTrafficData[segmentId][laneIndex].meanSpeed = newRelSpeed;

                    ushort trafficBuffer = LaneTrafficData[segmentId][laneIndex].trafficBuffer;

                    // remember historic data
                    LaneTrafficData[segmentId][laneIndex].lastTrafficBuffer = trafficBuffer;

                    if (trafficBuffer > LaneTrafficData[segmentId][laneIndex].maxTrafficBuffer)
                    {
                        LaneTrafficData[segmentId][laneIndex].maxTrafficBuffer = trafficBuffer;
                    }

                    // reset buffers
                    if (conf.AdvancedVehicleAI.MaxTrafficBuffer > 0)
                    {
                        if (LaneTrafficData[segmentId][laneIndex].trafficBuffer >
                            conf.AdvancedVehicleAI.MaxTrafficBuffer)
                        {
                            LaneTrafficData[segmentId][laneIndex].accumulatedSpeeds /=
                                LaneTrafficData[segmentId][laneIndex].trafficBuffer
                                / conf.AdvancedVehicleAI.MaxTrafficBuffer;
                            LaneTrafficData[segmentId][laneIndex].trafficBuffer =
                                (ushort)conf.AdvancedVehicleAI.MaxTrafficBuffer;
                        }
                        else if (LaneTrafficData[segmentId][laneIndex].trafficBuffer ==
                                 conf.AdvancedVehicleAI.MaxTrafficBuffer)
                        {
                            LaneTrafficData[segmentId][laneIndex].accumulatedSpeeds = 0;
                            LaneTrafficData[segmentId][laneIndex].trafficBuffer     = 0;
                        }
                    }
                    else
                    {
                        LaneTrafficData[segmentId][laneIndex].accumulatedSpeeds = 0;
                        LaneTrafficData[segmentId][laneIndex].trafficBuffer     = 0;
                    }
                }

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

            for (int i = 0; i < 2; ++i)
            {
                int segDirIndex = i == 0
                                      ? GetDirIndex(segmentId, NetInfo.Direction.Forward)
                                      : GetDirIndex(segmentId, NetInfo.Direction.Backward);

                if (meanSpeedLanes[i] > 0)
                {
                    SegmentDirTrafficData[segDirIndex].meanSpeed = (ushort)Math.Min(
                        REF_REL_SPEED,
                        meanSpeeds[i] / meanSpeedLanes[i]);
                }
                else
                {
                    SegmentDirTrafficData[segDirIndex].meanSpeed = REF_REL_SPEED;
                }
            }
        }
        private static void SetupTextures(NetInfo info, NetInfoVersion version)
        {
            switch (version)
            {
            case NetInfoVersion.Ground:
                info.SetAllSegmentsTexture(
                    new TextureSet
                        (@"Roads\PedestrianRoads\Promenade\Textures\Ground_Segment__MainTex.png",
                        @"Roads\PedestrianRoads\Promenade\Textures\Ground_Segment__AlphaMap.png",
                        @"Roads\PedestrianRoads\Promenade\Textures\Ground_Segment__XYSMap.png"),
                    new LODTextureSet
                        (@"Roads\PedestrianRoads\Promenade\Textures\Ground_Segment_LOD__MainTex.png",
                        @"Roads\PedestrianRoads\Promenade\Textures\Ground_Segment_LOD__AlphaMap.png",
                        @"Roads\PedestrianRoads\Promenade\Textures\Ground_Segment_LOD__XYSMap.png"));

                for (int i = 0; i < info.m_nodes.Length; i++)
                {
                    if (info.m_nodes[i].m_flagsRequired == NetNode.Flags.Transition)
                    {
                        info.m_nodes[i].SetTextures(
                            new TextureSet
                                (@"Roads\PedestrianRoads\Promenade\Textures\Ground_Trans__MainTex.png",
                                @"Roads\PedestrianRoads\Promenade\Textures\Ground_Trans__AlphaMap.png",
                                @"Roads\PedestrianRoads\Promenade\Textures\Ground_Node__XYSMap.png"),
                            new LODTextureSet
                                (@"Roads\PedestrianRoads\Common\Textures\Ground_Trans_LOD__MainTex.png",
                                @"Roads\PedestrianRoads\Common\Textures\Ground_Trans_LOD__AlphaMap.png",
                                @"Roads\PedestrianRoads\Common\Textures\Ground_Node_LOD__XYSMap.png"));
                    }
                    else
                    {
                        info.m_nodes[i].SetTextures(
                            new TextureSet
                                (@"Roads\PedestrianRoads\Promenade\Textures\Ground_Node__MainTex.png",
                                @"Roads\PedestrianRoads\Promenade\Textures\Ground_Node__AlphaMap.png",
                                @"Roads\PedestrianRoads\Promenade\Textures\Ground_Node__XYSMap.png"),
                            new LODTextureSet
                                (@"Roads\PedestrianRoads\Promenade\Textures\Ground_Node_LOD__MainTex.png",
                                @"Roads\PedestrianRoads\Promenade\Textures\Ground_Node_LOD__AlphaMap.png",
                                @"Roads\PedestrianRoads\Common\Textures\Ground_Node_LOD__XYSMap.png"));
                    }
                }
                break;

            case NetInfoVersion.Elevated:
                info.SetAllSegmentsTexture(
                    new TextureSet
                        (@"Roads\PedestrianRoads\Promenade\Textures\Elevated_Segment__MainTex.png",
                        @"Roads\PedestrianRoads\Promenade\Textures\Elevated_Segment__AlphaMap.png",
                        @"Roads\PedestrianRoads\Promenade\Textures\Elevated_Segment__XYSMap.png"),
                    new LODTextureSet
                        (@"Roads\PedestrianRoads\Promenade\Textures\Elevated_Segment_LOD__MainTex.png",
                        @"Roads\PedestrianRoads\Promenade\Textures\Elevated_Segment_LOD__AlphaMap.png",
                        @"Roads\PedestrianRoads\Promenade\Textures\Elevated_Segment_LOD__XYSMap.png"));

                for (int i = 0; i < info.m_nodes.Length; i++)
                {
                    if (info.m_nodes[i].m_flagsRequired == NetNode.Flags.Transition)
                    {
                        info.m_nodes[i].SetTextures(
                            new TextureSet
                                (@"Roads\PedestrianRoads\Promenade\Textures\Elevated_Trans__MainTex.png",
                                @"Roads\PedestrianRoads\Promenade\Textures\Elevated_Trans__AlphaMap.png"),
                            new LODTextureSet
                                (@"Roads\PedestrianRoads\Common\Textures\Elevated_Trans_LOD__MainTex.png",
                                @"Roads\PedestrianRoads\Common\Textures\Elevated_Trans_LOD__AlphaMap.png",
                                @"Roads\PedestrianRoads\Promenade\Textures\Elevated_Node_LOD__XYSMap.png"));
                    }
                    else
                    {
                        info.m_nodes[i].SetTextures(
                            new TextureSet
                                (@"Roads\PedestrianRoads\Promenade\Textures\Elevated_Node__MainTex.png",
                                @"Roads\PedestrianRoads\Promenade\Textures\Elevated_Node__AlphaMap.png",
                                @"Roads\PedestrianRoads\Promenade\Textures\Elevated_Segment__XYSMap.png"),
                            new LODTextureSet
                                (@"Roads\PedestrianRoads\Common\Textures\Elevated_Trans_LOD__MainTex.png",
                                @"Roads\PedestrianRoads\Promenade\Textures\Elevated_Node_LOD__AlphaMap.png",
                                @"Roads\PedestrianRoads\Promenade\Textures\Elevated_Node_LOD__XYSMap.png"));
                    }
                }
                break;
            }
        }
        public void BuildUp(NetInfo info, NetInfoVersion version)
        {
            ///////////////////////////
            // Template              //
            ///////////////////////////
            var roadInfo         = Prefabs.Find <NetInfo>(NetInfos.Vanilla.ROAD_2L);
            var owRoadTunnelInfo = Prefabs.Find <NetInfo>(NetInfos.Vanilla.ONEWAY_2L_TUNNEL);

            ///////////////////////////
            // 3DModeling            //
            ///////////////////////////
            info.Setup16m3mSWMesh(version, LanesLayoutStyle.AsymL1R2);

            ///////////////////////////
            // Texturing             //
            ///////////////////////////
            SetupTextures(info, version);

            ///////////////////////////
            // Set up                //
            ///////////////////////////
            info.m_hasParkingSpaces = false;
            info.m_class            = roadInfo.m_class.Clone(NetInfoClasses.NEXT_SMALL3L_ROAD);
            info.m_pavementWidth    = (version != NetInfoVersion.Slope && version != NetInfoVersion.Tunnel ? 3 : 6);
            info.m_halfWidth        = (version != NetInfoVersion.Slope && version != NetInfoVersion.Tunnel ? 8 : 11);

            if (version == NetInfoVersion.Tunnel)
            {
                info.m_setVehicleFlags = Vehicle.Flags.Transition | Vehicle.Flags.Underground;
                info.m_setCitizenFlags = CitizenInstance.Flags.Transition | CitizenInstance.Flags.Underground;
                info.m_class           = owRoadTunnelInfo.m_class.Clone(NetInfoClasses.NEXT_SMALL3L_ROAD_TUNNEL);
            }
            else
            {
                info.m_class = roadInfo.m_class.Clone(NetInfoClasses.NEXT_SMALL3L_ROAD);
            }

            // Setting up lanes
            info.SetRoadLanes(version, new LanesConfiguration
            {
                IsTwoWay    = true,
                LanesToAdd  = 1,
                LaneWidth   = 3.3f,
                SpeedLimit  = 1.0f,
                CenterLane  = CenterLaneType.None,
                LayoutStyle = LanesLayoutStyle.AsymL1R2
            });

            var leftPedLane  = info.GetLeftRoadShoulder();
            var rightPedLane = info.GetRightRoadShoulder();

            //Setting Up Props
            var leftRoadProps  = leftPedLane.m_laneProps.m_props.ToList();
            var rightRoadProps = rightPedLane.m_laneProps.m_props.ToList();

            if (version == NetInfoVersion.Slope)
            {
                leftRoadProps.AddLeftWallLights(info.m_pavementWidth);
                rightRoadProps.AddRightWallLights(info.m_pavementWidth);
            }

            leftPedLane.m_laneProps.m_props  = leftRoadProps.ToArray();
            rightPedLane.m_laneProps.m_props = rightRoadProps.ToArray();

            info.TrimAboveGroundProps(version);
            info.SetupNewSpeedLimitProps(50, 40);


            // AI
            var owPlayerNetAI = roadInfo.GetComponent <PlayerNetAI>();
            var playerNetAI   = info.GetComponent <PlayerNetAI>();

            if (owPlayerNetAI != null && playerNetAI != null)
            {
                playerNetAI.m_constructionCost = owPlayerNetAI.m_constructionCost * 3 / 2; // Charge by the lane?
                playerNetAI.m_maintenanceCost  = owPlayerNetAI.m_maintenanceCost * 3 / 2;  // Charge by the lane?
            }

            var roadBaseAI = info.GetComponent <RoadBaseAI>();

            if (roadBaseAI != null)
            {
                roadBaseAI.m_trafficLights = false;
            }
        }
Exemple #45
0
        public void BuildUp(NetInfo info, NetInfoVersion version)
        {
            ///////////////////////////
            // Texturing             //
            ///////////////////////////
            switch (version)
            {
            case NetInfoVersion.Ground:
            {
                foreach (var segment in info.m_segments)
                {
                    switch (segment.m_forwardRequired)
                    {
                    case NetSegment.Flags.StopLeft:
                    case NetSegment.Flags.StopRight:
                        segment.SetTextures(
                            new TextureSet
                                (@"Roads\BusRoads\Busway2L\Textures\Ground_Segment__MainTex.png",
                                @"Roads\BusRoads\Busway2L\Textures\Ground_Segment__AlphaMap.png"),
                            new LODTextureSet
                                (@"Roads\BusRoads\Busway2L\Textures\Ground_SegmentLOD_Bus__MainTex.png",
                                @"Roads\BusRoads\Busway2L\Textures\Ground_SegmentLOD_Bus__AlphaMap.png",
                                @"Roads\BusRoads\Busway2L\Textures\Ground_SegmentLOD__XYSMap.png"));
                        break;

                    case NetSegment.Flags.StopBoth:
                        segment.SetTextures(
                            new TextureSet
                                (@"Roads\BusRoads\Busway2L\Textures\Ground_Segment__MainTex.png",
                                @"Roads\BusRoads\Busway2L\Textures\Ground_Segment__AlphaMap.png"),
                            new LODTextureSet
                                (@"Roads\BusRoads\Busway2L\Textures\Ground_SegmentLOD_BusBoth__MainTex.png",
                                @"Roads\BusRoads\Busway2L\Textures\Ground_SegmentLOD_BusBoth__AlphaMap.png",
                                @"Roads\BusRoads\Busway2L\Textures\Ground_SegmentLOD__XYSMap.png"));
                        break;

                    default:
                        segment.SetTextures(
                            new TextureSet
                                (@"Roads\BusRoads\Busway2L\Textures\Ground_Segment__MainTex.png",
                                @"Roads\BusRoads\Busway2L\Textures\Ground_Segment__AlphaMap.png"),
                            new LODTextureSet
                                (@"Roads\BusRoads\Busway2L\Textures\Ground_SegmentLOD__MainTex.png",
                                @"Roads\BusRoads\Busway2L\Textures\Ground_SegmentLOD__AlphaMap.png",
                                @"Roads\BusRoads\Busway2L\Textures\Ground_SegmentLOD__XYSMap.png"));
                        break;
                    }
                }
            }
            break;

            case NetInfoVersion.GroundGrass:
            case NetInfoVersion.GroundTrees:
            {
                foreach (var segment in info.m_segments)
                {
                    switch (segment.m_forwardRequired)
                    {
                    case NetSegment.Flags.StopLeft:
                    case NetSegment.Flags.StopRight:
                        segment.SetTextures(
                            new TextureSet
                                (@"Roads\BusRoads\Busway2L\Textures_Grass\Ground_Segment__MainTex.png",
                                @"Roads\BusRoads\Busway2L\Textures_Grass\Ground_Segment_Bus__AlphaMap.png"),
                            new LODTextureSet
                                (@"Roads\BusRoads\Busway2L\Textures_Grass\Ground_SegmentLOD_Bus__MainTex.png",
                                @"Roads\BusRoads\Busway2L\Textures_Grass\Ground_SegmentLOD_Bus__AlphaMap.png",
                                @"Roads\BusRoads\Busway2L\Textures_Grass\Ground_SegmentLOD__XYSMap.png"));
                        break;

                    case NetSegment.Flags.StopBoth:
                        segment.SetTextures(
                            new TextureSet
                                (@"Roads\BusRoads\Busway2L\Textures_Grass\Ground_Segment__MainTex.png",
                                @"Roads\BusRoads\Busway2L\Textures_Grass\Ground_Segment_BusBoth__AlphaMap.png"),
                            new LODTextureSet
                                (@"Roads\BusRoads\Busway2L\Textures_Grass\Ground_SegmentLOD_BusBoth__MainTex.png",
                                @"Roads\BusRoads\Busway2L\Textures_Grass\Ground_SegmentLOD_BusBoth__AlphaMap.png",
                                @"Roads\BusRoads\Busway2L\Textures_Grass\Ground_SegmentLOD__XYSMap.png"));
                        break;

                    default:
                        segment.SetTextures(
                            new TextureSet
                                (@"Roads\BusRoads\Busway2L\Textures_Grass\Ground_Segment__MainTex.png",
                                @"Roads\BusRoads\Busway2L\Textures_Grass\Ground_Segment__AlphaMap.png"),
                            new LODTextureSet
                                (@"Roads\BusRoads\Busway2L\Textures_Grass\Ground_SegmentLOD__MainTex.png",
                                @"Roads\BusRoads\Busway2L\Textures_Grass\Ground_SegmentLOD__AlphaMap.png",
                                @"Roads\BusRoads\Busway2L\Textures_Grass\Ground_SegmentLOD__XYSMap.png"));
                        break;
                    }
                }
            }
            break;

            case NetInfoVersion.Bridge:
            case NetInfoVersion.Elevated:
            {
                foreach (var segment in info.m_segments)
                {
                    segment.SetTextures(
                        new TextureSet
                            (@"Roads\BusRoads\Busway2L\Textures\Elevated_Segment__MainTex.png",
                            @"Roads\BusRoads\Busway2L\Textures\Elevated_Segment__AlphaMap.png"),
                        new LODTextureSet
                            (@"Roads\BusRoads\Busway2L\Textures\Elevated_SegmentLOD__MainTex.png",
                            @"Roads\BusRoads\Busway2L\Textures\Elevated_SegmentLOD__AlphaMap.png",
                            @"Roads\BusRoads\Busway2L\Textures\Elevated_SegmentLOD__XYSMap.png"));
                }
            }
            break;

            case NetInfoVersion.Slope:
            {
                foreach (var segment in info.m_segments)
                {
                    segment.SetTextures(
                        new TextureSet
                            (@"Roads\BusRoads\Busway2L\Textures\Slope_Segment__MainTex.png",
                            @"Roads\BusRoads\Busway2L\Textures\Slope_Segment__AlphaMap.png"),
                        new LODTextureSet
                            (@"Roads\BusRoads\Busway2L\Textures\Slope_SegmentLOD__MainTex.png",
                            @"Roads\BusRoads\Busway2L\Textures\Slope_SegmentLOD__AlphaMap.png",
                            @"Roads\BusRoads\Busway2L\Textures\Slope_SegmentLOD__XYS.png"));
                }
            }
            break;

            case NetInfoVersion.Tunnel:
                break;
            }

            ///////////////////////////
            // Templates             //
            ///////////////////////////
            var highwayInfo = Prefabs.Find <NetInfo>(NetInfos.Vanilla.HIGHWAY_3L);

            ///////////////////////////
            // Set up                //
            ///////////////////////////
            info.m_UnlockMilestone = highwayInfo.m_UnlockMilestone;

            info.m_lanes     = info.m_lanes.Where(l => l.m_laneType != NetInfo.LaneType.Parking).ToArray();
            info.m_laneTypes = NetInfo.LaneType.Pedestrian | NetInfo.LaneType.PublicTransport | NetInfo.LaneType.TransportVehicle;

            for (int i = 0; i < info.m_lanes.Count(); i++)
            {
                var lane = info.m_lanes[i];

                if (lane.m_laneType == NetInfo.LaneType.Vehicle)
                {
                    if (version == NetInfoVersion.Ground)
                    {
                        if (lane.m_position < 0f)
                        {
                            lane.m_position   -= 1f;
                            lane.m_stopOffset += 1f;
                        }
                        else
                        {
                            lane.m_position   += 1f;
                            lane.m_stopOffset -= 1f;
                        }
                    }

                    lane.m_speedLimit = 1.6f;
                    lane.m_laneType   = NetInfo.LaneType.TransportVehicle;
                    lane.SetBusLaneProps();

                    info.m_lanes[i] = new ExtendedNetInfoLane(lane, ExtendedVehicleType.Bus | ExtendedVehicleType.EmergencyVehicles);
                }
            }

            var roadBaseAI = info.GetComponent <RoadBaseAI>();

            if (roadBaseAI != null)
            {
            }

            var roadAI = info.GetComponent <RoadAI>();

            if (roadAI != null)
            {
                roadAI.m_enableZoning = false;
            }
        }
Exemple #46
0
        public override void OnBeforeLoadData()
        {
            base.OnBeforeLoadData();

            // determine vanilla speed limits and customizable NetInfos
            SteamHelper.DLC_BitMask dlcMask = SteamHelper.GetOwnedDLCMask();

            int numLoaded = PrefabCollection <NetInfo> .LoadedCount();

            vanillaLaneSpeedLimitsByNetInfoName.Clear();
            customizableNetInfos.Clear();
            CustomLaneSpeedLimitIndexByNetInfoName.Clear();
            childNetInfoNamesByCustomizableNetInfoName.Clear();
            NetInfoByName.Clear();

            List <NetInfo> mainNetInfos = new List <NetInfo>();

            Log.Info($"SpeedLimitManager.OnBeforeLoadData: {numLoaded} NetInfos loaded.");
            for (uint i = 0; i < numLoaded; ++i)
            {
                NetInfo info = PrefabCollection <NetInfo> .GetLoaded(i);

                if (info == null || info.m_netAI == null || !(info.m_netAI is RoadBaseAI || info.m_netAI is MetroTrackAI || info.m_netAI is TrainTrackBaseAI) || !(info.m_dlcRequired == 0 || (uint)(info.m_dlcRequired & dlcMask) != 0u))
                {
                    if (info == null)
                    {
                        Log.Warning($"SpeedLimitManager.OnBeforeLoadData: NetInfo @ {i} is null!");
                    }
                    continue;
                }

                string infoName = info.name;
                if (infoName == null)
                {
                    Log.Warning($"SpeedLimitManager.OnBeforeLoadData: NetInfo name @ {i} is null!");
                    continue;
                }

                if (!vanillaLaneSpeedLimitsByNetInfoName.ContainsKey(infoName))
                {
                    if (info.m_lanes == null)
                    {
                        Log.Warning($"SpeedLimitManager.OnBeforeLoadData: NetInfo lanes @ {i} is null!");
                        continue;
                    }

                    Log.Info($"Loaded road NetInfo: {infoName}");
                    NetInfoByName[infoName] = info;
                    mainNetInfos.Add(info);

                    float[] vanillaLaneSpeedLimits = new float[info.m_lanes.Length];
                    for (int k = 0; k < info.m_lanes.Length; ++k)
                    {
                        vanillaLaneSpeedLimits[k] = info.m_lanes[k].m_speedLimit;
                    }
                    vanillaLaneSpeedLimitsByNetInfoName[infoName] = vanillaLaneSpeedLimits;
                }
            }

            mainNetInfos.Sort(delegate(NetInfo a, NetInfo b) {
                bool aRoad = a.m_netAI is RoadBaseAI;
                bool bRoad = b.m_netAI is RoadBaseAI;

                if (aRoad != bRoad)
                {
                    if (aRoad)
                    {
                        return(-1);
                    }
                    else
                    {
                        return(1);
                    }
                }

                bool aTrain = a.m_netAI is TrainTrackBaseAI;
                bool bTrain = b.m_netAI is TrainTrackBaseAI;

                if (aTrain != bTrain)
                {
                    if (aTrain)
                    {
                        return(1);
                    }
                    else
                    {
                        return(-1);
                    }
                }

                bool aMetro = a.m_netAI is MetroTrackAI;
                bool bMetro = b.m_netAI is MetroTrackAI;

                if (aMetro != bMetro)
                {
                    if (aMetro)
                    {
                        return(1);
                    }
                    else
                    {
                        return(-1);
                    }
                }

                if (aRoad && bRoad)
                {
                    bool aHighway = ((RoadBaseAI)a.m_netAI).m_highwayRules;
                    bool bHighway = ((RoadBaseAI)b.m_netAI).m_highwayRules;

                    if (aHighway != bHighway)
                    {
                        if (aHighway)
                        {
                            return(1);
                        }
                        else
                        {
                            return(-1);
                        }
                    }
                }

                int aNumVehicleLanes = 0;
                foreach (NetInfo.Lane lane in a.m_lanes)
                {
                    if ((lane.m_laneType & LANE_TYPES) != NetInfo.LaneType.None)
                    {
                        ++aNumVehicleLanes;
                    }
                }

                int bNumVehicleLanes = 0;
                foreach (NetInfo.Lane lane in b.m_lanes)
                {
                    if ((lane.m_laneType & LANE_TYPES) != NetInfo.LaneType.None)
                    {
                        ++bNumVehicleLanes;
                    }
                }

                int res = aNumVehicleLanes.CompareTo(bNumVehicleLanes);
                if (res == 0)
                {
                    return(a.name.CompareTo(b.name));
                }
                else
                {
                    return(res);
                }
            });

            // identify parent NetInfos
            int x = 0;

            while (x < mainNetInfos.Count)
            {
                NetInfo info     = mainNetInfos[x];
                string  infoName = info.name;

                // find parent with prefix name

                bool foundParent = false;
                for (int y = 0; y < mainNetInfos.Count; ++y)
                {
                    NetInfo parentInfo = mainNetInfos[y];

                    if (info.m_placementStyle == ItemClass.Placement.Procedural && !infoName.Equals(parentInfo.name) && infoName.StartsWith(parentInfo.name))
                    {
                        Log.Info($"Identified child NetInfo {infoName} of parent {parentInfo.name}");
                        List <string> childNetInfoNames;
                        if (!childNetInfoNamesByCustomizableNetInfoName.TryGetValue(parentInfo.name, out childNetInfoNames))
                        {
                            childNetInfoNamesByCustomizableNetInfoName[parentInfo.name] = childNetInfoNames = new List <string>();
                        }
                        childNetInfoNames.Add(info.name);
                        NetInfoByName[infoName] = info;
                        foundParent             = true;
                        break;
                    }
                }

                if (foundParent)
                {
                    mainNetInfos.RemoveAt(x);
                }
                else
                {
                    ++x;
                }
            }

            customizableNetInfos = mainNetInfos;
        }
Exemple #47
0
        public static void Setup16mMesh(this NetInfo info, NetInfoVersion version)
        {
            ///////////////////////////
            // Template              //
            ///////////////////////////
            var highwayInfo     = Prefabs.Find <NetInfo>(NetInfos.Vanilla.HIGHWAY_3L);
            var defaultMaterial = highwayInfo.m_nodes[0].m_material;

            switch (version)
            {
            case NetInfoVersion.Ground:
            {
                var segments0 = info.m_segments[0].ShallowClone();
                var nodes0    = info.m_nodes[0].ShallowClone();
                var nodes1    = info.m_nodes[0].ShallowClone();

                segments0
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Ground.obj",
                    @"Roads\Highways\Common\Meshes\16m\Ground_LOD.obj");

                nodes0
                .SetFlags(NetNode.Flags.None, NetNode.Flags.Transition)
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Ground_Node.obj",
                    @"Roads\Highways\Common\Meshes\16m\Ground_Node_LOD.obj");

                nodes1
                .SetFlags(NetNode.Flags.Transition, NetNode.Flags.None)
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Ground_Trans.obj",
                    @"Roads\Highways\Common\Meshes\16m\Ground_Trans_LOD.obj");

                info.m_segments = new[] { segments0 };
                info.m_nodes    = new[] { nodes0, nodes1 };
            }
            break;

            case NetInfoVersion.Elevated:
            case NetInfoVersion.Bridge:
            {
                var segments0 = info.m_segments[0].ShallowClone();
                var nodes0    = info.m_nodes[0].ShallowClone();
                var nodes1    = info.m_nodes[0].ShallowClone();

                segments0
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Elevated.obj",
                    @"Roads\Highways\Common\Meshes\16m\Elevated_LOD.obj");

                nodes0
                .SetFlags(NetNode.Flags.None, NetNode.Flags.Transition)
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Elevated_Node.obj",
                    @"Roads\Highways\Common\Meshes\16m\Elevated_Node_LOD.obj");

                nodes1
                .SetFlags(NetNode.Flags.Transition, NetNode.Flags.None)
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Elevated_Trans.obj",
                    @"Roads\Highways\Common\Meshes\16m\Elevated_Trans_LOD.obj");

                info.m_segments = new[] { segments0 };
                info.m_nodes    = new[] { nodes0, nodes1 };
            }
            break;

            case NetInfoVersion.Slope:
            {
                var segments0 = info.m_segments[0].ShallowClone();
                var segments1 = info.m_segments[1].ShallowClone();
                var segments2 = info.m_segments[1].ShallowClone();
                var nodes0    = info.m_nodes[0].ShallowClone();
                var nodes1    = info.m_nodes[0].ShallowClone();
                var nodes2    = info.m_nodes[1].ShallowClone();
                var nodes3    = info.m_nodes[1].ShallowClone();

                segments0
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Tunnel_Gray.obj",
                    @"Roads\Highways\Common\Meshes\16m\Ground_LOD.obj");
                segments1
                .SetFlagsDefault();
                segments2
                .SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Slope.obj",
                    @"Roads\Highways\Common\Meshes\16m\Slope_LOD.obj");

                nodes0
                .SetFlags(NetNode.Flags.Underground, NetNode.Flags.None)
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Tunnel_Node_Gray.obj",
                    @"Roads\Highways\Common\Meshes\16m\Ground_Node_LOD.obj");
                nodes1
                .SetFlags(NetNode.Flags.Underground, NetNode.Flags.None)
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Slope_U_Node.obj",
                    @"Roads\Highways\Common\Meshes\16m\Slope_U_Node_LOD.obj");
                nodes2
                .SetFlags(NetNode.Flags.None, NetNode.Flags.UndergroundTransition)
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Ground_Node.obj",
                    @"Roads\Highways\Common\Meshes\16m\Ground_Node_LOD.obj");
                nodes3
                .SetFlags(NetNode.Flags.Transition, NetNode.Flags.None)
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Ground_Trans.obj",
                    @"Roads\Highways\Common\Meshes\16m\Ground_Trans_LOD.obj");

                nodes1.m_material = defaultMaterial;

                info.m_segments = new[] { segments0, segments1, segments2 };
                info.m_nodes    = new[] { nodes0, nodes1, nodes2, nodes3 };
            }
            break;

            case NetInfoVersion.Tunnel:
            {
                var segments0 = info.m_segments[0].ShallowClone();
                var segments1 = info.m_segments[0].ShallowClone();
                var nodes0    = info.m_nodes[0].ShallowClone();
                var nodes1    = info.m_nodes[0].ShallowClone();

                segments0
                //.SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Tunnel_Gray.obj",
                    @"Roads\Highways\Common\Meshes\16m\Ground_LOD.obj");
                segments1
                //.SetFlagsDefault()
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Tunnel.obj",
                    @"Roads\Highways\Common\Meshes\16m\Tunnel_LOD.obj");
                nodes0
                .SetFlags(NetNode.Flags.None, NetNode.Flags.None)
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Tunnel_Node_Gray.obj",
                    @"Roads\Highways\Common\Meshes\16m\Ground_Node_LOD.obj");
                nodes1
                .SetFlags(NetNode.Flags.None, NetNode.Flags.None)
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\16m\Tunnel_Node.obj",
                    @"Roads\Highways\Common\Meshes\16m\Tunnel_Node_LOD.obj");

                segments1.m_material = defaultMaterial;
                nodes1.m_material    = defaultMaterial;

                info.m_segments = new[] { segments0, segments1 };
                info.m_nodes    = new[] { nodes0, nodes1 };
            }
            break;
            }
        }
        internal static bool mayHaveLaneArrows(uint laneId, bool?startNode = null)
        {
            if (laneId <= 0)
            {
                return(false);
            }
            NetManager netManager = Singleton <NetManager> .instance;

            if (((NetLane.Flags)Singleton <NetManager> .instance.m_lanes.m_buffer[laneId].m_flags & (NetLane.Flags.Created | NetLane.Flags.Deleted)) != NetLane.Flags.Created)
            {
                return(false);
            }

            ushort segmentId = netManager.m_lanes.m_buffer[laneId].m_segment;

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

            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;
            int     laneIndex   = 0;
            int     wIter       = 0;

            while (laneIndex < numLanes && curLaneId != 0u)
            {
                ++wIter;
                if (wIter >= 100)
                {
                    Log.Error("Too many iterations in Flags.mayHaveLaneArrows!");
                    break;
                }

                if (curLaneId == laneId)
                {
                    NetInfo.Lane laneInfo    = segmentInfo.m_lanes[laneIndex];
                    bool         isStartNode = (laneInfo.m_finalDirection & dir2) == NetInfo.Direction.None;
                    if (startNode != null && isStartNode != startNode)
                    {
                        return(false);
                    }
                    ushort nodeId = isStartNode ? netManager.m_segments.m_buffer[segmentId].m_startNode : netManager.m_segments.m_buffer[segmentId].m_endNode;

                    if ((netManager.m_nodes.m_buffer[nodeId].m_flags & (NetNode.Flags.Created | NetNode.Flags.Deleted)) != NetNode.Flags.Created)
                    {
                        return(false);
                    }
                    return((netManager.m_nodes.m_buffer[nodeId].m_flags & NetNode.Flags.Junction) != NetNode.Flags.None);
                }
                curLaneId = netManager.m_lanes.m_buffer[curLaneId].m_nextLane;
                ++laneIndex;
            }
            return(false);
        }
Exemple #49
0
        public bool CanToggleTrafficLight(ushort nodeId,
                                          bool flag, // override?
                                          ref NetNode node,
                                          out ToggleTrafficLightError reason)
        {
#if DEBUG
            bool logTrafficLights = DebugSwitch.TimedTrafficLights.Get() && DebugSettings.NodeId == nodeId;
#else
            const bool logTrafficLights = false;
#endif
            if (!flag && TrafficLightSimulationManager.Instance.HasTimedSimulation(nodeId))
            {
                reason = ToggleTrafficLightError.HasTimedLight;
                if (logTrafficLights)
                {
                    Log._Debug($"Cannot toggle traffic lights at node {nodeId}: Node has a timed traffic light");
                }

                return(false);
            }

            if (flag &&
                (!Services.NetService.IsNodeValid(nodeId) ||
                 !Services.NetService.CheckNodeFlags(nodeId, NetNode.Flags.Junction)))
            {
                reason = ToggleTrafficLightError.NoJunction;

                if (logTrafficLights)
                {
                    Log._Debug($"Cannot toggle traffic lights at node {nodeId}: Node is not a junction");
                }

                return(false);
            }

            if (!flag && Services.NetService.CheckNodeFlags(nodeId, NetNode.Flags.LevelCrossing))
            {
                reason = ToggleTrafficLightError.IsLevelCrossing;

                if (logTrafficLights)
                {
                    Log._Debug($"Cannot toggle traffic lights at node {nodeId}: Node is a level crossing");
                }

                return(false);
            }

            int numRoads          = 0;
            int numTrainTracks    = 0;
            int numMonorailTracks = 0;
            int numPedSegments    = 0;
            Services.NetService.IterateNodeSegments(
                nodeId,
                (ushort segmentId, ref NetSegment segment) => {
                NetInfo info = segment.Info;
                if (info.m_class.m_service == ItemClass.Service.Road)
                {
                    ++numRoads;
                }
                else if ((info.m_vehicleTypes & VehicleInfo.VehicleType.Train) !=
                         VehicleInfo.VehicleType.None)
                {
                    ++numTrainTracks;
                }
                else if ((info.m_vehicleTypes & VehicleInfo.VehicleType.Monorail) !=
                         VehicleInfo.VehicleType.None)
                {
                    ++numMonorailTracks;
                }

                if (info.m_hasPedestrianLanes)
                {
                    ++numPedSegments;
                }

                return(true);
            });

            if (numRoads >= 2 || numTrainTracks >= 2 || numMonorailTracks >= 2 || numPedSegments != 0)
            {
                if (logTrafficLights)
                {
                    Log._DebugFormat(
                        "Can toggle traffic lights at node {0}: numRoads={1} numTrainTracks={2} " +
                        "numMonorailTracks={3} numPedSegments={4}",
                        nodeId,
                        numRoads,
                        numTrainTracks,
                        numMonorailTracks,
                        numPedSegments);
                }

                reason = ToggleTrafficLightError.None;
                return(true);
            }

            if (logTrafficLights)
            {
                Log._DebugFormat(
                    "Cannot toggle traffic lights at node {0}: Insufficient segments. numRoads={1} " +
                    "numTrainTracks={2} numMonorailTracks={3} numPedSegments={4}",
                    nodeId,
                    numRoads,
                    numTrainTracks,
                    numMonorailTracks,
                    numPedSegments);
            }

            reason = ToggleTrafficLightError.InsufficientSegments;
            return(false);
        }
Exemple #50
0
        /// <summary>
        /// Creates a new node and returns it.
        /// </summary>
        /// <param name="newNodeId"></param>
        /// <param name="randomizer"></param>
        /// <param name="info"></param>
        /// <param name="newNodePosition"></param>
        /// <returns></returns>
        private static NetNode CreateNode(out ushort newNodeId, ref Randomizer randomizer, NetInfo info, Vector3 newNodePosition)
        {
            NetManager.instance.CreateNode(out newNodeId, ref randomizer, info, newNodePosition,
                                           Singleton <SimulationManager> .instance.m_currentBuildIndex + 1);

            return(NetManager.instance.m_nodes.m_buffer[newNodeId]);
        }
Exemple #51
0
        private void _guiVehicleRestrictionsWindow(int num)
        {
            if (GUILayout.Button(Translation.GetString("Invert")))
            {
                // invert pattern

                NetInfo         selectedSegmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[SelectedSegmentId].Info;
                List <object[]> sortedLanes         = TrafficManagerTool.GetSortedVehicleLanes(SelectedSegmentId, selectedSegmentInfo, null);        // TODO does not need to be sorted, but every lane should be a vehicle lane
                foreach (object[] laneData in sortedLanes)
                {
                    uint         laneId    = (uint)laneData[0];
                    uint         laneIndex = (uint)laneData[2];
                    NetInfo.Lane laneInfo  = selectedSegmentInfo.m_lanes[laneIndex];

                    ExtVehicleType baseMask = VehicleRestrictionsManager.Instance().GetBaseMask(laneInfo);

                    if (baseMask == ExtVehicleType.None)
                    {
                        continue;
                    }

                    ExtVehicleType allowedTypes = VehicleRestrictionsManager.Instance().GetAllowedVehicleTypes(SelectedSegmentId, selectedSegmentInfo, laneIndex, laneInfo);
                    allowedTypes = ~allowedTypes & baseMask;
                    VehicleRestrictionsManager.Instance().SetAllowedVehicleTypes(SelectedSegmentId, selectedSegmentInfo, laneIndex, laneInfo, laneId, allowedTypes);
                }
                RefreshCurrentRestrictedSegmentIds();
            }

            GUILayout.BeginHorizontal();
            if (GUILayout.Button(Translation.GetString("Allow_all_vehicles")))
            {
                // allow all vehicle types

                NetInfo         selectedSegmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[SelectedSegmentId].Info;
                List <object[]> sortedLanes         = TrafficManagerTool.GetSortedVehicleLanes(SelectedSegmentId, selectedSegmentInfo, null);        // TODO does not need to be sorted, but every lane should be a vehicle lane
                foreach (object[] laneData in sortedLanes)
                {
                    uint         laneId    = (uint)laneData[0];
                    uint         laneIndex = (uint)laneData[2];
                    NetInfo.Lane laneInfo  = selectedSegmentInfo.m_lanes[laneIndex];

                    ExtVehicleType baseMask = VehicleRestrictionsManager.Instance().GetBaseMask(laneInfo);

                    if (baseMask == ExtVehicleType.None)
                    {
                        continue;
                    }

                    VehicleRestrictionsManager.Instance().SetAllowedVehicleTypes(SelectedSegmentId, selectedSegmentInfo, laneIndex, laneInfo, laneId, baseMask);
                }
                RefreshCurrentRestrictedSegmentIds();
            }

            if (GUILayout.Button(Translation.GetString("Ban_all_vehicles")))
            {
                // ban all vehicle types

                NetInfo         selectedSegmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[SelectedSegmentId].Info;
                List <object[]> sortedLanes         = TrafficManagerTool.GetSortedVehicleLanes(SelectedSegmentId, selectedSegmentInfo, null);        // TODO does not need to be sorted, but every lane should be a vehicle lane
                foreach (object[] laneData in sortedLanes)
                {
                    uint         laneId    = (uint)laneData[0];
                    uint         laneIndex = (uint)laneData[2];
                    NetInfo.Lane laneInfo  = selectedSegmentInfo.m_lanes[laneIndex];

                    VehicleRestrictionsManager.Instance().SetAllowedVehicleTypes(SelectedSegmentId, selectedSegmentInfo, laneIndex, laneInfo, laneId, ExtVehicleType.None);
                }
                RefreshCurrentRestrictedSegmentIds();
            }
            GUILayout.EndHorizontal();

            if (GUILayout.Button(Translation.GetString("Apply_vehicle_restrictions_to_all_road_segments_between_two_junctions")))
            {
                ApplyRestrictionsToAllSegments();
                RefreshCurrentRestrictedSegmentIds();
            }

            GUI.DragWindow();
        }
Exemple #52
0
        /// <summary>
        ///     Mod's core.
        ///     First, we create the segment using game's original code.
        ///     Then we offset the 2 nodes of the segment, based on both direction and curve, so that we can finally create a
        ///     segment between the 2 offset nodes.
        /// </summary>
        /// <param name="segment"></param>
        /// <param name="randomizer"></param>
        /// <param name="info"></param>
        /// <param name="startNode"></param>
        /// <param name="endNode"></param>
        /// <param name="startDirection"></param>
        /// <param name="endDirection"></param>
        /// <param name="buildIndex"></param>
        /// <param name="modifiedIndex"></param>
        /// <param name="invert"></param>
        /// <returns></returns>
        private bool CreateSegment(out ushort segment, ref Randomizer randomizer, NetInfo info, ushort startNode,
                                   ushort endNode, Vector3 startDirection, Vector3 endDirection, uint buildIndex, uint modifiedIndex,
                                   bool invert)
        {
            DebugUtils.Log($"Creating a segment and {ParallelRoadTool.SelectedRoadTypes.Count} parallel segments");

            // Let's create the segment that the user requested
            var result = CreateSegmentOriginal(out segment, ref randomizer, info, startNode, endNode, startDirection,
                                               endDirection, buildIndex, modifiedIndex, invert);

            // If we're in upgrade mode we must stop here
            if (ParallelRoadTool.NetTool.m_mode == NetTool.Mode.Upgrade)
            {
                return(result);
            }

            // True if we have a slope that is going down from start to end node
            var isEnteringSlope = NetManager.instance.m_nodes.m_buffer[invert ? startNode : endNode].m_elevation >
                                  NetManager.instance.m_nodes.m_buffer[invert ? endNode : startNode].m_elevation;

            // HACK - [ISSUE-10] [ISSUE-18] Check if we've been called by an allowed caller, otherwise we can stop here
            var caller = string.Join(".", new []
            {
                new System.Diagnostics.StackFrame(3).GetMethod().DeclaringType?.Name,
                new System.Diagnostics.StackFrame(2).GetMethod().Name,
                new System.Diagnostics.StackFrame(1).GetMethod().Name
            });

            DebugUtils.Log($"Caller trace is {caller}");

            if (!_allowedCallers.Contains(caller))
            {
                return(result);
            }

            for (var i = 0; i < ParallelRoadTool.SelectedRoadTypes.Count; i++)
            {
                var currentRoadInfos = ParallelRoadTool.SelectedRoadTypes[i];

                var horizontalOffset = currentRoadInfos.HorizontalOffset;
                var verticalOffset   = currentRoadInfos.VerticalOffset;
                DebugUtils.Log($"Using offsets: h {horizontalOffset} | v {verticalOffset}");

                // If the user didn't select a NetInfo we'll use the one he's using for the main road
                var selectedNetInfo = info.GetNetInfoWithElevation(currentRoadInfos.NetInfo ?? info, out var isSlope);
                // If the user is using a vertical offset we try getting the relative elevated net info and use it
                if (verticalOffset > 0 && selectedNetInfo.m_netAI.GetCollisionType() !=
                    ItemClass.CollisionType.Elevated)
                {
                    selectedNetInfo = new RoadAIWrapper(selectedNetInfo.m_netAI).elevated ?? selectedNetInfo;
                }

                var isReversed = currentRoadInfos.IsReversed;

                // Left-hand drive means that any condition must be reversed
                if (ParallelRoadTool.Instance.IsLeftHandTraffic)
                {
                    invert     = !invert;
                    isReversed = !isReversed;
                }

                DebugUtils.Log($"Using netInfo {selectedNetInfo.name} | reversed={isReversed} | invert={invert}");

                // Get original nodes to clone them
                var startNetNode = NetManager.instance.m_nodes.m_buffer[startNode];
                var endNetNode   = NetManager.instance.m_nodes.m_buffer[endNode];

                // Create two clone nodes by offsetting the original ones.
                // If we're not in "invert" mode (aka final part of a curve) and we already have an ending node with the same id of our starting node, we need to use that so that the segments can be connected.
                // If the previous segment was in "invert" mode and the current startNode is the same as the previous one, we need to connect them.
                // If we don't have any previous node matching our starting one, we need to clone startNode as this may be a new segment.
                ushort newStartNodeId;
                if (!invert && _endNodeId[i].HasValue && _endNodeId[i].Value == startNode)
                {
                    DebugUtils.Log(
                        $"[START] Using old node from previous iteration {_clonedEndNodeId[i].Value} instead of the given one {startNode}");
                    newStartNodeId = _clonedEndNodeId[i].Value;
                    DebugUtils.Log(
                        $"[START] Start node{startNetNode.m_position} becomes {NetManager.instance.m_nodes.m_buffer[newStartNodeId].m_position}");
                }
                else if (!invert && _isPreviousInvert && _startNodeId[i].HasValue &&
                         _startNodeId[i].Value == startNode)
                {
                    DebugUtils.Log(
                        $"[START] Using old node from previous iteration {_clonedStartNodeId[i].Value} instead of the given one {startNode}");
                    newStartNodeId = _clonedStartNodeId[i].Value;
                    DebugUtils.Log(
                        $"[START] Start node{startNetNode.m_position} becomes {NetManager.instance.m_nodes.m_buffer[newStartNodeId].m_position}");
                }
                else
                {
                    var newStartPosition = startNetNode.m_position.Offset(startDirection, horizontalOffset,
                                                                          verticalOffset, invert);

                    DebugUtils.Log($"[START] {startNetNode.m_position} --> {newStartPosition} | isLeftHand = {ParallelRoadTool.Instance.IsLeftHandTraffic} | invert = {invert}  | isSlope = {isSlope}");
                    newStartNodeId = NodeAtPositionOrNew(ref randomizer, info, newStartPosition);
                }

                // Same thing as startNode, but this time we don't clone if we're in "invert" mode as we may need to connect this ending node with the previous ending one.
                ushort newEndNodeId;
                if (invert && _endNodeId[i].HasValue && _endNodeId[i].Value == endNode)
                {
                    DebugUtils.Log(
                        $"[END] Using old node from previous iteration {_clonedEndNodeId[i].Value} instead of the given one {endNode}");
                    newEndNodeId = _clonedEndNodeId[i].Value;
                    DebugUtils.Log(
                        $"[END] End node{endNetNode.m_position} becomes {NetManager.instance.m_nodes.m_buffer[newEndNodeId].m_position}");
                }
                else
                {
                    var newEndPosition = endNetNode.m_position.Offset(endDirection, horizontalOffset, verticalOffset, !(invert && isSlope && isEnteringSlope));

                    DebugUtils.Log($"[END] {endNetNode.m_position} --> {newEndPosition} | isEnteringSlope = {isEnteringSlope} | invert = {invert} | isSlope = {isSlope}");
                    newEndNodeId = NodeAtPositionOrNew(ref randomizer, info, newEndPosition);
                }

                // Store current end nodes in case we may need to connect the following segment to them
                _endNodeId[i]         = endNode;
                _clonedEndNodeId[i]   = newEndNodeId;
                _startNodeId[i]       = startNode;
                _clonedStartNodeId[i] = newStartNodeId;

                if (isReversed)
                {
                    Vector3 tempStartDirection;
                    Vector3 tempEndDirection;
                    if (startDirection == -endDirection)
                    {
                        // Straight segment, we invert both directions
                        tempStartDirection = -startDirection;
                        tempEndDirection   = -endDirection;
                    }
                    else
                    {
                        // Curve, we need to swap start and end direction
                        tempStartDirection = endDirection;
                        tempEndDirection   = startDirection;
                    }

                    // Create the segment between the two cloned nodes, inverting start and end node
                    result = CreateSegmentOriginal(out segment, ref randomizer, selectedNetInfo, newEndNodeId,
                                                   newStartNodeId,
                                                   tempStartDirection, tempEndDirection,
                                                   Singleton <SimulationManager> .instance.m_currentBuildIndex + 1,
                                                   Singleton <SimulationManager> .instance.m_currentBuildIndex, invert);
                }
                else
                {
                    // Create the segment between the two cloned nodes
                    result = CreateSegmentOriginal(out segment, ref randomizer, selectedNetInfo, newStartNodeId,
                                                   newEndNodeId, startDirection, endDirection,
                                                   Singleton <SimulationManager> .instance.m_currentBuildIndex + 1,
                                                   Singleton <SimulationManager> .instance.m_currentBuildIndex, invert);
                }
            }

            _isPreviousInvert = invert;
            return(result);
        }
Exemple #53
0
        public void BuildUp(NetInfo info, NetInfoVersion version)
        {
            ///////////////////////////
            // Template              //
            ///////////////////////////
            var roadTunnelInfo = Prefabs.Find <NetInfo>(NetInfos.Vanilla.ROAD_4L_TUNNEL);
            var roadInfo       = Prefabs.Find <NetInfo>(NetInfos.Vanilla.ROAD_6L);

            ///////////////////////////
            // 3DModeling            //
            ///////////////////////////
            info.Setup32m3mSW4mMdnMesh(version);

            ///////////////////////////
            // Texturing             //
            ///////////////////////////
            SetupTextures(info, version);

            ///////////////////////////
            // Set up                //
            ///////////////////////////
            info.m_hasParkingSpaces = true;
            if (version == NetInfoVersion.Ground)
            {
                info.m_pavementWidth = 3;
            }
            else if (version == NetInfoVersion.Tunnel)
            {
                info.m_pavementWidth = 6;
            }
            else
            {
                info.m_pavementWidth = 5;
            }

            info.m_halfWidth = (version == NetInfoVersion.Tunnel ? 17 : 16);

            if (version == NetInfoVersion.Tunnel)
            {
                info.m_setVehicleFlags = Vehicle.Flags.Transition | Vehicle.Flags.Underground;
                info.m_setCitizenFlags = CitizenInstance.Flags.Transition | CitizenInstance.Flags.Underground;
                info.m_class           = roadTunnelInfo.m_class.Clone(NetInfoClasses.NEXT_XLARGE_ROAD_TUNNEL);
            }
            else
            {
                info.m_class = roadInfo.m_class.Clone(NetInfoClasses.NEXT_XLARGE_ROAD);
            }

            // Setting up lanes
            info.SetRoadLanes(version, new LanesConfiguration
            {
                IsTwoWay        = true,
                LaneWidth       = 3,
                LanesToAdd      = 2,
                PedPropOffsetX  = version == NetInfoVersion.Slope ? 1.5f : 1f,
                CenterLane      = CenterLaneType.Median,
                CenterLaneWidth = 4,
                BusStopOffset   = 3
            });

            var medianLane   = info.GetMedianLane();
            var leftPedLane  = info.GetLeftRoadShoulder();
            var rightPedLane = info.GetRightRoadShoulder();

            // Fix for T++ legacy support (reordering)
            if (medianLane != null)
            {
                info.m_lanes = info
                               .m_lanes
                               .Except(medianLane)
                               .Union(medianLane)
                               .ToArray();
            }

            //Setting Up Props
            var leftPedLaneProps   = leftPedLane.m_laneProps.m_props.ToList();
            var rightPedLaneProps  = rightPedLane.m_laneProps.m_props.ToList();
            var medianPedLaneProps = medianLane?.m_laneProps?.m_props.ToList();

            if (version != NetInfoVersion.Tunnel)
            {
                var medianStreetLight = medianPedLaneProps?.FirstOrDefault(p => p.m_prop.name.ToLower().Contains("avenue light"));
                if (medianStreetLight != null)
                {
                    medianStreetLight.m_finalProp =
                        medianStreetLight.m_prop  = Prefabs.Find <PropInfo>(LargeAvenueMedianLightBuilder.NAME);
                }
            }

            if (medianPedLaneProps != null)
            {
                medianPedLaneProps.RemoveProps("50 Speed Limit");
            }

            if (version == NetInfoVersion.Slope)
            {
                leftPedLaneProps.AddLeftWallLights(info.m_pavementWidth);
                rightPedLaneProps.AddRightWallLights(info.m_pavementWidth);
            }

            leftPedLane.m_laneProps.m_props  = leftPedLaneProps.ToArray();
            rightPedLane.m_laneProps.m_props = rightPedLaneProps.ToArray();
            if (medianLane?.m_laneProps != null && medianPedLaneProps != null)
            {
                medianLane.m_laneProps.m_props = medianPedLaneProps.ToArray();
            }


            info.TrimAboveGroundProps(version);

            // AI
            var owPlayerNetAI = roadInfo.GetComponent <PlayerNetAI>();
            var playerNetAI   = info.GetComponent <PlayerNetAI>();

            if (owPlayerNetAI != null && playerNetAI != null)
            {
                playerNetAI.m_constructionCost = owPlayerNetAI.m_constructionCost * 2; // Charge by the lane?
                playerNetAI.m_maintenanceCost  = owPlayerNetAI.m_maintenanceCost * 2;  // Charge by the lane?
            }

            var roadBaseAI = info.GetComponent <RoadBaseAI>();

            if (roadBaseAI != null)
            {
                roadBaseAI.m_trafficLights = true;
            }
        }
Exemple #54
0
 /// <summary>
 /// Calculates if the given segment info describes a highway segment
 /// </summary>
 /// <param name="segmentInfo"></param>
 /// <returns></returns>
 private bool CalculateIsHighway(NetInfo segmentInfo)
 {
     return(segmentInfo.m_netAI is RoadBaseAI &&
            ((RoadBaseAI)segmentInfo.m_netAI).m_highwayRules);
 }
        public static void setLaneSpeedLimit(ushort segmentId, uint laneIndex, uint laneId, ushort?speedLimit)
        {
            if (segmentId <= 0 || laneIndex < 0 || laneId <= 0)
            {
                return;
            }
            if ((Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_flags & (NetSegment.Flags.Created | NetSegment.Flags.Deleted)) != NetSegment.Flags.Created)
            {
                return;
            }
            if (((NetLane.Flags)Singleton <NetManager> .instance.m_lanes.m_buffer[laneId].m_flags & (NetLane.Flags.Created | NetLane.Flags.Deleted)) != NetLane.Flags.Created)
            {
                return;
            }
            NetInfo segmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info;

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

            try {
                Monitor.Enter(laneSpeedLimitLock);
#if DEBUGFLAGS
                Log._Debug($"Flags.setLaneSpeedLimit: setting speed limit of lane index {laneIndex} @ seg. {segmentId} to {speedLimit}");
#endif

                if (speedLimit == null)
                {
                    laneSpeedLimit.Remove(laneId);

                    if (laneSpeedLimitArray[segmentId] == null)
                    {
                        return;
                    }
                    if (laneIndex >= laneSpeedLimitArray[segmentId].Length)
                    {
                        return;
                    }
                    laneSpeedLimitArray[segmentId][laneIndex] = null;
                }
                else
                {
                    laneSpeedLimit[laneId] = (ushort)speedLimit;

                    // save speed limit into the fast-access array.
                    // (1) ensure that the array is defined and large enough
                    if (laneSpeedLimitArray[segmentId] == null)
                    {
                        laneSpeedLimitArray[segmentId] = new ushort?[segmentInfo.m_lanes.Length];
                    }
                    else if (laneSpeedLimitArray[segmentId].Length < segmentInfo.m_lanes.Length)
                    {
                        var oldArray = laneSpeedLimitArray[segmentId];
                        laneSpeedLimitArray[segmentId] = new ushort?[segmentInfo.m_lanes.Length];
                        Array.Copy(oldArray, laneSpeedLimitArray[segmentId], oldArray.Length);
                    }
                    // (2) insert the custom speed limit
                    laneSpeedLimitArray[segmentId][laneIndex] = speedLimit;
                }
            } finally {
                Monitor.Exit(laneSpeedLimitLock);
            }
        }
        private static void SetupTextures(NetInfo info, NetInfoVersion version)
        {
            switch (version)
            {
            case NetInfoVersion.Ground:
                info.SetAllSegmentsTexture(
                    new TextureSet
                        (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_Segment__MainTex.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_Segment__AlphaMap.png"),
                    new LODTextureSet
                        (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_SegmentLOD__MainTex.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_SegmentLOD__AlphaMap.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_SegmentLOD__XYS.png"));
                break;

            case NetInfoVersion.Elevated:
            case NetInfoVersion.Bridge:
                info.SetAllSegmentsTexture(
                    new TextureSet
                        (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Elevated_MainTex.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Elevated_Segment__APRMap.png"),
                    new LODTextureSet
                        (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Elevated_LOD__MainTex.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Elevated_SegmentLOD__APRMap.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Elevated_LOD__XYSMap.png"));
                info.SetAllNodesTexture(
                    new TextureSet
                        (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Elevated_MainTex.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Elevated_Node__APRMap.png"),
                    new LODTextureSet
                        (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Elevated_LOD__MainTex.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Elevated_NodeLOD__APRMap.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Elevated_LOD__XYSMap.png"));
                break;

            case NetInfoVersion.Slope:
                for (int i = 0; i < info.m_segments.Length; i++)
                {
                    if (info.m_segments[i].m_mesh.name == "Slope")
                    {
                        info.m_segments[i].SetTextures(
                            new TextureSet
                                (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_Segment__MainTex.png",
                                @"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_Segment__AlphaMap.png"),
                            new LODTextureSet
                                (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_SegmentLOD__MainTex.png",
                                @"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_SegmentLOD__AlphaMap.png",
                                @"Roads\SmallHeavyRoads\OneWay4L\Textures\Slope_SegmentLOD2__XYSMap.png"));
                    }
                    else
                    {
                        info.m_segments[i].SetTextures(
                            new TextureSet
                                (@"Roads\Highways\Highway4L\Textures\Slope_Segment__MainTex.png",
                                @"Roads\SmallHeavyRoads\OneWay4L\Textures\Slope_Segment__APRMap.png"),
                            new LODTextureSet
                                (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Slope_SegmentLOD__MainTex.png",
                                @"Roads\SmallHeavyRoads\OneWay4L\Textures\Slope_SegmentLOD__APRMap.png",
                                @"Roads\SmallHeavyRoads\OneWay4L\Textures\Slope_SegmentLOD__XYSMap.png"));
                    }
                }
                for (int i = 0; i < info.m_nodes.Length; i++)
                {
                    if (info.m_nodes[i].m_mesh.name == "Slope_Node")
                    {
                        info.m_nodes[i].SetTextures(
                            new TextureSet
                                (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_Segment__MainTex.png",
                                @"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_Node__AlphaMap.png"),
                            new LODTextureSet
                                (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_SegmentLOD__MainTex.png",
                                @"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_SegmentLOD__AlphaMap.png",
                                @"Roads\SmallHeavyRoads\OneWay4L\Textures\Ground_SegmentLOD__XYS.png"));
                    }
                    else
                    {
                        info.m_nodes[i].SetTextures(
                            new TextureSet
                                (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_Segment__MainTex.png",
                                @"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_Node__APRMap.png"),
                            new LODTextureSet
                                (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_NodeLOD__MainTex.png",
                                @"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_LOD__APRMap.png",
                                @"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_LOD__XYSMap.png"));
                    }
                }
                //info.SetAllNodesTexture(
                //new TextureSet
                //    (@"Roads\Highways\Highway4L\Textures\Slope_Node__MainTex.png",
                //    @"Roads\Highways\Highway4L\Textures\Ground_Node__APRMap.png"),
                //new LODTextureSet
                //    (@"Roads\Highways\Highway4L\Textures\Ground_NodeLOD__MainTex.png",
                //    @"Roads\Highways\Highway4L\Textures\Ground_NodeLOD__APRMap.png",
                //    @"Roads\Highways\Highway4L\Textures\Ground_LOD__XYSMap.png"));
                break;

            case NetInfoVersion.Tunnel:
            {
                info.SetAllSegmentsTexture(
                    new TextureSet
                        (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_Segment__MainTex.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_Segment__APRMap.png"),
                    new LODTextureSet
                        (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_NodeLOD__MainTex.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_LOD__APRMap.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_LOD__XYSMap.png"));
                info.SetAllNodesTexture(
                    new TextureSet
                        (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_Segment__MainTex.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_Node__APRMap.png"),
                    new LODTextureSet
                        (@"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_NodeLOD__MainTex.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_LOD__APRMap.png",
                        @"Roads\SmallHeavyRoads\OneWay4L\Textures\Tunnel_LOD__XYSMap.png"));
                break;
            }
            }
        }
Exemple #57
0
        public void RefreshJunctionData(ushort nodeID, int segmentIndex, ushort nodeSegment, Vector3 centerPos, ref uint instanceIndex, ref RenderManager.Instance data)
        {
            NetNode    thisNode = NetManager.instance.m_nodes.m_buffer[nodeID];
            NetManager instance = Singleton <NetManager> .instance;

            data.m_position    = thisNode.m_position;
            data.m_rotation    = Quaternion.identity;
            data.m_initialized = true;
            float      vScale          = 0.05f;
            Vector3    zero            = Vector3.zero;
            Vector3    zero2           = Vector3.zero;
            Vector3    zero3           = Vector3.zero;
            Vector3    zero4           = Vector3.zero;
            Vector3    vector          = Vector3.zero;
            Vector3    vector2         = Vector3.zero;
            Vector3    a               = Vector3.zero;
            Vector3    a2              = Vector3.zero;
            Vector3    zero5           = Vector3.zero;
            Vector3    zero6           = Vector3.zero;
            Vector3    zero7           = Vector3.zero;
            Vector3    zero8           = Vector3.zero;
            NetSegment netSegment      = instance.m_segments.m_buffer[(int)nodeSegment];
            NetInfo    info            = netSegment.Info;
            ItemClass  connectionClass = info.GetConnectionClass();
            Vector3    vector3         = (nodeID != netSegment.m_startNode) ? netSegment.m_endDirection : netSegment.m_startDirection;
            float      num             = -4f;
            float      num2            = -4f;
            ushort     num3            = 0;
            ushort     num4            = 0;

            for (int i = 0; i < 8; i++)
            {
                ushort segment = thisNode.GetSegment(i);
                if (segment != 0 && segment != nodeSegment)
                {
                    NetInfo   info2            = instance.m_segments.m_buffer[(int)segment].Info;
                    ItemClass connectionClass2 = info2.GetConnectionClass();
                    if (connectionClass.m_service == connectionClass2.m_service)
                    {
                        NetSegment netSegment2 = instance.m_segments.m_buffer[(int)segment];
                        Vector3    vector4     = (nodeID != netSegment2.m_startNode) ? netSegment2.m_endDirection : netSegment2.m_startDirection;
                        float      num5        = vector3.x * vector4.x + vector3.z * vector4.z;
                        if (vector4.z * vector3.x - vector4.x * vector3.z < 0f)
                        {
                            if (num5 > num)
                            {
                                num  = num5;
                                num3 = segment;
                            }
                            num5 = -2f - num5;
                            if (num5 > num2)
                            {
                                num2 = num5;
                                num4 = segment;
                            }
                        }
                        else
                        {
                            if (num5 > num2)
                            {
                                num2 = num5;
                                num4 = segment;
                            }
                            num5 = -2f - num5;
                            if (num5 > num)
                            {
                                num  = num5;
                                num3 = segment;
                            }
                        }
                    }
                }
            }
            bool start = netSegment.m_startNode == nodeID;
            bool flag;

            netSegment.CalculateCorner(nodeSegment, true, start, false, out zero, out zero3, out flag);
            netSegment.CalculateCorner(nodeSegment, true, start, true, out zero2, out zero4, out flag);
            if (num3 != 0 && num4 != 0)
            {
                float num6 = info.m_pavementWidth / info.m_halfWidth * 0.5f;
                float y    = 1f;
                if (num3 != 0)
                {
                    NetSegment netSegment3 = instance.m_segments.m_buffer[(int)num3];
                    NetInfo    info3       = netSegment3.Info;
                    start = (netSegment3.m_startNode == nodeID);
                    netSegment3.CalculateCorner(num3, true, start, true, out vector, out a, out flag);
                    netSegment3.CalculateCorner(num3, true, start, false, out vector2, out a2, out flag);
                    float num7 = info3.m_pavementWidth / info3.m_halfWidth * 0.5f;
                    num6 = (num6 + num7) * 0.5f;
                    y    = 2f * info.m_halfWidth / (info.m_halfWidth + info3.m_halfWidth);
                }
                float num8 = info.m_pavementWidth / info.m_halfWidth * 0.5f;
                float w    = 1f;
                if (num4 != 0)
                {
                    NetSegment netSegment4 = instance.m_segments.m_buffer[(int)num4];
                    NetInfo    info4       = netSegment4.Info;
                    start = (netSegment4.m_startNode == nodeID);
                    netSegment4.CalculateCorner(num4, true, start, true, out zero5, out zero7, out flag);
                    netSegment4.CalculateCorner(num4, true, start, false, out zero6, out zero8, out flag);
                    float num9 = info4.m_pavementWidth / info4.m_halfWidth * 0.5f;
                    num8 = (num8 + num9) * 0.5f;
                    w    = 2f * info.m_halfWidth / (info.m_halfWidth + info4.m_halfWidth);
                }
                Vector3 vector5;
                Vector3 vector6;
                NetSegment.CalculateMiddlePoints(zero, -zero3, vector, -a, true, true, out vector5, out vector6);
                Vector3 vector7;
                Vector3 vector8;
                NetSegment.CalculateMiddlePoints(zero2, -zero4, vector2, -a2, true, true, out vector7, out vector8);
                Vector3 vector9;
                Vector3 vector10;
                NetSegment.CalculateMiddlePoints(zero, -zero3, zero5, -zero7, true, true, out vector9, out vector10);
                Vector3 vector11;
                Vector3 vector12;
                NetSegment.CalculateMiddlePoints(zero2, -zero4, zero6, -zero8, true, true, out vector11, out vector12);

                data.m_dataMatrix0             = NetSegment.CalculateControlMatrix(zero, vector5, vector6, vector, zero, vector5, vector6, vector, thisNode.m_position, vScale);
                data.m_extraData.m_dataMatrix2 = NetSegment.CalculateControlMatrix(zero2, vector7, vector8, vector2, zero2, vector7, vector8, vector2, thisNode.m_position, vScale);
                data.m_extraData.m_dataMatrix3 = NetSegment.CalculateControlMatrix(zero, vector9, vector10, zero5, zero, vector9, vector10, zero5, thisNode.m_position, vScale);
                data.m_dataMatrix1             = NetSegment.CalculateControlMatrix(zero2, vector11, vector12, zero6, zero2, vector11, vector12, zero6, thisNode.m_position, vScale);
                data.m_dataVector0             = new Vector4(0.5f / info.m_halfWidth, 1f / info.m_segmentLength, 0.5f - info.m_pavementWidth / info.m_halfWidth * 0.5f, info.m_pavementWidth / info.m_halfWidth * 0.5f);
                data.m_dataVector1             = centerPos - data.m_position;

                if ((thisNode.m_flags & NetNode.Flags.Junction) == NetNode.Flags.None)
                {
                    data.m_dataVector1.w = (data.m_dataMatrix0.m33 + data.m_extraData.m_dataMatrix2.m33 + data.m_extraData.m_dataMatrix3.m33 + data.m_dataMatrix1.m33) * 0.25f;
                }
                else
                {
                    data.m_dataVector1.w = 0.01f;
                }

                data.m_dataVector2             = new Vector4(num6, y, num8, w);
                data.m_extraData.m_dataVector4 = RenderManager.GetColorLocation(65536u + (uint)nodeID);
            }
            else
            {
                centerPos.x = (zero.x + zero2.x) * 0.5f;
                centerPos.z = (zero.z + zero2.z) * 0.5f;
                vector      = zero2;
                vector2     = zero;
                a           = zero4;
                a2          = zero3;
                float   d        = Mathf.Min(info.m_halfWidth * 1.33333337f, 16f);
                Vector3 vector13 = zero - zero3 * d;
                Vector3 vector14 = vector - a * d;
                Vector3 vector15 = zero2 - zero4 * d;
                Vector3 vector16 = vector2 - a2 * d;
                Vector3 vector17 = zero + zero3 * d;
                Vector3 vector18 = vector + a * d;
                Vector3 vector19 = zero2 + zero4 * d;
                Vector3 vector20 = vector2 + a2 * d;
                data.m_dataMatrix0             = NetSegment.CalculateControlMatrix(zero, vector13, vector14, vector, zero, vector13, vector14, vector, thisNode.m_position, vScale);
                data.m_extraData.m_dataMatrix2 = NetSegment.CalculateControlMatrix(zero2, vector19, vector20, vector2, zero2, vector19, vector20, vector2, thisNode.m_position, vScale);
                data.m_extraData.m_dataMatrix3 = NetSegment.CalculateControlMatrix(zero, vector17, vector18, vector, zero, vector17, vector18, vector, thisNode.m_position, vScale);
                data.m_dataMatrix1             = NetSegment.CalculateControlMatrix(zero2, vector15, vector16, vector2, zero2, vector15, vector16, vector2, thisNode.m_position, vScale);
                data.m_dataMatrix0.SetRow(3, data.m_dataMatrix0.GetRow(3) + new Vector4(0.2f, 0.2f, 0.2f, 0.2f));
                data.m_extraData.m_dataMatrix2.SetRow(3, data.m_extraData.m_dataMatrix2.GetRow(3) + new Vector4(0.2f, 0.2f, 0.2f, 0.2f));
                data.m_extraData.m_dataMatrix3.SetRow(3, data.m_extraData.m_dataMatrix3.GetRow(3) + new Vector4(0.2f, 0.2f, 0.2f, 0.2f));
                data.m_dataMatrix1.SetRow(3, data.m_dataMatrix1.GetRow(3) + new Vector4(0.2f, 0.2f, 0.2f, 0.2f));
                data.m_dataVector0             = new Vector4(0.5f / info.m_halfWidth, 1f / info.m_segmentLength, 0.5f - info.m_pavementWidth / info.m_halfWidth * 0.5f, info.m_pavementWidth / info.m_halfWidth * 0.5f);
                data.m_dataVector1             = centerPos - data.m_position;
                data.m_dataVector1.w           = (data.m_dataMatrix0.m33 + data.m_extraData.m_dataMatrix2.m33 + data.m_extraData.m_dataMatrix3.m33 + data.m_dataMatrix1.m33) * 0.25f;
                data.m_dataVector2             = new Vector4(info.m_pavementWidth / info.m_halfWidth * 0.5f, 1f, info.m_pavementWidth / info.m_halfWidth * 0.5f, 1f);
                data.m_extraData.m_dataVector4 = RenderManager.GetColorLocation(65536u + (uint)nodeID);
            }
            data.m_dataInt0     = segmentIndex;
            data.m_dataColor0   = info.m_color;
            data.m_dataColor0.a = 0f;
            if (info.m_requireSurfaceMaps)
            {
                Singleton <TerrainManager> .instance.GetSurfaceMapping(data.m_position, out data.m_dataTexture0, out data.m_dataTexture1, out data.m_dataVector3);
            }
            instanceIndex = (uint)data.m_nextInstance;
        }
        private bool drawSignHandles(bool debug,
                                     ushort nodeId,
                                     ref NetNode node,
                                     bool viewOnly,
                                     bool handleClick,
                                     ref Vector3 camPos,
                                     out bool stateUpdated)
        {
            bool hovered = false;

            stateUpdated = false;

            if (viewOnly && !(Options.junctionRestrictionsOverlay || PrioritySignsTool.showMassEditOverlay) &&
                (MainTool.GetToolMode() != ToolMode.JunctionRestrictions))
            {
                return(false);
            }

            // NetManager netManager = Singleton<NetManager>.instance;
            Color   guiColor = GUI.color;
            Vector3 nodePos  = Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId].m_position;
            IExtSegmentEndManager segEndMan = Constants.ManagerFactory.ExtSegmentEndManager;

            for (int i = 0; i < 8; ++i)
            {
                ushort segmentId = node.GetSegment(i);

                if (segmentId == 0)
                {
                    continue;
                }

                bool startNode = (bool)Constants.ServiceFactory.NetService.IsStartNode(segmentId, nodeId);
                bool incoming  = segEndMan.ExtSegmentEnds[segEndMan.GetIndex(segmentId, startNode)].incoming;

                int numSignsPerRow = incoming ? 2 : 1;

                NetInfo segmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info;

                ItemClass connectionClass = segmentInfo.GetConnectionClass();

                if (connectionClass.m_service != ItemClass.Service.Road)
                {
                    continue; // only for road junctions
                }

                // draw all junction restriction signs
                Vector3 segmentCenterPos = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId]
                                           .m_bounds.center;
                Vector3 yu = (segmentCenterPos - nodePos).normalized;
                Vector3 xu = Vector3.Cross(yu, new Vector3(0, 1f, 0)).normalized;
                float   f  = viewOnly ? 6f : 7f; // reserved sign size in game coordinates

                Vector3 centerStart = nodePos + (yu * (viewOnly ? 5f : 14f));
                Vector3 zero        = centerStart - (0.5f * (numSignsPerRow - 1) * f * xu); // "top left"
                if (viewOnly)
                {
                    if (Constants.ServiceFactory.SimulationService.TrafficDrivesOnLeft)
                    {
                        zero -= xu * 8f;
                    }
                    else
                    {
                        zero += xu * 8f;
                    }
                }

                bool signHovered;
                int  x = 0;
                int  y = 0;
                bool hasSignInPrevRow = false;

                // draw "lane-changing when going straight allowed" sign at (0; 0)
                bool allowed =
                    JunctionRestrictionsManager.Instance.IsLaneChangingAllowedWhenGoingStraight(
                        segmentId,
                        startNode);

                bool configurable =
                    Constants.ManagerFactory.JunctionRestrictionsManager
                    .IsLaneChangingAllowedWhenGoingStraightConfigurable(
                        segmentId,
                        startNode,
                        ref node);

                if (debug ||
                    (configurable &&
                     (!viewOnly ||
                      (allowed != Constants.ManagerFactory
                       .JunctionRestrictionsManager
                       .GetDefaultLaneChangingAllowedWhenGoingStraight(
                           segmentId,
                           startNode,
                           ref node)))))
                {
                    DrawSign(
                        viewOnly,
                        !configurable,
                        ref camPos,
                        ref xu,
                        ref yu,
                        f,
                        ref zero,
                        x,
                        y,
                        guiColor,
                        allowed
                            ? JunctionUITextures.LaneChangeAllowedTexture2D
                            : JunctionUITextures.LaneChangeForbiddenTexture2D,
                        out signHovered);

                    if (signHovered && handleClick)
                    {
                        hovered = true;
                        if (MainTool.CheckClicked())
                        {
                            JunctionRestrictionsManager.Instance.ToggleLaneChangingAllowedWhenGoingStraight(
                                segmentId,
                                startNode);
                            stateUpdated = true;
                        }
                    }

                    ++x;
                    hasSignInPrevRow = true;
                }

                // draw "u-turns allowed" sign at (1; 0)
                allowed      = JunctionRestrictionsManager.Instance.IsUturnAllowed(segmentId, startNode);
                configurable =
                    Constants.ManagerFactory.JunctionRestrictionsManager.IsUturnAllowedConfigurable(
                        segmentId,
                        startNode,
                        ref node);
                if (debug ||
                    (configurable &&
                     (!viewOnly ||
                      (allowed != Constants.ManagerFactory
                       .JunctionRestrictionsManager
                       .GetDefaultUturnAllowed(
                           segmentId,
                           startNode,
                           ref node)))))
                {
                    DrawSign(
                        viewOnly,
                        !configurable,
                        ref camPos,
                        ref xu,
                        ref yu,
                        f,
                        ref zero,
                        x,
                        y,
                        guiColor,
                        allowed
                            ? JunctionUITextures.UturnAllowedTexture2D
                            : JunctionUITextures.UturnForbiddenTexture2D,
                        out signHovered);

                    if (signHovered && handleClick)
                    {
                        hovered = true;

                        if (MainTool.CheckClicked())
                        {
                            if (!JunctionRestrictionsManager.Instance.ToggleUturnAllowed(
                                    segmentId,
                                    startNode))
                            {
                                // TODO MainTool.ShowTooltip(Translation.GetString("..."), Singleton<NetManager>.instance.m_nodes.m_buffer[nodeId].m_position);
                            }
                            else
                            {
                                stateUpdated = true;
                            }
                        }
                    }

                    x++;
                    hasSignInPrevRow = true;
                }

                x = 0;
                if (hasSignInPrevRow)
                {
                    ++y;
                    hasSignInPrevRow = false;
                }

                // draw "entering blocked junctions allowed" sign at (0; 1)
                allowed = JunctionRestrictionsManager.Instance.IsEnteringBlockedJunctionAllowed(
                    segmentId,
                    startNode);
                configurable =
                    Constants.ManagerFactory.JunctionRestrictionsManager
                    .IsEnteringBlockedJunctionAllowedConfigurable(
                        segmentId,
                        startNode,
                        ref node);

                if (debug ||
                    (configurable &&
                     (!viewOnly ||
                      (allowed != Constants.ManagerFactory
                       .JunctionRestrictionsManager
                       .GetDefaultEnteringBlockedJunctionAllowed(
                           segmentId,
                           startNode,
                           ref node)))))
                {
                    DrawSign(
                        viewOnly,
                        !configurable,
                        ref camPos,
                        ref xu,
                        ref yu,
                        f,
                        ref zero,
                        x,
                        y,
                        guiColor,
                        allowed
                            ? JunctionUITextures.EnterBlockedJunctionAllowedTexture2D
                            : JunctionUITextures.EnterBlockedJunctionForbiddenTexture2D,
                        out signHovered);

                    if (signHovered && handleClick)
                    {
                        hovered = true;

                        if (MainTool.CheckClicked())
                        {
                            JunctionRestrictionsManager
                            .Instance
                            .ToggleEnteringBlockedJunctionAllowed(segmentId, startNode);
                            stateUpdated = true;
                        }
                    }

                    ++x;
                    hasSignInPrevRow = true;
                }

                // draw "pedestrian crossing allowed" sign at (1; 1)
                allowed = JunctionRestrictionsManager.Instance.IsPedestrianCrossingAllowed(
                    segmentId,
                    startNode);
                configurable =
                    Constants.ManagerFactory.JunctionRestrictionsManager
                    .IsPedestrianCrossingAllowedConfigurable(
                        segmentId,
                        startNode,
                        ref node);

                if (debug ||
                    (configurable &&
                     (!viewOnly || !allowed)))
                {
                    DrawSign(
                        viewOnly,
                        !configurable,
                        ref camPos,
                        ref xu,
                        ref yu,
                        f,
                        ref zero,
                        x,
                        y,
                        guiColor,
                        allowed
                            ? JunctionUITextures.PedestrianCrossingAllowedTexture2D
                            : JunctionUITextures.PedestrianCrossingForbiddenTexture2D,
                        out signHovered);

                    if (signHovered && handleClick)
                    {
                        hovered = true;

                        if (MainTool.CheckClicked())
                        {
                            JunctionRestrictionsManager.Instance.TogglePedestrianCrossingAllowed(segmentId, startNode);
                            stateUpdated = true;
                        }
                    }

                    x++;
                    hasSignInPrevRow = true;
                }

                x = 0;

                if (hasSignInPrevRow)
                {
                    ++y;
                    hasSignInPrevRow = false;
                }

                if (!Options.turnOnRedEnabled)
                {
                    continue;
                }

                //--------------------------------
                // TURN ON RED ENABLED
                //--------------------------------
                IJunctionRestrictionsManager junctionRestrictionsManager =
                    Constants.ManagerFactory.JunctionRestrictionsManager;
                bool lht = Constants.ServiceFactory.SimulationService.TrafficDrivesOnLeft;

                // draw "turn-left-on-red allowed" sign at (2; 0)
                allowed      = junctionRestrictionsManager.IsTurnOnRedAllowed(lht, segmentId, startNode);
                configurable = junctionRestrictionsManager.IsTurnOnRedAllowedConfigurable(
                    lht,
                    segmentId,
                    startNode,
                    ref node);

                if (debug ||
                    (configurable &&
                     (!viewOnly ||
                      (allowed != junctionRestrictionsManager
                       .GetDefaultTurnOnRedAllowed(
                           lht,
                           segmentId,
                           startNode,
                           ref node)))))
                {
                    DrawSign(
                        viewOnly,
                        !configurable,
                        ref camPos,
                        ref xu,
                        ref yu,
                        f,
                        ref zero,
                        x,
                        y,
                        guiColor,
                        allowed
                            ? JunctionUITextures.LeftOnRedAllowedTexture2D
                            : JunctionUITextures.LeftOnRedForbiddenTexture2D,
                        out signHovered);

                    if (signHovered && handleClick)
                    {
                        hovered = true;

                        if (MainTool.CheckClicked())
                        {
                            junctionRestrictionsManager.ToggleTurnOnRedAllowed(
                                lht,
                                segmentId,
                                startNode);
                            stateUpdated = true;
                        }
                    }

                    hasSignInPrevRow = true;
                }

                x++;

                // draw "turn-right-on-red allowed" sign at (2; 1)
                allowed = junctionRestrictionsManager.IsTurnOnRedAllowed(
                    !lht,
                    segmentId,
                    startNode);
                configurable = junctionRestrictionsManager.IsTurnOnRedAllowedConfigurable(
                    !lht,
                    segmentId,
                    startNode,
                    ref node);

                if (debug ||
                    (configurable &&
                     (!viewOnly ||
                      (allowed != junctionRestrictionsManager
                       .GetDefaultTurnOnRedAllowed(
                           !lht,
                           segmentId,
                           startNode,
                           ref node)))))
                {
                    DrawSign(
                        viewOnly,
                        !configurable,
                        ref camPos,
                        ref xu,
                        ref yu,
                        f,
                        ref zero,
                        x,
                        y,
                        guiColor,
                        allowed
                            ? JunctionUITextures.RightOnRedAllowedTexture2D
                            : JunctionUITextures.RightOnRedForbiddenTexture2D,
                        out signHovered);

                    if (signHovered && handleClick)
                    {
                        hovered = true;

                        if (MainTool.CheckClicked())
                        {
                            junctionRestrictionsManager.ToggleTurnOnRedAllowed(
                                !lht,
                                segmentId,
                                startNode);
                            stateUpdated = true;
                        }
                    }

                    hasSignInPrevRow = true;
                }
            }

            guiColor.a = 1f;
            GUI.color  = guiColor;

            return(hovered);
        }
Exemple #59
0
        public static void Setup22mMesh(this NetInfo info, NetInfoVersion version, LanesLayoutStyle lanesLayoutStyle = LanesLayoutStyle.Symmetrical)
        {
            ///////////////////////////
            // Template              //
            ///////////////////////////
            var highwayInfo        = Prefabs.Find <NetInfo>(NetInfos.Vanilla.HIGHWAY_3L);
            var defaultMaterial    = highwayInfo.m_nodes[0].m_material;
            var defaultLODMaterial = highwayInfo.m_nodes[0].m_lodMaterial;

            if (version == NetInfoVersion.Ground)
            {
                if (lanesLayoutStyle != LanesLayoutStyle.Symmetrical)
                {
                    var segment0 = info.m_segments[0].ShallowClone();
                    RoadHelper.HandleAsymSegmentFlags(segment0);
                    info.m_segments = new[] { segment0 };
                }
            }
            if (version == NetInfoVersion.Elevated || version == NetInfoVersion.Bridge)
            {
                if (lanesLayoutStyle != LanesLayoutStyle.Symmetrical)
                {
                    var segment0 = info.m_segments[0].ShallowClone();
                    RoadHelper.HandleAsymSegmentFlags(segment0);
                    var segments = info.m_segments.ToList();
                    segments[0]     = segment0;
                    info.m_segments = segments.ToArray();
                }
            }
            if (version == NetInfoVersion.Slope)
            {
                var segments0 = info.m_segments[0].ShallowClone();
                var segments1 = info.m_segments[1].ShallowClone();
                var segments2 = info.m_segments[1].ShallowClone();
                var nodes0    = info.m_nodes[0].ShallowClone();
                var nodes1    = info.m_nodes[1].ShallowClone();
                var nodes2    = info.m_nodes[0].ShallowClone();
                //var nodes1 = info.m_nodes[1].ShallowClone();
                segments1
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\22m\Slope.obj");

                segments2
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\22m\Slope_Cover.obj",
                    @"Roads\Common\Meshes\Blank.obj")
                .SetConsistentUVs();

                nodes2
                .SetFlags(NetNode.Flags.Underground, NetNode.Flags.None)
                .SetMeshes
                    (@"Roads\Highways\Common\Meshes\22m\Slope_U_Node.obj",
                    @"Roads\Highways\Common\Meshes\22m\Slope_U_Node_LOD.obj");
                //nodes1
                //    .SetFlags(NetNode.Flags.UndergroundTransition, NetNode.Flags.None)
                //    .SetMeshes
                //    (@"Roads\Highways\Common\Meshes\22m\Slope_U_Trans.obj",
                //    @"Roads\Highways\Common\Meshes\22m\Slope_U_Trans_LOD.obj");
                if (lanesLayoutStyle != LanesLayoutStyle.Symmetrical)
                {
                    RoadHelper.HandleAsymSegmentFlags(segments1);
                }
                nodes2.m_material    = defaultMaterial;
                nodes2.m_lodMaterial = defaultLODMaterial;
                //nodes1.m_material = defaultMaterial;
                //nodes1.m_lodMaterial = defaultLODMaterial;

                info.m_segments = new[] { segments0, segments1 };
                info.m_nodes    = new[] { nodes0, nodes1, nodes2 };
            }
            else if (version == NetInfoVersion.Tunnel)
            {
                var segments0 = info.m_segments[0].ShallowClone();
                var segments1 = info.m_segments[0].ShallowClone();
                var nodes0    = info.m_nodes[0].ShallowClone();
                var nodes1    = info.m_nodes[0].ShallowClone();
                var nodes2    = info.m_nodes[0].ShallowClone();

                nodes1.m_flagsForbidden = NetNode.Flags.None;
                nodes1.m_flagsRequired  = NetNode.Flags.None;

                segments1.SetMeshes
                    (@"Roads\Highways\Common\Meshes\22m\Tunnel.obj",
                    @"Roads\Highways\Common\Meshes\22m\Tunnel_LOD.obj");

                nodes1.SetMeshes
                    (@"Roads\Highways\Common\Meshes\22m\Tunnel_Node.obj",
                    @"Roads\Highways\Common\Meshes\22m\Tunnel_Node_LOD.obj");

                //nodes2.SetMeshes
                //    (@"Roads\Highways\Common\Meshes\22m\Tunnel_Trans.obj",
                //     @"Roads\Highways\Common\Meshes\22m\Tunnel_Trans_LOD.obj");

                if (lanesLayoutStyle != LanesLayoutStyle.Symmetrical)
                {
                    RoadHelper.HandleAsymSegmentFlags(segments1);
                }

                segments1.m_material    = defaultMaterial;
                segments1.m_lodMaterial = defaultLODMaterial;
                nodes1.m_material       = defaultMaterial;
                nodes1.m_lodMaterial    = defaultLODMaterial;

                info.m_segments = new[] { segments0, segments1 };
                info.m_nodes    = new[] { nodes0, nodes1, nodes2 };
            }
        }
        private static BuildingInfo.PathInfo ChainPath(BuildingInfo.PathInfo startPath, Vector3 endNode, int startNodeIndex = -1, NetInfo info = null)
        {
            var newNodes = new List <Vector3>();
            var newPath  = startPath.ShallowClone();

            if (startNodeIndex == -1 || startNodeIndex >= startPath.m_nodes.Count())
            {
                startNodeIndex = startPath.m_nodes.Count() - 1;
            }
            if (info != null)
            {
                newPath.AssignNetInfo(info);
            }
            var startNode = startPath.m_nodes[startNodeIndex];

            newNodes.Add(startNode);
            newNodes.Add(endNode);

            newPath.m_nodes = newNodes.ToArray();
            MarkPathGenerated(newPath);
            return(newPath);
        }