class_name PowerUpSpawner extends Node2D @export var spawn_interval: float = 5.0 @export var test_mode: bool = true @onready var screensize: Vector2 = get_viewport().content_scale_size @onready var spawn_timer: Timer = $SpawnTimer # All weapon resources to spawn as pickups. # Populate in the editor with your weapon_shot resources. @export var all_weapon_shots: Array[WeaponShot] = [] var _pickups_spawned: int = 0 var _pickups_remaining: int = 0 func _ready() -> void: if spawn_timer == null: return spawn_timer.wait_time = spawn_interval func _on_spawn_timer_timeout() -> void: if test_mode: _spawn_test_pickups() else: # TODO: normal mode — spawn a single random pickup. pass func _spawn_test_pickups() -> void: for weapon: WeaponShot in all_weapon_shots: if weapon == null or weapon.shot_name.is_empty(): continue var pickup := _create_pickup(weapon) if not is_instance_valid(pickup): continue # skipped — no valid icon # Random position within viewport, with edge padding. var margin: float = 15.0 pickup.position = Vector2( randf_range(margin, screensize.x - margin), randf_range(margin, screensize.y - margin) ) add_child(pickup) _pickups_spawned += 1 _pickups_remaining = _pickups_spawned # Pause the timer while pickups are on screen; resume when all gone. if spawn_timer != null: spawn_timer.stop() func pickup_collected() -> void: # Called by the player when a pickup is collected. # Decrement counter; resume timer once all pickups are gone. _pickups_remaining = max(0, _pickups_remaining - 1) if _pickups_remaining <= 0: if spawn_timer != null: spawn_timer.start() _pickups_spawned = 0 func _create_pickup(weapon: WeaponShot) -> Area2D: var pickup := Area2D.new() pickup.name = "PowerUpPickup" # Icon texture — load from graphics/ matching the weapon's shot_name. var icon_path := "res://graphics/" + weapon.shot_name.replace(" ", "") + ".png" var icon_tex := load(icon_path) as Texture2D if icon_tex == null: printerr("[PowerUpSpawner] No texture found for weapon: ", weapon.shot_name) pickup.queue_free() # return a dead node — caller skips it return pickup var icon := TextureRect.new() icon.texture = icon_tex icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED icon.size = Vector2(16, 16) pickup.add_child(icon) # Collision shape — small rectangle matching the icon. var shape := RectangleShape2D.new() shape.size = Vector2(14, 14) var collision := CollisionShape2D.new() collision.shape = shape pickup.add_child(collision) # Store the weapon reference so we know what to give the player. pickup.set_meta("weapon_shot", weapon) # Configure collision so HelpBoxArea (Layer 2, Mask 1) detects it. pickup.collision_layer = 1 pickup.collision_mask = 0 return pickup # --- Timer control --- # Direct stop/start — no guard conditions. The timer's paused property # can cause deadlock if the guard checks "not paused" after stop().