using Arch.Core; using HSchool.Ai; using HSchool.Content; using HSchool.People; namespace HSchool.Simulation; /// Turns roster records into Arch entities. Parents have no map location — by design. public static class RosterSpawner { private static readonly QueryDescription People = new QueryDescription().WithAll(); private static readonly QueryDescription Classes = new QueryDescription().WithAll(); public static void Spawn(World world, Roster roster, DefCatalog? catalog = null) { foreach (var schoolClass in roster.Classes) { world.Create( new ClassIdentity( schoolClass.Id, schoolClass.Year, schoolClass.Letter, schoolClass.RoomId, schoolClass.Capacity)); } foreach (var person in roster.People) { world.Create( new PersonIdentity(person.Id, person.FamilyId, person.Female, person.BirthDate, person.Name), new PersonBody(person.Numbers, person.Choices), new PersonSkills(person.Skills.ToDictionary(pair => pair.Key, pair => (float)pair.Value, StringComparer.Ordinal)), new PersonTraits(person.Traits), new PersonNeeds(NeedsOf(person, catalog)), PersonInsulation.FromPerson(person, catalog), new PersonRoles( person.IsStudent, person.IsStaff, person.IsParent, person.ClassId, person.Position, person.WorkplaceRoomId), Presence.OffCampus, PersonActivity.Idle, Intent.None); } } /// Drops the previous composition and spawns . Called on yearly intake. public static void Replace(World world, Roster roster, DefCatalog? catalog = null) { DestroyAll(world, People); DestroyAll(world, Classes); Spawn(world, roster, catalog); } private static Dictionary NeedsOf(Person person, DefCatalog? catalog) { var values = new Dictionary(person.Needs, StringComparer.Ordinal); if (catalog is null) { return values; } foreach (var need in catalog.Needs.Values) { if (!need.Abstract && !values.ContainsKey(need.DefName)) { values[need.DefName] = need.Initial; } } return values; } private static void DestroyAll(World world, QueryDescription query) { var entities = new List(); world.Query(in query, (Entity entity) => entities.Add(entity)); foreach (var entity in entities) { world.Destroy(entity); } } }