Enhance school creation and staffing management with native language support
ci / server (push) Failing after 3m44s
ci / client (push) Successful in 14s

- Updated protocol documentation to include `nativeLanguages` in `nameSets` and added `nativeLanguage` to school creation options.
- Enhanced the UI for school creation to allow selection of native languages, improving user experience.
- Revised API interfaces to accommodate new native language features, ensuring proper data handling.
- Improved localization strings to support new native language functionalities in both English and Russian.
- Updated tests to validate the new native language features and ensure robust functionality in staffing scenarios.
This commit is contained in:
Leonid Pershin
2026-08-19 22:22:31 +03:00
parent 21d79cb49b
commit 5a00ad7746
48 changed files with 2064 additions and 312 deletions
+40
View File
@@ -120,6 +120,18 @@ public sealed class SkillDef : Def
public IReadOnlyList<AgeMeanPoint> AgeMeans { get; init; } = [];
public IReadOnlyList<BodySkillLimit> BodyLimits { get; init; } = [];
/// <summary>Everyone has this: body, speech, the floor under a profession.</summary>
public bool Always { get; init; }
/// <summary>Adult extras: cook, nurse, secretary. Not rolled for pupils.</summary>
public bool Work { get; init; }
/// <summary>
/// Probability that an adult also has this, on top of the native language. 0 means never
/// by chance — pupils still get it when a subject of their year points here.
/// </summary>
public float AdultChance { get; init; }
}
public sealed class SubjectSkillShare
@@ -338,6 +350,34 @@ public sealed class NameSetDef : Def
public string DefaultSurnameDeclension { get; init; } = NameGrammar.Ov;
/// <summary>
/// Languages this set can speak natively. Slavic names cover Russian, Belarusian and
/// Ukrainian; the school picks one at create. Singular <see cref="NativeLanguage"/> is still
/// accepted in JSONC for a one-language pack.
/// </summary>
public IReadOnlyList<string> NativeLanguages { get; init; } = [];
/// <summary>One-language form. Folded into <see cref="Spoken"/> when the list is empty.</summary>
public string? NativeLanguage { get; init; }
public IReadOnlyList<string> Spoken =>
NativeLanguages.Count > 0
? NativeLanguages
: string.IsNullOrWhiteSpace(NativeLanguage) ? [] : [NativeLanguage];
/// <summary>
/// Chance each other language in <see cref="Spoken"/> is present at a low level — a Russian
/// speaker who understands Belarusian. 0 leaves relatives off the card.
/// </summary>
public float RelatedLanguageChance { get; init; }
public float RelatedLanguageMean { get; init; } = 22f;
public float RelatedLanguageStdDev { get; init; } = 8f;
/// <summary>Cap so a related roll cannot look like a native speaker.</summary>
public int RelatedLanguageMax { get; init; } = 40;
public IReadOnlyList<GivenNameEntry> MaleGiven { get; init; } = [];
public IReadOnlyList<GivenNameEntry> FemaleGiven { get; init; } = [];