Enhance school creation functionality by introducing support for name sets in the API and UI. Update the catalog to include skills, traits, body attributes, needs, and name sets, improving character generation capabilities. Revise localization strings for better user guidance and update tests to validate the new name set functionality and ensure robustness in school creation processes.
This commit is contained in:
@@ -86,6 +86,7 @@ internal sealed record CatalogResponse(
|
||||
IReadOnlyList<DefInfoResponse> Floors,
|
||||
IReadOnlyList<RoomInfoResponse> Rooms,
|
||||
IReadOnlyList<DefInfoResponse> Things,
|
||||
IReadOnlyList<DefInfoResponse> NameSets,
|
||||
MapLayout DefaultMap)
|
||||
{
|
||||
public static CatalogResponse From(DefCatalog catalog, MapLayout map, string locale) =>
|
||||
@@ -95,6 +96,7 @@ internal sealed record CatalogResponse(
|
||||
Placeable(catalog.Floors.Values, catalog, locale),
|
||||
PlaceableRooms(catalog, locale),
|
||||
PlaceableThings(catalog, locale),
|
||||
Placeable(catalog.NameSets.Values, catalog, locale),
|
||||
map);
|
||||
|
||||
private static IReadOnlyList<DefInfoResponse> Placeable<T>(IEnumerable<T> defs, DefCatalog catalog, string locale)
|
||||
|
||||
@@ -50,6 +50,7 @@ internal static class SchoolEndpoints
|
||||
DateTime.SpecifyKind(request.StartDate, DateTimeKind.Utc),
|
||||
request.ModIds,
|
||||
request.Map,
|
||||
request.NameSetId,
|
||||
NewCompletion<SchoolCreationOutcome>());
|
||||
commands.Enqueue(command);
|
||||
|
||||
@@ -71,6 +72,8 @@ internal static class SchoolEndpoints
|
||||
Problem(StatusCodes.Status400BadRequest, "unknown-mod", "A selected mod is missing."),
|
||||
SchoolCreationError.InvalidCatalog =>
|
||||
Problem(StatusCodes.Status400BadRequest, "invalid-catalog", "The selected packs could not be loaded."),
|
||||
SchoolCreationError.UnknownNameSet =>
|
||||
Problem(StatusCodes.Status400BadRequest, "unknown-name-set", "The selected name set is not in the catalog."),
|
||||
_ => Results.Problem("Unknown error."),
|
||||
};
|
||||
})
|
||||
@@ -107,7 +110,12 @@ internal static class SchoolEndpoints
|
||||
}
|
||||
|
||||
/// <summary>Body of <c>POST /api/schools</c>. The start date is a game calendar date, not a real one.</summary>
|
||||
internal sealed record CreateSchoolRequest(string? Name, DateTime StartDate, IReadOnlyList<string>? ModIds, MapLayout? Map);
|
||||
internal sealed record CreateSchoolRequest(
|
||||
string? Name,
|
||||
DateTime StartDate,
|
||||
IReadOnlyList<string>? ModIds,
|
||||
MapLayout? Map,
|
||||
string? NameSetId);
|
||||
|
||||
internal sealed record SchoolResponse(int Id, string Name, DateTime GameTime, bool Running, byte SpeedIndex)
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ internal abstract record GameCommand
|
||||
DateTime StartDate,
|
||||
IReadOnlyList<string>? ExtraModIds,
|
||||
MapLayout? Map,
|
||||
string? NameSetId,
|
||||
TaskCompletionSource<SchoolCreationOutcome> Result) : GameCommand;
|
||||
|
||||
internal sealed record DeleteSchool(int SchoolId, TaskCompletionSource<bool> Result) : GameCommand;
|
||||
|
||||
@@ -216,10 +216,28 @@ internal sealed class GameLoopService(
|
||||
return;
|
||||
}
|
||||
|
||||
DefCatalog catalog;
|
||||
try
|
||||
{
|
||||
catalog = mods.LoadCatalog(packIds);
|
||||
}
|
||||
catch (Exception ex) when (ex is ContentLoadException or SchoolContentUnavailableException)
|
||||
{
|
||||
command.Result.TrySetResult(new SchoolCreationOutcome(null, SchoolCreationError.InvalidCatalog));
|
||||
return;
|
||||
}
|
||||
|
||||
var nameSetId = ResolveNameSetId(catalog, command.NameSetId);
|
||||
if (nameSetId is null)
|
||||
{
|
||||
command.Result.TrySetResult(new SchoolCreationOutcome(null, SchoolCreationError.UnknownNameSet));
|
||||
return;
|
||||
}
|
||||
|
||||
var id = _nextId++;
|
||||
store.WriteNextId(_nextId);
|
||||
|
||||
var worker = SpawnWorker(id, normalized, command.StartDate, running: true, ClockSpeed.DefaultIndex, isNew: true, packIds, command.Map);
|
||||
var worker = SpawnWorker(id, normalized, command.StartDate, running: true, ClockSpeed.DefaultIndex, isNew: true, packIds, command.Map, nameSetId);
|
||||
Track(worker);
|
||||
worker.Start();
|
||||
|
||||
@@ -385,7 +403,8 @@ internal sealed class GameLoopService(
|
||||
save.SpeedIndex,
|
||||
isNew: false,
|
||||
save.ModIds,
|
||||
save.Map);
|
||||
save.Map,
|
||||
save.NameSetId);
|
||||
worker.Start();
|
||||
|
||||
try
|
||||
@@ -431,7 +450,8 @@ internal sealed class GameLoopService(
|
||||
int speedIndex,
|
||||
bool isNew,
|
||||
IReadOnlyList<string>? modIds,
|
||||
MapLayout? map) =>
|
||||
MapLayout? map,
|
||||
string? nameSetId) =>
|
||||
new(
|
||||
id,
|
||||
name,
|
||||
@@ -441,6 +461,7 @@ internal sealed class GameLoopService(
|
||||
isNew,
|
||||
modIds,
|
||||
map,
|
||||
nameSetId,
|
||||
_options,
|
||||
clients,
|
||||
metrics,
|
||||
@@ -449,6 +470,30 @@ internal sealed class GameLoopService(
|
||||
onFailed: schoolId => commands.Enqueue(new GameCommand.WorkerFailed(schoolId)),
|
||||
loggerFactory.CreateLogger($"HSchool.Server.Game.SchoolWorker.{id}"));
|
||||
|
||||
/// <summary>
|
||||
/// Empty request uses the first placeable set (core's Slavic). A named id must exist in the
|
||||
/// catalog already loaded for this pack list — unknown extras were rejected above.
|
||||
/// </summary>
|
||||
internal static string? ResolveNameSetId(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)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(requested))
|
||||
{
|
||||
return available[0];
|
||||
}
|
||||
|
||||
return available.Contains(requested, StringComparer.Ordinal) ? requested : null;
|
||||
}
|
||||
|
||||
private void Track(SchoolWorker worker)
|
||||
{
|
||||
_workers[worker.Id] = worker;
|
||||
|
||||
@@ -23,6 +23,8 @@ internal sealed class SchoolSave
|
||||
public IReadOnlyList<string>? ModIds { get; init; }
|
||||
|
||||
public MapLayout? Map { get; init; }
|
||||
|
||||
public string? NameSetId { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>Allocates school ids that survive a process restart.</summary>
|
||||
@@ -152,6 +154,7 @@ internal sealed class SchoolStore
|
||||
SpeedIndex = save.SpeedIndex,
|
||||
ModIds = save.ModIds,
|
||||
Map = save.Map,
|
||||
NameSetId = save.NameSetId,
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -29,6 +29,7 @@ internal sealed class SchoolWorker
|
||||
private readonly bool _isNew;
|
||||
private readonly IReadOnlyList<string>? _modIds;
|
||||
private readonly MapLayout? _savedMap;
|
||||
private readonly string? _nameSetId;
|
||||
private readonly Action<int> _onFailed;
|
||||
|
||||
private readonly int _id;
|
||||
@@ -53,6 +54,7 @@ internal sealed class SchoolWorker
|
||||
bool isNew,
|
||||
IReadOnlyList<string>? modIds,
|
||||
MapLayout? savedMap,
|
||||
string? nameSetId,
|
||||
SimulationOptions options,
|
||||
ClientRegistry clients,
|
||||
GameMetrics metrics,
|
||||
@@ -69,6 +71,7 @@ internal sealed class SchoolWorker
|
||||
_isNew = isNew;
|
||||
_modIds = modIds;
|
||||
_savedMap = savedMap;
|
||||
_nameSetId = nameSetId;
|
||||
_options = options;
|
||||
_clients = clients;
|
||||
_metrics = metrics;
|
||||
@@ -411,6 +414,7 @@ internal sealed class SchoolWorker
|
||||
SpeedIndex = school.Clock.SpeedIndex,
|
||||
ModIds = school.Catalog?.PackIds,
|
||||
Map = school.Map,
|
||||
NameSetId = _nameSetId,
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"defName": "EyeColor",
|
||||
"kind": "choice",
|
||||
"options": [
|
||||
{ "value": "BrownEyes", "weight": 40 },
|
||||
{ "value": "BlueEyes", "weight": 20 },
|
||||
{ "value": "GrayEyes", "weight": 20 },
|
||||
{ "value": "GreenEyes", "weight": 12 },
|
||||
{ "value": "HazelEyes", "weight": 8 },
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"defName": "HairColor",
|
||||
"kind": "choice",
|
||||
"options": [
|
||||
{ "value": "BlackHair", "weight": 25 },
|
||||
{ "value": "BrownHair", "weight": 40 },
|
||||
{ "value": "BlondHair", "weight": 20 },
|
||||
{ "value": "RedHair", "weight": 8 },
|
||||
{ "value": "GrayHair", "weight": 2, "ageMin": 40 },
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"defName": "Height",
|
||||
"kind": "number",
|
||||
"distributions": [
|
||||
{ "sex": "male", "ageMin": 6, "ageMax": 9, "distribution": { "mean": 128, "stdDev": 6 }, "range": { "min": 110, "max": 150 } },
|
||||
{ "sex": "male", "ageMin": 10, "ageMax": 13, "distribution": { "mean": 150, "stdDev": 8 }, "range": { "min": 128, "max": 175 } },
|
||||
{ "sex": "male", "ageMin": 14, "ageMax": 17, "distribution": { "mean": 172, "stdDev": 8 }, "range": { "min": 150, "max": 195 } },
|
||||
{ "sex": "male", "ageMin": 18, "distribution": { "mean": 176, "stdDev": 7 }, "range": { "min": 155, "max": 205 } },
|
||||
{ "sex": "female", "ageMin": 6, "ageMax": 9, "distribution": { "mean": 127, "stdDev": 6 }, "range": { "min": 108, "max": 148 } },
|
||||
{ "sex": "female", "ageMin": 10, "ageMax": 13, "distribution": { "mean": 148, "stdDev": 7 }, "range": { "min": 128, "max": 170 } },
|
||||
{ "sex": "female", "ageMin": 14, "ageMax": 17, "distribution": { "mean": 163, "stdDev": 6 }, "range": { "min": 145, "max": 185 } },
|
||||
{ "sex": "female", "ageMin": 18, "distribution": { "mean": 164, "stdDev": 6 }, "range": { "min": 145, "max": 190 } },
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"defName": "Weight",
|
||||
"kind": "number",
|
||||
"distributions": [
|
||||
{ "sex": "male", "ageMin": 6, "ageMax": 9, "distribution": { "mean": 27, "stdDev": 5 }, "range": { "min": 16, "max": 45 } },
|
||||
{ "sex": "male", "ageMin": 10, "ageMax": 13, "distribution": { "mean": 42, "stdDev": 8 }, "range": { "min": 25, "max": 70 } },
|
||||
{ "sex": "male", "ageMin": 14, "ageMax": 17, "distribution": { "mean": 62, "stdDev": 10 }, "range": { "min": 40, "max": 95 } },
|
||||
{ "sex": "male", "ageMin": 18, "distribution": { "mean": 78, "stdDev": 12 }, "range": { "min": 50, "max": 130 } },
|
||||
{ "sex": "female", "ageMin": 6, "ageMax": 9, "distribution": { "mean": 26, "stdDev": 5 }, "range": { "min": 15, "max": 44 } },
|
||||
{ "sex": "female", "ageMin": 10, "ageMax": 13, "distribution": { "mean": 42, "stdDev": 8 }, "range": { "min": 24, "max": 70 } },
|
||||
{ "sex": "female", "ageMin": 14, "ageMax": 17, "distribution": { "mean": 54, "stdDev": 8 }, "range": { "min": 38, "max": 85 } },
|
||||
{ "sex": "female", "ageMin": 18, "distribution": { "mean": 62, "stdDev": 10 }, "range": { "min": 42, "max": 110 } },
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
{
|
||||
"defName": "Slavic",
|
||||
"patronymicRule": "slavic",
|
||||
"defaultGivenDeclension": "hard",
|
||||
"defaultSurnameDeclension": "ov",
|
||||
"maleGiven": [
|
||||
{ "form": "Александр" },
|
||||
{ "form": "Алексей" },
|
||||
{ "form": "Андрей" },
|
||||
{ "form": "Антон" },
|
||||
{ "form": "Артём" },
|
||||
{ "form": "Борис" },
|
||||
{ "form": "Вадим" },
|
||||
{ "form": "Валерий" },
|
||||
{ "form": "Виктор" },
|
||||
{ "form": "Виталий" },
|
||||
{ "form": "Владимир" },
|
||||
{ "form": "Владислав" },
|
||||
{ "form": "Григорий" },
|
||||
{ "form": "Денис" },
|
||||
{ "form": "Дмитрий" },
|
||||
{ "form": "Евгений" },
|
||||
{ "form": "Егор" },
|
||||
{ "form": "Иван" },
|
||||
{ "form": "Игорь", "declension": "soft" },
|
||||
{ "form": "Илья", "declension": "ya" },
|
||||
{ "form": "Кирилл" },
|
||||
{ "form": "Константин" },
|
||||
{ "form": "Максим" },
|
||||
{ "form": "Михаил" },
|
||||
{ "form": "Никита", "declension": "a" },
|
||||
{ "form": "Николай" },
|
||||
{ "form": "Олег" },
|
||||
{ "form": "Павел" },
|
||||
{ "form": "Пётр" },
|
||||
{ "form": "Роман" },
|
||||
{ "form": "Сергей" },
|
||||
{ "form": "Станислав" },
|
||||
{ "form": "Степан" },
|
||||
{ "form": "Фёдор" },
|
||||
{ "form": "Юрий" },
|
||||
],
|
||||
"femaleGiven": [
|
||||
{ "form": "Александра", "declension": "a" },
|
||||
{ "form": "Алина", "declension": "a" },
|
||||
{ "form": "Анастасия", "declension": "iya" },
|
||||
{ "form": "Анна", "declension": "a" },
|
||||
{ "form": "Валентина", "declension": "a" },
|
||||
{ "form": "Валерия", "declension": "iya" },
|
||||
{ "form": "Вера", "declension": "a" },
|
||||
{ "form": "Виктория", "declension": "iya" },
|
||||
{ "form": "Дарья", "declension": "ya" },
|
||||
{ "form": "Екатерина", "declension": "a" },
|
||||
{ "form": "Елена", "declension": "a" },
|
||||
{ "form": "Елизавета", "declension": "a" },
|
||||
{ "form": "Ирина", "declension": "a" },
|
||||
{ "form": "Ксения", "declension": "iya" },
|
||||
{
|
||||
"form": "Любовь",
|
||||
"cases": {
|
||||
"nom": "Любовь",
|
||||
"gen": "Любови",
|
||||
"dat": "Любови",
|
||||
"acc": "Любовь",
|
||||
"ins": "Любовью",
|
||||
"pre": "Любови",
|
||||
},
|
||||
},
|
||||
{ "form": "Людмила", "declension": "a" },
|
||||
{ "form": "Маргарита", "declension": "a" },
|
||||
{ "form": "Мария", "declension": "iya" },
|
||||
{ "form": "Надежда", "declension": "a" },
|
||||
{ "form": "Наталья", "declension": "ya" },
|
||||
{ "form": "Нина", "declension": "a" },
|
||||
{ "form": "Оксана", "declension": "a" },
|
||||
{ "form": "Ольга", "declension": "a" },
|
||||
{ "form": "Полина", "declension": "a" },
|
||||
{ "form": "Светлана", "declension": "a" },
|
||||
{ "form": "София", "declension": "iya" },
|
||||
{ "form": "Татьяна", "declension": "a" },
|
||||
{ "form": "Юлия", "declension": "iya" },
|
||||
{ "form": "Яна", "declension": "a" },
|
||||
{ "form": "Вероника", "declension": "a" },
|
||||
{ "form": "Диана", "declension": "a" },
|
||||
{ "form": "Марина", "declension": "a" },
|
||||
],
|
||||
"surnames": [
|
||||
{ "male": "Иванов", "female": "Иванова" },
|
||||
{ "male": "Петров", "female": "Петрова" },
|
||||
{ "male": "Смирнов", "female": "Смирнова" },
|
||||
{ "male": "Кузнецов", "female": "Кузнецова" },
|
||||
{ "male": "Попов", "female": "Попова" },
|
||||
{ "male": "Васильев", "female": "Васильева" },
|
||||
{ "male": "Соколов", "female": "Соколова" },
|
||||
{ "male": "Михайлов", "female": "Михайлова" },
|
||||
{ "male": "Новиков", "female": "Новикова" },
|
||||
{ "male": "Фёдоров", "female": "Фёдорова" },
|
||||
{ "male": "Морозов", "female": "Морозова" },
|
||||
{ "male": "Волков", "female": "Волкова" },
|
||||
{ "male": "Алексеев", "female": "Алексеева" },
|
||||
{ "male": "Лебедев", "female": "Лебедева" },
|
||||
{ "male": "Семёнов", "female": "Семёнова" },
|
||||
{ "male": "Егоров", "female": "Егорова" },
|
||||
{ "male": "Павлов", "female": "Павлова" },
|
||||
{ "male": "Козлов", "female": "Козлова" },
|
||||
{ "male": "Степанов", "female": "Степанова" },
|
||||
{ "male": "Николаев", "female": "Николаева" },
|
||||
{ "male": "Орлов", "female": "Орлова" },
|
||||
{ "male": "Андреев", "female": "Андреева" },
|
||||
{ "male": "Макаров", "female": "Макарова" },
|
||||
{ "male": "Никитин", "female": "Никитина", "declension": "in" },
|
||||
{ "male": "Захаров", "female": "Захарова" },
|
||||
{ "male": "Зайцев", "female": "Зайцева" },
|
||||
{ "male": "Соловьёв", "female": "Соловьёва" },
|
||||
{ "male": "Борисов", "female": "Борисова" },
|
||||
{ "male": "Яковлев", "female": "Яковлева" },
|
||||
{ "male": "Григорьев", "female": "Григорьева" },
|
||||
{ "male": "Романов", "female": "Романова" },
|
||||
{ "male": "Воробьёв", "female": "Воробьёва" },
|
||||
{ "male": "Сергеев", "female": "Сергеева" },
|
||||
{ "male": "Кузьмин", "female": "Кузьмина", "declension": "in" },
|
||||
{ "male": "Фролов", "female": "Фролова" },
|
||||
{ "male": "Александров", "female": "Александрова" },
|
||||
{ "male": "Дмитриев", "female": "Дмитриева" },
|
||||
{ "male": "Королёв", "female": "Королёва" },
|
||||
{ "male": "Громов", "female": "Громова" },
|
||||
{ "male": "Ильин", "female": "Ильина", "declension": "in" },
|
||||
{ "male": "Козловский", "female": "Козловская", "declension": "sky" },
|
||||
{ "male": "Орловский", "female": "Орловская", "declension": "sky" },
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{ "defName": "Sleep", "initial": 1, "decayPerHour": 0, "min": 0, "max": 1 },
|
||||
{ "defName": "Hunger", "initial": 1, "decayPerHour": 0, "min": 0, "max": 1 },
|
||||
{ "defName": "Toilet", "initial": 1, "decayPerHour": 0, "min": 0, "max": 1 },
|
||||
{ "defName": "Social", "initial": 1, "decayPerHour": 0, "min": 0, "max": 1 },
|
||||
]
|
||||
@@ -0,0 +1,69 @@
|
||||
[
|
||||
{
|
||||
"defName": "Mathematics",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 50, "stdDev": 14 },
|
||||
"ageMeans": [
|
||||
{ "age": 7, "mean": 28 },
|
||||
{ "age": 17, "mean": 55 },
|
||||
],
|
||||
},
|
||||
{
|
||||
"defName": "RussianLanguage",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 52, "stdDev": 13 },
|
||||
"ageMeans": [
|
||||
{ "age": 7, "mean": 32 },
|
||||
{ "age": 17, "mean": 56 },
|
||||
],
|
||||
},
|
||||
{
|
||||
"defName": "Literature",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 50, "stdDev": 14 },
|
||||
},
|
||||
{
|
||||
"defName": "Physics",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 48, "stdDev": 15 },
|
||||
"ageMeans": [
|
||||
{ "age": 12, "mean": 30 },
|
||||
{ "age": 17, "mean": 50 },
|
||||
],
|
||||
},
|
||||
{
|
||||
"defName": "History",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 50, "stdDev": 13 },
|
||||
},
|
||||
{
|
||||
"defName": "PhysicalEducation",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 55, "stdDev": 14 },
|
||||
},
|
||||
{
|
||||
"defName": "Biology",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 50, "stdDev": 13 },
|
||||
},
|
||||
{
|
||||
"defName": "Chemistry",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 48, "stdDev": 15 },
|
||||
},
|
||||
{
|
||||
"defName": "Geography",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 50, "stdDev": 12 },
|
||||
},
|
||||
{
|
||||
"defName": "Informatics",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 48, "stdDev": 16 },
|
||||
},
|
||||
{
|
||||
"defName": "ForeignLanguage",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 50, "stdDev": 15 },
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,30 @@
|
||||
[
|
||||
{
|
||||
"defName": "Agility",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 50, "stdDev": 14 },
|
||||
"bodyLimits": [
|
||||
{ "attribute": "Build", "value": "Obese", "max": 25 },
|
||||
{ "attribute": "Build", "value": "Heavy", "max": 45 },
|
||||
{ "attribute": "Build", "value": "Athletic", "min": 40 },
|
||||
],
|
||||
},
|
||||
{
|
||||
"defName": "Strength",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 50, "stdDev": 14 },
|
||||
"bodyLimits": [
|
||||
{ "attribute": "Build", "value": "Skinny", "max": 45 },
|
||||
{ "attribute": "Build", "value": "Athletic", "min": 40 },
|
||||
],
|
||||
},
|
||||
{
|
||||
"defName": "Endurance",
|
||||
"range": { "min": 0, "max": 100 },
|
||||
"distribution": { "mean": 50, "stdDev": 13 },
|
||||
"bodyLimits": [
|
||||
{ "attribute": "Build", "value": "Obese", "max": 35 },
|
||||
{ "attribute": "Build", "value": "Athletic", "min": 40 },
|
||||
],
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,78 @@
|
||||
[
|
||||
{
|
||||
"defName": "Diligent",
|
||||
"weight": 8,
|
||||
"incompatible": ["Lazy", "AbsentMinded"],
|
||||
"skillModifiers": [
|
||||
{ "skill": "Mathematics", "offset": 8 },
|
||||
{ "skill": "RussianLanguage", "offset": 6 },
|
||||
],
|
||||
},
|
||||
{
|
||||
"defName": "AbsentMinded",
|
||||
"weight": 6,
|
||||
"incompatible": ["Diligent"],
|
||||
"skillModifiers": [
|
||||
{ "skill": "Mathematics", "offset": -6 },
|
||||
{ "skill": "Informatics", "offset": -4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
"defName": "Bully",
|
||||
"weight": 4,
|
||||
"incompatible": ["Kind", "Quiet"],
|
||||
"roles": ["student"],
|
||||
"age": { "min": 7, "max": 18 },
|
||||
"skillModifiers": [
|
||||
{ "skill": "Strength", "offset": 8 },
|
||||
{ "skill": "Literature", "offset": -4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
"defName": "Quiet",
|
||||
"weight": 7,
|
||||
"incompatible": ["Leader", "Bully"],
|
||||
},
|
||||
{
|
||||
"defName": "Leader",
|
||||
"weight": 4,
|
||||
"incompatible": ["Quiet"],
|
||||
"skillModifiers": [
|
||||
{ "skill": "History", "offset": 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
"defName": "Lazy",
|
||||
"weight": 6,
|
||||
"incompatible": ["Diligent"],
|
||||
"skillModifiers": [
|
||||
{ "skill": "PhysicalEducation", "offset": -8 },
|
||||
{ "skill": "Mathematics", "offset": -6 },
|
||||
],
|
||||
},
|
||||
{
|
||||
"defName": "Curious",
|
||||
"weight": 7,
|
||||
"skillModifiers": [
|
||||
{ "skill": "Physics", "offset": 6 },
|
||||
{ "skill": "Informatics", "offset": 6 },
|
||||
],
|
||||
},
|
||||
{
|
||||
"defName": "HotTempered",
|
||||
"weight": 5,
|
||||
"incompatible": ["Quiet"],
|
||||
},
|
||||
{
|
||||
"defName": "Kind",
|
||||
"weight": 8,
|
||||
"incompatible": ["Bully"],
|
||||
},
|
||||
{
|
||||
"defName": "Neat",
|
||||
"weight": 6,
|
||||
"skillModifiers": [
|
||||
{ "skill": "Chemistry", "offset": 4 },
|
||||
],
|
||||
},
|
||||
]
|
||||
@@ -44,4 +44,52 @@
|
||||
"ComputerLab": "Computer lab",
|
||||
"GymHall": "Gym",
|
||||
"ChangingRoom": "Changing room",
|
||||
"Mathematics": "Mathematics",
|
||||
"RussianLanguage": "Russian",
|
||||
"Literature": "Literature",
|
||||
"Physics": "Physics",
|
||||
"History": "History",
|
||||
"PhysicalEducation": "PE",
|
||||
"Biology": "Biology",
|
||||
"Chemistry": "Chemistry",
|
||||
"Geography": "Geography",
|
||||
"Informatics": "Informatics",
|
||||
"ForeignLanguage": "Foreign language",
|
||||
"Agility": "Agility",
|
||||
"Strength": "Strength",
|
||||
"Endurance": "Endurance",
|
||||
"Diligent": "Diligent",
|
||||
"AbsentMinded": "Absent-minded",
|
||||
"Bully": "Bully",
|
||||
"Quiet": "Quiet",
|
||||
"Leader": "Leader",
|
||||
"Lazy": "Lazy",
|
||||
"Curious": "Curious",
|
||||
"HotTempered": "Hot-tempered",
|
||||
"Kind": "Kind",
|
||||
"Neat": "Neat",
|
||||
"Height": "Height",
|
||||
"Weight": "Weight",
|
||||
"HairColor": "Hair colour",
|
||||
"EyeColor": "Eye colour",
|
||||
"BlackHair": "Black",
|
||||
"BrownHair": "Brown",
|
||||
"BlondHair": "Blond",
|
||||
"RedHair": "Red",
|
||||
"GrayHair": "Grey",
|
||||
"BrownEyes": "Brown",
|
||||
"BlueEyes": "Blue",
|
||||
"GrayEyes": "Grey",
|
||||
"GreenEyes": "Green",
|
||||
"HazelEyes": "Hazel",
|
||||
"Sleep": "Sleep",
|
||||
"Hunger": "Hunger",
|
||||
"Toilet": "Toilet",
|
||||
"Social": "Social",
|
||||
"Slavic": "Slavic",
|
||||
"Skinny": "Skinny",
|
||||
"Average": "Average",
|
||||
"Athletic": "Athletic",
|
||||
"Heavy": "Heavy",
|
||||
"Obese": "Obese",
|
||||
}
|
||||
|
||||
@@ -44,4 +44,52 @@
|
||||
"ComputerLab": "Компьютерный класс",
|
||||
"GymHall": "Спортивный зал",
|
||||
"ChangingRoom": "Раздевалка",
|
||||
"Mathematics": "Математика",
|
||||
"RussianLanguage": "Русский язык",
|
||||
"Literature": "Литература",
|
||||
"Physics": "Физика",
|
||||
"History": "История",
|
||||
"PhysicalEducation": "Физкультура",
|
||||
"Biology": "Биология",
|
||||
"Chemistry": "Химия",
|
||||
"Geography": "География",
|
||||
"Informatics": "Информатика",
|
||||
"ForeignLanguage": "Иностранный язык",
|
||||
"Agility": "Ловкость",
|
||||
"Strength": "Сила",
|
||||
"Endurance": "Выносливость",
|
||||
"Diligent": "Усидчивый",
|
||||
"AbsentMinded": "Рассеянный",
|
||||
"Bully": "Задира",
|
||||
"Quiet": "Тихоня",
|
||||
"Leader": "Лидер",
|
||||
"Lazy": "Лентяй",
|
||||
"Curious": "Любопытный",
|
||||
"HotTempered": "Вспыльчивый",
|
||||
"Kind": "Добрый",
|
||||
"Neat": "Аккуратный",
|
||||
"Height": "Рост",
|
||||
"Weight": "Вес",
|
||||
"HairColor": "Цвет волос",
|
||||
"EyeColor": "Цвет глаз",
|
||||
"BlackHair": "Чёрные",
|
||||
"BrownHair": "Каштановые",
|
||||
"BlondHair": "Русые",
|
||||
"RedHair": "Рыжие",
|
||||
"GrayHair": "Седые",
|
||||
"BrownEyes": "Карие",
|
||||
"BlueEyes": "Голубые",
|
||||
"GrayEyes": "Серые",
|
||||
"GreenEyes": "Зелёные",
|
||||
"HazelEyes": "Ореховые",
|
||||
"Sleep": "Сон",
|
||||
"Hunger": "Голод",
|
||||
"Toilet": "Туалет",
|
||||
"Social": "Общение",
|
||||
"Slavic": "Славянский",
|
||||
"Skinny": "Худощавое",
|
||||
"Average": "Обычное",
|
||||
"Athletic": "Атлетическое",
|
||||
"Heavy": "Плотное",
|
||||
"Obese": "Полное",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user