Godot 4.5.1

This commit is contained in:
2025-12-14 22:43:11 +10:00
parent 5805ac2260
commit 4dd1ce64f5
433 changed files with 2922 additions and 585 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

@@ -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