feat: NPC mourning behavior on housemate death
When an NPC dies from starvation, their highest-familiarity companion enters mourning for 100 ticks (~half a day). Mourning NPCs skip work: they rest if energy is low, otherwise wander near home. Mourning_ticks counts down each tick through ActionExecutionSystem and is serialized for save/load continuity with backward-compatible default of 0. This gives the familiarity graph its first behavioral consequence.
This commit is contained in:
@@ -149,6 +149,7 @@ func simulate_tick() -> void:
|
||||
npc_died.emit(npc)
|
||||
npc_task_changed.emit(npc, old_task, npc.current_task)
|
||||
record_narrative_event(SimulationIds.EVENT_NPC_DIED, npc.id)
|
||||
_notify_mourning(npc)
|
||||
|
||||
if debug_logs:
|
||||
print("[SimulationManager] NPC died: ", npc.npc_name)
|
||||
@@ -491,6 +492,30 @@ func _npc_inventory_id(npc_id: int) -> StringName:
|
||||
return StringName("npc_%d_inventory" % npc_id)
|
||||
|
||||
|
||||
func _notify_mourning(dead_npc: SimNPC) -> void:
|
||||
var best_id := -1
|
||||
var best_score := -1.0
|
||||
for key in dead_npc.familiarity:
|
||||
var other_id: int = int(key)
|
||||
var score: float = float(dead_npc.familiarity[key])
|
||||
if score > best_score:
|
||||
best_score = score
|
||||
best_id = other_id
|
||||
if best_id < 0:
|
||||
return
|
||||
for npc in npcs:
|
||||
if npc.id == best_id and not npc.is_dead:
|
||||
npc.mourning_ticks = 100
|
||||
if debug_logs:
|
||||
print(
|
||||
"[SimulationManager] ",
|
||||
npc.npc_name,
|
||||
" is mourning ",
|
||||
dead_npc.npc_name
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
func _record_economic_event(
|
||||
event_type: StringName,
|
||||
actor_id: int,
|
||||
|
||||
Reference in New Issue
Block a user