Merge branch 'phase/41-opinions'

# Conflicts:
#	docs/phases/README.md
This commit is contained in:
Leonid Pershin
2026-08-20 07:58:05 +03:00
25 changed files with 1021 additions and 28 deletions
+2 -1
View File
@@ -53,9 +53,10 @@ internal static class ApparelWear
}
var morningChanged = MorningDress.Apply(school);
var opinionsChanged = MorningOpinions.Apply(school);
var ragsReplaced = SchoolDay.IsWorkday(school.Catalog, school.Clock.Time, school.SchoolWeekDays)
&& ReplaceRags(school);
return bandCrossed | morningChanged | ragsReplaced;
return bandCrossed | morningChanged | opinionsChanged | ragsReplaced;
}
internal static bool CrossedDayStart(DateTime before, DateTime after)
+66
View File
@@ -0,0 +1,66 @@
using HSchool.Content;
using HSchool.People;
namespace HSchool.Simulation;
/// <summary>Drifts non-zero opinions toward family basis or zero at six on work mornings.</summary>
internal static class MorningOpinions
{
public static bool Apply(School school)
{
if (school.Catalog?.BehaviorRules is not { } rules || school.Roster is null)
{
return false;
}
if (!SchoolDay.IsWorkday(school.Catalog, school.Clock.Time, school.SchoolWeekDays))
{
return false;
}
var peopleById = school.Roster.People.ToDictionary(person => person.Id, StringComparer.Ordinal);
var changed = false;
foreach (var person in school.Roster.People)
{
changed |= DriftPerson(school.Roster, rules, peopleById, person, rules.OpinionDriftPerMorning);
}
return changed;
}
private static bool DriftPerson(
Roster roster,
BehaviorDef rules,
IReadOnlyDictionary<string, Person> peopleById,
Person person,
int drift)
{
if (person.Opinions.Count == 0)
{
return false;
}
var changed = false;
foreach (var (targetId, current) in person.Opinions.ToArray())
{
if (!peopleById.TryGetValue(targetId, out var target))
{
changed |= OpinionStore.Remove(person, targetId);
continue;
}
var basis = OpinionStore.FamilyBasis(roster, rules, person, target);
var next = OpinionStore.MoveToward(current, basis, drift);
if (next == 0)
{
changed |= OpinionStore.Remove(person, targetId);
}
else
{
changed |= OpinionStore.Set(person, targetId, next);
}
}
return changed;
}
}