using HSchool.Content; using HSchool.People; using HSchool.Protocol; using HSchool.Schedule; using HSchool.Simulation; namespace HSchool.Server.Game; /// /// Overlays the current lesson onto map-tree nodes. Occupancy is derived from the timetable and /// the clock; it is not stored on the map. /// internal static class MapOccupancy { public static void Apply( MapSnapshotNode[] nodes, School school, int weekDays, string locale) { if (school.Timetable is null || school.Roster is null || school.Catalog is null) { return; } var occurring = TimetableClock.OccurringAt( school.Timetable, school.Catalog, school.Clock.Time, weekDays); if (occurring.Count == 0) { return; } var catalog = school.Catalog; var classes = school.Roster.Classes.ToDictionary(item => item.Id, StringComparer.Ordinal); var people = school.Roster.People.ToDictionary(person => person.Id, StringComparer.Ordinal); var byRoom = occurring.ToDictionary(lesson => lesson.RoomId, StringComparer.Ordinal); for (var i = 0; i < nodes.Length; i++) { if (!byRoom.TryGetValue(nodes[i].Id, out var lesson)) { continue; } classes.TryGetValue(lesson.ClassId, out var schoolClass); var subjectLabel = catalog.Subjects.TryGetValue(lesson.Subject, out var subject) ? catalog.Label(locale, subject) : lesson.Subject; var classLabel = schoolClass is null ? lesson.ClassId : $"{schoolClass.Year}{schoolClass.Letter}"; nodes[i] = nodes[i] with { ActivitySubject = subjectLabel, ActivityClass = classLabel, Characters = NamesOf(lesson, schoolClass, people), }; } } private static string[] NamesOf( LessonPlacement lesson, SchoolClass? schoolClass, IReadOnlyDictionary people) { var names = new List(); if (people.TryGetValue(lesson.TeacherId, out var teacher)) { names.Add(teacher.Name.Full); } else if (lesson.TeacherId.Length > 0) { names.Add(lesson.TeacherId); } if (schoolClass is not null) { foreach (var pupilId in schoolClass.PupilIds) { if (people.TryGetValue(pupilId, out var pupil)) { names.Add(pupil.Name.Full); } } } return names.Count > byte.MaxValue ? [.. names.Take(byte.MaxValue)] : [.. names]; } }