Refuse enemies joining an open talk circle.

RankInvitees already skipped enemies when a circle formed; a later Chat in the same node still joined without checking opinions.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-20 17:25:36 +03:00
co-authored by Cursor
parent b2b56d7af9
commit a80c6f097a
4 changed files with 135 additions and 13 deletions
+27 -13
View File
@@ -147,10 +147,10 @@ internal static class TalkCircleSystem
return TryStartPhone(school, person, nodeId, action);
}
var existing = FindOpenCircle(school, nodeId, actionId);
if (existing is not null)
var existing = FindOpenCircle(school, nodeId, actionId, person);
if (existing is not null && JoinCircle(school, existing, personId, action))
{
return JoinCircle(school, existing, personId, action);
return true;
}
return TryStartGroup(school, person, nodeId, action);
@@ -319,6 +319,14 @@ internal static class TalkCircleSystem
return false;
}
var sitting = circle.Members
.Select(id => school.Roster!.People.First(row => row.Id.Equals(id, StringComparison.Ordinal)))
.ToArray();
if (!TalkCircles.JoinerFits(person, sitting, rules))
{
return false;
}
circle.Members.Add(personId);
circle.Members.Sort(StringComparer.Ordinal);
school.TalkCircleByPerson[personId] = circle.Id;
@@ -326,20 +334,26 @@ internal static class TalkCircleSystem
return true;
}
private static ActiveTalkCircle? FindOpenCircle(School school, string nodeId, string actionId)
private static ActiveTalkCircle? FindOpenCircle(School school, string nodeId, string actionId, Person joiner)
{
var rules = school.Catalog!.BehaviorRules;
var max = TalkCircles.MaxSize(actionId, rules, [], school.Catalog);
foreach (var circle in school.TalkCirclesById.Values)
{
if (circle.NodeId.Equals(nodeId, StringComparison.Ordinal)
&& circle.ActionId.Equals(actionId, StringComparison.Ordinal)
&& circle.RemainingMinutes > 0)
if (!circle.NodeId.Equals(nodeId, StringComparison.Ordinal)
|| !circle.ActionId.Equals(actionId, StringComparison.Ordinal)
|| circle.RemainingMinutes <= 0
|| circle.Members.Count >= max)
{
var rules = school.Catalog!.BehaviorRules;
var max = TalkCircles.MaxSize(actionId, rules, [], school.Catalog);
if (circle.Members.Count < max)
{
return circle;
}
continue;
}
var sitting = circle.Members
.Select(id => school.Roster!.People.First(row => row.Id.Equals(id, StringComparison.Ordinal)))
.ToArray();
if (TalkCircles.JoinerFits(joiner, sitting, rules))
{
return circle;
}
}