Replace selectable name sets with a country that owns names and climate presets.

Create picks a country; climate is rolled from the school seed and stored. Old Slavic saves lift as Russia.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-20 02:55:13 +03:00
co-authored by Cursor
parent 450495f666
commit 1b66c89cd7
58 changed files with 902 additions and 477 deletions
+42 -37
View File
@@ -32,7 +32,8 @@ internal sealed class SchoolWorker
private readonly bool _isNew;
private readonly IReadOnlyList<string>? _modIds;
private readonly MapLayout? _savedMap;
private readonly string? _nameSetId;
private readonly string? _countryId;
private string? _climatePresetId;
private string? _nativeLanguage;
private readonly int? _createSeed;
private readonly IReadOnlyList<PresenceSnapshot>? _savedPresence;
@@ -66,7 +67,8 @@ internal sealed class SchoolWorker
bool isNew,
IReadOnlyList<string>? modIds,
MapLayout? savedMap,
string? nameSetId,
string? countryId,
string? climatePresetId,
string? nativeLanguage,
int? createSeed,
IReadOnlyList<PresenceSnapshot>? savedPresence,
@@ -86,7 +88,8 @@ internal sealed class SchoolWorker
_isNew = isNew;
_modIds = modIds;
_savedMap = savedMap;
_nameSetId = nameSetId;
_countryId = countryId;
_climatePresetId = climatePresetId;
_nativeLanguage = nativeLanguage;
_createSeed = createSeed;
_savedPresence = savedPresence;
@@ -857,12 +860,19 @@ internal sealed class SchoolWorker
private bool InstallPeople(School school, DefCatalog catalog, MapLayout map)
{
var nameSetId = ResolveNameSetId(catalog, _nameSetId);
if (nameSetId is null)
var countryId = ResolveCountryId(catalog, _countryId);
if (countryId is null)
{
throw new SchoolContentUnavailableException($"School {_id} has no name set in its catalog.");
throw new SchoolContentUnavailableException($"School {_id} has no country in its catalog.");
}
if (!catalog.Countries.TryGetValue(countryId, out var country) || country.Abstract)
{
throw new SchoolContentUnavailableException($"School {_id} has no country in its catalog.");
}
_climatePresetId = ResolveClimatePreset(country, _climatePresetId);
var demand = SchoolDemand.From(catalog, map);
Roster roster;
ApplicantPool applicants;
@@ -878,10 +888,10 @@ internal sealed class SchoolWorker
}
seed = createSeed;
native = ResolveNative(catalog, nameSetId, seed, _nativeLanguage, generating: true);
native = ResolveNative(country, seed, _nativeLanguage, generating: true);
_nativeLanguage = native;
roster = RosterGenerator.Generate(catalog, map, seed, nameSetId, school.Clock.Time, native);
applicants = ApplicantPool.Create(catalog, roster, seed, nameSetId, school.Clock.Time, native);
roster = RosterGenerator.Generate(catalog, map, seed, countryId, school.Clock.Time, native);
applicants = ApplicantPool.Create(catalog, roster, seed, countryId, school.Clock.Time, native);
generated = true;
}
else
@@ -890,16 +900,16 @@ internal sealed class SchoolWorker
if (loaded is null)
{
seed = school.Id;
native = ResolveNative(catalog, nameSetId, seed, _nativeLanguage, generating: true);
native = ResolveNative(country, seed, _nativeLanguage, generating: true);
_nativeLanguage = native;
roster = RosterGenerator.Generate(catalog, map, seed, nameSetId, school.Clock.Time, native);
applicants = ApplicantPool.Create(catalog, roster, seed, nameSetId, school.Clock.Time, native);
roster = RosterGenerator.Generate(catalog, map, seed, countryId, school.Clock.Time, native);
applicants = ApplicantPool.Create(catalog, roster, seed, countryId, school.Clock.Time, native);
generated = true;
}
else
{
seed = loaded.Seed;
native = ResolveNative(catalog, nameSetId, seed, _nativeLanguage, generating: false);
native = ResolveNative(country, seed, _nativeLanguage, generating: false);
_nativeLanguage = native;
roster = loaded.ToRoster();
if (loaded.Applicants is { Applicants.Count: > 0 })
@@ -908,7 +918,7 @@ internal sealed class SchoolWorker
}
else
{
applicants = ApplicantPool.Create(catalog, roster, seed, nameSetId, school.Clock.Time, native);
applicants = ApplicantPool.Create(catalog, roster, seed, countryId, school.Clock.Time, native);
generated = true;
}
}
@@ -920,47 +930,41 @@ internal sealed class SchoolWorker
$"School {_id} roster does not match its map; the people file was left untouched.");
}
school.InstallPeople(roster, seed, nameSetId, applicants, _nativeLanguage);
school.InstallPeople(roster, seed, countryId, applicants, _nativeLanguage, _climatePresetId);
InstallTimetable(school);
school.ConfigurePresence(_options.SchoolWeekDays, _options.MaxDecisionsPerTick);
school.RestorePresence(_savedPresence);
return generated;
}
private static string? ResolveNameSetId(DefCatalog catalog, string? requested)
private static string? ResolveCountryId(DefCatalog catalog, string? requested)
{
var available = catalog.NameSets.Values
.Where(def => !def.Abstract)
.Select(def => def.DefName)
.OrderBy(name => name, StringComparer.Ordinal)
.ToArray();
if (available.Length == 0)
if (string.IsNullOrWhiteSpace(requested))
{
return null;
}
if (string.IsNullOrWhiteSpace(requested))
return catalog.Countries.TryGetValue(requested, out var country) && !country.Abstract
? requested
: null;
}
private static string? ResolveClimatePreset(CountryDef country, string? requested)
{
if (!string.IsNullOrWhiteSpace(requested) && country.ClimatePresets.Contains(requested, StringComparer.Ordinal))
{
return available[0];
return requested;
}
return available.Contains(requested, StringComparer.Ordinal) ? requested : null;
return CountryClimate.Pick(country, schoolSeed: 0, rollIfOmitted: false);
}
private static string? ResolveNative(
DefCatalog catalog,
string nameSetId,
CountryDef country,
int schoolSeed,
string? requested,
bool generating)
{
if (!catalog.NameSets.TryGetValue(nameSetId, out var names))
{
return null;
}
return NativeLanguages.Pick(names, schoolSeed, requested, rollIfOmitted: generating && string.IsNullOrWhiteSpace(requested));
}
bool generating) =>
NativeLanguages.Pick(country.Names, schoolSeed, requested, rollIfOmitted: generating && string.IsNullOrWhiteSpace(requested));
private void Persist()
{
@@ -983,7 +987,8 @@ internal sealed class SchoolWorker
SpeedIndex = school.Clock.SpeedIndex,
ModIds = school.Catalog?.PackIds,
Map = school.Map,
NameSetId = _nameSetId,
CountryId = school.CountryId,
ClimatePresetId = school.ClimatePresetId,
NativeLanguage = _nativeLanguage,
Presence = school.CapturePresence(),
});