diff options
| author | historia <[not public]> | 2026-09-18 15:16:44 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-18 15:16:44 -0400 |
| commit | 7eab582d8a8ee2af1a6baae7baf0696c7005de2e (patch) | |
| tree | 902bbc8c6e39c9f62f779ca23267714ec420b9f5 /internal/game/cmd_drop.go | |
| parent | 153acb7f644d755c45533b7c5311e3ffa47e8973 (diff) | |
| download | thehouseoficarus-7eab582d8a8ee2af1a6baae7baf0696c7005de2e.tar.gz | |
fix: harden triggers, economy, casino, world data, and admin/net paths
Diffstat (limited to 'internal/game/cmd_drop.go')
| -rw-r--r-- | internal/game/cmd_drop.go | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/internal/game/cmd_drop.go b/internal/game/cmd_drop.go index 5920696..2e27f91 100644 --- a/internal/game/cmd_drop.go +++ b/internal/game/cmd_drop.go @@ -51,15 +51,24 @@ func (g *Game) doDropAllNamed(sess *net.Session, input string) { coloredName := g.itemColorize(sess, def, name) if def != nil && def.Stackable { - slot := p.InvSlot(matches[0].Slot) - qty := slot.Quantity - p.SetInvSlot(matches[0].Slot, nil) - g.World.AddGroundItem(p.RoomID, itemID, qty) + // Drop every matching stack, not just the first: multiple stacks of + // one stackable item are normal (trigger/gather/steal placement does + // not always merge), so "drop all <item>" must span them. + total := 0 + for _, match := range matches { + slot := p.InvSlot(match.Slot) + if slot == nil || slot.ItemID != itemID || slot.Quantity <= 0 { + continue + } + total += slot.Quantity + p.SetInvSlot(match.Slot, nil) + g.World.AddGroundItem(p.RoomID, itemID, slot.Quantity) + } g.saveCharacter(p) - if qty == 1 { + if total == 1 { sess.WriteLine(fmt.Sprintf("You drop a %s.", coloredName)) } else { - sess.WriteLine(fmt.Sprintf("You drop %d x %s.", qty, coloredName)) + sess.WriteLine(fmt.Sprintf("You drop %d x %s.", total, coloredName)) } return } @@ -110,11 +119,11 @@ func (g *Game) doDrop(sess *net.Session, input string) { if qty == 0 { if def != nil && def.Stackable { + // "drop <item>" means the whole item: sum every matching stack. for i := 0; i < 28; i++ { slot := p.InvSlot(i) if slot != nil && slot.ItemID == itemID && slot.Quantity > 0 { - qty = slot.Quantity - break + qty += slot.Quantity } } } else { @@ -128,21 +137,35 @@ func (g *Game) doDrop(sess *net.Session, input string) { } if def != nil && def.Stackable { - slot := p.InvSlot(matches[0].Slot) - if qty > slot.Quantity { - qty = slot.Quantity - } - if slot.Quantity > qty { - slot.Quantity -= qty - } else { - p.SetInvSlot(matches[0].Slot, nil) + // Consume the requested quantity across every matching stack, not just + // the first one. + remaining := qty + for _, match := range matches { + if remaining <= 0 { + break + } + slot := p.InvSlot(match.Slot) + if slot == nil || slot.ItemID != itemID || slot.Quantity <= 0 { + continue + } + take := slot.Quantity + if take > remaining { + take = remaining + } + if slot.Quantity > take { + slot.Quantity -= take + } else { + p.SetInvSlot(match.Slot, nil) + } + g.World.AddGroundItem(p.RoomID, itemID, take) + remaining -= take } - g.World.AddGroundItem(p.RoomID, itemID, qty) + dropped := qty - remaining g.saveCharacter(p) - if qty == 1 { + if dropped == 1 { sess.WriteLine(fmt.Sprintf("You drop a %s.", g.itemColorize(sess, def, name))) } else { - sess.WriteLine(fmt.Sprintf("You drop %d x %s.", qty, g.itemColorize(sess, def, name))) + sess.WriteLine(fmt.Sprintf("You drop %d x %s.", dropped, g.itemColorize(sess, def, name))) } return } |
