Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_FuelManagerComponent.c
Go to the documentation of this file.
1 [ComponentEditorProps(category: "GameScripted/Misc", description: "")]
3 {
4 }
5 
6 class SCR_FuelManagerComponent : FuelManagerComponent
7 {
9 
10  //------------------------------------------------------------------------------------------------
13  int GetScriptedFuelNodesList(out notnull array<SCR_FuelNode> outScriptedNodes)
14  {
15  outScriptedNodes.Clear();
16 
17  array<BaseFuelNode> fuelNodes = {};
18  GetFuelNodesList(fuelNodes);
19  SCR_FuelNode scrNode;
20 
21  foreach(BaseFuelNode node : fuelNodes)
22  {
23  scrNode = SCR_FuelNode.Cast(node);
24  if (!scrNode)
25  continue;
26 
27  outScriptedNodes.Insert(scrNode);
28  }
29 
30  return outScriptedNodes.Count();
31  }
32 
33  //------------------------------------------------------------------------------------------------
39  int GetScriptedFuelNodesList(out notnull array<SCR_FuelNode> outScriptedNodes, SCR_EFuelNodeTypeFlag hasFuelNodeFlags, SCR_EFuelNodeTypeFlag ignoreIfHasFlags = 0, SCR_EFuelNodeFlagQueryType queryType = SCR_EFuelNodeFlagQueryType.ALL_GIVEN_TYPES)
40  {
41  //~ No need to check flags if none are given
42  if (hasFuelNodeFlags <= 0 && ignoreIfHasFlags <= 0)
43  return GetScriptedFuelNodesList(outScriptedNodes);
44 
45  outScriptedNodes.Clear();
46 
47  array<BaseFuelNode> fuelNodes = {};
48  GetFuelNodesList(fuelNodes);
49  SCR_FuelNode scrNode;
50 
51  foreach(BaseFuelNode node : fuelNodes)
52  {
53  scrNode = SCR_FuelNode.Cast(node);
54  if (!scrNode)
55  continue;
56 
57  if (ignoreIfHasFlags > 0 && scrNode.HasAnyTypeFlag(ignoreIfHasFlags))
58  continue;
59 
60  if (hasFuelNodeFlags > 0)
61  {
62  bool validNode;
63 
64  switch (queryType)
65  {
66  case SCR_EFuelNodeFlagQueryType.EXACT_TYPE:
67  {
68  validNode = scrNode.HasExactTypeFlags(hasFuelNodeFlags);
69  break;
70  }
71  case SCR_EFuelNodeFlagQueryType.ALL_GIVEN_TYPES:
72  {
73  validNode = scrNode.HasAllTypeFlags(hasFuelNodeFlags);
74  break;
75  }
76  case SCR_EFuelNodeFlagQueryType.ANY_OF_GIVEN_TYPES:
77  {
78  validNode = scrNode.HasAnyTypeFlag(hasFuelNodeFlags);
79  break;
80  }
81  }
82 
83  if (!validNode)
84  continue;
85  }
86 
87  outScriptedNodes.Insert(scrNode);
88  }
89 
90  return outScriptedNodes.Count();
91  }
92 
93  //------------------------------------------------------------------------------------------------
98  bool CanBeRefueledScripted(array<int> fuelTanksReceivers = null, SCR_EFuelNodeTypeFlag ignoreIfHasFlags = 0)
99  {
100  array<SCR_FuelNode> nodes = {};
101  SCR_FuelNode node;
102  for (int i = GetScriptedFuelNodesList(nodes, SCR_EFuelNodeTypeFlag.CAN_RECEIVE_FUEL, ignoreIfHasFlags) - 1; i >= 0; i--)
103  {
104  node = nodes.Get(i);
105 
106  if (!node || node.GetFuel() >= node.GetMaxFuel())
107  continue;
108 
109  if (fuelTanksReceivers && !fuelTanksReceivers.IsEmpty())
110  {
111  if (!fuelTanksReceivers.Contains(node.GetFuelTankID()))
112  continue;
113  }
114  //~ Passes all tests
115  return true;
116  }
117 
118  //~ Has no nodes to refuel
119  return false;
120  }
121 
122  //~ Todo: move logic from SCR_FuelSupportStationComponent to SCR_FuelManagerComponent
123  //------------------------------------------------------------------------------------------------
129 // float TransferFuelWithFlow(float fuelToTransfer, SCR_FuelManagerComponent provider = null, array<int> fuelTanksReceivers = null, SCR_EFuelNodeTypeFlag ignoreIfHasFlags = 0)
130 // {
131 // }
132 
133  //------------------------------------------------------------------------------------------------
137  static int GetAllFuelManagers(notnull IEntity entity, out notnull array<SCR_FuelManagerComponent> fuelManagers)
138  {
139  fuelManagers.Clear();
140 
141  SCR_FuelManagerComponent fuelManager = SCR_FuelManagerComponent.Cast(entity.FindComponent(SCR_FuelManagerComponent));
142  if (fuelManager)
143  fuelManagers.Insert(fuelManager);
144 
145  SlotManagerComponent slotManager = SlotManagerComponent.Cast(entity.FindComponent(SlotManagerComponent));
146  if (!slotManager)
147  return fuelManagers.Count();
148 
149  array<EntitySlotInfo> slotInfos = {};
150  slotManager.GetSlotInfos(slotInfos);
151 
152  IEntity slotEntity;
153 
154  foreach (EntitySlotInfo slotInfo: slotInfos)
155  {
156  slotEntity = slotInfo.GetAttachedEntity();
157 
158  if (!slotEntity)
159  continue;
160 
161  fuelManager = SCR_FuelManagerComponent.Cast(slotEntity.FindComponent(SCR_FuelManagerComponent));
162  if (fuelManager)
163  fuelManagers.Insert(fuelManager);
164  }
165 
166  return fuelManagers.Count();
167  }
168 
169  //------------------------------------------------------------------------------------------------
173  bool HasFuelToProvide(SCR_EFuelNodeTypeFlag ignoreIfHasFlags = 0)
174  {
175  //~ Get all fuel providers
176  array<SCR_FuelNode> nodes = {};
177  GetScriptedFuelNodesList(nodes, SCR_EFuelNodeTypeFlag.CAN_PROVIDE_FUEL, ignoreIfHasFlags);
178 
179  //~ No nodes
180  if (nodes.IsEmpty())
181  return false;
182 
183  //~ Loop through fuel providers and check if it has any fuel
184  foreach(SCR_FuelNode node: nodes)
185  {
186  //~ Can provide and has fuel.
187  if (!float.AlmostEqual(node.GetFuel(), 0))
188  return true;
189  }
190 
191  //~ No valid fuel nodes found that can provide fuel
192  return false;
193  }
194 
195  //------------------------------------------------------------------------------------------------
203  void GetTotalValuesOfFuelNodes(out float totalFuel, out float totalMaxFuel, out float totalFuelPercentage, SCR_EFuelNodeTypeFlag hasFuelNodeFlags = 0, SCR_EFuelNodeTypeFlag ignoreIfHasFlags = 0, SCR_EFuelNodeFlagQueryType queryType = SCR_EFuelNodeFlagQueryType.ALL_GIVEN_TYPES)
204  {
205  totalFuel = 0;
206  totalMaxFuel = 0;
207  totalFuelPercentage = 0;
208 
209  //~ No flags are set no need to loop through all nodes
210  if (hasFuelNodeFlags <= 0 && ignoreIfHasFlags <= 0)
211  {
212  totalFuel = GetTotalFuel();
213  totalMaxFuel = GetTotalMaxFuel();
214  }
215  else
216  {
217  array<BaseFuelNode> fuelNodes = {};
218  GetFuelNodesList(fuelNodes);
219  SCR_FuelNode scrFuelNode;
220 
221  foreach(BaseFuelNode node: fuelNodes)
222  {
223  //~ If flags set
224  scrFuelNode = SCR_FuelNode.Cast(node);
225 
226  //~ Get valid fuel node (non-SCR are always valid)
227  if (scrFuelNode)
228  {
229  //~ Has a flag it should not
230  if (ignoreIfHasFlags > 0 && scrFuelNode.HasAnyTypeFlag(ignoreIfHasFlags))
231  continue;
232 
233  //~ Check if node is valid
234  if (hasFuelNodeFlags > 0)
235  {
236  bool validNode;
237 
238  switch (queryType)
239  {
240  case SCR_EFuelNodeFlagQueryType.EXACT_TYPE:
241  {
242  validNode = scrFuelNode.HasExactTypeFlags(hasFuelNodeFlags);
243  break;
244  }
245  case SCR_EFuelNodeFlagQueryType.ALL_GIVEN_TYPES:
246  {
247  validNode = scrFuelNode.HasAllTypeFlags(hasFuelNodeFlags);
248  break;
249  }
250  case SCR_EFuelNodeFlagQueryType.ANY_OF_GIVEN_TYPES:
251  {
252  validNode = scrFuelNode.HasAnyTypeFlag(hasFuelNodeFlags);
253  break;
254  }
255  }
256 
257  if (!validNode)
258  continue;
259  }
260  }
261 
262  totalFuel += node.GetFuel();
263  totalMaxFuel += node.GetMaxFuel();
264  }
265  }
266 
267  //~ Safty
268  if (totalMaxFuel <= 0)
269  {
270  totalFuel = 0;
271  totalMaxFuel = 0;
272  totalFuelPercentage = 0;
273  return;
274  }
275 
276  totalFuelPercentage = totalFuel / totalMaxFuel;
277  }
278 
279  //------------------------------------------------------------------------------------------------
288  static void GetTotalValuesOfFuelNodesOfFuelManagers(notnull array<SCR_FuelManagerComponent> fuelManagers, out float totalFuel, out float totalMaxFuel, out float totalFuelPercentage, SCR_EFuelNodeTypeFlag hasfuelNodeFlags = 0, SCR_EFuelNodeTypeFlag ignoreIfHasFlags = 0, SCR_EFuelNodeFlagQueryType queryType = SCR_EFuelNodeFlagQueryType.ALL_GIVEN_TYPES)
289  {
290  totalFuel = 0;
291  totalMaxFuel = 0;
292  totalFuelPercentage = 0;
293 
294  if (fuelManagers.IsEmpty())
295  return;
296 
297  float nodeTotalFuel, nodeTotalMaxFuel, nodeTotalFuelPercentage;
298 
299  //~ Get values of all fuelmanagers
300  foreach (SCR_FuelManagerComponent fuelManager: fuelManagers)
301  {
302  if (!fuelManager)
303  continue;
304 
305  fuelManager.GetTotalValuesOfFuelNodes(nodeTotalFuel, nodeTotalMaxFuel, nodeTotalFuelPercentage, hasfuelNodeFlags, ignoreIfHasFlags, queryType);
306 
307  totalFuel += nodeTotalFuel;
308  totalMaxFuel += nodeTotalMaxFuel;
309  }
310 
311  //~ Safty
312  if (totalMaxFuel <= 0)
313  {
314  totalFuel = 0;
315  totalMaxFuel = 0;
316  totalFuelPercentage = 0;
317  return;
318  }
319 
320  //~ Calculate total percentage
321  totalFuelPercentage = totalFuel / totalMaxFuel;
322  }
323 
324  //------------------------------------------------------------------------------------------------
331  void SetTotalFuelPercentage(float percentage, SCR_EFuelNodeTypeFlag hasFuelNodeFlags = 0, SCR_EFuelNodeTypeFlag ignoreIfHasFlags = 0, SCR_EFuelNodeFlagQueryType queryType = SCR_EFuelNodeFlagQueryType.ALL_GIVEN_TYPES)
332  {
333  //~ Safty clamp
334  percentage = Math.Clamp(percentage, 0 , 1);
335 
336  array<BaseFuelNode> fuelNodes = {};
337  array<BaseFuelNode> validFuelNodes = {};
338  SCR_FuelNode scrFuelNode;
339 
340  float totalFuel = 0;
341  float totalMaxFuel 0;
342 
343  GetFuelNodesList(fuelNodes);
344 
345  //~ Get total fuel and max fuel of all non providers
346  foreach(BaseFuelNode node: fuelNodes)
347  {
348  //~ If flags set
349  if (hasFuelNodeFlags > 0 || ignoreIfHasFlags > 0)
350  {
351  scrFuelNode = SCR_FuelNode.Cast(node);
352 
353  //~ Get valid fuel node (non-SCR are always valid)
354  if (scrFuelNode)
355  {
356  //~ Has a flag it should not
357  if (ignoreIfHasFlags > 0 && scrFuelNode.HasAnyTypeFlag(ignoreIfHasFlags))
358  continue;
359 
360  //~ Check if node is valid
361  if (hasFuelNodeFlags > 0)
362  {
363  bool validNode;
364 
365  switch (queryType)
366  {
367  case SCR_EFuelNodeFlagQueryType.EXACT_TYPE:
368  {
369  validNode = scrFuelNode.HasExactTypeFlags(hasFuelNodeFlags);
370  break;
371  }
372  case SCR_EFuelNodeFlagQueryType.ALL_GIVEN_TYPES:
373  {
374  validNode = scrFuelNode.HasAllTypeFlags(hasFuelNodeFlags);
375  break;
376  }
377  case SCR_EFuelNodeFlagQueryType.ANY_OF_GIVEN_TYPES:
378  {
379  validNode = scrFuelNode.HasAnyTypeFlag(hasFuelNodeFlags);
380  break;
381  }
382  }
383 
384  if (!validNode)
385  continue;
386  }
387  }
388  }
389 
390  validFuelNodes.Insert(node);
391  totalFuel += node.GetFuel();
392  totalMaxFuel += node.GetMaxFuel();
393  }
394 
395  float newFuel = totalMaxFuel * percentage;
396  float diff = newFuel - totalFuel;
397 
398  foreach(BaseFuelNode node: validFuelNodes)
399  {
400  float fuel = node.GetFuel();
401  float maxFuel = node.GetMaxFuel();
402 
403  if (diff > 0)
404  {
405  // Distribute remaining capacity
406  if (totalMaxFuel > totalFuel)
407  fuel += diff * (maxFuel - fuel) / (totalMaxFuel - totalFuel);
408  }
409  else if (diff < 0)
410  {
411  // Distribute remaining fuel
412  if (totalFuel > 0)
413  fuel += diff * fuel / totalFuel;
414  }
415 
416  node.SetFuel(fuel);
417  }
418  }
419 
420  //------------------------------------------------------------------------------------------------
428  static void SetTotalFuelPercentageOfFuelManagers(notnull array<SCR_FuelManagerComponent> fuelManagers, float percentage, SCR_EFuelNodeTypeFlag hasFuelNodeFlags = 0, SCR_EFuelNodeTypeFlag ignoreIfHasFlags = 0, SCR_EFuelNodeFlagQueryType queryType = SCR_EFuelNodeFlagQueryType.ALL_GIVEN_TYPES)
429  {
430  if (fuelManagers.IsEmpty())
431  return;
432 
433  foreach (SCR_FuelManagerComponent fuelManager: fuelManagers)
434  {
435  if (!fuelManager)
436  continue;
437 
438  fuelManager.SetTotalFuelPercentage(percentage, hasFuelNodeFlags, ignoreIfHasFlags, queryType);
439  }
440  }
441 
442  //------------------------------------------------------------------------------------------------
447  {
448  if (!m_OnFuelChanged)
449  {
451 
452  array<SCR_FuelNode> fuelNodes = {};
453 
454  GetScriptedFuelNodesList(fuelNodes);
455  foreach (SCR_FuelNode scrNode : fuelNodes)
456  {
457  scrNode.GetOnFuelChanged().Insert(OnFuelNodeAmountChanged);
458  }
459  }
460 
461  return m_OnFuelChanged;
462  }
463 
464  //------------------------------------------------------------------------------------------------
465  protected void OnFuelNodeAmountChanged(float newFuel)
466  {
467  m_OnFuelChanged.Invoke(GetTotalFuel());
468  }
469 
470  //------------------------------------------------------------------------------------------------
471  // constructor
475  void SCR_FuelManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
476  {
477  if (SCR_Global.IsEditMode())
478  return;
479 
480  #ifdef WORKBENCH
481  //~ Safty check if the Fuelmanager has any non SCR_FuelNode's in the array
482  array<BaseFuelNode> fuelNodes = {};
483  GetFuelNodesList(fuelNodes);
484 
485  foreach(BaseFuelNode node : fuelNodes)
486  {
487  if (!node.IsInherited(SCR_FuelNode))
488  {
489  Print("'SCR_FuelManagerComponent' has non SCR_FuelNode in the array! This is not supported with many of the SCR_Fuelmanager logics!", LogLevel.WARNING);
490  break;
491  }
492  }
493  #endif
494  }
495 }
496 
497 //~ Fuel node type flags
499 {
503 }
OnFuelNodeAmountChanged
protected void OnFuelNodeAmountChanged(float newFuel)
Definition: SCR_FuelManagerComponent.c:465
ComponentEditorProps
SCR_FragmentEntityClass ComponentEditorProps
FuelManagerComponentClass
Definition: FuelManagerComponent.c:12
HasFuelToProvide
bool HasFuelToProvide(SCR_EFuelNodeTypeFlag ignoreIfHasFlags=0)
Definition: SCR_FuelManagerComponent.c:173
GetTotalMaxFuel
proto external float GetTotalMaxFuel()
Get the current sum of the max amount of fuel in all nodes.
GetTotalValuesOfFuelNodes
void GetTotalValuesOfFuelNodes(out float totalFuel, out float totalMaxFuel, out float totalFuelPercentage, SCR_EFuelNodeTypeFlag hasFuelNodeFlags=0, SCR_EFuelNodeTypeFlag ignoreIfHasFlags=0, SCR_EFuelNodeFlagQueryType queryType=SCR_EFuelNodeFlagQueryType.ALL_GIVEN_TYPES)
Definition: SCR_FuelManagerComponent.c:203
BaseFuelNode
Definition: BaseFuelNode.c:12
SCR_FuelManagerComponentClass
Definition: SCR_FuelManagerComponent.c:2
ANY_OF_GIVEN_TYPES
@ ANY_OF_GIVEN_TYPES
Will only get fuelnode if at least one of the given flags is present on the fuel node....
Definition: SCR_FuelManagerComponent.c:502
m_OnFuelChanged
SCR_FuelManagerComponentClass m_OnFuelChanged
EntitySlotInfo
Adds ability to attach an object to a slot.
Definition: EntitySlotInfo.c:8
EXACT_TYPE
@ EXACT_TYPE
Will only get fuel node if flag type is the same as given flag.
Definition: SCR_FuelManagerComponent.c:500
GetOnFuelChanged
ScriptInvokerFloat GetOnFuelChanged()
Definition: SCR_FuelManagerComponent.c:446
ScriptInvokerFloat
ScriptInvokerBase< ScriptInvokerFloatMethod > ScriptInvokerFloat
Definition: SCR_ScriptInvokerHelper.c:58
GetFuelNodesList
FuelManagerComponentClass GameComponentClass GetFuelNodesList(out notnull array< BaseFuelNode > outNodes)
SCR_FuelManagerComponent
void SCR_FuelManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_FuelManagerComponent.c:475
GetTotalFuel
proto external float GetTotalFuel()
Get the current sum of amount of fuel in all nodes.
SCR_Global
Definition: Functions.c:6
GetScriptedFuelNodesList
int GetScriptedFuelNodesList(out notnull array< SCR_FuelNode > outScriptedNodes)
Definition: SCR_FuelManagerComponent.c:13
CanBeRefueledScripted
bool CanBeRefueledScripted(array< int > fuelTanksReceivers=null, SCR_EFuelNodeTypeFlag ignoreIfHasFlags=0)
Definition: SCR_FuelManagerComponent.c:98
SetTotalFuelPercentage
void SetTotalFuelPercentage(float percentage, SCR_EFuelNodeTypeFlag hasFuelNodeFlags=0, SCR_EFuelNodeTypeFlag ignoreIfHasFlags=0, SCR_EFuelNodeFlagQueryType queryType=SCR_EFuelNodeFlagQueryType.ALL_GIVEN_TYPES)
Definition: SCR_FuelManagerComponent.c:331
SCR_EFuelNodeFlagQueryType
SCR_EFuelNodeFlagQueryType
Definition: SCR_FuelManagerComponent.c:498
ALL_GIVEN_TYPES
@ ALL_GIVEN_TYPES
Will only get fuelnode if all the given types are present on the fuel node. (More than the given can ...
Definition: SCR_FuelManagerComponent.c:501
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180