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()