fix(mosstank): Buffs tab is VTank's own six controls, nothing more
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 <noreply@anthropic.com>
This commit is contained in:
parent
a2df6efaeb
commit
6be555ad47
5 changed files with 94 additions and 264 deletions
|
|
@ -28,7 +28,11 @@ public sealed class BuffSettings
|
|||
/// <summary>
|
||||
/// How far the casting skill must exceed a spell's difficulty before the
|
||||
/// tier is considered reliable — VTank's
|
||||
/// <c>SpellDiffExcessThreshold-Buff</c>.
|
||||
/// <c>SpellDiffExcessThreshold-Buff</c>, 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.
|
||||
/// </summary>
|
||||
public int SkillExcessOverDifficulty { get; set; } = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
};
|
||||
|
||||
/// <summary>The button is Force Buff; while a pass runs it cancels.</summary>
|
||||
public string BuffButtonText => _running ? "Stop buffing" : "Force buff";
|
||||
/// <summary>
|
||||
/// 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 <c>_status</c> state stays real and is exercised directly
|
||||
/// by <c>MossTankPanelTests</c>.
|
||||
/// </summary>
|
||||
public string BuffStatus => _status;
|
||||
public string CombatButtonText => _combat.ButtonText;
|
||||
/// <summary>
|
||||
|
|
@ -1578,7 +1587,13 @@ internal sealed partial class MossTankPanel
|
|||
/// <summary>Vitals line, using the same numbers the character panel shows.</summary>
|
||||
public string Vitals => _vitals;
|
||||
|
||||
/// <summary>What a buff pass would cover, named from the retail tables.</summary>
|
||||
/// <summary>
|
||||
/// 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 <c>MossTankPanelTests</c>' allocation
|
||||
/// and throttle pins.
|
||||
/// </summary>
|
||||
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.
|
||||
|
||||
/// <summary>
|
||||
/// VTank's <c>SpellDiffExcessThreshold-Buff</c>. 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.
|
||||
/// </summary>
|
||||
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<float> SetHelperStaminaPercent => value => SetHelperStamina(value / 100f);
|
||||
public Action<float> 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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -566,58 +566,37 @@
|
|||
|
||||
<!-- Buffs: VTank's REAL Buffs tab (docs/research/vtank-kb/08-ui-views.md
|
||||
§1 "Tab: Buffs") is ONLY two lists + two "Add..." buttons — Extra Buff
|
||||
Spells and Blacklisted Buff Families, each VTank's own 320x116, at the
|
||||
far left and far right of the 848-wide canvas (PluginCore.cs:
|
||||
Spells and Blacklisted Buff Families, each VTank's own 320x116 (grown
|
||||
+35 tall per Round D item 4's own font-driven scaling, matching every
|
||||
other tab), at the far left and far right of the panel (PluginCore.cs:
|
||||
7323-7355 — any cell click removes that row; "Add..." opens the
|
||||
shared SelfBuffChoiceView-style picker, mosstank-buffpicker.xml).
|
||||
|
||||
Fix round B item 2 (owner's silhouette rule: VTank's own controls are
|
||||
never shrunk/moved/reordered to make room for MossTank extras): the
|
||||
category toggles / difficulty / rebuff / Buff-cast-now block below
|
||||
(MossTank's own pre-existing extension, no VTank Buffs-tab
|
||||
counterpart) used to live in the same two columns as the narrowed
|
||||
lists, and its Difficulty "+" button (338,108) overlapped the Extra
|
||||
Buff Spells "Add..." button (336,102) — a real sibling-overlap bug
|
||||
the new AuthoredControlsInTheSameGroupNeverOverlap pin below now
|
||||
catches. Both lists are restored to VTank's full 320x116 at the far
|
||||
left (x=4) and far right (x=524, 848-4-320) with their own
|
||||
120-wide "Add..." row below each list; the whole MossTank-extras
|
||||
block moves into the EMPTY MIDDLE strip between the two lists,
|
||||
stacked compactly: 7 toggles at a 16px pitch, then Difficulty +/-,
|
||||
then Rebuff +/-, then the Buff button + status, then Coverage
|
||||
right under it — a proportion-preserving compromise fitting a
|
||||
real box, not a pixel-for-pixel VVS port (owner's bar: "looks
|
||||
basically the same", never VVS pixels).
|
||||
|
||||
Round F item 6 (resemblance re-check: "Buffs' 136 px middle gap
|
||||
and the orphaned Coverage label"). Coverage moved from y=213
|
||||
(anchored to the group's bottom edge, a real 55px empty hole
|
||||
above it once the panel grew past its original 194-tall size) to
|
||||
sit directly under the Buff button row instead — no anchor, since
|
||||
nothing below it needs the space that anchor used to protect.
|
||||
|
||||
The middle-gap half of this item turned out to have a hard
|
||||
geometric ceiling: Extra Buff Spells never moves (anchor="left
|
||||
top bottom", pinned at x=4..324) but Blacklisted Buff Families
|
||||
tracks the growing right edge (anchor="right"), sitting at
|
||||
x=524 at the panel's own tested floor (856x236, PanelIsResizable
|
||||
FlooredAtThePreRoundDAuthoredSize) and x=652 at the 984-wide
|
||||
enlarged default — a 128px swing. The extras strip (182px wide)
|
||||
is a single FIXED position, so it can only be centered relative
|
||||
to ONE of those two widths; centering it against the 984 default
|
||||
(x=397) put its right edge at 579, 55px INSIDE where the same
|
||||
list sits at the floor (524) — a real overlap
|
||||
ResolvedMainPanelHasNoOverlapOrOutOfBoundsChildAtThisSize's own
|
||||
856x236 case catches. x=333 is the strip's floor-centered
|
||||
position (9px margin on both sides against the floor's 324..524
|
||||
gap, the widest safe position a fixed strip can take) — the same
|
||||
position fix round B item 2 effectively already used (x=332, 1px
|
||||
off from exactly centered) before Round D's enlargement existed.
|
||||
The residual asymmetric gap at the 984 default (previously ~8/138,
|
||||
now ~9/137) is therefore an accepted, unavoidable-without-a-
|
||||
redesign limitation — the same "dead margin, polish later" trade
|
||||
the resemblance re-check already accepted for six other tabs at
|
||||
this same enlarged size. -->
|
||||
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). -->
|
||||
<group x="8" y="42" w="976" h="229" visible="{BuffsVisible}" anchor="left top right bottom">
|
||||
<!-- Fix round B item 14 (owner honesty rule): BuffPlan.Build does not
|
||||
read this set at all yet — a real, tracked wiring gap (see
|
||||
|
|
@ -644,40 +623,6 @@
|
|||
items="{BlacklistedBuffFamilyRows}" selected="{SelectedBlacklistedBuffIndex}"
|
||||
onchange="{DeleteBlacklistedBuffFamilyAt}" tooltip="Click a row to remove it." />
|
||||
<button x="652" y="173" w="120" h="18" text="Add..." onclick="{ShowBlacklistedBuffPicker}" anchor="right bottom" />
|
||||
|
||||
<toggle x="333" y="0" w="180" h="16" text="Trained skills only"
|
||||
checked="{TrainedOnlyEnabled}" onclick="{ToggleTrainedOnly}" />
|
||||
<toggle x="333" y="16" w="180" h="16" text="Attributes"
|
||||
checked="{AttributesEnabled}" onclick="{ToggleAttributes}" />
|
||||
<toggle x="333" y="32" w="180" h="16" text="Protections"
|
||||
checked="{ProtectionsEnabled}" onclick="{ToggleProtections}" />
|
||||
<toggle x="333" y="48" w="180" h="16" text="Weapon auras"
|
||||
checked="{AurasEnabled}" onclick="{ToggleAuras}" />
|
||||
<toggle x="333" y="64" w="180" h="16" text="Armor banes"
|
||||
checked="{BanesEnabled}" onclick="{ToggleBanes}" />
|
||||
<toggle x="333" y="80" w="180" h="16" text="Regeneration"
|
||||
checked="{RegenerationEnabled}" onclick="{ToggleRegeneration}" />
|
||||
<toggle x="333" y="96" w="180" h="16" text="Other self-spells"
|
||||
checked="{OtherEnabled}" onclick="{ToggleOther}" />
|
||||
|
||||
<label x="333" y="116" w="140" text="{DifficultyText}" color="#FFE8DEC3" />
|
||||
<button x="473" y="112" w="20" h="18" text="-" onclick="{DifficultyDown}"
|
||||
tooltip="Decrease the skill-over-difficulty margin." />
|
||||
<button x="495" y="112" w="20" h="18" text="+" onclick="{DifficultyUp}"
|
||||
tooltip="Increase the skill-over-difficulty margin." />
|
||||
<label x="333" y="136" w="140" text="{RebuffText}" color="#FFE8DEC3" />
|
||||
<button x="473" y="132" w="20" h="18" text="-" onclick="{RebuffDown}"
|
||||
tooltip="Rebuff later." />
|
||||
<button x="495" y="132" w="20" h="18" text="+" onclick="{RebuffUp}"
|
||||
tooltip="Rebuff earlier." />
|
||||
|
||||
<button x="333" y="154" w="110" h="18" text="{BuffButtonText}" onclick="{Buff}" />
|
||||
<label x="447" y="158" w="70" text="{BuffStatus}" color="#FFC7B98F" />
|
||||
<!-- Round F item 6: sits right under the button row above (154+18=172,
|
||||
+4px) instead of anchored to the group's bottom edge — the
|
||||
anchor used to leave a growing empty hole (55px at the enlarged
|
||||
984-wide default) between this label and the row it belongs to. -->
|
||||
<label x="333" y="176" w="184" h="16" text="{Coverage}" color="#FF9B9072" />
|
||||
</group>
|
||||
|
||||
<!-- Route: VTank's own 2-across button grid, row order, and bottom
|
||||
|
|
|
|||
|
|
@ -254,73 +254,17 @@ public sealed class MossTankMarkupBuildOverRealFilesTests
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Round F item 6 (resemblance re-check: "Buffs' 136 px middle gap").
|
||||
/// <see cref="ResolvedMainPanelHasNoOverlapOrOutOfBoundsChildAtThisSize"/>
|
||||
/// already proves the extras strip never overlaps the Blacklisted
|
||||
/// Buff Families list at the floor or the enlarged size (that generic
|
||||
/// sibling-overlap pass is exactly what caught the original x=397
|
||||
/// attempt at true 984-default centering colliding with the list's
|
||||
/// own floor position, x=524). This is the narrower, POSITIVE claim
|
||||
/// that overlap pass alone doesn't make: the strip is actually
|
||||
/// CENTERED at the panel's floor (856x236) — the one width at which
|
||||
/// centering and non-overlap can both hold, since Extra Buff Spells
|
||||
/// never moves but Blacklisted Buff Families tracks the growing
|
||||
/// right edge.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void BuffsExtrasStripStaysCenteredAndNonOverlappingAtTheFloor()
|
||||
{
|
||||
string xml = File.ReadAllText(
|
||||
Path.Combine(MossTankMarkupDirectory, "mosstank.xml"));
|
||||
var panel = new MossTankPanel(new StubHost());
|
||||
|
||||
UiNineSlicePanel built = MarkupDocument.Build(xml, panel, static id => (id, 32, 32));
|
||||
|
||||
UiPanel[] tabGroups = built.Children
|
||||
.Where(static child => child.GetType() == typeof(UiPanel))
|
||||
.Cast<UiPanel>()
|
||||
.ToArray();
|
||||
Assert.Equal(9, tabGroups.Length);
|
||||
foreach (UiPanel group in tabGroups)
|
||||
group.Visible = false;
|
||||
UiPanel buffsGroup = tabGroups[6];
|
||||
buffsGroup.Visible = true;
|
||||
|
||||
var device = new RecordingGpuDevice();
|
||||
var renderer = new TextRenderer(device, new NullGpuFrameSource(), "unused");
|
||||
renderer.Begin(new Vector2(1400f, 900f));
|
||||
var ctx = new UiRenderContext(renderer, new Vector2(1400f, 900f));
|
||||
|
||||
// First draw at the authored default captures anchor baselines;
|
||||
// only then resize down to the panel's own tested floor.
|
||||
built.DrawSelfAndChildren(ctx);
|
||||
built.Width = 856f;
|
||||
built.Height = 236f;
|
||||
built.DrawSelfAndChildren(ctx);
|
||||
|
||||
UiMarkupList[] lists = buffsGroup.Children.OfType<UiMarkupList>().ToArray();
|
||||
Assert.Equal(2, lists.Length);
|
||||
UiMarkupList leftList = lists.Single(static l => l.Left < 300f);
|
||||
UiMarkupList rightList = lists.Single(static l => l.Left >= 300f);
|
||||
|
||||
UiMarkupToggle trainedToggle = Assert.Single(
|
||||
buffsGroup.Children.OfType<UiMarkupToggle>(), static t => t.Text == "Trained skills only");
|
||||
UiSimpleButton rebuffUpButton = Assert.Single(
|
||||
buffsGroup.Children.OfType<UiSimpleButton>(), static b => b.Text == "+" && b.Top > 120f);
|
||||
|
||||
float leftMargin = trainedToggle.Left - (leftList.Left + leftList.Width);
|
||||
float rightMargin = rightList.Left - (rebuffUpButton.Left + rebuffUpButton.Width);
|
||||
Assert.True(
|
||||
rightMargin >= 0f,
|
||||
$"Extras strip (right edge {rebuffUpButton.Left + rebuffUpButton.Width}) "
|
||||
+ $"overlaps the right list (left edge {rightList.Left}) at the floor.");
|
||||
Assert.True(
|
||||
MathF.Abs(leftMargin - rightMargin) <= 4f,
|
||||
$"Extras strip not centered at the floor: left margin "
|
||||
+ $"{leftMargin}px, right margin {rightMargin}px.");
|
||||
}
|
||||
|
||||
// Owner's third live look (2026-09-07) deleted the MossTank-only extras
|
||||
// strip that used to sit between the Buffs tab's two lists (7 category
|
||||
// toggles, the difficulty/rebuff spinners, the Force/Stop buffing
|
||||
// button + status, the coverage counts) outright — VTank's real Buffs
|
||||
// tab has no such block (see MossTankMarkupContractTests'
|
||||
// BuffsTabIsVtankOnlySixControls for the authored-tree pin). The
|
||||
// former BuffsExtrasStripStaysCenteredAndNonOverlappingAtTheFloor test
|
||||
// that proved the (now-deleted) strip stayed centered at the panel's
|
||||
// floor is gone with it; the two remaining lists' own non-overlap/
|
||||
// within-bounds behavior at both the floor and the enlarged size stays
|
||||
// covered generically by ResolvedMainPanelHasNoOverlapOrOutOfBoundsChildAtThisSize.
|
||||
private static void AssertResolvedWithinParent(UiElement parent)
|
||||
{
|
||||
foreach (UiElement child in parent.Children)
|
||||
|
|
|
|||
|
|
@ -302,32 +302,21 @@ public sealed class MossTankMarkupContractTests
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Round F item 6 (resemblance re-check nits: "Buffs' 136 px middle
|
||||
/// gap and the orphaned Coverage label"). Coverage sits right under
|
||||
/// the Buff button row instead of anchored to the group's bottom
|
||||
/// edge, which used to leave a 55px empty hole above it as the panel
|
||||
/// grew.
|
||||
///
|
||||
/// The middle-gap half has a hard geometric ceiling documented at
|
||||
/// mosstank.xml's own Buffs comment: Extra Buff Spells never moves
|
||||
/// (x=4..324) but Blacklisted Buff Families tracks the growing right
|
||||
/// edge (anchor="right"), sitting at x=524 at the panel's own tested
|
||||
/// FLOOR (856x236) and x=652 (its authored declaration below) at the
|
||||
/// 984-wide enlarged default — a 128px swing this campaign's own
|
||||
/// Round D item 4 introduced. A single FIXED-position strip can only
|
||||
/// be centered relative to ONE of those two widths; centering
|
||||
/// against the 984 default would put the strip's right edge INSIDE
|
||||
/// where the list sits at the floor — a real overlap
|
||||
/// ResolvedMainPanelHasNoOverlapOrOutOfBoundsChildAtThisSize's own
|
||||
/// 856x236 case would catch. This pins centering against the FLOOR
|
||||
/// value instead (declared x minus the 128px Round D growth delta —
|
||||
/// 984-856) — the widest safe position a fixed strip can take,
|
||||
/// verified against the real-file resolved tree at both sizes by
|
||||
/// <c>MossTankMarkupBuildOverRealFilesTests.BuffsExtrasStripStaysCenteredAndNonOverlappingAtTheFloor</c>
|
||||
/// in the App test project.
|
||||
/// 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 lists + two "Add..." buttons, nothing in the empty
|
||||
/// middle strip between the lists. The MossTank-only extras block that
|
||||
/// used to live there (7 category toggles, the difficulty/rebuff
|
||||
/// spinners, the Force/Stop buffing button + status, the coverage
|
||||
/// counts — added by fix round B item 2, repolished by round F item 6)
|
||||
/// is gone outright, matching this same file's
|
||||
/// <see cref="ItemsTabIsVtankOnlyPlusTheAcceptedSliceOneRemoveButton"/>
|
||||
/// precedent for the Items tab's own round-F removal.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void BuffsExtrasStripIsCenteredAtThePanelsFloorAndCoverageSitsUnderTheButtonRow()
|
||||
public void BuffsTabIsVtankOnlySixControls()
|
||||
{
|
||||
XDocument document = XDocument.Load(
|
||||
Path.Combine(AppContext.BaseDirectory, "mosstank.xml"));
|
||||
|
|
@ -335,45 +324,25 @@ public sealed class MossTankMarkupContractTests
|
|||
XElement buffsGroup = root.Elements("group")
|
||||
.Single(static g => (string?)g.Attribute("visible") == "{BuffsVisible}");
|
||||
|
||||
XElement[] lists = buffsGroup.Elements("list").ToArray();
|
||||
Assert.Equal(2, lists.Length);
|
||||
float leftListRightEdge = Number(lists[0], "x") + Number(lists[0], "w");
|
||||
// Round D item 4's own +128 growth: the declared x below is the
|
||||
// 984-wide authored default; subtracting it back out gives the
|
||||
// resolved position at the panel's tested floor (856x236).
|
||||
const float roundDGrowthDelta = 984f - 856f;
|
||||
float rightListLeftEdgeAtFloor = Number(lists[1], "x") - roundDGrowthDelta;
|
||||
Assert.Equal(2, buffsGroup.Elements("list").Count());
|
||||
string[] buttonTexts = buffsGroup.Elements("button")
|
||||
.Select(static b => (string?)b.Attribute("text") ?? string.Empty)
|
||||
.ToArray();
|
||||
Assert.Equal(["Add...", "Add..."], buttonTexts);
|
||||
string[] labelTexts = buffsGroup.Elements("label")
|
||||
.Select(static l => (string?)l.Attribute("text") ?? string.Empty)
|
||||
.ToArray();
|
||||
Assert.Equal(["Extra Buff Spells", "Blacklisted Buff Families"], labelTexts);
|
||||
|
||||
XElement trainedToggle = buffsGroup.Elements("toggle")
|
||||
.Single(static t => (string?)t.Attribute("onclick") == "{ToggleTrainedOnly}");
|
||||
XElement rebuffUpButton = buffsGroup.Elements("button")
|
||||
.Single(static b => (string?)b.Attribute("onclick") == "{RebuffUp}");
|
||||
float extrasLeft = Number(trainedToggle, "x");
|
||||
float extrasRight = Number(rebuffUpButton, "x") + Number(rebuffUpButton, "w");
|
||||
|
||||
float leftMargin = extrasLeft - leftListRightEdge;
|
||||
float rightMarginAtFloor = rightListLeftEdgeAtFloor - extrasRight;
|
||||
Assert.True(
|
||||
rightMarginAtFloor >= 0f,
|
||||
$"Extras strip (right edge {extrasRight}) overlaps the "
|
||||
+ $"Blacklisted Buff Families list at the panel's floor "
|
||||
+ $"(left edge {rightListLeftEdgeAtFloor}).");
|
||||
Assert.True(
|
||||
MathF.Abs(leftMargin - rightMarginAtFloor) <= 4f,
|
||||
$"Extras strip not centered at the panel's floor: left margin "
|
||||
+ $"{leftMargin}px, right margin {rightMarginAtFloor}px.");
|
||||
|
||||
XElement buffButton = buffsGroup.Elements("button")
|
||||
.Single(static b => (string?)b.Attribute("onclick") == "{Buff}");
|
||||
XElement coverage = buffsGroup.Elements("label")
|
||||
.Single(static l => (string?)l.Attribute("text") == "{Coverage}");
|
||||
float rowBottom = Number(buffButton, "y") + Number(buffButton, "h");
|
||||
float coverageGap = Number(coverage, "y") - rowBottom;
|
||||
Assert.True(
|
||||
coverageGap is >= 0f and <= 12f,
|
||||
$"Coverage sits {coverageGap}px below the Buff button row — "
|
||||
+ "expected <=12px, not the old 55px hole from anchoring it to "
|
||||
+ "the group's bottom edge instead.");
|
||||
// Nothing else — no toggle, no slider, no MossTank-only status/
|
||||
// difficulty/rebuff/coverage label ever made it back in.
|
||||
Assert.Empty(buffsGroup.Elements("toggle"));
|
||||
Assert.Empty(buffsGroup.Elements("slider"));
|
||||
Assert.DoesNotContain("{BuffButtonText}", labelTexts);
|
||||
Assert.DoesNotContain("{BuffStatus}", labelTexts);
|
||||
Assert.DoesNotContain("{DifficultyText}", labelTexts);
|
||||
Assert.DoesNotContain("{RebuffText}", labelTexts);
|
||||
Assert.DoesNotContain("{Coverage}", labelTexts);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue