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; }
// 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; } }
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; }
static Services() { NetManager = new NetManager(); DeviceModelManager = new DeviceModelManager(); DeviceManager = new DeviceManager(); }
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 }
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; }
public UserViewer(NetManager mgr) : base(mgr) { }
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); } }
public View Build(NetManager mgr) { return(new UserViewer(mgr)); }
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(); }
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; }
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); }
/// <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); } }
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); }
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 } }
/// <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); }
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); }
/// <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; }
// 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); } }
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); }
// Use this for initialization void Start() { net = NetManager.Instance; }
public DebugInfo(NetManager mgr) : base(mgr) { }
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); }
// Use this for initialization void Awake() { Instance = this; }
public View Build(NetManager mgr) { return(new DebugInfo(mgr)); }
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; } }
// 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); }