Connect bear-save, massage, farm paywall, cheese catapults, Dressler hijack, final boss phases, fat-stim UI, and scene fixes so the satire path plays through.
129 lines
4.4 KiB
GDScript
129 lines
4.4 KiB
GDScript
extends Node3D
|
|
## Wiese: Eisbär retten (Schlangen holen → Massage ODER hier abgeben), Glitzos.
|
|
|
|
var _glitzo_timer: float = 0.0
|
|
var _bear_saved: bool = false
|
|
var _attack_cd: float = 0.0
|
|
var _first_glitzo_done: bool = false
|
|
|
|
func _ready() -> void:
|
|
GameState.current_scene_id = "meadow"
|
|
GameState.heal_full()
|
|
_bear_saved = bool(GameState.get_flag("bear_saved", false))
|
|
_first_glitzo_done = Achievements.is_unlocked("first_glitzo")
|
|
var ui := get_node_or_null("/root/UIRoot")
|
|
if ui and ui.has_method("show_dialog"):
|
|
if _bear_saved:
|
|
ui.show_dialog(Locale.tr_key("dialog_bear_saved"))
|
|
else:
|
|
ui.show_dialog(Locale.tr_key("dialog_bear_help"))
|
|
var bear := get_node_or_null("Bear")
|
|
if bear and bear.has_signal("interacted"):
|
|
bear.interacted.connect(_on_bear)
|
|
var snake := get_node_or_null("SnakePickup")
|
|
if snake and snake.has_signal("interacted"):
|
|
snake.interacted.connect(_on_snake_pickup)
|
|
# Disable mower kill if snakes already bagged? Keep hazard until massage done.
|
|
if GameState.get_flag("snake_massaged", false):
|
|
_disable_mower()
|
|
|
|
func _process(delta: float) -> void:
|
|
_glitzo_timer += delta
|
|
if _glitzo_timer >= 3.5:
|
|
_glitzo_timer = 0.0
|
|
_spawn_glitzo()
|
|
_tick_glitzo_attacks(delta)
|
|
_cull_glitzos_off_meadow()
|
|
|
|
func _tick_glitzo_attacks(delta: float) -> void:
|
|
_attack_cd = max(0.0, _attack_cd - delta)
|
|
if _attack_cd > 0.0:
|
|
return
|
|
var player := get_tree().get_first_node_in_group("player")
|
|
if player == null:
|
|
return
|
|
for child in get_children():
|
|
if not child.is_in_group("enemy"):
|
|
continue
|
|
if not str(child.get("texture_path")).ends_with("glitzo.png") and not child.name.begins_with("Glitzo"):
|
|
continue
|
|
if child is Node3D and player.global_position.distance_to(child.global_position) < 1.6:
|
|
_attack_cd = 1.15
|
|
GameState.register_glitzo_hit()
|
|
return
|
|
|
|
func _cull_glitzos_off_meadow() -> void:
|
|
## DESIGN: leave the meadow → they shed pixels and die.
|
|
for child in get_children():
|
|
if child is Node3D and (child.name.begins_with("Glitzo") or str(child.get("texture_path")).ends_with("glitzo.png")):
|
|
var p: Vector3 = child.global_position
|
|
if abs(p.x) > 18.0 or abs(p.z) > 18.0:
|
|
child.queue_free()
|
|
|
|
func _spawn_glitzo() -> void:
|
|
var scene: PackedScene = load("res://scenes/prefabs/enemy.tscn")
|
|
if scene == null:
|
|
return
|
|
var g: Node3D = scene.instantiate()
|
|
g.name = "GlitzoSpawn_%d" % Time.get_ticks_msec()
|
|
g.set("max_hp", 4)
|
|
g.set("texture_path", "res://assets/sprites/placeholders/glitzo.png")
|
|
if not _first_glitzo_done:
|
|
g.set("achievement_on_defeat", "first_glitzo")
|
|
add_child(g)
|
|
g.global_position = Vector3(randf_range(-8, 8), 0.1, randf_range(-6, 2))
|
|
var bill: Node = g.get_node_or_null("BillboardSprite")
|
|
if bill and bill.has_method("set_texture"):
|
|
var tex: Texture2D = load("res://assets/sprites/placeholders/glitzo.png")
|
|
if tex:
|
|
bill.set_texture(tex)
|
|
if g.has_signal("defeated"):
|
|
g.defeated.connect(_on_glitzo_killed)
|
|
|
|
func _on_glitzo_killed() -> void:
|
|
_first_glitzo_done = true
|
|
|
|
func _on_bear(_npc: Node = null) -> void:
|
|
var ui := get_node_or_null("/root/UIRoot")
|
|
if _bear_saved:
|
|
if ui and ui.has_method("show_dialog"):
|
|
ui.show_dialog(Locale.tr_key("dialog_bear_saved"))
|
|
return
|
|
# Need snakes rescued via inventory + preferably massaged; tooth if massaged or handing snakes in after pickup
|
|
if Inventory.has_item("snake") and GameState.get_flag("snake_massaged", false):
|
|
_save_bear()
|
|
return
|
|
if Inventory.has_item("snake"):
|
|
if ui and ui.has_method("show_dialog"):
|
|
ui.show_dialog(Locale.tr_key("dialog_villager_snake"))
|
|
return
|
|
# First talk: point at snakes / give hint, auto-pickup one for convenience
|
|
Inventory.add_item("snake", 1)
|
|
if ui and ui.has_method("show_dialog"):
|
|
ui.show_dialog(Locale.tr_key("dialog_snake_pain") + "\n" + Locale.tr_key("dialog_bear_help"))
|
|
|
|
func _on_snake_pickup(_npc: Node = null) -> void:
|
|
if not Inventory.has_item("snake"):
|
|
Inventory.add_item("snake", 1)
|
|
var ui := get_node_or_null("/root/UIRoot")
|
|
if ui and ui.has_method("show_dialog"):
|
|
ui.show_dialog(Locale.tr_key("dialog_snake_pain"))
|
|
|
|
func _save_bear() -> void:
|
|
_bear_saved = true
|
|
GameState.set_flag("bear_saved", true)
|
|
if not Inventory.has_item("tooth"):
|
|
Inventory.add_item("tooth", 1)
|
|
_disable_mower()
|
|
var ui := get_node_or_null("/root/UIRoot")
|
|
if ui and ui.has_method("show_dialog"):
|
|
ui.show_dialog(Locale.tr_key("dialog_bear_saved"), 4.5)
|
|
|
|
func _disable_mower() -> void:
|
|
var mower := get_node_or_null("MowerHazard")
|
|
if mower:
|
|
mower.queue_free()
|
|
|
|
func notify_snake_massaged() -> void:
|
|
if not _bear_saved:
|
|
_save_bear()
|