Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_PlayerControllerGroupComponent.c
Go to the documentation of this file.
1[EntityEditorProps(category: "GameScripted/Groups", description: "This component should be attached to player controller and is used by groups to send requests to server.")]
5
6class SCR_PlayerControllerGroupComponent : ScriptComponent
7{
8 protected int m_iGroupID = -1;
9 // Map with playerID and list of groups the player was invited to
11
12 // Keeps track of Group Invites <GroupID, PlayerID from player that sent Group Invite>
14
20
21 protected int m_iUISelectedGroupID = -1;
22 protected int m_iPreviousGroupID = -1;
23 protected string m_sGroupInviteFromPlayerName; //Player name is saved to get the name of the one who invited even if that player left the server
24
25 protected static const ref Color DEFAULT_COLOR = new Color(0, 0, 0, 0.4);
26
27 //------------------------------------------------------------------------------------------------
30 static SCR_PlayerControllerGroupComponent GetPlayerControllerComponent(int playerID)
31 {
32 PlayerController playerController = GetGame().GetPlayerManager().GetPlayerController(playerID);
33 if (!playerController)
34 return null;
35
36 return SCR_PlayerControllerGroupComponent.Cast(playerController.FindComponent(SCR_PlayerControllerGroupComponent));
37 }
38
39 //------------------------------------------------------------------------------------------------
41 static SCR_PlayerControllerGroupComponent GetLocalPlayerControllerGroupComponent()
42 {
43 SCR_PlayerController playerController = SCR_PlayerController.Cast(GetGame().GetPlayerController());
44 if (!playerController)
45 return null;
46
47 return SCR_PlayerControllerGroupComponent.Cast(playerController.FindComponent(SCR_PlayerControllerGroupComponent));
48 }
49
50 //------------------------------------------------------------------------------------------------
53 {
54 return m_iGroupID;
55 }
56
57 //------------------------------------------------------------------------------------------------
63
64 //------------------------------------------------------------------------------------------------
72 void RequestCreateGroupWithData(SCR_EGroupRole groupRole, bool isPrivate, string name, string description, bool joinGroup = true, bool deleteIfNoPlayer = true)
73 {
74 Rpc(RpcAsk_CreateGroupWithData, groupRole, isPrivate, name, description, joinGroup, deleteIfNoPlayer);
75 }
76
77 //------------------------------------------------------------------------------------------------
80 void RequestKickPlayer(int playerID)
81 {
82 Rpc(RPC_AskKickPlayer, playerID);
83 }
84
85 //------------------------------------------------------------------------------------------------
88 void RequestPromoteLeader(int playerID)
89 {
90 Rpc(RPC_AskPromoteLeader, playerID);
91 }
92
93 //------------------------------------------------------------------------------------------------
97 void RequestPrivateGroupChange(int playerID, bool isPrivate)
98 {
99 Rpc(RPC_ChangePrivateGroup, playerID, isPrivate);
100 }
101
102 //------------------------------------------------------------------------------------------------
106 void PlayerRequestToJoinPrivateGroup(int playerID, RplId groupID)
107 {
108 Rpc(RPC_PlayerRequestToJoinPrivateGroup, playerID, groupID);
109 }
110
111 //------------------------------------------------------------------------------------------------
115 {
116 Rpc(RPC_ClearAllRequesters, groupID);
117 RPC_ClearAllRequesters(groupID);
118 }
119
120 //------------------------------------------------------------------------------------------------
123 {
124 PlayerController playerController = PlayerController.Cast(GetOwner());
125 if (!playerController)
126 return -1;
127
128 return playerController.GetPlayerId();
129 }
130
131 //------------------------------------------------------------------------------------------------
136 bool CanPlayerJoinGroup(int playerID, notnull SCR_AIGroup group)
137 {
138 /*
139 Assumed issue:
140 SCR_FactionManager have cache mapping playerIds to factions.
141 This cache may not be in sysnc with the FactionAffiliation, because of different replication hieararchies and methods
142 Fix:
143 We do not use cache, but instead ask directly SCR_PlayerFactionAffiliationComponent.
144 This should work on client asking for its own PlayerId or server for any IDs.
145 */
146
147 // Flipping comment for quick switch of implementation
148 //*
149 Faction groupFaction = group.GetFaction();
150 if (!groupFaction)
151 {
152 #ifdef DEPLOY_MENU_DEBUG
153 Print(string.Format("SCR_PlayerControllerGroupComponent.CanPlayerJoinGroup(%1, %2) - No group faction", playerID, group), LogLevel.ERROR);
154 #endif
155 return false;
156 }
157
158 Faction playerFaction = SCR_FactionManager.SGetPlayerFaction(playerID);
159 if (playerFaction != groupFaction)
160 {
161 #ifdef DEPLOY_MENU_DEBUG
162 Print(string.Format("SCR_PlayerControllerGroupComponent.CanPlayerJoinGroup(%1, %2) - Faction mis-match! See, below:", playerID, group), LogLevel.ERROR);
163 Print(playerFaction, LogLevel.NORMAL);
164 if (playerFaction)
165 Print(playerFaction.GetFactionKey(), LogLevel.NORMAL);
166
167 Print(groupFaction, LogLevel.NORMAL);
168 if (groupFaction)
169 Print(groupFaction.GetFactionKey(), LogLevel.NORMAL);
170 #endif
171 return false;
172 }
173
174 /*/
175 // First we check the player is in the faction of the group
176 Faction playerFaction;
177 SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
178 if (factionManager)
179 {
180 // TODO (langepau): Remove temporary debug logging when respawn issue is fixed.
181 playerFaction = factionManager.GetPlayerFaction(playerID);
182 Faction groupFaction = group.GetFaction();
183 if (playerFaction != groupFaction)
184 {
185 #ifdef DEPLOY_MENU_DEBUG
186 Print(string.Format("SCR_PlayerControllerGroupComponent.CanPlayerJoinGroup(%1, %2) - Faction mis-match! See, below:", playerID, group), LogLevel.ERROR);
187 Print(playerFaction, LogLevel.NORMAL);
188 if (playerFaction)
189 Print(playerFaction.GetFactionKey(), LogLevel.NORMAL);
190
191 Print(groupFaction, LogLevel.NORMAL);
192 if (groupFaction)
193 Print(groupFaction.GetFactionKey(), LogLevel.NORMAL);
194 #endif
195
196 return false;
197 }
198 }
199 else
200 {
201 #ifdef DEPLOY_MENU_DEBUG
202 Print(string.Format("SCR_PlayerControllerGroupComponent.CanPlayerJoinGroup(%1, %2) - No SCR_FactionManager!", playerID, group), LogLevel.ERROR);
203 #endif
204 }
205 //*/
206
207 // Groups manager doesn't exist, no point in continuing, cannot join
208 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
209 if (!groupsManager)
210 {
211 #ifdef DEPLOY_MENU_DEBUG
212 Print(string.Format("SCR_PlayerControllerGroupComponent.CanPlayerJoinGroup(%1, %2) - No SCR_GroupsManagerComponent!", playerID, group), LogLevel.ERROR);
213 #endif
214 return false;
215 }
216
217 // Cannot join a full group
218 if (group.IsFull())
219 return false;
220
221 // Cannot join the group we are in already
222 if (groupsManager.GetPlayerGroup(playerID) == group)
223 {
224 #ifdef DEPLOY_MENU_DEBUG
225 Print(string.Format("SCR_PlayerControllerGroupComponent.CanPlayerJoinGroup(%1, %2) - Already in group!", playerID, group), LogLevel.ERROR);
226 #endif
227 return false;
228 }
229
230 SCR_Faction scrPlayerFaction = SCR_Faction.Cast(playerFaction);
231 if (scrPlayerFaction)
232 {
233 // Commander can only join group with Commander role
234 SCR_EGroupRole groupRole = group.GetGroupRole();
235 if (scrPlayerFaction.GetCommanderId() == playerID && groupRole != SCR_EGroupRole.COMMANDER)
236 return false;
237
238 // Check if player has required rank for group loadouts
239 SCR_GroupRolePresetConfig groupPreset = groupsManager.FindGroupRolePresetConfig(scrPlayerFaction, groupRole);
240 if (groupPreset)
241 return groupsManager.HasPlayerRequiredRank(groupPreset, playerID, true);
242 }
243
244 return true;
245 }
246
247 //------------------------------------------------------------------------------------------------
252 bool CanPlayerRemoveGroup(int playerID, notnull SCR_AIGroup group)
253 {
254 // First we check the player is in the faction of the group
255 SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
256 if (factionManager)
257 {
258 Faction playerFaction = factionManager.GetPlayerFaction(playerID);
259 if (!playerFaction)
260 return false;
261
262 Faction groupFaction = group.GetFaction();
263 if (playerFaction != groupFaction)
264 return false;
265
266 if (SCR_FactionCommanderHandlerComponent.GetInstance())
267 {
268 // commander group cannot be removed
269 if (group.GetGroupRole() == SCR_EGroupRole.COMMANDER)
270 return false;
271
272 // check if player is faction commander, only faction commander can remove group
273 SCR_Faction scrFaction = SCR_Faction.Cast(playerFaction);
274 if (!scrFaction || !group.IsCreatedByCommander() || scrFaction.GetCommanderId() != playerID)
275 return false;
276 }
277 }
278
279 // Groups manager doesn't exist
280 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
281 if (!groupsManager)
282 return false;
283
284 // Cannot remove, there is still players
285 if (group.GetPlayerCount() > 0)
286 return false;
287
288 return true;
289 }
290
291 //------------------------------------------------------------------------------------------------
296 bool IsPlayerLeader(int playerID, notnull SCR_AIGroup group)
297 {
298 return playerID == group.GetLeaderID();
299 }
300
301 //------------------------------------------------------------------------------------------------
305 {
306 SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
307 if (!groupManager)
308 return false;
309
310 //get controller from owner, because if this is used on server we cannot get local players player controller :wesmart:
312 if (!controller)
313 return false;
314
315 int playerID = controller.GetPlayerId();
316 SCR_AIGroup playerGroup = groupManager.GetPlayerGroup(playerID);
317 if (!playerGroup)
318 return false;
319
320 return IsPlayerLeader(playerID, playerGroup);
321 }
322
323 //------------------------------------------------------------------------------------------------
327 bool CanInvitePlayer(int playerID)
328 {
329 // Our group id is not valid -> cannot invite anyone
330 if (m_iGroupID < 0)
331 return false;
332
333 // Groups manager doesn't exist, no point in continuing, cannot invite
334 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
335 if (!groupsManager)
336 return false;
337
338 // We get our group
339 SCR_AIGroup group = groupsManager.GetPlayerGroup(GetPlayerID());
340 if (!group)
341 return false;
342
343 // Check if the player can join us
344 if (!CanPlayerJoinGroup(playerID, group))
345 return false;
346
347 // Already invited this player, cannot invite again
348 if (WasAlreadyInvited(playerID))
349 return false;
350
351 return true;
352 }
353
354 //------------------------------------------------------------------------------------------------
358 bool WasAlreadyInvited(int playerID)
359 {
360 // The map is not initialised -> didn't invite anyone yet
362 return false;
363
364 // We didn't invite this player to any group yet
365 if (!m_mPlayerInvitesToGroups.Contains(playerID))
366 return false;
367
368 // If our group is in the array of invites for this player, we return true (already invited)
369 // Otherwise we return false (wasn't invited yet)
370 return m_mPlayerInvitesToGroups.Get(playerID).Contains(m_iGroupID);
371 }
372
373 //------------------------------------------------------------------------------------------------
377 void AcceptJoinPrivateGroup(int playerID, bool accept)
378 {
379 SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
380
381 SCR_AIGroup group = groupManager.FindGroup(GetGroupID());
382 if (!group)
383 return;
384
385 group.GetOnJoinPrivateGroupConfirm().Invoke(DEFAULT_COLOR); // Saphyr TODO: temporary before definition from art dept.
386
387 if (accept)
388 Rpc(RPC_ConfirmJoinPrivateGroup,playerID, group.GetGroupID());
389 else
390 Rpc(RPC_CancelJoinPrivateGroup, playerID, group.GetGroupID());
391 }
392
393 //------------------------------------------------------------------------------------------------
396 void InvitePlayer(int playerID)
397 {
398 // When group id is not valid, return
399 if (m_iGroupID < 0)
400 return;
401
402 // Init map if not initialised yet
405
406 // Init array of groups the playerID was invited to if not initialised yet
407 if (!m_mPlayerInvitesToGroups.Contains(playerID))
408 m_mPlayerInvitesToGroups.Insert(playerID, {});
409
410 // We already invited this player to our group, don't invite again
411 if (m_mPlayerInvitesToGroups.Get(playerID).Contains(m_iGroupID))
412 return;
413
414 // We didn't invite this player to our group yet
415 // Get an array of all the groups the local player invited the other player to
416 array<int> invitedGroups = m_mPlayerInvitesToGroups.Get(playerID);
417
418 // Invite the player and log the invitation
419 Rpc(RPC_AskInvitePlayer, playerID);
420 invitedGroups.Insert(m_iGroupID);
421 }
422
423 //------------------------------------------------------------------------------------------------
427 void InviteThisPlayer(int groupID, int fromPlayerID)
428 {
429 Rpc(RPC_DoInvitePlayer, groupID, fromPlayerID)
430 }
431
432 //------------------------------------------------------------------------------------------------
435 {
437 return;
438
439 SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
440 if (!groupManager)
441 return;
442
443 SCR_AIGroup group = groupManager.FindGroup(m_iUISelectedGroupID);
444 if (!group)
445 return;
446
448
450
452
455
457 }
458
459 //------------------------------------------------------------------------------------------------
462 {
464 return;
465
466 SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
467 if (!groupManager)
468 return;
469
470 SCR_AIGroup group = groupManager.FindGroup(m_iUISelectedGroupID);
471 if (!group)
472 return;
473
475
477
480
482 }
483
484 //------------------------------------------------------------------------------------------------
493
494 //------------------------------------------------------------------------------------------------
497 {
498 if (!group)
499 return;
500
501 //in case of the selected group being deleted, remove it from selected
502 if (group.GetGroupID() == GetSelectedGroupID())
504
505 int groupId = group.GetGroupID();
506
507 if (m_mGroupIdInvites.Contains(groupId))
508 {
509 //delete the invite if the target group has been deleted
510 m_mGroupIdInvites.Remove(groupId);
512 m_OnInviteCancelled.Invoke();
513 }
514 }
515
516 //------------------------------------------------------------------------------------------------
523
524 //------------------------------------------------------------------------------------------------
528 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
529 void RPC_PlayerRequestToJoinPrivateGroup(int playerID, RplId groupID)
530 {
531 SCR_AIGroup group = SCR_AIGroup.Cast(Replication.FindItem(groupID));
532 if (!group)
533 return;
534
535 group.AddRequester(playerID);
536 SCR_NotificationsComponent.SendToPlayer(group.GetLeaderID(), ENotification.GROUPS_REQUEST_JOIN_PRIVATE_GROUP, playerID);
537 }
538
539 //------------------------------------------------------------------------------------------------
543 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
544 void RPC_ConfirmJoinPrivateGroup(int playerID, int groupID)
545 {
546 SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
547 if (!groupManager)
548 return;
549
550 SCR_AIGroup group = groupManager.FindGroup(groupID);
551 if (!group)
552 return;
553
554 PlayerController playerController = GetGame().GetPlayerManager().GetPlayerController(playerID);
555 if (!playerController)
556 return;
557
558 SCR_PlayerControllerGroupComponent playerComponent = SCR_PlayerControllerGroupComponent.Cast(playerController.FindComponent(SCR_PlayerControllerGroupComponent));
559
560 playerComponent.RequestJoinGroup(group.GetGroupID());
561
562 group.RemoveRequester(playerID);
563
564 SCR_NotificationsComponent.SendToPlayer(playerID, ENotification.GROUPS_REQUEST_ACCEPTED);
565 }
566
567 //------------------------------------------------------------------------------------------------
571 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
572 void RPC_CancelJoinPrivateGroup(int playerID, int groupID)
573 {
574 SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
575 if (!groupManager)
576 return;
577
578 SCR_AIGroup group = groupManager.FindGroup(groupID);
579 if (!group)
580 return;
581
582 group.RemoveRequester(playerID);
583 group.AddDeniedRequester(playerID);
584
585 SCR_NotificationsComponent.SendToPlayer(playerID, ENotification.GROUPS_REQUEST_DENIED);
586 }
587
588 //------------------------------------------------------------------------------------------------
592 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
593 void RPC_DoInvitePlayer(int groupID, int fromPlayerID)
594 {
595 if (!m_mGroupIdInvites.Contains(groupID))
596 m_mGroupIdInvites.Insert(groupID, fromPlayerID);
597
598 //Save player name so it can be obtained even if the player left
599 PlayerManager playerManager = GetGame().GetPlayerManager();
600 if (playerManager)
601 m_sGroupInviteFromPlayerName = SCR_PlayerNamesFilterCache.GetInstance().GetPlayerDisplayName(fromPlayerID);
602
604 m_OnInviteReceived.Invoke(groupID, fromPlayerID);
605 }
606
607 //------------------------------------------------------------------------------------------------
610 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
611 void RPC_AskInvitePlayer(int playerID)
612 {
613 PlayerController invitedPlayer = GetGame().GetPlayerManager().GetPlayerController(playerID);
614 if (!invitedPlayer)
615 return;
616
617 SCR_PlayerControllerGroupComponent invitedPlayerGroupComponent = SCR_PlayerControllerGroupComponent.Cast(invitedPlayer.FindComponent(SCR_PlayerControllerGroupComponent));
618 if (!invitedPlayerGroupComponent)
619 return;
620
621 SocialComponent socialComp = SocialComponent.Cast(invitedPlayer.FindComponent(SocialComponent));
622 if (socialComp)
623 {
624 PlayerController inviterComponent = PlayerController.Cast(GetOwner());
625 if (inviterComponent && socialComp.IsRestricted(inviterComponent.GetPlayerId(), EUserInteraction.Invitation))
626 return;
627 }
628
629 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
630 SCR_AIGroup group = groupsManager.FindGroup(m_iGroupID);
631 if (!group)
632 return;
633
634 SCR_GroupRolePresetConfig groupPreset = groupsManager.FindGroupRolePresetConfig(group.GetFaction(), group.GetGroupRole());
635 if (groupPreset && !groupsManager.HasPlayerRequiredRank(groupPreset, playerID, true))
636 {
637 // Show "Insufficient rank" notification to client
638 SCR_NotificationsComponent.SendToPlayer(GetPlayerID(), ENotification.GROUPS_INVITE_CANCELLED_INSUFFICIENT_RANK);
639 return;
640 }
641
642 invitedPlayerGroupComponent.InviteThisPlayer(m_iGroupID, GetPlayerID());
643 }
644
645 //------------------------------------------------------------------------------------------------
647 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
649 {
650 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
651 if (!groupsManager)
652 return;
653
654 SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
655 if (!factionManager)
656 return;
657
658 Faction faction = factionManager.GetPlayerFaction(GetPlayerID());
659 if (!faction)
660 return;
661
662 SCR_Faction scrFaction = SCR_Faction.Cast(faction);
663 if(!scrFaction)
664 return;
665
666 // We check if there is any empty group already for our faction
667 if (groupsManager.TryFindEmptyGroup(faction))
668 return;
669
670 // We check if other then predefined group can be created
671 if(scrFaction.GetCanCreateOnlyPredefinedGroups())
672 return;
673
674 // No empty group found, we allow creation of new group
675 SCR_AIGroup newGroup = groupsManager.CreateNewPlayableGroup(faction);
676
677 // No new group was created, return
678 if (!newGroup)
679 return;
680
681 // New group sucessfully created
682 // The player should be automatically added/moved to it
683 RPC_AskJoinGroup(newGroup.GetGroupID());
684 }
685
686 //------------------------------------------------------------------------------------------------
688 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
689 void RpcAsk_CreateGroupWithData(SCR_EGroupRole groupRole, bool isPrivate, string name, string description, bool joinGroup, bool deleteIfNoPlayer)
690 {
691 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
692 if (!groupsManager)
693 return;
694
695 SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
696 if (!factionManager)
697 return;
698
699 int playerId = GetPlayerID();
700 Faction faction = factionManager.GetPlayerFaction(playerId);
701 if (!faction)
702 return;
703
704 SCR_Faction scrFaction = SCR_Faction.Cast(faction);
705 if (!scrFaction)
706 return;
707
708 array<SCR_EGroupRole> availableGroupRoles = groupsManager.GetAvailableGroupRoles(faction, playerId);
709 if (!availableGroupRoles || !availableGroupRoles.Contains(groupRole))
710 {
711 PrintFormat("Group role %1 is not available", typename.EnumToString(SCR_EGroupRole, groupRole), level: LogLevel.WARNING);
712 return;
713 }
714
715 // No empty group found, we allow creation of new group
716 SCR_AIGroup newGroup = groupsManager.CreateNewPlayableGroup(faction, groupRole);
717
718 // No new group was created, return
719 if (!newGroup)
720 return;
721
722 array<SCR_GroupRolePresetConfig> groupRolePresetConfigs = {};
723 scrFaction.GetGroupRolePresetConfigs(groupRolePresetConfigs);
724 foreach (SCR_GroupRolePresetConfig preset : groupRolePresetConfigs)
725 {
726 if (preset && preset.GetGroupRole() == groupRole)
727 {
728 preset.SetupGroup(newGroup); // set defaults
729 preset.SetupGroupFlag(newGroup, scrFaction);
730
731 break;
732 }
733 }
734
735 newGroup.SetPrivate(isPrivate);
736 newGroup.SetCanDeleteIfNoPlayer(deleteIfNoPlayer);
737
738 /*
739 To set the name and description of the group, the calling of the SetCustomNameAndDescription function must be delayed to the next frame,
740 because the Rplcomponent on the new group is not set yet and the Rpc SetCustomName and SetCustomDescription are not called on the clients.
741 RplSave and RplLoad won't help in this case, because customName and description pass through asynchronous profanity filter,
742 so it takes a while for m_sCustomName and m_sCustomDescription to filter and set.
743 */
744 GetGame().GetCallqueue().Call(SetCustomNameAndDescription, newGroup, name, description, playerId);
745
746 // New group sucessfully created
747 // The player should be automatically added/moved to it
748 if (joinGroup)
749 RPC_AskJoinGroup(newGroup.GetGroupID());
750
751 // check if author is commander
752 if (scrFaction.GetCommanderId() == playerId)
753 newGroup.SetCreatedByCommander(true);
754 }
755
756 //------------------------------------------------------------------------------------------------
759 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
760 void RPC_AskKickPlayer(int playerID)
761 {
762 SCR_GroupsManagerComponent groupsManager;
763 SCR_PlayerControllerGroupComponent playerGroupController;
764 SCR_AIGroup group;
765 if (!InitiateComponents(playerID, groupsManager, playerGroupController, group))
766 return;
767
768 //requesting player is not leader of the targets group, do nothing
769 if (!group.IsPlayerLeader(GetPlayerID()))
770 return;
771
772 // if we have a reserves group, we prioritize putting the kicked player in there.
773 array<SCR_AIGroup> playableGroups = groupsManager.GetPlayableGroupsByFaction(group.GetFaction());
774 foreach (SCR_AIGroup groupInstance : playableGroups)
775 {
776 if (groupInstance.GetGroupRole() == SCR_EGroupRole.RESERVES)
777 {
778 playerGroupController.RequestJoinGroup(groupInstance.GetGroupID());
779 return;
780 }
781 }
782
783 // No reserve group found, so we will create a new group.
784 SCR_AIGroup newGroup = groupsManager.GetFirstNotFullForFaction(group.GetFaction(), group, true);
785 if (!newGroup)
786 newGroup = groupsManager.CreateNewPlayableGroup(group.GetFaction());
787
788 if (!newGroup)
789 return;
790 playerGroupController.RequestJoinGroup(newGroup.GetGroupID());
791 }
792
793 //------------------------------------------------------------------------------------------------
796 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
797 void RPC_AskPromoteLeader(int playerID)
798 {
799 SCR_GroupsManagerComponent groupsManager;
800 SCR_PlayerControllerGroupComponent playerGroupController;
801 SCR_AIGroup group;
802 if (!InitiateComponents(playerID, groupsManager, playerGroupController, group))
803 return;
804
805 if (!group.IsPlayerLeader(GetPlayerID()))
806 return;
807
808 groupsManager.SetGroupLeader(group.GetGroupID(), playerID);
809 }
810
811 //------------------------------------------------------------------------------------------------
815 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
816 void RPC_ChangePrivateGroup(int playerID, bool isPrivate)
817 {
818 SCR_GroupsManagerComponent groupsManager;
819 SCR_PlayerControllerGroupComponent playerGroupController;
820 SCR_AIGroup group;
821 if (!InitiateComponents(playerID, groupsManager, playerGroupController, group))
822 return;
823
824 groupsManager.SetPrivateGroup(group.GetGroupID(), isPrivate);
825 }
826
827 //------------------------------------------------------------------------------------------------
830 void RequestJoinGroup(int groupID)
831 {
832 Rpc(RPC_AskJoinGroup, groupID);
833 }
834
835 //------------------------------------------------------------------------------------------------
836 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
838 {
840 m_iGroupID = -1;
841 }
842
843 //------------------------------------------------------------------------------------------------
846 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
847 void RPC_DoChangeGroupID(int groupID)
848 {
849 m_iGroupID = groupID;
850 if (HasInviteFromGroup(groupID))
851 {
852 //reset the invite if player manually joined the group he is invited into
853 m_mGroupIdInvites.Remove(groupID);
855
857 m_OnInviteCancelled.Invoke(groupID);
858 }
860 GetGame().GetCallqueue().CallLater(OnGroupChangedDelayed, 0, false, groupID);
861 }
862
863 //------------------------------------------------------------------------------------------------
864 protected void OnGroupChangedDelayed(int groupId)
865 {
866 m_OnGroupChanged.Invoke(groupId);
867 }
868
869 //------------------------------------------------------------------------------------------------
872 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
873 void RPC_AskJoinGroup(int groupID)
874 {
875 // Trying to join the same group, reject.
876 if (groupID == m_iGroupID)
877 return;
878
879 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
880 if (!groupsManager)
881 return;
882
883 int groupIDAfter;
884 if (m_iGroupID != -1)
885 groupIDAfter = groupsManager.MovePlayerToGroup(GetPlayerID(), m_iGroupID, groupID);
886 else
887 groupIDAfter = groupsManager.AddPlayerToGroup(groupID, GetPlayerID());
888
889 if (groupIDAfter != m_iGroupID)
890 {
892 m_iGroupID = groupIDAfter;
894 Rpc(RPC_DoChangeGroupID, groupIDAfter);
895 }
896 }
897
898 //------------------------------------------------------------------------------------------------
901 void RequestRemovePlayer(int playerID)
902 {
903 Rpc(RpcAsk_RemovePlayer, playerID);
904 }
905
906 //------------------------------------------------------------------------------------------------
909 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
910 void RpcAsk_RemovePlayer(int playerID)
911 {
912 if (m_iGroupID < 0)
913 return;
914
915 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
916 if (!groupsManager)
917 return;
918
919 SCR_AIGroup group = groupsManager.FindGroup(m_iGroupID);
920 if (!group)
921 return;
922
923 m_iGroupID = -1;
924 group.RemovePlayer(playerID);
925 if (group.GetPlayerCount() == 0) // is the group still nonempty?
926 groupsManager.DeleteGroupDelayed(group);
927 }
928
929 //------------------------------------------------------------------------------------------------
932 void RequestRemoveGroup(int groupID)
933 {
934 Rpc(RpcAsk_RemoveGroup, groupID);
935 }
936
937 //------------------------------------------------------------------------------------------------
940 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
941 void RpcAsk_RemoveGroup(int groupID)
942 {
943 // Trying to remove the my group, reject.
944 if (groupID == m_iGroupID || m_iGroupID == -1)
945 return;
946
947 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
948 if (!groupsManager)
949 return;
950
951 SCR_AIGroup group = groupsManager.FindGroup(groupID);
952 if (!group || group.GetPlayerCount() > 0)
953 return;
954
955 groupsManager.DeleteGroupDelayed(group);
956 }
957
958 //------------------------------------------------------------------------------------------------
965 bool InitiateComponents(int playerID, out SCR_GroupsManagerComponent groupsManager, out SCR_PlayerControllerGroupComponent playerGroupController , out SCR_AIGroup group)
966 {
967 groupsManager = SCR_GroupsManagerComponent.GetInstance();
968 if (!groupsManager)
969 return false;
970
971 playerGroupController = SCR_PlayerControllerGroupComponent.GetPlayerControllerComponent(playerID);
972 if (!playerGroupController)
973 return false;
974
975 group = groupsManager.GetPlayerGroup(playerID);
976 if (!group)
977 return false;
978 return true;
979 }
980
981 //------------------------------------------------------------------------------------------------
984 {
986 }
987
988 //------------------------------------------------------------------------------------------------
997
998 //------------------------------------------------------------------------------------------------
1007
1008 //------------------------------------------------------------------------------------------------
1017
1018 //------------------------------------------------------------------------------------------------
1027
1028 //------------------------------------------------------------------------------------------------
1032 {
1033 return m_mGroupIdInvites.Get(index);
1034 }
1035
1036 //------------------------------------------------------------------------------------------------
1038 void RemoveGroupInviteId(int groupId)
1039 {
1040 m_mGroupIdInvites.Remove(groupId);
1041 }
1042
1043 //------------------------------------------------------------------------------------------------
1046 {
1047 return !m_mGroupIdInvites.IsEmpty();
1048 }
1049
1050 //------------------------------------------------------------------------------------------------
1053 bool HasInviteFromGroup(int groupId)
1054 {
1055 return m_mGroupIdInvites.Contains(groupId);
1056 }
1057
1058 //------------------------------------------------------------------------------------------------
1061 {
1062 int playerId;
1063 m_mGroupIdInvites.Find(groupId, playerId);
1064
1065 return playerId;
1066 }
1067
1068 //------------------------------------------------------------------------------------------------
1071 {
1072 return m_iPreviousGroupID;
1073 }
1074
1075 //------------------------------------------------------------------------------------------------
1081
1082 //------------------------------------------------------------------------------------------------
1084 void SetSelectedGroupID(int groupID)
1085 {
1086 m_iUISelectedGroupID = groupID;
1087
1089 m_OnSetSelectedGroupID.Invoke(groupID);
1090 }
1091
1092 //------------------------------------------------------------------------------------------------
1093 protected void SetCustomNameAndDescription(SCR_AIGroup group, string name, string description, int playerId)
1094 {
1095 group.SetCustomName(name, playerId);
1096 group.SetCustomDescription(description, playerId);
1097 }
1098
1099 //------------------------------------------------------------------------------------------------
1108
1109 //------------------------------------------------------------------------------------------------
1114 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1115 void RPC_AskSetCustomDescription(int groupID, string desc, int authorID)
1116 {
1117 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1118 if (!groupsManager)
1119 return;
1120
1121 SCR_AIGroup group = groupsManager.FindGroup(groupID);
1122 if (!group)
1123 return;
1124
1125 group.SetCustomDescription(desc, authorID);
1126 }
1127
1128 //------------------------------------------------------------------------------------------------
1132 void RequestSetGroupMaxMembers(int groupID, int maxMembers)
1133 {
1134 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1135 if (!groupsManager)
1136 return;
1137
1138 SCR_AIGroup group = groupsManager.FindGroup(groupID);
1139 if (!group)
1140 return;
1141
1142 if (group.GetMaxMembers() == maxMembers)
1143 return;
1144
1145 Rpc(RPC_AskSetGroupMaxMembers, groupID, maxMembers);
1146 }
1147
1148 //------------------------------------------------------------------------------------------------
1152 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1153 void RPC_AskSetGroupMaxMembers(int groupID, int maxMembers)
1154 {
1155 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1156 if (!groupsManager)
1157 return;
1158
1159 SCR_AIGroup group = groupsManager.FindGroup(groupID);
1160 if (!group)
1161 return;
1162
1163 if (group.GetMaxMembers() == maxMembers)
1164 return;
1165
1166 group.SetMaxMembers(maxMembers);
1167 }
1168
1169 //------------------------------------------------------------------------------------------------
1175 void RequestSetCustomFrequency(int groupID, int frequency)
1176 {
1177 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1178 if (!groupsManager)
1179 return;
1180
1181 SCR_AIGroup group = groupsManager.FindGroup(groupID);
1182 if (!group)
1183 return;
1184
1185 if (frequency < 0 || group.GetRadioFrequency() == frequency)
1186 return;
1187
1188 Rpc(RPC_AskSetFrequency, groupID, frequency);
1189 }
1190
1191 //------------------------------------------------------------------------------------------------
1194 void RequestSetNewGroupsAllowed(bool isAllowed)
1195 {
1196 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1197 if (!groupsManager || isAllowed == groupsManager.GetNewGroupsAllowed())
1198 return;
1199
1200 Rpc(RPC_AskSetNewGroupsAllowed, isAllowed);
1201 }
1202
1203 //------------------------------------------------------------------------------------------------
1207 {
1208 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1209 if (!groupsManager || isAllowed == groupsManager.GetNewGroupsAllowed())
1210 return;
1211
1213 }
1214
1215 //------------------------------------------------------------------------------------------------
1219 void RequestSetCustomGroupName(int groupID, string name)
1220 {
1223 }
1224
1225 //------------------------------------------------------------------------------------------------
1230 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1231 void RPC_AskSetCustomName(int groupID, string name, int authorID)
1232 {
1233 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1234 if (!groupsManager)
1235 return;
1236
1237 SCR_AIGroup group = groupsManager.FindGroup(groupID);
1238 if (!group)
1239 return;
1240
1241 group.SetCustomName(name, authorID);
1242 }
1243
1244 //------------------------------------------------------------------------------------------------
1247 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1248 void RPC_AskSetNewGroupsAllowed(bool isAllowed)
1249 {
1250 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1251 if (!groupsManager || isAllowed == groupsManager.GetNewGroupsAllowed())
1252 return;
1253
1254 groupsManager.SetNewGroupsAllowed(isAllowed);
1255 }
1256
1257 //------------------------------------------------------------------------------------------------
1260 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1262 {
1263 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1264 if (!groupsManager || isAllowed == groupsManager.GetNewGroupsAllowed())
1265 return;
1266
1267 groupsManager.SetCanPlayersChangeAttributes(isAllowed);
1268 }
1269
1270 //------------------------------------------------------------------------------------------------
1274 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1275 void RPC_AskSetFrequency(int groupID, int frequency)
1276 {
1277 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1278 if (!groupsManager)
1279 return;
1280
1281 SCR_AIGroup group = groupsManager.FindGroup(groupID);
1282 if (!group)
1283 return;
1284
1285 if (frequency < 0 || group.GetRadioFrequency() == frequency)
1286 return;
1287
1288 SCR_Faction groupFaction = SCR_Faction.Cast(group.GetFaction());
1289 if (!groupFaction)
1290 return;
1291
1292 int formerFrequency = group.GetRadioFrequency();
1293 int foundGroupsWithFrequency = 0;
1294
1295 //no null check here because the array will always at least contain the group that was passed as parameter into this method
1296 array<SCR_AIGroup> existingGroups = groupsManager.GetPlayableGroupsByFaction(groupFaction);
1297
1298 foreach (SCR_AIGroup checkedGroup: existingGroups)
1299 {
1300 if (checkedGroup.GetRadioFrequency() == formerFrequency)
1301 foundGroupsWithFrequency++;
1302 }
1303
1304 //if there is only our group with this frequency or none, release it before changing our frequency
1305 if (foundGroupsWithFrequency <= 1)
1306 groupsManager.ReleaseFrequency(formerFrequency, groupFaction);
1307
1308 //if the new frequency is unclaimed, claime it so newly created groups do not get it by default
1309 if (!groupsManager.IsFrequencyClaimed(frequency, groupFaction))
1310 groupsManager.ClaimFrequency(frequency, groupFaction);
1311
1312 group.SetRadioFrequency(frequency);
1313 }
1314
1315 //------------------------------------------------------------------------------------------------
1320 void RequestSetGroupFlag(int groupID, int flagIndex, bool isFromImageset)
1321 {
1322 Rpc(RPC_AskSetGroupFlag, groupID, flagIndex, isFromImageset);
1323 }
1324
1325 //------------------------------------------------------------------------------------------------
1330 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1331 void RPC_AskSetGroupFlag(int groupID, int flagIndex, bool isFromImageset)
1332 {
1333 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1334 if (!groupsManager)
1335 return;
1336
1337 SCR_AIGroup group = groupsManager.FindGroup(groupID);
1338 if (!group)
1339 return;
1340
1341 group.SetGroupFlag(flagIndex, isFromImageset);
1342 }
1343
1344 //------------------------------------------------------------------------------------------------
1347 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1349 {
1350 SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
1351 if (!groupManager)
1352 return;
1353
1354 SCR_AIGroup group = SCR_AIGroup.Cast(Replication.FindItem(groupID));
1355 if (!group)
1356 return;
1357
1358 group.ClearRequesters();
1359 group.ClearDeniedRequester();
1360 }
1361
1362 //------------------------------------------------------------------------------------------------
1366 {
1367 Rpc(RPC_AskCreateSlaveGroup, rplCompID);
1368 }
1369
1370 //------------------------------------------------------------------------------------------------
1373 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1375 {
1376 SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
1377 if (!groupManager)
1378 return;
1379
1380 SCR_CommandingManagerComponent commandingManager = SCR_CommandingManagerComponent.GetInstance();
1381 if (!commandingManager)
1382 return;
1383
1384 IEntity groupEntity = GetGame().SpawnEntityPrefab(Resource.Load(commandingManager.GetGroupPrefab()));
1385 if (!groupEntity)
1386 return;
1387
1388 SCR_AIGroup group = SCR_AIGroup.Cast(groupEntity);
1389 if (!group)
1390 return;
1391
1392 //we dont delete slave groups when empty, we disable them
1393 group.SetDeleteWhenEmpty(false);
1394
1395 RplComponent slaveRplComp = RplComponent.Cast(group.FindComponent(RplComponent));
1396 if (!slaveRplComp)
1397 return;
1398
1399 groupManager.RequestSetGroupSlave(rplCompID, slaveRplComp.Id());
1400 }
1401
1402 //------------------------------------------------------------------------------------------------
1407 bool IsAICharacterInAnyGroup(SCR_ChimeraCharacter character, SCR_Faction faction)
1408 {
1409 //TODO: kuceramar: come up with better solution that doesnt include going through all groups
1410 //possible JIP problems due ot using SCR_CHimeraCharacter
1411 SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
1412 if (!groupManager)
1413 return false;
1414
1415 array<SCR_AIGroup> groups = groupManager.GetPlayableGroupsByFaction(faction);
1416
1417 foreach(SCR_AIGroup group : groups)
1418 {
1419 if (group.IsAIControlledCharacterMember(character))
1420 return true;
1421 }
1422
1423 return false;
1424 }
1425
1426 //------------------------------------------------------------------------------------------------
1430 void RequestAddAIAgent(SCR_ChimeraCharacter character, int playerID)
1431 {
1432 RplComponent rplComp = RplComponent.Cast(character.FindComponent(RplComponent));
1433 if (!rplComp)
1434 return;
1435
1436 Rpc(RPC_AskAddAIAgent, rplComp.Id(), playerID);
1437 }
1438
1439 //------------------------------------------------------------------------------------------------
1443 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1444 void RPC_AskAddAIAgent(RplId characterID, int playerID)
1445 {
1446 SCR_GroupsManagerComponent groupsManager;
1447 SCR_PlayerControllerGroupComponent playerGroupController;
1448 SCR_AIGroup group;
1449 if (!InitiateComponents(playerID, groupsManager, playerGroupController, group))
1450 return;
1451
1452 RplComponent rplComp = RplComponent.Cast(Replication.FindItem(characterID));
1453 if (!rplComp)
1454 return;
1455
1456 SCR_ChimeraCharacter character = SCR_ChimeraCharacter.Cast(rplComp.GetEntity());
1457 if (!character)
1458 return;
1459
1460 if (!group.IsPlayerLeader(playerID))
1461 return;
1462
1463 AddAIToSlaveGroup(character, group);
1464 }
1465
1466 //------------------------------------------------------------------------------------------------
1470 void AddAIToSlaveGroup(notnull IEntity controlledEntity, SCR_AIGroup group)
1471 {
1472 SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
1473 if (!groupManager)
1474 return;
1475
1476 SCR_AIGroup slaveGroup = group.GetSlave();
1477 if (!slaveGroup)
1478 return;
1479
1480 if (!slaveGroup.IsAIActivated())
1481 slaveGroup.ActivateAI();
1482
1483 slaveGroup.AddAgentFromControlledEntity(controlledEntity);
1484
1485 RplId groupCompID, characterCompID;
1486 RplComponent rplComp = RplComponent.Cast(slaveGroup.FindComponent(RplComponent));
1487 if (!rplComp)
1488 return;
1489
1490 groupCompID = rplComp.Id();
1491 rplComp = RplComponent.Cast(controlledEntity.FindComponent(RplComponent));
1492 characterCompID = rplComp.Id();
1493
1494 groupManager.AskAddAiMemberToGroup(groupCompID, characterCompID);
1495 }
1496
1497 //------------------------------------------------------------------------------------------------
1501 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1502 void RPC_AskRemoveAIAgent(RplId characterID, int playerID)
1503 {
1504 SCR_GroupsManagerComponent groupsManager;
1505 SCR_PlayerControllerGroupComponent playerGroupController;
1506 SCR_AIGroup group;
1507 if (!InitiateComponents(playerID, groupsManager, playerGroupController, group))
1508 return;
1509
1510 RplComponent rplComp = RplComponent.Cast(Replication.FindItem(characterID));
1511 if (!rplComp)
1512 return;
1513
1514 SCR_ChimeraCharacter character = SCR_ChimeraCharacter.Cast(rplComp.GetEntity());
1515 if (!character)
1516 return;
1517
1518 if (!group.IsPlayerLeader(playerID))
1519 return;
1520
1521 RemoveAiFromSlaveGroup(character, group);
1522 }
1523
1524 //------------------------------------------------------------------------------------------------
1528 void RemoveAiFromSlaveGroup(notnull IEntity controlledEntity, SCR_AIGroup group)
1529 {
1530 SCR_GroupsManagerComponent groupManager = SCR_GroupsManagerComponent.GetInstance();
1531 if (!groupManager)
1532 return;
1533
1534 SCR_AIGroup slaveGroup = group.GetSlave();
1535 if (!slaveGroup)
1536 return;
1537
1538 //deactivate the group since we are removing last AI member
1539 if (slaveGroup.GetAgentsCount() == 1)
1540 slaveGroup.Deactivate();
1541
1542 slaveGroup.RemoveAgentFromControlledEntity(controlledEntity);
1543
1544 RplId groupCompID, characterCompID;
1545 RplComponent rplComp = RplComponent.Cast(slaveGroup.FindComponent(RplComponent));
1546 groupCompID = rplComp.Id();
1547 rplComp = RplComponent.Cast(controlledEntity.FindComponent(RplComponent));
1548 if (!rplComp)
1549 return;
1550
1551 characterCompID = rplComp.Id();
1552
1553 groupManager.AskRemoveAiMemberFromGroup(groupCompID, characterCompID);
1554 }
1555
1556 //------------------------------------------------------------------------------------------------
1560 void RequestRemoveAgent(SCR_ChimeraCharacter character, int playerID)
1561 {
1562 RplComponent rplComp = RplComponent.Cast(character.FindComponent(RplComponent));
1563 if (!rplComp)
1564 return;
1565
1566 Rpc(RPC_AskRemoveAIAgent, rplComp.Id(), playerID);
1567 }
1568
1569 //------------------------------------------------------------------------------------------------
1570 void RequestGroupLeaderVote(int playerID)
1571 {
1572 PlayerController playerController = GetGame().GetPlayerManager().GetPlayerController(playerID);
1573 if (!playerController)
1574 return;
1575
1576 SCR_VoterComponent votingComponent = SCR_VoterComponent.Cast(playerController.FindComponent(SCR_VoterComponent));
1577 if (!votingComponent)
1578 return;
1579
1580 votingComponent.Vote(EVotingType.GROUP_LEADER, playerID);
1581 }
1582
1583 //------------------------------------------------------------------------------------------------
1584 void SetGroupLeader(int playerID)
1585 {
1586 Rpc(RpcDo_SetGroupLeader, playerID);
1587 }
1588
1589 //------------------------------------------------------------------------------------------------
1590 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1591 protected void RpcDo_SetGroupLeader(int playerID)
1592 {
1593 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1594 if (!groupsManager)
1595 return;
1596
1597 SCR_AIGroup playerGroup = groupsManager.GetPlayerGroup(playerID);
1598 if (!playerGroup)
1599 return;
1600
1601 if (playerGroup.GetLeaderID() == playerID)
1602 return;
1603
1604 playerGroup.SetGroupLeader(playerID);
1605 }
1606
1607 //------------------------------------------------------------------------------------------------
1608 void SetRallyPoint(notnull SCR_MilitaryBaseComponent base, bool force)
1609 {
1610 Rpc(RpcAsk_SetRallyPoint, GetPlayerID(), base.GetCallsign(), force);
1611 }
1612
1613 //------------------------------------------------------------------------------------------------
1614 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1615 protected void RpcAsk_SetRallyPoint(int playerID, int callsignId, bool force)
1616 {
1617 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1618 if (!groupsManager)
1619 return;
1620
1621 SCR_AIGroup playerGroup = groupsManager.GetPlayerGroup(playerID);
1622 if (!playerGroup)
1623 return;
1624
1626 if (!campaign)
1627 return;
1628
1629 SCR_CampaignMilitaryBaseManager baseManager = campaign.GetBaseManager();
1630 if (!baseManager)
1631 return;
1632
1633 SCR_MilitaryBaseComponent base = baseManager.FindBaseByCallsign(callsignId);
1634 if (!base)
1635 return;
1636
1637 playerGroup.SetRallyPoint(base, force);
1638 }
1639
1640 //------------------------------------------------------------------------------------------------
1642 {
1644 }
1645
1646 //------------------------------------------------------------------------------------------------
1647 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1648 protected void RpcAsk_RemoveRallyPoint(int playerID)
1649 {
1650 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1651 if (!groupsManager)
1652 return;
1653
1654 SCR_AIGroup playerGroup = groupsManager.GetPlayerGroup(playerID);
1655 if (!playerGroup)
1656 return;
1657
1658 playerGroup.RemoveRallyPoint();
1659 }
1660
1661 //------------------------------------------------------------------------------------------------
1663 {
1664 RplId rplIdTransportUnitComponent = Replication.FindItemId(transportUnit);
1665 if (!rplIdTransportUnitComponent.IsValid())
1666 return;
1667
1668 int baseCallsign = SCR_CampaignMilitaryBaseComponent.INVALID_BASE_CALLSIGN;
1669 if (base)
1670 baseCallsign = base.GetCallsign();
1671
1672 Rpc(RpcDo_AskSetTransportUnitSourceBase, baseCallsign, rplIdTransportUnitComponent);
1673 }
1674
1675 //------------------------------------------------------------------------------------------------
1676 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1677 protected void RpcDo_AskSetTransportUnitSourceBase(int baseCallsign, RplId rplIdTransportUnitComponent)
1678 {
1679 if (!rplIdTransportUnitComponent.IsValid())
1680 return;
1681
1682 SCR_TransportUnitComponent transportUnit = SCR_TransportUnitComponent.Cast(Replication.FindItem(rplIdTransportUnitComponent));
1683 if (!transportUnit)
1684 return;
1685
1686 SCR_CampaignMilitaryBaseComponent base = SCR_GameModeCampaign.GetInstance().GetBaseManager().FindBaseByCallsign(baseCallsign);
1687 transportUnit.SetSourceBase(base);
1688 }
1689
1690 //------------------------------------------------------------------------------------------------
1691 override void OnPostInit(IEntity owner)
1692 {
1693 super.OnPostInit(owner);
1694
1695 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1696 if (!groupsManager)
1697 return;
1698
1699#ifdef ENABLE_DIAG
1700 DiagMenu.RegisterMenu(SCR_DebugMenuID.DEBUGUI_GROUPS, "Game Groups", "GameCode");
1701 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_GROUPS_ENABLE_DIAG, "", "Enable groups diag", "Game Groups");
1702 ConnectToDiagSystem(owner);
1703#endif
1704 groupsManager.GetOnPlayableGroupRemoved().Insert(OnGroupDeleted);
1705 }
1706
1707 //------------------------------------------------------------------------------------------------
1708 override void OnDelete(IEntity owner)
1709 {
1710#ifdef ENABLE_DIAG
1711 DisconnectFromDiagSystem(owner);
1712#endif
1713
1714 super.OnDelete(owner);
1715 }
1716
1717 //------------------------------------------------------------------------------------------------
1720 {
1721 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1722 if (!groupsManager)
1723 return null;
1724
1725 return groupsManager.FindGroup(m_iGroupID);
1726 }
1727
1728 //------------------------------------------------------------------------------------------------
1731 {
1732 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1733 if (!groupsManager)
1734 return 0;
1735
1736 SCR_AIGroup group = groupsManager.FindGroup(m_iGroupID);
1737 if (!group)
1738 return 0;
1739
1740 return group.GetRadioFrequency();
1741 }
1742
1743 //------------------------------------------------------------------------------------------------
1744 override void EOnDiag(IEntity owner, float timeSlice)
1745 {
1746 if (!DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_GROUPS_ENABLE_DIAG))
1747 return;
1748
1749 DbgUI.Begin("Groups");
1750
1751 int playerID = SCR_PlayerController.GetLocalPlayerId();
1752 Faction faction;
1753 SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
1754 if (factionManager)
1755 faction = factionManager.GetPlayerFaction(playerID);
1756
1757 if (!faction)
1758 {
1759 DbgUI.Text("Groups do not support factionless players now!!");
1760 DbgUI.End();
1761 return;
1762 }
1763
1764 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1765
1766 DbgUI.Text("Your Faction:" + faction.GetFactionKey());
1767 DbgUI.Spacer(2);
1768
1769 DbgUI.Text("Playable groups of your faction:");
1770 ListGroupsFromFaction(faction);
1771 DbgUI.Spacer(6);
1772
1773 DbgUI.Text("Your group:");
1774 SCR_AIGroup group = groupsManager.GetPlayerGroup(playerID);
1775 if (group)
1776 {
1777 DbgUI.Text("." + group.ToString());
1778 Print(group.ToString(), LogLevel.NORMAL);
1779 }
1780 DbgUI.Spacer(2);
1781
1782 if (DbgUI.Button("Create and join group for my faction"))
1783 CreateAndJoinGroup(faction);
1784
1785 DbgUI.Spacer(2);
1786 DbgUI.End();
1787 }
1788
1789 //------------------------------------------------------------------------------------------------
1793 {
1794 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1795 array<SCR_AIGroup> groups = groupsManager.GetPlayableGroupsByFaction(faction);
1796 if (!groups)
1797 {
1798 DbgUI.Text("No groups for your faction!!");
1799 return;
1800 }
1801
1802 foreach(SCR_AIGroup group : groups)
1803 {
1804 DbgUI.Text(group.ToString());
1805 }
1806 }
1807
1808 //------------------------------------------------------------------------------------------------
1812 void CreateAndJoinGroup(Faction faction, bool usePredefinedData = false)
1813 {
1814 SCR_GroupsManagerComponent groupsManager = SCR_GroupsManagerComponent.GetInstance();
1815 if (!groupsManager)
1816 return;
1817
1818 SCR_AIGroup group = groupsManager.GetFirstNotFullForFaction(faction, null, true);
1819 if (group)
1820 {
1822 }
1823 else
1824 {
1825 if (!usePredefinedData)
1826 {
1827 RequestCreateGroup(); //requestCreateGroup automatically puts player to the newly created group, if faction can only create predefined groups will get rejected automatically
1828 return;
1829 }
1830
1831 SCR_Faction scrFaction = SCR_Faction.Cast(faction);
1832 if (!scrFaction)
1833 return;
1834
1835 if (scrFaction.GetCanCreateOnlyPredefinedGroups())
1836 {
1837 RequestCreateGroupWithData(scrFaction.GetDefaultGroupRoleForNewGroup(), false, string.Empty, string.Empty, true, true);
1838 return;
1839 }
1840
1842 }
1843 }
1844}
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition DebugMenuID.c:4
ENotification
EVotingType
Definition EVotingType.c:2
ArmaReforgerScripted GetGame()
Definition game.c:1398
bool IsPlayerLeader(int playerID)
int m_iGroupID
void RemoveRallyPoint()
Removes current group Rally Point.
void SetGroupLeader(int playerID)
Called on the server (authority).
int GetGroupID()
SCR_BaseGameMode GetGameMode()
void SCR_CommandingManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
enum SCR_ECompassType EntityEditorProps(category:"GameScripted/Gadgets", description:"Compass", color:"0 0 255 255")
Prefab data class for compass component.
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
SCR_EGroupRole
Group roles.
override int GetPlayerID()
void SetRallyPoint(notnull SCR_EntityLabelPointComponent labelComp)
void SCR_FactionManager(IEntitySource src, IEntity parent)
void SCR_GameModeCampaign(IEntitySource src, IEntity parent)
void SCR_GroupsManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
void RPC_AskInvitePlayer(int playerID)
void RPC_CancelJoinPrivateGroup(int playerID, int groupID)
void RequestSetCustomGroupName(int groupID, string name)
void RPC_ConfirmJoinPrivateGroup(int playerID, int groupID)
ScriptInvoker GetOnInviteAccepted()
int GetGroupInviteIdFromIndex(int index)
ref map< int, ref array< int > > m_mPlayerInvitesToGroups
void CreateAndJoinGroup(Faction faction, bool usePredefinedData=false)
int GetPlayerIdFromGroupInvite(int groupId)
void ResetGroupIDs_S()
Resets the Group ID and Selected Group ID of the player, currently only called after the player has s...
void RemoveGroupInviteId(int groupId)
void OnGroupDeleted(SCR_AIGroup group)
void RequestCreateSlaveGroup(RplId rplCompID)
bool CanPlayerRemoveGroup(int playerID, notnull SCR_AIGroup group)
void RPC_ChangePrivateGroup(int playerID, bool isPrivate)
void RequestCreateGroupWithData(SCR_EGroupRole groupRole, bool isPrivate, string name, string description, bool joinGroup=true, bool deleteIfNoPlayer=true)
void SetSelectedGroupID(int groupID)
void SetTransportUnitSourceBase(notnull SCR_TransportUnitComponent transportUnit, SCR_CampaignMilitaryBaseComponent base)
void RpcAsk_SetRallyPoint(int playerID, int callsignId, bool force)
void RequestRemovePlayer(int playerID)
void RPC_PlayerRequestToJoinPrivateGroup(int playerID, RplId groupID)
ref ScriptInvokerInt m_OnSetSelectedGroupID
ScriptInvokerInt GetOnSetSelectedGroupID()
void RPC_AskSetCustomName(int groupID, string name, int authorID)
SCR_AIGroup GetPlayersGroup()
void RPC_AskSetFrequency(int groupID, int frequency)
void ClearAllRequesters(RplId groupID)
void RPC_AskSetGroupFlag(int groupID, int flagIndex, bool isFromImageset)
void PlayerRequestToJoinPrivateGroup(int playerID, RplId groupID)
void RequestRemoveAgent(SCR_ChimeraCharacter character, int playerID)
void RPC_AskJoinGroup(int groupID)
ScriptInvoker GetOnGroupChanged()
ref map< int, int > m_mGroupIdInvites
bool CanInvitePlayer(int playerID)
void RPC_AskSetCanPlayersChangeAttributes(bool isAllowed)
void RequestPromoteLeader(int playerID)
void RequestSetGroupMaxMembers(int groupID, int maxMembers)
void RPC_AskKickPlayer(int playerID)
void RequestSetCanPlayersChangeAttributes(bool isAllowed)
void AcceptJoinPrivateGroup(int playerID, bool accept)
void RpcAsk_RemoveGroup(int groupID)
ref ScriptInvoker< int > m_OnInviteAccepted
void RPC_DoChangeGroupID(int groupID)
ref ScriptInvoker< int > m_OnGroupChanged
ScriptInvoker GetOnInviteReceived()
bool CanPlayerJoinGroup(int playerID, notnull SCR_AIGroup group)
string GetGroupInviteFromPlayerName()
void RequestSetCustomGroupDescription(int groupID, string desc)
void RPC_AskRemoveAIAgent(RplId characterID, int playerID)
void RpcAsk_RemoveRallyPoint(int playerID)
void InviteThisPlayer(int groupID, int fromPlayerID)
void RpcDo_SetGroupLeader(int playerID)
void RequestKickPlayer(int playerID)
void RPC_AskSetGroupMaxMembers(int groupID, int maxMembers)
void RequestJoinGroup(int groupID)
void RPC_DoInvitePlayer(int groupID, int fromPlayerID)
ScriptInvoker GetOnInviteCancelled()
void RequestPrivateGroupChange(int playerID, bool isPrivate)
void RequestSetCustomFrequency(int groupID, int frequency)
ref ScriptInvoker< int > m_OnInviteCancelled
void RPC_AskSetNewGroupsAllowed(bool isAllowed)
void OnGroupChangedDelayed(int groupId)
bool WasAlreadyInvited(int playerID)
void RpcAsk_CreateGroupWithData(SCR_EGroupRole groupRole, bool isPrivate, string name, string description, bool joinGroup, bool deleteIfNoPlayer)
void RequestSetGroupFlag(int groupID, int flagIndex, bool isFromImageset)
void RPC_AskAddAIAgent(RplId characterID, int playerID)
bool InitiateComponents(int playerID, out SCR_GroupsManagerComponent groupsManager, out SCR_PlayerControllerGroupComponent playerGroupController, out SCR_AIGroup group)
void RequestGroupLeaderVote(int playerID)
ref ScriptInvoker< int, int > m_OnInviteReceived
bool HasInviteFromGroup(int groupId)
string m_sGroupInviteFromPlayerName
void AddAIToSlaveGroup(notnull IEntity controlledEntity, SCR_AIGroup group)
void RPC_AskSetCustomDescription(int groupID, string desc, int authorID)
void ListGroupsFromFaction(Faction faction)
void RpcDo_AskSetTransportUnitSourceBase(int baseCallsign, RplId rplIdTransportUnitComponent)
void RPC_AskPromoteLeader(int playerID)
void RPC_AskCreateSlaveGroup(RplId rplCompID)
void RequestRemoveGroup(int groupID)
void RequestAddAIAgent(SCR_ChimeraCharacter character, int playerID)
void SetCustomNameAndDescription(SCR_AIGroup group, string name, string description, int playerId)
void RpcAsk_RemovePlayer(int playerID)
void RPC_ClearAllRequesters(RplId groupID)
void InvitePlayer(int playerID)
void RemoveAiFromSlaveGroup(notnull IEntity controlledEntity, SCR_AIGroup group)
void RequestSetNewGroupsAllowed(bool isAllowed)
bool IsAICharacterInAnyGroup(SCR_ChimeraCharacter character, SCR_Faction faction)
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
ScriptInvokerBase< ScriptInvokerIntMethod > ScriptInvokerInt
Definition Color.c:13
Definition DbgUI.c:66
Diagnostic and developer menu system.
Definition DiagMenu.c:18
void Rpc(func method, void p0=NULL, void p1=NULL, void p2=NULL, void p3=NULL, void p4=NULL, void p5=NULL, void p6=NULL, void p7=NULL)
Main replication API.
Definition Replication.c:14
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
Replication item identifier.
Definition RplId.c:14
void AddDeniedRequester(int playerID)
void RemovePlayer(int playerID)
Called on the server (authority).
int GetPlayerCount(bool checkMasterAndSlaves=false)
bool IsPlayerLeader(int playerID)
SCR_AIGroup GetSlave()
void RemoveRequester(int playerID)
SCR_EGroupRole GetGroupRole()
void SetCustomDescription(string desc, int authorID)
called on server only
void SetCustomName(string name, int authorID)
void SetCreatedByCommander(bool isCreatedByCommander)
void AddAgentFromControlledEntity(notnull IEntity controlledEntity)
void SetRadioFrequency(int frequency)
void ClearRequesters()
void SetPrivate(bool isPrivate)
Called on the server (authority).
void SetRallyPoint(notnull SCR_MilitaryBaseComponent base, bool force=false)
void SetGroupFlag(int flagIndex, bool isFromImageset)
called on server only
void SetMaxMembers(int maxMembers)
called on server only
int GetRadioFrequency()
void SetCanDeleteIfNoPlayer(bool deleteEmpty)
Sets if the group should be deleted when all players leave.
int GetMaxMembers()
static ScriptInvoker GetOnJoinPrivateGroupConfirm()
void RemoveAgentFromControlledEntity(notnull IEntity controlledEntity)
void AddRequester(int playerID)
void ClearDeniedRequester()
int GetGroupID()
void RemoveRallyPoint()
Removes current group Rally Point.
int GetLeaderID()
Faction GetFaction()
static bool DeLocalizeText(out string input)
void SetGroupLeader(int playerID)
Called on the server (authority).
void SetDeleteWhenEmpty(bool deleteWhenEmpty)
SCR_CampaignMilitaryBaseComponent FindBaseByCallsign(int callsign)
bool GetCanCreateOnlyPredefinedGroups()
void GetGroupRolePresetConfigs(notnull array< SCR_GroupRolePresetConfig > groupArray)
int GetCommanderId()
SCR_EGroupRole GetDefaultGroupRoleForNewGroup()
static int GetLocalPlayerId()
Returns either a valid ID of local player or 0.
void SetSourceBase(SCR_CampaignMilitaryBaseComponent sourceBase)
proto external GenericEntity GetOwner()
Get owner entity.
Definition Types.c:486
IEntity GetOwner()
Owner entity of the fuel tank.
override void EOnDiag(IEntity owner, float timeSlice)
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
proto void PrintFormat(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL, LogLevel level=LogLevel.NORMAL)
proto external PlayerController GetPlayerController()
EUserInteraction
Interaction type between two players.
void RplRpc(RplChannel channel, RplRcver rcver, RplCondition condition=RplCondition.None, string customConditionName="")
Definition EnNetwork.c:95
RplRcver
Definition RplRcver.c:59
RplChannel
Communication channel. Reliable is guaranteed to be delivered. Unreliable not.
Definition RplChannel.c:14
ScriptInvokerBase< func > ScriptInvoker
Definition tools.c:134