|
|
|
@@ -5,6 +5,7 @@
|
|
|
|
|
#include "AgrarianBuildingPlacementComponent.h"
|
|
|
|
|
#include "AgrarianCraftingComponent.h"
|
|
|
|
|
#include "AgrarianGameCharacter.h"
|
|
|
|
|
#include "AgrarianGameState.h"
|
|
|
|
|
#include "AgrarianInteractable.h"
|
|
|
|
|
#include "AgrarianInventoryComponent.h"
|
|
|
|
|
#include "AgrarianPersistentActorComponent.h"
|
|
|
|
@@ -628,6 +629,36 @@ FString UAgrarianEditorAutomationLibrary::RunPersistenceSubsystemSmokeTest(TSubc
|
|
|
|
|
Persistence->RegisterWorldActorClass(TEXT("primitive_shelter"), ShelterClass);
|
|
|
|
|
UGameplayStatics::DeleteGameInSlot(EffectiveSlotName, 0);
|
|
|
|
|
|
|
|
|
|
AAgrarianGameState* GameState = TestWorld->GetGameState<AAgrarianGameState>();
|
|
|
|
|
if (!GameState)
|
|
|
|
|
{
|
|
|
|
|
Persistence->DefaultSlotName = PreviousSlotName;
|
|
|
|
|
Persistence->UserIndex = PreviousUserIndex;
|
|
|
|
|
Persistence->WorldActorClassRegistry = PreviousRegistry;
|
|
|
|
|
return TEXT("FAIL: no Agrarian game state found for persistence test");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FAgrarianMappedWeatherInputs SavedWeatherInputs;
|
|
|
|
|
SavedWeatherInputs.TileId = TEXT("automation_weather_tile");
|
|
|
|
|
SavedWeatherInputs.Latitude = 37.5925f;
|
|
|
|
|
SavedWeatherInputs.Longitude = -122.4995f;
|
|
|
|
|
SavedWeatherInputs.TemperatureC = 9.5f;
|
|
|
|
|
SavedWeatherInputs.DailyLowTemperatureC = 7.0f;
|
|
|
|
|
SavedWeatherInputs.DailyHighTemperatureC = 13.0f;
|
|
|
|
|
SavedWeatherInputs.PrecipitationMm = 4.0f;
|
|
|
|
|
SavedWeatherInputs.WindSpeedKmh = 18.0f;
|
|
|
|
|
SavedWeatherInputs.CloudCoverPercent = 85.0f;
|
|
|
|
|
SavedWeatherInputs.RelativeHumidityPercent = 92.0f;
|
|
|
|
|
SavedWeatherInputs.PressureMslHpa = 1007.0f;
|
|
|
|
|
SavedWeatherInputs.VisibilityMeters = 6000.0f;
|
|
|
|
|
SavedWeatherInputs.ProviderWeatherCode = 61;
|
|
|
|
|
SavedWeatherInputs.MappedWeather = EAgrarianWeatherType::Rain;
|
|
|
|
|
SavedWeatherInputs.Provider = TEXT("automation-weather");
|
|
|
|
|
SavedWeatherInputs.ProviderTimestamp = TEXT("2026-05-16T08:00:00Z");
|
|
|
|
|
SavedWeatherInputs.bHasProviderData = true;
|
|
|
|
|
GameState->WorldHours = 14.25f;
|
|
|
|
|
GameState->ApplyMappedWeatherInputs(SavedWeatherInputs);
|
|
|
|
|
|
|
|
|
|
FActorSpawnParameters SpawnParams;
|
|
|
|
|
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
|
|
|
|
AActor* TestShelter = TestWorld->SpawnActor<AActor>(
|
|
|
|
@@ -686,7 +717,20 @@ FString UAgrarianEditorAutomationLibrary::RunPersistenceSubsystemSmokeTest(TSubc
|
|
|
|
|
return TEXT("FAIL: loaded save did not include persistent world actors");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const int32 RestoredActorCount = Persistence->RestoreWorldActors(LoadedSave, true);
|
|
|
|
|
GameState->WorldHours = 3.5f;
|
|
|
|
|
GameState->SetWeather(EAgrarianWeatherType::Storm);
|
|
|
|
|
|
|
|
|
|
int32 RestoredPlayerCount = 0;
|
|
|
|
|
int32 RestoredActorCount = 0;
|
|
|
|
|
if (!Persistence->LoadCurrentWorld(RestoredPlayerCount, RestoredActorCount, true))
|
|
|
|
|
{
|
|
|
|
|
UGameplayStatics::DeleteGameInSlot(EffectiveSlotName, 0);
|
|
|
|
|
Persistence->DefaultSlotName = PreviousSlotName;
|
|
|
|
|
Persistence->UserIndex = PreviousUserIndex;
|
|
|
|
|
Persistence->WorldActorClassRegistry = PreviousRegistry;
|
|
|
|
|
return TEXT("FAIL: LoadCurrentWorld failed to restore world state");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (RestoredActorCount != SavedActorCount)
|
|
|
|
|
{
|
|
|
|
|
UGameplayStatics::DeleteGameInSlot(EffectiveSlotName, 0);
|
|
|
|
@@ -696,6 +740,23 @@ FString UAgrarianEditorAutomationLibrary::RunPersistenceSubsystemSmokeTest(TSubc
|
|
|
|
|
return FString::Printf(TEXT("FAIL: restored actor count mismatch, saved=%d restored=%d"), SavedActorCount, RestoredActorCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const FAgrarianWeatherDebugSnapshot RestoredWeather = GameState->GetWeatherDebugSnapshot();
|
|
|
|
|
const bool bWeatherRestored =
|
|
|
|
|
FMath::IsNearlyEqual(GameState->WorldHours, 14.25f, 0.01f) &&
|
|
|
|
|
GameState->Weather == EAgrarianWeatherType::Rain &&
|
|
|
|
|
RestoredWeather.TileId == SavedWeatherInputs.TileId &&
|
|
|
|
|
RestoredWeather.Provider == SavedWeatherInputs.Provider &&
|
|
|
|
|
RestoredWeather.ProviderTimestamp == SavedWeatherInputs.ProviderTimestamp &&
|
|
|
|
|
RestoredWeather.AppliedWeather == EAgrarianWeatherType::Rain;
|
|
|
|
|
if (!bWeatherRestored)
|
|
|
|
|
{
|
|
|
|
|
UGameplayStatics::DeleteGameInSlot(EffectiveSlotName, 0);
|
|
|
|
|
Persistence->DefaultSlotName = PreviousSlotName;
|
|
|
|
|
Persistence->UserIndex = PreviousUserIndex;
|
|
|
|
|
Persistence->WorldActorClassRegistry = PreviousRegistry;
|
|
|
|
|
return TEXT("FAIL: weather state did not survive save/load");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32 PersistentActorCountAfterRestore = 0;
|
|
|
|
|
for (TActorIterator<AActor> ActorIt(TestWorld); ActorIt; ++ActorIt)
|
|
|
|
|
{
|
|
|
|
@@ -713,9 +774,12 @@ FString UAgrarianEditorAutomationLibrary::RunPersistenceSubsystemSmokeTest(TSubc
|
|
|
|
|
Persistence->WorldActorClassRegistry = PreviousRegistry;
|
|
|
|
|
|
|
|
|
|
return FString::Printf(
|
|
|
|
|
TEXT("PASS: live persistence subsystem saved %d actor(s), restored %d actor(s), world now has %d persistent actor(s)"),
|
|
|
|
|
TEXT("PASS: live persistence subsystem saved %d actor(s), restored %d actor(s), restored %d player(s), restored weather %s from %s, world now has %d persistent actor(s)"),
|
|
|
|
|
SavedActorCount,
|
|
|
|
|
RestoredActorCount,
|
|
|
|
|
RestoredPlayerCount,
|
|
|
|
|
*UEnum::GetValueAsString(GameState->Weather),
|
|
|
|
|
*RestoredWeather.Provider,
|
|
|
|
|
PersistentActorCountAfterRestore);
|
|
|
|
|
#else
|
|
|
|
|
return TEXT("FAIL: editor automation is only available in editor builds");
|
|
|
|
|