BeltTest/ItemSpawner.gd

80 lines
2.7 KiB
GDScript3
Raw Normal View History

2025-06-10 19:16:45 +02:00
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()