Add campfire persistence state

This commit is contained in:
2026-05-17 19:09:55 -07:00
parent c60b975294
commit 7291c4844b
8 changed files with 171 additions and 2 deletions
+54
View File
@@ -3,6 +3,7 @@
#include "AgrarianCampfire.h"
#include "AgrarianGameCharacter.h"
#include "AgrarianInventoryComponent.h"
#include "AgrarianPersistentActorComponent.h"
#include "AgrarianSurvivalComponent.h"
#include "Particles/ParticleSystemComponent.h"
#include "Components/PointLightComponent.h"
@@ -29,6 +30,9 @@ AAgrarianCampfire::AAgrarianCampfire()
SmokeEffect->bAutoActivate = false;
SmokeEffect->SetRelativeLocation(FVector(0.0f, 0.0f, 80.0f));
SmokeEffect->SetVisibility(false);
PersistentActorComponent = CreateDefaultSubobject<UAgrarianPersistentActorComponent>(TEXT("PersistentActorComponent"));
PersistentActorComponent->ActorTypeId = TEXT("campfire");
}
void AAgrarianCampfire::Tick(float DeltaSeconds)
@@ -86,6 +90,56 @@ void AAgrarianCampfire::Interact_Implementation(AAgrarianGameCharacter* Interact
}
}
void AAgrarianCampfire::CapturePersistentState_Implementation(UAgrarianPersistentActorComponent* PersistentComponent) const
{
if (!PersistentComponent)
{
return;
}
PersistentComponent->NumberState.Add(TEXT("lit"), bLit ? 1.0f : 0.0f);
PersistentComponent->NumberState.Add(TEXT("fuel_seconds"), FuelSeconds);
PersistentComponent->NumberState.Add(TEXT("cooking_placeholder_enabled"), bCookingPlaceholderEnabled ? 1.0f : 0.0f);
PersistentComponent->NumberState.Add(TEXT("cooking_seconds_required"), CookingSecondsRequired);
PersistentComponent->NumberState.Add(TEXT("cooking_progress_seconds"), CookingProgressSeconds);
}
void AAgrarianCampfire::ApplyPersistentState_Implementation(UAgrarianPersistentActorComponent* PersistentComponent)
{
if (!HasAuthority() || !PersistentComponent)
{
return;
}
const float* SavedFuelSeconds = PersistentComponent->NumberState.Find(TEXT("fuel_seconds"));
const float* SavedCookingEnabled = PersistentComponent->NumberState.Find(TEXT("cooking_placeholder_enabled"));
const float* SavedCookingRequired = PersistentComponent->NumberState.Find(TEXT("cooking_seconds_required"));
const float* SavedCookingProgress = PersistentComponent->NumberState.Find(TEXT("cooking_progress_seconds"));
const float* SavedLit = PersistentComponent->NumberState.Find(TEXT("lit"));
if (SavedFuelSeconds)
{
FuelSeconds = FMath::Max(0.0f, *SavedFuelSeconds);
}
if (SavedCookingEnabled)
{
bCookingPlaceholderEnabled = *SavedCookingEnabled > 0.5f;
}
if (SavedCookingRequired)
{
CookingSecondsRequired = FMath::Max(0.0f, *SavedCookingRequired);
}
if (SavedCookingProgress)
{
CookingProgressSeconds = FMath::Clamp(*SavedCookingProgress, 0.0f, CookingSecondsRequired);
}
SetLit(SavedLit && *SavedLit > 0.5f && FuelSeconds > 0.0f);
}
void AAgrarianCampfire::AddFuel(float Seconds)
{
if (HasAuthority())
+8 -1
View File
@@ -5,14 +5,16 @@
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "AgrarianInteractable.h"
#include "AgrarianPersistentStateProvider.h"
#include "AgrarianCampfire.generated.h"
class UPointLightComponent;
class UParticleSystemComponent;
class UAgrarianPersistentActorComponent;
class UStaticMeshComponent;
UCLASS(Blueprintable)
class AAgrarianCampfire : public AActor, public IAgrarianInteractable
class AAgrarianCampfire : public AActor, public IAgrarianInteractable, public IAgrarianPersistentStateProvider
{
GENERATED_BODY()
@@ -31,6 +33,9 @@ public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Fire|Effects")
TObjectPtr<UParticleSystemComponent> SmokeEffect;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Fire|Persistence")
TObjectPtr<UAgrarianPersistentActorComponent> PersistentActorComponent;
UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing = OnRep_FireState, Category = "Agrarian|Fire")
bool bLit = false;
@@ -55,6 +60,8 @@ public:
virtual FText GetInteractionText_Implementation(const AAgrarianGameCharacter* Interactor) const override;
virtual bool CanInteract_Implementation(const AAgrarianGameCharacter* Interactor) const override;
virtual void Interact_Implementation(AAgrarianGameCharacter* Interactor) override;
virtual void CapturePersistentState_Implementation(UAgrarianPersistentActorComponent* PersistentComponent) const override;
virtual void ApplyPersistentState_Implementation(UAgrarianPersistentActorComponent* PersistentComponent) override;
UFUNCTION(BlueprintCallable, Category = "Agrarian|Fire")
void AddFuel(float Seconds);
@@ -2,6 +2,7 @@
#include "AgrarianGamePlayerController.h"
#include "AgrarianCampfire.h"
#include "AgrarianCraftingComponent.h"
#include "AgrarianGameCharacter.h"
#include "AgrarianInventoryComponent.h"
@@ -296,6 +297,7 @@ void AAgrarianGamePlayerController::ServerAgrarianLoadWorld_Implementation()
}
Persistence->RegisterWorldActorClass(TEXT("primitive_shelter"), AAgrarianShelterActor::StaticClass());
Persistence->RegisterWorldActorClass(TEXT("campfire"), AAgrarianCampfire::StaticClass());
int32 RestoredPlayerCount = 0;
int32 RestoredActorCount = 0;
const bool bLoaded = Persistence->LoadCurrentWorld(RestoredPlayerCount, RestoredActorCount);
@@ -1,6 +1,7 @@
// Copyright Pacificao. All Rights Reserved.
#include "AgrarianPersistentActorComponent.h"
#include "AgrarianPersistentStateProvider.h"
UAgrarianPersistentActorComponent::UAgrarianPersistentActorComponent()
{
@@ -14,6 +15,13 @@ bool UAgrarianPersistentActorComponent::IsSaveable() const
FAgrarianSavedWorldActor UAgrarianPersistentActorComponent::CaptureSaveState() const
{
if (const AActor* Owner = GetOwner(); Owner && Owner->Implements<UAgrarianPersistentStateProvider>())
{
IAgrarianPersistentStateProvider::Execute_CapturePersistentState(
const_cast<AActor*>(Owner),
const_cast<UAgrarianPersistentActorComponent*>(this));
}
FAgrarianSavedWorldActor SavedActor;
SavedActor.ActorTypeId = ActorTypeId;
SavedActor.StringState = StringState;
@@ -41,4 +49,9 @@ void UAgrarianPersistentActorComponent::ApplySaveState(const FAgrarianSavedWorld
{
GetOwner()->SetActorTransform(SavedActor.Transform);
}
if (AActor* Owner = GetOwner(); Owner && Owner->Implements<UAgrarianPersistentStateProvider>())
{
IAgrarianPersistentStateProvider::Execute_ApplyPersistentState(Owner, this);
}
}
@@ -0,0 +1,27 @@
// Copyright Pacificao. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "AgrarianPersistentStateProvider.generated.h"
class UAgrarianPersistentActorComponent;
UINTERFACE(BlueprintType)
class UAgrarianPersistentStateProvider : public UInterface
{
GENERATED_BODY()
};
class IAgrarianPersistentStateProvider
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintNativeEvent, Category = "Agrarian|Persistence")
void CapturePersistentState(UAgrarianPersistentActorComponent* PersistentComponent) const;
UFUNCTION(BlueprintNativeEvent, Category = "Agrarian|Persistence")
void ApplyPersistentState(UAgrarianPersistentActorComponent* PersistentComponent);
};