This commit is contained in:
2025-11-26 18:57:37 -06:00
parent 1e83200bba
commit d532a9ab21
25 changed files with 525 additions and 534 deletions

View File

@@ -1,34 +1,34 @@
class_name ClosableMenu extends Control
@export var isOpen: bool:
set(newValue):
isOpen = newValue
visible = newValue
if newValue:
opened.emit()
else:
closed.emit()
get():
return isOpen
set(newValue):
isOpen = newValue
visible = newValue
if newValue:
opened.emit()
else:
closed.emit()
get():
return isOpen
signal closed
signal opened
func _enter_tree() -> void:
visible = isOpen
visible = isOpen
func _exit_tree() -> void:
visible = false
visible = false
func _ready() -> void:
visible = isOpen
print("ClosableMenu is ready, isOpen: ", isOpen)
visible = isOpen
print("ClosableMenu is ready, isOpen: ", isOpen)
func close() -> void:
isOpen = false
isOpen = false
func open() -> void:
isOpen = true
isOpen = true
func toggle() -> void:
isOpen = !isOpen
isOpen = !isOpen

View File

@@ -12,62 +12,62 @@ var currentViewScrolled = true;
var isSpeedupDown = false;
var isClosed:bool = false:
get():
return !self.visible;
set(value):
self.visible = !value;
get():
return !self.visible;
set(value):
self.visible = !value;
signal textboxClosing
func _ready() -> void:
label = $MarginContainer/Label
isClosed = true
label = $MarginContainer/Label
isClosed = true
func _process(delta: float) -> void:
if label.getFinalText() == "":
isClosed = true;
return;
if label.visible_characters >= label.getCharactersDisplayedCount():
if (label.maxLines + label.startLine) < label.getTotalLineCount():
# Not on last page.
if Input.is_action_just_pressed("interact"):
label.startLine += label.maxLines;
label.visible_characters = 0;
currentViewScrolled = false;
return
if label.getFinalText() == "":
isClosed = true;
return;
if label.visible_characters >= label.getCharactersDisplayedCount():
if (label.maxLines + label.startLine) < label.getTotalLineCount():
# Not on last page.
if Input.is_action_just_pressed("interact"):
label.startLine += label.maxLines;
label.visible_characters = 0;
currentViewScrolled = false;
return
currentViewScrolled = true;
else:
# On last page
if Input.is_action_just_released("interact"):
textboxClosing.emit();
isClosed = true;
currentViewScrolled = true
return;
currentViewScrolled = true;
else:
# On last page
if Input.is_action_just_released("interact"):
textboxClosing.emit();
isClosed = true;
currentViewScrolled = true
return;
if Input.is_action_just_pressed("interact"):
isSpeedupDown = true;
elif Input.is_action_just_released("interact"):
isSpeedupDown = false;
elif !Input.is_action_pressed("interact"):
isSpeedupDown = false;
if Input.is_action_just_pressed("interact"):
isSpeedupDown = true;
elif Input.is_action_just_released("interact"):
isSpeedupDown = false;
elif !Input.is_action_pressed("interact"):
isSpeedupDown = false;
revealTimer += delta;
if isSpeedupDown:
revealTimer += delta;
revealTimer += delta;
if isSpeedupDown:
revealTimer += delta;
if revealTimer > VN_REVEAL_TIME:
revealTimer = 0;
label.visible_characters += 1;
if revealTimer > VN_REVEAL_TIME:
revealTimer = 0;
label.visible_characters += 1;
func setText(text:String) -> void:
isClosed = false;
revealTimer = 0;
currentViewScrolled = false;
label.visible_characters = 0;
label.startLine = 0;
label.text = ""
await get_tree().process_frame# Absolutely needed to make the text wrap
label.text = text;
label.visible_characters = 0;
isClosed = false;
revealTimer = 0;
currentViewScrolled = false;
label.visible_characters = 0;
label.startLine = 0;
label.text = ""
await get_tree().process_frame# Absolutely needed to make the text wrap
label.text = text;
label.visible_characters = 0;

View File

@@ -57,15 +57,7 @@ Line 10"
_finalText = "Hello, I'm an NPC!
This is the second line here, I am purposefully adding a tonne of words so that it is forced to go across multiple lines and you can see how the word wrapping works, not only using Godot's built in word wrapping but with my advanced visibile characters smart wrapping. Now I am doing a multiline thing
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
Line 10"
Line 2"
_newLineIndexes = Array[int]([0])
_lines = PackedStringArray("Hello, I\'m an NPC!", "This is the second line here, I am purposefully adding a tonne of words so that it is forced to go across multiple lines and you can see how the word wrapping works, not only using Godot\'s built in word wrapping but with my advanced visibile characters smart wrapping. Now I am doing a multiline thing", "Line 1", "Line 2", "Line 3", "Line 4", "Line 5", "Line 6", "Line 7", "Line 8", "Line 9", "Line 10")
maxLines = 4

View File

@@ -9,133 +9,133 @@ class_name AdvancedRichText extends RichTextLabel
# Hides the original RichTextLabel text property
func _set(property: StringName, value) -> bool:
if property == "text":
userText = value
_recalcText()
return true
elif property == "richtextlabel_text":
text = value
return true
return false
if property == "text":
userText = value
_recalcText()
return true
elif property == "richtextlabel_text":
text = value
return true
return false
func _get(property: StringName):
if property == "text":
return userText
elif property == "richtextlabel_text":
return text
return null
if property == "text":
return userText
elif property == "richtextlabel_text":
return text
return null
@export var translate:bool = true:
set(value):
translate = value
_recalcText()
get():
return translate
set(value):
translate = value
_recalcText()
get():
return translate
@export var smartWrap:bool = true:
set(value):
smartWrap = value
_recalcText()
get():
return smartWrap
set(value):
smartWrap = value
_recalcText()
get():
return smartWrap
@export var maxLines:int = -1:
set(value):
maxLines = value
_recalcText()
get():
return maxLines
set(value):
maxLines = value
_recalcText()
get():
return maxLines
@export var startLine:int = 0:
set(value):
startLine = value
_recalcText()
get():
return startLine
set(value):
startLine = value
_recalcText()
get():
return startLine
# Returns count of characters that can be displayed, assuming visible_chars = -1
func getCharactersDisplayedCount() -> int:
# Count characters
var count = 0
var lineCount = min(startLine + maxLines, _lines.size()) - startLine
for i in range(startLine, startLine + lineCount):
count += _lines[i].length()
if lineCount > 1:
count += lineCount - 1 # Add newlines
return count
# Count characters
var count = 0
var lineCount = min(startLine + maxLines, _lines.size()) - startLine
for i in range(startLine, startLine + lineCount):
count += _lines[i].length()
if lineCount > 1:
count += lineCount - 1 # Add newlines
return count
func getFinalText() -> String:
return _finalText
return _finalText
func getTotalLineCount() -> int:
return _lines.size()
return _lines.size()
func _enter_tree() -> void:
self.threaded = false;
self.threaded = false;
func _recalcText() -> void:
_lines.clear()
_lines.clear()
if userText.is_empty():
self.richtextlabel_text = ""
return
if userText.is_empty():
self.richtextlabel_text = ""
return
# Translate if needed
var textTranslated = userText
if self.translate:
textTranslated = tr(textTranslated)
# Translate if needed
var textTranslated = userText
if self.translate:
textTranslated = tr(textTranslated)
# Replace input bb tags.
var regex = RegEx.new()
regex.compile(r"\[input action=(.*?)\](.*?)\[/input\]")
var inputIconText = textTranslated
for match in regex.search_all(textTranslated):
var action = match.get_string(1).to_lower()
var height:int = get_theme_font_size("normal_font_size")
var img_tag = "[img height=%d valign=center,center]res://ui/input/%s.tres[/img]" % [ height, action ]
inputIconText = inputIconText.replace(match.get_string(0), img_tag)
# Replace input bb tags.
var regex = RegEx.new()
regex.compile(r"\[input action=(.*?)\](.*?)\[/input\]")
var inputIconText = textTranslated
for match in regex.search_all(textTranslated):
var action = match.get_string(1).to_lower()
var height:int = get_theme_font_size("normal_font_size")
var img_tag = "[img height=%d valign=center,center]res://ui/input/%s.tres[/img]" % [ height, action ]
inputIconText = inputIconText.replace(match.get_string(0), img_tag)
# Perform smart wrapping
var wrappedText = inputIconText
if smartWrap:
var unwrappedText = wrappedText.strip_edges()
# Perform smart wrapping
var wrappedText = inputIconText
if smartWrap:
var unwrappedText = wrappedText.strip_edges()
self.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART;
self.richtextlabel_text = unwrappedText
self.visible_characters = -1;
self.fit_content = false;
_newLineIndexes = [];
self.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART;
self.richtextlabel_text = unwrappedText
self.visible_characters = -1;
self.fit_content = false;
_newLineIndexes = [];
# Determine where the wrapped newlines are
var line = 0;
var wasNewLine = false;
for i in range(0, self.richtextlabel_text.length()):
var tLine = self.get_character_line(i);
if tLine == line:
wasNewLine = false
if self.richtextlabel_text[i] == "\n":
wasNewLine = true
continue;
if !wasNewLine:
_newLineIndexes.append(i);
line = tLine;
# Determine where the wrapped newlines are
var line = 0;
var wasNewLine = false;
for i in range(0, self.richtextlabel_text.length()):
var tLine = self.get_character_line(i);
if tLine == line:
wasNewLine = false
if self.richtextlabel_text[i] == "\n":
wasNewLine = true
continue;
if !wasNewLine:
_newLineIndexes.append(i);
line = tLine;
# Create fake pre-wrapped text.
wrappedText = "";
for i in range(0, self.richtextlabel_text.length()):
if _newLineIndexes.find(i) != -1 and i != 0:
wrappedText += "\n";
wrappedText += self.richtextlabel_text[i];
# Create fake pre-wrapped text.
wrappedText = "";
for i in range(0, self.richtextlabel_text.length()):
if _newLineIndexes.find(i) != -1 and i != 0:
wrappedText += "\n";
wrappedText += self.richtextlabel_text[i];
# Handle max and start line(s)
var maxText = wrappedText
if maxLines > 0:
_lines = maxText.split("\n", true);
var selectedLines = [];
for i in range(startLine, min(startLine + maxLines, _lines.size())):
selectedLines.append(_lines[i]);
maxText = "\n".join(selectedLines);
_finalText = maxText
self.richtextlabel_text = maxText
print("Updated text")
# Handle max and start line(s)
var maxText = wrappedText
if maxLines > 0:
_lines = maxText.split("\n", true);
var selectedLines = [];
for i in range(startLine, min(startLine + maxLines, _lines.size())):
selectedLines.append(_lines[i]);
maxText = "\n".join(selectedLines);
_finalText = maxText
self.richtextlabel_text = maxText
print("Updated text")

View File

@@ -6,13 +6,13 @@ class_name MainMenu extends Control
@export_file("*.tscn") var newGameScene:String
func _ready() -> void:
btnNewGame.pressed.connect(onNewGamePressed)
btnSettings.pressed.connect(onSettingsPressed)
btnNewGame.pressed.connect(onNewGamePressed)
btnSettings.pressed.connect(onSettingsPressed)
func onNewGamePressed() -> void:
SCENE.setScene(SceneSingleton.SceneType.OVERWORLD)
OVERWORLD.mapChange(newGameScene, "PlayerSpawnPoint")
SCENE.setScene(SceneSingleton.SceneType.OVERWORLD)
OVERWORLD.mapChange(newGameScene, "PlayerSpawnPoint")
func onSettingsPressed() -> void:
print("Settings button pressed")
settingsMenu.isOpen = true
print("Settings button pressed")
settingsMenu.isOpen = true

View File

@@ -1,18 +1,18 @@
class_name PauseMain extends VBoxContainer
func _ready() -> void:
visible = false
$HBoxContainer/ItemList.item_selected.connect(onItemSelected)
visible = false
$HBoxContainer/ItemList.item_selected.connect(onItemSelected)
func open():
visible = true
$HBoxContainer/ItemList.clear()
visible = true
$HBoxContainer/ItemList.clear()
func close():
visible = false
visible = false
func isOpen() -> bool:
return visible
return visible
func onItemSelected(index:int) -> void:
print("Selected item index: ", index)
print("Selected item index: ", index)

View File

@@ -4,16 +4,16 @@ class_name PauseMenu extends Control
@export var SETTINGS:PauseSettings
func _ready() -> void:
close()
close()
func isOpen() -> bool:
return visible
return visible
func open() -> void:
visible = true
MAIN.open()
visible = true
MAIN.open()
func close() -> void:
visible = false
MAIN.close()
SETTINGS.close()
visible = false
MAIN.close()
SETTINGS.close()

View File

@@ -1,10 +1,10 @@
class_name PauseSettings extends Control
func open() -> void:
visible = true
visible = true
func close() -> void:
visible = false
visible = false
func isOpen() -> bool:
return visible
return visible

View File

@@ -4,12 +4,12 @@ class_name SettingsMenu extends Control
@export var tabControls:Array[Control]
func _ready() -> void:
tabs.tab_changed.connect(onTabChanged)
onTabChanged(tabs.current_tab)
tabs.tab_changed.connect(onTabChanged)
onTabChanged(tabs.current_tab)
func onTabChanged(tabIndex:int) -> void:
for control in tabControls:
control.visible = false
if tabIndex >= 0 and tabIndex < tabControls.size():
tabControls[tabIndex].visible = true
for control in tabControls:
control.visible = false
if tabIndex >= 0 and tabIndex < tabControls.size():
tabControls[tabIndex].visible = true