Add server authoritative fire spread state
This commit is contained in:
@@ -146,6 +146,7 @@ void AAgrarianCampfire::Tick(float DeltaSeconds)
|
||||
UpdateFireRisk(DeltaSeconds);
|
||||
UpdateVegetationIgnitionRisk(DeltaSeconds);
|
||||
UpdateStructureIgnitionRisk(DeltaSeconds);
|
||||
UpdateServerAuthoritativeFireSpread(DeltaSeconds);
|
||||
WarmNearbyCharacters(DeltaSeconds);
|
||||
}
|
||||
}
|
||||
@@ -169,6 +170,10 @@ void AAgrarianCampfire::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& Ou
|
||||
DOREPLIFETIME(AAgrarianCampfire, bForestFuelIgnited);
|
||||
DOREPLIFETIME(AAgrarianCampfire, StructureIgnitionRiskScore);
|
||||
DOREPLIFETIME(AAgrarianCampfire, bStructureIgnited);
|
||||
DOREPLIFETIME(AAgrarianCampfire, GrassFireIntensity);
|
||||
DOREPLIFETIME(AAgrarianCampfire, ForestFireIntensity);
|
||||
DOREPLIFETIME(AAgrarianCampfire, StructureFireIntensity);
|
||||
DOREPLIFETIME(AAgrarianCampfire, ActiveFireSpreadRadius);
|
||||
}
|
||||
|
||||
FText AAgrarianCampfire::GetInteractionText_Implementation(const AAgrarianGameCharacter* Interactor) const
|
||||
@@ -218,6 +223,10 @@ void AAgrarianCampfire::CapturePersistentState_Implementation(UAgrarianPersisten
|
||||
PersistentComponent->NumberState.Add(TEXT("forest_fuel_ignited"), bForestFuelIgnited ? 1.0f : 0.0f);
|
||||
PersistentComponent->NumberState.Add(TEXT("structure_ignition_risk_score"), StructureIgnitionRiskScore);
|
||||
PersistentComponent->NumberState.Add(TEXT("structure_ignited"), bStructureIgnited ? 1.0f : 0.0f);
|
||||
PersistentComponent->NumberState.Add(TEXT("grass_fire_intensity"), GrassFireIntensity);
|
||||
PersistentComponent->NumberState.Add(TEXT("forest_fire_intensity"), ForestFireIntensity);
|
||||
PersistentComponent->NumberState.Add(TEXT("structure_fire_intensity"), StructureFireIntensity);
|
||||
PersistentComponent->NumberState.Add(TEXT("active_fire_spread_radius"), ActiveFireSpreadRadius);
|
||||
}
|
||||
|
||||
void AAgrarianCampfire::ApplyPersistentState_Implementation(UAgrarianPersistentActorComponent* PersistentComponent)
|
||||
@@ -243,6 +252,10 @@ void AAgrarianCampfire::ApplyPersistentState_Implementation(UAgrarianPersistentA
|
||||
const float* SavedForestIgnited = PersistentComponent->NumberState.Find(TEXT("forest_fuel_ignited"));
|
||||
const float* SavedStructureIgnitionRisk = PersistentComponent->NumberState.Find(TEXT("structure_ignition_risk_score"));
|
||||
const float* SavedStructureIgnited = PersistentComponent->NumberState.Find(TEXT("structure_ignited"));
|
||||
const float* SavedGrassFireIntensity = PersistentComponent->NumberState.Find(TEXT("grass_fire_intensity"));
|
||||
const float* SavedForestFireIntensity = PersistentComponent->NumberState.Find(TEXT("forest_fire_intensity"));
|
||||
const float* SavedStructureFireIntensity = PersistentComponent->NumberState.Find(TEXT("structure_fire_intensity"));
|
||||
const float* SavedActiveFireSpreadRadius = PersistentComponent->NumberState.Find(TEXT("active_fire_spread_radius"));
|
||||
|
||||
if (SavedFuelSeconds)
|
||||
{
|
||||
@@ -319,6 +332,26 @@ void AAgrarianCampfire::ApplyPersistentState_Implementation(UAgrarianPersistentA
|
||||
bStructureIgnited = *SavedStructureIgnited > 0.5f;
|
||||
}
|
||||
|
||||
if (SavedGrassFireIntensity)
|
||||
{
|
||||
GrassFireIntensity = FMath::Clamp(*SavedGrassFireIntensity, 0.0f, 100.0f);
|
||||
}
|
||||
|
||||
if (SavedForestFireIntensity)
|
||||
{
|
||||
ForestFireIntensity = FMath::Clamp(*SavedForestFireIntensity, 0.0f, 100.0f);
|
||||
}
|
||||
|
||||
if (SavedStructureFireIntensity)
|
||||
{
|
||||
StructureFireIntensity = FMath::Clamp(*SavedStructureFireIntensity, 0.0f, 100.0f);
|
||||
}
|
||||
|
||||
if (SavedActiveFireSpreadRadius)
|
||||
{
|
||||
ActiveFireSpreadRadius = FMath::Clamp(*SavedActiveFireSpreadRadius, 0.0f, MaxFireSpreadRadius);
|
||||
}
|
||||
|
||||
SetLit(SavedLit && *SavedLit > 0.5f && FuelSeconds > 0.0f);
|
||||
}
|
||||
|
||||
@@ -347,6 +380,10 @@ void AAgrarianCampfire::Extinguish()
|
||||
GrassIgnitionRiskScore = 0.0f;
|
||||
ForestIgnitionRiskScore = 0.0f;
|
||||
StructureIgnitionRiskScore = 0.0f;
|
||||
GrassFireIntensity = 0.0f;
|
||||
ForestFireIntensity = 0.0f;
|
||||
StructureFireIntensity = 0.0f;
|
||||
ActiveFireSpreadRadius = 0.0f;
|
||||
LitDurationSeconds = 0.0f;
|
||||
SecondsSinceMaintenance = 0.0f;
|
||||
SetLit(false);
|
||||
@@ -728,3 +765,64 @@ float AAgrarianCampfire::GetStructureFuelScoreNearFire() const
|
||||
|
||||
return StructureFuelScore;
|
||||
}
|
||||
|
||||
void AAgrarianCampfire::UpdateServerAuthoritativeFireSpread(float DeltaSeconds)
|
||||
{
|
||||
if (!HasAuthority())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool bAnyActiveFire = bGrassOrBrushIgnited || bForestFuelIgnited || bStructureIgnited;
|
||||
if (!bAnyActiveFire)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const float WeatherMultiplier = GetFireSpreadWeatherMultiplier();
|
||||
const float SuppressionMultiplier = FMath::Clamp(1.0f - FireSuppressionPressure, 0.0f, 1.0f);
|
||||
const float FuelScore = FMath::Max(1.0f, GetActiveBurningFuelScore());
|
||||
const float IntensityDelta = FireSpreadIntensityPerSecond * WeatherMultiplier * SuppressionMultiplier * FuelScore * DeltaSeconds;
|
||||
|
||||
if (bGrassOrBrushIgnited)
|
||||
{
|
||||
GrassFireIntensity = FMath::Clamp(GrassFireIntensity + IntensityDelta, 0.0f, 100.0f);
|
||||
}
|
||||
|
||||
if (bForestFuelIgnited)
|
||||
{
|
||||
ForestFireIntensity = FMath::Clamp(ForestFireIntensity + (IntensityDelta * 0.75f), 0.0f, 100.0f);
|
||||
}
|
||||
|
||||
if (bStructureIgnited)
|
||||
{
|
||||
StructureFireIntensity = FMath::Clamp(StructureFireIntensity + (IntensityDelta * 0.9f), 0.0f, 100.0f);
|
||||
}
|
||||
|
||||
const float TotalIntensity = GrassFireIntensity + ForestFireIntensity + StructureFireIntensity;
|
||||
ActiveFireSpreadRadius = FMath::Clamp(
|
||||
BaseFireSpreadRadius + (TotalIntensity * 12.0f * WeatherMultiplier),
|
||||
0.0f,
|
||||
MaxFireSpreadRadius);
|
||||
}
|
||||
|
||||
float AAgrarianCampfire::GetFireSpreadWeatherMultiplier() const
|
||||
{
|
||||
float Multiplier = GetVegetationIgnitionWeatherMultiplier();
|
||||
if (IsWetWeatherActive())
|
||||
{
|
||||
Multiplier *= 0.5f;
|
||||
}
|
||||
|
||||
return FMath::Max(0.0f, Multiplier);
|
||||
}
|
||||
|
||||
float AAgrarianCampfire::GetActiveBurningFuelScore() const
|
||||
{
|
||||
float GrassFuelScore = 0.0f;
|
||||
float ForestFuelScore = 0.0f;
|
||||
const float VegetationFuelScore = GetVegetationFuelScoreNearFire(GrassFuelScore, ForestFuelScore);
|
||||
const float StructureFuelScore = GetStructureFuelScoreNearFire();
|
||||
|
||||
return FMath::Max(0.0f, VegetationFuelScore + StructureFuelScore);
|
||||
}
|
||||
|
||||
@@ -150,6 +150,30 @@ public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Fire|Structure", meta = (ClampMin = "0"))
|
||||
float StructureIgnitionRiskPerSecond = 0.08f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "Agrarian|Fire|Spread", meta = (ClampMin = "0", ClampMax = "100"))
|
||||
float GrassFireIntensity = 0.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "Agrarian|Fire|Spread", meta = (ClampMin = "0", ClampMax = "100"))
|
||||
float ForestFireIntensity = 0.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "Agrarian|Fire|Spread", meta = (ClampMin = "0", ClampMax = "100"))
|
||||
float StructureFireIntensity = 0.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "Agrarian|Fire|Spread", meta = (ClampMin = "0"))
|
||||
float ActiveFireSpreadRadius = 0.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Fire|Spread", meta = (ClampMin = "0"))
|
||||
float BaseFireSpreadRadius = 250.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Fire|Spread", meta = (ClampMin = "0"))
|
||||
float MaxFireSpreadRadius = 3500.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Fire|Spread", meta = (ClampMin = "0"))
|
||||
float FireSpreadIntensityPerSecond = 0.18f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Fire|Spread", meta = (ClampMin = "0"))
|
||||
float FireSuppressionPressure = 0.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Fire|Weather", meta = (ClampMin = "1"))
|
||||
float RainFuelDrainMultiplier = 1.5f;
|
||||
|
||||
@@ -219,4 +243,7 @@ protected:
|
||||
float GetVegetationIgnitionWeatherMultiplier() const;
|
||||
void UpdateStructureIgnitionRisk(float DeltaSeconds);
|
||||
float GetStructureFuelScoreNearFire() const;
|
||||
void UpdateServerAuthoritativeFireSpread(float DeltaSeconds);
|
||||
float GetFireSpreadWeatherMultiplier() const;
|
||||
float GetActiveBurningFuelScore() const;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user