TowerGame/scripts/building_components/consumer.gd

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