extends Node var failures := 0 func check(ok: bool, message: String) -> void: if not ok: failures += 1 push_error(message) func count_numbers() -> int: var count := 0 for child: Node in get_children(): if child.get_script() == load("res://scripts/combat/damage_number.gd"): count += 1 return count func _ready() -> void: GameState.save_locked = true call_deferred("run") func run() -> void: var hero = load("res://scenes/player/player.tscn").instantiate() add_child(hero) hero.set_physics_process(false) var enemy = load("res://scenes/enemies/enemy.tscn").instantiate() add_child(enemy) enemy.set_physics_process(false) enemy.active = true for actor in [hero, enemy]: actor.health = 100.0 actor.attack_invulnerable = false var before := count_numbers() actor.take_damage(0.0, Vector2.RIGHT, 100.0) check(count_numbers() == before, "intentional zero hit emits no number") check(actor.health == 100.0 and actor.knockback_velocity.x > 0.0, "zero hit preserves health and knockback") if actor == hero: hero.invulnerability = 0.0 actor.attack_invulnerable = true before = count_numbers() actor.take_damage(0.0) check(count_numbers() == before, "invulnerability does not display an intentional zero") actor.take_damage(5.0) check(count_numbers() == before + 1, "blocked positive damage retains its feedback") actor.attack_invulnerable = false before = count_numbers() actor.take_damage(2.0) check(count_numbers() == before + 1, "positive damage still displays") check(hero._roll_damage(0.0) == 0.0, "zero authored hero damage stays zero") check(hero._roll_damage(0.1) >= 1.0, "positive damage retains existing minimum") print("ZERO HIT NUMBERS: ", "PASSED" if failures == 0 else "FAILED") get_tree().quit(0 if failures == 0 else 1)