diff --git a/client/scripts/main.gd b/client/scripts/main.gd index f9d38a0..c7e8a18 100644 --- a/client/scripts/main.gd +++ b/client/scripts/main.gd @@ -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: diff --git a/client/scripts/quest_hud_controller.gd b/client/scripts/quest_hud_controller.gd index 2cc2c8f..7c209aa 100644 --- a/client/scripts/quest_hud_controller.gd +++ b/client/scripts/quest_hud_controller.gd @@ -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") diff --git a/client/test/npc_runtime_hud_state_test.gd b/client/test/npc_runtime_hud_state_test.gd index c29249a..2a8165c 100644 --- a/client/test/npc_runtime_hud_state_test.gd +++ b/client/test/npc_runtime_hud_state_test.gd @@ -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: diff --git a/client/test/quest_hud_controller_test.gd b/client/test/quest_hud_controller_test.gd index cc96868..a29a39a 100644 --- a/client/test/quest_hud_controller_test.gd +++ b/client/test/quest_hud_controller_test.gd @@ -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")