public void AddMessage(string key, string text, double duration) { var clockTime = Owner.Viewer.Simulator.ClockTime; var gameTime = Owner.Viewer.Simulator.GameTime; while (true) { // Store the original list and make a clone for replacing it thread-safely. var oldMessages = Messages; var newMessages = new List <Message>(oldMessages); // Find an existing message if there is one. var existingMessage = String.IsNullOrEmpty(key) ? null : newMessages.FirstOrDefault(m => m.Key == key); // Clean out any existing duplicate key and expired messages. newMessages = (from m in newMessages where (String.IsNullOrEmpty(key) || m.Key != key) && m.EndTime + FadeTime > Owner.Viewer.Simulator.GameTime select m).ToList(); // Add the new message. newMessages.Add(new Message(key, String.Format("{0} {1}", FormatStrings.FormatTime(clockTime), text), existingMessage != null ? existingMessage.StartTime : gameTime, gameTime + duration)); // Sort the messages. newMessages = (from m in newMessages orderby m.StartTime descending select m).ToList(); // Thread-safely switch from the old list to the new list; we've only suceeded if the previous (return) value is the old list. if (Interlocked.CompareExchange(ref Messages, newMessages, oldMessages) == oldMessages) { break; } } MessagesChanged = true; }
public void FormattedTimeStrings() { TimeSpan duration = new TimeSpan(1, 13, 37, 45, 20); //1d 13:37:45.020 Assert.AreEqual("13:37:45", FormatStrings.FormatTime(duration.TotalSeconds)); Assert.AreEqual("13:37:45.20", FormatStrings.FormatPreciseTime(duration.TotalSeconds)); Assert.AreEqual("13:37", FormatStrings.FormatApproximateTime(duration.TotalSeconds)); }
/// <summary> /// Retrieve a formatted list <see cref="ListLabel"/>s to be displayed as an in-browser Track Monitor. /// </summary> /// <param name="viewer">The Viewer to read train data from.</param> /// <returns>A list of <see cref="ListLabel"/>s, one per row of the popup.</returns> public static IEnumerable <ListLabel> TrainDrivingDisplayList(this Viewer viewer, bool normalTextMode = true) { bool useMetric = viewer.MilepostUnitsMetric; var labels = new List <ListLabel>(); void AddLabel(ListLabel label) { CheckLabel(ref label, normalTextMode); labels.Add(label); } void AddSeparator() => AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Sprtr"), }); TrainCar trainCar = viewer.PlayerLocomotive; Train train = trainCar.Train; string trainBrakeStatus = trainCar.GetTrainBrakeStatus(); string dynamicBrakeStatus = trainCar.GetDynamicBrakeStatus(); string engineBrakeStatus = trainCar.GetEngineBrakeStatus(); MSTSLocomotive locomotive = (MSTSLocomotive)trainCar; string locomotiveStatus = locomotive.GetStatus(); bool combinedControlType = locomotive.CombinedControlType == MSTSLocomotive.CombinedControl.ThrottleDynamic; bool showMUReverser = Math.Abs(train.MUReverserPercent) != 100f; bool showRetainers = train.RetainerSetting != RetainerSetting.Exhaust; bool stretched = train.Cars.Count > 1 && train.NPull == train.Cars.Count - 1; bool bunched = !stretched && train.Cars.Count > 1 && train.NPush == train.Cars.Count - 1; Train.TrainInfo trainInfo = train.GetTrainInfo(); // First Block // Client and server may have a time difference. AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Time"), LastCol = FormatStrings.FormatTime(viewer.Simulator.ClockTime + (MultiPlayer.MPManager.IsClient() ? MultiPlayer.MPManager.Instance().serverTimeDifference : 0)), }); if (viewer.Simulator.IsReplaying) { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Replay"), LastCol = FormatStrings.FormatTime(viewer.Log.ReplayEndsAt - viewer.Simulator.ClockTime), }); } Color speedColor; if (locomotive.SpeedMpS < trainInfo.allowedSpeedMpS - 1f) { speedColor = Color.White; } else if (locomotive.SpeedMpS < trainInfo.allowedSpeedMpS) { speedColor = Color.PaleGreen; } else if (locomotive.SpeedMpS < trainInfo.allowedSpeedMpS + 5f) { speedColor = Color.Orange; } else { speedColor = Color.OrangeRed; } AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Speed"), LastCol = $"{FormatStrings.FormatSpeedDisplay(locomotive.SpeedMpS, useMetric)}{ColorCode[speedColor]}", }); // Gradient info if (normalTextMode) { float gradient = -trainInfo.currentElevationPercent; const float minSlope = 0.00015f; string gradientIndicator; if (gradient < -minSlope) { gradientIndicator = $"{gradient:F1}%{Symbols.GradientDown}{ColorCode[Color.LightSkyBlue]}"; } else if (gradient > minSlope) { gradientIndicator = $"{gradient:F1}%{Symbols.GradientUp}{ColorCode[Color.Yellow]}"; } else { gradientIndicator = $"{gradient:F1}%"; } AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Gradient"), LastCol = gradientIndicator, }); } // Separator AddSeparator(); // Second block // Direction { UserCommand?reverserCommand = GetPressedKey(UserCommand.ControlBackwards, UserCommand.ControlForwards); string reverserKey; bool moving = Math.Abs(trainCar.SpeedMpS) > 1; bool nonSteamEnd = trainCar.EngineType != TrainCar.EngineTypes.Steam && trainCar.Direction == Direction.N && (trainCar.ThrottlePercent >= 1 || moving); bool steamEnd = locomotive is MSTSSteamLocomotive steamLocomotive2 && steamLocomotive2.CutoffController.MaximumValue == Math.Abs(train.MUReverserPercent / 100); if (reverserCommand != null && (nonSteamEnd || steamEnd)) { reverserKey = Symbols.End + ColorCode[Color.Yellow]; } else if (reverserCommand == UserCommand.ControlBackwards) { reverserKey = Symbols.ArrowDown + ColorCode[Color.Yellow]; } else if (reverserCommand == UserCommand.ControlForwards) { reverserKey = Symbols.ArrowUp + ColorCode[Color.Yellow]; } else { reverserKey = ""; } string reverserIndicator = showMUReverser ? $"{Round(Math.Abs(train.MUReverserPercent))}% " : ""; AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString(locomotive.EngineType == TrainCar.EngineTypes.Steam ? "Reverser" : "Direction"), LastCol = $"{reverserIndicator}{FormatStrings.Catalog.GetParticularString("Reverser", GetStringAttribute.GetPrettyName(locomotive.Direction))}", KeyPressed = reverserKey, SymbolCol = reverserKey, }); } // Throttle { UserCommand?throttleCommand = GetPressedKey(UserCommand.ControlThrottleDecrease, UserCommand.ControlThrottleIncrease); string throttleKey; bool upperLimit = throttleCommand == UserCommand.ControlThrottleIncrease && locomotive.ThrottleController.MaximumValue == trainCar.ThrottlePercent / 100; bool lowerLimit = throttleCommand == UserCommand.ControlThrottleDecrease && trainCar.ThrottlePercent == 0; if (locomotive.DynamicBrakePercent < 1 && (upperLimit || lowerLimit)) { throttleKey = Symbols.End + ColorCode[Color.Yellow]; } else if (locomotive.DynamicBrakePercent > -1) { throttleKey = Symbols.EndLower + ColorCode[Color.Yellow]; } else if (throttleCommand == UserCommand.ControlThrottleIncrease) { throttleKey = Symbols.ArrowUp + ColorCode[Color.Yellow]; } else if (throttleCommand == UserCommand.ControlThrottleDecrease) { throttleKey = Symbols.ArrowDown + ColorCode[Color.Yellow]; } else { throttleKey = ""; } AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString(locomotive is MSTSSteamLocomotive ? "Regulator" : "Throttle"), LastCol = $"{Round(locomotive.ThrottlePercent)}%", KeyPressed = throttleKey, SymbolCol = throttleKey, }); } // Cylinder Cocks if (locomotive is MSTSSteamLocomotive steamLocomotive) { string cocksIndicator, cocksKey; if (steamLocomotive.CylinderCocksAreOpen) { cocksIndicator = Viewer.Catalog.GetString("Open") + ColorCode[Color.Orange]; cocksKey = Symbols.ArrowToRight + ColorCode[Color.Yellow]; } else { cocksIndicator = Viewer.Catalog.GetString("Closed") + ColorCode[Color.White]; cocksKey = ""; } AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Cylinder cocks"), LastCol = cocksIndicator, KeyPressed = cocksKey, SymbolCol = cocksKey, }); } // Sander if (locomotive.GetSanderOn()) { bool sanderBlocked = locomotive.AbsSpeedMpS > locomotive.SanderSpeedOfMpS; string sanderKey = Symbols.ArrowToRight + ColorCode[Color.Yellow]; AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Sander"), LastCol = sanderBlocked ? Viewer.Catalog.GetString("Blocked") + ColorCode[Color.OrangeRed] : Viewer.Catalog.GetString("On") + ColorCode[Color.Orange], KeyPressed = sanderKey, SymbolCol = sanderKey, }); } else { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Sander"), LastCol = Viewer.Catalog.GetString("Off"), KeyPressed = "", SymbolCol = "", }); } AddSeparator(); // Train Brake multi-lines // TODO: A better algorithm //var brakeStatus = Owner.Viewer.PlayerLocomotive.GetTrainBrakeStatus(); //steam loco string brakeInfoValue = ""; int index = 0; if (trainBrakeStatus.Contains(Viewer.Catalog.GetString("EQ"))) { string brakeKey; switch (GetPressedKey(UserCommand.ControlTrainBrakeDecrease, UserCommand.ControlTrainBrakeIncrease)) { case UserCommand.ControlTrainBrakeDecrease: brakeKey = Symbols.ArrowDown + ColorCode[Color.Yellow]; break; case UserCommand.ControlTrainBrakeIncrease: brakeKey = Symbols.ArrowUp + ColorCode[Color.Yellow]; break; default: brakeKey = ""; break; } brakeInfoValue = trainBrakeStatus.Substring(0, trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("EQ"))).TrimEnd(); AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Train brake"), LastCol = $"{brakeInfoValue}{ColorCode[Color.Cyan]}", KeyPressed = brakeKey, SymbolCol = brakeKey, }); index = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("EQ")); brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("BC")) - index).TrimEnd(); AddLabel(new ListLabel { LastCol = brakeInfoValue, }); if (trainBrakeStatus.Contains(Viewer.Catalog.GetString("EOT"))) { int indexOffset = Viewer.Catalog.GetString("EOT").Length + 1; index = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("BC")); brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("EOT")) - index).TrimEnd(); AddLabel(new ListLabel { LastCol = brakeInfoValue, }); index = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("EOT")) + indexOffset; brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.Length - index).TrimStart(); AddLabel(new ListLabel { LastCol = brakeInfoValue, }); } else { index = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("BC")); brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.Length - index).TrimEnd(); AddLabel(new ListLabel { LastCol = brakeInfoValue, }); } } else if (trainBrakeStatus.Contains(Viewer.Catalog.GetString("Lead"))) { int indexOffset = Viewer.Catalog.GetString("Lead").Length + 1; brakeInfoValue = trainBrakeStatus.Substring(0, trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("Lead"))).TrimEnd(); AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Train brake"), LastCol = $"{brakeInfoValue}{ColorCode[Color.Cyan]}", }); index = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("Lead")) + indexOffset; if (trainBrakeStatus.Contains(Viewer.Catalog.GetString("EOT"))) { brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("EOT")) - index).TrimEnd(); AddLabel(new ListLabel { LastCol = brakeInfoValue, }); index = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("EOT")) + indexOffset; brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.Length - index).TrimEnd(); AddLabel(new ListLabel { LastCol = brakeInfoValue, }); } else { brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.Length - index).TrimEnd(); AddLabel(new ListLabel { LastCol = brakeInfoValue, }); } } else if (trainBrakeStatus.Contains(Viewer.Catalog.GetString("BC"))) { brakeInfoValue = trainBrakeStatus.Substring(0, trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("BC"))).TrimEnd(); AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Train brake"), LastCol = $"{brakeInfoValue}{ColorCode[Color.Cyan]}", }); index = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("BC")); brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.Length - index).TrimEnd(); AddLabel(new ListLabel { LastCol = brakeInfoValue, }); } if (showRetainers) { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Retainers"), LastCol = $"{train.RetainerPercent} {Viewer.Catalog.GetString(GetStringAttribute.GetPrettyName(train.RetainerSetting))}", }); } if (engineBrakeStatus.Contains(Viewer.Catalog.GetString("BC"))) { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Engine brake"), LastCol = engineBrakeStatus.Substring(0, engineBrakeStatus.IndexOf("BC")) + ColorCode[Color.Cyan], }); index = engineBrakeStatus.IndexOf(Viewer.Catalog.GetString("BC")); brakeInfoValue = engineBrakeStatus.Substring(index, engineBrakeStatus.Length - index).TrimEnd(); AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString(""), LastCol = $"{brakeInfoValue}{ColorCode[Color.White]}", }); } else { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Engine brake"), LastCol = $"{engineBrakeStatus}{ColorCode[Color.Cyan]}", }); } if (dynamicBrakeStatus != null && locomotive.IsLeadLocomotive()) { if (locomotive.DynamicBrakePercent >= 0) { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Dynamic brake"), LastCol = locomotive.DynamicBrake ? dynamicBrakeStatus : Viewer.Catalog.GetString("Setup") + ColorCode[Color.Cyan], }); } else { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Dynamic brake"), LastCol = Viewer.Catalog.GetString("Off"), }); } } AddSeparator(); if (locomotiveStatus != null) { foreach (string data in locomotiveStatus.Split('\n').Where((string d) => !string.IsNullOrWhiteSpace(d))) { string[] parts = data.Split(new string[] { " = " }, 2, StringSplitOptions.None); string keyPart = parts[0]; string valuePart = parts?[1]; if (Viewer.Catalog.GetString(keyPart).StartsWith(Viewer.Catalog.GetString("Boiler pressure"))) { MSTSSteamLocomotive steamLocomotive2 = (MSTSSteamLocomotive)locomotive; float bandUpper = steamLocomotive2.PreviousBoilerHeatOutBTUpS * 1.025f; // find upper bandwidth point float bandLower = steamLocomotive2.PreviousBoilerHeatOutBTUpS * 0.975f; // find lower bandwidth point - gives a total 5% bandwidth string heatIndicator; if (steamLocomotive2.BoilerHeatInBTUpS > bandLower && steamLocomotive2.BoilerHeatInBTUpS < bandUpper) { heatIndicator = $"{Symbols.SmallDiamond}{ColorCode[Color.White]}"; } else if (steamLocomotive2.BoilerHeatInBTUpS < bandLower) { heatIndicator = $"{Symbols.SmallArrowDown}{ColorCode[Color.Cyan]}"; } else if (steamLocomotive2.BoilerHeatInBTUpS > bandUpper) { heatIndicator = $"{Symbols.SmallArrowUp}{ColorCode[Color.Orange]}"; } else { heatIndicator = ColorCode[Color.White]; } AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Boiler pressure"), LastCol = Viewer.Catalog.GetString(valuePart), SymbolCol = heatIndicator, }); } else if (!normalTextMode && Viewer.Catalog.GetString(parts[0]).StartsWith(Viewer.Catalog.GetString("Fuel levels"))) { AddLabel(new ListLabel { FirstCol = keyPart.EndsWith("?") || keyPart.EndsWith("!") ? Viewer.Catalog.GetString(keyPart.Substring(0, keyPart.Length - 3)) : Viewer.Catalog.GetString(keyPart), LastCol = valuePart.Length > 1 ? Viewer.Catalog.GetString(valuePart.Replace(" ", string.Empty)) : "", }); } else if (keyPart.StartsWith(Viewer.Catalog.GetString("Gear"))) { string gearKey; switch (GetPressedKey(UserCommand.ControlGearDown, UserCommand.ControlGearUp)) { case UserCommand.ControlGearDown: gearKey = Symbols.ArrowDown + ColorCode[Color.Yellow]; break; case UserCommand.ControlGearUp: gearKey = Symbols.ArrowUp + ColorCode[Color.Yellow]; break; default: gearKey = ""; break; } AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString(keyPart), LastCol = valuePart != null ? Viewer.Catalog.GetString(valuePart) : "", KeyPressed = gearKey, SymbolCol = gearKey, }); } else if (parts.Contains(Viewer.Catalog.GetString("Pantographs"))) { string pantoKey; switch (GetPressedKey(UserCommand.ControlPantograph1)) { case UserCommand.ControlPantograph1: string arrow = parts[1].StartsWith(Viewer.Catalog.GetString("Up")) ? Symbols.ArrowUp : Symbols.ArrowDown; pantoKey = arrow + ColorCode[Color.Yellow]; break; default: pantoKey = ""; break; } AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString(keyPart), LastCol = valuePart != null ? Viewer.Catalog.GetString(valuePart) : "", KeyPressed = pantoKey, SymbolCol = pantoKey, }); } else if (parts.Contains(Viewer.Catalog.GetString("Engine"))) { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString(keyPart), LastCol = valuePart != null ? $"{Viewer.Catalog.GetString(valuePart)}{ColorCode[Color.White]}" : "", }); } else { AddLabel(new ListLabel { FirstCol = keyPart.EndsWith("?") || keyPart.EndsWith("!") ? Viewer.Catalog.GetString(keyPart.Substring(0, keyPart.Length - 3)) : Viewer.Catalog.GetString(keyPart), LastCol = valuePart != null ? Viewer.Catalog.GetString(valuePart) : "", }); } } } AddSeparator(); if (normalTextMode) { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("FPS"), LastCol = $"{Math.Floor(viewer.RenderProcess.FrameRate.SmoothedValue)}", }); } // Messages // Autopilot bool autopilot = locomotive.Train.TrainType == Train.TRAINTYPE.AI_PLAYERHOSTING; AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Autopilot"), LastCol = autopilot ? Viewer.Catalog.GetString("On") + ColorCode[Color.Yellow] : Viewer.Catalog.GetString("Off"), }); // Grate limit if (locomotive is MSTSSteamLocomotive steamLocomotive1) { if (steamLocomotive1.IsGrateLimit && steamLocomotive1.GrateCombustionRateLBpFt2 > steamLocomotive1.GrateLimitLBpFt2) { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Grate limit"), LastCol = Viewer.Catalog.GetString("Exceeded") + ColorCode[Color.OrangeRed], }); } else { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Grate limit") + ColorCode[Color.Black], LastCol = Viewer.Catalog.GetString("Normal") + ColorCode[Color.Black], }); } } else { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Grate limit") + ColorCode[Color.Black], LastCol = Viewer.Catalog.GetString("-") + ColorCode[Color.Black], }); } // Wheel if (train.IsWheelSlip) { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Wheel"), LastCol = Viewer.Catalog.GetString("slip") + ColorCode[Color.OrangeRed], }); } else if (train.IsWheelSlipWarninq) { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Wheel"), LastCol = Viewer.Catalog.GetString("slip warning") + ColorCode[Color.Yellow], }); } else if (train.IsBrakeSkid) { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Wheel"), LastCol = Viewer.Catalog.GetString("skid") + ColorCode[Color.OrangeRed], }); } else { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Wheel") + ColorCode[Color.Black], LastCol = Viewer.Catalog.GetString("Normal") + ColorCode[Color.Black], }); } // Doors var wagon = (MSTSWagon)locomotive; if (wagon.DoorLeftOpen || wagon.DoorRightOpen) { var status = new List <string>(); bool flipped = locomotive.GetCabFlipped(); if (wagon.DoorLeftOpen) { status.Add(Viewer.Catalog.GetString(Viewer.Catalog.GetString(flipped ? "Right" : "Left"))); } if (wagon.DoorRightOpen) { status.Add(Viewer.Catalog.GetString(Viewer.Catalog.GetString(flipped ? "Left" : "Right"))); } AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Doors open"), LastCol = string.Join(" ", status) + ColorCode[locomotive.AbsSpeedMpS > 0.1f ? Color.OrangeRed : Color.Yellow], }); } else { AddLabel(new ListLabel { FirstCol = Viewer.Catalog.GetString("Doors open") + ColorCode[Color.Black], LastCol = Viewer.Catalog.GetString("Closed") + ColorCode[Color.Black], }); } AddLabel(new ListLabel()); return(labels); }
private void UpdateData() { //Update data expandWindow = '\u23FA'; // ⏺ toggle window keyPressed = ""; ListToLabel.Clear(); UpdateDataEnded = false; // First Block // Client and server may have a time difference. keyPressed = ""; if (StandardHUD) { if (Orts.MultiPlayer.MPManager.IsClient()) { InfoToLabel(keyPressed, Viewer.Catalog.GetString("Time") + ": " + FormatStrings.FormatTime(Owner.Viewer.Simulator.ClockTime + Orts.MultiPlayer.MPManager.Instance().serverTimeDifference), "", "", false, keyPressed); } else { InfoToLabel(keyPressed, Viewer.Catalog.GetString("Time") + ": " + FormatStrings.FormatTime(Owner.Viewer.Simulator.ClockTime), "", "", false, keyPressed); } } // MultiPlayer if (Orts.MultiPlayer.MPManager.IsMultiPlayer()) { var text = Orts.MultiPlayer.MPManager.Instance().GetOnlineUsersInfo(); if (StandardHUD) { InfoToLabel("", Viewer.Catalog.GetString("Sprtr"), "", "", false, keyPressed); InfoToLabel(" ", Viewer.Catalog.GetString("MultiPlayerStatus:") + " " + (Orts.MultiPlayer.MPManager.IsServer() ? Viewer.Catalog.GetString("Dispatcher") : Orts.MultiPlayer.MPManager.Instance().AmAider ? Viewer.Catalog.GetString("Helper") : Orts.MultiPlayer.MPManager.IsClient() ? Viewer.Catalog.GetString("Client") : ""), "", "", true, keyPressed); } else { InfoToLabel(" ", Viewer.Catalog.GetString("Status:") + " " + (Orts.MultiPlayer.MPManager.IsServer() ? Viewer.Catalog.GetString("Dispatcher") : Orts.MultiPlayer.MPManager.Instance().AmAider ? Viewer.Catalog.GetString("Helper") : Orts.MultiPlayer.MPManager.IsClient() ? Viewer.Catalog.GetString("Client") : ""), "", "", true, keyPressed); } // Number of player and trains InfoToLabel("", "NwLn", "", "", false, keyPressed); foreach (var t in text.Split('\t')) { if (StandardHUD) { InfoToLabel(" ", (t), "", "", true, keyPressed); } else { InfoToLabel(" ", (t), "", "", true, keyPressed); break; } } } UpdateDataEnded = true; keyPressed = ""; InfoToLabel(keyPressed, "", "", "", true, keyPressed); }
public override void PrepareFrame(ElapsedTime elapsedTime, bool updateFull) { base.PrepareFrame(elapsedTime, updateFull); if (updateFull) { CurrentTime.Text = FormatStrings.FormatTime(Owner.Viewer.Simulator.ClockTime); Activity act = Owner.Viewer.Simulator.ActivityRun; Train playerTrain = Owner.Viewer.Simulator.PlayerLocomotive.Train; if (playerTrain.Delay.HasValue) { CurrentDelay.Text = Viewer.Catalog.GetPluralStringFmt("Current Delay: {0} minute", "Current Delay: {0} minutes", (long)playerTrain.Delay.Value.TotalMinutes); } else { CurrentDelay.Text = ""; } bool metric = Owner.Viewer.MilepostUnitsMetric; bool InfoAvail = false; ActivityTaskPassengerStopAt at = null; ActivityTaskPassengerStopAt Current = null; // timetable information if (playerTrain.CheckStations) { TTTrain playerTimetableTrain = playerTrain as TTTrain; // train name StationPlatform.Text = String.Concat(playerTimetableTrain.Name.Substring(0, Math.Min(playerTimetableTrain.Name.Length, 20))); if (playerTimetableTrain.ControlMode == Train.TRAIN_CONTROL.INACTIVE || playerTimetableTrain.MovementState == Simulation.AIs.AITrain.AI_MOVEMENT_STATE.AI_STATIC) { // no info available StationPreviousName.Text = ""; StationPreviousArriveScheduled.Text = ""; StationPreviousArriveActual.Text = ""; StationPreviousDepartScheduled.Text = ""; StationPreviousDepartActual.Text = ""; StationPreviousDistance.Text = ""; StationCurrentName.Text = ""; StationCurrentArriveScheduled.Text = ""; StationCurrentArriveActual.Text = ""; StationCurrentDepartScheduled.Text = ""; StationCurrentDistance.Text = ""; StationNextName.Text = ""; StationNextArriveScheduled.Text = ""; StationNextDepartScheduled.Text = ""; StationNextDistance.Text = ""; bool validMessage = false; if (playerTimetableTrain.NeedAttach != null && playerTimetableTrain.NeedAttach.ContainsKey(-1)) { List <int> attachTrains = playerTimetableTrain.NeedAttach[-1]; TTTrain otherTrain = playerTimetableTrain.GetOtherTTTrainByNumber(attachTrains[0]); if (otherTrain == null) { if (playerTimetableTrain.Simulator.AutoGenDictionary.ContainsKey(attachTrains[0])) { otherTrain = playerTimetableTrain.Simulator.AutoGenDictionary[attachTrains[0]] as TTTrain; } } if (otherTrain == null) { Message.Text = Viewer.Catalog.GetString("Waiting for train to attach"); Message.Color = Color.Orange; validMessage = true; } else { Message.Text = String.Concat(Viewer.Catalog.GetString("Waiting for train to attach : "), otherTrain.Name); Message.Color = Color.Orange; validMessage = true; } } if (!validMessage && playerTimetableTrain.NeedTrainTransfer.Count > 0) { foreach (TrackCircuitSection occSection in playerTimetableTrain.OccupiedTrack) { if (playerTimetableTrain.NeedTrainTransfer.ContainsKey(occSection.Index)) { Message.Text = Viewer.Catalog.GetString("Waiting for transfer"); Message.Color = Color.Orange; break; } } } if (!validMessage) { Message.Color = Color.White; if (playerTimetableTrain.ActivateTime.HasValue) { DateTime activateDT = new DateTime((long)(Math.Pow(10, 7) * playerTimetableTrain.ActivateTime.Value)); if (playerTimetableTrain.ControlMode == Train.TRAIN_CONTROL.INACTIVE) { Message.Text = Viewer.Catalog.GetString("Train inactive."); } else if (playerTimetableTrain.MovementState == Simulation.AIs.AITrain.AI_MOVEMENT_STATE.AI_STATIC) { Message.Text = Viewer.Catalog.GetString("Train static."); } else { Message.Text = Viewer.Catalog.GetString("Train not active."); } // set activation message or time if (playerTimetableTrain.TriggeredActivationRequired) { Message.Text = String.Concat(Message.Text, Viewer.Catalog.GetString(" Activated by other train.")); } else { Message.Text = String.Concat(Message.Text, Viewer.Catalog.GetString(" Activation time : "), activateDT.ToString("HH:mm:ss")); } } else { Message.Text = Viewer.Catalog.GetString("Train has terminated."); } } } else { // previous stop if (playerTimetableTrain.PreviousStop == null) { StationPreviousName.Text = ""; StationPreviousArriveScheduled.Text = ""; StationPreviousArriveActual.Text = ""; StationPreviousDepartScheduled.Text = ""; StationPreviousDepartActual.Text = ""; StationPreviousDistance.Text = ""; } else { StationPreviousName.Text = playerTimetableTrain.PreviousStop.PlatformItem.Name; StationPreviousArriveScheduled.Text = playerTimetableTrain.PreviousStop.arrivalDT.ToString("HH:mm:ss"); if (playerTimetableTrain.PreviousStop.ActualArrival >= 0) { DateTime actArrDT = new DateTime((long)(Math.Pow(10, 7) * playerTimetableTrain.PreviousStop.ActualArrival)); StationPreviousArriveActual.Text = actArrDT.ToString("HH:mm:ss"); StationPreviousArriveActual.Color = actArrDT < playerTimetableTrain.PreviousStop.arrivalDT ? Color.LightGreen : Color.LightSalmon; DateTime actDepDT = new DateTime((long)(Math.Pow(10, 7) * playerTimetableTrain.PreviousStop.ActualDepart)); StationPreviousDepartActual.Text = actDepDT.ToString("HH:mm:ss"); StationPreviousDepartActual.Color = actDepDT > playerTimetableTrain.PreviousStop.arrivalDT ? Color.LightGreen : Color.LightSalmon; } else { StationPreviousArriveActual.Text = Viewer.Catalog.GetString("(missed)"); StationPreviousArriveActual.Color = Color.LightSalmon; StationPreviousDepartActual.Text = ""; } StationPreviousDepartScheduled.Text = playerTimetableTrain.PreviousStop.departureDT.ToString("HH:mm:ss"); StationPreviousDistance.Text = ""; } if (playerTimetableTrain.StationStops == null || playerTimetableTrain.StationStops.Count == 0) { StationCurrentName.Text = ""; StationCurrentArriveScheduled.Text = ""; StationCurrentArriveActual.Text = ""; StationCurrentDepartScheduled.Text = ""; StationCurrentDistance.Text = ""; StationNextName.Text = ""; StationNextArriveScheduled.Text = ""; StationNextDepartScheduled.Text = ""; StationNextDistance.Text = ""; Message.Text = Viewer.Catalog.GetString("No more stations."); Message.Color = Color.White; } else { StationCurrentName.Text = playerTimetableTrain.StationStops[0].PlatformItem.Name; StationCurrentArriveScheduled.Text = playerTimetableTrain.StationStops[0].arrivalDT.ToString("HH:mm:ss"); if (playerTimetableTrain.StationStops[0].ActualArrival >= 0) { DateTime actArrDT = new DateTime((long)(Math.Pow(10, 7) * playerTimetableTrain.StationStops[0].ActualArrival)); StationCurrentArriveActual.Text = actArrDT.ToString("HH:mm:ss"); StationCurrentArriveActual.Color = actArrDT < playerTimetableTrain.StationStops[0].arrivalDT ? Color.LightGreen : Color.LightSalmon; } else { StationCurrentArriveActual.Text = ""; } StationCurrentDepartScheduled.Text = playerTimetableTrain.StationStops[0].departureDT.ToString("HH:mm:ss"); StationCurrentDistance.Text = FormatStrings.FormatDistanceDisplay(playerTimetableTrain.StationStops[0].DistanceToTrainM, metric); Message.Text = playerTimetableTrain.DisplayMessage; Message.Color = playerTimetableTrain.DisplayColor; if (playerTimetableTrain.StationStops.Count >= 2) { StationNextName.Text = playerTimetableTrain.StationStops[1].PlatformItem.Name; StationNextArriveScheduled.Text = playerTimetableTrain.StationStops[1].arrivalDT.ToString("HH:mm:ss"); StationNextDepartScheduled.Text = playerTimetableTrain.StationStops[1].departureDT.ToString("HH:mm:ss"); StationNextDistance.Text = ""; } else { StationNextName.Text = ""; StationNextArriveScheduled.Text = ""; StationNextDepartScheduled.Text = ""; StationNextDistance.Text = ""; } } // check transfer details bool transferValid = false; string TransferMessage = String.Empty; if (playerTimetableTrain.TransferStationDetails != null && playerTimetableTrain.TransferStationDetails.Count > 0 && playerTimetableTrain.StationStops != null && playerTimetableTrain.StationStops.Count > 0) { if (playerTimetableTrain.TransferStationDetails.ContainsKey(playerTimetableTrain.StationStops[0].PlatformReference)) { TransferInfo thisTransfer = playerTimetableTrain.TransferStationDetails[playerTimetableTrain.StationStops[0].PlatformReference]; TransferMessage = Viewer.Catalog.GetString("Transfer units at next station with train "); TransferMessage = String.Concat(TransferMessage, thisTransfer.TransferTrainName); transferValid = true; } } else if (playerTimetableTrain.TransferTrainDetails != null && playerTimetableTrain.TransferTrainDetails.Count > 0) { foreach (KeyValuePair <int, List <TransferInfo> > transferDetails in playerTimetableTrain.TransferTrainDetails) { TransferInfo thisTransfer = transferDetails.Value[0]; TransferMessage = Viewer.Catalog.GetString("Transfer units with train "); TransferMessage = String.Concat(TransferMessage, thisTransfer.TransferTrainName); transferValid = true; break; // only show first } } // general details if (playerTimetableTrain.AttachDetails != null && playerTimetableTrain.AttachDetails.Valid) { Message.Text = Viewer.Catalog.GetString("Train is to attach to : "); Message.Text = String.Concat(Message.Text, playerTimetableTrain.AttachDetails.AttachTrainName); Message.Color = Color.Orange; } else if (playerTimetableTrain.AttachDetails != null) { Message.Text = Viewer.Catalog.GetString("Train is to attach to : "); Message.Text = String.Concat(Message.Text, playerTimetableTrain.AttachDetails.AttachTrainName); Message.Text = String.Concat(Message.Text, Viewer.Catalog.GetString(" ; other train not yet ready")); Message.Color = Color.Orange; } else if (playerTimetableTrain.PickUpStaticOnForms) { Message.Text = Viewer.Catalog.GetString("Train is to pickup train at end of path"); Message.Color = Color.Orange; } else if (playerTimetableTrain.NeedPickUp) { Message.Text = Viewer.Catalog.GetString("Pick up train ahead"); Message.Color = Color.Orange; } else if (transferValid) { Message.Text = String.Copy(TransferMessage); Message.Color = Color.Orange; } else if (playerTimetableTrain.NeedTransfer) { Message.Text = Viewer.Catalog.GetString("Transfer units with train ahead"); Message.Color = Color.Orange; } } } // activity mode - switched train else if (!Owner.Viewer.Simulator.TimetableMode && playerTrain != Owner.Viewer.Simulator.OriginalPlayerTrain) { // train name StationPlatform.Text = String.Concat(playerTrain.Name.Substring(0, Math.Min(playerTrain.Name.Length, 20))); if (playerTrain.ControlMode == Train.TRAIN_CONTROL.INACTIVE) { // no info available StationPreviousName.Text = ""; StationPreviousArriveScheduled.Text = ""; StationPreviousArriveActual.Text = ""; StationPreviousDepartScheduled.Text = ""; StationPreviousDepartActual.Text = ""; StationPreviousDistance.Text = ""; StationCurrentName.Text = ""; StationCurrentArriveScheduled.Text = ""; StationCurrentArriveActual.Text = ""; StationCurrentDepartScheduled.Text = ""; StationCurrentDistance.Text = ""; StationNextName.Text = ""; StationNextArriveScheduled.Text = ""; StationNextDepartScheduled.Text = ""; StationNextDistance.Text = ""; Message.Text = Viewer.Catalog.GetString("Train not active."); Message.Color = Color.White; if (playerTrain.GetType() == typeof(TTTrain)) { TTTrain playerTimetableTrain = playerTrain as TTTrain; if (playerTimetableTrain.ActivateTime.HasValue) { DateTime activateDT = new DateTime((long)(Math.Pow(10, 7) * playerTimetableTrain.ActivateTime.Value)); Message.Text = String.Concat(Message.Text, Viewer.Catalog.GetString(" Activation time : "), activateDT.ToString("HH:mm:ss")); } } } else { // previous stop if (playerTrain.PreviousStop == null) { StationPreviousName.Text = ""; StationPreviousArriveScheduled.Text = ""; StationPreviousArriveActual.Text = ""; StationPreviousDepartScheduled.Text = ""; StationPreviousDepartActual.Text = ""; StationPreviousDistance.Text = ""; } else { StationPreviousName.Text = playerTrain.PreviousStop.PlatformItem.Name; StationPreviousArriveScheduled.Text = playerTrain.PreviousStop.arrivalDT.ToString("HH:mm:ss"); if (playerTrain.PreviousStop.ActualArrival >= 0) { DateTime actArrDT = new DateTime((long)(Math.Pow(10, 7) * playerTrain.PreviousStop.ActualArrival)); StationPreviousArriveActual.Text = actArrDT.ToString("HH:mm:ss"); StationPreviousArriveActual.Color = actArrDT < playerTrain.PreviousStop.arrivalDT ? Color.LightGreen : Color.LightSalmon; DateTime actDepDT = new DateTime((long)(Math.Pow(10, 7) * playerTrain.PreviousStop.ActualDepart)); StationPreviousDepartActual.Text = actDepDT.ToString("HH:mm:ss"); StationPreviousDepartActual.Color = actDepDT > playerTrain.PreviousStop.arrivalDT ? Color.LightGreen : Color.LightSalmon; } else { StationPreviousArriveActual.Text = Viewer.Catalog.GetString("(missed)"); StationPreviousArriveActual.Color = Color.LightSalmon; StationPreviousDepartActual.Text = ""; } StationPreviousDepartScheduled.Text = playerTrain.PreviousStop.departureDT.ToString("HH:mm:ss"); StationPreviousDistance.Text = ""; } if (playerTrain.StationStops == null || playerTrain.StationStops.Count == 0) { StationCurrentName.Text = ""; StationCurrentArriveScheduled.Text = ""; StationCurrentArriveActual.Text = ""; StationCurrentDepartScheduled.Text = ""; StationCurrentDistance.Text = ""; StationNextName.Text = ""; StationNextArriveScheduled.Text = ""; StationNextDepartScheduled.Text = ""; StationNextDistance.Text = ""; Message.Text = Viewer.Catalog.GetString("No more stations."); } else { StationCurrentName.Text = playerTrain.StationStops[0].PlatformItem.Name; StationCurrentArriveScheduled.Text = playerTrain.StationStops[0].arrivalDT.ToString("HH:mm:ss"); if (playerTrain.StationStops[0].ActualArrival >= 0) { DateTime actArrDT = new DateTime((long)(Math.Pow(10, 7) * playerTrain.StationStops[0].ActualArrival)); StationCurrentArriveActual.Text = actArrDT.ToString("HH:mm:ss"); StationCurrentArriveActual.Color = actArrDT < playerTrain.StationStops[0].arrivalDT ? Color.LightGreen : Color.LightSalmon; } else { StationCurrentArriveActual.Text = ""; } StationCurrentDepartScheduled.Text = playerTrain.StationStops[0].departureDT.ToString("HH:mm:ss"); StationCurrentDistance.Text = FormatStrings.FormatDistanceDisplay(playerTrain.StationStops[0].DistanceToTrainM, metric); Message.Text = playerTrain.DisplayMessage; Message.Color = playerTrain.DisplayColor; if (playerTrain.StationStops.Count >= 2) { StationNextName.Text = playerTrain.StationStops[1].PlatformItem.Name; StationNextArriveScheduled.Text = playerTrain.StationStops[1].arrivalDT.ToString("HH:mm:ss"); StationNextDepartScheduled.Text = playerTrain.StationStops[1].departureDT.ToString("HH:mm:ss"); StationNextDistance.Text = ""; } else { StationNextName.Text = ""; StationNextArriveScheduled.Text = ""; StationNextDepartScheduled.Text = ""; StationNextDistance.Text = ""; } } } } // activity information if (act != null && playerTrain == Owner.Viewer.Simulator.OriginalPlayerTrain) { Current = act.Current == null ? act.Last as ActivityTaskPassengerStopAt : act.Current as ActivityTaskPassengerStopAt; at = Current != null ? Current.PrevTask as ActivityTaskPassengerStopAt : null; InfoAvail = true; } if (InfoAvail) { if (at != null) { StationPreviousName.Text = at.PlatformEnd1.Station; StationPreviousArriveScheduled.Text = at.SchArrive.ToString("HH:mm:ss"); StationPreviousArriveActual.Text = at.ActArrive.HasValue ? at.ActArrive.Value.ToString("HH:mm:ss") : Viewer.Catalog.GetString("(missed)"); StationPreviousArriveActual.Color = GetArrivalColor(at.SchArrive, at.ActArrive); StationPreviousDepartScheduled.Text = at.SchDepart.ToString("HH:mm:ss"); StationPreviousDepartActual.Text = at.ActDepart.HasValue ? at.ActDepart.Value.ToString("HH:mm:ss") : Viewer.Catalog.GetString("(missed)"); StationPreviousDepartActual.Color = GetDepartColor(at.SchDepart, at.ActDepart); StationPreviousDistance.Text = ""; if (playerTrain.StationStops.Count > 0 && playerTrain.StationStops[0].PlatformItem != null && String.Compare(playerTrain.StationStops[0].PlatformItem.Name, StationPreviousName.Text) == 0 && playerTrain.StationStops[0].DistanceToTrainM > 0) { StationPreviousDistance.Text = FormatStrings.FormatDistanceDisplay(playerTrain.StationStops[0].DistanceToTrainM, metric); } } else { StationPreviousName.Text = ""; StationPreviousArriveScheduled.Text = ""; StationPreviousArriveActual.Text = ""; StationPreviousDepartScheduled.Text = ""; StationPreviousDepartActual.Text = ""; StationPreviousDistance.Text = ""; } at = Current; if (at != null) { StationPlatform.Text = at.PlatformEnd1.ItemName; StationCurrentName.Text = at.PlatformEnd1.Station; StationCurrentArriveScheduled.Text = at.SchArrive.ToString("HH:mm:ss"); StationCurrentArriveActual.Text = at.ActArrive.HasValue ? at.ActArrive.Value.ToString("HH:mm:ss") : ""; StationCurrentArriveActual.Color = GetArrivalColor(at.SchArrive, at.ActArrive); StationCurrentDepartScheduled.Text = at.SchDepart.ToString("HH:mm:ss"); Message.Color = at.DisplayColor; Message.Text = at.DisplayMessage; StationCurrentDistance.Text = ""; if (playerTrain.StationStops.Count > 0 && playerTrain.StationStops[0].PlatformItem != null && String.Compare(playerTrain.StationStops[0].PlatformItem.Name, StationCurrentName.Text) == 0 && playerTrain.StationStops[0].DistanceToTrainM > 0) { StationCurrentDistance.Text = FormatStrings.FormatDistanceDisplay(playerTrain.StationStops[0].DistanceToTrainM, metric); } } else { StationPlatform.Text = ""; StationCurrentName.Text = ""; StationCurrentArriveScheduled.Text = ""; StationCurrentArriveActual.Text = ""; StationCurrentDepartScheduled.Text = ""; StationCurrentDistance.Text = ""; Message.Text = ""; } at = Current != null ? Current.NextTask as ActivityTaskPassengerStopAt : null; if (at != null) { StationNextName.Text = at.PlatformEnd1.Station; StationNextArriveScheduled.Text = at.SchArrive.ToString("HH:mm:ss"); StationNextDepartScheduled.Text = at.SchDepart.ToString("HH:mm:ss"); StationNextDistance.Text = ""; if (playerTrain.StationStops.Count > 0 && playerTrain.StationStops[0].PlatformItem != null && String.Compare(playerTrain.StationStops[0].PlatformItem.Name, StationNextName.Text) == 0 && playerTrain.StationStops[0].DistanceToTrainM > 0) { StationNextDistance.Text = FormatStrings.FormatDistanceDisplay(playerTrain.StationStops[0].DistanceToTrainM, metric); } } else { StationNextName.Text = ""; StationNextArriveScheduled.Text = ""; StationNextDepartScheduled.Text = ""; StationNextDistance.Text = ""; } if (act != null && act.IsComplete) { Message.Text = Viewer.Catalog.GetString("Activity completed."); } } } }
/// <summary> /// Retrieve a formatted list <see cref="ListLabel"/>s to be displayed as an in-browser Track Monitor. /// </summary> /// <param name="viewer">The Viewer to read train data from.</param> /// <returns>A list of <see cref="ListLabel"/>s, one per row of the popup.</returns> public IEnumerable <ListLabel> MultiPlayerWindowList(Viewer viewer) { //Update data keyPressed = ""; labels = new List <ListLabel>(); void AddLabel(ListLabel label) { CheckLabel(ref label); } void AddSeparator() => AddLabel(new ListLabel { FirstCol = "Sprtr", }); labels.Clear(); UpdateDataEnded = false; // First Block // Client and server may have a time difference. var time = FormatStrings.FormatTime(viewer.Simulator.ClockTime + (MultiPlayerManager.IsClient() ? MultiPlayerManager.Instance().serverTimeDifference : 0)); AddLabel(new ListLabel { FirstCol = $"{CatalogManager.Catalog.GetString("Time")}: {time}", LastCol = "" }); // Separator AddSeparator(); // MultiPlayer if (MultiPlayerManager.IsMultiPlayer()) { string text = MultiPlayerManager.Instance().GetOnlineUsersInfo(); string multiPlayerStatus = MultiPlayerManager.IsServer() ? $"{CatalogManager.Catalog.GetString("Dispatcher")} ({MultiPlayerManager.Client.UserName})" : MultiPlayerManager.Instance().AmAider ? CatalogManager.Catalog.GetString("Helper") : MultiPlayerManager.IsClient() ? $"{CatalogManager.Catalog.GetString("Client")} ({MultiPlayerManager.Client.UserName})" : ""; var status = $"{CatalogManager.Catalog.GetString("Status")}: {multiPlayerStatus}"; AddLabel(new ListLabel { FirstCol = status, LastCol = "" }); AddLabel(new ListLabel()); // Number of player and trains foreach (var t in text.Split('\t')) { AddLabel(new ListLabel { FirstCol = $"{t}", LastCol = "" }); } AddLabel(new ListLabel()); } else if (Simulator.Instance.Confirmer != null) { var status = $"{CatalogManager.Catalog.GetString("Status")}: {CatalogManager.Catalog.GetString("Connection to the server is lost, will play as single mode")}"; AddLabel(new ListLabel { FirstCol = status, LastCol = "" }); AddLabel(new ListLabel()); } AddLabel(new ListLabel()); UpdateDataEnded = true; return(labels); }
public override void PrepareFrame(ElapsedTime elapsedTime, bool updateFull) { base.PrepareFrame(elapsedTime, updateFull); if (updateFull) { CurrentTime.Text = FormatStrings.FormatTime(Owner.Viewer.Simulator.ClockTime); Activity act = Owner.Viewer.Simulator.ActivityRun; Train playerTrain = Owner.Viewer.Simulator.PlayerLocomotive.Train; if (playerTrain.Delay.HasValue) { CurrentDelay.Text = Viewer.Catalog.GetPluralStringFmt("Current Delay: {0} minute", "Current Delay: {0} minutes", (long)playerTrain.Delay.Value.TotalMinutes); } else { CurrentDelay.Text = ""; } bool metric = Owner.Viewer.MilepostUnitsMetric; bool InfoAvail = false; ActivityTaskPassengerStopAt at = null; ActivityTaskPassengerStopAt Current = null; // timetable information if (playerTrain.CheckStations || (!Owner.Viewer.Simulator.TimetableMode && playerTrain != Owner.Viewer.Simulator.OriginalPlayerTrain)) { // train name StationPlatform.Text = String.Concat(playerTrain.Name.Substring(0, Math.Min(playerTrain.Name.Length, 20))); if (playerTrain.ControlMode == Train.TRAIN_CONTROL.INACTIVE) { // no info available StationPreviousName.Text = ""; StationPreviousArriveScheduled.Text = ""; StationPreviousArriveActual.Text = ""; StationPreviousDepartScheduled.Text = ""; StationPreviousDepartActual.Text = ""; StationPreviousDistance.Text = ""; StationCurrentName.Text = ""; StationCurrentArriveScheduled.Text = ""; StationCurrentArriveActual.Text = ""; StationCurrentDepartScheduled.Text = ""; StationCurrentDistance.Text = ""; StationNextName.Text = ""; StationNextArriveScheduled.Text = ""; StationNextDepartScheduled.Text = ""; StationNextDistance.Text = ""; Message.Text = "Train not active."; Message.Color = Color.White; if (playerTrain.GetType() == typeof(TTTrain)) { TTTrain playerTimetableTrain = playerTrain as TTTrain; if (playerTimetableTrain.ActivateTime.HasValue) { DateTime activateDT = new DateTime((long)(Math.Pow(10, 7) * playerTimetableTrain.ActivateTime.Value)); Message.Text = String.Concat(Message.Text, " Activation time : ", activateDT.ToString("HH:mm:ss")); } } } else { // previous stop if (playerTrain.PreviousStop == null) { StationPreviousName.Text = ""; StationPreviousArriveScheduled.Text = ""; StationPreviousArriveActual.Text = ""; StationPreviousDepartScheduled.Text = ""; StationPreviousDepartActual.Text = ""; StationPreviousDistance.Text = ""; } else { StationPreviousName.Text = playerTrain.PreviousStop.PlatformItem.Name; StationPreviousArriveScheduled.Text = playerTrain.PreviousStop.arrivalDT.ToString("HH:mm:ss"); if (playerTrain.PreviousStop.ActualArrival >= 0) { DateTime actArrDT = new DateTime((long)(Math.Pow(10, 7) * playerTrain.PreviousStop.ActualArrival)); StationPreviousArriveActual.Text = actArrDT.ToString("HH:mm:ss"); StationPreviousArriveActual.Color = actArrDT < playerTrain.PreviousStop.arrivalDT ? Color.LightGreen : Color.LightSalmon; DateTime actDepDT = new DateTime((long)(Math.Pow(10, 7) * playerTrain.PreviousStop.ActualDepart)); StationPreviousDepartActual.Text = actDepDT.ToString("HH:mm:ss"); StationPreviousDepartActual.Color = actDepDT > playerTrain.PreviousStop.arrivalDT ? Color.LightGreen : Color.LightSalmon; } else { StationPreviousArriveActual.Text = Viewer.Catalog.GetString("(missed)"); StationPreviousArriveActual.Color = Color.LightSalmon; StationPreviousDepartActual.Text = ""; } StationPreviousDepartScheduled.Text = playerTrain.PreviousStop.departureDT.ToString("HH:mm:ss"); StationPreviousDistance.Text = ""; } if (playerTrain.StationStops == null || playerTrain.StationStops.Count == 0) { StationCurrentName.Text = ""; StationCurrentArriveScheduled.Text = ""; StationCurrentArriveActual.Text = ""; StationCurrentDepartScheduled.Text = ""; StationCurrentDistance.Text = ""; StationNextName.Text = ""; StationNextArriveScheduled.Text = ""; StationNextDepartScheduled.Text = ""; StationNextDistance.Text = ""; Message.Text = Viewer.Catalog.GetString("No more stations."); } else { StationCurrentName.Text = playerTrain.StationStops[0].PlatformItem.Name; StationCurrentArriveScheduled.Text = playerTrain.StationStops[0].arrivalDT.ToString("HH:mm:ss"); if (playerTrain.StationStops[0].ActualArrival >= 0) { DateTime actArrDT = new DateTime((long)(Math.Pow(10, 7) * playerTrain.StationStops[0].ActualArrival)); StationCurrentArriveActual.Text = actArrDT.ToString("HH:mm:ss"); StationCurrentArriveActual.Color = actArrDT < playerTrain.StationStops[0].arrivalDT ? Color.LightGreen : Color.LightSalmon; } else { StationCurrentArriveActual.Text = ""; } StationCurrentDepartScheduled.Text = playerTrain.StationStops[0].departureDT.ToString("HH:mm:ss"); StationCurrentDistance.Text = FormatStrings.FormatDistanceDisplay(playerTrain.StationStops[0].DistanceToTrainM, metric); Message.Text = playerTrain.DisplayMessage; Message.Color = playerTrain.DisplayColor; if (playerTrain.StationStops.Count >= 2) { StationNextName.Text = playerTrain.StationStops[1].PlatformItem.Name; StationNextArriveScheduled.Text = playerTrain.StationStops[1].arrivalDT.ToString("HH:mm:ss"); StationNextDepartScheduled.Text = playerTrain.StationStops[1].departureDT.ToString("HH:mm:ss"); StationNextDistance.Text = ""; } else { StationNextName.Text = ""; StationNextArriveScheduled.Text = ""; StationNextDepartScheduled.Text = ""; StationNextDistance.Text = ""; } } } } // activity information if (act != null && playerTrain == Owner.Viewer.Simulator.OriginalPlayerTrain) { Current = act.Current == null ? act.Last as ActivityTaskPassengerStopAt : act.Current as ActivityTaskPassengerStopAt; at = Current != null ? Current.PrevTask as ActivityTaskPassengerStopAt : null; InfoAvail = true; } if (InfoAvail) { if (at != null) { StationPreviousName.Text = at.PlatformEnd1.Station; StationPreviousArriveScheduled.Text = at.SchArrive.ToString("HH:mm:ss"); StationPreviousArriveActual.Text = at.ActArrive.HasValue ? at.ActArrive.Value.ToString("HH:mm:ss") : Viewer.Catalog.GetString("(missed)"); StationPreviousArriveActual.Color = GetArrivalColor(at.SchArrive, at.ActArrive); StationPreviousDepartScheduled.Text = at.SchDepart.ToString("HH:mm:ss"); StationPreviousDepartActual.Text = at.ActDepart.HasValue ? at.ActDepart.Value.ToString("HH:mm:ss") : Viewer.Catalog.GetString("(missed)"); StationPreviousDepartActual.Color = GetDepartColor(at.SchDepart, at.ActDepart); StationPreviousDistance.Text = ""; if (playerTrain.StationStops.Count > 0 && playerTrain.StationStops[0].PlatformItem != null && String.Compare(playerTrain.StationStops[0].PlatformItem.Name, StationPreviousName.Text) == 0 && playerTrain.StationStops[0].DistanceToTrainM > 0) { StationPreviousDistance.Text = FormatStrings.FormatDistanceDisplay(playerTrain.StationStops[0].DistanceToTrainM, metric); } } else { StationPreviousName.Text = ""; StationPreviousArriveScheduled.Text = ""; StationPreviousArriveActual.Text = ""; StationPreviousDepartScheduled.Text = ""; StationPreviousDepartActual.Text = ""; StationPreviousDistance.Text = ""; } at = Current; if (at != null) { StationPlatform.Text = at.PlatformEnd1.ItemName; StationCurrentName.Text = at.PlatformEnd1.Station; StationCurrentArriveScheduled.Text = at.SchArrive.ToString("HH:mm:ss"); StationCurrentArriveActual.Text = at.ActArrive.HasValue ? at.ActArrive.Value.ToString("HH:mm:ss") : ""; StationCurrentArriveActual.Color = GetArrivalColor(at.SchArrive, at.ActArrive); StationCurrentDepartScheduled.Text = at.SchDepart.ToString("HH:mm:ss"); Message.Color = at.DisplayColor; Message.Text = at.DisplayMessage; StationCurrentDistance.Text = ""; if (playerTrain.StationStops.Count > 0 && playerTrain.StationStops[0].PlatformItem != null && String.Compare(playerTrain.StationStops[0].PlatformItem.Name, StationCurrentName.Text) == 0 && playerTrain.StationStops[0].DistanceToTrainM > 0) { StationCurrentDistance.Text = FormatStrings.FormatDistanceDisplay(playerTrain.StationStops[0].DistanceToTrainM, metric); } } else { StationPlatform.Text = ""; StationCurrentName.Text = ""; StationCurrentArriveScheduled.Text = ""; StationCurrentArriveActual.Text = ""; StationCurrentDepartScheduled.Text = ""; StationCurrentDistance.Text = ""; Message.Text = ""; } at = Current != null ? Current.NextTask as ActivityTaskPassengerStopAt : null; if (at != null) { StationNextName.Text = at.PlatformEnd1.Station; StationNextArriveScheduled.Text = at.SchArrive.ToString("HH:mm:ss"); StationNextDepartScheduled.Text = at.SchDepart.ToString("HH:mm:ss"); StationNextDistance.Text = ""; if (playerTrain.StationStops.Count > 0 && playerTrain.StationStops[0].PlatformItem != null && String.Compare(playerTrain.StationStops[0].PlatformItem.Name, StationNextName.Text) == 0 && playerTrain.StationStops[0].DistanceToTrainM > 0) { StationNextDistance.Text = FormatStrings.FormatDistanceDisplay(playerTrain.StationStops[0].DistanceToTrainM, metric); } } else { StationNextName.Text = ""; StationNextArriveScheduled.Text = ""; StationNextDepartScheduled.Text = ""; StationNextDistance.Text = ""; } if (act != null && act.IsComplete) { Message.Text = Viewer.Catalog.GetString("Activity completed."); } } } }