extends Node # Signals signal OpeningOfOpenedChestAttempted # Exports @export var player: PlayerCharacter @export var auto_connect_all_chests := true # Private Variables var _chests_in_range: Array[BaseChest] = [] # Private Methods func _ready() -> void: player.interact_scanner.area_entered.connect(_on_interact_scanned) player.interact_scanner.area_exited.connect(_on_interact_unscanned) player.interact_scanner.InteractionActionTriggered.connect(_on_interact_triggered) var chests := GroupUtils.GetAllTreasureChests() for chest in chests: chest.OpeningAnimationStarted.connect(_on_chest_opening_animation_started) func _on_chest_opening_animation_started() -> void: var player := GroupUtils.GetPlayer() var children := player.get_children() player.QueueCutsceneState() var camera_idx := children.find_custom(func(x): return x is Camera2D) if camera_idx == -1: return # Zoom In var camera := children[camera_idx] as Camera2D var current_zoom := camera.zoom await get_tree().create_tween().tween_property(camera, "zoom", current_zoom + Vector2(2, 2), 0.5).finished # Player the player's chest opening animation player.state_machine.QueueStateChange(PlayerStateMachine.States.PLAY_ANIMATION, { "animation_name": "opening-chest-down" }) await player.state_machine.StateChanged var play_animation_state := player.state_machine.current_state as PlayerPlayAnimationState await play_animation_state.AnimationFinished player.state_machine.QueueStateChange(PlayerStateMachine.States.IDLE) # Zoom back out await get_tree().create_tween().tween_property(camera, "zoom", current_zoom, 0.5).finished func _on_interact_scanned(area: Area2D) -> void: var chest = area.get_parent() if chest == null or chest is not BaseChest: return if _chests_in_range.has(chest): return _chests_in_range.append(chest) func _on_interact_unscanned(area: Area2D) -> void: var chest = area.get_parent() if chest == null or chest is not BaseChest: return if !_chests_in_range.has(chest): return _chests_in_range.erase(chest) func _on_interact_triggered() -> void: if _chests_in_range.is_empty(): return var chest := _chests_in_range[0] if !chest.is_open: chest.Open() else: chest.OpenAlreadyOpened() OpeningOfOpenedChestAttempted.emit()