Add placed actor persistence foundation
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
// Copyright Pacificao. All Rights Reserved.
|
||||
|
||||
#include "AgrarianPersistenceSubsystem.h"
|
||||
#include "AgrarianPersistentActorComponent.h"
|
||||
#include "AgrarianSaveGame.h"
|
||||
#include "EngineUtils.h"
|
||||
#include "Engine/World.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
UAgrarianSaveGame* UAgrarianPersistenceSubsystem::CreateEmptySave() const
|
||||
@@ -31,3 +34,121 @@ bool UAgrarianPersistenceSubsystem::DoesSaveExist() const
|
||||
{
|
||||
return UGameplayStatics::DoesSaveGameExist(DefaultSlotName, UserIndex);
|
||||
}
|
||||
|
||||
void UAgrarianPersistenceSubsystem::RegisterWorldActorClass(FName ActorTypeId, TSubclassOf<AActor> ActorClass)
|
||||
{
|
||||
if (ActorTypeId != NAME_None && ActorClass)
|
||||
{
|
||||
WorldActorClassRegistry.Add(ActorTypeId, ActorClass);
|
||||
}
|
||||
}
|
||||
|
||||
int32 UAgrarianPersistenceSubsystem::CaptureWorldActors(UAgrarianSaveGame* SaveGame) const
|
||||
{
|
||||
if (!SaveGame)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
TArray<UAgrarianPersistentActorComponent*> PersistentComponents;
|
||||
FindPersistentComponents(PersistentComponents);
|
||||
|
||||
SaveGame->WorldActors.Reset();
|
||||
for (const UAgrarianPersistentActorComponent* Component : PersistentComponents)
|
||||
{
|
||||
if (Component && Component->IsSaveable())
|
||||
{
|
||||
SaveGame->WorldActors.Add(Component->CaptureSaveState());
|
||||
}
|
||||
}
|
||||
|
||||
return SaveGame->WorldActors.Num();
|
||||
}
|
||||
|
||||
int32 UAgrarianPersistenceSubsystem::RestoreWorldActors(const UAgrarianSaveGame* SaveGame, bool bClearExistingActors) const
|
||||
{
|
||||
UWorld* World = GetWorld();
|
||||
if (!World || !SaveGame)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bClearExistingActors)
|
||||
{
|
||||
TArray<UAgrarianPersistentActorComponent*> ExistingComponents;
|
||||
FindPersistentComponents(ExistingComponents);
|
||||
|
||||
for (UAgrarianPersistentActorComponent* Component : ExistingComponents)
|
||||
{
|
||||
if (AActor* Owner = Component ? Component->GetOwner() : nullptr)
|
||||
{
|
||||
Owner->Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32 RestoredCount = 0;
|
||||
for (const FAgrarianSavedWorldActor& SavedActor : SaveGame->WorldActors)
|
||||
{
|
||||
const TSubclassOf<AActor>* ActorClass = WorldActorClassRegistry.Find(SavedActor.ActorTypeId);
|
||||
if (!ActorClass || !(*ActorClass))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FActorSpawnParameters SpawnParams;
|
||||
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||
|
||||
AActor* SpawnedActor = World->SpawnActor<AActor>(*ActorClass, SavedActor.Transform, SpawnParams);
|
||||
if (!SpawnedActor)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (UAgrarianPersistentActorComponent* Component = SpawnedActor->FindComponentByClass<UAgrarianPersistentActorComponent>())
|
||||
{
|
||||
Component->ApplySaveState(SavedActor);
|
||||
}
|
||||
|
||||
RestoredCount++;
|
||||
}
|
||||
|
||||
return RestoredCount;
|
||||
}
|
||||
|
||||
bool UAgrarianPersistenceSubsystem::SaveCurrentWorld() const
|
||||
{
|
||||
UAgrarianSaveGame* SaveGame = LoadOrCreateSave();
|
||||
if (!SaveGame)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CaptureWorldActors(SaveGame);
|
||||
return WriteSave(SaveGame);
|
||||
}
|
||||
|
||||
void UAgrarianPersistenceSubsystem::FindPersistentComponents(TArray<UAgrarianPersistentActorComponent*>& OutComponents) const
|
||||
{
|
||||
OutComponents.Reset();
|
||||
|
||||
UWorld* World = GetWorld();
|
||||
if (!World)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (TActorIterator<AActor> ActorIt(World); ActorIt; ++ActorIt)
|
||||
{
|
||||
AActor* Actor = *ActorIt;
|
||||
if (!Actor || Actor->IsPendingKillPending())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (UAgrarianPersistentActorComponent* Component = Actor->FindComponentByClass<UAgrarianPersistentActorComponent>())
|
||||
{
|
||||
OutComponents.Add(Component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user