Enhance school simulation management by introducing a new SchoolWeekDays option, allowing configuration of the number of working days in a week. Update the API to include school week days in responses and enhance documentation to reflect these changes. Revise UI components to support the new management features, ensuring a seamless user experience when hiring and assigning staff. Update localization strings for improved clarity and consistency across the application.
ci / server (push) Failing after 3m37s
ci / client (push) Successful in 13s

This commit is contained in:
Leonid Pershin
2026-08-19 00:47:09 +03:00
parent 94842ab192
commit 2ebc783585
38 changed files with 1837 additions and 208 deletions
+88
View File
@@ -39,11 +39,26 @@ internal static class PeopleDefValidator
ValidateStaffing(staffing);
}
foreach (var frame in catalog.DayFrames.Values)
{
ValidateDayFrame(frame);
}
foreach (var holiday in catalog.Holidays.Values)
{
ValidateHoliday(holiday);
}
if (catalog.Staffing.Values.Count(def => !def.Abstract) > 1)
{
throw new ContentLoadException("A catalog may only have one concrete StaffingDef.");
}
if (catalog.DayFrames.Values.Count(def => !def.Abstract) > 1)
{
throw new ContentLoadException("A catalog may only have one concrete DayFrameDef.");
}
RequireBuildInputs(catalog);
}
@@ -268,6 +283,16 @@ internal static class PeopleDefValidator
throw new ContentLoadException($"SubjectDef '{subject.DefName}' skill '{share.Skill}' share cannot be negative.");
}
}
if (string.IsNullOrWhiteSpace(subject.Room))
{
return;
}
if (!catalog.Rooms.TryGetValue(subject.Room, out var room) || room.Abstract)
{
throw new ContentLoadException($"SubjectDef '{subject.DefName}' references unknown RoomDef '{subject.Room}'.");
}
}
private static void ValidateStaffing(StaffingDef staffing)
@@ -308,6 +333,69 @@ internal static class PeopleDefValidator
}
}
private static void ValidateDayFrame(DayFrameDef frame)
{
if (frame.Abstract)
{
return;
}
if (!SchoolDay.TryParseTime(frame.FirstLesson, out _))
{
throw new ContentLoadException($"DayFrameDef '{frame.DefName}' firstLesson '{frame.FirstLesson}' is not a time.");
}
if (frame.LessonCount is < 1 or > 12)
{
throw new ContentLoadException($"DayFrameDef '{frame.DefName}' lessonCount must be 112.");
}
if (frame.LessonMinutes is < 1 or > 180)
{
throw new ContentLoadException($"DayFrameDef '{frame.DefName}' lessonMinutes must be 1180.");
}
if (frame.BreakMinutes is < 0 or > 60)
{
throw new ContentLoadException($"DayFrameDef '{frame.DefName}' breakMinutes must be 060.");
}
if (frame.LongBreakMinutes is < 0 or > 120)
{
throw new ContentLoadException($"DayFrameDef '{frame.DefName}' longBreakMinutes must be 0120.");
}
if (frame.LongBreakAfter is < 0 || frame.LongBreakAfter >= frame.LessonCount)
{
throw new ContentLoadException($"DayFrameDef '{frame.DefName}' longBreakAfter must be 0 or a lesson before the last.");
}
}
private static void ValidateHoliday(HolidayDef holiday)
{
if (holiday.Abstract)
{
return;
}
ValidateMonthDay(holiday.Start, holiday.DefName, "start");
ValidateMonthDay(holiday.End, holiday.DefName, "end");
}
private static void ValidateMonthDay(MonthDay stamp, string defName, string field)
{
if (stamp.Month is < 1 or > 12)
{
throw new ContentLoadException($"HolidayDef '{defName}' {field} month must be 112.");
}
var days = DateTime.DaysInMonth(2000, stamp.Month);
if (stamp.Day < 1 || stamp.Day > days)
{
throw new ContentLoadException($"HolidayDef '{defName}' {field} day is not valid for that month.");
}
}
private static void ValidateNameSet(NameSetDef names)
{
if (!NameGrammar.IsKnownPatronymic(names.PatronymicRule))