feat: add witnessed knowledge and wind ambience

This commit is contained in:
Rijad Zuzo
2026-07-11 11:27:40 +02:00
parent 2ed93de6d1
commit 81409650df
72 changed files with 3001 additions and 606 deletions
+28 -27
View File
@@ -1,12 +1,7 @@
class_name ActionSelectionSystem
extends RefCounted
enum SchedulePeriod {
WORK,
SLEEP,
MEAL,
DISCRETIONARY
}
enum SchedulePeriod { WORK, SLEEP, MEAL, DISCRETIONARY }
const SLEEP_BEGIN := 0.88
const SLEEP_END := 0.15
@@ -17,9 +12,14 @@ const DINNER_END := 0.8
const WORK_BEGIN := 0.28
const WORK_END := 0.85
const UNAVAILABLE_ACTION_SCORE := -1000000.0
const RELATIONSHIP_AID_PANTRY_THRESHOLD := 25.0
var relationship_system: RefCounted
func select_action(npc: SimNPC, village: SimVillage, time_of_day: float = 0.5, all_npcs: Array = []) -> ActionSelectionResult:
func select_action(
npc: SimNPC, village: SimVillage, time_of_day: float = 0.5, all_npcs: Array = []
) -> ActionSelectionResult:
if npc.is_dead:
return null
@@ -70,9 +70,7 @@ func select_action(npc: SimNPC, village: SimVillage, time_of_day: float = 0.5, a
return ActionSelectionResult.new(
SimulationIds.ACTION_EAT, -1.0, "Night-time hunger; eating from inventory"
)
return ActionSelectionResult.new(
SimulationIds.ACTION_SLEEP, -1.0, "Night-time; going home"
)
return ActionSelectionResult.new(SimulationIds.ACTION_SLEEP, -1.0, "Night-time; going home")
if period == SchedulePeriod.MEAL:
if npc.hunger > 50.0:
@@ -112,6 +110,16 @@ func select_action(npc: SimNPC, village: SimVillage, time_of_day: float = 0.5, a
return ActionSelectionResult.new(
SimulationIds.ACTION_REST, -1.0, "Energy is below the rest threshold"
)
if village.food <= RELATIONSHIP_AID_PANTRY_THRESHOLD and relationship_system != null:
var trusted_starving_npc: SimNPC = relationship_system.get_trusted_starving_subject(
npc.id, all_npcs
)
if trusted_starving_npc != null:
return ActionSelectionResult.new(
SimulationIds.ACTION_GATHER_FOOD,
-1.0,
"Helping %s, a trusted acquaintance who is starving" % trusted_starving_npc.npc_name
)
if period == SchedulePeriod.DISCRETIONARY:
var roll := npc.random_source.randf()
@@ -120,10 +128,10 @@ func select_action(npc: SimNPC, village: SimVillage, time_of_day: float = 0.5, a
SimulationIds.ACTION_WANDER, -1.0, "Discretionary wander"
)
return _choose_best_work_action(npc, village, all_npcs)
return _choose_best_work_action(npc, village)
func _choose_best_work_action(npc: SimNPC, village: SimVillage, all_npcs: Array) -> ActionSelectionResult:
func _choose_best_work_action(npc: SimNPC, village: SimVillage) -> ActionSelectionResult:
var scores := {
SimulationIds.ACTION_GATHER_FOOD:
_calculate_score(
@@ -177,16 +185,6 @@ func _choose_best_work_action(npc: SimNPC, village: SimVillage, all_npcs: Array)
if not rejection.is_empty():
scores[action_id] = UNAVAILABLE_ACTION_SCORE
rejections[action_id] = rejection
for familiar_id in npc.familiarity:
if not familiar_id is int:
continue
var other_task: StringName
for other in all_npcs:
if other.id == familiar_id and not other.is_dead:
other_task = other.current_task
break
if other_task in scores:
scores[other_task] = float(scores[other_task]) + 0.3
var best_action := SimulationIds.ACTION_GATHER_FOOD
var best_score: float = scores[best_action]
for action_id in [
@@ -207,11 +205,14 @@ func _get_cost_rejection(definition: ActionDefinition, village: SimVillage) -> S
var available := _get_village_resource_amount(village, definition.completion_cost_resource_id)
if available >= definition.completion_cost_amount:
return ""
return "Needs %.0f %s (%.1f available)" % [
definition.completion_cost_amount,
String(definition.completion_cost_resource_id).capitalize(),
available,
]
return (
"Needs %.0f %s (%.1f available)"
% [
definition.completion_cost_amount,
String(definition.completion_cost_resource_id).capitalize(),
available,
]
)
func _get_village_resource_amount(village: SimVillage, resource_id: StringName) -> float:
+3 -1
View File
@@ -57,7 +57,9 @@ func _resolve_activity(
var best: Dictionary = {}
var best_distance := INF
var candidates: Array[Dictionary] = active_world_adapter.get_activity_candidates(npc.current_task)
var candidates: Array[Dictionary] = active_world_adapter.get_activity_candidates(
npc.current_task
)
for candidate in candidates:
var target_id := StringName(candidate["target_id"])
var capacity := maxi(int(candidate.get("capacity", 1)), 1)