extends Area2D ## Scrap drop — the positioning reward gradient (canon 2026-08-07: ## kills drop scrap physically; collecting it gates in-run card ## levels). Drifts to the mech inside the magnet radius, collected on ## contact, fades out if ignored. Constructed in code, no scene. var value := 1 var magnet_radius := 70.0 var drift_speed := 150.0 var lifetime := 20.0 var _t := 0.0 var _sprite: Sprite2D func _ready() -> void: add_to_group("salvage") collision_layer = 0 collision_mask = 2 monitorable = false var cs := CollisionShape2D.new() var sh := CircleShape2D.new() sh.radius = 6.0 cs.shape = sh add_child(cs) # Runtime load, not preload — resilient to a stale import cache. _sprite = Sprite2D.new() _sprite.texture = load("res://assets/sprites_ph/scrap_ph.png") add_child(_sprite) body_entered.connect(_on_body_entered) func _physics_process(delta: float) -> void: _t += delta if _t >= lifetime: queue_free() return var mech := get_tree().get_first_node_in_group("mech") as Node2D if mech != null and global_position.distance_to(mech.global_position) <= magnet_radius: global_position = global_position.move_toward(mech.global_position, drift_speed * delta) # Fade the sprite out over the last 3s of life. if _t >= lifetime - 3.0 and _sprite != null: _sprite.modulate.a = clampf((lifetime - _t) / 3.0, 0.0, 1.0) func _on_body_entered(body: Node) -> void: if body.is_in_group("mech"): var hand := get_tree().get_first_node_in_group("hand") if hand != null: hand.add_salvage(value) queue_free()