Fix some bugs with chat

This commit is contained in:
2026-06-12 09:16:19 -05:00
parent b364fae1c7
commit 5668250ea9
5 changed files with 74 additions and 53 deletions
+1 -4
View File
@@ -16,11 +16,8 @@ static func dialogueCallable(params:Dictionary) -> int:
UI.dialogueActive = true UI.dialogueActive = true
var line:DialogueLine = await DialogueManager.get_next_dialogue_line(resource, title, extraStates) var line:DialogueLine = await DialogueManager.get_next_dialogue_line(resource, title, extraStates)
while line != null: while line != null:
var text:String = line.text
if line.character:
text = line.character + ": " + text
var target:Node3D = _getLineTarget(line.character, characterTargets) var target:Node3D = _getLineTarget(line.character, characterTargets)
var text:String = line.text
if line.responses.size() > 0: if line.responses.size() > 0:
# Show text then auto-pick the first allowed response. # Show text then auto-pick the first allowed response.
+1 -3
View File
@@ -20,7 +20,7 @@ func _applyGravity() -> void:
func _applyPlayerMovement(delta:float): func _applyPlayerMovement(delta:float):
# Interactions, may move # Interactions, may move
if Input.is_action_just_pressed("interact") && interactingArea && interactingArea.hasInteraction(): if Input.is_action_just_pressed("interact") && interactingArea && interactingArea.hasInteraction():
if !UI.hasAdvanceableChatBox(): if !UI.hasAdvanceableChatBox() && !UI.dialogueActive:
interactingArea.interact() interactingArea.interact()
return return
@@ -63,8 +63,6 @@ func _applyFriction(delta:float) -> void:
entity.velocity.z *= delta * FRICTION entity.velocity.z *= delta * FRICTION
func _canMove() -> bool: func _canMove() -> bool:
if UI.dialogueActive:
return false
if !UI.MAIN_CHATBOX.isClosed: if !UI.MAIN_CHATBOX.isClosed:
return false return false
if UI.GAME_MENU && UI.GAME_MENU.isOpen(): if UI.GAME_MENU && UI.GAME_MENU.isOpen():
+14 -2
View File
@@ -3,9 +3,11 @@ class_name EntityProximityArea extends Area3D
@export var entity:Entity @export var entity:Entity
var _triggered:bool = false var _triggered:bool = false
var _chatbox:WorldChatBox = null
func _ready() -> void: func _ready() -> void:
body_entered.connect(_onBodyEntered) body_entered.connect(_onBodyEntered)
body_exited.connect(_onBodyExited)
func _onBodyEntered(body:Node3D) -> void: func _onBodyEntered(body:Node3D) -> void:
if _triggered: if _triggered:
@@ -16,5 +18,15 @@ func _onBodyEntered(body:Node3D) -> void:
return return
_triggered = true _triggered = true
assert(entity != null && entity.chatboxMessage != "") assert(entity != null && entity.chatboxMessage != "")
var chatbox:WorldChatBox = UI.spawnWorldChatBox(entity) if is_instance_valid(_chatbox) and _chatbox.visible:
chatbox.showTimed(entity.chatboxMessage, entity.chatboxDuration) _chatbox.resetTimer(entity.chatboxDuration)
else:
_chatbox = UI.spawnWorldChatBox(entity)
_chatbox.showTimed(entity.chatboxMessage, entity.chatboxDuration)
func _onBodyExited(body:Node3D) -> void:
if !(body is Entity):
return
if (body as Entity).entityId != "player":
return
_triggered = false
+55 -44
View File
@@ -68,75 +68,86 @@ func _updateWorldPosition() -> void:
func _process(delta: float) -> void: func _process(delta: float) -> void:
if isClosed: if isClosed:
return; return
_updateWorldPosition() _updateWorldPosition()
# _recalcText always resets fit_content to false; re-apply so the # _recalcText always resets fit_content; keep it on in world-space mode so
# PanelContainer can grow to its content height in world-space mode. # the PanelContainer auto-sizes to the full speech-bubble content.
if worldTarget != null and !label.fit_content: if worldTarget != null and !label.fit_content:
label.fit_content = true label.fit_content = true
if label.getFinalText() == "": if label.getFinalText() == "":
isClosed = true; isClosed = true
return;
if Input.is_action_just_released("interact") && !hasLetGoOfInteract:
hasLetGoOfInteract = true;
return return
# Have we finished displaying the current page? if Input.is_action_just_released("interact") and !hasLetGoOfInteract:
if label.visible_characters >= label.getCharactersDisplayedCount(): hasLetGoOfInteract = true
# Not finished displaying current page return
# World-space (speech-bubble) mode: all text is shown immediately with no
# typing reveal. One press advances to the next page; release closes the last.
if worldTarget != null:
if (label.maxLines + label.startLine) < label.getTotalLineCount(): if (label.maxLines + label.startLine) < label.getTotalLineCount():
if Input.is_action_just_pressed("interact") && hasLetGoOfInteract: if Input.is_action_just_pressed("interact") and hasLetGoOfInteract:
label.startLine += label.maxLines; label.startLine += label.maxLines
label.visible_characters = 0; label.fit_content = true
currentViewScrolled = false;
return
currentViewScrolled = true;
else: else:
# On last page if Input.is_action_just_released("interact") and hasLetGoOfInteract:
if Input.is_action_just_released("interact") && hasLetGoOfInteract: chatboxClosing.emit()
chatboxClosing.emit(); isClosed = true
isClosed = true; return
# Bottom-bar mode: typing reveal with paging.
if label.visible_characters >= label.getCharactersDisplayedCount():
if (label.maxLines + label.startLine) < label.getTotalLineCount():
if Input.is_action_just_pressed("interact") and hasLetGoOfInteract:
label.startLine += label.maxLines
label.visible_characters = 0
currentViewScrolled = false
return
currentViewScrolled = true currentViewScrolled = true
return; else:
if Input.is_action_just_released("interact") and hasLetGoOfInteract:
chatboxClosing.emit()
isClosed = true
currentViewScrolled = true
return
# This prevents the game trying to advance if the player is still holding if Input.is_action_just_pressed("interact") and hasLetGoOfInteract:
# down interact. isSpeedupDown = true
if Input.is_action_just_pressed("interact") && hasLetGoOfInteract: elif Input.is_action_just_released("interact") and hasLetGoOfInteract:
isSpeedupDown = true; isSpeedupDown = false
elif Input.is_action_just_released("interact") && hasLetGoOfInteract: elif !Input.is_action_pressed("interact") and hasLetGoOfInteract:
isSpeedupDown = false; isSpeedupDown = false
elif !Input.is_action_pressed("interact") && hasLetGoOfInteract:
isSpeedupDown = false;
revealTimer += delta; revealTimer += delta
if isSpeedupDown: if isSpeedupDown:
revealTimer += delta; revealTimer += delta
if revealTimer > VN_REVEAL_TIME: if revealTimer > VN_REVEAL_TIME:
revealTimer = 0; revealTimer = 0
label.visible_characters += 1; label.visible_characters += 1
func setText(text:String, target:Node3D = null) -> void: func setText(text:String, target:Node3D = null) -> void:
worldTarget = target worldTarget = target
_setWorldLayout(worldTarget != null) _setWorldLayout(worldTarget != null)
# Resets scroll revealTimer = 0
revealTimer = 0; currentViewScrolled = false
currentViewScrolled = false; label.startLine = 0
label.startLine = 0; label.text = text
label.text = text; if worldTarget != null:
label.visible_characters = 0; # Speech-bubble mode: show all text immediately and auto-size the container.
# _recalcText already sets visible_characters = -1; just enable fit_content.
label.fit_content = true
else:
label.visible_characters = 0
# Resets speedup and advancing hasLetGoOfInteract = !Input.is_action_pressed("interact")
hasLetGoOfInteract = !Input.is_action_pressed("interact");
isSpeedupDown = false isSpeedupDown = false
isClosed = false; isClosed = false
func setTextAndWait(text:String, target:Node3D = null) -> void: func setTextAndWait(text:String, target:Node3D = null) -> void:
self.setText(text, target); self.setText(text, target);
+3
View File
@@ -22,6 +22,9 @@ func showTimed(text:String, duration:float) -> void:
_label.text = text _label.text = text
visible = true visible = true
func resetTimer(duration:float) -> void:
_timer = duration
func showAdvanceable(text:String) -> void: func showAdvanceable(text:String) -> void:
mode = Mode.ADVANCEABLE mode = Mode.ADVANCEABLE
_label.text = text _label.text = text