Complete phase 47 romance pack on generic orientation and affinity hooks.
Vanilla catalogs stay without crushes; a content pack ships the overlay so later mods can reuse it.
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
namespace HSchool.People.Tests;
|
||||
|
||||
public class AffinityTests
|
||||
{
|
||||
private static readonly DateTime AsOf = new(2012, 3, 31, 6, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
[Fact]
|
||||
public void SixteenYearOlds_NeverPair_AtAnyOpinion()
|
||||
{
|
||||
var catalog = Fixtures.RomanceCatalog();
|
||||
var boy = Pupil("a", year: 10, age: 16, female: false, "Bisexual");
|
||||
var girl = Pupil("b", year: 10, age: 16, female: true, "Bisexual");
|
||||
SetOpinion(boy, girl.Id, 100);
|
||||
SetOpinion(girl, boy.Id, 100);
|
||||
var roster = RosterOf(boy, girl, classYear: 10);
|
||||
Affinity.Refresh(catalog, roster, AsOf);
|
||||
|
||||
Assert.Contains("b", boy.Bonds!.Crushes);
|
||||
Assert.Contains("a", girl.Bonds!.Crushes);
|
||||
Assert.Null(boy.Bonds.PartnerId);
|
||||
Assert.Null(girl.Bonds.PartnerId);
|
||||
Assert.False(Affinity.CanFormPair(catalog, roster, boy, girl, AsOf));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FirstYear_DoesNotCrushEleventh()
|
||||
{
|
||||
var catalog = Fixtures.RomanceCatalog();
|
||||
var young = Pupil("c1", year: 1, age: 7, female: true, "Bisexual", classId: "y1");
|
||||
var old = Pupil("c11", year: 11, age: 17, female: false, "Bisexual", classId: "y11");
|
||||
SetOpinion(young, old.Id, 100);
|
||||
var roster = new Roster(
|
||||
[young, old],
|
||||
[],
|
||||
[
|
||||
new SchoolClass("y1", 1, "А", "r1", 16, [young.Id]),
|
||||
new SchoolClass("y11", 11, "А", "r11", 16, [old.Id]),
|
||||
]);
|
||||
Affinity.Refresh(catalog, roster, AsOf);
|
||||
|
||||
Assert.DoesNotContain("c11", young.Bonds!.Crushes);
|
||||
Assert.False(Affinity.CanHaveSympathy(catalog, roster, young, old, AsOf));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Staff_NeverGetsCrushOnStudent()
|
||||
{
|
||||
var catalog = Fixtures.RomanceCatalog();
|
||||
var teacher = Staff("t", female: false, "Bisexual");
|
||||
var pupil = Pupil("p", year: 8, age: 14, female: true, "Bisexual");
|
||||
SetOpinion(teacher, pupil.Id, 100);
|
||||
SetOpinion(pupil, teacher.Id, 100);
|
||||
var roster = RosterOf(teacher, pupil, classYear: 8);
|
||||
Affinity.Refresh(catalog, roster, AsOf);
|
||||
|
||||
Assert.DoesNotContain(pupil.Id, teacher.Bonds!.Crushes);
|
||||
Assert.Contains(teacher.Id, pupil.Bonds!.Crushes);
|
||||
Assert.Null(teacher.Bonds.PartnerId);
|
||||
Assert.Null(pupil.Bonds.PartnerId);
|
||||
Assert.False(Affinity.CanHaveSympathy(catalog, roster, teacher, pupil, AsOf));
|
||||
Assert.True(Affinity.CanHaveSympathy(catalog, roster, pupil, teacher, AsOf));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StaffPair_IsAllowedWhenBothAdults()
|
||||
{
|
||||
var catalog = Fixtures.RomanceCatalog();
|
||||
var left = Staff("s1", female: false, "Bisexual");
|
||||
var right = Staff("s2", female: true, "Bisexual");
|
||||
SetOpinion(left, right.Id, 80);
|
||||
SetOpinion(right, left.Id, 80);
|
||||
var roster = new Roster([left, right], [], []);
|
||||
var events = Affinity.Refresh(catalog, roster, AsOf);
|
||||
|
||||
Assert.Equal(right.Id, left.Bonds!.PartnerId);
|
||||
Assert.Equal(left.Id, right.Bonds!.PartnerId);
|
||||
Assert.Contains(events, row => row.Type == Affinity.Pair);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PairBreak_BlocksNewPairUntilNextDay()
|
||||
{
|
||||
var catalog = Fixtures.RomanceCatalog();
|
||||
var left = Staff("s1", female: false, "Bisexual");
|
||||
var right = Staff("s2", female: true, "Bisexual");
|
||||
var third = Staff("s3", female: true, "Bisexual");
|
||||
SetOpinion(left, right.Id, 80);
|
||||
SetOpinion(right, left.Id, 80);
|
||||
var roster = new Roster([left, right, third], [], []);
|
||||
Affinity.Refresh(catalog, roster, AsOf);
|
||||
Assert.Equal(right.Id, left.Bonds!.PartnerId);
|
||||
|
||||
SetOpinion(left, right.Id, 0);
|
||||
Affinity.Refresh(catalog, roster, AsOf);
|
||||
Assert.Null(left.Bonds.PartnerId);
|
||||
Assert.NotNull(left.Bonds.PairEndedOn);
|
||||
|
||||
SetOpinion(left, third.Id, 80);
|
||||
SetOpinion(third, left.Id, 80);
|
||||
Affinity.Refresh(catalog, roster, AsOf);
|
||||
Assert.Null(left.Bonds.PartnerId);
|
||||
|
||||
Affinity.Refresh(catalog, roster, AsOf.AddDays(1));
|
||||
Assert.Equal(third.Id, left.Bonds.PartnerId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AdjacentYearStudents_CanHaveSympathy()
|
||||
{
|
||||
var catalog = Fixtures.RomanceCatalog();
|
||||
var younger = Pupil("y", year: 9, age: 15, female: true, "Bisexual", classId: "c9");
|
||||
var older = Pupil("o", year: 10, age: 18, female: false, "Bisexual", classId: "c10");
|
||||
SetOpinion(younger, older.Id, 80);
|
||||
var roster = new Roster(
|
||||
[younger, older],
|
||||
[],
|
||||
[
|
||||
new SchoolClass("c9", 9, "А", "r9", 16, [younger.Id]),
|
||||
new SchoolClass("c10", 10, "А", "r10", 16, [older.Id]),
|
||||
]);
|
||||
Assert.True(Affinity.CanHaveSympathy(catalog, roster, younger, older, AsOf));
|
||||
Affinity.Refresh(catalog, roster, AsOf);
|
||||
Assert.Contains(older.Id, younger.Bonds!.Crushes);
|
||||
}
|
||||
|
||||
private static void SetOpinion(Person person, string targetId, int value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
OpinionStore.Remove(person, targetId);
|
||||
return;
|
||||
}
|
||||
|
||||
OpinionStore.Set(person, targetId, value);
|
||||
}
|
||||
|
||||
private static Roster RosterOf(Person first, Person second, int classYear)
|
||||
{
|
||||
var pupils = new[] { first, second }.Where(person => person.IsStudent).Select(person => person.Id).ToArray();
|
||||
return new Roster(
|
||||
[first, second],
|
||||
[],
|
||||
[new SchoolClass("c", classYear, "А", "room", 16, pupils)]);
|
||||
}
|
||||
|
||||
private static Person Pupil(string id, int year, int age, bool female, string orientation, string? classId = null)
|
||||
{
|
||||
_ = year;
|
||||
var birth = AsOf.AddYears(-age);
|
||||
return AdultLike(id, female, orientation, isStudent: true, isStaff: false, birth, classId ?? "c");
|
||||
}
|
||||
|
||||
private static Person Staff(string id, bool female, string orientation) =>
|
||||
AdultLike(id, female, orientation, isStudent: false, isStaff: true, AsOf.AddYears(-30), classId: null);
|
||||
|
||||
private static Person AdultLike(
|
||||
string id,
|
||||
bool female,
|
||||
string orientation,
|
||||
bool isStudent,
|
||||
bool isStaff,
|
||||
DateTime birth,
|
||||
string? classId)
|
||||
{
|
||||
var cases = new CaseTable
|
||||
{
|
||||
Nom = id,
|
||||
Gen = id,
|
||||
Dat = id,
|
||||
Acc = id,
|
||||
Ins = id,
|
||||
Pre = id,
|
||||
};
|
||||
return new Person
|
||||
{
|
||||
Id = id,
|
||||
FamilyId = "f",
|
||||
Female = female,
|
||||
BirthDate = DateTime.SpecifyKind(birth, DateTimeKind.Utc),
|
||||
Name = new PersonName(id, id, id, cases, cases, cases),
|
||||
IsStudent = isStudent,
|
||||
IsStaff = isStaff,
|
||||
IsParent = false,
|
||||
ClassId = classId,
|
||||
Numbers = new Dictionary<string, int>(StringComparer.Ordinal),
|
||||
Choices = new Dictionary<string, string>(StringComparer.Ordinal),
|
||||
Skills = new Dictionary<string, int>(StringComparer.Ordinal),
|
||||
Traits = [],
|
||||
Needs = new Dictionary<string, float>(StringComparer.Ordinal),
|
||||
Opinions = new Dictionary<string, int>(StringComparer.Ordinal),
|
||||
Orientation = orientation,
|
||||
Bonds = new PersonBonds(),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user