Skip to content

Commit 4e0f372

Browse files
authored
Add operator aspect to crafting writer, Closes #76 (#245)
1 parent b9bd362 commit 4e0f372

6 files changed

Lines changed: 123 additions & 1 deletion

File tree

‎src/main/java/org/cyclops/integratedcrafting/gametest/GameTestsItemsCraft.java‎

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,18 @@
3636
import org.cyclops.integratedcrafting.part.aspect.CraftingAspectWriteBuilders;
3737
import org.cyclops.integratedcrafting.part.aspect.CraftingAspects;
3838
import org.cyclops.integrateddynamics.RegistryEntries;
39+
import org.cyclops.integrateddynamics.api.evaluate.operator.IOperator;
3940
import org.cyclops.integrateddynamics.api.part.PartPos;
4041
import org.cyclops.integrateddynamics.api.part.write.IPartStateWriter;
4142
import org.cyclops.integrateddynamics.core.block.IgnoredBlockStatus;
43+
import org.cyclops.integrateddynamics.core.evaluate.operator.CurriedOperator;
44+
import org.cyclops.integrateddynamics.core.evaluate.operator.Operators;
4245
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeItemStack;
4346
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeRecipe;
4447
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeBoolean;
48+
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeOperator;
4549
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypes;
50+
import org.cyclops.integrateddynamics.core.evaluate.variable.Variable;
4651
import org.cyclops.integrateddynamics.core.helper.NetworkHelpers;
4752
import org.cyclops.integrateddynamics.core.helper.PartHelpers;
4853
import org.cyclops.integratedtunnels.part.aspect.TunnelAspects;
@@ -100,6 +105,80 @@ public void testItemsCraftChestOne(GameTestHelper helper) {
100105
});
101106
}
102107

108+
@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
109+
public void testItemsCraftChestOneOperator(GameTestHelper helper) {
110+
GameTestHelpersIntegratedCrafting.INetworkPositions<PartTypeInterfaceCrafting.State> positions = createBasicNetwork(helper, POS);
111+
112+
// Insert items in interface chest
113+
ChestBlockEntity chestIn = helper.getBlockEntity(POS.east());
114+
chestIn.setItem(0, new ItemStack(Items.OAK_PLANKS, 64));
115+
116+
// Add chest recipe to crafting interface
117+
ResourceLocation recipeName = ResourceLocation.fromNamespaceAndPath("minecraft", "chest");
118+
positions.interfaceRecipeAdders().get(0).accept(Triple.of(0, RecipeType.CRAFTING, recipeName));
119+
120+
// Enable operator crafting aspect in crafting writer, with an operator that returns the chest recipe
121+
placeOperatorInWriter(helper, positions.writer(), new CurriedOperator(Operators.GENERAL_IDENTITY,
122+
new Variable<>(ValueTypes.OBJECT_RECIPE, ValueObjectTypeRecipe.ValueRecipe.of(createRecipeDefinition(helper.getLevel(), RecipeType.CRAFTING, recipeName)))));
123+
124+
helper.succeedWhen(() -> {
125+
IPartStateWriter partStateWriter = (IPartStateWriter) PartHelpers.getPart(positions.writer()).getState();
126+
helper.assertValueEqual(partStateWriter.getActiveAspect(), CraftingAspects.Write.OPERATOR_CRAFT, "Active aspect is incorrect");
127+
helper.assertTrue(partStateWriter.getErrors(CraftingAspects.Write.OPERATOR_CRAFT).isEmpty(), "Active aspect has errors");
128+
129+
// Check if items have been crafted
130+
helper.assertValueEqual(chestIn.getItem(0).getItem(), Items.OAK_PLANKS, "Slot 0 item is incorrect");
131+
helper.assertValueEqual(chestIn.getItem(0).getCount(), 56, "Slot 0 amount is incorrect");
132+
helper.assertValueEqual(chestIn.getItem(1).getItem(), Items.CHEST, "Slot 1 item is incorrect");
133+
helper.assertValueEqual(chestIn.getItem(1).getCount(), 1, "Slot 1 amount is incorrect");
134+
});
135+
}
136+
137+
@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
138+
public void testItemsCraftChestOneOperatorEmptyRecipe(GameTestHelper helper) {
139+
GameTestHelpersIntegratedCrafting.INetworkPositions<PartTypeInterfaceCrafting.State> positions = createBasicNetwork(helper, POS);
140+
141+
// Insert items in interface chest
142+
ChestBlockEntity chestIn = helper.getBlockEntity(POS.east());
143+
chestIn.setItem(0, new ItemStack(Items.OAK_PLANKS, 64));
144+
145+
// Add chest recipe to crafting interface
146+
positions.interfaceRecipeAdders().get(0).accept(Triple.of(0, RecipeType.CRAFTING, ResourceLocation.fromNamespaceAndPath("minecraft", "chest")));
147+
148+
// Enable operator crafting aspect in crafting writer, with an operator that returns an empty recipe
149+
placeOperatorInWriter(helper, positions.writer(), new CurriedOperator(Operators.GENERAL_IDENTITY,
150+
new Variable<>(ValueTypes.OBJECT_RECIPE, ValueObjectTypeRecipe.ValueRecipe.of(null))));
151+
152+
helper.runAfterDelay(100, () -> {
153+
IPartStateWriter partStateWriter = (IPartStateWriter) PartHelpers.getPart(positions.writer()).getState();
154+
helper.assertValueEqual(partStateWriter.getActiveAspect(), CraftingAspects.Write.OPERATOR_CRAFT, "Active aspect is incorrect");
155+
helper.assertTrue(partStateWriter.getErrors(CraftingAspects.Write.OPERATOR_CRAFT).isEmpty(), "Active aspect has errors");
156+
157+
// Check that nothing has been crafted
158+
helper.assertValueEqual(chestIn.getItem(0).getCount(), 64, "Slot 0 amount is incorrect");
159+
helper.assertTrue(chestIn.getItem(1).isEmpty(), "Slot 1 is not empty");
160+
helper.succeed();
161+
});
162+
}
163+
164+
@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
165+
public void testItemsCraftOperatorWithInputs(GameTestHelper helper) {
166+
GameTestHelpersIntegratedCrafting.INetworkPositions<PartTypeInterfaceCrafting.State> positions = createBasicNetwork(helper, POS);
167+
168+
// Enable operator crafting aspect in crafting writer, with an operator that still requires an input
169+
placeOperatorInWriter(helper, positions.writer(), Operators.GENERAL_IDENTITY);
170+
171+
helper.succeedWhen(() -> {
172+
IPartStateWriter partStateWriter = (IPartStateWriter) PartHelpers.getPart(positions.writer()).getState();
173+
helper.assertFalse(partStateWriter.getErrors(CraftingAspects.Write.OPERATOR_CRAFT).isEmpty(), "Active aspect has no errors");
174+
});
175+
}
176+
177+
private static void placeOperatorInWriter(GameTestHelper helper, PartPos writerPos, IOperator operator) {
178+
placeVariableInWriter(helper.getLevel(), writerPos, CraftingAspects.Write.OPERATOR_CRAFT,
179+
createVariableForValue(helper.getLevel(), ValueTypes.OPERATOR, ValueTypeOperator.ValueOperator.of(operator)));
180+
}
181+
103182
@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
104183
public void testItemsCraftChestOneRecipeDuration(GameTestHelper helper) {
105184
GameTestHelpersIntegratedCrafting.INetworkPositions<PartTypeInterfaceCrafting.State> positions = createBasicNetwork(helper, POS);

‎src/main/java/org/cyclops/integratedcrafting/part/PartTypeCraftingWriter.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ public PartTypeCraftingWriter(String name) {
2222
CraftingAspects.Write.RECIPE_CRAFT,
2323
CraftingAspects.Write.ITEMSTACK_CRAFT,
2424
CraftingAspects.Write.FLUIDSTACK_CRAFT,
25-
CraftingAspects.Write.ENERGY_CRAFT
25+
CraftingAspects.Write.ENERGY_CRAFT,
26+
CraftingAspects.Write.OPERATOR_CRAFT
2627
));
2728
}
2829

‎src/main/java/org/cyclops/integratedcrafting/part/aspect/CraftingAspectWriteBuilders.java‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.cyclops.integratedcrafting.part.aspect;
22

33
import com.google.common.collect.ImmutableList;
4+
import net.minecraft.network.chat.Component;
45
import net.minecraft.world.item.ItemStack;
56
import net.neoforged.neoforge.fluids.FluidStack;
67
import org.apache.commons.lang3.tuple.Triple;
@@ -11,18 +12,26 @@
1112
import org.cyclops.integratedcrafting.api.network.ICraftingNetwork;
1213
import org.cyclops.integratedcrafting.core.CraftingHelpers;
1314
import org.cyclops.integratedcrafting.part.PartTypeCraftingWriter;
15+
import org.cyclops.integrateddynamics.api.evaluate.EvaluationException;
16+
import org.cyclops.integrateddynamics.api.evaluate.operator.IOperator;
17+
import org.cyclops.integrateddynamics.api.evaluate.variable.IValue;
18+
import org.cyclops.integrateddynamics.api.evaluate.variable.IValueType;
19+
import org.cyclops.integrateddynamics.api.evaluate.variable.IVariable;
1420
import org.cyclops.integrateddynamics.api.network.INetwork;
1521
import org.cyclops.integrateddynamics.api.network.IPositionedAddonsNetworkIngredients;
1622
import org.cyclops.integrateddynamics.api.part.PartPos;
1723
import org.cyclops.integrateddynamics.api.part.PartTarget;
1824
import org.cyclops.integrateddynamics.api.part.aspect.property.IAspectProperties;
1925
import org.cyclops.integrateddynamics.api.part.aspect.property.IAspectPropertyTypeInstance;
26+
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueHelpers;
2027
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeFluidStack;
2128
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeItemStack;
2229
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeRecipe;
2330
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeBoolean;
2431
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeInteger;
32+
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeOperator;
2533
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypes;
34+
import org.cyclops.integrateddynamics.core.helper.L10NValues;
2635
import org.cyclops.integrateddynamics.core.helper.PartHelpers;
2736
import org.cyclops.integrateddynamics.core.part.aspect.build.AspectBuilder;
2837
import org.cyclops.integrateddynamics.core.part.aspect.build.IAspectValuePropagator;
@@ -86,6 +95,25 @@ public class CraftingAspectWriteBuilders {
8695
BUILDER_INTEGER = AspectWriteBuilders.BUILDER_INTEGER.byMod(IntegratedCrafting._instance)
8796
.appendKind("craft").handle(AspectWriteBuilders.PROP_GET_INTEGER);
8897

98+
public static final IAspectValuePropagator<Triple<PartTarget, IAspectProperties, ValueTypeOperator.ValueOperator>, Triple<PartTarget, IAspectProperties, IRecipeDefinition>>
99+
PROP_GET_OPERATOR_RECIPE = input -> {
100+
IOperator operator = input.getRight().getRawValue();
101+
if (operator.getRequiredInputLength() == 0
102+
&& ValueHelpers.correspondsTo(operator.getOutputType(), ValueTypes.OBJECT_RECIPE)) {
103+
IValue result = ValueHelpers.evaluateOperator(operator, new IVariable[0]);
104+
if (result instanceof ValueObjectTypeRecipe.ValueRecipe valueRecipe) {
105+
return Triple.of(input.getLeft(), input.getMiddle(), valueRecipe.getRawValue().orElse(null));
106+
}
107+
}
108+
Component current = ValueTypeOperator.getSignature(operator);
109+
Component expected = ValueTypeOperator.getSignature(new IValueType[0], ValueTypes.OBJECT_RECIPE);
110+
throw new EvaluationException(Component.translatable(L10NValues.ASPECT_ERROR_INVALIDTYPE,
111+
expected, current));
112+
};
113+
public static final AspectBuilder<ValueTypeOperator.ValueOperator, ValueTypeOperator, Triple<PartTarget, IAspectProperties, IRecipeDefinition>>
114+
BUILDER_OPERATOR = AspectWriteBuilders.BUILDER_OPERATOR.byMod(IntegratedCrafting._instance)
115+
.appendKind("craft").handle(PROP_GET_OPERATOR_RECIPE);
116+
89117
public static final IAspectValuePropagator<Triple<PartTarget, IAspectProperties, ItemStack>, CraftingJobData<ItemStack, Integer>>
90118
PROP_ITEMSTACK_CRAFTINGDATA = input -> {
91119
PartTarget partTarget = input.getLeft();

‎src/main/java/org/cyclops/integratedcrafting/part/aspect/CraftingAspects.java‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeRecipe;
2020
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeInteger;
2121
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeList;
22+
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeOperator;
2223
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypes;
2324
import org.cyclops.integrateddynamics.part.aspect.read.AspectReadBuilders;
2425

@@ -41,6 +42,11 @@ public static final class Write {
4142
.withProperties(CraftingAspectWriteBuilders.PROPERTIES_CRAFTING_RECIPE)
4243
.handle(CraftingAspectWriteBuilders.PROP_CRAFT_RECIPE)
4344
.buildWrite();
45+
public static final IAspectWrite<ValueTypeOperator.ValueOperator, ValueTypeOperator> OPERATOR_CRAFT =
46+
CraftingAspectWriteBuilders.BUILDER_OPERATOR
47+
.withProperties(CraftingAspectWriteBuilders.PROPERTIES_CRAFTING_RECIPE)
48+
.handle(CraftingAspectWriteBuilders.PROP_CRAFT_RECIPE)
49+
.buildWrite();
4450
public static final IAspectWrite<ValueObjectTypeItemStack.ValueItemStack, ValueObjectTypeItemStack> ITEMSTACK_CRAFT =
4551
CraftingAspectWriteBuilders.BUILDER_ITEMSTACK
4652
.withProperties(CraftingAspectWriteBuilders.PROPERTIES_CRAFTING)

‎src/main/resources/assets/integratedcrafting/lang/en_us.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@
7676
"_comment": "# Crafting",
7777
"aspect.integratedcrafting.write.recipe.craft": "Craft Recipe",
7878
"aspect.integratedcrafting.write.recipe.craft.info": "Craft the given recipe",
79+
"aspect.integratedcrafting.write.operator.craft": "Craft Recipe from Operator",
80+
"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.",
7981
"aspect.integratedcrafting.write.itemstack.craft": "Craft Item",
8082
"aspect.integratedcrafting.write.itemstack.craft.info": "Craft the given item",
8183
"aspect.integratedcrafting.write.fluidstack.craft": "Craft Fluid",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"parent": "builtin/generated",
3+
"textures": {
4+
"layer0": "integratedcrafting:aspect/write/recipe/craft"
5+
}
6+
}

0 commit comments

Comments
 (0)