using HSchool.Content; using HSchool.People; using HSchool.Server.Api; namespace HSchool.Server.Game; internal static partial class PersonCardReader { private static IReadOnlyList Body(Person person, DefCatalog? catalog, string locale) { var rows = new List(); if (catalog is not null) { foreach (var def in catalog.BodyAttributes.Values) { if (def.Abstract) { continue; } if (def.Kind == BodyAttributeKind.Number && person.Numbers.TryGetValue(def.DefName, out var number)) { rows.Add(new LabeledStatResponse(def.DefName, catalog.Label(locale, def), number.ToString())); } else if (def.Kind == BodyAttributeKind.Choice && person.Choices.TryGetValue(def.DefName, out var choice)) { rows.Add(new LabeledStatResponse(def.DefName, catalog.Label(locale, def), catalog.Text(locale, choice))); } } } else { foreach (var (id, number) in person.Numbers) { rows.Add(new LabeledStatResponse(id, id, number.ToString())); } foreach (var (id, choice) in person.Choices) { rows.Add(new LabeledStatResponse(id, id, choice)); } } if (person.Choices.TryGetValue(BodyBuilds.Attribute, out var build) && rows.TrueForAll(row => row.Id != BodyBuilds.Attribute)) { var label = catalog?.Text(locale, BodyBuilds.Attribute) ?? BodyBuilds.Attribute; var value = catalog?.Text(locale, build) ?? build; rows.Add(new LabeledStatResponse(BodyBuilds.Attribute, label, value)); } return rows; } private static IReadOnlyList Skills( Person person, IReadOnlyDictionary? live, DefCatalog? catalog, string locale) { if (catalog is null) { if (live is not null) { return live .Select(pair => new LabeledStatResponse(pair.Key, pair.Key, FormatSkill(pair.Value))) .ToArray(); } return person.Skills .Select(pair => new LabeledStatResponse(pair.Key, pair.Key, pair.Value.ToString())) .ToArray(); } var rows = new List(); foreach (var def in catalog.Skills.Values) { if (def.Abstract) { continue; } if (live is not null) { if (!live.TryGetValue(def.DefName, out var liveValue)) { continue; } rows.Add(new LabeledStatResponse(def.DefName, catalog.Label(locale, def), FormatSkill(liveValue))); continue; } if (!person.Skills.TryGetValue(def.DefName, out var value)) { continue; } rows.Add(new LabeledStatResponse(def.DefName, catalog.Label(locale, def), value.ToString())); } return rows; } private static string FormatSkill(float value) => Math.Round(value, 2).ToString("0.##"); private static IReadOnlyList Traits(Person person, DefCatalog? catalog, string locale) { var rows = new List(person.Traits.Count); foreach (var id in person.Traits) { var label = catalog is not null && catalog.Traits.TryGetValue(id, out var def) ? catalog.Label(locale, def) : id; rows.Add(new DefLabelResponse(id, label)); } return rows; } private static IReadOnlyList Needs( IReadOnlyDictionary values, DefCatalog? catalog, string locale) { if (catalog is null) { return values.Select(pair => new NeedStatResponse(pair.Key, pair.Key, pair.Value)).ToArray(); } var rows = new List(); foreach (var def in catalog.Needs.Values) { if (def.Abstract || !values.TryGetValue(def.DefName, out var value)) { continue; } rows.Add(new NeedStatResponse(def.DefName, catalog.Label(locale, def), value)); } return rows; } private static PersonFamilyResponse Family(Roster roster, Person person) { var family = roster.Families.FirstOrDefault(candidate => candidate.Id.Equals(person.FamilyId, StringComparison.Ordinal)); if (family is null) { return new PersonFamilyResponse([], [], [], []); } var people = roster.People.ToDictionary(member => member.Id, StringComparer.Ordinal); var inParents = InFamily(family.ParentIds, person.Id); var inChildren = InFamily(family.ChildIds, person.Id); return new PersonFamilyResponse( inChildren ? Relatives(family.ParentIds, people, except: person.Id) : [], inParents ? Relatives(family.ChildIds, people, except: person.Id) : [], inChildren ? Relatives(family.ChildIds, people, except: person.Id) : [], inParents ? Relatives(family.ParentIds, people, except: person.Id) : []); } private static bool InFamily(IReadOnlyList ids, string id) { foreach (var candidate in ids) { if (candidate.Equals(id, StringComparison.Ordinal)) { return true; } } return false; } private static IReadOnlyList Relatives( IReadOnlyList ids, IReadOnlyDictionary people, string except) { var rows = new List(); foreach (var id in ids) { if (id.Equals(except, StringComparison.Ordinal) || !people.TryGetValue(id, out var relative)) { continue; } rows.Add(new PersonRelResponse(relative.Id, relative.Name.Full, relative.Female)); } return rows; } }