Connect shelter to weather protection

This commit is contained in:
2026-05-16 01:12:41 -07:00
parent 8625583faa
commit 06508061da
6 changed files with 115 additions and 3 deletions
+2
View File
@@ -102,6 +102,7 @@ void AAgrarianDebugHUD::DrawCriticalStats(const UAgrarianSurvivalComponent* Surv
DrawScaledLine(FString::Printf(TEXT("Food %3.0f"), Survival.Hunger), X, Y, CriticalStatsTextScale, StatusColor(Survival.Hunger));
DrawScaledLine(FString::Printf(TEXT("Water %3.0f"), Survival.Thirst), X, Y, CriticalStatsTextScale, StatusColor(Survival.Thirst));
DrawScaledLine(FString::Printf(TEXT("Temp %4.1f C"), Survival.BodyTemperature), X, Y, CriticalStatsTextScale, Survival.BodyTemperature < 35.0f ? CriticalColor : StableColor);
DrawScaledLine(FString::Printf(TEXT("Shelter %3.0f%%"), SurvivalComponent->CurrentWeatherProtection * 100.0f), X, Y, CriticalStatsTextScale, SurvivalComponent->CurrentWeatherProtection > 0.0f ? StableColor : WarningColor);
DrawScaledLine(FString::Printf(TEXT("Exhaust %3.0f"), Survival.Exhaustion), X, Y, CriticalStatsTextScale, StatusColor(Survival.Exhaustion, true));
DrawScaledLine(FString::Printf(TEXT("Injury %3.0f"), Survival.InjurySeverity), X, Y, CriticalStatsTextScale, StatusColor(Survival.InjurySeverity, true));
DrawScaledLine(FString::Printf(TEXT("Sickness %3.0f"), Survival.SicknessSeverity), X, Y, CriticalStatsTextScale, StatusColor(Survival.SicknessSeverity, true));
@@ -171,6 +172,7 @@ void AAgrarianDebugHUD::DrawSurvival(const UAgrarianSurvivalComponent* SurvivalC
DrawLine(FString::Printf(TEXT("Hunger: %.0f"), Survival.Hunger), X, Y);
DrawLine(FString::Printf(TEXT("Thirst: %.0f"), Survival.Thirst), X, Y);
DrawLine(FString::Printf(TEXT("Temp: %.1f C"), Survival.BodyTemperature), X, Y);
DrawLine(FString::Printf(TEXT("Shelter: %.0f%%"), SurvivalComponent->CurrentWeatherProtection * 100.0f), X, Y);
DrawLine(FString::Printf(TEXT("Injury: %.0f"), Survival.InjurySeverity), X, Y);
DrawLine(FString::Printf(TEXT("Sick: %.0f"), Survival.SicknessSeverity), X, Y);
const FAgrarianCareHistorySnapshot& Care = SurvivalComponent->CareHistory;
@@ -2,6 +2,8 @@
#include "AgrarianSurvivalComponent.h"
#include "AgrarianGameState.h"
#include "AgrarianShelterActor.h"
#include "Components/BoxComponent.h"
#include "Engine/World.h"
#include "Net/UnrealNetwork.h"
@@ -32,6 +34,8 @@ void UAgrarianSurvivalComponent::TickComponent(float DeltaTime, ELevelTick TickT
Survival.Hunger -= HungerDecayPerMinute * Minutes;
Survival.Thirst -= ThirstDecayPerMinute * Minutes;
Survival.Stamina += StaminaRecoveryPerSecond * DeltaTime;
CurrentWeatherProtection = CalculateCurrentWeatherProtection();
CareHistory.ShelterQuality = FMath::FInterpTo(CareHistory.ShelterQuality, CurrentWeatherProtection, DeltaTime, 0.02f);
if (Survival.Stamina <= LowStaminaExhaustionThreshold)
{
@@ -57,7 +61,8 @@ void UAgrarianSurvivalComponent::TickComponent(float DeltaTime, ELevelTick TickT
{
if (const AAgrarianGameState* AgrarianGameState = World->GetGameState<AAgrarianGameState>())
{
const float ExposureDelta = (AgrarianGameState->AmbientTemperatureC - 18.0f) * 0.002f * DeltaTime;
const float ExposureProtectionMultiplier = 1.0f - FMath::Clamp(CurrentWeatherProtection, 0.0f, 1.0f);
const float ExposureDelta = (AgrarianGameState->AmbientTemperatureC - 18.0f) * 0.002f * DeltaTime * ExposureProtectionMultiplier;
Survival.BodyTemperature += FMath::Clamp(ExposureDelta, -0.035f, 0.02f);
}
}
@@ -74,7 +79,7 @@ void UAgrarianSurvivalComponent::TickComponent(float DeltaTime, ELevelTick TickT
if (Survival.BodyTemperature < 35.0f)
{
Survival.Health -= ColdDamagePerMinute * Minutes;
Survival.Health -= ColdDamagePerMinute * Minutes * (1.0f - FMath::Clamp(CurrentWeatherProtection, 0.0f, 1.0f));
}
if (Survival.SicknessSeverity >= 60.0f)
@@ -92,6 +97,7 @@ void UAgrarianSurvivalComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProp
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UAgrarianSurvivalComponent, Survival);
DOREPLIFETIME(UAgrarianSurvivalComponent, CareHistory);
DOREPLIFETIME(UAgrarianSurvivalComponent, CurrentWeatherProtection);
}
bool UAgrarianSurvivalComponent::IsAlive() const
@@ -229,6 +235,32 @@ void UAgrarianSurvivalComponent::ReduceExhaustion(float Amount)
}
}
float UAgrarianSurvivalComponent::CalculateCurrentWeatherProtection() const
{
const AActor* Owner = GetOwner();
if (!Owner)
{
return 0.0f;
}
TArray<AActor*> OverlappingShelterActors;
Owner->GetOverlappingActors(OverlappingShelterActors, AAgrarianShelterActor::StaticClass());
float BestProtection = 0.0f;
for (const AActor* Actor : OverlappingShelterActors)
{
const AAgrarianShelterActor* Shelter = Cast<AAgrarianShelterActor>(Actor);
if (!Shelter || !Shelter->ProtectionVolume || !Shelter->ProtectionVolume->IsOverlappingActor(Owner))
{
continue;
}
BestProtection = FMath::Max(BestProtection, FMath::Clamp(Shelter->WeatherProtection, 0.0f, 1.0f));
}
return BestProtection;
}
void UAgrarianSurvivalComponent::OnRep_Survival()
{
BroadcastSurvivalChanged();
@@ -30,6 +30,9 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, ReplicatedUsing = OnRep_CareHistory, Category = "Agrarian|Survival")
FAgrarianCareHistorySnapshot CareHistory;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Replicated, Category = "Agrarian|Survival|Shelter")
float CurrentWeatherProtection = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Survival|Rates", meta = (ClampMin = "0"))
float HungerDecayPerMinute = 0.55f;
@@ -102,6 +105,9 @@ public:
UFUNCTION(BlueprintCallable, Category = "Agrarian|Survival")
void ReduceExhaustion(float Amount);
UFUNCTION(BlueprintPure, Category = "Agrarian|Survival|Shelter")
float CalculateCurrentWeatherProtection() const;
protected:
UFUNCTION()
void OnRep_Survival();