Fill bomber hull during cooldown

This commit is contained in:
Loïc Wisniewski 2026-08-15 10:41:24 +02:00
commit 7da4531f25
3 changed files with 47 additions and 12 deletions

View file

@ -10,6 +10,8 @@ const COOLING_COLOR := Color(0.38, 0.16, 0.32)
func setup() -> void:
# Keep the ship's normal neon outline above the charge fill.
show_behind_parent = true
queue_redraw()
@ -37,18 +39,46 @@ func cooldown_progress() -> float:
return 1.0 - cooldown_left / maxf(cooldown_duration, 0.001)
func _filled_hull(points: PackedVector2Array, progress: float) -> PackedVector2Array:
if points.size() < 3 or progress <= 0.001:
return PackedVector2Array()
if progress >= 0.999:
return points.duplicate()
var top := INF
var bottom := -INF
for point in points:
top = minf(top, point.y)
bottom = maxf(bottom, point.y)
var fill_y: float = lerpf(bottom, top, clampf(progress, 0.0, 1.0))
var clipped := PackedVector2Array()
var previous: Vector2 = points[-1]
var previous_inside := previous.y >= fill_y
for current in points:
var current_inside := current.y >= fill_y
if current_inside != previous_inside:
var amount: float = (fill_y - previous.y) / (current.y - previous.y)
clipped.append(previous.lerp(current, amount))
if current_inside:
clipped.append(current)
previous = current
previous_inside = current_inside
return clipped
func _draw() -> void:
var parent_ship: Node = get_parent()
var core: Color = parent_ship.core_color if parent_ship != null else Color.WHITE
if is_ready():
# Bright, complete halo: this bomber owns one available shot.
NeonDraw.draw_glowing_circle(self, Vector2.ZERO, 31.0, READY_COLOR, 0.9, core)
draw_circle(Vector2.ZERO, 4.0, Color(READY_COLOR, 0.5))
if parent_ship == null or parent_ship.definition == null:
return
# A muted full ring says "not ready"; the bright arc fills clockwise so
# the individual bomber also communicates how close it is to rearming.
draw_arc(Vector2.ZERO, 31.0, 0.0, TAU, 48, Color(COOLING_COLOR, 0.65), 4.0, true)
var progress := cooldown_progress()
if progress > 0.001:
draw_arc(Vector2.ZERO, 31.0, -PI / 2.0,
-PI / 2.0 + TAU * progress, 48, Color(READY_COLOR, 0.92), 4.0, true)
var core: Color = parent_ship.core_color if parent_ship != null else Color.WHITE
var hull: PackedVector2Array = parent_ship.definition.hull_points
if is_ready():
# A fully lit hull means this individual bomber owns an available shot.
draw_colored_polygon(hull, Color(READY_COLOR, 0.42))
NeonDraw.draw_glowing_polygon(self, hull, READY_COLOR, 0.75, core, 0.75)
return
# Rearming is shown inside the bomber instead of as a shield-like ring:
# the muted silhouette fills from its engines toward its nose.
draw_colored_polygon(hull, Color(COOLING_COLOR, 0.58))
var filled := _filled_hull(hull, cooldown_progress())
if filled.size() >= 3:
draw_colored_polygon(filled, Color(READY_COLOR, 0.68))

View file

@ -21,8 +21,10 @@ func _ready() -> void:
var skill: GasBombController = main.get_node("GasBombController")
skill._process(0.0)
# Show both per-ship states in one frame: the first bomber is rearming,
# while the second has the bright complete ready halo and supplies the aim.
fleet.ships[2].get_component("gas_bomber").consume_shot(GasBombController.COOLDOWN)
# while the second has a fully lit hull and supplies the aim.
var rearming: Node = fleet.ships[2].get_component("gas_bomber")
rearming.consume_shot(GasBombController.COOLDOWN)
rearming.tick(GasBombController.COOLDOWN * 0.5)
main.get_node("Camera2D").zoom = Vector2(1.8, 1.8)
var button: Control = main.get_node("UI/GasBombButton")
var press := InputEventScreenTouch.new()

View file

@ -37,6 +37,9 @@ func _process(delta: float) -> bool:
skill._process(0.0)
if first.is_ready() or not second.is_ready() or not skill.button.enabled:
return _fail("the first shot disabled more than its firing bomber")
if not first._filled_hull(fleet.ships[0].definition.hull_points, 0.0).is_empty() \
or first._filled_hull(fleet.ships[0].definition.hull_points, 0.5).size() < 3:
return _fail("bomber cooldown did not produce an empty-to-filling hull")
if skill.projectiles.size() != 1:
return _fail("the first bomber did not launch exactly one projectile")