public override bool TrySpawn(ushort vehicleID, ref Vehicle vehicleData) { if ((vehicleData.m_flags & Vehicle.Flags.Spawned) != (Vehicle.Flags) 0) { // NON-STOCK CODE START if (Options.prioritySignsEnabled || Options.timedLightsEnabled) { VehicleStateManager.Instance().OnVehicleSpawned(vehicleID, ref vehicleData); } // NON-STOCK CODE END return(true); } if (vehicleData.m_path != 0u) { PathManager instance = Singleton <PathManager> .instance; PathUnit.Position pathPos; if (instance.m_pathUnits.m_buffer[(int)((UIntPtr)vehicleData.m_path)].GetPosition(0, out pathPos)) { uint laneID = PathManager.GetLaneID(pathPos); if (laneID != 0u && !Singleton <NetManager> .instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(1000f, vehicleID)) { vehicleData.m_flags |= Vehicle.Flags.WaitingSpace; return(false); } } } vehicleData.Spawn(vehicleID); vehicleData.m_flags &= ~Vehicle.Flags.WaitingSpace; CustomTrainAI.InitializePath(vehicleID, ref vehicleData); // NON-STOCK CODE START if (Options.prioritySignsEnabled || Options.timedLightsEnabled) { VehicleStateManager.Instance().OnVehicleSpawned(vehicleID, ref vehicleData); } // NON-STOCK CODE END return(true); }
public void CustomCheckNextLane(ushort vehicleID, ref Vehicle vehicleData, ref float maxSpeed, PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID, byte prevOffset, Bezier3 bezier) { if ((Options.prioritySignsEnabled || Options.timedLightsEnabled) && Options.simAccuracy <= 1) { try { VehicleStateManager.Instance().UpdateVehiclePos(vehicleID, ref vehicleData, ref prevPos, ref position); } catch (Exception e) { Log.Error("TrainAI CustomCheckNextLane Error: " + e.ToString()); } } NetManager instance = Singleton <NetManager> .instance; Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData(); Vector3 a = lastFrameData.m_position; Vector3 a2 = lastFrameData.m_position; Vector3 b = lastFrameData.m_rotation * new Vector3(0f, 0f, this.m_info.m_generatedInfo.m_wheelBase * 0.5f); a += b; a2 -= b; float num = 0.5f * lastFrameData.m_velocity.sqrMagnitude / this.m_info.m_braking; float a3 = Vector3.Distance(a, bezier.a); float b2 = Vector3.Distance(a2, bezier.a); if (Mathf.Min(a3, b2) >= num - 5f) { if (!instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(1000f, vehicleID)) { maxSpeed = 0f; return; } Vector3 vector = bezier.Position(0.5f); Segment3 segment; if (Vector3.SqrMagnitude(vehicleData.m_segment.a - vector) < Vector3.SqrMagnitude(bezier.a - vector)) { segment = new Segment3(vehicleData.m_segment.a, vector); } else { segment = new Segment3(bezier.a, vector); } if (segment.LengthSqr() >= 3f) { segment.a += (segment.b - segment.a).normalized * 2.5f; if (CustomTrainAI.CheckOverlap(vehicleID, ref vehicleData, segment, vehicleID)) { maxSpeed = 0f; return; } } segment = new Segment3(vector, bezier.d); if (segment.LengthSqr() >= 1f && CustomTrainAI.CheckOverlap(vehicleID, ref vehicleData, segment, vehicleID)) { maxSpeed = 0f; return; } ushort targetNodeId; if (offset < position.m_offset) { targetNodeId = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode; } else { targetNodeId = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode; } ushort prevTargetNodeId; if (prevOffset == 0) { prevTargetNodeId = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_startNode; } else { prevTargetNodeId = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_endNode; } if (targetNodeId == prevTargetNodeId) { float oldMaxSpeed = maxSpeed; #if DEBUG bool debug = false; // targetNodeId == 14527 || targetNodeId == 15048; if (debug) { Log._Debug($"Train {vehicleID} wants to change segment. seg. {prevPos.m_segment} -> node {targetNodeId} -> seg. {position.m_segment}"); } #else bool debug = false; #endif bool mayChange = CustomVehicleAI.MayChangeSegment(vehicleID, ref vehicleData, ref lastFrameData, false, ref prevPos, prevTargetNodeId, prevLaneID, ref position, targetNodeId, laneID, out maxSpeed, debug); if (!mayChange) { return; } maxSpeed = oldMaxSpeed; } } }
public void CustomCheckNextLane(ushort vehicleID, ref Vehicle vehicleData, ref float maxSpeed, PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID, byte prevOffset, Bezier3 bezier) { NetManager instance = Singleton <NetManager> .instance; Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData(); Vector3 a = lastFrameData.m_position; Vector3 a2 = lastFrameData.m_position; Vector3 b = lastFrameData.m_rotation * new Vector3(0f, 0f, this.m_info.m_generatedInfo.m_wheelBase * 0.5f); a += b; a2 -= b; float num = 0.5f * lastFrameData.m_velocity.sqrMagnitude / this.m_info.m_braking; float a3 = Vector3.Distance(a, bezier.a); float b2 = Vector3.Distance(a2, bezier.a); if (Mathf.Min(a3, b2) >= num - 5f) { if (!instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(1000f, vehicleID)) { maxSpeed = 0f; return; } Vector3 vector = bezier.Position(0.5f); Segment3 segment; if (Vector3.SqrMagnitude(vehicleData.m_segment.a - vector) < Vector3.SqrMagnitude(bezier.a - vector)) { segment = new Segment3(vehicleData.m_segment.a, vector); } else { segment = new Segment3(bezier.a, vector); } if (segment.LengthSqr() >= 3f) { segment.a += (segment.b - segment.a).normalized * 2.5f; if (CustomTrainAI.CheckOverlap(vehicleID, ref vehicleData, segment, vehicleID)) { maxSpeed = 0f; return; } } segment = new Segment3(vector, bezier.d); if (segment.LengthSqr() >= 1f && CustomTrainAI.CheckOverlap(vehicleID, ref vehicleData, segment, vehicleID)) { maxSpeed = 0f; return; } ushort num2; if (offset < position.m_offset) { num2 = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode; } else { num2 = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode; } ushort num3; if (prevOffset == 0) { num3 = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_startNode; } else { num3 = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_endNode; } if (num2 == num3) { NetNode.Flags flags = instance.m_nodes.m_buffer[(int)num2].m_flags; if ((flags & NetNode.Flags.TrafficLights) != NetNode.Flags.None) { uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex; uint num4 = (uint)(((int)num3 << 8) / 32768); uint num5 = currentFrameIndex - num4 & 255u; RoadBaseAI.TrafficLightState vehicleLightState; RoadBaseAI.TrafficLightState pedestrianLightState; bool flag; bool pedestrians; /// NON-STOCK CODE START /// CustomRoadAI.GetTrafficLightState(vehicleID, ref vehicleData, num3, prevPos.m_segment, position.m_segment, ref instance.m_segments.m_buffer[(int)prevPos.m_segment], currentFrameIndex - num4, out vehicleLightState, out pedestrianLightState, out flag, out pedestrians); /// NON-STOCK CODE END /// //RoadBaseAI.GetTrafficLightState(num3, ref instance.m_segments.m_buffer[(int)prevPos.m_segment], currentFrameIndex - num4, out vehicleLightState, out pedestrianLightState, out flag, out pedestrians); if (!flag && num5 >= 196u) { flag = true; RoadBaseAI.SetTrafficLightState(num3, ref instance.m_segments.m_buffer[(int)prevPos.m_segment], currentFrameIndex - num4, vehicleLightState, pedestrianLightState, flag, pedestrians); } switch (vehicleLightState) { case RoadBaseAI.TrafficLightState.RedToGreen: if (num5 < 60u) { maxSpeed = 0f; return; } break; case RoadBaseAI.TrafficLightState.Red: maxSpeed = 0f; return; case RoadBaseAI.TrafficLightState.GreenToRed: if (num5 >= 30u) { maxSpeed = 0f; return; } break; } } } } }