Add DiseaseDef diseases with weather vectors and excused absence.
Vanilla ships several diseases whose stages drive lesson gain, stay-home rolls, and illness attendance; cold/rain/snow raise onset via BehaviorDef scale.
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
using HSchool.Content;
|
||||
|
||||
namespace HSchool.People.Tests;
|
||||
|
||||
public class DiseaseEffectTests
|
||||
{
|
||||
[Fact]
|
||||
public void TwoDiseaseDefs_YieldDifferentSeverityCurves()
|
||||
{
|
||||
var catalog = LoadVanilla();
|
||||
var cold = catalog.Diseases["CommonCold"];
|
||||
var flu = catalog.Diseases["Influenza"];
|
||||
var started = new DateTime(2012, 4, 3, 8, 0, 0, DateTimeKind.Utc);
|
||||
var a = Blank("p1");
|
||||
var b = Blank("p1");
|
||||
HealthConditions.Add(a, Onset(cold.DefName, started, severity: 0.1f));
|
||||
HealthConditions.Add(b, Onset(flu.DefName, started, severity: 0.1f));
|
||||
|
||||
Assert.True(HealthConditions.Tick(a, peopleSeed: 7, dayNumber: 100, gameMinutes: 24 * 60, catalog, started));
|
||||
Assert.True(HealthConditions.Tick(b, peopleSeed: 7, dayNumber: 100, gameMinutes: 24 * 60, catalog, started));
|
||||
|
||||
Assert.NotEqual(a.Conditions![0].Severity, b.Conditions![0].Severity);
|
||||
Assert.True(a.Conditions[0].Severity > 0.1f);
|
||||
Assert.True(b.Conditions[0].Severity > 0.1f);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HeavyStage_StaysHomeMoreOftenThanMild()
|
||||
{
|
||||
var catalog = LoadVanilla();
|
||||
var started = new DateTime(2012, 1, 1, 6, 0, 0, DateTimeKind.Utc);
|
||||
var mild = Blank("pupil");
|
||||
var heavy = Blank("pupil");
|
||||
HealthConditions.Add(mild, Onset("Influenza", started, severity: 0.1f));
|
||||
HealthConditions.Add(heavy, Onset("Influenza", started, severity: 0.8f));
|
||||
|
||||
// Past incubation so stage effects apply. Same person, different days — the day salt varies the roll.
|
||||
var day = started.AddDays(2);
|
||||
var mildHome = 0;
|
||||
var heavyHome = 0;
|
||||
for (var i = 0; i < 200; i++)
|
||||
{
|
||||
var when = day.AddDays(i);
|
||||
if (DiseaseEffects.ShouldStayHome(mild, catalog, peopleSeed: 11, when))
|
||||
{
|
||||
mildHome++;
|
||||
}
|
||||
|
||||
if (DiseaseEffects.ShouldStayHome(heavy, catalog, peopleSeed: 11, when))
|
||||
{
|
||||
heavyHome++;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(heavyHome > mildHome);
|
||||
Assert.True(heavyHome > 100);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Attendance_IllnessReason_IsNotTruancy()
|
||||
{
|
||||
var person = Blank("p1");
|
||||
var rules = new BehaviorDef { DefName = "Behavior", AttendanceMax = 10 };
|
||||
var time = new DateTime(2012, 4, 3, 9, 15, 0, DateTimeKind.Utc);
|
||||
Assert.True(AttendanceMemory.Record(
|
||||
person,
|
||||
"Mathematics",
|
||||
AttendanceStatuses.Absent,
|
||||
time,
|
||||
period: 1,
|
||||
rules,
|
||||
AbsenceReasons.Illness));
|
||||
|
||||
Assert.Equal(AbsenceReasons.Illness, person.Attendance![0].AbsenceReason);
|
||||
Assert.NotEqual(AbsenceReasons.Truancy, person.Attendance[0].AbsenceReason);
|
||||
|
||||
var json = RosterJson.Serialize(RosterDocument.From(1, new Roster([person], [], [])));
|
||||
var loaded = RosterJson.Parse(json).ToRoster().People[0];
|
||||
Assert.Equal(AbsenceReasons.Illness, loaded.Attendance![0].AbsenceReason);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Recovery_GrantsTemporaryImmunity()
|
||||
{
|
||||
var catalog = LoadVanilla();
|
||||
var started = new DateTime(2012, 4, 3, 8, 0, 0, DateTimeKind.Utc);
|
||||
var person = Blank("p1");
|
||||
HealthConditions.Add(
|
||||
person,
|
||||
new HealthCondition
|
||||
{
|
||||
DefName = "CommonCold",
|
||||
Severity = 0.2f,
|
||||
Progress = 0.99f,
|
||||
Source = "cold",
|
||||
StartedAt = started,
|
||||
});
|
||||
|
||||
Assert.True(HealthConditions.Tick(
|
||||
person,
|
||||
peopleSeed: 3,
|
||||
dayNumber: 50,
|
||||
gameMinutes: 24 * 60 * 3,
|
||||
catalog,
|
||||
started.AddDays(1)));
|
||||
|
||||
Assert.Null(person.Conditions);
|
||||
Assert.NotNull(person.DiseaseImmunities);
|
||||
Assert.Equal("CommonCold", person.DiseaseImmunities![0].DefName);
|
||||
Assert.True(person.DiseaseImmunities[0].Until > started);
|
||||
Assert.True(DiseaseImmunities.IsImmune(person, "CommonCold", started.AddDays(2)));
|
||||
}
|
||||
|
||||
private static HealthCondition Onset(string defName, DateTime started, float severity) =>
|
||||
new()
|
||||
{
|
||||
DefName = defName,
|
||||
Severity = severity,
|
||||
Progress = 0f,
|
||||
Source = "cold",
|
||||
StartedAt = DateTime.SpecifyKind(started, DateTimeKind.Utc),
|
||||
};
|
||||
|
||||
private static DefCatalog LoadVanilla()
|
||||
{
|
||||
var root = Path.Combine(AppContext.BaseDirectory, "vanilla");
|
||||
return new CatalogLoader().Load(
|
||||
[CatalogLoader.CorePackId],
|
||||
PackDocuments.FromDirectory(CatalogLoader.CorePackId, root));
|
||||
}
|
||||
|
||||
private static Person Blank(string id)
|
||||
{
|
||||
var cases = new CaseTable
|
||||
{
|
||||
Nom = id,
|
||||
Gen = id,
|
||||
Dat = id,
|
||||
Acc = id,
|
||||
Ins = id,
|
||||
Pre = id,
|
||||
};
|
||||
return new Person
|
||||
{
|
||||
Id = id,
|
||||
FamilyId = "f",
|
||||
Female = false,
|
||||
BirthDate = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc),
|
||||
Name = new PersonName(id, id, id, cases, cases, cases),
|
||||
IsStudent = true,
|
||||
IsStaff = false,
|
||||
IsParent = false,
|
||||
Numbers = new Dictionary<string, int>(StringComparer.Ordinal),
|
||||
Choices = new Dictionary<string, string>(StringComparer.Ordinal),
|
||||
Skills = new Dictionary<string, int>(StringComparer.Ordinal),
|
||||
Traits = [],
|
||||
Needs = new Dictionary<string, float>(StringComparer.Ordinal),
|
||||
Opinions = new Dictionary<string, int>(StringComparer.Ordinal),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user