Implement yearly intake functionality in school simulation, allowing for the graduation of students and the addition of new first-year pupils. Update the roster management to reflect these changes, ensuring proper entity handling in the simulation. Enhance the API to support name sets during roster installation and revise related tests to validate the new intake process and roster updates.
This commit is contained in:
@@ -70,29 +70,64 @@ public sealed class School : IDisposable
|
||||
|
||||
public int PeopleSeed { get; private set; }
|
||||
|
||||
/// <summary>Name pack used to generate this school's people. Needed again on 1 September.</summary>
|
||||
public string? NameSetId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Installs a roster that already matches the map. Spawns entities; does not write to disk.
|
||||
/// </summary>
|
||||
public void InstallPeople(Roster roster, int seed)
|
||||
public void InstallPeople(Roster roster, int seed, string? nameSetId = null)
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||
ArgumentNullException.ThrowIfNull(roster);
|
||||
|
||||
Roster = roster;
|
||||
PeopleSeed = seed;
|
||||
NameSetId = nameSetId;
|
||||
RosterSpawner.Spawn(World, roster);
|
||||
}
|
||||
|
||||
/// <summary>Runs one fixed step of the school: calendar, then need decay.</summary>
|
||||
public void Tick(double deltaTime, double gameMinutesPerRealSecond)
|
||||
/// <summary>Runs one fixed step of the school: calendar, yearly intake if 1 September passed, then need decay.</summary>
|
||||
/// <returns><see langword="true"/> when the roster changed this step.</returns>
|
||||
public bool Tick(double deltaTime, double gameMinutesPerRealSecond)
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||
|
||||
var before = Clock.Time;
|
||||
var gameMinutes = Clock.Advance(deltaTime, gameMinutesPerRealSecond);
|
||||
if (gameMinutes > 0 && Catalog is not null)
|
||||
var peopleChanged = false;
|
||||
if (gameMinutes > 0)
|
||||
{
|
||||
NeedDecay.Apply(World, Catalog, gameMinutes);
|
||||
peopleChanged = TryYearlyIntake(before, Clock.Time);
|
||||
if (Catalog is not null)
|
||||
{
|
||||
NeedDecay.Apply(World, Catalog, gameMinutes);
|
||||
}
|
||||
}
|
||||
|
||||
return peopleChanged;
|
||||
}
|
||||
|
||||
private bool TryYearlyIntake(DateTime before, DateTime after)
|
||||
{
|
||||
if (Roster is null || Catalog is null || NameSetId is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var changed = false;
|
||||
foreach (var date in YearlyIntake.DatesBetween(before, after))
|
||||
{
|
||||
Roster = YearlyIntake.Apply(Catalog, Roster, PeopleSeed, NameSetId, date);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
RosterSpawner.Replace(World, Roster);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
Reference in New Issue
Block a user