Files
ProjectEleri/Source/ProjectEleri/System/Subsystem/ObjectPersistenceSubsystem.cpp

144 lines
4.3 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "ObjectPersistenceSubsystem.h"
#include "Interface/RemovableActorInterface.h"
#include "Kismet/GameplayStatics.h"
#include "../../Public/EleriSaveGame.h"
#include "../GameObjects/RemovableStaticMeshActor.h"
#include "../System/MainBlueprintFunctionLibrary.h"
int32 UObjectPersistenceSubsystem::ActorExistsInList(AActor* ActorToRemove)
{
if (!ActorToRemove) return -1;
for (int32 i = 0; i < PlacedActors.Num(); i++)
{
if (ActorToRemove->GetName() == PlacedActors[i].ActorName)
return i;
}
return -1;
}
void UObjectPersistenceSubsystem::RemoveActorFromLevel(AActor* ActorToRemove)
{
if (!ActorToRemove) return;
//Check if actor existed meaning we're placing it for the first time
int32 ActorIndex = ActorExistsInList(ActorToRemove);
if (ActorIndex != INDEX_NONE)
{
PlacedActors.RemoveAt(ActorIndex);
}
ActorToRemove->Destroy();
}
void UObjectPersistenceSubsystem::PlacebleActorMoved(AActor* ActorMoved, bool bNewVisiblity)
{
FPlaceableActorInfo* FoundActor = PlacedActors.FindByPredicate([ActorMoved](const FPlaceableActorInfo& ActorInfo) { return ActorInfo.ActorName == ActorMoved->GetName(); });
if (FoundActor)
{
if (bNewVisiblity)
{
FoundActor->Transform = ActorMoved->GetActorTransform();
FoundActor->bVisible = bNewVisiblity;
}
else
{
PlacedActors.Remove(*FoundActor);
ActorMoved->Destroy();
}
}
else
{
FPlaceableActorInfo NewPlaceableInfo;
NewPlaceableInfo.ClassReferencePath = ActorMoved->GetClass();
NewPlaceableInfo.ActorName = ActorMoved->GetName();
NewPlaceableInfo.Transform = ActorMoved->GetTransform();
NewPlaceableInfo.bVisible = bNewVisiblity;
PlacedActors.Add(NewPlaceableInfo);
}
}
void UObjectPersistenceSubsystem::GatherAllActorsInWorld()
{
TArray<AActor*> OutActors;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), ARemovableStaticMeshActor::StaticClass(), OutActors);
for (auto Actor : OutActors)
{
FPlaceableActorInfo NewPlaceableInfo;
NewPlaceableInfo.ClassReferencePath = Actor->GetClass();
NewPlaceableInfo.ActorName = Actor->GetName();
NewPlaceableInfo.Transform = Actor->GetTransform();
NewPlaceableInfo.bVisible = true;
PlacedActors.Add(NewPlaceableInfo);
}
size_t size = sizeof(FPlaceableActorInfo) * PlacedActors.Num();
UE_LOG(LogTemp, Verbose, TEXT("Collected actors finished"));
}
void UObjectPersistenceSubsystem::LoadSavedData(const TArray<FPlaceableActorInfo>& InPlacedActors)
{
UWorld* World = GetWorld();
if (!World) return;
TArray<AActor*> OutActors;
UGameplayStatics::GetAllActorsOfClass(World, ARemovableStaticMeshActor::StaticClass(), OutActors);
//Should never happen, if this ever happens quit programming and become like a hobo or something
if (OutActors.Num() == 0) return;
TArray<int32> IndexesOfFoundActors;
for (int32 i = 0; i < InPlacedActors.Num(); i++)
{
FString ActorName = InPlacedActors[i].ActorName;
AActor** FoundActor = OutActors.FindByPredicate([&ActorName](const AActor* Actor) { return ActorName == Actor->GetName(); });
if (FoundActor && *FoundActor)
{
if (!(*FoundActor)->GetActorTransform().Equals(InPlacedActors[i].Transform, 0.000001f))
{
AActor* ActorToModify = *FoundActor;
if (AStaticMeshActor* StaticMeshActor = Cast<AStaticMeshActor>(ActorToModify))
{
StaticMeshActor->SetMobility(EComponentMobility::Movable);
ActorToModify->SetActorTransform(InPlacedActors[i].Transform);
IndexesOfFoundActors.Add(i);
StaticMeshActor->SetMobility(EComponentMobility::Static);
}
}
}
else
{
UClass* ClassToLoad = InPlacedActors[i].ClassReferencePath.TryLoadClass<ARemovableStaticMeshActor>();
if (!ClassToLoad) continue;
FTransform PlaceableTransform = InPlacedActors[i].Transform;
if (ARemovableStaticMeshActor* SpawnedActor = Cast<ARemovableStaticMeshActor>(UMainBlueprintFunctionLibrary::SpawnPlaceable(GetWorld(), ClassToLoad, PlaceableTransform, FVector::OneVector)))
{
SpawnedActor->Place(true);
}
PlacedActors.Add(InPlacedActors[i]);
}
}
/*for (int32 i = 0; i < OutActors.Num(); i++)
{
bool ShouldDelete = true;
for (int32 j = 0; j < IndexesOfFoundActors.Num(); j++)
{
if (OutActors[i]->GetName() == OutActors[IndexesOfFoundActors[j]])
ShouldDelete = false;
}
if (ShouldDelete)
OutActors[i]->Destroy();
}*/
}