adventure: worn magic items bond when a slot frees, and can be taken off

An attunement item equipped while at the 3-bond cap sat permanently inert:
nothing re-bonded it when a slot opened, and the equip picker only lists
inventory, so a slotted item could never be reached again.

- reconcileMagicAttunements bonds worn-but-inert items whenever bond
  capacity is free (bonding is strictly beneficial; inert should only
  exist at the cap). Runs on equip-magic open and after any swap.
- New !adventure unequip-magic picker takes a worn item off and returns
  it to inventory at full value, freeing its bond slot (which then heals
  any straggler). Destructive-op-first ordering mirrors the equip path.
This commit is contained in:
prosolis
2026-07-15 22:41:01 -07:00
parent c9282cb18a
commit 27c2b48007
3 changed files with 311 additions and 3 deletions

View File

@@ -533,6 +533,8 @@ func (p *AdventurePlugin) dispatchCommand(ctx MessageContext) error {
return p.handleEquipCmd(ctx)
case lower == "equip-magic" || lower == "equipmagic" || lower == "equip magic":
return p.handleEquipMagicCmd(ctx)
case lower == "unequip-magic" || lower == "unequipmagic" || lower == "unequip magic":
return p.handleUnequipMagicCmd(ctx)
case lower == "inventory" || lower == "inv":
return p.handleInventoryCmd(ctx)
case lower == "leaderboard" || lower == "lb":
@@ -594,6 +596,7 @@ const advHelpText = `**Adventure Commands**
` + "`!adventure buy <item>`" + ` — Buy equipment (e.g. ` + "`buy Enchanted Blade`" + ` or ` + "`buy 4 sword`" + `)
` + "`!adventure equip`" + ` — Equip Masterwork gear from inventory
` + "`!adventure equip-magic`" + ` — Equip magic items (curios) into your D&D slots
` + "`!adventure unequip-magic`" + ` — Take a worn magic item off and return it to inventory
` + "`!adventure sell <item>`" + ` — Sell an inventory item (or ` + "`sell all`" + `)
` + "`!adventure inventory`" + ` — View your inventory
` + "`!adventure vault`" + ` — Store items safely (Tier-4 Established home; ` + "`vault store/take <item>`" + `)
@@ -940,6 +943,8 @@ func (p *AdventurePlugin) resolvePendingInteraction(ctx MessageContext, interact
return p.handleMasterworkEquipReply(ctx, interaction)
case "magic_equip":
return p.resolveMagicEquipReply(ctx, interaction)
case "magic_unequip":
return p.resolveMagicUnequipReply(ctx, interaction)
case "masterwork_equip_confirm":
return p.handleMasterworkEquipConfirm(ctx, interaction)
case "rival_rps":