Add Ground Zero weather exposure zones
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include "AgrarianSurvivalComponent.h"
|
||||
#include "AgrarianGameState.h"
|
||||
#include "AgrarianShelterActor.h"
|
||||
#include "AgrarianWeatherExposureZone.h"
|
||||
#include "Components/BoxComponent.h"
|
||||
#include "Engine/World.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
@@ -35,6 +36,8 @@ void UAgrarianSurvivalComponent::TickComponent(float DeltaTime, ELevelTick TickT
|
||||
Survival.Thirst -= ThirstDecayPerMinute * Minutes;
|
||||
Survival.Stamina += StaminaRecoveryPerSecond * DeltaTime;
|
||||
CurrentWeatherProtection = CalculateCurrentWeatherProtection();
|
||||
CurrentWeatherExposureMultiplier = CalculateCurrentWeatherExposureMultiplier();
|
||||
CurrentWeatherTemperatureOffsetC = CalculateCurrentWeatherTemperatureOffsetC();
|
||||
CareHistory.ShelterQuality = FMath::FInterpTo(CareHistory.ShelterQuality, CurrentWeatherProtection, DeltaTime, 0.02f);
|
||||
|
||||
if (Survival.Stamina <= LowStaminaExhaustionThreshold)
|
||||
@@ -62,7 +65,8 @@ void UAgrarianSurvivalComponent::TickComponent(float DeltaTime, ELevelTick TickT
|
||||
if (const AAgrarianGameState* AgrarianGameState = World->GetGameState<AAgrarianGameState>())
|
||||
{
|
||||
const float ExposureProtectionMultiplier = 1.0f - FMath::Clamp(CurrentWeatherProtection, 0.0f, 1.0f);
|
||||
const float ExposureDelta = (AgrarianGameState->AmbientTemperatureC - 18.0f) * 0.002f * DeltaTime * ExposureProtectionMultiplier;
|
||||
const float EffectiveAmbientTemperatureC = AgrarianGameState->AmbientTemperatureC + CurrentWeatherTemperatureOffsetC;
|
||||
const float ExposureDelta = (EffectiveAmbientTemperatureC - 18.0f) * 0.002f * DeltaTime * ExposureProtectionMultiplier * CurrentWeatherExposureMultiplier;
|
||||
Survival.BodyTemperature += FMath::Clamp(ExposureDelta, -0.035f, 0.02f);
|
||||
}
|
||||
}
|
||||
@@ -79,7 +83,7 @@ void UAgrarianSurvivalComponent::TickComponent(float DeltaTime, ELevelTick TickT
|
||||
|
||||
if (Survival.BodyTemperature < 35.0f)
|
||||
{
|
||||
Survival.Health -= ColdDamagePerMinute * Minutes * (1.0f - FMath::Clamp(CurrentWeatherProtection, 0.0f, 1.0f));
|
||||
Survival.Health -= ColdDamagePerMinute * Minutes * (1.0f - FMath::Clamp(CurrentWeatherProtection, 0.0f, 1.0f)) * CurrentWeatherExposureMultiplier;
|
||||
}
|
||||
|
||||
if (Survival.SicknessSeverity >= 60.0f)
|
||||
@@ -98,6 +102,8 @@ void UAgrarianSurvivalComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProp
|
||||
DOREPLIFETIME(UAgrarianSurvivalComponent, Survival);
|
||||
DOREPLIFETIME(UAgrarianSurvivalComponent, CareHistory);
|
||||
DOREPLIFETIME(UAgrarianSurvivalComponent, CurrentWeatherProtection);
|
||||
DOREPLIFETIME(UAgrarianSurvivalComponent, CurrentWeatherExposureMultiplier);
|
||||
DOREPLIFETIME(UAgrarianSurvivalComponent, CurrentWeatherTemperatureOffsetC);
|
||||
}
|
||||
|
||||
bool UAgrarianSurvivalComponent::IsAlive() const
|
||||
@@ -261,6 +267,66 @@ float UAgrarianSurvivalComponent::CalculateCurrentWeatherProtection() const
|
||||
return BestProtection;
|
||||
}
|
||||
|
||||
float UAgrarianSurvivalComponent::CalculateCurrentWeatherExposureMultiplier() const
|
||||
{
|
||||
const AActor* Owner = GetOwner();
|
||||
if (!Owner)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
TArray<AActor*> OverlappingZoneActors;
|
||||
Owner->GetOverlappingActors(OverlappingZoneActors, AAgrarianWeatherExposureZone::StaticClass());
|
||||
|
||||
float StrongestMultiplierDelta = 0.0f;
|
||||
for (const AActor* Actor : OverlappingZoneActors)
|
||||
{
|
||||
const AAgrarianWeatherExposureZone* Zone = Cast<AAgrarianWeatherExposureZone>(Actor);
|
||||
if (!Zone || !Zone->ExposureVolume || !Zone->ExposureVolume->IsOverlappingActor(Owner))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const float ZoneDelta = FMath::Clamp(Zone->ExposureMultiplier, 0.0f, 3.0f) - 1.0f;
|
||||
if (FMath::Abs(ZoneDelta) > FMath::Abs(StrongestMultiplierDelta))
|
||||
{
|
||||
StrongestMultiplierDelta = ZoneDelta;
|
||||
}
|
||||
}
|
||||
|
||||
return FMath::Clamp(1.0f + StrongestMultiplierDelta, 0.0f, 3.0f);
|
||||
}
|
||||
|
||||
float UAgrarianSurvivalComponent::CalculateCurrentWeatherTemperatureOffsetC() const
|
||||
{
|
||||
const AActor* Owner = GetOwner();
|
||||
if (!Owner)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
TArray<AActor*> OverlappingZoneActors;
|
||||
Owner->GetOverlappingActors(OverlappingZoneActors, AAgrarianWeatherExposureZone::StaticClass());
|
||||
|
||||
float StrongestOffset = 0.0f;
|
||||
for (const AActor* Actor : OverlappingZoneActors)
|
||||
{
|
||||
const AAgrarianWeatherExposureZone* Zone = Cast<AAgrarianWeatherExposureZone>(Actor);
|
||||
if (!Zone || !Zone->ExposureVolume || !Zone->ExposureVolume->IsOverlappingActor(Owner))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const float ZoneOffset = FMath::Clamp(Zone->TemperatureOffsetC, -20.0f, 20.0f);
|
||||
if (FMath::Abs(ZoneOffset) > FMath::Abs(StrongestOffset))
|
||||
{
|
||||
StrongestOffset = ZoneOffset;
|
||||
}
|
||||
}
|
||||
|
||||
return StrongestOffset;
|
||||
}
|
||||
|
||||
void UAgrarianSurvivalComponent::OnRep_Survival()
|
||||
{
|
||||
BroadcastSurvivalChanged();
|
||||
|
||||
Reference in New Issue
Block a user