fix(interaction): restore retail loot placement and world-drop projection
This commit is contained in:
parent
4d095be286
commit
921712f412
24 changed files with 1581 additions and 34 deletions
|
|
@ -46,6 +46,49 @@ public sealed class ClientObjectTableTests
|
|||
Assert.Equal(1, propUpdateCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsOwnedByObjectMatchesRetailDirectPackAndLocationRules()
|
||||
{
|
||||
const uint player = 0x5000_0001u;
|
||||
const uint pack = 0x4000_0001u;
|
||||
var repo = new ClientObjectTable();
|
||||
repo.AddOrUpdate(MakeItem(player, "Player"));
|
||||
repo.AddOrUpdate(new ClientObject
|
||||
{
|
||||
ObjectId = pack,
|
||||
Name = "Pack",
|
||||
Type = ItemType.Container,
|
||||
ContainerId = player,
|
||||
});
|
||||
repo.ReplaceContents(
|
||||
player,
|
||||
[new ContainerContentEntry(pack, ContainerType: 1u)]);
|
||||
|
||||
ClientObject loose = MakeItem(100u, "Loose");
|
||||
loose.ContainerId = player;
|
||||
repo.AddOrUpdate(loose);
|
||||
|
||||
ClientObject packed = MakeItem(101u, "Packed");
|
||||
packed.ContainerId = pack;
|
||||
repo.AddOrUpdate(packed);
|
||||
|
||||
ClientObject equipped = MakeItem(102u, "Equipped");
|
||||
equipped.WielderId = player;
|
||||
equipped.CurrentlyEquippedLocation = EquipMask.MeleeWeapon;
|
||||
repo.AddOrUpdate(equipped);
|
||||
|
||||
ClientObject foreign = MakeItem(103u, "Foreign");
|
||||
foreign.ContainerId = 0x6000_0001u;
|
||||
repo.AddOrUpdate(foreign);
|
||||
|
||||
Assert.True(repo.IsOwnedByObject(player, player));
|
||||
Assert.True(repo.IsOwnedByObject(loose.ObjectId, player));
|
||||
Assert.True(repo.IsOwnedByObject(packed.ObjectId, player));
|
||||
Assert.True(repo.IsOwnedByObject(equipped.ObjectId, player));
|
||||
Assert.False(repo.IsOwnedByObject(foreign.ObjectId, player));
|
||||
Assert.False(repo.IsOwnedByObject(packed.ObjectId, 0u));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StopViewingContents_RemovesOnlyTemporaryProjection()
|
||||
{
|
||||
|
|
@ -673,6 +716,96 @@ public sealed class ClientObjectTableTests
|
|||
Assert.Equal(new[] { item }, table.GetContents(pack));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AuthoritativePickup_PlacementZeroInsertsAtRetailListHead()
|
||||
{
|
||||
var table = new ClientObjectTable();
|
||||
const uint corpse = 0x40000001u;
|
||||
const uint pack = 0x50000001u;
|
||||
const uint existingA = 0xA01u;
|
||||
const uint existingB = 0xA02u;
|
||||
const uint firstLoot = 0xA03u;
|
||||
const uint secondLoot = 0xA04u;
|
||||
|
||||
table.InitializeInventoryManifest(pack, new[]
|
||||
{
|
||||
new ContainerContentEntry(existingA, 0u),
|
||||
new ContainerContentEntry(existingB, 0u),
|
||||
});
|
||||
table.ReplaceContents(corpse, new[] { firstLoot, secondLoot });
|
||||
|
||||
Assert.True(table.ApplyConfirmedServerMove(
|
||||
firstLoot,
|
||||
pack,
|
||||
newWielderId: 0u,
|
||||
newSlot: 0,
|
||||
containerTypeHint: 0u));
|
||||
Assert.Equal(
|
||||
new[] { firstLoot, existingA, existingB },
|
||||
table.GetContents(pack));
|
||||
Assert.Equal(
|
||||
new[] { 0, 1, 2 },
|
||||
table.GetContents(pack).Select(id => table.Get(id)!.ContainerSlot));
|
||||
|
||||
Assert.True(table.ApplyConfirmedServerMove(
|
||||
secondLoot,
|
||||
pack,
|
||||
newWielderId: 0u,
|
||||
newSlot: 0,
|
||||
containerTypeHint: 0u));
|
||||
Assert.Equal(
|
||||
new[] { secondLoot, firstLoot, existingA, existingB },
|
||||
table.GetContents(pack));
|
||||
Assert.Equal(
|
||||
new[] { 0, 1, 2, 3 },
|
||||
table.GetContents(pack).Select(id => table.Get(id)!.ContainerSlot));
|
||||
Assert.Empty(table.GetContents(corpse));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AuthoritativeContainerMove_IndexesOnlyTheRetailContainerList()
|
||||
{
|
||||
var table = new ClientObjectTable();
|
||||
const uint pack = 0x50000001u;
|
||||
const uint looseA = 0xA11u;
|
||||
const uint looseB = 0xA12u;
|
||||
const uint bagA = 0xA21u;
|
||||
const uint bagB = 0xA22u;
|
||||
|
||||
table.InitializeInventoryManifest(pack, new[]
|
||||
{
|
||||
new ContainerContentEntry(looseA, 0u),
|
||||
new ContainerContentEntry(bagA, 1u),
|
||||
new ContainerContentEntry(looseB, 0u),
|
||||
});
|
||||
table.AddOrUpdate(new ClientObject
|
||||
{
|
||||
ObjectId = bagB,
|
||||
Type = ItemType.Container,
|
||||
ItemsCapacity = 24,
|
||||
});
|
||||
|
||||
Assert.True(table.ApplyConfirmedServerMove(
|
||||
bagB,
|
||||
pack,
|
||||
newWielderId: 0u,
|
||||
newSlot: 0,
|
||||
containerTypeHint: 1u));
|
||||
|
||||
uint[] loose = table.GetContents(pack)
|
||||
.Where(id => table.Get(id)!.ContainerTypeHint == 0u
|
||||
&& (table.Get(id)!.Type & ItemType.Container) == 0)
|
||||
.ToArray();
|
||||
uint[] bags = table.GetContents(pack)
|
||||
.Where(id => table.Get(id)!.ContainerTypeHint != 0u
|
||||
|| (table.Get(id)!.Type & ItemType.Container) != 0)
|
||||
.ToArray();
|
||||
Assert.Equal(new[] { looseA, looseB }, loose);
|
||||
Assert.Equal(new[] { bagB, bagA }, bags);
|
||||
Assert.Equal(0, table.Get(bagB)!.ContainerSlot);
|
||||
Assert.Equal(1, table.Get(bagA)!.ContainerSlot);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProjectionEvictionNotification_ReentrantMoveSeesCommittedState()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue