Files
h-school/src/HSchool.Simulation/RosterSpawner.cs
T
Leonid PershinandCursor 8e7ab46e79 Sample outdoor weather from the climate preset so people can freeze and the clock can show it.
Protocol v8 adds tenths of a °C and precipitation to the clock frame; warmth drains from insulation versus place temperature.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 03:49:40 +03:00

86 lines
2.9 KiB
C#

using Arch.Core;
using HSchool.Ai;
using HSchool.Content;
using HSchool.People;
namespace HSchool.Simulation;
/// <summary>Turns roster records into Arch entities. Parents have no map location — by design.</summary>
public static class RosterSpawner
{
private static readonly QueryDescription People = new QueryDescription().WithAll<PersonIdentity>();
private static readonly QueryDescription Classes = new QueryDescription().WithAll<ClassIdentity>();
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);
}
}
/// <summary>Drops the previous composition and spawns <paramref name="roster"/>. Called on yearly intake.</summary>
public static void Replace(World world, Roster roster, DefCatalog? catalog = null)
{
DestroyAll(world, People);
DestroyAll(world, Classes);
Spawn(world, roster, catalog);
}
private static Dictionary<string, float> NeedsOf(Person person, DefCatalog? catalog)
{
var values = new Dictionary<string, float>(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<Entity>();
world.Query(in query, (Entity entity) => entities.Add(entity));
foreach (var entity in entities)
{
world.Destroy(entity);
}
}
}