1 using System; 2 using System.ComponentModel; 3 using System.Linq; 4 using OpenBveApi.Interface; 5 using SoundManager; 6 using TrainEditor2.Systems; 7 8 namespace TrainEditor2.Models.Trains 9 { 10 internal partial class Motor 11 { StartSimulation()12 internal void StartSimulation() 13 { 14 try 15 { 16 CreateCar(); 17 } 18 catch (Exception e) 19 { 20 Interface.AddMessage(MessageType.Error, false, $"{e.GetType().FullName}: {e.Message} at {e.StackTrace}"); 21 CurrentSimState = SimulationState.Disable; 22 return; 23 } 24 25 if (Simulation.TrainManager.TrainManager.PlayerTrain == null) 26 { 27 Interface.AddMessage(MessageType.Error, false, "Failed to create train."); 28 CurrentSimState = SimulationState.Disable; 29 return; 30 } 31 32 oldElapsedTime = 0; 33 startTime = DateTime.Now; 34 35 if (CurrentSimState != SimulationState.Paused) 36 { 37 nowSpeed = StartSpeed; 38 } 39 40 CurrentSimState = SimulationState.Started; 41 } 42 PauseSimulation()43 internal void PauseSimulation() 44 { 45 DisposeCar(); 46 CurrentSimState = SimulationState.Paused; 47 } 48 StopSimulation()49 internal void StopSimulation() 50 { 51 DisposeCar(); 52 CurrentSimState = SimulationState.Stopped; 53 54 IsRefreshGlControl = true; 55 } 56 CreateCar()57 private void CreateCar() 58 { 59 DisposeCar(); 60 61 Simulation.TrainManager.TrainManager.PlayerTrain = new Simulation.TrainManager.TrainManager.Train(); 62 Simulation.TrainManager.TrainManager.PlayerTrain.Car.Sounds.Motor.SpeedConversionFactor = 18.0; 63 Simulation.TrainManager.TrainManager.PlayerTrain.Car.Sounds.Motor.Tables = Tracks.Select(t => Track.EntriesToMotorSoundTable(Track.TrackToEntries(t))).ToArray(); 64 Simulation.TrainManager.TrainManager.PlayerTrain.Car.ApplySounds(); 65 } 66 RunSimulation()67 internal void RunSimulation() 68 { 69 if (Simulation.TrainManager.TrainManager.PlayerTrain == null) 70 { 71 return; 72 } 73 74 double nowElapsedTime = (DateTime.Now - startTime).TotalSeconds; 75 76 if (oldElapsedTime == 0.0) 77 { 78 oldElapsedTime = nowElapsedTime; 79 } 80 81 double deltaTime = nowElapsedTime - oldElapsedTime; 82 83 double outputAcceleration = Math.Sign(endSpeed - startSpeed) * Acceleration; 84 85 nowSpeed += outputAcceleration * deltaTime; 86 double minSpeed = Math.Min(startSpeed, endSpeed); 87 double maxSpeed = Math.Max(startSpeed, endSpeed); 88 89 if (IsLoop) 90 { 91 if (nowSpeed < minSpeed) 92 { 93 nowSpeed = maxSpeed; 94 outputAcceleration = 0.0; 95 } 96 97 if (nowSpeed > maxSpeed) 98 { 99 nowSpeed = minSpeed; 100 outputAcceleration = 0.0; 101 } 102 103 if (IsConstant) 104 { 105 nowSpeed = startSpeed; 106 outputAcceleration = Math.Sign(endSpeed - startSpeed) * acceleration; 107 } 108 } 109 else 110 { 111 if (nowSpeed < minSpeed || nowSpeed > maxSpeed) 112 { 113 StopSimulation(); 114 return; 115 } 116 } 117 118 Simulation.TrainManager.TrainManager.PlayerTrain.Car.CurrentSpeed = Simulation.TrainManager.TrainManager.PlayerTrain.Car.Specs.PerceivedSpeed = nowSpeed / 3.6; 119 Simulation.TrainManager.TrainManager.PlayerTrain.Car.Specs.Acceleration = outputAcceleration / 3.6; 120 121 Simulation.TrainManager.TrainManager.PlayerTrain.Car.UpdateRunSounds(deltaTime, RunIndex); 122 123 Simulation.TrainManager.TrainManager.PlayerTrain.Car.UpdateMotorSounds(IsPlayTrack1, IsPlayTrack2); 124 125 Program.SoundApi.Update(deltaTime, SoundModels.Inverse); 126 127 oldElapsedTime = nowElapsedTime; 128 129 DrawSimulation(); 130 } 131 DrawSimulation()132 internal void DrawSimulation() 133 { 134 double rangeVelocity = MaxVelocity - MinVelocity; 135 136 if (StartSpeed <= EndSpeed) 137 { 138 if (nowSpeed < MinVelocity || nowSpeed > MaxVelocity) 139 { 140 minVelocity = 10.0 * Math.Round(0.1 * nowSpeed); 141 142 if (MinVelocity < 0.0) 143 { 144 minVelocity = 0.0; 145 } 146 147 maxVelocity = MinVelocity + rangeVelocity; 148 149 OnPropertyChanged(new PropertyChangedEventArgs(nameof(MinVelocity))); 150 OnPropertyChanged(new PropertyChangedEventArgs(nameof(MaxVelocity))); 151 152 return; 153 } 154 } 155 else 156 { 157 if (nowSpeed < MinVelocity || nowSpeed > MaxVelocity) 158 { 159 maxVelocity = 10.0 * Math.Round(0.1 * nowSpeed); 160 161 if (MaxVelocity < rangeVelocity) 162 { 163 maxVelocity = rangeVelocity; 164 } 165 166 minVelocity = MaxVelocity - rangeVelocity; 167 168 OnPropertyChanged(new PropertyChangedEventArgs(nameof(MinVelocity))); 169 OnPropertyChanged(new PropertyChangedEventArgs(nameof(MaxVelocity))); 170 171 return; 172 } 173 } 174 175 IsRefreshGlControl = true; 176 } 177 DisposeCar()178 private void DisposeCar() 179 { 180 if (Simulation.TrainManager.TrainManager.PlayerTrain != null) 181 { 182 Simulation.TrainManager.TrainManager.PlayerTrain.Dispose(); 183 Simulation.TrainManager.TrainManager.PlayerTrain = null; 184 } 185 } 186 } 187 } 188