diff --git a/gradle.properties b/gradle.properties index 9e85510..222bebd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -32,7 +32,7 @@ neoforge_loader_version_range=[4,) neoforge_update_json_url=https://raw.githubusercontent.com/CyclopsMC/Versions/master/neoforge_update/structured-crafting.json # Forge -forge_version=52.0.3 +forge_version=52.0.24 forge_loader_version_range=[2,) forge_update_json_url=https://raw.githubusercontent.com/CyclopsMC/Versions/master/forge_update/structured-crafting.json diff --git a/loader-common/src/main/java/org/cyclops/structuredcrafting/gametest/GameTestsCommon.java b/loader-common/src/main/java/org/cyclops/structuredcrafting/gametest/GameTestsCommon.java new file mode 100644 index 0000000..e88f298 --- /dev/null +++ b/loader-common/src/main/java/org/cyclops/structuredcrafting/gametest/GameTestsCommon.java @@ -0,0 +1,252 @@ +package org.cyclops.structuredcrafting.gametest; + +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.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.ChestBlockEntity; +import org.cyclops.structuredcrafting.Reference; +import org.cyclops.structuredcrafting.RegistryEntries; +import org.cyclops.structuredcrafting.block.BlockStructuredCrafter; + +/** + * @author rubensworks + */ +public class GameTestsCommon { + + public static final String TEMPLATE_EMPTY = Reference.MOD_ID + ":empty10"; + public static final BlockPos POS = BlockPos.ZERO; + + @GameTest(template = TEMPLATE_EMPTY) + public void testPlacementDirection(GameTestHelper helper) { + Player player = helper.makeMockPlayer(GameType.SURVIVAL); + ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_STRUCTURED_CRAFTER.value()); + player.setItemInHand(InteractionHand.MAIN_HAND, itemStack); + helper.placeAt(player, itemStack, POS, Direction.SOUTH); + + helper.succeedIf(() -> { + helper.assertBlockPresent(RegistryEntries.BLOCK_STRUCTURED_CRAFTER.value(), POS.south()); + helper.assertBlockProperty(POS.south(), BlockStructuredCrafter.FACING, Direction.NORTH); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testCraftFromWorldToWorldStairs(GameTestHelper helper) { + helper.setBlock(POS.offset(2, 2, 2), RegistryEntries.BLOCK_STRUCTURED_CRAFTER.value() + .defaultBlockState() + .setValue(BlockStructuredCrafter.FACING, Direction.NORTH)); + + // Define inputs + helper.setBlock(POS.offset(3, 1, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(2, 1, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(1, 1, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(3, 2, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(2, 2, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(3, 3, 3), Blocks.OAK_PLANKS); + + // Activate crafter + helper.setBlock(POS.offset(1, 2, 2), Blocks.REDSTONE_BLOCK); + + helper.succeedWhen(() -> { + // Result + helper.assertBlockPresent(Blocks.OAK_STAIRS, POS.offset(2, 2, 1)); + + // Inputs must be consumed + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(3, 1, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(2, 1, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(1, 1, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(3, 2, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(2, 2, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(3, 3, 3)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testCraftFromWorldToWorldChest(GameTestHelper helper) { + helper.setBlock(POS.offset(2, 2, 2), RegistryEntries.BLOCK_STRUCTURED_CRAFTER.value() + .defaultBlockState() + .setValue(BlockStructuredCrafter.FACING, Direction.NORTH)); + + // Define inputs + helper.setBlock(POS.offset(3, 1, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(2, 1, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(1, 1, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(3, 2, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(1, 2, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(3, 3, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(2, 3, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(1, 3, 3), Blocks.OAK_PLANKS); + + // Activate crafter + helper.setBlock(POS.offset(1, 2, 2), Blocks.REDSTONE_BLOCK); + + helper.succeedWhen(() -> { + // Result + helper.assertBlockPresent(Blocks.CHEST, POS.offset(2, 2, 1)); + + // Inputs must be consumed + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(3, 1, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(2, 1, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(1, 1, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(3, 2, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(1, 2, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(3, 3, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(2, 3, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(1, 3, 3)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testCraftFromWorldToWorldChestTags(GameTestHelper helper) { + helper.setBlock(POS.offset(2, 2, 2), RegistryEntries.BLOCK_STRUCTURED_CRAFTER.value() + .defaultBlockState() + .setValue(BlockStructuredCrafter.FACING, Direction.NORTH)); + + // Define inputs + helper.setBlock(POS.offset(3, 1, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(2, 1, 3), Blocks.BIRCH_PLANKS); + helper.setBlock(POS.offset(1, 1, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(3, 2, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(1, 2, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(3, 3, 3), Blocks.BAMBOO_PLANKS); + helper.setBlock(POS.offset(2, 3, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(1, 3, 3), Blocks.OAK_PLANKS); + + // Activate crafter + helper.setBlock(POS.offset(1, 2, 2), Blocks.REDSTONE_BLOCK); + + helper.succeedWhen(() -> { + // Result + helper.assertBlockPresent(Blocks.CHEST, POS.offset(2, 2, 1)); + + // Inputs must be consumed + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(3, 1, 3)); + helper.assertBlockNotPresent(Blocks.BIRCH_PLANKS, POS.offset(2, 1, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(1, 1, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(3, 2, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(1, 2, 3)); + helper.assertBlockNotPresent(Blocks.BAMBOO_PLANKS, POS.offset(3, 3, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(2, 3, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(1, 3, 3)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testCraftFromChestsToWorldStairs(GameTestHelper helper) { + helper.setBlock(POS.offset(2, 2, 2), RegistryEntries.BLOCK_STRUCTURED_CRAFTER.value() + .defaultBlockState() + .setValue(BlockStructuredCrafter.FACING, Direction.NORTH)); + + // Define inputs + setChestWithItem(helper, POS.offset(3, 1, 3), new ItemStack(Blocks.OAK_PLANKS)); + setChestWithItem(helper, POS.offset(2, 1, 3), new ItemStack(Blocks.OAK_PLANKS)); + setChestWithItem(helper, POS.offset(1, 1, 3), new ItemStack(Blocks.OAK_PLANKS)); + setChestWithItem(helper, POS.offset(3, 2, 3), new ItemStack(Blocks.OAK_PLANKS)); + setChestWithItem(helper, POS.offset(2, 2, 3), new ItemStack(Blocks.OAK_PLANKS)); + setChestWithItem(helper, POS.offset(3, 3, 3), new ItemStack(Blocks.OAK_PLANKS)); + + // Activate crafter + helper.setBlock(POS.offset(1, 2, 2), Blocks.REDSTONE_BLOCK); + + helper.succeedWhen(() -> { + // Result + helper.assertBlockPresent(Blocks.OAK_STAIRS, POS.offset(2, 2, 1)); + + // Inputs must be consumed + assertChestEmpty(helper, POS.offset(3, 1, 3)); + assertChestEmpty(helper, POS.offset(2, 1, 3)); + assertChestEmpty(helper, POS.offset(1, 1, 3)); + assertChestEmpty(helper, POS.offset(3, 2, 3)); + assertChestEmpty(helper, POS.offset(2, 2, 3)); + assertChestEmpty(helper, POS.offset(3, 3, 3)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testCraftFromWorldToChestStairs(GameTestHelper helper) { + helper.setBlock(POS.offset(2, 2, 2), RegistryEntries.BLOCK_STRUCTURED_CRAFTER.value() + .defaultBlockState() + .setValue(BlockStructuredCrafter.FACING, Direction.NORTH)); + + // Define inputs + helper.setBlock(POS.offset(3, 1, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(2, 1, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(1, 1, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(3, 2, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(2, 2, 3), Blocks.OAK_PLANKS); + helper.setBlock(POS.offset(3, 3, 3), Blocks.OAK_PLANKS); + + // Set output chest + helper.setBlock(POS.offset(2, 2, 1), Blocks.CHEST); + + // Activate crafter + helper.setBlock(POS.offset(1, 2, 2), Blocks.REDSTONE_BLOCK); + + helper.succeedWhen(() -> { + // Result + assertChestContains(helper, POS.offset(2, 2, 1), new ItemStack(Blocks.OAK_STAIRS)); + + // Inputs must be consumed + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(3, 1, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(2, 1, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(1, 1, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(3, 2, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(2, 2, 3)); + helper.assertBlockNotPresent(Blocks.OAK_PLANKS, POS.offset(3, 3, 3)); + }); + } + + @GameTest(template = TEMPLATE_EMPTY) + public void testCraftFromChestsToChestStairs(GameTestHelper helper) { + helper.setBlock(POS.offset(2, 2, 2), RegistryEntries.BLOCK_STRUCTURED_CRAFTER.value() + .defaultBlockState() + .setValue(BlockStructuredCrafter.FACING, Direction.NORTH)); + + // Define inputs + setChestWithItem(helper, POS.offset(3, 1, 3), new ItemStack(Blocks.OAK_PLANKS)); + setChestWithItem(helper, POS.offset(2, 1, 3), new ItemStack(Blocks.OAK_PLANKS)); + setChestWithItem(helper, POS.offset(1, 1, 3), new ItemStack(Blocks.OAK_PLANKS)); + setChestWithItem(helper, POS.offset(3, 2, 3), new ItemStack(Blocks.OAK_PLANKS)); + setChestWithItem(helper, POS.offset(2, 2, 3), new ItemStack(Blocks.OAK_PLANKS)); + setChestWithItem(helper, POS.offset(3, 3, 3), new ItemStack(Blocks.OAK_PLANKS)); + + // Set output chest + helper.setBlock(POS.offset(2, 2, 1), Blocks.CHEST); + + // Activate crafter + helper.setBlock(POS.offset(1, 2, 2), Blocks.REDSTONE_BLOCK); + + helper.succeedWhen(() -> { + // Result + assertChestContains(helper, POS.offset(2, 2, 1), new ItemStack(Blocks.OAK_STAIRS)); + + // Inputs must be consumed + assertChestEmpty(helper, POS.offset(3, 1, 3)); + assertChestEmpty(helper, POS.offset(2, 1, 3)); + assertChestEmpty(helper, POS.offset(1, 1, 3)); + assertChestEmpty(helper, POS.offset(3, 2, 3)); + assertChestEmpty(helper, POS.offset(2, 2, 3)); + assertChestEmpty(helper, POS.offset(3, 3, 3)); + }); + } + + protected void setChestWithItem(GameTestHelper helper, BlockPos pos, ItemStack itemStack) { + helper.setBlock(pos, Blocks.CHEST); + ChestBlockEntity chest = helper.getBlockEntity(pos); + chest.setItem(0, itemStack); + } + + protected void assertChestEmpty(GameTestHelper helper, BlockPos pos) { + helper.assertBlockEntityData(pos, (ChestBlockEntity chest) -> chest.isEmpty(), () -> "Chest is not empty"); + } + + protected void assertChestContains(GameTestHelper helper, BlockPos pos, ItemStack itemStack) { + helper.assertBlockEntityData(pos, (ChestBlockEntity chest) -> ItemStack.isSameItemSameComponents(chest.getItem(0), itemStack), () -> "Chest is not empty"); + } + +} diff --git a/loader-common/src/main/resources/data/structuredcrafting/structure/empty10.nbt b/loader-common/src/main/resources/data/structuredcrafting/structure/empty10.nbt new file mode 100644 index 0000000..11ea2c5 Binary files /dev/null and b/loader-common/src/main/resources/data/structuredcrafting/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 d845bd0..aead4db 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.structuredcrafting.StructuredCraftingFabric" + ], + "fabric-gametest": [ + "org.cyclops.structuredcrafting.gametest.GameTestsCommon" ] }, diff --git a/loader-forge/src/main/java/org/cyclops/structuredcrafting/gametest/GameTestsLoaderForge.java b/loader-forge/src/main/java/org/cyclops/structuredcrafting/gametest/GameTestsLoaderForge.java new file mode 100644 index 0000000..31f26af --- /dev/null +++ b/loader-forge/src/main/java/org/cyclops/structuredcrafting/gametest/GameTestsLoaderForge.java @@ -0,0 +1,22 @@ +package org.cyclops.structuredcrafting.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.structuredcrafting.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/structuredcrafting/gametest/GameTestsLoaderNeoForge.java b/loader-neoforge/src/main/java/org/cyclops/structuredcrafting/gametest/GameTestsLoaderNeoForge.java new file mode 100644 index 0000000..fff3a90 --- /dev/null +++ b/loader-neoforge/src/main/java/org/cyclops/structuredcrafting/gametest/GameTestsLoaderNeoForge.java @@ -0,0 +1,22 @@ +package org.cyclops.structuredcrafting.gametest; + +import net.minecraft.gametest.framework.GameTestGenerator; +import net.minecraft.gametest.framework.TestFunction; +import net.neoforged.neoforge.gametest.GameTestHolder; +import org.cyclops.cyclopscore.gametest.GameTestLoaderHelpers; +import org.cyclops.structuredcrafting.Reference; + +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 + }); + } +}