diff options
Diffstat (limited to 'internal/game/act_fletch.go')
| -rw-r--r-- | internal/game/act_fletch.go | 72 |
1 files changed, 32 insertions, 40 deletions
diff --git a/internal/game/act_fletch.go b/internal/game/act_fletch.go index c52aae1..9796bda 100644 --- a/internal/game/act_fletch.go +++ b/internal/game/act_fletch.go @@ -34,31 +34,22 @@ func (g *Game) doInstantFletch(sess *net.Session, p *player.Player, def *item.It totalOutput := 0 skill := player.SkillName(c.EffectiveSkill()) tmpItem := &item.ItemDef{Craft: item.CraftList{*c}} + inventoryFull := false for { if !g.canDoFletchItem(p, tmpItem) { break } - - placed := false - if def.Stackable { - for i := 0; i < 28; i++ { - slot := p.InvSlot(i) - if slot != nil && slot.ItemID == def.ID { - consumeIngredients(c, p.CountItem, p.RemoveItem) - slot.Quantity += outputQty - placed = true - break - } - } + // A full inventory must never destroy materials: check placement + // BEFORE consuming the batch. + if !craftOutputFits(p, def.ID, def) { + inventoryFull = true + break } - if !placed { - consumeIngredients(c, p.CountItem, p.RemoveItem) - freeSlot := p.FirstFreeSlot() - if freeSlot == -1 { - break - } - p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: def.ID, Quantity: outputQty}) + + if !consumeIngredients(c, p.CountItem, p.RemoveItem) { + break } + placeCraftOutput(p, def.ID, def, outputQty) if c.XP > 0 { g.awardSkillXP(sess, p, skill, c.XP) @@ -76,7 +67,11 @@ func (g *Game) doInstantFletch(sess *net.Session, p *player.Player, def *item.It } if batches == 0 { - sess.WriteLine("You don't have the materials for that.") + if inventoryFull { + sess.WriteLine("Your inventory is too full!") + } else { + sess.WriteLine("You don't have the materials for that.") + } return } @@ -158,29 +153,26 @@ func (g *Game) advanceFletch(sess *net.Session, p *player.Player) { outputQty = 1 } + // A full inventory must never destroy materials: verify the output can + // be placed BEFORE consuming the batch. + if !craftOutputFits(p, itemID, def) { + sess.WriteLine("Your inventory is too full!") + g.cancelBgAction(p) + return + } + skill := player.SkillName(c.EffectiveSkill()) - placed := false - if def.Stackable { - for i := 0; i < 28; i++ { - slot := p.InvSlot(i) - if slot != nil && slot.ItemID == def.ID { - consumeIngredients(c, p.CountItem, p.RemoveItem) - slot.Quantity += outputQty - placed = true - break - } - } + if !consumeIngredients(c, p.CountItem, p.RemoveItem) { + g.cancelBgAction(p) + return } - if !placed { - consumeIngredients(c, p.CountItem, p.RemoveItem) - freeSlot := p.FirstFreeSlot() - if freeSlot == -1 { - sess.WriteLine("Your inventory is too full!") - g.cancelBgAction(p) - return - } - p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: def.ID, Quantity: outputQty}) + if !placeCraftOutput(p, itemID, def, outputQty) { + // Defensive: the fits check above should have guaranteed a stack + // or slot. + sess.WriteLine("Your inventory is too full!") + g.cancelBgAction(p) + return } if c.XP > 0 { |
