From 17e7725f252c7f5d3be2e9c37d62751c631f196f Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Thu, 18 Jun 2026 18:50:54 -0400 Subject: feat: fletching added including zero-time bolt feathering, which probably will break lots of things --- internal/game/cmd_remove.go | 102 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 99 insertions(+), 3 deletions(-) (limited to 'internal/game/cmd_remove.go') diff --git a/internal/game/cmd_remove.go b/internal/game/cmd_remove.go index 8f1a413..d36a8fd 100644 --- a/internal/game/cmd_remove.go +++ b/internal/game/cmd_remove.go @@ -24,6 +24,8 @@ func (g *Game) doRemove(sess *net.Session, input string) { g.CancelAction(p) + qty, itemName := parseQty(input) + var foundSlot object.EquipSlot var foundItemID string @@ -32,7 +34,7 @@ func (g *Game) doRemove(sess *net.Session, input string) { if !ok { continue } - if strings.ToLower(string(slot)) == lower { + if strings.ToLower(string(slot)) == strings.ToLower(itemName) { foundSlot = slot foundItemID = itemID break @@ -41,7 +43,7 @@ func (g *Game) doRemove(sess *net.Session, input string) { if err != nil { continue } - if def.MatchesName(input) { + if def.MatchesName(itemName) { foundSlot = slot foundItemID = itemID break @@ -53,6 +55,11 @@ func (g *Game) doRemove(sess *net.Session, input string) { return } + if foundSlot == object.SlotAmmo && p.AmmoQty > 0 { + g.removeAmmo(sess, p, qty) + return + } + freeSlot := p.FirstFreeSlot() if freeSlot == -1 { sess.WriteLine("Nowhere to put that!") @@ -79,6 +86,55 @@ func (g *Game) doRemove(sess *net.Session, input string) { sess.WriteLine(fmt.Sprintf("You remove %s.", g.itemColorize(sess, def, name))) } +func (g *Game) removeAmmo(sess *net.Session, p *player.Player, qty int) { + ammoID := p.Equipment[object.SlotAmmo] + removeQty := p.AmmoQty + if qty > 0 && qty < removeQty { + removeQty = qty + } + + for i := 0; i < 28; i++ { + s := p.InvSlot(i) + if s != nil && s.ItemID == ammoID { + s.Quantity += removeQty + p.AmmoQty -= removeQty + if p.AmmoQty <= 0 { + delete(p.Equipment, object.SlotAmmo) + p.AmmoQty = 0 + } + g.AccountStore.SaveCharacter(p) + def, _ := g.ItemStore.Load(ammoID) + name := ammoID + if def != nil { + name = def.Name + } + sess.WriteLine(fmt.Sprintf("You unequip %s (x%d).", g.itemColorize(sess, def, name), removeQty)) + return + } + } + + freeSlot := p.FirstFreeSlot() + if freeSlot == -1 { + sess.WriteLine("Nowhere to put that!") + return + } + + p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: ammoID, Quantity: removeQty}) + p.AmmoQty -= removeQty + if p.AmmoQty <= 0 { + delete(p.Equipment, object.SlotAmmo) + p.AmmoQty = 0 + } + g.AccountStore.SaveCharacter(p) + + def, _ := g.ItemStore.Load(ammoID) + name := ammoID + if def != nil { + name = def.Name + } + sess.WriteLine(fmt.Sprintf("You unequip %s (x%d).", g.itemColorize(sess, def, name), removeQty)) +} + func (g *Game) doRemoveAll(sess *net.Session) { p := sess.Player.(*player.Player) @@ -87,7 +143,12 @@ func (g *Game) doRemoveAll(sess *net.Session) { return } - if len(p.Equipment) > p.FreeSlots() { + needed := len(p.Equipment) + if _, hasAmmo := p.Equipment[object.SlotAmmo]; hasAmmo { + needed-- + needed++ + } + if needed > p.FreeSlots() { sess.WriteLine("You don't have room to remove everything!") return } @@ -100,6 +161,11 @@ func (g *Game) doRemoveAll(sess *net.Session) { continue } + if slot == object.SlotAmmo && p.AmmoQty > 0 { + g.removeAllAmmo(sess, p, itemID) + continue + } + freeSlot := p.FirstFreeSlot() delete(p.Equipment, slot) invSlot := &player.InventorySlot{ItemID: itemID, Quantity: 1} @@ -122,3 +188,33 @@ func (g *Game) doRemoveAll(sess *net.Session) { g.AccountStore.SaveCharacter(p) } + +func (g *Game) removeAllAmmo(sess *net.Session, p *player.Player, itemID string) { + for i := 0; i < 28; i++ { + s := p.InvSlot(i) + if s != nil && s.ItemID == itemID { + s.Quantity += p.AmmoQty + delete(p.Equipment, object.SlotAmmo) + p.AmmoQty = 0 + def, _ := g.ItemStore.Load(itemID) + name := itemID + if def != nil { + name = def.Name + } + sess.WriteLine(fmt.Sprintf("You remove %s.", g.itemColorize(sess, def, name))) + return + } + } + freeSlot := p.FirstFreeSlot() + if freeSlot >= 0 { + p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: itemID, Quantity: p.AmmoQty}) + } + delete(p.Equipment, object.SlotAmmo) + p.AmmoQty = 0 + def, _ := g.ItemStore.Load(itemID) + name := itemID + if def != nil { + name = def.Name + } + sess.WriteLine(fmt.Sprintf("You remove %s.", g.itemColorize(sess, def, name))) +} -- cgit v1.2.3