Files
2026-08-12 20:51:01 +02:00

63 lines
2.0 KiB
GDScript

class_name StorageRoutingPolicy
extends RefCounted
var catalog: ContentCatalog
func _init(content_catalog: ContentCatalog = null) -> void:
catalog = content_catalog
func resolve_definition(
item_id: StringName, available_storage_ids: Array[StringName] = []
) -> StorageDefinition:
var candidates := get_candidates(item_id, available_storage_ids)
return candidates[0] if not candidates.is_empty() else null
func resolve_state(
item_id: StringName, requested_amount: float, states: Array[StorageStateRecord]
) -> StorageStateRecord:
if not is_finite(requested_amount) or requested_amount <= 0.0:
return null
var states_by_id := {}
var available_ids: Array[StringName] = []
for state in states:
if state == null or state.get_available_capacity() < requested_amount:
continue
states_by_id[state.get_storage_id()] = state
available_ids.append(state.get_storage_id())
var definition := resolve_definition(item_id, available_ids)
return (
states_by_id.get(definition.storage_id) as StorageStateRecord
if definition != null
else null
)
func get_candidates(
item_id: StringName, available_storage_ids: Array[StringName] = []
) -> Array[StorageDefinition]:
var candidates: Array[StorageDefinition] = []
if catalog == null or not catalog.is_valid():
return candidates
var item := catalog.get_item(item_id)
if item == null:
return candidates
var available := {}
for storage_id in available_storage_ids:
available[storage_id] = true
for definition in catalog.get_storages():
if not available.is_empty() and not available.has(definition.storage_id):
continue
if definition.accepts_item(item):
candidates.append(definition)
candidates.sort_custom(_is_preferred_route)
return candidates
static func _is_preferred_route(first: StorageDefinition, second: StorageDefinition) -> bool:
if first.routing_priority != second.routing_priority:
return first.routing_priority > second.routing_priority
return String(first.storage_id) < String(second.storage_id)