Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_PlayerLoadoutComponent.c
Go to the documentation of this file.
1[ComponentEditorProps(category: "GameScripted/Respawn/PlayerController")]
5
6void PlayerLoadoutRequestDelegate(SCR_PlayerLoadoutComponent component, int loadoutIndex);
8typedef ScriptInvokerBase<PlayerLoadoutRequestDelegate> OnPlayerLoadoutRequestInvoker;
9
10void PlayerLoadoutResponseDelegate(SCR_PlayerLoadoutComponent component, int loadoutIndex, bool response);
12typedef ScriptInvokerBase<PlayerLoadoutResponseDelegate> OnPlayerLoadoutResponseInvoker;
13
17{
18 private PlayerController m_PlayerController;
19 private SCR_RespawnComponent m_RespawnComponent;
20 private RplComponent m_RplComponent;
21 private SCR_PlayerFactionAffiliationComponent m_FactionAffiliation;
22 private SCR_SpawnLockComponent m_Lock;
23
26
27 //------------------------------------------------------------------------------------------------
29 PlayerController GetPlayerController()
30 {
31 return m_PlayerController;
32 }
33
34 //------------------------------------------------------------------------------------------------
37 {
38 return GetPlayerController().GetPlayerId();
39 }
40
41 //------------------------------------------------------------------------------------------------
43 protected SCR_SpawnLockComponent GetLock()
44 {
45 return m_Lock;
46 }
47
48 //------------------------------------------------------------------------------------------------
51 {
52 return m_FactionAffiliation;
53 }
54
55 //------------------------------------------------------------------------------------------------
61
62 // ON CAN LOADOUT REQUEST
64
65 //------------------------------------------------------------------------------------------------
71
73
74 //------------------------------------------------------------------------------------------------
80
81 // ON CAN LOADOUT RESPONSE
83
84 //------------------------------------------------------------------------------------------------
90
92 //------------------------------------------------------------------------------------------------
98
99 // ON LOADOUT REQUEST
101
102 //------------------------------------------------------------------------------------------------
108
110 //------------------------------------------------------------------------------------------------
116
117 // ON LOADOUT RESPONSE
119
120 //------------------------------------------------------------------------------------------------
126
128
129 //------------------------------------------------------------------------------------------------
135
136 //------------------------------------------------------------------------------------------------
137 protected bool IsOwner()
138 {
139 return !m_RplComponent || m_RplComponent.IsOwner();
140 }
141
142 //------------------------------------------------------------------------------------------------
143 protected bool IsProxy()
144 {
145 return m_RplComponent && m_RplComponent.IsProxy();
146 }
147
148 //------------------------------------------------------------------------------------------------
149 protected override void OnPostInit(IEntity owner)
150 {
151 super.OnPostInit(owner);
152 m_PlayerController = PlayerController.Cast(owner);
153 if (!m_PlayerController)
154 Debug.Error(string.Format("%1 is not attached to a %2", Type().ToString(), PlayerController));
155
156 m_RespawnComponent = SCR_RespawnComponent.Cast(owner.FindComponent(SCR_RespawnComponent));
158 if (m_FactionAffiliation)
159 m_FactionAffiliation.GetOnFactionChanged().Insert(OnFactionChanged);
160
161 m_Lock = SCR_SpawnLockComponent.Cast(owner.FindComponent(SCR_SpawnLockComponent));
162 m_RplComponent = RplComponent.Cast(owner.FindComponent(RplComponent));
163
164 #ifdef ENABLE_DIAG
165 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_RESPAWN_PLAYER_LOADOUT_DIAG, "", "Player Loadouts", "GameMode");
166 GetGame().GetCallqueue().CallLater(OnDiag, 0, true);
167 #endif
168 }
169
170 //------------------------------------------------------------------------------------------------
171 protected override void OnDelete(IEntity owner)
172 {
173 if (m_FactionAffiliation)
174 m_FactionAffiliation.GetOnFactionChanged().Remove(OnFactionChanged);
175
176 super.OnDelete(owner);
177 }
178
179 //------------------------------------------------------------------------------------------------
180 protected void OnFactionChanged(FactionAffiliationComponent owner, Faction old, Faction current)
181 {
182 // If a faction changes, as the authority, always clear this player's
183 // loadout as there is no guarantee that new faction will
184 if (old != current && !m_RplComponent || !m_RplComponent.IsProxy())
185 {
186 SCR_LoadoutManager loadoutManager = GetGame().GetLoadoutManager();
187 if (!loadoutManager)
188 {
189 Print("Loadout manager is missing in the world!", LogLevel.ERROR);
190 return;
191 }
192
193 int previous = loadoutManager.GetLoadoutIndex(m_Loadout);
194
195 // Loadout is existant, see whether it is possible to be kept,
196 // or whether this loadout is no longer available after faction change
197 if (previous != -1)
198 {
199 // If it cannot be assigned (not part of faction, etc)
200 if (!CanAssignLoadout_S(previous))
201 {
202 // Directly clear loadout of target player,
203 // for previous loadout can no longer be deemed valid
204 AssignLoadout_S(-1);
206 }
207 }
208 }
209 }
210
211 //------------------------------------------------------------------------------------------------
218
219 //------------------------------------------------------------------------------------------------
226 {
227 #ifdef _ENABLE_RESPAWN_LOGS
228 PrintFormat("%1::RequestLoadout(loadout: %2)", Type().ToString(), loadout);
229 #endif
230
231 // Lock this
232 int loadoutIndex = GetGame().GetLoadoutManager().GetLoadoutIndex(loadout);
233 SCR_SpawnLockComponent lock = GetLock();
234 if (lock && !lock.TryLock(this, false))
235 {
236 Print("SCR_PlayerLoadoutComponent::RequestLoadout - Caught request on locked player!", LogLevel.DEBUG);
237 return false;
238 }
239
240 // Notify owner
241 if (IsOwner())
242 GetOnPlayerLoadoutRequestInvoker_O().Invoke(this, loadoutIndex);
243 // Notify authority
244 if (!IsProxy())
245 GetOnPlayerLoadoutRequestInvoker_S().Invoke(this, loadoutIndex);
246
247 Rpc(Rpc_RequestLoadout_S, loadoutIndex);
248 return true;
249 }
250
251 //------------------------------------------------------------------------------------------------
254 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
255 protected void Rpc_RequestLoadout_S(int loadoutIndex)
256 {
257 #ifdef _ENABLE_RESPAWN_LOGS
258 PrintFormat("%1::Rpc_RequestLoadout_S(loadoutIdx: %2)", Type().ToString(), loadoutIndex);
259 #endif
260
261 // Lock server
262 SCR_SpawnLockComponent lock = GetLock();
263 if (lock && !lock.TryLock(this, true))
264 {
265 Print("SCR_PlayerLoadoutComponent::Rpc_RequestLoadout_S - Caught request on locked player!", LogLevel.DEBUG);
266 return;
267 }
268
269 // Notify server
270 GetOnPlayerLoadoutRequestInvoker_S().Invoke(this, loadoutIndex);
271
272 // See whether loadout can be be set
273 if (CanAssignLoadout_S(loadoutIndex))
274 {
275 // Assign loadout
276 if (AssignLoadout_S(loadoutIndex))
277 {
278 // Success
279 SendRequestLoadoutResponse_S(loadoutIndex, true);
280 return;
281 }
282 }
283
284 // Failure
285 SendRequestLoadoutResponse_S(loadoutIndex, false);
286 }
287
288 //------------------------------------------------------------------------------------------------
289 protected bool AssignLoadout_S(int loadoutIndex)
290 {
291 // Assign new data
292 SCR_LoadoutManager loadoutManager = GetGame().GetLoadoutManager();
293 SCR_BasePlayerLoadout loadout = loadoutManager.GetLoadoutByIndex(loadoutIndex);
295
296 // Notify loadout manager
297 loadoutManager.UpdatePlayerLoadout_S(this);
298
299 // Notify game mode
301 gameMode.OnPlayerLoadoutSet_S(this, loadout);
302
303 return true;
304 }
305
306 //------------------------------------------------------------------------------------------------
311 protected void SendRequestLoadoutResponse_S(int loadoutIndex, bool response)
312 {
313 #ifdef _ENABLE_RESPAWN_LOGS
314 PrintFormat("%1::SendRequestLoadoutResponse_S(loadoutIdx: %2, response: %3)", Type().ToString(), loadoutIndex, response);
315 #endif
316
317 // Unlock server
318 SCR_SpawnLockComponent lock = GetLock();
319 if (lock)
320 {
321 lock.Unlock(this, true);
322 lock.Unlock(this, false);
323 }
324
325 // Notify this
326 GetOnPlayerLoadoutResponseInvoker_S().Invoke(this, loadoutIndex, response);
327
328 // Notify owner
329 Rpc(RequestLoadoutResponse_O, loadoutIndex, response);
330 }
331
332 //------------------------------------------------------------------------------------------------
337 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
338 protected void RequestLoadoutResponse_O(int loadoutIndex, bool response)
339 {
340 #ifdef _ENABLE_RESPAWN_LOGS
341 PrintFormat("%1::RequestLoadoutResponse_O(loadoutIdx: %2, response: %3)", Type().ToString(), loadoutIndex, response);
342 #endif
343
344 // Unlock this
345 SCR_SpawnLockComponent lock = GetLock();
346 if (lock)
347 {
348 lock.Unlock(this, false);
349 }
350
351 // Set loadout
352 SCR_LoadoutManager loadoutManager = GetGame().GetLoadoutManager();
353 m_Loadout = loadoutManager.GetLoadoutByIndex(loadoutIndex);
354
355 // Notify this
356 if (IsOwner())
357 GetOnPlayerLoadoutResponseInvoker_O().Invoke(this, loadoutIndex, response);
358 }
359
360 //------------------------------------------------------------------------------------------------
367 {
368 #ifdef _ENABLE_RESPAWN_LOGS
369 Print(string.Format("%1::CanRequestLoadout(loadout: %2)", Type().ToString(), loadout), LogLevel.NORMAL);
370 #endif
371
372 // Lock this
373 SCR_SpawnLockComponent lock = GetLock();
374 if (lock && !lock.TryLock(this, false))
375 {
376 Print("SCR_PlayerLoadoutComponent::CanRequestLoadout - Caught request on locked player!", LogLevel.DEBUG);
377 return false;
378 }
379
380 int loadoutIndex = GetGame().GetLoadoutManager().GetLoadoutIndex(loadout);
381 // Notify owner
382 if (IsOwner())
383 GetOnCanPlayerLoadoutRequestInvoker_O().Invoke(this, loadoutIndex);
384
385 // Notify authority
386 if (!IsProxy())
387 GetOnCanPlayerLoadoutRequestInvoker_S().Invoke(this, loadoutIndex);
388
389 Rpc(Rpc_CanRequestLoadout_S, loadoutIndex);
390 return true;
391 }
392
393 //------------------------------------------------------------------------------------------------
396 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
397 protected void Rpc_CanRequestLoadout_S(int loadoutIndex)
398 {
399 #ifdef _ENABLE_RESPAWN_LOGS
400 PrintFormat("%1::Rpc_CanRequestLoadout_S(loadoutIdx: %2)", Type().ToString(), loadoutIndex);
401 #endif
402
403 // Lock server
404 SCR_SpawnLockComponent lock = GetLock();
405 if (lock && !lock.TryLock(this, true))
406 {
407 Print("SCR_PlayerLoadoutComponent::Rpc_CanRequestLoadout_S - Caught request on locked player!", LogLevel.DEBUG);
408 return;
409 }
410
411 // Notify server
412 GetOnCanPlayerLoadoutRequestInvoker_S().Invoke(this, loadoutIndex);
413
414 // See whether game logic allows for assigning this loadout
415 if (!CanAssignLoadout_S(loadoutIndex))
416 {
417 SendCanRequestLoadoutResponse_S(loadoutIndex, false);
418 return;
419 }
420
421 SendCanRequestLoadoutResponse_S(loadoutIndex, true);
422 }
423
424 //------------------------------------------------------------------------------------------------
428 protected bool CanAssignLoadout_S(int loadoutIndex)
429 {
430 SCR_LoadoutManager loadoutManager = GetGame().GetLoadoutManager();
431 SCR_BasePlayerLoadout loadout = loadoutManager.GetLoadoutByIndex(loadoutIndex);
432
433 // If loadout is faction based, ensure loadout can be set
434 Faction playerFaction;
436 if (factionAffiliation)
437 playerFaction = factionAffiliation.GetAffiliatedFaction();
438
439 // Loadout is not of allowed faction, disallow mismatches
440 if (!IsLoadoutUseableByFaction(loadout, playerFaction))
441 return false;
442
443 return loadoutManager.CanAssignLoadout_S(this, loadout);
444 }
445
446 //------------------------------------------------------------------------------------------------
451 {
452 // Loadout can not belong to any faction
454 if (!factionLoadout)
455 return true;
456
457 FactionKey key;
458 if (faction)
459 key = faction.GetFactionKey();
460
461 return key == factionLoadout.GetFactionKey();
462 }
463
464 //------------------------------------------------------------------------------------------------
469 protected void SendCanRequestLoadoutResponse_S(int loadoutIndex, bool response)
470 {
471 #ifdef _ENABLE_RESPAWN_LOGS
472 PrintFormat("%1::SendCanRequestLoadoutResponse_S(loadoutIdx: %2, response: %3)", Type().ToString(), loadoutIndex, response);
473 #endif
474
475 // Unlock server
476 SCR_SpawnLockComponent lock = GetLock();
477 if (lock)
478 {
479 lock.Unlock(this, true);
480 lock.Unlock(this, false);
481 }
482
483 // Notify owner
484 GetOnCanPlayerLoadoutResponseInvoker_S().Invoke(this, loadoutIndex, response);
485
486 // Notify user
487 Rpc(CanRequestLoadoutResponse_O, loadoutIndex, response);
488 }
489
490 //------------------------------------------------------------------------------------------------
495 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
496 protected void CanRequestLoadoutResponse_O(int loadoutIndex, bool response)
497 {
498 #ifdef _ENABLE_RESPAWN_LOGS
499 PrintFormat("%1::CanRequestLoadoutResponse_O(loadoutIdx: %2, response: %3)", Type().ToString(), loadoutIndex, response);
500 #endif
501
502 // Unlock this
503 SCR_SpawnLockComponent lock = GetLock();
504 if (lock)
505 {
506 lock.Unlock(this, false);
507 }
508
509 // Notify owner
510 GetOnCanPlayerLoadoutResponseInvoker_O().Invoke(this, loadoutIndex, response);
511 }
512
513 //------------------------------------------------------------------------------------------------
514 void DoSetPlayerHasLoadout(bool loadoutValid, bool loadoutChanged, bool notification)
515 {
516 Rpc(DoSetPlayerHasLoadout_O, loadoutValid, loadoutChanged, notification);
517 }
518
519 //------------------------------------------------------------------------------------------------
520 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
521 protected void DoSetPlayerHasLoadout_O(bool loadoutValid, bool loadoutChanged, bool notification)
522 {
523 SCR_ArsenalManagerComponent arsenalManager;
524 if (!SCR_ArsenalManagerComponent.GetArsenalManager(arsenalManager))
525 return;
526
527 if (notification)
528 {
529 if (arsenalManager.GetLocalPlayerLoadoutAvailable() != loadoutValid || loadoutChanged)
530 {
531 const SCR_PlayerLoadoutData localData = arsenalManager.GetLocalPlayerLoadoutData();
532 if (localData && arsenalManager.GetCalculatedLoadoutSpawnSupplyCostMultiplier() > 0)
533 SCR_NotificationsComponent.SendLocal(ENotification.PLAYER_LOADOUT_SAVED_SUPPLY_COST, localData.LoadoutCost);
534 else
535 SCR_NotificationsComponent.SendLocal(ENotification.PLAYER_LOADOUT_SAVED);
536 }
537 else
538 SCR_NotificationsComponent.SendLocal(ENotification.PLAYER_LOADOUT_NOT_SAVED_UNCHANGED);
539 }
540
541 arsenalManager.SetLocalPlayerLoadoutAvailable(loadoutValid);
542 arsenalManager.GetOnLoadoutUpdated().Invoke(GetGame().GetPlayerController().GetPlayerId(), loadoutValid);
543 }
544
545 //------------------------------------------------------------------------------------------------
550
551 //------------------------------------------------------------------------------------------------
552 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
554 {
555 SCR_ArsenalManagerComponent arsenalManager;
556 if (!SCR_ArsenalManagerComponent.GetArsenalManager(arsenalManager))
557 return;
558
559 arsenalManager.m_LocalPlayerLoadoutData = loadoutData;
560 }
561
562 //------------------------------------------------------------------------------------------------
567
568 //------------------------------------------------------------------------------------------------
569 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
571 {
572 SCR_ArsenalManagerComponent arsenalManager;
573 if (!SCR_ArsenalManagerComponent.GetArsenalManager(arsenalManager))
574 return;
575
576 arsenalManager.SetLocalPlayerLoadoutAvailable(false);
577 arsenalManager.GetOnLoadoutUpdated().Invoke(GetGame().GetPlayerController().GetPlayerId(), false);
578 }
579
580 #ifdef ENABLE_DIAG
581 //------------------------------------------------------------------------------------------------
583 protected void OnDiag()
584 {
585 if (!DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_RESPAWN_PLAYER_LOADOUT_DIAG))
586 return;
587
588 int playerId = GetPlayerController().GetPlayerId();
589 DbgUI.Begin(string.Format("PlayerLoadout (id: %1)", playerId));
590 {
592 string loadoutName = "None";
593 if (loadout)
594 loadoutName = loadout.GetLoadoutName();
595
596 DbgUI.Text(string.Format("Current: %1 (%2)", loadout, loadout));
597
598 int wantedIdx;
599 DbgUI.InputInt("Wanted Loadout Idx", wantedIdx);
600
601 SCR_BasePlayerLoadout wantedLoadout = GetGame().GetLoadoutManager().GetLoadoutByIndex(wantedIdx);
602
603 if (wantedLoadout)
604 DbgUI.Text(string.Format("Wanted: %1 (%2)", wantedLoadout.GetLoadoutName(), wantedLoadout));
605 else
606 DbgUI.Text(string.Format("Wanted: None (Clear)"));
607
608 if (DbgUI.Button("CanRequest"))
609 CanRequestLoadout(wantedLoadout);
610 if (DbgUI.Button("Request"))
611 RequestLoadout(wantedLoadout);
612 }
613 DbgUI.End();
614 }
615 #endif
616}
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition DebugMenuID.c:4
ENotification
ArmaReforgerScripted GetGame()
Definition game.c:1398
enum EAIGroupCombatMode ComponentEditorProps(category:"GameScripted/AI", description:"Component for utility AI system for groups")
ref SCR_PlayerLoadoutData loadoutData
SCR_BaseGameMode GetGameMode()
void SCR_LoadoutManager(IEntitySource src, IEntity parent)
func PlayerLoadoutRequestDelegate
ScriptInvokerBase< PlayerLoadoutRequestDelegate > OnPlayerLoadoutRequestInvoker
ScriptInvokerBase< PlayerLoadoutResponseDelegate > OnPlayerLoadoutResponseInvoker
func PlayerLoadoutResponseDelegate
void SCR_RespawnComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
int Type
Definition DbgUI.c:66
Definition Debug.c:13
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)
proto external Managed FindComponent(typename typeName)
void OnPlayerLoadoutSet_S(SCR_PlayerLoadoutComponent loadoutComponent, SCR_BasePlayerLoadout loadout)
void Rpc_RequestLoadout_S(int loadoutIndex)
void SendRequestLoadoutResponse_S(int loadoutIndex, bool response)
bool IsLoadoutUseableByFaction(SCR_BasePlayerLoadout loadout, Faction faction)
bool RequestLoadout(SCR_BasePlayerLoadout loadout)
ref OnPlayerLoadoutRequestInvoker m_OnCanPlayerLoadoutRequestInvoker_S
OnPlayerLoadoutResponseInvoker GetOnCanPlayerLoadoutResponseInvoker_S()
ref OnPlayerLoadoutResponseInvoker m_OnPlayerLoadoutResponseInvoker_S
bool CanRequestLoadout(SCR_BasePlayerLoadout loadout)
void DoSetPlayerHasLoadout_O(bool loadoutValid, bool loadoutChanged, bool notification)
void DoSetPlayerHasLoadout(bool loadoutValid, bool loadoutChanged, bool notification)
override void OnDelete(IEntity owner)
override void OnPostInit(IEntity owner)
bool CanAssignLoadout_S(int loadoutIndex)
OnPlayerLoadoutRequestInvoker GetOnCanPlayerLoadoutRequestInvoker_S()
ref OnPlayerLoadoutRequestInvoker m_OnPlayerLoadoutRequestInvoker_S
OnPlayerLoadoutRequestInvoker GetOnPlayerLoadoutRequestInvoker_S()
OnPlayerLoadoutResponseInvoker GetOnCanPlayerLoadoutResponseInvoker_O()
ref OnPlayerLoadoutResponseInvoker m_OnCanPlayerLoadoutResponseInvoker_S
SCR_BasePlayerLoadout m_Loadout
Assigned loadout index. Relevant to authority only.
OnPlayerLoadoutRequestInvoker GetOnPlayerLoadoutRequestInvoker_O()
void SendCanRequestLoadoutResponse_S(int loadoutIndex, bool response)
void DoSendPlayerLoadout_O(SCR_PlayerLoadoutData loadoutData)
void RequestLoadoutResponse_O(int loadoutIndex, bool response)
void DoSendPlayerLoadout(SCR_PlayerLoadoutData loadoutData)
ref OnPlayerLoadoutResponseInvoker m_OnCanPlayerLoadoutResponseInvoker_O
SCR_PlayerFactionAffiliationComponent GetPlayerFactionAffiliationComponent()
void OnFactionChanged(FactionAffiliationComponent owner, Faction old, Faction current)
ref OnPlayerLoadoutResponseInvoker m_OnPlayerLoadoutResponseInvoker_O
OnPlayerLoadoutResponseInvoker GetOnPlayerLoadoutResponseInvoker_S()
ref OnPlayerLoadoutRequestInvoker m_OnCanPlayerLoadoutRequestInvoker_O
void CanRequestLoadoutResponse_O(int loadoutIndex, bool response)
ref OnPlayerLoadoutRequestInvoker m_OnPlayerLoadoutRequestInvoker_O
void Rpc_CanRequestLoadout_S(int loadoutIndex)
OnPlayerLoadoutRequestInvoker GetOnCanPlayerLoadoutRequestInvoker_O()
OnPlayerLoadoutResponseInvoker GetOnPlayerLoadoutResponseInvoker_O()
SCR_BasePlayerLoadout GetAssignedLoadout()
void OnDiag(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)
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
proto external string ToString()
Plain C++ pointer, no weak pointers, no memory management.