Untitled

Anonymous
plain_text
02/23/2026 2:49 AM
6.9 KB
10
Indexable
extends Node2D

@export var delivery_item_icon: Texture2D  # reward icon shown in overlay
@export var correct_box_index: int = 2     # 0-based index in `boxes` array

var dialogue_ui
var note_ui
var fade_rect
var item_get_overlay
var main_ref

@onready var player = $Player

# Put your box Interactable nodes into this array in the Inspector OR fetch them in _ready.
@export var boxes: Array[NodePath] = []

@onready var beep_wrong: AudioStreamPlayer = $Sounds/BeepWrong
@onready var beep_right: AudioStreamPlayer = $Sounds/BeepRight

var has_reward := false
var _spawn_from := "left"

@onready var spawn_left: Marker2D = get_node_or_null("SpawnLeft")
@onready var spawn_right: Marker2D = get_node_or_null("SpawnRight")

func set_spawn_from(side: String) -> void:
	_spawn_from = side

func bind_ui(d, n, f, i, m) -> void:
	dialogue_ui = d
	note_ui = n
	fade_rect = f
	item_get_overlay = i
	main_ref = m

func _ready() -> void:
	await _apply_spawn_if_present()
	_wire_boxes()

func _apply_spawn_if_present() -> void:
	if spawn_left == null or spawn_right == null:
		return

	var target := spawn_left if _spawn_from == "left" else spawn_right
	player.set_can_move(false)
	player.global_position = target.global_position
	await get_tree().create_timer(0.2).timeout
	player.set_can_move(true)

# -------------------------------------------------
# Dialogue choice helper
# -------------------------------------------------
func _connect_choice_once(handler: Callable) -> void:
	if dialogue_ui == null:
		push_error("Foxpost: dialogue_ui is null (bind_ui not called?)")
		return
	if dialogue_ui.choice_selected.is_connected(handler):
		dialogue_ui.choice_selected.disconnect(handler)
	dialogue_ui.choice_selected.connect(handler, CONNECT_ONE_SHOT)

# -------------------------------------------------
# Wire up box interactables
# -------------------------------------------------
func _wire_boxes() -> void:
	if boxes.is_empty():
		push_error("Foxpost: boxes array is empty. Assign box interactable NodePaths in Inspector.")
		return

	for idx in range(boxes.size()):
		var n := get_node_or_null(boxes[idx])
		if n == null:
			push_error("Foxpost: Missing box node at path: " + str(boxes[idx]))
			continue

		# supports either the node itself has interacted, or it has a child named Interactable
		var interactable := n
		if not interactable.has_signal("interacted"):
			var child := n.get_node_or_null("Interactable")
			if child != null and child.has_signal("interacted"):
				interactable = child

		if interactable == null or not interactable.has_signal("interacted"):
			push_error("Foxpost: Node has no interacted signal at: " + str(boxes[idx]))
			continue

		# bind index into callable
		interactable.interacted.connect(func(): _on_box_interacted(idx))

# -------------------------------------------------
# Box interaction
# -------------------------------------------------
func _on_box_interacted(idx: int) -> void:
	if has_reward:
		return

	player.set_can_move(false)

	if idx == correct_box_index:
		await _handle_right_box()
	else:
		_handle_wrong_box(idx)

func _handle_wrong_box(_idx: int) -> void:
	if beep_wrong:
		beep_wrong.play()

	dialogue_ui.show_dialogue(
		"Foxpost",
		"Ráteszed a kezed.\nMeg se moccan.\n\nNem ez az.",
		null,
		[
			{"label": "Bezár"}
		]
	)
	_connect_choice_once(_close_after_wrong)

func _close_after_wrong(_i: int) -> void:
	if dialogue_ui:
		dialogue_ui.hide_dialogue()
	player.set_can_move(true)

func _handle_right_box() -> void:
	if beep_right:
		beep_right.play()

	dialogue_ui.show_dialogue(
		"Foxpost",
		"Ráteszed a kezed.\nEgy pillanat…\n\nNyílik.",
		null,
		[]
	)

	# wait until typing is done, then wait for E to close
	while dialogue_ui != null and dialogue_ui.is_typing():
		await get_tree().process_frame

	while true:
		await get_tree().process_frame
		if Input.is_action_just_pressed("interact"):
			if dialogue_ui:
				dialogue_ui.hide_dialogue()
			break

	has_reward = true
	GameState.unlock_home = true

	await _play_item_get_sequence(delivery_item_icon)

	# Send player to final scene
	if main_ref != null and main_ref.has_method("go_home"):
		main_ref.go_home("right")
	else:
		push_error("Foxpost: main_ref.go_home missing")

# -------------------------------------------------
# Reward animation (same pattern as other scenes)
# -------------------------------------------------
func _play_item_get_sequence(texture: Texture2D) -> void:
	if fade_rect == null or item_get_overlay == null or texture == null:
		return

	var icon := item_get_overlay.get_node("Center/ItemIcon") as TextureRect
	if icon == null:
		return

	fade_rect.visible = true
	fade_rect.modulate.a = 0.0

	item_get_overlay.visible = true
	icon.visible = true
	icon.texture = texture
	icon.modulate = Color(1, 1, 1, 0)

	var t := create_tween()
	t.tween_property(fade_rect, "modulate:a", 1.0, 0.25)
	await t.finished

	var t2 := create_tween()
	t2.tween_property(icon, "modulate:a", 1.0, 0.2)
	await t2.finished

	await get_tree().create_timer(0.4).timeout

	var t3 := create_tween()
	t3.tween_property(icon, "modulate:a", 0.0, 0.2)
	await t3.finished

	item_get_overlay.visible = false

	var t4 := create_tween()
	t4.tween_property(fade_rect, "modulate:a", 0.0, 0.25)
	await t4.finished

	fade_rect.visible = false
Editor is loading...
Leave a Comment