Files
gamedev-the-steward/world/active_world_adapter.gd
T
2026-07-17 00:34:30 +02:00

108 lines
3.1 KiB
GDScript

class_name ActiveWorldAdapter
extends Node
const LoadedResourceSpatialIndexScript := preload(
"res://world/resource_nodes/LoadedResourceSpatialIndex.gd"
)
@export var pantry_storage: StorageNode
@export var woodpile_storage: StorageNode
@export_range(4.0, 128.0, 1.0) var resource_cell_size := 24.0
var _resource_index := LoadedResourceSpatialIndexScript.new()
func _ready() -> void:
_resource_index.configure(resource_cell_size)
add_to_group("active_world_adapter")
rebuild_resource_index()
func rebuild_resource_index() -> void:
_resource_index.clear()
for node in ResourceNode.get_all():
_resource_index.register_node(node, node.state)
func register_resource_node(node: ResourceNode, state: ResourceStateRecord = null) -> bool:
return _resource_index.register_node(node, state)
func unregister_resource_node(node_id: StringName) -> void:
_resource_index.unregister_node(node_id)
func get_resource_candidates(action_id: StringName) -> Array[Dictionary]:
return _resource_index.get_all_candidates(action_id)
func get_resource_candidates_in_radius(
action_id: StringName,
origin: Vector3,
max_distance: float,
min_distance_exclusive: float = -1.0
) -> Array[Dictionary]:
return _resource_index.get_candidates_in_radius(
action_id, origin, max_distance, min_distance_exclusive
)
func get_resource_query_profile(action_id: StringName, origin: Vector3) -> Dictionary:
return _resource_index.get_query_profile(action_id, origin)
func get_resource_nodes_in_radius(origin: Vector3, max_distance: float) -> Array[ResourceNode]:
return _resource_index.get_nodes_in_radius(origin, max_distance)
func get_resource_index_stats() -> Dictionary:
return _resource_index.get_stats()
func get_activity_target(action_id: StringName, origin: Vector3 = Vector3.ZERO) -> Dictionary:
var best_candidate: Dictionary = {}
var best_distance := INF
for candidate in get_activity_candidates(action_id):
var position: Vector3 = candidate["position"]
var distance := origin.distance_squared_to(position)
if distance < best_distance:
best_distance = distance
best_candidate = candidate
if not best_candidate.is_empty():
return best_candidate
match action_id:
SimulationIds.ACTION_EAT:
return _get_storage_target(pantry_storage)
SimulationIds.ACTION_DEPOSIT_FOOD, SimulationIds.ACTION_WITHDRAW_FOOD:
return _get_storage_target(pantry_storage)
SimulationIds.ACTION_DEPOSIT_WOOD:
return _get_storage_target(woodpile_storage)
return {}
func get_activity_candidates(action_id: StringName) -> Array[Dictionary]:
var candidates: Array[Dictionary] = []
for candidate in ActivitySite.get_all():
var site := candidate as ActivitySite
if site == null:
continue
if not site.supports_action(action_id):
continue
candidates.append(
{
"target_id": String(site.site_id),
"position": site.get_interaction_position(),
"capacity": site.capacity
}
)
return candidates
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()
}