Add talk circles with TopicDef, staff/phone chat, and opinion outcomes.
This commit is contained in:
@@ -324,6 +324,23 @@ internal static class PresenceSystem
|
||||
{
|
||||
var now = school.Clock.Time;
|
||||
var walks = school.Walks!;
|
||||
var slot = SchoolDay.At(school.Catalog!, now, school.SchoolWeekDays);
|
||||
var weekday = SchoolDay.WeekdayIndex(now);
|
||||
var lessons = Duty.LessonsToday(person, ClassOf(school, person), school.Timetable, weekday);
|
||||
var bound = Duty.IsOtherStaff(person)
|
||||
? slot.Kind != DaySlotKind.Outside
|
||||
: slot.Kind == DaySlotKind.Lesson && lessons.Any(lesson => lesson.Period == slot.Index);
|
||||
if (activity.IsActive && TalkActions.IsTalk(activity.ActionId))
|
||||
{
|
||||
if (!bound)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
TalkCircleSystem.Interrupt(school, person.Id);
|
||||
activity = PersonActivity.Idle;
|
||||
}
|
||||
|
||||
if (!presence.IsOnCampus)
|
||||
{
|
||||
intent = Intent.None;
|
||||
@@ -369,16 +386,11 @@ internal static class PresenceSystem
|
||||
return null;
|
||||
}
|
||||
|
||||
var slot = SchoolDay.At(school.Catalog!, now, school.SchoolWeekDays);
|
||||
var weekday = SchoolDay.WeekdayIndex(now);
|
||||
var lessons = Duty.LessonsToday(person, ClassOf(school, person), school.Timetable, weekday);
|
||||
var bound = Duty.IsOtherStaff(person)
|
||||
? slot.Kind != DaySlotKind.Outside
|
||||
: slot.Kind == DaySlotKind.Lesson && lessons.Any(lesson => lesson.Period == slot.Index);
|
||||
var frame = school.Catalog!.DayFrame;
|
||||
var lunchOpen = frame is not null
|
||||
&& SchoolDay.IsLunchWindow(frame, slot, ClassOf(school, person)?.Year);
|
||||
var apparel = ApparelPresence.Build(school, person, ClassOf(school, person));
|
||||
var talk = BuildTalkContext(school, person, bound, lunchOpen, slot);
|
||||
var state = new ActorState(
|
||||
presence.NodeId,
|
||||
presence.DestinationId,
|
||||
@@ -392,7 +404,8 @@ internal static class PresenceSystem
|
||||
needs.Values,
|
||||
intent,
|
||||
lunchOpen,
|
||||
apparel);
|
||||
apparel,
|
||||
talk);
|
||||
var decision = DecisionPlanner.Decide(
|
||||
school.Catalog!,
|
||||
school.Map!,
|
||||
@@ -401,17 +414,19 @@ internal static class PresenceSystem
|
||||
(node, thing) => occupied.GetValueOrDefault((node, thing)));
|
||||
|
||||
var changing = activity.IsActive && ActivitySystem.IsChangeClothes(activity.ActionId);
|
||||
var inTalk = activity.IsActive && TalkActions.IsTalk(activity.ActionId);
|
||||
|
||||
if (decision.WalkTo is not null
|
||||
&& !decision.WalkTo.Equals(presence.NodeId, StringComparison.Ordinal)
|
||||
&& activity.IsActive
|
||||
&& !changing)
|
||||
&& !changing
|
||||
&& !inTalk)
|
||||
{
|
||||
activity = PersonActivity.Idle;
|
||||
}
|
||||
|
||||
intent = decision.Intent;
|
||||
if (decision.WalkTo is not null && !changing)
|
||||
if (decision.WalkTo is not null && !changing && !inTalk)
|
||||
{
|
||||
presence = PresenceStepper.StartWalk(presence, walks, decision.WalkTo, headingHome: false);
|
||||
}
|
||||
@@ -523,6 +538,40 @@ internal static class PresenceSystem
|
||||
return new Intent(kind, row.GoalId, row.GoalWeight, row.GoalAction);
|
||||
}
|
||||
|
||||
private static TalkPlannerContext BuildTalkContext(
|
||||
School school,
|
||||
Person person,
|
||||
bool boundToLesson,
|
||||
bool lunchOpen,
|
||||
DaySlot slot)
|
||||
{
|
||||
var opinions = person.Opinions as IReadOnlyDictionary<string, int> ?? new Dictionary<string, int>(StringComparer.Ordinal);
|
||||
var nodes = SnapshotPersonNodes(school);
|
||||
var friendPull = !boundToLesson && (slot.Kind == DaySlotKind.Break || lunchOpen);
|
||||
return new TalkPlannerContext(
|
||||
person.Id,
|
||||
opinions,
|
||||
nodes,
|
||||
person.ClassId,
|
||||
TalkCircles.HasPhone(person.Items),
|
||||
friendPull,
|
||||
school.Catalog?.BehaviorRules);
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> SnapshotPersonNodes(School school)
|
||||
{
|
||||
var nodes = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
var world = school.World;
|
||||
world.Query(in People, (ref PersonIdentity identity, ref Presence presence) =>
|
||||
{
|
||||
if (presence.IsOnCampus && presence.NodeId is not null)
|
||||
{
|
||||
nodes[identity.Id] = presence.NodeId;
|
||||
}
|
||||
});
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private static SchoolClass? ClassOf(School school, Person person)
|
||||
{
|
||||
if (person.ClassId is null)
|
||||
|
||||
Reference in New Issue
Block a user