fix(movement): invalidate burden on enchantment changes
This commit is contained in:
parent
2b9dfec9d7
commit
d6e8b60303
13 changed files with 231 additions and 25 deletions
|
|
@ -89,6 +89,25 @@ public sealed class IndicatorBarControllerTests
|
|||
Assert.Equal(expectedState, button.ActiveRetailStateId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnchantmentChange_ReevaluatesBurdenFromEffectiveStrength()
|
||||
{
|
||||
var h = CreateHarness(strength: 10);
|
||||
using IndicatorBarController controller = h.Controller;
|
||||
h.Objects.UpdateIntProperty(Player, 5u, 1600);
|
||||
UiButton button = h.Button(IndicatorBarController.BurdenButtonId);
|
||||
Assert.Equal(IndicatorBarController.EncumberedState, button.ActiveRetailStateId);
|
||||
|
||||
h.Strength = 20;
|
||||
h.Spellbook.OnEnchantmentAdded(new ActiveEnchantmentRecord(
|
||||
42u, 1u, 60d, Player, Bucket: 1u));
|
||||
Assert.Equal(IndicatorBarController.UnencumberedState, button.ActiveRetailStateId);
|
||||
|
||||
h.Strength = 10;
|
||||
h.Spellbook.OnPurgeAll();
|
||||
Assert.Equal(IndicatorBarController.EncumberedState, button.ActiveRetailStateId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Burden_ClickOpensCharacterInformationPanel()
|
||||
{
|
||||
|
|
@ -205,7 +224,7 @@ public sealed class IndicatorBarControllerTests
|
|||
spellbook,
|
||||
objects,
|
||||
() => Player,
|
||||
() => strength,
|
||||
() => harness.Strength,
|
||||
() => harness.LinkStatus,
|
||||
() => harness.Time,
|
||||
harness.ToggledPanels.Add,
|
||||
|
|
@ -222,7 +241,7 @@ public sealed class IndicatorBarControllerTests
|
|||
public ImportedLayout Layout { get; } = layout;
|
||||
public Spellbook Spellbook { get; } = spellbook;
|
||||
public ClientObjectTable Objects { get; } = objects;
|
||||
public int Strength { get; } = strength;
|
||||
public int Strength { get; set; } = strength;
|
||||
public List<uint> ToggledPanels { get; } = [];
|
||||
public double Time { get; set; }
|
||||
public LinkStatusSnapshot LinkStatus { get; set; } = new(true, 0d);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using AcDream.App.UI;
|
|||
using AcDream.App.UI.Layout;
|
||||
using AcDream.Core.Items;
|
||||
using AcDream.Core.Selection;
|
||||
using AcDream.Core.Spells;
|
||||
using Xunit;
|
||||
|
||||
namespace AcDream.App.Tests.UI.Layout;
|
||||
|
|
@ -63,10 +64,12 @@ public class InventoryControllerTests
|
|||
Action? onClose = null,
|
||||
SelectionState? selection = null,
|
||||
StackSplitQuantityState? stackSplitQuantity = null,
|
||||
ItemInteractionController? itemInteraction = null)
|
||||
ItemInteractionController? itemInteraction = null,
|
||||
Func<int?>? strengthProvider = null,
|
||||
Spellbook? burdenSpellbook = null)
|
||||
=> InventoryController.Bind(layout, objects, () => Player,
|
||||
iconIds: (_, _, _, _, _) => 0u,
|
||||
strength: () => strength, datFont: null,
|
||||
strength: strengthProvider ?? (() => strength), datFont: null,
|
||||
ownerName: ownerName is null ? null : () => ownerName,
|
||||
sendUse: uses is null ? null : g => uses.Add(g),
|
||||
sendPutItemInContainer: puts is null ? null : (i, c, p) => puts.Add((i, c, p)),
|
||||
|
|
@ -78,7 +81,8 @@ public class InventoryControllerTests
|
|||
onClose: onClose,
|
||||
selection: selection ?? new SelectionState(),
|
||||
stackSplitQuantity: stackSplitQuantity,
|
||||
itemInteraction: itemInteraction);
|
||||
itemInteraction: itemInteraction,
|
||||
burdenSpellbook: burdenSpellbook);
|
||||
|
||||
private static UiButton MakeButton(uint id)
|
||||
{
|
||||
|
|
@ -238,6 +242,37 @@ public class InventoryControllerTests
|
|||
Assert.Contains("50%", CaptionText(burdenText));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnchantmentChange_RefreshesBurdenFromEffectiveStrength()
|
||||
{
|
||||
var (layout, _, _, _, meter, burdenText, _, _) = BuildLayout();
|
||||
var objects = new ClientObjectTable();
|
||||
var props = new PropertyBundle();
|
||||
props.Ints[5] = 1600;
|
||||
objects.UpsertProperties(Player, props);
|
||||
int effectiveStrength = 10;
|
||||
var spellbook = new Spellbook();
|
||||
using InventoryController controller = Bind(
|
||||
layout,
|
||||
objects,
|
||||
strengthProvider: () => effectiveStrength,
|
||||
burdenSpellbook: spellbook);
|
||||
|
||||
Assert.Equal(1600f / 1500f / 3f, meter.Fill() ?? -1f, 3);
|
||||
Assert.Contains("106%", CaptionText(burdenText));
|
||||
|
||||
effectiveStrength = 20;
|
||||
spellbook.OnEnchantmentAdded(new ActiveEnchantmentRecord(
|
||||
42u, 1u, 60d, Player, Bucket: 1u));
|
||||
Assert.Equal(1600f / 3000f / 3f, meter.Fill() ?? -1f, 3);
|
||||
Assert.Contains("53%", CaptionText(burdenText));
|
||||
|
||||
effectiveStrength = 10;
|
||||
spellbook.OnPurgeAll();
|
||||
Assert.Equal(1600f / 1500f / 3f, meter.Fill() ?? -1f, 3);
|
||||
Assert.Contains("106%", CaptionText(burdenText));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Captions_render_known_strings()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -233,6 +233,74 @@ public sealed class LiveSessionEventRouterTests
|
|||
router.Dispose();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StrengthEnchantmentChange_RecomputesBurdenWithoutBaseAttributeUpdate()
|
||||
{
|
||||
using var session = NewSession();
|
||||
const uint playerGuid = 0x50000001u;
|
||||
var objects = new ClientObjectTable();
|
||||
var character = new RuntimeCharacterState();
|
||||
character.InstallSpellMetadata(SpellTable.LoadFromReader(new StringReader(
|
||||
"Spell ID,Name,Flags [Hex]\n42,Strength Test,0x4\n")));
|
||||
int movementStatsUpdated = 0;
|
||||
|
||||
var router = new LiveSessionEventRouter(
|
||||
session,
|
||||
NoOpEntitySink(),
|
||||
NoOpEnvironmentSink(),
|
||||
new LiveInventorySessionBindings(
|
||||
objects,
|
||||
PlayerGuid: () => playerGuid,
|
||||
OnShortcuts: null,
|
||||
OnUseDone: null,
|
||||
ItemMana: new ItemManaState(),
|
||||
ExternalContainers: new ExternalContainerState()),
|
||||
new LiveCharacterSessionBindings(
|
||||
new CombatState(),
|
||||
character,
|
||||
ResolveSkillFormulaBonus: null,
|
||||
OnSkillsUpdated: null,
|
||||
OnConfirmationRequest: null,
|
||||
OnConfirmationDone: null,
|
||||
ClientTime: () => 0d,
|
||||
OnMovementStatsUpdated: () => movementStatsUpdated++),
|
||||
NewSocialBindings());
|
||||
|
||||
router.Attach();
|
||||
character.LocalPlayer.OnAttributeUpdate(
|
||||
atType: 1u, ranks: 90u, start: 10u, xp: 0u);
|
||||
var props = new PropertyBundle();
|
||||
props.Ints[(uint)PropertyInt.EncumbranceVal] = 16500;
|
||||
objects.UpsertProperties(playerGuid, props);
|
||||
Assert.Equal(1.1f, character.MovementSkills.Burden, precision: 4);
|
||||
|
||||
int beforeBuff = movementStatsUpdated;
|
||||
character.Spellbook.OnEnchantmentAdded(new ActiveEnchantmentRecord(
|
||||
SpellId: 42u,
|
||||
LayerId: 1u,
|
||||
Duration: 60d,
|
||||
CasterGuid: playerGuid,
|
||||
StatModType: (uint)EnchantmentMath.EnchantmentTypeFlag.Attribute,
|
||||
StatModKey: 1u,
|
||||
StatModValue: 1.2f,
|
||||
Bucket: 1u));
|
||||
|
||||
Assert.Equal(120, character.LocalPlayer.GetEffectiveAttribute(
|
||||
LocalPlayerState.AttributeKind.Strength));
|
||||
Assert.Equal(16500f / 18000f, character.MovementSkills.Burden, precision: 4);
|
||||
Assert.Equal(beforeBuff + 1, movementStatsUpdated);
|
||||
|
||||
int beforePurge = movementStatsUpdated;
|
||||
character.Spellbook.OnPurgeAll();
|
||||
|
||||
Assert.Equal(100, character.LocalPlayer.GetEffectiveAttribute(
|
||||
LocalPlayerState.AttributeKind.Strength));
|
||||
Assert.Equal(1.1f, character.MovementSkills.Burden, precision: 4);
|
||||
Assert.Equal(beforePurge + 1, movementStatsUpdated);
|
||||
|
||||
router.Dispose();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ObjectTablePropertyChange_RecomputesMovementSkillAugmentations()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue