Lesson multipliers stay explicit in tests; poor marks and unexcused absences toast and may auto-summon, while illness stays excused.
79 lines
2.1 KiB
C#
79 lines
2.1 KiB
C#
using HSchool.Content;
|
|
using HSchool.People;
|
|
|
|
namespace HSchool.Simulation;
|
|
|
|
/// <summary>
|
|
/// After marks or absences: info toast, class-teacher log, and optional auto summons weight.
|
|
/// Illness absences do not become summons offenses.
|
|
/// </summary>
|
|
internal static class GradeTrailSystem
|
|
{
|
|
public static void AfterMark(School school, Person person)
|
|
{
|
|
if (school.Catalog?.BehaviorRules is not { } rules)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TryReact(school, person, rules);
|
|
}
|
|
|
|
public static void AfterAbsent(School school, Person person, string? absenceReason)
|
|
{
|
|
if (school.Catalog?.BehaviorRules is not { } rules)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (GradeTrail.CountsAsSummonOffense(absenceReason)
|
|
&& OffenseMemory.Record(person, OffenseKinds.Truancy, school.Clock.Time, otherPersonId: null, rules))
|
|
{
|
|
school.RosterTalkDirty = true;
|
|
}
|
|
|
|
TryReact(school, person, rules);
|
|
}
|
|
|
|
private static void TryReact(School school, Person person, BehaviorDef rules)
|
|
{
|
|
if (!GradeTrail.IsPoor(person, rules))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!school.TryClaimGradeTrailNotice(person.Id, school.Clock.Time.Date))
|
|
{
|
|
return;
|
|
}
|
|
|
|
school.RaiseWorldEvent(new WorldEvent(EventTriggers.PoorGradeTrail, person.Id));
|
|
|
|
var schoolClass = ClassOf(school, person);
|
|
if (schoolClass?.ClassTeacherId is { } teacherId)
|
|
{
|
|
school.AppendDayLog(new PersonLogEvent(
|
|
person.Id,
|
|
school.Clock.Time,
|
|
PersonLogTypes.ClassTeacherGradeNote,
|
|
teacherId));
|
|
}
|
|
|
|
if (rules.GradeTrailSummonChance > 0f)
|
|
{
|
|
DirectorSummonSystem.TryEnqueue(school, person.Id, rules.GradeTrailSummonChance);
|
|
}
|
|
}
|
|
|
|
private static SchoolClass? ClassOf(School school, Person person)
|
|
{
|
|
if (person.ClassId is null || school.Roster is null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return school.Roster.Classes.FirstOrDefault(row =>
|
|
row.Id.Equals(person.ClassId, StringComparison.Ordinal));
|
|
}
|
|
}
|