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
13 changes: 13 additions & 0 deletions CHANGELOG-1.21.1.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
# Changelog for Minecraft 1.21.1
All notable changes to this project will be documented in this file.

<a name="Unreleased"></a>
## Unreleased


### Added
* Allow individual recipes to be enabled or disabled in the Attuned Crafting Interface, Closes #162, Closes #219
The Attuned Crafting Interface now has a gui that lists all recipes of its target machine.
Recipes can be toggled by clicking them, and bulk actions apply to the current search filter.
Disabled recipes are not registered in the crafting network, so no crafting job will use them.

### Changed
* Bump CommonCapabilities to 2.11.5, which is required for identifying recipes by their recipe id

<a name="1.21.1-1.5.0"></a>
## [1.21.1-1.5.0](https://github.com/CyclopsMC/IntegratedCrafting/compare/1.21.1-1.4.7...1.21.1-1.5.0) - 2026-08-24 21:07:04

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ org.gradle.caching=true
# Dependencies
cyclopscore_version=1.26.2-808
integrateddynamics_version=1.32.0-1630
commoncapabilities_version=2.9.12-263
commoncapabilities_version=2.11.5-363
integratedtunnels_version=1.8.44-484
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.cyclops.integratedcrafting.capability.network.NetworkCraftingHandlerCraftingNetwork;
import org.cyclops.integratedcrafting.core.CraftingProcessOverrideRegistry;
import org.cyclops.integratedcrafting.core.CraftingProcessOverrides;
import org.cyclops.integratedcrafting.inventory.container.ContainerPartInterfaceCraftingAttunedRecipesConfig;
import org.cyclops.integratedcrafting.inventory.container.ContainerPartInterfaceCraftingConfig;
import org.cyclops.integratedcrafting.inventory.container.ContainerPartInterfaceCraftingSettingsConfig;
import org.cyclops.integratedcrafting.part.PartTypes;
Expand Down Expand Up @@ -131,6 +132,7 @@ public void onConfigsRegister(ConfigHandler configHandler) {

configHandler.addConfigurable(new ContainerPartInterfaceCraftingConfig());
configHandler.addConfigurable(new ContainerPartInterfaceCraftingSettingsConfig());
configHandler.addConfigurable(new ContainerPartInterfaceCraftingAttunedRecipesConfig());

configHandler.addConfigurable(new RecipeSerializerDeadBushConfig()); // This one is only used in game tests.
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.neoforged.neoforge.registries.DeferredHolder;
import org.cyclops.integratedcrafting.inventory.container.ContainerPartInterfaceCrafting;
import org.cyclops.integratedcrafting.inventory.container.ContainerPartInterfaceCraftingAttunedRecipes;
import org.cyclops.integratedcrafting.inventory.container.ContainerPartInterfaceCraftingSettings;
import org.cyclops.integratedcrafting.recipe.type.RecipeDeadBush;
import org.cyclops.integrateddynamics.item.ItemVariable;
Expand All @@ -22,6 +23,7 @@ public class RegistryEntries {

public static final DeferredHolder<MenuType<?>, MenuType<ContainerPartInterfaceCrafting>> CONTAINER_INTERFACE_CRAFTING = DeferredHolder.create(Registries.MENU, ResourceLocation.parse("integratedcrafting:part_interface_crafting"));
public static final DeferredHolder<MenuType<?>, MenuType<ContainerPartInterfaceCraftingSettings>> CONTAINER_INTERFACE_CRAFTING_SETTINGS = DeferredHolder.create(Registries.MENU, ResourceLocation.parse("integratedcrafting:part_interface_crafting_settings"));
public static final DeferredHolder<MenuType<?>, MenuType<ContainerPartInterfaceCraftingAttunedRecipes>> CONTAINER_INTERFACE_CRAFTING_ATTUNED_RECIPES = DeferredHolder.create(Registries.MENU, ResourceLocation.parse("integratedcrafting:part_interface_crafting_attuned_recipes"));

public static final DeferredHolder<RecipeSerializer<?>, RecipeSerializer<RecipeDeadBush>> RECIPESERIALIZER_DEAD_BUSH = DeferredHolder.create(Registries.RECIPE_SERIALIZER, ResourceLocation.parse("integratedcrafting:crafting_special_dead_bush"));

Expand Down
129 changes: 129 additions & 0 deletions src/main/java/org/cyclops/integratedcrafting/api/recipe/RecipeKey.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package org.cyclops.integratedcrafting.api.recipe;

import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceLocation;
import org.cyclops.commoncapabilities.api.capability.recipehandler.IRecipeDefinition;

import javax.annotation.Nullable;
import java.util.Objects;

/**
* An opaque and persistable identifier of a recipe.
*
* Recipes that originate from a built-in recipe are identified by their recipe id,
* which keeps this key small, even for machines that expose thousands of recipes.
* All other recipes are identified by their full structural serialization.
*
* Keys are deliberately never resolved back into recipes,
* as {@link org.cyclops.commoncapabilities.api.capability.recipehandler.RecipeDefinition#fromRecipeId(HolderLookup.Provider, ResourceLocation)}
* throws once the recipe no longer exists.
* Keeping unknown keys opaque makes sure that a pack update can not silently
* change the meaning of a key that was stored before.
*
* @author rubensworks
*/
public final class RecipeKey {

/**
* The NBT key under which {@link IRecipeDefinition#serialize(HolderLookup.Provider, IRecipeDefinition)}
* stores the id of built-in recipes.
*/
private static final String NBT_RECIPE_ID = "recipeId";

@Nullable
private final String recipeId;
@Nullable
private final CompoundTag structure;

private RecipeKey(@Nullable String recipeId, @Nullable CompoundTag structure) {
this.recipeId = recipeId;
this.structure = structure;
}

/**
* Create a key for the given built-in recipe id.
* @param recipeId A recipe id.
* @return A key.
*/
public static RecipeKey ofRecipeId(String recipeId) {
return new RecipeKey(Objects.requireNonNull(recipeId), null);
}

/**
* Create a key for the given recipe.
* @param lookupProvider A lookup provider,
* only used for recipes that are not backed by a built-in recipe.
* @param recipe A recipe.
* @return A key.
*/
public static RecipeKey of(HolderLookup.Provider lookupProvider, IRecipeDefinition recipe) {
ResourceLocation recipeId = recipe.getRecipeId();
if (recipeId != null) {
return new RecipeKey(recipeId.toString(), null);
}
return new RecipeKey(null, IRecipeDefinition.serialize(lookupProvider, recipe));
}

/**
* Read a key from NBT.
* @param tag An NBT tag, as produced by {@link #serialize()}.
* @return A key.
*/
public static RecipeKey deserialize(CompoundTag tag) {
if (tag.contains(NBT_RECIPE_ID, Tag.TAG_STRING)) {
return new RecipeKey(tag.getString(NBT_RECIPE_ID), null);
}
return new RecipeKey(null, tag.copy());
}

/**
* @return An NBT representation of this key.
*/
public CompoundTag serialize() {
if (this.recipeId != null) {
CompoundTag tag = new CompoundTag();
tag.putString(NBT_RECIPE_ID, this.recipeId);
return tag;
}
return this.structure.copy();
}

/**
* @return The id of the built-in recipe this key refers to, or null if this key is structural.
*/
@Nullable
public String getRecipeId() {
return this.recipeId;
}

/**
* @return If this key identifies a recipe by its full structure instead of by a recipe id.
*/
public boolean isStructural() {
return this.recipeId == null;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof RecipeKey that)) {
return false;
}
return Objects.equals(this.recipeId, that.recipeId) && Objects.equals(this.structure, that.structure);
}

@Override
public int hashCode() {
return this.recipeId != null ? this.recipeId.hashCode() : this.structure.hashCode();
}

@Override
public String toString() {
return "[RecipeKey " + (this.recipeId != null ? this.recipeId : this.structure) + "]";
}

}
Loading
Loading