fix(ui): unify target-mode primary clicks

This commit is contained in:
Erik 2026-07-11 01:36:43 +02:00
parent b7e7ca9ee2
commit eb6229394a
12 changed files with 176 additions and 25 deletions

View file

@ -84,6 +84,32 @@ public sealed class ItemInteractionControllerTests
Assert.Empty(h.UseWithTarget);
}
[Fact]
public void PrimaryClickRouter_distinguishesInactiveSuccessAndConsumedRejection()
{
var h = new Harness();
h.AddContained(0x50000A01u, item =>
{
item.Useability = HealthKitUseability;
item.TargetType = (uint)ItemType.Creature;
});
h.AddContained(0x50000A02u, item => item.Type = ItemType.Armor);
Assert.Equal(ItemPrimaryClickResult.NotActive,
h.Controller.OfferPrimaryClick(Player));
h.Controller.ActivateItem(0x50000A01u);
Assert.Equal(ItemPrimaryClickResult.ConsumedRejected,
h.Controller.OfferPrimaryClick(0x50000A02u));
Assert.False(h.Controller.IsTargetModeActive);
h.Now += 200;
h.Controller.ActivateItem(0x50000A01u);
Assert.Equal(ItemPrimaryClickResult.ConsumedSuccess,
h.Controller.OfferSelfPrimaryClick());
Assert.Equal(new[] { (0x50000A01u, Player) }, h.UseWithTarget);
}
[Fact]
public void SelfTarget_sendsUseWithTargetAndClearsTargetMode()
{

View file

@ -163,7 +163,7 @@ public sealed class RetailUiInteractionFlowTests
return interaction;
}
public void BindPaperdoll()
public void BindPaperdoll(ItemInteractionController? itemInteraction = null)
=> PaperdollController.Bind(
Layout,
Objects,
@ -171,7 +171,8 @@ public sealed class RetailUiInteractionFlowTests
iconIds: static (_, _, _, _, _) => 0x1234u,
selection: Selection,
sendWield: (item, mask) => Wields.Add((item, mask)),
emptySlotSprite: 0x06004D20u);
emptySlotSprite: 0x06004D20u,
itemInteraction: itemInteraction);
public RetailUiAutomationProbe Probe()
=> new(Root, Objects);
@ -259,6 +260,44 @@ public sealed class RetailUiInteractionFlowTests
Assert.False(interaction.IsTargetModeActive);
}
[Fact]
public void InventoryTargetUse_invalidInventoryItem_isConsumedWithoutSelectionFallback()
{
var h = new Harness();
h.SeedHealthKit(slot: 0);
h.SeedHauberk(slot: 1);
var interaction = h.BindInventoryInteraction();
var probe = h.Probe();
Assert.True(probe.DoubleClickItem(HealthKit, ItemDragSource.Inventory));
Assert.True(probe.DoubleClickItem(Hauberk, ItemDragSource.Inventory));
Assert.Empty(h.UseWithTarget);
Assert.Empty(h.Wields);
Assert.False(interaction.IsTargetModeActive);
Assert.Equal(HealthKit, h.Selection.SelectedObjectId);
}
[Fact]
public void InventoryTargetUse_invalidWornItem_isConsumedWithoutPaperdollSelectionFallback()
{
var h = new Harness();
h.SeedHealthKit(slot: 0);
h.SeedHauberk(slot: 1);
h.Objects.MoveItem(Hauberk, Player, -1, HauberkMask);
var interaction = h.BindInventoryInteraction();
h.BindPaperdoll(interaction);
var probe = h.Probe();
Assert.True(probe.DoubleClickItem(HealthKit, ItemDragSource.Inventory));
Assert.True(probe.ClickElement(SlotsButtonId));
Assert.True(probe.ClickItem(Hauberk, ItemDragSource.Equipment));
Assert.Empty(h.UseWithTarget);
Assert.False(interaction.IsTargetModeActive);
Assert.Equal(HealthKit, h.Selection.SelectedObjectId);
}
[Fact]
public void InventoryDragOutsideUi_routesThroughRootOutsideHookAndDropsToWorld()
{