79 lines
2.7 KiB
GDScript
79 lines
2.7 KiB
GDScript
extends Building
|
|
class_name ItemSpawner
|
|
|
|
# TODO: Use CustomResources to set item types
|
|
@export var item_type_to_spawn: String = "TestItem"
|
|
@export var spawn_interval_seconds: float = 1.0
|
|
|
|
@onready var spawn_timer: Timer = $SpawnTimer
|
|
#@onready var spawn_point_offset: Vector2 = Vector2(0, -32)
|
|
|
|
var _spawned_item_scene: PackedScene = preload("res://Item.tscn")
|
|
|
|
func _ready():
|
|
super()
|
|
|
|
_on_grid_position_changed()
|
|
|
|
if spawn_timer:
|
|
spawn_timer.one_shot = true
|
|
spawn_timer.wait_time = spawn_interval_seconds
|
|
spawn_timer.timeout.connect(_on_spawn_timer_timeout)
|
|
spawn_timer.start()
|
|
|
|
func _on_grid_position_changed():
|
|
super()
|
|
|
|
name = "ItemSpawner_%s,%s" % [current_grid_pos.x, current_grid_pos.y]
|
|
|
|
# Can never accept items
|
|
func can_accept_item() -> bool:
|
|
return false
|
|
|
|
|
|
func handle_item_entry(item: Item, remaining_delta_from_previous: float = 0.0):
|
|
# Should never happen since can_accept_item() is always false
|
|
#item.queue_free()
|
|
print("Item %s tried to enter spawner at %s." % [item.type, current_grid_pos])
|
|
|
|
func _on_spawn_timer_timeout():
|
|
set_physics_process(true)
|
|
var next_grid_cell_pos = current_grid_pos + direction
|
|
var next_entity: Building = game_grid.get_content_at_grid(next_grid_cell_pos)
|
|
|
|
if not next_entity:
|
|
print("Spawner at %s is blocked: no entity at next cell." % current_grid_pos)
|
|
return
|
|
|
|
if not next_entity.can_accept_item():
|
|
# pause future spawning and "buffer" current item spawn until the space is free
|
|
# TODO: Use a signal FROM the belt here (belt should signal when it is free instead
|
|
# of the spawner checking every tick...
|
|
print("Spawner at %s is blocked: next entity (%s) cannot accept item. Pausing spawn." % [current_grid_pos, next_entity.name])
|
|
return
|
|
|
|
var new_item: Item = _spawned_item_scene.instantiate()
|
|
new_item.modulate = modulate
|
|
new_item.type = item_type_to_spawn
|
|
game_grid.add_child(new_item)
|
|
|
|
new_item.global_position = global_position # + spawn_point_offset
|
|
new_item.reset_physics_interpolation()
|
|
|
|
print("Spawner at %s is spawned item (%s) for next_entity (%s)." % [current_grid_pos, new_item.name, next_entity.name])
|
|
|
|
next_entity.handle_item_entry(new_item, 0.0) # TOOO: Use actual item pixel size
|
|
# Maybe have up to 4 or 8 items on a belt like factorio?
|
|
# Currently all items are in the center (easier), but we still
|
|
# need to use size to check if we are backed up and can't move
|
|
# Easierst would be to have ALL items be the same size, and use factorios approach of distances
|
|
# between items for checks
|
|
spawn_timer.start()
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
# We could disable physics_process() while the timer is running
|
|
if not spawn_timer.is_stopped():
|
|
set_physics_process(false)
|
|
return
|
|
|
|
_on_spawn_timer_timeout()
|