class_name Scene extends Node3D ### globals @export var next_scene: PackedScene @export var starting_dialogue: DialogicTimeline = null @onready var _player := %Player @onready var _prompt := %prompt ### overrides func _ready() -> void: # hook up Dialogic timeline signals to togger player control Dialogic.timeline_started.connect(_dialogic_timeline_start) Dialogic.timeline_ended.connect(_dialogic_timeline_end) Dialogic.signal_event.connect(_on_dialogic_signal) Dialogic.text_signal.connect(_on_dialogic_text_signal) if starting_dialogue: _start_dialogue(starting_dialogue) func _input(event: InputEvent): if event.is_action_pressed("capture_input"): if Dialogic.current_timeline == null: Input.mouse_mode = Input.MOUSE_MODE_CAPTURED elif event.is_action_pressed("ui_cancel"): if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: Input.mouse_mode = Input.MOUSE_MODE_VISIBLE else: get_tree().quit() elif event.is_action_pressed("player-action"): if _player.actionable_node: # TODO: player may have different actions than dialogue! var timeline: DialogicTimeline = _player.actionable_node.get_next_dialogue() var lookAt: Node3D = _player.actionable_node.get_tree().get_first_node_in_group("LookAt") _start_dialogue(timeline, lookAt if lookAt else _player.actionable_node) else: _player.toggle_phone_out() ### dialogue functions func _on_dialogic_signal(arg): print("Got Dialogic signal: " + str(arg)) if arg is String: match arg: "next_scene": get_tree().change_scene_to_packed(next_scene) elif arg is Dictionary: if "player_position" in arg: # move player to global position of node3D object var pos_name: String = arg["player_position"] var node: Node3D = get_tree().get_nodes_in_group("Location").filter( func (loc): return loc.name == pos_name ).front() if node == null: print_debug("Couldn't find a node with the name: " + pos_name) else: _player.global_position = node.global_position if "player_rotation" in arg: _player.global_rotation.y = arg["player_rotation"] if "player_lookat" in arg: # move player to global position of node3D object var pos_name: String = arg["player_lookat"] var node: Node3D = get_tree().get_nodes_in_group("LookAt").filter( func (loc): return loc.name == pos_name ).front() if node == null: print_debug("Couldn't find a node with the name: " + pos_name) else: _player.camera_look_at(node.global_position, arg.get("lookat_snap", false)) if "enable_trigger" in arg: var trigger_name: String = arg["enable_trigger"] var trigger: Trigger = get_tree().get_nodes_in_group("Trigger").filter( func (t): return t.name == trigger_name ).front() if trigger == null: print_debug("Couldn't find a trigger with the name: " + trigger_name) else: trigger.monitoring = true func _on_dialogic_text_signal(_arg:String): pass func _start_dialogue(timeline: DialogicTimeline, lookAt: Node3D = null) -> bool: # if lookAt node is provided, player should look in that direction if lookAt != null: _player.camera_look_at(lookAt.global_position) # if dialogic timeline is not running, start a new one if Dialogic.current_timeline == null: Dialogic.start(timeline) get_viewport().set_input_as_handled() return true return false func _on_dialogue_trigger_body_entered(trigger: DialogueTrigger, _body: Node3D) -> void: _start_dialogue(trigger.timeline, trigger) func _dialogic_timeline_start() -> void: print("Dialogue started") _player.movement_enabled = false _player.camera_movement_enabled = false _player.phone_out(false) _player.velocity = Vector3.ZERO Input.mouse_mode = Input.MOUSE_MODE_VISIBLE func _dialogic_timeline_end() -> void: print("Dialogue ended") Input.mouse_mode = Input.MOUSE_MODE_CAPTURED _player.movement_enabled = true _player.camera_movement_enabled = true ### actionable functions func _on_player_found_actionable_node(node: Node3D) -> void: _prompt.text = "[center]" + node.get("prompt") _prompt.visible = true func _on_player_no_actionable_node() -> void: _prompt.visible = false