63 lines
2.0 KiB
GDScript
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)
|