1 [
EntityEditorProps(
category:
"GameScripted/FiringRange", description:
"Handles score and MP synchronization. Only one per world.", color:
"0 0 255 255")]
10 [
Attribute(
"", UIWidgets.ResourcePickerThumbnail,
"Entity to spawn as communication entity.",
"et")]
11 private ResourceName m_ComEnt;
13 protected Widget m_wRoot;
14 protected Widget m_wTable
16 private ref array<int> m_aPlayerScores =
new array<int>;
17 private ref array<int> m_aPlayerScoresMax =
new array<int>;
18 private ref array<string> m_aPlayerNames =
new array<string>;
19 private ref array<SCR_PlayerScoreInfoFiringRange> m_aAllPlayersInfo =
new array<SCR_PlayerScoreInfoFiringRange>;
20 private ref array<Widget> m_aPlayerWidgets =
new array<Widget>;
22 private ref array<int> m_aPlayersInArea =
new array<int>;
25 private ref array<IEntity> m_aFiringLineControllers =
new array<IEntity>;
27 private int m_iLocalPlayerID = -1;
28 private int m_iLastSelectedTargetId = -1;
29 private int m_iSelectedIndex = -1;
35 private RplComponent m_RplComponent;
37 private int m_iPlayersInGameCount = -1;
38 private int m_iPlayersInAreaCount = -1;
43 void ClearPlayerScore(
int playerID)
46 if (!CheckMasterOnlyMethod(
"ClearPlayerScore()"))
53 m_ScoringSystem.ClearScore(playerID);
57 void CountPlayerScore(
int scoringPlayer,
int scorePoints)
60 if (!CheckMasterOnlyMethod(
"CountPlayerScore()"))
67 m_ScoringSystem.AddScore(scoringPlayer,scorePoints);
71 void SetPlayerScoreMax(
int playerID,
float maxScore)
75 if (!CheckMasterOnlyMethod(
"SetPlayerScoreMax()"))
81 m_ScoringSystem.SetScoreMax(playerID,maxScore);
85 void UpdateScoreboardData()
90 if (m_aPlayerWidgets.IsEmpty())
98 TextWidget nameWidget = TextWidget.Cast(m_aPlayerWidgets[i].FindAnyWidget(
"Name"));
100 nameWidget.SetText(info.GetName());
102 TextWidget scoreWidget = TextWidget.Cast(m_aPlayerWidgets[i].FindAnyWidget(
"Score"));
104 scoreWidget.SetText(info.GetScore(m_ScoringSystem).ToString());
107 TextWidget maxScoreWidget = TextWidget.Cast(m_aPlayerWidgets[i].FindAnyWidget(
"MaxScore"));
109 maxScoreWidget.SetText(info.GetScoreMax().ToString());
114 int GetHighScoreInfo(array<SCR_PlayerScoreInfoFiringRange> infos)
116 int highScore =
int.MIN;
123 int score = info.GetScore();
124 if (score > highScore)
139 if (count != m_aPlayerScores.Count())
142 m_aPlayerScores.Clear();
148 score = info.GetScore();
151 m_aPlayerScores.Insert(score);
157 bool changed =
false;
158 for (
int i = 0; i < count; i++)
164 int score = info.GetScore();
165 if (score != m_aPlayerScores.Get(i))
167 m_aPlayerScores.Set(i, score);
176 bool ScoreMaxChanged()
179 if (count != m_aPlayerScoresMax.Count())
182 m_aPlayerScoresMax.Clear();
185 int scoreMax = -1000;
188 scoreMax = info.GetScoreMax();
191 m_aPlayerScoresMax.Insert(scoreMax);
197 bool changed =
false;
198 for (
int i = 0; i < count; i++)
204 int scoreMax = info.GetScoreMax();
205 if (scoreMax != m_aPlayerScoresMax.Get(i))
207 m_aPlayerScoresMax.Set(i, scoreMax);
219 if (count != m_aPlayerNames.Count())
222 m_aPlayerNames.Clear();
227 name = info.GetName();
229 m_aPlayerNames.Insert(name);
235 bool changed =
false;
236 for (
int i = 0; i < count; i++)
242 string name = info.GetName();
243 if (name != m_aPlayerNames.Get(i))
245 m_aPlayerNames.Set(i, name);
255 bool PlayerCountChangedInArea()
258 if (!m_aPlayersInArea)
262 int currentPlayersCountInArea = m_aPlayersInArea.Count();
263 if (currentPlayersCountInArea == m_iPlayersInAreaCount)
266 m_iPlayersInAreaCount = currentPlayersCountInArea;
273 override void EOnFrame(IEntity owner,
float timeSlice)
276 if (!m_ScoringSystem)
281 if (PlayerCountChangedInArea())
284 UpdateScoreboardData();
287 if (ScoreChanged() || NameChanged() || ScoreMaxChanged())
288 UpdateScoreboardData();
293 override void OnActivate(IEntity ent)
295 int iLocalPlayerID =
GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(ent);
296 RegisterPlayerInArea(iLocalPlayerID);
301 if (playerEnt == ent)
304 m_wRoot =
GetGame().GetWorkspace().CreateWidgets(
"{1B8C7223B314408B}UI/layouts/HUD/FiringRangeScoreboard/FireRangeTable.layout");
308 m_wTable =
m_wRoot.FindAnyWidget(
"Table");
313 override void OnDeactivate(IEntity ent)
315 int iLocalPlayerID =
GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(ent);
316 RemovePlayerFromArea(iLocalPlayerID);
324 if (playerEnt == ent)
327 PlayerController playerController =
GetGame().GetPlayerController();
328 if (!playerController)
333 if (!firingRangeNetworkEntity)
355 foreach (Widget w : m_aPlayerWidgets)
357 w.RemoveFromHierarchy();
359 m_aPlayerWidgets.Clear();
364 Widget w =
GetGame().GetWorkspace().CreateWidgets(
"{8643D226A0A0A299}UI/layouts/HUD/FiringRangeScoreboard/FireRangeRow.layout", m_wTable);
365 m_aPlayerWidgets.Insert(w);
368 int id = info.GetPlayerID();
369 if (!IsPlayerInFiringRangeArea(
id))
374 UpdateScoreboardData();
378 override void EOnInit(IEntity owner)
380 ArmaReforgerScripted game =
GetGame();
390 if (s_FiringRangeManagerMain ==
this)
392 gameMode.GetOnPlayerConnected().Insert(SpawnCommunicationPrefab);
394 array<int> playerIds =
new array<int>();
395 GetGame().GetPlayerManager().GetPlayers(playerIds);
397 foreach (
int id : playerIds)
399 SpawnCommunicationPrefab(
id);
407 void RegisterFiringRangeController(IEntity firingLineController)
409 m_aFiringLineControllers.Insert(firingLineController);
414 void RemoveAssignedPlayerFromFireline(
int playerID)
417 foreach (IEntity currentElement: m_aFiringLineControllers)
420 if (controller.GetFiringLineOwnerId() == playerID)
421 controller.BackToDefaultTarget();
427 int GetPlayerID(IEntity ent)
429 return GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(ent);
434 void RegisterPlayerInArea(
int playerID)
436 m_aPlayersInArea.Insert(playerID);
437 Replication.BumpMe();
442 void RemovePlayerFromArea(
int playerID)
444 m_aPlayersInArea.RemoveItem(playerID);
445 Replication.BumpMe();
447 RpcAsk_ClearWidgets(playerID);
448 Rpc(RpcAsk_ClearWidgets, playerID);
453 bool IsPlayerInFiringRangeArea(
int playerID)
455 if (m_aPlayersInArea.Find(playerID) != -1)
464 return m_FiringRangeManagerInstance;
471 return s_FiringRangeManagerMain;
476 Widget GetRootWidget()
483 string GetPlayerName(IEntity ent)
485 auto pm =
GetGame().GetPlayerManager();
486 int iPlayerID = pm.GetPlayerIdFromControlledEntity(ent);
487 return pm.GetPlayerName(iPlayerID);
491 void SpawnCommunicationPrefab(
int playerID)
494 Resource resource = Resource.Load(m_ComEnt);
495 if (!resource.IsValid())
498 IEntity ent =
GetGame().SpawnEntityPrefab(resource,
GetGame().GetWorld());
502 RplComponent rpl = RplComponent.Cast(ent.FindComponent(RplComponent));
507 if (!firingRangeNetworkEntity)
510 PlayerController playerController =
GetGame().GetPlayerManager().GetPlayerController(playerID);
511 if (!playerController)
514 RplIdentity playerRplID = playerController.GetRplIdentity();
515 if (playerRplID == Replication.INVALID_IDENTITY)
518 rpl.Give(playerRplID);
519 firingRangeNetworkEntity.RegisterCommEntity(Replication.FindId(ent));
526 void AddIndicator(vector localCoordOfHit, vector localVectorOfHit, IEntity pOwnerEntity)
530 IEntity firingRangeController = pOwnerEntity.GetParent();
531 if (!firingRangeController)
535 Rpc(RpcAsk_AddIndicator, Replication.FindId(firingRangeController), localCoordOfHit, localVectorOfHit);
536 RpcAsk_AddIndicator(Replication.FindId(firingRangeController),localCoordOfHit,localVectorOfHit);
540 void RemoveIndicators(RplId controllerReplicationId)
542 Rpc(RpcAsk_RemoveIndicators, controllerReplicationId);
543 RpcAsk_RemoveIndicators(controllerReplicationId);
547 void ControllerLight(notnull IEntity firingRangeController,
ControllerLightType light,
bool mode)
549 Rpc(RpcAsk_ControllerLight, Replication.FindId(firingRangeController), light, mode);
550 RpcAsk_ControllerLight(Replication.FindId(firingRangeController), light, mode);
556 Rpc(RpcAsk_SetControllerCounter, Replication.FindId(firingRangeController),
type, value);
557 RpcAsk_SetControllerCounter(Replication.FindId(firingRangeController),
type, value);
561 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
562 protected void RpcAsk_RemoveIndicators(RplId controllerReplicationId)
565 if (m_LineController)
566 m_LineController.RemoveIndicators();
570 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
571 void RpcAsk_AddIndicator(RplId controllerReplicationId, vector localCoordOfHit, vector localVectorOfHit)
574 if (m_LineController)
575 m_LineController.AddIndicator(localCoordOfHit,localVectorOfHit);
580 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
581 protected void RpcAsk_ClearWidgets(
int playerID)
585 if (localPlayerID == playerID)
588 m_aPlayerWidgets.Clear();
596 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
597 protected void RpcAsk_ControllerLight(RplId controllerReplicationId,
ControllerLightType light,
bool mode)
600 if (m_LineController)
601 m_LineController.SetControllerLight(light, mode);
605 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
606 protected void RpcAsk_SetControllerCounter(RplId controllerReplicationId,
EControlerSection type,
int value)
609 if (m_LineController)
610 m_LineController.SetControllerCounter(
type, value);
614 protected bool CheckMasterOnlyMethod(
string methodName)
618 Print(
"Master-only method (SCR_FiringRangeController." + methodName +
") called on proxy. Some functionality might be broekn!", LogLevel.WARNING);
629 SetEventMask(EntityEvent.INIT | EntityEvent.FRAME);
631 if (s_FiringRangeManagerMain ==
null)
632 s_FiringRangeManagerMain =
this;
634 m_FiringRangeManagerInstance =
this;
643 if (s_FiringRangeManagerMain ==
this)
644 s_FiringRangeManagerMain ==
null;