Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
71 lines
3.2 KiB
GDScript
71 lines
3.2 KiB
GDScript
extends Node2D
|
|
|
|
# Preview, not a test - #58's aim-state screenshot: two laser ships (one
|
|
# ready, one rearming), aiming with the beam preview drawn and enemies
|
|
# placed along its line.
|
|
#
|
|
# bash tests/screenshot.sh res://tests/_laser_aim_preview.tscn /tmp/laser.png 20 720x1280
|
|
|
|
|
|
func _ready() -> void:
|
|
GameState.buildings.clear()
|
|
GameState.extractors.clear()
|
|
GameState.transporters.clear()
|
|
GameState.vessel_levels["unlock_laser"] = 1
|
|
GameState.intro_active = false
|
|
# A shot the fleet cannot pay for is refused before aiming starts, so
|
|
# without this the preview drew no guide at all - the state it exists
|
|
# to show. Deposited before Main is built, like test_laser_vessel.gd.
|
|
GameState.deposit_fleet_resource(GameState.RESOURCE_ENERGY, 40)
|
|
var main: Node = load("res://world/Main.tscn").instantiate()
|
|
add_child(main)
|
|
main.get_node("BackgroundLayer").visible = false
|
|
main.get_node("AsteroidField").visible = false
|
|
main.get_node("PlanetField").visible = false
|
|
main.get_node("BuildingField").visible = false
|
|
main.get_node("EnemySpawner").set_process(false)
|
|
main.get_node("AsteroidField").set_process(false)
|
|
var fleet: Node = main.get_node("Fleet")
|
|
# Three, not four: the starting fleet holds three hulls until the skill
|
|
# tree widens it, and a fourth entry was silently dropped - which took the
|
|
# ready laser with it and left this preview with nothing to aim.
|
|
fleet.spawn_ships(3, Vector2.ZERO, PackedStringArray([
|
|
GameState.VESSEL_SHIELD, GameState.VESSEL_LASER,
|
|
GameState.VESSEL_LASER]))
|
|
var skill: Node = main.get_node("LaserController")
|
|
skill._process(0.0)
|
|
# Show both per-ship states in one frame: one laser ship rearming, the
|
|
# other ready and supplying the shot.
|
|
var rearming: Node = fleet.ships[1].get_component("laser")
|
|
rearming.consume_shot()
|
|
rearming.tick(rearming.cooldown_duration * 0.5)
|
|
main.get_node("Camera2D").zoom = Vector2(1.8, 1.8)
|
|
var button: Control = main.get_node("UI/LaserButton")
|
|
var press := InputEventScreenTouch.new()
|
|
press.index = 9
|
|
press.position = button.global_position + button.size * 0.5
|
|
press.pressed = true
|
|
skill.handle_touch(press)
|
|
# Enemies BEFORE the drag, so the aim helper actually sees them. A nearer
|
|
# one on the heading and a further one just off it: the state this preview
|
|
# exists to show is the drag reaching past the first to name the second.
|
|
var heading: Vector2 = Vector2(-245.0, -235.0).normalized()
|
|
var reach: float = skill._aim_max_range()
|
|
var origin: Vector2 = fleet.get_centroid()
|
|
var far_offset: Vector2 = heading.rotated(deg_to_rad(8.0)) * 1900.0
|
|
for offset in [heading * 900.0, far_offset]:
|
|
var enemy: Node = load("res://enemies/Enemy.tscn").instantiate()
|
|
enemy.position = origin + offset
|
|
main.add_child(enemy)
|
|
enemy.speed = 0.0 # after add_child - _ready() sets it from the definition
|
|
|
|
var drag := InputEventScreenDrag.new()
|
|
drag.index = 9
|
|
# Dragged out to the further enemy's depth rather than to the beam's end.
|
|
drag.position = press.position + far_offset.normalized() \
|
|
* (1900.0 / reach * LaserController.DRAG_RADIUS)
|
|
skill.handle_drag(drag)
|
|
# The zoom eases now, so a preview that captures the first frame would
|
|
# catch it mid-move. Settle it before the screenshot is taken.
|
|
for _step in range(40):
|
|
skill._process(0.05)
|