Fixes Relay bug, adds a small "prep" timer when entering a new room, and lowers Anchors health

This commit is contained in:
2026-03-09 11:20:36 -04:00
parent 0fbaf1ee65
commit 8087c57c32
7 changed files with 46 additions and 11 deletions
+5 -2
View File
@@ -26,8 +26,8 @@ var _shot_timer: float = 1.0
var _anchor_timer: float = 0.0 var _anchor_timer: float = 0.0
func _ready() -> void: func _ready() -> void:
max_health = 40.0 max_health = 30.0
current_health = 40.0 current_health = 30.0
speed = 95.0 speed = 95.0
contact_damage = 0.5 contact_damage = 0.5
super._ready() super._ready()
@@ -43,10 +43,13 @@ func _pick_floor_point() -> void:
_target_pos = room_center + Vector2(rx, ry) _target_pos = room_center + Vector2(rx, ry)
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
_tick_spawn_delay(delta)
_find_player() _find_player()
_tick_contact(delta) _tick_contact(delta)
_tick_flash(delta) _tick_flash(delta)
_tick_slow(delta) _tick_slow(delta)
if not is_active():
return
match _state: match _state:
State.DRIFTING: State.DRIFTING:
+3
View File
@@ -17,10 +17,13 @@ func _ready() -> void:
_wobble_phase = randf() * TAU _wobble_phase = randf() * TAU
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
_tick_spawn_delay(delta)
_find_player() _find_player()
_tick_contact(delta) _tick_contact(delta)
_tick_flash(delta) _tick_flash(delta)
_tick_slow(delta) _tick_slow(delta)
if not is_active():
return
_do_arc_chase(delta) _do_arc_chase(delta)
velocity *= _slow_factor velocity *= _slow_factor
move_and_slide() move_and_slide()
+12
View File
@@ -13,10 +13,13 @@ var contact_cooldown: float = 0.8
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Internal state — shared across all enemies # Internal state — shared across all enemies
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
const SPAWN_DELAY: float = 0.5
var _contact_timer: float = 0.0 var _contact_timer: float = 0.0
var _flash_timer: float = 0.0 var _flash_timer: float = 0.0
var _slow_factor: float = 1.0 var _slow_factor: float = 1.0
var _slow_timer: float = 0.0 var _slow_timer: float = 0.0
var _spawn_timer: float = SPAWN_DELAY
var _player: Node2D = null var _player: Node2D = null
@onready var visual: Node2D = $Visual @onready var visual: Node2D = $Visual
@@ -25,6 +28,13 @@ func _ready() -> void:
add_to_group("enemies") add_to_group("enemies")
$ContactArea.body_entered.connect(_on_contact_entered) $ContactArea.body_entered.connect(_on_contact_entered)
func is_active() -> bool:
return _spawn_timer <= 0.0
func _tick_spawn_delay(delta: float) -> void:
if _spawn_timer > 0.0:
_spawn_timer -= delta
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Shared helpers — call from derived _physics_process as needed # Shared helpers — call from derived _physics_process as needed
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -83,6 +93,8 @@ func _spawn_drop() -> void:
# Contact damage # Contact damage
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
func _on_contact_entered(body: Node) -> void: func _on_contact_entered(body: Node) -> void:
if not is_active():
return
if body.is_in_group("player") and _contact_timer == 0.0: if body.is_in_group("player") and _contact_timer == 0.0:
body.take_damage(contact_damage) body.take_damage(contact_damage)
_contact_timer = contact_cooldown _contact_timer = contact_cooldown
+17 -9
View File
@@ -51,6 +51,8 @@ var _contact_area : Area2D
var _teleport_timer : float = 3.0 # initial delay before first teleport var _teleport_timer : float = 3.0 # initial delay before first teleport
var _in_transit : bool = false var _in_transit : bool = false
var _transit_timer : float = 0.0
var _fade_out : bool = false
var _teleport_count : int = 0 var _teleport_count : int = 0
var _next_drifter_threshold : int = 0 var _next_drifter_threshold : int = 0
@@ -75,12 +77,15 @@ func _ready() -> void:
_room_center = global_position _room_center = global_position
_roll_drifter_threshold() _roll_drifter_threshold()
_roll_teleport_cooldown() _teleport_timer = 2.5 # initial delay before first teleport
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
_tick_spawn_delay(delta)
if _phase == Phase.CLIMAX: if _phase == Phase.CLIMAX:
_tick_climax(delta) _tick_climax(delta)
return return
if not is_active():
return
_tick_teleport(delta) _tick_teleport(delta)
_tick_burst_projs(delta) _tick_burst_projs(delta)
@@ -93,6 +98,9 @@ func _physics_process(delta: float) -> void:
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
func _tick_teleport(delta: float) -> void: func _tick_teleport(delta: float) -> void:
if _in_transit: if _in_transit:
_transit_timer -= delta
if _transit_timer <= 0.0:
_reappear()
return return
_teleport_timer -= delta _teleport_timer -= delta
@@ -101,21 +109,21 @@ func _tick_teleport(delta: float) -> void:
func _start_teleport() -> void: func _start_teleport() -> void:
_in_transit = true _in_transit = true
_fade_out = true
# Fade out # Quick fade out
var tw := create_tween() var tw := create_tween()
tw.tween_property(_visual, "modulate:a", 0.0, FADE_OUT_TIME) tw.tween_property(_visual, "modulate:a", 0.0, FADE_OUT_TIME)
tw.tween_callback(Callable(self, "_on_fade_out_done")) tw.finished.connect(_on_fade_finished)
func _on_fade_out_done() -> void: func _on_fade_finished() -> void:
if not _fade_out:
return
_fade_out = false
_contact_area.monitoring = false _contact_area.monitoring = false
_contact_area.monitorable = false _contact_area.monitorable = false
_visual.visible = false _visual.visible = false
_transit_timer = TRANSIT_TIME
# Transit delay then reappear
var tw := create_tween()
tw.tween_interval(TRANSIT_TIME)
tw.tween_callback(Callable(self, "_reappear"))
func _reappear() -> void: func _reappear() -> void:
# Pick random position within room bounds # Pick random position within room bounds
+3
View File
@@ -56,10 +56,13 @@ func _snap_to_wall() -> void:
global_position = wall_pos global_position = wall_pos
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
_tick_spawn_delay(delta)
_find_player() _find_player()
_tick_contact(delta) _tick_contact(delta)
_tick_flash(delta) _tick_flash(delta)
_tick_slow(delta) _tick_slow(delta)
if not is_active():
return
velocity = Vector2.ZERO velocity = Vector2.ZERO
_do_fire(delta) _do_fire(delta)
velocity *= _slow_factor velocity *= _slow_factor
+3
View File
@@ -110,10 +110,13 @@ func _update_facing(dir: Vector2) -> void:
# Physics loop # Physics loop
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
_tick_spawn_delay(delta)
_find_player() _find_player()
_tick_contact(delta) _tick_contact(delta)
_tick_beam(delta) _tick_beam(delta)
_tick_flash(delta) _tick_flash(delta)
if not is_active():
return
var pct := current_health / max_health var pct := current_health / max_health
if _phase == Phase.ONE and pct <= 0.55: if _phase == Phase.ONE and pct <= 0.55:
+3
View File
@@ -79,10 +79,13 @@ func _ready() -> void:
# Physics loop # Physics loop
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
_tick_spawn_delay(delta)
_find_player() _find_player()
_tick_contact(delta) _tick_contact(delta)
_tick_flash(delta) _tick_flash(delta)
_tick_sweep_projs(delta) _tick_sweep_projs(delta)
if not is_active():
return
if _phase == Phase.ONE and current_health / max_health <= 0.4: if _phase == Phase.ONE and current_health / max_health <= 0.4:
_enter_phase_two() _enter_phase_two()