public void Update(double tb, double tf) { if (baseTrain.CurrentSpeed > -0.277777777777778 & baseTrain.CurrentSpeed < 0.277777777777778) { // correct stop position if (!Lit & (baseTrain.StationDistanceToStopPoint > tb | baseTrain.StationDistanceToStopPoint < -tf)) { AdjustAlarm.Play(baseTrain.Cars[baseTrain.DriverCar], false); if (baseTrain.IsPlayerTrain) { GeneralMessage message = new GeneralMessage { MessageOnTimeText = Translations.GetInterfaceString("message_station_correct"), Timeout = 5.0, MessageColor = MessageColor.Orange, Mode = GameMode.Normal }; TrainManagerBase.currentHost.AddMessage(message); } Lit = true; } } else { Lit = false; } }
public void Update(double TimeElapsed) { if (Enabled) { if (mainReservoir.CurrentPressure > mainReservoir.MaximumPressure) { Enabled = false; LoopStarted = false; EndSound.Play(baseCar, false); LoopSound.Stop(); } else { mainReservoir.CurrentPressure += Rate * TimeElapsed; if (!LoopStarted && TrainManagerBase.currentHost.InGameTime > TimeStarted + 5.0) { LoopStarted = true; LoopSound.Play(baseCar, true); } } } else { if (mainReservoir.CurrentPressure < mainReservoir.MinimumPressure) { Enabled = true; TimeStarted = TrainManagerBase.currentHost.InGameTime; StartSound.Play(baseCar, false); } } }
/// <summary> Updates the breaker</summary> /// <param name="BreakerActive">Whether the breaker is currently active</param> public void Update(bool BreakerActive) { if (BreakerActive & !Resumed) { // resume Resume.Play(Car, false); ResumeOrInterrupt.Play(Car, false); Resumed = true; } else if (!BreakerActive & Resumed) { // interrupt ResumeOrInterrupt.Play(Car, false); Resumed = false; } }
public void Release() { if (Driver) { // sound if (ReleaseSound != null) { ReleaseSound.Play(baseTrain.Cars[baseTrain.DriverCar], false); } else { baseTrain.Handles.Brake.Decrease.Play(baseTrain.Cars[baseTrain.DriverCar], false); } // apply if (baseTrain.Handles.Brake is AirBrakeHandle) { baseTrain.Handles.Brake.ApplyState(AirBrakeHandleState.Service); } else { baseTrain.Handles.Brake.ApplyState(baseTrain.Handles.Brake.MaximumNotch, true); baseTrain.Handles.Power.ApplyState(0, baseTrain.Handles.HandleType != HandleType.SingleHandle); } Driver = false; // plugin if (baseTrain.Plugin == null) { return; } baseTrain.Plugin.UpdatePower(); baseTrain.Plugin.UpdateBrake(); } }
/// <summary>Triggers the pass alarm</summary> public void Trigger() { Lit = true; if (TrainManagerBase.currentHost.SoundIsPlaying(Sound.Source)) { return; } switch (Type) { case PassAlarmType.Single: Sound.Play(baseCar, false); break; case PassAlarmType.Loop: Sound.Play(baseCar, true); break; } }
/// <summary>Updates the windscreen</summary> /// <param name="TimeElapsed">The time elapsed since the previous call to this method</param> public void Update(double TimeElapsed) { if (RainDrops == null || RainDrops.Length == 0) { return; } if (CurrentlyRaining) { int nextDrop = PickDrop(); dropTimer += TimeElapsed * 1000; var dev = (int)(0.4 * 2000 / Intensity); int dropInterval = 2000 / Intensity + TrainManagerBase.RandomNumberGenerator.Next(dev, dev * 2); if (dropTimer > dropInterval) { if (nextDrop != -1) { if (!RainDrops[nextDrop].Visible) { currentDrops++; } RainDrops[nextDrop].Visible = true; if (!legacyRainEvents) { int snowProbability = TrainManagerBase.RandomNumberGenerator.Next(100); if ((snowProbability < Car.FrontAxle.Follower.SnowIntensity) || Car.FrontAxle.Follower.RainIntensity == 0) { //Either we've met the snow probability roll (mixed snow and rain) or not raining RainDrops[nextDrop].IsSnowFlake = true; } } RainDrops[nextDrop].RemainingLife = TrainManagerBase.RandomNumberGenerator.NextDouble() * DropLife; } //We want to play the drop sound even if all drops are currently visible (e.g. the wipers are off and it's still raining) DropSound.Play(Car, false); dropTimer = 0.0; } } for (int i = 0; i < RainDrops.Length; i++) { RainDrops[i].RemainingLife -= TimeElapsed; if (RainDrops[i].RemainingLife <= 0 && RainDrops[i].Visible) { RainDrops[i].Visible = false; RainDrops[i].IsSnowFlake = false; currentDrops--; RainDrops[i].RemainingLife = 0.5 * TrainManagerBase.RandomNumberGenerator.NextDouble() * DropLife; } } Wipers.Update(TimeElapsed); }
public void Update(DoorStates newState) { if (oldState != DoorStates.None & newState == DoorStates.None) { Lit = true; OnSound.Play(baseCar, false); } else if (oldState == DoorStates.None & newState != DoorStates.None) { Lit = false; OffSound.Play(baseCar, false); } oldState = newState; }
public void Apply() { // sound if (!Driver) { baseTrain.Handles.Brake.Max.Play(baseTrain.Cars[baseTrain.DriverCar], false); ApplicationSound.Play(baseTrain.Cars[baseTrain.DriverCar], false); } // apply baseTrain.Handles.Brake.ApplyState(baseTrain.Handles.Brake.MaximumNotch, true); baseTrain.Handles.Power.ApplyState(0, baseTrain.Handles.HandleType != HandleType.SingleHandle); baseTrain.Handles.Brake.ApplyState(AirBrakeHandleState.Service); Driver = true; baseTrain.Handles.HoldBrake.Driver = false; baseTrain.Specs.CurrentConstSpeed = false; if (Driver) { switch (OtherHandlesBehaviour) { case EbHandleBehaviour.PowerNeutral: if (baseTrain.Handles.HandleType != HandleType.SingleHandle) { baseTrain.Handles.Power.ApplyState(0, false); } break; case EbHandleBehaviour.ReverserNeutral: baseTrain.Handles.Reverser.ApplyState(ReverserPosition.Neutral); break; case EbHandleBehaviour.PowerReverserNeutral: if (baseTrain.Handles.HandleType != HandleType.SingleHandle) { baseTrain.Handles.Power.ApplyState(0, false); } baseTrain.Handles.Reverser.ApplyState(ReverserPosition.Neutral); break; } } // plugin if (baseTrain.Plugin == null) { return; } baseTrain.Plugin.UpdatePower(); baseTrain.Plugin.UpdateBrake(); }
public void Update(double tb, double tf) { if (baseTrain.CurrentSpeed > -0.277777777777778 & baseTrain.CurrentSpeed < 0.277777777777778) { // correct stop position if (!Lit & (baseTrain.StationDistanceToStopPoint > tb | baseTrain.StationDistanceToStopPoint < -tf)) { AdjustAlarm.Play(baseTrain.Cars[baseTrain.DriverCar], false); if (baseTrain.IsPlayerTrain) { TrainManagerBase.currentHost.AddMessage(Translations.GetInterfaceString("message_station_correct"), MessageDependency.None, GameMode.Normal, MessageColor.Orange, TrainManagerBase.CurrentRoute.SecondsSinceMidnight + 5.0, null); } Lit = true; } } else { Lit = false; } }
/// <summary>Changes the wiper speed</summary> public void ChangeSpeed(Translations.Command Command) { SwitchSound.Play(Windscreen.Car, false); switch (Command) { case Translations.Command.WiperSpeedUp: if (CurrentSpeed < WiperSpeed.Fast) { CurrentSpeed++; } break; case Translations.Command.WiperSpeedDown: if (CurrentSpeed > WiperSpeed.Off) { CurrentSpeed--; } break; } }
public void ApplyState(int Value, bool Relative) { if (baseTrain.Handles.HandleType == HandleType.InterlockedReverserHandle && baseTrain.Handles.Power.Driver != 0) { return; } int a = (int)Driver; int r = Relative ? a + Value : Value; if (r < -1) { r = -1; } if (r > 1) { r = 1; } if (a != r) { Driver = (ReverserPosition)r; if (baseTrain.Plugin != null) { baseTrain.Plugin.UpdateReverser(); } TrainManagerBase.currentHost.AddBlackBoxEntry(); // sound if (a == 0 & r != 0) { EngageSound.Play(baseTrain.Cars[baseTrain.DriverCar], false); } else if (a != 0 & r == 0) { ReleaseSound.Play(baseTrain.Cars[baseTrain.DriverCar], false); } } }
/// <inheritdoc/> public override void Update(double TimeElapsed) { if (State == TrainState.Pending) { // pending train bool forceIntroduction = !IsPlayerTrain && TrainManagerBase.currentHost.SimulationState != SimulationState.MinimalisticSimulation; double time = 0.0; if (!forceIntroduction) { for (int i = 0; i < TrainManagerBase.CurrentRoute.Stations.Length; i++) { if (TrainManagerBase.CurrentRoute.Stations[i].StopMode == StationStopMode.AllStop | TrainManagerBase.CurrentRoute.Stations[i].StopMode == StationStopMode.PlayerPass) { if (TrainManagerBase.CurrentRoute.Stations[i].ArrivalTime >= 0.0) { time = TrainManagerBase.CurrentRoute.Stations[i].ArrivalTime; } else if (TrainManagerBase.CurrentRoute.Stations[i].DepartureTime >= 0.0) { time = TrainManagerBase.CurrentRoute.Stations[i].DepartureTime - TrainManagerBase.CurrentRoute.Stations[i].StopTime; } break; } } time -= TimetableDelta; } if (TrainManagerBase.CurrentRoute.SecondsSinceMidnight >= time | forceIntroduction) { bool introduce = true; if (!forceIntroduction) { if (CurrentSectionIndex >= 0 && TrainManagerBase.CurrentRoute.Sections.Length > CurrentSectionIndex) { if (!TrainManagerBase.CurrentRoute.Sections[CurrentSectionIndex].IsFree()) { introduce = false; } } } if (this == TrainManagerBase.PlayerTrain && TrainManagerBase.currentHost.SimulationState != SimulationState.Loading) { /* 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 == DriverCar && IsPlayerTrain && TrainManagerBase.CurrentOptions.InitialViewpoint == 0) { 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.... */ Cars[j].ChangeCarSection(CarSectionType.Exterior); if (IsPlayerTrain && TrainManagerBase.CurrentOptions.InitialViewpoint == 0) { Cars[j].ChangeCarSection(CarSectionType.NotVisible, true); } } } 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 && Cars[j].Sounds.Loop != null) { Cars[j].Sounds.Loop.Play(Cars[j], true); } } } } } else if (State == TrainState.Available) { // available train UpdatePhysicsAndControls(TimeElapsed); if (CurrentSpeed > CurrentRouteLimit) { if (previousRouteLimit != CurrentRouteLimit || TrainManagerBase.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. */ TrainManagerBase.currentHost.AddMessage(Translations.GetInterfaceString("message_route_overspeed"), MessageDependency.RouteLimit, GameMode.Normal, MessageColor.Orange, double.PositiveInfinity, null); } } if (TrainManagerBase.CurrentOptions.Accessibility) { if (previousRouteLimit != CurrentRouteLimit) { //Show for 10s and announce the current speed limit if screen reader present TrainManagerBase.currentHost.AddMessage(Translations.GetInterfaceString("message_route_newlimit"), MessageDependency.AccessibilityHelper, GameMode.Normal, MessageColor.White, TrainManagerBase.currentHost.InGameTime + 10.0, null); } Section nextSection = TrainManagerBase.CurrentRoute.NextSection(FrontCarTrackPosition()); if (nextSection != null) { //If we find an appropriate signal, and the distance to it is less than 500m, announce if screen reader is present //Aspect announce to be triggered via a separate keybind double tPos = nextSection.TrackPosition - FrontCarTrackPosition(); if (!nextSection.AccessibilityAnnounced && tPos < 500) { string s = Translations.GetInterfaceString("message_route_nextsection").Replace("[distance]", $"{tPos:0.0}") + "m"; TrainManagerBase.currentHost.AddMessage(s, MessageDependency.AccessibilityHelper, GameMode.Normal, MessageColor.White, TrainManagerBase.currentHost.InGameTime + 10.0, null); nextSection.AccessibilityAnnounced = true; } } RouteStation nextStation = TrainManagerBase.CurrentRoute.NextStation(FrontCarTrackPosition()); if (nextStation != null) { //If we find an appropriate signal, and the distance to it is less than 500m, announce if screen reader is present //Aspect announce to be triggered via a separate keybind double tPos = nextStation.DefaultTrackPosition - FrontCarTrackPosition(); if (!nextStation.AccessibilityAnnounced && tPos < 500) { string s = Translations.GetInterfaceString("message_route_nextstation").Replace("[distance]", $"{tPos:0.0}") + "m".Replace("[name]", nextStation.Name); TrainManagerBase.currentHost.AddMessage(s, MessageDependency.AccessibilityHelper, GameMode.Normal, MessageColor.White, TrainManagerBase.currentHost.InGameTime + 10.0, null); nextStation.AccessibilityAnnounced = true; } } } previousRouteLimit = CurrentRouteLimit; if (TrainManagerBase.CurrentOptions.GameMode == GameMode.Arcade) { if (CurrentSectionLimit == 0.0) { TrainManagerBase.currentHost.AddMessage(Translations.GetInterfaceString("message_signal_stop"), MessageDependency.PassedRedSignal, GameMode.Normal, MessageColor.Red, double.PositiveInfinity, null); } else if (CurrentSpeed > CurrentSectionLimit) { TrainManagerBase.currentHost.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++) { CarSound c = null; if (Cars[i].FrontAxle.PointSoundTriggered) { Cars[i].FrontAxle.PointSoundTriggered = false; int bufferIndex = Cars[i].FrontAxle.RunIndex; if (bufferIndex > Cars[i].FrontAxle.PointSounds.Length - 1) { //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; } if (Cars[i].FrontAxle.PointSounds == null || Cars[i].FrontAxle.PointSounds.Length == 0) { //No point sounds defined at all continue; } c = (CarSound)Cars[i].FrontAxle.PointSounds[bufferIndex]; if (c.Buffer == null) { c = (CarSound)Cars[i].FrontAxle.PointSounds[0]; } } if (c != 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) { c.Play(pitch, gain, Cars[i], false); } } } }
/// <summary>Updates the windscreen wipers</summary> /// <param name="TimeElapsed">The time elapsed since the last call to this method</param> internal void Update(double TimeElapsed) { wiperTimer += TimeElapsed; if (CurrentSpeed == WiperSpeed.Off) { if (RestPosition == WiperPosition.Left && CurrentPosition == 100) { wiperTimer = 0; return; } if (RestPosition == WiperPosition.Right && CurrentPosition == 0) { wiperTimer = 0; return; } } //Move the wiper if (wiperTimer > MovementSpeed) { wiperTimer = 0; switch (currentDirection) { case WiperPosition.Left: if (CurrentPosition > 0) { CurrentPosition--; } break; case WiperPosition.Right: if (CurrentPosition < 100) { CurrentPosition++; } break; } soundTriggered = false; } switch (CurrentPosition) { //When the wiper is at either end of the travel, determine what to do next case 0: if (CurrentSpeed > 0) { if (HoldPosition == WiperPosition.Right && CurrentSpeed != WiperSpeed.Fast) { holdTimer += TimeElapsed; if (holdTimer > HoldTime) { holdTimer = 0; currentDirection = WiperPosition.Right; } } else { currentDirection = WiperPosition.Right; } } else { if (RestPosition == WiperPosition.Left) { if (HoldPosition == WiperPosition.Right) { holdTimer += TimeElapsed; if (holdTimer > HoldTime) { holdTimer = 0; currentDirection = WiperPosition.Right; } } else { currentDirection = WiperPosition.Right; } } } break; case 100: if (CurrentSpeed > 0) { if (HoldPosition == WiperPosition.Left && CurrentSpeed != WiperSpeed.Fast) { holdTimer += TimeElapsed; if (holdTimer > HoldTime) { holdTimer = 0; currentDirection = WiperPosition.Left; } } else { currentDirection = WiperPosition.Left; } } else { if (RestPosition == WiperPosition.Right) { if (HoldPosition == WiperPosition.Left) { holdTimer += TimeElapsed; if (holdTimer > HoldTime) { holdTimer = 0; currentDirection = WiperPosition.Left; } } else { currentDirection = WiperPosition.Left; } } } break; //Wiper has started moving, determine which sound effect to play case 1: if (currentDirection == WiperPosition.Right) { if (Windscreen.currentDrops / (double)Windscreen.RainDrops.Length > 0.8) { if (soundTriggered == false) { WetWipeSound.Play(Windscreen.Car, false); soundTriggered = true; } } else { if (soundTriggered == false) { DryWipeSound.Play(Windscreen.Car, false); soundTriggered = true; } } } break; case 99: if (currentDirection == WiperPosition.Left) { if (Windscreen.currentDrops / (double)Windscreen.RainDrops.Length > 0.8) { if (soundTriggered == false) { WetWipeSound.Play(Windscreen.Car, false); soundTriggered = true; } } else { if (soundTriggered == false) { DryWipeSound.Play(Windscreen.Car, false); soundTriggered = true; } } } break; } int dropToRemove = Windscreen.RainDrops.Length - 1 - Math.Min(Windscreen.RainDrops.Length - 1, (int)(CurrentPosition / (100.0 / Windscreen.RainDrops.Length))); if (Windscreen.RainDrops[dropToRemove].Visible) { Windscreen.RainDrops[dropToRemove].Visible = false; Windscreen.RainDrops[dropToRemove].IsSnowFlake = false; Windscreen.RainDrops[dropToRemove].RemainingLife = 0.5 * TrainManagerBase.RandomNumberGenerator.NextDouble() * Windscreen.DropLife; Windscreen.currentDrops--; } }