fix(paperdoll): port quest-gated Aetheria slots
Add the three authored blue, yellow, and red sigil backgrounds and drive their visibility from player PropertyInt.AetheriaBitfield bits 1/2/4 at login and on live updates, matching gmPaperDollUI::UpdateAetheria. Include the sigil equip masks in the shared slot table and narrow AP-108. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
1be18cc4db
commit
edc9be3008
11 changed files with 208 additions and 16 deletions
|
|
@ -17,12 +17,19 @@ public class PaperdollControllerTests
|
|||
private const uint ShieldSlot = 0x100001E1u; // Shield 0x200000
|
||||
private const uint WeaponSlot = 0x100001DFu; // composite 0x3500000
|
||||
private const uint FingerLSlot= 0x100001DCu; // FingerWearLeft 0x40000
|
||||
private const uint BlueAetheriaSlot = 0x10000595u;
|
||||
private const uint YellowAetheriaSlot = 0x10000596u;
|
||||
private const uint RedAetheriaSlot = 0x10000597u;
|
||||
|
||||
private sealed class RootElement : UiElement { }
|
||||
|
||||
private static (ImportedLayout layout, Dictionary<uint, UiItemList> lists) BuildLayout()
|
||||
{
|
||||
var ids = new[] { HeadSlot, ChestSlot, ChestArmorSlot, ShieldSlot, WeaponSlot, FingerLSlot };
|
||||
var ids = new[]
|
||||
{
|
||||
HeadSlot, ChestSlot, ChestArmorSlot, ShieldSlot, WeaponSlot, FingerLSlot,
|
||||
BlueAetheriaSlot, YellowAetheriaSlot, RedAetheriaSlot,
|
||||
};
|
||||
var lists = new Dictionary<uint, UiItemList>();
|
||||
var byId = new Dictionary<uint, UiElement>();
|
||||
var root = new RootElement { Width = 224, Height = 214 };
|
||||
|
|
@ -241,6 +248,72 @@ public class PaperdollControllerTests
|
|||
Assert.Equal(sprite, lists[element].Cell.EmptySprite);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Aetheria_slots_default_hidden_without_unlock_property()
|
||||
{
|
||||
var (layout, lists) = BuildLayout();
|
||||
|
||||
Bind(layout, new ClientObjectTable());
|
||||
|
||||
Assert.False(lists[BlueAetheriaSlot].Visible);
|
||||
Assert.False(lists[YellowAetheriaSlot].Visible);
|
||||
Assert.False(lists[RedAetheriaSlot].Visible);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Aetheria_slots_follow_independent_player_unlock_bits_at_login()
|
||||
{
|
||||
var (layout, lists) = BuildLayout();
|
||||
var objects = new ClientObjectTable();
|
||||
objects.AddOrUpdate(new ClientObject { ObjectId = Player });
|
||||
objects.UpdateIntProperty(
|
||||
Player,
|
||||
AetheriaUnlocks.PropertyId,
|
||||
(int)(AetheriaUnlockState.Blue | AetheriaUnlockState.Red));
|
||||
|
||||
Bind(layout, objects);
|
||||
|
||||
Assert.True(lists[BlueAetheriaSlot].Visible);
|
||||
Assert.False(lists[YellowAetheriaSlot].Visible);
|
||||
Assert.True(lists[RedAetheriaSlot].Visible);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Live_aetheria_property_update_unlocks_new_slots()
|
||||
{
|
||||
var (layout, lists) = BuildLayout();
|
||||
var objects = new ClientObjectTable();
|
||||
objects.AddOrUpdate(new ClientObject { ObjectId = Player });
|
||||
Bind(layout, objects);
|
||||
|
||||
objects.UpdateIntProperty(
|
||||
Player,
|
||||
AetheriaUnlocks.PropertyId,
|
||||
(int)(AetheriaUnlockState.Blue | AetheriaUnlockState.Yellow));
|
||||
|
||||
Assert.True(lists[BlueAetheriaSlot].Visible);
|
||||
Assert.True(lists[YellowAetheriaSlot].Visible);
|
||||
Assert.False(lists[RedAetheriaSlot].Visible);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Unlocked_aetheria_slot_populates_its_equipped_sigil()
|
||||
{
|
||||
var (layout, lists) = BuildLayout();
|
||||
var objects = new ClientObjectTable();
|
||||
objects.AddOrUpdate(new ClientObject { ObjectId = Player });
|
||||
objects.UpdateIntProperty(
|
||||
Player,
|
||||
AetheriaUnlocks.PropertyId,
|
||||
(int)AetheriaUnlockState.Blue);
|
||||
SeedEquipped(objects, 0xA37u, EquipMask.SigilOne);
|
||||
|
||||
Bind(layout, objects);
|
||||
|
||||
Assert.True(lists[BlueAetheriaSlot].Visible);
|
||||
Assert.Equal(0xA37u, lists[BlueAetheriaSlot].Cell.ItemId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Live_player_wield_repaints_the_slot() // event-driven: ObjectMoved → Concerns → Populate
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ public class PaperdollSlotBackgroundTests
|
|||
{ 0x100001E3u, 0x1000044Fu }, // pants
|
||||
{ 0x1000058Eu, 0x1000058Fu }, // trinket
|
||||
{ 0x100005E9u, 0x100005EAu }, // cloak
|
||||
{ 0x10000595u, 0x10000592u }, // blue Aetheria
|
||||
{ 0x10000596u, 0x10000593u }, // yellow Aetheria
|
||||
{ 0x10000597u, 0x10000594u }, // red Aetheria
|
||||
{ 0x100005ABu, 0x100005B4u }, // head
|
||||
{ 0x100005ACu, 0x100005B5u }, // chest armor
|
||||
{ 0x100005ADu, 0x100005B6u }, // abdomen armor
|
||||
|
|
@ -67,6 +70,9 @@ public class PaperdollSlotBackgroundTests
|
|||
[0x100001E3u] = 0x060032C4u,
|
||||
[0x1000058Eu] = 0x06006A6Cu,
|
||||
[0x100005E9u] = 0x0600708Fu,
|
||||
[0x10000595u] = 0x06006BEFu,
|
||||
[0x10000596u] = 0x06006BF0u,
|
||||
[0x10000597u] = 0x06006BF1u,
|
||||
[0x100005ABu] = 0x06006D7Fu,
|
||||
[0x100005ACu] = 0x06006D7Bu,
|
||||
[0x100005ADu] = 0x06006D79u,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue