93 lines
2.7 KiB
GDScript
93 lines
2.7 KiB
GDScript
extends BuildingPart
|
|
class_name Consumer
|
|
signal item_added(item: Item)
|
|
|
|
@export var accepted_items: Array[Item] = []
|
|
@export var storage_size: int = 4
|
|
@export var max_inputs: int = 1
|
|
@export var void_excess_items: bool = false
|
|
|
|
var storage_total: int = 0
|
|
var storage: Dictionary[Item, int] = {}
|
|
|
|
class ItemRequest:
|
|
var item: Item
|
|
var timeout: float
|
|
var requests: Array[ItemRequest] = []
|
|
signal requested_item_received(request: ItemRequest)
|
|
|
|
func _process(delta: float) -> void:
|
|
for request in requests:
|
|
request.timeout -= delta
|
|
if request.timeout <= 0:
|
|
cancel_request(request)
|
|
|
|
func can_accept_item(item: Item) -> bool:
|
|
return ((storage_total < storage_size) or void_excess_items) \
|
|
and (accepted_items.has(item) or accepted_items.is_empty()) \
|
|
and enabled
|
|
|
|
func offer_item(item: Item) -> bool:
|
|
if !can_accept_item(item):
|
|
return false
|
|
if storage_total >= storage_size and void_excess_items:
|
|
return true # void item
|
|
var old_count: int = storage.get(item, 0)
|
|
storage.set(item, old_count + 1)
|
|
storage_total += 1
|
|
if !check_requested_items(item):
|
|
item_added.emit(item)
|
|
return true
|
|
|
|
func check_requested_items(new_item: Item):
|
|
for request in requests:
|
|
if new_item == request.item:
|
|
requested_item_received.emit(request)
|
|
break
|
|
|
|
func cancel_request(request: ItemRequest):
|
|
requested_item_received.emit(request)
|
|
|
|
func check_storage_for_item(item: Item) -> bool:
|
|
return check_storage_for_items({item:1})
|
|
|
|
func check_storage_for_items(items: Dictionary[Item, int]) -> bool:
|
|
for item: Item in items.keys():
|
|
if storage.get(item, 0) < items[item]:
|
|
return false
|
|
return true
|
|
|
|
func take_any_item_from_storage() -> Item:
|
|
for item: Item in storage.keys():
|
|
if storage[item] >= 1:
|
|
storage[item] -= 1
|
|
storage_total -= 1
|
|
return item
|
|
return null
|
|
|
|
func take_item_from_storage(item: Item) -> bool:
|
|
return take_items_from_storage({item: 1})
|
|
|
|
## Waits for an item to be available at this storage, or a timeout to be reached.
|
|
func wait_for_item(item: Item, timeout: float) -> bool:
|
|
if check_storage_for_item(item):
|
|
return true
|
|
var request: ItemRequest = ItemRequest.new()
|
|
request.item = item
|
|
request.timeout = timeout
|
|
requests.append(request)
|
|
var finished_request: ItemRequest = null
|
|
while finished_request != request:
|
|
finished_request = await requested_item_received
|
|
return check_storage_for_item(item)
|
|
|
|
func take_items_from_storage(items: Dictionary[Item, int]) -> bool:
|
|
if !check_storage_for_items(items):
|
|
return false
|
|
for item: Item in items.keys():
|
|
var old_count: int = storage.get(item, 0)
|
|
storage.set(item, old_count - items[item])
|
|
storage_total -= items[item]
|
|
#print("Removed %s from %s storage; previously had %d, new total %d" % [item.name, get_parent().name, old_count, storage_total])
|
|
return true
|