4b5fc858f8
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.
41 lines
1.2 KiB
GDScript
41 lines
1.2 KiB
GDScript
class_name ActionExecutionSystem
|
|
extends RefCounted
|
|
|
|
|
|
func advance_npc(npc: SimNPC, village: SimVillage) -> void:
|
|
if npc.is_dead:
|
|
return
|
|
_update_needs(npc, village)
|
|
if npc.mourning_ticks > 0:
|
|
npc.mourning_ticks -= 1
|
|
if npc.is_dead or npc.task_state != SimNPC.TASK_STATE_WORKING:
|
|
return
|
|
npc.task_progress += 1.0
|
|
if npc.task_progress >= npc.task_duration:
|
|
npc.task_complete = true
|
|
npc.task_state = SimNPC.TASK_STATE_COMPLETE
|
|
|
|
|
|
func _update_needs(npc: SimNPC, village: SimVillage) -> void:
|
|
npc.hunger += 0.125 * village.food_modifier
|
|
match npc.task_state:
|
|
SimNPC.TASK_STATE_IDLE:
|
|
npc.energy -= 0.125
|
|
SimNPC.TASK_STATE_TRAVELING:
|
|
npc.energy -= 0.5
|
|
SimNPC.TASK_STATE_WORKING:
|
|
if npc.current_task == SimulationIds.ACTION_SLEEP:
|
|
npc.energy = minf(npc.energy + 1.0, 100.0)
|
|
elif npc.current_task == SimulationIds.ACTION_REST:
|
|
pass
|
|
else:
|
|
npc.energy -= 0.5
|
|
SimNPC.TASK_STATE_COMPLETE:
|
|
npc.energy -= 0.0625
|
|
npc.hunger = clamp(npc.hunger, 0.0, 100.0)
|
|
npc.energy = clamp(npc.energy, 0.0, 100.0)
|
|
npc.is_starving = npc.hunger >= 90.0
|
|
npc.starvation_ticks = npc.starvation_ticks + 1 if npc.is_starving else 0
|
|
if npc.starvation_ticks >= npc.starvation_death_threshold:
|
|
npc.die_from_starvation()
|