feat: add ResourceNode system with target selection and reservation
Phase 1-2 of the ResourceNode migration plan: - Create ResourceNode class (world/resource_nodes/) with extraction, reservation, nearest-available selection, and debug label - Place 4 resource instances in main.tscn (2 berry bushes, 2 trees) - Add target_id to SimNPC for tracking which node an NPC is using - Add set_npc_target_id and release_npc_reservation to SimulationManager with cleanup on task change, completion, and death - Update WorldViewManager to query available ResourceNodes first, falling back to zone markers with a logged warning
This commit is contained in:
@@ -83,6 +83,11 @@ func update_npc_targets() -> void:
|
||||
continue
|
||||
|
||||
var visual = active_npc_visuals[npc.id]
|
||||
var resource_pos := _try_get_resource_target(npc, npc.current_task)
|
||||
if resource_pos != null:
|
||||
visual.set_target_position(resource_pos)
|
||||
continue
|
||||
|
||||
var target := get_target_for_task(npc.current_task)
|
||||
|
||||
if target == null:
|
||||
@@ -108,6 +113,32 @@ func get_target_for_task(task: String) -> Marker3D:
|
||||
_:
|
||||
return rest_zone
|
||||
|
||||
func _try_get_resource_target(npc: SimNPC, task: String):
|
||||
var action_map := {
|
||||
"gather_food": &"gather_food",
|
||||
"gather_wood": &"gather_wood"
|
||||
}
|
||||
var action_id := action_map.get(task) as StringName
|
||||
if action_id == null:
|
||||
return null
|
||||
|
||||
var visual = active_npc_visuals.get(npc.id) as Node3D
|
||||
if visual == null:
|
||||
return null
|
||||
|
||||
var node := ResourceNode.find_available(action_id, npc.id, visual.global_position)
|
||||
if node == null:
|
||||
debug_log("No available resource node for %s, using zone fallback" % task)
|
||||
return null
|
||||
|
||||
if not node.reserve(npc.id):
|
||||
debug_log("Failed to reserve %s for %s" % [node.node_id, npc.npc_name])
|
||||
return null
|
||||
|
||||
npc.target_id = node.node_id
|
||||
debug_log("%s reserved %s for %s" % [npc.npc_name, node.node_id, task])
|
||||
return node.interaction_point.global_position
|
||||
|
||||
func _on_npc_task_changed(npc: SimNPC, old_task: String, new_task: String) -> void:
|
||||
if DEBUG_LOGS:
|
||||
debug_log("%s changed task: %s -> %s" % [npc.npc_name, old_task, new_task])
|
||||
@@ -116,6 +147,11 @@ func _on_npc_task_changed(npc: SimNPC, old_task: String, new_task: String) -> vo
|
||||
return
|
||||
|
||||
var visual = active_npc_visuals[npc.id]
|
||||
var resource_pos := _try_get_resource_target(npc, new_task)
|
||||
if resource_pos != null:
|
||||
visual.set_target_position(resource_pos)
|
||||
return
|
||||
|
||||
var target := get_target_for_task(new_task)
|
||||
|
||||
if target != null:
|
||||
|
||||
Reference in New Issue
Block a user