class_name ActiveWorldAdapter extends Node @export var pantry_storage: StorageNode func get_resource_candidates(action_id: StringName) -> Array[Dictionary]: var candidates: Array[Dictionary] = [] for node in ResourceNode.get_all(): if node.action_id != action_id or node.interaction_point == null: continue candidates.append( { "target_id": String(node.node_id), "position": node.interaction_point.global_position, "resource_id": String(node.resource_id), "safety_risk": node.safety_risk, "comfort_distance": node.comfort_distance, "discovery_priority": node.discovery_priority } ) return candidates func get_activity_target(action_id: StringName, origin: Vector3 = Vector3.ZERO) -> Dictionary: match action_id: SimulationIds.ACTION_PATROL: return _get_activity_site_target(action_id, origin) SimulationIds.ACTION_STUDY: return _get_activity_site_target(action_id, origin) SimulationIds.ACTION_REST: return _get_activity_site_target(action_id, origin) SimulationIds.ACTION_EAT: return _get_storage_target(pantry_storage) SimulationIds.ACTION_DEPOSIT_FOOD, SimulationIds.ACTION_WITHDRAW_FOOD: return _get_storage_target(pantry_storage) return {} func _get_activity_site_target(action_id: StringName, origin: Vector3) -> Dictionary: var best_site: ActivitySite var best_distance := INF for candidate in ActivitySite.get_all(): var site := candidate as ActivitySite if site == null: continue if not site.supports_action(action_id): continue var distance := origin.distance_squared_to(site.get_interaction_position()) if distance < best_distance: best_distance = distance best_site = site if best_site == null: return {} return { "target_id": String(best_site.site_id), "position": best_site.get_interaction_position() } func _get_storage_target(storage_node: StorageNode) -> Dictionary: if storage_node == null: return {} return { "target_id": String(storage_node.storage_id), "position": storage_node.get_interaction_position() }