Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,89 +2,93 @@

import com.gregtechceu.gtceu.GTCEu;
import com.gregtechceu.gtceu.api.GTValues;
import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity;
import com.gregtechceu.gtceu.api.capability.recipe.IO;
import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability;
import com.gregtechceu.gtceu.api.machine.MetaMachine;
import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine;
import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockControllerMachine;
import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine;
import com.gregtechceu.gtceu.api.recipe.GTRecipe;
import com.gregtechceu.gtceu.api.recipe.GTRecipeType;
import com.gregtechceu.gtceu.common.machine.multiblock.part.ItemBusPartMachine;
import com.gregtechceu.gtceu.gametest.util.TestUtils;

import net.minecraft.core.BlockPos;
import net.minecraft.gametest.framework.BeforeBatch;
import net.minecraft.gametest.framework.GameTest;
import net.minecraft.gametest.framework.GameTestHelper;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.gametest.GameTestHolder;
import net.minecraftforge.gametest.PrefixGameTestTemplate;

import static com.gregtechceu.gtceu.gametest.util.TestUtils.getMetaMachine;

@PrefixGameTestTemplate(false)
@GameTestHolder(GTCEu.MOD_ID)
public class RecipeLogicTest {

public static NotifiableItemStackHandler getInputSlot(IRecipeLogicMachine recipeLogicMachine) {
RecipeHandlerList recipeHandlerList = recipeLogicMachine
.getCapabilitiesProxy()
.get(IO.IN)
.stream()
.filter(x -> x.hasCapability(ItemRecipeCapability.CAP))
.toList()
.get(0);
NotifiableItemStackHandler itemStackHandler = (NotifiableItemStackHandler) recipeHandlerList
.getCapability(ItemRecipeCapability.CAP).get(0);
return itemStackHandler;
private static GTRecipeType LCR_RECIPE_TYPE;
private static GTRecipeType CR_RECIPE_TYPE;

@BeforeBatch(batch = "RecipeLogic")
public static void prepare(ServerLevel level) {
LCR_RECIPE_TYPE = TestUtils.createRecipeType("recipe_logic_test_lcr");
CR_RECIPE_TYPE = TestUtils.createRecipeType("recipe_logic_test_cr");

LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE
.recipeBuilder(GTCEu.id("test_multiblock_recipelogic"))
.inputItems(new ItemStack(Blocks.COBBLESTONE))
.outputItems(new ItemStack(Blocks.STONE))
.EUt(GTValues.VA[GTValues.HV]).duration(1)
.buildRawRecipe());
LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE
.recipeBuilder(GTCEu.id("test_multiblock_recipelogic_16_items"))
.inputItems(new ItemStack(Blocks.STONE, 16))
.outputItems(new ItemStack(Blocks.STONE))
.EUt(GTValues.VA[GTValues.HV]).duration(1)
.buildRawRecipe());

CR_RECIPE_TYPE.getLookup().addRecipe(CR_RECIPE_TYPE
.recipeBuilder(GTCEu.id("test_singleblock_recipelogic"))
.inputItems(new ItemStack(Blocks.COBBLESTONE))
.outputItems(new ItemStack(Blocks.STONE))
.EUt(GTValues.VA[GTValues.HV]).duration(1)
.buildRawRecipe());
}

public static NotifiableItemStackHandler getOutputSlot(IRecipeLogicMachine recipeLogicMachine) {
RecipeHandlerList recipeHandlerList = recipeLogicMachine
.getCapabilitiesProxy()
.get(IO.OUT)
.stream()
.filter(x -> x.hasCapability(ItemRecipeCapability.CAP))
.toList()
.get(0);
NotifiableItemStackHandler itemStackHandler = (NotifiableItemStackHandler) recipeHandlerList
.getCapability(ItemRecipeCapability.CAP).get(0);
return itemStackHandler;
private record BusHolder(ItemBusPartMachine inputBus1, ItemBusPartMachine inputBus2, ItemBusPartMachine outputBus1,
WorkableMultiblockMachine controller) {}

/**
* Retrieves the busses for this specific template and force a multiblock structure check
*
* @param helper the GameTestHelper
* @return the busses, in the BusHolder record.
*/
private static RecipeLogicTest.BusHolder getBussesAndForm(GameTestHelper helper) {
WorkableMultiblockMachine controller = (WorkableMultiblockMachine) getMetaMachine(
helper.getBlockEntity(new BlockPos(1, 2, 0)));
TestUtils.formMultiblock(controller);
controller.setRecipeType(LCR_RECIPE_TYPE);
ItemBusPartMachine inputBus1 = (ItemBusPartMachine) getMetaMachine(
helper.getBlockEntity(new BlockPos(2, 1, 0)));
ItemBusPartMachine inputBus2 = (ItemBusPartMachine) getMetaMachine(
helper.getBlockEntity(new BlockPos(2, 2, 0)));
ItemBusPartMachine outputBus1 = (ItemBusPartMachine) getMetaMachine(
helper.getBlockEntity(new BlockPos(0, 1, 0)));
return new RecipeLogicTest.BusHolder(inputBus1, inputBus2, outputBus1, controller);
}

@GameTest(template = "lcr")
@GameTest(template = "lcr_input_separation", batch = "RecipeLogic")
public static void recipeLogicMultiBlockTest(GameTestHelper helper) {
BlockEntity holder = helper.getBlockEntity(new BlockPos(1, 2, 0));
if (!(holder instanceof MetaMachineBlockEntity metaMachineBlockEntity)) {
helper.fail("wrong block at relative pos [1,2,0]!");
return;
}
MetaMachine machine = metaMachineBlockEntity.getMetaMachine();
if (!(machine instanceof IRecipeLogicMachine recipeLogicMachine)) {
helper.fail("wrong machine in MetaMachineBlockEntity!");
return;
}
if (!(machine instanceof MultiblockControllerMachine controller)) {
helper.fail("wrong machine in MetaMachineBlockEntity!");
return;
}
TestUtils.formMultiblock(controller);

helper.assertTrue(controller.isFormed(), "Controller didn't form after structure check");
helper.assertTrue(controller.getParts().size() == 4,
"Controller didn't register all 4 parts after structure check");
RecipeLogicTest.BusHolder busHolder = getBussesAndForm(helper);

// Force insert the recipe into the manager.
GTRecipeType type = recipeLogicMachine.getRecipeType();
type.getLookup().removeAllRecipes();
type.getLookup().addRecipe(type
.recipeBuilder(GTCEu.id("test_multiblock_recipelogic"))
.inputItems(new ItemStack(Blocks.COBBLESTONE))
.outputItems(new ItemStack(Blocks.STONE))
.EUt(GTValues.VA[GTValues.UV]).duration(1)
// NBT has a schematic in it with an UV energy input hatch
.buildRawRecipe());
helper.assertTrue(busHolder.controller.isFormed(), "Controller didn't form after structure check");
helper.assertTrue(busHolder.controller.getParts().size() == 6,
"Controller didn't register all 6 parts after structure check, only registered " +
busHolder.controller.getParts().size());

RecipeLogic recipeLogic = recipeLogicMachine.getRecipeLogic();
RecipeLogic recipeLogic = busHolder.controller.getRecipeLogic();

recipeLogic.findAndHandleRecipe();

Expand All @@ -94,11 +98,10 @@ public static void recipeLogicMultiBlockTest(GameTestHelper helper) {
"Recipe logic has somehow found a recipe, when there should be none");

// Put an item in the inventory that will trigger recipe recheck
NotifiableItemStackHandler inputSlots = getInputSlot(recipeLogicMachine);
NotifiableItemStackHandler outputSlots = getOutputSlot(recipeLogicMachine);
NotifiableItemStackHandler inputSlots = busHolder.inputBus1.getInventory();
NotifiableItemStackHandler outputSlots = busHolder.outputBus1.getInventory();

inputSlots.insertItem(0, new ItemStack(Blocks.COBBLESTONE, 16), false);
inputSlots.onContentsChanged();

recipeLogic.findAndHandleRecipe();
helper.assertFalse(recipeLogic.getLastRecipe() == null,
Expand All @@ -114,7 +117,7 @@ public static void recipeLogicMultiBlockTest(GameTestHelper helper) {
recipeLogic.serverTick();
helper.assertTrue(recipeLogic.getLastRecipe().equals(prev), "lastRecipe is wrong");
helper.assertTrue(
TestUtils.isItemStackEqual(getOutputSlot(recipeLogicMachine).getStackInSlot(0),
TestUtils.isItemStackEqual(outputSlots.getStackInSlot(0),
new ItemStack(Blocks.STONE, 1)),
"wrong output stack.");
helper.assertTrue(recipeLogic.isActive(), "RecipeLogic is not active, when it should be.");
Expand All @@ -140,38 +143,30 @@ public static void recipeLogicMultiBlockTest(GameTestHelper helper) {
helper.assertTrue(recipeLogic.isActive(), "RecipeLogic didn't start running again");
recipeLogic.serverTick();
helper.assertTrue(
TestUtils.isItemStackEqual(getOutputSlot(recipeLogicMachine).getStackInSlot(0),
TestUtils.isItemStackEqual(outputSlots.getStackInSlot(0),
new ItemStack(Blocks.STONE, 1)),
"Wrong stack.");

// Finish.
helper.succeed();
}

@GameTest(template = "singleblock_chem_reactor")
// spotless:off
// Blocked by LDLib sync issues
/*
@GameTest(template = "singleblock_charged_cr", batch = "RecipeLogic")
public static void recipeLogicSingleBlockTest(GameTestHelper helper) {
BlockEntity holder = helper.getBlockEntity(new BlockPos(0, 1, 0));
if (!(holder instanceof MetaMachineBlockEntity metaMachineBlockEntity)) {
helper.fail("wrong block at relative pos [0,1,0]!");
return;
}
MetaMachine machine = metaMachineBlockEntity.getMetaMachine();
if (!(machine instanceof IRecipeLogicMachine recipeLogicMachine)) {
helper.fail("wrong machine in MetaMachineBlockEntity!");
return;
}
WorkableTieredMachine machine = (WorkableTieredMachine) getMetaMachine(
helper.getBlockEntity(new BlockPos(0, 1, 0)));

machine.setRecipeType(CR_RECIPE_TYPE);
NotifiableItemStackHandler inputSlots = (NotifiableItemStackHandler) machine
.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).get(0);
NotifiableItemStackHandler outputSlots = (NotifiableItemStackHandler) machine
.getCapabilitiesFlat(IO.OUT, ItemRecipeCapability.CAP).get(0);

// force insert the recipe into the manager.
GTRecipeType type = recipeLogicMachine.getRecipeType();
type.getLookup().removeAllRecipes();
type.getLookup().addRecipe(type
.recipeBuilder(GTCEu.id("test_singleblock"))
.inputItems(new ItemStack(Blocks.COBBLESTONE))
.outputItems(new ItemStack(Blocks.STONE))
.EUt(512).duration(1)
.buildRawRecipe());

RecipeLogic recipeLogic = recipeLogicMachine.getRecipeLogic();
RecipeLogic recipeLogic = machine.getRecipeLogic();

recipeLogic.findAndHandleRecipe();

Expand All @@ -180,10 +175,6 @@ public static void recipeLogicSingleBlockTest(GameTestHelper helper) {
helper.assertTrue(recipeLogic.getLastRecipe() == null,
"Recipe logic has somehow found a recipe, when there should be none");

// put an item in the inventory that will trigger recipe recheck
NotifiableItemStackHandler inputSlots = getInputSlot(recipeLogicMachine);
NotifiableItemStackHandler outputSlots = getOutputSlot(recipeLogicMachine);

inputSlots.insertItem(0, new ItemStack(Blocks.COBBLESTONE, 16), false);
inputSlots.onContentsChanged();

Expand All @@ -195,11 +186,11 @@ public static void recipeLogicSingleBlockTest(GameTestHelper helper) {
helper.assertTrue(stackCount == 15, "Count is wrong (should be 15, when it's %s)".formatted(stackCount));

// Save a reference to the old recipe so we can make sure it's getting reused
GTRecipe prev = recipeLogic.getLastRecipe();
ResourceLocation prev = recipeLogic.getLastRecipe().getId();

// Finish the recipe, the output should generate, and the next iteration should begin
recipeLogic.serverTick();
helper.assertTrue(recipeLogic.getLastRecipe().equals(prev), "lastRecipe is wrong");
helper.assertTrue(recipeLogic.getLastRecipe().getId().equals(prev), "lastRecipe is wrong");
helper.assertTrue(TestUtils.isItemStackEqual(
outputSlots.getStackInSlot(0),
new ItemStack(Blocks.STONE, 1)),
Expand Down Expand Up @@ -232,4 +223,21 @@ public static void recipeLogicSingleBlockTest(GameTestHelper helper) {
// Finish.
helper.succeed();
}
*/
// spotless:on

// Test for putting both ingredients in the same bus in 2 stacks.
@GameTest(template = "lcr_input_separation", batch = "RecipeLogicTest")
public static void recipeLogicInTwoStacksTest(GameTestHelper helper) {
RecipeLogicTest.BusHolder busHolder = getBussesAndForm(helper);
busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.STONE, 10));
busHolder.inputBus1.getInventory().setStackInSlot(1, new ItemStack(Blocks.STONE, 6));
helper.succeedWhen(() -> {
helper.assertTrue(
TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0),
new ItemStack(Blocks.STONE)),
"Crafting items in same bus failed, expected STONE but was " +
busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName());
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine;
import com.gregtechceu.gtceu.api.machine.trait.NotifiableEnergyContainer;
import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler;
import com.gregtechceu.gtceu.common.machine.multiblock.part.FluidHatchPartMachine;
import com.gregtechceu.gtceu.common.machine.multiblock.part.ItemBusPartMachine;
import com.gregtechceu.gtceu.gametest.util.TestUtils;

Expand Down Expand Up @@ -84,7 +83,7 @@ public static void prepare(ServerLevel level) {
}

private record BusHolder(ItemBusPartMachine inputBus1, ItemBusPartMachine inputBus2, ItemBusPartMachine outputBus1,
FluidHatchPartMachine outputHatch1, WorkableMultiblockMachine controller) {}
WorkableMultiblockMachine controller) {}

/**
* Retrieves the busses for this specific template and force a multiblock structure check
Expand All @@ -103,9 +102,7 @@ private static BusHolder getBussesAndForm(GameTestHelper helper) {
helper.getBlockEntity(new BlockPos(2, 2, 0)));
ItemBusPartMachine outputBus1 = (ItemBusPartMachine) getMetaMachine(
helper.getBlockEntity(new BlockPos(0, 1, 0)));
FluidHatchPartMachine outputHatch1 = (FluidHatchPartMachine) getMetaMachine(
helper.getBlockEntity(new BlockPos(0, 2, 0)));
return new BusHolder(inputBus1, inputBus2, outputBus1, outputHatch1, controller);
return new BusHolder(inputBus1, inputBus2, outputBus1, controller);
}

// Test for running HV recipe at HV
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public static void BLOCKED_BY_LDLIB_WEIRDNESS_TOO_PROBABLY_testAdvancedActivityD
});
}

@GameTest(template = "electrolyzer", batch = "coverTests", attempts = 5)
@GameTest(template = "electrolyzer", batch = "coverTests", attempts = 10)
public static void testAdvancedFluidDetectorCover(GameTestHelper helper) {
helper.pullLever(new BlockPos(2, 2, 2));
MetaMachine machine = ((IMachineBlockEntity) helper.getBlockEntity(new BlockPos(1, 2, 1))).getMetaMachine();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public static void fluidLinkCoverTest(GameTestHelper helper) {
}

@GameTest(template = "empty_5x5", batch = "coverTests", required = false)
public static void itemLinkCoverTest(GameTestHelper helper) {
public static void only_works_in_game_itemLinkCoverTest(GameTestHelper helper) {
QuantumChestMachine chest1 = (QuantumChestMachine) TestUtils.setMachine(helper, new BlockPos(1, 1, 1),
GTMachines.SUPER_CHEST[1]);
QuantumChestMachine chest2 = (QuantumChestMachine) TestUtils.setMachine(helper, new BlockPos(1, 1, 3),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ private static void placeSolar(GameTestHelper helper, MetaMachine machine) {

@GameTest(template = "empty_5x5", batch = "coverTests", required = false) // it doesn't fail only if running tests
// with the command for some reason
public static void generatesEnergyAtDayTest(GameTestHelper helper) {
public static void only_works_in_game_generatesEnergyAtDayTest(GameTestHelper helper) {
helper.setDayTime(6000);
BatteryBufferMachine machine = makeBatteryBuffer(helper, GTValues.HV);
machine.getBatteryInventory().insertItem(0, GTItems.BATTERY_HV_LITHIUM.asStack(), false);
Expand Down