Add nurse care queue and person-card health tab.

Sick people seek MedicalOffice for tend by Medicine skill; symptoms cut talk weight; no heal API.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-21 16:17:51 +03:00
co-authored by Cursor
parent afab014572
commit 33f253c9e3
33 changed files with 1568 additions and 34 deletions
@@ -346,6 +346,71 @@ public class DecisionPlannerTests
Assert.Equal(DecisionPlanner.DutyLessonWeight, peckishLesson.Intent.Weight);
}
[Fact]
public void LowSocialWeight_MakesChatLessAttractiveThanControl()
{
var (catalog, map, walks) = World();
var corridor = map.Rooms.First(room => room.Def == "Corridor").Id;
var needs = new Dictionary<string, float>(StringComparer.Ordinal)
{
["Toilet"] = 1f,
["Hunger"] = 1f,
["Social"] = 0.4f,
["Sleep"] = 1f,
};
var healthy = DecisionPlanner.Decide(
catalog,
map,
walks,
new ActorState(
corridor,
null,
false,
false,
true,
false,
false,
false,
corridor,
needs,
Intent.None,
SocialWeightFactor: 1f),
(_, _) => 0);
var sick = DecisionPlanner.Decide(
catalog,
map,
walks,
new ActorState(
corridor,
null,
false,
false,
true,
false,
false,
false,
corridor,
needs,
Intent.None,
SocialWeightFactor: 0.15f),
(_, _) => 0);
var chatWeight = catalog.Actions[TalkActions.Chat].Weight;
Assert.True(chatWeight * 0.15f < chatWeight);
if (healthy.Intent.ActionId == TalkActions.Chat)
{
Assert.True(
sick.Intent.ActionId != TalkActions.Chat
|| sick.Intent.Weight < healthy.Intent.Weight);
}
else
{
// Control did not pick Chat — still assert the scaled candidate loses to other leisure.
Assert.True(sick.Intent.ActionId != TalkActions.Chat || sick.Intent.Weight <= chatWeight * 0.15f + 1e-3f);
}
}
private static Decision Decide(
DefCatalog catalog,
MapLayout map,