Dialouge not moving to next one

Godot Version

4.3

Question

I have a dictionary of dialogues with on_finish and condition on it, the on_finish works that once the current dialogue finish, active the function in on_finish. inside the function I can place calls to the next dialogue and do other things. the conditions are simply checks to verify that the dialogue has finished or met its requirements. right now my tired dialogue does not work, when discover dialogue is finished, it doesn’t move to the next dialogue (tired). I don’t know why, my logic works for previous dialogues, and the system I built works for them, so I’m not sure what stops tired from working. You might need to look at my other dialogues and their functions and conditions to fully understand how my system works, see the similarities, maybe you spot something I missed.
I hope this won’t be complicated, but I have to share the whole script. I have been trying so many times for days and have found no solution. Maybe someone could find something in the whole script.
the issue is located at stringName("discover") and stringName("tired") dialogues, discover works but I believe there could be something there blocking tired from working.

extends Node2D

@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 = StringName("welcome")
@onready var playername = Intro.player_name

# flags 
var dialogue_active: bool = true  
var track_tutorial_inputs: bool = false  # Controls input tracking for the tutorial
var discover_shown: bool = false
var plant_show: bool = false
var is_tired: bool = false


var required_keys_pressed: Dictionary = {
	"left": false,
	"right": false,
	"attacking": false
}

# Dialogues with conditions and on_finish for each
var dialogues = {
	StringName("welcome"): {
		"text": "Welcome %player_name%! 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,
		"condition": condition_welcome  
	},
	StringName("teach_move"): {
		"text": "Press the keys to move and attack.",
		"on_finish": show_ui_prompt,  
		"condition": condition_tutorial_inputs_complete  
	},
	StringName("proceed"): {
		"text": "Great! Let's proceed with the adventure.",
		"on_finish": show_plant,
		"condition": condition_proceed  
	},
	StringName("discover"): {
		"text": "Oh look, there is a plant growing.\nLet's see what happens when you attack it.",
		"on_finish": show_tired,  # Directly call the tired function here to continue the flow
		"condition": condition_discover_plant  
	},
	StringName("tired"): {
		"text": "You seem to be getting tired, how about taking a break?\nLets stop attack for 30 seconds and then you can continue.",
		"on_finish": null,
		"condition": condition_is_tired_active
	},
	StringName("rested"): {
		"text": "you seem to be getting tierd, how about taking a break.\nlets wait for 30 seconds before attacking again.",
		"on_finish": null,
		"condition": null
	},
	StringName("attack1"): {
		"text": "you seem to be attacking for quite some time, why wont you rest up for a bit?",
		"on_finish": null,
		"condition": null # Condition for attack1, works at tired, when player attack reset dialouge and shows options
	},
	StringName("procced2"): {
		"text": "you doing great, keep up the good work.\n remember if you feeling tired then rest up, but do not give up.",
		"on_finish": null,
		"condition": null
	},
	StringName("attack2"): {
		"text": " you have great strengh, but even strong people must rest, how about a rest?",
		"on_finish": null,
		"condition": null # Condition for attack2, works at procced2, when player attack reset dialouge and shows options
	},
	StringName("transform"): {
		"text": "Look, the bush has transformed into a tree.\nKeep attacking it.",
		"on_finish": null,
		"condition": null  
	},
	StringName("plant_defeated"): {
		"text": "Well done!",
		"on_finish": null,
		"condition": condition_is_plant_defeated 
	},
		StringName("plant_regrown"): {
		"text": "oh, it seems the plant is regrowing, keep attacking it.",
		"on_finish": null,
		"condition": condition_health_regen  
	},
}

func _ready() -> void:
	player.disable_inputs()
	ui_prompt.visible = false  
	start_typing_dialogue(current_dialogue_key)  


func show_ui_prompt() -> void:
	ui_prompt.visible = true  
	player.enable_inputs()  
	track_tutorial_inputs = true  # Start tracking inputs now

func show_plant():
	if !plant_show:
		plant_show = true
		plant.show_bush() 
		plant.activate_regeneration()

	if !discover_shown and plant_show:
		discover_shown = true
		start_typing_dialogue(StringName("discover")) 

func show_tired():
	if !is_tired:
		is_tired = true
		start_typing_dialogue(StringName("tired"))


# inputs check functions for teach_move dialouge

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

# conditions functions for dialouge indexes

func condition_welcome() -> bool:
	return true  # This condition is immediately satisfied

func condition_tutorial_inputs_complete() -> bool:
	# This checks if the player has completed all tutorial inputs (move and attack)
	return all_keys_pressed()  # Returns true if all required keys are pressed

func condition_proceed() -> bool:
	return plant_show and !discover_shown 

func condition_discover_plant() -> bool:
	return discover_shown

func condition_is_tired_active() -> bool:
	return is_tired

func condition_is_plant_defeated() -> bool:
	return plant.health == 0

func condition_health_regen():
	return plant.health == 1


# fundamental mechanic for dialouge system

func start_typing_dialogue(key: StringName) -> void:
	if dialogues.has(key):
		dialogue_active = true  
		var dialogue = dialogues[key]
		
		if key == StringName("welcome") and playername != "":
			dialogue["text"] = dialogue["text"].replace("%player_name%", playername)
		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:
	# Check the condition before moving to the next dialogue
	var dialogue = dialogues.get(current_dialogue_key)
	if dialogue:
		var condition = dialogue.get("condition")
		if condition and not condition.call():
			return  # Wait until the condition is satisfied

		# Proceed to the next dialogue if there's no condition or it's met
		current_dialogue_key = get_next_dialogue_key(current_dialogue_key)
		start_typing_dialogue(current_dialogue_key)

func get_next_dialogue_key(key: StringName) -> StringName:
	# Returns the next key in the dialogues dictionary or an empty StringName if no more dialogues
	var keys = dialogues.keys()
	var idx = keys.find(key) + 1
	if idx < keys.size():
		return keys[idx]
	return StringName("")  # Return an empty StringName instead of null

clarification for plant.activate_regeneration(). this call is regenerating health for the plant, I checked if this is what caused the issue by simply removing it, and the issue still exists, so I don’t think this caused any problem, but just in case I will explain the flow.

when procced finish —> discover dialogue is active + health regen —>/ suppose to then move to tired but not moving forward to this point