Ejemplo n.º 1
0
        public MSTSSteamLocomotiveViewer(Viewer viewer, MSTSSteamLocomotive car)
            : base(viewer, car)
        {
            // Now all the particle drawers have been setup, assign them textures based
            // on what emitters we know about.
            string steamTexture = viewer.Simulator.BasePath + @"\GLOBAL\TEXTURES\smokemain.ace";

            foreach (var emitter in ParticleDrawers)
            {
                if (emitter.Key.ToLowerInvariant() == "cylindersfx")
                {
                    Cylinders.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "cylinders2fx")
                {
                    Cylinders2.AddRange(emitter.Value);
                    car.Cylinder2SteamEffects = true;
                }
//          Not used in either MSTS or OR
                else if (emitter.Key.ToLowerInvariant() == "drainpipefx")        // Drainpipe was not used in MSTS, and has no control
                {
                    Drainpipe.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "injectors1fx")
                {
                    Injectors1.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "injectors2fx")
                {
                    Injectors2.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "compressorfx")
                {
                    Compressor.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "generatorfx")
                {
                    Generator.AddRange(emitter.Value);
                    car.GeneratorSteamEffects = true;
                }
                else if (emitter.Key.ToLowerInvariant() == "safetyvalvesfx")
                {
                    SafetyValves.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "stackfx")
                {
                    Stack.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "whistlefx")
                {
                    Whistle.AddRange(emitter.Value);
                }
                foreach (var drawer in emitter.Value)
                {
                    drawer.Initialize(steamTexture);
                }
            }
        }
Ejemplo n.º 2
0
        void RecordSteamPerformance()
        {
            MSTSSteamLocomotive steamloco = (MSTSSteamLocomotive)Viewer.PlayerLocomotive;
            float SteamspeedMpH           = MpS.ToMpH(steamloco.SpeedMpS);

            if (SteamspeedMpH >= previousLoggedSteamSpeedMpH + 5)             // Add a new record every time speed increases by 5 mph
            {
                previousLoggedSteamSpeedMpH = (float)(int)SteamspeedMpH;      // Keep speed records close to whole numbers

                Logger.Data(MpS.FromMpS(Viewer.PlayerLocomotive.SpeedMpS, false).ToString("F0"));
                Logger.Data(S.ToM(steamloco.SteamPerformanceTimeS).ToString("F1"));
                Logger.Data(Viewer.PlayerLocomotive.ThrottlePercent.ToString("F0"));
                Logger.Data(Viewer.PlayerTrain.MUReverserPercent.ToString("F0"));
                Logger.Data(N.ToLbf(Viewer.PlayerLocomotive.MotiveForceN).ToString("F0"));
                Logger.Data(steamloco.IndicatedHorsePowerHP.ToString("F0"));
                Logger.Data(steamloco.DrawBarPullLbsF.ToString("F0"));
                Logger.Data(steamloco.DrawbarHorsePowerHP.ToString("F0"));
                Logger.Data(N.ToLbf(steamloco.LocomotiveCouplerForceN).ToString("F0"));
                Logger.Data(N.ToLbf(steamloco.LocoTenderFrictionForceN).ToString("F0"));
                Logger.Data(N.ToLbf(steamloco.TotalFrictionForceN).ToString("F0"));
                Logger.Data(Kg.ToTUK(steamloco.TrainLoadKg).ToString("F0"));
                Logger.Data(steamloco.BoilerPressurePSI.ToString("F0"));
                Logger.Data(steamloco.LogSteamChestPressurePSI.ToString("F0"));
                Logger.Data(steamloco.LogInitialPressurePSI.ToString("F0"));
                Logger.Data(steamloco.LogCutoffPressurePSI.ToString("F0"));
                Logger.Data(steamloco.LogReleasePressurePSI.ToString("F0"));
                Logger.Data(steamloco.LogBackPressurePSI.ToString("F0"));

                Logger.Data(steamloco.MeanEffectivePressurePSI.ToString("F0"));


                Logger.Data(steamloco.CurrentSuperheatTempF.ToString("F0"));

                Logger.Data(pS.TopH(steamloco.CylinderSteamUsageLBpS).ToString("F0"));
                Logger.Data(pS.TopH(steamloco.WaterConsumptionLbpS).ToString("F0"));
                Logger.Data(Kg.ToLb(pS.TopH(steamloco.FuelBurnRateSmoothedKGpS)).ToString("F0"));


                Logger.Data(steamloco.SuperheaterSteamUsageFactor.ToString("F2"));
                Logger.Data(steamloco.CumulativeCylinderSteamConsumptionLbs.ToString("F0"));
                Logger.Data(steamloco.CumulativeWaterConsumptionLbs.ToString("F0"));

                Logger.Data(steamloco.CutoffPressureDropRatio.ToString("F2"));

                Logger.Data(steamloco.HPCylinderMEPPSI.ToString("F0"));
                Logger.Data(steamloco.LogLPInitialPressurePSI.ToString("F0"));
                Logger.Data(steamloco.LogLPCutoffPressurePSI.ToString("F0"));
                Logger.Data(steamloco.LogLPReleasePressurePSI.ToString("F0"));
                Logger.Data(steamloco.LogLPBackPressurePSI.ToString("F0"));
                Logger.Data(steamloco.CutoffPressureDropRatio.ToString("F2"));
                Logger.Data(steamloco.LPCylinderMEPPSI.ToString("F0"));

                Logger.End();
            }
        }
Ejemplo n.º 3
0
        private void RecordSteamPerformance()
        {
            MSTSSteamLocomotive steamloco = viewer.PlayerLocomotive as MSTSSteamLocomotive;

            double steamspeedMpH = Speed.MeterPerSecond.ToMpH(steamloco.SpeedMpS);

            if (steamspeedMpH >= previousLoggedSteamSpeedMpH + 5) // Add a new record every time speed increases by 5 mph
            {
                previousLoggedSteamSpeedMpH = (int)steamspeedMpH; // Keep speed records close to whole numbers

                dataLog.Data($"{Speed.MeterPerSecond.FromMpS(steamloco.SpeedMpS, false):F0}");
                dataLog.Data($"{Time.Second.ToM(steamloco.SteamPerformanceTimeS):F1}");
                dataLog.Data($"{steamloco.ThrottlePercent:F0}");
                dataLog.Data($"{steamloco.Train.MUReverserPercent:F0}");
                dataLog.Data($"{Dynamics.Force.ToLbf(steamloco.MotiveForceN):F0}");
                dataLog.Data($"{steamloco.IndicatedHorsePowerHP:F0}");
                dataLog.Data($"{steamloco.DrawBarPullLbsF:F0}");
                dataLog.Data($"{steamloco.DrawbarHorsePowerHP:F0}");
                dataLog.Data($"{Dynamics.Force.ToLbf(steamloco.LocomotiveCouplerForceN):F0}");
                dataLog.Data($"{Dynamics.Force.ToLbf(steamloco.LocoTenderFrictionForceN):F0}");
                dataLog.Data($"{Dynamics.Force.ToLbf(steamloco.TotalFrictionForceN):F0}");
                dataLog.Data($"{Mass.Kilogram.ToTonsUK(steamloco.TrainLoadKg):F0}");
                dataLog.Data($"{steamloco.BoilerPressurePSI:F0}");
                dataLog.Data($"{steamloco.LogSteamChestPressurePSI:F0}");
                dataLog.Data($"{steamloco.LogInitialPressurePSI:F0}");
                dataLog.Data($"{steamloco.LogCutoffPressurePSI:F0}");
                dataLog.Data($"{steamloco.LogReleasePressurePSI:F0}");
                dataLog.Data($"{steamloco.LogBackPressurePSI:F0}");

                dataLog.Data($"{steamloco.MeanEffectivePressurePSI:F0}");

                dataLog.Data($"{steamloco.CurrentSuperheatTempF:F0}");

                dataLog.Data($"{Frequency.Periodic.ToHours(steamloco.CylinderSteamUsageLBpS):F0}");
                dataLog.Data($"{Frequency.Periodic.ToHours(steamloco.WaterConsumptionLbpS):F0}");
                dataLog.Data($"{Mass.Kilogram.ToLb(Frequency.Periodic.ToHours(steamloco.FuelBurnRateSmoothedKGpS)):F0}");

                dataLog.Data($"{steamloco.SuperheaterSteamUsageFactor:F2}");
                dataLog.Data($"{steamloco.CumulativeCylinderSteamConsumptionLbs:F0}");
                dataLog.Data($"{steamloco.CumulativeWaterConsumptionLbs:F0}");

                dataLog.Data($"{steamloco.CutoffPressureDropRatio:F0}");

                dataLog.Data($"{steamloco.HPCylinderMEPPSI:F0}");
                dataLog.Data($"{steamloco.LogLPInitialPressurePSI:F0}");
                dataLog.Data($"{steamloco.LogLPCutoffPressurePSI:F0}");
                dataLog.Data($"{steamloco.LogLPReleasePressurePSI:F0}");
                dataLog.Data($"{steamloco.LogLPBackPressurePSI:F0}");
                dataLog.Data($"{steamloco.CutoffPressureDropRatio:F0}");
                dataLog.Data($"{steamloco.LPCylinderMEPPSI:F0}");

                dataLog.EndLine();
            }
        }
Ejemplo n.º 4
0
        void RecordSteamPowerCurve()
        {
            MSTSSteamLocomotive loco = (MSTSSteamLocomotive)Viewer.PlayerLocomotive;
            float speedMpH           = MpS.ToMpH(loco.SpeedMpS);

            if (speedMpH >= previousLoggedSpeedMpH + 1)        // Add a new record every time speed increases by 1 mph
            {
                previousLoggedSpeedMpH = (float)(int)speedMpH; // Keep speed records close to whole numbers
                Logger.Data(speedMpH.ToString("F1"));
                float power = W.ToHp(loco.MotiveForceN * loco.SpeedMpS);
                Logger.Data(power.ToString("F1"));
                Logger.Data((Viewer.PlayerLocomotive as MSTSSteamLocomotive).ThrottlePercent.ToString("F0"));
                Logger.Data((Viewer.PlayerLocomotive as MSTSSteamLocomotive).Train.MUReverserPercent.ToString("F0"));
                Logger.End();
            }
        }
Ejemplo n.º 5
0
        private void RecordSteamPowerCurve()
        {
            MSTSSteamLocomotive steamloco = viewer.PlayerLocomotive as MSTSSteamLocomotive;
            double speedMpH = Speed.MeterPerSecond.ToMpH(steamloco.SpeedMpS);

            if (speedMpH >= previousLoggedSpeedMpH + 1) // Add a new record every time speed increases by 1 mph
            {
                previousLoggedSpeedMpH = (int)speedMpH; // Keep speed records close to whole numbers
                dataLog.Data($"{speedMpH:F1}");
                double power = Dynamics.Power.ToHp(steamloco.MotiveForceN * steamloco.SpeedMpS);
                dataLog.Data($"{power:F1}");
                dataLog.Data($"{steamloco.ThrottlePercent:F0}");
                dataLog.Data($"{steamloco.Train.MUReverserPercent:F0}");
                dataLog.EndLine();
            }
        }
Ejemplo n.º 6
0
        /// <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);
        }
Ejemplo n.º 7
0
        public static TrainCar Load(Simulator simulator, string wagFilePath, bool initialize = true)
        {
            GenericWAGFile wagFile = SharedGenericWAGFileManager.Get(wagFilePath);
            TrainCar       car;

            if (wagFile.OpenRails != null &&
                wagFile.OpenRails.DLL != null)
            {  // wag file specifies an external DLL
                try
                {
                    // TODO search the path list
                    string   wagFolder = Path.GetDirectoryName(wagFilePath);
                    string   dllPath   = FindTrainCarPlugin(wagFolder, wagFile.OpenRails.DLL);
                    Assembly customDLL = Assembly.LoadFrom(dllPath);
                    object[] args      = new object[] { wagFilePath };
                    car = (TrainCar)customDLL.CreateInstance("ORTS.CustomCar", true, BindingFlags.CreateInstance, null, args, null, null);
                    return(car);
                }
                catch (Exception error)
                {
                    Trace.WriteLine(new FileLoadException(wagFile.OpenRails.DLL, error));
                    // on error, fall through and try loading without the custom dll
                }
            }
            if (!wagFile.IsEngine)
            {
                // its an ordinary MSTS wagon
                car = new MSTSWagon(simulator, wagFilePath);
            }
            else
            {
                // its an ordinary MSTS engine of some type.
                if (wagFile.Engine.Type == null)
                {
                    throw new InvalidDataException(wagFilePath + "\r\n\r\nEngine type missing");
                }

                switch (wagFile.Engine.Type.ToLower())
                {
                // TODO complete parsing of proper car types
                case "electric": car = new MSTSElectricLocomotive(simulator, wagFilePath); break;

                case "steam": car = new MSTSSteamLocomotive(simulator, wagFilePath); break;

                case "diesel": car = new MSTSDieselLocomotive(simulator, wagFilePath); break;

                case "control": car = new MSTSControlTrailerCar(simulator, wagFilePath); break;

                default: throw new InvalidDataException(wagFilePath + "\r\n\r\nUnknown engine type: " + wagFile.Engine.Type);
                }
            }

            MSTSWagon wagon = car as MSTSWagon;

            if (car != null)
            {
                wagon.Load();

                if (initialize)
                {
                    wagon.Initialize();
                }
            }

            return(car);
        }
        public MSTSSteamLocomotiveViewer(Viewer viewer, MSTSSteamLocomotive car)
            : base(viewer, car)
        {
            // Now all the particle drawers have been setup, assign them textures based
            // on what emitters we know about.
            string steamTexture = viewer.Simulator.RouteFolder.ContentFolder.TextureFile("smokemain.ace");

            foreach (var emitter in ParticleDrawers)
            {
                if (emitter.Key.ToLowerInvariant() == "cylindersfx")
                {
                    Cylinders.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "cylinders2fx")
                {
                    Cylinders2.AddRange(emitter.Value);
                    car.Cylinder2SteamEffects = true;
                }
                else if (emitter.Key.ToLowerInvariant() == "blowdownfx")
                {
                    Blowdown.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "drainpipefx")        // Drainpipe was not used in MSTS, and has no control set up for it
                {
                    Drainpipe.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "injectors1fx")
                {
                    Injectors1.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "injectors2fx")
                {
                    Injectors2.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "smallejectorfx")
                {
                    SmallEjector.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "largeejectorfx")
                {
                    LargeEjector.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "compressorfx")
                {
                    Compressor.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "generatorfx")
                {
                    Generator.AddRange(emitter.Value);
                    car.GeneratorSteamEffects = true;
                }
                else if (emitter.Key.ToLowerInvariant() == "safetyvalvesfx")
                {
                    SafetyValves.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "stackfx")
                {
                    Stack.AddRange(emitter.Value);
                }
                else if (emitter.Key.ToLowerInvariant() == "whistlefx")
                {
                    Whistle.AddRange(emitter.Value);
                }
                foreach (var drawer in emitter.Value)
                {
                    drawer.Initialize(steamTexture);
                }
            }
        }