Inheritance: NetworkManager
        private static List<string> GetDistrictsForLine(TransportLine transportLine, NetManager theNetworkManager, DistrictManager theDistrictManager, out int stopCount)
        {
            var stop = TransportLine.GetPrevStop(transportLine.m_stops);
            var firstStop = stop;
            stopCount = 0;
            var districts = new List<string>();
            while (stop != 0)
            {
                stopCount++;
                var position = theNetworkManager.m_nodes.m_buffer[stop].m_position;
                var district = theDistrictManager.GetDistrict(position);
                if (district != 0)
                {
                    var districtName = theDistrictManager.GetDistrictName(district);
                    districtName = districtName.Trim();
                    if (districts.Contains(districtName) == false)
                        districts.Add(districtName);
                }
                else
                {
                    if (districts.Contains(string.Empty) == false)
                        districts.Add(string.Empty);
                }

                stop = TransportLine.GetNextStop(stop);
                if (stop == firstStop)
                    break;
            }
            return districts;
        }
        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;
        }
Example #3
0
	// Use this for initialization
	void Start () {

        //Create Directories if they don't exist
        if( !Directory.Exists("ServerData") )
        {
            Directory.CreateDirectory("ServerData");
        }

        if (!Directory.Exists("ServerData/Logins"))
        {
            Directory.CreateDirectory("ServerData/Logins");
        }

        if (!Directory.Exists("ServerData/Levels"))
        {
            Directory.CreateDirectory("ServerData/Levels");
        }

        //Create admin account
        tempCreateAccount();

        //Setup Canvases
        menuCanvas.gameObject.SetActive(false);
        loginCanvas.gameObject.SetActive(true);
        loginAlert.gameObject.SetActive(false);

        //Find NetworkManger script
        netManager = GameObject.Find("NetworkManager").GetComponent<NetManager>();
	}
        public static void ReleaseSegment(NetManager _this, ushort segmentID, bool keepNodes)
        {
            var segment = _this.m_segments.m_buffer[segmentID];

            int columnCount = 0;
            FindColumnCount(segment.m_blockEndLeft, ref columnCount);
            FindColumnCount(segment.m_blockEndRight, ref columnCount);
            FindColumnCount(segment.m_blockStartLeft, ref columnCount);
            FindColumnCount(segment.m_blockStartRight, ref columnCount);

            var caller = new System.Diagnostics.StackFrame(1).GetMethod().Name;

            //Debug.Log($"ReleaseSegment called by {caller}, id: {segmentID}, type: {segment.Info.name}");

            switch (caller)
            {
                case "MoveMiddleNode": // segment that was modified because user added network, keep data until replacement segments were created

                    // Save segment id
                    MoveMiddleNode_releasedColumnCount = columnCount;
                    break;

                case "SplitSegment": // segment that was split by new node, keep data until replacement segments were created

                    // Save segment id
                    SplitSegment_releasedColumnCount = columnCount;
                    break;

                default: // unknown caller
                    break;
            }

            // Call original method
            ReleaseSegmentRedirector.Revert();
            _this.ReleaseSegment(segmentID, keepNodes);
            ReleaseSegmentRedirector.Apply();
        }
 void OnDestroy()
 {
     if (instance == this)
     {
         instance = null;
     }
 }
Example #6
0
 private static bool isSegmentCreated(NetManager nMgr, ushort iSegmentIndex)
 {
     if ((nMgr.m_segments.m_buffer[iSegmentIndex].m_flags & NetSegment.Flags.Created) == NetSegment.Flags.Created)
     {
         return true;
     }
     return false;
 }
Example #7
0
		static Services()
		{
			NetManager = new NetManager();
			DeviceModelManager = new DeviceModelManager();
			DeviceManager = new DeviceManager();
		}
Example #8
0
        public void CustomCalculateSegmentPosition(ushort vehicleId,
                                                   ref Vehicle vehicleData,
                                                   PathUnit.Position nextNextPosition,
                                                   PathUnit.Position nextPosition,
                                                   uint nextLaneId,
                                                   byte nextOffset,
                                                   PathUnit.Position curPosition,
                                                   uint curLaneId,
                                                   byte curOffset,
                                                   int index,
                                                   out Vector3 pos,
                                                   out Vector3 dir,
                                                   out float maxSpeed)
        {
            NetManager netManager = Singleton <NetManager> .instance;
            ushort     nextSourceNodeId;
            ushort     nextTargetNodeId;

            NetSegment[] segmentsBuffer = netManager.m_segments.m_buffer;

            if (nextOffset < nextPosition.m_offset)
            {
                nextSourceNodeId = segmentsBuffer[nextPosition.m_segment].m_startNode;
                nextTargetNodeId = segmentsBuffer[nextPosition.m_segment].m_endNode;
            }
            else
            {
                nextSourceNodeId = segmentsBuffer[nextPosition.m_segment].m_endNode;
                nextTargetNodeId = segmentsBuffer[nextPosition.m_segment].m_startNode;
            }

            ushort curTargetNodeId;

            curTargetNodeId = curOffset == 0
                                  ? segmentsBuffer[curPosition.m_segment].m_startNode :
                              segmentsBuffer[curPosition.m_segment].m_endNode;

#if DEBUG
            bool logCalculation = DebugSwitch.CalculateSegmentPosition.Get() &&
                                  (DebugSettings.NodeId <= 0 ||
                                   curTargetNodeId == DebugSettings.NodeId) &&
                                  (GlobalConfig.Instance.Debug.ApiExtVehicleType == ExtVehicleType.None ||
                                   GlobalConfig.Instance.Debug.ApiExtVehicleType == ExtVehicleType.RoadVehicle) &&
                                  (DebugSettings.VehicleId == 0 ||
                                   DebugSettings.VehicleId == vehicleId);

            if (logCalculation)
            {
                Log._Debug($"CustomCarAI.CustomCalculateSegmentPosition({vehicleId}) called.\n" +
                           $"\tcurPosition.m_segment={curPosition.m_segment}, " +
                           $"curPosition.m_offset={curPosition.m_offset}\n" +
                           $"\tnextPosition.m_segment={nextPosition.m_segment}, " +
                           $"nextPosition.m_offset={nextPosition.m_offset}\n" +
                           $"\tnextNextPosition.m_segment={nextNextPosition.m_segment}, " +
                           $"nextNextPosition.m_offset={nextNextPosition.m_offset}\n" +
                           $"\tcurLaneId={curLaneId}, curOffset={curOffset}\n" +
                           $"\tnextLaneId={nextLaneId}, nextOffset={nextOffset}\n" +
                           $"\tnextSourceNodeId={nextSourceNodeId}, nextTargetNodeId={nextTargetNodeId}\n" +
                           $"\tcurTargetNodeId={curTargetNodeId}, curTargetNodeId={curTargetNodeId}\n" +
                           $"\tindex={index}");
            }
#endif

            Vehicle.Frame lastFrameData       = vehicleData.GetLastFrameData();
            Vector3       lastFrameVehiclePos = lastFrameData.m_position;
            float         sqrVelocity         = lastFrameData.m_velocity.sqrMagnitude;
            NetInfo       prevSegmentInfo     = segmentsBuffer[nextPosition.m_segment].Info;
            netManager.m_lanes.m_buffer[nextLaneId].CalculatePositionAndDirection(
                Constants.ByteToFloat(nextOffset), out pos, out dir);

            float braking = m_info.m_braking;
            if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0)
            {
                braking *= 2f;
            }

            // car position on the Bezier curve of the lane
            Vector3 refVehiclePosOnBezier = netManager.m_lanes.m_buffer[curLaneId].CalculatePosition(
                Constants.ByteToFloat(curOffset));

            // ushort currentSegmentId = netManager.m_lanes.m_buffer[prevLaneID].m_segment;
            // this seems to be like the required braking force in order to stop the vehicle within its half length.
            float crazyValue            = (0.5f * sqrVelocity / braking) + (m_info.m_generatedInfo.m_size.z * 0.5f);
            float d                     = Vector3.Distance(lastFrameVehiclePos, refVehiclePosOnBezier);
            bool  withinBrakingDistance = d >= crazyValue - 1f;

            if (nextSourceNodeId == curTargetNodeId &&
                withinBrakingDistance)
            {
                // NON-STOCK CODE START (stock code replaced)
                if (!VehicleBehaviorManager.Instance.MayChangeSegment(
                        vehicleId,
                        ref vehicleData,
                        sqrVelocity,
                        ref curPosition,
                        ref segmentsBuffer[curPosition.m_segment],
                        curTargetNodeId,
                        curLaneId,
                        ref nextPosition,
                        nextSourceNodeId,
                        ref netManager.m_nodes.m_buffer[nextSourceNodeId],
                        nextLaneId,
                        ref nextNextPosition,
                        nextTargetNodeId))
                {
                    // NON-STOCK CODE
                    maxSpeed = 0;
                    return;
                }

                ExtVehicleManager.Instance.UpdateVehiclePosition(
                    vehicleId, ref vehicleData /*, lastFrameData.m_velocity.magnitude*/);

                // NON-STOCK CODE END
            }

            if (prevSegmentInfo.m_lanes != null &&
                prevSegmentInfo.m_lanes.Length > nextPosition.m_lane)
            {
                // NON-STOCK CODE START
                float laneSpeedLimit = !Options.customSpeedLimitsEnabled
                                           ? prevSegmentInfo.m_lanes[nextPosition.m_lane].m_speedLimit
                                           : Constants.ManagerFactory.SpeedLimitManager.GetLockFreeGameSpeedLimit(
                    nextPosition.m_segment,
                    nextPosition.m_lane,
                    nextLaneId,
                    prevSegmentInfo.m_lanes[nextPosition.m_lane]);

                // NON-STOCK CODE END
                maxSpeed = CalculateTargetSpeed(
                    vehicleId,
                    ref vehicleData,
                    laneSpeedLimit,
                    netManager.m_lanes.m_buffer[nextLaneId].m_curve);
            }
            else
            {
                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f);
            }

            // NON-STOCK CODE START (stock code replaced)
            maxSpeed = Constants.ManagerFactory.VehicleBehaviorManager.CalcMaxSpeed(
                vehicleId,
                ref Constants.ManagerFactory.ExtVehicleManager.ExtVehicles[vehicleId],
                m_info,
                nextPosition,
                ref segmentsBuffer[nextPosition.m_segment],
                pos,
                maxSpeed,
                false);

            // NON-STOCK CODE END
        }
Example #9
0
        public static void drawCityMap()
        {
            TLMController controller = TLMController.instance;
            Dictionary <TransportInfo.TransportType, List <ushort> > linesByType = new Dictionary <TransportInfo.TransportType, List <ushort> >();

            linesByType[TransportInfo.TransportType.Metro] = new List <ushort>();
            linesByType[TransportInfo.TransportType.Train] = new List <ushort>();
            linesByType[TransportInfo.TransportType.Tram]  = new List <ushort>();
            linesByType[TransportInfo.TransportType.Ship]  = new List <ushort>();

            //			List<int> usedX = new List<int> ();
            //			List<int> usedY = new List<int> ();
            int nextStationId = 1;

            for (ushort lineId = 0; lineId < controller.tm.m_lines.m_size; lineId++)
            {
                TransportLine t = controller.tm.m_lines.m_buffer[(int)lineId];
                if (t.m_lineNumber > 0 && (t.Info.m_transportType == TransportInfo.TransportType.Metro ||
                                           t.Info.m_transportType == TransportInfo.TransportType.Train ||
                                           t.Info.m_transportType == TransportInfo.TransportType.Tram ||
                                           t.Info.m_transportType == TransportInfo.TransportType.Ship))
                {
                    switch (t.Info.m_transportType)
                    {
                    case TransportInfo.TransportType.Ship:
                    case TransportInfo.TransportType.Train:
                    case TransportInfo.TransportType.Metro:
                    case TransportInfo.TransportType.Tram:
                        linesByType[t.Info.m_transportType].Add(lineId);
                        break;
                    }
                }
            }

            CalculateCoords calc         = TLMLineUtils.gridPosition81Tiles;
            NetManager      nm           = NetManager.instance;
            float           invPrecision = 32;
            //Restart:
            Dictionary <int, List <int> > positions = new Dictionary <int, List <int> >();
            List <Station> stations = new List <Station>();
            Dictionary <Segment2, Color32>        svgLines       = new Dictionary <Segment2, Color32>();
            Dictionary <ushort, MapTransportLine> transportLines = new Dictionary <ushort, MapTransportLine>();

            foreach (TransportInfo.TransportType tt in new TransportInfo.TransportType[] { TransportInfo.TransportType.Ship, TransportInfo.TransportType.Train, TransportInfo.TransportType.Metro, TransportInfo.TransportType.Tram })
            {
                foreach (ushort lineId in linesByType[tt])
                {
                    TransportLine t     = controller.tm.m_lines.m_buffer[(int)lineId];
                    float         range = 75f;
                    switch (tt)
                    {
                    case TransportInfo.TransportType.Ship:
                        range = 150f;
                        break;

                    case TransportInfo.TransportType.Metro:
                    case TransportInfo.TransportType.Train:
                        range = 100f;
                        break;
                    }


                    int stopsCount = t.CountStops(lineId);
                    if (stopsCount == 0)
                    {
                        continue;
                    }
                    Color   color = t.m_color;
                    Vector2 ultPos = Vector2.zero;
                    bool    day, night;
                    t.GetActive(out day, out night);
                    transportLines[lineId] = new MapTransportLine(color, day, night, lineId);
                    int startStop = 0;
                    int finalStop = stopsCount;

                    for (int j = startStop; j < finalStop; j++)
                    {
                        //						Debug.Log ("ULT POS:" + ultPos);
                        ushort               nextStop = t.GetStop(j % stopsCount);
                        ItemClass.Service    service;
                        ItemClass.SubService nil2;
                        string               prefix;
                        ushort               buildingId;
                        string               name = TLMUtils.getStationName(nextStop, lineId, t.Info.m_stationSubService, out service, out nil2, out prefix, out buildingId);

                        Vector3 worldPos = TLMUtils.getStationBuildingPosition(nextStop, t.Info.m_stationSubService);
                        Vector2 pos2D    = calc(worldPos, invPrecision);
                        Vector2 gridAdd  = Vector2.zero;


                        var idx = stations.FirstOrDefault(x => x.stops.Contains(nextStop) || x.centralPos == pos2D);
                        if (idx != null)
                        {
                            transportLines[lineId].addStation(ref idx);
                        }
                        else
                        {
                            //if (positions.containskey((int)pos2d.x) && positions[(int)pos2d.x].contains((int)pos2d.y))
                            //{
                            //    float exp = (float)(math.log(invprecision) / math.log(2)) - 1;
                            //    invprecision = (float)math.pow(2, exp);
                            //    goto restart;
                            //}
                            List <ushort> nearStops = new List <ushort>();
                            TLMLineUtils.GetNearStopPoints(worldPos, range, ref nearStops, new ItemClass.SubService[] { ItemClass.SubService.PublicTransportShip }, 10);
                            TLMLineUtils.GetNearStopPoints(worldPos, range, ref nearStops, new ItemClass.SubService[] { ItemClass.SubService.PublicTransportTrain, ItemClass.SubService.PublicTransportMetro }, 10);
                            TLMLineUtils.GetNearStopPoints(worldPos, range, ref nearStops, new ItemClass.SubService[] { ItemClass.SubService.PublicTransportTram }, 10);
                            TLMUtils.doLog("Station: ${0}; nearStops: ${1}", name, string.Join(",", nearStops.Select(x => x.ToString()).ToArray()));
                            Station thisStation = new Station(name, pos2D, nearStops, nextStationId++, service, nextStop);
                            stations.Add(thisStation);
                            transportLines[lineId].addStation(ref thisStation);
                        }
                        if (!positions.ContainsKey((int)pos2D.x))
                        {
                            positions[(int)pos2D.x] = new List <int>();
                        }
                        positions[(int)pos2D.x].Add((int)pos2D.y);
                        //						Debug.Log ("POS:" + pos);
                        ultPos = pos2D;
                    }
                }
            }
            printToSVG(stations, transportLines, Singleton <SimulationManager> .instance.m_metaData.m_CityName + "_" + Singleton <SimulationManager> .instance.m_currentGameTime.ToString("yyyy.MM.dd"));
        }
        //加入好友功能(包括好友、临时好友、黑名单)
        public void addFriend(RELATION_GROUP nGroup, string name)
        {
            string            strva    = name;
            CGRelation        Msg      = new CGRelation();
            CObject_Character pCharObj = null;

            Msg.GetRelation().m_Type = (byte)RELATION_REQUEST_TYPE.REQ_ADDFRIEND;
            REQUEST_ADD_RELATION_WITH_GROUP pFriend = new REQUEST_ADD_RELATION_WITH_GROUP();

            Msg.GetRelation().mRelation = pFriend;
            pFriend.CleanUp();

            bool valueIsNum = false;                                /*Ogre::StringConverter::isNumber(strva.c_str());*/

            if (nGroup == RELATION_GROUP.RELATION_GROUP_FRIEND_ALL) // 如果直接一个名字,就自动往所有的列表里加,
            {
                nGroup = RELATION_GROUP.RELATION_GROUP_F1;
            }
            else if (nGroup == RELATION_GROUP.RELATION_GROUP_TEMPFRIEND) //临时好友
            {
                SDATA_RELATION_MEMBER pMember = new SDATA_RELATION_MEMBER();

                if (!valueIsNum)
                {
                    pCharObj = (CObject_Character)CObjectManager.Instance.FindCharacterByName(strva);
                    if (pCharObj == null)
                    {
                        return;
                    }
                    pMember.m_szName = strva;
                }
                else
                {
                    pCharObj = (CObject_Character)CObjectManager.Instance.GetMainTarget();
                    if (pCharObj == null)
                    {
                        return;
                    }
                    pMember.m_szName = pCharObj.GetCharacterData().Get_Name();
                }
                // 如果是玩家并且是统一阵营的才会添加
                ENUM_RELATION sCamp = Interface.GameInterface.Instance.GetCampType(pCharObj, CObjectManager.Instance.getPlayerMySelf());
                if ((pCharObj is CObject_PlayerOther) == false)
                {
                    return;
                }
                if (sCamp != ENUM_RELATION.RELATION_FRIEND)
                {
                    return;
                }

                int nTmpGroup = -1, nIndex = -1;
                CDataPool.Instance.GetRelation().GetRelationByName(pMember.m_szName, ref nTmpGroup, ref nIndex);
                if (nTmpGroup >= 0)
                {
                    return;
                }

                pMember.m_RelationType = RELATION_TYPE.RELATION_TYPE_TEMPFRIEND;
                if (CDataPool.Instance.GetRelation().AddRelation(RELATION_GROUP.RELATION_GROUP_TEMPFRIEND, pMember))
                {
                    string szText = "你将" + pMember.m_szName + " 添加为临时好友";
                    GameProcedure.s_pEventSystem.PushEvent(GAME_EVENT_ID.GE_INFO_SELF, szText);
                }
                CEventSystem.Instance.PushEvent(GAME_EVENT_ID.GE_UPDATE_FRIEND);
                return;
            }
            else if (nGroup == RELATION_GROUP.RELATION_GROUP_BLACK)
            { // 增加黑名单的添加
                CGRelation Msg1                 = new CGRelation();
                Msg1.GetRelation().m_Type       = (byte)RELATION_REQUEST_TYPE.REQ_ADDTOBLACKLIST;
                REQUEST_ADD_RELATION pBlackName = new REQUEST_ADD_RELATION();
                Msg1.GetRelation().mRelation    = pBlackName;
                pBlackName.CleanUp();

                if (strva == "")
                {
                    pCharObj = (CObject_Character)CObjectManager.Instance.GetMainTarget();
                    if (pCharObj == null)
                    {
                        return;
                    }
                    pBlackName.SetTargetName(EncodeUtility.Instance.GetGbBytes(pCharObj.GetCharacterData().Get_Name()));
                }
                else if (valueIsNum)
                {
//                      pCharObj = (CObject_Character)CObjectManager.Instance.FindCharacterByRaceID(int.Parse(strva));
//                      if( pCharObj == null ) pCharObj = (CObject_Character*)CObjectManager::GetMe()->FindCharacterByName(strva.c_str());
//                      if( pCharObj == null ) return ;
//                      pBlackName->SetTargetGUID( Ogre::StringConverter::parseInt(strva.c_str()) );
                }
                else
                {
                    pCharObj = (CObject_Character)CObjectManager.Instance.FindCharacterByName(strva);
                    if (pCharObj == null)
                    {
                        return;
                    }
                    pBlackName.SetTargetName(EncodeUtility.Instance.GetGbBytes(strva));
                }

                if (pCharObj == CObjectManager.Instance.getPlayerMySelf())
                {
                    return;
                }

                if (pCharObj is CObject_PlayerOther)        // 如果是玩家
                {
                    ENUM_RELATION sCamp = Interface.GameInterface.Instance.GetCampType(pCharObj, CObjectManager.Instance.getPlayerMySelf());
                    if (sCamp != ENUM_RELATION.RELATION_FRIEND)
                    {
                        GameProcedure.s_pEventSystem.PushEvent(GAME_EVENT_ID.GE_INFO_SELF, "不能添加不同阵营的人到黑名单");
                        return;
                    }
                }
                else
                {
                    GameProcedure.s_pEventSystem.PushEvent(GAME_EVENT_ID.GE_INFO_SELF, "不能添加非玩家到黑名单");
                    return;
                }

                pBlackName.SetRelationType((byte)RELATION_TYPE.RELATION_TYPE_BLACKNAME);
                NetManager.GetNetManager().SendPacket(Msg1);
                return;
            }

            if (strva == "")
            {
                pCharObj = (CObject_Character)CObjectManager.Instance.GetMainTarget();
                if (pCharObj == null)
                {
                    return;
                }
                pFriend.SetTargetName(EncodeUtility.Instance.GetGbBytes(pCharObj.GetCharacterData().Get_Name()));
            }
            else if (valueIsNum)
            {
//              pCharObj = (CObject_Character)CObjectManager::GetMe()->FindCharacterByRaceID(Ogre::StringConverter::parseInt(strva.c_str()));
//              if( pCharObj == NULL ) pCharObj = (CObject_Character*)CObjectManager::GetMe()->FindCharacterByName(strva.c_str());
//              if( pCharObj == NULL ) return 0;
//              pFriend->SetTargetGUID( Ogre::StringConverter::parseInt(strva.c_str()) );
            }
            else
            {
                pFriend.SetTargetName(EncodeUtility.Instance.GetGbBytes(strva));
                pCharObj = (CObject_Character)CObjectManager.Instance.FindCharacterByName(strva);
                if (pCharObj == null)
                {
                    return;
                }
            }
            if (pCharObj == CObjectManager.Instance.getPlayerMySelf())      // 如果是自己,就不加
            {
                return;
            }

            if (pCharObj is CObject_PlayerOther)       // 如果是玩家
            {
                ENUM_RELATION sCamp = Interface.GameInterface.Instance.GetCampType(pCharObj, CObjectManager.Instance.getPlayerMySelf());
                if (sCamp != ENUM_RELATION.RELATION_FRIEND)             // 如果不是同一阵营的
                {
                    GameProcedure.s_pEventSystem.PushEvent(GAME_EVENT_ID.GE_INFO_SELF, "不能添加不同阵营的人到好友");
                    return;
                }
//              // 改为势力判断 [9/26/2011 Ivan edit]
//              if (pCharObj.GetCharacterData().GetShiLi() !=
//                  CObjectManager::GetMe()->GetMySelf()->GetCharacterData()->GetShiLi())
//              {
//                  CGameProcedure::s_pEventSystem->PushEvent( GE_INFO_SELF, "不能添加不同势力的人到好友" );
//                  return 0;
//              }
            }
            else
            {
                GameProcedure.s_pEventSystem.PushEvent(GAME_EVENT_ID.GE_INFO_SELF, "不能添加非玩家到好友");
                return;
            }

            pFriend.SetGroup((byte)nGroup);
            pFriend.SetRelationType((byte)RELATION_TYPE.RELATION_TYPE_FRIEND);

            NetManager.GetNetManager().SendPacket(Msg);

            return;
        }
        private bool drawSignHandles(ushort nodeId, bool viewOnly, bool handleClick, ref Vector3 camPos, out bool stateUpdated)
        {
            bool hovered = false;

            stateUpdated = false;

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

            NetManager netManager = Singleton <NetManager> .instance;
            var        guiColor   = GUI.color;

            Vector3 nodePos = Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId].m_position;

            for (int i = 0; i < 8; ++i)
            {
                ushort segmentId = netManager.m_nodes.m_buffer[nodeId].GetSegment(i);
                if (segmentId == 0)
                {
                    continue;
                }

                SegmentGeometry geometry = SegmentGeometry.Get(segmentId);
                if (geometry == null)
                {
                    Log.Error($"JunctionRestrictionsTool.drawSignHandles: No geometry information available for segment {segmentId}");
                    continue;
                }
                bool startNode = geometry.StartNodeId() == nodeId;
                bool incoming  = geometry.IsIncoming(startNode);

                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 * (float)(numSignsPerRow - 1) * f * xu;        // "top left"
                if (viewOnly)
                {
                    if (Constants.ServiceFactory.SimulationService.LeftHandDrive)
                    {
                        zero -= xu * 8f;
                    }
                    else
                    {
                        zero += xu * 8f;
                    }
                }

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

                // draw "lane-changing when going straight allowed" sign at (0; 0)
                bool allowed = JunctionRestrictionsManager.Instance.IsLaneChangingAllowedWhenGoingStraight(segmentId, startNode);
                if (incoming && (!viewOnly || allowed != Options.allowLaneChangesWhileGoingStraight))
                {
                    DrawSign(viewOnly, ref camPos, ref xu, ref yu, f, ref zero, x, y, ref guiColor, allowed ? TextureResources.LaneChangeAllowedTexture2D : TextureResources.LaneChangeForbiddenTexture2D, out signHovered);
                    if (signHovered && handleClick)
                    {
                        hovered = true;
                        if (MainTool.CheckClicked())
                        {
                            JunctionRestrictionsManager.Instance.ToggleLaneChangingAllowedWhenGoingStraight(segmentId, startNode);
                            stateUpdated = true;
                        }
                    }

                    if (viewOnly)
                    {
                        ++y;
                    }
                    else
                    {
                        ++x;
                    }
                }

                // draw "u-turns allowed" sign at (1; 0)
                allowed = JunctionRestrictionsManager.Instance.IsUturnAllowed(segmentId, startNode);
                if (incoming && (!viewOnly || allowed != Options.allowUTurns))
                {
                    DrawSign(viewOnly, ref camPos, ref xu, ref yu, f, ref zero, x, y, ref guiColor, allowed ? TextureResources.UturnAllowedTexture2D : TextureResources.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;
                            }
                        }
                    }

                    ++y;
                    x = 0;
                }

                // draw "entering blocked junctions allowed" sign at (0; 1)
                allowed = JunctionRestrictionsManager.Instance.IsEnteringBlockedJunctionAllowed(segmentId, startNode);
                if (incoming && (!viewOnly || allowed != Options.allowEnterBlockedJunctions))
                {
                    DrawSign(viewOnly, ref camPos, ref xu, ref yu, f, ref zero, x, y, ref guiColor, allowed ? TextureResources.EnterBlockedJunctionAllowedTexture2D : TextureResources.EnterBlockedJunctionForbiddenTexture2D, out signHovered);
                    if (signHovered && handleClick)
                    {
                        hovered = true;

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

                    if (viewOnly)
                    {
                        ++y;
                    }
                    else
                    {
                        ++x;
                    }
                }

                // draw "pedestrian crossing allowed" sign at (1; 1)
                allowed = JunctionRestrictionsManager.Instance.IsPedestrianCrossingAllowed(segmentId, startNode);
                if (!viewOnly || !allowed)
                {
                    DrawSign(viewOnly, ref camPos, ref xu, ref yu, f, ref zero, x, y, ref guiColor, allowed ? TextureResources.PedestrianCrossingAllowedTexture2D : TextureResources.PedestrianCrossingForbiddenTexture2D, out signHovered);
                    if (signHovered && handleClick)
                    {
                        hovered = true;

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

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

            return(hovered);
        }
        public bool FindPathPositionWithSpiralLoop(Vector3 position,
                                                   Vector3?secondaryPosition,
                                                   ItemClass.Service service,
                                                   NetInfo.LaneType laneType,
                                                   VehicleInfo.VehicleType vehicleType,
                                                   NetInfo.LaneType otherLaneType,
                                                   VehicleInfo.VehicleType otherVehicleType,
                                                   VehicleInfo.VehicleType stopType,
                                                   bool allowUnderground,
                                                   bool requireConnect,
                                                   float maxDistance,
                                                   out PathUnit.Position pathPosA,
                                                   out PathUnit.Position pathPosB,
                                                   out float distanceSqrA,
                                                   out float distanceSqrB)
        {
            int iMin = Mathf.Max(
                (int)(((position.z - NetManager.NODEGRID_CELL_SIZE) / NetManager.NODEGRID_CELL_SIZE) +
                      (NetManager.NODEGRID_RESOLUTION / 2f)),
                0);
            int iMax = Mathf.Min(
                (int)(((position.z + NetManager.NODEGRID_CELL_SIZE) / NetManager.NODEGRID_CELL_SIZE) +
                      (NetManager.NODEGRID_RESOLUTION / 2f)),
                NetManager.NODEGRID_RESOLUTION - 1);

            int jMin = Mathf.Max(
                (int)(((position.x - NetManager.NODEGRID_CELL_SIZE) / NetManager.NODEGRID_CELL_SIZE) +
                      (NetManager.NODEGRID_RESOLUTION / 2f)),
                0);
            int jMax = Mathf.Min(
                (int)(((position.x + NetManager.NODEGRID_CELL_SIZE) / NetManager.NODEGRID_CELL_SIZE) +
                      (NetManager.NODEGRID_RESOLUTION / 2f)),
                NetManager.NODEGRID_RESOLUTION - 1);

            int width  = iMax - iMin + 1;
            int height = jMax - jMin + 1;

            int centerI = (int)(position.z / NetManager.NODEGRID_CELL_SIZE +
                                NetManager.NODEGRID_RESOLUTION / 2f);
            int centerJ = (int)(position.x / NetManager.NODEGRID_CELL_SIZE +
                                NetManager.NODEGRID_RESOLUTION / 2f);

            NetManager netManager = Singleton <NetManager> .instance;

            /*pathPosA.m_segment = 0;
             * pathPosA.m_lane = 0;
             * pathPosA.m_offset = 0;*/
            distanceSqrA = 1E+10f;

            /*pathPosB.m_segment = 0;
             * pathPosB.m_lane = 0;
             * pathPosB.m_offset = 0;*/
            distanceSqrB = 1E+10f;
            float minDist = float.MaxValue;

            PathUnit.Position myPathPosA     = default;
            float             myDistanceSqrA = float.MaxValue;

            PathUnit.Position myPathPosB     = default;
            float             myDistanceSqrB = float.MaxValue;

            int  lastSpiralDist = 0;
            bool found          = false;

            bool FindHelper(int i, int j)
            {
                if (i < 0 || i >= NetManager.NODEGRID_RESOLUTION ||
                    j < 0 || j >= NetManager.NODEGRID_RESOLUTION)
                {
                    return(true);
                }

                int spiralDist = Math.Max(Math.Abs(i - centerI), Math.Abs(j - centerJ)); // maximum norm

                if (found && spiralDist > lastSpiralDist)
                {
                    // last iteration
                    return(false);
                }

                ushort segmentId  = netManager.m_segmentGrid[i * NetManager.NODEGRID_RESOLUTION + j];
                int    iterations = 0;

                while (segmentId != 0)
                {
                    NetInfo segmentInfo = netManager.m_segments.m_buffer[segmentId].Info;

                    if (segmentInfo != null && segmentInfo.m_class.m_service == service &&
                        (netManager.m_segments.m_buffer[segmentId].m_flags &
                         (NetSegment.Flags.Collapsed | NetSegment.Flags.Flooded)) ==
                        NetSegment.Flags.None &&
                        (allowUnderground || !segmentInfo.m_netAI.IsUnderground()))
                    {
                        bool otherPassed = true;
                        if (otherLaneType != NetInfo.LaneType.None ||
                            otherVehicleType != VehicleInfo.VehicleType.None)
                        {
                            // check if any lane is present that matches the given conditions
                            otherPassed = false;
                            Constants.ServiceFactory.NetService.IterateSegmentLanes(
                                segmentId,
                                (uint laneId,
                                 ref NetLane lane,
                                 NetInfo.Lane laneInfo,
                                 ushort segtId,
                                 ref NetSegment segment,
                                 byte laneIndex) => {
                                if ((otherLaneType == NetInfo.LaneType.None ||
                                     (laneInfo.m_laneType & otherLaneType) !=
                                     NetInfo.LaneType.None) &&
                                    (otherVehicleType ==
                                     VehicleInfo.VehicleType.None ||
                                     (laneInfo.m_vehicleType & otherVehicleType) !=
                                     VehicleInfo.VehicleType.None))
                                {
                                    otherPassed = true;
                                    return(false);
                                }

                                return(true);
                            });
                        }

                        if (otherPassed)
                        {
                            if (netManager.m_segments.m_buffer[segmentId].GetClosestLanePosition(
                                    position,
                                    laneType,
                                    vehicleType,
                                    stopType,
                                    requireConnect,
                                    out Vector3 posA,
                                    out int laneIndexA,
                                    out float laneOffsetA,
                                    out Vector3 posB,
                                    out int laneIndexB,
                                    out float laneOffsetB))
                            {
                                float dist = Vector3.SqrMagnitude(position - posA);
                                if (secondaryPosition != null)
                                {
                                    dist += Vector3.SqrMagnitude((Vector3)secondaryPosition - posA);
                                }

                                if (dist < minDist)
                                {
                                    found = true;

                                    minDist = dist;
                                    myPathPosA.m_segment = segmentId;
                                    myPathPosA.m_lane    = (byte)laneIndexA;
                                    myPathPosA.m_offset  = (byte)Mathf.Clamp(
                                        Mathf.RoundToInt(laneOffsetA * 255f),
                                        0,
                                        255);
                                    myDistanceSqrA = dist;

                                    dist = Vector3.SqrMagnitude(position - posB);
                                    if (secondaryPosition != null)
                                    {
                                        dist += Vector3.SqrMagnitude(
                                            (Vector3)secondaryPosition - posB);
                                    }

                                    if (laneIndexB < 0)
                                    {
                                        myPathPosB.m_segment = 0;
                                        myPathPosB.m_lane    = 0;
                                        myPathPosB.m_offset  = 0;
                                        myDistanceSqrB       = float.MaxValue;
                                    }
                                    else
                                    {
                                        myPathPosB.m_segment = segmentId;
                                        myPathPosB.m_lane    = (byte)laneIndexB;
                                        myPathPosB.m_offset  = (byte)Mathf.Clamp(
                                            Mathf.RoundToInt(laneOffsetB * 255f),
                                            0,
                                            255);
                                        myDistanceSqrB = dist;
                                    }
                                }
                            } // if GetClosestLanePosition
                        }     // if othersPassed
                    }         // if

                    segmentId = netManager.m_segments.m_buffer[segmentId].m_nextGridSegment;
                    if (++iterations >= NetManager.MAX_SEGMENT_COUNT)
                    {
                        CODebugBase <LogChannel> .Error(
                            LogChannel.Core,
                            "Invalid list detected!\n" + Environment.StackTrace);

                        break;
                    }
                }

                lastSpiralDist = spiralDist;
                return(true);
            }

            LoopUtil.SpiralLoop(centerI, centerJ, width, height, FindHelper);

            pathPosA     = myPathPosA;
            distanceSqrA = myDistanceSqrA;
            pathPosB     = myPathPosB;
            distanceSqrB = myDistanceSqrB;

            return(pathPosA.m_segment != 0);
        }
 void Awake()
 {
     mInstance = this;
 }
Example #14
0
 public UserViewer(NetManager mgr) : base(mgr)
 {
 }
Example #15
0
        public void CalculateSegmentPosition(ushort vehicleID, ref Vehicle vehicleData, PathUnit.Position nextPosition,
                                             PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID,
                                             byte prevOffset, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            NetManager instance = Singleton <NetManager> .instance;

            instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection((float)offset * 0.003921569f, out pos, out dir);
            Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();
            Vector3       position2     = lastFrameData.m_position;
            Vector3       b             = instance.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].CalculatePosition((float)prevOffset * 0.003921569f);
            float         num           = 0.5f * lastFrameData.m_velocity.sqrMagnitude / this.m_info.m_braking + this.m_info.m_generatedInfo.m_size.z * 0.5f;

            if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Car)
            {
                if (!TrafficPriority.vehicleList.ContainsKey(vehicleID))
                {
                    TrafficPriority.vehicleList.Add(vehicleID, new PriorityCar());
                }
            }

            if (Vector3.Distance(position2, b) >= num - 1f)
            {
                Segment3 segment;
                segment.a = pos;
                ushort num2;
                ushort num3;
                if (offset < position.m_offset)
                {
                    segment.b = pos + dir.normalized * this.m_info.m_generatedInfo.m_size.z;
                    num2      = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode;
                    num3      = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode;
                }
                else
                {
                    segment.b = pos - dir.normalized * this.m_info.m_generatedInfo.m_size.z;
                    num2      = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode;
                    num3      = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode;
                }
                ushort num4;
                if (prevOffset == 0)
                {
                    num4 = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_startNode;
                }
                else
                {
                    num4 = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_endNode;
                }

                if (num2 == num4)
                {
                    uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                    uint num5 = (uint)(((int)num4 << 8) / 32768);
                    uint num6 = currentFrameIndex - num5 & 255u;

                    NetNode.Flags flags  = instance.m_nodes.m_buffer[(int)num2].m_flags;
                    NetLane.Flags flags2 =
                        (NetLane.Flags)instance.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_flags;
                    bool flag  = (flags & NetNode.Flags.TrafficLights) != NetNode.Flags.None;
                    bool flag2 = (flags & NetNode.Flags.LevelCrossing) != NetNode.Flags.None;
                    bool flag3 = (flags2 & NetLane.Flags.JoinedJunction) != NetLane.Flags.None;
                    if ((flags & (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) ==
                        NetNode.Flags.Junction && instance.m_nodes.m_buffer[(int)num2].CountSegments() != 2)
                    {
                        float len = vehicleData.CalculateTotalLength(vehicleID) + 2f;
                        if (!instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(len))
                        {
                            bool flag4 = false;
                            if (nextPosition.m_segment != 0 &&
                                instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_length < 30f)
                            {
                                NetNode.Flags flags3 = instance.m_nodes.m_buffer[(int)num3].m_flags;
                                if ((flags3 &
                                     (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) !=
                                    NetNode.Flags.Junction || instance.m_nodes.m_buffer[(int)num3].CountSegments() == 2)
                                {
                                    uint laneID2 = PathManager.GetLaneID(nextPosition);
                                    if (laneID2 != 0u)
                                    {
                                        flag4 = instance.m_lanes.m_buffer[(int)((UIntPtr)laneID2)].CheckSpace(len);
                                    }
                                }
                            }
                            if (!flag4)
                            {
                                maxSpeed = 0f;
                                return;
                            }
                        }
                    }

                    if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Car &&
                        TrafficPriority.vehicleList.ContainsKey(vehicleID) &&
                        TrafficPriority.isPrioritySegment(num2, prevPos.m_segment))
                    {
                        uint currentFrameIndex2 = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                        uint frame = currentFrameIndex2 >> 4;

                        var prioritySegment = TrafficPriority.getPrioritySegment(num2, prevPos.m_segment);
                        if (TrafficPriority.vehicleList[vehicleID].toNode != num2 ||
                            TrafficPriority.vehicleList[vehicleID].fromSegment != prevPos.m_segment)
                        {
                            if (TrafficPriority.vehicleList[vehicleID].toNode != 0 &&
                                TrafficPriority.vehicleList[vehicleID].fromSegment != 0)
                            {
                                var oldNode    = TrafficPriority.vehicleList[vehicleID].toNode;
                                var oldSegment = TrafficPriority.vehicleList[vehicleID].fromSegment;

                                if (TrafficPriority.isPrioritySegment(oldNode, oldSegment))
                                {
                                    var oldPrioritySegment = TrafficPriority.getPrioritySegment(oldNode, oldSegment);
                                    TrafficPriority.vehicleList[vehicleID].waitTime = 0;
                                    TrafficPriority.vehicleList[vehicleID].stopped  = false;
                                    oldPrioritySegment.RemoveCar(vehicleID);
                                }
                            }

                            // prevPos - current segment
                            // position - next segment
                            TrafficPriority.vehicleList[vehicleID].toNode        = num2;
                            TrafficPriority.vehicleList[vehicleID].fromSegment   = prevPos.m_segment;
                            TrafficPriority.vehicleList[vehicleID].toSegment     = position.m_segment;
                            TrafficPriority.vehicleList[vehicleID].toLaneID      = PathManager.GetLaneID(position);
                            TrafficPriority.vehicleList[vehicleID].fromLaneID    = PathManager.GetLaneID(prevPos);
                            TrafficPriority.vehicleList[vehicleID].fromLaneFlags =
                                instance.m_lanes.m_buffer[PathManager.GetLaneID(prevPos)].m_flags;
                            TrafficPriority.vehicleList[vehicleID].yieldSpeedReduce = UnityEngine.Random.Range(13f,
                                                                                                               18f);

                            prioritySegment.AddCar(vehicleID);
                        }

                        TrafficPriority.vehicleList[vehicleID].lastFrame = frame;
                        TrafficPriority.vehicleList[vehicleID].lastSpeed =
                            vehicleData.GetLastFrameData().m_velocity.sqrMagnitude;
                    }

                    if (flag && (!flag3 || flag2))
                    {
                        var nodeSimulation = CustomRoadAI.GetNodeSimulation(num4);

                        NetInfo info = instance.m_nodes.m_buffer[(int)num2].Info;
                        RoadBaseAI.TrafficLightState vehicleLightState;
                        RoadBaseAI.TrafficLightState pedestrianLightState;
                        bool flag5;
                        bool pedestrians;

                        if (nodeSimulation == null || (nodeSimulation.FlagTimedTrafficLights && !nodeSimulation.TimedTrafficLightsActive))
                        {
                            RoadBaseAI.GetTrafficLightState(num4,
                                                            ref instance.m_segments.m_buffer[(int)prevPos.m_segment],
                                                            currentFrameIndex - num5, out vehicleLightState, out pedestrianLightState, out flag5,
                                                            out pedestrians);
                            if (!flag5 && num6 >= 196u)
                            {
                                flag5 = true;
                                RoadBaseAI.SetTrafficLightState(num4,
                                                                ref instance.m_segments.m_buffer[(int)prevPos.m_segment], currentFrameIndex - num5,
                                                                vehicleLightState, pedestrianLightState, flag5, pedestrians);
                            }

                            if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == Vehicle.Flags.None ||
                                info.m_class.m_service != ItemClass.Service.Road)
                            {
                                switch (vehicleLightState)
                                {
                                case RoadBaseAI.TrafficLightState.RedToGreen:
                                    if (num6 < 60u)
                                    {
                                        maxSpeed = 0f;
                                        return;
                                    }
                                    break;

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

                                case RoadBaseAI.TrafficLightState.GreenToRed:
                                    if (num6 >= 30u)
                                    {
                                        maxSpeed = 0f;
                                        return;
                                    }
                                    break;
                                }
                            }
                        }
                        else
                        {
                            var stopCar = false;

                            if (TrafficPriority.isLeftSegment(prevPos.m_segment, position.m_segment, num2, true) >= 0)
                            {
                                vehicleLightState =
                                    TrafficLightsManual.GetSegmentLight(num4, prevPos.m_segment).GetLightLeft();
                            }
                            else if (TrafficPriority.isRightSegment(prevPos.m_segment, position.m_segment, num2, true) >= 0)
                            {
                                vehicleLightState =
                                    TrafficLightsManual.GetSegmentLight(num4, prevPos.m_segment).GetLightRight();
                            }
                            else
                            {
                                vehicleLightState =
                                    TrafficLightsManual.GetSegmentLight(num4, prevPos.m_segment).GetLightMain();
                            }

                            if (vehicleLightState == RoadBaseAI.TrafficLightState.Green)
                            {
                                var hasIncomingCars = TrafficPriority.incomingVehicles(vehicleID, num2);

                                if (hasIncomingCars)
                                {
                                    stopCar = true;
                                }
                            }

                            if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == Vehicle.Flags.None ||
                                info.m_class.m_service != ItemClass.Service.Road)
                            {
                                switch (vehicleLightState)
                                {
                                case RoadBaseAI.TrafficLightState.RedToGreen:
                                    if (num6 < 60u)
                                    {
                                        stopCar = true;
                                    }
                                    break;

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

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

                            if (stopCar)
                            {
                                maxSpeed = 0f;
                                return;
                            }
                        }
                    }
                    else
                    {
                        if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Car &&
                            TrafficPriority.vehicleList.ContainsKey(vehicleID) &&
                            TrafficPriority.isPrioritySegment(num2, prevPos.m_segment))
                        {
                            uint currentFrameIndex2 = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                            uint frame = currentFrameIndex2 >> 4;

                            var prioritySegment = TrafficPriority.getPrioritySegment(num2, prevPos.m_segment);

                            if (TrafficPriority.vehicleList[vehicleID].carState == PriorityCar.CarState.None)
                            {
                                TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Enter;
                            }

                            if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == Vehicle.Flags.None &&
                                TrafficPriority.vehicleList[vehicleID].carState != PriorityCar.CarState.Leave)
                            {
                                if (prioritySegment.type == PrioritySegment.PriorityType.Stop)
                                {
                                    if (TrafficPriority.vehicleList[vehicleID].waitTime < 75)
                                    {
                                        TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Stop;

                                        if (vehicleData.GetLastFrameData().m_velocity.sqrMagnitude < 0.1f ||
                                            TrafficPriority.vehicleList[vehicleID].stopped)
                                        {
                                            TrafficPriority.vehicleList[vehicleID].stopped = true;
                                            TrafficPriority.vehicleList[vehicleID].waitTime++;

                                            if (TrafficPriority.vehicleList[vehicleID].waitTime > 2)
                                            {
                                                var hasIncomingCars = TrafficPriority.incomingVehicles(vehicleID, num2);

                                                if (hasIncomingCars)
                                                {
                                                    maxSpeed = 0f;
                                                    return;
                                                }
                                            }
                                            else
                                            {
                                                maxSpeed = 0f;
                                                return;
                                            }
                                        }
                                        else
                                        {
                                            maxSpeed = 0f;
                                            return;
                                        }
                                    }
                                    else
                                    {
                                        TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Leave;
                                    }
                                }
                                else if (prioritySegment.type == PrioritySegment.PriorityType.Yield)
                                {
                                    if (TrafficPriority.vehicleList[vehicleID].waitTime < 75)
                                    {
                                        TrafficPriority.vehicleList[vehicleID].waitTime++;
                                        TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Stop;
                                        maxSpeed = 0f;

                                        if (vehicleData.GetLastFrameData().m_velocity.sqrMagnitude <
                                            TrafficPriority.vehicleList[vehicleID].yieldSpeedReduce)
                                        {
                                            var hasIncomingCars = TrafficPriority.incomingVehicles(vehicleID, num2);

                                            if (hasIncomingCars)
                                            {
                                                return;
                                            }
                                        }
                                        else
                                        {
                                            return;
                                        }
                                    }
                                    else
                                    {
                                        TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Leave;
                                    }
                                }
                                else if (prioritySegment.type == PrioritySegment.PriorityType.Main)
                                {
                                    TrafficPriority.vehicleList[vehicleID].waitTime++;
                                    TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Stop;
                                    maxSpeed = 0f;

                                    var hasIncomingCars = TrafficPriority.incomingVehicles(vehicleID, num2);

                                    if (hasIncomingCars)
                                    {
                                        TrafficPriority.vehicleList[vehicleID].stopped = true;
                                        return;
                                    }
                                    else
                                    {
                                        TrafficPriority.vehicleList[vehicleID].stopped = false;

                                        NetInfo info3 = instance.m_segments.m_buffer[(int)position.m_segment].Info;
                                        if (info3.m_lanes != null && info3.m_lanes.Length > (int)position.m_lane)
                                        {
                                            maxSpeed =
                                                this.CalculateTargetSpeed(vehicleID, ref vehicleData,
                                                                          info3.m_lanes[(int)position.m_lane].m_speedLimit,
                                                                          instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve) * 0.8f;
                                        }
                                        else
                                        {
                                            maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, 1f, 0f) *
                                                       0.8f;
                                        }
                                        return;
                                    }
                                }
                            }
                            else
                            {
                                TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Transit;
                            }
                        }
                    }
                }
            }

            NetInfo info2 = instance.m_segments.m_buffer[(int)position.m_segment].Info;

            if (info2.m_lanes != null && info2.m_lanes.Length > (int)position.m_lane)
            {
                var laneSpeedLimit = info2.m_lanes[(int)position.m_lane].m_speedLimit;

                if (TrafficRoadRestrictions.isSegment(position.m_segment))
                {
                    var restrictionSegment = TrafficRoadRestrictions.getSegment(position.m_segment);

                    if (restrictionSegment.speedLimits[(int)position.m_lane] > 0.1f)
                    {
                        laneSpeedLimit = restrictionSegment.speedLimits[(int)position.m_lane];
                    }
                }

                maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, laneSpeedLimit, instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve);
            }
            else
            {
                maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, 1f, 0f);
            }
        }
Example #16
0
 public View Build(NetManager mgr)
 {
     return(new UserViewer(mgr));
 }
Example #17
0
        void NetThread()
        {
            EventBasedNetListener listener = new EventBasedNetListener();
            int unique = Environment.TickCount;

            listener.ConnectionRequestEvent += request =>
            {
                if (Server.ConnectedPeersCount > MaxConnections)
                {
                    request.Reject();
                }
                else
                {
                    request.AcceptIfKey(AppIdentifier);
                }
            };
            listener.PeerConnectedEvent += peer =>
            {
                FLLog.Info("Server", $"Connected: {peer.EndPoint}");
                BeginAuthentication(peer);
            };
            listener.PeerDisconnectedEvent += (peer, info) =>
            {
                FLLog.Info("Server", $"Disconnected: {peer.EndPoint}");
                if (peer.Tag is Player player)
                {
                    player.Disconnected();
                    lock (game.ConnectedPlayers)
                    {
                        game.ConnectedPlayers.Remove(player);
                    }
                }
            };
            listener.NetworkReceiveUnconnectedEvent += (point, reader, type) =>
            {
                try
                {
                    if (type == UnconnectedMessageType.Broadcast)
                    {
                        if (!reader.TryGetString(out string str))
                        {
                            return;
                        }
                        if (str != LNetConst.BROADCAST_KEY)
                        {
                            return;
                        }
                        var dw = new NetDataWriter();
                        dw.Put((int)1);
                        dw.Put(unique);
                        dw.Put(game.ServerName);
                        dw.Put(game.ServerDescription);
                        dw.Put(game.GameData.DataVersion);
                        dw.Put(Server.ConnectedPeersCount);
                        dw.Put(MaxConnections);
                        Server.SendUnconnectedMessage(dw, point);
                    }
                    else if (type == UnconnectedMessageType.BasicMessage)
                    {
                        if (!reader.TryGetUInt(out uint magic))
                        {
                            return;
                        }
                        if (magic != LNetConst.PING_MAGIC)
                        {
                            return;
                        }
                        var dw = new NetDataWriter();
                        dw.Put((int)0);
                        Server.SendUnconnectedMessage(dw, point);
                    }
                }
                finally
                {
                    reader.Recycle();
                }
            };
            listener.NetworkReceiveEvent += (peer, reader, channel, method) =>
            {
                try
                {
                    var pkt = Packets.Read(reader);
                    if (peer.Tag == TagConnecting)
                    {
                        if (pkt is AuthenticationReplyPacket)
                        {
                            var auth = (AuthenticationReplyPacket)pkt;
                            if (auth.Guid == Guid.Empty)
                            {
                                var dw = new NetDataWriter();
                                dw.Put("bad GUID");
                                peer.Disconnect(dw);
                            }
                            else
                            {
                                var p = new Player(new RemotePacketClient(peer),
                                                   game, auth.Guid);
                                peer.Tag = p;
                                Task.Run(() => p.DoAuthSuccess());
                                lock (game.ConnectedPlayers)
                                {
                                    game.ConnectedPlayers.Add(p);
                                }
                            }
                        }
                        else
                        {
                            var dw = new NetDataWriter();
                            dw.Put("Invalid packet");
                            peer.Disconnect(dw);
                        }
                    }
                    else
                    {
                        var player = (Player)peer.Tag;
                        //Task.Run(() => player.ProcessPacket(pkt));
                        player.ProcessPacket(pkt);
                    }
                }
                catch (Exception)
                {
                    throw;
                    var dw = new NetDataWriter();
                    dw.Put("Packet processing error");
                    peer.Disconnect(dw);
                    if (peer.Tag is Player p)
                    {
                        p.Disconnected();
                    }
                }
                finally
                {
                    reader.Recycle();
                }
            };
            listener.DeliveryEvent += (peer, data) =>
            {
                if (data is Action onAck)
                {
                    onAck();
                }
            };
            Server          = new NetManager(listener);
            Server.IPv6Mode = IPv6Mode.SeparateSocket;
            Server.UnconnectedMessagesEnabled = true;
            Server.BroadcastReceiveEnabled    = true;
            Server.ChannelsCount  = 3;
            Server.UnsyncedEvents = true;
            Server.Start(Port);
            FLLog.Info("Server", "Listening on port " + Port);
            var        sw       = Stopwatch.StartNew();
            var        last     = 0.0;
            ServerLoop sendLoop = null;

            sendLoop = new ServerLoop((time) =>
            {
                foreach (var p in Server.ConnectedPeerList)
                {
                    if (p.Tag is Player player)
                    {
                        (player.Client as RemotePacketClient)?.Update(time.TotalSeconds);
                    }
                }

                if (!running)
                {
                    sendLoop.Stop();
                }
            });
            sendLoop.Start();
            Server.Stop();
        }
 void OnApplicationQuit()
 {
     NetManager.GetInstance().DisconnectServer();
 }
Example #19
0
        void _OnBeforeSimulationTick()
        {
            if (toolMode == ToolMode.None)
            {
                return;
            }

            if (!mouseDown)
            {
                dragging = false;
                prevBuiltSegmentIndex = 0;
            }

            if (buildTool != null)
            {
                buildTool.isHoveringSegment = false;
                buildTool.toolMode          = toolMode;
                buildTool.ToolCursor        = netTool.m_upgradeCursor;
            }

            if (!mouseRayValid)
            {
                return;
            }

            ToolBase.RaycastInput raycastInput = new ToolBase.RaycastInput(mouseRay, mouseRayLength);
            raycastInput.m_netService         = raycastService;
            raycastInput.m_ignoreTerrain      = true;
            raycastInput.m_ignoreNodeFlags    = NetNode.Flags.All;
            raycastInput.m_ignoreSegmentFlags = NetSegment.Flags.Untouchable;

            ToolBase.RaycastOutput raycastOutput;
            if (BuildTool144.RayCast(raycastInput, out raycastOutput))
            {
                int segmentIndex = raycastOutput.m_netSegment;
                if (segmentIndex != 0)
                {
                    NetManager net           = Singleton <NetManager> .instance;
                    NetInfo    newRoadPrefab = null;

                    NetTool.ControlPoint startPoint;
                    NetTool.ControlPoint middlePoint;
                    NetTool.ControlPoint endPoint;

                    GetSegmentControlPoints(segmentIndex, out startPoint, out middlePoint, out endPoint);

                    ushort node;
                    ushort outSegment;
                    int    cost;
                    int    productionRate;
                    // Check for out-of-area error and initialized collide arrays for visualization
                    ToolBase.ToolErrors errors = NetTool.CreateNode(net.m_segments.m_buffer[segmentIndex].Info,
                                                                    startPoint, middlePoint, endPoint, NetTool.m_nodePositionsSimulation, 1000,
                                                                    true, false, true, false, false, false, (ushort)0, out node, out outSegment, out cost, out productionRate);

                    if ((errors & ToolBase.ToolErrors.OutOfArea) != 0)
                    {
                        toolError = ToolError.OutOfArea;
                    }
                    else
                    {
                        if (mouseDown)
                        {
                            HandleMouseDrag(ref raycastOutput, ref toolError, false, ref newRoadPrefab, ref segmentIndex);

                            if (segmentIndex == prevBuiltSegmentIndex)
                            {
                                toolError = ToolError.AlreadyBuilt;
                            }
                        }
                        else
                        {
                            HandleMouseDrag(ref raycastOutput, ref toolError, true, ref newRoadPrefab, ref segmentIndex);
                        }
                    }

                    if (buildTool != null)
                    {
                        buildTool.segment           = net.m_segments.m_buffer[segmentIndex];
                        buildTool.segmentIndex      = segmentIndex;
                        buildTool.isHoveringSegment = toolError != ToolError.Unknown;
                        if (newRoadPrefab != null)
                        {
                            buildTool.newPrefab = newRoadPrefab;
                        }
                        GetSegmentControlPoints(segmentIndex, out buildTool.startPoint, out buildTool.middlePoint, out buildTool.endPoint);
                    }
                }
            }

            if (buildTool != null)
            {
                buildTool.toolError = toolError;
            }
        }
 void OnDestroy()
 {
     mInstance = null;
 }
        public void CustomCalculateSegmentPosition(ushort vehicleID, ref Vehicle vehicleData, PathUnit.Position nextPosition, PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID, byte prevOffset, int index, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            NetManager instance = Singleton <NetManager> .instance;

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

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

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

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

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

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

            if (info.m_lanes != null && info.m_lanes.Length > (int)position.m_lane)
            {
                //maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, info.m_lanes[(int)position.m_lane].m_speedLimit, instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve);
                maxSpeed = CalculateTargetSpeed(vehicleID, ref vehicleData, SpeedLimitManager.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, info.m_lanes[position.m_lane]), instance.m_lanes.m_buffer[laneID].m_curve);
            }
            else
            {
                maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, 1f, 0f);
            }
        }
        private void ShowSigns(bool viewOnly)
        {
            Quaternion camRot = Camera.main.transform.rotation;
            Vector3    camPos = Camera.main.transform.position;

            NetManager netManager = Singleton <NetManager> .instance;

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

                for (ushort segmentId = 1; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId)
                {
                    if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Created) == NetSegment.Flags.None)
                    {
                        continue;
                    }
                    if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Untouchable) != NetSegment.Flags.None)
                    {
                        continue;
                    }

                    if ((netManager.m_segments.m_buffer[segmentId].m_bounds.center - camPos).magnitude > TrafficManagerTool.PriorityCloseLod)
                    {
                        continue;                         // do not draw if too distant
                    }
                    Vector3 screenPos = Camera.main.WorldToScreenPoint(netManager.m_segments.m_buffer[segmentId].m_bounds.center);
                    if (screenPos.z < 0)
                    {
                        continue;
                    }

                    ItemClass connectionClass = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info.GetConnectionClass();
                    if (!(connectionClass.m_service == ItemClass.Service.Road ||
                          (connectionClass.m_service == ItemClass.Service.PublicTransport && connectionClass.m_subService == ItemClass.SubService.PublicTransportTrain)))
                    {
                        continue;
                    }

                    currentlyVisibleSegmentIds.Add(segmentId);
                }

                lastCamPos = camPos;
                lastCamRot = camRot;
            }

            bool handleHovered = false;

            foreach (ushort segmentId in currentlyVisibleSegmentIds)
            {
                Vector3 screenPos = Camera.main.WorldToScreenPoint(netManager.m_segments.m_buffer[segmentId].m_bounds.center);
                screenPos.y = Screen.height - screenPos.y;
                if (screenPos.z < 0)
                {
                    continue;
                }

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

                // draw speed limits
                if (TrafficManagerTool.GetToolMode() != ToolMode.VehicleRestrictions || segmentId != SelectedSegmentId)                   // no speed limit overlay on selected segment when in vehicle restrictions mode
                {
                    if (drawSpeedLimitHandles((ushort)segmentId, viewOnly, ref camPos))
                    {
                        handleHovered = true;
                    }
                }
            }
            overlayHandleHovered = handleHovered;
        }
Example #23
0
    class CustomTransportLineAI : TransportLineAI {     // TODO inherit from NetAI (in order to keep the correct references to `base`)
        public static bool CustomStartPathFind(ushort segmentID, ref NetSegment data, ItemClass.Service netService, ItemClass.Service netService2, VehicleInfo.VehicleType vehicleType, bool skipQueue)
        {
            if (data.m_path != 0u)
            {
                Singleton <PathManager> .instance.ReleasePath(data.m_path);

                data.m_path = 0u;
            }

            NetManager netManager = Singleton <NetManager> .instance;

            if ((netManager.m_nodes.m_buffer[(int)data.m_startNode].m_flags & NetNode.Flags.Ambiguous) != NetNode.Flags.None)
            {
                for (int i = 0; i < 8; i++)
                {
                    ushort segment = netManager.m_nodes.m_buffer[(int)data.m_startNode].GetSegment(i);
                    if (segment != 0 && segment != segmentID && netManager.m_segments.m_buffer[(int)segment].m_path != 0u)
                    {
                        return(true);
                    }
                }
            }
            if ((netManager.m_nodes.m_buffer[(int)data.m_endNode].m_flags & NetNode.Flags.Ambiguous) != NetNode.Flags.None)
            {
                for (int j = 0; j < 8; j++)
                {
                    ushort segment2 = netManager.m_nodes.m_buffer[(int)data.m_endNode].GetSegment(j);
                    if (segment2 != 0 && segment2 != segmentID && netManager.m_segments.m_buffer[(int)segment2].m_path != 0u)
                    {
                        return(true);
                    }
                }
            }

            Vector3 position  = netManager.m_nodes.m_buffer[(int)data.m_startNode].m_position;
            Vector3 position2 = netManager.m_nodes.m_buffer[(int)data.m_endNode].m_position;

#if DEBUG
            bool debug = GlobalConfig.Instance.Debug.Switches[18];
            if (debug)
            {
                Log._Debug($"TransportLineAI.CustomStartPathFind({segmentID}, ..., {netService}, {netService2}, {vehicleType}, {skipQueue}): startNode={data.m_startNode} @ {position}, endNode={data.m_endNode} @ {position2} -- line: {netManager.m_nodes.m_buffer[(int)data.m_startNode].m_transportLine}/{netManager.m_nodes.m_buffer[(int)data.m_endNode].m_transportLine}");
            }
#endif

            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             startSqrDistA;
            float             startSqrDistB;
            if (!CustomPathManager.FindPathPosition(position, netService, netService2, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, vehicleType, true, false, 32f, out startPosA, out startPosB, out startSqrDistA, out startSqrDistB))
            {
                CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
                return(true);
            }

            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             endSqrDistA;
            float             endSqrDistB;
            if (!CustomPathManager.FindPathPosition(position2, netService, netService2, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, vehicleType, true, false, 32f, out endPosA, out endPosB, out endSqrDistA, out endSqrDistB))
            {
                CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
                return(true);
            }

            if ((netManager.m_nodes.m_buffer[(int)data.m_startNode].m_flags & NetNode.Flags.Fixed) != NetNode.Flags.None)
            {
                startPosB = default(PathUnit.Position);
            }

            if ((netManager.m_nodes.m_buffer[(int)data.m_endNode].m_flags & NetNode.Flags.Fixed) != NetNode.Flags.None)
            {
                endPosB = default(PathUnit.Position);
            }

            if (vehicleType != VehicleInfo.VehicleType.None)
            {
                startPosA.m_offset = 128;
                startPosB.m_offset = 128;
                endPosA.m_offset   = 128;
                endPosB.m_offset   = 128;
            }
            else
            {
                startPosA.m_offset = (byte)Mathf.Clamp(startPosA.m_offset, 1, 254);
                startPosB.m_offset = (byte)Mathf.Clamp(startPosB.m_offset, 1, 254);
                endPosA.m_offset   = (byte)Mathf.Clamp(endPosA.m_offset, 1, 254);
                endPosB.m_offset   = (byte)Mathf.Clamp(endPosB.m_offset, 1, 254);
            }

            bool stopLane  = CustomTransportLineAI.GetStopLane(ref startPosA, vehicleType);
            bool stopLane2 = CustomTransportLineAI.GetStopLane(ref startPosB, vehicleType);
            bool stopLane3 = CustomTransportLineAI.GetStopLane(ref endPosA, vehicleType);
            bool stopLane4 = CustomTransportLineAI.GetStopLane(ref endPosB, vehicleType);

            if ((!stopLane && !stopLane2) || (!stopLane3 && !stopLane4))
            {
                CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
                return(true);
            }

            ExtVehicleType extVehicleType = ExtVehicleType.None;
#if BENCHMARK
            using (var bm = new Benchmark(null, "extVehicleType")) {
#endif
            if ((vehicleType & VehicleInfo.VehicleType.Car) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.Bus;
            }
            if ((vehicleType & (VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Metro | VehicleInfo.VehicleType.Monorail)) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.PassengerTrain;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Tram) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.Tram;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Ship) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.PassengerShip;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Plane) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.PassengerPlane;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Ferry) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.Ferry;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Blimp) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.Blimp;
            }
            if ((vehicleType & VehicleInfo.VehicleType.CableCar) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.CableCar;
            }
#if BENCHMARK
        }
#endif
            //Log._Debug($"Transport line. extVehicleType={extVehicleType}");
            uint path;
            // NON-STOCK CODE START
            PathCreationArgs args;
            args.extPathType         = ExtCitizenInstance.ExtPathType.None;
            args.extVehicleType      = extVehicleType;
            args.vehicleId           = 0;
            args.buildIndex          = Singleton <SimulationManager> .instance.m_currentBuildIndex;
            args.startPosA           = startPosA;
            args.startPosB           = startPosB;
            args.endPosA             = endPosA;
            args.endPosB             = endPosB;
            args.vehiclePosition     = default(PathUnit.Position);
            args.vehicleTypes        = vehicleType;
            args.isHeavyVehicle      = false;
            args.hasCombustionEngine = false;
            args.ignoreBlocked       = true;
            args.ignoreFlooded       = false;
            args.ignoreCosts         = false;
            args.randomParking       = false;
            args.stablePath          = true;
            args.skipQueue           = skipQueue;

            if (vehicleType == VehicleInfo.VehicleType.None)
            {
                args.laneTypes = NetInfo.LaneType.Pedestrian;
                args.maxLength = 160000f;
            }
            else
            {
                args.laneTypes = (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle);
                args.maxLength = 20000f;
            }

            if (CustomPathManager._instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, args))
            {
                // NON-STOCK CODE END
                if (startPosA.m_segment != 0 && startPosB.m_segment != 0)
                {
                    netManager.m_nodes.m_buffer[data.m_startNode].m_flags |= NetNode.Flags.Ambiguous;
                }
                else
                {
                    netManager.m_nodes.m_buffer[data.m_startNode].m_flags &= ~NetNode.Flags.Ambiguous;
                }
                if (endPosA.m_segment != 0 && endPosB.m_segment != 0)
                {
                    netManager.m_nodes.m_buffer[data.m_endNode].m_flags |= NetNode.Flags.Ambiguous;
                }
                else
                {
                    netManager.m_nodes.m_buffer[data.m_endNode].m_flags &= ~NetNode.Flags.Ambiguous;
                }
                data.m_path   = path;
                data.m_flags |= NetSegment.Flags.WaitingPath;
#if DEBUG
                if (debug)
                {
                    Log._Debug($"TransportLineAI.CustomStartPathFind({segmentID}, ..., {netService}, {netService2}, {vehicleType}, {skipQueue}): Started calculating path {path} for extVehicleType={extVehicleType}, startPosA=[seg={startPosA.m_segment}, lane={startPosA.m_lane}, off={startPosA.m_offset}], startPosB=[seg={startPosB.m_segment}, lane={startPosB.m_lane}, off={startPosB.m_offset}], endPosA=[seg={endPosA.m_segment}, lane={endPosA.m_lane}, off={endPosA.m_offset}], endPosB=[seg={endPosB.m_segment}, lane={endPosB.m_lane}, off={endPosB.m_offset}]");
                }
#endif
                return(false);
            }

            CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
            return(true);
        }
Example #24
0
        /// <summary>
        /// Adds a lane connection between two lanes
        /// </summary>
        /// <param name="sourceLaneId">From lane id</param>
        /// <param name="targetLaneId">To lane id</param>
        /// <param name="sourceStartNode">The affected node</param>
        /// <returns></returns>
        internal bool AddLaneConnection(uint sourceLaneId,
                                        uint targetLaneId,
                                        bool sourceStartNode)
        {
            if (sourceLaneId == targetLaneId)
            {
                return(false);
            }

            bool ret = Flags.AddLaneConnection(sourceLaneId, targetLaneId, sourceStartNode);

#if DEBUG
            bool logLaneConnections = DebugSwitch.LaneConnections.Get();
#else
            const bool logLaneConnections = false;
#endif

            if (logLaneConnections)
            {
                Log._Debug($"LaneConnectionManager.AddLaneConnection({sourceLaneId}, " +
                           $"{targetLaneId}, {sourceStartNode}): ret={ret}");
            }

            if (!ret)
            {
                return(false);
            }

            GetCommonNodeId(
                sourceLaneId,
                targetLaneId,
                sourceStartNode,
                out ushort commonNodeId,
                out bool targetStartNode);

            RecalculateLaneArrows(sourceLaneId, commonNodeId, sourceStartNode);
            RecalculateLaneArrows(targetLaneId, commonNodeId, targetStartNode);

            NetManager netManager = Singleton <NetManager> .instance;

            ushort sourceSegmentId = netManager.m_lanes.m_buffer[sourceLaneId].m_segment;
            ushort targetSegmentId = netManager.m_lanes.m_buffer[targetLaneId].m_segment;

            if (sourceSegmentId == targetSegmentId)
            {
                JunctionRestrictionsManager.Instance.SetUturnAllowed(
                    sourceSegmentId,
                    sourceStartNode,
                    true);
            }

            RoutingManager.Instance.RequestRecalculation(sourceSegmentId, false);
            RoutingManager.Instance.RequestRecalculation(targetSegmentId, false);

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

            // return ret, ret is true at this point
            return(true);
        }
        private void ShowSigns(bool viewOnly)
        {
            NetManager netManager = Singleton <NetManager> .instance;
            var        camPos     = Singleton <SimulationManager> .instance.m_simulationView.m_position;

            if (!viewOnly && SelectedNodeId != 0)
            {
                currentRestrictedNodeIds.Add(SelectedNodeId);
            }

            ushort updatedNodeId = 0;
            bool   handleHovered = false;
            bool   cursorInPanel = this.IsCursorInPanel();

            foreach (ushort nodeId in currentRestrictedNodeIds)
            {
                if (!Constants.ServiceFactory.NetService.IsNodeValid(nodeId))
                {
                    continue;
                }

                Vector3 nodePos = netManager.m_nodes.m_buffer[nodeId].m_position;
                var     diff    = nodePos - camPos;

                if (diff.magnitude > TrafficManagerTool.MaxOverlayDistance)
                {
                    continue;                     // do not draw if too distant
                }
                Vector3 screenPos = Camera.main.WorldToScreenPoint(nodePos);
                screenPos.y = Screen.height - screenPos.y;

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

                bool viewOnlyNode = true;
                if (!viewOnly && nodeId == SelectedNodeId)
                {
                    viewOnlyNode = false;
                }

                // draw junction restrictions
                bool update;
                if (drawSignHandles(nodeId, viewOnlyNode, !cursorInPanel, ref camPos, out update))
                {
                    handleHovered = true;
                }

                if (update)
                {
                    updatedNodeId = nodeId;
                }
            }
            overlayHandleHovered = handleHovered;

            if (updatedNodeId != 0)
            {
                RefreshCurrentRestrictedNodeIds(updatedNodeId);
            }
        }
Example #26
0
        internal bool GetLaneEndPoint(ushort segmentId,
                                      bool startNode,
                                      byte laneIndex,
                                      uint?laneId,
                                      NetInfo.Lane laneInfo,
                                      out bool outgoing,
                                      out bool incoming,
                                      out Vector3?pos)
        {
            NetManager netManager = Singleton <NetManager> .instance;

            pos      = null;
            outgoing = false;
            incoming = false;

            if ((netManager.m_segments.m_buffer[segmentId].m_flags &
                 (NetSegment.Flags.Created | NetSegment.Flags.Deleted)) != NetSegment.Flags.Created)
            {
                return(false);
            }

            if (laneId == null)
            {
                laneId = FindLaneId(segmentId, laneIndex);
                if (laneId == null)
                {
                    return(false);
                }
            }

            if ((netManager.m_lanes.m_buffer[(uint)laneId].m_flags &
                 ((ushort)NetLane.Flags.Created | (ushort)NetLane.Flags.Deleted)) !=
                (ushort)NetLane.Flags.Created)
            {
                return(false);
            }

            if (laneInfo == null)
            {
                if (laneIndex < netManager.m_segments.m_buffer[segmentId].Info.m_lanes.Length)
                {
                    laneInfo = netManager.m_segments.m_buffer[segmentId].Info.m_lanes[laneIndex];
                }
                else
                {
                    return(false);
                }
            }

            NetInfo.Direction laneDir =
                ((NetManager.instance.m_segments.m_buffer[segmentId].m_flags &
                  NetSegment.Flags.Invert) == NetSegment.Flags.None)
                    ? laneInfo.m_finalDirection
                    : NetInfo.InvertDirection(laneInfo.m_finalDirection);

            if (startNode)
            {
                if ((laneDir & NetInfo.Direction.Backward) != NetInfo.Direction.None)
                {
                    outgoing = true;
                }

                if ((laneDir & NetInfo.Direction.Forward) != NetInfo.Direction.None)
                {
                    incoming = true;
                }

                pos = NetManager.instance.m_lanes.m_buffer[(uint)laneId].m_bezier.a;
            }
            else
            {
                if ((laneDir & NetInfo.Direction.Forward) != NetInfo.Direction.None)
                {
                    outgoing = true;
                }

                if ((laneDir & NetInfo.Direction.Backward) != NetInfo.Direction.None)
                {
                    incoming = true;
                }

                pos = NetManager.instance.m_lanes.m_buffer[(uint)laneId].m_bezier.d;
            }

            return(true);
        }
Example #27
0
        protected void CustomUpdatePathTargetPositions(ushort vehicleID, ref Vehicle vehicleData, Vector3 refPos, ref int targetPosIndex, int maxTargetPosIndex, float minSqrDistanceA, float minSqrDistanceB)
        {
            PathManager pathMan    = Singleton <PathManager> .instance;
            NetManager  netManager = Singleton <NetManager> .instance;

            Vector4 targetPos = vehicleData.m_targetPos0;

            targetPos.w = 1000f;
            float minSqrDistA      = minSqrDistanceA;
            uint  pathId           = vehicleData.m_path;
            byte  finePathPosIndex = vehicleData.m_pathPositionIndex;
            byte  lastPathOffset   = vehicleData.m_lastPathOffset;

            // initial position
            if (finePathPosIndex == 255)
            {
                finePathPosIndex = 0;
                if (targetPosIndex <= 0)
                {
                    vehicleData.m_pathPositionIndex = 0;
                }

                if (!Singleton <PathManager> .instance.m_pathUnits.m_buffer[pathId].CalculatePathPositionOffset(finePathPosIndex >> 1, targetPos, out lastPathOffset))
                {
                    this.InvalidPath(vehicleID, ref vehicleData, vehicleID, ref vehicleData);
                    return;
                }
            }

            // get current path position, check for errors
            PathUnit.Position currentPosition;
            if (!pathMan.m_pathUnits.m_buffer[pathId].GetPosition(finePathPosIndex >> 1, out currentPosition))
            {
                this.InvalidPath(vehicleID, ref vehicleData, vehicleID, ref vehicleData);
                return;
            }

            // get current segment info, check for errors
            NetInfo curSegmentInfo = netManager.m_segments.m_buffer[(int)currentPosition.m_segment].Info;

            if (curSegmentInfo.m_lanes.Length <= (int)currentPosition.m_lane)
            {
                this.InvalidPath(vehicleID, ref vehicleData, vehicleID, ref vehicleData);
                return;
            }

            // main loop
            uint curLaneId = PathManager.GetLaneID(currentPosition);

            NetInfo.Lane laneInfo = curSegmentInfo.m_lanes[(int)currentPosition.m_lane];
            Bezier3      bezier;
            bool         firstIter = true;     // NON-STOCK CODE

            while (true)
            {
                if ((finePathPosIndex & 1) == 0)
                {
                    // vehicle is not in transition
                    if (laneInfo.m_laneType != NetInfo.LaneType.CargoVehicle)
                    {
                        bool first = true;
                        while (lastPathOffset != currentPosition.m_offset)
                        {
                            // catch up and update target position until we get to the current segment offset
                            if (first)
                            {
                                first = false;
                            }
                            else
                            {
                                float distDiff = Mathf.Sqrt(minSqrDistA) - Vector3.Distance(targetPos, refPos);
                                int   pathOffsetDelta;
                                if (distDiff < 0f)
                                {
                                    pathOffsetDelta = 4;
                                }
                                else
                                {
                                    pathOffsetDelta = 4 + Mathf.Max(0, Mathf.CeilToInt(distDiff * 256f / (netManager.m_lanes.m_buffer[curLaneId].m_length + 1f)));
                                }
                                if (lastPathOffset > currentPosition.m_offset)
                                {
                                    lastPathOffset = (byte)Mathf.Max((int)lastPathOffset - pathOffsetDelta, (int)currentPosition.m_offset);
                                }
                                else if (lastPathOffset < currentPosition.m_offset)
                                {
                                    lastPathOffset = (byte)Mathf.Min((int)lastPathOffset + pathOffsetDelta, (int)currentPosition.m_offset);
                                }
                            }

                            Vector3 curSegPos;
                            Vector3 curSegDir;
                            float   curSegOffset;
                            this.CalculateSegmentPosition(vehicleID, ref vehicleData, currentPosition, curLaneId, lastPathOffset, out curSegPos, out curSegDir, out curSegOffset);
                            targetPos.Set(curSegPos.x, curSegPos.y, curSegPos.z, Mathf.Min(targetPos.w, curSegOffset));
                            float refPosSqrDist = (curSegPos - refPos).sqrMagnitude;
                            if (refPosSqrDist >= minSqrDistA)
                            {
                                if (targetPosIndex <= 0)
                                {
                                    vehicleData.m_lastPathOffset = lastPathOffset;
                                }
                                vehicleData.SetTargetPos(targetPosIndex++, targetPos);
                                minSqrDistA = minSqrDistanceB;
                                refPos      = targetPos;
                                targetPos.w = 1000f;
                                if (targetPosIndex == maxTargetPosIndex)
                                {
                                    // maximum target position index reached
                                    return;
                                }
                            }
                        }
                    }

                    // set vehicle in transition
                    finePathPosIndex += 1;
                    lastPathOffset    = 0;
                    if (targetPosIndex <= 0)
                    {
                        vehicleData.m_pathPositionIndex = finePathPosIndex;
                        vehicleData.m_lastPathOffset    = lastPathOffset;
                    }
                }

                // vehicle is in transition now

                /*
                 * coarse path position format: 0..11 (always equals 'fine path position' / 2 == 'fine path position' >> 1)
                 * fine path position format: 0..23
                 */

                // find next path unit (or abort if at path end)

                // skip normal process if toll booth flag is set
                if ((vehicleData.m_flags2 & Vehicle.Flags2.EndStop) == (Vehicle.Flags2) 0)
                {
                    int  nextCoarsePathPosIndex = (finePathPosIndex >> 1) + 1;
                    uint nextPathId             = pathId;
                    if (nextCoarsePathPosIndex >= (int)pathMan.m_pathUnits.m_buffer[pathId].m_positionCount)
                    {
                        nextCoarsePathPosIndex = 0;
                        nextPathId             = pathMan.m_pathUnits.m_buffer[pathId].m_nextPathUnit;
                        if (nextPathId == 0u)
                        {
                            if (targetPosIndex <= 0)
                            {
                                Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);

                                vehicleData.m_path = 0u;
                            }
                            targetPos.w = 1f;
                            vehicleData.SetTargetPos(targetPosIndex++, targetPos);
                            return;
                        }
                    }

                    // check for errors
                    PathUnit.Position nextPathPos;
                    if (!pathMan.m_pathUnits.m_buffer[nextPathId].GetPosition(nextCoarsePathPosIndex, out nextPathPos))
                    {
                        this.InvalidPath(vehicleID, ref vehicleData, vehicleID, ref vehicleData);
                        return;
                    }

                    // check for errors
                    NetInfo nextSegmentInfo = netManager.m_segments.m_buffer[(int)nextPathPos.m_segment].Info;
                    if (nextSegmentInfo.m_lanes.Length <= (int)nextPathPos.m_lane)
                    {
                        this.InvalidPath(vehicleID, ref vehicleData, vehicleID, ref vehicleData);
                        return;
                    }

                    // find next lane (emergency vehicles / dynamic lane selection)
                    int bestLaneIndex = nextPathPos.m_lane;
                    if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) != (Vehicle.Flags) 0)
                    {
                        bestLaneIndex = FindBestLane(vehicleID, ref vehicleData, nextPathPos);
                    }
                    else
                    {
                        // NON-STOCK CODE START
                        if (firstIter &&
                            this.m_info.m_vehicleType == VehicleInfo.VehicleType.Car &&
                            !this.m_info.m_isLargeVehicle
                            )
                        {
                            bool mayFindBestLane = false;
#if BENCHMARK
                            using (var bm = new Benchmark(null, "MayFindBestLane")) {
#endif
                            mayFindBestLane = VehicleBehaviorManager.Instance.MayFindBestLane(vehicleID, ref vehicleData, ref VehicleStateManager.Instance.VehicleStates[vehicleID]);
#if BENCHMARK
                        }
#endif

                            if (mayFindBestLane)
                            {
                                uint next2PathId       = nextPathId;
                                int  next2PathPosIndex = nextCoarsePathPosIndex;
                                bool next2Invalid;
                                PathUnit.Position next2PathPos;
                                NetInfo           next2SegmentInfo = null;
                                PathUnit.Position next3PathPos;
                                NetInfo           next3SegmentInfo = null;
                                PathUnit.Position next4PathPos;
                                if (PathUnit.GetNextPosition(ref next2PathId, ref next2PathPosIndex, out next2PathPos, out next2Invalid))
                                {
                                    next2SegmentInfo = netManager.m_segments.m_buffer[(int)next2PathPos.m_segment].Info;

                                    uint next3PathId       = next2PathId;
                                    int  next3PathPosIndex = next2PathPosIndex;
                                    bool next3Invalid;
                                    if (PathUnit.GetNextPosition(ref next3PathId, ref next3PathPosIndex, out next3PathPos, out next3Invalid))
                                    {
                                        next3SegmentInfo = netManager.m_segments.m_buffer[(int)next3PathPos.m_segment].Info;

                                        uint next4PathId       = next3PathId;
                                        int  next4PathPosIndex = next3PathPosIndex;
                                        bool next4Invalid;
                                        if (!PathUnit.GetNextPosition(ref next4PathId, ref next4PathPosIndex, out next4PathPos, out next4Invalid))
                                        {
                                            next4PathPos = default(PathUnit.Position);
                                        }
                                    }
                                    else
                                    {
                                        next3PathPos = default(PathUnit.Position);
                                        next4PathPos = default(PathUnit.Position);
                                    }
                                }
                                else
                                {
                                    next2PathPos = default(PathUnit.Position);
                                    next3PathPos = default(PathUnit.Position);
                                    next4PathPos = default(PathUnit.Position);
                                }

#if BENCHMARK
                                using (var bm = new Benchmark(null, "FindBestLane")) {
#endif
                                bestLaneIndex = VehicleBehaviorManager.Instance.FindBestLane(vehicleID, ref vehicleData, ref VehicleStateManager.Instance.VehicleStates[vehicleID], curLaneId, currentPosition, curSegmentInfo, nextPathPos, nextSegmentInfo, next2PathPos, next2SegmentInfo, next3PathPos, next3SegmentInfo, next4PathPos);
#if BENCHMARK
                            }
#endif
                            }
                            // NON-STOCK CODE END
                        }
                    }

                    // update lane index
                    if (bestLaneIndex != (int)nextPathPos.m_lane)
                    {
                        nextPathPos.m_lane = (byte)bestLaneIndex;
                        pathMan.m_pathUnits.m_buffer[nextPathId].SetPosition(nextCoarsePathPosIndex, nextPathPos);
#if BENCHMARK
                        using (var bm = new Benchmark(null, "AddTraffic")) {
#endif
                        // prevent multiple lane changes to the same lane from happening at the same time
                        TrafficMeasurementManager.Instance.AddTraffic(nextPathPos.m_segment, nextPathPos.m_lane
#if MEASUREDENSITY
                                                                      , VehicleStateManager.Instance.VehicleStates[vehicleID].totalLength
#endif
                                                                      , 0); // NON-STOCK CODE
#if BENCHMARK
                    }
#endif
                    }

                    // check for errors
                    uint nextLaneId           = PathManager.GetLaneID(nextPathPos);
                    NetInfo.Lane nextLaneInfo = nextSegmentInfo.m_lanes[(int)nextPathPos.m_lane];
                    ushort curSegStartNodeId  = netManager.m_segments.m_buffer[(int)currentPosition.m_segment].m_startNode;
                    ushort curSegEndNodeId    = netManager.m_segments.m_buffer[(int)currentPosition.m_segment].m_endNode;
                    ushort nextSegStartNodeId = netManager.m_segments.m_buffer[(int)nextPathPos.m_segment].m_startNode;
                    ushort nextSegEndNodeId   = netManager.m_segments.m_buffer[(int)nextPathPos.m_segment].m_endNode;
                    if (nextSegStartNodeId != curSegStartNodeId &&
                        nextSegStartNodeId != curSegEndNodeId &&
                        nextSegEndNodeId != curSegStartNodeId &&
                        nextSegEndNodeId != curSegEndNodeId &&
                        ((netManager.m_nodes.m_buffer[(int)curSegStartNodeId].m_flags | netManager.m_nodes.m_buffer[(int)curSegEndNodeId].m_flags) & NetNode.Flags.Disabled) == NetNode.Flags.None &&
                        ((netManager.m_nodes.m_buffer[(int)nextSegStartNodeId].m_flags | netManager.m_nodes.m_buffer[(int)nextSegEndNodeId].m_flags) & NetNode.Flags.Disabled) != NetNode.Flags.None)
                    {
                        this.InvalidPath(vehicleID, ref vehicleData, vehicleID, ref vehicleData);
                        return;
                    }

                    // park vehicle
                    if (nextLaneInfo.m_laneType == NetInfo.LaneType.Pedestrian)
                    {
                        if (vehicleID != 0 && (vehicleData.m_flags & Vehicle.Flags.Parking) == (Vehicle.Flags) 0)
                        {
                            byte inOffset  = currentPosition.m_offset;
                            byte outOffset = currentPosition.m_offset;
                            if (this.ParkVehicle(vehicleID, ref vehicleData, currentPosition, nextPathId, nextCoarsePathPosIndex << 1, out outOffset))
                            {
                                if (outOffset != inOffset)
                                {
                                    if (targetPosIndex <= 0)
                                    {
                                        vehicleData.m_pathPositionIndex = (byte)((int)vehicleData.m_pathPositionIndex & -2);
                                        vehicleData.m_lastPathOffset    = inOffset;
                                    }
                                    currentPosition.m_offset = outOffset;
                                    pathMan.m_pathUnits.m_buffer[(int)((UIntPtr)pathId)].SetPosition(finePathPosIndex >> 1, currentPosition);
                                }
                                vehicleData.m_flags |= Vehicle.Flags.Parking;
                            }
                            else
                            {
                                this.InvalidPath(vehicleID, ref vehicleData, vehicleID, ref vehicleData);
                            }
                        }
                        return;
                    }

                    // check for errors
                    if ((byte)(nextLaneInfo.m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.CargoVehicle | NetInfo.LaneType.TransportVehicle)) == 0)
                    {
                        this.InvalidPath(vehicleID, ref vehicleData, vehicleID, ref vehicleData);
                        return;
                    }



                    // change vehicle
                    if (nextLaneInfo.m_vehicleType != this.m_info.m_vehicleType &&
                        this.NeedChangeVehicleType(vehicleID, ref vehicleData, nextPathPos, nextLaneId, nextLaneInfo.m_vehicleType, ref targetPos)
                        )
                    {
                        float targetPos0ToRefPosSqrDist = ((Vector3)targetPos - refPos).sqrMagnitude;
                        if (targetPos0ToRefPosSqrDist >= minSqrDistA)
                        {
                            vehicleData.SetTargetPos(targetPosIndex++, targetPos);
                        }
                        if (targetPosIndex <= 0)
                        {
                            while (targetPosIndex < maxTargetPosIndex)
                            {
                                vehicleData.SetTargetPos(targetPosIndex++, targetPos);
                            }
                            if (nextPathId != vehicleData.m_path)
                            {
                                Singleton <PathManager> .instance.ReleaseFirstUnit(ref vehicleData.m_path);
                            }
                            vehicleData.m_pathPositionIndex = (byte)(nextCoarsePathPosIndex << 1);
                            PathUnit.CalculatePathPositionOffset(nextLaneId, targetPos, out vehicleData.m_lastPathOffset);
                            if (vehicleID != 0 && !this.ChangeVehicleType(vehicleID, ref vehicleData, nextPathPos, nextLaneId))
                            {
                                this.InvalidPath(vehicleID, ref vehicleData, vehicleID, ref vehicleData);
                            }
                        }
                        else
                        {
                            while (targetPosIndex < maxTargetPosIndex)
                            {
                                vehicleData.SetTargetPos(targetPosIndex++, targetPos);
                            }
                        }
                        return;
                    }

                    // unset leaving flag
                    if (nextPathPos.m_segment != currentPosition.m_segment && vehicleID != 0)
                    {
                        vehicleData.m_flags &= ~Vehicle.Flags.Leaving;
                    }

                    // calculate next segment offset
                    byte nextSegOffset = 0;
                    if ((vehicleData.m_flags & Vehicle.Flags.Flying) != (Vehicle.Flags) 0)
                    {
                        nextSegOffset = (byte)((nextPathPos.m_offset < 128) ? 255 : 0);
                    }
                    else if (curLaneId != nextLaneId && laneInfo.m_laneType != NetInfo.LaneType.CargoVehicle)
                    {
                        PathUnit.CalculatePathPositionOffset(nextLaneId, targetPos, out nextSegOffset);
                        bezier = default(Bezier3);
                        Vector3 curSegDir;
                        float   maxSpeed;
                        this.CalculateSegmentPosition(vehicleID, ref vehicleData, currentPosition, curLaneId, currentPosition.m_offset, out bezier.a, out curSegDir, out maxSpeed);
                        bool calculateNextNextPos = lastPathOffset == 0;
                        if (calculateNextNextPos)
                        {
                            if ((vehicleData.m_flags & Vehicle.Flags.Reversed) != (Vehicle.Flags) 0)
                            {
                                calculateNextNextPos = (vehicleData.m_trailingVehicle == 0);
                            }
                            else
                            {
                                calculateNextNextPos = (vehicleData.m_leadingVehicle == 0);
                            }
                        }
                        Vector3 nextSegDir;
                        float   nextMaxSpeed;
                        if (calculateNextNextPos)
                        {
                            PathUnit.Position nextNextPathPos;
                            if (!pathMan.m_pathUnits.m_buffer[nextPathId].GetNextPosition(nextCoarsePathPosIndex, out nextNextPathPos))
                            {
                                nextNextPathPos = default(PathUnit.Position);
                            }
                            this.CalculateSegmentPosition(vehicleID, ref vehicleData, nextNextPathPos, nextPathPos, nextLaneId, nextSegOffset, currentPosition, curLaneId, currentPosition.m_offset, targetPosIndex, out bezier.d, out nextSegDir, out nextMaxSpeed);
                        }
                        else
                        {
                            this.CalculateSegmentPosition(vehicleID, ref vehicleData, nextPathPos, nextLaneId, nextSegOffset, out bezier.d, out nextSegDir, out nextMaxSpeed);
                        }
                        if (nextMaxSpeed < 0.01f || (netManager.m_segments.m_buffer[(int)nextPathPos.m_segment].m_flags & (NetSegment.Flags.Collapsed | NetSegment.Flags.Flooded)) != NetSegment.Flags.None)
                        {
                            if (targetPosIndex <= 0)
                            {
                                vehicleData.m_lastPathOffset = lastPathOffset;
                            }
                            targetPos   = bezier.a;
                            targetPos.w = 0f;
                            while (targetPosIndex < maxTargetPosIndex)
                            {
                                vehicleData.SetTargetPos(targetPosIndex++, targetPos);
                            }
                            return;
                        }
                        if (currentPosition.m_offset == 0)
                        {
                            curSegDir = -curSegDir;
                        }
                        if (nextSegOffset < nextPathPos.m_offset)
                        {
                            nextSegDir = -nextSegDir;
                        }
                        curSegDir.Normalize();
                        nextSegDir.Normalize();
                        float dist;
                        NetSegment.CalculateMiddlePoints(bezier.a, curSegDir, bezier.d, nextSegDir, true, true, out bezier.b, out bezier.c, out dist);
                        if (dist > 1f)
                        {
                            ushort nextNodeId;
                            if (nextSegOffset == 0)
                            {
                                nextNodeId = netManager.m_segments.m_buffer[(int)nextPathPos.m_segment].m_startNode;
                            }
                            else if (nextSegOffset == 255)
                            {
                                nextNodeId = netManager.m_segments.m_buffer[(int)nextPathPos.m_segment].m_endNode;
                            }
                            else
                            {
                                nextNodeId = 0;
                            }
                            float curve = 1.57079637f * (1f + Vector3.Dot(curSegDir, nextSegDir));
                            if (dist > 1f)
                            {
                                curve /= dist;
                            }
                            nextMaxSpeed = Mathf.Min(nextMaxSpeed, this.CalculateTargetSpeed(vehicleID, ref vehicleData, 1000f, curve));
                            while (lastPathOffset < 255)
                            {
                                float distDiff = Mathf.Sqrt(minSqrDistA) - Vector3.Distance(targetPos, refPos);
                                int   pathOffsetDelta;
                                if (distDiff < 0f)
                                {
                                    pathOffsetDelta = 8;
                                }
                                else
                                {
                                    pathOffsetDelta = 8 + Mathf.Max(0, Mathf.CeilToInt(distDiff * 256f / (dist + 1f)));
                                }
                                lastPathOffset = (byte)Mathf.Min((int)lastPathOffset + pathOffsetDelta, 255);
                                Vector3 bezierPos = bezier.Position((float)lastPathOffset * 0.003921569f);
                                targetPos.Set(bezierPos.x, bezierPos.y, bezierPos.z, Mathf.Min(targetPos.w, nextMaxSpeed));
                                float sqrMagnitude2 = (bezierPos - refPos).sqrMagnitude;
                                if (sqrMagnitude2 >= minSqrDistA)
                                {
                                    if (targetPosIndex <= 0)
                                    {
                                        vehicleData.m_lastPathOffset = lastPathOffset;
                                    }
                                    if (nextNodeId != 0)
                                    {
                                        this.UpdateNodeTargetPos(vehicleID, ref vehicleData, nextNodeId, ref netManager.m_nodes.m_buffer[(int)nextNodeId], ref targetPos, targetPosIndex);
                                    }
                                    vehicleData.SetTargetPos(targetPosIndex++, targetPos);
                                    minSqrDistA = minSqrDistanceB;
                                    refPos      = targetPos;
                                    targetPos.w = 1000f;
                                    if (targetPosIndex == maxTargetPosIndex)
                                    {
                                        return;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        PathUnit.CalculatePathPositionOffset(nextLaneId, targetPos, out nextSegOffset);
                    }

                    // check for arrival
                    if (targetPosIndex <= 0)
                    {
                        if ((netManager.m_segments.m_buffer[(int)nextPathPos.m_segment].m_flags & NetSegment.Flags.Untouchable) != NetSegment.Flags.None && (netManager.m_segments.m_buffer[(int)currentPosition.m_segment].m_flags & NetSegment.Flags.Untouchable) == NetSegment.Flags.None)
                        {
                            int ownerBuilding = NetSegment.FindOwnerBuilding(nextPathPos.m_segment, 363f);
                            if (ownerBuilding != 0)
                            {
                                BuildingManager instance3 = Singleton <BuildingManager> .instance;
                                BuildingInfo    info3     = instance3.m_buildings.m_buffer[ownerBuilding].Info;
                                InstanceID      itemID    = new InstanceID();
                                itemID.Vehicle = vehicleID;
                                info3.m_buildingAI.EnterBuildingSegment((ushort)ownerBuilding, ref instance3.m_buildings.m_buffer[ownerBuilding], nextPathPos.m_segment, nextPathPos.m_offset, itemID);
                            }
                        }
                        if (nextCoarsePathPosIndex == 0)
                        {
                            Singleton <PathManager> .instance.ReleaseFirstUnit(ref vehicleData.m_path);
                        }
                        if (nextCoarsePathPosIndex >= (int)(pathMan.m_pathUnits.m_buffer[(int)((UIntPtr)nextPathId)].m_positionCount - 1) && pathMan.m_pathUnits.m_buffer[(int)((UIntPtr)nextPathId)].m_nextPathUnit == 0u && vehicleID != 0)
                        {
                            this.ArrivingToDestination(vehicleID, ref vehicleData);
                        }
                    }

                    // prepare next loop iteration: go to next path position
                    pathId           = nextPathId;
                    finePathPosIndex = (byte)(nextCoarsePathPosIndex << 1);
                    lastPathOffset   = nextSegOffset;
                    if (targetPosIndex <= 0)
                    {
                        vehicleData.m_pathPositionIndex = finePathPosIndex;
                        vehicleData.m_lastPathOffset    = lastPathOffset;
                        vehicleData.m_flags             = ((vehicleData.m_flags & ~(Vehicle.Flags.OnGravel | Vehicle.Flags.Underground | Vehicle.Flags.Transition)) | nextSegmentInfo.m_setVehicleFlags);
                        if (this.LeftHandDrive(nextLaneInfo))
                        {
                            vehicleData.m_flags |= Vehicle.Flags.LeftHandDrive;
                        }
                        else
                        {
                            vehicleData.m_flags &= (Vehicle.Flags.Created | Vehicle.Flags.Deleted | Vehicle.Flags.Spawned | Vehicle.Flags.Inverted | Vehicle.Flags.TransferToTarget | Vehicle.Flags.TransferToSource | Vehicle.Flags.Emergency1 | Vehicle.Flags.Emergency2 | Vehicle.Flags.WaitingPath | Vehicle.Flags.Stopped | Vehicle.Flags.Leaving | Vehicle.Flags.Arriving | Vehicle.Flags.Reversed | Vehicle.Flags.TakingOff | Vehicle.Flags.Flying | Vehicle.Flags.Landing | Vehicle.Flags.WaitingSpace | Vehicle.Flags.WaitingCargo | Vehicle.Flags.GoingBack | Vehicle.Flags.WaitingTarget | Vehicle.Flags.Importing | Vehicle.Flags.Exporting | Vehicle.Flags.Parking | Vehicle.Flags.CustomName | Vehicle.Flags.OnGravel | Vehicle.Flags.WaitingLoading | Vehicle.Flags.Congestion | Vehicle.Flags.DummyTraffic | Vehicle.Flags.Underground | Vehicle.Flags.Transition | Vehicle.Flags.InsideBuilding);
                        }
                    }
                    currentPosition = nextPathPos;
                    curLaneId       = nextLaneId;
                    laneInfo        = nextLaneInfo;
                }
                else
                {
                    //handle toll booth
                    if (targetPosIndex <= 0)
                    {
                        targetPos.w = 0.0f;
                        if ((double)VectorUtils.LengthSqrXZ(vehicleData.GetLastFrameVelocity()) < 0.00999999977648258)
                        {
                            vehicleData.m_flags2 &= ~Vehicle.Flags2.EndStop;
                            VehicleStateManager.Instance.VehicleStates[vehicleID].leftToll = true;
                        }
                    }
                    else
                    {
                        targetPos.w = 1f;
                    }

                    while (targetPosIndex < maxTargetPosIndex)
                    {
                        int intTargetPosIndex;
                        targetPosIndex = (intTargetPosIndex = targetPosIndex) + 1;
                        vehicleData.SetTargetPos(intTargetPosIndex, targetPos);
                    }

                    return;
                }
                firstIter = false;                 // NON-STOCK CODE
            }
        }
Example #28
0
        /// <summary>
        /// Recalculates lane arrows based on present lane connections.
        /// </summary>
        /// <param name="laneId">Affected lane</param>
        /// <param name="nodeId">Affected node</param>
        private void RecalculateLaneArrows(uint laneId, ushort nodeId, bool startNode)
        {
#if DEBUG
            bool logLaneConnections = DebugSwitch.LaneConnections.Get();
#else
            const bool logLaneConnections = false;
#endif
            if (logLaneConnections)
            {
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}) called");
            }

            if (!Options.laneConnectorEnabled)
            {
                return;
            }

            if (!Flags.CanHaveLaneArrows(laneId, startNode))
            {
                if (logLaneConnections)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                               $"lane {laneId}, startNode? {startNode} must not have lane arrows");
                }

                return;
            }

            if (!HasConnections(laneId, startNode))
            {
                if (logLaneConnections)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                               $"lane {laneId} does not have outgoing connections");
                }

                return;
            }

            if (nodeId == 0)
            {
                if (logLaneConnections)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                               "invalid node");
                }

                return;
            }

            var        arrows     = LaneArrows.None;
            NetManager netManager = Singleton <NetManager> .instance;
            ushort     segmentId  = netManager.m_lanes.m_buffer[laneId].m_segment;

            if (segmentId == 0)
            {
                if (logLaneConnections)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                               "invalid segment");
                }

                return;
            }

            if (logLaneConnections)
            {
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                           $"startNode? {startNode}");
            }

            if (!Services.NetService.IsNodeValid(nodeId))
            {
                if (logLaneConnections)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                               "Node is invalid");
                }

                return;
            }

            IExtSegmentEndManager segEndMan = Constants.ManagerFactory.ExtSegmentEndManager;
            ExtSegmentEnd         segEnd    = segEndMan.ExtSegmentEnds[segEndMan.GetIndex(segmentId, startNode)];

            Services.NetService.IterateNodeSegments(
                nodeId,
                (ushort otherSegmentId, ref NetSegment otherSeg) => {
                ArrowDirection dir = segEndMan.GetDirection(ref segEnd, otherSegmentId);

                if (logLaneConnections)
                {
                    Log._Debug(
                        $"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                        $"processing connected segment {otherSegmentId}. dir={dir}");
                }

                // check if arrow has already been set for this direction
                switch (dir)
                {
                case ArrowDirection.Turn: {
                    if (Constants.ServiceFactory.SimulationService.LeftHandDrive)
                    {
                        if ((arrows & LaneArrows.Right) != LaneArrows.None)
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        if ((arrows & LaneArrows.Left) != LaneArrows.None)
                        {
                            return(true);
                        }
                    }

                    break;
                }

                case ArrowDirection.Forward: {
                    if ((arrows & LaneArrows.Forward) != LaneArrows.None)
                    {
                        return(true);
                    }

                    break;
                }

                case ArrowDirection.Left: {
                    if ((arrows & LaneArrows.Left) != LaneArrows.None)
                    {
                        return(true);
                    }

                    break;
                }

                case ArrowDirection.Right: {
                    if ((arrows & LaneArrows.Right) != LaneArrows.None)
                    {
                        return(true);
                    }

                    break;
                }

                default: {
                    return(true);
                }
                }

                if (logLaneConnections)
                {
                    Log._Debug(
                        $"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                        $"processing connected segment {otherSegmentId}: need to determine arrows");
                }

                bool addArrow  = false;
                uint curLaneId = netManager.m_segments.m_buffer[otherSegmentId].m_lanes;

                while (curLaneId != 0)
                {
                    if (logLaneConnections)
                    {
                        Log._Debug(
                            $"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                            $"processing connected segment {otherSegmentId}: checking lane {curLaneId}");
                    }

                    if (AreLanesConnected(laneId, curLaneId, startNode))
                    {
                        if (logLaneConnections)
                        {
                            Log._Debug(
                                $"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                                $"processing connected segment {otherSegmentId}: checking lane " +
                                $"{curLaneId}: lanes are connected");
                        }

                        addArrow = true;
                        break;
                    }

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

                if (logLaneConnections)
                {
                    Log._Debug(
                        $"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                        $"processing connected segment {otherSegmentId}: finished processing " +
                        $"lanes. addArrow={addArrow} arrows (before)={arrows}");
                }

                if (!addArrow)
                {
                    return(true);
                }

                switch (dir)
                {
                case ArrowDirection.Turn: {
                    if (Constants.ServiceFactory.SimulationService.LeftHandDrive)
                    {
                        arrows |= LaneArrows.Right;
                    }
                    else
                    {
                        arrows |= LaneArrows.Left;
                    }

                    break;
                }

                case ArrowDirection.Forward: {
                    arrows |= LaneArrows.Forward;
                    break;
                }

                case ArrowDirection.Left: {
                    arrows |= LaneArrows.Left;
                    break;
                }

                case ArrowDirection.Right: {
                    arrows |= LaneArrows.Right;
                    break;
                }

                default: {
                    return(true);
                }
                }

                if (logLaneConnections)
                {
                    Log._Debug(
                        $"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                        $"processing connected segment {otherSegmentId}: arrows={arrows}");
                }

                return(true);
            });

            if (logLaneConnections)
            {
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): " +
                           $"setting lane arrows to {arrows}");
            }

            LaneArrowManager.Instance.SetLaneArrows(laneId, arrows, true);
        }
Example #29
0
        private Vector3 GetSnapDelta(Vector3 moveDelta, float angleDelta, Vector3 center, out bool autoCurve)
        {
            autoCurve = false;

            if (VectorUtils.XZ(moveDelta) == Vector2.zero)
            {
                return(moveDelta);
            }

            Vector3 newMoveDelta = moveDelta;

            NetManager netManager = NetManager.instance;

            NetSegment[] segmentBuffer  = netManager.m_segments.m_buffer;
            NetNode[]    nodeBuffer     = netManager.m_nodes.m_buffer;
            Building[]   buildingBuffer = BuildingManager.instance.m_buildings.m_buffer;

            Matrix4x4 matrix4x = default(Matrix4x4);

            matrix4x.SetTRS(center, Quaternion.AngleAxis(angleDelta * Mathf.Rad2Deg, Vector3.down), Vector3.one);

            bool snap = false;

            HashSet <InstanceState> newStates = null;

            if (ActionQueue.instance.current is TransformAction transformAction)
            {
                newStates = transformAction.CalculateStates(moveDelta, angleDelta, center, followTerrain);
            }

            if (ActionQueue.instance.current is CloneAction cloneAction)
            {
                newStates = cloneAction.CalculateStates(moveDelta, angleDelta, center, followTerrain);
            }

            // Snap to direction
            if (newStates.Count == 1)
            {
                foreach (InstanceState state in newStates)
                {
                    if (state.instance.id.Type == InstanceType.NetSegment)
                    {
                        return(SnapSegmentDirections(state.instance.id.NetSegment, state.position, moveDelta));
                    }
                    else if (state.instance.id.Type == InstanceType.NetNode)
                    {
                        if (TrySnapNodeDirections(state.instance.id.NetNode, state.position, moveDelta, out newMoveDelta, out autoCurve))
                        {
                            DebugUtils.Log("Snap to direction: " + moveDelta + ", " + newMoveDelta);
                            return(newMoveDelta);
                        }
                    }
                }
            }

            HashSet <ushort> ingnoreSegments = new HashSet <ushort>();
            HashSet <ushort> segmentList     = new HashSet <ushort>();

            ushort[] closeSegments = new ushort[16];

            // Get list of closest segments
            foreach (InstanceState state in newStates)
            {
                netManager.GetClosestSegments(state.position, closeSegments, out int closeSegmentCount);
                segmentList.UnionWith(closeSegments);

                if (ToolState != ToolStates.Cloning)
                {
                    ingnoreSegments.UnionWith(state.instance.segmentList);
                }
            }

            float distanceSq = float.MaxValue;

            // Snap to node
            foreach (ushort segment in segmentList)
            {
                if (!ingnoreSegments.Contains(segment))
                {
                    foreach (InstanceState state in newStates)
                    {
                        if (state.instance.id.Type == InstanceType.NetNode)
                        {
                            float minSqDistance = segmentBuffer[segment].Info.GetMinNodeDistance() / 2f;
                            minSqDistance *= minSqDistance;

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

                            snap = TrySnapping(nodeBuffer[startNode].m_position, state.position, minSqDistance, ref distanceSq, moveDelta, ref newMoveDelta) || snap;
                            snap = TrySnapping(nodeBuffer[endNode].m_position, state.position, minSqDistance, ref distanceSq, moveDelta, ref newMoveDelta) || snap;
                        }
                    }
                }
            }

            if (snap)
            {
                DebugUtils.Log("Snap to node: " + moveDelta + ", " + newMoveDelta);
                return(newMoveDelta);
            }

            // Snap to segment
            foreach (ushort segment in segmentList)
            {
                if (!ingnoreSegments.Contains(segment))
                {
                    foreach (InstanceState state in newStates)
                    {
                        if (state.instance.id.Type == InstanceType.NetNode)
                        {
                            float minSqDistance = segmentBuffer[segment].Info.GetMinNodeDistance() / 2f;
                            minSqDistance *= minSqDistance;

                            segmentBuffer[segment].GetClosestPositionAndDirection(state.position, out Vector3 testPos, out Vector3 direction);

                            snap = TrySnapping(testPos, state.position, minSqDistance, ref distanceSq, moveDelta, ref newMoveDelta) || snap;
                        }
                    }
                }
            }

            if (snap)
            {
                DebugUtils.Log("Snap to segment: " + moveDelta + ", " + newMoveDelta);
                return(newMoveDelta);
            }

            // Snap to grid
            ushort  block         = 0;
            ushort  previousBlock = 0;
            Vector3 refPosition   = Vector3.zero;
            bool    smallRoad     = false;

            foreach (ushort segment in segmentList)
            {
                bool hasBlocks = segment != 0 && (segmentBuffer[segment].m_blockStartLeft != 0 || segmentBuffer[segment].m_blockStartRight != 0 || segmentBuffer[segment].m_blockEndLeft != 0 || segmentBuffer[segment].m_blockEndRight != 0);
                if (hasBlocks && !ingnoreSegments.Contains(segment))
                {
                    foreach (InstanceState state in newStates)
                    {
                        if (state.instance.id.Type != InstanceType.NetSegment)
                        {
                            Vector3 testPosition = state.position;

                            if (state.instance.id.Type == InstanceType.Building)
                            {
                                ushort building = state.instance.id.Building;
                                testPosition = GetBuildingSnapPoint(state.position, state.angle, buildingBuffer[building].Length, buildingBuffer[building].Width);
                            }

                            segmentBuffer[segment].GetClosestZoneBlock(testPosition, ref distanceSq, ref block);

                            if (block != previousBlock)
                            {
                                refPosition = testPosition;

                                if (state.instance.id.Type == InstanceType.NetNode)
                                {
                                    if (nodeBuffer[state.instance.id.NetNode].Info.m_halfWidth <= 4f)
                                    {
                                        smallRoad = true;
                                    }
                                }

                                previousBlock = block;
                            }
                        }
                    }
                }
            }

            if (block != 0)
            {
                Vector3   newPosition = refPosition;
                ZoneBlock zoneBlock   = ZoneManager.instance.m_blocks.m_buffer[block];
                SnapToBlock(ref newPosition, zoneBlock.m_position, zoneBlock.m_angle, smallRoad);

                DebugUtils.Log("Snap to grid: " + moveDelta + ", " + (moveDelta + newPosition - refPosition));
                return(moveDelta + newPosition - refPosition);
            }

            // Snap to editor grid
            if ((ToolManager.instance.m_properties.m_mode & ItemClass.Availability.AssetEditor) != ItemClass.Availability.None)
            {
                Vector3 assetGridPosition = Vector3.zero;
                float   testMagnitude     = 0;

                foreach (InstanceState state in newStates)
                {
                    Vector3 testPosition = state.position;

                    if (state.instance.id.Type == InstanceType.Building)
                    {
                        ushort building = state.instance.id.Building;
                        testPosition = GetBuildingSnapPoint(state.position, state.angle, buildingBuffer[building].Length, buildingBuffer[building].Width);
                    }


                    float x = Mathf.Round(testPosition.x / 8f) * 8f;
                    float z = Mathf.Round(testPosition.z / 8f) * 8f;

                    Vector3 newPosition    = new Vector3(x, testPosition.y, z);
                    float   deltaMagnitude = (newPosition - testPosition).sqrMagnitude;

                    if (assetGridPosition == Vector3.zero || deltaMagnitude < testMagnitude)
                    {
                        refPosition       = testPosition;
                        assetGridPosition = newPosition;
                        deltaMagnitude    = testMagnitude;
                    }
                }

                DebugUtils.Log("Snap to grid: " + moveDelta + ", " + (moveDelta + assetGridPosition - refPosition));
                return(moveDelta + assetGridPosition - refPosition);
            }

            return(moveDelta);
        }
Example #30
0
        /// <summary>
        /// coppies vehicle restrictions of the current segment
        /// and applies them to all segments until the next junction.
        /// </summary>
        /// <param name="sortedLaneIndex">if provided only current lane is considered</param>
        /// <param name="vehicleTypes">
        /// if provided only bits for which vehicleTypes is set are considered.
        /// </param>
        private void ApplyRestrictionsToAllSegments(
            int?sortedLaneIndex         = null,
            ExtVehicleType?vehicleTypes = null)
        {
            NetManager netManager = Singleton <NetManager> .instance;

            NetInfo selectedSegmentInfo = netManager.m_segments.m_buffer[SelectedSegmentId].Info;

            bool LaneVisitorFun(SegmentLaneVisitData data)
            {
                if (data.SegVisitData.Initial)
                {
                    return(true);
                }

                if (sortedLaneIndex != null && data.SortedLaneIndex != sortedLaneIndex)
                {
                    return(true);
                }

                ushort  segmentId   = data.SegVisitData.CurSeg.segmentId;
                NetInfo segmentInfo = netManager.m_segments.m_buffer[segmentId].Info;

                byte selectedLaneIndex = data.InitLanePos.laneIndex;

                NetInfo.Lane selectedLaneInfo = selectedSegmentInfo.m_lanes[selectedLaneIndex];

                uint laneId    = data.CurLanePos.laneId;
                byte laneIndex = data.CurLanePos.laneIndex;

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

                // apply restrictions of selected segment & lane
                ExtVehicleType mask =
                    VehicleRestrictionsManager.Instance.GetAllowedVehicleTypes(
                        SelectedSegmentId,
                        selectedSegmentInfo,
                        selectedLaneIndex,
                        selectedLaneInfo,
                        VehicleRestrictionsMode.Configured);;

                if (vehicleTypes != null)
                {
                    ExtVehicleType currentMask =
                        VehicleRestrictionsManager.Instance.GetAllowedVehicleTypes(
                            segmentId,
                            segmentInfo,
                            laneIndex,
                            laneInfo,
                            VehicleRestrictionsMode.Configured);

                    // only apply changes where types is 1. that means:
                    // for bits where types is 0, use currentMask,
                    // for bits where types is 1, use initial mask.
                    ExtVehicleType types2 = (ExtVehicleType)vehicleTypes; //cast
                    mask = (types2 & mask) | (~types2 & currentMask);
                }

                VehicleRestrictionsManager.Instance.SetAllowedVehicleTypes(
                    segmentId,
                    segmentInfo,
                    laneIndex,
                    laneInfo,
                    laneId,
                    mask);

                RefreshCurrentRestrictedSegmentIds(segmentId);

                return(true);
            }

            SegmentLaneTraverser.Traverse(
                SelectedSegmentId,
                SegmentTraverser.TraverseDirection.AnyDirection,
                SegmentTraverser.TraverseSide.AnySide,
                SegmentLaneTraverser.LaneStopCriterion.LaneCount,
                SegmentTraverser.SegmentStopCriterion.Junction,
                VehicleRestrictionsManager.LANE_TYPES,
                VehicleRestrictionsManager.VEHICLE_TYPES,
                LaneVisitorFun);
        }
	void Awake () {
		net = gameObject.AddComponent<NetManager> ();
		net.Init ();

		net.messageReceived += ReceiveMessageFromClient;
		net.onUpdateConnection += OnUpdateConnection;
		net.onSocketDisconnected += OnSocketDisconnect;
	}
Example #32
0
 // Use this for initialization
 void Start()
 {
     net = NetManager.Instance;
     settings = GameSettings.Instance;
 }
 void Awake()
 {
     if (instance == null)
     {
         instance = this;
         DontDestroyOnLoad(gameObject);
         messenger = new Messenger();
     }
     else
     {
         Destroy(gameObject);
     }
 }
Example #34
0
        void HandleMouseDrag(ref ToolBase.RaycastOutput raycastOutput, ref ToolError error, bool test, ref NetInfo newRoadPrefab, ref int newSegmentIndex)
        {
            Vector3 hitPosDelta = Vector3.zero;

            if (!test)
            {
                if (currentTime - prevRebuildTime < 0.1f)
                {
                    return;
                }

                if (dragging)
                {
                    hitPosDelta = raycastOutput.m_hitPos - prevHitPos;
                    if (hitPosDelta.magnitude < 12.0f)
                    {
                        return;
                    }
                }
                else
                {
                    prevHitPos = raycastOutput.m_hitPos;
                    dragging   = true;
                    if (toolMode == ToolMode.Oneway)
                    {
                        return;
                    }
                }

                prevHitPos = raycastOutput.m_hitPos;
            }

            int segmentIndex = raycastOutput.m_netSegment;

            if (segmentIndex != 0)
            {
                NetManager net    = Singleton <NetManager> .instance;
                NetInfo    prefab = net.m_segments.m_buffer[segmentIndex].Info;

                bool isOneway = !prefab.m_hasForwardVehicleLanes || !prefab.m_hasBackwardVehicleLanes;


                string prefabName = null;
                if (!roadPrefabNames.TryGetValue(prefab.GetInstanceID(), out prefabName) || prefabName == null)
                {
                    ModDebug.Error("Prefab name not found");
                    error = ToolError.Unknown;
                    return;
                }

                string newPrefabName = null;
                if (toolMode == ToolMode.Oneway)
                {
                    if (!isOneway)
                    {
                        newPrefabName = FindMatchingName(prefabName, twowayNames, onewayNames);
                    }
                    else
                    {
                        newPrefabName = prefabName;
                    }
                }
                else
                {
                    if (isOneway)
                    {
                        newPrefabName = FindMatchingName(prefabName, onewayNames, twowayNames);
                    }
                    else
                    {
                        toolError = ToolError.AlreadyTwoway;
                        return;
                    }
                }

                if (newPrefabName != null)
                {
                    if (test)
                    {
                        toolError = ToolError.None;
                        return;
                    }

                    NetInfo newPrefab;
                    if (!roadPrefabs.TryGetValue(newPrefabName, out newPrefab) || newPrefab == null)
                    {
                        ModDebug.Error("Prefab not found: " + newPrefabName);
                        error = ToolError.Unknown;
                        return;
                    }

                    newRoadPrefab = newPrefab;

                    int newIndex = RebuildSegment(segmentIndex, newPrefab, toolMode == ToolMode.Oneway, raycastOutput.m_hitPos, hitPosDelta, ref error);

                    if (newIndex != 0)
                    {
                        if (error != ToolError.None)
                        {
                            return;
                        }

                        prevBuiltSegmentIndex = newSegmentIndex;
                        prevRebuildTime       = currentTime;
                        newSegmentIndex       = newIndex;
                    }
                }
                else
                {
                    toolError = ToolError.CannotUpgradeThisType;
                    return;
                }
            }
        }
 //public static bool newLogin;
 // Use this for initialization
 void Start()
 {
     manager = GameObject.Find("NetManager").GetComponent<NetManager>();
     manager.AskForLevels(0);
 }
Example #36
0
 // Use this for initialization
 void Start()
 {
     net = NetManager.Instance;
 }
Example #37
0
 public DebugInfo(NetManager mgr) : base(mgr)
 {
 }
Example #38
0
        int RebuildSegment(int segmentIndex, NetInfo newPrefab, bool roadDirectionMatters, Vector3 directionPoint, Vector3 direction, ref ToolError error)
        {
            NetManager net = Singleton <NetManager> .instance;

            NetInfo prefab = net.m_segments.m_buffer[segmentIndex].Info;

            NetTool.ControlPoint startPoint;
            NetTool.ControlPoint middlePoint;
            NetTool.ControlPoint endPoint;
            GetSegmentControlPoints(segmentIndex, out startPoint, out middlePoint, out endPoint);

            if (direction.magnitude > 0.0f)
            {
                float dot       = Vector3.Dot(direction.normalized, (endPoint.m_position - startPoint.m_position).normalized);
                float threshold = Mathf.Cos(Mathf.PI / 4);

                if (dot > -threshold && dot < threshold)
                {
                    return(0);
                }

                if (roadDirectionMatters)
                {
                    bool inverted = (net.m_segments.m_buffer[segmentIndex].m_flags & NetSegment.Flags.Invert) != 0;

                    if (Singleton <SimulationManager> .instance.m_metaData.m_invertTraffic == SimulationMetaData.MetaBool.True)
                    {
                        inverted = !inverted; // roads need to be placed in the opposite direction with left-hand traffic
                    }

                    bool reverseDirection = inverted ? (dot > 0.0f) : (dot < -0.0f);

                    if (reverseDirection)
                    {
                        var tmp = startPoint;
                        startPoint = endPoint;
                        endPoint   = tmp;

                        startPoint.m_direction  = -startPoint.m_direction;
                        endPoint.m_direction    = -endPoint.m_direction;
                        middlePoint.m_direction = startPoint.m_direction;
                    }
                    else
                    {
                        if (prefab == newPrefab)
                        {
                            error = ToolError.SameDirection;
                            return(0);
                        }
                    }
                }
            }

            bool test      = false;
            bool visualize = false;
            bool autoFix   = true;
            bool needMoney = false;
            bool invert    = false;

            ushort node           = 0;
            ushort segment        = 0;
            int    cost           = 0;
            int    productionRate = 0;

            NetTool.CreateNode(newPrefab, startPoint, middlePoint, endPoint, NetTool.m_nodePositionsSimulation, 1000, test, visualize, autoFix, needMoney, invert, false, (ushort)0, out node, out segment, out cost, out productionRate);

            if (segment != 0)
            {
                if (newPrefab.m_class.m_service == ItemClass.Service.Road)
                {
                    Singleton <CoverageManager> .instance.CoverageUpdated(ItemClass.Service.None, ItemClass.SubService.None, ItemClass.Level.None);
                }

                error = ToolError.None;
                return(segment);
            }

            return(0);
        }
Example #39
0
 // Use this for initialization
 void Awake()
 {
     Instance = this;
 }
Example #40
0
 public View Build(NetManager mgr)
 {
     return(new DebugInfo(mgr));
 }
Example #41
0
 public HeartbeatMgr(NetManager netMgr)
 {
     _netMgr = netMgr;
 }
        // simplified assuming its called by NetSegment.CalculateCornerOffset.
        public static void CalculateCorner(
            NetInfo info, Vector3 startPos, Vector3 endPos, Vector3 startDir, Vector3 endDir,
            ushort ignoreSegmentID, ushort startNodeID, bool heightOffset, bool leftSide,
            out Vector3 cornerPos, out Vector3 cornerDirection, out bool smooth)
        {
            NetManager instance = Singleton <NetManager> .instance;
            Bezier3    bezier   = default(Bezier3);
            Bezier3    bezier2  = default(Bezier3);

            NetNode.Flags flags = NetNode.Flags.End;
            flags = instance.m_nodes.m_buffer[(int)startNodeID].m_flags;
            ushort startNodeBuildingID = startNodeID.ToNode().m_building;

            cornerDirection = startDir;
            smooth          = flags.IsFlagSet(NetNode.Flags.Middle);

            float hw = info.m_halfWidth;

            if (!leftSide)
            {
                hw = -hw;
            }

            if (flags.IsFlagSet(NetNode.Flags.Middle))
            {
                for (int i = 0; i < 8; ++i)
                {
                    ushort segmentID = startNodeID.ToNode().GetSegment(i);
                    if (segmentID == 0 || segmentID == ignoreSegmentID)
                    {
                        continue;
                    }
                    Vector3 dir = segmentID.ToSegment().GetDirection(startNodeID);
                    cornerDirection = VectorUtils.NormalizeXZ(cornerDirection - dir);
                    break;
                }
            }

            Vector3 dirAcross = Vector3.Cross(cornerDirection, Vector3.up).normalized;
            Vector3 VV1       = dirAcross;

            if (info.m_twistSegmentEnds)
            {
                if (startNodeBuildingID != 0)
                {
                    float   angle = Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)startNodeBuildingID].m_angle;
                    Vector3 v     = new Vector3(Mathf.Cos(angle), 0f, Mathf.Sin(angle));
                    VV1 = (Vector3.Dot(VV1, v) < 0f) ? (-v) : v;
                }
                else if (flags.IsFlagSet(NetNode.Flags.Junction))
                {
                    Vector3 v = default;
                    int     untouchableCount = 0;
                    for (int i = 0; i < 8; i++)
                    {
                        ushort segmentID = startNodeID.ToNode().GetSegment(i);
                        if (segmentID == 0 || segmentID == ignoreSegmentID)
                        {
                            continue;
                        }

                        if (segmentID.ToSegment().m_flags.IsFlagSet(NetSegment.Flags.Untouchable))
                        {
                            Vector3 dir = segmentID.ToSegment().GetDirection(startNodeID);
                            v = new Vector3(dir.z, 0f, -dir.x); // rotate vector by 90 degree and remove vertical element.
                            untouchableCount++;
                        }
                    }
                    if (untouchableCount == 1)
                    {
                        VV1 = ((Vector3.Dot(VV1, v) < 0f) ? (-v) : v);
                    }
                }
            }

            bezier.a  = startPos + VV1 * hw;
            bezier2.a = startPos - VV1 * hw;
            cornerPos = bezier.a;
            if (
                (flags.IsFlagSet(NetNode.Flags.Junction) && info.m_clipSegmentEnds) ||
                flags.IsFlagSet(NetNode.Flags.Bend | NetNode.Flags.End)
                )
            {
                VV1       = Vector3.Cross(endDir, Vector3.up).normalized;
                bezier.d  = endPos - VV1 * hw;
                bezier2.d = endPos + VV1 * hw;
                NetSegment.CalculateMiddlePoints(bezier.a, cornerDirection, bezier.d, endDir, false, false, out bezier.b, out bezier.c);
                NetSegment.CalculateMiddlePoints(bezier2.a, cornerDirection, bezier2.d, endDir, false, false, out bezier2.b, out bezier2.c);
                Bezier2 bezier3 = Bezier2.XZ(bezier);
                Bezier2 bezier4 = Bezier2.XZ(bezier2);
                float   num5    = -1f;
                float   num6    = -1f;
                bool    flag    = false;
                float   a       = info.m_halfWidth * 0.5f;

                int segmentCount = 0;
                for (int i = 0; i < 8; ++i)
                {
                    ushort segmentID = startNodeID.ToNode().GetSegment(i);
                    if (segmentID == 0 || segmentID == ignoreSegmentID)
                    {
                        continue;
                    }
                    Vector3 vector4 = instance.m_segments.m_buffer[(int)segmentID].GetDirection(startNodeID);
                    NetInfo netInfo = instance.m_segments.m_buffer[(int)segmentID].Info;
                    if (netInfo == null)
                    {
                        continue;
                    }
                    if (info.m_clipSegmentEnds != netInfo.m_clipSegmentEnds)
                    {
                        continue;
                    }
                    if (netInfo.m_netAI.GetSnapElevation() > info.m_netAI.GetSnapElevation())
                    {
                        float num10 = 0.01f - Mathf.Min(info.m_maxTurnAngleCos, netInfo.m_maxTurnAngleCos);
                        float num11 = vector4.x * startDir.x + vector4.z * startDir.z;
                        if ((info.m_vehicleTypes & netInfo.m_vehicleTypes) == VehicleInfo.VehicleType.None || num11 >= num10)
                        {
                            continue;
                        }
                    }
                    a = Mathf.Max(a, netInfo.m_halfWidth * 0.5f);
                    segmentCount++;
                }
                if (segmentCount >= 1 || flags.IsFlagSet(NetNode.Flags.Outside))
                {
                    for (int i = 0; i < 8; ++i)
                    {
                        ushort segmentID = startNodeID.ToNode().GetSegment(i);
                        if (segmentID == 0 || segmentID == ignoreSegmentID)
                        {
                            continue;
                        }
                        ushort  startNode2 = instance.m_segments.m_buffer[(int)segmentID].m_startNode;
                        ushort  num12      = instance.m_segments.m_buffer[(int)segmentID].m_endNode;
                        Vector3 vector6    = instance.m_segments.m_buffer[(int)segmentID].m_startDirection;
                        Vector3 vector7    = instance.m_segments.m_buffer[(int)segmentID].m_endDirection;
                        if (startNodeID != startNode2)
                        {
                            num12 = startNode2;
                            //swap
                            Vector3 temp = vector6;
                            vector6 = vector7;
                            vector7 = temp;
                        }
                        NetInfo netInfo = instance.m_segments.m_buffer[(int)segmentID].Info;
                        if (netInfo == null)
                        {
                            continue;
                        }
                        if (info.m_clipSegmentEnds != netInfo.m_clipSegmentEnds)
                        {
                            continue;
                        }
                        Vector3 vector5 = instance.m_nodes.m_buffer[(int)num12].m_position;
                        if (netInfo.m_netAI.GetSnapElevation() > info.m_netAI.GetSnapElevation())
                        {
                            float num14 = 0.01f - Mathf.Min(info.m_maxTurnAngleCos, netInfo.m_maxTurnAngleCos);
                            float num15 = vector6.x * startDir.x + vector6.z * startDir.z;
                            if ((info.m_vehicleTypes & netInfo.m_vehicleTypes) == VehicleInfo.VehicleType.None || num15 >= num14)
                            {
                                continue;
                            }
                        }
                        if (vector6.z * cornerDirection.x - vector6.x * cornerDirection.z > 0f == leftSide)
                        {
                            Bezier3 bezier5 = default(Bezier3);
                            float   num16   = Mathf.Max(a, netInfo.m_halfWidth);
                            if (!leftSide)
                            {
                                num16 = -num16;
                            }
                            VV1       = Vector3.Cross(vector6, Vector3.up).normalized;
                            bezier5.a = startPos - VV1 * num16;
                            VV1       = Vector3.Cross(vector7, Vector3.up).normalized;
                            bezier5.d = vector5 + VV1 * num16;
                            NetSegment.CalculateMiddlePoints(bezier5.a, vector6, bezier5.d, vector7, false, false, out bezier5.b, out bezier5.c);
                            Bezier2 b2 = Bezier2.XZ(bezier5);
                            float   b3;
                            float   num17;
                            if (bezier3.Intersect(b2, out b3, out num17, 6))
                            {
                                num5 = Mathf.Max(num5, b3);
                            }
                            else if (bezier3.Intersect(b2.a, b2.a - VectorUtils.XZ(vector6) * 16f, out b3, out num17, 6))
                            {
                                num5 = Mathf.Max(num5, b3);
                            }
                            else if (b2.Intersect(bezier3.d + (bezier3.d - bezier4.d) * 0.01f, bezier4.d, out b3, out num17, 6))
                            {
                                num5 = Mathf.Max(num5, 1f);
                            }
                            float num18 = cornerDirection.x * vector6.x + cornerDirection.z * vector6.z;
                            if (num18 >= -0.75f)
                            {
                                flag = true;
                            }
                        }

                        Bezier3 bezier6 = default(Bezier3);
                        float   num19   = cornerDirection.x * vector6.x + cornerDirection.z * vector6.z;
                        if (num19 >= 0f)
                        {
                            vector6.x -= cornerDirection.x * num19 * 2f;
                            vector6.z -= cornerDirection.z * num19 * 2f;
                        }
                        float num20 = Mathf.Max(a, netInfo.m_halfWidth);
                        if (!leftSide)
                        {
                            num20 = -num20;
                        }
                        VV1       = Vector3.Cross(vector6, Vector3.up).normalized;
                        bezier6.a = startPos + VV1 * num20;
                        VV1       = Vector3.Cross(vector7, Vector3.up).normalized;
                        bezier6.d = vector5 - VV1 * num20;
                        NetSegment.CalculateMiddlePoints(bezier6.a, vector6, bezier6.d, vector7, false, false, out bezier6.b, out bezier6.c);
                        Bezier2 b4 = Bezier2.XZ(bezier6);
                        float   b5;
                        float   num21;
                        if (bezier4.Intersect(b4, out b5, out num21, 6))
                        {
                            num6 = Mathf.Max(num6, b5);
                            continue;
                        }
                        if (bezier4.Intersect(b4.a, b4.a - VectorUtils.XZ(vector6) * 16f, out b5, out num21, 6))
                        {
                            num6 = Mathf.Max(num6, b5);
                            continue;
                        }
                        if (b4.Intersect(bezier3.d, bezier4.d + (bezier4.d - bezier3.d) * 0.01f, out b5, out num21, 6))
                        {
                            num6 = Mathf.Max(num6, 1f);
                            continue;
                        }
                        continue;
                    }
                    if ((flags & NetNode.Flags.Junction) != NetNode.Flags.None)
                    {
                        if (!flag)
                        {
                            num5 = Mathf.Max(num5, num6);
                        }
                    }
                    else if ((flags & NetNode.Flags.Bend) != NetNode.Flags.None && !flag)
                    {
                        num5 = Mathf.Max(num5, num6);
                    }
                    if ((flags & NetNode.Flags.Outside) != NetNode.Flags.None)
                    {
                        float   num22    = 8640f;
                        Vector2 vector9  = new Vector2(-num22, -num22);
                        Vector2 vector10 = new Vector2(-num22, num22);
                        Vector2 vector11 = new Vector2(num22, num22);
                        Vector2 vector12 = new Vector2(num22, -num22);
                        float   b6;
                        float   num23;
                        if (bezier3.Intersect(vector9, vector10, out b6, out num23, 6))
                        {
                            num5 = Mathf.Max(num5, b6);
                        }
                        if (bezier3.Intersect(vector10, vector11, out b6, out num23, 6))
                        {
                            num5 = Mathf.Max(num5, b6);
                        }
                        if (bezier3.Intersect(vector11, vector12, out b6, out num23, 6))
                        {
                            num5 = Mathf.Max(num5, b6);
                        }
                        if (bezier3.Intersect(vector12, vector9, out b6, out num23, 6))
                        {
                            num5 = Mathf.Max(num5, b6);
                        }
                        num5 = Mathf.Clamp01(num5);
                    }
                    else
                    {
                        if (num5 < 0f)
                        {
                            if (info.m_halfWidth < 4f)
                            {
                                num5 = 0f;
                            }
                            else
                            {
                                num5 = bezier3.Travel(0f, 8f);
                            }
                        }
                        float num24 = info.m_minCornerOffset;
                        if ((flags & (NetNode.Flags.AsymForward | NetNode.Flags.AsymBackward)) != NetNode.Flags.None)
                        {
                            num24 = Mathf.Max(num24, 8f);
                        }
                        num5 = Mathf.Clamp01(num5);
                        float num25 = VectorUtils.LengthXZ(bezier.Position(num5) - bezier.a);
                        num5 = bezier3.Travel(num5, Mathf.Max(num24 - num25, 2f));
                        if (info.m_straightSegmentEnds)
                        {
                            if (num6 < 0f)
                            {
                                if (info.m_halfWidth < 4f)
                                {
                                    num6 = 0f;
                                }
                                else
                                {
                                    num6 = bezier4.Travel(0f, 8f);
                                }
                            }
                            num6  = Mathf.Clamp01(num6);
                            num25 = VectorUtils.LengthXZ(bezier2.Position(num6) - bezier2.a);
                            num6  = bezier4.Travel(num6, Mathf.Max(info.m_minCornerOffset - num25, 2f));
                            num5  = Mathf.Max(num5, num6);
                        }
                    }
                    float y = cornerDirection.y;
                    cornerDirection   = bezier.Tangent(num5);
                    cornerDirection.y = 0f;
                    cornerDirection.Normalize();
                    if (!info.m_flatJunctions)
                    {
                        cornerDirection.y = y;
                    }
                    cornerPos   = bezier.Position(num5);
                    cornerPos.y = startPos.y;
                }
            }
            else if ((flags & NetNode.Flags.Junction) != NetNode.Flags.None && info.m_minCornerOffset >= 0.01f)
            {
                VV1       = Vector3.Cross(endDir, Vector3.up).normalized;
                bezier.d  = endPos - VV1 * hw;
                bezier2.d = endPos + VV1 * hw;
                NetSegment.CalculateMiddlePoints(bezier.a, cornerDirection, bezier.d, endDir, false, false, out bezier.b, out bezier.c);
                NetSegment.CalculateMiddlePoints(bezier2.a, cornerDirection, bezier2.d, endDir, false, false, out bezier2.b, out bezier2.c);
                Bezier2 bezier7 = Bezier2.XZ(bezier);
                Bezier2 bezier8 = Bezier2.XZ(bezier2);
                float   num26;
                if (info.m_halfWidth < 4f)
                {
                    num26 = 0f;
                }
                else
                {
                    num26 = bezier7.Travel(0f, 8f);
                }
                num26 = Mathf.Clamp01(num26);
                float num27 = VectorUtils.LengthXZ(bezier.Position(num26) - bezier.a);
                num26 = bezier7.Travel(num26, Mathf.Max(info.m_minCornerOffset - num27, 2f));
                if (info.m_straightSegmentEnds)
                {
                    float num28;
                    if (info.m_halfWidth < 4f)
                    {
                        num28 = 0f;
                    }
                    else
                    {
                        num28 = bezier8.Travel(0f, 8f);
                    }
                    num28 = Mathf.Clamp01(num28);
                    num27 = VectorUtils.LengthXZ(bezier2.Position(num28) - bezier2.a);
                    num28 = bezier8.Travel(num28, Mathf.Max(info.m_minCornerOffset - num27, 2f));
                    num26 = Mathf.Max(num26, num28);
                }
                float y2 = cornerDirection.y;
                cornerDirection   = bezier.Tangent(num26);
                cornerDirection.y = 0f;
                cornerDirection.Normalize();
                if (!info.m_flatJunctions)
                {
                    cornerDirection.y = y2;
                }
                cornerPos   = bezier.Position(num26);
                cornerPos.y = startPos.y;
            }
            if (heightOffset && startNodeID != 0)
            {
                cornerPos.y += (float)instance.m_nodes.m_buffer[(int)startNodeID].m_heightOffset * 0.015625f;
            }
        }
Example #43
0
 // Use this for initialization
 void Start()
 {
     Debug.Log("GameLogic Start");
     m_netManager = m_objGameLogic.AddComponent<NetManager>();
 }
        internal void PacketItem_UserItem(CActionItem_Item pActionItem, int targetServerID, Vector2 fvPos)
        {
            //空物品
            if (pActionItem == null || pActionItem.GetType() != ACTION_OPTYPE.AOT_ITEM)
            {
                return;
            }
            CObject_Item pItem = pActionItem.ItemImpl;

            if (pItem == null)
            {
                return;
            }
            //必须是能够使用的物品
            if (pItem.GetItemClass() != ITEM_CLASS.ICLASS_COMITEM && pItem.GetItemClass() != ITEM_CLASS.ICLASS_TASKITEM)
            {
                return;
            }

            //特殊物品不能在背包中直接使用,例如,宠物技能书
//          STRING strTemp;
//          if(!CObject_Item::CheckUseInPackage(pItem, strTemp))
//          {
//              if(!strTemp.empty()) CGameProcedure::s_pEventSystem->PushEvent(GE_INFO_SELF, strTemp.c_str());
//              return;
//          }
            //组队跟随中...
            //if(CObjectManager::GetMe()->GetMySelf()->GetCharacterData()->Get_TeamFollowFlag()) return;

            //检查目前选中的目标
            CObject pObj = CObjectManager.Instance.FindServerObject(targetServerID);

            //检查物品是否能够直接使用
            int        objID = 0;
            PET_GUID_t petID = new PET_GUID_t();
            fVector2   pos;

            pos.x = fvPos.x;
            pos.y = fvPos.y;
            bool bCanuseDir = ((CObject_Item_Medicine)pItem).IsValidTarget(pObj, ref pos, ref objID, ref petID);

            if (bCanuseDir)
            {
                WORLD_POS posTarget;
                posTarget.m_fX = pos.x;
                posTarget.m_fZ = pos.y;

                //能够直接使用
                CGUseItem msg = new CGUseItem();
                msg.BagIndex      = (byte)pItem.GetPosIndex();
                msg.Target        = (uint)objID;
                msg.TargetPetGUID = petID;
                msg.PosTarget     = posTarget;
                NetManager.GetNetManager().SendPacket(msg);
                return;
            }

            //如果已经选中目标,说明目标不合适,如果是用在自己宠物上的物品,说明宠物没有释放
            if (pObj != null || ((CObject_Item_Medicine)pItem).IsTargetOne())
            {
                CEventSystem.Instance.PushEvent(GAME_EVENT_ID.GE_INFO_SELF, "无效目标");
                return;
            }

            //需要选中目标,在鼠标上挂上物品
            CActionSystem.Instance.SetDefaultAction(pActionItem);
        }