aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_wear.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/cmd_wear.go')
-rw-r--r--internal/game/cmd_wear.go106
1 files changed, 97 insertions, 9 deletions
diff --git a/internal/game/cmd_wear.go b/internal/game/cmd_wear.go
index 8910e75..ddc970b 100644
--- a/internal/game/cmd_wear.go
+++ b/internal/game/cmd_wear.go
@@ -25,9 +25,11 @@ func (g *Game) doWear(sess *net.Session, input string) {
g.CancelAction(p)
- matches := g.findInventoryMatches(input, p)
+ qty, itemName := parseQty(input)
+
+ matches := g.findInventoryMatches(itemName, p)
if len(matches) == 0 {
- sess.WriteLine(fmt.Sprintf("You don't have any '%s'.", input))
+ sess.WriteLine(fmt.Sprintf("You don't have any '%s'.", itemName))
return
}
@@ -52,6 +54,11 @@ func (g *Game) doWear(sess *net.Session, input string) {
return
}
+ if def.EquipSlot == object.SlotAmmo && def.Stackable {
+ g.equipAmmo(sess, p, match.Slot, slot, def, qty)
+ return
+ }
+
existingItemID, slotOccupied := p.Equipment[def.EquipSlot]
if slotOccupied {
@@ -88,13 +95,64 @@ func (g *Game) doWear(sess *net.Session, input string) {
sess.WriteLine(fmt.Sprintf("You %s %s.", verb, g.itemColorize(sess, def, match.Name)))
}
+func (g *Game) equipAmmo(sess *net.Session, p *player.Player, invIdx int, slot *player.InventorySlot, def *object.ItemDef, qty int) {
+ transferQty := slot.Quantity
+ if qty > 0 && qty < transferQty {
+ transferQty = qty
+ }
+
+ existingAmmoID, hasAmmo := p.Equipment[object.SlotAmmo]
+ if hasAmmo && existingAmmoID != slot.ItemID {
+ g.unequipAmmo(p)
+ }
+
+ if slot.Quantity <= transferQty {
+ p.SetInvSlot(invIdx, nil)
+ } else {
+ slot.Quantity -= transferQty
+ }
+
+ if hasAmmo && existingAmmoID == slot.ItemID {
+ p.AmmoQty += transferQty
+ } else {
+ p.Equipment[object.SlotAmmo] = slot.ItemID
+ p.AmmoQty = transferQty
+ }
+
+ g.AccountStore.SaveCharacter(p)
+ displayName := g.itemColorize(sess, def, def.Name)
+ sess.WriteLine(fmt.Sprintf("You equip %s (x%d).", displayName, p.AmmoQty))
+}
+
+func (g *Game) unequipAmmo(p *player.Player) {
+ ammoID, ok := p.Equipment[object.SlotAmmo]
+ if !ok || p.AmmoQty <= 0 {
+ return
+ }
+ for i := 0; i < 28; i++ {
+ s := p.InvSlot(i)
+ if s != nil && s.ItemID == ammoID {
+ s.Quantity += p.AmmoQty
+ delete(p.Equipment, object.SlotAmmo)
+ p.AmmoQty = 0
+ return
+ }
+ }
+ freeSlot := p.FirstFreeSlot()
+ if freeSlot >= 0 {
+ p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: ammoID, Quantity: p.AmmoQty})
+ }
+ delete(p.Equipment, object.SlotAmmo)
+ p.AmmoQty = 0
+}
+
func (g *Game) doWearAll(sess *net.Session) {
p := sess.Player.(*player.Player)
g.CancelAction(p)
bestPerSlot := make(map[object.EquipSlot]struct {
- itemID string
- value int
+ itemID string
+ value int
invSlot int
})
@@ -108,12 +166,16 @@ func (g *Game) doWearAll(sess *net.Session) {
continue
}
current, exists := bestPerSlot[def.EquipSlot]
- if !exists || def.Value > current.value {
+ val := def.Value
+ if def.EquipSlot == object.SlotAmmo && def.Stackable {
+ val = def.Value * slot.Quantity
+ }
+ if !exists || val > current.value {
bestPerSlot[def.EquipSlot] = struct {
- itemID string
- value int
+ itemID string
+ value int
invSlot int
- }{slot.ItemID, def.Value, i}
+ }{slot.ItemID, val, i}
}
}
@@ -125,7 +187,33 @@ func (g *Game) doWearAll(sess *net.Session) {
var equipped []string
for eqSlot, best := range bestPerSlot {
if existing, ok := p.Equipment[eqSlot]; ok && existing == best.itemID {
- continue
+ if eqSlot != object.SlotAmmo {
+ continue
+ }
+ }
+
+ if eqSlot == object.SlotAmmo {
+ bestDef, _ := g.ItemStore.Load(best.itemID)
+ if bestDef != nil && bestDef.Stackable {
+ invSlot := p.InvSlot(best.invSlot)
+ if invSlot == nil {
+ continue
+ }
+ existingID, hasAmmo := p.Equipment[object.SlotAmmo]
+ if hasAmmo && existingID != best.itemID {
+ g.unequipAmmo(p)
+ }
+ transferQty := invSlot.Quantity
+ p.SetInvSlot(best.invSlot, nil)
+ if hasAmmo && existingID == best.itemID {
+ p.AmmoQty += transferQty
+ } else {
+ p.Equipment[object.SlotAmmo] = best.itemID
+ p.AmmoQty = transferQty
+ }
+ equipped = append(equipped, g.itemColorize(sess, bestDef, bestDef.Name))
+ continue
+ }
}
if existing, ok := p.Equipment[eqSlot]; ok {