NEO-132: Move economy refresh into quest HUD controller for lint budget.

Pass inventory and skill clients into setup; refresh on completion
transition in quest_hud_controller.gd; fix line-length and file-size
gdlint limits for pre-push.
pull/171/head
VinPropane 2026-06-14 14:15:46 -04:00
parent 726926b901
commit acf3d079d2
4 changed files with 46 additions and 22 deletions

View File

@ -866,15 +866,10 @@ func _setup_quest_progress_sync() -> void:
Callable(self, "_apply_authority_http_config_to_client"), Callable(self, "_apply_authority_http_config_to_client"),
_quest_reward_delivery_label, _quest_reward_delivery_label,
_item_defs_client, _item_defs_client,
Callable(self, "_on_quest_completion_reward_transition") _inventory_client,
_skill_progression_client
) )
func _on_quest_completion_reward_transition(_quest_id: String, _summary: Dictionary) -> void:
_request_inventory_refresh()
var skill_client := _skill_progression_client
if is_instance_valid(skill_client) and skill_client.has_method("request_sync_from_server"):
skill_client.call("request_sync_from_server")
func _request_quest_progress_refresh() -> void: func _request_quest_progress_refresh() -> void:
if is_instance_valid(_quest_hud): if is_instance_valid(_quest_hud):

View File

@ -26,7 +26,8 @@ var _previous_status_by_quest: Dictionary = {}
var _quest_was_active_in_session: Dictionary = {} var _quest_was_active_in_session: Dictionary = {}
var _last_reward_quest_id: String = "" var _last_reward_quest_id: String = ""
var _last_reward_summary: Dictionary = {} var _last_reward_summary: Dictionary = {}
var _economy_refresh_callback: Callable = Callable() var _inventory_client: Node = null
var _skill_progression_client: Node = null
func setup( func setup(
@ -37,15 +38,17 @@ func setup(
apply_http_config: Callable, apply_http_config: Callable,
reward_label: Label = null, reward_label: Label = null,
item_defs_client: Node = null, item_defs_client: Node = null,
economy_refresh_callback: Callable = Callable() inventory_client: Node = null,
skill_progression_client: Node = null
) -> void: ) -> void:
_progress_client = progress_client _progress_client = progress_client
_defs_client = defs_client _defs_client = defs_client
_item_defs_client = item_defs_client _item_defs_client = item_defs_client
_inventory_client = inventory_client
_skill_progression_client = skill_progression_client
_progress_label = progress_label _progress_label = progress_label
_accept_label = accept_label _accept_label = accept_label
_reward_label = reward_label _reward_label = reward_label
_economy_refresh_callback = economy_refresh_callback
if apply_http_config.is_valid(): if apply_http_config.is_valid():
apply_http_config.call(progress_client) apply_http_config.call(progress_client)
apply_http_config.call(defs_client) apply_http_config.call(defs_client)
@ -213,8 +216,20 @@ func _detect_and_apply_completion_transitions(snapshot: Dictionary) -> void:
_last_reward_summary = {} _last_reward_summary = {}
if not _last_reward_quest_id.is_empty() and not _last_reward_summary.is_empty(): if not _last_reward_quest_id.is_empty() and not _last_reward_summary.is_empty():
quest_completion_reward_transition.emit(_last_reward_quest_id, _last_reward_summary) quest_completion_reward_transition.emit(_last_reward_quest_id, _last_reward_summary)
if _economy_refresh_callback.is_valid(): _refresh_economy_hud()
_economy_refresh_callback.call(_last_reward_quest_id, _last_reward_summary)
func _refresh_economy_hud() -> void:
if (
is_instance_valid(_inventory_client)
and _inventory_client.has_method("request_sync_from_server")
):
_inventory_client.call("request_sync_from_server")
if (
is_instance_valid(_skill_progression_client)
and _skill_progression_client.has_method("request_sync_from_server")
):
_skill_progression_client.call("request_sync_from_server")
func _quest_ids_in_render_order(snapshot: Dictionary) -> Array: func _quest_ids_in_render_order(snapshot: Dictionary) -> Array:

View File

@ -38,6 +38,15 @@ class StubItemDefsClient:
return item_id return item_id
class MockEconomySyncClient:
extends Node
var sync_count: int = 0
func request_sync_from_server() -> void:
sync_count += 1
func _make_defs_client(transport: Node) -> Node: func _make_defs_client(transport: Node) -> Node:
var c: Node = QuestDefinitionsClient.new() var c: Node = QuestDefinitionsClient.new()
c.set("injected_http", transport) c.set("injected_http", transport)
@ -291,15 +300,22 @@ func test_completion_transition_emits_economy_refresh_signal() -> void:
func test_completion_transition_invokes_economy_refresh_callback() -> void: func test_completion_transition_invokes_economy_refresh_callback() -> void:
# Arrange # Arrange
var controller: Node = QuestHudController.new() var controller: Node = QuestHudController.new()
var called := false var inventory_client := MockEconomySyncClient.new()
var skill_client := MockEconomySyncClient.new()
auto_free(controller) auto_free(controller)
auto_free(inventory_client)
auto_free(skill_client)
add_child(controller) add_child(controller)
controller.set("_economy_refresh_callback", func(_qid, _summary): called = true) add_child(inventory_client)
add_child(skill_client)
controller.set("_inventory_client", inventory_client)
controller.set("_skill_progression_client", skill_client)
# Act # Act
controller.call("_on_progress_received", _active_gather_snapshot()) controller.call("_on_progress_received", _active_gather_snapshot())
controller.call("_on_progress_received", _completed_gather_with_summary_snapshot()) controller.call("_on_progress_received", _completed_gather_with_summary_snapshot())
# Assert # Assert
assert_bool(called).is_true() assert_int(inventory_client.sync_count).is_equal(1)
assert_int(skill_client.sync_count).is_equal(1)
func test_boot_completed_does_not_emit_economy_refresh_signal() -> void: func test_boot_completed_does_not_emit_economy_refresh_signal() -> void:
@ -311,8 +327,6 @@ func test_boot_completed_does_not_emit_economy_refresh_signal() -> void:
# Act # Act
controller.call("_on_progress_received", _completed_gather_with_summary_snapshot()) controller.call("_on_progress_received", _completed_gather_with_summary_snapshot())
# Assert # Assert
await ( await (assert_signal(controller).wait_until(200).is_not_emitted(
assert_signal(controller) "quest_completion_reward_transition"
.wait_until(200) ))
.is_not_emitted("quest_completion_reward_transition")
)

View File

@ -58,8 +58,8 @@
- **`docs/manual-qa/NEO-132.md`** — four-quest capstone extending NEO-123 with reward HUD + economy verification + idempotency steps. - **`docs/manual-qa/NEO-132.md`** — four-quest capstone extending NEO-123 with reward HUD + economy verification + idempotency steps.
- **`client/README.md`** — **End-to-end quest reward loop (NEO-132)** section with flow table and cross-links. - **`client/README.md`** — **End-to-end quest reward loop (NEO-132)** section with flow table and cross-links.
- **`client/scripts/quest_hud_controller.gd`** — **`quest_completion_reward_transition`** signal on in-session completion with summary. - **`client/scripts/quest_hud_controller.gd`** — **`quest_completion_reward_transition`** signal + **`_refresh_economy_hud()`** on in-session completion (inventory + skill GET).
- **`client/scripts/main.gd`** — connects signal to inventory + skill progression GET refresh (NEO-131 deferred economy HUD gap). - **`client/scripts/main.gd`** — passes **`InventoryClient`** + **`SkillProgressionClient`** into quest HUD **`setup`**.
- **`docs/manual-qa/NEO-123.md`**, **`docs/manual-qa/NEO-131.md`** — cross-links to NEO-132 capstone. - **`docs/manual-qa/NEO-123.md`**, **`docs/manual-qa/NEO-131.md`** — cross-links to NEO-132 capstone.
- **`docs/plans/E7M2-prototype-backlog.md`**, **`E7_M2_RewardAndUnlockRouter.md`**, **`documentation_and_implementation_alignment.md`**, **`module_dependency_register.md`** — E7M2-09 landed; E7.M2 **Ready**; Epic 7 Slice 2 client capstone complete. - **`docs/plans/E7M2-prototype-backlog.md`**, **`E7_M2_RewardAndUnlockRouter.md`**, **`documentation_and_implementation_alignment.md`**, **`module_dependency_register.md`** — E7M2-09 landed; E7.M2 **Ready**; Epic 7 Slice 2 client capstone complete.