Untitled
unknown
python
a year ago
4.4 kB
16
Indexable
class_name DialogueBox
extends Control
enum MEMBER_TYPE {Dialogue, Choice, Animation}
@onready var speaker_label: Label = $%Name
@onready var text_label: RichTextLabel = $%Text
@onready var choice_container: HBoxContainer = %ChoiceContainer
@onready var name_box: TextureRect = %NameBox
@onready var animation_player: AnimationPlayer = $AnimationPlayer
@onready var tag_handler: TagHandler = %TagHandler
@onready var continue_label: Label = %ContinueLabel
const DEFAULT_TEXT_SPEED = 0.016
var conversation: Array
var text_speed: float = DEFAULT_TEXT_SPEED
var skip_pressed: bool = false
var dialogue_index: int
var break_dialogue: bool = false
var name_positions: Dictionary = {
"move_name_in": -49,
"move_name_out": 0,
}
func _ready() -> void:
continue_label.visible = false
var tween: Tween = create_tween()
modulate.a = 0
tween.tween_property(self, "modulate:a", 1, 0.5)
var json: String = FileAccess.get_file_as_string("res://tools/dialogue/test_dialogue.json")
parse_dialogue_json(json)
func _unhandled_input(_event: InputEvent) -> void:
if Input.is_action_just_pressed("primary_attack") && !skip_pressed:
skip_pressed = true
func parse_dialogue_json(json: String) -> void:
if len(json) == 0:
json = FileAccess.get_file_as_string("res://tools/dialogue/error_dialogue.json")
conversation = JSON.parse_string(json)
assign_next(conversation[0])
func assign_next(member: Dictionary) -> void:
match int(member.get("type", MEMBER_TYPE.Dialogue)):
MEMBER_TYPE.Dialogue:
handle_dialogue(member)
MEMBER_TYPE.Choice:
handle_choices(member)
MEMBER_TYPE.Animation:
pass
func handle_dialogue(dialogue: Dictionary) -> void:
text_speed = DEFAULT_TEXT_SPEED
speaker_label.text = dialogue.get("name", "")
if speaker_label.text == "":
if name_box.position.y != name_positions["move_name_out"]:
animation_player.play("move_name_in")
else:
if name_box.position.y != name_positions["move_name_in"]:
animation_player.play("move_name_out")
var text: String = dialogue.get("text", "An error has occured! Please report this to the developers.")
dialogue_index = conversation.find(dialogue)
tag_handler.find_pauses(text)
text = tag_handler.extract_tags(text)
text_label.text = text
text_label.visible_characters = 0
skip_pressed = false
for index in text.length():
text_label.visible_characters = index + 1
await handle_tag(text_label.visible_characters - 1)
if break_dialogue:
break_dialogue = false
goto_next()
return
if skip_pressed && !"skip" in dialogue.get("text"):
text_label.visible_characters = -1
continue_label.time = 0
await get_tree().process_frame
break
continue_label.time = 0
await get_tree().create_timer(text_speed).timeout
while true:
continue_label.visible = true
if Input.is_action_just_pressed("primary_attack"):
break
await get_tree().process_frame
continue_label.visible = false
goto_next()
func goto_next() -> void:
if dialogue_index < conversation.size() - 1:
speaker_label.text = ""
text_label.text = ""
assign_next(conversation[dialogue_index + 1])
else:
var tween: Tween = create_tween()
tween.tween_property(self, "modulate:a", 0, 0.5)
tween.finished.connect(tween_finished)
func handle_tag(_string_pos: int) -> void:
for tag: Tag in tag_handler.tags:
if tag.pos == _string_pos:
match tag.type:
"pause":
await get_tree().create_timer(tag.value).timeout
"speed":
text_speed = tag.value
"skip":
break_dialogue = true
func tween_finished() -> void:
queue_free()
func handle_choices(member: Dictionary) -> void:
if name_box.position.y != name_positions["move_name_out"]:
animation_player.play("move_name_in")
var choices: Dictionary = member.get("choices", {})
var flag: String = member.get("flag", "default")
for choice: String in choices:
var button := ChoiceButton.new()
button.text = choice
choice_container.add_child(button)
button.connect("button_down", choice_made.bind(flag, choice, choices[choice]))
func choice_made(flag: String, choice: String, next_json: String) -> void:
for button in choice_container.get_children():
button.queue_free()
if flag != "default":
Flags.flags[flag] = choice
parse_dialogue_json(FileAccess.get_file_as_string(next_json))
Editor is loading...
Leave a Comment