Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_PlayerListMenu.c
Go to the documentation of this file.
2 {
3  ALL = 0,
4  GROUPS = 1
5 }
6 
7 class SCR_PlayerListEntry
8 {
10  int m_iID;
11  Widget m_wRow;
14 
19 
20  TextWidget m_wName;
21  TextWidget m_wKills;
22  TextWidget m_wFreq;
23  TextWidget m_wDeaths;
24  TextWidget m_wScore;
25  ImageWidget m_wLoadoutIcon;
26  ImageWidget m_wPlatformIcon;
27  Widget m_wTaskIcon;
30 };
31 
32 //------------------------------------------------------------------------------------------------
34 {
35  protected ResourceName m_sScoreboardRow = "{65369923121A38E7}UI/layouts/Menus/PlayerList/PlayerListEntry.layout";
36 
37  protected ref array<ref SCR_PlayerListEntry> m_aEntries = new array<ref SCR_PlayerListEntry>();
38  protected ref map<int, SCR_ScoreInfo> m_aAllPlayersInfo = new map<int, SCR_ScoreInfo>();
39  protected ref array<Faction> m_aFactions = {null};
40 
41  protected SCR_InputButtonComponent m_Mute;
42  protected SCR_InputButtonComponent m_Block;
43  protected SCR_InputButtonComponent m_Friend;
44  protected SCR_InputButtonComponent m_Vote;
45  protected SCR_InputButtonComponent m_Invite;
46  protected SCR_InputButtonComponent m_ViewProfile;
47 
48  protected SCR_VotingManagerComponent m_VotingManager;
49  protected SCR_VoterComponent m_VoterComponent;
50  //protected SCR_RespawnSystemComponent m_RespawnSystem;
51  protected SCR_BaseScoringSystemComponent m_ScoringSystem;
52  protected SCR_PlayerListEntry m_SelectedEntry;
53  protected SCR_PlayerControllerGroupComponent m_PlayerGroupController;
54  protected PlayerController m_PlayerController;
55  SCR_SortHeaderComponent m_Header;
56  protected Widget m_wTable;
57  protected bool m_bFiltering;
58  protected float m_fTimeSkip;
59 
60  protected const float TIME_STEP = 1.0;
61 
62  protected const string ADD_FRIEND = "#AR-PlayerList_AddFriend";
63  protected const string REMOVE_FRIEND = "#AR-PlayerList_RemoveFriend";
64  protected const string MUTE = "#AR-PlayerList_Mute";
65  protected const string UNMUTE = "#AR-PlayerList_Unmute";
66  protected const string BLOCK = "#AR-PlayerList_Block";
67  protected const string UNBLOCK = "#AR-PlayerList_Unblock";
68  protected const string INVITE_PLAYER_VOTE = "#AR-PlayerList_Invite";
69  protected const string MUTE_TEXTURE = "sound-off";
70  protected const string OPTIONS_COMBO_ACCEPT = "#AR-Group_AcceptJoinPrivateGroup";
71  protected const string OPTIONS_COMBO_CANCEL = "#AR-Group_RefuseJoinPrivateGroup";
72  protected const string VOTING_PLAYER_COUNT_FORMAT = "#AR-Voting_PlayerCountFormatting";
73 
74  protected const string FILTER_FAV = "Favourite";
75  protected const string FILTER_NAME = "Name";
76  protected const string FILTER_FREQ = "Freq";
77  protected const string FILTER_KILL = "Kills";
78  protected const string FILTER_DEATH = "Deaths";
79  protected const string FILTER_SCORE = "Score";
80  protected const string FILTER_MUTE = "Mute";
81  protected const string FILTER_BLOCK = "Block";
82 
83  protected static const ResourceName FACTION_COUNTER_LAYOUT = "{5AD2CE85825EDA11}UI/layouts/Menus/PlayerList/FactionPlayerCounter.layout";
84 
85  protected const int DEFAULT_SORT_INDEX = 1;
86 
87  protected string m_sGameMasterIndicatorName = "GameMasterIndicator";
88 
89  protected static ref ScriptInvoker s_OnPlayerListMenu = new ScriptInvoker();
90 
91  protected ref Color m_PlayerNameSelfColor = new Color(0.898, 0.541, 0.184, 1);
92 
97  static ScriptInvoker GetOnPlayerListMenu()
98  {
99  return s_OnPlayerListMenu;
100  }
101 
102  //------------------------------------------------------------------------------------------------
103  protected void InitSorting()
104  {
105  if (!GetRootWidget())
106  return;
107 
108  Widget w = GetRootWidget().FindAnyWidget("SortHeader");
109  if (!w)
110  return;
111 
112  m_Header = SCR_SortHeaderComponent.Cast(w.FindHandler(SCR_SortHeaderComponent));
113  if (!m_Header)
114  return;
115 
116  m_Header.m_OnChanged.Insert(OnHeaderChanged);
117 
118  if (m_ScoringSystem)
119  return;
120 
121  SCR_AIGroup.GetOnJoinPrivateGroupConfirm().Insert(SetEntryBackgrounColor);
122  SCR_AIGroup.GetOnJoinPrivateGroupCancel().Insert(SetEntryBackgrounColor);
123 
124  // Hide K/D/S sorting headers if the re is no scoreboard
125  ButtonWidget sortKills = ButtonWidget.Cast(w.FindAnyWidget("sortKills"));
126  ButtonWidget sortDeaths = ButtonWidget.Cast(w.FindAnyWidget("sortDeaths"));
127  ButtonWidget sortScore = ButtonWidget.Cast(w.FindAnyWidget("sortScore"));
128 
129  if (sortKills)
130  sortKills.SetOpacity(0);
131  if (sortDeaths)
132  sortDeaths.SetOpacity(0);
133  if (sortScore)
134  sortScore.SetOpacity(0);
135  }
136 
137  //------------------------------------------------------------------------------------------------
138  protected void OnHeaderChanged(SCR_SortHeaderComponent sortHeader)
139  {
140  string filterName = sortHeader.GetSortElementName();
141  bool sortUp = sortHeader.GetSortOrderAscending();
142  Sort(filterName, sortUp);
143  }
144 
145 
146  //------------------------------------------------------------------------------------------------
147  protected void Sort(string filterName, bool sortUp)
148  {
149  if (filterName == FILTER_NAME)
150  SortByName(sortUp);
151  else if (filterName == FILTER_FAV)
152  SortByFriends(sortUp);
153  else if (filterName == FILTER_FREQ)
154  SortByFrequency(sortUp);
155  else if (filterName == FILTER_KILL)
156  SortByKills(sortUp);
157  else if (filterName == FILTER_DEATH)
158  SortByDeaths(sortUp);
159  else if (filterName == FILTER_SCORE)
160  SortByScore(sortUp);
161  else if (filterName == FILTER_MUTE)
162  SortByMuted(sortUp);
163  else if (filterName == FILTER_BLOCK)
164  SortByBlocked(sortUp);
165  }
166 
167  //------------------------------------------------------------------------------------------------
168  void SortByMuted(bool reverseSort = false)
169  {
170  int direction = 1;
171  if (reverseSort)
172  direction = -1;
173 
174  foreach (SCR_PlayerListEntry entry : m_aEntries)
175  {
176  entry.m_wRow.SetZOrder(entry.m_Mute.IsToggled() * direction);
177  }
178  }
179 
180  //------------------------------------------------------------------------------------------------
181  void SortByBlocked(bool reverseSort = false)
182  {
183  int direction = 1;
184  if (reverseSort)
185  direction = -1;
186 
187  foreach (SCR_PlayerListEntry entry : m_aEntries)
188  {
189  entry.m_wRow.SetZOrder(entry.m_Block.IsToggled() * direction);
190  }
191  }
192 
193  //------------------------------------------------------------------------------------------------
194  void SortByName(bool reverseSort = false)
195  {
196  int direction = 1;
197  if (reverseSort)
198  direction = -1;
199 
200  array<string> names = {};
201  foreach (SCR_PlayerListEntry entry : m_aEntries)
202  {
203  if (entry.m_wName)
204  names.Insert(entry.m_wName.GetText());
205  }
206 
207  names.Sort();
208 
209  foreach (SCR_PlayerListEntry entry : m_aEntries)
210  {
211  if (!entry.m_wName)
212  continue;
213 
214  string text = entry.m_wName.GetText();
215 
216  foreach (int i, string s : names)
217  {
218  if (s != text)
219  continue;
220 
221  if (entry.m_wRow)
222  entry.m_wRow.SetZOrder(i * direction);
223  continue;
224  }
225  }
226  }
227 
228  //------------------------------------------------------------------------------------------------
229  void SortByFriends(bool reverseSort = false)
230  {
231  int direction = 1;
232  if (reverseSort)
233  direction = -1;
234 
235  foreach (SCR_PlayerListEntry entry : m_aEntries)
236  {
237  entry.m_wRow.SetZOrder(entry.m_Friend.IsToggled() * direction);
238  }
239  }
240 
241  //------------------------------------------------------------------------------------------------
242  void SortByFrequency(bool reverseSort = false)
243  {
244  int direction = 1;
245  if (reverseSort)
246  direction = -1;
247 
248  foreach (SCR_PlayerListEntry entry : m_aEntries)
249  {
250  entry.m_wRow.SetZOrder(entry.m_iSortFrequency * direction);
251  }
252  }
253 
254  //------------------------------------------------------------------------------------------------
255  void SortByKills(bool reverseSort = false)
256  {
257  int direction = 1;
258  if (reverseSort)
259  direction = -1;
260 
261  foreach (SCR_PlayerListEntry entry : m_aEntries)
262  {
263  SCR_ScoreInfo score = entry.m_Info;
264  if (score)
265  entry.m_wRow.SetZOrder(score.m_iKills * direction);
266  }
267  }
268 
269  //------------------------------------------------------------------------------------------------
270  void SortByDeaths(bool reverseSort = false)
271  {
272  int direction = 1;
273  if (reverseSort)
274  direction = -1;
275 
276  foreach (SCR_PlayerListEntry entry : m_aEntries)
277  {
278  SCR_ScoreInfo score = entry.m_Info;
279  if (score)
280  entry.m_wRow.SetZOrder(score.m_iDeaths * direction);
281  }
282  }
283 
284  //------------------------------------------------------------------------------------------------
285  void SortByScore(bool reverseSort = false)
286  {
287  int direction = 1;
288  if (reverseSort)
289  direction = -1;
290 
291  foreach (SCR_PlayerListEntry entry : m_aEntries)
292  {
293  SCR_ScoreInfo info = entry.m_Info;
294  if (info)
295  {
296  int score;
297  if (m_ScoringSystem)
298  score = m_ScoringSystem.GetPlayerScore(entry.m_iID);
299  else
300  score = 0;
301 
302  entry.m_wRow.SetZOrder(score * direction);
303  }
304  }
305  }
306 
307  //------------------------------------------------------------------------------------------------
308  void OnBlock()
309  {
310  if (!m_SelectedEntry)
311  return;
312 
313  SCR_ButtonBaseComponent block = m_SelectedEntry.m_Block;
314  if (!block)
315  return;
316 
317  block.SetToggled(!block.IsToggled());
318  }
319 
320  //------------------------------------------------------------------------------------------------
321  void OnMute()
322  {
323  if (!m_SelectedEntry)
324  return;
325 
326  SCR_ButtonBaseComponent mute = m_SelectedEntry.m_Mute; // This is temporary, until mute and block are not the same
327  if (!mute)
328  return;
329  mute.SetToggled(!mute.IsToggled());
330  }
331 
332  //------------------------------------------------------------------------------------------------
333  void OnAddFriend()
334  {
335  if (!m_SelectedEntry)
336  return;
337 
338  SCR_ButtonBaseComponent friend = m_SelectedEntry.m_Friend;
339  if (!friend)
340  return;
341 
342  friend.SetToggled(!friend.IsToggled());
343  }
344 
345  //------------------------------------------------------------------------------------------------
346  void OnTabChanged(SCR_TabViewComponent comp, Widget w, int selectedTab)
347  {
348  if (selectedTab < 0)
349  return;
350 
351  Faction faction = null;
352  foreach (Faction playableFaction : m_aFactions)
353  {
354  if (comp.GetShownTabComponent().m_sTabButtonContent == playableFaction.GetFactionName())
355  faction = playableFaction;
356  }
357 
358  int lowestZOrder = int.MAX;
359  foreach (SCR_PlayerListEntry entry : m_aEntries)
360  {
361  if (!entry.m_wRow)
362  continue;
363 
364  //if the tab is the first one, it's the All tab for now
365  if (comp.GetShownTab() == 0)
366  entry.m_wRow.SetVisible(true);
367  else if (faction == entry.m_Faction)
368  entry.m_wRow.SetVisible(true);
369  else
370  entry.m_wRow.SetVisible(false);
371  }
372 
373  if (m_Header)
374  m_Header.SetCurrentSortElement(DEFAULT_SORT_INDEX, ESortOrder.ASCENDING, useDefaultSortOrder: true);
375  CloseAllVoting();
376  }
377 
378  //------------------------------------------------------------------------------------------------
379  void OnBack()
380  {
381  if (m_bFiltering)
382  OnFilter();
383  else
384  Close();
385  }
386 
387  //------------------------------------------------------------------------------------------------
388  void OnFilter()
389  {
390  }
391 
392  //------------------------------------------------------------------------------------------------
393  void OnVoting()
394  {
395  if (!m_SelectedEntry)
396  return;
397 
398  SCR_ComboBoxComponent comp = m_SelectedEntry.m_PlayerActionList;
399  if (!comp)
400  return;
401 
402  if (comp.IsOpened())
403  comp.CloseList();
404  else
405  comp.OpenList();
406  }
407 
408  //------------------------------------------------------------------------------------------------
409  void OnInvite()
410  {
411  if (!m_SelectedEntry)
412  return;
413  SCR_PlayerControllerGroupComponent.GetLocalPlayerControllerGroupComponent().InvitePlayer(m_SelectedEntry.m_iID);
414  }
415 
416  //------------------------------------------------------------------------------------------------
417  protected void OnViewProfile()
418  {
419  if (!m_SelectedEntry)
420  return;
421 
422  GetGame().GetPlayerManager().ShowUserProfile(m_SelectedEntry.m_iID);
423  }
424 
425  //------------------------------------------------------------------------------------------------
426  void OnMuteClick(SCR_ButtonBaseComponent comp, bool selected)
427  {
428  int id = -1;
429  foreach (SCR_PlayerListEntry entry : m_aEntries)
430  {
431  if (entry.m_Mute != comp)
432  continue;
433 
434  id = entry.m_iID;
435  break;
436  }
437 
438  m_PlayerController.SetPlayerMutedState(id, selected);
439 
440  if (m_PlayerController.GetPlayerMutedState(id) == PermissionState.DISALLOWED)
441  m_Mute.SetLabel(UNMUTE);
442  else
443  m_Mute.SetLabel(MUTE);
444  }
445 
446  //------------------------------------------------------------------------------------------------
447  void OnBlockClick(SCR_ButtonBaseComponent comp, bool selected)
448  {
450  if (!m_PlayerController)
451  return;
452 
453  int id = -1;
454  foreach (SCR_PlayerListEntry entry : m_aEntries)
455  {
456  if (entry.m_Block != comp)
457  continue;
458  mute = entry.m_Mute;
459  id = entry.m_iID;
460  break;
461  }
462 
463  m_PlayerController.SetPlayerBlockedState(id, selected);
464 
465  // Set button state, set nav button state
466  if (m_PlayerController.GetPlayerBlockedState(id) == PermissionState.DISALLOWED)
467  m_Block.SetLabel(UNBLOCK);
468  else
469  m_Block.SetLabel(BLOCK);
470 
471  if (mute)
472  {
473  mute.SetToggled(true);
474  mute.SetEnabled(!mute.IsEnabled());
475  m_Mute.SetEnabled(!m_Mute.IsEnabled());
476  }
477  }
478 
479  //------------------------------------------------------------------------------------------------
480  void OnFriendClick(SCR_ButtonBaseComponent comp, bool selected)
481  {
482  // TODO: waiting for API
483  if (selected)
484  m_Friend.SetLabel(REMOVE_FRIEND);
485  else
486  m_Friend.SetLabel(ADD_FRIEND);
487  }
488 
489  //------------------------------------------------------------------------------------------------
490  void OnEntryFocused(Widget w)
491  {
492  if (!m_PlayerController)
493  return;
494 
495  foreach (SCR_PlayerListEntry entry : m_aEntries)
496  {
497  if (!entry)
498  continue;
499 
500  Widget row = entry.m_wRow;
501  if (row != w)
502  continue;
503 
504  m_SelectedEntry = entry;
505  break;
506  }
507 
508  bool enableFriend;
509  bool enableBlock;
510  bool enableMute;
511  bool enablePlayerOptionList = CanOpenPlayerActionList(m_SelectedEntry);
512 
513  if (m_SelectedEntry)
514  {
515  if (m_SelectedEntry.m_Friend)
516  enableFriend = m_SelectedEntry.m_Friend.IsEnabled();
517  if (m_SelectedEntry.m_Mute)
518  enableMute = m_SelectedEntry.m_Mute.IsEnabled();
519  if (m_SelectedEntry.m_Block)
520  {
521  enableBlock = m_SelectedEntry.m_Block.IsEnabled();
522  if (m_SelectedEntry.m_Block.IsToggled())
523  m_Friend.SetLabel(REMOVE_FRIEND);
524  else
525  m_Friend.SetLabel(ADD_FRIEND);
526  }
527  if (m_SelectedEntry.m_PlayerActionList)
528  m_SelectedEntry.m_PlayerActionList.SetEnabled(enablePlayerOptionList);
529  }
530 
531  if (m_Friend)
532  m_Friend.SetEnabled(enableFriend);
533 
534  if (m_Block)
535  {
536  m_Block.SetEnabled(enableBlock);
537  if (m_PlayerController.GetPlayerBlockedState(m_SelectedEntry.m_iID) == PermissionState.DISALLOWED)
538  {
539  enableMute = false;
540  m_Block.SetLabel(UNBLOCK);
541  }
542  else
543  m_Block.SetLabel(BLOCK);
544  }
545 
546  if (m_Mute)
547  {
548  m_Mute.SetEnabled(enableMute);
549  if (m_PlayerController.GetPlayerMutedState(m_SelectedEntry.m_iID) == PermissionState.DISALLOWED)
550  m_Mute.SetLabel(UNMUTE);
551  else
552  m_Mute.SetLabel(MUTE);
553  }
554 
555  if (m_Vote)
556  m_Vote.SetEnabled(enablePlayerOptionList);
557 
558  if (m_Invite && m_PlayerGroupController)
559  m_Invite.SetEnabled(m_PlayerGroupController.CanInvitePlayer(m_SelectedEntry.m_iID));
560 
561  if (m_SelectedEntry)
562  UpdateViewProfileButton(m_SelectedEntry.m_iID);
563  }
564 
565  //------------------------------------------------------------------------------------------------
566  void OnEntryFocusLost(Widget w)
567  {
568  UpdateViewProfileButton(0, true);
569  }
570 
571  //------------------------------------------------------------------------------------------------
572  void FocusFirstItem()
573  {
574  Widget firstEntry;
575  int lowestZOrder = int.MAX;
576  foreach (SCR_PlayerListEntry entry : m_aEntries)
577  {
578  if (!entry.m_wRow.IsVisible())
579  continue;
580 
581  int z = entry.m_wRow.GetZOrder();
582  if (z < lowestZOrder)
583  {
584  lowestZOrder = z;
585  firstEntry = entry.m_wRow;
586  }
587  }
588 
589  if (firstEntry)
590  GetGame().GetWorkspace().SetFocusedWidget(firstEntry);
591  }
592 
593  //------------------------------------------------------------------------------------------------
594  protected void UpdateViewProfileButton(int playerId, bool forceHidden = false)
595  {
596  if (!m_ViewProfile)
597  return;
598 
599  m_ViewProfile.SetVisible(!forceHidden && GetGame().GetPlayerManager().IsUserProfileAvailable(playerId), false);
600  }
601 
602  //------------------------------------------------------------------------------------------------
603  protected void SetupPlayerActionList(notnull SCR_ComboBoxComponent combo)
604  {
605  if (!m_VotingManager || !m_VoterComponent)
606  return;
607 
608  combo.ClearAll();
609 
610  int playerID = GetVotingPlayerID(combo);
611  SCR_VotingUIInfo info;
612  array<EVotingType> votingTypes = {};
613  for (int i, count = m_VotingManager.GetVotingsAboutPlayer(playerID, votingTypes, true, true); i < count; i++)
614  {
615  EVotingType votingType = votingTypes[i];
616  info = m_VotingManager.GetVotingInfo(votingType);
617 
618  if (!info)
619  {
620  Print("'SCR_PlayerListMenu' function 'SetupPlayerActionList' could not find votingInfo for vote: '" + typename.EnumToString(EVotingType, votingType) + "' is it added to the voting component?", LogLevel.ERROR);
621  continue;
622  }
623 
624  if (!m_VotingManager.IsVoting(votingType, playerID))
625  {
626  //--- Voting not in progress, start it
627  combo.AddItem(info.GetStartVotingName(), false, new SCR_PlayerListComboEntryData(votingType, SCR_EPlayerListComboAction.START_VOTE));
628  }
629  //--- Voting in progress
630  else
631  {
632  //~ Did cast a vote, withdraw it
633  if (m_VoterComponent.DidVote(votingType, playerID))
634  {
635  int currentVotes, VotesRequired;
636  if (m_VotingManager.GetVoteCounts(votingType, playerID, currentVotes, VotesRequired))
637  combo.AddItem(WidgetManager.Translate(VOTING_PLAYER_COUNT_FORMAT, info.GetCancelVotingName(), currentVotes, VotesRequired), false, new SCR_PlayerListComboEntryData(votingType, SCR_EPlayerListComboAction.CANCEL_VOTE));
638  else
639  combo.AddItem(info.GetCancelVotingName(), false, new SCR_PlayerListComboEntryData(votingType, SCR_EPlayerListComboAction.CANCEL_VOTE));
640  }
641  else
642  {
643  //~ The player did not abstain from voting
644  if (!m_VoterComponent.HasAbstained(votingType, playerID))
645  {
646  //~ Did not cast a vote, do it or abstain from doing it
647  int currentVotes, VotesRequired;
648  if (m_VotingManager.GetVoteCounts(votingType, playerID, currentVotes, VotesRequired))
649  {
650  combo.AddItem(WidgetManager.Translate(VOTING_PLAYER_COUNT_FORMAT, info.GetName(), currentVotes, VotesRequired), false, new SCR_PlayerListComboEntryData(votingType, SCR_EPlayerListComboAction.VOTE));
651  combo.AddItem(info.GetAbstainVoteName(), false, new SCR_PlayerListComboEntryData(votingType, SCR_EPlayerListComboAction.ABSTAIN_VOTE));
652  }
653  else
654  {
655  combo.AddItem(info.GetName(), false, new SCR_PlayerListComboEntryData(votingType, SCR_EPlayerListComboAction.VOTE));
656  combo.AddItem(info.GetAbstainVoteName(), false, new SCR_PlayerListComboEntryData(votingType, SCR_EPlayerListComboAction.ABSTAIN_VOTE));
657  }
658  }
659  //~ The Player abstained from voting. Revote again
660  else
661  {
662  int currentVotes, VotesRequired;
663  if (m_VotingManager.GetVoteCounts(votingType, playerID, currentVotes, VotesRequired))
664  combo.AddItem(WidgetManager.Translate(VOTING_PLAYER_COUNT_FORMAT, info.GetRevoteName(), currentVotes, VotesRequired), false, new SCR_PlayerListComboEntryData(votingType, SCR_EPlayerListComboAction.VOTE));
665  else
666  combo.AddItem(info.GetRevoteName(), false, new SCR_PlayerListComboEntryData(votingType, SCR_EPlayerListComboAction.VOTE));
667  }
668  }
669  }
670  }
671 
672  SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
673  if (!groupManager)
674  return;
675 
676  SCR_AIGroup group = groupManager.GetPlayerGroup(SCR_PlayerController.GetLocalPlayerId());
677  if (!group)
678  return;
679 
680  array<int> requesters = {};
681  group.GetRequesterIDs(requesters);
682 
683  if (requesters.Contains(playerID))
684  {
685  combo.AddItem(OPTIONS_COMBO_ACCEPT, false, new SCR_PlayerListComboEntryData(SCR_EPlayerListComboType.GROUP, SCR_EPlayerListComboAction.COMFIRM_JOIN_PRIVATE_GROUP));
686  combo.AddItem(OPTIONS_COMBO_CANCEL, false, new SCR_PlayerListComboEntryData(SCR_EPlayerListComboType.GROUP, SCR_EPlayerListComboAction.CANCEL_JOIN_PRIVATE_GROUP));
687  }
688  else if (m_PlayerGroupController.CanInvitePlayer(playerID))
689  combo.AddItem(INVITE_PLAYER_VOTE, false, new SCR_PlayerListComboEntryData(SCR_EPlayerListComboType.GROUP, SCR_EPlayerListComboAction.INVITE_TO_GROUP));
690  }
691 
692  //------------------------------------------------------------------------------------------------
693  protected void OnComboBoxConfirm(notnull SCR_ComboBoxComponent combo, int index)
694  {
695  if (!m_VoterComponent)
696  return;
697 
698  int playerID = GetVotingPlayerID(combo);
699 
700  SCR_PlayerListComboEntryData comboData = SCR_PlayerListComboEntryData.Cast(combo.GetItemData(index));
701  if (comboData)
702  {
703  switch (comboData.GetComboEntryAction())
704  {
705  case SCR_EPlayerListComboAction.VOTE: case SCR_EPlayerListComboAction.START_VOTE:
706  {
707  m_VoterComponent.Vote(comboData.GetComboEntryType(), playerID);
708  break;
709  }
710  case SCR_EPlayerListComboAction.CANCEL_VOTE:
711  {
712  if (m_VoterComponent.DidVote(comboData.GetComboEntryType(), playerID))
713  m_VoterComponent.RemoveVote(comboData.GetComboEntryType(), playerID);
714 
715  break;
716  }
717  case SCR_EPlayerListComboAction.ABSTAIN_VOTE:
718  {
719  m_VoterComponent.AbstainVote(comboData.GetComboEntryType(), playerID);
720  break;
721  }
722  case SCR_EPlayerListComboAction.INVITE_TO_GROUP:
723  {
724  SCR_PlayerControllerGroupComponent groupComponent = SCR_PlayerControllerGroupComponent.GetLocalPlayerControllerGroupComponent();
725  if (groupComponent)
726  groupComponent.InvitePlayer(playerID);
727 
728  break;
729  }
730  case SCR_EPlayerListComboAction.COMFIRM_JOIN_PRIVATE_GROUP:
731  {
732  m_PlayerGroupController.AcceptJoinPrivateGroup(playerID, true);
733  break;
734  }
735  case SCR_EPlayerListComboAction.CANCEL_JOIN_PRIVATE_GROUP:
736  {
737  m_PlayerGroupController.AcceptJoinPrivateGroup(playerID, false);
738  break;
739  }
740  }
741  }
742 
743  combo.SetCurrentItem(-1, false, false);
744  }
745 
746  //------------------------------------------------------------------------------------------------
747  protected int GetVotingPlayerID(SCR_ComboBoxComponent combo)
748  {
749  for (int i, count = m_aEntries.Count(); i < count; i++)
750  {
751  if (m_aEntries[i].m_PlayerActionList == combo)
752  return m_aEntries[i].m_iID;
753  }
754  return 0;
755  }
756 
757  //------------------------------------------------------------------------------------------------
758  void SetEntryBackgrounColor(Color color)
759  {
760  SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
761  if (!groupManager)
762  return;
763 
764  SCR_AIGroup group = groupManager.GetPlayerGroup(m_PlayerController.GetPlayerId());
765  if (!group)
766  return;
767 
768  array<int> requesters = {};
769  array<string> reqNames = {};
770 
771  group.GetRequesterIDs(requesters);
772 
773  foreach (int req : requesters)
774  {
775  reqNames.Insert(GetGame().GetPlayerManager().GetPlayerName(req));
776  }
777 
778  if (!requesters.Contains(m_SelectedEntry.m_iID))
779  return;
780 
781  Widget w = GetGame().GetWorkspace().FindAnyWidget("Button");
782 
784  if (!button)
785  return;
786 
787  ImageWidget background = ImageWidget.Cast(m_SelectedEntry.m_wRow.FindAnyWidget("Background"));
788 
789  background.SetColor(color);
790  }
791 
792  //------------------------------------------------------------------------------------------------
793  void CreateEntry(int id, SCR_PlayerDelegateEditorComponent editorDelegateManager)
794  {
795  //check for existing entry, return if it exists already
796  foreach (SCR_PlayerListEntry entry : m_aEntries)
797  {
798  if (entry.m_iID == id)
799  return;
800  }
801 
802  ImageWidget badgeTop, badgeMiddle, badgeBottom;
803 
804  Widget w = GetGame().GetWorkspace().CreateWidgets(m_sScoreboardRow, m_wTable);
805  if (!w)
806  return;
807 
808  SCR_PlayerListEntry entry = new SCR_PlayerListEntry();
809  entry.m_iID = id;
810  entry.m_wRow = w;
811 
812  //--- Initialize voting combo box
813  entry.m_PlayerActionList = SCR_ComboBoxComponent.GetComboBoxComponent("VotingCombo", w);
814  if (m_VotingManager)
815  {
816  entry.m_PlayerActionList.m_OnOpened.Insert(SetupPlayerActionList);
817  entry.m_PlayerActionList.m_OnChanged.Insert(OnComboBoxConfirm);
818  entry.m_PlayerActionList.SetEnabled(CanOpenPlayerActionList(entry));
819 
820  entry.m_wVotingNotification = entry.m_wRow.FindAnyWidget("VotingNotification");
821  entry.m_wVotingNotification.SetVisible(IsVotedAbout(entry));
822  }
823  else
824  {
825  entry.m_PlayerActionList.SetVisible(false);
826  }
827 
829  if (handler)
830  {
831  handler.m_OnFocus.Insert(OnEntryFocused);
832  handler.m_OnFocusLost.Insert(OnEntryFocusLost);
833  }
834 
835  if (m_aAllPlayersInfo)
836  {
837  foreach (int playerId, SCR_ScoreInfo info : m_aAllPlayersInfo)
838  {
839  if (!info || playerId != id)
840  continue;
841 
842  entry.m_Info = info;
843  break;
844  }
845  }
846 
847  // Find faction
848  SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
849  if (factionManager)
850  {
851  Faction faction = factionManager.GetPlayerFaction(entry.m_iID);
852  entry.m_Faction = faction;
853  }
854 
855  Widget factionImage = w.FindAnyWidget("FactionImage");
856 
857  if (factionImage)
858  {
859  if (entry.m_Faction)
860  factionImage.SetColor(entry.m_Faction.GetFactionColor());
861  else
862  factionImage.SetVisible(false);
863  }
864 
865  entry.m_wName = TextWidget.Cast(w.FindAnyWidget("PlayerName"));
866 
867  if (entry.m_wName)
868  {
869  entry.m_wName.SetText(GetGame().GetPlayerManager().GetPlayerName(id));
870  if (entry.m_iID == m_PlayerController.GetPlayerId())
871  entry.m_wName.SetColor(m_PlayerNameSelfColor);
872  }
873 
874  if (editorDelegateManager)
875  {
876  SCR_EditablePlayerDelegateComponent playerEditorDelegate = editorDelegateManager.GetDelegate(id);
877 
878  if (playerEditorDelegate)
879  {
880  playerEditorDelegate.GetOnLimitedEditorChanged().Insert(OnEditorRightsChanged);
881  UpdateGameMasterIndicator(entry, playerEditorDelegate.HasLimitedEditor());
882  }
883  }
884 
885  entry.m_wFreq = TextWidget.Cast(w.FindAnyWidget("Freq"));
886  entry.m_wKills = TextWidget.Cast(w.FindAnyWidget("Kills"));
887  entry.m_wDeaths = TextWidget.Cast(w.FindAnyWidget("Deaths"));
888  entry.m_wScore = TextWidget.Cast(w.FindAnyWidget("Score"));
889  if (entry.m_Info)
890  {
891  if (entry.m_wKills)
892  entry.m_wKills.SetText(entry.m_Info.m_iKills.ToString());
893  if (entry.m_wDeaths)
894  entry.m_wDeaths.SetText(entry.m_Info.m_iDeaths.ToString());
895  if (entry.m_wScore)
896  {
897  // Use modifiers from scoring system where applicable!!!
898  int score;
899  if (m_ScoringSystem)
900  score = m_ScoringSystem.GetPlayerScore(id);
901 
902  entry.m_wScore.SetText(score.ToString());
903  }
904  }
905  else
906  {
907 
908  if (entry.m_wKills)
909  entry.m_wKills.SetText("");
910  if (entry.m_wDeaths)
911  entry.m_wDeaths.SetText("");
912  if (entry.m_wScore)
913  entry.m_wScore.SetText("");
914  // Unfortunately the parent that must be hidden is two parents above the text widgets
915  /*
916  if (entry.m_wKills)
917  entry.m_wKills.GetParent().GetParent().SetVisible(false);
918  if (entry.m_wDeaths)
919  entry.m_wDeaths.GetParent().GetParent().SetVisible(false);
920  if (entry.m_wScore)
921  entry.m_wScore.GetParent().GetParent().SetVisible(false);
922  */
923  }
924 
925  entry.m_Mute = SCR_ButtonBaseComponent.GetButtonBase("Mute", w);
926  entry.m_Friend = SCR_ButtonBaseComponent.GetButtonBase("Friend", w);
927  entry.m_Block = SCR_ButtonBaseComponent.GetButtonBase("Block", w);
928  entry.m_wTaskIcon = entry.m_wRow.FindAnyWidget("TaskIcon");
929  entry.m_wLoadoutIcon = ImageWidget.Cast(entry.m_wRow.FindAnyWidget("LoadoutIcon"));
930  entry.m_wPlatformIcon = ImageWidget.Cast(entry.m_wRow.FindAnyWidget("PlatformIcon"));
931 
932  ImageWidget background = ImageWidget.Cast(w.FindAnyWidget("Background"));
933  SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
934  if (!groupManager)
935  return;
936 
937  SCR_AIGroup group = groupManager.GetPlayerGroup(m_PlayerController.GetPlayerId());
938 
939  if (group && group.HasRequesterID(id))
940  background.SetColor(m_PlayerNameSelfColor); // Saphyr TODO: temporary before definition from art dept.
941 
942  if (entry.m_wTaskIcon && GetTaskManager())
943  {
944  SCR_BaseTaskExecutor taskExecutor = SCR_BaseTaskExecutor.FindTaskExecutorByID(entry.m_iID);
945  if (taskExecutor.GetAssignedTask())
946  {
947  entry.m_wTaskIcon.SetColor(entry.m_Faction.GetFactionColor());
948  }
949  else
950  {
951  entry.m_wTaskIcon.SetOpacity(0);
952  }
953  }
954 
955 
956  Faction playerFaction;
957  Faction entryPlayerFaction;
958  if (factionManager)
959  {
960  playerFaction = factionManager.GetPlayerFaction(m_PlayerController.GetPlayerId());
961  entryPlayerFaction = factionManager.GetPlayerFaction(entry.m_iID);
962  }
963 
964 
965  SCR_BasePlayerLoadout playerLoadout;
966  SCR_LoadoutManager loadoutManager = GetGame().GetLoadoutManager();
967  if (loadoutManager)
968  playerLoadout = loadoutManager.GetPlayerLoadout(entry.m_iID);
969 
970 
971 
972  if (entry.m_wLoadoutIcon && (playerFaction != entryPlayerFaction))
973  entry.m_wLoadoutIcon.SetVisible(false);
974 
975  //enable GM to see everyones loadout icon, temporary solution until we get improved ways to say who's GM
976  if (SCR_EditorManagerEntity.IsOpenedInstance())
977  entry.m_wLoadoutIcon.SetVisible(true);
978 
979  if (entry.m_wLoadoutIcon && playerLoadout && entry.m_wLoadoutIcon.IsVisible())
980  {
981  Resource res = Resource.Load(playerLoadout.GetLoadoutResource());
982  IEntityComponentSource source = SCR_BaseContainerTools.FindComponentSource(res, "SCR_EditableCharacterComponent");
983  if (!source)
984  return;
985  BaseContainer container = source.GetObject("m_UIInfo");
986  SCR_EditableEntityUIInfo info = SCR_EditableEntityUIInfo.Cast(BaseContainerTools.CreateInstanceFromContainer(container));
987  info.SetIconTo(entry.m_wLoadoutIcon);
988  }
989 
990  if (entry.m_wPlatformIcon)
991  {
992  PlayerManager playerManager = GetGame().GetPlayerManager();
993  PlatformKind playerPlatform = playerManager.GetPlatformKind(entry.m_iID);
994  string iconName = SCR_Global.GetPlatformName(playerPlatform);
995  entry.m_wPlatformIcon.LoadImageFromSet(0, "{D17288006833490F}UI/Textures/Icons/icons_wrapperUI-32.imageset", iconName);
996  entry.m_wPlatformIcon.SetImage(0);
997  }
998  else
999  {
1000  Print("No platform icon detected in players list. This is against MS Xbox Live rules.", LogLevel.WARNING);
1001  }
1002 
1003 
1004  badgeTop = ImageWidget.Cast(entry.m_wRow.FindAnyWidget("BadgeTop"));
1005  badgeMiddle = ImageWidget.Cast(entry.m_wRow.FindAnyWidget("BadgeMiddle"));
1006  badgeBottom = ImageWidget.Cast(entry.m_wRow.FindAnyWidget("BadgeBottom"));
1007  Color factionColor;
1008 
1009  if (badgeTop && badgeMiddle && badgeBottom && entry.m_Faction)
1010  {
1011  factionColor = entry.m_Faction.GetFactionColor();
1012  badgeTop.SetColor(factionColor);
1013  badgeMiddle.SetColor(factionColor);
1014  badgeBottom.SetColor(factionColor);
1015  }
1016 
1017  // If this is player, set all buttons invisible
1018  if (IsLocalPlayer(entry.m_iID))
1019  {
1020  if (entry.m_Friend)
1021  entry.m_Friend.SetEnabled(false);
1022 
1023  if (entry.m_Mute)
1024  entry.m_Mute.SetEnabled(false);
1025 
1026  if (entry.m_Block)
1027  entry.m_Block.SetEnabled(false);
1028  }
1029  else
1030  {
1031  if (entry.m_Mute)
1032  {
1033  // Find out if the person is aleady muted
1034  //entry.m_Mute.SetEnabled(false);
1035 
1036  if (m_PlayerController)
1037  {
1038  entry.m_Mute.SetEnabled(true);
1039  if (m_PlayerController.GetPlayerMutedState(entry.m_iID) == PermissionState.DISALLOWED)
1040  entry.m_Mute.SetToggled(true);
1041 
1042  else if (m_PlayerController.GetPlayerMutedState(entry.m_iID) == PermissionState.ALLOWED)
1043 
1044  entry.m_Mute.SetToggled(false);
1045 
1046  if (m_PlayerController.GetPlayerMutedState(entry.m_iID) == PermissionState.DISABLED)
1047  entry.m_Mute.SetEnabled(false);
1048 
1049  }
1050  entry.m_Mute.m_OnToggled.Insert(OnMuteClick);
1051  }
1052 
1053  if (entry.m_Friend)
1054  {
1055  entry.m_Friend.SetEnabled(false);
1056  entry.m_Friend.m_OnToggled.Insert(OnFriendClick);
1057  }
1058 
1059  if (entry.m_Block)
1060  {
1061  if (m_PlayerController)
1062  {
1063  entry.m_Block.SetEnabled(true);
1064  if (m_PlayerController.GetPlayerBlockedState(entry.m_iID) == PermissionState.DISALLOWED)
1065  entry.m_Block.SetToggled(true);
1066 
1067  else if (m_PlayerController.GetPlayerBlockedState(entry.m_iID) == PermissionState.ALLOWED)
1068 
1069  entry.m_Block.SetToggled(false);
1070 
1071  if (m_PlayerController.GetPlayerBlockedState(entry.m_iID) == PermissionState.DISABLED)
1072  entry.m_Block.SetEnabled(false);
1073 
1074  }
1075 
1076  entry.m_Block.m_OnToggled.Insert(OnBlockClick);
1077  }
1078  }
1079 
1080  m_aEntries.Insert(entry);
1081  }
1082 
1083  //------------------------------------------------------------------------------------------------
1084  protected void OnEditorRightsChanged(int playerID, bool newLimited)
1085  {
1086  foreach (SCR_PlayerListEntry entry : m_aEntries)
1087  {
1088  if (entry.m_iID == playerID)
1089  {
1090  UpdateGameMasterIndicator(entry, newLimited);
1091  break;
1092  }
1093  }
1094  }
1095 
1096  //------------------------------------------------------------------------------------------------
1097  protected void UpdateGameMasterIndicator(SCR_PlayerListEntry entry, bool editorIslimited)
1098  {
1099  Widget gameMasterIndicator = entry.m_wRow.FindAnyWidget(m_sGameMasterIndicatorName);
1100  if (gameMasterIndicator)
1101  gameMasterIndicator.SetVisible(!editorIslimited);
1102  }
1103 
1104  //------------------------------------------------------------------------------------------------
1105  // IsLocalPlayer would be better naming
1106  protected bool IsLocalPlayer(int id)
1107  {
1108  if (id <= 0)
1109  return false;
1110 
1111  return SCR_PlayerController.GetLocalPlayerId() == id;
1112  }
1113 
1114  //------------------------------------------------------------------------------------------------
1115  void RemoveEntry(notnull SCR_PlayerListEntry entry)
1116  {
1117  if (entry.m_wRow)
1118  entry.m_wRow.RemoveFromHierarchy();
1119 
1121 
1122  //Remove the subscription to player right changed
1123  if (editorDelegateManager)
1124  {
1125  SCR_EditablePlayerDelegateComponent playerEditorDelegate = editorDelegateManager.GetDelegate(entry.m_iID);
1126 
1127  if (playerEditorDelegate)
1128  {
1129  playerEditorDelegate.GetOnLimitedEditorChanged().Remove(OnEditorRightsChanged);
1130  }
1131  }
1132 
1133  m_aEntries.RemoveItem(entry);
1134  }
1135 
1136  //------------------------------------------------------------------------------------------------
1137  protected void OpenPauseMenu()
1138  {
1139  GetGame().OpenPauseMenu();
1140  Close();
1141  }
1142 
1143  //------------------------------------------------------------------------------------------------
1144  protected void OnVotingChanged(EVotingType type, int value, int playerID)
1145  {
1146  UpdateVoting();
1147  }
1148  protected void GetOnVotingStart(EVotingType type, int value)
1149  {
1150  UpdateVoting();
1151  }
1152  protected void UpdateVoting()
1153  {
1154  foreach (SCR_PlayerListEntry entry : m_aEntries)
1155  {
1156  entry.m_PlayerActionList.SetEnabled(CanOpenPlayerActionList(entry));
1157  entry.m_wVotingNotification.SetVisible(IsVotedAbout(entry));
1158  }
1159 
1160  if (m_SelectedEntry)
1161  m_Vote.SetEnabled(CanOpenPlayerActionList(m_SelectedEntry));
1162  }
1163  protected bool IsVotedAbout(SCR_PlayerListEntry entry)
1164  {
1165  if (!entry || !m_VotingManager)
1166  return false;
1167 
1168  array<EVotingType> votingTypes = {};
1169  int count = m_VotingManager.GetVotingsAboutPlayer(entry.m_iID, votingTypes, false, true);
1170  int validEntries = count;
1171 
1172  //~ Remove any votes that cannot be shown to the player. Eg faction specific votes
1173  foreach (EVotingType voteType : votingTypes)
1174  {
1175  if (!m_VotingManager.IsVotingAvailable(voteType, entry.m_iID))
1176  validEntries--;
1177  }
1178 
1179  return validEntries > 0;
1180  }
1181 
1182  protected bool CanOpenPlayerActionList(SCR_PlayerListEntry entry)
1183  {
1184  if (!entry)
1185  return false;
1186 
1187  if (m_VotingManager)
1188  {
1189  //~ Check if can vote, if yes return true
1190  array<EVotingType> votingTypes = {};
1191  m_VotingManager.GetVotingsAboutPlayer(entry.m_iID, votingTypes, true, true);
1192 
1193  //~ Check if UI info can be found
1194  foreach(EVotingType votingType : votingTypes)
1195  {
1196  if (m_VotingManager.GetVotingInfo(votingType))
1197  return true;
1198  }
1199  }
1200 
1201  //~ Can invite the player so return true
1202  if (m_PlayerGroupController.CanInvitePlayer(entry.m_iID))
1203  return true;
1204 
1205  //~ Check if Player actions have group dropdown
1206  SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
1207  if (groupManager)
1208  {
1209  //~ No group so no drop down
1210  SCR_AIGroup group = groupManager.GetPlayerGroup(SCR_PlayerController.GetLocalPlayerId());
1211  if (group)
1212  {
1213  array<int> requesters = {};
1214  group.GetRequesterIDs(requesters);
1215 
1216  if (requesters.Contains(entry.m_iID))
1217  return true;
1218  }
1219  }
1220 
1221  //~ None of the conditions met
1222  return false;
1223  }
1224 
1225  //------------------------------------------------------------------------------------------------
1226  private void OnPlayerAdded(int playerId)
1227  {
1228  UpdatePlayerList(true, playerId);
1229  }
1230  private void OnPlayerRemoved(int playerId)
1231  {
1232  UpdatePlayerList(false, playerId);
1233  }
1234  private void OnScoreChanged()
1235  {
1236  UpdateScore();
1237  }
1238  private void OnPlayerScoreChanged(int playerId, SCR_ScoreInfo scoreInfo)
1239  {
1240  OnScoreChanged();
1241  }
1242  private void OnFactionScoreChanged(Faction faction, SCR_ScoreInfo scoreInfo)
1243  {
1244  OnScoreChanged();
1245  }
1246 
1247  //------------------------------------------------------------------------------------------------
1248  override void OnMenuOpen()
1249  {
1250  super.OnMenuOpen();
1251 
1252  //if (!m_ChatPanel)
1253  // m_ChatPanel = SCR_ChatPanel.Cast(m_wRoot.FindAnyWidget("ChatPanel").FindHandler(SCR_ChatPanel));
1254 
1255  m_PlayerController = GetGame().GetPlayerController();
1256 
1258  hudManager.SetVisibleLayers(hudManager.GetVisibleLayers() & ~EHudLayers.HIGH);
1259 
1261  if (!gameMode)
1262  return;
1263  m_PlayerGroupController = SCR_PlayerControllerGroupComponent.GetLocalPlayerControllerGroupComponent();
1264  m_PlayerController = GetGame().GetPlayerController();
1265  m_VoterComponent = SCR_VoterComponent.GetInstance();
1266  m_VotingManager = SCR_VotingManagerComponent.GetInstance();
1267 
1268  if (m_VotingManager)
1269  {
1270  m_VotingManager.GetOnVotingEnd().Insert(OnVotingChanged);
1271  m_VotingManager.GetOnVotingStart().Insert(GetOnVotingStart);
1272  m_VotingManager.GetOnRemoveVote().Insert(OnVotingChanged);
1273  }
1274 
1275  //gameMode.GetOnPlayerKilled().Insert(OnPlayerKilled);
1276  gameMode.GetOnPlayerRegistered().Insert(OnPlayerConnected);
1277 
1278  m_ScoringSystem = gameMode.GetScoringSystemComponent();
1279  if (m_ScoringSystem)
1280  {
1281  m_ScoringSystem.GetOnPlayerAdded().Insert(OnPlayerAdded);
1282  m_ScoringSystem.GetOnPlayerRemoved().Insert(OnPlayerRemoved);
1283  m_ScoringSystem.GetOnPlayerScoreChanged().Insert(OnPlayerScoreChanged);
1284  m_ScoringSystem.GetOnFactionScoreChanged().Insert(OnFactionScoreChanged);
1285 
1286  array<int> players = {};
1287  PlayerManager playerManager = GetGame().GetPlayerManager();
1288  playerManager.GetPlayers(players);
1289 
1290  m_aAllPlayersInfo.Clear();
1291  foreach (int playerId : players)
1292  m_aAllPlayersInfo.Insert(playerId, m_ScoringSystem.GetPlayerScoreInfo(playerId));
1293  }
1294 
1295  FactionManager fm = GetGame().GetFactionManager();
1296  if (fm)
1297  {
1298  fm.GetFactionsList(m_aFactions);
1299  }
1300 
1301  m_wTable = GetRootWidget().FindAnyWidget("Table");
1302 
1303  // Create navigation buttons
1304  Widget footer = GetRootWidget().FindAnyWidget("FooterLeft");
1305  Widget footerBack = GetRootWidget().FindAnyWidget("Footer");
1306  SCR_InputButtonComponent back = SCR_InputButtonComponent.GetInputButtonComponent("Back", footerBack);
1307  if (back)
1308  back.m_OnActivated.Insert(OnBack);
1309 
1310  m_Friend = SCR_InputButtonComponent.GetInputButtonComponent("Friend", footer);
1311  if (m_Friend)
1312  {
1313  m_Friend.SetEnabled(false);
1314  m_Friend.m_OnActivated.Insert(OnAddFriend);
1315  }
1316 
1317  m_Block = SCR_InputButtonComponent.GetInputButtonComponent("Block", footer);
1318  if (m_Block)
1319  {
1320  m_Block.SetEnabled(false);
1321  m_Block.m_OnActivated.Insert(OnBlock);
1322  }
1323 
1324  m_Mute = SCR_InputButtonComponent.GetInputButtonComponent("Mute", footer);
1325  if (m_Mute)
1326  {
1327  m_Mute.SetEnabled(false);
1328  m_Mute.m_OnActivated.Insert(OnMute);
1329  }
1330 
1331  SCR_InputButtonComponent filter = SCR_InputButtonComponent.GetInputButtonComponent("Filter", footer);
1332  if (filter)
1333  filter.m_OnActivated.Insert(OnFilter);
1334 
1335  m_Vote = SCR_InputButtonComponent.GetInputButtonComponent("Vote", footer);
1336  if (m_Vote)
1337  {
1338  if (m_VotingManager)
1339  m_Vote.m_OnActivated.Insert(OnVoting);
1340  else
1341  m_Vote.SetVisible(false,false);
1342  }
1343 
1344  m_Invite = SCR_InputButtonComponent.GetInputButtonComponent("Invite", footer);
1345  if (m_Invite)
1346  {
1347  if (m_PlayerGroupController)
1348  m_Invite.m_OnActivated.Insert(OnInvite);
1349  else
1350  m_Invite.SetVisible(false, false);
1351  }
1352 
1353  m_ViewProfile = SCR_InputButtonComponent.GetInputButtonComponent("ViewProfile", footer);
1354  if (m_ViewProfile)
1355  {
1356  UpdateViewProfileButton(0, true);
1357  m_ViewProfile.m_OnActivated.Insert(OnViewProfile);
1358  }
1359 
1360  // Create table
1361  if (!m_wTable || m_sScoreboardRow == string.Empty)
1362  return;
1363 
1364  //Get editor Delegate manager to check if has editor rights
1366 
1367 
1368  array<int> ids = {};
1369  GetGame().GetPlayerManager().GetPlayers(ids);
1370 
1371  foreach (int id : ids)
1372  {
1373  CreateEntry(id, editorDelegateManager);
1374  }
1375 
1376  InitSorting();
1377 
1378  m_SuperMenuComponent.GetTabView().GetOnChanged().Insert(OnTabChanged);
1379 
1380  // Create new tabs
1381  SCR_Faction scrFaction;
1382  foreach (Faction faction : m_aFactions)
1383  {
1384  if (!faction)
1385  continue;
1386 
1387  scrFaction = SCR_Faction.Cast(faction);
1388  if (scrFaction && !scrFaction.IsPlayable())
1389  continue; //--- ToDo: Refresh dynamically when a new faction is added/removed
1390 
1391  string name = faction.GetFactionName();
1392  m_SuperMenuComponent.GetTabView().AddTab(ResourceName.Empty,name);
1393 
1394  AddFactionPlayerCounter(faction);
1395  }
1396 
1397  //handle groups tab
1398  SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1399  Faction playerFaction;
1400  SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
1401  if (factionManager)
1402  playerFaction = factionManager.GetLocalPlayerFaction();
1403 
1404 
1405  if (!groupsManager || !playerFaction)
1406  m_SuperMenuComponent.GetTabView().SetTabVisible(EPlayerListTab.GROUPS, false);
1407  UpdateFrequencies();
1408 
1409  s_OnPlayerListMenu.Invoke(true);
1410  }
1411 
1412  //------------------------------------------------------------------------------------------------
1413  override void OnMenuUpdate(float tDelta)
1414  {
1415  m_fTimeSkip = m_fTimeSkip + tDelta;
1416 
1417  if (m_fTimeSkip >= TIME_STEP)
1418  {
1419  DeleteDisconnectedEntries();
1420  m_fTimeSkip = 0.0;
1421  }
1422 
1423  GetGame().GetInputManager().ActivateContext("PlayerMenuContext");
1424  }
1425 
1426  //------------------------------------------------------------------------------------------------
1427  override void OnMenuFocusGained()
1428  {
1429  GetGame().GetInputManager().AddActionListener("ShowScoreboard", EActionTrigger.DOWN, Close);
1430 
1431  if (m_Header)
1432  m_Header.SetCurrentSortElement(DEFAULT_SORT_INDEX, ESortOrder.ASCENDING, useDefaultSortOrder: true);
1433 
1434  FocusFirstItem();
1435  }
1436 
1437  //------------------------------------------------------------------------------------------------
1438  override void OnMenuFocusLost()
1439  {
1440  GetGame().GetInputManager().RemoveActionListener("ShowScoreboard", EActionTrigger.DOWN, Close);
1441 
1442  //--- Close when some other menu is opened on top
1443  Close();
1444  }
1445 
1446  //------------------------------------------------------------------------------------------------
1447  override void OnMenuClose()
1448  {
1449  super.OnMenuClose();
1450 
1452  if (hudManager)
1453  hudManager.SetVisibleLayers(hudManager.GetVisibleLayers() | EHudLayers.HIGH);
1454 
1456 
1457  //Remove the subscriptions to player right changed
1458  if (editorDelegateManager)
1459  {
1460  foreach (SCR_PlayerListEntry entry : m_aEntries)
1461  {
1462  if (entry)
1463  {
1464  SCR_EditablePlayerDelegateComponent playerEditorDelegate = editorDelegateManager.GetDelegate(entry.m_iID);
1465 
1466  if (playerEditorDelegate)
1467  {
1468  playerEditorDelegate.GetOnLimitedEditorChanged().Remove(OnEditorRightsChanged);
1469  }
1470  }
1471  }
1472  }
1473 
1474  m_aAllPlayersInfo.Clear();
1475  m_aFactions.Clear();
1476 
1477  if (m_ScoringSystem)
1478  {
1479  m_ScoringSystem.GetOnPlayerAdded().Remove(OnPlayerAdded);
1480  m_ScoringSystem.GetOnPlayerRemoved().Remove(OnPlayerRemoved);
1481  m_ScoringSystem.GetOnPlayerScoreChanged().Remove(OnPlayerScoreChanged);
1482  m_ScoringSystem.GetOnFactionScoreChanged().Remove(OnFactionScoreChanged);
1483  }
1484 
1485  s_OnPlayerListMenu.Invoke(false);
1486  }
1487 
1488  // Call updates with delay, so name is synced properly
1489  //------------------------------------------------------------------------------------------------
1490  void OnPlayerConnected(int id)
1491  {
1492  GetGame().GetCallqueue().CallLater(UpdatePlayerList, 1000, false, true, id);
1493  }
1494 
1495  //------------------------------------------------------------------------------------------------
1496  void UpdatePlayerList(bool addPlayer, int id)
1497  {
1498  if (addPlayer)
1499  {
1501  CreateEntry(id, editorDelegateManager);
1502 
1503  // Get current sort method and re-apply sorting
1504  if (!m_Header)
1505  return;
1506 
1507  OnHeaderChanged(m_Header);
1508  }
1509  else
1510  {
1511  // Delete entry from the list
1512  SCR_PlayerListEntry playerEntry;
1513  foreach (SCR_PlayerListEntry entry : m_aEntries)
1514  {
1515  if (entry.m_iID != id)
1516  continue;
1517 
1518  playerEntry = entry;
1519  break;
1520  }
1521 
1522  if (!playerEntry)
1523  return;
1524 
1525  playerEntry.m_wRow.RemoveFromHierarchy();
1526  m_aEntries.RemoveItem(playerEntry);
1527  }
1528  }
1529 
1530  //------------------------------------------------------------------------------------------------
1531  void UpdateFrequencies()
1532  {
1533  SCR_GadgetManagerComponent gadgetManager;
1534  IEntity localPlayer = SCR_PlayerController.GetLocalMainEntity();
1535  Faction localFaction;
1536  set<int> localFrequencies = new set<int>();
1537  if (localPlayer)
1538  {
1539  gadgetManager = SCR_GadgetManagerComponent.Cast(localPlayer.FindComponent(SCR_GadgetManagerComponent));
1540  SCR_Global.GetFrequencies(gadgetManager, localFrequencies);
1541 
1542  FactionAffiliationComponent factionAffiliation = FactionAffiliationComponent.Cast(localPlayer.FindComponent(FactionAffiliationComponent));
1543  if (factionAffiliation)
1544  localFaction = factionAffiliation.GetAffiliatedFaction();
1545  }
1546 
1547  foreach (SCR_PlayerListEntry entry : m_aEntries)
1548  {
1549  if (entry.m_Faction == localFaction)
1550  {
1551  IEntity playerEntity = GetGame().GetPlayerManager().GetPlayerControlledEntity(entry.m_iID);
1552  if (playerEntity)
1553  {
1554  //--- ToDo: Don't extract frequencies locally; do it on server and distribute values to all clients
1555  gadgetManager = SCR_GadgetManagerComponent.Cast(playerEntity.FindComponent(SCR_GadgetManagerComponent));
1556  set<int> frequencies = new set<int>();
1557  SCR_Global.GetFrequencies(gadgetManager, frequencies);
1558  if (!frequencies.IsEmpty())
1559  {
1560  entry.m_iSortFrequency = frequencies[0];
1561  entry.m_wFreq.SetText(SCR_FormatHelper.FormatFrequencies(frequencies, localFrequencies));
1562  continue;
1563  }
1564  }
1565  }
1566  entry.m_iSortFrequency = int.MAX;
1567  entry.m_wFreq.SetText("-");
1568  }
1569  GetGame().GetCallqueue().CallLater(UpdateFrequencies, 1000, false);
1570  }
1571 
1572  //------------------------------------------------------------------------------------------------
1573  void UpdateScore()
1574  {
1575  if (!m_aAllPlayersInfo || m_aAllPlayersInfo.Count() == 0 || !m_ScoringSystem)
1576  return;
1577 
1578  foreach (SCR_PlayerListEntry entry : m_aEntries)
1579  {
1580  foreach (int playerId, SCR_ScoreInfo info : m_aAllPlayersInfo)
1581  {
1582  if (!info || playerId != entry.m_iID)
1583  continue;
1584 
1585  entry.m_Info = info;
1586  break;
1587  }
1588 
1589  if (!entry.m_Info)
1590  continue;
1591 
1592  if (entry.m_wKills)
1593  entry.m_wKills.SetText(entry.m_Info.m_iKills.ToString());
1594  if (entry.m_wDeaths)
1595  entry.m_wDeaths.SetText(entry.m_Info.m_iDeaths.ToString());
1596  if (entry.m_wScore)
1597  {
1598  // Use modifiers from scoring system where applicable!!!
1599  int score;
1600  if (m_ScoringSystem)
1601  score = m_ScoringSystem.GetPlayerScore(entry.m_iID);
1602 
1603  entry.m_wScore.SetText(score.ToString());
1604  }
1605  }
1606 
1607  // Get current sort method and re-apply sorting
1608  if (!m_Header)
1609  return;
1610 
1611  OnHeaderChanged(m_Header);
1612  }
1613 
1614  //------------------------------------------------------------------------------------------------
1615  void CloseAllVoting()
1616  {
1617  foreach (SCR_PlayerListEntry entry : m_aEntries)
1618  {
1619  if (entry.m_PlayerActionList && entry.m_PlayerActionList.IsOpened())
1620  entry.m_PlayerActionList.CloseList();
1621  }
1622  }
1623 
1624  //------------------------------------------------------------------------------------------------
1625  void DeleteDisconnectedEntries()
1626  {
1627  for (int i = m_aEntries.Count() - 1; i >= 0; i--)
1628  {
1629  if (GetGame().GetPlayerManager().IsPlayerConnected(m_aEntries[i].m_iID))
1630  continue;
1631  m_aEntries[i].m_wRow.RemoveFromHierarchy();
1632  m_aEntries.RemoveItem(m_aEntries[i]);
1633  }
1634  }
1635 
1636  //------------------------------------------------------------------------------------------------
1637  void AddFactionPlayerCounter(Faction faction)
1638  {
1639  SCR_Faction scriptedFaction = SCR_Faction.Cast(faction);
1640  if (!scriptedFaction)
1641  return;
1642 
1643  Widget contentLayout = GetRootWidget().FindAnyWidget("FactionPlayerNumbersLayout");
1644  if (!contentLayout)
1645  return;
1646 
1647  Widget factionTile = GetGame().GetWorkspace().CreateWidgets(FACTION_COUNTER_LAYOUT, contentLayout);
1648  if (!factionTile)
1649  return;
1650 
1651  RichTextWidget playerCount = RichTextWidget.Cast(factionTile.FindAnyWidget("PlayerCount"));
1652  if (!playerCount)
1653  return;
1654 
1655  ImageWidget factionFlag = ImageWidget.Cast(factionTile.FindAnyWidget("FactionFlag"));
1656  if (!factionFlag)
1657  return;
1658 
1659  int x, y;
1660  factionFlag.LoadImageTexture(0, scriptedFaction.GetFactionFlag());
1661  factionFlag.GetImageSize(0, x, y);
1662  factionFlag.SetSize(x, y);
1663 
1664  playerCount.SetText(scriptedFaction.GetPlayerCount().ToString());
1665  }
1666 };
1667 
1668 //------------------------------------------------------------------------------------------------
1669 //~ Holds the data of the player list combo entry
1671 {
1672  protected SCR_EPlayerListComboType m_eComboEntryType;
1673  protected SCR_EPlayerListComboAction m_eComboEntryAction;
1674 
1675  void SCR_PlayerListComboEntryData(SCR_EPlayerListComboType comboEntryType, SCR_EPlayerListComboAction comboEntryAction)
1676  {
1677  m_eComboEntryType = comboEntryType;
1678  m_eComboEntryAction = comboEntryAction;
1679  }
1680 
1684  SCR_EPlayerListComboType GetComboEntryType()
1685  {
1686  return m_eComboEntryType;
1687  }
1688 
1692  SCR_EPlayerListComboAction GetComboEntryAction()
1693  {
1694  return m_eComboEntryAction;
1695  }
1696 }
1697 
1698 //------------------------------------------------------------------------------------------------
1699 //~ Types of combo list data entry, inherents from Voting as voting is the main type used
1700 enum SCR_EPlayerListComboType : EVotingType
1701 {
1702  GROUP, //~ Makes sure System knows the combo data is regarding group
1703 };
1704 
1705 //------------------------------------------------------------------------------------------------
1706 //~ Available actions valid for the player combo box data types
1708 {
1709  //~ Voting
1710  VOTE = 0,
1714 
1715  //Group
1719 };
GROUPS
@ GROUPS
Definition: SCR_PlayerListMenu.c:4
SCR_BaseGameMode
Definition: SCR_BaseGameMode.c:137
SCR_HUDManagerComponent
Definition: SCR_HUDManagerComponent.c:23
m_wName
TextWidget m_wName
Definition: SCR_PlayerListMenu.c:20
m_Friend
SCR_ButtonBaseComponent m_Friend
Definition: SCR_PlayerListMenu.c:17
direction
vector direction
Definition: SCR_DestructibleTreeV2.c:31
m_iID
int m_iID
Definition: SCR_PlayerListMenu.c:10
m_wVotingNotification
Widget m_wVotingNotification
Definition: SCR_PlayerListMenu.c:29
SCR_ComboBoxComponent
Definition: SCR_ComboBoxComponent.c:1
SCR_PlayerController
Definition: SCR_PlayerController.c:31
EPlayerListTab
EPlayerListTab
Definition: SCR_PlayerListMenu.c:1
ALL
@ ALL
Definition: SCR_PlayerListMenu.c:3
GROUP
SCR_PlayerListComboEntryData GROUP
m_wFactionImage
Widget m_wFactionImage
Definition: SCR_PlayerListMenu.c:28
SCR_FormatHelper
Definition: SCR_FormatHelper.c:1
m_PlayerActionList
SCR_ComboBoxComponent m_PlayerActionList
Definition: SCR_PlayerListMenu.c:18
m_wKills
TextWidget m_wKills
Definition: SCR_PlayerListMenu.c:21
m_Info
enum EPlayerListTab m_Info
COMFIRM_JOIN_PRIVATE_GROUP
@ COMFIRM_JOIN_PRIVATE_GROUP
Definition: SCR_PlayerListMenu.c:1717
SCR_PlayerListMenu
Definition: SCR_PlayerListMenu.c:33
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_GadgetManagerComponent
Definition: SCR_GadgetManagerComponent.c:138
m_wDeaths
TextWidget m_wDeaths
Definition: SCR_PlayerListMenu.c:23
INVITE_TO_GROUP
@ INVITE_TO_GROUP
Definition: SCR_PlayerListMenu.c:1716
SCR_BaseScoringSystemComponent
Definition: SCR_BaseScoringSystemComponent.c:26
SCR_EditableEntityUIInfo
Definition: SCR_EditableEntityUIInfo.c:2
m_iSortFrequency
int m_iSortFrequency
Definition: SCR_PlayerListMenu.c:13
PermissionState
PermissionState
Definition: PermissionState.c:12
SCR_LoadoutManager
void SCR_LoadoutManager(IEntitySource src, IEntity parent)
Definition: SCR_LoadoutManager.c:500
SCR_PlayerDelegateEditorComponent
Definition: SCR_PlayerDelegateEditorComponent.c:9
SCR_TabViewComponent
Definition: SCR_TabViewComponent.c:13
GetRootWidget
Widget GetRootWidget()
Definition: SCR_UITaskManagerComponent.c:160
GetGameMode
SCR_BaseGameMode GetGameMode()
Definition: SCR_BaseGameModeComponent.c:15
TIME_STEP
const protected float TIME_STEP
Definition: SCR_FuelConsumptionComponent.c:21
EHudLayers
EHudLayers
Definition: SCR_HUDManagerComponent.c:5
m_aEntries
protected ref array< ref SCR_TextsTaskManagerEntry > m_aEntries
Definition: SCR_TextsTaskManagerComponent.c:3
m_aAllPlayersInfo
protected ref array< ref SCR_PlayerScoreInfoFiringRange > m_aAllPlayersInfo
Contains score info of all the players.
Definition: SCR_FiringRangeScoringComponent.c:11
GetTaskManager
SCR_BaseTaskManager GetTaskManager()
Definition: SCR_BaseTaskManager.c:7
m_wFreq
TextWidget m_wFreq
Definition: SCR_PlayerListMenu.c:22
SCR_EPlayerListComboAction
SCR_EPlayerListComboAction
Definition: SCR_PlayerListMenu.c:1707
m_Block
SCR_ButtonBaseComponent m_Block
Definition: SCR_PlayerListMenu.c:16
START_VOTE
@ START_VOTE
Definition: SCR_PlayerListMenu.c:1711
SCR_ButtonBaseComponent
Base class for any button, regardless its own content.
Definition: SCR_ButtonBaseComponent.c:3
m_wTaskIcon
Widget m_wTaskIcon
Definition: SCR_PlayerListMenu.c:27
m_wRow
Widget m_wRow
Definition: SCR_PlayerListMenu.c:11
ABSTAIN_VOTE
@ ABSTAIN_VOTE
Definition: SCR_PlayerListMenu.c:1713
m_wLoadoutIcon
ImageWidget m_wLoadoutIcon
Definition: SCR_PlayerListMenu.c:25
SCR_SuperMenuBase
Definition: SCR_SuperMenuBase.c:6
SCR_ScoreInfo
Definition: SCR_ScoreInfo.c:6
SCR_BaseContainerTools
Definition: SCR_BaseContainerTools.c:3
Faction
Definition: Faction.c:12
SCR_GroupsManagerComponent
void SCR_GroupsManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_GroupsManagerComponent.c:1320
SCR_BaseTaskExecutor
Definition: SCR_BaseTaskExecutor.c:7
m_Faction
Faction m_Faction
Definition: SCR_PlayerListMenu.c:12
index
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
Definition: SCR_DestructionSynchronizationComponent.c:17
EVotingType
EVotingType
Definition: EVotingType.c:1
m_wScore
TextWidget m_wScore
Definition: SCR_PlayerListMenu.c:24
SCR_Global
Definition: Functions.c:6
SCR_VotingUIInfo
Definition: SCR_VotingUIInfo.c:2
CANCEL_JOIN_PRIVATE_GROUP
@ CANCEL_JOIN_PRIVATE_GROUP
Definition: SCR_PlayerListMenu.c:1718
m_PlayerController
SCR_CampaignNetworkComponentClass m_PlayerController
Takes care of Campaign-specific server <> client communication and requests.
m_fTimeSkip
protected float m_fTimeSkip
Definition: SCR_FuelNode.c:58
SCR_AIGroup
Definition: SCR_AIGroup.c:68
type
EDamageType type
Definition: SCR_DestructibleTreeV2.c:32
m_wPlatformIcon
ImageWidget m_wPlatformIcon
Definition: SCR_PlayerListMenu.c:26
SCR_VotingManagerComponent
void SCR_VotingManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_VotingManagerComponent.c:878
SCR_FactionManager
void SCR_FactionManager(IEntitySource src, IEntity parent)
Definition: SCR_FactionManager.c:461
VOTE
@ VOTE
Definition: SCR_PlayerListMenu.c:1710
m_Mute
SCR_ButtonBaseComponent m_Mute
Definition: SCR_PlayerListMenu.c:15
SCR_PlayerListComboEntryData
Definition: SCR_PlayerListMenu.c:1670
CANCEL_VOTE
@ CANCEL_VOTE
Definition: SCR_PlayerListMenu.c:1712
SCR_SortHeaderComponent
Definition: SCR_SortHeaderComponent.c:7
SCR_BasePlayerLoadout
Definition: SCR_BasePlayerLoadout.c:2
PlayerManager
Definition: PlayerManager.c:12
SCR_Faction
Definition: SCR_Faction.c:6
ESortOrder
ESortOrder
Definition: SCR_SortElementComponent.c:1
SCR_InputButtonComponent
Definition: SCR_InputButtonComponent.c:1
SCR_EditorManagerEntity
Definition: SCR_EditorManagerEntity.c:26