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