diff --git a/tests/testSlotAction.cpp b/tests/testSlotAction.cpp index c33fe23..5c189b1 100644 --- a/tests/testSlotAction.cpp +++ b/tests/testSlotAction.cpp @@ -154,3 +154,160 @@ VF_TEST(aLeftClickMergesIntoAMatchingStackAndSwapsWithAForeignOne) { session.menu.slot(1).cell.stack = makeStack(ItemId::Sand, 60); session.menu.slot(2).cell.stack = makeStack(ItemId::Planks, 8); + session.click(ClickKind::Left, 0); + SlotActionResult merge = session.click(ClickKind::Left, 1); + CHECK(merge.applied); + CHECK_EQ(merge.moved, 4); + CHECK_EQ(session.menu.stackAt(1).count, 64); + CHECK_EQ(session.cursor.held.count, 46); + + SlotActionResult swap = session.click(ClickKind::Left, 2); + CHECK(swap.applied); + CHECK_EQ(swap.moved, 54); + CHECK(session.cursor.held.item == ItemId::Planks); + CHECK_EQ(session.cursor.held.count, 8); + CHECK(session.menu.stackAt(2).item == ItemId::Sand); + CHECK_EQ(session.menu.stackAt(2).count, 46); + + // A full matching stack accepts nothing and is not swapped either. + session.menu.slot(3).cell.stack = makeStack(ItemId::Planks, 64); + CHECK(!session.click(ClickKind::Left, 3).applied); + CHECK_EQ(session.cursor.held.count, 8); +} + +VF_TEST(aRightClickTakesTheLargerHalfAndThenPlacesOneAtATime) { + Session session(MenuKind::Chest); + session.menu.slot(0).cell.stack = makeStack(ItemId::CoalLump, 9); + + SlotActionResult half = session.click(ClickKind::Right, 0); + CHECK(half.applied); + CHECK_EQ(half.moved, 5); + CHECK_EQ(session.cursor.held.count, 5); + CHECK_EQ(session.menu.stackAt(0).count, 4); + + SlotActionResult one = session.click(ClickKind::Right, 6); + CHECK(one.applied); + CHECK_EQ(one.moved, 1); + CHECK_EQ(session.menu.stackAt(6).count, 1); + CHECK_EQ(session.cursor.held.count, 4); + + session.click(ClickKind::Right, 6); + CHECK_EQ(session.menu.stackAt(6).count, 2); + CHECK_EQ(session.cursor.held.count, 3); + + // A right click over an incompatible stack does nothing at all. + session.menu.slot(7).cell.stack = makeStack(ItemId::Stone, 1); + CHECK(!session.click(ClickKind::Right, 7).applied); + CHECK_EQ(session.cursor.held.count, 3); + CHECK_EQ(session.menu.stackAt(7).count, 1); +} + +VF_TEST(shiftClickTopsUpExistingStacksBeforeItTouchesAnEmptySlot) { + Session session(MenuKind::Chest); + std::vector player = session.menu.playerSectionSlots(); + session.menu.slot(0).cell.stack = makeStack(ItemId::Sand, 30); + session.menu.slot(player[0]).cell.stack = makeStack(ItemId::Stone, 64); + session.menu.slot(player[1]).cell.stack = makeStack(ItemId::Sand, 50); + + SlotActionResult moved = session.click(ClickKind::ShiftLeft, 0); + CHECK(moved.applied); + CHECK_EQ(moved.moved, 30); + CHECK(session.menu.stackAt(0).empty()); + CHECK_EQ(session.menu.stackAt(player[1]).count, 64); + CHECK_EQ(session.menu.stackAt(player[2]).count, 16); + CHECK(session.menu.stackAt(player[2]).item == ItemId::Sand); +} + +VF_TEST(shiftClickPutsWhatDoesNotFitStraightBackWhereItCameFrom) { + Session session(MenuKind::Hopper); + for (int index : session.menu.playerSectionSlots()) { + session.menu.slot(index).cell.stack = makeStack(ItemId::Obsidian, 64); + } + session.menu.slot(0).cell.stack = makeStack(ItemId::Sand, 12); + + SlotActionResult blocked = session.click(ClickKind::ShiftLeft, 0); + CHECK(!blocked.applied); + CHECK_EQ(session.menu.stackAt(0).count, 12); + CHECK_EQ(session.menu.totalOf(ItemId::Sand), 12); +} + +VF_TEST(shiftClickInAPlayerInventoryMovesBetweenTheRowsAndTheHotbar) { + Session session(MenuKind::PlayerInventory); + const MenuLayout& layout = session.menu.layout(); + int firstRow = layout.inventoryFirst; + int firstHotbar = layout.hotbarFirst; + + session.menu.slot(firstRow).cell.stack = makeStack(ItemId::Bread, 10); + SlotActionResult down = session.click(ClickKind::ShiftLeft, firstRow); + CHECK(down.applied); + CHECK_EQ(down.moved, 10); + CHECK(session.menu.stackAt(firstRow).empty()); + CHECK_EQ(session.menu.stackAt(firstHotbar).count, 10); + + SlotActionResult up = session.click(ClickKind::ShiftRight, firstHotbar); + CHECK(up.applied); + CHECK_EQ(session.menu.stackAt(firstRow).count, 10); + CHECK(session.menu.stackAt(firstHotbar).empty()); + + // The crafting grid is not a shift-click destination. + CHECK_EQ(session.menu.totalOf(ItemId::Bread), 10); + for (int cell = 0; cell < layout.craftCells(); ++cell) { + CHECK(session.menu.stackAt(layout.craftFirst + cell).empty()); + } +} + +VF_TEST(shiftClickHonoursTheDestinationFilters) { + Session session(MenuKind::Furnace); + int hotbar = session.menu.layout().hotbarFirst; + session.menu.slot(hotbar).cell.stack = makeStack(ItemId::Stone, 5); + + SlotActionResult refused = session.click(ClickKind::ShiftLeft, hotbar); + CHECK(!refused.applied); + CHECK_EQ(session.menu.stackAt(hotbar).count, 5); + + session.menu.slot(hotbar + 1).cell.stack = makeStack(ItemId::CoalLump, 5); + SlotActionResult accepted = session.click(ClickKind::ShiftLeft, hotbar + 1); + CHECK(accepted.applied); + CHECK_EQ(session.menu.stackAt(session.menu.slotsWithRole(MenuSlot::Role::FuelInput)[0]).count, + 5); +} + +VF_TEST(shiftClickingTheResultSlotCraftsEverythingTheGridCanMake) { + Session session(MenuKind::CraftingTable); + CraftingView grid = session.menu.crafting(); + grid.input(0, 0) = makeStack(ItemId::Planks, 4); + grid.input(0, 1) = makeStack(ItemId::Planks, 4); + grid.refresh(); + + SlotActionResult crafted = session.click(ClickKind::ShiftLeft, session.menu.layout().resultSlot); + CHECK(crafted.applied); + CHECK(crafted.craftedResult); + CHECK_EQ(crafted.craftedCount, 4); + CHECK_EQ(session.menu.totalOf(ItemId::Stick), 16); + CHECK_EQ(session.menu.totalOf(ItemId::Planks), 0); +} + +VF_TEST(aNumberKeyExchangesTheHoveredSlotWithThatHotbarSlot) { + Session session(MenuKind::Chest); + int hotbar = session.menu.layout().hotbarFirst; + session.menu.slot(0).cell.stack = makeStack(ItemId::Sand, 20); + session.menu.slot(hotbar + 3).cell.stack = makeStack(ItemId::Stone, 7); + + SlotActionResult swap = session.hotbar(0, 3); + CHECK(swap.applied); + CHECK_EQ(swap.moved, 27); + CHECK(session.menu.stackAt(0).item == ItemId::Stone); + CHECK_EQ(session.menu.stackAt(0).count, 7); + CHECK(session.menu.stackAt(hotbar + 3).item == ItemId::Sand); + CHECK_EQ(session.menu.stackAt(hotbar + 3).count, 20); + + CHECK(!session.hotbar(0, -1).applied); + CHECK(!session.hotbar(0, 9).applied); + CHECK(!session.hotbar(hotbar + 3, 3).applied); +} + +VF_TEST(aNumberKeyRespectsTheTargetSlotsFilter) { + Session session(MenuKind::Furnace); + int hotbar = session.menu.layout().hotbarFirst; + int fuel = session.menu.slotsWithRole(MenuSlot::Role::FuelInput)[0]; +