TowerGame/scripts/building_components/producer.gd

86 lines
2.1 KiB
GDScript

extends BuildingPart
class_name Producer
@export var produced_item: Item
@export var output_period: float = 0.1
@export var max_outputs: int = 1
@export var consumers: Array[Consumer]
var last_consumer_idx: int = 0
#var output_timer: float = 0.0
#var output_item: Item
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_produce() -> bool:
return can_send_item(produced_item)
func produce() -> bool:
return send_item(produced_item)
func can_send_item(item: Item) -> bool:
if !enabled:
return false
for request in requests:
if request.item == item:
return true
for consumer in consumers:
if consumer.can_accept_item(item):
return true
return false
func send_item(item: Item) -> bool:
if !enabled:
return false
if check_requested_items(item):
return true
if consumers.is_empty():
return false
var start_idx: int = last_consumer_idx
var first_try: bool = true
var idx: int = start_idx
while idx != start_idx or first_try:
idx += 1
if idx >= consumers.size():
idx = 0
first_try = false
var consumer: Consumer = consumers[idx]
var accepted: bool = consumer.offer_item(item)
if accepted:
last_consumer_idx = idx
return true
return false
func check_requested_items(new_item: Item) -> bool:
for request in requests:
if new_item == request.item:
requested_item_received.emit(request)
return true
return false
func cancel_request(request: ItemRequest):
requested_item_received.emit(request)
## 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:
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
requests.erase(request)
return finished_request.timeout > 0