From 6be555ad4722f06228b43f935d06ed2f7066ed66 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 7 Sep 2026 21:11:42 +0200 Subject: [PATCH 1/3] fix(mosstank): Buffs tab is VTank's own six controls, nothing more MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Owner's third live look (2026-09-07): "Screenshot shows options under the buffing tab circled in red. Those are made up, remove them from here." VTank's real Buffs tab (docs/research/vtank-kb/08-ui-views.md §1 "Tab: Buffs") is exactly two labels + two 320x116 lists + two "Add..." buttons — nothing in the middle strip. The MossTank-only extras block that used to live there (7 category toggles, the difficulty-margin/rebuff-under spinners, a second Force/Stop buffing button + status, and the "N attributes, N trained skills, N buff lines" coverage counts) is removed outright from mosstank.xml. The underlying settings are not lost: BuffSettings' seven category bools, SkillExcessOverDifficulty, and RebuffWhenUnderSeconds stay in the model and its JSON side-car, and the latter two are real, already-editable VtankOptionCatalog entries (SpellDiffExcessThreshold-Buff / RebuffTimeRemainingSeconds) reachable from Advanced Options. Force Buff / Cancel Force Buff stay on the Options tab, exactly where VTank has them. Orphaned XML-only bindings deleted from MossTankPanel.cs: the seven *Enabled/Toggle* pairs (TrainedOnlyEnabled/ToggleTrainedOnly, AttributesEnabled/ToggleAttributes, ProtectionsEnabled/ ToggleProtections, AurasEnabled/ToggleAuras, BanesEnabled/ToggleBanes, RegenerationEnabled/ToggleRegeneration, OtherEnabled/ToggleOther), DifficultyText/DifficultyUp/DifficultyDown, RebuffText/RebuffUp/ RebuffDown, BuffButtonText, and the Buff action property (StartOrStop itself stays — still reachable from the `/mt buff` slash command, MossTankCommands.cs). BuffStatus and Coverage stay: both are still exercised directly by MossTankPanelTests independent of any control reading them, and neither is listed among the settings the owner's report says must stay in the model, since neither backs a real BuffSettings field — they're the "force-buff status" and "coverage" strings the report never asked to keep alive as UI, only as state. Test changes: MossTankMarkupContractTests' old BuffsExtrasStripIsCenteredAtThePanelsFloorAndCoverageSitsUnderTheButtonRow (which asserted the removed strip's geometry) is replaced with BuffsTabIsVtankOnlySixControls, asserting the Buffs group is exactly two lists + two "Add..." buttons + two labels, with no toggle, no slider, and none of the deleted bindings anywhere in it. Shown to fail first against a targeted mutation (a stray toggle re-added to the group) before the fix was restored. MossTankMarkupBuildOverRealFilesTests' BuffsExtrasStripStaysCenteredAndNonOverlappingAtTheFloor (which proved the same now-deleted strip stayed centered at the panel's floor) is deleted outright; the two remaining lists' own non-overlap/ within-bounds behavior stays covered generically by ResolvedMainPanelHasNoOverlapOrOutOfBoundsChildAtThisSize. MossTank suite: 726 -> 726 (one Fact replaced, same count). App markup/plugin filter: 262 -> 261 (one Fact removed, none added here). Co-Authored-By: Claude Fable 5.1 --- src/AcDream.Plugins.MossTank/BuffPlan.cs | 6 +- src/AcDream.Plugins.MossTank/MossTankPanel.cs | 70 +++-------- src/AcDream.Plugins.MossTank/mosstank.xml | 111 +++++------------- .../MossTankMarkupBuildOverRealFilesTests.cs | 78 ++---------- .../MossTankMarkupContractTests.cs | 93 +++++---------- 5 files changed, 94 insertions(+), 264 deletions(-) diff --git a/src/AcDream.Plugins.MossTank/BuffPlan.cs b/src/AcDream.Plugins.MossTank/BuffPlan.cs index 4b223c28..91439d16 100644 --- a/src/AcDream.Plugins.MossTank/BuffPlan.cs +++ b/src/AcDream.Plugins.MossTank/BuffPlan.cs @@ -28,7 +28,11 @@ public sealed class BuffSettings /// /// How far the casting skill must exceed a spell's difficulty before the /// tier is considered reliable — VTank's - /// SpellDiffExcessThreshold-Buff. + /// SpellDiffExcessThreshold-Buff, editable through Advanced + /// Options (VtankOptionCatalog). Signed on purpose — the wiki is + /// explicit that "a positive number raises the skill necessary to cast + /// spells, a negative number lowers it", so a lower-level character can + /// reach for higher tiers by going negative. /// public int SkillExcessOverDifficulty { get; set; } = 5; diff --git a/src/AcDream.Plugins.MossTank/MossTankPanel.cs b/src/AcDream.Plugins.MossTank/MossTankPanel.cs index 84c359c1..7458fa2a 100644 --- a/src/AcDream.Plugins.MossTank/MossTankPanel.cs +++ b/src/AcDream.Plugins.MossTank/MossTankPanel.cs @@ -426,7 +426,11 @@ internal sealed partial class MossTankPanel } // ── main panel bindings ─────────────────────────────────────────────── - public Action Buff => StartOrStop; + // Campaign VT slice 7 — owner's third live look (2026-09-07): the + // Buffs tab's own "{Buff}"/"{BuffButtonText}" button (a redundant + // second Force/Stop control with no VTank counterpart) was deleted + // from mosstank.xml; StartOrStop itself stays, still reachable from + // the `/mt buff` slash command (MossTankCommands.cs). public Action ForceBuff => StartForceBuff; public Action CancelForceBuff => CancelForceBuffCore; public Action ToggleCombat => ToggleMacro; @@ -695,8 +699,13 @@ internal sealed partial class MossTankPanel ApplyAdvancedOptionCore(); }; - /// The button is Force Buff; while a pass runs it cancels. - public string BuffButtonText => _running ? "Stop buffing" : "Force buff"; + /// + /// The force-buff status. No longer read by any Buffs-tab control + /// (owner's third live look, 2026-09-07 — the Buffs tab's own + /// "{BuffStatus}" label had no VTank counterpart and is gone), but the + /// underlying _status state stays real and is exercised directly + /// by MossTankPanelTests. + /// public string BuffStatus => _status; public string CombatButtonText => _combat.ButtonText; /// @@ -1578,7 +1587,13 @@ internal sealed partial class MossTankPanel /// Vitals line, using the same numbers the character panel shows. public string Vitals => _vitals; - /// What a buff pass would cover, named from the retail tables. + /// + /// What a buff pass would cover, named from the retail tables. No + /// longer read by any Buffs-tab control (owner's third live look, + /// 2026-09-07 — the count had no VTank counterpart and is gone), but + /// still exercised directly by MossTankPanelTests' allocation + /// and throttle pins. + /// public string Coverage => _coverage; // ── settings bindings ───────────────────────────────────────────────── @@ -1586,18 +1601,6 @@ internal sealed partial class MossTankPanel // in plugin markup, whereas an editable field would need keyboard routing // plumbed through to plugin panels first. - /// - /// VTank's SpellDiffExcessThreshold-Buff. Signed on purpose — the - /// wiki is explicit that "a positive number raises the skill necessary to - /// cast spells, a negative number lowers it", so a lower-level character - /// can reach for higher tiers by going negative. - /// - public string DifficultyText => - $"Spell difficulty margin: {_buffSettings.SkillExcessOverDifficulty:+0;-0;0}"; - - public string RebuffText => - $"Rebuff when under: {_buffSettings.RebuffWhenUnderSeconds / 60.0:0.#} min"; - public string NormalHealthText => Percent(_vitalSettings.NormalHealth); public string NormalStaminaText => Percent(_vitalSettings.NormalStamina); public string NormalManaText => Percent(_vitalSettings.NormalMana); @@ -1626,13 +1629,6 @@ internal sealed partial class MossTankPanel public bool VitalUpkeepEnabled => _vitalSettings.Enabled; public bool HelpOthersEnabled => _vitalSettings.HelpOthers; - public bool TrainedOnlyEnabled => _buffSettings.BuffTrainedSkillsOnly; - public bool AttributesEnabled => _buffSettings.BuffAttributes; - public bool ProtectionsEnabled => _buffSettings.BuffProtections; - public bool AurasEnabled => _buffSettings.BuffAuras; - public bool BanesEnabled => _buffSettings.BuffBanes; - public bool RegenerationEnabled => _buffSettings.BuffRegeneration; - public bool OtherEnabled => _buffSettings.BuffOther; // ── Buffs tab Extra/Blacklisted lists + picker (Campaign VT S7.4: // VTank's own lstBuffSpells/lstAntiBuffSpells, docs/research/vtank-kb/ @@ -1774,20 +1770,6 @@ internal sealed partial class MossTankPanel public Action SetHelperStaminaPercent => value => SetHelperStamina(value / 100f); public Action SetHelperManaPercent => value => SetHelperMana(value / 100f); - public Action DifficultyDown => () => UpdateProfile(() => - _buffSettings.SkillExcessOverDifficulty = - Math.Max(-100, _buffSettings.SkillExcessOverDifficulty - 5)); - public Action DifficultyUp => () => UpdateProfile(() => - _buffSettings.SkillExcessOverDifficulty = - Math.Min(100, _buffSettings.SkillExcessOverDifficulty + 5)); - - public Action RebuffDown => () => UpdateProfile(() => - _buffSettings.RebuffWhenUnderSeconds = - Math.Max(30, _buffSettings.RebuffWhenUnderSeconds - 30)); - public Action RebuffUp => () => UpdateProfile(() => - _buffSettings.RebuffWhenUnderSeconds = - Math.Min(1800, _buffSettings.RebuffWhenUnderSeconds + 30)); - public Action ToggleVitalUpkeep => () => { _vitalSettings.Enabled = !_vitalSettings.Enabled; @@ -1809,20 +1791,6 @@ internal sealed partial class MossTankPanel ExpressionValue.Boolean(!_inventorySettings.ManaChargesWhenOff)); public Action ToggleHelpOthers => () => UpdateVital(() => _vitalSettings.HelpOthers = !_vitalSettings.HelpOthers); - public Action ToggleTrainedOnly => () => UpdateProfile(() => - _buffSettings.BuffTrainedSkillsOnly = !_buffSettings.BuffTrainedSkillsOnly); - public Action ToggleAttributes => () => UpdateProfile(() => - _buffSettings.BuffAttributes = !_buffSettings.BuffAttributes); - public Action ToggleProtections => () => UpdateProfile(() => - _buffSettings.BuffProtections = !_buffSettings.BuffProtections); - public Action ToggleAuras => () => UpdateProfile(() => - _buffSettings.BuffAuras = !_buffSettings.BuffAuras); - public Action ToggleBanes => () => UpdateProfile(() => - _buffSettings.BuffBanes = !_buffSettings.BuffBanes); - public Action ToggleRegeneration => () => UpdateProfile(() => - _buffSettings.BuffRegeneration = !_buffSettings.BuffRegeneration); - public Action ToggleOther => () => UpdateProfile(() => - _buffSettings.BuffOther = !_buffSettings.BuffOther); public Action CycleTargetMethod => () => UpdateProfile(() => _combatSettings.SelectionMethod = _combatSettings.SelectionMethod switch { diff --git a/src/AcDream.Plugins.MossTank/mosstank.xml b/src/AcDream.Plugins.MossTank/mosstank.xml index 4f93e083..4a0b6e40 100644 --- a/src/AcDream.Plugins.MossTank/mosstank.xml +++ b/src/AcDream.Plugins.MossTank/mosstank.xml @@ -566,58 +566,37 @@ + Owner's third live look (2026-09-07): "Screenshot shows options under + the buffing tab circled in red. Those are made up, remove them from + here." The MossTank-only extras block that used to sit in the empty + middle strip between the two lists (7 category toggles, the + difficulty-margin and rebuff-under spinners, the Force/Stop buffing + button + status, and the "N attributes, N trained skills, N buff + lines" coverage counts — added by fix round B item 2, then repolished + by round F item 6) is gone outright: VTank's real Buffs tab has no + such block, and this campaign's own silhouette rule (fix round B item + 2's own reasoning) cuts both ways — a VTank-authentic tab gets no + MossTank-only middle strip either. The underlying settings are not + lost: BuffSettings' seven category bools, SkillExcessOverDifficulty + and RebuffWhenUnderSeconds all stay in the model and its JSON + side-car, and the same two numbers are real, already-editable + VtankOptionCatalog entries (SpellDiffExcessThreshold-Buff, + RebuffTimeRemainingSeconds) reachable from Advanced Options. Force + Buff / Cancel Force Buff stay right where VTank has them, on the + Options tab (ForceBuff/CancelForceBuff, unchanged by this edit). The + XML-only bindings that fed the removed controls (the seven + *Enabled/Toggle* pairs, DifficultyText/Up/Down, RebuffText/Up/Down, + BuffButtonText, and the Buff action — StartOrStop itself stays, still + reachable from the `/mt buff` slash command) are deleted from + MossTankPanel.cs as orphans; BuffStatus and Coverage stay (both are + still exercised directly by MossTankPanelTests, independent of any + control reading them). --> - + footprint (minh follows); minw stays 392. + + Owner's third live look (2026-09-07): "Also still have tooltips in the + advanced options, remove please." VTank's own AdvancedOptionsView has no + tooltip mechanism at all — its own description readout + (AdvancedOptionDescription, the label at the bottom) is the retail + in-popup info channel, not a hover tooltip. The three tooltip= attributes + this popup had grown (the option list, the category checklist, the value + field) are removed; nothing else in this file ever set one. --> + selected="{SelectedAdvancedOptionIndex}" onchange="{SelectAdvancedOption}"> @@ -181,15 +188,13 @@ pure checklist with no real selection concept — see SelectedAdvancedOptionCategoryIndex's own doc comment. --> + selected="{SelectedAdvancedOptionCategoryIndex}"> + maxlength="160" clearonsubmit="false" background="#E6000000" /> diff --git a/tests/AcDream.App.Tests/UI/MossTankMarkupBuildOverRealFilesTests.cs b/tests/AcDream.App.Tests/UI/MossTankMarkupBuildOverRealFilesTests.cs index df6a1e5b..6f72e462 100644 --- a/tests/AcDream.App.Tests/UI/MossTankMarkupBuildOverRealFilesTests.cs +++ b/tests/AcDream.App.Tests/UI/MossTankMarkupBuildOverRealFilesTests.cs @@ -184,6 +184,43 @@ public sealed class MossTankMarkupBuildOverRealFilesTests + $"the repositioned category list (left edge {categoryList.Left})."); } + /// + /// Owner's third live look (2026-09-07): "Also still have tooltips in + /// the advanced options, remove please." VTank's own AdvancedOptionsView + /// has no tooltip mechanism at all — its description readout is the + /// retail in-popup info channel, not a hover tooltip. Builds the real + /// mosstank-advanced.xml against a real panel (the same shape every + /// other test in this file uses) and walks the WHOLE resolved tree — + /// not just the three elements that used to carry tooltip= — so a + /// tooltip added anywhere else in this popup in the future fails this + /// pin too. only ever sets + /// when the source + /// element declared a real tooltip= attribute (MarkupDocument.cs's own + /// ApplyCommonAttributes), so a null source function here means no + /// tooltip was ever bound for that element. + /// + [Fact] + public void AdvancedOptionsPopupHasNoElementWithATooltip() + { + string xml = File.ReadAllText( + Path.Combine(MossTankMarkupDirectory, "mosstank-advanced.xml")); + var panel = new MossTankPanel(new StubHost()); + + UiNineSlicePanel built = MarkupDocument.Build(xml, panel, static id => (id, 32, 32)); + + AssertNoElementHasATooltip(built); + } + + private static void AssertNoElementHasATooltip(UiElement element) + { + Assert.True( + element.RuntimeTooltipTextSource is null, + $"{element.GetType().Name} carries a tooltip — the Advanced " + + "Options popup must have none (owner's third live look)."); + foreach (UiElement child in element.Children) + AssertNoElementHasATooltip(child); + } + /// /// D-6 (round E architecture re-check): every real-file re-layout pin /// so far only inspects ONE named element after a resize (the From ce44d8c7207ce10c7890eb16c5c3cc0259a66dc4 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 7 Sep 2026 21:12:43 +0200 Subject: [PATCH 3/3] =?UTF-8?q?docs(vt):=20slice=207=20ledger=20=E2=80=94?= =?UTF-8?q?=20owner's=20third=20live=20look,=20Buffs=20strip=20+=20tooltip?= =?UTF-8?q?s=20fixed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Records this round's two owner-reported fixes (the fabricated Buffs-tab middle strip removed; Advanced Options tooltips removed) against the already-closed slice 7 campaign, with commit references and the MossTank/App test-count deltas. Co-Authored-By: Claude Fable 5.1 --- docs/plans/2026-09-07-campaign-vt-slice7-tabs.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/plans/2026-09-07-campaign-vt-slice7-tabs.md b/docs/plans/2026-09-07-campaign-vt-slice7-tabs.md index 07e6c661..c151e86b 100644 --- a/docs/plans/2026-09-07-campaign-vt-slice7-tabs.md +++ b/docs/plans/2026-09-07-campaign-vt-slice7-tabs.md @@ -153,3 +153,4 @@ re-review, merge to the campaign branch, then the owner's visual gate. ## Closeout - 2026-09-07 21:10 final combined re-check (E+F, both lenses): all twelve items CLOSED with failable tests, no per-frame allocation regression, the three recall tables agree pairwise, plugin references BCL + Abstractions only — MERGE-READY. **Merged into the campaign branch at `4a825c23c`.** Owner's second-look items all closed (Advanced Options bottom block gone; string settings hidden; Items tab VTank-only). Accepted, documented deviations: the Buffs extras strip centres at the 856 floor only (anchors have no "centre"); the recall combo lists "Marketplace" in place of VTank's duplicated "Fac. Hub"; dead margins on six tabs at the 984 default. Carried polish (owner: "we do that later"): strip the retired `scroll="true"` from five markup sites and make its test failable or document that unknown attributes are ignored; delete the ~20 bindings round F orphaned; cache the two Buffs row sources like every other column; two comment corrections; Meta's delete cell as an icon. Open issues from this slice: #490 part 1 (host: `StartVisible=false` + `ShowInSidePanel=false` unshowable), #491 (buff lists not consumed by `BuffPlan.Build`), #492 (Vulkan device-loss crash + shutdown re-throw), #493 (in-game meta/loot rule editors, deferred). Owner's visual gate: the merged build launched from the gate worktree for the final look. +- 2026-09-07 owner's third live look, post-closeout: (1) "Screenshot shows options under the buffing tab circled in red. Those are made up, remove them from here" — the whole MossTank-extras middle strip fix round B item 2 added between the Buffs tab's two lists (7 category toggles, difficulty/rebuff spinners, a second Force/Stop buffing button + status, the coverage counts) is gone outright; the Buffs tab is now VTank's own exact six controls (2 labels, 2 lists, 2 "Add..." buttons), matching the Items-tab precedent from round F item 3. The underlying BuffSettings fields (seven category bools, SkillExcessOverDifficulty, RebuffWhenUnderSeconds) stay in the model/side-car and remain editable through Advanced Options (SpellDiffExcessThreshold-Buff / RebuffTimeRemainingSeconds); Force Buff / Cancel Force Buff stay on the Options tab. Twenty-two now-orphaned XML-only bindings deleted from MossTankPanel.cs (the seven Enabled/Toggle pairs, DifficultyText/Up/Down, RebuffText/Up/Down, BuffButtonText, the Buff action) — this is the "delete the ~20 bindings round F orphaned" carried-polish item from the closeout, done as part of this fix rather than separately; BuffStatus/Coverage stay since MossTankPanelTests still exercises both directly. Commit `6be555ad4`. (2) "Also still have tooltips in the advanced options, remove please" — the three tooltip= attributes mosstank-advanced.xml had grown (option list, category checklist, value field) are removed; VTank's real AdvancedOptionsView has no tooltip mechanism, only its own description readout. New whole-tree test AdvancedOptionsPopupHasNoElementWithATooltip guards against any future re-addition. Commit `617a9c221`. Both fixes' new/changed tests shown to fail first against targeted mutations (a stray toggle re-added to the Buffs group; a tooltip= reintroduced on the option list), then reverted and restored green. MossTank suite 726 -> 726 (one Fact replaced); App markup/plugin filter 262 -> 261 (item 1, one Fact removed) -> 262 (item 2, one Fact added). Full solution Release build green throughout.