vonmanager.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. class VONManagerBase : Managed
  2. {
  3. protected bool m_VoNToggled;
  4. ref ScriptInvoker m_OnVonStateEvent;
  5. ref ScriptInvoker m_OnPartyChatChangedEvent;
  6. void VONManagerBase()
  7. {
  8. m_VoNToggled = false;
  9. }
  10. void HideVoiceNotification();
  11. void ShowVoiceNotification(int level, bool fading);
  12. void HandleInput(Input inp);
  13. void OnVOIPThresholdChanged();
  14. void OnEvent(EventType eventTypeId, Param params);
  15. bool IsVonToggled()
  16. {
  17. return m_VoNToggled;
  18. }
  19. }
  20. class VONManagerImplementation : VONManagerBase
  21. {
  22. void VONManagerImplementation()
  23. {
  24. m_OnVonStateEvent = new ScriptInvoker();
  25. m_OnPartyChatChangedEvent = new ScriptInvoker();
  26. }
  27. void ~VONManagerImplementation()
  28. {
  29. m_OnVonStateEvent.Clear();
  30. m_OnPartyChatChangedEvent.Clear();
  31. }
  32. /**
  33. \brief Hides the VON notification completely and immediately
  34. */
  35. override void HideVoiceNotification()
  36. {
  37. if (GetGame().IsMissionMainMenu())
  38. {
  39. return;
  40. }
  41. Mission mission = GetGame().GetMission();
  42. mission.GetMicrophoneIcon().Show(false);
  43. mission.HideVoiceLevelWidgets();
  44. }
  45. /**
  46. \brief Shows the voice notification
  47. \param level the loudness of the player voice. 0 = whisper, 1 = normal, 2 = shout
  48. \param fading specifies whether icon should slowly fade to invisibility after being displayed
  49. */
  50. override void ShowVoiceNotification(int level, bool fading)
  51. {
  52. if (GetGame().IsMissionMainMenu())
  53. {
  54. return;
  55. }
  56. Mission mission = GetGame().GetMission();
  57. ImageWidget micIcon = mission.GetMicrophoneIcon();
  58. WidgetFadeTimer micTimer = mission.GetMicWidgetFadeTimer();
  59. map<int,ImageWidget> voiceLeveWidgets = mission.GetVoiceLevelWidgets();
  60. map<int,ref WidgetFadeTimer> voiceLevelTimers = mission.GetVoiceLevelTimers();
  61. // microphone icon
  62. micTimer.Stop();
  63. micIcon.SetAlpha(1.0);
  64. micIcon.Show(true);
  65. if (fading)
  66. {
  67. micTimer.FadeOut(micIcon, 3.0);
  68. }
  69. // range icons
  70. for( int n = 0; n < voiceLeveWidgets.Count(); n++ )
  71. {
  72. int voiceKey = voiceLeveWidgets.GetKey(n);
  73. ImageWidget voiceWidget = voiceLeveWidgets.Get(n);
  74. // stop fade timer since it will be refreshed
  75. WidgetFadeTimer timer = voiceLevelTimers.Get(n);
  76. timer.Stop();
  77. // show widgets according to the level
  78. if ( voiceKey <= level )
  79. {
  80. voiceWidget.SetAlpha(1.0); // reset from possible previous fade out
  81. voiceWidget.Show(true);
  82. if (fading)
  83. {
  84. timer.FadeOut(voiceWidget, 3.0);
  85. }
  86. }
  87. else
  88. {
  89. voiceWidget.Show(false);
  90. }
  91. }
  92. }
  93. /**
  94. \brief Handles some VON related input
  95. \param inp input to handle
  96. */
  97. override void HandleInput(Input inp)
  98. {
  99. #ifdef PLATFORM_XBOX
  100. // ignore VON-related input if user is in an xbox party
  101. if (GetGame().IsInPartyChat())
  102. {
  103. return;
  104. }
  105. #endif
  106. int oldLevel = GetGame().GetVoiceLevel();
  107. if (oldLevel == -1) //VoN system not initialized!
  108. return;
  109. int newLevel = -1;
  110. if (inp.LocalPress_ID(UAVoiceDistanceUp,false))
  111. {
  112. newLevel = ( oldLevel + 1 ) % ( VoiceLevelShout + 1 );
  113. }
  114. if (inp.LocalPress_ID(UAVoiceDistanceDown,false))
  115. {
  116. newLevel = oldLevel - 1;
  117. if (newLevel < VoiceLevelWhisper) //nah...
  118. {
  119. newLevel = VoiceLevelShout;
  120. }
  121. }
  122. if (newLevel > -1)
  123. {
  124. CGame game = GetGame();
  125. game.SetVoiceLevel(newLevel);
  126. if (game.GetMission().IsVoNActive()) // icon is already visible, just update the range
  127. {
  128. UpdateVoiceIcon();
  129. }
  130. else // Show the icon and let it fade out
  131. {
  132. int level = GetGame().GetVoiceLevel();
  133. ShowVoiceNotification(level, true);
  134. }
  135. }
  136. }
  137. private void UpdateVoiceIcon()
  138. {
  139. Mission mission = GetGame().GetMission();
  140. int rangeLevel = GetGame().GetVoiceLevel();
  141. if (mission.IsVoNActive())
  142. {
  143. if (m_VoNToggled)
  144. {
  145. if (VONManager.IsVoiceThresholdMinimum())
  146. {
  147. ShowVoiceNotification(rangeLevel, false);
  148. }
  149. else
  150. {
  151. ShowVoiceNotification(rangeLevel, true);
  152. }
  153. }
  154. else
  155. {
  156. ShowVoiceNotification(rangeLevel, false);
  157. }
  158. }
  159. else
  160. {
  161. HideVoiceNotification();
  162. }
  163. }
  164. /**
  165. \brief Fires every time VOIP threshold value changes
  166. */
  167. override void OnVOIPThresholdChanged()
  168. {
  169. UpdateVoiceIcon();
  170. }
  171. /**
  172. \brief Handles VON-related events
  173. \param eventTypeId event that fired
  174. \param params event-specific parameters
  175. */
  176. override void OnEvent(EventType eventTypeId, Param params)
  177. {
  178. Mission mission = GetGame().GetMission();
  179. switch (eventTypeId)
  180. {
  181. case VONUserStartedTransmittingAudioEventTypeID:
  182. {
  183. // only handle this if we are in Voice Activation mode, so ignore if in PTT mode
  184. if (m_VoNToggled)
  185. {
  186. if (!VONManager.IsVoiceThresholdMinimum())
  187. {
  188. ShowVoiceNotification(GetGame().GetVoiceLevel(), false);
  189. }
  190. }
  191. break;
  192. }
  193. case VONUserStoppedTransmittingAudioEventTypeID:
  194. {
  195. // only handle this if we are in Voice Activation mode, so ignore if in PTT mode
  196. if (m_VoNToggled)
  197. {
  198. if (!VONManager.IsVoiceThresholdMinimum())
  199. {
  200. HideVoiceNotification();
  201. }
  202. }
  203. break;
  204. }
  205. case VONStateEventTypeID:
  206. {
  207. if (!mission)
  208. {
  209. break;
  210. }
  211. VONStateEventParams vonStateParams = VONStateEventParams.Cast( params );
  212. mission.SetVoNActive(vonStateParams.param1);
  213. m_VoNToggled = vonStateParams.param2;
  214. UpdateVoiceIcon();
  215. m_OnVonStateEvent.Invoke();
  216. break;
  217. }
  218. case PartyChatStatusChangedEventTypeID:
  219. {
  220. m_OnPartyChatChangedEvent.Invoke();
  221. break;
  222. }
  223. case VONStartSpeakingEventTypeID:
  224. {
  225. VONStartSpeakingEventParams vonStartParams;
  226. if (Class.CastTo(vonStartParams, params))
  227. {
  228. GetDayZGame().AddVoiceNotification(vonStartParams);
  229. }
  230. break;
  231. }
  232. case VONStopSpeakingEventTypeID:
  233. {
  234. VONStopSpeakingEventParams vonStopParams;
  235. if (Class.CastTo(vonStopParams, params))
  236. {
  237. GetDayZGame().RemoveVoiceNotification(vonStopParams);
  238. }
  239. break;
  240. }
  241. case MPSessionPlayerReadyEventTypeID:
  242. {
  243. UpdateVoiceIcon();
  244. break;
  245. }
  246. }
  247. }
  248. }
  249. //! Manager class which handles Voice-over-network functionality while player is connected to a server
  250. class VONManager
  251. {
  252. private static ref VONManagerBase m_VONManager = new VONManagerBase();
  253. /**
  254. \brief Main way to access VONManager functionality from script
  255. \return \p Instance of VONManagerImplementation if logged on to server, or VONManagerBase otherwise
  256. */
  257. static VONManagerBase GetInstance()
  258. {
  259. return m_VONManager;
  260. }
  261. /**
  262. \brief Initializes VONManager, runs when user first connects to a server
  263. */
  264. static void Init()
  265. {
  266. delete m_VONManager;
  267. m_VONManager = new VONManagerImplementation();
  268. }
  269. /**
  270. \brief Uninitializes VONManager, runs when user disconnects from server
  271. */
  272. static void CleanupInstance()
  273. {
  274. delete m_VONManager;
  275. m_VONManager = new VONManagerBase();
  276. }
  277. /**
  278. \brief Specifies whether VON mode is toggled or not
  279. \return \p True if in Voice Activation mode, False if in Push-to-Talk mode
  280. */
  281. static bool IsVONToggled()
  282. {
  283. return m_VONManager.IsVonToggled();
  284. }
  285. /**
  286. \brief Specifies whether user's voice activation threshold value is equal to the minimum voice activation threshold value
  287. \return \p True if threshold minimum, false otherwise
  288. */
  289. static bool IsVoiceThresholdMinimum()
  290. {
  291. GameOptions gameOptions = new GameOptions();
  292. NumericOptionsAccess noa;
  293. Class.CastTo(noa, gameOptions.GetOptionByType( OptionAccessType.AT_OPTIONS_VON_THRESHOLD_SLIDER ));
  294. return noa.ReadValue() <= GetGame().GetSoundScene().GetSilenceThreshold();
  295. }
  296. }