diff options
| author | historia <[not public]> | 2026-09-18 05:31:09 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-18 05:31:09 -0400 |
| commit | 153acb7f644d755c45533b7c5311e3ffa47e8973 (patch) | |
| tree | 7645e6f7b65bc3830b078e3b9336d2e6b199d584 /internal/game/cmd_remove.go | |
| parent | 87d08f0151e643951769e323995f1c5ed89ee200 (diff) | |
| download | thehouseoficarus-153acb7f644d755c45533b7c5311e3ffa47e8973.tar.gz | |
fix: harden engine across casino, economy, concurrency, security, and content
Diffstat (limited to 'internal/game/cmd_remove.go')
| -rw-r--r-- | internal/game/cmd_remove.go | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/internal/game/cmd_remove.go b/internal/game/cmd_remove.go index 349617d..5bc02a7 100644 --- a/internal/game/cmd_remove.go +++ b/internal/game/cmd_remove.go @@ -97,9 +97,12 @@ func (g *Game) removeAmmo(sess *net.Session, p *player.Player, qty int) { removeQty = qty } + quality, maxQuality := g.pickedStackProps(ammoID) for i := 0; i < 28; i++ { s := p.InvSlot(i) - if s != nil && s.ItemID == ammoID { + // Only a stack with the properties a fresh stack gets may absorb the + // equipped stack (see pickedStackProps). + if s != nil && s.ItemID == ammoID && s.Quality == quality && s.MaxQuality == maxQuality { s.Quantity += removeQty p.AmmoQty -= removeQty if p.AmmoQty <= 0 { @@ -123,7 +126,7 @@ func (g *Game) removeAmmo(sess *net.Session, p *player.Player, qty int) { return } - p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: ammoID, Quantity: removeQty}) + p.SetInvSlot(freeSlot, g.newInventorySlot(ammoID, removeQty)) p.AmmoQty -= removeQty if p.AmmoQty <= 0 { delete(p.Equipment, item.SlotAmmo) @@ -193,10 +196,17 @@ func (g *Game) doRemoveAll(sess *net.Session) { g.saveCharacter(p) } +// removeAllAmmo moves the whole equipped ammo stack into the inventory. The +// equipment entry is only cleared once the stack has been merged into an +// existing stack or placed in a free slot, so a full inventory reports a +// failure instead of silently destroying the ammo. func (g *Game) removeAllAmmo(sess *net.Session, p *player.Player, itemID string) { + quality, maxQuality := g.pickedStackProps(itemID) for i := 0; i < 28; i++ { s := p.InvSlot(i) - if s != nil && s.ItemID == itemID { + // Only a stack with the properties a fresh stack gets may absorb the + // equipped stack (see pickedStackProps). + if s != nil && s.ItemID == itemID && s.Quality == quality && s.MaxQuality == maxQuality { s.Quantity += p.AmmoQty delete(p.Equipment, item.SlotAmmo) p.AmmoQty = 0 @@ -210,9 +220,13 @@ func (g *Game) removeAllAmmo(sess *net.Session, p *player.Player, itemID string) } } freeSlot := p.FirstFreeSlot() - if freeSlot >= 0 { - p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: itemID, Quantity: p.AmmoQty}) + if freeSlot < 0 { + // Nowhere to put the equipped stack: leave it equipped and report + // nothing removed. + sess.WriteLine("Nowhere to put that!") + return } + p.SetInvSlot(freeSlot, g.newInventorySlot(itemID, p.AmmoQty)) delete(p.Equipment, item.SlotAmmo) p.AmmoQty = 0 def, _ := g.ItemStore.Load(itemID) |
