Merge branch 'phase/41-opinions'
# Conflicts: # docs/phases/README.md
This commit is contained in:
@@ -88,7 +88,8 @@ internal static class PersonCardReader
|
||||
Capacity(person, skills, catalog),
|
||||
person.LockerRoomId is not null
|
||||
|| person.Items.Any(item => item.Location.Equals(ItemLocations.Locker, StringComparison.Ordinal)),
|
||||
person.Items.Count(item => item.Location.Equals(ItemLocations.Home, StringComparison.Ordinal)));
|
||||
person.Items.Count(item => item.Location.Equals(ItemLocations.Home, StringComparison.Ordinal)),
|
||||
Connections: Connections(roster, person, catalog, locale));
|
||||
}
|
||||
|
||||
private static IReadOnlyDictionary<string, float>? LiveNeeds(World world, string personId)
|
||||
@@ -376,8 +377,8 @@ internal static class PersonCardReader
|
||||
}
|
||||
|
||||
var people = roster.People.ToDictionary(member => member.Id, StringComparer.Ordinal);
|
||||
var inParents = family.ParentIds.Contains(person.Id, StringComparer.Ordinal);
|
||||
var inChildren = family.ChildIds.Contains(person.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) : [],
|
||||
@@ -385,6 +386,19 @@ internal static class PersonCardReader
|
||||
inParents ? Relatives(family.ParentIds, people, except: person.Id) : []);
|
||||
}
|
||||
|
||||
private static bool InFamily(IReadOnlyList<string> ids, string id)
|
||||
{
|
||||
foreach (var candidate in ids)
|
||||
{
|
||||
if (candidate.Equals(id, StringComparison.Ordinal))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static IReadOnlyList<PersonRelResponse> Relatives(
|
||||
IReadOnlyList<string> ids,
|
||||
IReadOnlyDictionary<string, Person> people,
|
||||
@@ -403,4 +417,98 @@ internal static class PersonCardReader
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
private static PersonConnectionsResponse Connections(
|
||||
Roster roster,
|
||||
Person person,
|
||||
DefCatalog? catalog,
|
||||
string locale)
|
||||
{
|
||||
var familyIds = OpinionStore.FamilyMemberIds(roster, person);
|
||||
var people = roster.People.ToDictionary(member => member.Id, StringComparer.Ordinal);
|
||||
var family = FamilyWithOpinions(roster, person, people, catalog, locale);
|
||||
var others = new List<PersonOpinionLinkResponse>();
|
||||
foreach (var (targetId, value) in person.Opinions)
|
||||
{
|
||||
if (familyIds.Contains(targetId) || !people.TryGetValue(targetId, out var target))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
others.Add(Link(target, value, catalog, locale));
|
||||
}
|
||||
|
||||
others.Sort((left, right) =>
|
||||
{
|
||||
var byAbs = Math.Abs(right.Opinion).CompareTo(Math.Abs(left.Opinion));
|
||||
return byAbs != 0
|
||||
? byAbs
|
||||
: string.Compare(left.FullName, right.FullName, StringComparison.Ordinal);
|
||||
});
|
||||
|
||||
var top = catalog?.BehaviorRules?.OpinionTopCount ?? 5;
|
||||
var friends = others.Where(row => row.Opinion > 0).Take(top).ToArray();
|
||||
var enemies = others.Where(row => row.Opinion < 0).Take(top).ToArray();
|
||||
return new PersonConnectionsResponse(family, friends, enemies, others);
|
||||
}
|
||||
|
||||
private static PersonFamilyResponse FamilyWithOpinions(
|
||||
Roster roster,
|
||||
Person person,
|
||||
IReadOnlyDictionary<string, Person> people,
|
||||
DefCatalog? catalog,
|
||||
string locale)
|
||||
{
|
||||
var family = roster.Families.FirstOrDefault(candidate => candidate.Id.Equals(person.FamilyId, StringComparison.Ordinal));
|
||||
if (family is null)
|
||||
{
|
||||
return new PersonFamilyResponse([], [], [], []);
|
||||
}
|
||||
|
||||
var inParents = InFamily(family.ParentIds, person.Id);
|
||||
var inChildren = InFamily(family.ChildIds, person.Id);
|
||||
return new PersonFamilyResponse(
|
||||
inChildren ? RelativesWithOpinions(family.ParentIds, people, person, except: person.Id, catalog, locale) : [],
|
||||
inParents ? RelativesWithOpinions(family.ChildIds, people, person, except: person.Id, catalog, locale) : [],
|
||||
inChildren ? RelativesWithOpinions(family.ChildIds, people, person, except: person.Id, catalog, locale) : [],
|
||||
inParents ? RelativesWithOpinions(family.ParentIds, people, person, except: person.Id, catalog, locale) : []);
|
||||
}
|
||||
|
||||
private static IReadOnlyList<PersonRelResponse> RelativesWithOpinions(
|
||||
IReadOnlyList<string> ids,
|
||||
IReadOnlyDictionary<string, Person> people,
|
||||
Person person,
|
||||
string except,
|
||||
DefCatalog? catalog,
|
||||
string locale)
|
||||
{
|
||||
var rows = new List<PersonRelResponse>();
|
||||
foreach (var id in ids)
|
||||
{
|
||||
if (id.Equals(except, StringComparison.Ordinal) || !people.TryGetValue(id, out var relative))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int? opinion = null;
|
||||
string? label = null;
|
||||
if (person.Opinions.TryGetValue(id, out var value))
|
||||
{
|
||||
opinion = value;
|
||||
label = catalog is null ? OpinionLabels.BandId(null, value) : OpinionLabels.Label(catalog, locale, value);
|
||||
}
|
||||
|
||||
rows.Add(new PersonRelResponse(relative.Id, relative.Name.Full, relative.Female, opinion, label));
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
private static PersonOpinionLinkResponse Link(Person target, int opinion, DefCatalog? catalog, string locale) =>
|
||||
new(
|
||||
target.Id,
|
||||
target.Name.Full,
|
||||
target.Female,
|
||||
opinion,
|
||||
catalog is null ? OpinionLabels.BandId(null, opinion) : OpinionLabels.Label(catalog, locale, opinion));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user