Equipment layers + paperdoll UI (IEquippable, worn-gump layering) #106
Labels
No labels
alpha:wave-0
alpha:wave-1
alpha:wave-2
alpha:wave-3
area:assets
area:combat
area:ecology
area:infra
area:render
area:scripting
area:ui
area:world
enhancement
epic
migration
post-alpha
roadmap
tech-debt
type:bug
type:chore
type:design
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
marco/IsoMmo#106
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Full worn-gump layering paperdoll + a proper equipment model. Supersedes the UO-gump direction of #39/#19 (we go own extraction from UOML for the paperdoll wardrobe). Being built on
feat/paperdoll-ui.Goal (player POV)
Open the paperdoll (Ctrl+P): your character (M/F body) with worn equipment drawn on it — sword in hand, armor on the torso. Double-click a wearable (backpack OR ground <=1 tile) to equip; double-click a worn item to take it off. Equipping auto-replaces conflicting gear (old piece back to the backpack). All server-validated.
Equipment model (server, ModernUO-informed)
enum EquipLayer { OneHanded, TwoHanded, Torso }(extensible) — replacesEquipSlot { Weapon, Armor }.interface IEquippable { EquipLayer Layer; void OnEquip(Mobile wearer); void OnUnequip(Mobile wearer); }on the item definition (Sword/Armorimplement;Coin/Stonedon't ->CannotEquip).EquipConflicts), replace-on-equip: equipping a layer clears itself + conflicting layers; freed items return to backpack. OneHanded<->TwoHanded mutually exclusive; Torso independent (2x2h / 2h+1h impossible by construction).OnEquip/OnUnequip= effect hooks (per-type reaction; the system orchestrates conflicts, not the item). v1: weaponOnEquiptriggers the existingApplyEquippedWeapon. Future: "sword +20 STR" as an override. Effects are derived & re-applied at restore, never persisted baked;OnUnequipMUST run on every removal path (swap/unequip/restore) or stats leak. Future gate:CanEquip(Mobile)(str requirements, with #8).EquipmentSystemcomponent;Worldstays a thin facade.Equip flow + validation (server-authoritative)
Equip(ItemId)(exists). Client never picks slot/source.InteractionRange(1 tile) + equippable -> atomic pickup+equip; ground too far ->OutOfRange; not equippable ->CannotEquip(DONE). Range checked server-side only.Persistence + protocol
EquipSlot->EquipLayer: bump the item's serialization version + branch in itsDeserialize.OwnedItem.Slotcarries the layer name on the wire.ProtocolVersionbump (already 2 viaCannotEquip).Paperdoll rendering (client)
gump/paperdoll(0x07D0); its dragon region is the character window (like the empty area of a standard UO paperdoll) -> we draw the PG there.body_male 0x000C/body_female 0x000D), then worn overlays in layer order (all 260x237 same canvas -> align by stacking).0xC5C8(F0xECD8), torso armor0xC721(F0xEE31). Female = male + 10000 pergump.def.PaperdollArtcatalogKind -> (wornGump, layer)(gumps are presentation, no protocol). Double-click worn ->Unequip. Fallback plain panel if pack absent.Interaction
DoubleClickDetector(Client.Core, DONE) runs on the backpack panel + world ground sprites. No drag-to-equip in v1.Art pipeline (config-driven)
Program.csinto a data file read by the extractor: adding a gump = a data row +just pack, zero recompile.paperdoll 0x07D0,body_male 0x000C,body_female 0x000D,sword 0xC5C8(+F),armor 0xC721(+F).Namespaces (folded-in refactor)
Namespaces as logical domains crossing the Core/Client assemblies (boundary enforced by project refs, not namespaces):
IsoMmo.Client.UI(layouts + panels),IsoMmo.Client.Gumps(ItemArt/PaperdollArt),IsoMmo.Client.Iso, etc.Already done (
feat/paperdoll-ui)CannotEquip+ integration test (green).DoubleClickDetector+PaperdollLayout(Client.Core, tested). Extracted+committed pack: frame, M/F bodies, worn sword, worn armor.Definition of Done
just pack(no code change).dotnet testgreen (new layout/equip tests);ProtocolVersionbumped.Deferred
Multi-piece wardrobe beyond current items; stat-mod system via
OnEquip;CanEquiprequirements (with #8 M6); richer worn art from a stock UO gumpart.mul (this UOML pack's wardrobe is thin) or own-art.Landed via #116: composable client gump framework + draggable paperdoll (body + worn gumps, double-click equip/unequip), the EquipLayer/IEquippable model with conflict resolution (2H displaces 1H) + OnEquip/OnUnequip hooks (weapon arms the wearer), Greatsword (2H), CannotEquip cue, config-driven gump manifest, item save v2. Green: 170 GameServer + 65 Client.Core tests, 0 warnings.
Remaining follow-ups (keeping this open):
Done — delivered by PR #116: server model (`IEquippable`/`EquipLayer`/`EquipConflicts`, `OnEquip/OnUnequip`) and client `PaperdollGump` (body + worn-gump layering by convention, double-click to unequip, draggable, right-click close). Showing worn gear on other players' in-world sprites is tracked separately by #18. Closing.