Add MVP reconnect snapshots
This commit is contained in:
@@ -1,11 +1,37 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "AgrarianGameGameMode.h"
|
||||
#include "AgrarianGameCharacter.h"
|
||||
#include "AgrarianDebugHUD.h"
|
||||
#include "AgrarianGameState.h"
|
||||
#include "AgrarianPersistenceSubsystem.h"
|
||||
|
||||
AAgrarianGameGameMode::AAgrarianGameGameMode()
|
||||
{
|
||||
GameStateClass = AAgrarianGameState::StaticClass();
|
||||
HUDClass = AAgrarianDebugHUD::StaticClass();
|
||||
}
|
||||
|
||||
void AAgrarianGameGameMode::RestartPlayer(AController* NewPlayer)
|
||||
{
|
||||
Super::RestartPlayer(NewPlayer);
|
||||
|
||||
AAgrarianGameCharacter* AgrarianCharacter = NewPlayer ? Cast<AAgrarianGameCharacter>(NewPlayer->GetPawn()) : nullptr;
|
||||
UAgrarianPersistenceSubsystem* Persistence = GetGameInstance() ? GetGameInstance()->GetSubsystem<UAgrarianPersistenceSubsystem>() : nullptr;
|
||||
if (AgrarianCharacter && Persistence && Persistence->RestorePlayerSnapshot(AgrarianCharacter))
|
||||
{
|
||||
UE_LOG(LogTemp, Log, TEXT("Agrarian restored reconnect snapshot for %s."), *AgrarianCharacter->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
void AAgrarianGameGameMode::Logout(AController* Exiting)
|
||||
{
|
||||
AAgrarianGameCharacter* AgrarianCharacter = Exiting ? Cast<AAgrarianGameCharacter>(Exiting->GetPawn()) : nullptr;
|
||||
UAgrarianPersistenceSubsystem* Persistence = GetGameInstance() ? GetGameInstance()->GetSubsystem<UAgrarianPersistenceSubsystem>() : nullptr;
|
||||
if (AgrarianCharacter && Persistence)
|
||||
{
|
||||
Persistence->SavePlayerSnapshot(AgrarianCharacter);
|
||||
}
|
||||
|
||||
Super::Logout(Exiting);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ public:
|
||||
|
||||
/** Constructor */
|
||||
AAgrarianGameGameMode();
|
||||
|
||||
virtual void RestartPlayer(AController* NewPlayer) override;
|
||||
virtual void Logout(AController* Exiting) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -173,24 +173,7 @@ int32 UAgrarianPersistenceSubsystem::CapturePlayers(UAgrarianSaveGame* SaveGame)
|
||||
SaveGame->Players.Reset();
|
||||
for (const AAgrarianGameCharacter* Character : Players)
|
||||
{
|
||||
const UAgrarianSurvivalComponent* SurvivalComponent = Character ? Character->GetSurvivalComponent() : nullptr;
|
||||
if (!Character || !SurvivalComponent)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FAgrarianSavedPlayer SavedPlayer;
|
||||
SavedPlayer.PlayerId = GetPlayerPersistenceId(Character);
|
||||
SavedPlayer.Transform = Character->GetActorTransform();
|
||||
SavedPlayer.Survival = SurvivalComponent->Survival;
|
||||
SavedPlayer.CareHistory = SurvivalComponent->CareHistory;
|
||||
|
||||
if (const UAgrarianInventoryComponent* InventoryComponent = Character->GetInventoryComponent())
|
||||
{
|
||||
SavedPlayer.Inventory = InventoryComponent->Items;
|
||||
}
|
||||
|
||||
SaveGame->Players.Add(SavedPlayer);
|
||||
CapturePlayerIntoSave(Character, SaveGame);
|
||||
}
|
||||
|
||||
return SaveGame->Players.Num();
|
||||
@@ -209,38 +192,32 @@ int32 UAgrarianPersistenceSubsystem::RestorePlayers(const UAgrarianSaveGame* Sav
|
||||
int32 RestoredCount = 0;
|
||||
for (AAgrarianGameCharacter* Character : Players)
|
||||
{
|
||||
UAgrarianSurvivalComponent* SurvivalComponent = Character ? Character->GetSurvivalComponent() : nullptr;
|
||||
if (!Character || !SurvivalComponent)
|
||||
if (RestorePlayerFromSave(Character, SaveGame))
|
||||
{
|
||||
continue;
|
||||
RestoredCount++;
|
||||
}
|
||||
|
||||
const FString PlayerId = GetPlayerPersistenceId(Character);
|
||||
const FAgrarianSavedPlayer* SavedPlayer = SaveGame->Players.FindByPredicate(
|
||||
[&PlayerId](const FAgrarianSavedPlayer& Candidate)
|
||||
{
|
||||
return Candidate.PlayerId == PlayerId;
|
||||
});
|
||||
|
||||
if (!SavedPlayer)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Character->SetActorTransform(SavedPlayer->Transform, false, nullptr, ETeleportType::TeleportPhysics);
|
||||
SurvivalComponent->ApplySavedState(SavedPlayer->Survival, SavedPlayer->CareHistory);
|
||||
|
||||
if (UAgrarianInventoryComponent* InventoryComponent = Character->GetInventoryComponent())
|
||||
{
|
||||
InventoryComponent->RestoreSavedItems(SavedPlayer->Inventory);
|
||||
}
|
||||
|
||||
RestoredCount++;
|
||||
}
|
||||
|
||||
return RestoredCount;
|
||||
}
|
||||
|
||||
bool UAgrarianPersistenceSubsystem::SavePlayerSnapshot(const AAgrarianGameCharacter* Character) const
|
||||
{
|
||||
UAgrarianSaveGame* SaveGame = LoadOrCreateSave();
|
||||
if (!SaveGame || !CapturePlayerIntoSave(Character, SaveGame))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return WriteSave(SaveGame);
|
||||
}
|
||||
|
||||
bool UAgrarianPersistenceSubsystem::RestorePlayerSnapshot(AAgrarianGameCharacter* Character) const
|
||||
{
|
||||
const UAgrarianSaveGame* SaveGame = LoadOrCreateSave();
|
||||
return SaveGame ? RestorePlayerFromSave(Character, SaveGame) : false;
|
||||
}
|
||||
|
||||
int32 UAgrarianPersistenceSubsystem::CaptureResourceNodes(UAgrarianSaveGame* SaveGame) const
|
||||
{
|
||||
if (!SaveGame)
|
||||
@@ -339,6 +316,64 @@ bool UAgrarianPersistenceSubsystem::LoadCurrentWorld(int32& RestoredPlayerCount,
|
||||
return bRestoredWorldState;
|
||||
}
|
||||
|
||||
bool UAgrarianPersistenceSubsystem::CapturePlayerIntoSave(const AAgrarianGameCharacter* Character, UAgrarianSaveGame* SaveGame) const
|
||||
{
|
||||
const UAgrarianSurvivalComponent* SurvivalComponent = Character ? Character->GetSurvivalComponent() : nullptr;
|
||||
if (!Character || !SurvivalComponent || !SaveGame)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FAgrarianSavedPlayer SavedPlayer;
|
||||
SavedPlayer.PlayerId = GetPlayerPersistenceId(Character);
|
||||
SavedPlayer.Transform = Character->GetActorTransform();
|
||||
SavedPlayer.Survival = SurvivalComponent->Survival;
|
||||
SavedPlayer.CareHistory = SurvivalComponent->CareHistory;
|
||||
|
||||
if (const UAgrarianInventoryComponent* InventoryComponent = Character->GetInventoryComponent())
|
||||
{
|
||||
SavedPlayer.Inventory = InventoryComponent->Items;
|
||||
}
|
||||
|
||||
SaveGame->Players.RemoveAll([&SavedPlayer](const FAgrarianSavedPlayer& Candidate)
|
||||
{
|
||||
return Candidate.PlayerId == SavedPlayer.PlayerId;
|
||||
});
|
||||
SaveGame->Players.Add(SavedPlayer);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UAgrarianPersistenceSubsystem::RestorePlayerFromSave(AAgrarianGameCharacter* Character, const UAgrarianSaveGame* SaveGame) const
|
||||
{
|
||||
UAgrarianSurvivalComponent* SurvivalComponent = Character ? Character->GetSurvivalComponent() : nullptr;
|
||||
if (!Character || !SurvivalComponent || !SaveGame)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const FString PlayerId = GetPlayerPersistenceId(Character);
|
||||
const FAgrarianSavedPlayer* SavedPlayer = SaveGame->Players.FindByPredicate(
|
||||
[&PlayerId](const FAgrarianSavedPlayer& Candidate)
|
||||
{
|
||||
return Candidate.PlayerId == PlayerId;
|
||||
});
|
||||
|
||||
if (!SavedPlayer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Character->SetActorTransform(SavedPlayer->Transform, false, nullptr, ETeleportType::TeleportPhysics);
|
||||
SurvivalComponent->ApplySavedState(SavedPlayer->Survival, SavedPlayer->CareHistory);
|
||||
|
||||
if (UAgrarianInventoryComponent* InventoryComponent = Character->GetInventoryComponent())
|
||||
{
|
||||
InventoryComponent->RestoreSavedItems(SavedPlayer->Inventory);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UAgrarianPersistenceSubsystem::FindPersistentComponents(TArray<UAgrarianPersistentActorComponent*>& OutComponents) const
|
||||
{
|
||||
OutComponents.Reset();
|
||||
|
||||
@@ -59,6 +59,12 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category = "Agrarian|Persistence")
|
||||
int32 RestorePlayers(const UAgrarianSaveGame* SaveGame) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Agrarian|Persistence")
|
||||
bool SavePlayerSnapshot(const AAgrarianGameCharacter* Character) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Agrarian|Persistence")
|
||||
bool RestorePlayerSnapshot(AAgrarianGameCharacter* Character) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Agrarian|Persistence")
|
||||
int32 CaptureResourceNodes(UAgrarianSaveGame* SaveGame) const;
|
||||
|
||||
@@ -72,6 +78,8 @@ public:
|
||||
bool LoadCurrentWorld(int32& RestoredPlayerCount, int32& RestoredWorldActorCount, bool bClearExistingActors = true) const;
|
||||
|
||||
protected:
|
||||
bool CapturePlayerIntoSave(const AAgrarianGameCharacter* Character, UAgrarianSaveGame* SaveGame) const;
|
||||
bool RestorePlayerFromSave(AAgrarianGameCharacter* Character, const UAgrarianSaveGame* SaveGame) const;
|
||||
void FindPersistentComponents(TArray<UAgrarianPersistentActorComponent*>& OutComponents) const;
|
||||
void FindAgrarianPlayers(TArray<AAgrarianGameCharacter*>& OutPlayers) const;
|
||||
void FindResourceNodes(TArray<AAgrarianResourceNode*>& OutResourceNodes) const;
|
||||
|
||||
Reference in New Issue
Block a user