Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_HUDManagerComponent.c
Go to the documentation of this file.
1 //#define DISABLE_HUD_MANAGER
2 
3 //------------------------------------------------------------------------------------------------
4 // (i): The enum values needs to be power of 2
6 {
7  BACKGROUND = 1, // Only background textures like Screen effects
8  LOW = 2, // Read-only information, like weapon info
9  MEDIUM = 4, //
10  HIGH = 8, // Dialogue-like elements like weapon switching
11  OVERLAY = 16, // Interactive elements that should always be on top
12  ALWAYS_TOP = 32
13 }
14 
15 [ComponentEditorProps(icon: HYBRID_COMPONENT_ICON)]
16 class SCR_HUDManagerComponentClass : HUDManagerComponentClass
17 {
18 }
19 
20 void OnScreenBrightnessChanged(float opacity, float sceneBrightness);
22 
23 class SCR_HUDManagerComponent : HUDManagerComponent
24 {
25  [Attribute()]
26  protected ref array<ref SCR_HUDManagerHandler> m_aHandlers;
27  protected ref array<SCR_HUDManagerHandler> m_aUpdatableHandlers = {};
28 
29  [Attribute()]
30  string m_sDefaultBackgroundLayer;
31  [Attribute()]
32  string m_sDefaultForegroundLayer;
33 
34  [Attribute("0 0 1 1", UIWidgets.GraphDialog, params: "0.1 0.6 0 0.4", desc: "Adaptive opacity (y) based on screen brightness (x).", category: "AdaptiveOpacity")]
35  private ref Curve m_AdaptiveOpacityCurve;
36 
37  private ref map<EHudLayers, Widget> m_aLayerWidgets = new map<EHudLayers, Widget>;
38  private Widget m_wRoot;
39  private Widget m_wRootTop;
40 
41  protected BaseWorld m_World;
42 
43  private bool m_MenuOpen;
44 
45  protected ref ScriptInvokerBase<OnScreenBrightnessChanged> m_OnSceneBrightnessChanged = new ScriptInvokerBase<OnScreenBrightnessChanged>();
46 
47  protected float m_fUpdateTime = -1;
48  const float UPDATE_DELAY = 500;
49 
50  const float ADAPTIVE_OPACITY_BRIGHTNESS_THROTTLE = 0.001;
51  const float ADAPTIVE_OPACITY_THROTTLE = 0.01; // threshold opacity change to fire the AdaptiveOpacity invoker
52 
53  protected float m_fSceneBrightness = -1;
54  protected float m_fOpacity = -1;
55 
56  protected IEntity m_Owner;
57 
58  protected ref array<SCR_HUDManagerHandler> m_aHandlersToRemoveFromUpdate = {};
59 
60  #ifndef DISABLE_HUD_MANAGER
61 
62  //------------------------------------------------------------------------------------------------
63  int GetInfoDisplayCount()
64  {
65  return m_aHUDElements.Count();
66  }
67 
68  //------------------------------------------------------------------------------------------------
69  IEntity GetOwner()
70  {
71  return m_Owner;
72  }
73 
74  //------------------------------------------------------------------------------------------------
75  SCR_HUDManagerHandler FindHandler(typename handlerType)
76  {
77  foreach (SCR_HUDManagerHandler handler : m_aHandlers)
78  {
79  if (handler.Type() == handlerType)
80  return handler;
81  }
82 
83  return null;
84  }
85 
86  //------------------------------------------------------------------------------------------------
87  void RemoveHandlerFromUpdatableHandlers(notnull SCR_HUDManagerHandler handler)
88  {
89  m_aHandlersToRemoveFromUpdate.Insert(handler);
90  }
91 
92  //------------------------------------------------------------------------------------------------
93  Widget GetHUDRootWidget()
94  {
95  return m_wRoot;
96  }
97 
98  //------------------------------------------------------------------------------------------------
99  protected override void OnInit(IEntity owner)
100  {
101  if (!GetGame().GetWorldEntity())
102  return;
103  m_Owner = owner;
104 
105  foreach (SCR_HUDManagerHandler handler : m_aHandlers)
106  {
107  handler.OnInit(this);
108 
109  if (handler.CanUpdate())
110  m_aUpdatableHandlers.Insert(handler);
111  }
112 
113  foreach (SCR_HUDManagerHandler handler : m_aHandlers)
114  {
115  handler.OnStart(this);
116  }
117 
118  ArmaReforgerScripted game = GetGame();
119  if (game && !game.GetHUDManager())
120  {
121  game.SetHUDManager(this);
122  CreateHUDLayers();
123  }
124 
125  m_World = GetGame().GetWorld();
126  }
127 
128  //------------------------------------------------------------------------------------------------
129  protected override void OnUpdate(IEntity owner)
130  {
131  if (!m_World)
132  return;
133 
134  if (!m_aHandlersToRemoveFromUpdate.IsEmpty())
135  {
136  foreach (SCR_HUDManagerHandler handler : m_aHandlersToRemoveFromUpdate)
137  {
138  m_aUpdatableHandlers.RemoveItem(handler);
139  handler.SetCanUpdate(false);
140  }
141 
142  m_aHandlersToRemoveFromUpdate.Clear();
143  }
144 
145  foreach (SCR_HUDManagerHandler handler : m_aUpdatableHandlers)
146  {
147  handler.OnUpdate(this);
148  }
149 
150  float time = m_World.GetWorldTime();
151 
152  if (time < m_fUpdateTime)
153  return;
154 
155  m_fUpdateTime = time + UPDATE_DELAY;
156 
157  //------------------------------------------------------------------------------------------------
158  // Adaptive opacity
159  //------------------------------------------------------------------------------------------------
160 
161  // We want to enforce full opacity for brightness > 0.1 (midday, good weather)
162  float sceneBrightness = Math.Clamp(m_World.GetCameraSceneMiddleBrightness(0), 0, 0.1);
163 
164  // Throttle the opacity update if brightness change is not bigger than n%
165  if (Math.AbsFloat(m_fSceneBrightness - sceneBrightness) < ADAPTIVE_OPACITY_BRIGHTNESS_THROTTLE)
166  return;
167 
168  // Curve based opacity interpolation
169  float opacity = Math3D.Curve(ECurveType.CurveProperty2D, sceneBrightness, m_AdaptiveOpacityCurve)[1];
170  opacity = Math.Clamp(Math.Round(opacity * 100) / 100, 0, 1);
171 
172  // Invoke the opacity update only if change is greater than n%
173  if (Math.AbsFloat(m_fOpacity - opacity) >= ADAPTIVE_OPACITY_THROTTLE)
174  {
175  //PrintFormat("sceneBrightness: %1 -> opacity %2", sceneBrightness, opacity);
176 
177  m_fSceneBrightness = sceneBrightness;
178  m_fOpacity = opacity;
179 
180  if (m_OnSceneBrightnessChanged)
181  m_OnSceneBrightnessChanged.Invoke(opacity, sceneBrightness);
182  }
183  }
184 
185  //------------------------------------------------------------------------------------------------
186  float GetAdaptiveOpacity()
187  {
188  return m_fOpacity;
189  }
190 
191  //------------------------------------------------------------------------------------------------
192  float GetSceneBrightness()
193  {
194  return m_fSceneBrightness;
195  }
196 
197  //------------------------------------------------------------------------------------------------
198  ScriptInvokerBase<OnScreenBrightnessChanged> GetSceneBrightnessChangedInvoker()
199  {
200  return m_OnSceneBrightnessChanged;
201  }
202 
203  //------------------------------------------------------------------------------------------------
204  protected void ~SCR_HUDManagerComponent()
205  {
206  if (m_wRoot)
207  m_wRoot.RemoveFromHierarchy();
208  }
209 
210  #endif
211 
212  //------------------------------------------------------------------------------------------------
213  protected void CreateHUDLayers()
214  {
215  m_wRoot = GetGame().GetWorkspace().CreateWidget(WidgetType.FrameWidgetTypeID, WidgetFlags.VISIBLE, Color.FromInt(Color.WHITE), 0);
216  m_wRootTop = GetGame().GetWorkspace().CreateWidget(WidgetType.FrameWidgetTypeID, WidgetFlags.VISIBLE, Color.FromInt(Color.WHITE), 0);
217  m_wRootTop.SetZOrder(100); //set high to be always on top, even above MenuManager layouts
218 
219  if (m_wRoot && m_wRootTop)
220  {
221  InitRootWidget(m_wRoot, "SCR_HUDManagerComponent.m_wRoot");
222  InitRootWidget(m_wRootTop, "SCR_HUDManagerComponent.m_wRootTop");
223 
224  array<int> bitValues = new array<int>;
225  int bitCount = SCR_Enum.GetEnumValues(EHudLayers, bitValues);
226 
227  for (int i = 0; i < bitCount; i++)
228  {
229  Widget frame;
230  Widget parent = m_wRoot;
231  if (bitValues[i] == EHudLayers.ALWAYS_TOP)
232  parent = m_wRootTop;
233 
234  frame = GetGame().GetWorkspace().CreateWidget(WidgetType.FrameWidgetTypeID, WidgetFlags.VISIBLE, Color.FromInt(Color.WHITE), 0, parent);
235  FrameSlot.SetAnchorMin(frame, 0, 0);
236  FrameSlot.SetAnchorMax(frame, 1, 1);
237  FrameSlot.SetOffsets(frame, 0, 0, 0, 0);
238  frame.SetFlags(WidgetFlags.IGNORE_CURSOR);
239  frame.SetName(string.Format("SCR_HudManagerComponent: %1", typename.EnumToString(EHudLayers, bitValues[i])));
240 
241  m_aLayerWidgets.Insert(bitValues[i], frame);
242  }
243  }
244  }
245 
246  //------------------------------------------------------------------------------------------------
248  SCR_InfoDisplay FindInfoDisplay(typename type)
249  {
250  foreach (SCR_InfoDisplay display : m_aHUDElements)
251  {
252  if (display.Type() == type)
253  return display;
254  }
255 
256  return null;
257  }
258 
259  //------------------------------------------------------------------------------------------------
261  SCR_InfoDisplay FindInfoDisplayByResourceName(ResourceName path)
262  {
263  foreach (SCR_InfoDisplay display : m_aHUDElements)
264  {
265  if (display.m_LayoutPath == path)
266  return display;
267  }
268 
269  return null;
270  }
271 
272  //------------------------------------------------------------------------------------------------
274  Widget FindLayoutByResourceName(ResourceName path)
275  {
276  foreach (SCR_InfoDisplay display : m_aHUDElements)
277  {
278  if (display.m_LayoutPath == path)
279  return display.GetRootWidget();
280  }
281 
282  return null;
283  }
284 
285  //------------------------------------------------------------------------------------------------
286  protected void InitRootWidget(Widget root, string name)
287  {
288  FrameSlot.SetAnchorMin(root, 0, 0);
289  FrameSlot.SetAnchorMax(root, 1, 1);
290  FrameSlot.SetOffsets(root, 0, 0, 0, 0);
291  root.SetFlags(WidgetFlags.IGNORE_CURSOR);
292  root.SetName(name);
293  }
294 
295  //------------------------------------------------------------------------------------------------
296  Widget CreateLayout(ResourceName path, EHudLayers layer, int zOrder = 0)
297  {
298  #ifndef DISABLE_HUD_MANAGER
299 
300  if (path == string.Empty)
301  return null;
302 
303  Widget parent;
304  if (m_aLayerWidgets.Find(layer, parent) && parent)
305  {
306  Widget w = GetGame().GetWorkspace().CreateWidgets(path, parent);
307  if (w)
308  {
309  FrameSlot.SetAnchorMin(w, 0, 0);
310  FrameSlot.SetAnchorMax(w, 1, 1);
311  FrameSlot.SetOffsets(w, 0, 0, 0, 0);
312  w.SetFlags(WidgetFlags.IGNORE_CURSOR);
313  if (zOrder != 0)
314  w.SetZOrder(zOrder);
315 
316  return w;
317  }
318  }
319 
320  #endif
321 
322  return null;
323  }
324 
325  SCR_HUDElement CreateFreeElement(ResourceName path, string parentName)
326  {
328  if (!layoutHandler)
329  return null;
330 
331  SCR_HUDLayout owningLayout;
332  Widget parentWidget = layoutHandler.FindWidgetByNameFromAnyLayout(parentName, owningLayout);
333  if (!parentWidget)
334  return null;
335 
336  if (parentWidget.FindHandler(SCR_HUDSlotUIComponent))
337  {
338  Print(parentName + " is a HUD Slot! Use InfoDisplay instead!", LogLevel.ERROR);
339  return null;
340  }
341 
342  Widget elementWidget = GetGame().GetWorkspace().CreateWidgets(path, parentWidget);
343 
344  SCR_HUDElement hudElement = new SCR_HUDElement();
345  hudElement.SetWidget(elementWidget);
346  hudElement.SetParentWidgetName(parentName);
347  hudElement.SetParentLayout(owningLayout);
348  owningLayout.AddHudElement(hudElement);
349 
350  return hudElement;
351  }
352 
357  void SetVisible(bool isVisible)
358  {
359  m_wRoot.SetVisible(isVisible);
360  m_wRootTop.SetVisible(isVisible);
361  }
366  bool IsVisible()
367  {
368  return m_wRoot.IsVisible();
369  }
370 
375  void SetVisibleLayers(EHudLayers layers = -1)
376  {
377  if (layers == -1)
378  {
379  //--- Show all
380  foreach (EHudLayers layer, Widget w : m_aLayerWidgets)
381  {
382  w.SetVisible(true);
383  }
384  }
385  else
386  {
387  //--- Show custom
388  foreach (EHudLayers layer, Widget w : m_aLayerWidgets)
389  {
390  w.SetVisible(layers & layer);
391  }
392  }
393  }
399  EHudLayers GetVisibleLayers()
400  {
401  EHudLayers layers;
402  foreach (EHudLayers layer, Widget w : m_aLayerWidgets)
403  {
404  if (w.IsVisible()) layers = layers | layer;
405  }
406  return layers;
407  }
408 
409  //------------------------------------------------------------------------------------------------
410  static SCR_HUDManagerComponent GetHUDManager()
411  {
412  #ifndef DISABLE_HUD_MANAGER
413 
414  ArmaReforgerScripted game = GetGame();
415 
416  if (game)
417  return game.GetHUDManager();
418 
419  #endif
420 
421  return null;
422  }
423 
424  #ifdef WORKBENCH
425  // The two methods below allow us to open a context menu over the SCR_HUDManagerComponent
426  // It adds a 'Add actions to AvailableActionsDisplay info' entry
427  // After selection a dialog with all actions is shown from which the user can select some
428  // AvailableActionsDisplay is then filled with entries of selected actions
429  // Entry is only added if we have a SCR_AvailableActionsDisplay object in the hud manager
430  // Multiple SCR_AvailableActionsDisplay are not supported
431 
432  //------------------------------------------------------------------------------------------------
433  const int CONTEXT_GENERATE_AVAILABLE_INPUT_ACTION = 0;
434  //------------------------------------------------------------------------------------------------
435  override array<ref WB_UIMenuItem> _WB_GetContextMenuItems(IEntity owner)
436  {
437  // Prep array
438  array<ref WB_UIMenuItem> items = new array<ref WB_UIMenuItem>();
439 
440  // Find available actions display
441  array<BaseInfoDisplay> elements = new array<BaseInfoDisplay>();
442  GetInfoDisplays(elements);
443  foreach (auto element : elements)
444  {
445  // Create item option
446  if (SCR_AvailableActionsDisplay.Cast(element))
447  {
448  ref WB_UIMenuItem actionsContextItem = new WB_UIMenuItem("Add actions to AvailableActionsDisplay info", CONTEXT_GENERATE_AVAILABLE_INPUT_ACTION);
449  items.Insert(actionsContextItem);
450  break;
451  }
452  }
453  // Return arr
454  return items;
455  }
456 
457  //------------------------------------------------------------------------------------------------
458  override void _WB_OnContextMenu(IEntity owner, int id)
459  {
460  if (id == CONTEXT_GENERATE_AVAILABLE_INPUT_ACTION)
461  {
463 
464  // Find available actions display
465  array<BaseInfoDisplay> elements = new array<BaseInfoDisplay>();
466  GetInfoDisplays(elements);
467  foreach (auto element : elements)
468  {
469  if (SCR_AvailableActionsDisplay.Cast(element))
470  {
471  target = SCR_AvailableActionsDisplay.Cast(element);
472  break;
473  }
474  }
475 
476  if (!target)
477  return;
478 
479  GenericEntity genericOwner = GenericEntity.Cast(owner);
480  if (!genericOwner)
481  return;
482 
483  // Get all actions
484  InputManager mgr = GetGame().GetInputManager();
485  array<string> actions = new array<string>();
486  if (mgr)
487  {
488  int cnt = mgr.GetActionCount();
489  for (int i = 0; i < cnt; i++)
490  {
491  auto act = mgr.GetActionName(i);
492  actions.Insert(act);
493  }
494  }
495 
496  // Get wb we api
497  WorldEditorAPI api = genericOwner._WB_GetEditorAPI();
498  if (!api)
499  return;
500 
501  // Pass them into a dialog
502  // TODO: Make this not use cpp and make it more reasonable in general
503  array<int> selection = new array<int>();
504  api.ShowItemListDialog("Actions Selection", "Select actions from the actions manager to create entry for.", 340, 480, actions, selection, 0);
505 
506  // Parent entity source
507  IEntitySource entitySource = api.EntityToSource(owner);
508  if (!entitySource)
509  return;
510 
511  // Hud manager source
512  BaseContainer componentContainer;
513  int cmpCount = entitySource.GetComponentCount();
514  for (int i = 0; i < cmpCount; i++)
515  {
516  IEntityComponentSource componentSource = entitySource.GetComponent(i);
517  if (componentSource.GetClassName() == "SCR_HUDManagerComponent")
518  {
519  componentContainer = componentSource.ToBaseContainer();
520  break;
521  }
522  }
523 
524  if (!componentContainer)
525  return;
526 
527  // InfoDisplays array of hud manager
528  BaseContainerList infoDisplays = componentContainer.GetObjectArray("InfoDisplays");
529  if (!infoDisplays)
530  return;
531 
532  // SCR_AvailableActionsDisplay object
533  BaseContainer displaySource;
534  for (int i = 0; i < infoDisplays.Count(); i++)
535  {
536  BaseContainer container = infoDisplays.Get(i);
537  if (container.GetClassName() == "SCR_AvailableActionsDisplay")
538  {
539  displaySource = container;
540  break;
541  }
542  }
543 
544  if (!displaySource)
545  return;
546 
547  api.BeginEntityAction("Create action container");
548 
549  const string list = "m_aActions";
550  // Create object for each action
551  foreach (auto sel : selection)
552  {
553  string selectedActionName = actions[sel];
554  if (selectedActionName == string.Empty)
555  continue;
556 
557  const int objIndex = 0;
558  // Create object, push it into array
559  api.CreateObjectArrayVariableMember(displaySource, null, list, "SCR_AvailableActionContext", objIndex);
560  // Retrieve the source
561  BaseContainerList itemsList = displaySource.GetObjectArray(list);
562  BaseContainer thisContainer = itemsList.Get(objIndex);
563  thisContainer.Set("m_sAction", selectedActionName);
564  thisContainer.Set("m_sName", selectedActionName);
565  }
566 
567  api.EndEntityAction();
568  return;
569  }
570  }
571  #endif
572 }
SCR_HUDManagerComponent
Definition: SCR_HUDManagerComponent.c:23
m_aHandlers
protected ref array< ref SCR_InfoDisplayHandler > m_aHandlers
Definition: SCR_InfoDisplay.c:57
SCR_HUDManagerHandler
Definition: SCR_HUDManagerHandler.c:2
HUDManagerComponentClass
Definition: HUDManagerComponent.c:12
SCR_Enum
Definition: SCR_Enum.c:1
m_wRoot
protected Widget m_wRoot
Definition: SCR_ScenarioFrameworkLayerTaskDefend.c:59
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_HUDLayout
Definition: SCR_HUDLayout.c:2
ALWAYS_TOP
ALWAYS_TOP
Definition: SCR_HUDManagerComponent.c:7
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
GenericEntity
SCR_GenericBoxEntityClass GenericEntity
func
func
Definition: SCR_AIThreatSystem.c:5
LOW
LOW
Definition: SCR_HUDManagerComponent.c:3
EHudLayers
EHudLayers
Definition: SCR_HUDManagerComponent.c:5
HIGH
HIGH
Definition: SCR_HUDManagerComponent.c:5
GetInfoDisplays
BaseHUDComponentClass GameComponentClass GetInfoDisplays(out notnull array< BaseInfoDisplay > outInfoDisplays)
Attribute
typedef Attribute
Post-process effect of scripted camera.
m_World
protected BaseWorld m_World
Definition: SCR_PreviewEntityEditorUIComponent.c:46
OnScreenBrightnessChanged
func OnScreenBrightnessChanged
Definition: SCR_HUDManagerComponent.c:21
SCR_HUDManagerLayoutHandler
Definition: SCR_HUDManagerLayoutHandler.c:7
m_aUpdatableHandlers
protected ref array< ref SCR_InfoDisplayHandler > m_aUpdatableHandlers
Definition: SCR_InfoDisplay.c:74
OVERLAY
OVERLAY
Definition: SCR_HUDManagerComponent.c:6
type
EDamageType type
Definition: SCR_DestructibleTreeV2.c:32
MEDIUM
MEDIUM
Definition: SCR_HUDManagerComponent.c:4
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
ComponentEditorProps
enum EHudLayers ComponentEditorProps(icon:HYBRID_COMPONENT_ICON)
Definition: SCR_HUDManagerComponent.c:15
SCR_HUDElement
Definition: SCR_HUDFreeSlot.c:1
BACKGROUND
BACKGROUND
Definition: SCR_HUDManagerComponent.c:2
m_Owner
SCR_AIGroupUtilityComponentClass m_Owner
SCR_AvailableActionsDisplay
Definition: SCR_AvailableActionsDisplay.c:237
SCR_HUDSlotUIComponent
Definition: SCR_HUDSlotUIComponent.c:5
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180