Godot Version
4.3
suggestions
I made a script that handles dialogues with a dictionary and enums based on conditions or no conditions at all, my script works as it should, but I would like it to be more optimized if anyone has suggestions on how to make it more organized and easy to add new dialogues. the problem I’m facing is that whenever I add a new dialogue, I have to remodify other parts in the code for the flow to keep going as it is, when a new dialogue is added the flow is sometimes broken, depending on where the dialogue index is located.
extends Node2D
# Enum for dialogue keys
enum DialogueKeys { WELCOME, TEACH_MOVE, PROCEED, DISCOVER, STATIC, TRANSFORM }
@onready var player = $"../Player"
@onready var text_label = $RichTextLabel
@onready var ui_prompt = $ui_container
@onready var plant = $"../tree"
var typing_speed: float = 0.05
var is_typing: bool = false
var char_index: int = 0
var current_text: String = ""
var current_dialogue_key: int = DialogueKeys.WELCOME
# flags
var dialogue_active: bool = true
var track_tutorial_inputs: bool = false # Controls input tracking for the tutorial
var transform_dialogue_shown: bool = false
var static_dialogue_shown: bool = false
var required_keys_pressed: Dictionary = {
"left": false,
"right": false,
"attacking": false
}
var dialogues: Dictionary = {
DialogueKeys.WELCOME: {
"text": "Welcome! My name is the one. I'm glad you have arrived.\nI'm going to teach you the basics of this world and how to survive.",
"on_finish": null
},
DialogueKeys.TEACH_MOVE: {
"text": "Press the keys to move and attack.",
"on_finish": show_ui_prompt # Start tracking inputs here
},
DialogueKeys.PROCEED: {
"text": "Great! Let's proceed with the adventure.",
"on_finish": null
},
DialogueKeys.DISCOVER: {
"text": "Oh look, there is a plant growing.\nLet's cut it out. Go and attack it.",
"on_finish": discover_plant
},
DialogueKeys.STATIC: {
"text": "dialogue text.",
"on_finish": null
},
DialogueKeys.TRANSFORM: {
"text": "look, the bush has transformed into a tree.\nkeep attacking it.",
"on_finish": null
}
}
func _ready() -> void:
player.disable_inputs()
ui_prompt.visible = false
start_typing_dialogue(current_dialogue_key)
func _process(delta: float) -> void:
# Check if the plant health is 10 and the dialogue hasn't been shown yet
if plant.health == 10 and !transform_dialogue_shown:
transform_dialogue_shown = true
plant.transform_to_tree()
func start_typing_dialogue(key: int) -> void:
if dialogues.has(key):
dialogue_active = true
var dialogue = dialogues[key]
start_typing(dialogue["text"])
func start_typing(text: String) -> void:
char_index = 0
text_label.text = text
text_label.visible_characters = 0
is_typing = true
current_text = text
_type_character()
func _type_character() -> void:
if is_typing and char_index < current_text.length():
char_index += 1
text_label.visible_characters = char_index
await get_tree().create_timer(typing_speed).timeout
_type_character()
else:
is_typing = false
handle_dialogue_finish()
func handle_dialogue_finish() -> void:
var dialogue = dialogues[current_dialogue_key]
var on_finish = dialogue.get("on_finish", null)
if on_finish and on_finish is Callable:
on_finish.call()
else:
move_to_next_dialogue()
func move_to_next_dialogue() -> void:
if current_dialogue_key + 1 in dialogues:
current_dialogue_key += 1
start_typing_dialogue(current_dialogue_key)
else:
print("All dialogues have been completed.")
dialogue_active = false
track_tutorial_inputs = false # Stop tracking inputs after tutorial
func show_ui_prompt() -> void:
ui_prompt.visible = true
player.enable_inputs()
track_tutorial_inputs = true # Start tracking inputs now
func discover_plant() -> void:
plant.show_bush()
plant.activate_regeneration()
print("Dialogue complete. Plant discovered and activated!")
# Directly show STATIC dialogue immediately after DISCOVER
if !static_dialogue_shown:
static_dialogue_shown = true # Prevent this from re-triggering
start_typing_dialogue(DialogueKeys.STATIC) # Show STATIC dialogue
func _input(event: InputEvent) -> void:
if not dialogue_active or not track_tutorial_inputs:
return # Ignore inputs unless explicitly allowed
if event.is_action_pressed("left"):
required_keys_pressed["left"] = true
elif event.is_action_pressed("right"):
required_keys_pressed["right"] = true
elif event.is_action_pressed("attacking"):
required_keys_pressed["attacking"] = true
if all_keys_pressed():
ui_prompt.visible = false
track_tutorial_inputs = false # Stop tracking inputs after completion
move_to_next_dialogue()
func all_keys_pressed() -> bool:
for key in required_keys_pressed.keys():
if not required_keys_pressed[key]:
return false
return true