Added dialogue manager plugin
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
@tool
|
||||
|
||||
@icon("uid://ja67jst5iqyy")
|
||||
|
||||
## A special [Area2D] node to hold information about starting dialogue.
|
||||
##
|
||||
## Assuming [code]dialogue_resource[/code] and [code]cue[/code] have been configured you can
|
||||
## call [code]action()[/code] on this node at runtime to start dialogue.
|
||||
class_name DialogueActionable2D extends Area2D
|
||||
|
||||
|
||||
## Emitted when this [DialogueActionable2D] has [code]action()[/code] called on it.
|
||||
signal actioned()
|
||||
|
||||
## Emitted when the [DialogueResource] associated with this [DialogueActionable2D] ends. [b]NOTE:[/b] The
|
||||
## signal is also emitted if the same resource is used for multiple [DialogueActionable2D] nodes in the tree.
|
||||
signal dialogue_ended()
|
||||
|
||||
|
||||
## The [DialogueResource] to use when starting dialogue.
|
||||
@export var dialogue_resource: DialogueResource = null:
|
||||
set(value):
|
||||
dialogue_resource = value
|
||||
if dialogue_resource == null:
|
||||
dialogue_cue = ""
|
||||
notify_property_list_changed()
|
||||
get:
|
||||
return dialogue_resource
|
||||
|
||||
## The target cue to start dialogue from.
|
||||
@export var dialogue_cue: String = ""
|
||||
|
||||
## The dialogue balloon that was last used by calling [code]action()[/code] (if there was one).
|
||||
var dialogue_balloon: Node
|
||||
|
||||
## The method used to start dialogue action [code]action()[/code] is called. Override if you need different logic.
|
||||
static var start_dialogue: Callable = func(with_dialogue_resource: DialogueResource, from_cue: String, extra_game_states: Array) -> Node:
|
||||
return Engine.get_singleton("DialogueManager").show_dialogue_balloon(with_dialogue_resource, from_cue, extra_game_states)
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if not Engine.is_editor_hint():
|
||||
add_to_group("dialogue_actionables")
|
||||
Engine.get_singleton("DialogueManager").dialogue_ended.connect(_on_dialogue_ended)
|
||||
|
||||
|
||||
#region Public
|
||||
|
||||
|
||||
## Action this [DialogueActionable2D]. If a [DialogueResource] and cue have been set on this node then
|
||||
## it will start dialogue.
|
||||
func action() -> void:
|
||||
if is_instance_valid(dialogue_resource) and not dialogue_cue.is_empty():
|
||||
dialogue_balloon = start_dialogue.call(dialogue_resource, dialogue_cue, [{ actionable = self }, owner])
|
||||
actioned.emit()
|
||||
|
||||
|
||||
## Find the nearest [DialogueActionable2D] to a given position.
|
||||
static func get_nearest_actionable_to(target_position: Vector2) -> DialogueActionable2D:
|
||||
var nearest_distance: float = INF
|
||||
var nearest_actionable: DialogueActionable2D = null
|
||||
var actionables: Array[Node] = (Engine.get_main_loop() as SceneTree).get_nodes_in_group("dialogue_actionables")
|
||||
for actionable: DialogueActionable2D in actionables:
|
||||
var distance: float = actionable.global_position.distance_squared_to(target_position)
|
||||
if distance < nearest_distance:
|
||||
nearest_distance = distance
|
||||
nearest_actionable = actionable
|
||||
|
||||
return nearest_actionable
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Signals
|
||||
|
||||
|
||||
func _on_dialogue_ended(ending_dialogue_resource: DialogueResource) -> void:
|
||||
if ending_dialogue_resource == dialogue_resource:
|
||||
dialogue_ended.emit()
|
||||
|
||||
|
||||
#endregion
|
||||
Reference in New Issue
Block a user