Fix party threat border size writing to and reading the raid value - #1257
Open
dfrisone wants to merge 2 commits into
Open
Fix party threat border size writing to and reading the raid value#1257dfrisone wants to merge 2 commits into
dfrisone wants to merge 2 commits into
Conversation
The "Threat Borders" slider is drawn on the Health Bar row, so the party tab's blocking overlay lets you edit it whenever Health Bar is unsynced. threatBorderSize was filed under the Indicators party-sync section, so the write only produced a party value when Indicators was ALSO unsynced; otherwise it went to the shared raid key. File it under "healthBar" to match where its control lives. The runtime read had the same split. UpdateButton resolved the party proxy, but the two threat event handlers read db.profile directly, and the hub one resolves party buttons via ns._partyUnitToButton immediately before reading the raid value, so a party override was overwritten on every threat update. Both now resolve the same proxy chain as every other per-button read (the Extra Frames tracker uses the extra-aware form its sibling reads already use, since that pool holds no party buttons). A stored party_threatBorderSize normally implies both sections were custom, so it stays live and unchanged under the new section. The legacy showThreat -> slider migration could also write the key directly, leaving a value dormant under a synced Health Bar that would switch on here; a profile migration neutralizes only that case so no frame changes look.
… not copy Three defects in the first version. It ran at the parent ADDON_LOADED, before ERF:OnInitialize performs the legacy party_showThreat -> party_threatBorderSize conversion. For a profile carrying that legacy key the body saw nil, returned, and stamped its flag, and the dormant 0 written moments later went live under the now-custom Health Bar section, turning party aggro borders off. Exactly the case it existed to prevent, and it could never re-run. It now performs and consumes that conversion itself, so ordering cannot matter. It only handled dormant becoming live. A legacy value that was LIVE under a custom Indicators section goes dormant under the new mapping, and those party frames would start showing a border the user had turned off. Both directions are handled by keying on whether the state flips at all. It neutralized by copying the raid value, which pins a permanent party override: later raid slider edits stop propagating to party, and "Re-sync Health Bar" prompts about discarding a setting the user never made. Clearing the key is identical at migration time and avoids both. Id bumped to v2 so profiles that ran the broken v1 while testing this branch still get the corrected pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found while auditing the party section maps for #1256. Same root cause, different section, plus a runtime half.
Cause
Two independent things decide how a control on the Party tab behaves.
Whether you can edit it - the party tab draws a "Synced with Raid Settings" blocking overlay per section, sized from that section's
onSection(key, startY, endY)y-range. A control is editable whenever the section whose header it is drawn under is unsynced.Which value it writes -
SSetconsultsns._PARTY_KEY_SECTION[key]and only writesparty_<key>if that section is custom.The "Threat Borders" slider is drawn on the Health Bar row, but
threatBorderSizewas filed underindicators. With Health Bar unsynced and Indicators synced, the overlay allowed the edit and the write fell through to the shared raid key, so both tabs read the same value and could never diverge.The runtime read had the same split.
UpdateButtonresolves the party proxy, but the two threat event handlers readdb.profiledirectly, and the hub one resolves party buttons vians._partyUnitToButtonimmediately before reading the raid value. So even a correctly stored party override was repainted at the raid thickness on every threat update.Change
threatBorderSizefiles underhealthBar, matching where its control is drawn.Migration
A stored
party_threatBorderSizenormally implies both sections were custom (Health Bar to reach the control, Indicators to route the write), so it stays live and unchanged under the new section.The exception is the legacy
showThreat-> slider migration, which writesparty_threatBorderSizedirectly, bypassing the UI gate. Such a value could sit dormant under a synced Health Bar and would switch on here.rf_threat_border_party_section_v1(profile scope) neutralizes only that case, so no frame changes appearance. Its predicate is self-clearing, making a re-run a true no-op.Testing
Both files pass
luac -p. Verified in game on a merge of this branch and #1256, with Health Bar unsynced and Indicators left synced:party_threatBorderSize = 4stored, the raid key left at its default, and the migration stamped once without error (EllesmereUI._migrationErrorsempty).Update after review
The migration was rewritten (
_v1->_v2) to fix three defects:ADDON_LOADED, beforeERF:OnInitializeperforms the legacyparty_showThreat->party_threatBorderSizeconversion. For a profile carrying that legacy key the body sawnil, returned, and stamped its flag, and the dormant0written moments later went live under the now-custom Health Bar section. It now performs and consumes that conversion itself.The two code changes are unchanged and remain as tested. The migration path needs a re-test before merge.
Migration testing (the re-test noted above is done)
Offline: a harness loads this file, registers the full chain, and runs the real
RunRegisteredMigrations()over synthetic profiles covering every gating combination, including both legacyparty_showThreatvariants. Both-custom keeps the override, both-synced keeps it, each single-sided flip clears it, and a legacy value that stays live under both mappings is preserved rather than discarded. Zero errors across the chain.In game, on the exact case v1 got wrong: a profile carrying
party_showThreat = falsewith Health Bar custom and Indicators synced,threatBorderSize = 1, and the v2 flag removed so it would run.0after the migration had stamped, and it would read 0.party_showThreatconsumed,party_threatBorderSizecleared,threatBorderSizestill 1, migration stamped once,EllesmereUI._migrationErrorsempty.That reading of 1 is only reachable if the migration performed the legacy conversion itself before deciding, which is the ordering fix.