Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_FactionCommanderHandlerComponent.c
Go to the documentation of this file.
1void OnFactionCommanderChangedDelegate(SCR_Faction faction, int commanderPlayerId);
3typedef ScriptInvokerBase<OnFactionCommanderChangedDelegate> OnFactionCommanderChangedInvoker;
4
6[ComponentEditorProps(category: "GameScripted/Commander", description: "Handles voting and AI decisions for the faction Commander role. Should be attached to gamemode entity.")]
10
11class SCR_FactionCommanderHandlerComponent : SCR_BaseGameModeComponent
12{
13 [Attribute("600", desc: "How often can a player volunteer for the Commander role (seconds).", params: "0 inf 1")]
14 protected int m_iVolunteerCooldown;
15
16 [Attribute("300", desc: "When the commander can be replaced after being elected (seconds).", params: "0 inf 1")]
17 protected int m_iReplaceCommanderCooldown;
18
19 [Attribute("1", desc: "When enabled, players need to gain a specific rank to be able to voluteer for the Commander role.")]
20 protected bool m_bCheckRank;
21
22 [Attribute(SCR_ECharacterRank.PRIVATE.ToString(), uiwidget: UIWidgets.ComboBox, desc: "If enabled, only players with this rank or higher can voluteer for the Commander role.", enumType:SCR_ECharacterRank)]
23 protected SCR_ECharacterRank m_eMinimumCommanderRank;
24
25 [Attribute(desc: "Array of AI faction commanders")]
26 protected ref array<ref SCR_BaseAIFactionCommander> m_aAIFactionCommanders;
27
28 protected ref OnFactionCommanderChangedInvoker m_OnFactionCommanderChanged;
29
30 protected ref map<int, WorldTimestamp> m_mVotingTimestamps = new map<int, WorldTimestamp>();
31
32 [RplProp(onRplName: "OnFactionCommanderChanged")]
33 protected ref array<int> m_aFactionCommanders = {}; // {factionIndex, commanderId, factionIndex, commanderId, ...}
34
35 protected RplComponent m_RplComponent;
36
38
39 //------------------------------------------------------------------------------------------------
40 static SCR_FactionCommanderHandlerComponent GetInstance()
41 {
42 BaseGameMode gameMode = GetGame().GetGameMode();
43
44 if (!gameMode)
45 return null;
46
47 return SCR_FactionCommanderHandlerComponent.Cast(gameMode.FindComponent(SCR_FactionCommanderHandlerComponent));
48 }
49
50 //------------------------------------------------------------------------------------------------
52 {
53 if (!m_OnFactionCommanderChanged)
54 m_OnFactionCommanderChanged = new OnFactionCommanderChangedInvoker();
55
56 return m_OnFactionCommanderChanged;
57 }
58
59 //------------------------------------------------------------------------------------------------
61 {
62 return m_iVolunteerCooldown;
63 }
64
65 //------------------------------------------------------------------------------------------------
67 {
68 return m_mReplaceCommanderCooldowns.Get(factionIndex);
69 }
70
71 //------------------------------------------------------------------------------------------------
72 bool CheckRank()
73 {
74 return m_bCheckRank;
75 }
76
77 //------------------------------------------------------------------------------------------------
78 SCR_ECharacterRank GetMinimumRank()
79 {
80 return m_eMinimumCommanderRank;
81 }
82
83 //------------------------------------------------------------------------------------------------
86 protected void SetGroupForOldCommander(int oldCommanderId)
87 {
88 if (oldCommanderId <= 0)
89 return;
90
92 if (!groupsManager)
93 return;
94
95 PlayerController playerController = GetGame().GetPlayerManager().GetPlayerController(oldCommanderId);
96 if (!playerController)
97 return;
98
99 SCR_Faction faction = SCR_Faction.Cast(SCR_FactionManager.SGetPlayerFaction(oldCommanderId));
100 if (!faction)
101 return;
102
103 SCR_PlayerControllerGroupComponent playerControllerGroupComponent = SCR_PlayerControllerGroupComponent.Cast(playerController.FindComponent(SCR_PlayerControllerGroupComponent));
104 if (!playerControllerGroupComponent)
105 return;
106
107 // return player back to previous non commander group
108 int previousGroupID = playerControllerGroupComponent.GetPreviousGroupID();
109 if (previousGroupID >= 0)
110 {
111 SCR_AIGroup previousGroup = groupsManager.FindGroup(previousGroupID);
112 if (previousGroup && !previousGroup.IsFull())
113 {
114 playerControllerGroupComponent.RequestJoinGroup(previousGroupID);
115 return;
116 }
117 }
118
119 SCR_AIGroup group = groupsManager.GetFirstNotFullForFaction(faction, null, true);
120 if (group)
121 {
122 playerControllerGroupComponent.RequestJoinGroup(group.GetGroupID());
123 return;
124 }
125
126 playerControllerGroupComponent.RequestCreateGroupWithData(SCR_EGroupRole.ASSAULT, false, "", "");
127
128 group = groupsManager.GetFirstNotFullForFaction(faction, null, true);
129 if (group)
130 {
131 playerControllerGroupComponent.RequestJoinGroup(group.GetGroupID());
132 }
133 }
134
135 //------------------------------------------------------------------------------------------------
138 protected void SetGroupForNewCommander(int newCommanderId)
139 {
141 if (!groupsManager)
142 return;
143
144 PlayerController playerController = GetGame().GetPlayerManager().GetPlayerController(newCommanderId);
145 if (!playerController)
146 return;
147
148 SCR_Faction faction = SCR_Faction.Cast(SCR_FactionManager.SGetPlayerFaction(newCommanderId));
149 if (!faction)
150 return;
151
152 array<SCR_AIGroup> playableGroups = groupsManager.GetPlayableGroupsByFaction(faction);
153 if (!playableGroups)
154 return;
155
156 SCR_AIGroup commanderGroup;
157 foreach (SCR_AIGroup aiGroup : playableGroups)
158 {
159 if (aiGroup && aiGroup.GetGroupRole() == SCR_EGroupRole.COMMANDER)
160 {
161 commanderGroup = aiGroup;
162 break;
163 }
164 }
165
166 if (!commanderGroup || commanderGroup.GetPlayerCount() > 0)
167 return;
168
169 SCR_PlayerControllerGroupComponent playerControllerGroupComponent = SCR_PlayerControllerGroupComponent.Cast(playerController.FindComponent(SCR_PlayerControllerGroupComponent));
170 if (!playerControllerGroupComponent)
171 return;
172
173 playerControllerGroupComponent.RequestJoinGroup(commanderGroup.GetGroupID());
174 }
175
176 //------------------------------------------------------------------------------------------------
177 void SetFactionCommander(notnull SCR_Faction faction, int commanderPlayerId)
178 {
179 if (faction.GetCommanderId() == commanderPlayerId)
180 return;
181
182 FactionManager fManager = GetGame().GetFactionManager();
183
184 if (!fManager)
185 return;
186
187 int factionIndex = fManager.GetFactionIndex(faction);
188 bool found;
189
190 foreach (int index, int element : m_aFactionCommanders)
191 {
192 if (index % 2 != 0)
193 continue;
194
195 if (element != factionIndex)
196 continue;
197
198 if (m_aFactionCommanders.IsIndexValid(index + 1))
199 m_aFactionCommanders.Set(index + 1, commanderPlayerId);
200 else
201 m_aFactionCommanders.Insert(commanderPlayerId);
202
203 found = true;
204 }
205
206 if (!found)
207 {
208 m_aFactionCommanders.Insert(factionIndex);
209 m_aFactionCommanders.Insert(commanderPlayerId);
210 }
211
212 ChimeraWorld world = GetGame().GetWorld();
213 if (!world)
214 return;
215
216 if (commanderPlayerId > 0)
217 {
218 WorldTimestamp timeStamp = world.GetServerTimestamp().PlusSeconds(m_iReplaceCommanderCooldown);
219 m_mReplaceCommanderCooldowns.Set(factionIndex, timeStamp);
220 Rpc(RpcDo_FactionCooldown, factionIndex, timeStamp);
221 }
222 else
223 {
224 m_mReplaceCommanderCooldowns.Remove(factionIndex);
225 Rpc(RpcDo_FactionCooldown, factionIndex, world.GetServerTimestamp());
226 }
227
229 Replication.BumpMe();
230 }
231
232 //------------------------------------------------------------------------------------------------
233 [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
234 protected void RpcDo_FactionCooldown(int factionIdx, WorldTimestamp timeStamp)
235 {
236 SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
237 if (!factionManager)
238 return;
239
240 SCR_Faction myFaction = SCR_Faction.Cast(factionManager.GetLocalPlayerFaction());
241 if (!myFaction)
242 return;
243
244 int myFactionIdx = factionManager.GetFactionIndex(myFaction);
245 if (myFactionIdx != factionIdx)
246 return;
247
248 PlayerController playerController = GetGame().GetPlayerController();
249 if (!playerController)
250 return;
251
252 SCR_FactionCommanderPlayerComponent comp = SCR_FactionCommanderPlayerComponent.Cast(playerController.FindComponent(SCR_FactionCommanderPlayerComponent));
253 if (!comp)
254 return;
255
256 comp.SetReplaceCommanderCooldownTimestamp(timeStamp);
257 }
258
259 //------------------------------------------------------------------------------------------------
261 {
262 FactionManager fManager = GetGame().GetFactionManager();
263
264 if (!fManager)
265 return;
266
267 foreach (int index, int element : m_aFactionCommanders)
268 {
269 if (index % 2 != 0)
270 continue;
271
272 if (!m_aFactionCommanders.IsIndexValid(index + 1))
273 return;
274
275 SCR_Faction faction = SCR_Faction.Cast(fManager.GetFactionByIndex(element));
276
277 if (!faction)
278 continue;
279
280 int commanderId = m_aFactionCommanders[index + 1];
281 int commanderIdOld = faction.GetCommanderId();
282
283 if (commanderIdOld == commanderId)
284 continue;
285
286 faction.SetCommanderId(commanderId);
287
288 // called on server
289 if (m_RplComponent && m_RplComponent.Role() == RplRole.Authority)
290 OnServerCommanderChanged(commanderId, commanderIdOld);
291
292 PlayerController pc = GetGame().GetPlayerController();
293
294 if (pc)
295 {
296 int playerId = pc.GetPlayerId();
297
298 if (commanderIdOld == playerId || commanderId == playerId)
299 {
300 SCR_FactionCommanderPlayerComponent component = SCR_FactionCommanderPlayerComponent.Cast(pc.FindComponent(SCR_FactionCommanderPlayerComponent));
301
302 if (component)
303 {
304 if (commanderIdOld == playerId)
305 component.OnCommanderRightsLost();
306 else
307 component.OnCommanderRightsGained();
308 }
309 }
310 }
311
312 if (m_OnFactionCommanderChanged)
313 m_OnFactionCommanderChanged.Invoke(faction, commanderId);
314 }
315 }
316
317 //------------------------------------------------------------------------------------------------
318 protected void OnServerCommanderChanged(int newCommanderId, int oldCommanderId)
319 {
320 SetGroupForOldCommander(oldCommanderId);
321 SetGroupForNewCommander(newCommanderId);
322 }
323
324 //------------------------------------------------------------------------------------------------
326 protected void OnPlayerFactionChanged(int playerId, SCR_PlayerFactionAffiliationComponent playerFactionAffiliationComponent, Faction faction)
327 {
328 FactionManager fManager = GetGame().GetFactionManager();
329
330 if (!fManager)
331 return;
332
333 int factionIndex = -1;
334
335 foreach (int index, int element : m_aFactionCommanders)
336 {
337 if (index % 2 == 0)
338 continue;
339
340 if (element != playerId)
341 continue;
342
343 factionIndex = m_aFactionCommanders[index - 1];
344 break;
345 }
346
347 if (factionIndex == -1)
348 return;
349
350 SCR_Faction commandedFaction = SCR_Faction.Cast(fManager.GetFactionByIndex(factionIndex));
351
352 if (!commandedFaction || commandedFaction == faction)
353 return;
354
355 SetFactionCommander(commandedFaction, 0);
356 SCR_NotificationsComponent.SendToFaction(commandedFaction, false, ENotification.VOTING_COMMANDER_WITHDRAW, playerId);
357 }
358
359 //------------------------------------------------------------------------------------------------
360 protected void OnVotingStart(EVotingType type, int value)
361 {
362 if (type != EVotingType.COMMANDER)
363 return;
364
365 ChimeraWorld world = GetGame().GetWorld();
366
367 if (!world)
368 return;
369
370 WorldTimestamp timestamp = world.GetServerTimestamp().PlusSeconds(m_iVolunteerCooldown);
371 m_mVotingTimestamps.Set(value, timestamp);
372 SetNextVolunteeringTimestamp(value, timestamp);
373 }
374
375 //------------------------------------------------------------------------------------------------
376 protected void OnVotingEnd(EVotingType type, int value, int winner)
377 {
378 if (type != EVotingType.COMMANDER && type != EVotingType.COMMANDER_WITHDRAW)
379 return;
380
381 PlayerController controller = GetGame().GetPlayerManager().GetPlayerController(winner);
382
383 if (!controller)
384 return;
385
386 SCR_PlayerXPHandlerComponent playerXPHandlerComponent = SCR_PlayerXPHandlerComponent.Cast(controller.FindComponent(SCR_PlayerXPHandlerComponent));
387
388 if (!playerXPHandlerComponent)
389 return;
390
391 playerXPHandlerComponent.UpdatePlayerRank(true);
392 }
393
394 //------------------------------------------------------------------------------------------------
395 protected void SetNextVolunteeringTimestamp(int playerId, WorldTimestamp timestamp)
396 {
397 PlayerController pc = GetGame().GetPlayerManager().GetPlayerController(playerId);
398
399 if (!pc)
400 return;
401
402 SCR_FactionCommanderPlayerComponent comp = SCR_FactionCommanderPlayerComponent.Cast(pc.FindComponent(SCR_FactionCommanderPlayerComponent));
403
404 if (!comp)
405 return;
406
407 comp.SetNextVolunteeringTimestamp(timestamp);
408 }
409
410 //------------------------------------------------------------------------------------------------
411 protected void DisableVolunteerCooldown(int playerId, KickCauseCode cause)
412 {
413 WorldTimestamp cooldownTimestamp = m_mVotingTimestamps.Get(playerId);
414 if (!cooldownTimestamp)
415 return;
416
417 string groupId, reasonId;
418 KickCauseGroup2 groupInt;
419 int reasonInt;
420
421 // Remove volunteer cooldown timer on stalls and timeouts
422 GetGame().GetFullKickReason(cause, groupInt, reasonInt, groupId, reasonId);
423 if (groupInt == KickCauseGroup2.PLAYER_MANAGER || (groupInt == RplKickCauseGroup.REPLICATION && reasonInt == RplError.SHUTDOWN))
424 return;
425
426 ChimeraWorld world = GetGame().GetWorld();
427 if (!world)
428 return;
429
430 WorldTimestamp now = world.GetServerTimestamp();
431 if (cooldownTimestamp.Greater(now))
432 {
433 m_mVotingTimestamps.Set(playerId, now);
434 SetNextVolunteeringTimestamp(playerId, now);
435 }
436
437 }
438
439 //------------------------------------------------------------------------------------------------
440 override void OnPlayerRegistered(int playerId)
441 {
442 super.OnPlayerRegistered(playerId);
443
444 if (m_mVotingTimestamps.Get(playerId))
445 SetNextVolunteeringTimestamp(playerId, m_mVotingTimestamps.Get(playerId));
446 }
447
448 //------------------------------------------------------------------------------------------------
450 override void OnPlayerDisconnected(int playerId, KickCauseCode cause, int timeout)
451 {
452 super.OnPlayerDisconnected(playerId, cause, timeout);
453
454 if (Replication.IsClient())
455 return;
456
457 DisableVolunteerCooldown(playerId, cause);
458
459 FactionManager fManager = GetGame().GetFactionManager();
460
461 if (!fManager)
462 return;
463
464 int factionIndex = -1;
465
466 foreach (int index, int element : m_aFactionCommanders)
467 {
468 if (index % 2 == 0)
469 continue;
470
471 if (element != playerId)
472 continue;
473
474 factionIndex = m_aFactionCommanders[index - 1];
475 break;
476 }
477
478 if (factionIndex == -1)
479 return;
480
481 SCR_Faction faction = SCR_Faction.Cast(fManager.GetFactionByIndex(factionIndex));
482
483 if (!faction)
484 return;
485
486 if (faction.GetCommanderId() != playerId)
487 return;
488
489 SetFactionCommander(faction, 0);
490 SCR_NotificationsComponent.SendToFaction(faction, false, ENotification.VOTING_COMMANDER_WITHDRAW, playerId);
491
492 int factionIdx = fManager.GetFactionIndex(faction);
493 m_mReplaceCommanderCooldowns.Remove(factionIdx);
494
495 }
496
497 //------------------------------------------------------------------------------------------------
498 override void OnGameModeStart()
499 {
500 if (!m_RplComponent || m_RplComponent.IsProxy())
501 return;
502
503 foreach (SCR_BaseAIFactionCommander commander : m_aAIFactionCommanders)
504 {
505 commander.Init(this);
506 }
507 }
508
509 //------------------------------------------------------------------------------------------------
510 override void OnGameEnd()
511 {
512 if (!m_RplComponent || m_RplComponent.IsProxy())
513 return;
514
515 foreach (SCR_BaseAIFactionCommander commander : m_aAIFactionCommanders)
516 {
517 commander.Deinit();
518 }
519 }
520
521 //------------------------------------------------------------------------------------------------
522 override void EOnInit(IEntity owner)
523 {
524 super.EOnInit(owner);
525
526 m_RplComponent = RplComponent.Cast(owner.FindComponent(RplComponent));
527
528 if (Replication.IsServer())
529 {
530 SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
531
532 if (factionManager)
533 factionManager.GetOnPlayerFactionChanged_S().Insert(OnPlayerFactionChanged);
534
535 SCR_VotingManagerComponent votingManager = SCR_VotingManagerComponent.GetInstance();
536
537 if (votingManager)
538 {
539 votingManager.GetOnVotingStart().Insert(OnVotingStart);
540 votingManager.GetOnVotingEnd().Insert(OnVotingEnd);
541 }
542 }
543 }
544
545 //------------------------------------------------------------------------------------------------
546 override void OnPostInit(IEntity owner)
547 {
548 super.OnPostInit(owner);
549
550 if (!GetGame().InPlayMode())
551 return;
552
553 SetEventMask(owner, EntityEvent.INIT);
554 }
555}
ENotification
EVotingType
Definition EVotingType.c:2
ArmaReforgerScripted GetGame()
Definition game.c:1398
RplKickCauseGroup
enum EAIGroupCombatMode ComponentEditorProps(category:"GameScripted/AI", description:"Component for utility AI system for groups")
override void OnGameEnd()
Called on all machines when the world ends.
SCR_BaseGameMode GetGameMode()
void SCR_BaseGameModeComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
override void OnGameModeStart()
SCR_CacheNoteComponentClass ScriptComponentClass RplProp()] protected ref array< string > m_aLines
RplComponent m_RplComponent
void OnServerCommanderChanged(int newCommanderId, int oldCommanderId)
EDamageType type
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
SCR_EGroupRole
Group roles.
void SetGroupForNewCommander(int newCommanderId)
WorldTimestamp GetFactionCooldown(int factionIndex)
ScriptInvokerBase< OnFactionCommanderChangedDelegate > OnFactionCommanderChangedInvoker
OnFactionCommanderChangedInvoker GetOnFactionCommanderChanged()
void SetFactionCommander(notnull SCR_Faction faction, int commanderPlayerId)
SCR_ECharacterRank GetMinimumRank()
void OnVotingStart(EVotingType type, int value)
ref map< int, WorldTimestamp > m_mReplaceCommanderCooldowns
void RpcDo_FactionCooldown(int factionIdx, WorldTimestamp timeStamp)
void SetNextVolunteeringTimestamp(int playerId, WorldTimestamp timestamp)
void SetGroupForOldCommander(int oldCommanderId)
func OnFactionCommanderChangedDelegate
void DisableVolunteerCooldown(int playerId, KickCauseCode cause)
void SCR_FactionManager(IEntitySource src, IEntity parent)
void SCR_GroupsManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
void OnPlayerFactionChanged(SCR_PlayerFactionAffiliationComponent component, Faction previous, Faction current)
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
override void OnVotingEnd(int value=DEFAULT_VALUE, int winner=DEFAULT_VALUE)
void SCR_VotingManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
proto external Managed FindComponent(typename typeName)
Main replication API.
Definition Replication.c:14
int GetPlayerCount(bool checkMasterAndSlaves=false)
int GetFactionIndex()
int GetGroupID()
bool IsFull()
Handles voting and AI decisions for the faction Commander role. Should be attached to gamemode entity...
void SetCommanderId(int playerId)
int GetCommanderId()
Definition Types.c:486
override void EOnInit(IEntity owner)
SCR_FieldOfViewSettings Attribute
EntityEvent
Various entity events.
Definition EntityEvent.c:14
override void OnPlayerRegistered(int playerId)
override void OnPlayerDisconnected(int playerId, KickCauseCode cause, int timeout)
KickCauseGroup2
Extends KickCauseGroup by adding game-specific groups.
RplRole
Role of replicated node (and all items in it) within the replication system.
Definition RplRole.c:14
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
RplError
Definition RplError.c:13