diff --git a/TLM/SharedAssemblyInfo.cs b/TLM/SharedAssemblyInfo.cs index 90f5725a6..e14a70fa3 100644 --- a/TLM/SharedAssemblyInfo.cs +++ b/TLM/SharedAssemblyInfo.cs @@ -20,4 +20,4 @@ // Minor Version // Build Number // Revision -[assembly: AssemblyVersion("11.1.2.*")] +[assembly: AssemblyVersion("11.2.0.*")] diff --git a/TLM/TLM/Custom/AI/CustomRoadBaseAI.cs b/TLM/TLM/Custom/AI/CustomRoadBaseAI.cs index 0bb8398df..df6006cb2 100644 --- a/TLM/TLM/Custom/AI/CustomRoadBaseAI.cs +++ b/TLM/TLM/Custom/AI/CustomRoadBaseAI.cs @@ -39,7 +39,7 @@ public void CustomClickNodeButton(ushort nodeId, ref NetNode data, int index) { NetManager netManager = Singleton.instance; NetInfo info = netManager.m_segments.m_buffer[segmentId].Info; - if ((info.m_vehicleTypes & (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Tram)) == + if ((info.m_vehicleTypes & (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Trolleybus)) == VehicleInfo.VehicleType.None) { return; } diff --git a/TLM/TLM/Custom/AI/CustomTransportLineAI.cs b/TLM/TLM/Custom/AI/CustomTransportLineAI.cs index d5e7b8b3a..833399e9b 100644 --- a/TLM/TLM/Custom/AI/CustomTransportLineAI.cs +++ b/TLM/TLM/Custom/AI/CustomTransportLineAI.cs @@ -168,6 +168,10 @@ public static bool CustomStartPathFind(ushort segmentId, extVehicleType = ExtVehicleType.CableCar; } + if ((vehicleType & VehicleInfo.VehicleType.Trolleybus) != VehicleInfo.VehicleType.None) { + extVehicleType = ExtVehicleType.Trolleybus; + } + // Log._Debug($"Transport line. extVehicleType={extVehicleType}"); // NON-STOCK CODE START PathCreationArgs args; diff --git a/TLM/TLM/Custom/AI/CustomTrolleybusAI.cs b/TLM/TLM/Custom/AI/CustomTrolleybusAI.cs new file mode 100644 index 000000000..4a9ad2216 --- /dev/null +++ b/TLM/TLM/Custom/AI/CustomTrolleybusAI.cs @@ -0,0 +1,213 @@ +namespace TrafficManager.Custom.AI { + using ColossalFramework; + using JetBrains.Annotations; + using Manager.Impl; + using State; + using TrafficManager.API.Traffic.Data; + using TrafficManager.API.Traffic.Enums; + using TrafficManager.Custom.PathFinding; + using TrafficManager.RedirectionFramework.Attributes; + using UnityEngine; + + [TargetType(typeof(TrolleybusAI))] + public class CustomTrolleybusAI : CarAI { + [RedirectMethod] + public void CustomCalculateSegmentPosition(ushort vehicleId, + ref Vehicle vehicleData, + PathUnit.Position nextPosition, + PathUnit.Position prevPosition, + uint prevLaneId, + byte prevOffset, + PathUnit.Position refPosition, + uint refLaneId, + byte refOffset, + int index, + out Vector3 pos, + out Vector3 dir, + out float maxSpeed) { + NetManager netManager = Singleton.instance; + ushort prevSourceNodeId; + ushort prevTargetNodeId; + NetSegment[] segBuffer = netManager.m_segments.m_buffer; + + if (prevOffset < prevPosition.m_offset) { + prevSourceNodeId = segBuffer[prevPosition.m_segment].m_startNode; + prevTargetNodeId = segBuffer[prevPosition.m_segment].m_endNode; + } else { + prevSourceNodeId = segBuffer[prevPosition.m_segment].m_endNode; + prevTargetNodeId = segBuffer[prevPosition.m_segment].m_startNode; + } + + ushort refTargetNodeId = refOffset == 0 + ? segBuffer[refPosition.m_segment].m_startNode + : segBuffer[refPosition.m_segment].m_endNode; + Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData(); + float sqrVelocity = lastFrameData.m_velocity.sqrMagnitude; + + netManager.m_lanes.m_buffer[prevLaneId].CalculatePositionAndDirection( + Constants.ByteToFloat(prevOffset), + out pos, + out dir); + Vector3 b = netManager.m_lanes.m_buffer[refLaneId].CalculatePosition( + Constants.ByteToFloat(refOffset)); + Vector3 a = lastFrameData.m_position; + Vector3 a2 = lastFrameData.m_position; + Vector3 b2 = lastFrameData.m_rotation * new Vector3( + 0f, + 0f, + m_info.m_generatedInfo.m_wheelBase * 0.5f); + a += b2; + a2 -= b2; + float crazyValue = 0.5f * sqrVelocity / m_info.m_braking; + float a3 = Vector3.Distance(a, b); + float b3 = Vector3.Distance(a2, b); + + if (Mathf.Min(a3, b3) >= crazyValue - 1f) { + // dead stock code + /*Segment3 segment; + segment.a = pos; + if (prevOffset < prevPosition.m_offset) { + segment.b = pos + dir.normalized * this.m_info.m_generatedInfo.m_size.z; + } else { + segment.b = pos - dir.normalized * this.m_info.m_generatedInfo.m_size.z; + }*/ + if (prevSourceNodeId == refTargetNodeId) { + if (!VehicleBehaviorManager.Instance.MayChangeSegment( + vehicleId, + ref vehicleData, + sqrVelocity, + ref refPosition, + ref segBuffer[refPosition.m_segment], + refTargetNodeId, + refLaneId, + ref prevPosition, + prevSourceNodeId, + ref netManager.m_nodes.m_buffer[ + prevSourceNodeId], + prevLaneId, + ref nextPosition, + prevTargetNodeId, + out maxSpeed)) { + maxSpeed = 0; + return; + } + + ExtVehicleManager.Instance.UpdateVehiclePosition( + vehicleId, + ref vehicleData + /*, lastFrameData.m_velocity.magnitude*/ + ); + } + } + + NetInfo info = segBuffer[prevPosition.m_segment].Info; + if (info.m_lanes != null && info.m_lanes.Length > prevPosition.m_lane) { + float speedLimit = Options.customSpeedLimitsEnabled + ? SpeedLimitManager.Instance.GetLockFreeGameSpeedLimit( + prevPosition.m_segment, + prevPosition.m_lane, + prevLaneId, + info.m_lanes[prevPosition.m_lane]) + : info.m_lanes[prevPosition.m_lane].m_speedLimit; + + // NON-STOCK CODE + maxSpeed = CalculateTargetSpeed( + vehicleId, + ref vehicleData, + speedLimit, + netManager.m_lanes.m_buffer[prevLaneId].m_curve); + } else { + maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f); + } + } + + + [RedirectMethod] + [UsedImplicitly] + public bool CustomStartPathFind(ushort vehicleId, + ref Vehicle vehicleData, + Vector3 startPos, + Vector3 endPos, + bool startBothWays, + bool endBothWays) { + VehicleInfo info = m_info; + bool allowUnderground = + (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0; + + if (!PathManager.FindPathPosition( + startPos, + ItemClass.Service.Road, + NetInfo.LaneType.Vehicle, + info.m_vehicleType, + allowUnderground, + false, + 32f, + out PathUnit.Position startPosA, + out PathUnit.Position startPosB, + out float startDistSqrA, + out float startDistSqrB) + || !PathManager.FindPathPosition( + endPos, + ItemClass.Service.Road, + NetInfo.LaneType.Vehicle, + info.m_vehicleType, + false, + false, + 32f, + out PathUnit.Position endPosA, + out PathUnit.Position endPosB, + out float endDistSqrA, + out float endDistSqrB)) { + return false; + } + + if (!startBothWays || startDistSqrB > startDistSqrA * 1.2f) { + startPosB = default(PathUnit.Position); + } + + if (!endBothWays || endDistSqrB > endDistSqrA * 1.2f) { + endPosB = default(PathUnit.Position); + } + + // NON-STOCK CODE START + PathCreationArgs args; + args.extPathType = ExtPathType.None; + args.extVehicleType = ExtVehicleType.Trolleybus; + args.vehicleId = vehicleId; + args.spawned = (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0; + args.buildIndex = Singleton.instance.m_currentBuildIndex; + args.startPosA = startPosA; + args.startPosB = startPosB; + args.endPosA = endPosA; + args.endPosB = endPosB; + args.vehiclePosition = default; + args.laneTypes = NetInfo.LaneType.Vehicle; + args.vehicleTypes = info.m_vehicleType; + args.maxLength = 20000f; + args.isHeavyVehicle = IsHeavyVehicle(); + args.hasCombustionEngine = CombustionEngine(); + args.ignoreBlocked = IgnoreBlocked(vehicleId, ref vehicleData); + args.ignoreFlooded = false; + args.randomParking = false; + args.ignoreCosts = false; + args.stablePath = true; + args.skipQueue = true; + + if (CustomPathManager._instance.CustomCreatePath( + out uint path, + ref Singleton.instance.m_randomizer, + args)) { + // NON-STOCK CODE END + if (vehicleData.m_path != 0u) { + Singleton.instance.ReleasePath(vehicleData.m_path); + } + + vehicleData.m_path = path; + vehicleData.m_flags |= Vehicle.Flags.WaitingPath; + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/TLM/TLM/Custom/PathFinding/CustomPathFind.cs b/TLM/TLM/Custom/PathFinding/CustomPathFind.cs index 31588416d..2b6c649f7 100644 --- a/TLM/TLM/Custom/PathFinding/CustomPathFind.cs +++ b/TLM/TLM/Custom/PathFinding/CustomPathFind.cs @@ -491,7 +491,7 @@ private void PathFindImplementation(uint unit, ref PathUnit data) { bool detourMissing = (vehicleTypes_ & (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Monorail | - VehicleInfo.VehicleType.Metro)) != VehicleInfo.VehicleType.None && + VehicleInfo.VehicleType.Metro | VehicleInfo.VehicleType.Trolleybus)) != VehicleInfo.VehicleType.None && !queueItem_.queued; if (detourMissing) { @@ -781,7 +781,7 @@ ref netManager.m_segments.m_buffer 255f); #if PARKINGAI PathUnits.m_buffer[unit].m_laneTypes = (byte)finalBufferItem.LanesUsed; - PathUnits.m_buffer[unit].m_vehicleTypes = (ushort)finalBufferItem.VehiclesUsed; + PathUnits.m_buffer[unit].m_vehicleTypes = (uint)finalBufferItem.VehiclesUsed; #endif uint currentPathUnitId = unit; @@ -1960,7 +1960,7 @@ and we are at the start segment */ #endif if (exploreUturn - && (vehicleTypes_ & VehicleInfo.VehicleType.Tram) == VehicleInfo.VehicleType.None) + && (vehicleTypes_ & (VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Trolleybus)) == VehicleInfo.VehicleType.None) { if (isLogEnabled) { DebugLog( @@ -2553,9 +2553,11 @@ private bool ProcessItemCosts( bool acuteTurningAngle = false; if (prevLaneType == NetInfo.LaneType.Vehicle && (prevVehicleType & VehicleInfo.VehicleType.Car) == VehicleInfo.VehicleType.None) { - float turningAngle = 0.01f - Mathf.Min( - nextSegmentInfo.m_maxTurnAngleCos, - prevSegmentInfo.m_maxTurnAngleCos); + float turningAngle = !nextSegment.m_overridePathFindDirectionLimit + ? (0.01f - Mathf.Min( + nextSegmentInfo.m_maxTurnAngleCos, + prevSegmentInfo.m_maxTurnAngleCos)) + : 1f; if (turningAngle < 1f) { Vector3 vector = nextNodeId != prevSegment.m_startNode ? prevSegment.m_endDirection @@ -3652,7 +3654,7 @@ private bool ProcessItemRouted( */ bool isUturnAllowedHere = false; // is u-turn allowed at this place? if ((vehicleTypes_ & - (VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Monorail)) == + (VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Monorail | VehicleInfo.VehicleType.Trolleybus)) == VehicleInfo.VehicleType.None) { // is vehicle able to perform a u-turn? bool isStockUturnPoint = (nextNode.m_flags & (NetNode.Flags.End | NetNode.Flags.OneWayOut)) != NetNode.Flags.None; @@ -4060,6 +4062,7 @@ private bool CanUseLane(ushort segmentId, if (!Options.vehicleRestrictionsEnabled || queueItem_.vehicleType == ExtVehicleType.None || queueItem_.vehicleType == ExtVehicleType.Tram || + queueItem_.vehicleType == ExtVehicleType.Trolleybus || (laneInfo.m_vehicleType & (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train)) == VehicleInfo.VehicleType.None) { diff --git a/TLM/TLM/Custom/PathFinding/CustomPathManager.cs b/TLM/TLM/Custom/PathFinding/CustomPathManager.cs index cd091fcd3..ae43839a7 100644 --- a/TLM/TLM/Custom/PathFinding/CustomPathManager.cs +++ b/TLM/TLM/Custom/PathFinding/CustomPathManager.cs @@ -235,7 +235,7 @@ public bool CustomCreatePath(out uint unit, m_pathUnits.m_buffer[unit].m_position03 = args.endPosB; m_pathUnits.m_buffer[unit].m_position11 = args.vehiclePosition; m_pathUnits.m_buffer[unit].m_laneTypes = (byte)args.laneTypes; - m_pathUnits.m_buffer[unit].m_vehicleTypes = (ushort)args.vehicleTypes; + m_pathUnits.m_buffer[unit].m_vehicleTypes = (uint)args.vehicleTypes; m_pathUnits.m_buffer[unit].m_length = args.maxLength; m_pathUnits.m_buffer[unit].m_positionCount = 20; diff --git a/TLM/TLM/Custom/PathFinding/StockPathFind.cs b/TLM/TLM/Custom/PathFinding/StockPathFind.cs index 0a8c6c029..bf16a56df 100644 --- a/TLM/TLM/Custom/PathFinding/StockPathFind.cs +++ b/TLM/TLM/Custom/PathFinding/StockPathFind.cs @@ -613,7 +613,7 @@ private void ProcessItemMain(BufferItem item, ushort nextNodeId, ref NetNode nex nextSegmentId = netManager.m_segments.m_buffer[nextSegmentId].GetRightSegment(nextNodeId); } - if (isUturnAllowedHere && (m_vehicleTypes & VehicleInfo.VehicleType.Tram) == VehicleInfo.VehicleType.None) { + if (isUturnAllowedHere && (m_vehicleTypes & VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Trolleybus) == VehicleInfo.VehicleType.None) { nextSegmentId = item.m_position.m_segment; ProcessItemCosts(item, nextNodeId, nextSegmentId, ref netManager.m_segments.m_buffer[nextSegmentId], ref prevRelSimilarLaneIndex, connectOffset, true, false); } diff --git a/TLM/TLM/LoadingExtension.cs b/TLM/TLM/LoadingExtension.cs index cb7c9e4bb..036958130 100644 --- a/TLM/TLM/LoadingExtension.cs +++ b/TLM/TLM/LoadingExtension.cs @@ -66,6 +66,10 @@ public class ManualHarmonyPatch { public static bool IsGameLoaded { get; private set; } + public static bool IsPathManagerReplaced { + get; private set; + } + /// /// Manually deployed Harmony patches /// @@ -318,8 +322,9 @@ public override void OnReleased() { public override void OnLevelUnloading() { Log.Info("OnLevelUnloading"); base.OnLevelUnloading(); - - CustomPathManager._instance.WaitForAllPaths(); + if (IsPathManagerReplaced) { + CustomPathManager._instance.WaitForAllPaths(); + } try { var reverseManagers = new List(RegisteredManagers); @@ -345,14 +350,8 @@ void Destroy() where T : MonoBehaviour { Destroy(); Destroy(); - // Custom path manger is destroyed when reloading. That is why the following code - // is commented out. - //simManager?.Remove(CustomPathManager); - //Object.Destroy(CustomPathManager); - //CustomPathManager = null; - - if (TransportDemandUI != null) { - UIView uiView = UIView.GetAView(); + //It's MonoBehaviour - comparing to null is wrong + if (TransportDemandUI) { Object.Destroy(TransportDemandUI); TransportDemandUI = null; } @@ -469,68 +468,74 @@ public override void OnLevelLoaded(LoadMode mode) { } } - try { - Log.Info("Pathfinder Compatible. Setting up CustomPathManager and SimManager."); - FieldInfo pathManagerInstance = typeof(Singleton).GetField( - "sInstance", - BindingFlags.Static | BindingFlags.NonPublic); - if (pathManagerInstance == null) { - throw new Exception("pathManagerInstance is null"); - } - - - PathManager stockPathManager = PathManager.instance; - if (stockPathManager == null) { - throw new Exception("stockPathManager is null"); - } - - Log._Debug($"Got stock PathManager instance {stockPathManager?.GetName()}"); - - CustomPathManager = stockPathManager.gameObject.AddComponent(); - Log._Debug("Added CustomPathManager to gameObject List"); - - if (CustomPathManager == null) { - Log.Error("CustomPathManager null. Error creating it."); - return; - } + //it will replace stock PathManager or already Replaced before HotReload + if (!IsPathManagerReplaced || TrafficManagerMod.Instance.InGameHotReload) { + try { + Log.Info("Pathfinder Compatible. Setting up CustomPathManager and SimManager."); + FieldInfo pathManagerInstance = typeof(Singleton).GetField( + "sInstance", + BindingFlags.Static | BindingFlags.NonPublic); + if (pathManagerInstance == null) { + throw new Exception("pathManagerInstance is null"); + } - CustomPathManager.UpdateWithPathManagerValues(stockPathManager); - Log._Debug("UpdateWithPathManagerValues success"); - pathManagerInstance.SetValue(null, CustomPathManager); + PathManager stockPathManager = PathManager.instance; + if (stockPathManager == null) { + throw new Exception("stockPathManager is null"); + } - Log._Debug("Getting Current SimulationManager"); - var simManager = this.simManager; - if (simManager == null) { - throw new Exception("simManager is null"); - } + Log._Debug($"Got stock PathManager instance {stockPathManager?.GetName()}"); - Log._Debug("Removing Stock PathManager"); - simManager.Remove(stockPathManager); + CustomPathManager = + stockPathManager.gameObject.AddComponent(); + Log._Debug("Added CustomPathManager to gameObject List"); - Log._Debug("Adding Custom PathManager"); - simManager.Add(CustomPathManager); + if (CustomPathManager == null) { + Log.Error("CustomPathManager null. Error creating it."); + return; + } - Object.Destroy(stockPathManager, 10f); + CustomPathManager.UpdateWithPathManagerValues(stockPathManager); + Log._Debug("UpdateWithPathManagerValues success"); - Log._Debug("Should be custom: " + Singleton.instance.GetType()); + pathManagerInstance.SetValue(null, CustomPathManager); - } - catch (Exception ex) { - string error = "Traffic Manager: President Edition failed to load. You can continue " + - "playing but it's NOT recommended. Traffic Manager will not work as expected."; - Log.Error(error); - Log.Error($"Path manager replacement error: {ex}"); + Log._Debug("Getting Current SimulationManager"); + var simManager = this.simManager; + if (simManager == null) { + throw new Exception("simManager is null"); + } - Singleton.instance.m_ThreadingWrapper.QueueMainThread( - () => { - UIView.library - .ShowModal("ExceptionPanel") - .SetMessage( - "TM:PE failed to load", - error, - true); - }); + Log._Debug("Removing Stock PathManager"); + simManager.Remove(stockPathManager); + + Log._Debug("Adding Custom PathManager"); + simManager.Add(CustomPathManager); + + Object.Destroy(stockPathManager, 10f); + + Log._Debug("Should be custom: " + Singleton.instance.GetType()); + + IsPathManagerReplaced = true; + } catch (Exception ex) { + string error = + "Traffic Manager: President Edition failed to load. You can continue " + + "playing but it's NOT recommended. Traffic Manager will not work as expected."; + Log.Error(error); + Log.Error($"Path manager replacement error: {ex}"); + + Singleton.instance.m_ThreadingWrapper.QueueMainThread( + () => { + UIView.library + .ShowModal( + "ExceptionPanel") + .SetMessage( + "TM:PE failed to load", + error, + true); + }); + } } Log.Info("Adding Controls to UI."); diff --git a/TLM/TLM/Manager/Impl/AdvancedParkingManager.cs b/TLM/TLM/Manager/Impl/AdvancedParkingManager.cs index 1a4b26caa..d738359f4 100644 --- a/TLM/TLM/Manager/Impl/AdvancedParkingManager.cs +++ b/TLM/TLM/Manager/Impl/AdvancedParkingManager.cs @@ -975,7 +975,7 @@ protected ExtSoftPathState OnCitizenPathFindSuccess(ushort instanceId, byte laneTypes = CustomPathManager ._instance.m_pathUnits.m_buffer[instanceData.m_path].m_laneTypes; - ushort vehicleTypes = CustomPathManager + uint vehicleTypes = CustomPathManager ._instance.m_pathUnits.m_buffer[instanceData.m_path] .m_vehicleTypes; bool usesPublicTransport = diff --git a/TLM/TLM/Manager/Impl/ExtSegmentEndManager.cs b/TLM/TLM/Manager/Impl/ExtSegmentEndManager.cs index 8b3b6cc8a..ab671399d 100644 --- a/TLM/TLM/Manager/Impl/ExtSegmentEndManager.cs +++ b/TLM/TLM/Manager/Impl/ExtSegmentEndManager.cs @@ -319,9 +319,7 @@ private void CalculateIncomingOutgoing(ushort segmentId, (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; + (ExtVehicleManager.VEHICLE_TYPES)) != 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 & dir2) != diff --git a/TLM/TLM/Manager/Impl/ExtSegmentManager.cs b/TLM/TLM/Manager/Impl/ExtSegmentManager.cs index 98145f32d..87cc281af 100644 --- a/TLM/TLM/Manager/Impl/ExtSegmentManager.cs +++ b/TLM/TLM/Manager/Impl/ExtSegmentManager.cs @@ -108,9 +108,7 @@ public bool CalculateIsOneWay(ushort segmentId) { (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; + (ExtVehicleManager.VEHICLE_TYPES)) != 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) { diff --git a/TLM/TLM/Manager/Impl/ExtVehicleManager.cs b/TLM/TLM/Manager/Impl/ExtVehicleManager.cs index 6d293ff34..306ba84a1 100644 --- a/TLM/TLM/Manager/Impl/ExtVehicleManager.cs +++ b/TLM/TLM/Manager/Impl/ExtVehicleManager.cs @@ -20,10 +20,10 @@ public class ExtVehicleManager private const int STATE_UPDATE_SHIFT = 6; public const int JUNCTION_RECHECK_SHIFT = 4; - private const VehicleInfo.VehicleType VEHICLE_TYPES = + public const VehicleInfo.VehicleType VEHICLE_TYPES = VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Metro | - VehicleInfo.VehicleType.Monorail; + VehicleInfo.VehicleType.Monorail | VehicleInfo.VehicleType.Trolleybus; /// /// Known vehicles and their current known positions. Index: vehicle id @@ -998,6 +998,10 @@ private void DetermineVehicleType(ref ExtVehicle extVehicle, ref Vehicle vehicle case VehicleInfo.VehicleType.CableCar: { return ExtVehicleType.CableCar; } + + case VehicleInfo.VehicleType.Trolleybus: { + return ExtVehicleType.Trolleybus; + } } #if DEBUGVSTATE diff --git a/TLM/TLM/Manager/Impl/LaneConnectionManager.cs b/TLM/TLM/Manager/Impl/LaneConnectionManager.cs index dac6255fc..fa2f3b2c2 100644 --- a/TLM/TLM/Manager/Impl/LaneConnectionManager.cs +++ b/TLM/TLM/Manager/Impl/LaneConnectionManager.cs @@ -25,7 +25,8 @@ public class LaneConnectionManager | VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Metro - | VehicleInfo.VehicleType.Monorail; + | VehicleInfo.VehicleType.Monorail + | VehicleInfo.VehicleType.Trolleybus; public static LaneConnectionManager Instance { get; } diff --git a/TLM/TLM/Manager/Impl/RoutingManager.cs b/TLM/TLM/Manager/Impl/RoutingManager.cs index 3ac70348a..b311e7280 100644 --- a/TLM/TLM/Manager/Impl/RoutingManager.cs +++ b/TLM/TLM/Manager/Impl/RoutingManager.cs @@ -24,7 +24,7 @@ public class RoutingManager private const VehicleInfo.VehicleType ROUTED_VEHICLE_TYPES = VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Metro | VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Tram | - VehicleInfo.VehicleType.Monorail; + VehicleInfo.VehicleType.Monorail | VehicleInfo.VehicleType.Trolleybus; private const VehicleInfo.VehicleType ARROW_VEHICLE_TYPES = VehicleInfo.VehicleType.Car; diff --git a/TLM/TLM/Manager/Impl/SpeedLimitManager.cs b/TLM/TLM/Manager/Impl/SpeedLimitManager.cs index 8c504d83a..1295d509e 100644 --- a/TLM/TLM/Manager/Impl/SpeedLimitManager.cs +++ b/TLM/TLM/Manager/Impl/SpeedLimitManager.cs @@ -28,7 +28,7 @@ public class SpeedLimitManager public const VehicleInfo.VehicleType VEHICLE_TYPES = VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Metro | VehicleInfo.VehicleType.Train | - VehicleInfo.VehicleType.Monorail; + VehicleInfo.VehicleType.Monorail | VehicleInfo.VehicleType.Trolleybus; /// Ingame speed units, max possible speed public const float MAX_SPEED = 10f * 2f; // 1000 km/h @@ -766,7 +766,7 @@ public override void OnBeforeLoadData() { log.Append("SpeedLimitManager.OnBeforeLoadData: Scan complete.\n"); Log.Info(log.ToString()); - + mainNetInfos.Sort( (NetInfo a, NetInfo b) => { // todo: move arrow function somewhere else? bool aRoad = a.m_netAI is RoadBaseAI; diff --git a/TLM/TLM/Manager/Impl/VehicleBehaviorManager.cs b/TLM/TLM/Manager/Impl/VehicleBehaviorManager.cs index f84122f01..e7e5ef3f2 100644 --- a/TLM/TLM/Manager/Impl/VehicleBehaviorManager.cs +++ b/TLM/TLM/Manager/Impl/VehicleBehaviorManager.cs @@ -1193,7 +1193,8 @@ protected VehicleJunctionTransitState MayChangeSegment( NetNode.Flags.OneWayIn)) == NetNode.Flags.Junction) { if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Tram || - vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Train) + vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Train || + vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Trolleybus) { if ((vehicleData.m_flags2 & Vehicle.Flags2.Yielding) == 0) { @@ -1460,7 +1461,8 @@ ref segEndMan.ExtSegmentEnds[segEndMan.GetIndex(prevPos.m_segment, isTargetStart "JunctionTransitState to STOP"); if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Tram || - vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Train) + vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Train || + vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Trolleybus) { vehicleData.m_flags2 |= Vehicle.Flags2.Yielding; vehicleData.m_waitCounter = 0; @@ -1476,7 +1478,8 @@ ref segEndMan.ExtSegmentEnds[segEndMan.GetIndex(prevPos.m_segment, isTargetStart $"Setting JunctionTransitState to LEAVE ({vehicleLightState})"); if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Tram || - vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Train) + vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Train || + vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Trolleybus) { vehicleData.m_flags2 &= ~Vehicle.Flags2.Yielding; vehicleData.m_waitCounter = 0; diff --git a/TLM/TLM/Manager/Impl/VehicleRestrictionsManager.cs b/TLM/TLM/Manager/Impl/VehicleRestrictionsManager.cs index 023da5441..8e46f0eda 100644 --- a/TLM/TLM/Manager/Impl/VehicleRestrictionsManager.cs +++ b/TLM/TLM/Manager/Impl/VehicleRestrictionsManager.cs @@ -22,12 +22,12 @@ public class VehicleRestrictionsManager public const VehicleInfo.VehicleType VEHICLE_TYPES = VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Tram - | VehicleInfo.VehicleType.Monorail; + | VehicleInfo.VehicleType.Monorail | VehicleInfo.VehicleType.Trolleybus; public const ExtVehicleType EXT_VEHICLE_TYPES = ExtVehicleType.PassengerTrain | ExtVehicleType.CargoTrain | ExtVehicleType.PassengerCar | ExtVehicleType.Bus | ExtVehicleType.Taxi | ExtVehicleType.CargoTruck - | ExtVehicleType.Service | ExtVehicleType.Emergency; + | ExtVehicleType.Service | ExtVehicleType.Emergency | ExtVehicleType.Trolleybus; public static readonly float[] PATHFIND_PENALTIES = { 10f, 100f, 1000f }; diff --git a/TLM/TLM/TLM.csproj b/TLM/TLM/TLM.csproj index 688bc668e..dbec3d0ff 100644 --- a/TLM/TLM/TLM.csproj +++ b/TLM/TLM/TLM.csproj @@ -140,6 +140,7 @@ + diff --git a/TLM/TLM/Traffic/ExtVehicleType.cs b/TLM/TLM/Traffic/ExtVehicleType.cs index 3dfe8f8a1..52c6dfd59 100644 --- a/TLM/TLM/Traffic/ExtVehicleType.cs +++ b/TLM/TLM/Traffic/ExtVehicleType.cs @@ -38,6 +38,7 @@ public enum ExtVehicleType { PassengerFerry = 1 << 16, PassengerBlimp = 1 << 17, CargoPlane = 1 << 18, + TrolleyBus = 1 << 19, [UsedImplicitly] Plane = PassengerPlane | CargoPlane, @@ -47,7 +48,7 @@ public enum ExtVehicleType { [UsedImplicitly] CargoVehicle = CargoTruck | CargoTrain | CargoShip | CargoPlane, - PublicTransport = Bus | Taxi | Tram | PassengerTrain, + PublicTransport = Bus | Taxi | Tram | PassengerTrain | TrolleyBus, [UsedImplicitly] RoadPublicTransport = Bus | Taxi, diff --git a/TLM/TLM/TrafficManagerMod.cs b/TLM/TLM/TrafficManagerMod.cs index a5525ceb8..bcd475a20 100644 --- a/TLM/TLM/TrafficManagerMod.cs +++ b/TLM/TLM/TrafficManagerMod.cs @@ -23,11 +23,11 @@ public class TrafficManagerMod : IUserMod { #endif // These values from `BuildConfig` class (`APPLICATION_VERSION` constants) in game file `Managed/Assembly-CSharp.dll` (use ILSpy to inspect them) - public const uint GAME_VERSION = 185066000u; + public const uint GAME_VERSION = 188868368U; public const uint GAME_VERSION_A = 1u; - public const uint GAME_VERSION_B = 12u; - public const uint GAME_VERSION_C = 3u; - public const uint GAME_VERSION_BUILD = 2u; + public const uint GAME_VERSION_B = 13u; + public const uint GAME_VERSION_C = 0u; + public const uint GAME_VERSION_BUILD = 7u; // Use SharedAssemblyInfo.cs to modify TM:PE version // External mods (eg. CSUR Toolbox) reference the versioning for compatibility purposes diff --git a/TLM/TMPE.API/Traffic/Enums/ExtVehicleType.cs b/TLM/TMPE.API/Traffic/Enums/ExtVehicleType.cs index a9b4e6692..711f75d03 100644 --- a/TLM/TMPE.API/Traffic/Enums/ExtVehicleType.cs +++ b/TLM/TMPE.API/Traffic/Enums/ExtVehicleType.cs @@ -27,15 +27,16 @@ public enum ExtVehicleType { PassengerFerry = 1 << 16, PassengerBlimp = 1 << 17, CargoPlane = 1 << 18, + Trolleybus = 1 << 19, Plane = PassengerPlane | CargoPlane, Ship = PassengerShip | CargoShip, CargoVehicle = CargoTruck | CargoTrain | CargoShip | CargoPlane, - PublicTransport = Bus | Taxi | Tram | PassengerTrain, - RoadPublicTransport = Bus | Taxi, - RoadVehicle = PassengerCar | Bus | Taxi | CargoTruck | Service | Emergency, + PublicTransport = Bus | Taxi | Tram | PassengerTrain | Trolleybus, + RoadPublicTransport = Bus | Taxi | Trolleybus, + RoadVehicle = PassengerCar | Bus | Taxi | CargoTruck | Service | Emergency,//may perform u-turn RailVehicle = PassengerTrain | CargoTrain, NonTransportRoadVehicle = RoadVehicle & ~PublicTransport, Ferry = PassengerFerry, - Blimp = PassengerBlimp + Blimp = PassengerBlimp, } } \ No newline at end of file