diff options
Diffstat (limited to 'internal/game/cmd_get.go')
| -rw-r--r-- | internal/game/cmd_get.go | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/internal/game/cmd_get.go b/internal/game/cmd_get.go index a2ad137..33f55de 100644 --- a/internal/game/cmd_get.go +++ b/internal/game/cmd_get.go @@ -75,7 +75,7 @@ func (g *Game) doGet(sess *net.Session, input string) { // doGetAllNamed). See TestPickupMergesIntoFullInventory. if def != nil && def.Stackable { - quality, maxQuality := g.pickedStackProps(itemID) + quality, maxQuality := g.groundStackProps(p, itemID) for i := 0; i < 28; i++ { slot := p.InvSlot(i) if slot == nil || slot.ItemID != itemID || slot.Quality != quality || slot.MaxQuality != maxQuality { @@ -96,11 +96,12 @@ func (g *Game) doGet(sess *net.Session, input string) { sess.WriteLine("Your inventory is full.") return } - if _, ok := g.World.RemoveReservedItem(p.RoomID, itemID, qty, p.Name); !ok { + removed, q, mq, ok := g.World.RemoveReservedItemQ(p.RoomID, itemID, qty, p.Name) + if !ok { sess.WriteLine("That's not yours!") return } - p.SetInvSlot(freeSlot, g.newInventorySlot(itemID, qty)) + p.SetInvSlot(freeSlot, g.groundSlot(itemID, removed, q, mq)) g.saveCharacter(p) if qty == 1 { sess.WriteLine(fmt.Sprintf("You pick up a %s.", g.itemColorize(sess, def, def.Name))) @@ -116,10 +117,11 @@ func (g *Game) doGet(sess *net.Session, input string) { if fs == -1 { break } - if _, ok := g.World.RemoveReservedItem(p.RoomID, itemID, 1, p.Name); !ok { + _, q, mq, ok := g.World.RemoveReservedItemQ(p.RoomID, itemID, 1, p.Name) + if !ok { break } - p.SetInvSlot(fs, g.newInventorySlot(itemID, 1)) + p.SetInvSlot(fs, g.groundSlot(itemID, 1, q, mq)) picked++ } @@ -195,7 +197,7 @@ func (g *Game) doGetAllNamed(sess *net.Session, input string) { coloredName := g.itemColorize(sess, def, name) if def != nil && def.Stackable { - quality, maxQuality := g.pickedStackProps(itemID) + quality, maxQuality := g.groundStackProps(p, itemID) for i := 0; i < 28; i++ { slot := p.InvSlot(i) if slot == nil || slot.ItemID != itemID || slot.Quality != quality || slot.MaxQuality != maxQuality { @@ -216,12 +218,12 @@ func (g *Game) doGetAllNamed(sess *net.Session, input string) { sess.WriteLine("Your inventory is full.") return } - removed, ok := g.World.RemoveReservedItem(p.RoomID, itemID, wanted, p.Name) + removed, q, mq, ok := g.World.RemoveReservedItemQ(p.RoomID, itemID, wanted, p.Name) if !ok { sess.WriteLine("That's not yours!") return } - p.SetInvSlot(freeSlot, g.newInventorySlot(itemID, removed)) + p.SetInvSlot(freeSlot, g.groundSlot(itemID, removed, q, mq)) g.saveCharacter(p) if removed == 1 { sess.WriteLine(fmt.Sprintf("You pick up a %s.", coloredName)) @@ -237,11 +239,11 @@ func (g *Game) doGetAllNamed(sess *net.Session, input string) { if fs == -1 { break } - _, ok := g.World.RemoveReservedItem(p.RoomID, itemID, 1, p.Name) + _, q, mq, ok := g.World.RemoveReservedItemQ(p.RoomID, itemID, 1, p.Name) if !ok { break } - p.SetInvSlot(fs, g.newInventorySlot(itemID, 1)) + p.SetInvSlot(fs, g.groundSlot(itemID, 1, q, mq)) picked++ } @@ -303,7 +305,7 @@ func (g *Game) doGetAll(sess *net.Session) { for qty > 0 { if def != nil && def.Stackable { stacked := false - quality, maxQuality := g.pickedStackProps(itemID) + quality, maxQuality := g.groundStackProps(p, itemID) for i := 0; i < 28; i++ { slot := p.InvSlot(i) if slot == nil || slot.ItemID != itemID || slot.Quality != quality || slot.MaxQuality != maxQuality { @@ -335,11 +337,11 @@ func (g *Game) doGetAll(sess *net.Session) { g.saveCharacter(p) return } - _, ok := g.World.RemoveReservedItem(p.RoomID, itemID, qty, p.Name) + removed, q, mq, ok := g.World.RemoveReservedItemQ(p.RoomID, itemID, qty, p.Name) if !ok { break } - p.SetInvSlot(freeSlot, g.newInventorySlot(itemID, qty)) + p.SetInvSlot(freeSlot, g.groundSlot(itemID, removed, q, mq)) name := itemID if def != nil { name = def.Name @@ -361,11 +363,11 @@ func (g *Game) doGetAll(sess *net.Session) { } take := 1 - _, ok := g.World.RemoveReservedItem(p.RoomID, itemID, take, p.Name) + _, q, mq, ok := g.World.RemoveReservedItemQ(p.RoomID, itemID, take, p.Name) if !ok { break } - p.SetInvSlot(freeSlot, g.newInventorySlot(itemID, take)) + p.SetInvSlot(freeSlot, g.groundSlot(itemID, take, q, mq)) name := itemID if def != nil { name = def.Name @@ -433,6 +435,28 @@ func (g *Game) pickedStackProps(itemID string) (quality, maxQuality int) { return stackProps(def) } +// groundStackProps is pickedStackProps for a ground pickup: it prefers the +// quality carried by the ground entry so a partially-used item is not +// re-created at full quality (and a pickup only merges into a slot with the +// same properties). +func (g *Game) groundStackProps(p *player.Player, itemID string) (quality, maxQuality int) { + if q, mq, ok := g.World.AccessibleGroundQuality(p.RoomID, itemID, p.Name); ok && mq > 0 { + return q, mq + } + return g.pickedStackProps(itemID) +} + +// groundSlot builds an inventory slot for a ground pickup, preserving the +// quality carried by the ground entry. A ground entry with no quality record +// (loot/trigger/spawn drops) falls back to the item's full quality, matching +// newInventorySlot. +func (g *Game) groundSlot(itemID string, qty, quality, maxQuality int) *player.InventorySlot { + if maxQuality > 0 { + return &player.InventorySlot{ItemID: itemID, Quantity: qty, Quality: quality, MaxQuality: maxQuality} + } + return g.newInventorySlot(itemID, qty) +} + func (g *Game) collectMatches(input string, each func(func(itemID string, slot int) bool)) []itemMatch { var matches []itemMatch each(func(itemID string, slot int) bool { |
