fix(vtank): slice 7 fix round B item 14 — persist Extra Buff Spells / Blacklisted Buff Families, reword tooltips
ExtraBuffSpellNames/BlacklistedBuffFamilyNames (Buffs tab, Campaign VT
S7.4) were never captured by SideCarDocument (the active JSON persistence
alongside the real VTank .usd) — a restart or profile switch silently
dropped them. BuffPlan.Build still does not READ either set when choosing
what to cast — that remains a real, separately tracked wiring gap (see
BuffSettings' own doc comments); this only fixes the storage/display
honesty the owner asked for.
- SideCarDocument gained BuffExtraSpellNames/BuffBlacklistedFamilyNames
(string[]), captured via the same Sorted() helper CombatItemNames/
ConsumableNames use, and applied via the same Replace() clear-then-
repopulate helper — a profile switch can't carry a stale entry over from
whichever profile was loaded before.
- PickBuffAtCore and DeleteExtraBuffAt/DeleteBlacklistedBuffFamilyAt now
call SaveProfile(), matching every other Add/Delete mutator in this file
— without this the newly-wired capture/apply would only fire
opportunistically on some unrelated save.
- Reworded both tab tooltips ("Named spell exemplars added beyond the
school-driven picks" / "Named buff families never cast, even if
otherwise wanted") to state plainly that the lists are stored and shown
but not yet used for casting, instead of implying they already affect
cast selection.
- (False start, reverted: an earlier pass edited LegacyBuffProfileDocument,
which the file's own comment marks migration-only dead code that nothing
else writes any more — the real fix belongs in SideCarDocument, the
active format SaveCurrent/LoadCurrent actually round-trip.)
New test: ExtraBuffAndBlacklistedFamilyNamesPersistAcrossSessions (add via
the picker in one panel, confirm both survive in a second panel sharing
the same storage). Mutation check: commenting out the two Replace() calls
in SideCarDocument.Apply turned it red ("Expected: [Spell 1], Actual: []");
restoring them turns it green.
tests/AcDream.Plugins.MossTank.Tests: 675/675 (was 674/674, +1).
tests/AcDream.App.Tests --filter Markup|Plugin|UiMenu|Slider: 278/3 skipped/281 (unchanged).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
169a6c6e32
commit
b0fee80e6f
4 changed files with 68 additions and 2 deletions
|
|
@ -1433,11 +1433,13 @@ internal sealed partial class MossTankPanel
|
|||
{
|
||||
_selectedExtraBuffRow = row;
|
||||
DeleteFromNamedSet(_buffSettings.ExtraBuffSpellNames, row);
|
||||
SaveProfile();
|
||||
};
|
||||
public Action<int> DeleteBlacklistedBuffFamilyAt => row =>
|
||||
{
|
||||
_selectedBlacklistedBuffRow = row;
|
||||
DeleteFromNamedSet(_buffSettings.BlacklistedBuffFamilyNames, row);
|
||||
SaveProfile();
|
||||
};
|
||||
public Action ShowExtraBuffPicker => () => ShowBuffPickerCore(forBlacklist: false);
|
||||
public Action ShowBlacklistedBuffPicker => () => ShowBuffPickerCore(forBlacklist: true);
|
||||
|
|
@ -1900,6 +1902,11 @@ internal sealed partial class MossTankPanel
|
|||
else
|
||||
_buffSettings.ExtraBuffSpellNames.Add(name);
|
||||
_buffPickerVisible = false;
|
||||
// Fix round B item 14: these two sets are now captured/applied by
|
||||
// LegacyBuffProfileDocument — an explicit save is needed here (same
|
||||
// as every other Add/Delete mutator in this file) for a pick to
|
||||
// actually survive past this session.
|
||||
SaveProfile();
|
||||
}
|
||||
|
||||
private static int ClampRow(int index, int count) => count == 0
|
||||
|
|
|
|||
|
|
@ -762,6 +762,17 @@ internal sealed class MossTankProfileStore
|
|||
public bool BuffRegeneration { get; set; } = true;
|
||||
public bool BuffOther { get; set; }
|
||||
public bool BuffTrainedSkillsOnly { get; set; } = true;
|
||||
// Fix round B item 14: these two Buffs-tab sets (Campaign VT S7.4)
|
||||
// had no VTank Settings-table row of their own (VTank's
|
||||
// ExtraBuffSpells/AntiExtraBuffSpells are separate tables, not
|
||||
// scalar Settings rows) and were never captured by this side-car
|
||||
// either — a restart or profile switch silently dropped them.
|
||||
// BuffPlan.Build still does not READ either set when choosing what
|
||||
// to cast (a real, separately tracked wiring gap — see
|
||||
// BuffSettings' own doc comments); this only fixes the storage/
|
||||
// display honesty.
|
||||
public string[] BuffExtraSpellNames { get; set; } = [];
|
||||
public string[] BuffBlacklistedFamilyNames { get; set; } = [];
|
||||
public bool VitalsEnabled { get; set; } = true;
|
||||
public double InventoryScanIntervalSeconds { get; set; } = 0.25d;
|
||||
// InventoryEnableLooting was deleted here (round 3, item 1): it
|
||||
|
|
@ -802,6 +813,8 @@ internal sealed class MossTankProfileStore
|
|||
BuffRegeneration = settings.Buffs.BuffRegeneration,
|
||||
BuffOther = settings.Buffs.BuffOther,
|
||||
BuffTrainedSkillsOnly = settings.Buffs.BuffTrainedSkillsOnly,
|
||||
BuffExtraSpellNames = Sorted(settings.Buffs.ExtraBuffSpellNames),
|
||||
BuffBlacklistedFamilyNames = Sorted(settings.Buffs.BlacklistedBuffFamilyNames),
|
||||
VitalsEnabled = settings.Vitals.Enabled,
|
||||
InventoryScanIntervalSeconds = settings.Inventory.ScanIntervalSeconds,
|
||||
InventoryLootClassifierId = settings.Inventory.Loot.ExternalClassifierId,
|
||||
|
|
@ -870,6 +883,12 @@ internal sealed class MossTankProfileStore
|
|||
settings.Buffs.BuffRegeneration = BuffRegeneration;
|
||||
settings.Buffs.BuffOther = BuffOther;
|
||||
settings.Buffs.BuffTrainedSkillsOnly = BuffTrainedSkillsOnly;
|
||||
// Fix round B item 14: clear-then-repopulate (Replace, same
|
||||
// helper CombatItemNames/ConsumableNames/NoBuffItemNames use) —
|
||||
// a profile switch must not carry a stale entry over from
|
||||
// whichever profile was loaded before.
|
||||
Replace(settings.Buffs.ExtraBuffSpellNames, BuffExtraSpellNames);
|
||||
Replace(settings.Buffs.BlacklistedBuffFamilyNames, BuffBlacklistedFamilyNames);
|
||||
|
||||
settings.Vitals.Enabled = VitalsEnabled;
|
||||
|
||||
|
|
|
|||
|
|
@ -508,15 +508,22 @@
|
|||
compromise fitting a real 184x194 box, not a pixel-for-pixel VVS
|
||||
port (owner's bar: "looks basically the same", never VVS pixels). -->
|
||||
<group x="8" y="42" w="848" h="194" visible="{BuffsVisible}">
|
||||
<!-- Fix round B item 14 (owner honesty rule): BuffPlan.Build does not
|
||||
read this set at all yet — a real, tracked wiring gap (see
|
||||
BuffSettings.ExtraBuffSpellNames' own doc comment), not a display
|
||||
bug. The tooltip says so instead of implying these names already
|
||||
affect what gets cast. -->
|
||||
<label x="4" y="0" w="320" h="16" text="Extra Buff Spells" color="#FFE8DEC3"
|
||||
tooltip="Named spell exemplars added beyond the school-driven picks (best similar will be used)." />
|
||||
tooltip="Named spell exemplars — stored and shown here, not yet used when choosing what to cast." />
|
||||
<list x="4" y="18" w="320" h="116" rowheight="17"
|
||||
items="{ExtraBuffRows}" selected="{SelectedExtraBuffIndex}"
|
||||
onchange="{DeleteExtraBuffAt}" tooltip="Click a row to remove it." />
|
||||
<button x="4" y="138" w="120" h="18" text="Add..." onclick="{ShowExtraBuffPicker}" />
|
||||
|
||||
<!-- Fix round B item 14: same honesty note as Extra Buff Spells — not
|
||||
yet read by BuffPlan.Build. -->
|
||||
<label x="524" y="0" w="320" h="16" text="Blacklisted Buff Families" color="#FFE8DEC3"
|
||||
tooltip="Named buff families never cast, even if otherwise wanted." />
|
||||
tooltip="Named buff families — stored and shown here, not yet used when choosing what to cast." />
|
||||
<list x="524" y="18" w="320" h="116" rowheight="17"
|
||||
items="{BlacklistedBuffFamilyRows}" selected="{SelectedBlacklistedBuffIndex}"
|
||||
onchange="{DeleteBlacklistedBuffFamilyAt}" tooltip="Click a row to remove it." />
|
||||
|
|
|
|||
|
|
@ -1030,6 +1030,39 @@ public sealed class MossTankPanelTests
|
|||
Assert.Equal(callsAfterAdd, automation.CaptureOwnedItemsCallCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtraBuffAndBlacklistedFamilyNamesPersistAcrossSessions()
|
||||
{
|
||||
// Fix round B item 14: these two Buffs-tab sets were never captured
|
||||
// by LegacyBuffProfileDocument, so a restart or profile switch
|
||||
// silently dropped them — a real display/storage honesty bug
|
||||
// (BuffPlan.Build still doesn't READ either set for casting, a
|
||||
// separately tracked wiring gap; this only fixes storage).
|
||||
var storage = new MemoryStorage();
|
||||
var automation = new FakeAutomation
|
||||
{
|
||||
Name = "Persist Check",
|
||||
KnownSelfBuffs =
|
||||
[
|
||||
Spell(1, 10, "Increases the caster's Strength by 10 points."),
|
||||
Spell(2, 20, "Increases the caster's Focus by 10 points."),
|
||||
],
|
||||
};
|
||||
var first = new MossTankPanel(new FakeHost(automation, storage));
|
||||
first.ShowExtraBuffPicker();
|
||||
first.PickBuffAt(0); // "Spell 1"
|
||||
first.ShowBlacklistedBuffPicker();
|
||||
first.PickBuffAt(1); // "Spell 2"
|
||||
Assert.Equal(["Spell 1"], first.ExtraBuffRows);
|
||||
Assert.Equal(["Spell 2"], first.BlacklistedBuffFamilyRows);
|
||||
|
||||
var second = new MossTankPanel(new FakeHost(
|
||||
new FakeAutomation { Name = "Persist Check" }, storage));
|
||||
|
||||
Assert.Equal(["Spell 1"], second.ExtraBuffRows);
|
||||
Assert.Equal(["Spell 2"], second.BlacklistedBuffFamilyRows);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuffPickerAddsToTheRequestedListAndAnyCellClickDeletes()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue