Merge branch 'phase/84-wet-aftereffect'

This commit is contained in:
Leonid Pershin
2026-08-21 20:35:51 +03:00
16 changed files with 456 additions and 20 deletions
+87 -4
View File
@@ -37,6 +37,7 @@ internal static class DiseaseSystem
if (school.LastDiseaseDay != dayNumber)
{
school.LastDiseaseDay = dayNumber;
changed |= TryWet(school);
changed |= TryOnset(school);
changed |= TryContagion(school);
}
@@ -58,6 +59,70 @@ internal static class DiseaseSystem
return changed;
}
private static bool TryWet(School school)
{
var catalog = school.Catalog!;
var rules = catalog.BehaviorRules;
if (rules is null || !catalog.Diseases.ContainsKey(DiseaseFamilies.WetDefName))
{
return false;
}
var chance = school.Weather.Precipitation switch
{
Precipitation.Rain => rules.WetRainChance,
Precipitation.Snow => rules.WetSnowChance,
_ => 0f,
};
if (chance <= 0f)
{
return false;
}
var dayNumber = DateOnly.FromDateTime(school.Clock.Time).DayNumber;
var source = school.Weather.Precipitation == Precipitation.Snow ? "snow" : "rain";
var changed = false;
foreach (var person in school.Roster!.People)
{
if (!person.IsStudent && !person.IsStaff)
{
continue;
}
if (school.Plans.TryGetValue(person.Id, out var plan) && !plan.Comes)
{
continue;
}
if (HealthConditions.Has(person, DiseaseFamilies.WetDefName))
{
continue;
}
var roll = Seed.Mix(school.PeopleSeed, person.Id, dayNumber, Seed.WetSalt);
var unit = (roll & int.MaxValue) / (float)int.MaxValue;
if (unit >= chance)
{
continue;
}
HealthConditions.Add(
person,
new HealthCondition
{
DefName = DiseaseFamilies.WetDefName,
Severity = 0.65f,
Progress = 0f,
Source = source,
StartedAt = school.Clock.Time,
});
changed = true;
}
return changed;
}
private static bool TryOnset(School school)
{
var catalog = school.Catalog!;
@@ -78,16 +143,19 @@ internal static class DiseaseSystem
continue;
}
var wet = HealthConditions.Has(person, DiseaseFamilies.WetDefName);
foreach (var disease in catalog.Diseases.Values)
{
if (disease.Abstract
|| disease.Family.Equals(DiseaseFamilies.Condition, StringComparison.Ordinal)
|| HealthConditions.Has(person, disease.DefName)
|| DiseaseImmunities.IsImmune(person, disease.DefName, school.Clock.Time))
{
continue;
}
var chance = OnsetChance(disease, weather, rules.DiseaseVectorScale);
var chance = OnsetChance(disease, weather, rules.DiseaseVectorScale, wet);
if (chance <= 0f)
{
continue;
@@ -108,7 +176,7 @@ internal static class DiseaseSystem
DefName = disease.DefName,
Severity = 0.05f,
Progress = 0f,
Source = SourceOf(disease, weather),
Source = SourceOf(disease, weather, wet),
StartedAt = school.Clock.Time,
});
changed = true;
@@ -145,6 +213,7 @@ internal static class DiseaseSystem
{
if (!catalog.Diseases.TryGetValue(condition.DefName, out var disease)
|| disease.Abstract
|| disease.Family.Equals(DiseaseFamilies.Condition, StringComparison.Ordinal)
|| !CanTransmit(condition, disease, now))
{
continue;
@@ -348,7 +417,11 @@ internal static class DiseaseSystem
return map;
}
internal static float OnsetChance(DiseaseDef disease, OutdoorWeather weather, float vectorScale)
internal static float OnsetChance(
DiseaseDef disease,
OutdoorWeather weather,
float vectorScale,
bool wet = false)
{
if (vectorScale <= 0f)
{
@@ -368,11 +441,21 @@ internal static class DiseaseSystem
_ => 0f,
};
if (wet)
{
chance += disease.WetChancePerDay;
}
return Math.Clamp(chance * vectorScale, 0f, 1f);
}
private static string SourceOf(DiseaseDef disease, OutdoorWeather weather)
private static string SourceOf(DiseaseDef disease, OutdoorWeather weather, bool wet)
{
if (wet && disease.WetChancePerDay > 0f)
{
return "wet";
}
if (disease.ColdBelowC is { } below && weather.TemperatureC <= below)
{
return "cold";