extends Node3D ## Glitschkönig: Reveal, Quirxel-Schüsse, Split, Flucht (DESIGN.md §12). enum Phase { FULL, SPLIT, FLEE, DONE } var _phase: Phase = Phase.FULL var _revealed: bool = false var _splits_done: int = 0 const SPLITS_MAX := 2 func _ready() -> void: GameState.current_scene_id = "final_boss" GameState.heal_full() _revealed = bool(GameState.get_flag("glitsch_revealed", false)) if not _revealed: _do_reveal() var boss := get_node_or_null("Hongkong") if boss: boss.set("max_hp", 16) boss.set("hp", 16) boss.set("ai_enabled", true) boss.set("move_speed", 1.8) boss.set("attack_damage", 1) boss.set("attack_cooldown", 1.4) boss.set("death_cause_key", "death_default") boss.set("billboard_height", SpriteFit.WORLD_BOSS_HEIGHT) boss.set("shout_key", "dialog_hongkong_boss") boss.set("shout_interval", 8.0) if boss.has_signal("hit"): boss.hit.connect(_on_boss_hit) if boss.has_signal("defeated"): boss.defeated.connect(_on_boss_defeated) var t := Timer.new() t.wait_time = 2.2 t.autostart = true t.timeout.connect(_spawn_quirxel) add_child(t) func _do_reveal() -> void: GameState.set_flag("glitsch_revealed", true) Inventory.add_item("banana", 1) Inventory.add_item("wartchen", 1) var ui := get_node_or_null("/root/UIRoot") if ui and ui.has_method("show_dialog"): ui.show_dialog_key("dialog_reveal", 5.5) await get_tree().create_timer(2.0).timeout ui.show_dialog_key("dialog_boss_unclever", 3.5) func _on_boss_hit(remaining: int) -> void: var boss := get_node_or_null("Hongkong") if remaining <= 10 and _splits_done < SPLITS_MAX and _phase != Phase.FLEE: _phase = Phase.SPLIT _splits_done += 1 _spawn_split_clone() var ui := get_node_or_null("/root/UIRoot") if ui and ui.has_method("show_dialog"): ui.show_dialog("Er teilt sich wie Minecraft-Schleim!", 2.5) if remaining <= 3 and _phase != Phase.DONE: _phase = Phase.FLEE if boss: boss.set("flee_below_hp", 99) boss.set("move_speed", 5.5) boss.set("ai_enabled", true) func _spawn_split_clone() -> void: var scene: PackedScene = load("res://scenes/prefabs/enemy.tscn") if scene == null: return var c: Node3D = scene.instantiate() c.name = "GlitschSplit_%d" % _splits_done add_child(c) c.global_position = Vector3(randf_range(-4, 4), 0.1, -2) c.set("max_hp", 5) c.set("texture_path", "res://assets/sprites/placeholders/glitschkoenig.png") c.set("ai_enabled", true) c.set("move_speed", 3.2) c.set("attack_damage", 1) c.set("billboard_height", 1.2) c.set("death_cause_key", "death_quirxel") var bill = c.get_node_or_null("BillboardSprite") if bill and bill.has_method("set_texture"): var tex: Texture2D = load("res://assets/sprites/placeholders/glitschkoenig.png") if tex: bill.set_texture(tex) func _spawn_quirxel() -> void: if _phase == Phase.DONE or GameState.get_flag("hongkong_defeated", false): return var scene: PackedScene = load("res://scenes/prefabs/quirxel_projectile.tscn") if scene == null: return var player := get_tree().get_first_node_in_group("player") var boss := get_node_or_null("Hongkong") var origin := Vector3(0, 0.8, -2) if boss is Node3D: origin = (boss as Node3D).global_position + Vector3(0, 0.9, 0) var q: Node3D = scene.instantiate() add_child(q) q.global_position = origin + Vector3(randf_range(-1.5, 1.5), 0, randf_range(-1, 1)) var dir := Vector3(0, 0, 1) if player is Node3D: dir = ((player as Node3D).global_position + Vector3(0, 0.8, 0) - q.global_position).normalized() q.set("velocity", dir * 7.5) func _on_boss_defeated() -> void: _phase = Phase.DONE Achievements.unlock("beat_hongkong") GameState.set_flag("hongkong_defeated", true) var ui := get_node_or_null("/root/UIRoot") if ui and ui.has_method("show_dialog"): ui.show_dialog_key("dialog_hongkong_boss", 3.0) await get_tree().create_timer(2.5).timeout ui.show_dialog_key("dialog_bear_end", 5.0) await get_tree().create_timer(3.5).timeout GameState.goto_scene("end_screen")