MissionSoundBase.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #include "MissionSoundBase.h"
  2. MissionSoundBase::MissionSoundBase() : sounds(_FL_)
  3. {
  4. fadeInTime = 0.0f;
  5. fadeOutTime = 0.0f;
  6. }
  7. MissionSoundBase::~MissionSoundBase()
  8. {
  9. Release();
  10. }
  11. //Активировать
  12. void MissionSoundBase::Activate(bool isActive)
  13. {
  14. // bool old = IsActive();
  15. // if(isActive == old) return;
  16. MissionObject::Activate(isActive);
  17. if(isActive)
  18. {
  19. for(long i = 0; i < sounds; i++)
  20. {
  21. SoundElement & se = sounds[i];
  22. if(se.sound)
  23. {
  24. se.sound->Stop();
  25. }
  26. se.waitTime = se.minTime + Rnd(se.maxTime);
  27. se.states &= ~s_stoped;
  28. }
  29. SetUpdate(&MissionSoundBase::Work, ML_POSTEFFECTS - 10);
  30. LogicDebug("Activate");
  31. }else{
  32. DelUpdate(&MissionSoundBase::Work);
  33. for(long i = 0; i < sounds; i++)
  34. {
  35. SoundElement & se = sounds[i];
  36. if(!se.sound) continue;
  37. se.sound->FadeOut(fadeOutTime);
  38. }
  39. LogicDebug("Deactivate");
  40. }
  41. }
  42. //Пересоздать объект
  43. void MissionSoundBase::Restart()
  44. {
  45. ReCreate();
  46. }
  47. #ifndef MIS_STOP_EDIT_FUNCS
  48. //Перевести объект в спящий режим
  49. void MissionSoundBase::EditMode_Sleep(bool isSleep)
  50. {
  51. if(isSleep)
  52. {
  53. bool curState = IsActive();
  54. Activate(false);
  55. MissionObject::Activate(curState);
  56. }else{
  57. Activate(IsActive());
  58. }
  59. }
  60. //Получить размеры описывающего ящика
  61. void MissionSoundBase::EditMode_Select(bool isSelect)
  62. {
  63. bool current = EditMode_IsSelect();
  64. MissionObject::EditMode_Select(isSelect);
  65. if(isSelect && !current)
  66. {
  67. PreviewStart();
  68. }else{
  69. Stop();
  70. }
  71. }
  72. #endif
  73. //Работа
  74. void _cdecl MissionSoundBase::Work(float dltTime, long level)
  75. {
  76. Update(dltTime);
  77. }
  78. //Инициализировать объект
  79. bool MissionSoundBase::CreateSounds(MOPReader & reader, const Vector * pos)
  80. {
  81. Release();
  82. long counter = reader.Array();
  83. for(long i = 0; i < counter; i++)
  84. {
  85. long n = i;
  86. if(n >= sounds)
  87. {
  88. n = sounds.Add();
  89. sounds[n].sound = null;
  90. }
  91. SoundElement & se = sounds[n];
  92. ConstString name = reader.String();
  93. se.volume = reader.Float();
  94. se.minTime = reader.Float();
  95. se.maxTime = reader.Float();
  96. se.minTime = coremax(se.minTime, 0);
  97. se.maxTime = coremax(se.maxTime, se.minTime);
  98. se.waitTime = Rnd(se.maxTime);
  99. se.states = reader.Bool() ? s_periodical : 0;
  100. if(reader.Bool())
  101. {
  102. //Если звук включён, то создаём его
  103. if(se.sound)
  104. {
  105. if(!string::IsEqual(name.c_str(), se.sound->GetName()))
  106. {
  107. se.sound->Release();
  108. se.sound = null;
  109. }
  110. }
  111. if(!se.sound)
  112. {
  113. if(pos)
  114. {
  115. se.sound = Sound().Create3D(name, *pos, _FL_, false, false);
  116. }else{
  117. se.sound = Sound().Create(name, _FL_, false, false);
  118. }
  119. }
  120. }else{
  121. if(se.sound)
  122. {
  123. se.sound->Release();
  124. se.sound = null;
  125. }
  126. }
  127. }
  128. float vol = reader.Float();
  129. for(long i = 0; i < sounds; i++)
  130. {
  131. SoundElement & se = sounds[i];
  132. se.volume *= vol;
  133. if(se.sound)
  134. {
  135. se.sound->SetVolume(se.volume);
  136. }
  137. }
  138. fadeInTime = reader.Float();
  139. fadeOutTime = reader.Float();
  140. Activate(reader.Bool());
  141. return sounds > 0;
  142. }
  143. //Обновить состояние счётчиков и звуков
  144. void MissionSoundBase::Update(float dltTime)
  145. {
  146. if(EditMode_IsOn() && !EditMode_IsSelect())
  147. {
  148. return;
  149. }
  150. for(long i = 0; i < sounds; i++)
  151. {
  152. SoundElement & se = sounds[i];
  153. if(!se.sound) continue;
  154. if(se.states & s_stoped) continue;
  155. if(se.sound->IsPlay()) continue;
  156. se.waitTime -= dltTime;
  157. if(se.waitTime > 0.0f) continue;
  158. if((se.states & s_periodical) == 0 && !se.sound->IsLoop())
  159. {
  160. se.states |= s_stoped;
  161. }
  162. se.waitTime = se.minTime + Rnd(se.maxTime - se.minTime);
  163. se.sound->FadeIn(fadeInTime);
  164. }
  165. }
  166. //Обновить позицию
  167. void MissionSoundBase::UpdatePosition(const Vector & pos)
  168. {
  169. for(long i = 0; i < sounds; i++)
  170. {
  171. SoundElement & se = sounds[i];
  172. if(!se.sound) continue;
  173. ((ISound3D *)se.sound)->SetPosition(pos);
  174. }
  175. }
  176. //Обновить громкость
  177. void MissionSoundBase::UpdateVolumes(float vol)
  178. {
  179. for(long i = 0; i < sounds; i++)
  180. {
  181. SoundElement & se = sounds[i];
  182. if(!se.sound) continue;
  183. ((ISound3D *)se.sound)->SetVolume(se.volume*vol);
  184. }
  185. }
  186. //Запустить последовательное проигрывание звуков
  187. void MissionSoundBase::PreviewStart()
  188. {
  189. for(long i = 0; i < sounds; i++)
  190. {
  191. sounds[i].waitTime = i*1.0f;
  192. }
  193. }
  194. //Остановить проигрывание звуков
  195. void MissionSoundBase::Stop()
  196. {
  197. for(long i = 0; i < sounds; i++)
  198. {
  199. SoundElement & se = sounds[i];
  200. if(!se.sound) continue;
  201. se.sound->Stop();
  202. }
  203. }
  204. //Приостановить проигрывание звуков с фэйдом
  205. void MissionSoundBase::Fadeout()
  206. {
  207. for(long i = 0; i < sounds; i++)
  208. {
  209. SoundElement & se = sounds[i];
  210. if(!se.sound) continue;
  211. se.sound->FadeOut(fadeOutTime);
  212. }
  213. }
  214. //Удалить все звуки
  215. void MissionSoundBase::Release()
  216. {
  217. for(long i = 0; i < sounds; i++)
  218. {
  219. SoundElement & se = sounds[i];
  220. if(!se.sound) continue;
  221. se.sound->Release();
  222. se.sound = null;
  223. }
  224. sounds.DelAll();
  225. }