gameplayeffectwidgets.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. /*
  2. TODO - doxygen formating
  3. */
  4. //! grouped gameplay effect widgets and their handling
  5. class GameplayEffectWidgets extends GameplayEffectWidgets_base
  6. {
  7. protected ref Widget m_Root; //dummy parent node
  8. protected ref map<int,ref Widget> m_Layouts;
  9. protected ref set<ref Widget> m_UniqueLayouts;
  10. protected ref GameplayEffectDataMap m_WidgetDataMap;
  11. protected ref set<int> m_RunningEffects;
  12. protected ref set<int> m_RunningEffectsPrevious;
  13. protected ref array<int> m_UpdatingEffects;
  14. protected ref array<ref Widget> m_UpdatedWidgetsCheck; //to make sure widgets are not updated over and over (case of multiple IDs sharing same widget set)
  15. protected ref array<int> m_UpdatedWidgetSetsCheck; //to make sure sets are not updated over and over (case of multiple IDs sharing same widget set)
  16. protected ref set<int> m_SuspendRequests;
  17. protected ref map<int,typename> m_IDToTypeMap;
  18. protected float m_TimeProgBreath;
  19. protected float m_BreathMultStamina;
  20. protected float m_BreathResidue;
  21. //UserID's for widget containers that use something different from 'EffectWidgetsTypes' defaults
  22. protected const int WIDGETSET_BREATH = 100;
  23. //effect values
  24. protected int m_BreathColor;
  25. protected float m_BreathAlphaVal;
  26. protected float m_FlashbangCoverAlphaVal;
  27. void GameplayEffectWidgets()
  28. {
  29. m_Root = GetGame().GetWorkspace().CreateWidget(FrameWidgetTypeID,0,0,1.0,1.0,WidgetFlags.VISIBLE | WidgetFlags.HEXACTPOS | WidgetFlags.VEXACTPOS, 0xffffffff, 0);
  30. m_Layouts = new map<int,ref Widget>;
  31. m_UniqueLayouts = new set<ref Widget>;
  32. m_WidgetDataMap = new GameplayEffectDataMap;
  33. m_RunningEffects = new set<int>;
  34. m_RunningEffectsPrevious = new set<int>;
  35. m_UpdatingEffects = new array<int>;
  36. m_UpdatedWidgetsCheck = new array<ref Widget>;
  37. m_UpdatedWidgetSetsCheck = new array<int>;
  38. m_SuspendRequests = new set<int>;
  39. m_IDToTypeMap = new map<int,typename>;
  40. m_TimeProgBreath = 0.0;
  41. m_BreathMultStamina = 1.0;
  42. Init();
  43. UpdateVisibility();
  44. }
  45. void ~GameplayEffectWidgets()
  46. {
  47. for (int i = 0; i < m_Layouts.Count(); i++)
  48. {
  49. if (m_Layouts.GetElement(i))
  50. m_Layouts.GetElement(i).Unlink();
  51. }
  52. }
  53. ////////////////////////////////////
  54. //inits
  55. protected void Init()
  56. {
  57. PairIDToTypes();
  58. InitLayouts();
  59. InitWidgetSets();
  60. }
  61. //! Links types to unique handler types, if needed. Vanilla stuff was already handled in the generic update, left that as it was. (naming!)
  62. protected void PairIDToTypes()
  63. {
  64. m_IDToTypeMap.Insert(EffectWidgetsTypes.BLEEDING_LAYER,GameplayEffectsDataBleeding);
  65. }
  66. protected void InitLayouts()
  67. {
  68. RegisterLayouts("gui/layouts/gameplay/CameraEffects.layout",CompileEffectListing());
  69. RegisterLayouts("gui/layouts/gameplay/BleedingEffects.layout",{EffectWidgetsTypes.BLEEDING_LAYER});
  70. }
  71. protected void InitWidgetSets()
  72. {
  73. InitWidgetSet(EffectWidgetsTypes.MASK_BREATH,true,WIDGETSET_BREATH);
  74. InitWidgetSet(EffectWidgetsTypes.HELMET_BREATH,true,WIDGETSET_BREATH);
  75. InitWidgetSet(EffectWidgetsTypes.MOTO_BREATH,true,WIDGETSET_BREATH);
  76. InitWidgetSet(EffectWidgetsTypes.MASK_OCCLUDER);
  77. InitWidgetSet(EffectWidgetsTypes.HELMET_OCCLUDER);
  78. InitWidgetSet(EffectWidgetsTypes.HELMET2_OCCLUDER);
  79. InitWidgetSet(EffectWidgetsTypes.MOTO_OCCLUDER);
  80. InitWidgetSet(EffectWidgetsTypes.NVG_OCCLUDER);
  81. InitWidgetSet(EffectWidgetsTypes.PUMPKIN_OCCLUDER,false,EffectWidgetsTypes.NVG_OCCLUDER);
  82. InitWidgetSet(EffectWidgetsTypes.EYEPATCH_OCCLUDER);
  83. InitWidgetSet(EffectWidgetsTypes.COVER_FLASHBANG);
  84. InitWidgetSet(EffectWidgetsTypes.BLEEDING_LAYER,true);
  85. }
  86. ////////////////////////////////////
  87. /**
  88. \brief Registers new layout and ties effect IDs to it
  89. \note Order of layout creation matters, they get layered on top of each other. Within a single layout, widget priorities govern the widget order.
  90. */
  91. protected void RegisterLayouts(string path, array<int> types)
  92. {
  93. Widget w = GetGame().GetWorkspace().CreateWidgets(path,m_Root,false);
  94. m_UniqueLayouts.Insert(w);
  95. w.Show(false);
  96. foreach (int i : types)
  97. {
  98. m_Layouts.Set(i,w);
  99. }
  100. }
  101. protected typename TranslateIDToType(int typeID)
  102. {
  103. return m_IDToTypeMap.Get(typeID);
  104. }
  105. override void RegisterGameplayEffectData(int id, Param p)
  106. {
  107. if (!m_WidgetDataMap.Get(id).DataInitialized())
  108. {
  109. m_WidgetDataMap.Get(id).RegisterData(p);
  110. }
  111. }
  112. /**
  113. \brief InitWidgetSet
  114. \param type \p int ID of effect widget type
  115. \param updating \p bool Marks widgets for 'PlayerBase.EOnFrame' updating
  116. \param user_id_override \p int UserID of a widget to be used instead (allows multiple types to use single widget)
  117. @code
  118. InitWidgetSet(EffectWidgetsTypes.MASK_BREATH,true,BREATH);
  119. @endcode
  120. \note All child widgets MUST be of the same type if special functionality is required (ImageWidget etc.)
  121. */
  122. protected void InitWidgetSet(int type, bool updating = false, int user_id_override = -1)
  123. {
  124. Widget parent = null;
  125. if (user_id_override != -1)
  126. {
  127. parent = m_Layouts.Get(type).FindAnyWidgetById(user_id_override);
  128. }
  129. else
  130. {
  131. parent = m_Layouts.Get(type).FindAnyWidgetById(type);
  132. }
  133. if (!parent)
  134. {
  135. Print("InitWidgetSet | type: " + type + " - parent not found!");
  136. return;
  137. }
  138. array<ref Widget> output;
  139. Widget w = parent.GetChildren();
  140. if (w)
  141. {
  142. output = new array<ref Widget>;
  143. while (w)
  144. {
  145. w.Update();
  146. w.Show(false,true);
  147. output.Insert(w);
  148. w = w.GetSibling();
  149. }
  150. if (parent.GetChildren())
  151. {
  152. typename handled_type = TranslateIDToType(type);
  153. if ( handled_type )
  154. {
  155. CreateHandledClass(handled_type,output,type,user_id_override);
  156. }
  157. else
  158. {
  159. if (ImageWidget.Cast(parent.GetChildren()))
  160. {
  161. m_WidgetDataMap.Set(type, new GameplayEffectsDataImage(output,type,user_id_override) );
  162. }
  163. else
  164. {
  165. m_WidgetDataMap.Set(type, new GameplayEffectsData(output,type,user_id_override) );
  166. }
  167. }
  168. }
  169. if (updating)
  170. m_UpdatingEffects.Insert(type);
  171. }
  172. }
  173. bool CreateHandledClass(typename handled_type, array<ref Widget> input, int type, int user_override)
  174. {
  175. if (handled_type)
  176. {
  177. GameplayEffectsData data = GameplayEffectsData.Cast(handled_type.Spawn());
  178. data.Init(input,type,m_Layouts.Get(type),user_override);
  179. m_WidgetDataMap.Set(type, data);
  180. return true;
  181. }
  182. return false;
  183. }
  184. //! returns all vanilla effects, nested in a vanilla layout. If using different layouts for custom effects, please register and link separately
  185. array<int> CompileEffectListing()
  186. {
  187. array<int> ret = new array<int>;
  188. ret.Insert(EffectWidgetsTypes.MASK_OCCLUDER);
  189. ret.Insert(EffectWidgetsTypes.MASK_BREATH);
  190. ret.Insert(EffectWidgetsTypes.HELMET_OCCLUDER);
  191. ret.Insert(EffectWidgetsTypes.HELMET_BREATH);
  192. ret.Insert(EffectWidgetsTypes.MOTO_OCCLUDER);
  193. ret.Insert(EffectWidgetsTypes.MOTO_BREATH);
  194. ret.Insert(EffectWidgetsTypes.COVER_FLASHBANG);
  195. ret.Insert(EffectWidgetsTypes.NVG_OCCLUDER);
  196. ret.Insert(EffectWidgetsTypes.PUMPKIN_OCCLUDER);
  197. ret.Insert(EffectWidgetsTypes.EYEPATCH_OCCLUDER);
  198. ret.Insert(EffectWidgetsTypes.HELMET2_OCCLUDER);
  199. return ret;
  200. }
  201. protected void UpdateVisibility()
  202. {
  203. Widget w;
  204. //Hide diff
  205. int value;
  206. int runningEffectCount = m_RunningEffects.Count();
  207. bool runningEffectsPresent = runningEffectCount > 0;
  208. GameplayEffectsData dta;
  209. for (int i = 0; i < m_RunningEffectsPrevious.Count(); i++)
  210. {
  211. value = m_RunningEffectsPrevious.Get(i);
  212. dta = m_WidgetDataMap.Get(value);
  213. if (runningEffectCount < 1 || m_RunningEffects.Find(value) == -1)
  214. {
  215. if (dta.HasDefinedHandle())
  216. {
  217. dta.UpdateVisibility(false);
  218. }
  219. else
  220. {
  221. for (int j = 0; j < m_WidgetDataMap.Get(value).GetWidgetSet().Count(); j++)
  222. {
  223. w = m_WidgetDataMap.Get(value).GetWidgetSet().Get(j);
  224. w.Show(false);
  225. }
  226. w.GetParent().Show(false);
  227. }
  228. }
  229. }
  230. //Show running effects
  231. if (runningEffectsPresent)
  232. {
  233. value = 0;
  234. for (i = 0; i < runningEffectCount; i++)
  235. {
  236. value = m_RunningEffects.Get(i);
  237. dta = m_WidgetDataMap.Get(value);
  238. if (dta.HasDefinedHandle())
  239. {
  240. dta.m_LayoutRoot.Show(true);
  241. dta.UpdateVisibility(true);
  242. }
  243. else
  244. {
  245. for (j = 0; j < m_WidgetDataMap.Get(value).GetWidgetSet().Count(); j++)
  246. {
  247. w = m_WidgetDataMap.Get(value).GetWidgetSet().Get(j);
  248. w.Update();
  249. w.Show(true);
  250. }
  251. while (w) //dumb but necessary because of uncertain "visible" setting of the layout
  252. {
  253. w = w.GetParent();
  254. if (w)
  255. {
  256. w.Show(true);
  257. }
  258. }
  259. }
  260. }
  261. }
  262. m_Root.Show(runningEffectsPresent && m_SuspendRequests.Count() < 1);
  263. m_RunningEffectsPrevious.Clear();
  264. }
  265. override void AddActiveEffects(array<int> effects)
  266. {
  267. if (effects && effects.Count() > 0)
  268. {
  269. m_RunningEffectsPrevious.Copy(m_RunningEffects);
  270. int value;
  271. for (int i = 0; i < effects.Count(); i++)
  272. {
  273. value = effects.Get(i);
  274. m_RunningEffects.Insert(value);
  275. }
  276. if (m_RunningEffectsPrevious.Count() != m_RunningEffects.Count())
  277. {
  278. UpdateVisibility();
  279. }
  280. }
  281. }
  282. override void RemoveActiveEffects(array<int> effects)
  283. {
  284. if (effects && effects.Count() > 0)
  285. {
  286. m_RunningEffectsPrevious.Copy(m_RunningEffects);
  287. int count = effects.Count();
  288. int value;
  289. int idx;
  290. for (int i = 0; i < count; ++i)
  291. {
  292. value = effects.Get(i);
  293. idx = m_RunningEffects.Find(value);
  294. if (idx != -1)
  295. {
  296. m_RunningEffects.Remove(idx);
  297. }
  298. }
  299. if (m_RunningEffectsPrevious.Count() != m_RunningEffects.Count())
  300. {
  301. UpdateVisibility();
  302. }
  303. }
  304. }
  305. override void StopAllEffects()
  306. {
  307. m_Root.Show(false); //to avoid visual 'peeling'
  308. if (IsAnyEffectRunning())
  309. {
  310. int count = m_RunningEffects.Count();
  311. GameplayEffectsData data;
  312. for (int i = 0; i < count; i++) //iterates over running metadata, in case anything requires its own stop handling
  313. {
  314. data = m_WidgetDataMap.Get(m_RunningEffects[i]);
  315. data.ForceStop();
  316. }
  317. }
  318. m_RunningEffectsPrevious.Copy(m_RunningEffects);
  319. m_RunningEffects.Clear();
  320. UpdateVisibility();
  321. }
  322. override bool IsAnyEffectRunning()
  323. {
  324. return m_RunningEffects && m_RunningEffects.Count() > 0;
  325. }
  326. override void AddSuspendRequest(int request_id)
  327. {
  328. m_SuspendRequests.Insert(request_id);
  329. UpdateVisibility();
  330. }
  331. override void RemoveSuspendRequest(int request_id)
  332. {
  333. int idx = m_SuspendRequests.Find(request_id);
  334. if (idx != -1)
  335. {
  336. m_SuspendRequests.Remove(idx);
  337. }
  338. UpdateVisibility();
  339. }
  340. override void ClearSuspendRequests()
  341. {
  342. m_SuspendRequests.Clear();
  343. UpdateVisibility();
  344. }
  345. override int GetSuspendRequestCount()
  346. {
  347. return m_SuspendRequests.Count();
  348. }
  349. //! Usually called in course of an OnFrame update, can be manually called from elsewhere with parameters
  350. override void UpdateWidgets(int type = -1, float timeSlice = 0, Param p = null, int handle = -1)
  351. {
  352. GameplayEffectsData dta;
  353. array<ref Widget> widget_set;
  354. if (type == EffectWidgetsTypes.ROOT)
  355. {
  356. HandleWidgetRoot(timeSlice,p,handle);
  357. }
  358. else if (type == -1) //update stuff from the m_UpdatingEffects
  359. {
  360. int type_widgetset = 0;
  361. for (int i = 0; i < m_UpdatingEffects.Count(); i++)
  362. {
  363. if (m_RunningEffects.Find(m_UpdatingEffects.Get(i)) != -1)
  364. {
  365. type_widgetset = m_UpdatingEffects.Get(i);
  366. dta = m_WidgetDataMap.Get(type_widgetset);
  367. if (dta.HasDefinedHandle() && dta.DataInitialized())
  368. {
  369. dta.Update(timeSlice,p,handle); //calculate and apply
  370. }
  371. else
  372. {
  373. CalculateValues(type_widgetset,timeSlice,p,handle);
  374. widget_set = dta.GetWidgetSet();
  375. foreach (Widget w : widget_set)
  376. {
  377. if (w.IsVisibleHierarchy() && m_UpdatedWidgetsCheck.Find(w) == -1)
  378. {
  379. m_UpdatedWidgetsCheck.Insert(w);
  380. ProcessWidgetUpdate(w,type_widgetset,timeSlice,p,handle);
  381. }
  382. }
  383. }
  384. }
  385. }
  386. }
  387. else //update specific widget set
  388. {
  389. if (m_RunningEffects.Find(type) != -1) //only do if the effect is running (FPS stonks!)
  390. {
  391. dta = m_WidgetDataMap.Get(type);
  392. if (dta.HasDefinedHandle() && dta.DataInitialized())
  393. {
  394. dta.Update(timeSlice,p,handle); //calculate and apply
  395. }
  396. else
  397. {
  398. CalculateValues(type,timeSlice,p,handle);
  399. widget_set = dta.GetWidgetSet();
  400. foreach (Widget w2 : widget_set)
  401. {
  402. if (w2.IsVisibleHierarchy() && m_UpdatedWidgetsCheck.Find(w2) == -1)
  403. {
  404. m_UpdatedWidgetsCheck.Insert(w2);
  405. ProcessWidgetUpdate(w2,type,timeSlice,p,handle);
  406. }
  407. }
  408. }
  409. }
  410. }
  411. m_UpdatedWidgetsCheck.Clear();
  412. m_UpdatedWidgetSetsCheck.Clear();
  413. }
  414. //! Only one calculation per unique WidgetSet
  415. protected void CalculateValues(int type = -1, float timeSlice = 0, Param p = null, int handle = -1)
  416. {
  417. if (m_UpdatedWidgetSetsCheck.Find(m_WidgetDataMap.Get(type).GetWidgetSetID()) != -1)
  418. {
  419. //Print("skipped updating set ID " + m_WidgetDataMap.Get(type).GetWidgetSetID() + " | effect: " + type);
  420. return;
  421. }
  422. switch (type)
  423. {
  424. case EffectWidgetsTypes.MOTO_BREATH:
  425. case EffectWidgetsTypes.HELMET_BREATH:
  426. case EffectWidgetsTypes.MASK_BREATH:
  427. {
  428. CalculateBreathEffect(timeSlice);
  429. }
  430. break;
  431. case EffectWidgetsTypes.MOTO_OCCLUDER:
  432. case EffectWidgetsTypes.EYEPATCH_OCCLUDER:
  433. case EffectWidgetsTypes.HELMET_OCCLUDER:
  434. case EffectWidgetsTypes.HELMET2_OCCLUDER:
  435. case EffectWidgetsTypes.MASK_OCCLUDER:
  436. {
  437. CalculateOccluderEffect(type,timeSlice,p,handle);
  438. }
  439. break;
  440. case EffectWidgetsTypes.COVER_FLASHBANG:
  441. {
  442. CalculateFlashbangEffect(type,timeSlice,p,handle);
  443. }
  444. break;
  445. default:
  446. return; //no need to calculate anything
  447. break;
  448. }
  449. m_UpdatedWidgetSetsCheck.Insert(m_WidgetDataMap.Get(type).GetWidgetSetID());
  450. }
  451. protected void ProcessWidgetUpdate(Widget w, int type, float timeSlice = 0, Param p = null, int handle = -1)
  452. {
  453. switch (type)
  454. {
  455. case EffectWidgetsTypes.MOTO_BREATH:
  456. case EffectWidgetsTypes.HELMET_BREATH:
  457. case EffectWidgetsTypes.MASK_BREATH:
  458. {
  459. UpdateBreathEffect(ImageWidget.Cast(w));
  460. }
  461. break;
  462. case EffectWidgetsTypes.MOTO_OCCLUDER:
  463. case EffectWidgetsTypes.EYEPATCH_OCCLUDER:
  464. case EffectWidgetsTypes.HELMET_OCCLUDER:
  465. case EffectWidgetsTypes.HELMET2_OCCLUDER:
  466. case EffectWidgetsTypes.MASK_OCCLUDER:
  467. {
  468. UpdateOccluderEffect(ImageWidget.Cast(w),type,timeSlice,p,handle);
  469. }
  470. break;
  471. case EffectWidgetsTypes.COVER_FLASHBANG:
  472. {
  473. UpdateFlashbangEffect(ImageWidget.Cast(w));
  474. }
  475. break;
  476. default:
  477. //Print("---invalid widget type to update---");
  478. break;
  479. }
  480. }
  481. //-----------------------------------------
  482. //specific widget 'handlers'
  483. const float BREATH_HDR_MIN = 0.005; //dusk?
  484. const float BREATH_HDR_MAX = 1.0; //dark?
  485. const float BREATH_COLOR_MULT_MIN = 0.5;
  486. const float BREATH_COLOR_MULT_MAX = 0.8;
  487. //-----------------------------------------
  488. //Breath
  489. //-----------------------------------------
  490. protected void CalculateBreathEffect(float timeSlice = 0, int type = -1, Param p = null)
  491. {
  492. float modifier = Math.Lerp(0.25, 0.5, m_BreathResidue);
  493. float speed = timeSlice * modifier;
  494. m_BreathResidue -= speed;
  495. m_BreathResidue = Math.Clamp(m_BreathResidue,0,1);
  496. float residue_final = Math.Lerp(0, 0.7, m_BreathResidue);
  497. float hdr_mult;
  498. hdr_mult = GetSceneHDRMul(0);
  499. hdr_mult = Math.Clamp(hdr_mult,BREATH_HDR_MIN,BREATH_HDR_MAX);
  500. hdr_mult = Math.InverseLerp(BREATH_HDR_MIN,BREATH_HDR_MAX,hdr_mult);
  501. hdr_mult = Math.Lerp(BREATH_COLOR_MULT_MAX,BREATH_COLOR_MULT_MIN,hdr_mult);
  502. m_BreathColor = ARGBF(0.0,1.0 * hdr_mult,1.0 * hdr_mult,1.0 * hdr_mult); //grayscaling of the image
  503. m_BreathAlphaVal = Math.Lerp(m_BreathAlphaVal, residue_final, timeSlice);
  504. }
  505. protected void UpdateBreathEffect(ImageWidget w)
  506. {
  507. w.SetColor(m_BreathColor);
  508. w.SetAlpha(m_BreathAlphaVal);
  509. }
  510. //-----------------------------------------
  511. //Occluders
  512. //-----------------------------------------
  513. protected void CalculateOccluderEffect(int type, float timeSlice, Param p, int handle)
  514. {
  515. }
  516. protected void UpdateOccluderEffect(ImageWidget w, int type, float timeSlice, Param p, int handle)
  517. {
  518. }
  519. //-----------------------------------------
  520. //Flashbang
  521. //-----------------------------------------
  522. protected void CalculateFlashbangEffect(int type, float timeSlice, Param p, int handle)
  523. {
  524. Param1<float> par = Param1<float>.Cast(p);
  525. m_FlashbangCoverAlphaVal = par.param1;
  526. /*if (m_FlashbangCoverAlphaVal <= 0.0)
  527. {
  528. RemoveActiveEffects({EffectWidgetsTypes.COVER_FLASHBANG});
  529. return;
  530. }*/
  531. }
  532. protected void UpdateFlashbangEffect(ImageWidget w)
  533. {
  534. w.SetAlpha(1 - m_FlashbangCoverAlphaVal);
  535. }
  536. //-----------------------------------------
  537. //root handling (generic 'Widget', so mainly alpha and hiding?)
  538. //-----------------------------------------
  539. protected void HandleWidgetRoot(float timeSlice = 0, Param p = null, int handle = -1)
  540. {
  541. switch (handle)
  542. {
  543. default:
  544. {
  545. Param1<float> par = Param1<float>.Cast(p);
  546. if (par)
  547. {
  548. float alpha_mod = Math.Clamp(par.param1,0.0,1.0);
  549. m_Root.SetAlpha(alpha_mod);
  550. }
  551. }
  552. break;
  553. }
  554. }
  555. //-----------------------------------------
  556. //! Generic update, called on frame from the player
  557. override void Update(float timeSlice)
  558. {
  559. if (m_SuspendRequests.Count() > 0)
  560. {
  561. return;
  562. }
  563. UpdateWidgets(-1,timeSlice);
  564. }
  565. /*
  566. override void SetBreathIntensityStamina(float stamina_cap, float stamina_current)
  567. {
  568. float stamina_normalized = Math.InverseLerp(0, stamina_cap, stamina_current);
  569. stamina_normalized = Math.Clamp(stamina_normalized,0,1);
  570. if ( stamina_normalized < STAMINA_SOUND_TR2 )
  571. {
  572. m_BreathMultStamina = 2.0;
  573. }
  574. else if ( stamina_normalized < STAMINA_SOUND_TR1 )
  575. {
  576. m_BreathMultStamina = 1.5;
  577. }
  578. else
  579. {
  580. m_BreathMultStamina = 1.0;
  581. }
  582. }
  583. */
  584. override void OnVoiceEvent(float breathing_resistance01)
  585. {
  586. m_BreathResidue += Math.Lerp(0,0.35,breathing_resistance01);
  587. m_BreathResidue = Math.Clamp(m_BreathResidue,0,1);
  588. }
  589. }