Lots of little tweaks and fixes

This commit is contained in:
2026-06-12 20:26:00 -05:00
parent 7fc1a4645c
commit 3d01fcce86
32 changed files with 570 additions and 160 deletions
+30
View File
@@ -0,0 +1,30 @@
class_name ConfirmDialog extends ClosableMenu
signal confirmed
@export var btnYes:Button
@export var btnNo:Button
func _ready() -> void:
close()
btnYes.pressed.connect(_onYes)
btnNo.pressed.connect(close)
btnYes.focus_neighbor_top = btnNo.get_path()
btnYes.focus_neighbor_bottom = btnNo.get_path()
btnNo.focus_neighbor_top = btnYes.get_path()
btnNo.focus_neighbor_bottom = btnYes.get_path()
func _onYes() -> void:
close()
confirmed.emit()
func open() -> void:
super.open()
btnNo.grab_focus()
func _unhandled_input(event:InputEvent) -> void:
if !isOpen:
return
if event.is_action_pressed("ui_cancel"):
close()
get_viewport().set_input_as_handled()
+7 -19
View File
@@ -5,8 +5,7 @@ const SCENE:PackedScene = preload("res://ui/component/DialogueTextbox.tscn")
enum AdvancementMode { PLAYER, TIMED }
const LINES_PER_PAGE:int = 4
const CHARS_PER_SECOND:float = 20.0
const SPEEDUP_MULTIPLIER:float = 4.0
const CHARS_PER_SECOND:float = 24.0
const PAUSE_COMMA:float = 0.15
const PAUSE_SENTENCE:float = 0.4
const PAUSE_ELLIPSIS_DOT:float = 0.3
@@ -24,7 +23,6 @@ var _pauseTimer:float = 0.0
var _autoAdvanceTimer:float = 0.0
var _isRevealing:bool = false
var _isWaitingForInput:bool = false
var _hasLetGoOfInteract:bool = true
var _advancementMode:AdvancementMode = AdvancementMode.PLAYER
@onready var _speakerLabel:Label = $VBoxContainer/SpeakerLabel
@@ -68,7 +66,6 @@ func setup(line:DialogueLine, entity:Entity, mode:AdvancementMode = AdvancementM
_autoAdvanceTimer = 0.0
_isRevealing = true
_isWaitingForInput = false
_hasLetGoOfInteract = !Input.is_action_pressed("interact")
_updateWorldPosition()
visible = true
@@ -85,9 +82,10 @@ func _process(delta:float) -> void:
return
_updateWorldPosition()
_advanceIndicator.visible = _isWaitingForInput
if _isWaitingForInput:
_advanceIndicator.modulate.a = 0.5 + 0.5 * sin(Time.get_ticks_msec() / 300.0)
else:
_advanceIndicator.modulate.a = 0.0
if _isRevealing:
_processReveal(delta)
@@ -119,16 +117,13 @@ func _buildPreWrappedText(parsed:String) -> String:
return result
func _processReveal(delta:float) -> void:
if Input.is_action_just_released("interact"):
_hasLetGoOfInteract = true
var speedMult:float = SPEEDUP_MULTIPLIER if (_hasLetGoOfInteract and Input.is_action_pressed("interact")) else 1.0
var scaledDelta:float = delta * SETTINGS.textSpeed
if _pauseTimer > 0.0:
_pauseTimer -= delta * speedMult
_pauseTimer -= scaledDelta
return
_revealTimer += delta * speedMult
_revealTimer += scaledDelta
while _revealTimer >= 1.0 / CHARS_PER_SECOND:
_revealTimer -= 1.0 / CHARS_PER_SECOND
@@ -185,12 +180,6 @@ func _onRevealComplete() -> void:
_isWaitingForInput = true
func _processAdvanceInput() -> void:
if Input.is_action_just_released("interact"):
_hasLetGoOfInteract = true
if not _hasLetGoOfInteract:
return
if Input.is_action_just_pressed("interact"):
_advance()
@@ -200,8 +189,7 @@ func _processAutoAdvance(delta:float) -> void:
_advance()
func _advance() -> void:
_advanceIndicator.visible = false
_advanceIndicator.modulate.a = 1.0
_advanceIndicator.modulate.a = 0.0
var totalLines:int = _parsedText.count("\n") + 1
var hasMorePages:bool = _startLine + _linesPerPage < totalLines
if hasMorePages:
+1 -1
View File
@@ -28,6 +28,6 @@ autowrap_mode = 3
[node name="AdvanceIndicator" type="Label" parent="VBoxContainer"]
layout_mode = 2
modulate = Color(1, 1, 1, 0)
text = "▼"
horizontal_alignment = 2
visible = false
+56
View File
@@ -0,0 +1,56 @@
class_name InteractIndicator extends PanelContainer
var _entity:Entity = null
func _enter_tree() -> void:
UI.interactIndicator = self
func _exit_tree() -> void:
if UI.interactIndicator == self:
UI.interactIndicator = null
func _ready() -> void:
visible = false
DialogueManager.dialogue_started.connect(_onDialogueStarted)
DialogueManager.dialogue_ended.connect(_onDialogueEnded)
func setEntity(entity:Entity) -> void:
if is_instance_valid(_entity):
_entity.tree_exiting.disconnect(_onEntityExiting)
_entity = entity
_entity.tree_exiting.connect(_onEntityExiting)
visible = _canShow()
if visible:
updateWorldPosition()
func clear() -> void:
if is_instance_valid(_entity):
_entity.tree_exiting.disconnect(_onEntityExiting)
_entity = null
visible = false
func _canShow() -> bool:
return _entity != null and not UI.dialogueActive
func _onEntityExiting() -> void:
_entity = null
visible = false
func _onDialogueStarted(_resource:DialogueResource) -> void:
visible = false
func _onDialogueEnded(_resource:DialogueResource) -> void:
visible = _canShow()
if visible:
updateWorldPosition()
func updateWorldPosition() -> void:
var camera:Camera3D = get_viewport().get_camera_3d()
if camera == null:
return
var worldPos:Vector3 = _entity.global_position + Vector3(0, 2.5, 0)
var screenPos:Vector2 = camera.unproject_position(worldPos)
var viewportSize:Vector2 = get_viewport().get_visible_rect().size
position = screenPos - size * 0.5
position.x = clamp(position.x, 0.0, viewportSize.x - size.x)
position.y = clamp(position.y, 0.0, viewportSize.y - size.y)
+1
View File
@@ -0,0 +1 @@
uid://xrcb2e7jwlm0
+13
View File
@@ -0,0 +1,13 @@
[gd_scene load_steps=3 format=3]
[ext_resource type="Theme" path="res://ui/UI Theme.tres" id="1"]
[ext_resource type="Script" path="res://ui/component/InteractIndicator.gd" id="2"]
[node name="InteractIndicator" type="PanelContainer"]
mouse_filter = 2
theme = ExtResource("1")
script = ExtResource("2")
[node name="Label" type="Label" parent="."]
layout_mode = 2
text = "INTERACT"
+38
View File
@@ -0,0 +1,38 @@
[gd_scene load_steps=2 format=3 uid="uid://bmmc3x8n1d7qp"]
[ext_resource type="Script" path="res://ui/component/ConfirmDialog.gd" id="1_mmcd"]
[node name="MainMenuConfirmDialog" type="Control" node_paths=PackedStringArray("btnYes", "btnNo")]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
process_mode = 3
script = ExtResource("1_mmcd")
btnYes = NodePath("VBoxContainer/Yes")
btnNo = NodePath("VBoxContainer/No")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
grow_horizontal = 2
grow_vertical = 2
[node name="Label" type="Label" parent="VBoxContainer"]
layout_mode = 2
text = "Return to main menu?"
horizontal_alignment = 1
[node name="Yes" type="Button" parent="VBoxContainer"]
layout_mode = 2
text = "Yes"
[node name="No" type="Button" parent="VBoxContainer"]
layout_mode = 2
text = "No"
+48
View File
@@ -0,0 +1,48 @@
class_name ModalBackdrop extends ColorRect
# Tracks which overlays are currently open. Each entry must be a direct sibling
# (child of the same parent). The backdrop repositions itself in the scene tree
# to sit immediately below whichever open overlay has the highest tree index,
# so only one backdrop is ever visible regardless of how many overlays are open.
var _openOverlays:Array[Control] = []
func _ready() -> void:
visible = false
func register(overlay:Control) -> void:
assert(overlay.get_parent() == get_parent(), "ModalBackdrop: overlay must be a sibling")
assert(overlay.has_signal("opened") and overlay.has_signal("closed"),
"ModalBackdrop: overlay must have opened/closed signals")
overlay.connect("opened", func(): _onOpened(overlay))
overlay.connect("closed", func(): _onClosed(overlay))
func _onOpened(overlay:Control) -> void:
if overlay not in _openOverlays:
_openOverlays.append(overlay)
_reposition()
func _onClosed(overlay:Control) -> void:
_openOverlays.erase(overlay)
_reposition()
func _reposition() -> void:
if _openOverlays.is_empty():
visible = false
return
visible = true
var top := _topOverlay()
var topIdx := top.get_index()
var myIdx := get_index()
if myIdx == topIdx - 1:
return
if myIdx < topIdx:
get_parent().move_child(self, topIdx - 1)
else:
get_parent().move_child(self, topIdx)
func _topOverlay() -> Control:
var top:Control = _openOverlays[0]
for overlay in _openOverlays:
if overlay.get_index() > top.get_index():
top = overlay
return top
+5
View File
@@ -0,0 +1,5 @@
class_name QuitConfirmDialog extends ConfirmDialog
func _ready() -> void:
super._ready()
confirmed.connect(func(): get_tree().quit())
+1
View File
@@ -0,0 +1 @@
uid://deov3ob0lojyo
+38
View File
@@ -0,0 +1,38 @@
[gd_scene load_steps=2 format=3 uid="uid://cqdf1x7m2canp"]
[ext_resource type="Script" path="res://ui/component/QuitConfirmDialog.gd" id="1_qcd"]
[node name="QuitConfirmDialog" type="Control" node_paths=PackedStringArray("btnYes", "btnNo")]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
process_mode = 3
script = ExtResource("1_qcd")
btnYes = NodePath("VBoxContainer/Yes")
btnNo = NodePath("VBoxContainer/No")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
grow_horizontal = 2
grow_vertical = 2
[node name="Label" type="Label" parent="VBoxContainer"]
layout_mode = 2
text = "Quit to desktop?"
horizontal_alignment = 1
[node name="Yes" type="Button" parent="VBoxContainer"]
layout_mode = 2
text = "Yes"
[node name="No" type="Button" parent="VBoxContainer"]
layout_mode = 2
text = "No"