feat: introduce identity-backed goat

This commit is contained in:
Rijad Zuzo
2026-07-26 22:26:00 +02:00
parent 1f09ebe6b6
commit f79c2bb630
47 changed files with 1903 additions and 96 deletions
+10 -1
View File
@@ -23,7 +23,8 @@ func select_action(
time_of_day: float = 0.5,
all_npcs: Array = [],
opportunity_helper: OpportunityHelperResult = null,
population_view: SimulationPopulationView = null
population_view: SimulationPopulationView = null,
animal_feed_name: String = ""
) -> ActionSelectionResult:
if npc.is_dead:
return null
@@ -126,6 +127,14 @@ func select_action(
return ActionSelectionResult.new(
SimulationIds.ACTION_REST, -1.0, "Energy is below the rest threshold"
)
if not animal_feed_name.is_empty():
var feed_definition := SimulationDefinitions.get_action(SimulationIds.ACTION_FEED_ANIMAL)
if _get_cost_rejection(feed_definition, village).is_empty():
return ActionSelectionResult.new(
SimulationIds.ACTION_FEED_ANIMAL,
-1.0,
"%s is hungry; pantry food is available" % animal_feed_name
)
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, population_view
@@ -17,6 +17,8 @@ func resolve(
)
SimulationIds.TARGET_ACTIVITY:
return _resolve_activity(npc, origin, simulation_manager, active_world_adapter)
SimulationIds.TARGET_ANIMAL:
return _resolve_animal(npc, origin, simulation_manager, active_world_adapter)
SimulationIds.TARGET_FREE:
return {
"target_id": "", "position": origin + simulation_manager.get_wander_offset(npc.id)
@@ -202,6 +204,32 @@ func _resolve_activity(
return active_world_adapter.get_activity_target(npc.current_task, origin)
func _resolve_animal(
npc: SimNPC, origin: Vector3, simulation_manager: Node, active_world_adapter: Node
) -> Dictionary:
if not active_world_adapter.has_method("get_animal_candidates"):
return {}
var best: Dictionary = {}
var best_distance := INF
var candidates: Array[Dictionary] = active_world_adapter.get_animal_candidates(npc.current_task)
for candidate in candidates:
var animal_id := StringName(candidate["target_id"])
var state: AnimalStateRecord = simulation_manager.animal_care.get_state(animal_id)
if state == null or not state.can_npc_feed() or not state.is_available_for(npc.id):
continue
var position: Vector3 = candidate["position"]
var distance := origin.distance_squared_to(position)
if distance < best_distance:
best_distance = distance
best = candidate
if best.is_empty():
return {}
var target_id := StringName(best["target_id"])
if not simulation_manager.animal_care.reserve(target_id, npc.id):
return {}
return best
func score_resource_candidate(
npc: SimNPC, origin: Vector3, position: Vector3, state: ResourceStateRecord
) -> float: