Skip to content
Open
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 @@ -34,6 +34,14 @@ public class GeneralConfig extends DummyConfig {
public static int interfaceCraftingBaseConsumption = 5;
@ConfigurableProperty(category = "general", comment = "The base energy usage for the attuned crafting interface per crafting job being processed.", minimalValue = 0, configLocation = ModConfig.Type.SERVER)
public static int interfaceCraftingAttunedBaseConsumption = 10;
@ConfigurableProperty(category = "general", comment = "The base energy usage for the list-based crafting interface per crafting job being processed.", minimalValue = 0, configLocation = ModConfig.Type.SERVER)
public static int interfaceCraftingListBaseConsumption = 10;

@ConfigurableProperty(category = "machine", comment = "The maximum number of recipes that will be read from a list inside a list-based crafting interface. This is a guard against runaway lists, not a tuning knob: it is set well above the recipe count of any regular machine. Set to 0 for no limit.", minimalValue = 0, isCommandable = true, configLocation = ModConfig.Type.SERVER)
public static int maxCraftingInterfaceListRecipes = 4096;

@ConfigurableProperty(category = "machine", comment = "The minimal update frequency in ticks to use for list-based crafting interfaces. Reading a list of recipes is more expensive than reading a single recipe, so this defaults higher than the regular crafting interface.", minimalValue = 1, configLocation = ModConfig.Type.SERVER)
public static int minCraftingInterfaceListUpdateFreq = 20;

@ConfigurableProperty(category = "machine", comment = "The maximum number of recipes that a crafting interface remembers crafting durations for, which are used to estimate the duration of crafting jobs. Set to 0 to disable recipe-specific estimations.", minimalValue = 0, isCommandable = true, configLocation = ModConfig.Type.SERVER)
public static int craftingInterfaceRecipeDurationEntries = 32;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import org.cyclops.cyclopscore.client.gui.image.IImage;
import org.cyclops.cyclopscore.client.gui.image.Images;
import org.cyclops.cyclopscore.helper.GuiHelpers;
import org.cyclops.integratedcrafting.Reference;
import org.cyclops.integratedcrafting.core.part.PartTypeInterfaceCraftingVariableBase;
import org.cyclops.integratedcrafting.inventory.container.ContainerPartInterfaceCrafting;
import org.cyclops.integrateddynamics.core.inventory.container.ContainerMultipartAspects;

Expand Down Expand Up @@ -39,7 +39,7 @@ public void init() {

@Override
protected ResourceLocation constructGuiTexture() {
return ResourceLocation.fromNamespaceAndPath(Reference.MOD_ID, "textures/gui/part_interface_crafting.png");
return ((PartTypeInterfaceCraftingVariableBase<?, ?>) getMenu().getPartType()).getGuiTexture();
}

@Override
Expand All @@ -58,8 +58,9 @@ protected void renderBg(GuiGraphics guiGraphics, float partialTicks, int mouseX,

RenderSystem.setShaderColor(1, 1, 1, 1);
int y = topPos + 42;
int slotsX = ContainerPartInterfaceCrafting.getVariableSlotsX(getMenu().getContainerInventory().getContainerSize());
for (int i = 0; i < getMenu().getContainerInventory().getContainerSize(); i++) {
int x = leftPos + 10 + i * GuiHelpers.SLOT_SIZE;
int x = leftPos + slotsX + 2 + i * GuiHelpers.SLOT_SIZE;
if (!getMenu().getContainerInventory().getItem(i).isEmpty()) {
IImage image = container.isRecipeSlotValid(i) ? Images.OK : Images.ERROR;
image.draw(guiGraphics, x, y);
Expand All @@ -74,8 +75,9 @@ protected void renderLabels(GuiGraphics guiGraphics, int mouseX, int mouseY) {
guiGraphics.pose().last().pose(), guiGraphics.bufferSource(), Font.DisplayMode.NORMAL, 0, 15728880);

int y = 42;
int slotsX = ContainerPartInterfaceCrafting.getVariableSlotsX(getMenu().getContainerInventory().getContainerSize());
for (int i = 0; i < getMenu().getContainerInventory().getContainerSize(); i++) {
int x = 10 + i * GuiHelpers.SLOT_SIZE;
int x = slotsX + 2 + i * GuiHelpers.SLOT_SIZE;
int slot = i;
GuiHelpers.renderTooltipOptional(this, guiGraphics.pose(), x, y, 14, 13, mouseX, mouseY,
() -> {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.ChestBlockEntity;
import net.minecraft.world.level.block.entity.FurnaceBlockEntity;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.cyclops.commoncapabilities.IngredientComponents;
import org.cyclops.commoncapabilities.api.capability.itemhandler.ItemMatch;
import org.cyclops.commoncapabilities.api.capability.recipehandler.IPrototypedIngredientAlternatives;
import org.cyclops.commoncapabilities.api.capability.recipehandler.IRecipeDefinition;
import org.cyclops.commoncapabilities.api.capability.recipehandler.PrototypedIngredientAlternativesItemStackTag;
import org.cyclops.commoncapabilities.api.capability.recipehandler.PrototypedIngredientAlternativesList;
import org.cyclops.commoncapabilities.api.capability.recipehandler.RecipeDefinition;
Expand All @@ -44,6 +46,7 @@
import org.cyclops.integrateddynamics.api.part.aspect.property.IAspectPropertyTypeInstance;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeItemStack;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeRecipe;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeList;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypes;
import org.cyclops.integrateddynamics.core.helper.PartHelpers;
import org.cyclops.integratedtunnels.part.aspect.TunnelAspects;
Expand Down Expand Up @@ -73,7 +76,10 @@ public static INetworkPositions<PartTypeInterfaceCrafting.State> createBasicNetw
}

public static <T extends PartTypeInterfaceCraftingBase.State<?, ?>> INetworkPositions<T> createBasicNetwork(GameTestHelper helper, BlockPos pos, boolean attuned, Block... crafters) {
PartTypeInterfaceCraftingBase<? extends PartTypeInterfaceCraftingBase<?, ?>, ? extends PartTypeInterfaceCraftingBase.State<? extends PartTypeInterfaceCraftingBase<?, ?>, ? extends PartTypeInterfaceCraftingBase.State<?, ?>>> partInterface = attuned ? PartTypes.INTERFACE_CRAFTING_ATTUNED : PartTypes.INTERFACE_CRAFTING;
return createBasicNetwork(helper, pos, attuned ? PartTypes.INTERFACE_CRAFTING_ATTUNED : PartTypes.INTERFACE_CRAFTING, crafters);
}

public static <T extends PartTypeInterfaceCraftingBase.State<?, ?>> INetworkPositions<T> createBasicNetwork(GameTestHelper helper, BlockPos pos, PartTypeInterfaceCraftingBase<? extends PartTypeInterfaceCraftingBase<?, ?>, ? extends PartTypeInterfaceCraftingBase.State<? extends PartTypeInterfaceCraftingBase<?, ?>, ? extends PartTypeInterfaceCraftingBase.State<?, ?>>> partInterface, Block... crafters) {

// Place cable
helper.setBlock(pos, RegistryEntries.BLOCK_CABLE.value());
Expand Down Expand Up @@ -137,6 +143,19 @@ public static INetworkPositions<PartTypeInterfaceCrafting.State> createBasicNetw
}

public static ItemStack createVariableForRecipe(Level level, RecipeType<?> recipeType, ResourceLocation recipeName) {
return createVariableForValue(level, ValueTypes.OBJECT_RECIPE,
ValueObjectTypeRecipe.ValueRecipe.of(createRecipeDefinition(level, recipeType, recipeName)));
}

public static ItemStack createVariableForRecipeList(Level level, List<Pair<RecipeType<?>, ResourceLocation>> recipes) {
List<ValueObjectTypeRecipe.ValueRecipe> values = Lists.newArrayList();
for (Pair<RecipeType<?>, ResourceLocation> recipe : recipes) {
values.add(ValueObjectTypeRecipe.ValueRecipe.of(createRecipeDefinition(level, recipe.getLeft(), recipe.getRight())));
}
return createVariableForValue(level, ValueTypes.LIST, ValueTypeList.ValueList.ofList(ValueTypes.OBJECT_RECIPE, values));
}

public static IRecipeDefinition createRecipeDefinition(Level level, RecipeType<?> recipeType, ResourceLocation recipeName) {
RecipeHolder<?> recipeUnknown = null;
try {
recipeUnknown = (RecipeHolder<?>) IModHelpers.get().getCraftingHelpers().<RecipeInput, Recipe>getServerRecipe((RecipeType) recipeType, recipeName).orElseThrow(() -> new IllegalStateException("Recipe " + recipeName.toString() + " could not be found"));
Expand Down Expand Up @@ -225,7 +244,7 @@ public static ItemStack createVariableForRecipe(Level level, RecipeType<?> recip
} else {
throw new IllegalStateException("Unknown recipe type " + recipeType);
}
return createVariableForValue(level, ValueTypes.OBJECT_RECIPE, ValueObjectTypeRecipe.ValueRecipe.of(new RecipeDefinition(recipeIn, new MixedIngredients(recipeOut))));
return new RecipeDefinition(recipeIn, new MixedIngredients(recipeOut));
}

public static void enableRecipeInWriter(GameTestHelper helper, PartPos writerPos, ItemStack itemStack) {
Expand All @@ -241,7 +260,7 @@ public static <T extends IValueType<V>, V extends IValue> void setWriterAspectPr

public static <T extends IValueType<V>, V extends IValue> void setCraftingInterfaceBlockingMode(PartPos writerPos, boolean blocking) {
PartHelpers.PartStateHolder partStateHolder = PartHelpers.getPart(writerPos);
((PartTypeInterfaceCrafting.State) partStateHolder.getState()).getCraftingJobHandler().setBlockingJobsMode(blocking);
((PartTypeInterfaceCraftingBase.State<?, ?>) partStateHolder.getState()).getCraftingJobHandler().setBlockingJobsMode(blocking);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,33 @@ public void testAdvancementCraftCraftingInterfaceAttuned(GameTestHelper helper)
});
}

/**
* Test for the craft_crafting_interface_list advancement.
* Trigger: cyclopscore:item_crafted
* Condition: player crafts integratedcrafting:part_interface_crafting_list
*/
@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
public void testAdvancementCraftCraftingInterfaceList(GameTestHelper helper) {
ServerPlayer player = helper.makeMockServerPlayerInLevel();

// Fire the PlayerEvent.ItemCraftedEvent via the NeoForge event bus
NeoForge.EVENT_BUS.post(new PlayerEvent.ItemCraftedEvent(
player,
new ItemStack(PartTypes.INTERFACE_CRAFTING_LIST.getItem()),
new SimpleContainer(9)
));

helper.succeedWhen(() -> {
AdvancementHolder advancement = helper.getLevel().getServer().getAdvancements()
.get(ResourceLocation.fromNamespaceAndPath(Reference.MOD_ID, "autocrafting_setup/craft_crafting_interface_list"));
helper.assertTrue(advancement != null, "craft_crafting_interface_list advancement not found");
helper.assertTrue(
player.getAdvancements().getOrStartProgress(advancement).isDone(),
"craft_crafting_interface_list advancement not granted"
);
});
}

/**
* Test for the craft_crafting_writer advancement.
* Trigger: cyclopscore:item_crafted
Expand Down Expand Up @@ -290,6 +317,25 @@ public void testAdvancementCraftCraftingInterfaceAttunedNegative(GameTestHelper
helper.succeedWhen(() -> assertAdvancementNotDone(helper, player, "autocrafting_setup/craft_crafting_interface_attuned"));
}

/**
* Negative test for the craft_crafting_interface_list advancement.
* Trigger: cyclopscore:item_crafted
* Condition: player crafts integratedcrafting:part_interface_crafting_list
* Here we craft the non-list interface instead – advancement must NOT be granted.
*/
@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
public void testAdvancementCraftCraftingInterfaceListNegative(GameTestHelper helper) {
ServerPlayer player = helper.makeMockServerPlayerInLevel();

NeoForge.EVENT_BUS.post(new PlayerEvent.ItemCraftedEvent(
player,
new ItemStack(PartTypes.INTERFACE_CRAFTING.getItem()),
new SimpleContainer(9)
));

helper.succeedWhen(() -> assertAdvancementNotDone(helper, player, "autocrafting_setup/craft_crafting_interface_list"));
}

/**
* Negative test for the craft_crafting_writer advancement.
* Trigger: cyclopscore:item_crafted
Expand Down
Loading
Loading