Complete early roadmap foundation and calendar helpers

This commit is contained in:
2026-05-15 21:41:37 -07:00
parent 6cd6729b7b
commit 8ee1f83b16
80 changed files with 3354 additions and 157 deletions
@@ -1,10 +1,14 @@
// Copyright Pacificao. All Rights Reserved.
#include "AgrarianPersistenceSubsystem.h"
#include "AgrarianGameCharacter.h"
#include "AgrarianInventoryComponent.h"
#include "AgrarianPersistentActorComponent.h"
#include "AgrarianSaveGame.h"
#include "AgrarianSurvivalComponent.h"
#include "EngineUtils.h"
#include "Engine/World.h"
#include "GameFramework/PlayerState.h"
#include "Kismet/GameplayStatics.h"
UAgrarianSaveGame* UAgrarianPersistenceSubsystem::CreateEmptySave() const
@@ -116,6 +120,87 @@ int32 UAgrarianPersistenceSubsystem::RestoreWorldActors(const UAgrarianSaveGame*
return RestoredCount;
}
int32 UAgrarianPersistenceSubsystem::CapturePlayers(UAgrarianSaveGame* SaveGame) const
{
if (!SaveGame)
{
return 0;
}
TArray<AAgrarianGameCharacter*> Players;
FindAgrarianPlayers(Players);
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);
}
return SaveGame->Players.Num();
}
int32 UAgrarianPersistenceSubsystem::RestorePlayers(const UAgrarianSaveGame* SaveGame) const
{
if (!SaveGame)
{
return 0;
}
TArray<AAgrarianGameCharacter*> Players;
FindAgrarianPlayers(Players);
int32 RestoredCount = 0;
for (AAgrarianGameCharacter* Character : Players)
{
UAgrarianSurvivalComponent* SurvivalComponent = Character ? Character->GetSurvivalComponent() : nullptr;
if (!Character || !SurvivalComponent)
{
continue;
}
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->Items = SavedPlayer->Inventory;
}
RestoredCount++;
}
return RestoredCount;
}
bool UAgrarianPersistenceSubsystem::SaveCurrentWorld() const
{
UAgrarianSaveGame* SaveGame = LoadOrCreateSave();
@@ -124,6 +209,7 @@ bool UAgrarianPersistenceSubsystem::SaveCurrentWorld() const
return false;
}
CapturePlayers(SaveGame);
CaptureWorldActors(SaveGame);
return WriteSave(SaveGame);
}
@@ -152,3 +238,42 @@ void UAgrarianPersistenceSubsystem::FindPersistentComponents(TArray<UAgrarianPer
}
}
}
void UAgrarianPersistenceSubsystem::FindAgrarianPlayers(TArray<AAgrarianGameCharacter*>& OutPlayers) const
{
OutPlayers.Reset();
UWorld* World = GetWorld();
if (!World)
{
return;
}
for (TActorIterator<AAgrarianGameCharacter> ActorIt(World); ActorIt; ++ActorIt)
{
AAgrarianGameCharacter* Character = *ActorIt;
if (Character && !Character->IsPendingKillPending())
{
OutPlayers.Add(Character);
}
}
}
FString UAgrarianPersistenceSubsystem::GetPlayerPersistenceId(const AAgrarianGameCharacter* Character) const
{
if (!Character)
{
return TEXT("UnknownPlayer");
}
if (const APlayerState* PlayerState = Character->GetPlayerState())
{
const FString PlayerName = PlayerState->GetPlayerName();
if (!PlayerName.IsEmpty())
{
return PlayerName;
}
}
return Character->GetName();
}