fix(client): address PR #25 review — 5 critical bugs, 4 warnings, 3 suggestions
Critical fixes: - hide_dialogue() sent PAUSE instead of UNPAUSE, permanently freezing simulation after every dialogue (both reviewers) - Confrontation monologue hardcoded in GDScript constant, violating D-042/D-020 — moved to ui-strings.yaml as dialogue.confrontation_beat - Walk-away WASD didn't call set_input_as_handled(), letting movement event propagate and potentially stepping on the same frame - is_dialogue_active() returned _is_showing only — interaction list could flash during 300ms fade gap. Now includes dialogue_active state - Removed dead _last_dialogue_id / get_dialogue_id() state (never read) Warnings addressed: - Audio registry now scans res://audio/ recursively (subdirs registered) - add_bus_effect guarded against duplicate calls in tests - int64 encoder dead code tagged KNOWN-DEFECT, filed as ticket #516 - D-073 zone crossfade stub comment clarifies Sprint 9+ deferral - listening_focus dip documents caller tick-gate responsibility (D-069/D-071) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,7 +23,6 @@ var _option_response_ids: Array[String] = [] # response_id per option, same ind
|
||||
var _option_texts: Array[String] = [] # raw display text per option
|
||||
var _option_is_confrontation: Array[bool] = [] # confrontation flag per option
|
||||
var _npc_name: String = ""
|
||||
var _dialogue_id: int = 0 # Tracks current dialogue to prevent consume-once race
|
||||
|
||||
const FADE_IN: float = 0.2
|
||||
const FADE_OUT: float = 0.3 # D-064: 300ms fade on walk-away
|
||||
@@ -32,7 +31,7 @@ const MAX_HEIGHT_RATIO: float = 0.2 # D-061: max 20% viewport height
|
||||
const MAX_WIDTH_PX: float = 832.0 # D-061: max-width cap (~65% of 1280)
|
||||
const CONFRONTATION_BEAT_DURATION: float = 1.5 # D-063: pause before sending
|
||||
const CONFRONTATION_DIM_ALPHA: float = 0.7 # D-063: dialogue box dims during beat
|
||||
const CONFRONTATION_MONOLOGUE: String = "This changes things. No taking it back."
|
||||
const CONFRONTATION_MONOLOGUE_KEY: String = "dialogue.confrontation_beat"
|
||||
|
||||
# D-064: movement actions that trigger walk-away
|
||||
const _WALK_AWAY_ACTIONS: Array[StringName] = [
|
||||
@@ -58,6 +57,7 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||
if event is InputEventKey and event.pressed:
|
||||
for action in _WALK_AWAY_ACTIONS:
|
||||
if event.is_action_pressed(action):
|
||||
get_viewport().set_input_as_handled()
|
||||
_cancel_beat()
|
||||
hide_dialogue()
|
||||
dialogue_dismissed.emit()
|
||||
@@ -82,7 +82,6 @@ func _update_layout() -> void:
|
||||
# D-063: confrontation options render italic.
|
||||
func show_dialogue(npc_name: String, speech: String, options: Array = []) -> void:
|
||||
_npc_name = npc_name
|
||||
_dialogue_id += 1
|
||||
_cancel_beat()
|
||||
|
||||
# NPC speech — name prefix in bold
|
||||
@@ -158,7 +157,7 @@ func hide_dialogue() -> void:
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
|
||||
# D-061: unpause when dialogue closes
|
||||
SimBridge.send_input({"action": InputMapper.Action.PAUSE, "timestamp_msec": Time.get_ticks_msec()})
|
||||
SimBridge.send_input({"action": InputMapper.Action.UNPAUSE, "timestamp_msec": Time.get_ticks_msec()})
|
||||
|
||||
if _active_tween and _active_tween.is_valid():
|
||||
_active_tween.kill()
|
||||
@@ -172,11 +171,7 @@ func hide_dialogue() -> void:
|
||||
|
||||
|
||||
func is_dialogue_active() -> bool:
|
||||
return _is_showing
|
||||
|
||||
|
||||
func get_dialogue_id() -> int:
|
||||
return _dialogue_id
|
||||
return _is_showing or GameState.dialogue_active
|
||||
|
||||
|
||||
func _on_option_pressed(index: int) -> void:
|
||||
@@ -209,8 +204,8 @@ func _start_confrontation_beat(response_id: String, text: String) -> void:
|
||||
_active_tween = create_tween()
|
||||
_active_tween.tween_property(panel, "modulate:a", CONFRONTATION_DIM_ALPHA, 0.2)
|
||||
|
||||
# D-063: monologue beat — hardcoded v0.1 line
|
||||
confrontation_monologue.emit(CONFRONTATION_MONOLOGUE, CONFRONTATION_BEAT_DURATION)
|
||||
# D-063: monologue beat — text from ui-strings.yaml (D-042)
|
||||
confrontation_monologue.emit(UIStrings.get_text(CONFRONTATION_MONOLOGUE_KEY), CONFRONTATION_BEAT_DURATION)
|
||||
|
||||
# D-063: audio dip via AudioManager
|
||||
AudioManager.apply_dip("confrontation")
|
||||
|
||||
Reference in New Issue
Block a user