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:
@@ -206,6 +206,15 @@ public class TalkCirclesTests
|
||||
Assert.Equal(2, TalkCircles.AppearanceModifier(ApparelIssue.None));
|
||||
Assert.Equal(-2, TalkCircles.AppearanceModifier(ApparelIssue.Formality));
|
||||
Assert.Equal(0, TalkCircles.AppearanceModifier(ApparelIssue.Color));
|
||||
|
||||
var (catalog, _, _) = World();
|
||||
var rules = catalog.BehaviorRules!;
|
||||
var topic = catalog.Topics["TopicAppearance"];
|
||||
var from = Person("a", ["RussianLanguage"]);
|
||||
var to = Person("b", ["RussianLanguage"]);
|
||||
var compliment = TalkCircles.OpinionDelta(from, to, topic, 50f, true, TalkActions.Chat, ApparelIssue.None, rules, catalog);
|
||||
var mockery = TalkCircles.OpinionDelta(from, to, topic, 50f, true, TalkActions.Chat, ApparelIssue.Formality, rules, catalog);
|
||||
Assert.True(compliment > mockery);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -219,6 +228,42 @@ public class TalkCirclesTests
|
||||
Assert.Equal(50f + rules.TalkSkillPerHour, afterTalkHour);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LessonWhisperFactor_CutsWhisper_LeavesOrdinaryChat()
|
||||
{
|
||||
var (catalog, _, _) = World();
|
||||
var rules = catalog.BehaviorRules!;
|
||||
Assert.True(TalkCircles.LessonWhisperFactor(TalkActions.Whisper, rules) < 1f);
|
||||
Assert.Equal(1f, TalkCircles.LessonWhisperFactor(TalkActions.Chat, rules));
|
||||
Assert.Equal(rules.LessonWhisperSkillFactor, TalkCircles.LessonWhisperFactor(TalkActions.Whisper, rules));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Outgoing_RaisesMaxSize_WhenTalkCircleMaxIsBelowHardLimit()
|
||||
{
|
||||
var (catalog, _, _) = World();
|
||||
var rules = new BehaviorDef { DefName = "Rules", TalkCircleMin = 2, TalkCircleMax = 3 };
|
||||
Assert.Equal(3, TalkCircles.MaxSize(TalkActions.Chat, rules, [], catalog));
|
||||
Assert.Equal(4, TalkCircles.MaxSize(TalkActions.Chat, rules, ["Outgoing"], catalog));
|
||||
Assert.Equal(4, TalkCircles.MaxSize(TalkActions.Chat, catalog.BehaviorRules, ["Outgoing"], catalog));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Joiner_IsRejectedWhenEitherSideIsEnemy()
|
||||
{
|
||||
var (catalog, _, _) = World();
|
||||
var rules = catalog.BehaviorRules!;
|
||||
var sitting = Person("a", []) with { Opinions = new Dictionary<string, int>(StringComparer.Ordinal) { ["c"] = 10 } };
|
||||
var friend = Person("b", []) with { Opinions = new Dictionary<string, int>(StringComparer.Ordinal) { ["a"] = 50 } };
|
||||
var enemy = Person("c", []) with { Opinions = new Dictionary<string, int>(StringComparer.Ordinal) { ["a"] = -55 } };
|
||||
Assert.True(TalkCircles.JoinerFits(friend, [sitting], rules));
|
||||
Assert.False(TalkCircles.JoinerFits(enemy, [sitting], rules));
|
||||
|
||||
var hated = Person("d", []) with { Opinions = new Dictionary<string, int>(StringComparer.Ordinal) };
|
||||
var hater = Person("a", []) with { Opinions = new Dictionary<string, int>(StringComparer.Ordinal) { ["d"] = -55 } };
|
||||
Assert.False(TalkCircles.JoinerFits(hated, [hater], rules));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StudyOnlyPolicy_NeverPicksNonStudyTopic()
|
||||
{
|
||||
|
||||
@@ -52,6 +52,44 @@ public class TalkCircleTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Enemy_StartsNeighborCircle_InsteadOfJoiningFriends()
|
||||
{
|
||||
var (school, pupils) = FivePupilsOnBreak();
|
||||
using (school)
|
||||
{
|
||||
var first = pupils[0];
|
||||
var second = pupils[1];
|
||||
var enemy = pupils[2];
|
||||
var ally = pupils[3];
|
||||
OpinionStore.Set(first, second.Id, 55);
|
||||
OpinionStore.Set(second, first.Id, 55);
|
||||
OpinionStore.Set(enemy, first.Id, -55);
|
||||
OpinionStore.Set(first, enemy.Id, -55);
|
||||
OpinionStore.Set(enemy, second.Id, -55);
|
||||
OpinionStore.Set(second, enemy.Id, -55);
|
||||
OpinionStore.Set(enemy, ally.Id, 55);
|
||||
OpinionStore.Set(ally, enemy.Id, 55);
|
||||
|
||||
PlaceAt(school, first.Id, "corridor-1");
|
||||
PlaceAt(school, second.Id, "corridor-1");
|
||||
Assert.True(school.TryStartAction(first.Id, TalkActions.Chat));
|
||||
var friends = school.TalkCircleOf(first.Id);
|
||||
Assert.NotNull(friends);
|
||||
Assert.DoesNotContain(enemy.Id, friends.MemberIds);
|
||||
|
||||
PlaceAt(school, enemy.Id, "corridor-1");
|
||||
PlaceAt(school, ally.Id, "corridor-1");
|
||||
Assert.True(school.TryStartAction(enemy.Id, TalkActions.Chat));
|
||||
var neighbor = school.TalkCircleOf(enemy.Id);
|
||||
Assert.NotNull(neighbor);
|
||||
Assert.NotEqual(friends.MemberIds, neighbor.MemberIds);
|
||||
Assert.Contains(ally.Id, neighbor.MemberIds);
|
||||
Assert.DoesNotContain(first.Id, neighbor.MemberIds);
|
||||
Assert.Equal(friends.MemberIds, school.TalkCircleOf(first.Id)?.MemberIds);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FifthPerson_DoesNotJoinFullCircle()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user