diff --git a/loader-common/src/main/java/org/cyclops/colossalchests/RegistryEntries.java b/loader-common/src/main/java/org/cyclops/colossalchests/RegistryEntries.java index d09ab4f2..b5101c19 100644 --- a/loader-common/src/main/java/org/cyclops/colossalchests/RegistryEntries.java +++ b/loader-common/src/main/java/org/cyclops/colossalchests/RegistryEntries.java @@ -22,6 +22,8 @@ public class RegistryEntries { public static final DeferredHolderCommon ITEM_CHEST = DeferredHolderCommon.create(Registries.ITEM, ResourceLocation.parse("minecraft:chest")); + public static final DeferredHolderCommon ITEM_UPGRADE_TOOL = DeferredHolderCommon.create(Registries.ITEM, ResourceLocation.parse("colossalchests:upgrade_tool")); + public static final DeferredHolderCommon ITEM_UPGRADE_TOOL_REVERSE = DeferredHolderCommon.create(Registries.ITEM, ResourceLocation.parse("colossalchests:upgrade_tool_reverse")); public static final DeferredHolderCommon BLOCK_UNCOLOSSAL_CHEST = DeferredHolderCommon.create(Registries.BLOCK, ResourceLocation.parse("colossalchests:uncolossal_chest")); diff --git a/loader-common/src/main/java/org/cyclops/colossalchests/gametest/GameTestsCommon.java b/loader-common/src/main/java/org/cyclops/colossalchests/gametest/GameTestsCommon.java new file mode 100644 index 00000000..8d131444 --- /dev/null +++ b/loader-common/src/main/java/org/cyclops/colossalchests/gametest/GameTestsCommon.java @@ -0,0 +1,1064 @@ +package org.cyclops.colossalchests.gametest; + +import com.google.common.collect.Sets; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.HopperBlock; +import net.minecraft.world.level.block.entity.HopperBlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import org.cyclops.colossalchests.Reference; +import org.cyclops.colossalchests.RegistryEntries; +import org.cyclops.colossalchests.block.*; +import org.cyclops.colossalchests.blockentity.BlockEntityColossalChest; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author rubensworks + */ +public class GameTestsCommon { + + public static final String TEMPLATE_EMPTY = Reference.MOD_ID + ":empty10"; + public static final BlockPos POS = BlockPos.ZERO.offset(1, 0, 1); + + @GameTest(template = TEMPLATE_EMPTY) + public void testUncolossalPlacementDirection(GameTestHelper helper) { + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.BLOCK_UNCOLOSSAL_CHEST.value()); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + helper.placeAt(player, itemStack, POS, Direction.SOUTH); + + helper.succeedWhen(() -> { + helper.assertBlockPresent(RegistryEntries.BLOCK_UNCOLOSSAL_CHEST.value(), POS.south()); + helper.assertBlockProperty(POS.south(), UncolossalChest.FACING, Direction.NORTH); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testUncolossalPlacementDirectionOpposite(GameTestHelper helper) { + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.BLOCK_UNCOLOSSAL_CHEST.value()); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + helper.placeAt(player, itemStack, POS, Direction.NORTH); + + helper.succeedWhen(() -> { + helper.assertBlockPresent(RegistryEntries.BLOCK_UNCOLOSSAL_CHEST.value(), POS.north()); + helper.assertBlockProperty(POS.north(), UncolossalChest.FACING, Direction.NORTH); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testUncolossalHoppers(GameTestHelper helper) { + // Place hopper above and below chest + helper.setBlock(POS.above(), Blocks.HOPPER); + helper.setBlock(POS, RegistryEntries.BLOCK_UNCOLOSSAL_CHEST.value()); + helper.setBlock(POS.below(), Blocks.HOPPER); + + // Throw apple in hopper + helper.spawnItem(Items.APPLE, POS.above().above()); + + // Expect apple to be in final hopper + helper.succeedWhen(() -> assertHopperContains(helper, POS.below(), new ItemStack(Items.APPLE))); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood2x2(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.WOOD, 2); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.WOOD, 2)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood3x3(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.WOOD, 3); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.WOOD, 3)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood5x5(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.WOOD, 5); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.WOOD, 5)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood9x9(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.WOOD, 9); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.WOOD, 9)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood3x3MissingCore(GameTestHelper helper) { + Set excluded = Sets.newHashSet(POS); + createChest(helper, POS, ChestMaterial.WOOD, 3, excluded); + + helper.succeedWhen(() -> assertChestInvalid(helper, POS, ChestMaterial.WOOD, 3, excluded, Sets.newHashSet())); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood3x3MissingWall(GameTestHelper helper) { + Set excluded = Sets.newHashSet(POS.above()); + createChest(helper, POS, ChestMaterial.WOOD, 3, Sets.newHashSet(excluded)); + + helper.succeedWhen(() -> assertChestInvalid(helper, POS, ChestMaterial.WOOD, 3, excluded, Sets.newHashSet())); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood3x3MissingWallMultiple(GameTestHelper helper) { + Set excluded = Sets.newHashSet(POS.above(), POS.above().above(), POS.above().north()); + createChest(helper, POS, ChestMaterial.WOOD, 3, excluded); + + helper.succeedWhen(() -> assertChestInvalid(helper, POS, ChestMaterial.WOOD, 3, excluded, Sets.newHashSet())); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalCopper5x5(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.COPPER, 5); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.COPPER, 5)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalCopper9x9(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.COPPER, 9); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.COPPER, 9)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalIron5x5(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.IRON, 5); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.IRON, 5)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalIron9x9(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.IRON, 9); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.IRON, 9)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalSilver5x5(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.SILVER, 5); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.SILVER, 5)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalSilver9x9(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.SILVER, 9); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.SILVER, 9)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalGold5x5(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.GOLD, 5); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.GOLD, 5)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalGold9x9(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.GOLD, 9); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.GOLD, 9)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalDiamond5x5(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.DIAMOND, 5); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.DIAMOND, 5)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalDiamond9x9(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.DIAMOND, 9); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.DIAMOND, 9)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalObsidian5x5(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.OBSIDIAN, 5); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.OBSIDIAN, 5)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalObsidian9x9(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.OBSIDIAN, 9); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.OBSIDIAN, 9)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood5x5HopperInsert(GameTestHelper helper) { + // For some unknown reason, this test does not work in Fabric (does work in-game only if the player is close) + // TODO: try to re-enable later + if (isFabric()) { + helper.succeed(); + return; + } + + createChest(helper, POS.above().south(), ChestMaterial.WOOD, 5); + + // Place hopper towards core + helper.setBlock(POS.above(), Blocks.HOPPER + .defaultBlockState() + .setValue(HopperBlock.FACING, Direction.SOUTH)); + + // Throw items in hopper + helper.spawnItem(Items.APPLE, POS.above().above()); + helper.spawnItem(Items.WHITE_WOOL, POS.above().above()); + helper.spawnItem(Items.ACACIA_LEAVES, POS.above().above()); + + // Expect items to be in chest + helper.succeedWhen(() -> { + assertCoreContains(helper, POS.above().south(), new ItemStack(Items.APPLE)); + assertCoreContains(helper, POS.above().south(), new ItemStack(Items.WHITE_WOOL)); + assertCoreContains(helper, POS.above().south(), new ItemStack(Items.ACACIA_LEAVES)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood5x5HopperExtract(GameTestHelper helper) { + BlockEntityColossalChest core = createChest(helper, POS.above().south(), ChestMaterial.WOOD, 5); + + // Place hopper below core + helper.setBlock(POS.south(), Blocks.HOPPER + .defaultBlockState() + .setValue(HopperBlock.FACING, Direction.SOUTH)); + + // Initialize items in core + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + core.getInventory().setItem(1, new ItemStack(Items.WHITE_WOOL)); + core.getInventory().setItem(2, new ItemStack(Items.ACACIA_LEAVES)); + + // Expect items to be in hopper + helper.succeedWhen(() -> { + assertHopperContains(helper, POS.south(), new ItemStack(Items.APPLE)); + assertHopperContains(helper, POS.south(), new ItemStack(Items.WHITE_WOOL)); + assertHopperContains(helper, POS.south(), new ItemStack(Items.ACACIA_LEAVES)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood5x5HopperInsertExtract(GameTestHelper helper) { + // For some unknown reason, this test does not work in Fabric (does work in-game only if the player is close) + // TODO: try to re-enable later + if (isFabric()) { + helper.succeed(); + return; + } + + BlockEntityColossalChest core = createChest(helper, POS.above().south(), ChestMaterial.WOOD, 5); + + // Place hopper towards core + helper.setBlock(POS.above(), Blocks.HOPPER + .defaultBlockState() + .setValue(HopperBlock.FACING, Direction.SOUTH)); + + // Place hopper below core + helper.setBlock(POS.south(), Blocks.HOPPER + .defaultBlockState() + .setValue(HopperBlock.FACING, Direction.SOUTH)); + + // Throw items in hopper + helper.spawnItem(Items.APPLE, POS.above().above()); + helper.spawnItem(Items.WHITE_WOOL, POS.above().above()); + helper.spawnItem(Items.ACACIA_LEAVES, POS.above().above()); + + // Expect items to be in hopper + helper.succeedWhen(() -> { + assertHopperContains(helper, POS.south(), new ItemStack(Items.APPLE)); + assertHopperContains(helper, POS.south(), new ItemStack(Items.WHITE_WOOL)); + assertHopperContains(helper, POS.south(), new ItemStack(Items.ACACIA_LEAVES)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood5x5Interfaces(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.WOOD, 5, Sets.newHashSet(), Sets.newHashSet(POS.north().above(), POS.south().above())); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.WOOD, 5, Sets.newHashSet(POS.north().above(), POS.south().above()), true)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalDiamond5x5Interfaces(GameTestHelper helper) { + createChest(helper, POS, ChestMaterial.DIAMOND, 5, Sets.newHashSet(), Sets.newHashSet(POS.north().above(), POS.south().above())); + + helper.succeedWhen(() -> assertChestValid(helper, POS, ChestMaterial.DIAMOND, 5, Sets.newHashSet(POS.north().above(), POS.south().above()), true)); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood3x3InterfacesMissingWall(GameTestHelper helper) { + Set excluded = Sets.newHashSet(POS.above()); + createChest(helper, POS, ChestMaterial.WOOD, 3, Sets.newHashSet(excluded), Sets.newHashSet(POS.north())); + + helper.succeedWhen(() -> assertChestInvalid(helper, POS, ChestMaterial.WOOD, 3, excluded, Sets.newHashSet(POS.north()))); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood5x5InterfacesHopperInsertExtract(GameTestHelper helper) { + // For some unknown reason, this test does not work in Fabric (does work in-game only if the player is close) + // TODO: try to re-enable later + if (isFabric()) { + helper.succeed(); + return; + } + + createChest(helper, POS.above(), ChestMaterial.WOOD, 5, Sets.newHashSet(), Sets.newHashSet(POS.offset(0, 5, 0), POS.above().south())); + + // Place hopper towards top interface + helper.setBlock(POS.offset(0, 5, 0).above(), Blocks.HOPPER + .defaultBlockState() + .setValue(HopperBlock.FACING, Direction.DOWN)); + + // Place hopper below bottom interface + helper.setBlock(POS.south(), Blocks.HOPPER + .defaultBlockState() + .setValue(HopperBlock.FACING, Direction.DOWN)); + + // Throw items in top hopper + helper.spawnItem(Items.APPLE, POS.offset(0, 5, 0).above().above()); + helper.spawnItem(Items.WHITE_WOOL, POS.offset(0, 5, 0).above().above()); + helper.spawnItem(Items.ACACIA_LEAVES, POS.offset(0, 5, 0).above().above()); + + // Expect items to be in hopper + helper.succeedWhen(() -> { + assertHopperContains(helper, POS.south(), new ItemStack(Items.APPLE)); + assertHopperContains(helper, POS.south(), new ItemStack(Items.WHITE_WOOL)); + assertHopperContains(helper, POS.south() , new ItemStack(Items.ACACIA_LEAVES)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood3x3Upgrade(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.WOOD, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.COPPER.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.COPPER.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.COPPER.getBlockWall(), 23)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult.indicateItemUse(), "Interaction must succeed"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.COPPER, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockWall(), 23)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.WOOD.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.WOOD.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.WOOD.getBlockWall(), 23)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood3x3UpgradeInsufficientItems(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.WOOD, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.COPPER.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.COPPER.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.COPPER.getBlockWall(), 22)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult == InteractionResult.FAIL, "Interaction must fail"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.WOOD, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.WOOD.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.WOOD.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.WOOD.getBlockWall(), 22)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockWall(), 22)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalCopper3x3Upgrade(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.COPPER, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.IRON.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.IRON.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.IRON.getBlockWall(), 23)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult.indicateItemUse(), "Interaction must succeed"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.IRON, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.IRON.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.IRON.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.IRON.getBlockWall(), 23)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockWall(), 23)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalIron3x3Upgrade(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.IRON, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.SILVER.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.SILVER.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.SILVER.getBlockWall(), 23)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult.indicateItemUse(), "Interaction must succeed"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.SILVER, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.SILVER.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.SILVER.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.SILVER.getBlockWall(), 23)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.IRON.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.IRON.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.IRON.getBlockWall(), 23)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalSilver3x3Upgrade(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.SILVER, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.GOLD.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.GOLD.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.GOLD.getBlockWall(), 23)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult.indicateItemUse(), "Interaction must succeed"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.GOLD, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.GOLD.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.GOLD.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.GOLD.getBlockWall(), 23)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.SILVER.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.SILVER.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.SILVER.getBlockWall(), 23)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalGold3x3Upgrade(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.GOLD, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.DIAMOND.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.DIAMOND.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.DIAMOND.getBlockWall(), 23)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult.indicateItemUse(), "Interaction must succeed"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.DIAMOND, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.DIAMOND.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.DIAMOND.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.DIAMOND.getBlockWall(), 23)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.GOLD.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.GOLD.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.GOLD.getBlockWall(), 23)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalDiamond3x3Upgrade(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.DIAMOND, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.OBSIDIAN.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.OBSIDIAN.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.OBSIDIAN.getBlockWall(), 23)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult.indicateItemUse(), "Interaction must succeed"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.OBSIDIAN, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.OBSIDIAN.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.OBSIDIAN.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.OBSIDIAN.getBlockWall(), 23)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.DIAMOND.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.DIAMOND.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.DIAMOND.getBlockWall(), 23)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalCopper3x3Downgrade(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.COPPER, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL_REVERSE); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.WOOD.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.WOOD.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.WOOD.getBlockWall(), 23)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult.indicateItemUse(), "Interaction must succeed"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.WOOD, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.WOOD.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.WOOD.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.WOOD.getBlockWall(), 23)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockWall(), 23)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalCopper3x3DowngradeInsufficientItems(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.COPPER, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.WOOD.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.WOOD.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.WOOD.getBlockWall(), 22)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult == InteractionResult.FAIL, "Interaction must fail"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.COPPER, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockWall(), 22)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.WOOD.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.WOOD.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.WOOD.getBlockWall(), 22)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalIron3x3Downgrade(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.IRON, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL_REVERSE); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.COPPER.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.COPPER.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.COPPER.getBlockWall(), 23)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult.indicateItemUse(), "Interaction must succeed"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.COPPER, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.COPPER.getBlockWall(), 23)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.IRON.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.IRON.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.IRON.getBlockWall(), 23)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalSilver3x3Downgrade(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.SILVER, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL_REVERSE); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.IRON.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.IRON.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.IRON.getBlockWall(), 23)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult.indicateItemUse(), "Interaction must succeed"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.IRON, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.IRON.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.IRON.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.IRON.getBlockWall(), 23)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.SILVER.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.SILVER.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.SILVER.getBlockWall(), 23)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalGold3x3Downgrade(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.GOLD, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL_REVERSE); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.SILVER.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.SILVER.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.SILVER.getBlockWall(), 23)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult.indicateItemUse(), "Interaction must succeed"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.SILVER, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.SILVER.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.SILVER.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.SILVER.getBlockWall(), 23)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.GOLD.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.GOLD.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.GOLD.getBlockWall(), 23)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalDiamond3x3Downgrade(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.DIAMOND, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL_REVERSE); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.GOLD.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.GOLD.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.GOLD.getBlockWall(), 23)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult.indicateItemUse(), "Interaction must succeed"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.GOLD, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.GOLD.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.GOLD.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.GOLD.getBlockWall(), 23)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.DIAMOND.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.DIAMOND.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.DIAMOND.getBlockWall(), 23)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalObsidian3x3Downgrade(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.OBSIDIAN, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Upgrade + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_UPGRADE_TOOL_REVERSE); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + player.getInventory().add(new ItemStack(ChestMaterial.DIAMOND.getBlockCore(), 1)); + player.getInventory().add(new ItemStack(ChestMaterial.DIAMOND.getBlockInterface(), 2)); + player.getInventory().add(new ItemStack(ChestMaterial.DIAMOND.getBlockWall(), 23)); + InteractionResult interactionResult = itemStack.useOn(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(POS.getCenter(), Direction.NORTH, helper.absolutePos(POS), false))); + helper.assertTrue(interactionResult.indicateItemUse(), "Interaction must succeed"); + + helper.succeedWhen(() -> { + // Chest must be transformed and keep inventory + assertChestValid(helper, POS, ChestMaterial.DIAMOND, 3, interfaces, false); + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + + // Player items must be swapped + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.DIAMOND.getBlockCore(), 1)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.DIAMOND.getBlockInterface(), 2)); + assertPlayerInventoryNotContains(helper, player, new ItemStack(ChestMaterial.DIAMOND.getBlockWall(), 23)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.OBSIDIAN.getBlockCore(), 1)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.OBSIDIAN.getBlockInterface(), 2)); + assertPlayerInventoryContains(helper, player, new ItemStack(ChestMaterial.OBSIDIAN.getBlockWall(), 23)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood3x3BreakPlaceWall(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.WOOD, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Break wall + destroyBlock(helper, POS.east()); + + // Replace wall + helper.setBlock(POS.east(), ChestMaterial.WOOD.getBlockWall()); + + helper.succeedWhen(() -> { + assertChestValid(helper, POS, ChestMaterial.WOOD, 3, interfaces, false); + + // Chest must still contain item, and there must be no dropped items on the ground + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + helper.assertEntityNotPresent(EntityType.ITEM); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood3x3BreakPlaceInterface(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS, ChestMaterial.WOOD, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + + // Break interface + destroyBlock(helper, POS.east().above()); + + // Replace interface + helper.setBlock(POS.east().above(), ChestMaterial.WOOD.getBlockInterface()); + + helper.succeedWhen(() -> { + assertChestValid(helper, POS, ChestMaterial.WOOD, 3, interfaces, false); + + // Chest must still contain item, and there must be no dropped items on the ground + assertCoreContains(helper, POS, new ItemStack(Items.APPLE)); + helper.assertEntityNotPresent(EntityType.ITEM); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood3x3BreakPlaceCore(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.offset(4, 1, 4).east().above(), POS.offset(4, 1, 4).south().above()); + BlockEntityColossalChest core = createChest(helper, POS.offset(4, 1, 4), ChestMaterial.WOOD, 3, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + core.getInventory().setItem(1, new ItemStack(Items.ACACIA_LEAVES)); + core.getInventory().setItem(2, new ItemStack(Items.WHITE_WOOL)); + + // Break core + destroyBlock(helper, POS.offset(4, 1, 4)); + + // Replace core + helper.setBlock(POS.offset(4, 1, 4), ChestMaterial.WOOD.getBlockCore()); + + helper.succeedWhen(() -> { + // Chest must not contain item, and all items must be dropped on the ground + assertChestValid(helper, POS.offset(4, 1, 4), ChestMaterial.WOOD, 3, interfaces, true); + helper.assertItemEntityPresent(Items.APPLE); + helper.assertItemEntityPresent(Items.ACACIA_LEAVES); + helper.assertItemEntityPresent(Items.WHITE_WOOL); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testColossalWood3x3DestroyTnt(GameTestHelper helper) { + HashSet interfaces = Sets.newHashSet(POS.east().above(), POS.south().above()); + BlockEntityColossalChest core = createChest(helper, POS.above(), ChestMaterial.WOOD, 2, Sets.newHashSet(), interfaces); + + // Insert item + core.getInventory().setItem(0, new ItemStack(Items.APPLE)); + core.getInventory().setItem(1, new ItemStack(Items.ACACIA_LEAVES)); + + // Destroy chest with TNT + helper.setBlock(POS.above().offset(2, 0, 0), Blocks.TNT); + helper.setBlock(POS.above().offset(2, 1, 0), Blocks.REDSTONE_BLOCK); + + helper.succeedWhen(() -> { + // Chest and contents must be dropped + helper.assertItemEntityPresent(Items.APPLE); + helper.assertItemEntityPresent(Items.ACACIA_LEAVES); + helper.assertItemEntityPresent(ChestMaterial.WOOD.getBlockCore().asItem()); + helper.assertItemEntityPresent(ChestMaterial.WOOD.getBlockInterface().asItem()); + helper.assertItemEntityPresent(ChestMaterial.WOOD.getBlockWall().asItem()); + }); + } + + protected BlockEntityColossalChest createChest(GameTestHelper helper, BlockPos pos, ChestMaterial material, int dimension) { + return this.createChest(helper, pos, material, dimension, Sets.newHashSet()); + } + + protected BlockEntityColossalChest createChest(GameTestHelper helper, BlockPos pos, ChestMaterial material, int dimension, Set exclude) { + return createChest(helper, pos, material, dimension, exclude, Sets.newHashSet()); + } + + protected BlockEntityColossalChest createChest(GameTestHelper helper, BlockPos pos, ChestMaterial material, int dimension, Set exclude, Set interfaces) { + for (int x = 0; x < dimension; x++) { + for (int y = 0; y < dimension; y++) { + for (int z = 0; z < dimension; z++) { + BlockPos poso = pos.offset(x, y, z); + if (!exclude.contains(poso)) { + if (x == 0 && y == 0 && z == 0) { + helper.setBlock(poso, material.getBlockCore()); + } else if (x == 0 || y == 0 || z == 0 || x == dimension - 1 || y == dimension - 1 || z == dimension - 1) { + if (interfaces.contains(poso)) { + helper.setBlock(poso, material.getBlockInterface()); + } else { + helper.setBlock(poso, material.getBlockWall()); + } + } + } + } + } + } + return exclude.contains(pos) ? null : helper.getBlockEntity(pos); + } + + protected int chestSize(int dimension, ChestMaterial material) { + return (int) Math.ceil((Math.pow(dimension, 3) * 27) * material.getInventoryMultiplier() / 9) * 9; + } + + protected void assertChestValid(GameTestHelper helper, BlockPos pos, ChestMaterial material, int dimension) { + assertChestValid(helper, pos, material, dimension, Sets.newHashSet(), true); + } + + protected void assertChestValid(GameTestHelper helper, BlockPos pos, ChestMaterial material, int dimension, Set interfaces, boolean mustBeEmpty) { + int inventorySize = chestSize(dimension, material); + for (int x = 0; x < dimension; x++) { + for (int y = 0; y < dimension; y++) { + for (int z = 0; z < dimension; z++) { + BlockPos poso = pos.offset(x, y, z); + if (x == 0 && y == 0 && z == 0) { + helper.assertBlockPresent(material.getBlockCore(), poso); + helper.assertBlockProperty(poso, ColossalChest.ENABLED, true); + helper.assertBlockEntityData(poso, (BlockEntityColossalChest be) -> be.getInventory().getContainerSize() == inventorySize, () -> "Inventory is not of size " + inventorySize); + if (mustBeEmpty) { + helper.assertBlockEntityData(poso, (BlockEntityColossalChest be) -> be.getInventory().isEmpty(), () -> "Inventory is not empty"); + } + } else if (x == 0 || y == 0 || z == 0 || x == dimension - 1 || y == dimension - 1 || z == dimension - 1) { + if (interfaces.contains(poso)) { + helper.assertBlockPresent(material.getBlockInterface(), poso); + helper.assertBlockProperty(poso, Interface.ENABLED, true); + } else { + helper.assertBlockPresent(material.getBlockWall(), poso); + helper.assertBlockProperty(poso, ChestWall.ENABLED, true); + } + } + } + } + } + } + + protected void assertChestInvalid(GameTestHelper helper, BlockPos pos, ChestMaterial material, int dimension, Set exclude, Set interfaces) { + for (int x = 0; x < dimension; x++) { + for (int y = 0; y < dimension; y++) { + for (int z = 0; z < dimension; z++) { + BlockPos poso = pos.offset(x, y, z); + if (exclude.contains(poso)) { + helper.assertBlockPresent(Blocks.AIR, poso); + } else { + if (x == 0 && y == 0 && z == 0) { + helper.assertBlockPresent(material.getBlockCore(), poso); + helper.assertBlockProperty(poso, ColossalChest.ENABLED, false); + helper.assertBlockEntityData(poso, (BlockEntityColossalChest be) -> be.getInventory().getContainerSize() == 0, () -> "Inventory is not of size zero"); + helper.assertBlockEntityData(poso, (BlockEntityColossalChest be) -> be.getInventory().isEmpty(), () -> "Inventory is not empty"); + } else if (x == 0 || y == 0 || z == 0 || x == dimension - 1 || y == dimension - 1 || z == dimension - 1) { + if (interfaces.contains(poso)) { + helper.assertBlockPresent(material.getBlockInterface(), poso); + helper.assertBlockProperty(poso, Interface.ENABLED, false); + } else { + helper.assertBlockPresent(material.getBlockWall(), poso); + helper.assertBlockProperty(poso, ChestWall.ENABLED, false); + } + } + } + } + } + } + } + + protected void assertHopperContains(GameTestHelper helper, BlockPos pos, ItemStack itemStack) { + helper.assertBlockEntityData(pos, (HopperBlockEntity be) -> { + for (int i = 0; i < be.getContainerSize(); i++) { + if (ItemStack.isSameItemSameComponents(be.getItem(i), itemStack)) { + return true; + } + } + return false; + }, () -> "Hopper does not contain item"); + } + + protected void assertCoreContains(GameTestHelper helper, BlockPos pos, ItemStack itemStack) { + helper.assertBlockEntityData(pos, (BlockEntityColossalChest be) -> { + for (int i = 0; i < be.getInventory().getContainerSize(); i++) { + if (ItemStack.isSameItemSameComponents(be.getInventory().getItem(i), itemStack)) { + return true; + } + } + return false; + }, () -> "Colossal chest core does not contain item"); + } + + protected void assertPlayerInventoryContains(GameTestHelper helper, Player player, ItemStack itemStack) { + boolean contains = false; + for (int i = 0; i < player.getInventory().getContainerSize(); i++) { + if (ItemStack.isSameItemSameComponents(player.getInventory().getItem(i), itemStack)) { + contains = true; + break; + } + } + helper.assertTrue(contains, "Player does not contain item"); + } + + protected void assertPlayerInventoryNotContains(GameTestHelper helper, Player player, ItemStack itemStack) { + boolean contains = false; + for (int i = 0; i < player.getInventory().getContainerSize(); i++) { + if (ItemStack.isSameItemSameComponents(player.getInventory().getItem(i), itemStack)) { + contains = true; + break; + } + } + helper.assertFalse(contains, "Player does contain item"); + } + + protected void destroyBlock(GameTestHelper helper, BlockPos pos) { + BlockState blockState = helper.getBlockState(pos); + boolean removed = helper.getLevel().removeBlock(helper.absolutePos(pos), false); + if (removed) { + blockState.getBlock().destroy(helper.getLevel(), helper.absolutePos(pos), blockState); + } + } + + protected boolean isFabric() { + try { + Class.forName("net.fabricmc.fabric.api.transfer.v1.item.ItemStorage"); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + +} diff --git a/loader-common/src/main/java/org/cyclops/colossalchests/item/ItemUpgradeTool.java b/loader-common/src/main/java/org/cyclops/colossalchests/item/ItemUpgradeTool.java index 0ae68b69..4a9d2940 100644 --- a/loader-common/src/main/java/org/cyclops/colossalchests/item/ItemUpgradeTool.java +++ b/loader-common/src/main/java/org/cyclops/colossalchests/item/ItemUpgradeTool.java @@ -187,7 +187,9 @@ && consumeItems(player, requiredWalls, true))) { tileInterface.setCorePosition(coreLocation.get()); } - RegistryEntries.TRIGGER_CHEST_FORMED.value().test((ServerPlayer) player, newType, size.getX() + 1); + if (player instanceof ServerPlayer serverPlayer) { + RegistryEntries.TRIGGER_CHEST_FORMED.value().test(serverPlayer, newType, size.getX() + 1); + } } // Add the lower tier items to the players inventory again. diff --git a/loader-common/src/main/resources/data/colossalchests/structure/empty10.nbt b/loader-common/src/main/resources/data/colossalchests/structure/empty10.nbt new file mode 100644 index 00000000..11ea2c5d Binary files /dev/null and b/loader-common/src/main/resources/data/colossalchests/structure/empty10.nbt differ diff --git a/loader-fabric/src/main/resources/fabric.mod.json b/loader-fabric/src/main/resources/fabric.mod.json index 149accbb..a50b22b4 100644 --- a/loader-fabric/src/main/resources/fabric.mod.json +++ b/loader-fabric/src/main/resources/fabric.mod.json @@ -20,6 +20,9 @@ "entrypoints": { "main": [ "org.cyclops.colossalchests.ColossalChestsFabric" + ], + "fabric-gametest": [ + "org.cyclops.colossalchests.gametest.GameTestsCommon" ] }, "accessWidener" : "colossalchests.accesswidener", diff --git a/loader-forge/src/main/java/org/cyclops/colossalchests/gametest/GameTestsLoaderForge.java b/loader-forge/src/main/java/org/cyclops/colossalchests/gametest/GameTestsLoaderForge.java new file mode 100644 index 00000000..65dc46d4 --- /dev/null +++ b/loader-forge/src/main/java/org/cyclops/colossalchests/gametest/GameTestsLoaderForge.java @@ -0,0 +1,22 @@ +package org.cyclops.colossalchests.gametest; + +import net.minecraft.gametest.framework.GameTestGenerator; +import net.minecraft.gametest.framework.TestFunction; +import net.minecraftforge.gametest.GameTestHolder; +import org.cyclops.cyclopscore.gametest.GameTestLoaderHelpers; +import org.cyclops.colossalchests.Reference; + +import java.util.Collection; + +/** + * @author rubensworks + */ +@GameTestHolder(Reference.MOD_ID) +public class GameTestsLoaderForge extends GameTestsCommon { + @GameTestGenerator + public Collection generateCommonTests() throws InstantiationException, IllegalAccessException { + return GameTestLoaderHelpers.generateCommonTests(Reference.MOD_ID, new Class[]{ + GameTestsCommon.class + }); + } +} diff --git a/loader-neoforge/src/main/java/org/cyclops/colossalchests/gametest/GameTestsLoaderNeoForge.java b/loader-neoforge/src/main/java/org/cyclops/colossalchests/gametest/GameTestsLoaderNeoForge.java new file mode 100644 index 00000000..901a66f9 --- /dev/null +++ b/loader-neoforge/src/main/java/org/cyclops/colossalchests/gametest/GameTestsLoaderNeoForge.java @@ -0,0 +1,22 @@ +package org.cyclops.colossalchests.gametest; + +import net.minecraft.gametest.framework.GameTestGenerator; +import net.minecraft.gametest.framework.TestFunction; +import net.neoforged.neoforge.gametest.GameTestHolder; +import org.cyclops.colossalchests.Reference; +import org.cyclops.cyclopscore.gametest.GameTestLoaderHelpers; + +import java.util.Collection; + +/** + * @author rubensworks + */ +@GameTestHolder(Reference.MOD_ID) +public class GameTestsLoaderNeoForge extends GameTestsCommon { + @GameTestGenerator + public Collection generateCommonTests() throws InstantiationException, IllegalAccessException { + return GameTestLoaderHelpers.generateCommonTests(Reference.MOD_ID, new Class[]{ + GameTestsCommon.class + }); + } +}