2026-09-03 10:33:05 +02:00
|
|
|
class_name BossEye
|
|
|
|
|
extends Area2D
|
|
|
|
|
|
|
|
|
|
signal destroyed
|
2026-09-03 11:49:51 +02:00
|
|
|
signal health_changed(current: int, maximum: int)
|
2026-09-03 10:33:05 +02:00
|
|
|
|
|
|
|
|
const COMBAT_TARGET = preload("res://core/CombatTarget.gd")
|
|
|
|
|
|
2026-09-03 22:00:26 +02:00
|
|
|
@export var max_hp: int = 5
|
2026-09-03 10:33:05 +02:00
|
|
|
|
2026-09-03 22:00:26 +02:00
|
|
|
var hp: int = 5
|
2026-09-03 10:33:05 +02:00
|
|
|
var opened: bool = false
|
|
|
|
|
var phase: float = 0.0
|
2026-09-03 11:49:51 +02:00
|
|
|
var redraw_left: float = 0.0
|
|
|
|
|
|
|
|
|
|
const REDRAW_INTERVAL: float = 1.0 / 12.0
|
2026-09-03 10:33:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
func _ready() -> void:
|
|
|
|
|
hp = max_hp
|
|
|
|
|
$CollisionShape2D.disabled = true
|
|
|
|
|
queue_redraw()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func open_eye() -> void:
|
|
|
|
|
if opened:
|
|
|
|
|
return
|
|
|
|
|
opened = true
|
|
|
|
|
COMBAT_TARGET.register(self, COMBAT_TARGET.DANGER_PRIORITY)
|
|
|
|
|
add_to_group("boss_eyes")
|
|
|
|
|
$CollisionShape2D.set_deferred("disabled", false)
|
|
|
|
|
queue_redraw()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func take_damage(amount: int) -> bool:
|
|
|
|
|
if not opened or hp <= 0:
|
|
|
|
|
return false
|
|
|
|
|
hp -= maxi(amount, 1)
|
2026-09-03 11:49:51 +02:00
|
|
|
health_changed.emit(maxi(hp, 0), max_hp)
|
2026-09-03 10:33:05 +02:00
|
|
|
if hp > 0:
|
|
|
|
|
queue_redraw()
|
|
|
|
|
return false
|
|
|
|
|
hp = 0
|
|
|
|
|
EnemyExplosionVFX.spawn(get_tree().root, global_position)
|
|
|
|
|
Sfx.play(get_tree(), Sfx.ENEMY_DEATH)
|
|
|
|
|
destroyed.emit()
|
|
|
|
|
queue_free()
|
|
|
|
|
return true
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
|
|
|
phase += delta
|
2026-09-03 11:49:51 +02:00
|
|
|
redraw_left -= delta
|
|
|
|
|
if opened and redraw_left <= 0.0:
|
|
|
|
|
redraw_left = REDRAW_INTERVAL
|
2026-09-03 10:33:05 +02:00
|
|
|
queue_redraw()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _draw() -> void:
|
|
|
|
|
var flesh := Color(0.95, 0.18, 0.58)
|
|
|
|
|
var dark := Color(0.08, 0.005, 0.055)
|
|
|
|
|
if not opened:
|
|
|
|
|
# A sealed lid at the end of the tentacle.
|
|
|
|
|
NeonDraw.draw_glowing_line(self, Vector2(-20, -5), Vector2(20, 5),
|
|
|
|
|
flesh, 0.5, 0.75, dark)
|
|
|
|
|
NeonDraw.draw_glowing_line(self, Vector2(-20, 5), Vector2(20, -5),
|
|
|
|
|
flesh, 0.5, 0.75, dark)
|
|
|
|
|
return
|
|
|
|
|
var pulse: float = 0.78 + 0.22 * sin(phase * 5.0)
|
|
|
|
|
draw_set_transform(Vector2.ZERO, 0.0, Vector2(1.0, 0.66))
|
|
|
|
|
NeonDraw.draw_glowing_circle(self, Vector2.ZERO, 25.0,
|
|
|
|
|
Color(0.25, 0.92, 1.0), pulse, dark)
|
|
|
|
|
NeonDraw.draw_glowing_circle(self, Vector2.ZERO, 10.0,
|
|
|
|
|
Color(1.0, 0.9, 0.3), 1.0, dark)
|
|
|
|
|
draw_set_transform(Vector2.ZERO, 0.0, Vector2.ONE)
|