Merge branch 'review/slice-7-a-recheck'

This commit is contained in:
Leonid Pershin
2026-08-20 15:57:12 +03:00
7 changed files with 182 additions and 137 deletions
+18 -4
View File
@@ -71,7 +71,7 @@ public static class DressGenerator
int? pupilYear,
int age)
{
if (person.Items.Count > 0)
if (person.Items.Count > 0 && ItemsUsable(catalog, person.Items))
{
return person;
}
@@ -130,11 +130,12 @@ public static class DressGenerator
return pool with { Applicants = applicants };
}
public static bool NeedsDressing(Roster roster, ApplicantPool? pool)
public static bool NeedsDressing(DefCatalog catalog, Roster roster, ApplicantPool? pool)
{
ArgumentNullException.ThrowIfNull(catalog);
foreach (var person in roster.People)
{
if (person.Items.Count == 0)
if (person.Items.Count == 0 || !ItemsUsable(catalog, person.Items))
{
return true;
}
@@ -147,7 +148,7 @@ public static class DressGenerator
foreach (var applicant in pool.Applicants)
{
if (applicant.Person.Items.Count == 0)
if (applicant.Person.Items.Count == 0 || !ItemsUsable(catalog, applicant.Person.Items))
{
return true;
}
@@ -156,6 +157,19 @@ public static class DressGenerator
return false;
}
private static bool ItemsUsable(DefCatalog catalog, IReadOnlyList<InventoryItem> items)
{
foreach (var item in items)
{
if (!catalog.Things.TryGetValue(item.Def, out var def) || def.Abstract)
{
return false;
}
}
return true;
}
/// <summary>
/// Adds textbooks for subjects the pupil just became old enough for. Existing clothes stay.
/// </summary>
+54 -2
View File
@@ -30,6 +30,9 @@ internal sealed class SchoolSave
public string? ClimatePresetId { get; init; }
/// <summary>Legacy field. Format 2 and older; mapped to <see cref="CountryId"/> on load.</summary>
public string? NameSetId { get; init; }
public string? NativeLanguage { get; init; }
public IReadOnlyList<PresenceSnapshot>? Presence { get; init; }
@@ -155,6 +158,11 @@ internal sealed class SchoolStore
continue;
}
if (save.Format < CurrentFormat)
{
save = UpgradeOlderSave(save);
}
// Claimed last, so a file rejected above does not reserve an id a good file needs.
if (!claimed.TryAdd(save.Id, path))
{
@@ -178,6 +186,7 @@ internal sealed class SchoolStore
Map = save.Map,
CountryId = save.CountryId,
ClimatePresetId = save.ClimatePresetId,
NameSetId = save.NameSetId,
NativeLanguage = save.NativeLanguage,
Presence = save.Presence,
DressRules = save.DressRules,
@@ -196,9 +205,52 @@ internal sealed class SchoolStore
return saves;
}
/// <summary>Older and newer files stay on disk for the menu to delete; they never start.</summary>
/// <summary>
/// Format 2 stored a name set. Slavic becomes Russia; any other id is tried as a country
/// (the example pack kept its defName). Climate is filled on the worker from the country's
/// first preset so the file is not rewritten until the school saves itself.
/// </summary>
internal static SchoolSave UpgradeOlderSave(SchoolSave save)
{
if (!string.IsNullOrWhiteSpace(save.CountryId))
{
return save;
}
var countryId = save.NameSetId switch
{
"Slavic" or null or "" => "Russia",
_ => save.NameSetId,
};
return new SchoolSave
{
Format = save.Format,
Id = save.Id,
Name = save.Name,
GameTime = save.GameTime,
Running = save.Running,
SpeedIndex = save.SpeedIndex,
ModIds = save.ModIds,
Map = save.Map,
CountryId = countryId,
ClimatePresetId = save.ClimatePresetId,
NameSetId = save.NameSetId,
NativeLanguage = save.NativeLanguage,
Presence = save.Presence,
DressRules = save.DressRules,
SpeechRules = save.SpeechRules,
Owner = save.Owner,
PortraitSettings = save.PortraitSettings,
};
}
/// <summary>
/// Newer files, and current-format files without a country, stay on disk for the menu to
/// delete; they never start. Format 2 name-set saves are lifted first, then this gate.
/// </summary>
public static bool CanStart(SchoolSave save) =>
save.Format == CurrentFormat && !string.IsNullOrWhiteSpace(save.CountryId);
save.Format <= CurrentFormat && !string.IsNullOrWhiteSpace(save.CountryId);
public void Save(SchoolSave save)
{
+1 -1
View File
@@ -307,7 +307,7 @@ internal sealed partial class SchoolWorker
generated = true;
}
if (DressGenerator.NeedsDressing(roster, applicants))
if (DressGenerator.NeedsDressing(catalog, roster, applicants))
{
roster = DressGenerator.EnsureRoster(catalog, roster, seed, school.Clock.Time);
applicants = DressGenerator.EnsurePool(catalog, applicants, roster, seed, school.Clock.Time);