private static void DrawConsistSpeedLimit() { if (Instance == null) { return; } if (sortedTrainSet == null) { return; } scanCar = scanDir > 0 ? sortedTrainSet.cars.Last().trainCar : sortedTrainSet.cars.First().trainCar; scanBogie = scanCar.Bogies[(sortedTrainSet[scanCar].forward == (scanDir > 0)) ? 0 : scanCar.Bogies.Length - 1]; var track = scanBogie.track; if (track == null) { return; } var startSpan = scanBogie.traveller.Span; var direction = !(sortedTrainSet[scanCar].forward == (scanDir > 0)) ^ (scanBogie.trackDirection > 0); var currentGrade = TrackIndexer.Grade(scanBogie.point1) * (direction ? 1 : -1); var events = TrackFollower.FollowTrack( track, startSpan, direction ? trainLength : -trainLength); var eventDescriptions = events .ExceptUnnamedTracks() .ResolveJunctionSpeedLimits() .FilterRedundantSpeedLimits() .FilterGradeEvents(currentGrade) .Take(Main.settings.maxEventCount) .TakeWhile(ev => ev.span < trainLength); var speeds = eventDescriptions.Where(e => e is SpeedLimitEvent).Cast <SpeedLimitEvent>().Select(s => ((float)s.span, (float)s.limit)); var limit = (speeds.Count() > 0) ? speeds.Min(s => s.Item2) : 200; limit = Mathf.Min(limit, TrackFollower.GetSpeedLimit(track, startSpan, direction) ?? 0f); Instance.SetSpeedLimitConsist(speedLimitConsist = limit); }
private static void DrawUpcomingEvents() { if (Instance == null) { return; } if (sortedTrainSet == null) { return; } scanCar = scanDir > 0 ? sortedTrainSet.cars.First().trainCar : sortedTrainSet.cars.Last().trainCar; scanBogie = scanCar.Bogies[(sortedTrainSet[scanCar].forward == (scanDir > 0)) ? scanCar.Bogies.Length - 1 : 0]; var track = scanBogie.track; if (track == null) { return; } var startSpan = scanBogie.traveller.Span; var direction = !(sortedTrainSet[scanCar].forward == (scanDir > 0)) ^ (scanBogie.trackDirection > 0); // !(scanDir >= 0f) ^ (scanBogie.trackDirection > 0); var currentGrade = TrackIndexer.Grade(scanBogie.point1) * (direction ? 1 : -1); var scanDistance = Instance.TrackPlannerDisplayDistance + 100; var events = TrackFollower.FollowTrack( track, startSpan, direction ? scanDistance : -scanDistance); var eventDescriptions = events .ExceptUnnamedTracks() .ResolveJunctionSpeedLimits() .FilterRedundantSpeedLimits() .FilterGradeEvents(currentGrade) .Take(Main.settings.maxEventCount) .TakeWhile(ev => ev.span < Main.settings.maxEventSpan); IEnumerable <(float span, float limit)> trackSpeedEvents = eventDescriptions.Where(e => e is SpeedLimitEvent).Cast <SpeedLimitEvent>().Select(s => ((float)s.span, (float)s.limit)); var nextSpeedEvents = trackSpeedEvents.Where(e => e.span < 250); (float span, float limit)nextForSpan = trackSpeedEvents.Aggregate((a, b) => a.span < b.span ? a : b); (float span, float limit)nextForLimit = trackSpeedEvents.Aggregate((a, b) => a.limit < b.limit ? a : b); float lerpVal = Mathf.Clamp01(nextForLimit.span * 0.002f); float maxSpeed = Mathf.Min(Mathf.Lerp(nextForLimit.limit, speedLimitConsist, lerpVal), speedLimitConsist); Instance.SetSpeedMax(maxSpeed); if (nextForSpan.span <= 0.1f) { Instance.SetSpeedLimitNext(currentSpeedLimitNext = nextForSpan.limit); } if (currentSpeedLimitNext > nextForLimit.limit) { Instance.SetSpeedLimitNext(currentSpeedLimitNext = nextForLimit.limit); } Instance.SetTrackSpeedItems(trackSpeedEvents.ToArray()); Instance.SetTrackGradeItems(eventDescriptions.Where(e => e is GradeEvent).Cast <GradeEvent>().Select(s => ((float)s.span, (float)s.grade * 10, -1f)).ToArray()); var junctionEvents = eventDescriptions.Where(e => e is JunctionEvent); Junction?nextJunction = null; if (junctionEvents.Any()) { nextJunction = ((JunctionEvent)junctionEvents.Aggregate((a, b) => a.span < b.span ? a : b)).junction; Instance.SetTrackJunctionItems(junctionEvents.Cast <JunctionEvent>().Select(s => ((float)(s.span - 1.3), (float)0)).ToArray()); } Instance.NextJunction = nextJunction; Instance.SetNextWyeDir((nextJunction == null) ? WyeDirection.NA : (nextJunction.selectedBranch == 0) ? WyeDirection.Left : WyeDirection.Right); }