package game // Regression: picking up a stackable item must merge into an existing stack // even when every inventory slot is occupied — capacity is required only // when a NEW slot is needed, matching the get-all paths. import ( "path/filepath" "testing" "thehouseoficarus/internal/net" "thehouseoficarus/internal/player" ) func TestPickupMergesIntoFullInventory(t *testing.T) { h := newHarness(t) h.seedAccount("alice") p := h.seedCharacter("alice", "alice") writeSeedFile(t, filepath.Join(h.dir, "items", "chips.yaml"), []byte("id: chips\nname: chips\nstackable: true\n")) sess := &net.Session{Conn: newChanConn(), Player: p} sess.SetState(net.StateGame) h.g.RunOnOwner(func() { h.g.ItemStore.Reload(h.dir) for i := 0; i < 28; i++ { p.SetInvSlot(i, &player.InventorySlot{ItemID: "filler", Quantity: 1}) } p.SetInvSlot(0, &player.InventorySlot{ItemID: "chips", Quantity: 10}) h.g.World.AddGroundItem(1, "chips", 5) h.g.doGet(sess, "chips") if got := countChips(p); got != 15 { t.Errorf("pickup rejected despite existing chip stack: have %d, want 15", got) } }) } func TestPickupFullInventoryWithoutStackStillRefused(t *testing.T) { h := newHarness(t) h.seedAccount("alice") p := h.seedCharacter("alice", "alice") writeSeedFile(t, filepath.Join(h.dir, "items", "chips.yaml"), []byte("id: chips\nname: chips\nstackable: true\n")) sess := &net.Session{Conn: newChanConn(), Player: p} sess.SetState(net.StateGame) h.g.RunOnOwner(func() { h.g.ItemStore.Reload(h.dir) for i := 0; i < 28; i++ { p.SetInvSlot(i, &player.InventorySlot{ItemID: "filler", Quantity: 1}) } h.g.World.AddGroundItem(1, "chips", 5) h.g.doGet(sess, "chips") if got := countChips(p); got != 0 { t.Errorf("pickup without an existing stack must be refused, have %d", got) } if got := h.g.World.GroundItems(1)["chips"]; got != 5 { t.Errorf("refused pickup must leave the ground stack intact, have %d", got) } }) }