NEO-122: Fix CI flake and address Bugbot quest HUD feedback.

Harden npc windup timing test, refresh quest progress on encounter
complete, surface accept busy/loading feedback, and treat missing quest
rows as not_started for Shift+Q eligibility.
pull/161/head
VinPropane 2026-06-07 14:38:06 -04:00
parent 2514772b43
commit 3606d0ba57
4 changed files with 65 additions and 14 deletions

View File

@ -745,6 +745,7 @@ func _on_encounter_progress_received(snapshot: Dictionary) -> void:
var row: Dictionary = _encounter_row(PROTOTYPE_ENCOUNTER_ID)
if str(row.get("state", "")) == "completed":
_request_inventory_refresh()
_request_quest_progress_refresh()
func _on_encounter_progress_sync_failed(reason: String) -> void:

View File

@ -225,8 +225,7 @@ func _find_first_eligible_quest_id() -> String:
var qid: String = str(def.get("id", ""))
if qid.is_empty():
continue
var row: Dictionary = _quest_row(qid)
if str(row.get("status", "")) != "not_started":
if _quest_status(qid) != "not_started":
continue
var prereqs: Variant = def.get("prerequisiteQuestIds", [])
if not prereqs is Array:
@ -234,7 +233,7 @@ func _find_first_eligible_quest_id() -> String:
var prereqs_met := true
for p_variant in prereqs as Array:
var pid: String = str(p_variant)
if str(_quest_row(pid).get("status", "")) != "completed":
if _quest_status(pid) != "completed":
prereqs_met = false
break
if prereqs_met:
@ -242,19 +241,39 @@ func _find_first_eligible_quest_id() -> String:
return ""
func _request_accept(quest_id: String) -> void:
func _quest_status(quest_id: String) -> String:
var row: Dictionary = _quest_row(quest_id)
if row.is_empty():
return "not_started"
return str(row.get("status", "not_started"))
func _request_accept(quest_id: String) -> bool:
if not is_instance_valid(_progress_client):
return
var accept_busy := false
if _progress_client.has_method("is_accept_busy"):
accept_busy = bool(_progress_client.call("is_accept_busy"))
if accept_busy:
return
if _progress_client.has_method("request_accept"):
_progress_client.call("request_accept", quest_id)
_render_accept_feedback_label("Quest accept: failed — client unavailable")
return false
if (
_progress_client.has_method("is_accept_busy")
and bool(_progress_client.call("is_accept_busy"))
):
_render_accept_feedback_label("Quest accept: busy — try again")
return false
if not _progress_client.has_method("request_accept"):
_render_accept_feedback_label("Quest accept: failed — client unavailable")
return false
var started: bool = bool(_progress_client.call("request_accept", quest_id))
if not started:
_render_accept_feedback_label("Quest accept: failed — could not start")
return started
func _request_eligible_accept() -> void:
if _progress_error.is_empty() and _last_snapshot.is_empty():
_render_accept_feedback_label("Quest accept: progress loading — try again")
return
if _defs_error.is_empty() and _defs_snapshot().is_empty():
_render_accept_feedback_label("Quest accept: definitions loading — try again")
return
var eligible_id: String = _find_first_eligible_quest_id()
if eligible_id.is_empty():
_render_accept_feedback_label("Quest accept: no eligible quest")

View File

@ -29,11 +29,13 @@ func test_display_windup_remaining_decreases_over_time() -> void:
state.call("apply_snapshot", _telegraph_snapshot(2.0))
var first: float = float(state.call("display_windup_remaining", "prototype_npc_elite"))
# Act
await (Engine.get_main_loop() as SceneTree).create_timer(0.05).timeout
for _i in 3:
await get_tree().process_frame
await (Engine.get_main_loop() as SceneTree).create_timer(0.1).timeout
var second: float = float(state.call("display_windup_remaining", "prototype_npc_elite"))
# Assert
assert_that(second).is_less(first)
assert_that(second).is_greater(1.9)
assert_that(second).is_greater(1.85)
func test_new_snapshot_reconciles_windup_anchor() -> void:

View File

@ -58,3 +58,32 @@ func test_progress_label_shows_loading_before_snapshot() -> void:
# Assert
assert_str(text).contains("Quests:")
assert_str(text).contains("Loading")
func test_shift_q_shows_progress_loading_before_snapshot() -> void:
# Arrange
var controller: Node = QuestHudController.new()
var accept_label := Label.new()
add_child(controller)
controller.set("_progress_client", QuestProgressClient.new())
controller.set("_defs_client", QuestDefinitionsClient.new())
controller.set("_accept_label", accept_label)
controller.set("_last_snapshot", {})
controller.set("_progress_error", "")
# Act
controller.call("_request_eligible_accept")
# Assert
assert_str(accept_label.text).contains("progress loading")
func test_request_accept_shows_busy_feedback() -> void:
# Arrange
var controller := await _build_controller()
var progress: Node = controller.get("_progress_client")
progress.call("request_accept", QuestHudController.GATHER_QUEST_ID)
var accept_label: Label = controller.get("_accept_label")
# Act
var started: bool = bool(controller.call("_request_accept", QuestHudController.GATHER_QUEST_ID))
# Assert
assert_bool(started).is_false()
assert_str(accept_label.text).contains("busy")