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 @@ -36,13 +36,18 @@
import org.cyclops.integratedcrafting.part.aspect.CraftingAspectWriteBuilders;
import org.cyclops.integratedcrafting.part.aspect.CraftingAspects;
import org.cyclops.integrateddynamics.RegistryEntries;
import org.cyclops.integrateddynamics.api.evaluate.operator.IOperator;
import org.cyclops.integrateddynamics.api.part.PartPos;
import org.cyclops.integrateddynamics.api.part.write.IPartStateWriter;
import org.cyclops.integrateddynamics.core.block.IgnoredBlockStatus;
import org.cyclops.integrateddynamics.core.evaluate.operator.CurriedOperator;
import org.cyclops.integrateddynamics.core.evaluate.operator.Operators;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeItemStack;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeRecipe;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeBoolean;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeOperator;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypes;
import org.cyclops.integrateddynamics.core.evaluate.variable.Variable;
import org.cyclops.integrateddynamics.core.helper.NetworkHelpers;
import org.cyclops.integrateddynamics.core.helper.PartHelpers;
import org.cyclops.integratedtunnels.part.aspect.TunnelAspects;
Expand Down Expand Up @@ -100,6 +105,80 @@ public void testItemsCraftChestOne(GameTestHelper helper) {
});
}

@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
public void testItemsCraftChestOneOperator(GameTestHelper helper) {
GameTestHelpersIntegratedCrafting.INetworkPositions<PartTypeInterfaceCrafting.State> positions = createBasicNetwork(helper, POS);

// Insert items in interface chest
ChestBlockEntity chestIn = helper.getBlockEntity(POS.east());
chestIn.setItem(0, new ItemStack(Items.OAK_PLANKS, 64));

// Add chest recipe to crafting interface
ResourceLocation recipeName = ResourceLocation.fromNamespaceAndPath("minecraft", "chest");
positions.interfaceRecipeAdders().get(0).accept(Triple.of(0, RecipeType.CRAFTING, recipeName));

// Enable operator crafting aspect in crafting writer, with an operator that returns the chest recipe
placeOperatorInWriter(helper, positions.writer(), new CurriedOperator(Operators.GENERAL_IDENTITY,
new Variable<>(ValueTypes.OBJECT_RECIPE, ValueObjectTypeRecipe.ValueRecipe.of(createRecipeDefinition(helper.getLevel(), RecipeType.CRAFTING, recipeName)))));

helper.succeedWhen(() -> {
IPartStateWriter partStateWriter = (IPartStateWriter) PartHelpers.getPart(positions.writer()).getState();
helper.assertValueEqual(partStateWriter.getActiveAspect(), CraftingAspects.Write.OPERATOR_CRAFT, "Active aspect is incorrect");
helper.assertTrue(partStateWriter.getErrors(CraftingAspects.Write.OPERATOR_CRAFT).isEmpty(), "Active aspect has errors");

// Check if items have been crafted
helper.assertValueEqual(chestIn.getItem(0).getItem(), Items.OAK_PLANKS, "Slot 0 item is incorrect");
helper.assertValueEqual(chestIn.getItem(0).getCount(), 56, "Slot 0 amount is incorrect");
helper.assertValueEqual(chestIn.getItem(1).getItem(), Items.CHEST, "Slot 1 item is incorrect");
helper.assertValueEqual(chestIn.getItem(1).getCount(), 1, "Slot 1 amount is incorrect");
});
}

@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
public void testItemsCraftChestOneOperatorEmptyRecipe(GameTestHelper helper) {
GameTestHelpersIntegratedCrafting.INetworkPositions<PartTypeInterfaceCrafting.State> positions = createBasicNetwork(helper, POS);

// Insert items in interface chest
ChestBlockEntity chestIn = helper.getBlockEntity(POS.east());
chestIn.setItem(0, new ItemStack(Items.OAK_PLANKS, 64));

// Add chest recipe to crafting interface
positions.interfaceRecipeAdders().get(0).accept(Triple.of(0, RecipeType.CRAFTING, ResourceLocation.fromNamespaceAndPath("minecraft", "chest")));

// Enable operator crafting aspect in crafting writer, with an operator that returns an empty recipe
placeOperatorInWriter(helper, positions.writer(), new CurriedOperator(Operators.GENERAL_IDENTITY,
new Variable<>(ValueTypes.OBJECT_RECIPE, ValueObjectTypeRecipe.ValueRecipe.of(null))));

helper.runAfterDelay(100, () -> {
IPartStateWriter partStateWriter = (IPartStateWriter) PartHelpers.getPart(positions.writer()).getState();
helper.assertValueEqual(partStateWriter.getActiveAspect(), CraftingAspects.Write.OPERATOR_CRAFT, "Active aspect is incorrect");
helper.assertTrue(partStateWriter.getErrors(CraftingAspects.Write.OPERATOR_CRAFT).isEmpty(), "Active aspect has errors");

// Check that nothing has been crafted
helper.assertValueEqual(chestIn.getItem(0).getCount(), 64, "Slot 0 amount is incorrect");
helper.assertTrue(chestIn.getItem(1).isEmpty(), "Slot 1 is not empty");
helper.succeed();
});
}

@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
public void testItemsCraftOperatorWithInputs(GameTestHelper helper) {
GameTestHelpersIntegratedCrafting.INetworkPositions<PartTypeInterfaceCrafting.State> positions = createBasicNetwork(helper, POS);

// Enable operator crafting aspect in crafting writer, with an operator that still requires an input
placeOperatorInWriter(helper, positions.writer(), Operators.GENERAL_IDENTITY);

helper.succeedWhen(() -> {
IPartStateWriter partStateWriter = (IPartStateWriter) PartHelpers.getPart(positions.writer()).getState();
helper.assertFalse(partStateWriter.getErrors(CraftingAspects.Write.OPERATOR_CRAFT).isEmpty(), "Active aspect has no errors");
});
}

private static void placeOperatorInWriter(GameTestHelper helper, PartPos writerPos, IOperator operator) {
placeVariableInWriter(helper.getLevel(), writerPos, CraftingAspects.Write.OPERATOR_CRAFT,
createVariableForValue(helper.getLevel(), ValueTypes.OPERATOR, ValueTypeOperator.ValueOperator.of(operator)));
}

@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
public void testItemsCraftChestOneRecipeDuration(GameTestHelper helper) {
GameTestHelpersIntegratedCrafting.INetworkPositions<PartTypeInterfaceCrafting.State> positions = createBasicNetwork(helper, POS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public PartTypeCraftingWriter(String name) {
CraftingAspects.Write.RECIPE_CRAFT,
CraftingAspects.Write.ITEMSTACK_CRAFT,
CraftingAspects.Write.FLUIDSTACK_CRAFT,
CraftingAspects.Write.ENERGY_CRAFT
CraftingAspects.Write.ENERGY_CRAFT,
CraftingAspects.Write.OPERATOR_CRAFT
));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.cyclops.integratedcrafting.part.aspect;

import com.google.common.collect.ImmutableList;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.fluids.FluidStack;
import org.apache.commons.lang3.tuple.Triple;
Expand All @@ -11,18 +12,26 @@
import org.cyclops.integratedcrafting.api.network.ICraftingNetwork;
import org.cyclops.integratedcrafting.core.CraftingHelpers;
import org.cyclops.integratedcrafting.part.PartTypeCraftingWriter;
import org.cyclops.integrateddynamics.api.evaluate.EvaluationException;
import org.cyclops.integrateddynamics.api.evaluate.operator.IOperator;
import org.cyclops.integrateddynamics.api.evaluate.variable.IValue;
import org.cyclops.integrateddynamics.api.evaluate.variable.IValueType;
import org.cyclops.integrateddynamics.api.evaluate.variable.IVariable;
import org.cyclops.integrateddynamics.api.network.INetwork;
import org.cyclops.integrateddynamics.api.network.IPositionedAddonsNetworkIngredients;
import org.cyclops.integrateddynamics.api.part.PartPos;
import org.cyclops.integrateddynamics.api.part.PartTarget;
import org.cyclops.integrateddynamics.api.part.aspect.property.IAspectProperties;
import org.cyclops.integrateddynamics.api.part.aspect.property.IAspectPropertyTypeInstance;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueHelpers;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeFluidStack;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeItemStack;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeRecipe;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeBoolean;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeInteger;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeOperator;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypes;
import org.cyclops.integrateddynamics.core.helper.L10NValues;
import org.cyclops.integrateddynamics.core.helper.PartHelpers;
import org.cyclops.integrateddynamics.core.part.aspect.build.AspectBuilder;
import org.cyclops.integrateddynamics.core.part.aspect.build.IAspectValuePropagator;
Expand Down Expand Up @@ -86,6 +95,25 @@ public class CraftingAspectWriteBuilders {
BUILDER_INTEGER = AspectWriteBuilders.BUILDER_INTEGER.byMod(IntegratedCrafting._instance)
.appendKind("craft").handle(AspectWriteBuilders.PROP_GET_INTEGER);

public static final IAspectValuePropagator<Triple<PartTarget, IAspectProperties, ValueTypeOperator.ValueOperator>, Triple<PartTarget, IAspectProperties, IRecipeDefinition>>
PROP_GET_OPERATOR_RECIPE = input -> {
IOperator operator = input.getRight().getRawValue();
if (operator.getRequiredInputLength() == 0
&& ValueHelpers.correspondsTo(operator.getOutputType(), ValueTypes.OBJECT_RECIPE)) {
IValue result = ValueHelpers.evaluateOperator(operator, new IVariable[0]);
if (result instanceof ValueObjectTypeRecipe.ValueRecipe valueRecipe) {
return Triple.of(input.getLeft(), input.getMiddle(), valueRecipe.getRawValue().orElse(null));
}
}
Component current = ValueTypeOperator.getSignature(operator);
Component expected = ValueTypeOperator.getSignature(new IValueType[0], ValueTypes.OBJECT_RECIPE);
throw new EvaluationException(Component.translatable(L10NValues.ASPECT_ERROR_INVALIDTYPE,
expected, current));
};
public static final AspectBuilder<ValueTypeOperator.ValueOperator, ValueTypeOperator, Triple<PartTarget, IAspectProperties, IRecipeDefinition>>
BUILDER_OPERATOR = AspectWriteBuilders.BUILDER_OPERATOR.byMod(IntegratedCrafting._instance)
.appendKind("craft").handle(PROP_GET_OPERATOR_RECIPE);

public static final IAspectValuePropagator<Triple<PartTarget, IAspectProperties, ItemStack>, CraftingJobData<ItemStack, Integer>>
PROP_ITEMSTACK_CRAFTINGDATA = input -> {
PartTarget partTarget = input.getLeft();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeRecipe;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeInteger;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeList;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeOperator;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypes;
import org.cyclops.integrateddynamics.part.aspect.read.AspectReadBuilders;

Expand All @@ -41,6 +42,11 @@ public static final class Write {
.withProperties(CraftingAspectWriteBuilders.PROPERTIES_CRAFTING_RECIPE)
.handle(CraftingAspectWriteBuilders.PROP_CRAFT_RECIPE)
.buildWrite();
public static final IAspectWrite<ValueTypeOperator.ValueOperator, ValueTypeOperator> OPERATOR_CRAFT =
CraftingAspectWriteBuilders.BUILDER_OPERATOR
.withProperties(CraftingAspectWriteBuilders.PROPERTIES_CRAFTING_RECIPE)
.handle(CraftingAspectWriteBuilders.PROP_CRAFT_RECIPE)
.buildWrite();
public static final IAspectWrite<ValueObjectTypeItemStack.ValueItemStack, ValueObjectTypeItemStack> ITEMSTACK_CRAFT =
CraftingAspectWriteBuilders.BUILDER_ITEMSTACK
.withProperties(CraftingAspectWriteBuilders.PROPERTIES_CRAFTING)
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/assets/integratedcrafting/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
"_comment": "# Crafting",
"aspect.integratedcrafting.write.recipe.craft": "Craft Recipe",
"aspect.integratedcrafting.write.recipe.craft.info": "Craft the given recipe",
"aspect.integratedcrafting.write.operator.craft": "Craft Recipe from Operator",
"aspect.integratedcrafting.write.operator.craft.info": "Craft the recipe returned by the given operator without inputs. If the operator returns an empty recipe, nothing is crafted.",
"aspect.integratedcrafting.write.itemstack.craft": "Craft Item",
"aspect.integratedcrafting.write.itemstack.craft.info": "Craft the given item",
"aspect.integratedcrafting.write.fluidstack.craft": "Craft Fluid",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "integratedcrafting:aspect/write/recipe/craft"
}
}
Loading