Procházet zdrojové kódy

Invalidate ability buckets when the equipped subclass changes

Swapping the subclass item only ever went through the ordinary equipment-swap
commit path, which never invalidated the published ability-buckets domain the
character screen resolves ability picks against. Only an explicit ability-entry
pick (opcode 801) woke the investment worker to rebuild it, so a subclass swap
left the screen resolving against the previous subclass until something
unrelated happened to trigger a refresh.
Millie před 3 týdny
rodič
revize
637bddcc17

+ 10 - 0
Sunrise/src/server/bap/encrypted/transactions/service_outcome_commit.cpp

@@ -56,11 +56,21 @@ bool commit(ServiceOutcome& outcome, Publication& publication) noexcept {
         return state::matchmaking::commit(*mutation);
     }
     if (auto* transaction = transaction_if<EquipmentSwapTransaction>(outcome)) {
+        const bool isSubclassSlot = transaction->pending.equipmentSlotIndex
+                                    == static_cast<std::size_t>(
+                                        state::account::inventory::EquipmentSlot::subclass);
         const bool committed = state::commit_equipment_swap(transaction->pending);
         core::log::write(core::log::Channel::server,
                          committed ? core::log::Level::debug : core::log::Level::warn,
                          committed ? "ev=equip stage=transaction_commit result=ok"
                                    : "ev=equip stage=transaction_commit result=fail");
+        if (committed && isSubclassSlot) {
+            // The equipped subclass just changed, which makes the published ability buckets
+            // stale the same way an ability-entry pick does; wake the investment worker so the
+            // character screen does not keep showing the previous subclass's resolution until
+            // some unrelated pump happens to refresh it.
+            client::content::investment::worker::request_slice();
+        }
         return committed;
     }
     if (auto* transaction = transaction_if<SubclassSelectionTransaction>(outcome)) {

+ 9 - 0
Sunrise/src/state/runtime/state_account_runtime.cpp

@@ -600,6 +600,15 @@ bool commit_equipment_swap(PendingEquipmentSwap& mutation) noexcept {
     runtime::storage::g_state.account = candidate;
     ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
 
+    // The published ability buckets are resolved against whichever subclass is currently
+    // equipped; swapping that item away makes the domain stale the same way an ability-entry
+    // pick does, so it needs the same invalidation or the character screen keeps showing
+    // whatever the previous subclass resolved to until something else happens to refresh it.
+    if (prepared.equipmentSlotIndex
+        == static_cast<std::size_t>(authored_inventory::EquipmentSlot::subclass)) {
+        build_data::invalidate_ability_buckets();
+    }
+
     report_equipment("commit_end",
                      "ok",
                      prepared.kind,