Track gas bomb cooldowns per bomber

This commit is contained in:
Loïc Wisniewski 2026-08-15 10:12:33 +02:00
commit eb79efdafe
6 changed files with 193 additions and 49 deletions

View file

@ -23,16 +23,20 @@ var aim_screen := Vector2.ZERO
var aim_target := Vector2.ZERO
var saved_zoom := 1.0
var restoring_zoom := false
var cooldown_left := 0.0
var projectile_active := false
var projectile_position := Vector2.ZERO
var projectile_target := Vector2.ZERO
var projectile_trail := PackedVector2Array()
var explosion_time := 0.0
var explosion_position := Vector2.ZERO
var projectiles: Array = []
var explosions: Array = []
var last_hit_count := 0
var projectile_active: bool:
get: return not projectiles.is_empty()
var explosion_time: float:
get:
var longest := 0.0
for explosion in explosions:
longest = maxf(longest, float(explosion.time))
return longest
func _ready() -> void:
button.visible = false
@ -40,10 +44,9 @@ func _ready() -> void:
func _process(delta: float) -> void:
var was_exploding := explosion_time > 0.0
var had_visuals := aiming or not projectiles.is_empty() or not explosions.is_empty()
button.visible = fleet.has_capability("gas_bomber")
cooldown_left = maxf(cooldown_left - delta, 0.0)
button.enabled = cooldown_left <= 0.0
button.enabled = _next_ready_bomber() != null
if not button.visible and aiming:
_cancel_aim()
@ -53,27 +56,33 @@ func _process(delta: float) -> void:
if is_equal_approx(z, saved_zoom):
restoring_zoom = false
if projectile_active:
var distance := projectile_position.distance_to(projectile_target)
for i in range(projectiles.size() - 1, -1, -1):
var projectile: Dictionary = projectiles[i]
var distance: float = (projectile.position as Vector2).distance_to(projectile.target)
if distance <= PROJECTILE_SPEED * delta:
projectile_position = projectile_target
projectile_active = false
_explode(projectile_target)
projectile.position = projectile.target
_explode(projectile.target)
projectiles.remove_at(i)
else:
projectile_position = projectile_position.move_toward(projectile_target,
projectile.position = (projectile.position as Vector2).move_toward(projectile.target,
PROJECTILE_SPEED * delta)
projectile_trail.append(projectile_position)
while projectile_trail.size() > 12:
projectile_trail.remove_at(0)
if explosion_time > 0.0:
explosion_time = maxf(explosion_time - delta, 0.0)
if aiming or projectile_active or explosion_time > 0.0 or was_exploding:
var trail: PackedVector2Array = projectile.trail
trail.append(projectile.position)
while trail.size() > 12:
trail.remove_at(0)
projectile.trail = trail
for i in range(explosions.size() - 1, -1, -1):
var explosion: Dictionary = explosions[i]
explosion.time = maxf(float(explosion.time) - delta, 0.0)
if float(explosion.time) <= 0.0:
explosions.remove_at(i)
if aiming or not projectiles.is_empty() or not explosions.is_empty() or had_visuals:
queue_redraw()
func can_begin_aim() -> bool:
return button.visible and button.enabled and not button._blocked_by_modal() \
and not aiming and not projectile_active
and not aiming
func handle_touch(event: InputEventScreenTouch) -> bool:
@ -143,21 +152,35 @@ func _cancel_aim() -> void:
func _fire() -> void:
var bomber: Node2D = fleet.first_ship_with_capability("gas_bomber")
var bomber: Node2D = _next_ready_bomber()
if bomber == null:
_cancel_aim()
return
projectile_active = true
projectile_position = bomber.global_position
projectile_target = aim_target
projectile_trail = PackedVector2Array([projectile_position])
cooldown_left = COOLDOWN
var component: Node = bomber.get_component("gas_bomber")
if not component.consume_shot(COOLDOWN):
_cancel_aim()
return
projectiles.append({
"position": bomber.global_position,
"target": aim_target,
"trail": PackedVector2Array([bomber.global_position]),
})
_finish_aim()
button.enabled = _next_ready_bomber() != null
func _next_ready_bomber() -> Node2D:
for ship in fleet.ships:
if not is_instance_valid(ship):
continue
var component: Node = ship.get_component("gas_bomber")
if component != null and component.is_ready():
return ship
return null
func _explode(at: Vector2) -> void:
explosion_position = at
explosion_time = 0.8
explosions.append({"position": at, "time": 0.8})
last_hit_count = 0
for enemy in get_tree().get_nodes_in_group("enemies"):
if is_instance_valid(enemy) and enemy is Node2D \
@ -172,22 +195,23 @@ func _draw() -> void:
NeonDraw.draw_glowing_line(self, origin, aim_target, TARGET_COLOR, 0.7, 0.8)
_draw_ring(aim_target, AOE_RADIUS, TARGET_COLOR, 0.8)
_draw_ring(aim_target, 18.0, BOMB_COLOR, 1.0)
if projectile_trail.size() >= 2 and projectile_active:
for i in range(1, projectile_trail.size()):
var alpha := float(i) / projectile_trail.size()
draw_line(projectile_trail[i - 1], projectile_trail[i],
Color(BOMB_COLOR, alpha * 0.65), 4.0 + alpha * 4.0, true)
if projectile_active:
draw_circle(projectile_position, 12.0, Color(BOMB_COLOR, 0.35))
NeonDraw.draw_glowing_circle(self, projectile_position, 7.0, BOMB_COLOR, 1.0)
if explosion_time > 0.0:
var progress := 1.0 - explosion_time / 0.8
for projectile in projectiles:
var trail: PackedVector2Array = projectile.trail
if trail.size() >= 2:
for i in range(1, trail.size()):
var alpha := float(i) / trail.size()
draw_line(trail[i - 1], trail[i],
Color(BOMB_COLOR, alpha * 0.65), 4.0 + alpha * 4.0, true)
draw_circle(projectile.position, 12.0, Color(BOMB_COLOR, 0.35))
NeonDraw.draw_glowing_circle(self, projectile.position, 7.0, BOMB_COLOR, 1.0)
for explosion in explosions:
var progress := 1.0 - float(explosion.time) / 0.8
var radius := lerpf(24.0, AOE_RADIUS, minf(progress * 1.5, 1.0))
draw_circle(explosion_position, radius, Color(BOMB_COLOR, (1.0 - progress) * 0.16))
_draw_ring(explosion_position, radius, BOMB_COLOR, 1.0 - progress)
draw_circle(explosion.position, radius, Color(BOMB_COLOR, (1.0 - progress) * 0.16))
_draw_ring(explosion.position, radius, BOMB_COLOR, 1.0 - progress)
for i in range(7):
var angle := TAU * float(i) / 7.0 + progress
var cloud_at := explosion_position + Vector2(cos(angle), sin(angle)) * radius * 0.55
var cloud_at: Vector2 = explosion.position + Vector2(cos(angle), sin(angle)) * radius * 0.55
draw_circle(cloud_at, 18.0 + 14.0 * progress, Color(BOMB_COLOR, (1.0 - progress) * 0.22))