Files
urm03/scripts/mech.gd
T
vh fc4fc59a2b feat: M2 run skeleton — belt, card draft, node fork, room sequencing, run tally
Belt (canon: charges are the cost, the belt is the ammo): cards are
CARD_TYPES indices consumed on play, next slides into the 2-slot hand;
belt cap 8; HUD shows hand glyphs + upcoming-card ticks. Card pool
grows to 4: SHOCKWAVE, HEATWAVE, DASH (impulse along held movement
direction — aimable while frozen, no aim input), IGNITE (nearest-enemy
heat spike past threshold). Rooms: spawn-budget waves (base 8 +4/room,
4 rooms/run); clear -> interstitial fork (CARD vs SCRAP +8) -> CARD
opens a 3-option draft + scrap decline (+4) -> next room; final clear
or mech destruction -> tally overlay (rooms/kills/scrap/chem) with
relaunch on 1. Interstitial owns the pause while active; the hand
yields input and time authority to it. Mech death now signals the run
manager instead of hard-reloading.

Chain semantics (same-tag surge / cross-tag chemistry trigger)
deliberately deferred to M3.

Smoke gate: belt consumption white-boxed in the card phase, _until
moved to process_frame (physics awaits deadlock under pause), run
phase covers clear->fork->draft->belt growth->room advance->tally.
3/3 green on nh3-dev headless 4.7.1.
2026-08-07 20:30:43 -07:00

50 lines
1.2 KiB
GDScript

class_name Mech
extends CharacterBody2D
## M03, greybox slab. Piloting is positioning ONLY (canon: no aim, no
## combos) — movement input is the entire control surface.
signal hull_changed(hull: float, hull_max: float)
signal destroyed
@export var move_speed := 160.0
@export var accel := 900.0
@export var decel := 1200.0
@export var hull_max := 100.0
@export var dash_decay := 4.0
var hull: float
var _dash := Vector2.ZERO
func _ready() -> void:
add_to_group("mech")
hull = hull_max
func _physics_process(delta: float) -> void:
var dir := Input.get_vector("move_left", "move_right", "move_up", "move_down")
var rate := accel if dir != Vector2.ZERO else decel
_dash = _dash.lerp(Vector2.ZERO, 1.0 - exp(-dash_decay * delta))
velocity = velocity.move_toward(dir * move_speed, rate * delta) + _dash
move_and_slide()
velocity -= _dash
func impulse(v: Vector2) -> void:
_dash += v
func take_damage(amount: float) -> void:
if hull <= 0.0:
return
hull = maxf(hull - amount, 0.0)
hull_changed.emit(hull, hull_max)
if hull <= 0.0:
# The run manager decides what death means (tally + relaunch).
destroyed.emit()
func _draw() -> void:
draw_rect(Rect2(-10, -12, 20, 24), Color(0.82, 0.84, 0.88))
draw_rect(Rect2(-6, -6, 12, 12), Color(0.55, 0.6, 0.68))