diff --git a/README.md b/README.md index e343c0e9..dab43425 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,16 @@ A work-in-progress modification for **Cities: Skylines** to add additional traff User manual: http://www.viathinksoft.de/tmpe # Changelog -1.9.0, 04/09/2017 +1.9.2, 05/20/2017 +- UI: Main menu & UI tools performance improved +- Bugfix: Traffic lights can be removed from junctions that are controlled by a timed traffic light program + +1.9.1, 05/19/2017 +- Updated French, Dutch and Korean translation +- Bugfix: Using the vanilla traffic light toggling feature crashes the game if TMPE's main menu has not been opened at least once +- Bugfix: AI: More car traffic and less public transportation present than in vanilla + +1.9.0, 05/18/2017 - Updated for game version 1.7.0-f5 - New feature: Parking restrictions - New feature: Speed limits can be set up for individual lanes with the Control key @@ -19,9 +28,10 @@ User manual: http://www.viathinksoft.de/tmpe - Path-finding cost multiplicator for vehicle restrictions is now configurable in TMPE_GlobalConfig.xml - UI: More compact, movable main menu UI - Added support for custom languages +- Added Korean translation (thanks to @Toothless FLY [ROK]LSh.st for translating) - Updated translations: German, Polish, Russian, Portuguese, Traditional Chinese - Major code refactorings -- AI: Tuned parameters +- AI: Tuned path-finding parameters - New option: Main button position can be locked - New option: Main menu position can be locked - New option: Added language selection in options dialog diff --git a/TLM/TLM/Custom/PathFinding/CustomPathFind.cs b/TLM/TLM/Custom/PathFinding/CustomPathFind.cs index 1d7b2ab7..a6e24fc6 100644 --- a/TLM/TLM/Custom/PathFinding/CustomPathFind.cs +++ b/TLM/TLM/Custom/PathFinding/CustomPathFind.cs @@ -1596,7 +1596,7 @@ private bool ProcessItemCosts(bool debug, bool allowAdvancedAI, bool obeyStockLa Randomizer randomizer = new Randomizer(this._pathFindIndex << 16 | (uint)item.m_position.m_segment); prevCost *= (float)(randomizer.Int32(900, 1000 + (int)(prevSegment.m_trafficDensity * 10)) + this._pathRandomizer.Int32(20u)) * 0.001f; } else { - prevCost *= (1f - _conf.SpeedCostFactor) + _conf.SpeedCostFactor * (1f - prevSpeed); + prevCost *= 1f + _conf.SpeedCostFactor * (1f - prevSpeed); } } diff --git a/TLM/TLM/Geometry/SegmentEndGeometry.cs b/TLM/TLM/Geometry/SegmentEndGeometry.cs index 5d44f383..7840b4e6 100644 --- a/TLM/TLM/Geometry/SegmentEndGeometry.cs +++ b/TLM/TLM/Geometry/SegmentEndGeometry.cs @@ -337,6 +337,10 @@ internal void Recalculate(GeometryCalculationMode calcMode) { IncomingOneWay = true; } OnlyHighways = true; +#if DEBUGGEO + if (GlobalConfig.Instance.DebugSwitches[5]) + Log._Debug($"Checking if segment {SegmentId} is connected to highways only at node {NodeId()}. OnlyHighways={OnlyHighways}"); +#endif //ItemClass connectionClass = netManager.m_segments.m_buffer[SegmentId].Info.GetConnectionClass(); @@ -362,8 +366,13 @@ internal void Recalculate(GeometryCalculationMode calcMode) { bool otherIsOneWay; bool otherIsOutgoingOneWay; SegmentGeometry.calculateOneWayAtNode(otherSegmentId, nodeId, out otherIsOneWay, out otherIsOutgoingOneWay); + bool otherIsHighway = SegmentGeometry.calculateIsHighway(otherSegmentId); - if (!(SegmentGeometry.calculateIsHighway(otherSegmentId) && otherIsOneWay)) +#if DEBUGGEO + if (GlobalConfig.Instance.DebugSwitches[5]) + Log._Debug($"Segment {SegmentId} is connected to segment {otherSegmentId} at node {NodeId()}. otherIsOneWay={otherIsOneWay} otherIsOutgoingOneWay={otherIsOutgoingOneWay} otherIsHighway={otherIsHighway}"); +#endif + if (! otherIsHighway || ! otherIsOneWay) OnlyHighways = false; if (IsRightSegment(SegmentId, otherSegmentId, nodeId)) { @@ -404,8 +413,13 @@ internal void Recalculate(GeometryCalculationMode calcMode) { NumIncomingSegments = (byte)(NumIncomingLeftSegments + NumIncomingStraightSegments + NumIncomingRightSegments); NumOutgoingSegments = (byte)(NumOutgoingLeftSegments + NumOutgoingStraightSegments + NumOutgoingRightSegments); - if (!hasOtherSegments) + if (!hasOtherSegments) { +#if DEBUGGEO + if (GlobalConfig.Instance.DebugSwitches[5]) + Log._Debug($"Segment {SegmentId} is not connected to any other segments at node {NodeId()}."); +#endif OnlyHighways = false; + } // propagate information to other segments if (calcMode == GeometryCalculationMode.Init || (calcMode == GeometryCalculationMode.Propagate && nodeIdBeforeRecalc != nodeId)) { diff --git a/TLM/TLM/Geometry/SegmentGeometry.cs b/TLM/TLM/Geometry/SegmentGeometry.cs index c2b3abd8..b9b5ba38 100644 --- a/TLM/TLM/Geometry/SegmentGeometry.cs +++ b/TLM/TLM/Geometry/SegmentGeometry.cs @@ -1036,6 +1036,7 @@ public ArrowDirection GetDirection(ushort otherSegmentId, bool startNode) { /// /// /// + [Obsolete] public bool AreHighwayRulesEnabled(bool startNode) { if (!Options.highwayRules) return false; @@ -1086,9 +1087,14 @@ internal static bool calculateIsOutgoingOneWay(ushort segmentId, ushort nodeId) var laneId = instance.m_segments.m_buffer[segmentId].m_lanes; var laneIndex = 0; while (laneIndex < info.m_lanes.Length && laneId != 0u) { - if (info.m_lanes[laneIndex].m_laneType != NetInfo.LaneType.Pedestrian && - ((info.m_lanes[laneIndex].m_finalDirection & dir) != NetInfo.Direction.None)) { - return false; + bool validLane = (info.m_lanes[laneIndex].m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) != NetInfo.LaneType.None && + (info.m_lanes[laneIndex].m_vehicleType & (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Metro | VehicleInfo.VehicleType.Monorail)) != VehicleInfo.VehicleType.None; + // TODO the lane types and vehicle types should be specified to make it clear which lanes we need to check + + if (validLane) { + if ((info.m_lanes[laneIndex].m_finalDirection & dir) != NetInfo.Direction.None) { + return false; + } } laneId = instance.m_lanes.m_buffer[laneId].m_nextLane; @@ -1116,18 +1122,22 @@ private static bool calculateIsOneWay(ushort segmentId) { var laneId = instance.m_segments.m_buffer[segmentId].m_lanes; var laneIndex = 0; while (laneIndex < info.m_lanes.Length && laneId != 0u) { - if (info.m_lanes[laneIndex].m_laneType != NetInfo.LaneType.Pedestrian && - (info.m_lanes[laneIndex].m_direction & NetInfo.Direction.Forward) != NetInfo.Direction.None) { - hasForward = true; - } + bool validLane = (info.m_lanes[laneIndex].m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) != NetInfo.LaneType.None && + (info.m_lanes[laneIndex].m_vehicleType & (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Metro | VehicleInfo.VehicleType.Monorail)) != VehicleInfo.VehicleType.None; + // TODO the lane types and vehicle types should be specified to make it clear which lanes we need to check - if (info.m_lanes[laneIndex].m_laneType != NetInfo.LaneType.Pedestrian && - (info.m_lanes[laneIndex].m_direction & NetInfo.Direction.Backward) != NetInfo.Direction.None) { - hasBackward = true; - } + if (validLane) { + if ((info.m_lanes[laneIndex].m_direction & NetInfo.Direction.Forward) != NetInfo.Direction.None) { + hasForward = true; + } + + if ((info.m_lanes[laneIndex].m_direction & NetInfo.Direction.Backward) != NetInfo.Direction.None) { + hasBackward = true; + } - if (hasForward && hasBackward) { - return false; + if (hasForward && hasBackward) { + return false; + } } laneId = instance.m_lanes.m_buffer[(int)((UIntPtr)laneId)].m_nextLane; @@ -1192,19 +1202,22 @@ internal static void calculateOneWayAtNode(ushort segmentId, ushort nodeId, out var laneId = instance.m_segments.m_buffer[segmentId].m_lanes; var laneIndex = 0; while (laneIndex < info.m_lanes.Length && laneId != 0u) { - if (info.m_lanes[laneIndex].m_laneType != NetInfo.LaneType.Pedestrian && - (info.m_lanes[laneIndex].m_finalDirection & dir2) != NetInfo.Direction.None) { - isOutgoingOneWay = false; - } + bool validLane = (info.m_lanes[laneIndex].m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) != NetInfo.LaneType.None && + (info.m_lanes[laneIndex].m_vehicleType & (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Metro | VehicleInfo.VehicleType.Monorail)) != VehicleInfo.VehicleType.None; + // TODO the lane types and vehicle types should be specified to make it clear which lanes we need to check - if (info.m_lanes[laneIndex].m_laneType != NetInfo.LaneType.Pedestrian && - (info.m_lanes[laneIndex].m_direction & NetInfo.Direction.Forward) != NetInfo.Direction.None) { - hasForward = true; - } + if (validLane) { + if ((info.m_lanes[laneIndex].m_finalDirection & dir2) != NetInfo.Direction.None) { + isOutgoingOneWay = false; + } - if (info.m_lanes[laneIndex].m_laneType != NetInfo.LaneType.Pedestrian && - (info.m_lanes[laneIndex].m_direction & NetInfo.Direction.Backward) != NetInfo.Direction.None) { - hasBackward = true; + if ((info.m_lanes[laneIndex].m_direction & NetInfo.Direction.Forward) != NetInfo.Direction.None) { + hasForward = true; + } + + if ((info.m_lanes[laneIndex].m_direction & NetInfo.Direction.Backward) != NetInfo.Direction.None) { + hasBackward = true; + } } laneId = instance.m_lanes.m_buffer[laneId].m_nextLane; diff --git a/TLM/TLM/Manager/LaneConnectionManager.cs b/TLM/TLM/Manager/LaneConnectionManager.cs index 3a359ce1..747b9db9 100644 --- a/TLM/TLM/Manager/LaneConnectionManager.cs +++ b/TLM/TLM/Manager/LaneConnectionManager.cs @@ -71,6 +71,29 @@ public bool HasConnections(uint sourceLaneId, bool startNode) { return ret; } + /// + /// Determines if there exist custom lane connections at the specified node + /// + /// + public bool HasNodeConnections(ushort nodeId) { +#if DEBUGCONN + Log._Debug($"LaneConnectionManager.RemoveLaneConnectionsFromNode({nodeId}) called."); +#endif + + bool ret = false; + Services.NetService.IterateNodeSegments(nodeId, delegate (ushort segmentId, ref NetSegment segment) { + Services.NetService.IterateSegmentLanes(segmentId, delegate (uint laneId, ref NetLane lane, NetInfo.Lane laneInfo, ushort segId, ref NetSegment seg, byte laneIndex) { + if (HasConnections(laneId, seg.m_startNode == nodeId)) { + ret = true; + return false; + } + return true; + }); + return !ret; + }); + return ret; + } + public bool HasUturnConnections(ushort segmentId, bool startNode) { NetManager netManager = Singleton.instance; int nodeArrayIndex = startNode ? 0 : 1; diff --git a/TLM/TLM/Manager/TrafficLightManager.cs b/TLM/TLM/Manager/TrafficLightManager.cs index 9b7605b1..aad43136 100644 --- a/TLM/TLM/Manager/TrafficLightManager.cs +++ b/TLM/TLM/Manager/TrafficLightManager.cs @@ -34,7 +34,9 @@ public bool SetTrafficLight(ushort nodeId, bool flag) { public bool SetTrafficLight(ushort nodeId, bool flag, out UnableReason reason) { if (! IsTrafficLightToggleable(nodeId, out reason)) { - return false; + if (reason != UnableReason.HasTimedLight || !flag) { + return false; + } } Constants.ServiceFactory.NetService.ProcessNode(nodeId, delegate (ushort nId, ref NetNode node) { @@ -85,7 +87,7 @@ public bool IsTrafficLightToggleable(ushort nodeId, out UnableReason reason) { return false; } - if (TrafficLightSimulationManager.Instance.HasActiveTimedSimulation(nodeId)) { + if (TrafficLightSimulationManager.Instance.HasTimedSimulation(nodeId)) { reason = UnableReason.HasTimedLight; return false; } diff --git a/TLM/TLM/Manager/TrafficMeasurementManager.cs b/TLM/TLM/Manager/TrafficMeasurementManager.cs index eaa6dc68..0aee1d48 100644 --- a/TLM/TLM/Manager/TrafficMeasurementManager.cs +++ b/TLM/TLM/Manager/TrafficMeasurementManager.cs @@ -11,6 +11,7 @@ namespace TrafficManager.Manager { public class TrafficMeasurementManager : AbstractCustomManager { + public const VehicleInfo.VehicleType VEHICLE_TYPES = VehicleInfo.VehicleType.Car; public const NetInfo.LaneType LANE_TYPES = NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle; public static readonly TrafficMeasurementManager Instance = new TrafficMeasurementManager(); @@ -210,6 +211,8 @@ public void SimulationStep(ushort segmentId, ref NetSegment segmentData) { ushort maxBuffer = 0; for (uint li = 0; li < numLanes; ++li) { NetInfo.Lane laneInfo = segmentInfo.m_lanes[li]; + if ((laneInfo.m_vehicleType & VEHICLE_TYPES) == VehicleInfo.VehicleType.None) + continue; if ((laneInfo.m_laneType & LANE_TYPES) == NetInfo.LaneType.None) continue; diff --git a/TLM/TLM/Manager/TrafficPriorityManager.cs b/TLM/TLM/Manager/TrafficPriorityManager.cs index a174d96b..5b510277 100644 --- a/TLM/TLM/Manager/TrafficPriorityManager.cs +++ b/TLM/TLM/Manager/TrafficPriorityManager.cs @@ -496,7 +496,7 @@ private bool HasVehiclePriority(bool debug, ushort transitNodeId, ushort targetV #endif if (targetEnd.NodeId != incomingEnd.NodeId) { - Log.Error($"HasVehiclePriority: Incompatible SegmentEnds!"); + Log._Debug($"HasVehiclePriority: Incompatible SegmentEnds: targetEnd.NodeId={targetEnd.NodeId}, incomingEnd.NodeId={incomingEnd.NodeId}"); return true; } diff --git a/TLM/TLM/Resources/lang.txt b/TLM/TLM/Resources/lang.txt index 11c7336c..4969a102 100644 --- a/TLM/TLM/Resources/lang.txt +++ b/TLM/TLM/Resources/lang.txt @@ -168,4 +168,5 @@ Lock_main_menu_button_position Lock main menu button position Lock_main_menu_position Lock main menu position Recalculating_lane_routing Recalculating lane routing Please_wait Please wait -Parking_restrictions Parking restrictions \ No newline at end of file +Parking_restrictions Parking restrictions +Simulation Simulation \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_de.txt b/TLM/TLM/Resources/lang_de.txt index 82b4f4c9..765cfaf4 100644 --- a/TLM/TLM/Resources/lang_de.txt +++ b/TLM/TLM/Resources/lang_de.txt @@ -167,4 +167,5 @@ Lock_main_menu_button_position Position der Hauptmenü-Schaltfläche sperren Lock_main_menu_position Position des Hauptmenüs sperren Recalculating_lane_routing Berechne Routenführung neu Please_wait Bitte warten -Parking_restrictions Parkverbote \ No newline at end of file +Parking_restrictions Parkverbote +Simulation Simulation \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_es.txt b/TLM/TLM/Resources/lang_es.txt index 2f7f35ca..c2eb9097 100644 --- a/TLM/TLM/Resources/lang_es.txt +++ b/TLM/TLM/Resources/lang_es.txt @@ -167,4 +167,5 @@ Lock_main_menu_button_position Lock main menu button position Lock_main_menu_position Lock main menu position Recalculating_lane_routing Recalculating lane routing Please_wait Please wait -Parking_restrictions Parking restrictions \ No newline at end of file +Parking_restrictions Parking restrictions +Simulation Simulation \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_fr.txt b/TLM/TLM/Resources/lang_fr.txt index a9484475..0d695663 100644 --- a/TLM/TLM/Resources/lang_fr.txt +++ b/TLM/TLM/Resources/lang_fr.txt @@ -167,4 +167,5 @@ Lock_main_menu_button_position Lock main menu button position Lock_main_menu_position Lock main menu position Recalculating_lane_routing Recalculating lane routing Please_wait Please wait -Parking_restrictions Parking restrictions \ No newline at end of file +Parking_restrictions Parking restrictions +Simulation Simulation \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_it.txt b/TLM/TLM/Resources/lang_it.txt index d01d58d4..c7712dee 100644 --- a/TLM/TLM/Resources/lang_it.txt +++ b/TLM/TLM/Resources/lang_it.txt @@ -167,4 +167,5 @@ Lock_main_menu_button_position Lock main menu button position Lock_main_menu_position Lock main menu position Recalculating_lane_routing Recalculating lane routing Please_wait Please wait -Parking_restrictions Parking restrictions \ No newline at end of file +Parking_restrictions Parking restrictions +Simulation Simulation \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_ja.txt b/TLM/TLM/Resources/lang_ja.txt index 7826514d..424b529f 100644 --- a/TLM/TLM/Resources/lang_ja.txt +++ b/TLM/TLM/Resources/lang_ja.txt @@ -168,4 +168,5 @@ Lock_main_menu_button_position Lock main menu button position Lock_main_menu_position Lock main menu position Recalculating_lane_routing Recalculating lane routing Please_wait Please wait -Parking_restrictions Parking restrictions \ No newline at end of file +Parking_restrictions Parking restrictions +Simulation Simulation \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_kr.txt b/TLM/TLM/Resources/lang_kr.txt index 77cf847a..d6d6e926 100644 --- a/TLM/TLM/Resources/lang_kr.txt +++ b/TLM/TLM/Resources/lang_kr.txt @@ -60,7 +60,7 @@ Busses_may_ignore_lane_arrows 버스가 도로 화살표를 무시 할 수 있 Reckless_driving 난폭 운전 (베타 기능) TMPE_Title 트래픽 매니저 : 대통령 에디션 Settings_are_defined_for_each_savegame_separately 설정은 각 저장된 게임마다 별개로 작동합니다. -Simulation_accuracy 시뮬레이션 정확도 (효과가 올라갈수록 성능은 감소합니다) +Simulation_accuracy 시뮬레이션 정확도 (높을수록 더 많은 연산을 요구합니다) Enable_highway_specific_lane_merging/splitting_rules 고속도로 특정도로 병합/분할 기능 활성화 Drivers_want_to_change_lanes_(only_applied_if_Advanced_AI_is_enabled): 운전자가 차선을 변경합니다 (발전된 차량 AI를 사용 중일 때만 적용됩니다) Maintenance 유지보수 (추가정보) @@ -70,7 +70,7 @@ Sometimes 가끔 Rarely 드물게 Very_rarely 매우 드물게 Only_if_necessary 필요한 경우에만 -Nodes_and_segments 도로와 세그먼트(구간) +Nodes_and_segments 도로와 세그먼트(노드) Lanes 차선 Path_Of_Evil_(10_%) 악마의 도로 (10 %) Rush_Hour_(5_%) 출퇴근정도의 혼잡 (5 %) @@ -158,14 +158,15 @@ Vehicle_behavior 차량 제한 Policies_&_Restrictions 정책 및 제한 At_junctions 교차로 설정 In_case_of_emergency 긴급 상황 설정 -Show_lane-wise_speed_limits Show lane-wise speed limits -Language Language -Game_language Game language -requires_game_restart requires game restart -Customizations_come_into_effect_instantaneously Customizations come into effect instantaneously -Options Options -Lock_main_menu_button_position Lock main menu button position -Lock_main_menu_position Lock main menu position -Recalculating_lane_routing Recalculating lane routing -Please_wait Please wait -Parking_restrictions Parking restrictions \ No newline at end of file +Show_lane-wise_speed_limits 차선 속도제한 보기 +Language 언어 +Game_language 게임 언어 +requires_game_restart 게임 재시작후 적용됩니다 +Customizations_come_into_effect_instantaneously 커스텀 기능이 즉시 적용됩니다 +Options 설정 +Lock_main_menu_button_position TMPE 모드버튼 위치 잠금 +Lock_main_menu_position TMPE 모드매뉴 위치 잠금 +Recalculating_lane_routing 차선 경로 재 계산하기 +Please_wait 잠시만 기다려주십시오 +Parking_restrictions 주차 제한 +Simulation 시뮬레이션 \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_nl.txt b/TLM/TLM/Resources/lang_nl.txt index 4469eee8..aa46231d 100644 --- a/TLM/TLM/Resources/lang_nl.txt +++ b/TLM/TLM/Resources/lang_nl.txt @@ -158,14 +158,14 @@ Vehicle_behavior Vortuiggedrag Policies_&_Restrictions Beleidsregels & beperkingen At_junctions Bij splitsingen In_case_of_emergency In geval van nood -Show_lane-wise_speed_limits Show lane-wise speed limits -Language Language -Game_language Game language -requires_game_restart requires game restart -Customizations_come_into_effect_instantaneously Customizations come into effect instantaneously -Options Options -Lock_main_menu_button_position Lock main menu button position -Lock_main_menu_position Lock main menu position -Recalculating_lane_routing Recalculating lane routing -Please_wait Please wait -Parking_restrictions Parking restrictions \ No newline at end of file +Show_lane-wise_speed_limits Toon rijstrookspecifieke snelheidslimieten +Language Taal +Game_language Taal van spel +requires_game_restart Vereist spelherstart +Customizations_come_into_effect_instantaneously Aanpassingen zijn onmiddelijk van toepassing +Options Instellingen +Lock_main_menu_button_position Vergendel positie van hoofdmenuknop +Lock_main_menu_position Vergrendel positie van hoofdmenu +Recalculating_lane_routing Rijstrookroutering wordt herberekend +Please_wait Even geduld graag +Parking_restrictions Parkeerbeperkingen \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_pl.txt b/TLM/TLM/Resources/lang_pl.txt index 1c78c312..2a225f76 100644 --- a/TLM/TLM/Resources/lang_pl.txt +++ b/TLM/TLM/Resources/lang_pl.txt @@ -167,4 +167,5 @@ Lock_main_menu_button_position Zablokuj pozycjê przycisku menu g³ównego Lock_main_menu_position Zablokuj pozycjê menu g³ównego Recalculating_lane_routing Ponowne obliczanie tras Please_wait Proszê czekaæ -Parking_restrictions Ograniczenia parkingowe \ No newline at end of file +Parking_restrictions Ograniczenia parkingowe +Simulation Simulation \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_pt.txt b/TLM/TLM/Resources/lang_pt.txt index 1bfd165c..a1f3383a 100644 --- a/TLM/TLM/Resources/lang_pt.txt +++ b/TLM/TLM/Resources/lang_pt.txt @@ -169,4 +169,5 @@ Recalculating_lane_routing Recalculando o roteamento de faixa Please_wait Por favor, aguarde Parking_restrictions Restrições de estacionamento Please_wait Please wait -Parking_restrictions Parking restrictions \ No newline at end of file +Parking_restrictions Parking restrictions +Simulation Simulation \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_ru.txt b/TLM/TLM/Resources/lang_ru.txt index 61bfcefa..b9c27a97 100644 --- a/TLM/TLM/Resources/lang_ru.txt +++ b/TLM/TLM/Resources/lang_ru.txt @@ -168,4 +168,5 @@ Lock_main_menu_button_position Блокировка позиции кнопки Lock_main_menu_position Блокировка позиции главного меню Recalculating_lane_routing Обновление маршрута Please_wait Подождите пожалуйста -Parking_restrictions Ограничения парковки \ No newline at end of file +Parking_restrictions Ограничения парковки +Simulation Simulation \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_template.txt b/TLM/TLM/Resources/lang_template.txt index 6fe6bd97..123304bc 100644 --- a/TLM/TLM/Resources/lang_template.txt +++ b/TLM/TLM/Resources/lang_template.txt @@ -167,4 +167,5 @@ Lock_main_menu_button_position Lock_main_menu_position Recalculating_lane_routing Please_wait -Parking_restrictions \ No newline at end of file +Parking_restrictions +Simulation \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_zh-tw.txt b/TLM/TLM/Resources/lang_zh-tw.txt index 6272b490..06e02016 100644 --- a/TLM/TLM/Resources/lang_zh-tw.txt +++ b/TLM/TLM/Resources/lang_zh-tw.txt @@ -168,4 +168,5 @@ Lock_main_menu_button_position 鎖定主選單的選項位置 Lock_main_menu_position 鎖定主選單的位置 Recalculating_lane_routing 重新規劃行駛路線 Please_wait 請稍候 -Parking_restrictions 停車限制 \ No newline at end of file +Parking_restrictions 停車限制 +Simulation Simulation \ No newline at end of file diff --git a/TLM/TLM/Resources/lang_zh.txt b/TLM/TLM/Resources/lang_zh.txt index 33d226e7..c372919c 100644 --- a/TLM/TLM/Resources/lang_zh.txt +++ b/TLM/TLM/Resources/lang_zh.txt @@ -59,7 +59,7 @@ All_vehicles_may_ignore_lane_arrows 所有车辆可忽略车道行驶方向 Busses_may_ignore_lane_arrows 公交车可忽略车道行驶方向 Reckless_driving 违规驾驶(功能测试中) TMPE_Title 交通管理:总统版(贴吧简体中文翻译) -Settings_are_defined_for_each_savegame_separately 贴吧简体中文温馨提示: 设置项目自动跳出关闭就好,MOD设置说明文档地址: +Settings_are_defined_for_each_savegame_separately 贴吧简体中文温馨提示: 设置项目自动跳出关闭就好,欢迎订阅“天吧简体中文”最接地气的中文,MOD设置说明文档地址: Simulation_accuracy 模拟真实度(高真实模拟会影响性能) Enable_highway_specific_lane_merging/splitting_rules 实行高速公路特定的车道合流/分离规则 Drivers_want_to_change_lanes_(only_applied_if_Advanced_AI_is_enabled): 司机习惯变换车道(仅适用于加强版AI启动时) @@ -157,14 +157,15 @@ Vehicle_behavior 车辆行为 Policies_&_Restrictions 政策和限制 At_junctions 位于十字路口 In_case_of_emergency 在紧急情况下 -Show_lane-wise_speed_limits Show lane-wise speed limits -Language Language -Game_language Game language -requires_game_restart requires game restart -Customizations_come_into_effect_instantaneously Customizations come into effect instantaneously -Options Options -Lock_main_menu_button_position Lock main menu button position -Lock_main_menu_position Lock main menu position -Recalculating_lane_routing Recalculating lane routing -Please_wait Please wait -Parking_restrictions Parking restrictions \ No newline at end of file +Show_lane-wise_speed_limits 开启道路各个车道限速设置 +Language 语言设置 +Game_language 自动识别游戏语言 +requires_game_restart 需重新启动方可生效,请订阅“天吧简体中文” +Customizations_come_into_effect_instantaneously 订制模拟真实度开启选项则将会立即生效 +Options 选项 +Lock_main_menu_button_position 锁定主菜单按钮位置 +Lock_main_menu_position 主菜单位置 +Recalculating_lane_routing 重新计算车道路线 +Please_wait 请稍候 +Parking_restrictions 道路边停车控制管理 +Simulation 模拟 \ No newline at end of file diff --git a/TLM/TLM/State/GlobalConfig.cs b/TLM/TLM/State/GlobalConfig.cs index afe90c84..763647c2 100644 --- a/TLM/TLM/State/GlobalConfig.cs +++ b/TLM/TLM/State/GlobalConfig.cs @@ -17,7 +17,7 @@ namespace TrafficManager.State { public class GlobalConfig { public const string FILENAME = "TMPE_GlobalConfig.xml"; public const string BACKUP_FILENAME = FILENAME + ".bak"; - private static int LATEST_VERSION = 6; + private static int LATEST_VERSION = 7; #if DEBUG private static uint lastModificationCheckFrame = 0; #endif @@ -124,7 +124,7 @@ internal static void OnLevelUnloading() { /// /// Relative factor for lane speed cost calculation /// - public float SpeedCostFactor = 0.25f; + public float SpeedCostFactor = 1f; /// /// lane changing cost reduction modulo diff --git a/TLM/TLM/State/Options.cs b/TLM/TLM/State/Options.cs index 91ac47dd..563d3dfd 100644 --- a/TLM/TLM/State/Options.cs +++ b/TLM/TLM/State/Options.cs @@ -374,6 +374,8 @@ private static void onPrioritySignsOverlayChanged(bool newPrioritySignsOverlay) Log._Debug($"prioritySignsOverlay changed to {newPrioritySignsOverlay}"); prioritySignsOverlay = newPrioritySignsOverlay; + + UIBase.GetTrafficManagerTool(false)?.InitializeSubTools(); } private static void onTimedLightsOverlayChanged(bool newTimedLightsOverlay) { @@ -382,6 +384,8 @@ private static void onTimedLightsOverlayChanged(bool newTimedLightsOverlay) { Log._Debug($"timedLightsOverlay changed to {newTimedLightsOverlay}"); timedLightsOverlay = newTimedLightsOverlay; + + UIBase.GetTrafficManagerTool(false)?.InitializeSubTools(); } private static void onSpeedLimitsOverlayChanged(bool newSpeedLimitsOverlay) { @@ -390,6 +394,8 @@ private static void onSpeedLimitsOverlayChanged(bool newSpeedLimitsOverlay) { Log._Debug($"speedLimitsOverlay changed to {newSpeedLimitsOverlay}"); speedLimitsOverlay = newSpeedLimitsOverlay; + + UIBase.GetTrafficManagerTool(false)?.InitializeSubTools(); } private static void onVehicleRestrictionsOverlayChanged(bool newVehicleRestrictionsOverlay) { @@ -398,6 +404,8 @@ private static void onVehicleRestrictionsOverlayChanged(bool newVehicleRestricti Log._Debug($"vehicleRestrictionsOverlay changed to {newVehicleRestrictionsOverlay}"); vehicleRestrictionsOverlay = newVehicleRestrictionsOverlay; + + UIBase.GetTrafficManagerTool(false)?.InitializeSubTools(); } private static void onParkingRestrictionsOverlayChanged(bool newParkingRestrictionsOverlay) { @@ -406,6 +414,8 @@ private static void onParkingRestrictionsOverlayChanged(bool newParkingRestricti Log._Debug($"parkingRestrictionsOverlay changed to {newParkingRestrictionsOverlay}"); parkingRestrictionsOverlay = newParkingRestrictionsOverlay; + + UIBase.GetTrafficManagerTool(false)?.InitializeSubTools(); } private static void onJunctionRestrictionsOverlayChanged(bool newValue) { @@ -414,6 +424,8 @@ private static void onJunctionRestrictionsOverlayChanged(bool newValue) { Log._Debug($"junctionRestrictionsOverlay changed to {newValue}"); junctionRestrictionsOverlay = newValue; + + UIBase.GetTrafficManagerTool(false)?.InitializeSubTools(); } private static void onConnectedLanesOverlayChanged(bool newValue) { @@ -422,6 +434,8 @@ private static void onConnectedLanesOverlayChanged(bool newValue) { Log._Debug($"connectedLanesOverlay changed to {newValue}"); connectedLanesOverlay = newValue; + + UIBase.GetTrafficManagerTool(false)?.InitializeSubTools(); } private static void onLanguageChanged(int newLanguageIndex) { diff --git a/TLM/TLM/TrafficLight/TimedTrafficLights.cs b/TLM/TLM/TrafficLight/TimedTrafficLights.cs index 069758bb..90e31158 100644 --- a/TLM/TLM/TrafficLight/TimedTrafficLights.cs +++ b/TLM/TLM/TrafficLight/TimedTrafficLights.cs @@ -292,7 +292,9 @@ public void Start() { /*if (!housekeeping()) return;*/ - + + TrafficLightManager.Instance.AddTrafficLight(NodeId); + foreach (TimedTrafficLightsStep step in Steps) { foreach (KeyValuePair e in step.CustomSegmentLights) { e.Value.housekeeping(true, true); diff --git a/TLM/TLM/TrafficManagerMod.cs b/TLM/TLM/TrafficManagerMod.cs index 0dc9405f..cf49fd29 100644 --- a/TLM/TLM/TrafficManagerMod.cs +++ b/TLM/TLM/TrafficManagerMod.cs @@ -6,7 +6,7 @@ namespace TrafficManager { public class TrafficManagerMod : IUserMod { - public static readonly string Version = "1.9.0"; + public static readonly string Version = "1.9.2"; public static readonly uint GameVersion = 163702032u; public static readonly uint GameVersionA = 1u; diff --git a/TLM/TLM/UI/MainMenu/MenuButton.cs b/TLM/TLM/UI/MainMenu/MenuButton.cs index a4dcf575..44b0a0cc 100644 --- a/TLM/TLM/UI/MainMenu/MenuButton.cs +++ b/TLM/TLM/UI/MainMenu/MenuButton.cs @@ -116,15 +116,16 @@ protected override void OnClick(UIMouseEventParameter p) { public abstract bool Visible { get; } internal void UpdateProperties() { - normalBgSprite = disabledBgSprite = focusedBgSprite = GetButtonBackgroundTextureId(ButtonMouseState.Base, Active); - hoveredBgSprite = GetButtonBackgroundTextureId(ButtonMouseState.Hovered, Active); - pressedBgSprite = GetButtonBackgroundTextureId(ButtonMouseState.MouseDown, Active); + m_BackgroundSprites.m_Normal = m_BackgroundSprites.m_Disabled = m_BackgroundSprites.m_Focused = GetButtonBackgroundTextureId(ButtonMouseState.Base, Active); + m_BackgroundSprites.m_Hovered = GetButtonBackgroundTextureId(ButtonMouseState.Hovered, Active); + m_PressedBgSprite = GetButtonBackgroundTextureId(ButtonMouseState.MouseDown, Active); - normalFgSprite = disabledFgSprite = focusedFgSprite = GetButtonForegroundTextureId(Function, Active); - hoveredFgSprite = pressedFgSprite = GetButtonForegroundTextureId(Function, true); + m_ForegroundSprites.m_Normal = m_ForegroundSprites.m_Disabled = m_ForegroundSprites.m_Focused = GetButtonForegroundTextureId(Function, Active); + m_ForegroundSprites.m_Hovered = m_PressedFgSprite = GetButtonForegroundTextureId(Function, true); tooltip = Translation.GetString(Tooltip); isVisible = Visible; + this.Invalidate(); } } } diff --git a/TLM/TLM/UI/SubTools/JunctionRestrictionsTool.cs b/TLM/TLM/UI/SubTools/JunctionRestrictionsTool.cs index ef091726..26f657c8 100644 --- a/TLM/TLM/UI/SubTools/JunctionRestrictionsTool.cs +++ b/TLM/TLM/UI/SubTools/JunctionRestrictionsTool.cs @@ -68,10 +68,14 @@ private void ShowSigns(bool viewOnly) { currentRestrictedNodeIds.Add(SelectedNodeId); } - bool stateUpdated = false; + 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; @@ -93,13 +97,15 @@ private void ShowSigns(bool viewOnly) { if (drawSignHandles(nodeId, viewOnlyNode, !cursorInPanel, ref camPos, out update)) handleHovered = true; - if (update) - stateUpdated = true; + if (update) { + updatedNodeId = nodeId; + } } overlayHandleHovered = handleHovered; - if (stateUpdated) - RefreshCurrentRestrictedNodeIds(); + if (updatedNodeId != 0) { + RefreshCurrentRestrictedNodeIds(updatedNodeId); + } } public override void OnPrimaryClickOverlay() { @@ -125,18 +131,29 @@ public override void OnActivate() { } public override void Cleanup() { - RefreshCurrentRestrictedNodeIds(); + } public override void Initialize() { Cleanup(); + if (Options.junctionRestrictionsOverlay) { + RefreshCurrentRestrictedNodeIds(); + } else { + currentRestrictedNodeIds.Clear(); + } } - private void RefreshCurrentRestrictedNodeIds() { - currentRestrictedNodeIds.Clear(); - for (uint nodeId = 1; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { - if ((Singleton.instance.m_nodes.m_buffer[nodeId].m_flags & NetNode.Flags.Created) == NetNode.Flags.None) + private void RefreshCurrentRestrictedNodeIds(ushort forceNodeId=0) { + if (forceNodeId == 0) { + currentRestrictedNodeIds.Clear(); + } else { + currentRestrictedNodeIds.Remove(forceNodeId); + } + + for (uint nodeId = (forceNodeId == 0 ? 1u : forceNodeId); nodeId <= (forceNodeId == 0 ? NetManager.MAX_NODE_COUNT - 1 : forceNodeId); ++nodeId) { + if (!Constants.ServiceFactory.NetService.IsNodeValid((ushort)nodeId)) { continue; + } if (JunctionRestrictionsManager.Instance.HasJunctionRestrictions((ushort)nodeId)) currentRestrictedNodeIds.Add((ushort)nodeId); diff --git a/TLM/TLM/UI/SubTools/LaneArrowTool.cs b/TLM/TLM/UI/SubTools/LaneArrowTool.cs index a50a4767..9bf32b45 100644 --- a/TLM/TLM/UI/SubTools/LaneArrowTool.cs +++ b/TLM/TLM/UI/SubTools/LaneArrowTool.cs @@ -17,10 +17,18 @@ namespace TrafficManager.UI.SubTools { public class LaneArrowTool : SubTool { private bool _cursorInSecondaryPanel; - private Texture2D SecondPanelTexture; + private Texture2D SecondPanelTexture { + get { + if (secondPanelTexture == null) { + secondPanelTexture = TrafficManagerTool.MakeTex(1, 1, new Color(0.5f, 0.5f, 0.5f, 1f)); + } + return secondPanelTexture; + } + } + private Texture2D secondPanelTexture = null; public LaneArrowTool(TrafficManagerTool mainTool) : base(mainTool) { - SecondPanelTexture = TrafficManagerTool.MakeTex(1, 1, new Color(0.5f, 0.5f, 0.5f, 1f)); + } public override bool IsCursorInPanel() { diff --git a/TLM/TLM/UI/SubTools/LaneConnectorTool.cs b/TLM/TLM/UI/SubTools/LaneConnectorTool.cs index 95237928..11778ead 100644 --- a/TLM/TLM/UI/SubTools/LaneConnectorTool.cs +++ b/TLM/TLM/UI/SubTools/LaneConnectorTool.cs @@ -77,58 +77,63 @@ private void ShowOverlay(bool viewOnly, RenderManager.CameraInfo cameraInfo) { //Bounds bounds = new Bounds(Vector3.zero, Vector3.one); Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition); - foreach (KeyValuePair> e in currentNodeMarkers) { - ushort nodeId = e.Key; - List nodeMarkers = e.Value; - Vector3 nodePos = NetManager.instance.m_nodes.m_buffer[nodeId].m_position; + for (ushort nodeId = 1; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { + if (!Constants.ServiceFactory.NetService.IsNodeValid(nodeId)) { + continue; + } - var diff = nodePos - camPos; + var diff = NetManager.instance.m_nodes.m_buffer[nodeId].m_position - camPos; if (diff.magnitude > TrafficManagerTool.MaxOverlayDistance) continue; // do not draw if too distant + List nodeMarkers; + bool hasMarkers = currentNodeMarkers.TryGetValue(nodeId, out nodeMarkers); + if (!viewOnly && GetMarkerSelectionMode() == MarkerSelectionMode.None) { MainTool.DrawNodeCircle(cameraInfo, nodeId, DefaultNodeMarkerColor, true); } - foreach (NodeLaneMarker laneMarker in nodeMarkers) { - foreach (NodeLaneMarker targetLaneMarker in laneMarker.connectedMarkers) { - // render lane connection from laneMarker to targetLaneMarker - RenderLane(cameraInfo, laneMarker.position, targetLaneMarker.position, nodePos, laneMarker.color); - } - - if (!viewOnly && nodeId == SelectedNodeId) { - //bounds.center = laneMarker.position; - bool markerIsHovered = IsLaneMarkerHovered(laneMarker, ref mouseRay);// bounds.IntersectRay(mouseRay); - - // draw source marker in source selection mode, - // draw target marker (if segment turning angles are within bounds) and selected source marker in target selection mode - bool drawMarker = (GetMarkerSelectionMode() == MarkerSelectionMode.SelectSource && laneMarker.isSource) || - (GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget && ( - (!laneMarker.isSource && - (laneMarker.vehicleType & selectedMarker.vehicleType) != VehicleInfo.VehicleType.None && - CheckSegmentsTurningAngle(selectedMarker.segmentId, ref netManager.m_segments.m_buffer[selectedMarker.segmentId], selectedMarker.startNode, laneMarker.segmentId, ref netManager.m_segments.m_buffer[laneMarker.segmentId], laneMarker.startNode) - ) || laneMarker == selectedMarker)); - // highlight hovered marker and selected marker - bool highlightMarker = drawMarker && (laneMarker == selectedMarker || markerIsHovered); - - if (drawMarker) { - if (highlightMarker) { - laneMarker.radius = 2f; - } else - laneMarker.radius = 1f; - } else { - markerIsHovered = false; + if (hasMarkers) { + foreach (NodeLaneMarker laneMarker in nodeMarkers) { + foreach (NodeLaneMarker targetLaneMarker in laneMarker.connectedMarkers) { + // render lane connection from laneMarker to targetLaneMarker + RenderLane(cameraInfo, laneMarker.position, targetLaneMarker.position, NetManager.instance.m_nodes.m_buffer[nodeId].m_position, laneMarker.color); } - if (markerIsHovered) { - /*if (hoveredMarker != sourceLaneMarker) - Log._Debug($"Marker @ lane {sourceLaneMarker.laneId} hovered");*/ - hoveredMarker = laneMarker; - } + if (!viewOnly && nodeId == SelectedNodeId) { + //bounds.center = laneMarker.position; + bool markerIsHovered = IsLaneMarkerHovered(laneMarker, ref mouseRay);// bounds.IntersectRay(mouseRay); + + // draw source marker in source selection mode, + // draw target marker (if segment turning angles are within bounds) and selected source marker in target selection mode + bool drawMarker = (GetMarkerSelectionMode() == MarkerSelectionMode.SelectSource && laneMarker.isSource) || + (GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget && ( + (!laneMarker.isSource && + (laneMarker.vehicleType & selectedMarker.vehicleType) != VehicleInfo.VehicleType.None && + CheckSegmentsTurningAngle(selectedMarker.segmentId, ref netManager.m_segments.m_buffer[selectedMarker.segmentId], selectedMarker.startNode, laneMarker.segmentId, ref netManager.m_segments.m_buffer[laneMarker.segmentId], laneMarker.startNode) + ) || laneMarker == selectedMarker)); + // highlight hovered marker and selected marker + bool highlightMarker = drawMarker && (laneMarker == selectedMarker || markerIsHovered); + + if (drawMarker) { + if (highlightMarker) { + laneMarker.radius = 2f; + } else + laneMarker.radius = 1f; + } else { + markerIsHovered = false; + } + + if (markerIsHovered) { + /*if (hoveredMarker != sourceLaneMarker) + Log._Debug($"Marker @ lane {sourceLaneMarker.laneId} hovered");*/ + hoveredMarker = laneMarker; + } - if (drawMarker) { - //DrawLaneMarker(laneMarker, cameraInfo); - RenderManager.instance.OverlayEffect.DrawCircle(cameraInfo, laneMarker.color, laneMarker.position, laneMarker.radius, laneMarker.position.y - 100f, laneMarker.position.y + 100f, false, true); + if (drawMarker) { + //DrawLaneMarker(laneMarker, cameraInfo); + RenderManager.instance.OverlayEffect.DrawCircle(cameraInfo, laneMarker.color, laneMarker.position, laneMarker.radius, laneMarker.position.y - 100f, laneMarker.position.y + 100f, false, true); + } } } } @@ -173,7 +178,7 @@ public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { if (deleteAll) { // remove all connections at selected node LaneConnectionManager.Instance.RemoveLaneConnectionsFromNode(SelectedNodeId); - RefreshCurrentNodeMarkers(); + RefreshCurrentNodeMarkers(SelectedNodeId); } if (stayInLane) { @@ -218,7 +223,7 @@ public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { } } } - RefreshCurrentNodeMarkers(); + RefreshCurrentNodeMarkers(SelectedNodeId); } } } @@ -364,12 +369,21 @@ public override void OnActivate() { RefreshCurrentNodeMarkers(); } - private void RefreshCurrentNodeMarkers() { - currentNodeMarkers.Clear(); + private void RefreshCurrentNodeMarkers(ushort forceNodeId=0) { + if (forceNodeId == 0) { + currentNodeMarkers.Clear(); + } else { + currentNodeMarkers.Remove(forceNodeId); + } + + for (uint nodeId = (forceNodeId == 0 ? 1u : forceNodeId); nodeId <= (forceNodeId == 0 ? NetManager.MAX_NODE_COUNT-1 : forceNodeId); ++nodeId) { + if (!Constants.ServiceFactory.NetService.IsNodeValid((ushort)nodeId)) { + continue; + } - for (uint nodeId = 1; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { - if ((Singleton.instance.m_nodes.m_buffer[nodeId].m_flags & NetNode.Flags.Created) == NetNode.Flags.None) + if (! LaneConnectionManager.Instance.HasNodeConnections((ushort)nodeId)) { continue; + } List nodeMarkers = GetNodeMarkers((ushort)nodeId); if (nodeMarkers == null) @@ -387,11 +401,16 @@ private MarkerSelectionMode GetMarkerSelectionMode() { } public override void Cleanup() { - RefreshCurrentNodeMarkers(); + } public override void Initialize() { Cleanup(); + if (Options.connectedLanesOverlay) { + RefreshCurrentNodeMarkers(); + } else { + currentNodeMarkers.Clear(); + } } private List GetNodeMarkers(ushort nodeId) { diff --git a/TLM/TLM/UI/SubTools/ParkingRestrictionsTool.cs b/TLM/TLM/UI/SubTools/ParkingRestrictionsTool.cs index dd120cef..9023a0ec 100644 --- a/TLM/TLM/UI/SubTools/ParkingRestrictionsTool.cs +++ b/TLM/TLM/UI/SubTools/ParkingRestrictionsTool.cs @@ -72,8 +72,9 @@ private void ShowSigns(bool viewOnly) { currentlyVisibleSegmentIds.Clear(); for (uint segmentId = 1; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId) { - if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Created) == NetSegment.Flags.None) + if (!Constants.ServiceFactory.NetService.IsSegmentValid((ushort)segmentId)) { continue; + } /*if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Untouchable) != NetSegment.Flags.None) continue;*/ diff --git a/TLM/TLM/UI/SubTools/PrioritySignsTool.cs b/TLM/TLM/UI/SubTools/PrioritySignsTool.cs index 998af6e7..3c9f0fec 100644 --- a/TLM/TLM/UI/SubTools/PrioritySignsTool.cs +++ b/TLM/TLM/UI/SubTools/PrioritySignsTool.cs @@ -69,6 +69,10 @@ private void RefreshCurrentPriorityNodeIds() { currentPriorityNodeIds.Clear(); for (ushort nodeId = 0; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { + if (!Constants.ServiceFactory.NetService.IsNodeValid(nodeId)) { + continue; + } + if (!tpm.MayNodeHavePrioritySigns(nodeId)) { continue; } @@ -110,6 +114,10 @@ public void ShowGUI(bool viewOnly) { ushort removedNodeId = 0; bool showRemoveButton = false; foreach (ushort nodeId in currentPriorityNodeIds) { + if (! Constants.ServiceFactory.NetService.IsNodeValid(nodeId)) { + continue; + } + if (!MainTool.IsNodeWithinViewDistance(nodeId)) { continue; } @@ -249,11 +257,20 @@ public override void Cleanup() { // } //} + + } + + public override void OnActivate() { RefreshCurrentPriorityNodeIds(); } public override void Initialize() { Cleanup(); + if (Options.prioritySignsOverlay) { + RefreshCurrentPriorityNodeIds(); + } else { + currentPriorityNodeIds.Clear(); + } } private bool MayNodeHavePrioritySigns(ushort nodeId) { diff --git a/TLM/TLM/UI/SubTools/SpeedLimitsTool.cs b/TLM/TLM/UI/SubTools/SpeedLimitsTool.cs index 40a8380c..7e12ead0 100644 --- a/TLM/TLM/UI/SubTools/SpeedLimitsTool.cs +++ b/TLM/TLM/UI/SubTools/SpeedLimitsTool.cs @@ -26,20 +26,34 @@ public class SpeedLimitsTool : SubTool { private Dictionary> segmentCenterByDir = new Dictionary>(); private readonly float speedLimitSignSize = 80f; private readonly int guiSpeedSignSize = 100; - private Texture2D SecondPanelTexture; + private Texture2D SecondPanelTexture { + get { + if (secondPanelTexture == null) { + secondPanelTexture = TrafficManagerTool.MakeTex(1, 1, new Color(0.5f, 0.5f, 0.5f, 1f)); + } + return secondPanelTexture; + } + } + private Texture2D secondPanelTexture = null; private Rect windowRect = TrafficManagerTool.MoveGUI(new Rect(0, 0, 7 * 105, 225)); private Rect defaultsWindowRect = TrafficManagerTool.MoveGUI(new Rect(0, 280, 400, 400)); private HashSet currentlyVisibleSegmentIds; private bool defaultsWindowVisible = false; private int currentInfoIndex = -1; private int currentSpeedLimitIndex = -1; - private Texture2D roadTex; + private Texture2D RoadTexture { + get { + if (roadTexture == null) { + roadTexture = new Texture2D(guiSpeedSignSize, guiSpeedSignSize); + } + return roadTexture; + } + } + private Texture2D roadTexture = null; private bool showLimitsPerLane = false; public SpeedLimitsTool(TrafficManagerTool mainTool) : base(mainTool) { - SecondPanelTexture = TrafficManagerTool.MakeTex(1, 1, new Color(0.5f, 0.5f, 0.5f, 1f)); currentlyVisibleSegmentIds = new HashSet(); - roadTex = new Texture2D(guiSpeedSignSize, guiSpeedSignSize); } public override bool IsCursorInPanel() { @@ -103,8 +117,9 @@ private void ShowSigns(bool viewOnly) { currentlyVisibleSegmentIds.Clear(); for (uint segmentId = 1; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId) { - if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Created) == NetSegment.Flags.None) + if (!Constants.ServiceFactory.NetService.IsSegmentValid((ushort)segmentId)) { continue; + } /*if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Untouchable) != NetSegment.Flags.None) continue;*/ @@ -201,7 +216,7 @@ private void _guiDefaultsWindow(int num) { GUILayout.FlexibleSpace(); // NetInfo thumbnail - GUILayout.Box(roadTex, GUILayout.Height(guiSpeedSignSize)); + GUILayout.Box(RoadTexture, GUILayout.Height(guiSpeedSignSize)); GUILayout.FlexibleSpace(); GUILayout.EndVertical(); @@ -297,9 +312,9 @@ private void UpdateRoadTex(NetInfo info) { if (spriteInfo != null && spriteInfo.texture != null && spriteInfo.texture.width > 0 && spriteInfo.texture.height > 0) { try { - roadTex = new Texture2D((int)spriteInfo.texture.width, (int)spriteInfo.texture.height, TextureFormat.ARGB32, false); - roadTex.SetPixels(0, 0, roadTex.width, roadTex.height, mainTex.GetPixels((int)(spriteInfo.region.x * mainTex.width), (int)(spriteInfo.region.y * mainTex.height), (int)(spriteInfo.region.width * mainTex.width), (int)(spriteInfo.region.height * mainTex.height))); - roadTex.Apply(); + roadTexture = new Texture2D((int)spriteInfo.texture.width, (int)spriteInfo.texture.height, TextureFormat.ARGB32, false); + roadTexture.SetPixels(0, 0, roadTexture.width, roadTexture.height, mainTex.GetPixels((int)(spriteInfo.region.x * mainTex.width), (int)(spriteInfo.region.y * mainTex.height), (int)(spriteInfo.region.width * mainTex.width), (int)(spriteInfo.region.height * mainTex.height))); + roadTexture.Apply(); return; } catch (Exception e) { Log.Warning($"Could not get texture from NetInfo {info.name}: {e.ToString()}"); @@ -309,7 +324,7 @@ private void UpdateRoadTex(NetInfo info) { } // fallback to "noimage" texture - roadTex = TextureResources.NoImageTexture2D; + roadTexture = TextureResources.NoImageTexture2D; } private void _guiSpeedLimitsWindow(int num) { diff --git a/TLM/TLM/UI/SubTools/TimedTrafficLightsTool.cs b/TLM/TLM/UI/SubTools/TimedTrafficLightsTool.cs index 31c25892..c4abc9b0 100644 --- a/TLM/TLM/UI/SubTools/TimedTrafficLightsTool.cs +++ b/TLM/TLM/UI/SubTools/TimedTrafficLightsTool.cs @@ -18,7 +18,7 @@ public class TimedTrafficLightsTool : SubTool { private readonly GUIStyle _counterStyle = new GUIStyle(); private readonly int[] _hoveredButton = new int[2]; private bool nodeSelectionLocked = false; - private List SelectedNodeIndexes = new List(); + private List SelectedNodeIds = new List(); private bool _cursorInSecondaryPanel; private Rect _windowRect = TrafficManagerTool.MoveGUI(new Rect(0, 0, 480, 350)); private Rect _windowRect2 = TrafficManagerTool.MoveGUI(new Rect(0, 0, 300, 150)); @@ -52,13 +52,19 @@ public override bool IsCursorInPanel() { return base.IsCursorInPanel() || _cursorInSecondaryPanel; } - private void RefreshCurrentTimedNodeIds() { + private void RefreshCurrentTimedNodeIds(ushort forceNodeId=0) { TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; - currentTimedNodeIds.Clear(); - for (uint nodeId = 1; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { - if ((Singleton.instance.m_nodes.m_buffer[nodeId].m_flags & NetNode.Flags.Created) == NetNode.Flags.None) + if (forceNodeId == 0) { + currentTimedNodeIds.Clear(); + } else { + currentTimedNodeIds.Remove(forceNodeId); + } + + for (uint nodeId = (forceNodeId == 0 ? 1u : forceNodeId); nodeId <= (forceNodeId == 0 ? NetManager.MAX_NODE_COUNT - 1 : forceNodeId); ++nodeId) { + if (!Constants.ServiceFactory.NetService.IsNodeValid((ushort)nodeId)) { continue; + } TrafficLightSimulation lightSim = tlsMan.GetNodeSimulation((ushort)nodeId); if (lightSim != null && lightSim.IsTimedLight()) { @@ -74,6 +80,10 @@ public override void OnActivate() { nodeSelectionLocked = false; foreach (ushort nodeId in currentTimedNodeIds) { + if (!Constants.ServiceFactory.NetService.IsNodeValid(nodeId)) { + continue; + } + TrafficLightSimulation lightSim = tlsMan.GetNodeSimulation(nodeId); if (lightSim != null) { lightSim.housekeeping(); @@ -110,12 +120,12 @@ public override void OnPrimaryClickOverlay() { AddSelectedNode(HoveredNodeId); } } else { - if (SelectedNodeIndexes.Count == 0) { + if (SelectedNodeIds.Count == 0) { //timedSim.housekeeping(); var timedLight = timedSim.TimedLight; if (timedLight != null) { - SelectedNodeIndexes = new List(timedLight.NodeGroup); + SelectedNodeIds = new List(timedLight.NodeGroup); MainTool.SetToolMode(ToolMode.TimedLightsShowLights); } } else { @@ -124,17 +134,17 @@ public override void OnPrimaryClickOverlay() { } break; case ToolMode.TimedLightsAddNode: - if (SelectedNodeIndexes.Count <= 0) { + if (SelectedNodeIds.Count <= 0) { MainTool.SetToolMode(ToolMode.TimedLightsSelectNode); return; } - if (SelectedNodeIndexes.Contains(HoveredNodeId)) + if (SelectedNodeIds.Contains(HoveredNodeId)) return; //bool mayEnterBlocked = Options.mayEnterBlockedJunctions; TimedTrafficLights existingTimedLight = null; - foreach (var nodeId in SelectedNodeIndexes) { + foreach (var nodeId in SelectedNodeIds) { var nodeSimulation = tlsMan.GetNodeSimulation(nodeId); if (nodeSimulation == null || !nodeSimulation.IsTimedLight()) continue; @@ -161,20 +171,21 @@ public override void OnPrimaryClickOverlay() { timedLight2.Join(existingTimedLight); ClearSelectedNodes(); - foreach (ushort nodeId in timedLight2.NodeGroup) + foreach (ushort nodeId in timedLight2.NodeGroup) { + RefreshCurrentTimedNodeIds(nodeId); AddSelectedNode(nodeId); + } MainTool.SetToolMode(ToolMode.TimedLightsShowLights); - RefreshCurrentTimedNodeIds(); break; case ToolMode.TimedLightsRemoveNode: - if (SelectedNodeIndexes.Count <= 0) { + if (SelectedNodeIds.Count <= 0) { MainTool.SetToolMode(ToolMode.TimedLightsSelectNode); return; } - if (SelectedNodeIndexes.Contains(HoveredNodeId)) { + if (SelectedNodeIds.Contains(HoveredNodeId)) { tlsMan.RemoveNodeFromSimulation(HoveredNodeId, false, false); - RefreshCurrentTimedNodeIds(); + RefreshCurrentTimedNodeIds(HoveredNodeId); } RemoveSelectedNode(HoveredNodeId); MainTool.SetToolMode(ToolMode.TimedLightsShowLights); @@ -207,6 +218,7 @@ public override void OnPrimaryClickOverlay() { targetSim.SetupTimedTrafficLight(new List { HoveredNodeId }); targetSim.TimedLight.PasteSteps(sourceTimedLights); + RefreshCurrentTimedNodeIds(HoveredNodeId); Cleanup(); AddSelectedNode(HoveredNodeId); @@ -259,9 +271,9 @@ public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { //} } - if (SelectedNodeIndexes.Count <= 0) return; + if (SelectedNodeIds.Count <= 0) return; - foreach (var index in SelectedNodeIndexes) { + foreach (var index in SelectedNodeIds) { //var segment = Singleton.instance.m_segments.m_buffer[Singleton.instance.m_nodes.m_buffer[index].m_segment0]; MainTool.DrawNodeCircle(cameraInfo, index, true, false); @@ -294,7 +306,7 @@ private void _guiTimedControlPanel(int num) { } } - var nodeSimulation = tlsMan.GetNodeSimulation(SelectedNodeIndexes[0]); + var nodeSimulation = tlsMan.GetNodeSimulation(SelectedNodeIds[0]); var timedNodeMain = nodeSimulation?.TimedLight; if (nodeSimulation == null || timedNodeMain == null) { @@ -313,7 +325,7 @@ private void _guiTimedControlPanel(int num) { if (!timedLightActive && numSteps > 0 && !_timedPanelAdd && _timedEditStep < 0 && _timedViewedStep < 0) { _timedViewedStep = 0; - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { sim.TimedLight.GetStep(_timedViewedStep).UpdateLiveLights(true); } } @@ -360,7 +372,7 @@ private void _guiTimedControlPanel(int num) { GUILayout.Space(5); GUILayout.EndVertical(); if (GUILayout.Button(Translation.GetString("Skip"), GUILayout.Width(80))) { - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { sim.TimedLight.SkipStep(); } } @@ -379,7 +391,7 @@ private void _guiTimedControlPanel(int num) { if (i > 0) { if (GUILayout.Button(Translation.GetString("up"), GUILayout.Width(48))) { - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { sim.TimedLight.MoveStep(i, i - 1); _timedViewedStep = i - 1; } @@ -390,7 +402,7 @@ private void _guiTimedControlPanel(int num) { if (i < numSteps - 1) { if (GUILayout.Button(Translation.GetString("down"), GUILayout.Width(48))) { - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { sim.TimedLight.MoveStep(i, i + 1); _timedViewedStep = i + 1; } @@ -405,7 +417,7 @@ private void _guiTimedControlPanel(int num) { _timedPanelAdd = false; _timedViewedStep = i; - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { sim.TimedLight.GetStep(i).UpdateLiveLights(true); } } @@ -421,7 +433,7 @@ private void _guiTimedControlPanel(int num) { _stepMaxValueStr = _stepMaxValue.ToString(); nodeSelectionLocked = true; - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { sim.TimedLight.GetStep(i).UpdateLiveLights(true); } } @@ -430,7 +442,7 @@ private void _guiTimedControlPanel(int num) { _timedPanelAdd = false; _timedViewedStep = -1; - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { sim.TimedLight.RemoveStep(i); } } @@ -453,7 +465,7 @@ private void _guiTimedControlPanel(int num) { _stepMaxValue = oldStepMaxValue; if (GUILayout.Button(Translation.GetString("Save"), GUILayout.Width(70))) { - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { if (_stepMinValue < 0) _stepMinValue = 0; @@ -503,7 +515,7 @@ private void _guiTimedControlPanel(int num) { _stepMaxValue = oldStepMaxValue; if (GUILayout.Button(Translation.GetString("Add"), GUILayout.Width(70))) { - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { if (_stepMinValue < 0) _stepMinValue = 0; if (_stepMaxValue <= 0) @@ -549,7 +561,7 @@ private void _guiTimedControlPanel(int num) { } if (GUILayout.Button(Translation.GetString("Stop"))) { - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { sim.TimedLight.Stop(); } } @@ -565,13 +577,13 @@ private void _guiTimedControlPanel(int num) { var curStep = timedNodeMain.CurrentStep; _waitFlowBalance = timedNodeMain.GetStep(curStep).waitFlowBalance; makeFlowPolicyDisplay(inTestMode); - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { sim.TimedLight.GetStep(curStep).waitFlowBalance = _waitFlowBalance; } //var mayEnterIfBlocked = GUILayout.Toggle(timedNodeMain.vehiclesMayEnterBlockedJunctions, Translation.GetString("Vehicles_may_enter_blocked_junctions"), new GUILayoutOption[] { }); var testMode = GUILayout.Toggle(inTestMode, Translation.GetString("Enable_test_mode_(stay_in_current_step)"), new GUILayoutOption[] { }); - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { sim.TimedLight.SetTestMode(testMode); //sim.TimedLight.vehiclesMayEnterBlockedJunctions = mayEnterIfBlocked; } @@ -581,7 +593,7 @@ private void _guiTimedControlPanel(int num) { _timedPanelAdd = false; nodeSelectionLocked = false; - foreach (var sim in SelectedNodeIndexes.Select(tlsMan.GetNodeSimulation)) { + foreach (var sim in SelectedNodeIds.Select(tlsMan.GetNodeSimulation)) { #if DEBUG // Log._Debug("Starting traffic light @ " + sim.TimedLight.NodeId); #endif @@ -599,7 +611,7 @@ private void _guiTimedControlPanel(int num) { GUILayout.Space(30); - if (SelectedNodeIndexes.Count == 1 && timedNodeMain.NumSteps() > 0) { + if (SelectedNodeIds.Count == 1 && timedNodeMain.NumSteps() > 0) { GUILayout.BeginHorizontal(); if (GUILayout.Button(Translation.GetString("Rotate_left"))) { @@ -609,7 +621,7 @@ private void _guiTimedControlPanel(int num) { } if (GUILayout.Button(Translation.GetString("Copy"))) { - nodeIdToCopy = SelectedNodeIndexes[0]; + nodeIdToCopy = SelectedNodeIds[0]; MainTool.SetToolMode(ToolMode.TimedLightsCopyLights); } @@ -629,7 +641,7 @@ private void _guiTimedControlPanel(int num) { MainTool.SetToolMode(ToolMode.TimedLightsAddNode); } - if (SelectedNodeIndexes.Count > 1) { + if (SelectedNodeIds.Count > 1) { if (GUILayout.Button(Translation.GetString("Remove_junction_from_timed_light"))) { MainTool.SetToolMode(ToolMode.TimedLightsRemoveNode); } @@ -660,11 +672,16 @@ public override void Cleanup() { _timedViewedStep = -1; timedLightActive = false; nodeIdToCopy = 0; - RefreshCurrentTimedNodeIds(); } public override void Initialize() { Cleanup(); + + if (Options.timedLightsOverlay) { + RefreshCurrentTimedNodeIds(); + } else { + currentTimedNodeIds.Clear(); + } } private void makeFlowPolicyDisplay(bool editable) { @@ -760,24 +777,24 @@ private void _guiTimedTrafficLightsPasteWindow(int num) { private void _guiTimedTrafficLightsNodeWindow(int num) { TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; - if (SelectedNodeIndexes.Count < 1) { + if (SelectedNodeIds.Count < 1) { GUILayout.Label(Translation.GetString("Select_nodes")); } else { - var txt = SelectedNodeIndexes.Aggregate("", (current, t) => current + (Translation.GetString("Node") + " " + t + "\n")); + var txt = SelectedNodeIds.Aggregate("", (current, t) => current + (Translation.GetString("Node") + " " + t + "\n")); GUILayout.Label(txt); - if (SelectedNodeIndexes.Count > 0 && GUILayout.Button(Translation.GetString("Deselect_all_nodes"))) { + if (SelectedNodeIds.Count > 0 && GUILayout.Button(Translation.GetString("Deselect_all_nodes"))) { ClearSelectedNodes(); } if (!GUILayout.Button(Translation.GetString("Setup_timed_traffic_light"))) return; _waitFlowBalance = 0.8f; - foreach (var selectedNodeIndex in SelectedNodeIndexes) { - tlsMan.AddNodeToSimulation(selectedNodeIndex); - var nodeSimulation = tlsMan.GetNodeSimulation(selectedNodeIndex); - nodeSimulation.SetupTimedTrafficLight(SelectedNodeIndexes); - RefreshCurrentTimedNodeIds(); + foreach (var nodeId in SelectedNodeIds) { + tlsMan.AddNodeToSimulation(nodeId); + var nodeSimulation = tlsMan.GetNodeSimulation(nodeId); + nodeSimulation.SetupTimedTrafficLight(SelectedNodeIds); + RefreshCurrentTimedNodeIds(nodeId); /*for (var s = 0; s < 8; s++) { var segment = Singleton.instance.m_nodes.m_buffer[selectedNodeIndex].GetSegment(s); @@ -815,31 +832,32 @@ private string getWaitFlowBalanceInfo() { return Translation.GetString("Extreme_short_green/red_phases"); } } + private void DisableTimed() { - if (SelectedNodeIndexes.Count <= 0) return; + if (SelectedNodeIds.Count <= 0) return; TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; - foreach (var selectedNodeIndex in SelectedNodeIndexes) { - tlsMan.RemoveNodeFromSimulation(selectedNodeIndex, true, false); + foreach (var selectedNodeId in SelectedNodeIds) { + tlsMan.RemoveNodeFromSimulation(selectedNodeId, true, false); + RefreshCurrentTimedNodeIds(selectedNodeId); } - RefreshCurrentTimedNodeIds(); } private void AddSelectedNode(ushort node) { - SelectedNodeIndexes.Add(node); + SelectedNodeIds.Add(node); } private bool IsNodeSelected(ushort node) { - return SelectedNodeIndexes.Contains(node); + return SelectedNodeIds.Contains(node); } private void RemoveSelectedNode(ushort node) { - SelectedNodeIndexes.Remove(node); + SelectedNodeIds.Remove(node); } private void ClearSelectedNodes() { - SelectedNodeIndexes.Clear(); + SelectedNodeIds.Clear(); } private void drawStraightLightTexture(RoadBaseAI.TrafficLightState state, Rect rect) { @@ -963,14 +981,15 @@ public override void ShowGUIOverlay(bool viewOnly) { }*/ TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; - var guiColor = GUI.color; - guiColor.a = 0.5f; - for (uint nodeId = 0; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { + foreach (ushort nodeId in currentTimedNodeIds) { + if (!Constants.ServiceFactory.NetService.IsNodeValid((ushort)nodeId)) { + continue; + } #if DEBUG bool debug = nodeId == 21361; #endif - if (SelectedNodeIndexes.Contains((ushort)nodeId)) { + if (SelectedNodeIds.Contains((ushort)nodeId)) { #if DEBUG if (debug) Log._Debug($"TimedTrafficLightsTool.ShowGUIOverlay: Node {nodeId} is selected"); @@ -981,15 +1000,6 @@ public override void ShowGUIOverlay(bool viewOnly) { TrafficLightSimulation lightSim = tlsMan.GetNodeSimulation((ushort)nodeId); if (lightSim != null && lightSim.IsTimedLight()) { TimedTrafficLights timedNode = lightSim.TimedLight; - if (timedNode == null) { -#if DEBUG - if (debug) - Log._Debug($"TimedTrafficLightsTool.ShowGUIOverlay: Node {nodeId} does not have an instance of TimedTrafficLights. Removing node from simulation"); -#endif - tlsMan.RemoveNodeFromSimulation((ushort)nodeId, true, false); - RefreshCurrentTimedNodeIds(); - break; - } var nodePositionVector3 = Singleton.instance.m_nodes.m_buffer[nodeId].m_position; var camPos = Singleton.instance.m_simulationView.m_position; @@ -1003,8 +1013,9 @@ public override void ShowGUIOverlay(bool viewOnly) { continue; var zoom = 1.0f / diff.magnitude * 100f * MainTool.GetBaseZoom(); var size = 120f * zoom; - - GUI.color = guiColor; + + var guiColor = GUI.color; + guiColor.a = 0.5f; var nodeDrawingBox = new Rect(nodeScreenPosition.x - size / 2, nodeScreenPosition.y - size / 2, size, size); //Log._Debug($"GUI Color: {guiColor} {GUI.color}"); GUI.DrawTexture(nodeDrawingBox, lightSim.IsTimedLightActive() ? (timedNode.IsInTestMode() ? TextureResources.ClockTestTexture2D : TextureResources.ClockPlayTexture2D) : TextureResources.ClockPauseTexture2D); @@ -1018,7 +1029,7 @@ private void ShowGUI() { var hoveredSegment = false; - foreach (var nodeId in SelectedNodeIndexes) { + foreach (var nodeId in SelectedNodeIds) { var nodeSimulation = tlsMan.GetNodeSimulation(nodeId); //nodeSimulation.housekeeping(); if (nodeSimulation == null || !nodeSimulation.IsTimedLight()) diff --git a/TLM/TLM/UI/SubTools/VehicleRestrictionsTool.cs b/TLM/TLM/UI/SubTools/VehicleRestrictionsTool.cs index b65e0131..2d77e503 100644 --- a/TLM/TLM/UI/SubTools/VehicleRestrictionsTool.cs +++ b/TLM/TLM/UI/SubTools/VehicleRestrictionsTool.cs @@ -22,12 +22,10 @@ public class VehicleRestrictionsTool : SubTool { private readonly float vehicleRestrictionsSignSize = 80f; private bool _cursorInSecondaryPanel; private bool overlayHandleHovered; - private Texture2D SecondPanelTexture; private Rect windowRect = TrafficManagerTool.MoveGUI(new Rect(0, 0, 620, 100)); private HashSet currentRestrictedSegmentIds; public VehicleRestrictionsTool(TrafficManagerTool mainTool) : base(mainTool) { - SecondPanelTexture = TrafficManagerTool.MakeTex(1, 1, new Color(0.5f, 0.5f, 0.5f, 1f)); currentRestrictedSegmentIds = new HashSet(); } @@ -36,11 +34,17 @@ public override void OnActivate() { RefreshCurrentRestrictedSegmentIds(); } - private void RefreshCurrentRestrictedSegmentIds() { - currentRestrictedSegmentIds.Clear(); - for (uint segmentId = 1; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId) { - if ((Singleton.instance.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Created) == NetSegment.Flags.None) + private void RefreshCurrentRestrictedSegmentIds(ushort forceSegmentId=0) { + if (forceSegmentId == 0) { + currentRestrictedSegmentIds.Clear(); + } else { + currentRestrictedSegmentIds.Remove(forceSegmentId); + } + + for (uint segmentId = (forceSegmentId == 0 ? 1u : forceSegmentId); segmentId <= (forceSegmentId == 0 ? NetManager.MAX_SEGMENT_COUNT - 1 : forceSegmentId); ++segmentId) { + if (!Constants.ServiceFactory.NetService.IsSegmentValid((ushort)segmentId)) { continue; + } if (VehicleRestrictionsManager.Instance.HasSegmentRestrictions((ushort)segmentId)) currentRestrictedSegmentIds.Add((ushort)segmentId); @@ -48,11 +52,16 @@ private void RefreshCurrentRestrictedSegmentIds() { } public override void Cleanup() { - RefreshCurrentRestrictedSegmentIds(); + } public override void Initialize() { Cleanup(); + if (Options.vehicleRestrictionsOverlay) { + RefreshCurrentRestrictedSegmentIds(); + } else { + currentRestrictedSegmentIds.Clear(); + } } public override bool IsCursorInPanel() { @@ -113,9 +122,13 @@ public override void ShowGUIOverlay(bool viewOnly) { private void ShowSigns(bool viewOnly) { Vector3 camPos = Camera.main.transform.position; NetManager netManager = Singleton.instance; - bool stateUpdated = false; + ushort updatedSegmentId = 0; bool handleHovered = false; foreach (ushort segmentId in currentRestrictedSegmentIds) { + if (!Constants.ServiceFactory.NetService.IsSegmentValid(segmentId)) { + continue; + } + var segmentInfo = netManager.m_segments.m_buffer[segmentId].Info; Vector3 centerPos = netManager.m_segments.m_buffer[segmentId].m_bounds.center; @@ -133,13 +146,15 @@ private void ShowSigns(bool viewOnly) { if (drawVehicleRestrictionHandles(segmentId, ref netManager.m_segments.m_buffer[segmentId], viewOnly || segmentId != SelectedSegmentId, out update)) handleHovered = true; - if (update) - stateUpdated = true; + if (update) { + updatedSegmentId = segmentId; + } } overlayHandleHovered = handleHovered; - if (stateUpdated) - RefreshCurrentRestrictedSegmentIds(); + if (updatedSegmentId != 0) { + RefreshCurrentRestrictedSegmentIds(updatedSegmentId); + } } private void _guiVehicleRestrictionsWindow(int num) { @@ -162,7 +177,7 @@ private void _guiVehicleRestrictionsWindow(int num) { allowedTypes = ~(allowedTypes & VehicleRestrictionsManager.EXT_VEHICLE_TYPES) & baseMask; VehicleRestrictionsManager.Instance.SetAllowedVehicleTypes(SelectedSegmentId, selectedSegmentInfo, laneIndex, laneInfo, laneId, allowedTypes); } - RefreshCurrentRestrictedSegmentIds(); + RefreshCurrentRestrictedSegmentIds(SelectedSegmentId); } GUILayout.BeginHorizontal(); @@ -183,7 +198,7 @@ private void _guiVehicleRestrictionsWindow(int num) { VehicleRestrictionsManager.Instance.SetAllowedVehicleTypes(SelectedSegmentId, selectedSegmentInfo, laneIndex, laneInfo, laneId, baseMask); } - RefreshCurrentRestrictedSegmentIds(); + RefreshCurrentRestrictedSegmentIds(SelectedSegmentId); } if (GUILayout.Button(Translation.GetString("Ban_all_vehicles"))) { @@ -203,13 +218,12 @@ private void _guiVehicleRestrictionsWindow(int num) { VehicleRestrictionsManager.Instance.SetAllowedVehicleTypes(SelectedSegmentId, selectedSegmentInfo, laneIndex, laneInfo, laneId, ~VehicleRestrictionsManager.EXT_VEHICLE_TYPES & baseMask); } - RefreshCurrentRestrictedSegmentIds(); + RefreshCurrentRestrictedSegmentIds(SelectedSegmentId); } GUILayout.EndHorizontal(); if (GUILayout.Button(Translation.GetString("Apply_vehicle_restrictions_to_all_road_segments_between_two_junctions"))) { ApplyRestrictionsToAllSegments(); - RefreshCurrentRestrictedSegmentIds(); } DragWindow(ref windowRect); @@ -253,6 +267,8 @@ private void ApplyRestrictionsToAllSegments(int? sortedLaneIndex=null) { VehicleRestrictionsManager.Instance.SetAllowedVehicleTypes(segmentId, segmentInfo, laneIndex, laneInfo, laneId, mask); + RefreshCurrentRestrictedSegmentIds(segmentId); + return true; }); } diff --git a/TLM/TLM/UI/TrafficManagerTool.cs b/TLM/TLM/UI/TrafficManagerTool.cs index 1fb745ac..f8876c9b 100644 --- a/TLM/TLM/UI/TrafficManagerTool.cs +++ b/TLM/TLM/UI/TrafficManagerTool.cs @@ -119,15 +119,19 @@ internal void Initialize() { subTools[ToolMode.JunctionRestrictions] = new JunctionRestrictionsTool(this); subTools[ToolMode.ParkingRestrictions] = new ParkingRestrictionsTool(this); - foreach (KeyValuePair e in subTools) { - e.Value.Initialize(); - } + InitializeSubTools(); SetToolMode(ToolMode.None); Log.Info("TrafficManagerTool: Initialization completed."); } + internal void InitializeSubTools() { + foreach (KeyValuePair e in subTools) { + e.Value.Initialize(); + } + } + protected override void Awake() { Log._Debug($"TrafficLightTool: Awake {this.GetHashCode()}"); base.Awake(); diff --git a/TLM/TLM/UI/UIMainMenuButton.cs b/TLM/TLM/UI/UIMainMenuButton.cs index 980031b9..73c6555c 100644 --- a/TLM/TLM/UI/UIMainMenuButton.cs +++ b/TLM/TLM/UI/UIMainMenuButton.cs @@ -84,20 +84,21 @@ protected override void OnPositionChanged() { internal void UpdateSprites() { if (! LoadingExtension.BaseUI.IsVisible()) { - normalBgSprite = disabledBgSprite = focusedBgSprite = MAIN_MENU_BUTTON_BG_BASE; - hoveredBgSprite = MAIN_MENU_BUTTON_BG_HOVERED; - pressedBgSprite = MAIN_MENU_BUTTON_BG_ACTIVE; + m_BackgroundSprites.m_Normal = m_BackgroundSprites.m_Disabled = m_BackgroundSprites.m_Focused = MAIN_MENU_BUTTON_BG_BASE; + m_BackgroundSprites.m_Hovered = MAIN_MENU_BUTTON_BG_HOVERED; + m_PressedBgSprite = MAIN_MENU_BUTTON_BG_ACTIVE; - normalFgSprite = disabledFgSprite = focusedFgSprite = MAIN_MENU_BUTTON_FG_BASE; - hoveredFgSprite = MAIN_MENU_BUTTON_FG_HOVERED; - pressedFgSprite = MAIN_MENU_BUTTON_FG_ACTIVE; + m_ForegroundSprites.m_Normal = m_ForegroundSprites.m_Disabled = m_ForegroundSprites.m_Focused = MAIN_MENU_BUTTON_FG_BASE; + m_ForegroundSprites.m_Hovered = MAIN_MENU_BUTTON_FG_HOVERED; + m_PressedFgSprite = MAIN_MENU_BUTTON_FG_ACTIVE; } else { - normalBgSprite = disabledBgSprite = focusedBgSprite = hoveredBgSprite = MAIN_MENU_BUTTON_BG_ACTIVE; - pressedBgSprite = MAIN_MENU_BUTTON_BG_HOVERED; + m_BackgroundSprites.m_Normal = m_BackgroundSprites.m_Disabled = m_BackgroundSprites.m_Focused = m_BackgroundSprites.m_Hovered = MAIN_MENU_BUTTON_BG_ACTIVE; + m_PressedBgSprite = MAIN_MENU_BUTTON_BG_HOVERED; - normalFgSprite = disabledFgSprite = focusedFgSprite = hoveredFgSprite = MAIN_MENU_BUTTON_FG_ACTIVE; - pressedFgSprite = MAIN_MENU_BUTTON_FG_HOVERED; + m_ForegroundSprites.m_Normal = m_ForegroundSprites.m_Disabled = m_ForegroundSprites.m_Focused = m_ForegroundSprites.m_Hovered = MAIN_MENU_BUTTON_FG_ACTIVE; + m_PressedFgSprite = MAIN_MENU_BUTTON_FG_HOVERED; } + this.Invalidate(); } } }