]> Untitled Git - wolf-seeking-sheep.git/blob - addons/dialogic/Modules/Text/node_dialog_text.gd
Squashed commit of the following:
[wolf-seeking-sheep.git] / addons / dialogic / Modules / Text / node_dialog_text.gd
1 @icon("node_dialog_text_icon.svg")
2 class_name DialogicNode_DialogText
3 extends RichTextLabel
4
5 ## Dialogic node that can reveal text at a given (changeable speed).
6
7 signal started_revealing_text()
8 signal continued_revealing_text(new_character : String)
9 signal finished_revealing_text()
10 enum Alignment {LEFT, CENTER, RIGHT}
11
12 @export var enabled := true
13 @export var alignment := Alignment.LEFT
14 @export var textbox_root: Node = self
15
16 @export var hide_when_empty := false
17 @export var start_hidden := true
18
19 var revealing := false
20 var base_visible_characters := 0
21
22 # The used speed per revealed character.
23 # May be overwritten when syncing reveal speed to voice.
24 var active_speed: float = 0.01
25
26 var speed_counter: float = 0
27
28 func _set(property: StringName, what: Variant) -> bool:
29         if property == 'text' and typeof(what) == TYPE_STRING:
30
31                 text = what
32
33                 if hide_when_empty:
34                         textbox_root.visible = !what.is_empty()
35
36                 return true
37         return false
38
39
40 func _ready() -> void:
41         # add to necessary
42         add_to_group('dialogic_dialog_text')
43         meta_hover_ended.connect(_on_meta_hover_ended)
44         meta_hover_started.connect(_on_meta_hover_started)
45         meta_clicked.connect(_on_meta_clicked)
46         gui_input.connect(on_gui_input)
47         bbcode_enabled = true
48         if textbox_root == null:
49                 textbox_root = self
50
51         if start_hidden:
52                 textbox_root.hide()
53         text = ""
54
55
56 # this is called by the DialogicGameHandler to set text
57
58 func reveal_text(_text: String, keep_previous:=false) -> void:
59         if !enabled:
60                 return
61         show()
62
63         if !keep_previous:
64                 text = _text
65                 base_visible_characters = 0
66
67                 if alignment == Alignment.CENTER:
68                         text = '[center]'+text
69                 elif alignment == Alignment.RIGHT:
70                         text = '[right]'+text
71                 visible_characters = 0
72
73         else:
74                 base_visible_characters = len(text)
75                 visible_characters = len(get_parsed_text())
76                 text = text + _text
77
78                 # If Auto-Skip is enabled and we append the text (keep_previous),
79                 # we can skip revealing the text and just show it all at once.
80                 if DialogicUtil.autoload().Inputs.auto_skip.enabled:
81                         visible_characters = 1
82                         return
83
84         revealing = true
85         speed_counter = 0
86         started_revealing_text.emit()
87
88
89 func set_speed(delay_per_character:float) -> void:
90         if DialogicUtil.autoload().Text.is_text_voice_synced() and DialogicUtil.autoload().Voice.is_running():
91                 var total_characters := get_total_character_count() as float
92                 var remaining_time: float = DialogicUtil.autoload().Voice.get_remaining_time()
93                 var synced_speed :=  remaining_time / total_characters
94                 active_speed = synced_speed
95
96         else:
97                 active_speed = delay_per_character
98
99
100 ## Reveals one additional character.
101 func continue_reveal() -> void:
102         if visible_characters <= get_total_character_count():
103                 revealing = false
104
105                 var current_index := visible_characters - base_visible_characters
106                 await DialogicUtil.autoload().Text.execute_effects(current_index, self, false)
107
108                 if visible_characters == -1:
109                         return
110
111                 revealing = true
112                 visible_characters += 1
113
114                 if visible_characters > -1 and visible_characters <= len(get_parsed_text()):
115                         continued_revealing_text.emit(get_parsed_text()[visible_characters-1])
116         else:
117                 finish_text()
118                 # if the text finished organically, add a small input block
119                 # this prevents accidental skipping when you expected the text to be longer
120                 DialogicUtil.autoload().Inputs.block_input(ProjectSettings.get_setting('dialogic/text/advance_delay', 0.1))
121
122
123 ## Reveals the entire text instantly.
124 func finish_text() -> void:
125         visible_ratio = 1
126         DialogicUtil.autoload().Text.execute_effects(-1, self, true)
127         revealing = false
128         DialogicUtil.autoload().current_state = DialogicGameHandler.States.IDLE
129
130         finished_revealing_text.emit()
131
132
133 ## Checks if the next character in the text can be revealed.
134 func _process(delta: float) -> void:
135         if !revealing or DialogicUtil.autoload().paused:
136                 return
137
138         speed_counter += delta
139
140         while speed_counter > active_speed and revealing and !DialogicUtil.autoload().paused:
141                 speed_counter -= active_speed
142                 continue_reveal()
143
144
145
146 func _on_meta_hover_started(_meta:Variant) -> void:
147         DialogicUtil.autoload().Inputs.action_was_consumed = true
148
149 func _on_meta_hover_ended(_meta:Variant) -> void:
150         DialogicUtil.autoload().Inputs.action_was_consumed = false
151
152 func _on_meta_clicked(_meta:Variant) -> void:
153         DialogicUtil.autoload().Inputs.action_was_consumed = true
154
155
156 ## Handle mouse input
157 func on_gui_input(event:InputEvent) -> void:
158         DialogicUtil.autoload().Inputs.handle_node_gui_input(event)