Add survival death state

This commit is contained in:
2026-05-18 13:22:45 -07:00
parent 164169f6c4
commit d318e97977
7 changed files with 125 additions and 5 deletions
+2
View File
@@ -100,6 +100,7 @@ void AAgrarianDebugHUD::DrawCriticalStats(const UAgrarianSurvivalComponent* Surv
};
DrawScaledLine(TEXT("SURVIVAL"), X, Y, CriticalStatsTextScale, HeaderColor);
DrawScaledLine(Survival.bIsDead ? TEXT("State DEAD") : TEXT("State ALIVE"), X, Y, CriticalStatsTextScale, Survival.bIsDead ? CriticalColor : StableColor);
DrawScaledLine(FString::Printf(TEXT("Health %3.0f"), Survival.Health), X, Y, CriticalStatsTextScale, StatusColor(Survival.Health));
DrawScaledLine(FString::Printf(TEXT("Stamina %3.0f"), Survival.Stamina), X, Y, CriticalStatsTextScale, StatusColor(Survival.Stamina));
DrawScaledLine(FString::Printf(TEXT("Food %3.0f"), Survival.Hunger), X, Y, CriticalStatsTextScale, StatusColor(Survival.Hunger));
@@ -334,6 +335,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("State: %s"), Survival.bIsDead ? TEXT("DEAD") : TEXT("ALIVE")), X, Y, Survival.bIsDead ? FColor::Red : FColor::Green);
DrawLine(FString::Printf(TEXT("Shelter: %.0f%%"), SurvivalComponent->CurrentWeatherProtection * 100.0f), X, Y);
DrawLine(FString::Printf(TEXT("Expose: x%.2f %+3.1f C"), SurvivalComponent->CurrentWeatherExposureMultiplier, SurvivalComponent->CurrentWeatherTemperatureOffsetC), X, Y);
DrawLine(FString::Printf(TEXT("Injury: %.0f"), Survival.InjurySeverity), X, Y);
@@ -149,7 +149,8 @@ void AAgrarianGamePlayerController::AgrarianSurvival()
const FAgrarianSurvivalSnapshot& Survival = SurvivalComponent->Survival;
ClientMessage(FString::Printf(
TEXT("Health %.1f | Stamina %.1f | Exhaustion %.1f | Hunger %.1f | Thirst %.1f | Temp %.1fC | Injury %.1f | Bleeding %.1f | Sprain %.1f | Sickness %.1f"),
TEXT("%s | Health %.1f | Stamina %.1f | Exhaustion %.1f | Hunger %.1f | Thirst %.1f | Temp %.1fC | Injury %.1f | Bleeding %.1f | Sprain %.1f | Sickness %.1f | Death %s"),
Survival.bIsDead ? TEXT("DEAD") : TEXT("ALIVE"),
Survival.Health,
Survival.Stamina,
Survival.Exhaustion,
@@ -159,7 +160,8 @@ void AAgrarianGamePlayerController::AgrarianSurvival()
Survival.InjurySeverity,
Survival.BleedingSeverity,
Survival.SprainSeverity,
Survival.SicknessSeverity));
Survival.SicknessSeverity,
*Survival.LastDeathReason.ToString()));
}
void AAgrarianGamePlayerController::AgrarianHeal()
@@ -322,7 +324,7 @@ void AAgrarianGamePlayerController::ServerAgrarianHeal_Implementation()
return;
}
SurvivalComponent->RestoreHealth(100.0f);
SurvivalComponent->Revive(100.0f);
SurvivalComponent->AddFood(100.0f);
SurvivalComponent->AddWater(100.0f);
SurvivalComponent->ReduceExhaustion(100.0f);
@@ -128,7 +128,12 @@ void UAgrarianSurvivalComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProp
bool UAgrarianSurvivalComponent::IsAlive() const
{
return Survival.Health > 0.0f;
return !Survival.bIsDead && Survival.Health > 0.0f;
}
bool UAgrarianSurvivalComponent::IsDead() const
{
return Survival.bIsDead || Survival.Health <= 0.0f;
}
void UAgrarianSurvivalComponent::ApplyDamage(float Amount)
@@ -145,12 +150,42 @@ void UAgrarianSurvivalComponent::RestoreHealth(float Amount)
{
if (GetOwner() && GetOwner()->HasAuthority())
{
if (Survival.bIsDead)
{
return;
}
Survival.Health += FMath::Max(0.0f, Amount);
ClampSurvival();
BroadcastSurvivalChanged();
}
}
void UAgrarianSurvivalComponent::MarkDead(FName Reason)
{
if (GetOwner() && GetOwner()->HasAuthority())
{
Survival.Health = 0.0f;
Survival.Stamina = 0.0f;
Survival.bIsDead = true;
Survival.LastDeathReason = Reason.IsNone() ? FName(TEXT("unknown")) : Reason;
BroadcastSurvivalChanged();
}
}
void UAgrarianSurvivalComponent::Revive(float HealthAmount)
{
if (GetOwner() && GetOwner()->HasAuthority())
{
Survival.bIsDead = false;
Survival.LastDeathReason = NAME_None;
Survival.Health = FMath::Clamp(HealthAmount, 1.0f, 100.0f);
Survival.Stamina = FMath::Max(Survival.Stamina, 25.0f);
ClampSurvival();
BroadcastSurvivalChanged();
}
}
void UAgrarianSurvivalComponent::AddFood(float Amount)
{
if (GetOwner() && GetOwner()->HasAuthority())
@@ -429,6 +464,7 @@ void UAgrarianSurvivalComponent::ClampSurvival()
Survival.BleedingSeverity = FMath::Clamp(Survival.BleedingSeverity, 0.0f, 100.0f);
Survival.SprainSeverity = FMath::Clamp(Survival.SprainSeverity, 0.0f, 100.0f);
Survival.SicknessSeverity = FMath::Clamp(Survival.SicknessSeverity, 0.0f, 100.0f);
UpdateDeathState();
}
void UAgrarianSurvivalComponent::ClampCareHistory()
@@ -447,3 +483,21 @@ void UAgrarianSurvivalComponent::BroadcastSurvivalChanged()
{
OnSurvivalChanged.Broadcast(Survival);
}
void UAgrarianSurvivalComponent::UpdateDeathState()
{
if (Survival.Health <= 0.0f)
{
Survival.Health = 0.0f;
Survival.Stamina = 0.0f;
Survival.bIsDead = true;
if (Survival.LastDeathReason.IsNone())
{
Survival.LastDeathReason = FName(TEXT("health_depleted"));
}
}
else if (!Survival.bIsDead)
{
Survival.LastDeathReason = NAME_None;
}
}
@@ -84,12 +84,21 @@ public:
UFUNCTION(BlueprintCallable, Category = "Agrarian|Survival")
bool IsAlive() const;
UFUNCTION(BlueprintCallable, Category = "Agrarian|Survival")
bool IsDead() const;
UFUNCTION(BlueprintCallable, Category = "Agrarian|Survival")
void ApplyDamage(float Amount);
UFUNCTION(BlueprintCallable, Category = "Agrarian|Survival")
void RestoreHealth(float Amount);
UFUNCTION(BlueprintCallable, Category = "Agrarian|Survival")
void MarkDead(FName Reason);
UFUNCTION(BlueprintCallable, Category = "Agrarian|Survival")
void Revive(float HealthAmount = 100.0f);
UFUNCTION(BlueprintCallable, Category = "Agrarian|Survival")
void AddFood(float Amount);
@@ -153,5 +162,6 @@ protected:
void ClampSurvival();
void ClampCareHistory();
void UpdateDeathState();
void BroadcastSurvivalChanged();
};
+6
View File
@@ -362,6 +362,12 @@ struct FAgrarianSurvivalSnapshot
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Survival")
float SicknessSeverity = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Survival")
bool bIsDead = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Survival")
FName LastDeathReason = NAME_None;
};
USTRUCT(BlueprintType)