Add MVP reconnect snapshots

This commit is contained in:
2026-05-18 15:23:01 -07:00
parent 3b772da73c
commit 0b9a8b7b30
7 changed files with 208 additions and 49 deletions
@@ -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();