159 lines
6.1 KiB
C++
159 lines
6.1 KiB
C++
#include "testHarness.h"
|
|
#include "vf/ContainerMenu.h"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
using namespace vf;
|
|
|
|
namespace {
|
|
|
|
const CraftingRegistry& sharedRegistry() {
|
|
static CraftingRegistry registry;
|
|
return registry;
|
|
}
|
|
|
|
// A recipe nothing in the default set uses: a tool sits in the grid as a proper
|
|
// ingredient, which is the only way to exercise the remainder rule.
|
|
CraftingRegistry registryWithToolRecipe() {
|
|
CraftingRegistry registry;
|
|
ShapedRecipe carving;
|
|
carving.width = 1;
|
|
carving.height = 2;
|
|
carving.pattern = {ItemId::IronShovel, ItemId::Planks};
|
|
carving.result = {ItemId::Stick, 4};
|
|
carving.allowMirror = false;
|
|
registry.addShaped(carving);
|
|
return registry;
|
|
}
|
|
|
|
int countSlotsWithRole(const ContainerMenu& menu, MenuSlot::Role role) {
|
|
return static_cast<int>(menu.slotsWithRole(role).size());
|
|
}
|
|
|
|
} // namespace
|
|
|
|
VF_TEST(everyMenuKindLaysOutTheSectionsItsScreenNeeds) {
|
|
for (int i = 0; i < static_cast<int>(MenuKind::Count); ++i) {
|
|
MenuKind kind = static_cast<MenuKind>(i);
|
|
ContainerMenu menu(kind, &sharedRegistry());
|
|
CHECK(menu.slotCount() > 0);
|
|
CHECK_EQ(menu.slotCount(), menu.layout().totalSlots);
|
|
CHECK_EQ(menu.layout().inventoryCount, playerInventorySlots);
|
|
CHECK_EQ(menu.layout().hotbarCount, playerHotbarSlots);
|
|
CHECK(std::string(menuKindName(kind)) != std::string("unknown"));
|
|
}
|
|
|
|
CHECK_EQ(ContainerMenu(MenuKind::Chest).slotCount(), 27 + 27 + 9);
|
|
CHECK_EQ(ContainerMenu(MenuKind::LargeChest).slotCount(), 54 + 27 + 9);
|
|
CHECK_EQ(ContainerMenu(MenuKind::Hopper).slotCount(), 5 + 27 + 9);
|
|
CHECK_EQ(countSlotsWithRole(ContainerMenu(MenuKind::Hopper), MenuSlot::Role::Storage), 5);
|
|
}
|
|
|
|
VF_TEST(thePlayerInventoryKeepsItsTwoByTwoGridAndAnOffHandSlot) {
|
|
ContainerMenu menu(MenuKind::PlayerInventory, &sharedRegistry());
|
|
const MenuLayout& layout = menu.layout();
|
|
|
|
CHECK_EQ(layout.craftWidth, 2);
|
|
CHECK_EQ(layout.craftHeight, 2);
|
|
CHECK_EQ(layout.craftCells(), 4);
|
|
CHECK(layout.hasCrafting());
|
|
CHECK(layout.resultSlot >= 0);
|
|
CHECK(layout.offHandSlot >= 0);
|
|
CHECK_EQ(countSlotsWithRole(menu, MenuSlot::Role::CraftInput), 4);
|
|
CHECK_EQ(countSlotsWithRole(menu, MenuSlot::Role::OffHand), 1);
|
|
CHECK(menu.isPlayerSection(layout.offHandSlot));
|
|
CHECK(!menu.isPlayerSection(layout.resultSlot));
|
|
}
|
|
|
|
VF_TEST(theCraftingTableGivesTheFullThreeByThreeGrid) {
|
|
ContainerMenu menu(MenuKind::CraftingTable, &sharedRegistry());
|
|
CHECK_EQ(menu.layout().craftWidth, 3);
|
|
CHECK_EQ(menu.layout().craftHeight, 3);
|
|
CHECK_EQ(countSlotsWithRole(menu, MenuSlot::Role::CraftInput), 9);
|
|
CHECK(menu.hasCrafting());
|
|
CHECK_EQ(menu.layout().offHandSlot, -1);
|
|
}
|
|
|
|
VF_TEST(theFurnaceFuelSlotRefusesAnythingThatWillNotBurn) {
|
|
ContainerMenu menu(MenuKind::Furnace, &sharedRegistry());
|
|
std::vector<int> fuelSlots = menu.slotsWithRole(MenuSlot::Role::FuelInput);
|
|
CHECK_EQ(fuelSlots.size(), 1u);
|
|
int fuel = fuelSlots[0];
|
|
|
|
CHECK(menu.canPlace(fuel, makeStack(ItemId::CoalLump, 8)));
|
|
CHECK(menu.canPlace(fuel, makeStack(ItemId::Planks, 8)));
|
|
CHECK(!menu.canPlace(fuel, makeStack(ItemId::Stone, 8)));
|
|
CHECK(!menu.canPlace(fuel, makeStack(ItemId::IronIngot, 1)));
|
|
|
|
MetaStack stone = makeStack(ItemId::Stone, 8);
|
|
CHECK_EQ(menu.insertAt(fuel, stone), 0);
|
|
CHECK_EQ(stone.count, 8);
|
|
|
|
MetaStack coal = makeStack(ItemId::CoalLump, 8);
|
|
CHECK_EQ(menu.insertAt(fuel, coal), 8);
|
|
CHECK(coal.empty());
|
|
CHECK_EQ(menu.stackAt(fuel).count, 8);
|
|
}
|
|
|
|
VF_TEST(theFurnaceInputSlotOnlyTakesItemsWithASmeltingRecipe) {
|
|
ContainerMenu menu(MenuKind::Furnace, &sharedRegistry());
|
|
int input = menu.slotsWithRole(MenuSlot::Role::SmeltInput)[0];
|
|
|
|
CHECK(menu.canPlace(input, makeStack(ItemId::IronOre, 4)));
|
|
CHECK(menu.canPlace(input, makeStack(ItemId::RawBeef, 4)));
|
|
CHECK(!menu.canPlace(input, makeStack(ItemId::Stick, 4)));
|
|
CHECK(!menu.canPlace(input, makeStack(ItemId::Glowstone, 4)));
|
|
|
|
// Without a registry there is nothing to consult, so nothing is smeltable.
|
|
ContainerMenu blind(MenuKind::Furnace, nullptr);
|
|
CHECK(!blind.canPlace(input, makeStack(ItemId::IronOre, 4)));
|
|
}
|
|
|
|
VF_TEST(theEnchantingTableTakesOnlyLapisForPaymentAndOnlyGearForTheItem) {
|
|
ContainerMenu menu(MenuKind::EnchantingTable, &sharedRegistry());
|
|
int item = menu.slotsWithRole(MenuSlot::Role::EnchantItem)[0];
|
|
int lapis = menu.slotsWithRole(MenuSlot::Role::EnchantLapis)[0];
|
|
|
|
CHECK(menu.canPlace(lapis, makeStack(ItemId::LapisLazuli, 3)));
|
|
CHECK(!menu.canPlace(lapis, makeStack(ItemId::DiamondGem, 3)));
|
|
CHECK(!menu.canPlace(lapis, makeStack(ItemId::LapisOre, 3)));
|
|
|
|
CHECK(menu.canPlace(item, makeTool(ItemId::DiamondSword)));
|
|
CHECK(!menu.canPlace(item, makeStack(ItemId::Stone, 1)));
|
|
CHECK(!menu.canPlace(item, makeStack(ItemId::LapisLazuli, 1)));
|
|
}
|
|
|
|
VF_TEST(theAnvilOnlyAcceptsItemsThatCarryDurability) {
|
|
ContainerMenu menu(MenuKind::Anvil, &sharedRegistry());
|
|
std::vector<int> inputs = menu.slotsWithRole(MenuSlot::Role::AnvilInput);
|
|
CHECK_EQ(inputs.size(), 2u);
|
|
|
|
CHECK(menu.canPlace(inputs[0], makeTool(ItemId::GoldHoe)));
|
|
CHECK(menu.canPlace(inputs[1], makeTool(ItemId::DiamondAxe)));
|
|
CHECK(!menu.canPlace(inputs[0], makeStack(ItemId::IronIngot, 4)));
|
|
}
|
|
|
|
VF_TEST(theBrewingStandFiltersIngredientsAndHoldsOneItemPerBottleSlot) {
|
|
ContainerMenu menu(MenuKind::BrewingStand, &sharedRegistry());
|
|
int ingredient = menu.slotsWithRole(MenuSlot::Role::BrewIngredient)[0];
|
|
std::vector<int> bottles = menu.slotsWithRole(MenuSlot::Role::BrewBottle);
|
|
CHECK_EQ(bottles.size(), 3u);
|
|
|
|
CHECK(menu.canPlace(ingredient, makeStack(ItemId::Gunpowder, 2)));
|
|
CHECK(menu.canPlace(ingredient, makeStack(ItemId::RedstoneDust, 2)));
|
|
CHECK(!menu.canPlace(ingredient, makeStack(ItemId::Stick, 2)));
|
|
|
|
MetaStack pile = makeStack(ItemId::Glowstone, 20);
|
|
int moved = menu.insertAt(bottles[0], pile);
|
|
CHECK_EQ(moved, 1);
|
|
CHECK_EQ(menu.stackAt(bottles[0]).count, 1);
|
|
CHECK_EQ(pile.count, 19);
|
|
CHECK_EQ(menu.insertAt(bottles[0], pile), 0);
|
|
}
|
|
|
|
VF_TEST(aResultSlotCanBeEmptiedButNeverFilledByHand) {
|
|
ContainerMenu menu(MenuKind::CraftingTable, &sharedRegistry());
|
|
int result = menu.layout().resultSlot;
|
|
|