4ae0876e34
Per canon decisions 2026-08-07 (advisor CONCEPT.md f12cb15, falsifier response): charges now generate on kills (kills_per_charge, chemistry chain kills feed the hand; per-hit generation removed). Kills drop scrap as physical pickups (amber diamond, magnet radius 70, drift to mech, 20s fade; grunt 1 / burster 3) — collection is the positioning reward gradient. Cumulative collected scrap gates card levels 1-3 (thresholds 12/30; per-level radius x1.25/x1.5 and power x1.15/x1.5 — HEAT L3 hits one-cast detonation threshold). HUD: level notches under slots + scrap counter. Salvage spawn is call_deferred: death can fire inside a physics signal flush where Area2D setup is blocked. Smoke gate: charge accrual now kill-fed, salvage drop + collection + level gating phases added, heat-target selection made retry-tolerant. 4/4 green on nh3-dev headless 4.7.1.
52 lines
1.5 KiB
GDScript
52 lines
1.5 KiB
GDScript
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
|
|
|
|
|
|
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)
|
|
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)
|
|
if _t >= lifetime - 3.0:
|
|
queue_redraw()
|
|
|
|
|
|
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()
|
|
|
|
|
|
func _draw() -> void:
|
|
var a := 1.0 if _t < lifetime - 3.0 else clampf((lifetime - _t) / 3.0, 0.0, 1.0)
|
|
var pts := PackedVector2Array([Vector2(0, -5), Vector2(4, 0), Vector2(0, 5), Vector2(-4, 0)])
|
|
draw_colored_polygon(pts, Color(0.95, 0.8, 0.35, a))
|