26 protected SCR_RespawnSystemComponent m_RespawnSystem;
31 protected ref array<ref Tuple3<SCR_PlayerController, UUID, UUID>> m_aStoredControlledEntityIds = {};
32 protected ref map<int, UUID> m_mPendingPosessions =
new map<int, UUID>();
35 protected static vector s_vPlayFromCameraPos;
36 protected static vector s_vPlayFromCameraYpr;
40 void OnInit(SCR_RespawnSystemComponent owner)
42 m_RespawnSystem = owner;
46 SetupPersistenceCollections(owner);
51 protected void SetupPersistenceCollections(SCR_RespawnSystemComponent owner)
53 m_PlayerCollection = m_Persistence.FindCollection(
"Player");
54 m_CharacterCollection = m_Persistence.FindCollection(
"Character");
58 void OnPlayerRegistered_S(
int playerId)
60 #ifdef _ENABLE_RESPAWN_LOGS
65 respawnComponent.GetOnRespawnRequestInvoker_S().Insert(OnPlayerSpawnRequest_S);
66 respawnComponent.GetOnRespawnResponseInvoker_S().Insert(OnPlayerSpawnResponse_S);
70 void OnPlayerAuditSuccess_S(
int playerId)
72 #ifdef _ENABLE_RESPAWN_LOGS
80 const SCR_PlayerController playerController = SCR_PlayerController.Cast(
GetGame().GetPlayerManager().
GetPlayerController(playerId));
81 const UUID identity = SCR_PlayerIdentityUtils.GetPlayerIdentityId(playerId);
82 m_Persistence.SetId(playerController, identity);
86 void OnPlayerDisconnected_S(
int playerId, KickCauseCode cause,
int timeout)
88 #ifdef _ENABLE_RESPAWN_LOGS
93 respawnComponent.GetOnRespawnRequestInvoker_S().Remove(OnPlayerSpawnRequest_S);
94 respawnComponent.GetOnRespawnResponseInvoker_S().Remove(OnPlayerSpawnResponse_S);
100 ForgetControlledEntityIds(playerController);
102 switch (m_eDisconnectPlayerControllerBehaviour)
107 m_Persistence.Save(playerController);
108 m_Persistence.StopTracking(playerController,
false);
114 m_Persistence.StopTracking(playerController);
121 void OnPlayerSpawnRequest_S(SCR_SpawnRequestComponent requestComponent)
123 #ifdef _ENABLE_RESPAWN_LOGS
129 void OnPlayerSpawnResponse_S(SCR_SpawnRequestComponent requestComponent,
SCR_ESpawnResult response)
131 #ifdef _ENABLE_RESPAWN_LOGS
132 PrintFormat(
"%1::OnPlayerSpawnResponse_S(playerId: %2, response: %3)",
137 OnPlayerSpawnFailed_S(requestComponent.GetPlayerId());
141 protected void OnPlayerSpawnFailed_S(
int playerId)
146 void OnPlayerSpawned_S(
int playerId,
IEntity entity)
148 #ifdef _ENABLE_RESPAWN_LOGS
156 #ifdef _ENABLE_RESPAWN_LOGS
157 PrintFormat(
"%1::OnPlayerEntityChanged_S(playerId: %2, previousEntity: %3, newEntity: %4)",
158 Type().
ToString(), playerId, previousEntity, newEntity);
162 OnPlayerEntityLost_S(playerId);
169 m_Persistence.ReloadConfig(previousEntity);
173 m_Persistence.ReloadConfig(newEntity);
175 ApplyPendingPosession(playerId);
179 void OnPlayerKilled_S(
int playerId,
IEntity playerEntity,
IEntity killerEntity, notnull Instigator killer)
181 #ifdef _ENABLE_RESPAWN_LOGS
182 PrintFormat(
"%1::OnPlayerKilled_S(playerId: %2, playerEntity: %3, killerEntity: %4, killerId: %5)",
183 Type().
ToString(), playerId, playerEntity, killerEntity, killer.GetInstigatorPlayerID());
186 OnPlayerEntityLost_S(playerId);
190 void OnPlayerDeleted_S(
int playerId,
bool isDisconnect)
192 #ifdef _ENABLE_RESPAWN_LOGS
193 PrintFormat(
"%1::OnPlayerDeleted_S(playerId: %2, isDisconnect:%3)",
Type().
ToString(), playerId, isDisconnect);
197 OnPlayerEntityLost_S(playerId);
201 void OnPlayerEntityCleanup_S(notnull
IEntity playerEntity)
203 #ifdef _ENABLE_RESPAWN_LOGS
210 switch (m_eDisconnectCharacterBehaviour)
215 m_Persistence.Save(playerEntity);
216 m_Persistence.StopTracking(playerEntity,
false);
222 m_Persistence.StopTracking(playerEntity);
233 protected void OnPlayerEntityLost_S(
int playerId)
235 #ifdef _ENABLE_RESPAWN_LOGS
245 protected void NotifyPlayerReadyForSpawn(
int playerId)
247 GetPlayerRespawnComponent_S(playerId).NotifyReadyForSpawn_S();
251 protected void ApplyPendingPosession(
int playerId)
253 UUID posessCharacterId;
254 if (!m_mPendingPosessions.Take(playerId, posessCharacterId))
257 Tuple2<int, bool> characterAvailableContext(playerId,
false);
258 PersistenceWhenAvailableTask linkControlledEntityTask(OnControlledCharacterAvailable, characterAvailableContext);
259 m_Persistence.WhenAvailable(posessCharacterId, linkControlledEntityTask);
263 protected void ExcuteInitialLoadOrSpawn_S(
int playerId)
265 #ifdef _ENABLE_RESPAWN_LOGS
271 GetGame().GetCallqueue().Call(RequestPlayerData_S, playerId);
273 RequestPlayerData_S(playerId);
278 protected void RequestPlayerData_S(
int playerId)
280 #ifdef _ENABLE_RESPAWN_LOGS
284 const PlayerController playerController =
GetGame().GetPlayerManager().GetPlayerController(playerId);
287 IEntity controlledEntity = playerController.GetControlledEntity();
288 if (controlledEntity)
290 s_vPlayFromCameraPos = controlledEntity.
GetOrigin();
295 if (!m_Persistence || !m_CharacterCollection)
310 PersistenceLoadRequest request();
311 request.Instances = {playerController};
314 m_Persistence.RequestLoad(request, callback);
318 protected void OnPlayerDataLoaded_S(
EPersistenceStatusCode statusCode, Managed result,
bool isLast, Managed context)
320 #ifdef _ENABLE_RESPAWN_LOGS
325 if (!playerController)
328 const int playerId = playerController.GetPlayerId();
329 if (ResolveReconnection(playerId))
331 ForgetControlledEntityIds(playerController);
338 DoInitialSpawn_S(playerId);
342 if (playerController != result)
345 UUID playerCharacterId, controlledCharacterId;
346 ConsumeControlledEntityIds(playerController, playerCharacterId, controlledCharacterId);
348 if (playerCharacterId.IsNull())
351 if (!controlledCharacterId.IsNull())
353 Tuple2<int, bool> characterAvailableContext(playerController.GetPlayerId(),
true);
354 PersistenceWhenAvailableTask linkControlledEntityTask(OnControlledCharacterAvailable, characterAvailableContext);
355 m_Persistence.WhenAvailable(controlledCharacterId, linkControlledEntityTask);
360 DoInitialSpawn_S(playerController.GetPlayerId());
365 if (!controlledCharacterId.IsNull() && controlledCharacterId != playerCharacterId)
366 m_mPendingPosessions.Set(playerId, controlledCharacterId);
368 PersistenceSpawnRequest request();
369 request.Collection = m_CharacterCollection;
370 request.Include = {playerCharacterId};
373 PersistenceResultCallback callback(OnPlayerCharacterLoaded_S, playerCharContext);
374 m_Persistence.RequestSpawn(request, callback);
378 protected void OnPlayerCharacterLoaded_S(
EPersistenceStatusCode statusCode, Managed result,
bool isLast, Managed context)
380 #ifdef _ENABLE_RESPAWN_LOGS
384 auto playerDataContext =
Tuple1<int>.Cast(context);
387 auto character = ChimeraCharacter.Cast(result);
396 character.GetWorldTransform(transform);
398 if (s_vPlayFromCameraPos != vector.Zero)
400 transform[3] = s_vPlayFromCameraPos;
402 s_vPlayFromCameraPos = vector.Zero;
405 if (s_vPlayFromCameraYpr != vector.Zero)
407 Math3D.AnglesToMatrix(s_vPlayFromCameraYpr, transform);
409 s_vPlayFromCameraYpr = vector.Zero;
413 character.Teleport(transform);
417 PlayerController playerController =
GetGame().GetPlayerManager().GetPlayerController(playerDataContext.param1);
418 IEntity controlledEntity = playerController.GetControlledEntity();
419 SCR_EntityHelper.DeleteEntityAndChildren(controlledEntity);
423 if (character && character.GetCharacterController().IsDead())
429 DoInitialSpawn_S(playerDataContext.param1);
433 auto data = SCR_PossessSpawnData.FromEntity(character);
434 GetPlayerRespawnComponent_S(playerDataContext.param1).RequestSpawn(
data);
438 protected void OnControlledCharacterAvailable(Managed instance, PersistenceDeferredDeserializeTask
task,
bool expired, Managed context)
440 auto characterAvailableContext = Tuple2<int, bool>.Cast(context);
442 auto entity =
IEntity.Cast(instance);
446 auto charController = CharacterControllerComponent.Cast(entity.
FindComponent(CharacterControllerComponent));
449 auto playerController = SCR_PlayerController.Cast(
GetGame().GetPlayerManager().
GetPlayerController(characterAvailableContext.param1));
450 playerController.SetPossessedEntity(entity);
456 if (characterAvailableContext.param2)
457 DoInitialSpawn_S(characterAvailableContext.param1);
461 void StoreControlledEntityIds(notnull SCR_PlayerController playerController, UUID playerCharacterId, UUID controlledCharacterId)
467 protected bool ConsumeControlledEntityIds(notnull SCR_PlayerController playerController, out UUID playerCharacterId, out UUID controlledCharacterId)
469 for (
int i = 0, count = m_aStoredControlledEntityIds.Count(); i < count; i++)
471 if (m_aStoredControlledEntityIds[i].
param1 == playerController)
473 playerCharacterId = m_aStoredControlledEntityIds[i].param2;
474 controlledCharacterId = m_aStoredControlledEntityIds[i].param3;
475 m_aStoredControlledEntityIds.Remove(i);
484 protected bool ForgetControlledEntityIds(notnull SCR_PlayerController playerController)
486 for (
int i = 0, count = m_aStoredControlledEntityIds.Count(); i < count; i++)
488 if (m_aStoredControlledEntityIds[i].
param1 == playerController)
490 m_aStoredControlledEntityIds.Remove(i);
499 protected void DoInitialSpawn_S(
int playerId)
501 #ifdef _ENABLE_RESPAWN_LOGS
515 protected void DoSpawn_S(
int playerId)
527 protected bool ResolveReconnection(
int playerId)
529 #ifdef _ENABLE_RESPAWN_LOGS
533 SCR_ReconnectComponent reconnect = SCR_ReconnectComponent.GetInstance();
539 protected bool HandlePlayFromCamera()
542 PlayerController playerController =
GetGame().GetPlayerController();
543 IEntity controlledEntity = playerController.GetControlledEntity();
544 if (controlledEntity)
546 auto respawnSystem = SCR_RespawnSystemComponent.GetInstance();
548 respawnSystem.DestroyLoadingPlaceholder();
570 SCR_PlayerFactionAffiliationComponent GetPlayerFactionComponent_S(
int playerId)
572 return SCR_PlayerFactionAffiliationComponent.Cast(
GetGame().GetPlayerManager().
GetPlayerController(playerId).FindComponent(SCR_PlayerFactionAffiliationComponent));
576 SCR_PlayerLoadoutComponent GetPlayerLoadoutComponent_S(
int playerId)
578 return SCR_PlayerLoadoutComponent.Cast(
GetGame().GetPlayerManager().
GetPlayerController(playerId).FindComponent(SCR_PlayerLoadoutComponent));