PlayerStopsAtStation() static private méthode

Indicates whether the player's train stops at a station.
static private PlayerStopsAtStation ( int StationIndex ) : bool
StationIndex int
Résultat bool
Exemple #1
0
 internal override void Trigger(int Direction, EventTriggerType TriggerType, TrainManager.Train Train, int CarIndex)
 {
     if (TriggerType == EventTriggerType.FrontCarFrontAxle)
     {
         if (Direction < 0)
         {
             Train.StationFrontCar = true;
         }
         else if (Direction > 0)
         {
             Train.StationFrontCar = false;
             if (Train == TrainManager.PlayerTrain)
             {
                 Timetable.UpdateCustomTimetable(Game.Stations[this.StationIndex].TimetableDaytimeTexture, Game.Stations[this.StationIndex].TimetableNighttimeTexture);
             }
         }
     }
     else if (TriggerType == EventTriggerType.RearCarRearAxle)
     {
         if (Direction < 0)
         {
             Train.Station        = this.StationIndex;
             Train.StationRearCar = true;
             if (Train.NextStopSkipped != TrainManager.StopSkipMode.None)
             {
                 Train.LastStation = this.StationIndex;
             }
             Train.NextStopSkipped = TrainManager.StopSkipMode.None;
         }
         else if (Direction > 0)
         {
             if (Train.Station == StationIndex)
             {
                 if (Train == TrainManager.PlayerTrain)
                 {
                     if (Game.PlayerStopsAtStation(StationIndex) & TrainManager.PlayerTrain.StationState == TrainManager.TrainStopState.Pending)
                     {
                         string s = Interface.GetInterfaceString("message_station_passed");
                         s = s.Replace("[name]", Game.Stations[StationIndex].Name);
                         Game.AddMessage(s, MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.Orange, Game.SecondsSinceMidnight + 10.0, null);
                     }
                     else if (Game.PlayerStopsAtStation(StationIndex) & TrainManager.PlayerTrain.StationState == TrainManager.TrainStopState.Boarding)
                     {
                         string s = Interface.GetInterfaceString("message_station_passed_boarding");
                         s = s.Replace("[name]", Game.Stations[StationIndex].Name);
                         Game.AddMessage(s, MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.Red, Game.SecondsSinceMidnight + 10.0, null);
                     }
                 }
                 Train.Station        = -1;
                 Train.StationRearCar = false;
                 Train.StationState   = TrainManager.TrainStopState.Pending;
                 int d = Train.DriverCar;
                 Sounds.StopSound(Train.Cars[d].Sounds.Halt.Source);
             }
         }
     }
 }
Exemple #2
0
        /// <summary>This method is called once the route and train data have been preprocessed, in order to physically setup the simulation</summary>
        private void SetupSimulation()
        {
            if (Loading.Cancel)
            {
                Close();
            }
            Timetable.CreateTimetable();
            //Check if any critical errors have occured during the route or train loading
            for (int i = 0; i < Interface.MessageCount; i++)
            {
                if (Interface.Messages[i].Type == Interface.MessageType.Critical)
                {
                    MessageBox.Show("A critical error has occured:\n\n" + Interface.Messages[i].Text + "\n\nPlease inspect the error log file for further information.", "Load", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                    Close();
                }
            }
            Renderer.InitializeLighting();
            Game.LogRouteName = System.IO.Path.GetFileName(MainLoop.currentResult.RouteFile);
            Game.LogTrainName = System.IO.Path.GetFileName(MainLoop.currentResult.TrainFolder);
            Game.LogDateTime  = DateTime.Now;

            if (Interface.CurrentOptions.LoadInAdvance)
            {
                Textures.LoadAllTextures();
            }
            else
            {
                Textures.UnloadAllTextures();
            }
            // camera
            ObjectManager.InitializeVisibility();
            World.CameraTrackFollower.Update(0.0, true, false);
            World.CameraTrackFollower.Update(-0.1, true, false);
            World.CameraTrackFollower.Update(0.1, true, false);
            World.CameraTrackFollower.TriggerType = TrackManager.EventTriggerType.Camera;
            // starting time and track position
            Game.SecondsSinceMidnight = 0.0;
            Game.StartupTime          = 0.0;
            int    PlayerFirstStationIndex = -1;
            double PlayerFirstStationPosition;
            int    os = -1;
            bool   f  = false;

            for (int i = 0; i < Game.Stations.Length; i++)
            {
                if (!String.IsNullOrEmpty(Game.InitialStationName))
                {
                    if (Game.InitialStationName.ToLowerInvariant() == Game.Stations[i].Name.ToLowerInvariant())
                    {
                        PlayerFirstStationIndex = i;
                    }
                }
                if (Game.Stations[i].StopMode == StationStopMode.AllStop | Game.Stations[i].StopMode == StationStopMode.PlayerStop & Game.Stations[i].Stops.Length != 0)
                {
                    if (f == false)
                    {
                        os = i;
                        f  = true;
                    }
                }
            }
            if (PlayerFirstStationIndex == -1)
            {
                PlayerFirstStationIndex = os;
            }
            {
                int s = Game.GetStopIndex(PlayerFirstStationIndex, TrainManager.PlayerTrain.Cars.Length);
                if (s >= 0)
                {
                    PlayerFirstStationPosition = Game.Stations[PlayerFirstStationIndex].Stops[s].TrackPosition;

                    double TrainLength = 0.0;
                    for (int c = 0; c < TrainManager.Trains[TrainManager.PlayerTrain.TrainIndex].Cars.Length; c++)
                    {
                        TrainLength += TrainManager.Trains[TrainManager.PlayerTrain.TrainIndex].Cars[c].Length;
                    }

                    for (int j = 0; j < Game.BufferTrackPositions.Length; j++)
                    {
                        if (PlayerFirstStationPosition > Game.BufferTrackPositions[j] && PlayerFirstStationPosition - TrainLength < Game.BufferTrackPositions[j])
                        {
                            /*
                             * HACK: The initial start position for the player train is stuck on a set of buffers
                             * This means we have to make some one the fly adjustments to the first station stop position
                             */

                            //Set the start position to be the buffer position plus the train length plus 1m
                            PlayerFirstStationPosition = Game.BufferTrackPositions[j] + TrainLength + 1;
                            //Update the station stop location
                            if (s >= 0)
                            {
                                Game.Stations[PlayerFirstStationIndex].Stops[s].TrackPosition = PlayerFirstStationPosition;
                            }
                            else
                            {
                                Game.Stations[PlayerFirstStationIndex].DefaultTrackPosition = PlayerFirstStationPosition;
                            }
                            break;
                        }
                    }
                }
                else
                {
                    PlayerFirstStationPosition = Game.Stations[PlayerFirstStationIndex].DefaultTrackPosition;
                }
                if (Game.InitialStationTime != -1)
                {
                    Game.SecondsSinceMidnight = Game.InitialStationTime;
                    Game.StartupTime          = Game.InitialStationTime;
                }
                else
                {
                    if (Game.Stations[PlayerFirstStationIndex].ArrivalTime < 0.0)
                    {
                        if (Game.Stations[PlayerFirstStationIndex].DepartureTime < 0.0)
                        {
                            Game.SecondsSinceMidnight = 0.0;
                            Game.StartupTime          = 0.0;
                        }
                        else
                        {
                            Game.SecondsSinceMidnight = Game.Stations[PlayerFirstStationIndex].DepartureTime -
                                                        Game.Stations[PlayerFirstStationIndex].StopTime;
                            Game.StartupTime = Game.Stations[PlayerFirstStationIndex].DepartureTime -
                                               Game.Stations[PlayerFirstStationIndex].StopTime;
                        }
                    }
                    else
                    {
                        Game.SecondsSinceMidnight = Game.Stations[PlayerFirstStationIndex].ArrivalTime;
                        Game.StartupTime          = Game.Stations[PlayerFirstStationIndex].ArrivalTime;
                    }
                }
            }
            int    OtherFirstStationIndex    = -1;
            double OtherFirstStationPosition = 0.0;
            double OtherFirstStationTime     = 0.0;

            for (int i = 0; i < Game.Stations.Length; i++)
            {
                if (Game.Stations[i].StopMode == StationStopMode.AllStop | Game.Stations[i].StopMode == StationStopMode.PlayerPass & Game.Stations[i].Stops.Length != 0)
                {
                    OtherFirstStationIndex = i;
                    int s = Game.GetStopIndex(i, TrainManager.PlayerTrain.Cars.Length);
                    if (s >= 0)
                    {
                        OtherFirstStationPosition = Game.Stations[i].Stops[s].TrackPosition;
                    }
                    else
                    {
                        OtherFirstStationPosition = Game.Stations[i].DefaultTrackPosition;
                    }
                    if (Game.Stations[i].ArrivalTime < 0.0)
                    {
                        if (Game.Stations[i].DepartureTime < 0.0)
                        {
                            OtherFirstStationTime = 0.0;
                        }
                        else
                        {
                            OtherFirstStationTime = Game.Stations[i].DepartureTime - Game.Stations[i].StopTime;
                        }
                    }
                    else
                    {
                        OtherFirstStationTime = Game.Stations[i].ArrivalTime;
                    }
                    break;
                }
            }
            if (Game.PrecedingTrainTimeDeltas.Length != 0)
            {
                OtherFirstStationTime -= Game.PrecedingTrainTimeDeltas[Game.PrecedingTrainTimeDeltas.Length - 1];
                if (OtherFirstStationTime < Game.SecondsSinceMidnight)
                {
                    Game.SecondsSinceMidnight = OtherFirstStationTime;
                }
            }
            // initialize trains
            for (int i = 0; i < TrainManager.Trains.Length; i++)
            {
                TrainManager.Trains[i].Initialize();
                int s = i == TrainManager.PlayerTrain.TrainIndex ? PlayerFirstStationIndex : OtherFirstStationIndex;
                if (s >= 0)
                {
                    if (Game.Stations[s].OpenLeftDoors)
                    {
                        for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++)
                        {
                            TrainManager.Trains[i].Cars[j].Doors[0].AnticipatedOpen = true;
                        }
                    }
                    if (Game.Stations[s].OpenRightDoors)
                    {
                        for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++)
                        {
                            TrainManager.Trains[i].Cars[j].Doors[1].AnticipatedOpen = true;
                        }
                    }
                }
                if (Game.Sections.Length != 0)
                {
                    Game.Sections[0].Enter(TrainManager.Trains[i]);
                }
                for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++)
                {
                    double length = TrainManager.Trains[i].Cars[0].Length;
                    TrainManager.Trains[i].Cars[j].Move(-length, 0.01);
                    TrainManager.Trains[i].Cars[j].Move(length, 0.01);
                }
            }
            // score
            Game.CurrentScore.ArrivalStation   = PlayerFirstStationIndex + 1;
            Game.CurrentScore.DepartureStation = PlayerFirstStationIndex;
            Game.CurrentScore.Maximum          = 0;
            for (int i = 0; i < Game.Stations.Length; i++)
            {
                if (i != PlayerFirstStationIndex & Game.PlayerStopsAtStation(i))
                {
                    if (i == 0 || Game.Stations[i - 1].Type != StationType.ChangeEnds)
                    {
                        Game.CurrentScore.Maximum += Game.ScoreValueStationArrival;
                    }
                }
            }
            if (Game.CurrentScore.Maximum <= 0)
            {
                Game.CurrentScore.Maximum = Game.ScoreValueStationArrival;
            }
            // signals
            if (Game.Sections.Length > 0)
            {
                Game.UpdateSection(Game.Sections.Length - 1);
            }
            // move train in position
            for (int i = 0; i < TrainManager.Trains.Length; i++)
            {
                double p;
                if (i == TrainManager.PlayerTrain.TrainIndex)
                {
                    p = PlayerFirstStationPosition;
                }
                else if (TrainManager.Trains[i].State == TrainManager.TrainState.Bogus)
                {
                    p = Game.BogusPretrainInstructions[0].TrackPosition;
                    TrainManager.Trains[i].AI = new Game.BogusPretrainAI(TrainManager.Trains[i]);
                }
                else
                {
                    p = OtherFirstStationPosition;
                }
                for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++)
                {
                    TrainManager.Trains[i].Cars[j].Move(p, 0.01);
                }
            }
            // timetable
            if (Timetable.DefaultTimetableDescription.Length == 0)
            {
                Timetable.DefaultTimetableDescription = Game.LogTrainName;
            }

            // initialize camera
            if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable)
            {
                World.CameraMode = World.CameraViewMode.InteriorLookAhead;
            }
            //Place the initial camera in the driver car
            TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].UpdateCamera();
            World.CameraTrackFollower.Update(-1.0, true, false);
            ObjectManager.UpdateVisibility(World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z);
            World.CameraSavedExterior = new World.CameraAlignment(new OpenBveApi.Math.Vector3(-2.5, 1.5, -15.0), 0.3, -0.2, 0.0, PlayerFirstStationPosition, 1.0);
            World.CameraSavedTrack    = new World.CameraAlignment(new OpenBveApi.Math.Vector3(-3.0, 2.5, 0.0), 0.3, 0.0, 0.0, TrainManager.PlayerTrain.Cars[0].FrontAxle.Follower.TrackPosition - 10.0, 1.0);
            // signalling sections
            for (int i = 0; i < TrainManager.Trains.Length; i++)
            {
                int s = TrainManager.Trains[i].CurrentSectionIndex;
                Game.Sections[s].Enter(TrainManager.Trains[i]);
            }
            if (Game.Sections.Length > 0)
            {
                Game.UpdateSection(Game.Sections.Length - 1);
            }
            // fast-forward until start time
            {
                Game.MinimalisticSimulation = true;
                const double w = 0.25;
                double       u = Game.StartupTime - Game.SecondsSinceMidnight;
                if (u > 0)
                {
                    while (true)
                    {
                        double v = u < w ? u : w; u -= v;
                        Game.SecondsSinceMidnight += v;
                        TrainManager.UpdateTrains(v);
                        if (u <= 0.0)
                        {
                            break;
                        }
                        TotalTimeElapsedForSectionUpdate += v;
                        if (TotalTimeElapsedForSectionUpdate >= 1.0)
                        {
                            if (Game.Sections.Length > 0)
                            {
                                Game.UpdateSection(Game.Sections.Length - 1);
                            }
                            TotalTimeElapsedForSectionUpdate = 0.0;
                        }
                    }
                }
                Game.MinimalisticSimulation = false;
            }
            // animated objects
            ObjectManager.UpdateAnimatedWorldObjects(0.0, true);
            TrainManager.UpdateTrainObjects(0.0, true);
            //HACK: This function calls a single update on all objects attached to the player's train
            //      but ignores any specified damping so that all needles etc. are in the correct place
            //      for the first frame, rather than spinning wildly to get to the starting point.
            TrainManager.PlayerTrain.UpdateCabObjects();
            // timetable
            if (TrainManager.PlayerTrain.Station >= 0)
            {
                Timetable.UpdateCustomTimetable(Game.Stations[TrainManager.PlayerTrain.Station].TimetableDaytimeTexture, Game.Stations[TrainManager.PlayerTrain.Station].TimetableNighttimeTexture);
                if (Timetable.CustomObjectsUsed != 0 & Timetable.CustomTimetableAvailable && Interface.CurrentOptions.TimeTableStyle != Interface.TimeTableMode.AutoGenerated && Interface.CurrentOptions.TimeTableStyle != Interface.TimeTableMode.None)
                {
                    Timetable.CurrentTimetable = Timetable.TimetableState.Custom;
                }
            }
            //Create AI driver for the player train if specified via the commmand line
            if (Game.InitialAIDriver == true)
            {
                TrainManager.PlayerTrain.AI = new Game.SimpleHumanDriverAI(TrainManager.PlayerTrain);
                if (TrainManager.PlayerTrain.Plugin != null && !TrainManager.PlayerTrain.Plugin.SupportsAI)
                {
                    Game.AddMessage(Interface.GetInterfaceString("notification_aiunable"), MessageManager.MessageDependency.None, Interface.GameMode.Expert,
                                    OpenBveApi.Colors.MessageColor.White, Game.SecondsSinceMidnight + 10.0, null);
                }
            }

            // warnings / errors
            if (Interface.MessageCount != 0)
            {
                int filesNotFound = 0;
                int errors        = 0;
                int warnings      = 0;
                for (int i = 0; i < Interface.MessageCount; i++)
                {
                    if (Interface.Messages[i].FileNotFound)
                    {
                        filesNotFound++;
                    }
                    else if (Interface.Messages[i].Type == Interface.MessageType.Error)
                    {
                        errors++;
                    }
                    else if (Interface.Messages[i].Type == Interface.MessageType.Warning)
                    {
                        warnings++;
                    }
                }
                string NotFound = null;
                string Messages = null;
                if (filesNotFound != 0)
                {
                    NotFound = filesNotFound.ToString() + " file(s) not found";
                    Game.AddMessage(NotFound, MessageManager.MessageDependency.None, Interface.GameMode.Expert, MessageColor.Magenta, Game.SecondsSinceMidnight + 10.0, null);
                }
                if (errors != 0 & warnings != 0)
                {
                    Messages = errors.ToString() + " error(s), " + warnings.ToString() + " warning(s)";
                    Game.AddMessage(Messages, MessageManager.MessageDependency.None, Interface.GameMode.Expert, MessageColor.Magenta, Game.SecondsSinceMidnight + 10.0, null);
                }
                else if (errors != 0)
                {
                    Messages = errors.ToString() + " error(s)";
                    Game.AddMessage(Messages, MessageManager.MessageDependency.None, Interface.GameMode.Expert, MessageColor.Magenta, Game.SecondsSinceMidnight + 10.0, null);
                }
                else
                {
                    Messages = warnings.ToString() + " warning(s)";
                    Game.AddMessage(Messages, MessageManager.MessageDependency.None, Interface.GameMode.Expert, MessageColor.Magenta, Game.SecondsSinceMidnight + 10.0, null);
                }
                Game.RouteInformation.FilesNotFound     = NotFound;
                Game.RouteInformation.ErrorsAndWarnings = Messages;
                //Print the plugin error encountered (If any) for 10s
                //This must be done after the simulation has init, as otherwise the timeout doesn't work
                if (Loading.PluginError != null)
                {
                    Game.AddMessage(Loading.PluginError, MessageManager.MessageDependency.None, Interface.GameMode.Expert, OpenBveApi.Colors.MessageColor.Red, Game.SecondsSinceMidnight + 5.0, null);
                    Game.AddMessage(Interface.GetInterfaceString("errors_plugin_failure2"), MessageManager.MessageDependency.None, Interface.GameMode.Expert, OpenBveApi.Colors.MessageColor.Red, Game.SecondsSinceMidnight + 5.0, null);
                }
            }
            loadComplete          = true;
            RenderRealTimeElapsed = 0.0;
            RenderTimeElapsed     = 0.0;
            World.InitializeCameraRestriction();
            Loading.SimulationSetup = true;
            switch (Game.InitialViewpoint)
            {
            case 1:
                //Switch camera to exterior
                MainLoop.SaveCameraSettings();
                World.CameraMode = World.CameraViewMode.Exterior;
                MainLoop.RestoreCameraSettings();
                for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                {
                    TrainManager.PlayerTrain.Cars[j].ChangeCarSection(TrainManager.CarSectionType.Exterior);
                }
                //Make bogies visible
                for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                {
                    TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0);
                    TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0);
                }
                World.CameraAlignmentDirection = new World.CameraAlignment();
                World.CameraAlignmentSpeed     = new World.CameraAlignment();
                MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange);
                World.UpdateAbsoluteCamera(0.0);
                World.UpdateViewingDistances();
                break;

            case 2:
                //Switch camera to track
                MainLoop.SaveCameraSettings();
                World.CameraMode = World.CameraViewMode.Track;
                MainLoop.RestoreCameraSettings();
                for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                {
                    TrainManager.PlayerTrain.Cars[j].ChangeCarSection(TrainManager.CarSectionType.Exterior);
                }

                for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                {
                    TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0);
                    TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0);
                }

                World.CameraAlignmentDirection = new World.CameraAlignment();
                World.CameraAlignmentSpeed     = new World.CameraAlignment();
                MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange);
                World.UpdateAbsoluteCamera(0.0);
                World.UpdateViewingDistances();
                break;

            case 3:
                //Switch camera to flyby
                MainLoop.SaveCameraSettings();
                World.CameraMode = World.CameraViewMode.FlyBy;
                MainLoop.RestoreCameraSettings();
                for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                {
                    TrainManager.PlayerTrain.Cars[j].ChangeCarSection(TrainManager.CarSectionType.Exterior);
                }

                for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                {
                    TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0);
                    TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0);
                }

                World.CameraAlignmentDirection = new World.CameraAlignment();
                World.CameraAlignmentSpeed     = new World.CameraAlignment();
                MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange);
                World.UpdateAbsoluteCamera(0.0);
                World.UpdateViewingDistances();
                break;

            case 4:
                //Switch camera to flyby
                MainLoop.SaveCameraSettings();
                World.CameraMode = World.CameraViewMode.FlyByZooming;
                MainLoop.RestoreCameraSettings();
                for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                {
                    TrainManager.PlayerTrain.Cars[j].ChangeCarSection(TrainManager.CarSectionType.Exterior);
                }

                for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                {
                    TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0);
                    TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0);
                }

                World.CameraAlignmentDirection = new World.CameraAlignment();
                World.CameraAlignmentSpeed     = new World.CameraAlignment();
                MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange);
                World.UpdateAbsoluteCamera(0.0);
                World.UpdateViewingDistances();
                break;
            }
        }
Exemple #3
0
        //
        // CREATE GRADIENT PROFILE
        //
        /// <summary>Creates the route gradient profile.</summary>
        /// <returns>The route gradient profile as Bitmap.</returns>
        /// <param name="Width">The width of the bitmap to create.</param>
        /// <param name="Height">The height of the bitmap to create.</param>
        /// <param name="inGame"><c>true</c> = bitmap for in-game overlay | <c>false</c> = for standard window.</param>
        internal static Bitmap CreateRouteGradientProfile(int Width, int Height, bool inGame)
        {
            if (TrackManager.CurrentTrack.Elements.Length > 36 && Game.Stations.Length == 0)
            {
                // If we have track elements, but no stations, show a specific error message, rather
                // than the more generic one thrown later
                // NOTE: Will throw the generic error message on routes shorter than 900m with no stations
                throw new Exception(Interface.GetInterfaceString("errors_route_corrupt_nostations"));
            }
            // Track elements are assumed to be all of the same length, and this length
            // is used as measure unit, rather than computing the incremental track length
            // in any 'real world' unit (like m).

            // HORIZONTAL RANGE: find first and last used element based on stations
            int n, n0, n1;

            RouteRange(out n, out n0, out n1);
            // VERTICAL RANGE
            double y0 = double.PositiveInfinity, y1 = double.NegativeInfinity;

            for (int i = n0; i <= n1; i++)
            {
                double y = TrackManager.CurrentTrack.Elements[i].WorldPosition.Y;
                if (y < y0)
                {
                    y0 = y;
                }
                if (y > y1)
                {
                    y1 = y;
                }
            }
            if (y0 >= y1 - 1.0)
            {
                y0 = y1 - 1.0;
            }

            // allow for some padding around actual data
            double ox = LeftPad, oy = TopPad;
            double w = (double)(Width - (LeftPad + RightPad));
            double h = (double)(Height - (TopPad + BottomPad + TrackOffsPad));
            // horizontal and vertical scale
            double nd = w / (double)(n1 - n0);
            double yd = h / (double)(y1 - y0);
            // set total bitmap track position range; used by in-game profile to place
            // the current position of the trains; as the train positions are known as track positions,
            // actual track positions are needed here, rather than indices into the track element array.
            double minX = TrackManager.CurrentTrack.Elements[n0].StartingTrackPosition;
            double maxX = TrackManager.CurrentTrack.Elements[n1].StartingTrackPosition;
            double offX = ox * (maxX - minX) / w;

            lastGradientMinTrack = (int)(minX - offX);
            lastGradientMaxTrack = (int)(maxX + offX);

            // BITMAP (in-game display needs transparency)
            Bitmap b = new Bitmap(Width, Height,
                                  inGame ? System.Drawing.Imaging.PixelFormat.Format32bppArgb
                                        : System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            Graphics g = Graphics.FromImage(b);

            g.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            int mode = inGame ? 1 : 0;

            g.Clear(mapColors[mode].background);

            // BELOW SEA LEVEL
            {
                double y  = oy + (h - 0.5 * (double)(-Game.RouteInitialElevation - y0) * yd);
                double x0 = ox - (double)(0) * nd;
                double x1 = ox + (double)(n1 - n0) * nd;
                g.FillRectangle(mapColors[mode].belowSeaFill, (float)x0, (float)y, (float)x1, (float)(oy + h) - (float)y);
                g.DrawLine(mapColors[mode].belowSeaBrdr, (float)x0, (float)y, (float)x1, (float)y);
            }
            // GRADIENT PROFILE
            {
                n = n1 - n0 + 1;
                PointF[] p = new PointF[n + 2];
                p[0] = new PointF((float)ox, (float)(oy + h));
                for (int i = n0; i <= n1; i++)
                {
                    double x = ox + (double)(i - n0) * nd;
                    double y = oy + (h - 0.5 *
                                     (double)(TrackManager.CurrentTrack.Elements[i].WorldPosition.Y - y0) * yd);
                    p[i - n0 + 1] = new PointF((float)x, (float)y);
                }
                p[n + 1] = new PointF((float)(ox + (double)(n - 1) * nd), (float)(oy + h));
                g.FillPolygon(mapColors[mode].elevFill, p);
                for (int i = 1; i < n; i++)
                {
                    g.DrawLine(mapColors[mode].elevBrdr, p[i], p[i + 1]);
                }
                g.DrawLine(mapColors[mode].elevBrdr, 0.0f, (float)(oy + h), (float)Width, (float)(oy + h));
            }
            // STATION NAMES
            {
                Font         f = new Font(FontFamily.GenericSansSerif, 12.0f, GraphicsUnit.Pixel);
                StringFormat m = new StringFormat();
                for (int i = n0; i <= n1; i++)
                {
                    for (int j = 0; j < TrackManager.CurrentTrack.Elements[i].Events.Length; j++)
                    {
                        if (TrackManager.CurrentTrack.Elements[i].Events[j] is TrackManager.StationStartEvent)
                        {
                            TrackManager.StationStartEvent e = (TrackManager.StationStartEvent)TrackManager.CurrentTrack.Elements[i].Events[j];
                            if (Game.Stations[e.StationIndex].Name != string.Empty)
                            {
                                bool stop = Game.PlayerStopsAtStation(e.StationIndex);
                                if (Interface.IsJapanese(Game.Stations[e.StationIndex].Name))
                                {
                                    m.Alignment     = StringAlignment.Near;
                                    m.LineAlignment = StringAlignment.Near;
                                    double x = ox + (double)(i - n0) * nd;
                                    double y = oy + (h - 0.5 *
                                                     (double)(TrackManager.CurrentTrack.Elements[i].WorldPosition.Y - y0) * yd);
                                    string t = Game.Stations[e.StationIndex].Name;
                                    float  tx = 0.0f, ty = (float)oy;
                                    for (int k = 0; k < t.Length; k++)
                                    {
                                        SizeF s = g.MeasureString(t.Substring(k, 1), f, 65536, StringFormat.GenericTypographic);
                                        if (s.Width > tx)
                                        {
                                            tx = s.Width;
                                        }
                                    }
                                    for (int k = 0; k < t.Length; k++)
                                    {
                                        g.DrawString(t.Substring(k, 1), f,
                                                     stop ? mapColors[mode].actNameText : mapColors[mode].inactNameText,
                                                     (float)x - 0.5f * tx, ty);
                                        SizeF s = g.MeasureString(t.Substring(k, 1), f, 65536, StringFormat.GenericTypographic);
                                        ty += s.Height;
                                    }
                                    g.DrawLine(stop ? mapColors[mode].actNameBrdr : mapColors[mode].inactNameBrdr,
                                               new PointF((float)x, ty + 4.0f), new PointF((float)x, (float)y));
                                }
                                else
                                {
                                    m.Alignment     = StringAlignment.Far;
                                    m.LineAlignment = StringAlignment.Near;
                                    double x = ox + (double)(i - n0) * nd;
                                    double y = oy + (h - 0.5 *
                                                     (double)(TrackManager.CurrentTrack.Elements[i].WorldPosition.Y - y0) * yd);
                                    g.RotateTransform(-90.0f);
                                    g.TranslateTransform((float)x, (float)oy, System.Drawing.Drawing2D.MatrixOrder.Append);
                                    g.DrawString(Game.Stations[e.StationIndex].Name, f,
                                                 stop ? mapColors[mode].actNameText : mapColors[mode].inactNameText,
                                                 new PointF(0.0f, -5.0f), m);
                                    g.ResetTransform();
                                    SizeF s = g.MeasureString(Game.Stations[e.StationIndex].Name, f);
                                    g.DrawLine(stop ? mapColors[mode].actNameBrdr : mapColors[mode].inactNameBrdr,
                                               new PointF((float)x, (float)(oy + s.Width + 4)), new PointF((float)x, (float)y));
                                }
                            }
                        }
                    }
                }
            }
            // ROUTE MARKERS
            {
                Font         f  = new Font(FontFamily.GenericSansSerif, 10.0f, GraphicsUnit.Pixel);
                Font         fs = new Font(FontFamily.GenericSansSerif, 9.0f, GraphicsUnit.Pixel);
                StringFormat m  = new StringFormat
                {
                    Alignment     = StringAlignment.Far,
                    LineAlignment = StringAlignment.Center
                };
                System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
                int k = TrackOffDist * n / Width;
                if (k == 0)
                {
                    //If k is equal to zero, this generally means that the WithTrack section is missing from our routefile
                    //Adding zero to the loop control variable will also produce an infinite loop, so that's a bad idea too
                    throw new Exception(Interface.GetInterfaceString("errors_route_corrupt_withtrack"));
                }
                for (int i = n0; i <= n1; i += k)
                {
                    double x = ox + (double)(i - n0) * nd;
                    double y = (double)(TrackManager.CurrentTrack.Elements[i].WorldPosition.Y - y0) * yd;
                    // track offset label
                    if (x < w)
                    {
                        string t = ((int)Math.Round(TrackManager.CurrentTrack.Elements[i].StartingTrackPosition)).ToString(Culture);
                        g.DrawString(t + "m", f, mapColors[mode].actNameText, (float)x, (float)(oy + h + TrackOffY));
                    }
                    // route height at track offset (with measure and vertical line)
                    {
                        y = oy + (h - 0.5 * y) + 2.0f;
                        string t = ((int)Math.Round(Game.RouteInitialElevation + TrackManager.CurrentTrack.Elements[i].WorldPosition.Y)).ToString(Culture);
                        SizeF  s = g.MeasureString(t, fs);
                        if (y < oy + h - (double)s.Width - 10.0)
                        {
                            g.RotateTransform(-90.0f);
                            g.TranslateTransform((float)x, (float)y + 4.0f, System.Drawing.Drawing2D.MatrixOrder.Append);
                            g.DrawString(t + "m", fs, mapColors[mode].actNameText, 0.0f, 0.0f, m);
                            g.ResetTransform();
                            g.DrawLine(mapColors[mode].inactNameBrdr,
                                       (float)x, (float)(y + s.Width + 12.0), (float)x, (float)(oy + h));
                        }
                    }
                }
            }
            // finalize
            return(b);
        }
Exemple #4
0
        //
        // CREATE ROUTE MAP
        //
        /// <summary>Creates and returns the route map as Bitmap.</summary>
        /// <returns>The route map.</returns>
        /// <param name="Width">The width of the bitmap to create.</param>
        /// <param name="Height">The height of the bitmap to create.</param>
        /// <param name="inGame"><c>true</c> = bitmap for in-game overlay | <c>false</c> = for standard window.</param>
        internal static Bitmap CreateRouteMap(int Width, int Height, bool inGame)
        {
            int n, n0, n1;

            RouteRange(out n, out n0, out n1);
            // find dimensions
            double x0 = double.PositiveInfinity, z0 = double.PositiveInfinity;
            double x1 = double.NegativeInfinity, z1 = double.NegativeInfinity;

            for (int i = n0; i <= n1; i++)
            {
                double x = TrackManager.CurrentTrack.Elements[i].WorldPosition.X;
                double z = TrackManager.CurrentTrack.Elements[i].WorldPosition.Z;
                if (x < x0)
                {
                    x0 = x;
                }
                if (x > x1)
                {
                    x1 = x;
                }
                if (z < z0)
                {
                    z0 = z;
                }
                if (z > z1)
                {
                    z1 = z;
                }
            }
            // avoid 0 or negative height or width
            if (x0 >= x1 - 1.0)
            {
                x0 = x1 - 1.0;
            }
            if (z0 >= z1 - 1.0)
            {
                z0 = z1 - 1.0;
            }
            // remember area occupied so far
            double xMin, xMax, zMin, zMax;                              // used to track the bitmap area actually occupied by drawings

            xMin = x0;
            xMax = x1;
            zMin = z1;                                                                          // bitmap z goes down, while world z goes up
            zMax = z0;
            // fit route w/h ratio in image w/h ratio
            double wrh = (double)Width / (double)Height;

            if ((x1 - x0) / (z1 - z0) <= wrh)                           // if route ratio is taller than bitmap ratio
            {
                double dx = 0.5 * (z1 - z0) * wrh;                      //	scale (half of) x range as much as (half of) z range
                double px = 0.5 * (x0 + x1);                            //	x range mid point
                x0 = px - dx;                                           //	centre scaled x range around mid point
                x1 = px + dx;
            }
            else                                                                                // if route ratio is wider than bitmap ratio
            {                                                                                   //	do the opposite (scale z range on x)
                double dz = 0.5 * (x1 - x0) / wrh;
                double pz = 0.5 * (z0 + z1);
                z0 = pz - dz;
                z1 = pz + dz;
            }
            double ox = LeftPad, oy = TopPad;
            double w = (double)(Width - (LeftPad + RightPad));
            double h = (double)(Height - (TopPad + BottomPad));
            // horizontal and vertical scales
            double xd = w / (x1 - x0);
            double zd = h / (z1 - z0);

            // convert bitmap occupied area from world to bitmap coordinates
            xMin = ox + (xMin - x0) * xd;
            xMax = ox + (xMax - x0) * xd;
            zMin = oy + (z0 - zMin) * zd + h;
            zMax = oy + (z0 - zMax) * zd + h;
            // create bitmap
            int    mode = inGame ? 1 : 0;
            Bitmap b    = new Bitmap(Width, Height, inGame ? System.Drawing.Imaging.PixelFormat.Format32bppArgb
                                : System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            Graphics g = Graphics.FromImage(b);

            g.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            g.Clear(mapColors[mode].background);

            // ROUTE PATH
            {
                int  start = 0;
                bool atc   = false;
                n = n1 - n0 + 1;
                PointF[] p = new PointF[n];
                for (int i = 0; i < n; i++)
                {
                    double x = TrackManager.CurrentTrack.Elements[i + n0].WorldPosition.X;
                    double z = TrackManager.CurrentTrack.Elements[i + n0].WorldPosition.Z;
                    x    = ox + (x - x0) * xd;
                    z    = oy + (z0 - z) * zd + h;
                    p[i] = new PointF((float)x, (float)z);
                    // ATS / ATC
                    // for each track element, look for a StationStartEvent
                    for (int j = 0; j < TrackManager.CurrentTrack.Elements[i + n0].Events.Length; j++)
                    {
                        if (TrackManager.CurrentTrack.Elements[i + n0].Events[j] is TrackManager.StationStartEvent)
                        {
                            TrackManager.StationStartEvent e =
                                (TrackManager.StationStartEvent)TrackManager.CurrentTrack.Elements[i + n0].Events[j];
                            // if StationStartEvent found, look for a change in ATS/ATC control;
                            // if there is a change, draw all previous track elements
                            // with colour for the previous control state
                            if (Game.Stations[e.StationIndex].SafetySystem == Game.SafetySystem.Atc)
                            {
                                if (!atc)
                                {
                                    atc = true;
                                    if (i - start - 1 > 0)
                                    {
                                        g.DrawCurve(mapColors[mode].normalMap, p, start, i - start - 1);
                                    }
                                    start = i;
                                }
                            }
                            else
                            {
                                if (atc)
                                {
                                    atc = false;
                                    if (i - start - 1 > 0)
                                    {
                                        g.DrawCurve(mapColors[mode].atcMap, p, start, i - start - 1);
                                    }
                                    start = i;
                                }
                            }
                            break;
                        }
                    }
                }
                // draw all remaining track element not drawn yet
                DrawSegmentedCurve(g, atc ? mapColors[mode].atcMap : mapColors[mode].normalMap, p, start, n - start - 1);
            }

            // STATION ICONS
            for (int i = n0; i <= n1; i++)
            {
                for (int j = 0; j < TrackManager.CurrentTrack.Elements[i].Events.Length; j++)
                {
                    if (TrackManager.CurrentTrack.Elements[i].Events[j] is TrackManager.StationStartEvent)
                    {
                        TrackManager.StationStartEvent e = (TrackManager.StationStartEvent)TrackManager.CurrentTrack.Elements[i].Events[j];
                        if (Game.Stations[e.StationIndex].Name != string.Empty)
                        {
                            double x = TrackManager.CurrentTrack.Elements[i].WorldPosition.X;
                            double y = TrackManager.CurrentTrack.Elements[i].WorldPosition.Z;
                            x = ox + (x - x0) * xd;
                            y = oy + (z0 - y) * zd + h;
                            // station circle
                            RectangleF r = new RectangleF((float)x - StationRadius, (float)y - StationRadius,
                                                          StationDiameter, StationDiameter);
                            bool q = Game.PlayerStopsAtStation(e.StationIndex);
                            g.FillEllipse(q ? mapColors[mode].actStatnFill : mapColors[mode].inactStatnFill, r);
                            g.DrawEllipse(q ? mapColors[mode].actStatnBrdr : mapColors[mode].inactStatnBrdr, r);
                            // adjust bitmap occupied area
                            if (r.Left < xMin)
                            {
                                xMin = r.Left;
                            }
                            if (r.Top < zMin)
                            {
                                zMin = r.Top;
                            }
                            if (r.Right > xMax)
                            {
                                xMax = r.Right;
                            }
                            if (r.Bottom > zMax)
                            {
                                zMax = r.Bottom;
                            }
                        }
                    }
                }
            }

            // STATION NAMES
            {
                double wh = w * h;
                Font   f  = new Font(FontFamily.GenericSansSerif, wh < 65536.0 ? 9.0f : 10.0f, GraphicsUnit.Pixel);
                for (int i = n0; i <= n1; i++)
                {
                    for (int j = 0; j < TrackManager.CurrentTrack.Elements[i].Events.Length; j++)
                    {
                        if (TrackManager.CurrentTrack.Elements[i].Events[j] is TrackManager.StationStartEvent)
                        {
                            TrackManager.StationStartEvent e = (TrackManager.StationStartEvent)TrackManager.CurrentTrack.Elements[i].Events[j];
                            if (Game.Stations[e.StationIndex].Name != string.Empty)
                            {
                                double x = TrackManager.CurrentTrack.Elements[i].WorldPosition.X;
                                double y = TrackManager.CurrentTrack.Elements[i].WorldPosition.Z;
                                x = ox + (x - x0) * xd;
                                y = oy + (z0 - y) * zd + h;
                                RectangleF r = new RectangleF((float)x - StationRadius, (float)y - StationRadius,
                                                              StationDiameter, StationDiameter);
                                bool   stop = Game.PlayerStopsAtStation(e.StationIndex);
                                string t = Game.Stations[e.StationIndex].Name;
                                SizeF  m = g.MeasureString(t, f, Width, StringFormat.GenericDefault);
                                double sx = TrackManager.CurrentTrack.Elements[i].WorldSide.X;
                                double sz = TrackManager.CurrentTrack.Elements[i].WorldSide.Z;
                                double xt, yt;
                                if (Math.Sign(sx) == Math.Sign(sz))
                                {
                                    // descending
                                    bool o = (x - ox) * (h - y) <= (w - x) * (y - oy);
                                    if (o)
                                    {
                                        // up-right
                                        xt = x + StationTextPad;
                                        yt = y - StationTextPad - m.Height;
                                    }
                                    else
                                    {
                                        // down-left
                                        xt = x - StationTextPad - m.Width;
                                        yt = y + StationTextPad;
                                    }
                                }
                                else
                                {
                                    // ascending
                                    bool o = (h - y) * (w - x) <= (x - ox) * (y - oy);
                                    if (o)
                                    {
                                        // up-left
                                        xt = x - StationTextPad - m.Width;
                                        yt = y - StationTextPad - m.Height;
                                    }
                                    else
                                    {
                                        // down-right
                                        xt = x + StationTextPad;
                                        yt = y + StationTextPad;
                                    }
                                }
                                // constrain text within bitmap edges (taking into account also paddings)
                                if (xt < ox)
                                {
                                    xt = ox;
                                }
                                else if (xt + m.Width > w)
                                {
                                    xt = w - m.Width;
                                }
                                if (yt < oy)
                                {
                                    yt = oy;
                                }
                                else if (yt + m.Height > h)
                                {
                                    yt = h - m.Height;
                                }
                                r = new RectangleF((float)xt - 1.0f, (float)yt - 1.0f, m.Width + 2.0f, m.Height + 2.0f);
                                g.FillRectangle(stop ? mapColors[mode].actNameFill : mapColors[mode].inactNameFill,
                                                r.Left, r.Top, r.Width, r.Height);
                                g.DrawRectangle(stop ? mapColors[mode].actNameBrdr : mapColors[mode].inactNameBrdr,
                                                r.Left, r.Top, r.Width, r.Height);
                                g.DrawString(t, f, stop ? mapColors[mode].actNameText : mapColors[mode].inactNameText,
                                             (float)xt, (float)yt);
                                // adjust bitmap occupied area
                                if (r.Left < xMin)
                                {
                                    xMin = r.Left;
                                }
                                if (r.Top < zMin)
                                {
                                    zMin = r.Top;
                                }
                                if (r.Right > xMax)
                                {
                                    xMax = r.Right;
                                }
                                if (r.Bottom > zMax)
                                {
                                    zMax = r.Bottom;
                                }
                            }
                        }
                    }
                }
            }
            // if in-game, trim unused parts of the bitmap
            if (inGame)
            {
                xMin -= LeftPad;
                xMax += RightPad;
                zMin -= TopPad;
                zMax += BottomPad;
                if (xMin < 0)
                {
                    xMin = 0;
                }
                if (xMax >= Width)
                {
                    xMax = Width - 1;
                }
                if (zMin < 0)
                {
                    zMin = 0;
                }
                if (zMax >= Height)
                {
                    zMax = Height - 1;
                }
                Bitmap nb = new Bitmap((int)(xMax - xMin + 1.0), (int)(zMax - zMin + 1.0));                     // round up
                g = Graphics.FromImage(nb);
                g.DrawImage(b, (int)-xMin, (int)-zMin);                                                         // round down
                // set total bitmap world X and Z ranges from bitmap ranges
                lastRouteMinX = (int)((xMin - ox) / xd + x0);
                lastRouteMaxX = (int)((xMax - ox) / xd + x0);
                lastRouteMinZ = (int)(z0 - (zMax - oy - h) / zd);
                lastRouteMaxZ = (int)(z0 - (zMin - oy - h) / zd);
                return(nb);
            }
            //set total bitmap X and Z ranges
            lastRouteMinX = (int)(x0 - ox * (x1 - x0) / w);
            lastRouteMaxX = (int)(x1 + (Width - w - ox) * (x1 - x0) / w);
            lastRouteMinZ = (int)(z0 - oy * (z1 - z0) / h);
            lastRouteMaxZ = (int)(z1 + (Height - h - oy) * (z1 - z0) / h);
            return(b);
        }
Exemple #5
0
        // collect data
        internal static void CollectData(out Table Table)
        {
            System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
            Table.Stations = new Station[16];
            Table.Tracks   = new Track[16];
            int    n = 0;
            double Limit = -1.0, LastLimit = 6.94444444444444;
            int    LastArrivalHours = -1, LastDepartureHours = -1;
            double LastTime = -1.0;

            for (int i = 0; i < TrackManager.CurrentTrack.Elements.Length; i++)
            {
                for (int j = 0; j < TrackManager.CurrentTrack.Elements[i].Events.Length; j++)
                {
                    TrackManager.StationStartEvent sse = TrackManager.CurrentTrack.Elements[i].Events[j] as TrackManager.StationStartEvent;
                    if (sse != null && Game.Stations[sse.StationIndex].Name != string.Empty)
                    {
                        if (Limit == -1.0)
                        {
                            Limit = LastLimit;
                        }
                        // update station
                        if (n == Table.Stations.Length)
                        {
                            Array.Resize <Station>(ref Table.Stations, Table.Stations.Length << 1);
                        }
                        Table.Stations[n].Name         = Game.Stations[sse.StationIndex].Name;
                        Table.Stations[n].NameJapanese = Game.Stations[sse.StationIndex].Name.IsJapanese();
                        Table.Stations[n].Pass         = !Game.PlayerStopsAtStation(sse.StationIndex);
                        Table.Stations[n].Terminal     = Game.Stations[sse.StationIndex].Type != StationType.Normal;
                        double x;
                        if (Game.Stations[sse.StationIndex].ArrivalTime >= 0.0)
                        {
                            x  = Game.Stations[sse.StationIndex].ArrivalTime;
                            x -= 86400.0 * Math.Floor(x / 86400.0);
                            int hours = (int)Math.Floor(x / 3600.0);
                            x -= 3600.0 * (double)hours;
                            int minutes = (int)Math.Floor(x / 60.0);
                            x -= 60.0 * (double)minutes;
                            int seconds = (int)Math.Floor(x);
                            Table.Stations[n].Arrival.Hour = hours != LastArrivalHours?hours.ToString("00", Culture) : "";

                            Table.Stations[n].Arrival.Minute = minutes.ToString("00", Culture);
                            Table.Stations[n].Arrival.Second = seconds.ToString("00", Culture);
                            LastArrivalHours = hours;
                        }
                        else
                        {
                            Table.Stations[n].Arrival.Hour   = "";
                            Table.Stations[n].Arrival.Minute = "";
                            Table.Stations[n].Arrival.Second = "";
                        }
                        if (Game.Stations[sse.StationIndex].DepartureTime >= 0.0)
                        {
                            x  = Game.Stations[sse.StationIndex].DepartureTime;
                            x -= 86400.0 * Math.Floor(x / 86400.0);
                            int hours = (int)Math.Floor(x / 3600.0);
                            x -= 3600.0 * (double)hours;
                            int minutes = (int)Math.Floor(x / 60.0);
                            x -= 60.0 * (double)minutes;
                            int seconds = (int)Math.Floor(x);
                            Table.Stations[n].Departure.Hour = hours != LastDepartureHours?hours.ToString("00", Culture) : "";

                            Table.Stations[n].Departure.Minute = minutes.ToString("00", Culture);
                            Table.Stations[n].Departure.Second = seconds.ToString("00", Culture);
                            LastDepartureHours = hours;
                        }
                        else
                        {
                            Table.Stations[n].Departure.Hour   = "";
                            Table.Stations[n].Departure.Minute = "";
                            Table.Stations[n].Departure.Second = "";
                        }
                        // update track
                        if (n >= 1)
                        {
                            int m = n - 1;
                            if (m == Table.Tracks.Length)
                            {
                                Array.Resize <Track>(ref Table.Tracks, Table.Tracks.Length << 1);
                            }
                            // speed
                            x = Math.Round(3.6 * Limit);
                            Table.Tracks[m].Speed = x.ToString(Culture);
                            // time
                            if (LastTime >= 0.0)
                            {
                                if (Game.Stations[sse.StationIndex].ArrivalTime >= 0.0)
                                {
                                    x = Game.Stations[sse.StationIndex].ArrivalTime;
                                }
                                else if (Game.Stations[sse.StationIndex].DepartureTime >= 0.0)
                                {
                                    x = Game.Stations[sse.StationIndex].DepartureTime;
                                }
                                else
                                {
                                    x = -1.0;
                                }
                                if (x >= 0.0)
                                {
                                    x -= LastTime;
                                    int hours = (int)Math.Floor(x / 3600.0);
                                    x -= 3600.0 * (double)hours;
                                    int minutes = (int)Math.Floor(x / 60.0);
                                    x -= 60.0 * (double)minutes;
                                    int seconds = (int)Math.Floor(x);
                                    Table.Tracks[m].Time.Hour   = hours != 0 ? hours.ToString("0", Culture) : "";
                                    Table.Tracks[m].Time.Minute = minutes != 0 ? minutes.ToString("00", Culture) : "";
                                    Table.Tracks[m].Time.Second = seconds != 0 ? seconds.ToString("00", Culture) : "";
                                }
                                else
                                {
                                    Table.Tracks[m].Time.Hour   = "";
                                    Table.Tracks[m].Time.Minute = "";
                                    Table.Tracks[m].Time.Second = "";
                                }
                            }
                            else
                            {
                                Table.Tracks[m].Time.Hour   = "";
                                Table.Tracks[m].Time.Minute = "";
                                Table.Tracks[m].Time.Second = "";
                            }
                        }
                        // update last data
                        if (Game.Stations[sse.StationIndex].DepartureTime >= 0.0)
                        {
                            LastTime = Game.Stations[sse.StationIndex].DepartureTime;
                        }
                        else if (Game.Stations[sse.StationIndex].ArrivalTime >= 0.0)
                        {
                            LastTime = Game.Stations[sse.StationIndex].ArrivalTime;
                        }
                        else
                        {
                            LastTime = -1.0;
                        }
                        LastLimit = Limit;
                        Limit     = -1.0;
                        n++;
                    }
                    if (n >= 1)
                    {
                        TrackManager.LimitChangeEvent lce = TrackManager.CurrentTrack.Elements[i].Events[j] as TrackManager.LimitChangeEvent;
                        if (lce != null)
                        {
                            if (lce.NextSpeedLimit != double.PositiveInfinity & lce.NextSpeedLimit > Limit)
                            {
                                Limit = lce.NextSpeedLimit;
                            }
                        }
                    }
                }
            }
            Array.Resize <Station>(ref Table.Stations, n);
            if (n >= 2)
            {
                Array.Resize <Track>(ref Table.Tracks, n - 1);
            }
            else
            {
                Table.Tracks = new Track[] { };
            }
        }
Exemple #6
0
        /// <summary>Renders all default HUD elements</summary>
        /// <param name="Element">The HUD element these are to be rendererd onto</param>
        /// <param name="TimeElapsed">The time elapsed</param>
        private static void RenderHUDElement(HUD.Element Element, double TimeElapsed)
        {
            TrainManager.TrainDoorState      LeftDoors  = TrainManager.GetDoorsState(TrainManager.PlayerTrain, true, false);
            TrainManager.TrainDoorState      RightDoors = TrainManager.GetDoorsState(TrainManager.PlayerTrain, false, true);
            System.Globalization.CultureInfo Culture    = System.Globalization.CultureInfo.InvariantCulture;
            string Command = Element.Subject.ToLowerInvariant();
            // default
            double w, h;

            if (Element.CenterMiddle.BackgroundTexture != null)
            {
                if (Textures.LoadTexture(Element.CenterMiddle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                {
                    w = (double)Element.CenterMiddle.BackgroundTexture.Width;
                    h = (double)Element.CenterMiddle.BackgroundTexture.Height;
                }
                else
                {
                    w = 0.0; h = 0.0;
                }
            }
            else
            {
                w = 0.0; h = 0.0;
            }
            double x = Element.Alignment.X < 0 ? 0.0 : Element.Alignment.X == 0 ? 0.5 * (Screen.Width - w) : Screen.Width - w;
            double y = Element.Alignment.Y < 0 ? 0.0 : Element.Alignment.Y == 0 ? 0.5 * (Screen.Height - h) : Screen.Height - h;

            x += Element.Position.X;
            y += Element.Position.Y;
            // command
            const double speed = 1.0;
            MessageColor sc    = MessageColor.None;
            string       t;

            switch (Command)
            {
            case "reverser":
                if (TrainManager.PlayerTrain.Handles.Reverser.Driver < 0)
                {
                    sc = MessageColor.Orange;
                    if (TrainManager.PlayerTrain.ReverserDescriptions != null && TrainManager.PlayerTrain.ReverserDescriptions.Length > 2)
                    {
                        t = TrainManager.PlayerTrain.ReverserDescriptions[2];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandleBackward;
                    }
                }
                else if (TrainManager.PlayerTrain.Handles.Reverser.Driver > 0)
                {
                    sc = MessageColor.Blue;
                    if (TrainManager.PlayerTrain.ReverserDescriptions != null && TrainManager.PlayerTrain.ReverserDescriptions.Length > 0)
                    {
                        t = TrainManager.PlayerTrain.ReverserDescriptions[0];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandleForward;
                    }
                }
                else
                {
                    sc = MessageColor.Gray;
                    if (TrainManager.PlayerTrain.ReverserDescriptions != null && TrainManager.PlayerTrain.ReverserDescriptions.Length > 1)
                    {
                        t = TrainManager.PlayerTrain.ReverserDescriptions[1];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandleNeutral;
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "power":
                if (TrainManager.PlayerTrain.Handles.SingleHandle)
                {
                    return;
                }
                if (TrainManager.PlayerTrain.Handles.Power.Driver == 0)
                {
                    sc = MessageColor.Gray;
                    if (TrainManager.PlayerTrain.PowerNotchDescriptions != null && TrainManager.PlayerTrain.PowerNotchDescriptions.Length > 0)
                    {
                        t = TrainManager.PlayerTrain.PowerNotchDescriptions[0];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandlePowerNull;
                    }
                }
                else
                {
                    sc = MessageColor.Blue;
                    if (TrainManager.PlayerTrain.PowerNotchDescriptions != null && TrainManager.PlayerTrain.Handles.Power.Driver < TrainManager.PlayerTrain.PowerNotchDescriptions.Length)
                    {
                        t = TrainManager.PlayerTrain.PowerNotchDescriptions[TrainManager.PlayerTrain.Handles.Power.Driver];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandlePower + TrainManager.PlayerTrain.Handles.Power.Driver.ToString(Culture);
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "brake":
                if (TrainManager.PlayerTrain.Handles.SingleHandle)
                {
                    return;
                }
                if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle)
                {
                    if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver)
                    {
                        sc = MessageColor.Red;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 0)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[0];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleEmergency;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Release)
                    {
                        sc = MessageColor.Gray;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleRelease;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Lap)
                    {
                        sc = MessageColor.Blue;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 2)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[2];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleLap;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 3)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[3];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleService;
                        }
                    }
                }
                else
                {
                    if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver)
                    {
                        sc = MessageColor.Red;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 0)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[0];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleEmergency;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.HoldBrake.Driver)
                    {
                        sc = MessageColor.Green;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 2)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[2];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleHoldBrake;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.Brake.Driver == 0)
                    {
                        sc = MessageColor.Gray;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleBrakeNull;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && ((TrainManager.PlayerTrain.Handles.HasHoldBrake && TrainManager.PlayerTrain.Handles.Brake.Driver + 2 < TrainManager.PlayerTrain.BrakeNotchDescriptions.Length) || (!TrainManager.PlayerTrain.Handles.HasHoldBrake && TrainManager.PlayerTrain.Handles.Brake.Driver + 1 < TrainManager.PlayerTrain.BrakeNotchDescriptions.Length)))
                        {
                            t = TrainManager.PlayerTrain.Handles.HasHoldBrake ? TrainManager.PlayerTrain.BrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.Brake.Driver + 2] : TrainManager.PlayerTrain.BrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.Brake.Driver + 1];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleBrake + TrainManager.PlayerTrain.Handles.Brake.Driver.ToString(Culture);
                        }
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "locobrake":
                if (!TrainManager.PlayerTrain.Handles.HasLocoBrake)
                {
                    return;
                }

                if (TrainManager.PlayerTrain.Handles.LocoBrake is TrainManager.LocoAirBrakeHandle)
                {
                    if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == (int)TrainManager.AirBrakeHandleState.Release)
                    {
                        sc = MessageColor.Gray;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleRelease;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == (int)TrainManager.AirBrakeHandleState.Lap)
                    {
                        sc = MessageColor.Blue;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 2)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[2];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleLap;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 3)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[3];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleService;
                        }
                    }
                }
                else
                {
                    if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == 0)
                    {
                        sc = MessageColor.Gray;
                        if (TrainManager.PlayerTrain.LocoBrakeNotchDescriptions != null && TrainManager.PlayerTrain.LocoBrakeNotchDescriptions.Length > 1)
                        {
                            t = TrainManager.PlayerTrain.LocoBrakeNotchDescriptions[1];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleBrakeNull;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.LocoBrakeNotchDescriptions != null && TrainManager.PlayerTrain.Handles.LocoBrake.Driver < TrainManager.PlayerTrain.LocoBrakeNotchDescriptions.Length)
                        {
                            t = TrainManager.PlayerTrain.LocoBrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.LocoBrake.Driver];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleLocoBrake + TrainManager.PlayerTrain.Handles.LocoBrake.Driver.ToString(Culture);
                        }
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "single":
                if (!TrainManager.PlayerTrain.Handles.SingleHandle)
                {
                    return;
                }
                if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver)
                {
                    sc = MessageColor.Red;
                    if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 0)
                    {
                        t = TrainManager.PlayerTrain.BrakeNotchDescriptions[0];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandleEmergency;
                    }
                }
                else if (TrainManager.PlayerTrain.Handles.HoldBrake.Driver)
                {
                    sc = MessageColor.Green;
                    if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1)
                    {
                        t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandleHoldBrake;
                    }
                }
                else if (TrainManager.PlayerTrain.Handles.Brake.Driver > 0)
                {
                    sc = MessageColor.Orange;
                    if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.Handles.Brake.Driver + 3 < TrainManager.PlayerTrain.BrakeNotchDescriptions.Length)
                    {
                        t = TrainManager.PlayerTrain.BrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.Brake.Driver + 3];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandleBrake + TrainManager.PlayerTrain.Handles.Brake.Driver.ToString(Culture);
                    }
                }
                else if (TrainManager.PlayerTrain.Handles.Power.Driver > 0)
                {
                    sc = MessageColor.Blue;
                    if (TrainManager.PlayerTrain.PowerNotchDescriptions != null && TrainManager.PlayerTrain.Handles.Power.Driver < TrainManager.PlayerTrain.PowerNotchDescriptions.Length)
                    {
                        t = TrainManager.PlayerTrain.PowerNotchDescriptions[TrainManager.PlayerTrain.Handles.Power.Driver];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandlePower + TrainManager.PlayerTrain.Handles.Power.Driver.ToString(Culture);
                    }
                }
                else
                {
                    sc = MessageColor.Gray;
                    if (TrainManager.PlayerTrain.PowerNotchDescriptions != null && TrainManager.PlayerTrain.PowerNotchDescriptions.Length > 0)
                    {
                        t = TrainManager.PlayerTrain.PowerNotchDescriptions[0];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandlePowerNull;
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "doorsleft":
            case "doorsright":
            {
                if ((LeftDoors & TrainManager.TrainDoorState.AllClosed) == 0 | (RightDoors & TrainManager.TrainDoorState.AllClosed) == 0)
                {
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                TrainManager.TrainDoorState Doors = Command == "doorsleft" ? LeftDoors : RightDoors;
                if ((Doors & TrainManager.TrainDoorState.Mixed) != 0)
                {
                    sc = MessageColor.Orange;
                }
                else if ((Doors & TrainManager.TrainDoorState.AllClosed) != 0)
                {
                    sc = MessageColor.Gray;
                }
                else if (TrainManager.PlayerTrain.Specs.DoorCloseMode == TrainManager.DoorMode.Manual)
                {
                    sc = MessageColor.Green;
                }
                else
                {
                    sc = MessageColor.Blue;
                }
                t = Command == "doorsleft" ? Translations.QuickReferences.DoorsLeft : Translations.QuickReferences.DoorsRight;
            }
            break;

            case "stopleft":
            case "stopright":
            case "stopnone":
            {
                int s = TrainManager.PlayerTrain.Station;
                if (s >= 0 && Game.PlayerStopsAtStation(s) && Interface.CurrentOptions.GameMode != Interface.GameMode.Expert)
                {
                    bool cond;
                    if (Command == "stopleft")
                    {
                        cond = Game.Stations[s].OpenLeftDoors;
                    }
                    else if (Command == "stopright")
                    {
                        cond = Game.Stations[s].OpenRightDoors;
                    }
                    else
                    {
                        cond = !Game.Stations[s].OpenLeftDoors & !Game.Stations[s].OpenRightDoors;
                    }
                    if (TrainManager.PlayerTrain.StationState == TrainManager.TrainStopState.Pending & cond)
                    {
                        Element.TransitionState -= speed * TimeElapsed;
                        if (Element.TransitionState < 0.0)
                        {
                            Element.TransitionState = 0.0;
                        }
                    }
                    else
                    {
                        Element.TransitionState += speed * TimeElapsed;
                        if (Element.TransitionState > 1.0)
                        {
                            Element.TransitionState = 1.0;
                        }
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                t = Element.Text;
            }
            break;

            case "stoplefttick":
            case "stoprighttick":
            case "stopnonetick":
            {
                int s = TrainManager.PlayerTrain.Station;
                if (s >= 0 && Game.PlayerStopsAtStation(s) && Interface.CurrentOptions.GameMode != Interface.GameMode.Expert)
                {
                    int c = Game.Stations[s].GetStopIndex(TrainManager.PlayerTrain.Cars.Length);
                    if (c >= 0)
                    {
                        bool cond;
                        if (Command == "stoplefttick")
                        {
                            cond = Game.Stations[s].OpenLeftDoors;
                        }
                        else if (Command == "stoprighttick")
                        {
                            cond = Game.Stations[s].OpenRightDoors;
                        }
                        else
                        {
                            cond = !Game.Stations[s].OpenLeftDoors & !Game.Stations[s].OpenRightDoors;
                        }
                        if (TrainManager.PlayerTrain.StationState == TrainManager.TrainStopState.Pending & cond)
                        {
                            Element.TransitionState -= speed * TimeElapsed;
                            if (Element.TransitionState < 0.0)
                            {
                                Element.TransitionState = 0.0;
                            }
                        }
                        else
                        {
                            Element.TransitionState += speed * TimeElapsed;
                            if (Element.TransitionState > 1.0)
                            {
                                Element.TransitionState = 1.0;
                            }
                        }
                        double d = TrainManager.PlayerTrain.StationDistanceToStopPoint;
                        double r;
                        if (d > 0.0)
                        {
                            r = d / Game.Stations[s].Stops[c].BackwardTolerance;
                        }
                        else
                        {
                            r = d / Game.Stations[s].Stops[c].ForwardTolerance;
                        }
                        if (r < -1.0)
                        {
                            r = -1.0;
                        }

                        if (r > 1.0)
                        {
                            r = 1.0;
                        }

                        y -= r * (double)Element.Value1;
                    }
                    else
                    {
                        Element.TransitionState += speed * TimeElapsed;
                        if (Element.TransitionState > 1.0)
                        {
                            Element.TransitionState = 1.0;
                        }
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                t = Element.Text;
            }
            break;

            case "clock":
            {
                int hours   = (int)Math.Floor(Game.SecondsSinceMidnight);
                int seconds = hours % 60; hours /= 60;
                int minutes = hours % 60; hours /= 60;
                hours %= 24;
                t      = hours.ToString(Culture).PadLeft(2, '0') + ":" + minutes.ToString(Culture).PadLeft(2, '0') + ":" + seconds.ToString(Culture).PadLeft(2, '0');
                if (OptionClock)
                {
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
            }
            break;

            case "gradient":
                if (OptionGradient == GradientDisplayMode.Percentage)
                {
                    if (World.CameraTrackFollower.Pitch != 0)
                    {
                        double pc = World.CameraTrackFollower.Pitch;
                        t = Math.Abs(pc).ToString("0.00", Culture) + "%" + (Math.Abs(pc) == pc ? " ↗" : " ↘");
                    }
                    else
                    {
                        t = "Level";
                    }
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else if (OptionGradient == GradientDisplayMode.UnitOfChange)
                {
                    if (World.CameraTrackFollower.Pitch != 0)
                    {
                        double gr = 1000 / World.CameraTrackFollower.Pitch;
                        t = "1 in " + Math.Abs(gr).ToString("0", Culture) + (Math.Abs(gr) == gr ? " ↗" : " ↘");
                    }
                    else
                    {
                        t = "Level";
                    }
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else if (OptionGradient == GradientDisplayMode.Permil)
                {
                    if (World.CameraTrackFollower.Pitch != 0)
                    {
                        double pm = World.CameraTrackFollower.Pitch;
                        t = Math.Abs(pm).ToString("0.00", Culture) + "‰" + (Math.Abs(pm) == pm ? " ↗" : " ↘");
                    }
                    else
                    {
                        t = "Level";
                    }
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    if (World.CameraTrackFollower.Pitch != 0)
                    {
                        double gr = 1000 / World.CameraTrackFollower.Pitch;
                        t = "1 in " + Math.Abs(gr).ToString("0", Culture) + (Math.Abs(gr) == gr ? " ↗" : " ↘");
                    }
                    else
                    {
                        t = "Level";
                    }
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                break;

            case "speed":
                if (OptionSpeed == SpeedDisplayMode.Kmph)
                {
                    double kmph = Math.Abs(TrainManager.PlayerTrain.Specs.CurrentAverageSpeed) * 3.6;
                    t = kmph.ToString("0.00", Culture) + " km/h";
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else if (OptionSpeed == SpeedDisplayMode.Mph)
                {
                    double mph = Math.Abs(TrainManager.PlayerTrain.Specs.CurrentAverageSpeed) * 2.2369362920544;
                    t = mph.ToString("0.00", Culture) + " mph";
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    double mph = Math.Abs(TrainManager.PlayerTrain.Specs.CurrentAverageSpeed) * 2.2369362920544;
                    t = mph.ToString("0.00", Culture) + " mph";
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                break;

            case "dist_next_station":
                int i;
                if (TrainManager.PlayerTrain.Station >= 0 && TrainManager.PlayerTrain.StationState != TrainManager.TrainStopState.Completed)
                {
                    i = TrainManager.PlayerTrain.LastStation;
                }
                else
                {
                    i = TrainManager.PlayerTrain.LastStation + 1;
                }
                if (i > Game.Stations.Length - 1)
                {
                    i = TrainManager.PlayerTrain.LastStation;
                }
                int    n  = Game.Stations[i].GetStopIndex(TrainManager.PlayerTrain.Cars.Length);
                double p0 = TrainManager.PlayerTrain.Cars[0].FrontAxle.Follower.TrackPosition - TrainManager.PlayerTrain.Cars[0].FrontAxle.Position + 0.5 * TrainManager.PlayerTrain.Cars[0].Length;
                double p1;
                if (Game.Stations[i].Stops.Length > 0)
                {
                    p1 = Game.Stations[i].Stops[n].TrackPosition;
                }
                else
                {
                    p1 = Game.Stations[i].DefaultTrackPosition;
                }
                double m = p1 - p0;
                if (OptionDistanceToNextStation == DistanceToNextStationDisplayMode.Km)
                {
                    if (Game.PlayerStopsAtStation(i))
                    {
                        t = "Stop: ";
                        if (Math.Abs(m) <= 10.0)
                        {
                            t += m.ToString("0.00", Culture) + " m";
                        }
                        else
                        {
                            m /= 1000.0;
                            t += m.ToString("0.000", Culture) + " km";
                        }
                    }
                    else
                    {
                        m /= 1000.0;
                        t  = "Pass: "******"0.000", Culture) + " km";
                    }
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else if (OptionDistanceToNextStation == DistanceToNextStationDisplayMode.Mile)
                {
                    m /= 1609.34;
                    if (Game.PlayerStopsAtStation(i))
                    {
                        t = "Stop: ";
                    }
                    else
                    {
                        t = "Pass: "******"0.0000", Culture) + " miles";
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    m /= 1609.34;
                    if (Game.PlayerStopsAtStation(i))
                    {
                        t = "Stop: ";
                    }
                    else
                    {
                        t = "Pass: "******"0.0000", Culture) + " miles";
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                break;

            case "fps":
                int fps = (int)Math.Round(Game.InfoFrameRate);
                t = fps.ToString(Culture) + " fps";
                if (OptionFrameRates)
                {
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                break;

            case "ai":
                t = "A.I.";
                if (TrainManager.PlayerTrain.AI != null)
                {
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                break;

            case "score":
                if (Interface.CurrentOptions.GameMode == Interface.GameMode.Arcade)
                {
                    t = Game.CurrentScore.CurrentValue.ToString(Culture) + " / " + Game.CurrentScore.Maximum.ToString(Culture);
                    if (Game.CurrentScore.CurrentValue < 0)
                    {
                        sc = MessageColor.Red;
                    }
                    else if (Game.CurrentScore.CurrentValue > 0)
                    {
                        sc = MessageColor.Green;
                    }
                    else
                    {
                        sc = MessageColor.Gray;
                    }
                    Element.TransitionState = 0.0;
                }
                else
                {
                    Element.TransitionState = 1.0;
                    t = "";
                }
                break;

            default:
                t = Element.Text;
                break;
            }
            // transitions
            float alpha = 1.0f;

            if ((Element.Transition & HUD.Transition.Move) != 0)
            {
                double s = Element.TransitionState;
                x += Element.TransitionVector.X * s * s;
                y += Element.TransitionVector.Y * s * s;
            }
            if ((Element.Transition & HUD.Transition.Fade) != 0)
            {
                alpha = (float)(1.0 - Element.TransitionState);
            }
            else if (Element.Transition == HUD.Transition.None)
            {
                alpha = (float)(1.0 - Element.TransitionState);
            }
            // render
            if (alpha != 0.0f)
            {
                // background
                if (Element.Subject == "reverser")
                {
                    w = Math.Max(w, TrainManager.PlayerTrain.MaxReverserWidth);
                    //X-Pos doesn't need to be changed
                }
                if (Element.Subject == "power")
                {
                    w = Math.Max(w, TrainManager.PlayerTrain.MaxPowerNotchWidth);
                    if (TrainManager.PlayerTrain.MaxReverserWidth > 48)
                    {
                        x += (TrainManager.PlayerTrain.MaxReverserWidth - 48);
                    }
                }
                if (Element.Subject == "brake")
                {
                    w = Math.Max(w, TrainManager.PlayerTrain.MaxBrakeNotchWidth);
                    if (TrainManager.PlayerTrain.MaxReverserWidth > 48)
                    {
                        x += (TrainManager.PlayerTrain.MaxReverserWidth - 48);
                    }
                    if (TrainManager.PlayerTrain.MaxPowerNotchWidth > 48)
                    {
                        x += (TrainManager.PlayerTrain.MaxPowerNotchWidth - 48);
                    }
                }
                if (Element.Subject == "single")
                {
                    w = Math.Max(Math.Max(w, TrainManager.PlayerTrain.MaxPowerNotchWidth), TrainManager.PlayerTrain.MaxBrakeNotchWidth);
                    if (TrainManager.PlayerTrain.MaxReverserWidth > 48)
                    {
                        x += (TrainManager.PlayerTrain.MaxReverserWidth - 48);
                    }
                }
                if (Element.CenterMiddle.BackgroundTexture != null)
                {
                    if (Textures.LoadTexture(Element.CenterMiddle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        float r, g, b, a;
                        CreateBackColor(Element.BackgroundColor, sc, out r, out g, out b, out a);
                        GL.Color4(r, g, b, a * alpha);
                        RenderOverlayTexture(Element.CenterMiddle.BackgroundTexture, x, y, x + w, y + h);
                    }
                }
                {                 // text
                    System.Drawing.Size size = MeasureString(Element.Font, t);
                    float  u = size.Width;
                    float  v = size.Height;
                    double p = Math.Round(Element.TextAlignment.X < 0 ? x : Element.TextAlignment.X == 0 ? x + 0.5 * (w - u) : x + w - u);
                    double q = Math.Round(Element.TextAlignment.Y < 0 ? y : Element.TextAlignment.Y == 0 ? y + 0.5 * (h - v) : y + h - v);
                    p += Element.TextPosition.X;
                    q += Element.TextPosition.Y;
                    float r, g, b, a;
                    CreateTextColor(Element.TextColor, sc, out r, out g, out b, out a);
                    DrawString(Element.Font, t, new System.Drawing.Point((int)p, (int)q), TextAlignment.TopLeft, new Color128(r, g, b, a * alpha), Element.TextShadow);
                }
                // overlay
                if (Element.CenterMiddle.OverlayTexture != null)
                {
                    if (Textures.LoadTexture(Element.CenterMiddle.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        float r, g, b, a;
                        CreateBackColor(Element.OverlayColor, sc, out r, out g, out b, out a);
                        GL.Color4(r, g, b, a * alpha);
                        RenderOverlayTexture(Element.CenterMiddle.OverlayTexture, x, y, x + w, y + h);
                    }
                }
            }
        }
Exemple #7
0
            public int TopItem;                     // the top displayed menu item


            /********************
             *      MENU C'TOR
             *********************/
            public SingleMenu(MenuType menuType, int data = 0)
            {
                int  i, menuItem;
                int  jump = 0;
                Size size;

                Align     = TextAlignment.TopMiddle;
                Height    = Width = 0;
                Selection = 0;                                      // defaults to first menu item
                switch (menuType)
                {
                case MenuType.Top:                                  // top level menu
                    for (i = 0; i < Game.Stations.Length; i++)
                    {
                        if (Game.PlayerStopsAtStation(i) & Game.Stations[i].Stops.Length > 0)
                        {
                            jump = 1;
                            break;
                        }
                    }
                    Items    = new MenuEntry[4 + jump];
                    Items[0] = new MenuCommand(Translations.GetInterfaceString("menu_resume"), MenuTag.BackToSim, 0);
                    if (jump > 0)
                    {
                        Items[1] = new MenuCommand(Translations.GetInterfaceString("menu_jump"), MenuTag.MenuJumpToStation, 0);
                    }
                    if (!Interface.CurrentOptions.KioskMode)
                    {
                        //Don't allow quitting or customisation of the controls in kiosk mode
                        Items[1 + jump] = new MenuCommand(Translations.GetInterfaceString("menu_exit"), MenuTag.MenuExitToMainMenu, 0);
                        Items[2 + jump] = new MenuCommand(Translations.GetInterfaceString("menu_customize_controls"), MenuTag.MenuControls, 0);
                        Items[3 + jump] = new MenuCommand(Translations.GetInterfaceString("menu_quit"), MenuTag.MenuQuit, 0);
                    }
                    else
                    {
                        Array.Resize(ref Items, Items.Length - 3);
                    }
                    break;

                case MenuType.JumpToStation:                            // list of stations to jump to
                    // count the number of available stations
                    menuItem = 0;
                    for (i = 0; i < Game.Stations.Length; i++)
                    {
                        if (Game.PlayerStopsAtStation(i) & Game.Stations[i].Stops.Length > 0)
                        {
                            menuItem++;
                        }
                    }
                    // list available stations, selecting the next station as predefined choice
                    jump     = 0;                                                   // no jump found yet
                    Items    = new MenuEntry[menuItem + 1];
                    Items[0] = new MenuCommand(Translations.GetInterfaceString("menu_back"), MenuTag.MenuBack, 0);
                    menuItem = 1;
                    for (i = 0; i < Game.Stations.Length; i++)
                    {
                        if (Game.PlayerStopsAtStation(i) & Game.Stations[i].Stops.Length > 0)
                        {
                            Items[menuItem] = new MenuCommand(Game.Stations[i].Name, MenuTag.JumpToStation, i);
                            // if no preferred jump-to-station found yet and this station is
                            // after the last station the user stopped at, select this item
                            if (jump == 0 && i > TrainManager.PlayerTrain.LastStation)
                            {
                                jump      = i;
                                Selection = menuItem;
                            }
                            menuItem++;
                        }
                    }
                    Align = TextAlignment.TopLeft;
                    break;

                case MenuType.ExitToMainMenu:
                    Items     = new MenuEntry[3];
                    Items[0]  = new MenuCaption(Translations.GetInterfaceString("menu_exit_question"));
                    Items[1]  = new MenuCommand(Translations.GetInterfaceString("menu_exit_no"), MenuTag.MenuBack, 0);
                    Items[2]  = new MenuCommand(Translations.GetInterfaceString("menu_exit_yes"), MenuTag.ExitToMainMenu, 0);
                    Selection = 1;
                    break;

                case MenuType.Quit:                                 // ask for quit confirmation
                    Items     = new MenuEntry[3];
                    Items[0]  = new MenuCaption(Translations.GetInterfaceString("menu_quit_question"));
                    Items[1]  = new MenuCommand(Translations.GetInterfaceString("menu_quit_no"), MenuTag.MenuBack, 0);
                    Items[2]  = new MenuCommand(Translations.GetInterfaceString("menu_quit_yes"), MenuTag.Quit, 0);
                    Selection = 1;
                    break;

                case MenuType.Controls:
                    //Refresh the joystick list
                    Program.Joysticks.RefreshJoysticks();
                    Items    = new MenuEntry[Interface.CurrentControls.Length + 1];
                    Items[0] = new MenuCommand(Translations.GetInterfaceString("menu_back"), MenuTag.MenuBack, 0);
                    for (i = 0; i < Interface.CurrentControls.Length; i++)
                    {
                        Items[i + 1] = new MenuCommand(Interface.CurrentControls[i].Command.ToString(), MenuTag.Control, i);
                    }
                    Align = TextAlignment.TopLeft;
                    break;

                case MenuType.Control:
                    //Refresh the joystick list
                    Program.Joysticks.RefreshJoysticks();
                    Selection = SelectionNone;
                    Items     = new MenuEntry[4];
                    // get code name and description
                    Interface.Control loadedControl = Interface.CurrentControls[data];
                    for (int h = 0; h < Translations.CommandInfos.Length; h++)
                    {
                        if (Translations.CommandInfos[h].Command == loadedControl.Command)
                        {
                            Items[0] = new MenuCommand(loadedControl.Command.ToString() + " - " +
                                                       Translations.CommandInfos[h].Description, MenuTag.None, 0);
                            break;
                        }
                    }
                    // get assignment
                    String str = "";
                    switch (loadedControl.Method)
                    {
                    case Interface.ControlMethod.Keyboard:
                        string keyName = loadedControl.Key.ToString();
                        for (int k = 0; k < Translations.TranslatedKeys.Length; k++)
                        {
                            if (Translations.TranslatedKeys[k].Key == loadedControl.Key)
                            {
                                keyName = Translations.TranslatedKeys[k].Description;
                                break;
                            }
                        }
                        if (loadedControl.Modifier != Interface.KeyboardModifier.None)
                        {
                            str = Translations.GetInterfaceString("menu_keyboard") + " [" + loadedControl.Modifier + "-" + keyName + "]";
                        }
                        else
                        {
                            str = Translations.GetInterfaceString("menu_keyboard") + " [" + keyName + "]";
                        }
                        break;

                    case Interface.ControlMethod.Joystick:
                        str = Translations.GetInterfaceString("menu_joystick") + " " + loadedControl.Device + " [" + loadedControl.Component + " " + loadedControl.Element + "]";
                        switch (loadedControl.Component)
                        {
                        case Interface.JoystickComponent.FullAxis:
                        case Interface.JoystickComponent.Axis:
                            str += " " + (loadedControl.Direction == 1 ? Translations.GetInterfaceString("menu_joystickdirection_positive") : Translations.GetInterfaceString("menu_joystickdirection_negative"));
                            break;

                        //						case Interface.JoystickComponent.Button:	// NOTHING TO DO FOR THIS CASE!
                        //							str = str;
                        //							break;
                        case Interface.JoystickComponent.Hat:
                            str += " " + (OpenTK.Input.HatPosition)loadedControl.Direction;
                            break;

                        case Interface.JoystickComponent.Invalid:
                            str = Translations.GetInterfaceString("menu_joystick_notavailable");
                            break;
                        }
                        break;

                    case Interface.ControlMethod.RailDriver:
                        str = "RailDriver [" + loadedControl.Component + " " + loadedControl.Element + "]";
                        switch (loadedControl.Component)
                        {
                        case Interface.JoystickComponent.FullAxis:
                        case Interface.JoystickComponent.Axis:
                            str += " " + (loadedControl.Direction == 1 ? Translations.GetInterfaceString("menu_joystickdirection_positive") : Translations.GetInterfaceString("menu_joystickdirection_negative"));
                            break;

                        case Interface.JoystickComponent.Invalid:
                            str = Translations.GetInterfaceString("menu_joystick_notavailable");
                            break;
                        }
                        break;

                    case Interface.ControlMethod.Invalid:
                        str = Translations.GetInterfaceString("menu_joystick_notavailable");
                        break;
                    }
                    Items[1] = new MenuCommand(Translations.GetInterfaceString("menu_assignment_current") + " " + str, MenuTag.None, 0);
                    Items[2] = new MenuCommand(" ", MenuTag.None, 0);
                    Items[3] = new MenuCommand(Translations.GetInterfaceString("menu_assign"), MenuTag.None, 0);
                    break;
                }

                // compute menu extent
                for (i = 0; i < Items.Length; i++)
                {
                    if (Items[i] == null)
                    {
                        continue;
                    }
                    size = Renderer.MeasureString(Game.Menu.MenuFont, Items[i].Text);
                    if (size.Width > Width)
                    {
                        Width = size.Width;
                    }
                    if (!(Items[i] is MenuCaption) && size.Width > ItemWidth)
                    {
                        ItemWidth = size.Width;
                    }
                }
                Height  = Items.Length * Game.Menu.LineHeight;
                TopItem = 0;
            }
Exemple #8
0
        // create route map
        internal static Bitmap CreateRouteMap(int Width, int Height)
        {
            // find first and last used element based on stations
            int n  = TrackManager.CurrentTrack.Elements.Length;
            int n0 = n - 1;
            int n1 = 0;

            for (int i = 0; i < TrackManager.CurrentTrack.Elements.Length; i++)
            {
                for (int j = 0; j < TrackManager.CurrentTrack.Elements[i].Events.Length; j++)
                {
                    if (TrackManager.CurrentTrack.Elements[i].Events[j] is TrackManager.StationStartEvent)
                    {
                        if (i < n0)
                        {
                            n0 = i;
                        }
                        if (i > n1)
                        {
                            n1 = i;
                        }
                    }
                }
            }
            n0 -= 4;
            n1 += 8;
            if (n0 < 0)
            {
                n0 = 0;
            }
            if (n1 >= TrackManager.CurrentTrack.Elements.Length)
            {
                n1 = TrackManager.CurrentTrack.Elements.Length - 1;
            }
            if (n1 <= n0)
            {
                n1 = n0 + 1;
            }
            // find dimensions
            double x0 = double.PositiveInfinity, z0 = double.PositiveInfinity;
            double x1 = double.NegativeInfinity, z1 = double.NegativeInfinity;

            for (int i = n0; i <= n1; i++)
            {
                double x = TrackManager.CurrentTrack.Elements[i].WorldPosition.X;
                double z = TrackManager.CurrentTrack.Elements[i].WorldPosition.Z;
                if (x < x0)
                {
                    x0 = x;
                }
                if (x > x1)
                {
                    x1 = x;
                }
                if (z < z0)
                {
                    z0 = z;
                }
                if (z > z1)
                {
                    z1 = z;
                }
            }
            if (x0 >= x1 - 1.0)
            {
                x0 = x1 - 1.0;
            }
            if (z0 >= z1 - 1.0)
            {
                z0 = z1 - 1.0;
            }
            double wrh = (double)Width / (double)Height;

            if ((x1 - x0) / (z1 - z0) <= wrh)
            {
                double dx = 0.5 * (z1 - z0) * wrh;
                double px = 0.5 * (x0 + x1);
                x0 = px - dx;
                x1 = px + dx;
            }
            else
            {
                double dz = 0.5 * (x1 - x0) / wrh;
                double pz = 0.5 * (z0 + z1);
                z0 = pz - dz;
                z1 = pz + dz;
            }
            double xd = 1.0 / (x1 - x0);
            double zd = 1.0 / (z1 - z0);
            double ox = 8.0, oy = 8.0;
            double w = (double)(Width - 16);
            double h = (double)(Height - 16);
            // create bitmap
            Bitmap   b = new Bitmap(Width, Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            Graphics g = Graphics.FromImage(b);

            g.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            g.Clear(Color.White);
            // draw route path
            {
                int      start = 0;
                bool     atc   = false;
                PointF[] p     = new PointF[n];
                for (int i = 0; i < n; i++)
                {
                    double x = TrackManager.CurrentTrack.Elements[i].WorldPosition.X;
                    double z = TrackManager.CurrentTrack.Elements[i].WorldPosition.Z;
                    x    = ox + w * (x - x0) * xd;
                    z    = oy + h + h * zd * (z0 - z);
                    p[i] = new PointF((float)x, (float)z);
                    // ats/atc
                    for (int j = 0; j < TrackManager.CurrentTrack.Elements[i].Events.Length; j++)
                    {
                        if (TrackManager.CurrentTrack.Elements[i].Events[j] is TrackManager.StationStartEvent)
                        {
                            TrackManager.StationStartEvent e = (TrackManager.StationStartEvent)TrackManager.CurrentTrack.Elements[i].Events[j];
                            if (Game.Stations[e.StationIndex].SafetySystem == Game.SafetySystem.Atc)
                            {
                                if (!atc)
                                {
                                    atc = true;
                                    if (i - start - 1 > 0)
                                    {
                                        g.DrawCurve(Pens.Black, p, start, i - start - 1);
                                    }
                                    start = i;
                                }
                            }
                            else
                            {
                                if (atc)
                                {
                                    atc = false;
                                    if (i - start - 1 > 0)
                                    {
                                        g.DrawCurve(Pens.DarkRed, p, start, i - start - 1);
                                    }
                                    start = i;
                                }
                            }
                        }
                    }
                }
                DrawSegmentedCurve(g, atc ? Pens.DarkRed : Pens.Black, p, start, n - start - 1);
            }
            // draw station circles
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < TrackManager.CurrentTrack.Elements[i].Events.Length; j++)
                {
                    if (TrackManager.CurrentTrack.Elements[i].Events[j] is TrackManager.StationStartEvent)
                    {
                        TrackManager.StationStartEvent e = (TrackManager.StationStartEvent)TrackManager.CurrentTrack.Elements[i].Events[j];
                        if (Game.Stations[e.StationIndex].Name != string.Empty)
                        {
                            double x = TrackManager.CurrentTrack.Elements[i].WorldPosition.X;
                            double y = TrackManager.CurrentTrack.Elements[i].WorldPosition.Z;
                            x = ox + w * (x - x0) * xd;
                            y = oy + h + h * zd * (z0 - y);
                            // station circle
                            RectangleF r = new RectangleF((float)x - 4.0f, (float)y - 4.0f, 8.0f, 8.0f);
                            bool       q = Game.PlayerStopsAtStation(e.StationIndex);
                            g.FillEllipse(q ? Brushes.SkyBlue : Brushes.LightGray, r);
                            g.DrawEllipse(q ? Pens.Black : Pens.Gray, r);
                        }
                    }
                }
            }
            // draw station names
            {
                double wh = w * h;
                Font   f  = new Font(FontFamily.GenericSansSerif, wh < 65536.0 ? 9.0f : 10.0f, GraphicsUnit.Pixel);
                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < TrackManager.CurrentTrack.Elements[i].Events.Length; j++)
                    {
                        if (TrackManager.CurrentTrack.Elements[i].Events[j] is TrackManager.StationStartEvent)
                        {
                            TrackManager.StationStartEvent e = (TrackManager.StationStartEvent)TrackManager.CurrentTrack.Elements[i].Events[j];
                            if (Game.Stations[e.StationIndex].Name != string.Empty)
                            {
                                double x = TrackManager.CurrentTrack.Elements[i].WorldPosition.X;
                                double y = TrackManager.CurrentTrack.Elements[i].WorldPosition.Z;
                                x = ox + w * (x - x0) * xd;
                                y = oy + h + h * zd * (z0 - y);
                                RectangleF r = new RectangleF((float)x - 4.0f, (float)y - 4.0f, 8.0f, 8.0f);
                                bool       stop = Game.PlayerStopsAtStation(e.StationIndex);
                                string     t = Game.Stations[e.StationIndex].Name;
                                SizeF      m = g.MeasureString(t, f, Width, StringFormat.GenericDefault);
                                double     sx = TrackManager.CurrentTrack.Elements[i].WorldSide.X;
                                double     sz = TrackManager.CurrentTrack.Elements[i].WorldSide.Z;
                                double     xt, yt;
                                if (Math.Sign(sx) == Math.Sign(sz))
                                {
                                    // descending
                                    bool o = (x - ox) * (h - y) <= (w - x) * (y - oy);
                                    if (o)
                                    {
                                        // up-right
                                        xt = x + 6.0;
                                        yt = y - 6.0 - m.Height;
                                    }
                                    else
                                    {
                                        // down-left
                                        xt = x - 6.0 - m.Width;
                                        yt = y + 6.0;
                                    }
                                }
                                else
                                {
                                    // ascending
                                    bool o = (h - y) * (w - x) <= (x - ox) * (y - oy);
                                    if (o)
                                    {
                                        // up-left
                                        xt = x - 6.0 - m.Width;
                                        yt = y - 6.0 - m.Height;
                                    }
                                    else
                                    {
                                        // down-right
                                        xt = x + 6.0;
                                        yt = y + 6.0;
                                    }
                                }
                                if (xt < ox)
                                {
                                    xt = ox;
                                }
                                else if (xt + m.Width > w)
                                {
                                    xt = w - m.Width;
                                }
                                if (yt < oy)
                                {
                                    yt = oy;
                                }
                                else if (yt + m.Height > h)
                                {
                                    yt = h - m.Height;
                                }
                                r = new RectangleF((float)xt, (float)yt, m.Width, m.Height);
                                g.FillRectangle(stop ? Brushes.White : Brushes.LightGray, r.Left - 1.0f, r.Top - 1.0f, r.Width + 2.0f, r.Height + 2.0f);
                                g.DrawRectangle(stop ? Pens.Black : Pens.Gray, r.Left - 1.0f, r.Top - 1.0f, r.Width + 2.0f, r.Height + 2.0f);
                                g.DrawString(t, f, stop ? Brushes.Black : Brushes.Gray, (float)xt, (float)yt);
                            }
                        }
                    }
                }
            }
            // finalize
            return(b);
        }
Exemple #9
0
        // create route gradient profile
        internal static Bitmap CreateRouteGradientProfile(int Width, int Height)
        {
            // find first and last used element based on stations
            int n  = TrackManager.CurrentTrack.Elements.Length;
            int n0 = n - 1;
            int n1 = 0;

            for (int i = 0; i < TrackManager.CurrentTrack.Elements.Length; i++)
            {
                for (int j = 0; j < TrackManager.CurrentTrack.Elements[i].Events.Length; j++)
                {
                    if (TrackManager.CurrentTrack.Elements[i].Events[j] is TrackManager.StationStartEvent)
                    {
                        if (i < n0)
                        {
                            n0 = i;
                        }
                        if (i > n1)
                        {
                            n1 = i;
                        }
                    }
                }
            }
            n0 -= 4;
            n1 += 8;
            if (n0 < 0)
            {
                n0 = 0;
            }
            if (n1 >= TrackManager.CurrentTrack.Elements.Length)
            {
                n1 = TrackManager.CurrentTrack.Elements.Length - 1;
            }
            if (n1 <= n0)
            {
                n1 = n0 + 1;
            }
            // find dimensions
            double y0 = double.PositiveInfinity, y1 = double.NegativeInfinity;

            for (int i = n0; i <= n1; i++)
            {
                double y = TrackManager.CurrentTrack.Elements[i].WorldPosition.Y;
                if (y < y0)
                {
                    y0 = y;
                }
                if (y > y1)
                {
                    y1 = y;
                }
            }
            if (y0 >= y1 - 1.0)
            {
                y0 = y1 - 1.0;
            }
            double nd = 1.0 / (double)(n1 - n0);
            double yd = 1.0 / (double)(y1 - y0);
            double ox = 8.0, oy = 8.0;
            double w = (double)(Width - 16);
            double h = (double)(Height - 32);
            // create bitmap
            Bitmap   b = new Bitmap(Width, Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            Graphics g = Graphics.FromImage(b);

            g.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            g.Clear(Color.White);
            // draw below sea level
            {
                double y  = oy + h * (1.0 - 0.5 * (double)(-Game.RouteInitialElevation - y0) * yd);
                double x0 = ox - w * (double)(n0) * nd;
                double x1 = ox + w * (double)(n - n0) * nd;
                g.FillRectangle(Brushes.PaleGoldenrod, (float)x0, (float)y, (float)x1, (float)(oy + h) - (float)y);
                g.DrawLine(Pens.Gray, (float)x0, (float)y, (float)x1, (float)y);
            }
            // draw route path
            {
                PointF[] p = new PointF[n + 2];
                p[0] = new PointF((float)(ox - w * (double)n0 * nd), (float)(oy + h));
                for (int i = 0; i < n; i++)
                {
                    double x = ox + w * (double)(i - n0) * nd;
                    double y = oy + h * (1.0 - 0.5 * (double)(TrackManager.CurrentTrack.Elements[i].WorldPosition.Y - y0) * yd);
                    p[i + 1] = new PointF((float)x, (float)y);
                }
                p[n + 1] = new PointF((float)(ox + w * (double)(n - n0 - 1) * nd), (float)(oy + h));
                g.FillPolygon(Brushes.Tan, p);
                for (int i = 1; i < n; i++)
                {
                    g.DrawLine(Pens.Black, p[i], p[i + 1]);
                }
                g.DrawLine(Pens.Black, 0.0f, (float)(oy + h), (float)Width, (float)(oy + h));
            }
            // draw station names
            {
                Font         f = new Font(FontFamily.GenericSansSerif, 12.0f, GraphicsUnit.Pixel);
                StringFormat m = new StringFormat();
                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < TrackManager.CurrentTrack.Elements[i].Events.Length; j++)
                    {
                        if (TrackManager.CurrentTrack.Elements[i].Events[j] is TrackManager.StationStartEvent)
                        {
                            TrackManager.StationStartEvent e = (TrackManager.StationStartEvent)TrackManager.CurrentTrack.Elements[i].Events[j];
                            if (Game.Stations[e.StationIndex].Name != string.Empty)
                            {
                                bool stop = Game.PlayerStopsAtStation(e.StationIndex);
                                if (Interface.IsJapanese(Game.Stations[e.StationIndex].Name))
                                {
                                    m.Alignment     = StringAlignment.Near;
                                    m.LineAlignment = StringAlignment.Near;
                                    double x = ox + w * (double)(i - n0) * nd;
                                    double y = oy + h * (1.0 - 0.5 * (double)(TrackManager.CurrentTrack.Elements[i].WorldPosition.Y - y0) * yd);
                                    string t = Game.Stations[e.StationIndex].Name;
                                    float  tx = 0.0f, ty = (float)oy;
                                    for (int k = 0; k < t.Length; k++)
                                    {
                                        SizeF s = g.MeasureString(t.Substring(k, 1), f, 65536, StringFormat.GenericTypographic);
                                        if (s.Width > tx)
                                        {
                                            tx = s.Width;
                                        }
                                    }
                                    for (int k = 0; k < t.Length; k++)
                                    {
                                        g.DrawString(t.Substring(k, 1), f, stop ? Brushes.Black : Brushes.LightGray, (float)x - 0.5f * tx, ty);
                                        SizeF s = g.MeasureString(t.Substring(k, 1), f, 65536, StringFormat.GenericTypographic);
                                        ty += s.Height;
                                    }
                                    g.DrawLine(stop ? Pens.Gray : Pens.LightGray, new PointF((float)x, ty + 4.0f), new PointF((float)x, (float)y));
                                }
                                else
                                {
                                    m.Alignment     = StringAlignment.Far;
                                    m.LineAlignment = StringAlignment.Near;
                                    double x = ox + w * (double)(i - n0) * nd;
                                    double y = oy + h * (1.0 - 0.5 * (double)(TrackManager.CurrentTrack.Elements[i].WorldPosition.Y - y0) * yd);
                                    g.RotateTransform(-90.0f);
                                    g.TranslateTransform((float)x, (float)oy, System.Drawing.Drawing2D.MatrixOrder.Append);
                                    g.DrawString(Game.Stations[e.StationIndex].Name, f, stop ? Brushes.Black : Brushes.LightGray, new PointF(0.0f, -5.0f), m);
                                    g.ResetTransform();
                                    SizeF s = g.MeasureString(Game.Stations[e.StationIndex].Name, f);
                                    g.DrawLine(stop ? Pens.Gray : Pens.LightGray, new PointF((float)x, (float)(oy + s.Width + 4)), new PointF((float)x, (float)y));
                                }
                            }
                        }
                    }
                }
            }
            // draw route markers
            {
                Font         f  = new Font(FontFamily.GenericSansSerif, 10.0f, GraphicsUnit.Pixel);
                Font         fs = new Font(FontFamily.GenericSansSerif, 9.0f, GraphicsUnit.Pixel);
                StringFormat m  = new StringFormat();
                m.Alignment     = StringAlignment.Far;
                m.LineAlignment = StringAlignment.Center;
                System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
                int k = 48 * n / Width;
                for (int i = 0; i < n; i += k)
                {
                    double x = ox + w * (double)(i - n0) * nd;
                    double y = (double)(TrackManager.CurrentTrack.Elements[i].WorldPosition.Y - y0) * yd;
                    if (x < w)
                    {
                        string t = ((int)Math.Round(TrackManager.CurrentTrack.Elements[i].StartingTrackPosition)).ToString(Culture);
                        g.DrawString(t + "m", f, Brushes.Black, (float)x, (float)(oy + h + 6.0));
                    }
                    {
                        y = oy + h * (1.0 - 0.5 * y) + 2.0f;
                        string t = ((int)Math.Round(Game.RouteInitialElevation + TrackManager.CurrentTrack.Elements[i].WorldPosition.Y)).ToString(Culture);
                        SizeF  s = g.MeasureString(t, fs);
                        if (y < oy + h - (double)s.Width - 10.0)
                        {
                            g.RotateTransform(-90.0f);
                            g.TranslateTransform((float)x, (float)y + 4.0f, System.Drawing.Drawing2D.MatrixOrder.Append);
                            g.DrawString(t + "m", fs, Brushes.Black, 0.0f, 0.0f, m);
                            g.ResetTransform();
                            g.DrawLine(Pens.Gray, (float)x, (float)(y + s.Width + 12.0), (float)x, (float)(oy + h));
                        }
                    }
                }
            }
            // finalize
            return(b);
        }
Exemple #10
0
        /// <summary>This method is called once the route and train data have been preprocessed, in order to physically setup the simulation</summary>
        private void SetupSimulation()
        {
            if (Loading.Cancel)
            {
                Close();
            }
            Timetable.CreateTimetable();
            //Check if any critical errors have occured during the route or train loading
            for (int i = 0; i < Interface.MessageCount; i++)
            {
                if (Interface.Messages[i].Type == Interface.MessageType.Critical)
                {
                    MessageBox.Show("A critical error has occured:\n\n" + Interface.Messages[i].Text + "\n\nPlease inspect the error log file for further information.", "Load", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                    Close();
                }
            }
            Renderer.InitializeLighting();
            Game.LogRouteName = System.IO.Path.GetFileName(MainLoop.currentResult.RouteFile);
            Game.LogTrainName = System.IO.Path.GetFileName(MainLoop.currentResult.TrainFolder);
            Game.LogDateTime  = DateTime.Now;

            if (Interface.CurrentOptions.LoadInAdvance)
            {
                Textures.LoadAllTextures();
            }
            else
            {
                Textures.UnloadAllTextures();
            }
            // camera
            ObjectManager.InitializeVisibility();
            TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, 0.0, true, false);
            TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, -0.1, true, false);
            TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, 0.1, true, false);
            World.CameraTrackFollower.TriggerType = TrackManager.EventTriggerType.Camera;
            // starting time and track position
            Game.SecondsSinceMidnight = 0.0;
            Game.StartupTime          = 0.0;
            int    PlayerFirstStationIndex    = -1;
            double PlayerFirstStationPosition = 0.0;

            for (int i = 0; i < Game.Stations.Length; i++)
            {
                if (Game.Stations[i].StopMode == Game.StationStopMode.AllStop | Game.Stations[i].StopMode == Game.StationStopMode.PlayerStop & Game.Stations[i].Stops.Length != 0)
                {
                    PlayerFirstStationIndex = i;
                    int s = Game.GetStopIndex(i, TrainManager.PlayerTrain.Cars.Length);
                    if (s >= 0)
                    {
                        PlayerFirstStationPosition = Game.Stations[i].Stops[s].TrackPosition;

                        double TrainLength = 0.0;
                        for (int c = 0; c < TrainManager.Trains[TrainManager.PlayerTrain.TrainIndex].Cars.Length; c++)
                        {
                            TrainLength += TrainManager.Trains[TrainManager.PlayerTrain.TrainIndex].Cars[c].Length;
                        }

                        for (int j = 0; j < Game.BufferTrackPositions.Length; j++)
                        {
                            if (PlayerFirstStationPosition > Game.BufferTrackPositions[j] && PlayerFirstStationPosition - TrainLength < Game.BufferTrackPositions[j])
                            {
                                /*
                                 * HACK: The initial start position for the player train is stuck on a set of buffers
                                 * This means we have to make some one the fly adjustments to the first station stop position
                                 */

                                //Set the start position to be the buffer position plus the train length plus 1m
                                PlayerFirstStationPosition = Game.BufferTrackPositions[j] + TrainLength + 1;
                                //Update the station stop location
                                if (s >= 0)
                                {
                                    Game.Stations[PlayerFirstStationIndex].Stops[s].TrackPosition = PlayerFirstStationPosition;
                                }
                                else
                                {
                                    Game.Stations[PlayerFirstStationIndex].DefaultTrackPosition = PlayerFirstStationPosition;
                                }
                                break;
                            }
                        }
                    }
                    else
                    {
                        PlayerFirstStationPosition = Game.Stations[i].DefaultTrackPosition;
                    }
                    if (Game.Stations[i].ArrivalTime < 0.0)
                    {
                        if (Game.Stations[i].DepartureTime < 0.0)
                        {
                            Game.SecondsSinceMidnight = 0.0;
                            Game.StartupTime          = 0.0;
                        }
                        else
                        {
                            Game.SecondsSinceMidnight = Game.Stations[i].DepartureTime - Game.Stations[i].StopTime;
                            Game.StartupTime          = Game.Stations[i].DepartureTime - Game.Stations[i].StopTime;
                        }
                    }
                    else
                    {
                        Game.SecondsSinceMidnight = Game.Stations[i].ArrivalTime;
                        Game.StartupTime          = Game.Stations[i].ArrivalTime;
                    }
                    break;
                }
            }
            int    OtherFirstStationIndex    = -1;
            double OtherFirstStationPosition = 0.0;
            double OtherFirstStationTime     = 0.0;

            for (int i = 0; i < Game.Stations.Length; i++)
            {
                if (Game.Stations[i].StopMode == Game.StationStopMode.AllStop | Game.Stations[i].StopMode == Game.StationStopMode.PlayerPass & Game.Stations[i].Stops.Length != 0)
                {
                    OtherFirstStationIndex = i;
                    int s = Game.GetStopIndex(i, TrainManager.PlayerTrain.Cars.Length);
                    if (s >= 0)
                    {
                        OtherFirstStationPosition = Game.Stations[i].Stops[s].TrackPosition;
                    }
                    else
                    {
                        OtherFirstStationPosition = Game.Stations[i].DefaultTrackPosition;
                    }
                    if (Game.Stations[i].ArrivalTime < 0.0)
                    {
                        if (Game.Stations[i].DepartureTime < 0.0)
                        {
                            OtherFirstStationTime = 0.0;
                        }
                        else
                        {
                            OtherFirstStationTime = Game.Stations[i].DepartureTime - Game.Stations[i].StopTime;
                        }
                    }
                    else
                    {
                        OtherFirstStationTime = Game.Stations[i].ArrivalTime;
                    }
                    break;
                }
            }
            if (Game.PrecedingTrainTimeDeltas.Length != 0)
            {
                OtherFirstStationTime -= Game.PrecedingTrainTimeDeltas[Game.PrecedingTrainTimeDeltas.Length - 1];
                if (OtherFirstStationTime < Game.SecondsSinceMidnight)
                {
                    Game.SecondsSinceMidnight = OtherFirstStationTime;
                }
            }
            // initialize trains
            for (int i = 0; i < TrainManager.Trains.Length; i++)
            {
                TrainManager.InitializeTrain(TrainManager.Trains[i]);
                int s = i == TrainManager.PlayerTrain.TrainIndex ? PlayerFirstStationIndex : OtherFirstStationIndex;
                if (s >= 0)
                {
                    if (Game.Stations[s].OpenLeftDoors)
                    {
                        for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++)
                        {
                            TrainManager.Trains[i].Cars[j].Specs.AnticipatedLeftDoorsOpened = true;
                        }
                    }
                    if (Game.Stations[s].OpenRightDoors)
                    {
                        for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++)
                        {
                            TrainManager.Trains[i].Cars[j].Specs.AnticipatedRightDoorsOpened = true;
                        }
                    }
                }
                if (Game.Sections.Length != 0)
                {
                    Game.Sections[0].Enter(TrainManager.Trains[i]);
                }
                for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++)
                {
                    double length = TrainManager.Trains[i].Cars[0].Length;
                    TrainManager.MoveCar(TrainManager.Trains[i], j, -length, 0.01);
                    TrainManager.MoveCar(TrainManager.Trains[i], j, length, 0.01);
                }
            }
            // score
            Game.CurrentScore.ArrivalStation   = PlayerFirstStationIndex + 1;
            Game.CurrentScore.DepartureStation = PlayerFirstStationIndex;
            Game.CurrentScore.Maximum          = 0;
            for (int i = 0; i < Game.Stations.Length; i++)
            {
                if (i != PlayerFirstStationIndex & Game.PlayerStopsAtStation(i))
                {
                    if (i == 0 || Game.Stations[i - 1].StationType != Game.StationType.ChangeEnds)
                    {
                        Game.CurrentScore.Maximum += Game.ScoreValueStationArrival;
                    }
                }
            }
            if (Game.CurrentScore.Maximum <= 0)
            {
                Game.CurrentScore.Maximum = Game.ScoreValueStationArrival;
            }
            // signals
            if (Game.Sections.Length > 0)
            {
                Game.UpdateSection(Game.Sections.Length - 1);
            }
            // move train in position
            for (int i = 0; i < TrainManager.Trains.Length; i++)
            {
                double p;
                if (i == TrainManager.PlayerTrain.TrainIndex)
                {
                    p = PlayerFirstStationPosition;
                }
                else if (TrainManager.Trains[i].State == TrainManager.TrainState.Bogus)
                {
                    p = Game.BogusPretrainInstructions[0].TrackPosition;
                    TrainManager.Trains[i].AI = new Game.BogusPretrainAI(TrainManager.Trains[i]);
                }
                else
                {
                    p = OtherFirstStationPosition;
                }
                for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++)
                {
                    TrainManager.MoveCar(TrainManager.Trains[i], j, p, 0.01);
                }
            }
            // timetable
            if (Timetable.DefaultTimetableDescription.Length == 0)
            {
                Timetable.DefaultTimetableDescription = Game.LogTrainName;
            }

            // initialize camera
            if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable)
            {
                World.CameraMode = World.CameraViewMode.InteriorLookAhead;
            }
            //Place the initial camera in the driver car
            TrainManager.UpdateCamera(TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar);
            TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, -1.0, true, false);
            ObjectManager.UpdateVisibility(World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z);
            World.CameraSavedInterior = new World.CameraAlignment();
            World.CameraSavedExterior = new World.CameraAlignment(new OpenBveApi.Math.Vector3(-2.5, 1.5, -15.0), 0.3, -0.2, 0.0, PlayerFirstStationPosition, 1.0);
            World.CameraSavedTrack    = new World.CameraAlignment(new OpenBveApi.Math.Vector3(-3.0, 2.5, 0.0), 0.3, 0.0, 0.0, TrainManager.PlayerTrain.Cars[0].FrontAxle.Follower.TrackPosition - 10.0, 1.0);
            // signalling sections
            for (int i = 0; i < TrainManager.Trains.Length; i++)
            {
                int s = TrainManager.Trains[i].CurrentSectionIndex;
                Game.Sections[s].Enter(TrainManager.Trains[i]);
            }
            if (Game.Sections.Length > 0)
            {
                Game.UpdateSection(Game.Sections.Length - 1);
            }
            // fast-forward until start time
            {
                Game.MinimalisticSimulation = true;
                const double w = 0.25;
                double       u = Game.StartupTime - Game.SecondsSinceMidnight;
                if (u > 0)
                {
                    while (true)
                    {
                        double v = u < w ? u : w; u -= v;
                        Game.SecondsSinceMidnight += v;
                        TrainManager.UpdateTrains(v);
                        if (u <= 0.0)
                        {
                            break;
                        }
                        TotalTimeElapsedForSectionUpdate += v;
                        if (TotalTimeElapsedForSectionUpdate >= 1.0)
                        {
                            if (Game.Sections.Length > 0)
                            {
                                Game.UpdateSection(Game.Sections.Length - 1);
                            }
                            TotalTimeElapsedForSectionUpdate = 0.0;
                        }
                    }
                }
                Game.MinimalisticSimulation = false;
            }
            // animated objects
            ObjectManager.UpdateAnimatedWorldObjects(0.0, true);
            TrainManager.UpdateTrainObjects(0.0, true);
            // timetable
            if (TrainManager.PlayerTrain.Station >= 0)
            {
                Timetable.UpdateCustomTimetable(Game.Stations[TrainManager.PlayerTrain.Station].TimetableDaytimeTexture, Game.Stations[TrainManager.PlayerTrain.Station].TimetableNighttimeTexture);
                if (Timetable.CustomObjectsUsed != 0 & Timetable.CustomTimetableAvailable && Interface.CurrentOptions.TimeTableStyle != Interface.TimeTableMode.AutoGenerated && Interface.CurrentOptions.TimeTableStyle != Interface.TimeTableMode.None)
                {
                    Timetable.CurrentTimetable = Timetable.TimetableState.Custom;
                }
            }

            // warnings / errors
            if (Interface.MessageCount != 0)
            {
                int filesNotFound = 0;
                int errors        = 0;
                int warnings      = 0;
                for (int i = 0; i < Interface.MessageCount; i++)
                {
                    if (Interface.Messages[i].FileNotFound)
                    {
                        filesNotFound++;
                    }
                    else if (Interface.Messages[i].Type == Interface.MessageType.Error)
                    {
                        errors++;
                    }
                    else if (Interface.Messages[i].Type == Interface.MessageType.Warning)
                    {
                        warnings++;
                    }
                }
                string NotFound = null;
                string Messages = null;
                if (filesNotFound != 0)
                {
                    NotFound = filesNotFound.ToString() + " file(s) not found";
                    Game.AddDebugMessage(NotFound, 10.0);
                }
                if (errors != 0 & warnings != 0)
                {
                    Messages = errors.ToString() + " error(s), " + warnings.ToString() + " warning(s)";
                    Game.AddDebugMessage(Messages, 10.0);
                }
                else if (errors != 0)
                {
                    Messages = errors.ToString() + " error(s)";
                    Game.AddDebugMessage(Messages, 10.0);
                }
                else
                {
                    Messages = warnings.ToString() + " warning(s)";
                    Game.AddDebugMessage(Messages, 10.0);
                }
                Game.RouteInformation.FilesNotFound     = NotFound;
                Game.RouteInformation.ErrorsAndWarnings = Messages;
                //Print the plugin error encountered (If any) for 10s
                //This must be done after the simulation has init, as otherwise the timeout doesn't work
                if (Loading.PluginError != null)
                {
                    Game.AddMessage(Loading.PluginError, Game.MessageDependency.None, Interface.GameMode.Expert, OpenBveApi.Colors.MessageColor.Red, Game.SecondsSinceMidnight + 5.0);
                    Game.AddMessage(Interface.GetInterfaceString("errors_plugin_failure2"), Game.MessageDependency.None, Interface.GameMode.Expert, OpenBveApi.Colors.MessageColor.Red, Game.SecondsSinceMidnight + 5.0);
                }
            }
            loadComplete          = true;
            RenderRealTimeElapsed = 0.0;
            RenderTimeElapsed     = 0.0;
            World.InitializeCameraRestriction();
        }