1 [
EntityEditorProps(
category:
"GameScripted/FiringRange", description:
"Controller of firing line, handles behaviour of targets.", color:
"0 0 255 255", dynamicBox:
true)]
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;
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;
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";
32 const static int LIGHT_EMISSIVITY_ON = 1;
33 const static int LIGHT_EMISSIVITY_OFF = 0;
35 const static bool LIGHT_ON =
true;
36 const static bool LIGHT_OFF =
false;
44 private bool m_bRoundLightState =
false;
45 private int m_iDistanceIndicatorValue;
46 private int m_iNumberOfTargetsIndicatorValue;
49 const static int ERROR_LIGHT_DURATION = 1000;
52 [
Attribute(
"4", UIWidgets.Slider,
"For how long target stays in erected position in seconds.",
"1 100 1")]
53 protected int m_iErectTargetTime;
56 [
Attribute(
"{F2E83D562703F861}Assets/Decals/Impact/DecalHitIndicator.emat", UIWidgets.ResourceNamePicker,
"Material used for target hit indicator",
"emat")]
57 private ResourceName m_PreviewDecal;
59 [
Attribute(
"", UIWidgets.ResourceNamePicker,
"Power light entity",
"et")]
60 private ResourceName m_LightPowerRes;
62 [
Attribute(
"", UIWidgets.ResourceNamePicker,
"Sequence light entity",
"et")]
63 private ResourceName m_LightSequenceRes;
65 [
Attribute(
"", UIWidgets.ResourceNamePicker,
"Malfunction light entity",
"et")]
66 private ResourceName m_LightMalfunctionRes;
68 [
Attribute(
"1", UIWidgets.Slider,
"Targets in one round",
"1 20 10")]
69 private int m_iTargetsInRound;
72 private int m_iCountShots = 0;
75 private int m_iTargetSetDistance;
79 private int m_iFiringLineOwner = NO_TARGET_OWNER;
84 private int m_iElementInArray = 0;
85 private int m_iValuePos;
86 private int m_iHighestPossibleDistance;
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 = {};
94 private ref array<vector> m_aIndicatorsCoords = {};
95 private ref array<vector> m_aIndicatorsVector = {};
98 private float m_fTargetErectedDuration;
101 private IEntity m_Indicator;
104 private RplComponent m_RplComponent;
105 private SignalsManagerComponent m_SignalManager;
110 override void EOnInit(IEntity owner)
112 m_SignalManager = SignalsManagerComponent.Cast(owner.FindComponent(SignalsManagerComponent));
114 array<EntitySlotInfo> slots = {};
EntitySlotInfo.GetSlotInfos(owner, slots);
123 IEntity ent = slot.GetAttachedEntity();
127 slotBone = slot.GetBoneName();
128 if (!slotBone.IsEmpty())
140 CollectAllDistances(owner);
147 void AnimateTargets(IEntity pOwnerEntity,
int playerID)
151 if (!CheckMasterOnlyMethod(
"AnimateTargets()"))
156 if (soundManagerEntity)
157 soundManagerEntity.CreateAndPlayAudioSource(pOwnerEntity,
SCR_SoundEvent.SOUND_RANGECP_STARTBUTTON);
163 IEntity child = pOwnerEntity.GetChildren();
164 array<SCR_FiringRangeTarget> targetArray =
new array<SCR_FiringRangeTarget>();
167 m_iFiringLineOwner = playerID;
168 Replication.BumpMe();
175 if (!target.IsIndicator())
178 m_aAllTargetsArray.Insert(target);
180 if ((target.GetSetDistance() == m_iTargetSetDistance) || m_iTargetSetDistance == -1)
182 targetArray.Insert(target);
187 target.SetAutoResetTarget(
false);
190 target.SetTargetOwner(playerID);
195 child = child.GetSibling();
199 if (soundManagerEntity)
200 soundManagerEntity.CreateAndPlayAudioSource(pOwnerEntity,
SCR_SoundEvent.SOUND_RANGECP_ROUNDSTART);
202 GetGame().GetCallqueue().CallLater(ResetCountPopUpTargets, RESET_COUNTER_TIME,
false);
203 GetGame().GetCallqueue().CallLater(ErectRandomTarget, m_iErectTargetTime * 1000,
true, targetArray, m_aAllTargetsArray);
205 if (m_FiringRangeManager)
211 void ErectRandomTarget(array<SCR_FiringRangeTarget> targetArray)
214 if (m_iCountShots >= m_iTargetsInRound)
216 BackToDefaultTarget();
220 m_LastSelectedTarget = m_CurrentSelectedTarget;
221 while (m_LastSelectedTarget == m_CurrentSelectedTarget && targetArray.Count() > 1)
223 m_CurrentSelectedTarget = targetArray.GetRandomElement();
226 if (m_CurrentSelectedTarget)
228 m_fTargetErectedDuration = m_CurrentSelectedTarget.GetErectedDuration();
229 m_CurrentSelectedTarget.SetState(
ETargetState.TARGET_UP);
230 GetGame().GetCallqueue().CallLater(FoldTarget, m_fTargetErectedDuration,
false, m_CurrentSelectedTarget);
238 if (m_fTargetErectedDuration == 0)
243 float TargetState = selectedTarget.GetState();
244 if (TargetState == 0)
251 void BackToDefaultTarget()
255 if (!CheckMasterOnlyMethod(
"BackToDefaultTarget()"))
260 m_iFiringLineOwner = NO_TARGET_OWNER;
261 Replication.BumpMe();
263 GetGame().GetCallqueue().Remove(ErectRandomTarget);
265 for (
int i = m_aAllTargetsArray.Count() - 1; i >= 0; i--)
272 target.SetAutoResetTarget(
true);
274 target.SetTargetOwner(NO_TARGET_OWNER);
278 m_aAllTargetsArray.Clear();
279 if (m_FiringRangeManager)
284 void SetIndicator(IEntity indicator)
286 m_Indicator = indicator;
291 void BackToDefaultTargetsFromLineArea()
294 m_fTargetErectedDuration = 0;
297 PlayerController playerController =
GetGame().GetPlayerController();
298 if (!playerController)
303 if (!firingRangeNetworkEntity)
306 firingRangeNetworkEntity.BackToDefaultTarget(
this);
307 if (m_FiringRangeManager)
309 m_FiringRangeManager.ControllerLight(
this,
ControllerLightType.LIGHT_MALFUNCTION, LIGHT_ON);
311 GetGame().GetCallqueue().CallLater(m_FiringRangeManager.ControllerLight, ERROR_LIGHT_DURATION,
false,
this,
ControllerLightType.LIGHT_MALFUNCTION, LIGHT_OFF);
316 if (soundManagerEntity)
317 soundManagerEntity.CreateAndPlayAudioSource(
this,
SCR_SoundEvent.SOUND_RANGECP_ROUNDABORT);
322 void CollectAllDistances(IEntity owner)
324 IEntity child = owner.GetChildren();
328 if (target && !target.IsIndicator())
330 int distance = target.GetSetDistance();
331 if (m_aDistances.Find(
distance) == -1)
335 child = child.GetSibling();
338 if (m_aDistances.IsEmpty())
342 m_iTargetSetDistance = m_aDistances[0];
349 Replication.BumpMe();
354 array<int> GetAllDistances()
361 int GetFiringLineOwnerId()
363 return m_iFiringLineOwner;
367 bool IsLowestDistanceSet()
369 return GetTargetDistance() == m_aDistances[0];
373 bool IsHighestDistanceSet()
375 return GetTargetDistance() == m_aDistances[m_aDistances.Count()-1];
380 int CalculateTargetDistance(
bool increase)
384 if (!CheckMasterOnlyMethod(
"CalculateTargetDistance()"))
389 int currentDistance = m_iTargetSetDistance;
392 if (m_iTargetSetDistance == -1)
394 m_iTargetSetDistance = 0;
395 Replication.BumpMe();
399 m_iHighestPossibleDistance = m_aDistances.Count()-1;
401 m_iValuePos = m_aDistances.Find(m_iTargetSetDistance);
410 m_iTargetSetDistance = m_aDistances[m_iValuePos];
411 Replication.BumpMe();
416 m_FiringRangeManager.SetControllerCounter(
this,
EControlerSection.DISTANCE, m_iTargetSetDistance);
420 if (soundManagerEntity)
421 soundManagerEntity.CreateAndPlayAudioSource(
this,
SCR_SoundEvent.SOUND_RANGECP_CHANGEDISTANCE);
423 return m_iTargetSetDistance;
428 void UpdateNumberOfTargets(
bool increase)
441 m_FiringRangeManager.SetControllerCounter(
this,
EControlerSection.NUMBER_OF_TARGETS, m_iTargetsInRound);
445 if (soundManagerEntity)
446 soundManagerEntity.CreateAndPlayAudioSource(
this,
SCR_SoundEvent.SOUND_RANGECP_CHANGETARGET);
456 int digitHundredIndex;
457 int digitThousandIndex;
468 m_iDistanceIndicatorValue = value;
477 m_iNumberOfTargetsIndicatorValue = value;
483 array<int> digits = {0,0,0,0};
494 for (
int y = digits.Count() - 1; y >= 0; y--)
496 float signalVal = GetSignalValue(digits[y]);
509 float GetSignalValue(
int num)
513 case 0: {
return DIGIT_ZERO;
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;};
529 void CountPopUpTargets()
532 Replication.BumpMe();
537 void ResetCountPopUpTargets()
540 Replication.BumpMe();
545 void AddIndicator(vector localCoordOfHit, vector localVectorOfHit)
551 World world = GetWorld();
552 Decal decal = world.CreateDecal(
554 m_Indicator.CoordToParent(localCoordOfHit),
555 m_Indicator.VectorToParent(localVectorOfHit),
569 m_aIndicators.Insert(decal);
570 Replication.BumpMe();
572 m_aIndicatorsCoords.Insert(localCoordOfHit);
573 m_aIndicatorsVector.Insert(localVectorOfHit);
578 IEntity GetIndicator()
585 void RemoveIndicators()
587 World world = GetWorld();
588 while (m_aIndicators.Count() > 0)
590 Decal decal = m_aIndicators.Get(0);
593 world.RemoveDecal(decal);
594 m_aIndicators.Remove(0);
598 m_aIndicatorsVector.Clear();
599 m_aIndicatorsCoords.Clear();
603 int GetTargetDistance()
605 return m_iTargetSetDistance;
609 int GetTargetsInRound()
611 return m_iTargetsInRound;
615 float GetMaxScoreInRound()
621 protected bool CheckMasterOnlyMethod(
string methodName)
625 Print(
"Master-only method (SCR_FiringRangeController." + methodName +
") called on proxy. Some functionality might be broekn!", LogLevel.WARNING);
637 case ControllerLightType.LIGHT_SEQUENCE: {SetEmissivity(m_LightSequence, mode); m_bRoundLightState = mode;
break;};
638 case ControllerLightType.LIGHT_MALFUNCTION: {SetEmissivity(m_LightMalfunction, mode);
break;};
650 light.SetEmissiveMultiplier(LIGHT_EMISSIVITY_ON);
654 light.SetEmissiveMultiplier(LIGHT_EMISSIVITY_OFF);
660 protected bool IsProxy()
669 override bool RplSave(ScriptBitWriter writer)
672 writer.WriteIntRange(m_iDistanceIndicatorValue, 0, INDICATOR_MAX_VALUE);
673 writer.WriteIntRange(m_iNumberOfTargetsIndicatorValue, 0, INDICATOR_MAX_VALUE);
676 writer.WriteBool(m_bRoundLightState);
679 int count = m_aIndicatorsCoords.Count();
680 writer.WriteInt(count);
682 for (
int i = 0; i < count; i++)
684 writer.WriteVector(m_aIndicatorsCoords[i]);
685 writer.WriteVector(m_aIndicatorsVector[i]);
692 override bool RplLoad(ScriptBitReader reader)
695 reader.ReadIntRange(m_iDistanceIndicatorValue, 0, INDICATOR_MAX_VALUE);
696 reader.ReadIntRange(m_iNumberOfTargetsIndicatorValue, 0, INDICATOR_MAX_VALUE);
699 reader.ReadBool(m_bRoundLightState);
703 reader.ReadInt(count);
705 for (
int i = 0; i < count; i++)
717 SetControllerCounter(
EControlerSection.NUMBER_OF_TARGETS ,m_iNumberOfTargetsIndicatorValue);
725 SetEventMask(EntityEvent.INIT);
728 s_aInstances.Insert(
this);
732 if (m_FiringRangeManager)
733 m_FiringRangeManager.RegisterFiringRangeController(
this);
740 s_aInstances.RemoveItem(
this);