Add campfire smoke placeholder

This commit is contained in:
2026-05-17 19:00:42 -07:00
parent 0ac4bec3cf
commit c60b975294
5 changed files with 76 additions and 1 deletions
+3 -1
View File
@@ -590,7 +590,9 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
- [x] Add cooking placeholder if needed. Added replicated campfire cooking - [x] Add cooking placeholder if needed. Added replicated campfire cooking
placeholder state, a native cookability check, and progress ratio helpers so placeholder state, a native cookability check, and progress ratio helpers so
later recipe UI and food systems have a stable hook. later recipe UI and food systems have a stable hook.
- [ ] Add smoke/visual effect placeholder. - [x] Add smoke/visual effect placeholder. Added a native campfire smoke
particle component placeholder that activates and hides with replicated fire
state, leaving final visual assets assignable later.
- [x] Add replication. - [x] Add replication.
- [ ] Add persistence. - [ ] Add persistence.
- [x] Connect fire to body temperature. - [x] Connect fire to body temperature.
+5
View File
@@ -297,6 +297,11 @@ enabled, `AAgrarianCampfire` advances `CookingProgressSeconds` toward
`CookingSecondsRequired` on the server and exposes `CanCook` plus a normalized `CookingSecondsRequired` on the server and exposes `CanCook` plus a normalized
progress ratio for future recipe UI, food transformation, and interaction hooks. progress ratio for future recipe UI, food transformation, and interaction hooks.
Campfire visuals include an assetless `SmokeEffect` particle-system component
placeholder. It is attached above the fire, starts inactive, and follows the
same replicated lit-state visual update path as fire light intensity so final
smoke or ember assets can be assigned later without changing gameplay code.
The first real-weather adapter is `UAgrarianWeatherProviderSubsystem`. It uses The first real-weather adapter is `UAgrarianWeatherProviderSubsystem`. It uses
Open-Meteo forecast requests keyed by tile center latitude/longitude, parses the Open-Meteo forecast requests keyed by tile center latitude/longitude, parses the
current temperature, daily low/high, precipitation, wind, humidity, cloud cover, current temperature, daily low/high, precipitation, wind, humidity, cloud cover,
+44
View File
@@ -0,0 +1,44 @@
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
REQUIRED = {
ROOT / "Source" / "AgrarianGame" / "AgrarianCampfire.h": [
"class UParticleSystemComponent;",
"TObjectPtr<UParticleSystemComponent> SmokeEffect;",
],
ROOT / "Source" / "AgrarianGame" / "AgrarianCampfire.cpp": [
"#include \"Particles/ParticleSystemComponent.h\"",
"SmokeEffect = CreateDefaultSubobject<UParticleSystemComponent>(TEXT(\"SmokeEffect\"));",
"SmokeEffect->bAutoActivate = false;",
"SmokeEffect->SetVisibility(false);",
"SmokeEffect->SetVisibility(bLit);",
"SmokeEffect->ActivateSystem();",
"SmokeEffect->DeactivateSystem();",
],
ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md": [
"- [x] Add smoke/visual effect placeholder.",
],
ROOT / "Docs" / "TechnicalDesignDocument.md": [
"assetless `SmokeEffect` particle-system component",
],
}
def main():
missing = []
for path, snippets in REQUIRED.items():
text = path.read_text(encoding="utf-8")
for snippet in snippets:
if snippet not in text:
missing.append(f"{path.relative_to(ROOT)} missing {snippet!r}")
if missing:
raise SystemExit("Campfire smoke placeholder verification failed:\n" + "\n".join(missing))
print("PASS: campfire smoke placeholder is implemented and documented.")
if __name__ == "__main__":
main()
+20
View File
@@ -4,6 +4,7 @@
#include "AgrarianGameCharacter.h" #include "AgrarianGameCharacter.h"
#include "AgrarianInventoryComponent.h" #include "AgrarianInventoryComponent.h"
#include "AgrarianSurvivalComponent.h" #include "AgrarianSurvivalComponent.h"
#include "Particles/ParticleSystemComponent.h"
#include "Components/PointLightComponent.h" #include "Components/PointLightComponent.h"
#include "Components/StaticMeshComponent.h" #include "Components/StaticMeshComponent.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
@@ -22,6 +23,12 @@ AAgrarianCampfire::AAgrarianCampfire()
FireLight->SetIntensity(0.0f); FireLight->SetIntensity(0.0f);
FireLight->SetAttenuationRadius(WarmthRadius); FireLight->SetAttenuationRadius(WarmthRadius);
FireLight->SetLightColor(FLinearColor(1.0f, 0.45f, 0.18f)); FireLight->SetLightColor(FLinearColor(1.0f, 0.45f, 0.18f));
SmokeEffect = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("SmokeEffect"));
SmokeEffect->SetupAttachment(RootComponent);
SmokeEffect->bAutoActivate = false;
SmokeEffect->SetRelativeLocation(FVector(0.0f, 0.0f, 80.0f));
SmokeEffect->SetVisibility(false);
} }
void AAgrarianCampfire::Tick(float DeltaSeconds) void AAgrarianCampfire::Tick(float DeltaSeconds)
@@ -140,6 +147,19 @@ void AAgrarianCampfire::UpdateVisualState()
{ {
FireLight->SetIntensity(bLit ? 4200.0f : 0.0f); FireLight->SetIntensity(bLit ? 4200.0f : 0.0f);
} }
if (SmokeEffect)
{
SmokeEffect->SetVisibility(bLit);
if (bLit)
{
SmokeEffect->ActivateSystem();
}
else
{
SmokeEffect->DeactivateSystem();
}
}
} }
void AAgrarianCampfire::WarmNearbyCharacters(float DeltaSeconds) void AAgrarianCampfire::WarmNearbyCharacters(float DeltaSeconds)
+4
View File
@@ -8,6 +8,7 @@
#include "AgrarianCampfire.generated.h" #include "AgrarianCampfire.generated.h"
class UPointLightComponent; class UPointLightComponent;
class UParticleSystemComponent;
class UStaticMeshComponent; class UStaticMeshComponent;
UCLASS(Blueprintable) UCLASS(Blueprintable)
@@ -27,6 +28,9 @@ public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Fire") UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Fire")
TObjectPtr<UPointLightComponent> FireLight; TObjectPtr<UPointLightComponent> FireLight;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Fire|Effects")
TObjectPtr<UParticleSystemComponent> SmokeEffect;
UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing = OnRep_FireState, Category = "Agrarian|Fire") UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing = OnRep_FireState, Category = "Agrarian|Fire")
bool bLit = false; bool bLit = false;