feat: starvation balance rework and Ghibli wind-stroke visuals
- Reduce hunger rate to 0.125/tick (~25/day) for ~6-7 day death timeline - Slow energy drain: idle 0.125, travel 0.5, work 0.5, complete 0.0625/tick - Use exact binary fractions for all rates to preserve float precision in save/load - Starving/critically-hungry NPCs always override sleep to seek food first - Extend starvation death threshold from 20 to 600 ticks (~3 days of starvation) - Add calligraphy-style wind stroke particles (WindStrokes scene + shader) - Two wind stroke emitters in valley and ridge for Ghibli atmosphere - Rework terrain macro-variation colors for vibrant warm-green palette - Enhance environment: stronger glow/bloom, higher saturation, warmer sky/fog/ambient
This commit is contained in:
@@ -15,19 +15,21 @@ func advance_npc(npc: SimNPC, village: SimVillage) -> void:
|
||||
|
||||
|
||||
func _update_needs(npc: SimNPC, village: SimVillage) -> void:
|
||||
npc.hunger += 3.0 * village.food_modifier
|
||||
npc.hunger += 0.125 * village.food_modifier
|
||||
match npc.task_state:
|
||||
SimNPC.TASK_STATE_IDLE:
|
||||
npc.energy -= 0.5
|
||||
npc.energy -= 0.125
|
||||
SimNPC.TASK_STATE_TRAVELING:
|
||||
npc.energy -= 2.0
|
||||
npc.energy -= 0.5
|
||||
SimNPC.TASK_STATE_WORKING:
|
||||
if npc.current_task == SimulationIds.ACTION_SLEEP:
|
||||
npc.energy = minf(npc.energy + 5.0, 100.0)
|
||||
elif npc.current_task != SimulationIds.ACTION_REST:
|
||||
npc.energy -= 3.0
|
||||
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.25
|
||||
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
|
||||
|
||||
@@ -22,6 +22,31 @@ func select_action(npc: SimNPC, village: SimVillage, time_of_day: float = 0.5) -
|
||||
if npc.is_dead:
|
||||
return null
|
||||
|
||||
if npc.is_starving:
|
||||
if npc.get_inventory_amount(SimulationIds.RESOURCE_FOOD) >= 1.0:
|
||||
return ActionSelectionResult.new(
|
||||
SimulationIds.ACTION_EAT, 1.0, "Starving and carrying food"
|
||||
)
|
||||
if village.food > 0:
|
||||
return ActionSelectionResult.new(
|
||||
SimulationIds.ACTION_WITHDRAW_FOOD, 1.0, "Starving; pantry has food"
|
||||
)
|
||||
return ActionSelectionResult.new(
|
||||
SimulationIds.ACTION_GATHER_FOOD, -1.0, "Starving; must find food"
|
||||
)
|
||||
if npc.hunger > 80.0:
|
||||
if npc.get_inventory_amount(SimulationIds.RESOURCE_FOOD) >= 1.0:
|
||||
return ActionSelectionResult.new(
|
||||
SimulationIds.ACTION_EAT, -1.0, "Critically hungry and carrying food"
|
||||
)
|
||||
if village.food > 0:
|
||||
return ActionSelectionResult.new(
|
||||
SimulationIds.ACTION_WITHDRAW_FOOD, -1.0, "Critically hungry; pantry has food"
|
||||
)
|
||||
return ActionSelectionResult.new(
|
||||
SimulationIds.ACTION_GATHER_FOOD, -1.0, "Critically hungry; must find food"
|
||||
)
|
||||
|
||||
var period := _get_period(time_of_day)
|
||||
|
||||
if period == SchedulePeriod.SLEEP:
|
||||
|
||||
Reference in New Issue
Block a user