1 using OpenBveApi; 2 using OpenBveApi.Math; 3 using SoundManager; 4 using TrainManager.Car; 5 6 namespace TrainManager.Trains 7 { 8 /// <summary>Represents a horn or whistle</summary> 9 public class Horn 10 { 11 /// <summary>The sound source for this horn</summary> 12 public SoundSource Source; 13 /// <summary>The sound buffer to be played once when playback commences</summary> 14 public SoundBuffer StartSound; 15 /// <summary>The loop sound</summary> 16 public SoundBuffer LoopSound; 17 /// <summary>The sound buffer to be played once when playback ends</summary> 18 public SoundBuffer EndSound; 19 /// <summary>The position of the sound within the train car</summary> 20 public Vector3 SoundPosition; 21 /// <summary>Whether this horn has start and end sounds, or uses the legacy loop/ stretch method</summary> 22 public bool StartEndSounds; 23 /// <summary>Stores whether the sound is looped or stretched when using the legacy method</summary> 24 public bool Loop; 25 /// <summary>Stores the loop state</summary> 26 private bool LoopStarted; 27 /// <summary>Holds a reference to the base car</summary> 28 public readonly CarBase baseCar; 29 30 /// <summary>The default constructor</summary> Horn(CarBase car)31 public Horn(CarBase car) 32 { 33 this.StartSound = null; 34 this.LoopSound = null; 35 this.EndSound = null; 36 this.Loop = false; 37 this.baseCar = car; 38 } 39 Horn(SoundBuffer startSound, SoundBuffer loopSound, SoundBuffer endSound, bool loop, CarBase car)40 public Horn(SoundBuffer startSound, SoundBuffer loopSound, SoundBuffer endSound, bool loop, CarBase car) 41 { 42 this.Source = null; 43 this.StartSound = startSound; 44 this.LoopSound = loopSound; 45 this.EndSound = endSound; 46 this.Loop = loop; 47 this.StartEndSounds = false; 48 this.LoopStarted = false; 49 this.SoundPosition = new Vector3(); 50 this.baseCar = car; 51 } 52 53 /// <summary>Called by the controls loop to start playback of this horn</summary> Play()54 public void Play() 55 { 56 if (TrainManagerBase.currentHost.SimulationState == SimulationState.MinimalisticSimulation) 57 { 58 return; 59 } 60 61 if (StartEndSounds) 62 { 63 //New style three-part sounds 64 if (LoopStarted == false) 65 { 66 if (!TrainManagerBase.currentHost.SoundIsPlaying(Source)) 67 { 68 if (StartSound != null) 69 { 70 //The start sound is not currently playing, so start it 71 Source = (SoundSource)TrainManagerBase.currentHost.PlaySound(StartSound, 1.0, 1.0, SoundPosition, baseCar, false); 72 73 //Set the loop control variable to started 74 LoopStarted = true; 75 } 76 else 77 { 78 if (LoopSound != null) 79 { 80 Source = (SoundSource)TrainManagerBase.currentHost.PlaySound(LoopSound, 1.0, 1.0, SoundPosition, baseCar, true); 81 } 82 } 83 } 84 } 85 else 86 { 87 if (!TrainManagerBase.currentHost.SoundIsPlaying(Source) && LoopSound != null) 88 { 89 //Start our loop sound playing if the start sound is finished 90 Source = (SoundSource)TrainManagerBase.currentHost.PlaySound(LoopSound, 1.0, 1.0, SoundPosition, baseCar, true); 91 } 92 } 93 } 94 else 95 { 96 //Original single part sounds 97 if (LoopSound != null) 98 { 99 //Loop is ONLY true if this is a Music Horn 100 if (Loop) 101 { 102 if (!TrainManagerBase.currentHost.SoundIsPlaying(Source) && !LoopStarted) 103 { 104 //On the first keydown event, start the sound source playing and trigger the loop control variable 105 Source = (SoundSource)TrainManagerBase.currentHost.PlaySound(LoopSound, 1.0, 1.0, SoundPosition, 106 baseCar, true); 107 LoopStarted = true; 108 } 109 else 110 { 111 if (!LoopStarted) 112 { 113 //Our loop control variable is reset by the keyup event so this code will only trigger on the 114 //second keydown meaning our horn toggles 115 TrainManagerBase.currentHost.StopSound(Source); 116 LoopStarted = true; 117 } 118 } 119 } 120 else 121 { 122 if (!LoopStarted) 123 { 124 Source = (SoundSource)TrainManagerBase.currentHost.PlaySound(LoopSound, 1.0, 1.0, SoundPosition, baseCar, false); 125 } 126 127 LoopStarted = true; 128 } 129 } 130 } 131 132 } 133 134 /// <summary>Called by the controls loop to stop playback of this horn</summary> Stop()135 public void Stop() 136 { 137 //Reset loop control variable 138 LoopStarted = false; 139 if (!StartEndSounds & !Loop) 140 { 141 //Don't stop horns which are play-once single part sounds 142 return; 143 } 144 145 if (!StartEndSounds & Loop) 146 { 147 //This sound is a toggle music horn sound 148 return; 149 } 150 151 if (TrainManagerBase.currentHost.SoundIsPlaying(Source)) 152 { 153 //Stop the loop sound playing 154 TrainManagerBase.currentHost.StopSound(Source); 155 } 156 157 if (StartEndSounds && !TrainManagerBase.currentHost.SoundIsPlaying(Source) && EndSound != null) 158 { 159 //If our end sound is defined and in use, play once 160 Source =(SoundSource)TrainManagerBase.currentHost.PlaySound(EndSound, 1.0, 1.0, SoundPosition, baseCar, false); 161 } 162 } 163 } 164 } 165