AddMessage() static private method

Adds a message to the in-game interface render queue
static private AddMessage ( string Text, MessageDependency Depencency, Interface Mode, MessageColor Color, double Timeout ) : void
Text string The text of the message
Depencency MessageDependency
Mode Interface
Color MessageColor The color of the message text
Timeout double The time this message will display for
return void
示例#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);
             }
         }
     }
 }
示例#2
0
 /// <inheritdoc/>
 public override void SectionChange()
 {
     if (CurrentSectionLimit == 0.0 && Game.MinimalisticSimulation == false)
     {
         Game.AddMessage(Translations.GetInterfaceString("message_signal_stop"), MessageDependency.PassedRedSignal, GameMode.Normal, MessageColor.Red, double.PositiveInfinity, null);
     }
     else if (CurrentSpeed > CurrentSectionLimit)
     {
         Game.AddMessage(Translations.GetInterfaceString("message_signal_overspeed"), MessageDependency.SectionLimit, GameMode.Normal, MessageColor.Orange, double.PositiveInfinity, null);
     }
 }
示例#3
0
            public override void Trigger(int Direction, EventTriggerType TriggerType, TrainManager.Train Train, AbstractCar Car)
            {
                if (TriggerType == EventTriggerType.FrontCarFrontAxle)
                {
                    if (Direction > 0)
                    {
                        if (Train.IsPlayerTrain)
                        {
                            Timetable.UpdateCustomTimetable(CurrentRoute.Stations[this.StationIndex].TimetableDaytimeTexture, CurrentRoute.Stations[this.StationIndex].TimetableNighttimeTexture);
                        }
                    }
                }
                else if (TriggerType == EventTriggerType.RearCarRearAxle)
                {
                    if (Direction < 0)
                    {
                        Train.Station = this.StationIndex;
                        if (Train.NextStopSkipped != StopSkipMode.None)
                        {
                            Train.LastStation = this.StationIndex;
                        }
                        Train.NextStopSkipped = StopSkipMode.None;
                    }
                    else if (Direction > 0)
                    {
                        if (Train.Station == StationIndex)
                        {
                            if (Train.IsPlayerTrain)
                            {
                                if (CurrentRoute.Stations[StationIndex].PlayerStops() & TrainManager.PlayerTrain.StationState == TrainStopState.Pending)
                                {
                                    string s = Translations.GetInterfaceString("message_station_passed");
                                    s = s.Replace("[name]", CurrentRoute.Stations[StationIndex].Name);
                                    Game.AddMessage(s, MessageDependency.None, GameMode.Normal, MessageColor.Orange, Game.SecondsSinceMidnight + 10.0, null);
                                }
                                else if (CurrentRoute.Stations[StationIndex].PlayerStops() & TrainManager.PlayerTrain.StationState == TrainStopState.Boarding)
                                {
                                    string s = Translations.GetInterfaceString("message_station_passed_boarding");
                                    s = s.Replace("[name]", CurrentRoute.Stations[StationIndex].Name);
                                    Game.AddMessage(s, MessageDependency.None, GameMode.Normal, MessageColor.Red, Game.SecondsSinceMidnight + 10.0, null);
                                }
                            }
                            Train.Station = -1;
                            if (Train.StationState != TrainStopState.Jumping)
                            {
                                Train.StationState = TrainStopState.Pending;
                            }

                            int d = Train.DriverCar;
                            Program.Sounds.StopSound(Train.Cars[d].Sounds.Halt);
                        }
                    }
                }
            }
示例#4
0
 private void UpdateFrontForward(TrainManager.Train Train, bool UpdateTrain, bool UpdateSection)
 {
     if (UpdateTrain)
     {
         // update train
         if (this.NextSectionIndex >= 0)
         {
             if (!Game.Sections[this.NextSectionIndex].Invisible)
             {
                 if (Game.Sections[this.NextSectionIndex].CurrentAspect >= 0)
                 {
                     Train.CurrentSectionLimit = Game.Sections[this.NextSectionIndex].Aspects[Game.Sections[this.NextSectionIndex].CurrentAspect].Speed;
                 }
                 else
                 {
                     Train.CurrentSectionLimit = double.PositiveInfinity;
                 }
                 Train.CurrentSectionIndex = this.NextSectionIndex;
             }
         }
         else
         {
             Train.CurrentSectionLimit = double.PositiveInfinity;
             Train.CurrentSectionIndex = -1;
         }
         // messages
         if (this.NextSectionIndex < 0 || !Game.Sections[this.NextSectionIndex].Invisible)
         {
             if (Train.CurrentSectionLimit == 0.0 && Game.MinimalisticSimulation == false)
             {
                 Game.AddMessage(Interface.GetInterfaceString("message_signal_stop"), MessageManager.MessageDependency.PassedRedSignal, Interface.GameMode.Normal, MessageColor.Red, double.PositiveInfinity, null);
             }
             else if (Train.Specs.CurrentAverageSpeed > Train.CurrentSectionLimit)
             {
                 Game.AddMessage(Interface.GetInterfaceString("message_signal_overspeed"), MessageManager.MessageDependency.SectionLimit, Interface.GameMode.Normal, MessageColor.Orange, double.PositiveInfinity, null);
             }
         }
     }
     if (UpdateSection)
     {
         // update sections
         if (this.NextSectionIndex >= 0)
         {
             Game.Sections[this.NextSectionIndex].Enter(Train);
             Game.UpdateSection(this.NextSectionIndex);
         }
     }
 }
示例#5
0
            /// <inheritdoc/>
            public override void LeaveStation(int stationIndex, int direction)
            {
                if (direction < 0)
                {
                    Station = stationIndex;
                    if (NextStopSkipped != StopSkipMode.None)
                    {
                        LastStation = stationIndex;
                    }
                    NextStopSkipped = StopSkipMode.None;
                }
                else if (direction > 0)
                {
                    if (Station == stationIndex)
                    {
                        if (this.IsPlayerTrain)
                        {
                            if (Program.CurrentRoute.Stations[stationIndex].PlayerStops() & TrainManager.PlayerTrain.StationState == TrainStopState.Pending)
                            {
                                string s = Translations.GetInterfaceString("message_station_passed");
                                s = s.Replace("[name]", Program.CurrentRoute.Stations[stationIndex].Name);
                                Game.AddMessage(s, MessageDependency.None, GameMode.Normal, MessageColor.Orange, Program.CurrentRoute.SecondsSinceMidnight + 10.0, null);
                            }
                            else if (Program.CurrentRoute.Stations[stationIndex].PlayerStops() & TrainManager.PlayerTrain.StationState == TrainStopState.Boarding)
                            {
                                string s = Translations.GetInterfaceString("message_station_passed_boarding");
                                s = s.Replace("[name]", Program.CurrentRoute.Stations[stationIndex].Name);
                                Game.AddMessage(s, MessageDependency.None, GameMode.Normal, MessageColor.Red, Program.CurrentRoute.SecondsSinceMidnight + 10.0, null);
                            }
                        }
                        Station = -1;
                        if (StationState != TrainStopState.Jumping)
                        {
                            StationState = TrainStopState.Pending;
                        }

                        SafetySystems.PassAlarm.Halt();
                    }
                }
            }
示例#6
0
 internal override void Trigger(int Direction, EventTriggerType TriggerType, TrainManager.Train Train, int CarIndex)
 {
     if (Train == null)
     {
         return;
     }
     if (Train.RouteLimits == null)
     {
         Train.RouteLimits = new double[] { };
     }
     if (Direction < 0)
     {
         if (TriggerType == EventTriggerType.FrontCarFrontAxle)
         {
             int n = Train.RouteLimits.Length;
             if (n > 0)
             {
                 Array.Resize <double>(ref Train.RouteLimits, n - 1);
                 Train.CurrentRouteLimit = double.PositiveInfinity;
                 for (int i = 0; i < n - 1; i++)
                 {
                     if (Train.RouteLimits[i] < Train.CurrentRouteLimit)
                     {
                         Train.CurrentRouteLimit = Train.RouteLimits[i];
                     }
                 }
             }
         }
         else if (TriggerType == EventTriggerType.RearCarRearAxle)
         {
             int n = Train.RouteLimits.Length;
             Array.Resize <double>(ref Train.RouteLimits, n + 1);
             for (int i = n; i > 0; i--)
             {
                 Train.RouteLimits[i] = Train.RouteLimits[i - 1];
             }
             Train.RouteLimits[0] = this.PreviousSpeedLimit;
         }
     }
     else if (Direction > 0)
     {
         if (TriggerType == EventTriggerType.FrontCarFrontAxle)
         {
             int n = Train.RouteLimits.Length;
             Array.Resize <double>(ref Train.RouteLimits, n + 1);
             Train.RouteLimits[n] = this.NextSpeedLimit;
             if (this.NextSpeedLimit < Train.CurrentRouteLimit)
             {
                 Train.CurrentRouteLimit = this.NextSpeedLimit;
             }
             if (Train.Specs.CurrentAverageSpeed > this.NextSpeedLimit)
             {
                 Game.AddMessage(Translations.GetInterfaceString("message_route_overspeed"), MessageManager.MessageDependency.RouteLimit, Interface.GameMode.Normal, MessageColor.Orange, double.PositiveInfinity, null);
             }
         }
         else if (TriggerType == EventTriggerType.RearCarRearAxle)
         {
             int n = Train.RouteLimits.Length;
             if (n > 0)
             {
                 Train.CurrentRouteLimit = double.PositiveInfinity;
                 for (int i = 0; i < n - 1; i++)
                 {
                     Train.RouteLimits[i] = Train.RouteLimits[i + 1];
                     if (Train.RouteLimits[i] < Train.CurrentRouteLimit)
                     {
                         Train.CurrentRouteLimit = Train.RouteLimits[i];
                     }
                 }
                 Array.Resize <double>(ref Train.RouteLimits, n - 1);
             }
         }
     }
 }
示例#7
0
        /// <summary>Moves the camera to a point of interest</summary>
        /// <param name="Value">The value of the jump to perform:
        /// -1= Previous POI
        ///  0= Return to currently selected POI (From cab etc.)
        ///  1= Next POI</param>
        /// <param name="Relative">Whether the relative camera position should be retained</param>
        /// <returns>False if the previous / next POI would be outside those defined, true otherwise</returns>
        internal static bool ApplyPointOfInterest(int Value, bool Relative)
        {
            double t = 0.0;
            int    j = -1;

            if (Relative)
            {
                // relative
                if (Value < 0)
                {
                    // previous poi
                    t = double.NegativeInfinity;
                    for (int i = 0; i < PointsOfInterest.Length; i++)
                    {
                        if (PointsOfInterest[i].TrackPosition < World.CameraTrackFollower.TrackPosition)
                        {
                            if (PointsOfInterest[i].TrackPosition > t)
                            {
                                t = PointsOfInterest[i].TrackPosition;
                                j = i;
                            }
                        }
                    }
                }
                else if (Value > 0)
                {
                    // next poi
                    t = double.PositiveInfinity;
                    for (int i = 0; i < PointsOfInterest.Length; i++)
                    {
                        if (PointsOfInterest[i].TrackPosition > World.CameraTrackFollower.TrackPosition)
                        {
                            if (PointsOfInterest[i].TrackPosition < t)
                            {
                                t = PointsOfInterest[i].TrackPosition;
                                j = i;
                            }
                        }
                    }
                }
            }
            else
            {
                // absolute
                j = Value >= 0 & Value < PointsOfInterest.Length ? Value : -1;
            }
            // process poi
            if (j < 0)
            {
                return(false);
            }
            TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, t, true, false);
            World.CameraCurrentAlignment.Position      = PointsOfInterest[j].TrackOffset;
            World.CameraCurrentAlignment.Yaw           = PointsOfInterest[j].TrackYaw;
            World.CameraCurrentAlignment.Pitch         = PointsOfInterest[j].TrackPitch;
            World.CameraCurrentAlignment.Roll          = PointsOfInterest[j].TrackRoll;
            World.CameraCurrentAlignment.TrackPosition = t;
            World.UpdateAbsoluteCamera(0.0);
            if (PointsOfInterest[j].Text != null)
            {
                double n = 3.0 + 0.5 * Math.Sqrt((double)PointsOfInterest[j].Text.Length);
                Game.AddMessage(PointsOfInterest[j].Text, MessageManager.MessageDependency.PointOfInterest, Interface.GameMode.Expert, MessageColor.White, Game.SecondsSinceMidnight + n, null);
            }
            return(true);
        }
示例#8
0
        /// <summary>Is called once a frame to update the station state for the given train</summary>
        /// <param name="Train">The train</param>
        /// <param name="TimeElapsed">The frame time elapsed</param>
        private static void UpdateTrainStation(Train Train, double TimeElapsed)
        {
            if (Train.Station >= 0)
            {
                int    i = Train.Station;
                int    n = Game.Stations[Train.Station].GetStopIndex(Train.Cars.Length);
                double tf, tb;
                if (n >= 0)
                {
                    double p0 = Train.Cars[0].FrontAxle.Follower.TrackPosition - Train.Cars[0].FrontAxle.Position + 0.5 * Train.Cars[0].Length;
                    double p1 = Game.Stations[i].Stops[n].TrackPosition;
                    tf = Game.Stations[i].Stops[n].ForwardTolerance;
                    tb = Game.Stations[i].Stops[n].BackwardTolerance;
                    Train.StationDistanceToStopPoint = p1 - p0;
                }
                else
                {
                    Train.StationDistanceToStopPoint = 0.0;
                    tf = 5.0;
                    tb = 5.0;
                }
                if (Train.StationState == TrainStopState.Pending)
                {
                    Train.StationDepartureSoundPlayed = false;
                    if (Game.StopsAtStation(i, Train))
                    {
                        Train.StationDepartureSoundPlayed = false;
                        //Check whether all doors are controlled by the driver
                        if (Train.Specs.DoorOpenMode != DoorMode.Manual)
                        {
                            //Check that we are not moving
                            if (Math.Abs(Train.Specs.CurrentAverageSpeed) < 0.1 / 3.6 &
                                Math.Abs(Train.Specs.CurrentAverageAcceleration) < 0.1 / 3.6)
                            {
                                //Check the interlock state for the doors
                                switch (Train.Specs.DoorInterlockState)
                                {
                                case DoorInterlockStates.Unlocked:
                                    if (Game.Stations[i].OpenLeftDoors || Game.Stations[i].OpenRightDoors)
                                    {
                                        AttemptToOpenDoors(Train, i, tb, tf);
                                    }
                                    break;

                                case DoorInterlockStates.Left:
                                    if (Game.Stations[i].OpenLeftDoors && !Game.Stations[i].OpenRightDoors)
                                    {
                                        AttemptToOpenDoors(Train, i, tb, tf);
                                    }
                                    break;

                                case DoorInterlockStates.Right:
                                    if (!Game.Stations[i].OpenLeftDoors && Game.Stations[i].OpenRightDoors)
                                    {
                                        AttemptToOpenDoors(Train, i, tb, tf);
                                    }
                                    break;

                                case DoorInterlockStates.Locked:
                                    //All doors are currently locked, do nothing
                                    break;
                                }
                            }
                        }
                        // detect arrival
                        if (Train.Specs.CurrentAverageSpeed > -0.277777777777778 & Train.Specs.CurrentAverageSpeed < 0.277777777777778)
                        {
                            bool left, right;
                            if (Game.Stations[i].OpenLeftDoors)
                            {
                                left = false;
                                for (int j = 0; j < Train.Cars.Length; j++)
                                {
                                    if (Train.Cars[j].Doors[0].AnticipatedOpen)
                                    {
                                        left = true; break;
                                    }
                                }
                            }
                            else
                            {
                                left = true;
                            }
                            if (Game.Stations[i].OpenRightDoors)
                            {
                                right = false;
                                for (int j = 0; j < Train.Cars.Length; j++)
                                {
                                    if (Train.Cars[j].Doors[1].AnticipatedOpen)
                                    {
                                        right = true; break;
                                    }
                                }
                            }
                            else
                            {
                                right = true;
                            }
                            if (left & right)
                            {
                                // arrival
                                Train.StationState  = TrainStopState.Boarding;
                                Train.StationAdjust = false;
                                Train.Specs.DoorClosureAttempted = false;
                                Sounds.StopSound(Train.Cars[Train.DriverCar].Sounds.Halt.Source);
                                Sounds.SoundBuffer buffer = Game.Stations[i].ArrivalSoundBuffer;
                                if (buffer != null)
                                {
                                    OpenBveApi.Math.Vector3 pos = Game.Stations[i].SoundOrigin;
                                    Sounds.PlaySound(buffer, 1.0, 1.0, pos, false);
                                }
                                Train.StationArrivalTime   = Game.SecondsSinceMidnight;
                                Train.StationDepartureTime = Game.Stations[i].DepartureTime - Train.TimetableDelta;
                                if (Train.StationDepartureTime - Game.SecondsSinceMidnight < Game.Stations[i].StopTime)
                                {
                                    Train.StationDepartureTime = Game.SecondsSinceMidnight + Game.Stations[i].StopTime;
                                }
                                Train.Passengers.PassengerRatio = Game.Stations[i].PassengerRatio;
                                UpdateTrainMassFromPassengerRatio(Train);
                                if (Train == PlayerTrain)
                                {
                                    double early = 0.0;
                                    if (Game.Stations[i].ArrivalTime >= 0.0)
                                    {
                                        early = (Game.Stations[i].ArrivalTime - Train.TimetableDelta) - Train.StationArrivalTime;
                                    }
                                    string s;
                                    if (early < -1.0)
                                    {
                                        s = Translations.GetInterfaceString("message_station_arrival_late");
                                    }
                                    else if (early > 1.0)
                                    {
                                        s = Translations.GetInterfaceString("message_station_arrival_early");
                                    }
                                    else
                                    {
                                        s = Translations.GetInterfaceString("message_station_arrival");
                                    }
                                    System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
                                    TimeSpan a = TimeSpan.FromSeconds(Math.Abs(early));
                                    string   b = a.Hours.ToString("00", Culture) + ":" + a.Minutes.ToString("00", Culture) + ":" + a.Seconds.ToString("00", Culture);
                                    if (Train.StationDistanceToStopPoint < -0.1)
                                    {
                                        s += Translations.GetInterfaceString("message_delimiter") + Translations.GetInterfaceString("message_station_overrun");
                                    }
                                    else if (Train.StationDistanceToStopPoint > 0.1)
                                    {
                                        s += Translations.GetInterfaceString("message_delimiter") + Translations.GetInterfaceString("message_station_underrun");
                                    }
                                    double d = Math.Abs(Train.StationDistanceToStopPoint);
                                    string c = d.ToString("0.0", Culture);
                                    if (Game.Stations[i].Type == StationType.Terminal)
                                    {
                                        s += Translations.GetInterfaceString("message_delimiter") + Translations.GetInterfaceString("message_station_terminal");
                                    }
                                    s = s.Replace("[name]", Game.Stations[i].Name);
                                    s = s.Replace("[time]", b);
                                    s = s.Replace("[difference]", c);
                                    Game.AddMessage(s, MessageManager.MessageDependency.StationArrival, Interface.GameMode.Normal, MessageColor.White, Game.SecondsSinceMidnight + 10.0, null);
                                    if (Game.Stations[i].Type == StationType.Normal)
                                    {
                                        s = Translations.GetInterfaceString("message_station_deadline");
                                        Game.AddMessage(s, MessageManager.MessageDependency.StationDeparture, Interface.GameMode.Normal, MessageColor.White, double.PositiveInfinity, null);
                                    }
                                    Timetable.UpdateCustomTimetable(Game.Stations[i].TimetableDaytimeTexture, Game.Stations[i].TimetableNighttimeTexture);
                                }
                                // schedule door locks (passengers stuck between the doors)
                                for (int j = 0; j < Train.Cars.Length; j++)
                                {
                                    for (int k = 0; k < Train.Cars[j].Doors.Length; k++)
                                    {
                                        Train.Cars[j].Doors[k].DoorLockDuration = 0.0;
                                        if (Game.Stations[i].OpenLeftDoors & Train.Cars[j].Doors[k].Direction == -1 | Game.Stations[i].OpenRightDoors & Train.Cars[j].Doors[k].Direction == 1)
                                        {
                                            double p = 0.005 * Game.Stations[i].PassengerRatio * Game.Stations[i].PassengerRatio * Game.Stations[i].PassengerRatio * Game.Stations[i].PassengerRatio;
                                            if (Program.RandomNumberGenerator.NextDouble() < p)
                                            {
                                                /*
                                                 * -- door lock at state --
                                                 * minimum: 0.2 (nearly closed)
                                                 * maximum: 0.8 (nearly opened)
                                                 * */
                                                Train.Cars[j].Doors[k].DoorLockState = 0.2 + 0.6 * Program.RandomNumberGenerator.NextDouble();

                                                /* -- waiting time --
                                                 * minimum: 2.9 s
                                                 * maximum: 40.0 s
                                                 * average: 7.6 s
                                                 * */
                                                p = Program.RandomNumberGenerator.NextDouble();
                                                Train.Cars[j].Doors[k].DoorLockDuration = (50.0 - 10.0 * p) / (17.0 - 16.0 * p);
                                            }
                                        }
                                    }
                                }
                            }
                            else if (Train.Specs.CurrentAverageSpeed > -0.277777777777778 & Train.Specs.CurrentAverageSpeed < 0.277777777777778)
                            {
                                // correct stop position
                                if (!Train.StationAdjust & (Train.StationDistanceToStopPoint > tb | Train.StationDistanceToStopPoint < -tf))
                                {
                                    Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.Adjust.Buffer;
                                    if (buffer != null)
                                    {
                                        OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.Adjust.Position;
                                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false);
                                    }
                                    if (Train == TrainManager.PlayerTrain)
                                    {
                                        Game.AddMessage(Translations.GetInterfaceString("message_station_correct"), MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.Orange, Game.SecondsSinceMidnight + 5.0, null);
                                    }
                                    Train.StationAdjust = true;
                                }
                            }
                            else
                            {
                                Train.StationAdjust = false;
                            }
                        }
                    }
                }
                else if (Train.StationState == TrainStopState.Boarding)
                {
                    for (int j = 0; j < Train.Cars.Length; j++)
                    {
                        if (GetDoorsState(Train, j, Game.Stations[i].OpenLeftDoors, Game.Stations[i].OpenRightDoors) == (TrainDoorState.Opened | TrainDoorState.AllOpened))
                        {
                            //Check whether all doors are controlled by the driver, and whether this is a non-standard station type
                            //e.g. Change ends
                            if (Train.Specs.DoorCloseMode != DoorMode.Manual & Game.Stations[i].Type == StationType.Normal)
                            {
                                //Check the interlock state for the doors
                                switch (Train.Specs.DoorInterlockState)
                                {
                                case DoorInterlockStates.Unlocked:
                                    AttemptToCloseDoors(Train);
                                    break;

                                case DoorInterlockStates.Left:
                                    if (Game.Stations[i].OpenLeftDoors)
                                    {
                                        AttemptToCloseDoors(Train);
                                    }
                                    break;

                                case DoorInterlockStates.Right:
                                    if (Game.Stations[i].OpenRightDoors)
                                    {
                                        AttemptToCloseDoors(Train);
                                    }
                                    break;

                                case DoorInterlockStates.Locked:
                                    //All doors are currently locked, do nothing
                                    break;
                                }

                                if (Train.Specs.DoorInterlockState != DoorInterlockStates.Locked & Train.Specs.DoorClosureAttempted)
                                {
                                    if (Game.Stations[i].OpenLeftDoors && !Train.Cars[j].Doors[0].AnticipatedReopen && Program.RandomNumberGenerator.NextDouble() < Game.Stations[i].ReopenDoor)
                                    {
                                        Train.Cars[j].Doors[0].ReopenLimit           = Program.RandomNumberGenerator.Next(1, Game.Stations[i].ReopenStationLimit);
                                        Train.Cars[j].Doors[0].ReopenCounter         = 0;
                                        Train.Cars[j].Doors[0].InterferingObjectRate = Program.RandomNumberGenerator.Next(1, Game.Stations[i].MaxInterferingObjectRate) * 0.01;
                                        if (Train.Cars[j].Doors[0].InterferingObjectRate * Train.Specs.DoorWidth >= Train.Specs.DoorMaxTolerance)
                                        {
                                            Train.Cars[j].Doors[0].AnticipatedReopen = true;
                                        }
                                    }
                                    if (Game.Stations[i].OpenRightDoors && !Train.Cars[j].Doors[1].AnticipatedReopen && Program.RandomNumberGenerator.NextDouble() < Game.Stations[i].ReopenDoor)
                                    {
                                        Train.Cars[j].Doors[1].ReopenLimit           = Program.RandomNumberGenerator.Next(1, Game.Stations[i].ReopenStationLimit);
                                        Train.Cars[j].Doors[1].ReopenCounter         = 0;
                                        Train.Cars[j].Doors[1].InterferingObjectRate = Program.RandomNumberGenerator.Next(1, Game.Stations[i].MaxInterferingObjectRate) * 0.01;
                                        if (Train.Cars[j].Doors[1].InterferingObjectRate * Train.Specs.DoorWidth >= Train.Specs.DoorMaxTolerance)
                                        {
                                            Train.Cars[j].Doors[1].AnticipatedReopen = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    // detect departure
                    bool left, right;
                    if (!Game.Stations[i].OpenLeftDoors & !Game.Stations[i].OpenRightDoors)
                    {
                        left  = true;
                        right = true;
                    }
                    else
                    {
                        if (Game.Stations[i].OpenLeftDoors)
                        {
                            left = false;
                            for (int j = 0; j < Train.Cars.Length; j++)
                            {
                                for (int k = 0; k < Train.Cars[j].Doors.Length; k++)
                                {
                                    if (Train.Cars[j].Doors[k].State != 0.0)
                                    {
                                        left = true; break;
                                    }
                                }
                                if (left)
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            left = false;
                        }
                        if (Game.Stations[i].OpenRightDoors)
                        {
                            right = false;
                            for (int j = 0; j < Train.Cars.Length; j++)
                            {
                                for (int k = 0; k < Train.Cars[j].Doors.Length; k++)
                                {
                                    if (Train.Cars[j].Doors[k].State != 0.0)
                                    {
                                        right = true; break;
                                    }
                                }
                                if (right)
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            right = false;
                        }
                    }
                    // departure sound
                    if (!Train.StationDepartureSoundPlayed)
                    {
                        Sounds.SoundBuffer buffer = Game.Stations[i].DepartureSoundBuffer;
                        if (buffer != null)
                        {
                            double dur = Sounds.GetDuration(buffer);
                            if (Game.SecondsSinceMidnight >= Train.StationDepartureTime - dur)
                            {
                                Sounds.PlaySound(buffer, 1.0, 1.0, Game.Stations[i].SoundOrigin, false);
                                Train.StationDepartureSoundPlayed = true;
                            }
                        }
                    }
                    for (int j = 0; j < Train.Cars.Length; j++)
                    {
                        if (Train.Cars[j].Doors[0].AnticipatedReopen && Train.Cars[j].Doors[0].State == Train.Cars[j].Doors[0].InterferingObjectRate)
                        {
                            if (Train.Cars[j].Doors[0].NextReopenTime == 0.0)
                            {
                                Train.Cars[j].Doors[0].NextReopenTime = Game.SecondsSinceMidnight + Game.Stations[i].InterferenceInDoor;
                            }
                            else if (Train.Cars[j].Doors[0].ReopenCounter < Train.Cars[j].Doors[0].ReopenLimit)
                            {
                                if (Game.SecondsSinceMidnight >= Train.Cars[j].Doors[0].NextReopenTime)
                                {
                                    OpenTrainDoors(Train, j, true, false);
                                }
                            }
                            else
                            {
                                Train.Cars[j].Doors[0].AnticipatedReopen = false;
                            }
                        }
                        if (Train.Cars[j].Doors[1].AnticipatedReopen && Train.Cars[j].Doors[1].State == Train.Cars[j].Doors[1].InterferingObjectRate)
                        {
                            if (Train.Cars[j].Doors[1].NextReopenTime == 0.0)
                            {
                                Train.Cars[j].Doors[1].NextReopenTime = Game.SecondsSinceMidnight + Game.Stations[i].InterferenceInDoor;
                            }
                            else if (Train.Cars[j].Doors[1].ReopenCounter < Train.Cars[j].Doors[1].ReopenLimit)
                            {
                                if (Game.SecondsSinceMidnight >= Train.Cars[j].Doors[1].NextReopenTime)
                                {
                                    OpenTrainDoors(Train, j, false, true);
                                }
                            }
                            else
                            {
                                Train.Cars[j].Doors[1].AnticipatedReopen = false;
                            }
                        }
                    }
                    TrainDoorState doorState = GetDoorsState(Train, Game.Stations[i].OpenLeftDoors, Game.Stations[i].OpenRightDoors);
                    if (Train.Specs.DoorCloseMode == DoorMode.Manual || doorState == TrainDoorState.None || doorState == (TrainDoorState.Closed | TrainDoorState.AllClosed))
                    {
                        if (left | right)
                        {
                            // departure message
                            if (Game.SecondsSinceMidnight > Train.StationDepartureTime && (Game.Stations[i].Type != StationType.Terminal || Train != PlayerTrain))
                            {
                                Train.StationState = TrainStopState.Completed;
                                if (Train == PlayerTrain & Game.Stations[i].Type == StationType.Normal)
                                {
                                    if (!Game.Stations[i].OpenLeftDoors & !Game.Stations[i].OpenRightDoors | Train.Specs.DoorCloseMode != DoorMode.Manual)
                                    {
                                        Game.AddMessage(Translations.GetInterfaceString("message_station_depart"), MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.White, Game.SecondsSinceMidnight + 5.0, null);
                                    }
                                    else
                                    {
                                        Game.AddMessage(Translations.GetInterfaceString("message_station_depart_closedoors"), MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.White, Game.SecondsSinceMidnight + 5.0, null);
                                    }
                                }
                                else if (Game.Stations[i].Type == StationType.ChangeEnds)
                                {
                                    JumpTrain(Train, i + 1);
                                }
                            }
                            if (Interface.CurrentOptions.LoadingSway)
                            {
                                // passengers boarding
                                for (int j = 0; j < Train.Cars.Length; j++)
                                {
                                    double r = 2.0 * Game.Stations[i].PassengerRatio * TimeElapsed;
                                    if (r >= Program.RandomNumberGenerator.NextDouble())
                                    {
                                        int d =
                                            (int)Math.Floor(Program.RandomNumberGenerator.NextDouble() * (double)Train.Cars[j].Doors.Length);
                                        if (Train.Cars[j].Doors[d].State == 1.0)
                                        {
                                            Train.Cars[j].Specs.CurrentRollShakeDirection += (double)Train.Cars[j].Doors[d].Direction;
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            Train.StationState = TrainStopState.Completed;
                            if (Train == PlayerTrain & Game.Stations[i].Type == StationType.Normal)
                            {
                                Game.AddMessage(Translations.GetInterfaceString("message_station_depart"), MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.White, Game.SecondsSinceMidnight + 5.0, null);
                            }
                        }
                    }
                }
            }
            else
            {
                if (Train.StationState != TrainStopState.Jumping)
                {
                    Train.StationState = TrainStopState.Pending;
                }
            }
            // automatically close doors
            if (Train.Specs.DoorCloseMode != DoorMode.Manual & Train.Specs.DoorInterlockState != DoorInterlockStates.Locked & !Train.Specs.DoorClosureAttempted)
            {
                if (Train.Station == -1 | Train.StationState == TrainStopState.Completed)
                {
                    if ((GetDoorsState(Train, true, true) & TrainDoorState.AllClosed) == 0)
                    {
                        CloseTrainDoors(Train, true, true);
                        Train.Specs.DoorClosureAttempted = true;
                    }
                }
            }
        }
示例#9
0
            /// <inheritdoc/>
            public override void RequestStop(RequestStop stopRequest)
            {
                if (stopRequest.MaxCars != 0 && NumberOfCars > stopRequest.MaxCars)
                {
                    //Check whether our train length is valid for this before doing anything else
                    Program.Sounds.PlayCarSound(Cars[DriverCar].Sounds.RequestStop[2], 1.0, 1.0, Cars[DriverCar], false);
                    return;
                }
                if (Program.RandomNumberGenerator.Next(0, 100) <= stopRequest.Probability)
                {
                    //We have hit our probability roll
                    if (Program.CurrentRoute.Stations[stopRequest.StationIndex].StopMode == StationStopMode.AllRequestStop || (IsPlayerTrain && Program.CurrentRoute.Stations[stopRequest.StationIndex].StopMode == StationStopMode.PlayerRequestStop))
                    {
                        //If our train can stop at this station, set it's index accordingly
                        Station         = stopRequest.StationIndex;
                        NextStopSkipped = StopSkipMode.None;
                        //Play sound
                        Program.Sounds.PlayCarSound(Cars[DriverCar].Sounds.RequestStop[0], 1.0, 1.0, Cars[DriverCar], false);
                    }
                    else
                    {
                        //We don't meet the conditions for this request stop
                        if (stopRequest.FullSpeed)
                        {
                            //Pass at linespeed, rather than braking as if for stop
                            NextStopSkipped = StopSkipMode.Linespeed;
                        }
                        else
                        {
                            NextStopSkipped = StopSkipMode.Decelerate;
                        }

                        //Play sound
                        Program.Sounds.PlayCarSound(Cars[DriverCar].Sounds.RequestStop[1], 1.0, 1.0, Cars[DriverCar], false);
                        //If message is not empty, add it
                        if (!string.IsNullOrEmpty(stopRequest.PassMessage) && IsPlayerTrain)
                        {
                            Game.AddMessage(stopRequest.PassMessage, MessageDependency.None, GameMode.Normal, MessageColor.White, Program.CurrentRoute.SecondsSinceMidnight + 10.0, null);
                        }

                        return;
                    }

                    //Play sound
                    Program.Sounds.PlayCarSound(Cars[DriverCar].Sounds.RequestStop[0], 1.0, 1.0, Cars[DriverCar], false);
                    //If message is not empty, add it
                    if (!string.IsNullOrEmpty(stopRequest.StopMessage) && IsPlayerTrain)
                    {
                        Game.AddMessage(stopRequest.StopMessage, MessageDependency.None, GameMode.Normal, MessageColor.White, Program.CurrentRoute.SecondsSinceMidnight + 10.0, null);
                    }
                }
                else
                {
                    Program.Sounds.PlayCarSound(Cars[DriverCar].Sounds.RequestStop[1], 1.0, 1.0, Cars[DriverCar], false);
                    if (stopRequest.FullSpeed)
                    {
                        //Pass at linespeed, rather than braking as if for stop
                        NextStopSkipped = StopSkipMode.Linespeed;
                    }
                    else
                    {
                        NextStopSkipped = StopSkipMode.Decelerate;
                    }

                    //Play sound
                    Program.Sounds.PlayCarSound(Cars[DriverCar].Sounds.RequestStop[1], 1.0, 1.0, Cars[DriverCar], false);
                    //If message is not empty, add it
                    if (!string.IsNullOrEmpty(stopRequest.PassMessage) && IsPlayerTrain)
                    {
                        Game.AddMessage(stopRequest.PassMessage, MessageDependency.None, GameMode.Normal, MessageColor.White, Program.CurrentRoute.SecondsSinceMidnight + 10.0, null);
                    }
                }
            }
示例#10
0
 /// <summary>May be called from a .Net plugin, in order to add a message to the in-game display</summary>
 /// <param name="Message">The message to display</param>
 /// <param name="Color">The color in which to display the message</param>
 /// <param name="Time">The time in seconds for which to display the message</param>
 internal void AddInterfaceMessage(string Message, MessageColor Color, double Time)
 {
     Game.AddMessage(Message, MessageManager.MessageDependency.Plugin, Interface.GameMode.Expert, Color, Game.SecondsSinceMidnight + Time, null);
 }
示例#11
0
 /// <summary>May be called from a .Net plugin, in order to add a message to the in-game display</summary>
 /// <param name="Message">The message to display</param>
 /// <param name="Color">The color in which to display the message</param>
 /// <param name="Time">The time in seconds for which to display the message</param>
 internal void AddInterfaceMessage(string Message, MessageColor Color, double Time)
 {
     Game.AddMessage(Message, MessageDependency.Plugin, GameMode.Expert, Color, Program.CurrentRoute.SecondsSinceMidnight + Time, null);
 }
示例#12
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();
        }
示例#13
0
            /// <summary>Updates the physics and controls for this train</summary>
            /// <param name="TimeElapsed">The time elapsed</param>
            private void UpdatePhysicsAndControls(double TimeElapsed)
            {
                if (TimeElapsed == 0.0 || TimeElapsed > 1000)
                {
                    //HACK: The physics engine really does not like update times above 1000ms
                    //This works around a bug experienced when jumping to a station on a steep hill
                    //causing exessive acceleration
                    return;
                }
                // move cars
                for (int i = 0; i < Cars.Length; i++)
                {
                    Cars[i].Move(Cars[i].CurrentSpeed * TimeElapsed);
                    if (State == TrainState.Disposed)
                    {
                        return;
                    }
                }
                // update station and doors
                UpdateTrainStation(this, TimeElapsed);
                UpdateTrainDoors(this, TimeElapsed);
                // delayed handles
                if (Plugin == null)
                {
                    Handles.Power.Safety          = Handles.Power.Driver;
                    Handles.Brake.Safety          = Handles.Brake.Driver;
                    Handles.EmergencyBrake.Safety = Handles.EmergencyBrake.Driver;
                }
                Handles.Power.Update();
                Handles.Brake.Update();
                Handles.Brake.Update();
                Handles.EmergencyBrake.Update();
                Handles.HoldBrake.Actual = Handles.HoldBrake.Driver;
                // update speeds
                UpdateSpeeds(TimeElapsed);
                // Update Run and Motor sounds
                for (int i = 0; i < Cars.Length; i++)
                {
                    Cars[i].UpdateRunSounds(TimeElapsed);
                    Cars[i].UpdateMotorSounds(TimeElapsed);
                }

                // safety system
                if (!Game.MinimalisticSimulation | !IsPlayerTrain)
                {
                    UpdateSafetySystem();
                }
                {
                    // breaker sound
                    bool breaker;
                    if (Cars[DriverCar].CarBrake is AutomaticAirBrake)
                    {
                        breaker = Handles.Reverser.Actual != 0 & Handles.Power.Safety >= 1 & Handles.Brake.Safety == (int)AirBrakeHandleState.Release & !Handles.EmergencyBrake.Safety & !Handles.HoldBrake.Actual;
                    }
                    else
                    {
                        breaker = Handles.Reverser.Actual != 0 & Handles.Power.Safety >= 1 & Handles.Brake.Safety == 0 & !Handles.EmergencyBrake.Safety & !Handles.HoldBrake.Actual;
                    }
                    if (breaker & !Cars[DriverCar].Sounds.BreakerResumed)
                    {
                        // resume
                        if (Cars[DriverCar].Sounds.BreakerResume.Buffer != null)
                        {
                            Program.Sounds.PlaySound(Cars[DriverCar].Sounds.BreakerResume.Buffer, 1.0, 1.0, Cars[DriverCar].Sounds.BreakerResume.Position, Cars[DriverCar], false);
                        }
                        if (Cars[DriverCar].Sounds.BreakerResumeOrInterrupt.Buffer != null)
                        {
                            Program.Sounds.PlaySound(Cars[DriverCar].Sounds.BreakerResumeOrInterrupt.Buffer, 1.0, 1.0, Cars[DriverCar].Sounds.BreakerResumeOrInterrupt.Position, Cars[DriverCar], false);
                        }
                        Cars[DriverCar].Sounds.BreakerResumed = true;
                    }
                    else if (!breaker & Cars[DriverCar].Sounds.BreakerResumed)
                    {
                        // interrupt
                        if (Cars[DriverCar].Sounds.BreakerResumeOrInterrupt.Buffer != null)
                        {
                            Program.Sounds.PlaySound(Cars[DriverCar].Sounds.BreakerResumeOrInterrupt.Buffer, 1.0, 1.0, Cars[DriverCar].Sounds.BreakerResumeOrInterrupt.Position, Cars[DriverCar], false);
                        }
                        Cars[DriverCar].Sounds.BreakerResumed = false;
                    }
                }
                // passengers
                Passengers.Update(Specs.CurrentAverageAcceleration, TimeElapsed);
                // signals
                if (CurrentSectionLimit == 0.0)
                {
                    if (Handles.EmergencyBrake.Driver & CurrentSpeed > -0.03 & CurrentSpeed < 0.03)
                    {
                        CurrentSectionLimit = 6.94444444444444;
                        if (IsPlayerTrain)
                        {
                            string s = Translations.GetInterfaceString("message_signal_proceed");
                            double a = (3.6 * CurrentSectionLimit) * Game.SpeedConversionFactor;
                            s = s.Replace("[speed]", a.ToString("0", CultureInfo.InvariantCulture));
                            s = s.Replace("[unit]", Game.UnitOfSpeed);
                            Game.AddMessage(s, MessageDependency.None, GameMode.Normal, MessageColor.Red, Program.CurrentRoute.SecondsSinceMidnight + 5.0, null);
                        }
                    }
                }
                // infrequent updates
                InternalTimerTimeElapsed += TimeElapsed;
                if (InternalTimerTimeElapsed > 10.0)
                {
                    InternalTimerTimeElapsed -= 10.0;
                    Synchronize();
                    UpdateAtmosphericConstants();
                }
            }
示例#14
0
            /// <summary>Call this method to update the train</summary>
            /// <param name="TimeElapsed">The elapsed time this frame</param>
            internal void Update(double TimeElapsed)
            {
                if (State == TrainState.Pending)
                {
                    // pending train
                    bool   forceIntroduction = !IsPlayerTrain && !Game.MinimalisticSimulation;
                    double time = 0.0;
                    if (!forceIntroduction)
                    {
                        for (int i = 0; i < Program.CurrentRoute.Stations.Length; i++)
                        {
                            if (Program.CurrentRoute.Stations[i].StopMode == StationStopMode.AllStop | Program.CurrentRoute.Stations[i].StopMode == StationStopMode.PlayerPass)
                            {
                                if (Program.CurrentRoute.Stations[i].ArrivalTime >= 0.0)
                                {
                                    time = Program.CurrentRoute.Stations[i].ArrivalTime;
                                }
                                else if (Program.CurrentRoute.Stations[i].DepartureTime >= 0.0)
                                {
                                    time = Program.CurrentRoute.Stations[i].DepartureTime - Program.CurrentRoute.Stations[i].StopTime;
                                }
                                break;
                            }
                        }
                        time -= TimetableDelta;
                    }
                    if (Program.CurrentRoute.SecondsSinceMidnight >= time | forceIntroduction)
                    {
                        bool introduce = true;
                        if (!forceIntroduction)
                        {
                            if (CurrentSectionIndex >= 0)
                            {
                                if (!Program.CurrentRoute.Sections[CurrentSectionIndex].IsFree())
                                {
                                    introduce = false;
                                }
                            }
                        }

                        if (this == PlayerTrain && Loading.SimulationSetup)
                        {
                            /* Loading has finished, but we still have an AI train in the current section
                             * This may be caused by an iffy RunInterval value, or simply by having no sections							 *
                             *
                             * We must introduce the player's train as otherwise the cab and loop sounds are missing
                             * NOTE: In this case, the signalling cannot prevent the player from colliding with
                             * the AI train
                             */

                            introduce = true;
                        }
                        if (introduce)
                        {
                            // train is introduced
                            State = TrainState.Available;
                            for (int j = 0; j < Cars.Length; j++)
                            {
                                if (Cars[j].CarSections.Length != 0)
                                {
                                    if (j == this.DriverCar && IsPlayerTrain)
                                    {
                                        this.Cars[j].ChangeCarSection(CarSectionType.Interior);
                                    }
                                    else
                                    {
                                        /*
                                         * HACK: Load in exterior mode first to ensure everything is cached
                                         * before switching immediately to not visible
                                         * https://github.com/leezer3/OpenBVE/issues/226
                                         * Stuff like the R142A really needs to downsize the textures supplied,
                                         * but we have no control over external factors....
                                         */
                                        this.Cars[j].ChangeCarSection(CarSectionType.Exterior);
                                        if (IsPlayerTrain)
                                        {
                                            this.Cars[j].ChangeCarSection(CarSectionType.NotVisible);
                                        }
                                    }
                                }
                                Cars[j].FrontBogie.ChangeSection(!IsPlayerTrain ? 0 : -1);
                                Cars[j].RearBogie.ChangeSection(!IsPlayerTrain ? 0 : -1);
                                Cars[j].Coupler.ChangeSection(!IsPlayerTrain ? 0 : -1);

                                if (Cars[j].Specs.IsMotorCar)
                                {
                                    if (Cars[j].Sounds.Loop.Buffer != null)
                                    {
                                        Cars[j].Sounds.Loop.Source = Program.Sounds.PlaySound(Cars[j].Sounds.Loop.Buffer, 1.0, 1.0, Cars[j].Sounds.Loop.Position, Cars[j], true);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (State == TrainState.Available)
                {
                    // available train
                    UpdatePhysicsAndControls(TimeElapsed);
                    if (CurrentSpeed > CurrentRouteLimit)
                    {
                        if (previousRouteLimit != CurrentRouteLimit || Interface.CurrentOptions.GameMode == GameMode.Arcade)
                        {
                            /*
                             * HACK: If the limit has changed, or we are in arcade mode, notify the player
                             *       This conforms to the original behaviour, but doesn't need to raise the message from the event.
                             */
                            Game.AddMessage(Translations.GetInterfaceString("message_route_overspeed"), MessageDependency.RouteLimit, GameMode.Normal, MessageColor.Orange, Double.PositiveInfinity, null);
                        }
                    }
                    previousRouteLimit = CurrentRouteLimit;
                    if (Interface.CurrentOptions.GameMode == GameMode.Arcade)
                    {
                        if (CurrentSectionLimit == 0.0)
                        {
                            Game.AddMessage(Translations.GetInterfaceString("message_signal_stop"), MessageDependency.PassedRedSignal, GameMode.Normal, MessageColor.Red, double.PositiveInfinity, null);
                        }
                        else if (CurrentSpeed > CurrentSectionLimit)
                        {
                            Game.AddMessage(Translations.GetInterfaceString("message_signal_overspeed"), MessageDependency.SectionLimit, GameMode.Normal, MessageColor.Orange, Double.PositiveInfinity, null);
                        }
                    }
                    if (AI != null)
                    {
                        AI.Trigger(TimeElapsed);
                    }
                }
                else if (State == TrainState.Bogus)
                {
                    // bogus train
                    if (AI != null)
                    {
                        AI.Trigger(TimeElapsed);
                    }
                }
                //Trigger point sounds if appropriate
                for (int i = 0; i < Cars.Length; i++)
                {
                    Vector3     p      = Vector3.Zero;
                    SoundBuffer buffer = null;
                    if (Cars[i].FrontAxle.PointSoundTriggered)
                    {
                        Cars[i].FrontAxle.PointSoundTriggered = false;
                        int bufferIndex = Cars[i].FrontAxle.RunIndex;
                        if (Cars[i].FrontAxle.PointSounds == null || Cars[i].FrontAxle.PointSounds.Length == 0)
                        {
                            //No point sounds defined at all
                            continue;
                        }
                        if (bufferIndex > Cars[i].FrontAxle.PointSounds.Length - 1 ||
                            Cars[i].FrontAxle.PointSounds[bufferIndex].Buffer == null)
                        {
                            //If the switch sound does not exist, return zero
                            //Required to handle legacy trains which don't have idx specific run sounds defined
                            bufferIndex = 0;
                        }
                        buffer = Cars[i].FrontAxle.PointSounds[bufferIndex].Buffer;
                        p      = Cars[i].FrontAxle.PointSounds[bufferIndex].Position;
                    }
                    if (buffer != null)
                    {
                        double spd   = Math.Abs(CurrentSpeed);
                        double pitch = spd / 12.5;
                        double gain  = pitch < 0.5 ? 2.0 * pitch : 1.0;
                        if (pitch < 0.2 | gain < 0.2)
                        {
                            buffer = null;
                        }
                        if (buffer != null)
                        {
                            Program.Sounds.PlaySound(buffer, pitch, gain, p, Cars[i], false);
                        }
                    }
                }
            }
示例#15
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;
            }
        }
示例#16
0
 internal override void Trigger(int Direction, EventTriggerType TriggerType, TrainManager.Train Train, int CarIndex)
 {
     if (TriggerType == EventTriggerType.FrontCarFrontAxle)
     {
         RequestStop stop;                     //Temp probability value
         if (Early.Time != -1 && Game.SecondsSinceMidnight < Early.Time)
         {
             stop = Early;
         }
         else if (Early.Time != -1 && Game.SecondsSinceMidnight > Early.Time && Late.Time != -1 && Game.SecondsSinceMidnight < Late.Time)
         {
             stop = OnTime;
         }
         else if (Late.Time != -1 && Game.SecondsSinceMidnight > Late.Time)
         {
             stop = Late;
         }
         else
         {
             stop = OnTime;
         }
         if (MaxCars != 0 && Train.Cars.Length > MaxCars)
         {
             //Check whether our train length is valid for this before doing anything else
             Sounds.PlayCarSound(Train.Cars[Train.DriverCar].Sounds.RequestStop[2], 1.0, 1.0, Train, Train.DriverCar, false);
             return;
         }
         if (Direction > 0)
         {
             if (Program.RandomNumberGenerator.Next(0, 100) <= stop.Probability)
             {
                 //We have hit our probability roll
                 if (Game.Stations[StationIndex].StopMode == StationStopMode.AllRequestStop || (Train == TrainManager.PlayerTrain && Game.Stations[StationIndex].StopMode == StationStopMode.PlayerRequestStop))
                 {
                     //If our train can stop at this station, set it's index accordingly
                     Train.Station         = StationIndex;
                     Train.NextStopSkipped = TrainManager.StopSkipMode.None;
                     //Play sound
                     Sounds.PlayCarSound(Train.Cars[Train.DriverCar].Sounds.RequestStop[0], 1.0, 1.0, Train, Train.DriverCar, false);
                 }
                 else
                 {
                     //We don't meet the conditions for this request stop
                     if (FullSpeed)
                     {
                         //Pass at linespeed, rather than braking as if for stop
                         Train.NextStopSkipped = TrainManager.StopSkipMode.Linespeed;
                     }
                     else
                     {
                         Train.NextStopSkipped = TrainManager.StopSkipMode.Decelerate;
                     }
                     //Play sound
                     Sounds.PlayCarSound(Train.Cars[Train.DriverCar].Sounds.RequestStop[1], 1.0, 1.0, Train, Train.DriverCar, false);
                     //If message is not empty, add it
                     if (!string.IsNullOrEmpty(stop.PassMessage) && Train == TrainManager.PlayerTrain)
                     {
                         Game.AddMessage(stop.PassMessage, MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.White, Game.SecondsSinceMidnight + 10.0, null);
                     }
                     return;
                 }
                 //Play sound
                 Sounds.PlayCarSound(Train.Cars[Train.DriverCar].Sounds.RequestStop[0], 1.0, 1.0, Train, Train.DriverCar, false);
                 //If message is not empty, add it
                 if (!string.IsNullOrEmpty(stop.StopMessage) && Train == TrainManager.PlayerTrain)
                 {
                     Game.AddMessage(stop.StopMessage, MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.White, Game.SecondsSinceMidnight + 10.0, null);
                 }
             }
             else
             {
                 Sounds.PlayCarSound(Train.Cars[Train.DriverCar].Sounds.RequestStop[1], 1.0, 1.0, Train, Train.DriverCar, false);
                 if (FullSpeed)
                 {
                     //Pass at linespeed, rather than braking as if for stop
                     Train.NextStopSkipped = TrainManager.StopSkipMode.Linespeed;
                 }
                 else
                 {
                     Train.NextStopSkipped = TrainManager.StopSkipMode.Decelerate;
                 }
                 //Play sound
                 Sounds.PlayCarSound(Train.Cars[Train.DriverCar].Sounds.RequestStop[1], 1.0, 1.0, Train, Train.DriverCar, false);
                 //If message is not empty, add it
                 if (!string.IsNullOrEmpty(stop.PassMessage) && Train == TrainManager.PlayerTrain)
                 {
                     Game.AddMessage(stop.PassMessage, MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.White, Game.SecondsSinceMidnight + 10.0, null);
                 }
             }
         }
     }
 }
示例#17
0
 /// <summary>May be called from a .Net plugin, in order to add a message to the in-game display</summary>
 /// <param name="Message">The message to display</param>
 /// <param name="Color">The color in which to display the message</param>
 /// <param name="Time">The time in seconds for which to display the message</param>
 internal void AddInterfaceMessage(string Message, MessageColor Color, double Time)
 {
     Game.AddMessage(Message, Game.MessageDependency.None, Interface.GameMode.Expert, Color, Game.SecondsSinceMidnight + Time);
 }