Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_InventoryHitZonePointUI.c
Go to the documentation of this file.
1 //---- REFACTOR NOTE START: This code will need to be refactored as current implementation is not conforming to the standards ----
3{
4 [Attribute("Bleeding")]
5 protected string m_sBleedingHitZoneName;
6
7 [Attribute("Damage")]
8 protected string m_sDamageHitZoneName;
9
10 protected SCR_InventoryHitZonePointUI m_pDamageHandler;
11
12 protected ref array<HitZone> m_aGroupHitZones = {};
15 protected IEntity m_Player;
19
20 protected Widget m_wRoot;
21 protected Widget m_wGlow;
23 protected BaseInventoryStorageComponent m_pStorage;
25
26 protected bool m_bSelected;
29
30 //------------------------------------------------------------------------------------------------
31 override void HandlerAttached(Widget w)
32 {
33 m_wRoot = w;
34
35 m_wGlow = w.FindAnyWidget("Glow");
36 m_wGlow.SetVisible(false);
37
38 Widget damageW = w.FindAnyWidget(m_sDamageHitZoneName);
39 m_pDamageHandler = SCR_InventoryHitZonePointUI.Cast(damageW.FindHandler(SCR_InventoryHitZonePointUI));
40 }
41
42 override bool OnClick(Widget w, int x, int y, int button)
43 {
44 if (button == 0)
45 {
48 else
50 }
51
52 return false;
53 }
54
56 {
58 m_TourniquetStorage.RemoveTourniquetFromSlot(m_eHitZoneGroup);
59 }
60
61 override bool OnMouseEnter(Widget w, int x, int y)
62 {
63 Highlight(true);
64
65 SCR_InventorySpinBoxComponent spinbox = m_pInventoryMenu.GetAttachmentSpinBoxComponent();
66 if (spinbox)
67 {
68 int id = spinbox.FindItem(GetHitZoneName());
69 if (id > -1)
70 spinbox.SetCurrentItem(id);
71 }
72
73 m_pStorageUI.OnFocus(m_pStorageUI.GetRootWidget(), 0, 0);
74
75 return false;
76 }
77
78 override bool OnMouseLeave(Widget w, Widget enterW, int x, int y)
79 {
80 Highlight(false);
81
82 m_pStorageUI.OnFocusLost(m_pStorageUI.GetRootWidget(), 0, 0);
83
84 return false;
85 }
86
87 protected void Highlight(bool highlight)
88 {
89 m_pDamageHandler.Highlight(highlight);
90 }
91
92 void SetGlowVisible(bool visible)
93 {
94 m_wGlow.SetVisible(visible);
95 }
96
97 void Select(bool select = true)
98 {
100 {
101 s_pSelectedPoint.m_bSelected = false;
102 s_pSelectedPoint.Highlight(false);
103 }
104
105 m_bSelected = select;
106 Highlight(select);
107 if (select)
108 {
109 s_pSelectedPoint = this;
110 }
111 else
112 {
113 s_pSelectedPoint = null;
114 }
115 }
116
117 //------------------------------------------------------------------------------------------------
119 {
121 Select(true);
122 SCR_ApplicableMedicalItemPredicate predicate = new SCR_ApplicableMedicalItemPredicate();
123 predicate.characterEntity = m_Player;
124 predicate.hitZoneGroup = m_eHitZoneGroup;
125 m_pInventoryMenu.ShowAttachmentStorage(predicate);
126 }
127
129 {
131 if (m_pInventoryMenu.GetAttachmentStorageUI())
132 {
133 m_pInventoryMenu.RemoveAttachmentStorage(m_pInventoryMenu.GetAttachmentStorageUI());
134 m_pStorageUI.GetRootWidget().SetVisible(false);
135 Select(false);
136 }
137 }
138
139 //------------------------------------------------------------------------------------------------
144
145 //------------------------------------------------------------------------------------------------
147 {
148 switch (m_eHitZoneGroup)
149 {
150 case ECharacterHitZoneGroup.HEAD:
151 {
152 return "#AR-Inventory_Head";
153 } break;
154
155 case ECharacterHitZoneGroup.UPPERTORSO:
156 {
157 return "#AR-Inventory_Chest";
158 } break;
159
160 case ECharacterHitZoneGroup.LOWERTORSO:
161 {
162 return "#AR-Inventory_Abdomen";
163 } break;
164
165 case ECharacterHitZoneGroup.LEFTARM:
166 {
167 return "#AR-Inventory_LeftArm";
168 } break;
169
170 case ECharacterHitZoneGroup.RIGHTARM:
171 {
172 return "#AR-Inventory_RightArm";
173 } break;
174
175 case ECharacterHitZoneGroup.LEFTLEG:
176 {
177 return "#AR-Inventory_LeftLeg";
178 } break;
179
180 case ECharacterHitZoneGroup.RIGHTLEG:
181 {
182 return "#AR-Inventory_RightLeg";
183 } break;
184 }
185
186 return string.Empty;
187 }
188
189 //------------------------------------------------------------------------------------------------
190 void InitializeHitZoneUI(BaseInventoryStorageComponent storage, SCR_InventoryMenuUI menuManager, int hitZoneId, IEntity player, bool updateAttachmentStorage = true)
191 {
192 m_pStorage = storage;
193 m_pInventoryMenu = menuManager;
194 m_Player = player;
195
197 m_TourniquetStorage.GetOnTourniquetMoved().Insert(OnTourniquetMoved);
198
201 return;
202
203 m_eHitZoneGroup = m_pCharDmgManager.LIMB_GROUPS.Get( hitZoneId );
204 m_pDamageHandler.SetParentContainer(this);
205
206 m_pBloodHitZone = m_pCharDmgManager.GetBloodHitZone();
207 m_pBloodHitZone.GetOnDamageStateChanged().Insert(UpdateHitZoneState);
209
210 UpdateHitZoneState(m_pBloodHitZone, updateAttachmentStorage);
211
212 m_pCharDmgManager.GetOnDamageEffectAdded().Insert(UpdateHitZoneDOTAdded);
213 m_pCharDmgManager.GetOnDamageEffectRemoved().Insert(UpdateHitZoneDOTRemoved);
215 m_iBoneIndex = m_Player.GetAnimation().GetBoneIndex(m_pCharDmgManager.GetBoneName(m_eHitZoneGroup));
216
217 SCR_CharacterHitZone scrHZ;
218 const int lastId = m_aGroupHitZones.Count() - 1;
219 foreach (int i, HitZone hz : m_aGroupHitZones)
220 {
221 scrHZ = SCR_CharacterHitZone.Cast(hz);
222 if (!scrHZ)
223 continue;
224
225 scrHZ.GetOnDamageStateChanged().Insert(UpdateHitZoneState);
226 UpdateHitZoneState(scrHZ, updateAttachmentStorage && i == lastId); // only update attachment storage with the last HZ data to not waste time
227 }
228
229 const Widget newStorage = GetGame().GetWorkspace().CreateWidgets(m_pInventoryMenu.BACKPACK_STORAGE_LAYOUT, m_wRoot);
230 m_pStorageUI = new SCR_InventoryHitZoneUI(storage, null, menuManager, 0, null, this, m_pCharDmgManager.GetGroupTourniquetted(m_eHitZoneGroup));
231 newStorage.AddHandler(m_pStorageUI);
232 m_pStorageUI.GetRootWidget().SetVisible(false);
233 }
234
235 protected void OnTourniquetMoved(int hzGroupId)
236 {
237 array<HitZone> hzs = {};
238 m_pCharDmgManager.GetHitZonesOfGroup(hzGroupId, hzs);
239 UpdateHitZoneState(SCR_HitZone.Cast(hzs[0]));
240
241 }
242
243 //------------------------------------------------------------------------------------------------
244 protected void UpdateHitZoneDOTAdded(notnull SCR_DamageEffect dmgEffect)
245 {
246 UpdateHitZoneState(SCR_HitZone.Cast(dmgEffect.GetAffectedHitZone()));
247 }
248
249 //------------------------------------------------------------------------------------------------
250 protected void UpdateHitZoneDOTRemoved(notnull SCR_DamageEffect dmgEffect)
251 {
252 UpdateHitZoneState(SCR_HitZone.Cast(dmgEffect.GetAffectedHitZone()));
253 }
254
255 //------------------------------------------------------------------------------------------------
256 protected void UpdateBleedingHitZoneRemoved(EDamageType dType, HitZone hz = null)
257 {
258 if (dType != EDamageType.BLEEDING)
259 return;
260
262 }
263
264 //------------------------------------------------------------------------------------------------
265 protected void UpdateHitZoneState(SCR_HitZone hz, bool updateAttachmentStorage = true)
266 {
267 if (!hz || !m_aGroupHitZones.Contains(hz))
268 return;
269
270 const float health = m_pCharDmgManager.GetGroupHealthScaled(m_eHitZoneGroup);
271 float bleeding;
272
273 SCR_RegeneratingHitZone regenHitZone;
274 foreach (HitZone groupHZ : m_aGroupHitZones)
275 {
276 if (groupHZ == m_pBloodHitZone)
277 continue;
278
279 regenHitZone = SCR_RegeneratingHitZone.Cast(groupHZ);
280 if (!regenHitZone)
281 continue;
282
283 if (regenHitZone.GetHitZoneDamageOverTime(EDamageType.BLEEDING) <= 0)
284 continue;
285
286 bleeding = m_pCharDmgManager.GetGroupDamageOverTime(m_eHitZoneGroup, EDamageType.BLEEDING);
287 break;
288 }
289
290 const float dotHealing = -m_pCharDmgManager.GetGroupDamageOverTime(m_eHitZoneGroup, EDamageType.HEALING);
291 const float dotRegen = m_pCharDmgManager.GetGroupDamageOverTime(m_eHitZoneGroup, EDamageType.REGENERATION);
292 const float regen = (dotHealing + dotRegen);
293
294 const bool tourniquetted = m_pCharDmgManager.GetGroupTourniquetted(m_eHitZoneGroup);
295 const bool salineBagged = m_pCharDmgManager.GetGroupSalineBagged(m_eHitZoneGroup);
296
297 if (m_pStorageUI)
298 m_pStorageUI.SetTourniquetted(tourniquetted);
299
300 const bool bleedingVisible = (bleeding > 0 || tourniquetted || salineBagged);
301 const bool damageVisible = (health < 1 && bleeding == 0);
302 m_pDamageHandler.GetRootWidget().SetVisible(damageVisible || bleedingVisible);
303 m_pDamageHandler.UpdateHitZoneState(bleeding, regen, tourniquetted, salineBagged);
304
305 SetGlowVisible(bleedingVisible);
306
307 if (!m_pInventoryMenu)
308 return;
309
310 if (updateAttachmentStorage && (m_bSelected || m_pInventoryMenu.IsUsingGamepad()))
312
313 if (bleeding > 0 || health < 1 || tourniquetted || salineBagged)
314 m_pInventoryMenu.AddItemToAttachmentSelection(GetHitZoneName(), this);
315 else
316 m_pInventoryMenu.RemoveItemFromAttachmentSelection(GetHitZoneName());
317 }
318
319 void SetGlowColor(Color color)
320 {
321 if (m_wGlow)
322 m_wGlow.SetColor(color);
323 }
324
325 //------------------------------------------------------------------------------------------------
327 {
328 return m_wRoot;
329 }
330
332 {
333 return m_iBoneIndex;
334 }
335
340
345}
346
347//------------------------------------------------------------------------------------------------
348class SCR_InventoryHitZonePointUI : ScriptedWidgetComponent
349{
352
353 [Attribute("1")]
354 protected bool m_bAllowHoverOver;
355
356 [Attribute("0")]
357 protected bool m_bAllowProgressAnim;
358
359 [Attribute("0")]
360 protected bool m_bBleedingHitZone;
361
362 [Attribute()]
363 protected ref array<int> m_aDOTLevels;
364
365 [Attribute("IconOverlay")]
366 protected string m_sIconOverlay;
368
369 [Attribute("Icon")]
370 protected string m_sIcon;
372
373 [Attribute("Outline")]
374 protected string m_sOutline;
376
377 [Attribute("Background")]
378 protected string m_sBackground;
380
381 [Attribute("Tourniquet")]
382 protected string m_sIconTourniquet;
384
385 [Attribute("Saline")]
386 protected string m_sIconSalineBag;
388
389 protected Widget m_wRoot;
391
392 protected static SCR_InventoryHitZonePointUI s_pSelectedPoint;
393 protected bool m_bSelected;
394
395 protected const float OPACITY_DEFAULT = 0.4;
396 protected const float OPACITY_BLOOD = 0.5;
397 protected const float OPACITY_SOLID = 1;
398
399 //------------------------------------------------------------------------------------------------
401 protected ref array<HitZone> m_aGroupHitZones = {};
402
403 protected string m_sSevereDamage = "#AR-DamageInfo_Damage_Severe";
404 protected string m_sHighDamage = "#AR-DamageInfo_Damage_High";
405 protected string m_sMediumDamage = "#AR-DamageInfo_Damage_Medium";
406 protected string m_sLowDamage = "#AR-DamageInfo_Damage_Low";
407
408 protected string m_sSevereBleeding = "#AR-DamageInfo_Bleeding_Severe";
409 protected string m_sHighBleeding = "#AR-DamageInfo_Bleeding_High";
410 protected string m_sMediumBleeding = "#AR-DamageInfo_Bleeding_Medium";
411 protected string m_sLowBleeding = "#AR-DamageInfo_Bleeding_Low";
412
413 protected string m_sSevereBloodLoss = "#AR-DamageInfo_Bloodloss_Severe";
414 protected string m_sHighBloodLoss = "#AR-DamageInfo_Bloodloss_High";
415 protected string m_sMediumBloodLoss = "#AR-DamageInfo_Bloodloss_Medium";
416 protected string m_sLowBloodLoss = "#AR-DamageInfo_Bloodloss_Low";
417
418 protected const string DAMAGE_INFO = "{55AFA256E1C20FB2}UI/layouts/Menus/Inventory/InventoryDamageInfo.layout";
419
429
430 protected IEntity m_Player;
433
434 [Attribute("Anim")]
435 protected string m_sAnimWidgetName;
436 protected Widget m_wAnim;
438
443
444 protected bool m_bIsRegenAnim;
445 protected bool m_bIsBloodAnim;
446
447 //------------------------------------------------------------------------------------------------
448 override void HandlerAttached(Widget w)
449 {
450 m_wRoot = w;
451
452 float opacity = OPACITY_DEFAULT;
454 opacity = OPACITY_SOLID;
455
456 m_wButton = ButtonWidget.Cast(w.FindAnyWidget("Btn"));
457 m_wIconOverlay = w.FindAnyWidget(m_sIconOverlay);
458 m_wIcon = ImageWidget.Cast(w.FindAnyWidget(m_sIcon));
459 m_wBackground = ImageWidget.Cast(w.FindAnyWidget(m_sBackground));
460 m_wOutline = ImageWidget.Cast(w.FindAnyWidget(m_sOutline));
461 m_wIconTourniquet = ImageWidget.Cast(w.FindAnyWidget(m_sIconTourniquet));
462 m_wIconSalineBag = ImageWidget.Cast(w.FindAnyWidget(m_sIconSalineBag));
463 m_wAnim = w.FindAnyWidget(m_sAnimWidgetName);
464
465 Widget damageOverlay = w.FindAnyWidget("DamageOverlay");
466 if (damageOverlay)
467 {
471 }
472
474 }
475
476 override void HandlerDeattached(Widget w)
477 {
481 }
482
483 //------------------------------------------------------------------------------------------------
484 override bool OnMouseEnter(Widget w, int x, int y)
485 {
486 if (w.GetName() == "BigBloodIcon")
487 ShowVirtualHZInfo(w, true, false);
488 else if (w.GetName() == "BigDamageIcon")
489 ShowVirtualHZInfo(w, false, true);
490
491 return false;
492 }
493
494 //------------------------------------------------------------------------------------------------
495 override bool OnMouseLeave(Widget w, Widget enterW, int x, int y)
496 {
497 if (w.GetName() == "BigBloodIcon")
499 else if (w.GetName() == "BigDamageIcon")
501
502 return false;
503 }
504
505 //------------------------------------------------------------------------------------------------
506 void Select(bool select)
507 {
508 if (s_pSelectedPoint)
509 {
510 s_pSelectedPoint.m_bSelected = false;
511 s_pSelectedPoint.Highlight(false);
512 }
513
514 m_bSelected = select;
515 Highlight(select);
516 if (select)
517 s_pSelectedPoint = this;
518 else
519 s_pSelectedPoint = null;
520 }
521
522 //------------------------------------------------------------------------------------------------
523 void Highlight(bool highlight)
524 {
525 ShowHitZoneInfo(highlight);
526
528 return;
529
530 float opacity = OPACITY_SOLID;
531 if (!highlight)
532 opacity = OPACITY_DEFAULT;
533
534 if (m_wIconOverlay)
535 m_wIconOverlay.SetOpacity(opacity);
536 }
537
538 //------------------------------------------------------------------------------------------------
540 {
541 SCR_InventoryMenuUI inventoryMenuUI = SCR_InventoryMenuUI.Cast(GetGame().GetMenuManager().FindMenuByPreset(ChimeraMenuPreset.Inventory20Menu));
542 if (!inventoryMenuUI)
543 return null;
544
545 return inventoryMenuUI;
546 }
547
548 //------------------------------------------------------------------------------------------------
550 protected void ShowVirtualHZInfo(Widget w, bool bloodIcon = false, bool fractureIcon = false)
551 {
552 if (!bloodIcon && !fractureIcon)
553 return;
554
555 int groupDamageIntensity;
556 bool regenerating;
557 float bleedingRate, bloodHealth;
558 bool isTourniquetted, isSalineBagged, isArmFractured, isLegFractured;
559 string damageIntensity, damageIntensityText, bleedingIntensityText, bloodLevelText;
560
561 GetHitZoneInfo(ECharacterHitZoneGroup.VIRTUAL, groupDamageIntensity, regenerating, bleedingRate, bloodHealth, isTourniquetted, isSalineBagged, isArmFractured, isLegFractured);
562 GetDamageInfoTexts(ECharacterHitZoneGroup.VIRTUAL, groupDamageIntensity, bleedingRate, damageIntensity, damageIntensityText, bleedingIntensityText);
563 GetBloodInfoText(bloodHealth, bloodLevelText);
564
565 Widget localInfoWidget;
566 if (!m_DamageInfo)
567 {
568 SCR_InventoryMenuUI inventoryMenuUI = GetInventoryMenuUI();
569 if (!inventoryMenuUI)
570 return;
571
572 localInfoWidget = GetGame().GetWorkspace().CreateWidgets(DAMAGE_INFO, inventoryMenuUI.GetRootWidget());
573 if (!localInfoWidget)
574 return;
575
576 localInfoWidget.SetVisible(true);
577 localInfoWidget.SetOpacity(0);
578
579 localInfoWidget.AddHandler(new SCR_InventoryDamageInfoUI());
580 m_DamageInfo = SCR_InventoryDamageInfoUI.Cast(localInfoWidget.FindHandler(SCR_InventoryDamageInfoUI));
581 }
582
583 if (!m_DamageInfo)
584 return;
585
586 m_DamageInfo.SetName("");
587 if (fractureIcon)
588 m_DamageInfo.SetFractureStateVisible(isArmFractured, isLegFractured);
589 else if (bloodIcon)
590 m_DamageInfo.SetBleedingStateVisible(bloodHealth < 1, bloodLevelText);
591
592 //callLater is here because the widget needs to be created before size can be determined and location can be set
593 GetGame().GetCallqueue().CallLater(EnableVirtualHZInfoWidget, 300, false, localInfoWidget, w);
594 }
595
596 //------------------------------------------------------------------------------------------------
598 protected void EnableVirtualHZInfoWidget(Widget localInfoWidget, Widget w)
599 {
600 if (!m_DamageInfo)
601 return;
602
603 float x, y;
604 w.GetScreenPos(x, y);
605
606 float width, height;
607 w.GetScreenSize(width, height);
608
609 float screenSizeX, screenSizeY;
610 GetGame().GetWorkspace().GetScreenSize(screenSizeX, screenSizeY);
611
612 localInfoWidget.SetOpacity(1);
613
614 float infoWidth, infoHeight;
615 int iMouseX, iMouseY;
616
617 localInfoWidget.GetScreenSize(infoWidth, infoHeight);
618 iMouseX = x;
619 iMouseY = y + height;
620 if (x + infoWidth > screenSizeX)
621 iMouseX = screenSizeX - infoWidth - width * 0.5; // offset info if it would go outside of the screen
622
623 m_DamageInfo.Move( GetGame().GetWorkspace().DPIUnscale( iMouseX ) - infoWidth * 0.60, GetGame().GetWorkspace().DPIUnscale( iMouseY ) );
624 }
625
626 protected void HideVirtualHZInfo()
627 {
628 if ( !m_DamageInfo )
629 return;
630 m_DamageInfo.Hide();
631 m_DamageInfo.Destroy();
632 }
633
634 protected void ShowHitZoneInfo(bool show, bool virtualHZ = false)
635 {
636 if (!m_pParentContainer && !virtualHZ)
637 return;
638
639 if (!show && !virtualHZ)
640 {
641 m_pParentContainer.GetInventoryHandler().HideDamageInfo();
642 return;
643 }
644
646 if (!virtualHZ)
647 group = m_pParentContainer.GetHitZoneGroup();
648
649 int groupDamageIntensity;
650 bool regenerating;
651 float bleedingRate, bloodHealth;
652 bool isTourniquetted, isSalineBagged, isArmFractured, isLegFractured;
653 const bool isMorphined; // TODO: check for good const usage
654 string damageIntensity, damageIntensityText, bleedingIntensityText;
655
656 GetHitZoneInfo(group, groupDamageIntensity, regenerating, bleedingRate, bloodHealth, isTourniquetted, isSalineBagged, isArmFractured, isLegFractured);
657 GetDamageInfoTexts(group, groupDamageIntensity, bleedingRate, damageIntensity, damageIntensityText, bleedingIntensityText);
658
659 SCR_InventoryDamageUIInfo damageUIInfo;
660 damageUIInfo = new SCR_InventoryDamageUIInfo(
661 groupDamageIntensity != 0,
662 regenerating,
663 bleedingRate != 0,
664 isTourniquetted,
665 isSalineBagged,
666 isMorphined,
667 isArmFractured,
668 isLegFractured,
669 damageIntensity,
670 damageIntensityText,
671 bleedingIntensityText
672 );
673
674 string name;
675 if (!virtualHZ)
676 name = m_pParentContainer.GetHitZoneName();
677
678 m_pParentContainer.GetInventoryHandler().ShowDamageInfo(name, damageUIInfo);
679 }
680
681 //------------------------------------------------------------------------------------------------
682 void GetDamageInfoTexts(EHitZoneGroup group, int groupDamageIntensity, float bleedingRate, out string damageIntensity, out string damageIntensityText, out string bleedingIntensityText)
683 {
684 if (groupDamageIntensity == 0)
685 {
686 damageIntensity = "";
687 damageIntensityText = "";
688 }
689 else if (groupDamageIntensity == 1)
690 {
691 damageIntensity = "Wound_1_UI";
692 damageIntensityText = m_sLowDamage;
693 }
694 else if (groupDamageIntensity == 2)
695 {
696 damageIntensity = "Wound_2_UI";
697 damageIntensityText = m_sMediumDamage;
698 }
699 else if (groupDamageIntensity == 3)
700 {
701 damageIntensity = "Wound_3_UI";
702 damageIntensityText = m_sHighDamage;
703 }
704 else if (groupDamageIntensity == 4)
705 {
706 damageIntensity = "Wound_4_UI";
707 damageIntensityText = m_sSevereDamage;
708 }
709
710 if (bleedingRate < m_fLowBleedingThreshold)
711 bleedingIntensityText = m_sLowBleeding;
712 else if (bleedingRate >= m_fLowBleedingThreshold && bleedingRate < m_fMediumBleedingThreshold)
713 bleedingIntensityText = m_sMediumBleeding;
714 else if (bleedingRate >= m_fMediumBleedingThreshold && bleedingRate < m_fHighBleedingThreshold)
715 bleedingIntensityText = m_sHighBleeding;
716 else if (bleedingRate >= m_fHighBleedingThreshold)
717 bleedingIntensityText = m_sSevereBleeding;
718 }
719
720 //------------------------------------------------------------------------------------------------
721 void GetBloodInfoText(float bloodHitZoneHealthScaled, out string bloodLossText)
722 {
723 if (bloodHitZoneHealthScaled > m_fLowBloodLossThreshold)
724 bloodLossText = m_sLowBloodLoss;
725 else if (bloodHitZoneHealthScaled > m_fMediumBloodLossThreshold)
726 bloodLossText = m_sMediumBloodLoss;
727 else if (bloodHitZoneHealthScaled > m_fHighBloodLossThreshold)
728 bloodLossText = m_sHighBloodLoss;
729 else
730 bloodLossText = m_sSevereBloodLoss;
731 }
732
733 //------------------------------------------------------------------------------------------------
734 protected void GetHitZoneInfo(EHitZoneGroup group, out int groupDamageIntensity, out bool regenerating, out float bleedingRate, out float bloodHealth, out bool isTourniquetted, out bool isSalineBagged, out bool isArmFractured, out bool isLegFractured)
735 {
737 if (!character)
738 return;
739
740 SCR_CharacterDamageManagerComponent damageMan = SCR_CharacterDamageManagerComponent.Cast( character.GetDamageManager() );
741 if (!damageMan)
742 return;
743
744 const float groupHealth = damageMan.GetGroupHealthScaled(group);
745 bleedingRate = damageMan.GetGroupDamageOverTime(group, EDamageType.BLEEDING);
746 isTourniquetted = damageMan.GetGroupTourniquetted(group);
747 isSalineBagged = damageMan.GetGroupSalineBagged(group);
748
749 if (group == ECharacterHitZoneGroup.VIRTUAL)
750 {
751 isArmFractured = damageMan.GetAimingDamage() > 0;
752 isLegFractured = damageMan.GetMovementDamage() > 0;
754 if (!hz)
755 return;
756
757 bleedingRate = hz.GetTotalBleedingAmount();
758 bloodHealth = hz.GetHealthScaled();
759 }
760
761 if (group == ECharacterHitZoneGroup.LEFTARM || group == ECharacterHitZoneGroup.RIGHTARM)
762 isArmFractured = damageMan.GetAimingDamage() > 0;
763 else if (group == ECharacterHitZoneGroup.LEFTLEG || group == ECharacterHitZoneGroup.RIGHTLEG)
764 isLegFractured = damageMan.GetMovementDamage() > 0;
765
766 if (damageMan.GetGroupDamageOverTime(group, EDamageType.HEALING) == 0 && damageMan.GetGroupDamageOverTime(group, EDamageType.REGENERATION) == 0)
767 regenerating = false;
768 else
769 regenerating = true;
770
771 if (groupHealth == 1)
772 groupDamageIntensity = 0;
773 else if (groupHealth < m_fLowDamageThreshold)
774 groupDamageIntensity = 4;
775 else if (groupHealth >= m_fLowDamageThreshold && groupHealth < m_fMediumDamageThreshold)
776 groupDamageIntensity = 3;
777 else if (groupHealth >= m_fMediumDamageThreshold && groupHealth < m_fHighDamageThreshold)
778 groupDamageIntensity = 2;
779 else if (groupHealth >= m_fHighDamageThreshold)
780 groupDamageIntensity = 1;
781 }
782
783 //------------------------------------------------------------------------------------------------
784 void UpdateHitZoneState(float bleeding, float regen, bool tourniquetted, bool salineBagged)
785 {
787 return;
788
789 if (bleeding > 0)
790 {
791 if (tourniquetted || salineBagged)
793 else
795 }
796 else
797 {
799 }
800
801 int damageIntensity;
802 float bleedRate, bloodHealth;
803 bool regenerating;
804 bool isArmFractured, isLegFractured;
805 GetHitZoneInfo(m_eHitZoneGroup, damageIntensity, regenerating, bleedRate, bloodHealth, tourniquetted, salineBagged, isArmFractured, isLegFractured);
806 if (damageIntensity > 0)
807 m_DamageStateUIComp.SetVisuals(m_DamageState, damageIntensity-1);
808
809 SetRegeneration(regen, bleeding);
810
811 m_wIcon.SetVisible(!tourniquetted && !salineBagged);
813 m_wIconTourniquet.SetVisible(tourniquetted);
815 m_wIconSalineBag.SetVisible(salineBagged && !tourniquetted);
816 }
817
818 protected void SetRegeneration(float regen, float bleeding)
819 {
820 if (!m_DamageState)
821 return;
822
823 bool isRegen = (regen > 0);
824 float regenSpeed = Math.AbsFloat(regen);
825 if (regenSpeed < 0.3)
826 regenSpeed = 0.3;
827
828 if (isRegen && !bleeding)
829 PlayRegenAnim(regenSpeed);
830 else
832
833 Color bckg = m_DamageState.GetBackgroundColor();
834 Color outline = m_DamageState.GetOutlineColor();
835
836 bool glow = true;
837 if (isRegen && bleeding == 0)
838 {
839 bckg = m_DamageState.GetBackgroundColorRegen();
840 outline = m_DamageState.GetOutlineColorRegen();
841 glow = false;
842 }
843
844 m_pParentContainer.SetGlowVisible(!isRegen && glow);
845 m_wBackground.SetColor(bckg);
846 m_wOutline.SetColor(outline);
847 }
848
849 protected void PlayRegenAnim(float regenSpeed = 1)
850 {
851 if (!m_DamageState)
852 return;
853
855 {
856 m_IconOutlineAnim.SetSpeed(regenSpeed);
857 return;
858 }
859
860 m_bIsRegenAnim = true;
861 m_IconOutlineAnim = AnimateWidget.Color(m_wOutline, m_DamageState.GetOutlineColorRegen(), regenSpeed);
863 {
864 m_IconOutlineAnim.SetRepeat(true);
865 m_IconOutlineAnim.GetOnCycleCompleted().Insert(OnAnimCycleComplete);
866 }
867 }
868
869 protected void StopRegenAnim()
870 {
871 if (!m_bIsRegenAnim)
872 return;
873
874 m_bIsRegenAnim = false;
876 {
877 m_IconOutlineAnim.GetOnCycleCompleted().Remove(OnAnimCycleComplete);
879 }
880 }
881
882 protected void PlayBloodDropAnim(float speed = 1)
883 {
884 if (m_bIsBloodAnim)
885 {
886 m_IconOpacityAnim.SetSpeed(speed);
887 m_IconSizeAnim.SetSpeed(speed);
888 m_DamageIconOpacityAnim.SetSpeed(speed);
889 return;
890 }
891
892 if (m_wAnim && !m_bIsBloodAnim)
893 {
894 m_wAnim.SetVisible(true);
895
896 float targetOpacity = OPACITY_BLOOD;
897 float opacitySpeed = speed;
898 m_IconOpacityAnim = AnimateWidget.Opacity(m_wAnim, targetOpacity, opacitySpeed);
900 {
901 m_IconOpacityAnim.SetRepeat(true);
902 m_IconOpacityAnim.GetOnCycleCompleted().Insert(OnAnimCycleComplete);
903 }
904
905 float targetSize[2] = {32, 32};
906 m_IconSizeAnim = AnimateWidget.Size(m_wAnim, targetSize, speed);
907 if (m_IconSizeAnim)
908 {
909 m_IconSizeAnim.SetRepeat(true);
910 m_IconSizeAnim.GetOnCycleCompleted().Insert(OnAnimCycleComplete);
911 }
912
913 m_bIsBloodAnim = true;
914
915 m_wIcon.SetOpacity(0);
918 {
919 m_DamageIconOpacityAnim.SetRepeat(true);
920 m_DamageIconOpacityAnim.GetOnCycleCompleted().Insert(OnAnimCycleComplete);
921 }
922 }
923 }
924
926 {
927 /*
928 DO NOT REMOVE OR YOU'LL BREAK ANIM REPEAT FUNCTIONALITY
929 WidgetAnimationBase.m_OnCycleCompleted needs to exist,
930 otherwise WidgetAnimationBase.OnUpdate will return false after the cycle is finished and stop animating
931 */
932 }
933
934 protected void StopBloodDropAnim()
935 {
936 m_bIsBloodAnim = false;
937
939 m_IconOpacityAnim.GetOnCycleCompleted().Remove(OnAnimCycleComplete);
940 if (m_IconSizeAnim)
941 m_IconSizeAnim.GetOnCycleCompleted().Remove(OnAnimCycleComplete);
943 m_DamageIconOpacityAnim.GetOnCycleCompleted().Remove(OnAnimCycleComplete);
944
948
949 if (m_wIcon)
950 m_wIcon.SetOpacity(1);
951 if (m_wAnim)
952 m_wAnim.SetVisible(false);
953 }
954
955 void SetBloodLevelProgress(float bloodLevel)
956 {
958 return;
959
960 float mask = Math.Lerp(0.25, 0.75, 1 - bloodLevel);
961 m_wIcon.SetMaskProgress(mask);
962 }
963
965 {
966 return m_wRoot;
967 }
968
974};
975 //---- REFACTOR NOTE END ----
ChimeraMenuPreset
Menu presets.
EHitZoneGroup
ArmaReforgerScripted GetGame()
Definition game.c:1398
ChimeraCharacter m_Player
ECharacterHitZoneGroup m_eHitZoneGroup
override bool OnMouseLeave(Widget w, Widget enterW, int x, int y)
override bool OnMouseEnter(Widget w, int x, int y)
Widget m_wRoot
ref array< int > m_aDOTLevels
string m_sLowBloodLoss
string m_sBackground
float m_fMediumDamageThreshold
void ShowHitZoneInfo(bool show, bool virtualHZ=false)
string m_sMediumDamage
const float OPACITY_DEFAULT
void GetHitZoneInfo(EHitZoneGroup group, out int groupDamageIntensity, out bool regenerating, out float bleedingRate, out float bloodHealth, out bool isTourniquetted, out bool isSalineBagged, out bool isArmFractured, out bool isLegFractured)
void Select(bool select)
void UpdateHitZoneState(float bleeding, float regen, bool tourniquetted, bool salineBagged)
WidgetAnimationBase m_IconOpacityAnim
string m_sIconSalineBag
float m_fMediumBloodLossThreshold
string m_sMediumBloodLoss
float m_fLowDamageThreshold
void ShowVirtualHZInfo(Widget w, bool bloodIcon=false, bool fractureIcon=false)
Gather data for, and create, infowidget for virtual hitzones.
string m_sIconOverlay
WidgetAnimationBase m_IconOutlineAnim
string m_sSevereDamage
SCR_InventoryHitZonePointContainerUI m_DamageState
string m_sIconTourniquet
string m_sHighDamage
SCR_InventoryHitZonePointContainerUI m_pParentContainer
SCR_InventoryDamageInfoUI m_DamageInfo
void Highlight(bool highlight)
string m_sHighBloodLoss
void PlayRegenAnim(float regenSpeed=1)
float m_fHighBleedingThreshold
ref SCR_InventoryHitZoneUI m_pStorageHandler
ImageWidget m_wIconSalineBag
SCR_DamageStateUIComponent m_DamageStateUIComp
const float OPACITY_BLOOD
void StopRegenAnim()
ImageWidget m_wIconTourniquet
string m_sSevereBloodLoss
void GetBloodInfoText(float bloodHitZoneHealthScaled, out string bloodLossText)
string m_sAnimWidgetName
ImageWidget m_wIcon
string m_sHighBleeding
float m_fLowBloodLossThreshold
ImageWidget m_wOutline
float m_fLowBleedingThreshold
string m_sLowBleeding
string m_sLowDamage
float m_fHighBloodLossThreshold
void HideVirtualHZInfo()
void SetBloodLevelProgress(float bloodLevel)
void SetParentContainer(SCR_InventoryHitZonePointContainerUI container)
void GetDamageInfoTexts(EHitZoneGroup group, int groupDamageIntensity, float bleedingRate, out string damageIntensity, out string damageIntensityText, out string bleedingIntensityText)
void EnableVirtualHZInfoWidget(Widget localInfoWidget, Widget w)
Determine size and location for the infowidget.
void OnAnimCycleComplete(WidgetAnimationBase anim)
void StopBloodDropAnim()
ButtonWidget m_wButton
bool m_bAllowProgressAnim
void PlayBloodDropAnim(float speed=1)
WidgetAnimationBase m_DamageIconOpacityAnim
void SetRegeneration(float regen, float bleeding)
WidgetAnimationBase m_IconSizeAnim
ref array< HitZone > m_aGroupHitZones
SCR_InventoryMenuUI GetInventoryMenuUI()
string m_sSevereBleeding
float m_fMediumBleedingThreshold
const float OPACITY_SOLID
bool m_bBleedingHitZone
float m_fHighDamageThreshold
Widget m_wIconOverlay
const string DAMAGE_INFO
string m_sMediumBleeding
void SCR_InventoryHitZoneUI(BaseInventoryStorageComponent storage, LoadoutAreaType slotID=null, SCR_InventoryMenuUI menuManager=null, int iPage=0, array< BaseInventoryStorageComponent > aTraverseStorage=null, SCR_InventoryHitZonePointContainerUI parent=null, bool isTourniquetted=false)
Widget m_wBackground
Widget GetRootWidget()
override void HandlerAttached(Widget w)
override void HandlerDeattached(Widget w)
void WidgetAnimationBase(Widget w, float speed)
static bool StopAnimation(Widget w, typename typeName)
static WidgetAnimationFrameSize Size(Widget widget, float size[2], float speed)
static WidgetAnimationOpacity Opacity(Widget widget, float targetValue, float speed, bool toggleVisibility=false)
static WidgetAnimationColor Color(Widget widget, Color color, float speed)
Definition Color.c:13
proto external Managed FindComponent(typename typeName)
Definition Math.c:13
Blood - does not receive damage directly, only via scripted events.
float GetGroupHealthScaled(ECharacterHitZoneGroup hitZoneGroup)
bool GetGroupSalineBagged(ECharacterHitZoneGroup hitZoneGroup)
bool GetGroupTourniquetted(ECharacterHitZoneGroup hitZoneGroup)
override float GetGroupDamageOverTime(ECharacterHitZoneGroup hitZoneGroup, EDamageType damageType)
SCR_TourniquetStorageComponent m_TourniquetStorage
void UpdateHitZoneDOTRemoved(notnull SCR_DamageEffect dmgEffect)
override bool OnClick(Widget w, int x, int y, int button)
static SCR_InventoryHitZonePointContainerUI s_pSelectedPoint
override bool OnMouseEnter(Widget w, int x, int y)
SCR_CharacterDamageManagerComponent m_pCharDmgManager
void InitializeHitZoneUI(BaseInventoryStorageComponent storage, SCR_InventoryMenuUI menuManager, int hitZoneId, IEntity player, bool updateAttachmentStorage=true)
void UpdateHitZoneDOTAdded(notnull SCR_DamageEffect dmgEffect)
override bool OnMouseLeave(Widget w, Widget enterW, int x, int y)
void UpdateBleedingHitZoneRemoved(EDamageType dType, HitZone hz=null)
void UpdateHitZoneState(SCR_HitZone hz, bool updateAttachmentStorage=true)
float GetHitZoneDamageOverTime(EDamageType targetDamageType)
Get current total damage per second of this hitZone.
SCR_EditableEntityComponent GetControlledEntity()
SCR_FieldOfViewSettings Attribute
int TNodeId
Node global id is a hash of name of the node.
Definition EnEntity.c:18
proto external PlayerController GetPlayerController()
EDamageType
Definition EDamageType.c:13