Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_FiringRangeController.c
Go to the documentation of this file.
1 [EntityEditorProps(category: "GameScripted/FiringRange", description: "Controller of firing line, handles behaviour of targets.", color: "0 0 255 255", dynamicBox: true)]
2 
3 
4 class SCR_FiringRangeControllerClass: GenericEntityClass
5 {
6 };
7 
8 //------------------------------------------------------------------------------------------------
10 {
11  const static int NO_TARGET_OWNER = -1;
12  const static int RESET_COUNTER_TIME = 1500;
13  const static int POWER_LIGHT_DELAY = 1000;
14  const static int INDICATOR_MAX_VALUE = 9999;
15 
16  // Digits cone rotatioin value
17  const static int DIGIT_ZERO = 0;
18  const static int DIGIT_ONE = 315;
19  const static int DIGIT_TWO = 280;
20  const static int DIGIT_THREE = 245;
21  const static int DIGIT_FOUR = 210;
22  const static int DIGIT_FIVE = 175;
23  const static int DIGIT_SIX = 140;
24  const static int DIGIT_SEVEN = 105;
25  const static int DIGIT_EIGHT = 70;
26  const static int DIGIT_NINE = 35;
27 
28  const static string LIGHT_POWER = "light_001_power";
29  const static string LIGHT_SEQUENCE = "light_002_sequence";
30  const static string LIGHT_MALFUNCTION = "light_003_malfunction";
31 
32  const static int LIGHT_EMISSIVITY_ON = 1;
33  const static int LIGHT_EMISSIVITY_OFF = 0;
34 
35  const static bool LIGHT_ON = true;
36  const static bool LIGHT_OFF = false;
37 
38  private ParametricMaterialInstanceComponent m_LightPower;
39  private ParametricMaterialInstanceComponent m_LightSequence;
40  private ParametricMaterialInstanceComponent m_LightMalfunction;
41 
42  // Variable used for JIP synchronization. Because Power light don't change it's state and Malfunction light blink only for one sec, only this worht of synchronization.
43  // Todo: Replace this with EmissiveMultiplier getter (ParametricMaterialInstanceComponent).
44  private bool m_bRoundLightState = false;
45  private int m_iDistanceIndicatorValue;
46  private int m_iNumberOfTargetsIndicatorValue;
47 
48  // Time for how long warning light should be on when player leaves the area
49  const static int ERROR_LIGHT_DURATION = 1000;
50 
52  [Attribute("4", UIWidgets.Slider, "For how long target stays in erected position in seconds.", "1 100 1")]
53  protected int m_iErectTargetTime;
54 
56  [Attribute("{F2E83D562703F861}Assets/Decals/Impact/DecalHitIndicator.emat", UIWidgets.ResourceNamePicker, "Material used for target hit indicator", "emat")]
57  private ResourceName m_PreviewDecal;
58 
59  [Attribute("", UIWidgets.ResourceNamePicker, "Power light entity", "et")]
60  private ResourceName m_LightPowerRes;
61 
62  [Attribute("", UIWidgets.ResourceNamePicker, "Sequence light entity", "et")]
63  private ResourceName m_LightSequenceRes;
64 
65  [Attribute("", UIWidgets.ResourceNamePicker, "Malfunction light entity", "et")]
66  private ResourceName m_LightMalfunctionRes;
67 
68  [Attribute("1", UIWidgets.Slider, "Targets in one round", "1 20 10")]
69  private int m_iTargetsInRound;
70 
71  [RplProp()]
72  private int m_iCountShots = 0;
73 
74  [RplProp()]
75  private int m_iTargetSetDistance;
76 
77  // owner of the firing line PlayerController (player)
78  [RplProp()]
79  private int m_iFiringLineOwner = NO_TARGET_OWNER;
80 
81  private SCR_FiringRangeTarget m_LastSelectedTarget;
82  private SCR_FiringRangeTarget m_CurrentSelectedTarget;
83 
84  private int m_iElementInArray = 0;
85  private int m_iValuePos;
86  private int m_iHighestPossibleDistance;
87 
88  private static ref array<SCR_FiringRangeController> s_aInstances = {};
89  private ref array<SCR_FiringRangeTarget> m_aAllTargetsArray = {};
90  private ref array<int> m_aDistances = {};
91  private ref array<Decal> m_aIndicators = {};
92 
93  // Arrays with saved coordinates and vectors of decals
94  private ref array<vector> m_aIndicatorsCoords = {};
95  private ref array<vector> m_aIndicatorsVector = {};
96 
97  // time for how long target stays erected
98  private float m_fTargetErectedDuration;
99 
100  // target which serves as an indicators
101  private IEntity m_Indicator;
102 
103  // components
104  private RplComponent m_RplComponent;
105  private SignalsManagerComponent m_SignalManager;
106 
107  private SCR_FiringRangeManager m_FiringRangeManager;
108 
109  //------------------------------------------------------------------------------------------------
110  override void EOnInit(IEntity owner)
111  {
112  m_SignalManager = SignalsManagerComponent.Cast(owner.FindComponent(SignalsManagerComponent));
113 
114  array<EntitySlotInfo> slots = {}; EntitySlotInfo.GetSlotInfos(owner, slots);
115  IEntity slotEntity;
116  string slotBone;
117 
118  foreach (EntitySlotInfo slot: slots)
119  {
120  if (!slot)
121  continue;
122 
123  IEntity ent = slot.GetAttachedEntity();
124  if (!ent)
125  continue;
126 
127  slotBone = slot.GetBoneName();
128  if (!slotBone.IsEmpty())
129  {
130  switch (slotBone)
131  {
132  case LIGHT_POWER: {m_LightPower = ParametricMaterialInstanceComponent.Cast(ent.FindComponent(ParametricMaterialInstanceComponent)); break;};
133  case LIGHT_SEQUENCE: {m_LightSequence = ParametricMaterialInstanceComponent.Cast(ent.FindComponent(ParametricMaterialInstanceComponent)); break;};
134  case LIGHT_MALFUNCTION: {m_LightMalfunction = ParametricMaterialInstanceComponent.Cast(ent.FindComponent(ParametricMaterialInstanceComponent)); break;};
135  }
136  }
137  }
138 
139  // get an array of all distances of targets
140  CollectAllDistances(owner);
141  SetControllerLight(ControllerLightType.LIGHT_POWER, LIGHT_ON)
142 
143  }
144 
145  //------------------------------------------------------------------------------------------------
147  void AnimateTargets(IEntity pOwnerEntity,int playerID)
148  {
149  #ifdef ENABLE_DIAG
150  // safe check this method should be executed only on server
151  if (!CheckMasterOnlyMethod("AnimateTargets()"))
152  return;
153  #endif
154 
155  SCR_SoundManagerEntity soundManagerEntity = GetGame().GetSoundManagerEntity();
156  if (soundManagerEntity)
157  soundManagerEntity.CreateAndPlayAudioSource(pOwnerEntity, SCR_SoundEvent.SOUND_RANGECP_STARTBUTTON);
158 
159  // Gets all child targets in the fire line
160  if (!pOwnerEntity)
161  return;
162 
163  IEntity child = pOwnerEntity.GetChildren();
164  array<SCR_FiringRangeTarget> targetArray = new array<SCR_FiringRangeTarget>();
165 
166  // Set the owner of firing Line
167  m_iFiringLineOwner = playerID;
168  Replication.BumpMe();
169 
170  while (child)
171  {
172  SCR_FiringRangeTarget target = SCR_FiringRangeTarget.Cast(child);
173  if (target)
174  {
175  if (!target.IsIndicator())
176  {
177  // array of all targets in line. Not just those which were selected.
178  m_aAllTargetsArray.Insert(target);
179 
180  if ((target.GetSetDistance() == m_iTargetSetDistance) || m_iTargetSetDistance == -1)
181  {
182  targetArray.Insert(target);
183  };
184 
185  // Reset All targets into folded position
186  target.SetState(ETargetState.TARGET_DOWN);
187  target.SetAutoResetTarget(false); // The BumpMe is called in SetState!
188 
189  // Set target owner and target mode
190  target.SetTargetOwner(playerID);
191  target.SetTargetMode(ETargetMode.COMPETITION);
192  }
193  }
194 
195  child = child.GetSibling();
196  };
197 
198  // Sound of starting round
199  if (soundManagerEntity)
200  soundManagerEntity.CreateAndPlayAudioSource(pOwnerEntity, SCR_SoundEvent.SOUND_RANGECP_ROUNDSTART);
201 
202  GetGame().GetCallqueue().CallLater(ResetCountPopUpTargets, RESET_COUNTER_TIME, false);
203  GetGame().GetCallqueue().CallLater(ErectRandomTarget, m_iErectTargetTime * 1000, true, targetArray, m_aAllTargetsArray);
204 
205  if (m_FiringRangeManager)
206  m_FiringRangeManager.ControllerLight(this, ControllerLightType.LIGHT_SEQUENCE, LIGHT_ON);
207  }
208 
209  //------------------------------------------------------------------------------------------------
211  void ErectRandomTarget(array<SCR_FiringRangeTarget> targetArray)
212  {
213  // if the round finished, reset targets back to default behaviour
214  if (m_iCountShots >= m_iTargetsInRound)
215  {
216  BackToDefaultTarget();
217  return;
218  }
219 
220  m_LastSelectedTarget = m_CurrentSelectedTarget;
221  while (m_LastSelectedTarget == m_CurrentSelectedTarget && targetArray.Count() > 1)
222  {
223  m_CurrentSelectedTarget = targetArray.GetRandomElement();
224  };
225 
226  if (m_CurrentSelectedTarget)
227  {
228  m_fTargetErectedDuration = m_CurrentSelectedTarget.GetErectedDuration();
229  m_CurrentSelectedTarget.SetState(ETargetState.TARGET_UP);
230  GetGame().GetCallqueue().CallLater(FoldTarget, m_fTargetErectedDuration, false, m_CurrentSelectedTarget);
231  }
232  }
233 
234  //------------------------------------------------------------------------------------------------
236  void FoldTarget(SCR_FiringRangeTarget selectedTarget)
237  {
238  if (m_fTargetErectedDuration == 0)
239  return;
240 
241  if (selectedTarget)
242  {
243  float TargetState = selectedTarget.GetState();
244  if (TargetState == 0)
245  selectedTarget.SetState(ETargetState.TARGET_DOWN);
246  }
247  }
248 
249  //------------------------------------------------------------------------------------------------
251  void BackToDefaultTarget()
252  {
253  #ifdef ENABLE_DIAG
254  // safe check this method should be executed only on server
255  if (!CheckMasterOnlyMethod("BackToDefaultTarget()"))
256  return;
257  #endif
258 
259  // Reset the owner of firing Line
260  m_iFiringLineOwner = NO_TARGET_OWNER;
261  Replication.BumpMe();
262 
263  GetGame().GetCallqueue().Remove(ErectRandomTarget);
264 
265  for (int i = m_aAllTargetsArray.Count() - 1; i >= 0; i--)
266  {
267  SCR_FiringRangeTarget target = SCR_FiringRangeTarget.Cast(m_aAllTargetsArray[i]);
268 
269  if (target)
270  {
271  target.SetState(ETargetState.TARGET_UP);
272  target.SetAutoResetTarget(true); // The BumpMe is called in SetState!
273  target.SetTargetMode(ETargetMode.TRAINING);
274  target.SetTargetOwner(NO_TARGET_OWNER);
275  }
276  }
277 
278  m_aAllTargetsArray.Clear();
279  if (m_FiringRangeManager)
280  m_FiringRangeManager.ControllerLight(this, ControllerLightType.LIGHT_SEQUENCE, LIGHT_OFF);
281  }
282 
283  //------------------------------------------------------------------------------------------------
284  void SetIndicator(IEntity indicator)
285  {
286  m_Indicator = indicator;
287  }
288 
289  //------------------------------------------------------------------------------------------------
291  void BackToDefaultTargetsFromLineArea()
292  {
293  // set the time for how long the target should be in erected position to zero.
294  m_fTargetErectedDuration = 0;
295 
296  // Find local player controller
297  PlayerController playerController = GetGame().GetPlayerController();
298  if (!playerController)
299  return;
300 
301  // Find firing range network entity to send RPC to server
302  SCR_FiringRangeNetworkEntity firingRangeNetworkEntity = SCR_FiringRangeNetworkEntity.GetInstance();
303  if (!firingRangeNetworkEntity)
304  return;
305 
306  firingRangeNetworkEntity.BackToDefaultTarget(this);
307  if (m_FiringRangeManager)
308  {
309  m_FiringRangeManager.ControllerLight(this, ControllerLightType.LIGHT_MALFUNCTION, LIGHT_ON);
310  m_FiringRangeManager.ControllerLight(this, ControllerLightType.LIGHT_SEQUENCE, LIGHT_OFF);
311  GetGame().GetCallqueue().CallLater(m_FiringRangeManager.ControllerLight, ERROR_LIGHT_DURATION, false, this, ControllerLightType.LIGHT_MALFUNCTION, LIGHT_OFF);
312  }
313 
314  // Sound of presed button
315  SCR_SoundManagerEntity soundManagerEntity = GetGame().GetSoundManagerEntity();
316  if (soundManagerEntity)
317  soundManagerEntity.CreateAndPlayAudioSource(this, SCR_SoundEvent.SOUND_RANGECP_ROUNDABORT);
318  }
319 
320  //------------------------------------------------------------------------------------------------
322  void CollectAllDistances(IEntity owner)
323  {
324  IEntity child = owner.GetChildren();
325  while (child)
326  {
327  SCR_FiringRangeTarget target = SCR_FiringRangeTarget.Cast(child);
328  if (target && !target.IsIndicator())
329  {
330  int distance = target.GetSetDistance();
331  if (m_aDistances.Find(distance) == -1)
332  m_aDistances.Insert(distance);
333  }
334 
335  child = child.GetSibling();
336  };
337 
338  if (m_aDistances.IsEmpty())
339  return;
340 
341  m_aDistances.Sort();
342  m_iTargetSetDistance = m_aDistances[0];
343  if (m_SignalManager)
344  {
345  SetControllerCounter(EControlerSection.DISTANCE, GetTargetDistance());
346  SetControllerCounter(EControlerSection.NUMBER_OF_TARGETS ,GetTargetsInRound());
347  }
348 
349  Replication.BumpMe();
350  }
351 
352  //------------------------------------------------------------------------------------------------
354  array<int> GetAllDistances()
355  {
356  return m_aDistances;
357  }
358 
359  //------------------------------------------------------------------------------------------------
361  int GetFiringLineOwnerId()
362  {
363  return m_iFiringLineOwner;
364  }
365 
366  //------------------------------------------------------------------------------------------------
367  bool IsLowestDistanceSet()
368  {
369  return GetTargetDistance() == m_aDistances[0];
370  }
371 
372  //------------------------------------------------------------------------------------------------
373  bool IsHighestDistanceSet()
374  {
375  return GetTargetDistance() == m_aDistances[m_aDistances.Count()-1];
376  }
377 
378  //------------------------------------------------------------------------------------------------
380  int CalculateTargetDistance(bool increase)
381  {
382  #ifdef ENABLE_DIAG
383  // safe check this method should be executed only on server
384  if (!CheckMasterOnlyMethod("CalculateTargetDistance()"))
385  return -1;
386  #endif
387 
388  // get the current set distance
389  int currentDistance = m_iTargetSetDistance;
390 
391  // if the last state was last, lets go back to the beginning of the row
392  if (m_iTargetSetDistance == -1)
393  {
394  m_iTargetSetDistance = 0;
395  Replication.BumpMe();
396  }
397 
398  // check if it's highest possible distance in current row. If so, select all targets (-1) or go to the next element in row
399  m_iHighestPossibleDistance = m_aDistances.Count()-1;
400 
401  m_iValuePos = m_aDistances.Find(m_iTargetSetDistance);
402  if (increase)
403  {
404  m_iValuePos++;
405  }
406  else
407  {
408  m_iValuePos--;
409  }
410  m_iTargetSetDistance = m_aDistances[m_iValuePos];
411  Replication.BumpMe();
412 
413 
414  // Entity has a signal manager, try to set up the value on counter
415  if (m_SignalManager && m_FiringRangeManager)
416  m_FiringRangeManager.SetControllerCounter(this, EControlerSection.DISTANCE, m_iTargetSetDistance);
417 
418  // Sound of presed button
419  SCR_SoundManagerEntity soundManagerEntity = GetGame().GetSoundManagerEntity();
420  if (soundManagerEntity)
421  soundManagerEntity.CreateAndPlayAudioSource(this, SCR_SoundEvent.SOUND_RANGECP_CHANGEDISTANCE);
422 
423  return m_iTargetSetDistance;
424  }
425 
426  //------------------------------------------------------------------------------------------------
427  // Increase or decrease a number of targets in one round.
428  void UpdateNumberOfTargets(bool increase)
429  {
430  if (increase)
431  {
432  m_iTargetsInRound++;
433  }
434  else
435  {
436  m_iTargetsInRound--;
437  }
438 
439  // Entity has a signal manager, try to set up the value on counter
440  if (m_SignalManager)
441  m_FiringRangeManager.SetControllerCounter(this, EControlerSection.NUMBER_OF_TARGETS, m_iTargetsInRound);
442 
443  // Sound of presed button
444  SCR_SoundManagerEntity soundManagerEntity = GetGame().GetSoundManagerEntity();
445  if (soundManagerEntity)
446  soundManagerEntity.CreateAndPlayAudioSource(this, SCR_SoundEvent.SOUND_RANGECP_CHANGETARGET);
447  }
448 
449  //------------------------------------------------------------------------------------------------
451  void SetControllerCounter(EControlerSection indicator, int value)
452  {
453  // Prepare signals
454  int digitOneIndex;
455  int digitTenIndex;
456  int digitHundredIndex;
457  int digitThousandIndex;
458 
459  switch (indicator)
460  {
461  case EControlerSection.DISTANCE :
462  {
463 
464  digitOneIndex = m_SignalManager.FindSignal("DistanceOne");
465  digitTenIndex = m_SignalManager.FindSignal("DistanceTen");
466  digitHundredIndex = m_SignalManager.FindSignal("DistanceHundred");
467  digitThousandIndex = m_SignalManager.FindSignal("DistanceThousand");
468  m_iDistanceIndicatorValue = value;
469  break;
470  }
471  case EControlerSection.NUMBER_OF_TARGETS :
472  {
473  digitOneIndex = m_SignalManager.FindSignal("RoundOne");
474  digitTenIndex = m_SignalManager.FindSignal("RoundTen");
475  digitHundredIndex = m_SignalManager.FindSignal("RoundHundred");
476  digitThousandIndex = m_SignalManager.FindSignal("RoundThousand");
477  m_iNumberOfTargetsIndicatorValue = value;
478  break;
479  }
480  }
481 
482  // Calculate value
483  array<int> digits = {0,0,0,0};
484  int i = 0;
485  while (value != 0)
486  {
487  int m = value % 10;
488  digits.Set(i,m);
489  i++;
490  value = value / 10;
491  }
492 
493  // Set signals
494  for (int y = digits.Count() - 1; y >= 0; y--)
495  {
496  float signalVal = GetSignalValue(digits[y]);
497  switch (y)
498  {
499  case EDigit.DIGIT_ONE: {m_SignalManager.SetSignalValue(digitOneIndex,signalVal); break;};
500  case EDigit.DIGIT_TEN: {m_SignalManager.SetSignalValue(digitTenIndex,signalVal); break;};
501  case EDigit.DIGIT_HUNDRED: {m_SignalManager.SetSignalValue(digitHundredIndex,signalVal); break;};
502  case EDigit.DIGIT_THOUSAND: {m_SignalManager.SetSignalValue(digitThousandIndex,signalVal); break;};
503  }
504  }
505  }
506 
507  //------------------------------------------------------------------------------------------------
509  float GetSignalValue(int num)
510  {
511  switch (num)
512  {
513  case 0: {return DIGIT_ZERO; break;};
514  case 1: {return DIGIT_ONE; break;};
515  case 2: {return DIGIT_TWO; break;};
516  case 3: {return DIGIT_THREE; break;};
517  case 4: {return DIGIT_FOUR; break;};
518  case 5: {return DIGIT_FIVE; break;};
519  case 6: {return DIGIT_SIX; break;};
520  case 7: {return DIGIT_SEVEN; break;};
521  case 8: {return DIGIT_EIGHT; break;};
522  case 9: {return DIGIT_NINE; break;};
523  }
524  return 0;
525  }
526 
527  //------------------------------------------------------------------------------------------------
529  void CountPopUpTargets()
530  {
531  m_iCountShots++;
532  Replication.BumpMe();
533  }
534 
535  //------------------------------------------------------------------------------------------------
537  void ResetCountPopUpTargets()
538  {
539  m_iCountShots = 0;
540  Replication.BumpMe();
541  }
542 
543  //------------------------------------------------------------------------------------------------
545  void AddIndicator(vector localCoordOfHit, vector localVectorOfHit)
546  {
547  // Check if the indicator exist
548  if (!m_Indicator)
549  return;
550 
551  World world = GetWorld();
552  Decal decal = world.CreateDecal(
553  m_Indicator, // Entity
554  m_Indicator.CoordToParent(localCoordOfHit), // origin vector (position)
555  m_Indicator.VectorToParent(localVectorOfHit), // project vector
556  0.0, // nearclip
557  0.2, // farclip
558  0, // angle
559  0.1, // size
560  1, // stretch
561  m_PreviewDecal, //emat path
562  -1,// lifetime, if <= 0 the decal is created as static
563  0xFFFFFFFF); //color of decal
564 
565  if (!decal)
566  return;
567 
568 
569  m_aIndicators.Insert(decal);
570  Replication.BumpMe();
571 
572  m_aIndicatorsCoords.Insert(localCoordOfHit);
573  m_aIndicatorsVector.Insert(localVectorOfHit);
574  }
575 
576  //------------------------------------------------------------------------------------------------
578  IEntity GetIndicator()
579  {
580  return m_Indicator;
581  }
582 
583  //------------------------------------------------------------------------------------------------
585  void RemoveIndicators()
586  {
587  World world = GetWorld();
588  while (m_aIndicators.Count() > 0)
589  {
590  Decal decal = m_aIndicators.Get(0);
591  if (decal)
592  {
593  world.RemoveDecal(decal);
594  m_aIndicators.Remove(0);
595  }
596  }
597 
598  m_aIndicatorsVector.Clear();
599  m_aIndicatorsCoords.Clear();
600  }
601 
602  //------------------------------------------------------------------------------------------------
603  int GetTargetDistance()
604  {
605  return m_iTargetSetDistance;
606  }
607 
608  //------------------------------------------------------------------------------------------------
609  int GetTargetsInRound()
610  {
611  return m_iTargetsInRound;
612  }
613  //------------------------------------------------------------------------------------------------
615  float GetMaxScoreInRound()
616  {
617  return m_iTargetsInRound * SCR_FiringRangeTarget.SCORE_CENTER;
618  }
619 
620  //------------------------------------------------------------------------------------------------
621  protected bool CheckMasterOnlyMethod(string methodName)
622  {
623  if (IsProxy())
624  {
625  Print("Master-only method (SCR_FiringRangeController." + methodName + ") called on proxy. Some functionality might be broekn!", LogLevel.WARNING);
626  return false;
627  }
628  return true;
629  }
630 
631  //------------------------------------------------------------------------------------------------
632  void SetControllerLight(ControllerLightType light, bool mode)
633  {
634  switch (light)
635  {
636  case ControllerLightType.LIGHT_POWER: {SetEmissivity(m_LightPower, mode); break;};
637  case ControllerLightType.LIGHT_SEQUENCE: {SetEmissivity(m_LightSequence, mode); m_bRoundLightState = mode; break;};
638  case ControllerLightType.LIGHT_MALFUNCTION: {SetEmissivity(m_LightMalfunction, mode); break;};
639  }
640  }
641 
642  //------------------------------------------------------------------------------------------------
643  void SetEmissivity(ParametricMaterialInstanceComponent light, bool on)
644  {
645  if (!light)
646  return;
647 
648  if (on)
649  {
650  light.SetEmissiveMultiplier(LIGHT_EMISSIVITY_ON);
651  }
652  else
653  {
654  light.SetEmissiveMultiplier(LIGHT_EMISSIVITY_OFF);
655  }
656  }
657 
658  //------------------------------------------------------------------------------------------------
660  protected bool IsProxy()
661  {
662  if (!m_RplComponent)
663  m_RplComponent = RplComponent.Cast(FindComponent(RplComponent));
664 
665  return (m_RplComponent && m_RplComponent.IsProxy());
666  }
667 
668  //------------------------------------------------------------------------------------------------
669  override bool RplSave(ScriptBitWriter writer)
670  {
671  // Counters on the controller
672  writer.WriteIntRange(m_iDistanceIndicatorValue, 0, INDICATOR_MAX_VALUE);
673  writer.WriteIntRange(m_iNumberOfTargetsIndicatorValue, 0, INDICATOR_MAX_VALUE);
674 
675  // Sequence light indicator status
676  writer.WriteBool(m_bRoundLightState);
677 
678  // Decals on hit indicator
679  int count = m_aIndicatorsCoords.Count();
680  writer.WriteInt(count);
681 
682  for (int i = 0; i < count; i++)
683  {
684  writer.WriteVector(m_aIndicatorsCoords[i]);
685  writer.WriteVector(m_aIndicatorsVector[i]);
686  }
687 
688  return true;
689  }
690 
691  //------------------------------------------------------------------------------------------------
692  override bool RplLoad(ScriptBitReader reader)
693  {
694  // Counters on the controller
695  reader.ReadIntRange(m_iDistanceIndicatorValue, 0, INDICATOR_MAX_VALUE);
696  reader.ReadIntRange(m_iNumberOfTargetsIndicatorValue, 0, INDICATOR_MAX_VALUE);
697 
698  // Sequence light indicator status
699  reader.ReadBool(m_bRoundLightState);
700 
701  // Hit indicator
702  int count;
703  reader.ReadInt(count);
704 
705  for (int i = 0; i < count; i++)
706  {
707  vector position;
708  vector rotation;
709  reader.ReadVector(position);
710  reader.ReadVector(rotation);
711 
712  AddIndicator(position, rotation);
713  }
714 
715  SetControllerLight(ControllerLightType.LIGHT_SEQUENCE, m_bRoundLightState);
716  SetControllerCounter(EControlerSection.DISTANCE ,m_iDistanceIndicatorValue);
717  SetControllerCounter(EControlerSection.NUMBER_OF_TARGETS ,m_iNumberOfTargetsIndicatorValue);
718  return true;
719  }
720 
721  //------------------------------------------------------------------------------------------------
722  // Constructor
723  void SCR_FiringRangeController(IEntitySource src, IEntity parent)
724  {
725  SetEventMask(EntityEvent.INIT);
726 
727  if (s_aInstances)
728  s_aInstances.Insert(this);
729 
730  m_FiringRangeManager = SCR_FiringRangeManager.Cast(parent);
731 
732  if (m_FiringRangeManager)
733  m_FiringRangeManager.RegisterFiringRangeController(this);
734  }
735 
736  //------------------------------------------------------------------------------------------------
738  {
739  if (s_aInstances)
740  s_aInstances.RemoveItem(this);
741  }
742 };
743 
745 {
748 };
749 
750 enum EDigit
751 {
756 };
757 
759 {
763 };
DIGIT_THOUSAND
@ DIGIT_THOUSAND
Definition: SCR_FiringRangeController.c:755
EntityEditorProps
enum EQueryType EntityEditorProps(category:"GameScripted/Sound", description:"THIS IS THE SCRIPT DESCRIPTION.", color:"0 0 255 255")
Definition: SCR_AmbientSoundsComponent.c:12
SCR_FiringRangeTarget
Definition: SCR_FiringRangeTarget.c:19
RplProp
SCR_RplTestEntityClass RplProp
Used for handling entity spawning requests for SCR_CatalogEntitySpawnerComponent and inherited classe...
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
EControlerSection
EControlerSection
Definition: SCR_FiringRangeController.c:744
SCR_SoundEvent
Definition: SCR_SoundEvent.c:1
GenericEntity
SCR_GenericBoxEntityClass GenericEntity
SCR_SoundManagerEntity
Definition: SCR_SoundManagerEntity.c:17
EDigit
EDigit
Definition: SCR_FiringRangeController.c:750
ETargetState
ETargetState
Definition: SCR_FiringRangeTarget.c:7
EntitySlotInfo
Adds ability to attach an object to a slot.
Definition: EntitySlotInfo.c:8
DIGIT_TEN
@ DIGIT_TEN
Definition: SCR_FiringRangeController.c:753
m_SignalManager
protected SignalsManagerComponent m_SignalManager
Definition: SCR_WristwatchComponent.c:55
DIGIT_HUNDRED
@ DIGIT_HUNDRED
Definition: SCR_FiringRangeController.c:754
SCR_FiringRangeManager
Definition: SCR_FiringRangeManager.c:7
DISTANCE
@ DISTANCE
Definition: SCR_FiringRangeController.c:746
Attribute
typedef Attribute
Post-process effect of scripted camera.
distance
float distance
Definition: SCR_DestructibleTreeV2.c:29
rotation
RespawnSystemComponentClass GameComponentClass vector vector rotation
Definition: RespawnSystemComponent.c:23
DIGIT_ONE
@ DIGIT_ONE
Definition: SCR_FiringRangeController.c:752
NUMBER_OF_TARGETS
@ NUMBER_OF_TARGETS
Definition: SCR_FiringRangeController.c:747
ControllerLightType
ControllerLightType
Definition: SCR_FiringRangeController.c:758
SCR_FiringRangeNetworkEntity
Definition: SCR_FiringRangeNetworkEntity.c:7
m_RplComponent
protected RplComponent m_RplComponent
Definition: SCR_CampaignBuildingManagerComponent.c:42
LIGHT_MALFUNCTION
@ LIGHT_MALFUNCTION
Definition: SCR_FiringRangeController.c:762
SCR_FiringRangeControllerClass
Definition: SCR_FiringRangeController.c:4
LIGHT_POWER
@ LIGHT_POWER
Definition: SCR_FiringRangeController.c:760
ParametricMaterialInstanceComponent
Definition: ParametricMaterialInstanceComponent.c:12
LIGHT_SEQUENCE
@ LIGHT_SEQUENCE
Definition: SCR_FiringRangeController.c:761
position
vector position
Definition: SCR_DestructibleTreeV2.c:30
SCR_FiringRangeController
Definition: SCR_FiringRangeController.c:9
ETargetMode
ETargetMode
Definition: SCR_FiringRangeTarget.c:13
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180