Interface IRecipeHandler<T extends net.minecraft.world.item.crafting.Recipe<?>>
- Type Parameters:
T- The generic type the recipe handler can receive. Refer to the implementation specifications for more information.
- All Known Implementing Classes:
CookingRecipeHandler,CTShapedRecipeHandler,CTShapelessRecipeHandler,ShapedRecipeHandler,ShapelessRecipeHandler,SmithingRecipeHandler,StoneCutterRecipeHandler
Differently from IRecipeManager, there can be more than one handler for recipe type, since handlers are
bound to the actual class type of the recipe in question (e.g. ShapelessRecipe.class, not
minecraft:crafting_shapeless).
A recipe handler is responsible for recipe-class-specific behavior, documented in the following table:
| Behavior | Description | Method Responsible |
|---|---|---|
| Recipe Dumping | Following a dump command, a recipe may need to be converted into a string that represents how that same recipe can be added via a CraftTweaker script. | dumpToCommandString(IRecipeManager, Recipe) |
| Ingredient Replacement |
Following script method calls, a recipe may need to be replaced with an equivalent one, albeit with
some ingredients replaced with others according to certain IReplacementRules.
|
replaceIngredients(IRecipeManager, Recipe, List) |
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic @interfaceAnnotates aIRecipeHandlerindicating which recipe classes it is able to handle.static classException that indicates that the current recipe handler does not support replacing for the targeted recipe class. -
Method Summary
Modifier and TypeMethodDescriptionstatic <S extends net.minecraft.world.item.crafting.Recipe<?>,U>
Optional<U>attemptReplacing(U ingredient, Class<U> type, S recipe, List<IReplacementRule> rules) Attempts replacing the ingredient given as an argument according to the specifiedIReplacementRules and type.default <U extends net.minecraft.world.item.crafting.Recipe<?>>
booleandoesConflict(IRecipeManager manager, T firstRecipe, U secondRecipe) Checks if the two recipes conflict with each other.dumpToCommandString(IRecipeManager manager, T recipe) Creates a String representation of a validaddRecipe(or alternative) call for the given subclass ofRecipe.replaceIngredients(IRecipeManager manager, T recipe, List<IReplacementRule> rules) Handles the replacement of ingredients according to the given set ofIReplacementRules for the given subclass ofRecipe.
-
Method Details
-
attemptReplacing
static <S extends net.minecraft.world.item.crafting.Recipe<?>,U> Optional<U> attemptReplacing(U ingredient, Class<U> type, S recipe, List<IReplacementRule> rules) Attempts replacing the ingredient given as an argument according to the specifiedIReplacementRules and type.The rules are applied one after the other in the same order as they are given in the
ruleslist.The result of each rule application is considered as the new ingredient, which will be passed to the upcoming rule. Effectively, this creates a chain of calls in the form of
...(rule3(rule2(rule1(ingredient))))...which ensures that all rules always act on the most up-to-date representation of the current ingredient.The value of
typerepresents the class type of the ingredient. Its value should be the most general class type possible that the recipe can accept (e.g., a recipe that can accept any form of ingredient would specify eitherIIngredientorIngredientas the value fortype).- Type Parameters:
S- The type of the recipe whose ingredients are currently undergoing replacement. The given type must be a subtype ofRecipe. If no valid type exists, thenRecipeis assumed.U- The type of the ingredient that should undergo replacement. No restrictions are placed on the type of the ingredient.- Parameters:
ingredient- The ingredient that should undergo replacement.type- The actual class type of the ingredient, or one of its superclasses, as determined by the client.recipe- The recipe whose ingredients are currently undergoing replacement; ornullif no valid recipe can be provided.rules- A series ofIReplacementRules in the order they should be applied.- Returns:
- An
Optionalholding the replaced ingredient, if any replacements have been carried out. If no replacement rule affected the current ingredient, the return value should beOptional.empty(). It is customary, though not required, that the value wrapped by the optional is a completely different object fromingredient(i.e.ingredient != result.get()).
-
dumpToCommandString
Creates a String representation of a validaddRecipe(or alternative) call for the given subclass ofRecipe.Recipe dumps are triggered by the
/ct recipesor/ct recipes handcommands.All newlines added to either the start or the end of the string will be automatically trimmed.
- Parameters:
manager- The recipe manager responsible for this kind of recipes.recipe- The recipe that is currently being dumped.- Returns:
- A String representing a
addRecipe(or similar) call.
-
replaceIngredients
default Optional<Function<net.minecraft.resources.ResourceLocation,T>> replaceIngredients(IRecipeManager manager, T recipe, List<IReplacementRule> rules) throws IRecipeHandler.ReplacementNotSupportedException Handles the replacement of ingredients according to the given set ofIReplacementRules for the given subclass ofRecipe.This method should try to apply all of the applicable rules to the recipe. If one of the rules fails to apply, an error message should be generated via
CraftTweakerAPI.LOGGER. Incomplete application of the replacement rules may or may not apply depending on the specific implementation: no specific contracts are enforced by this method.If a particular recipe handler does not support replacement, a
IRecipeHandler.ReplacementNotSupportedExceptionshould be raised, along with a helpful error message. A recipe handler must be consistent, meaning that given the same recipe class, the behavior should be consistent: either an exception gets thrown or the replacement gets carried out.- Parameters:
manager- The recipe manager responsible for this kind of recipes.recipe- The recipe whose ingredients should be replaced.rules- A series ofIReplacementRules in the order they should be applied. Implementations are nevertheless allowed to reorder these rules as they see fit. Refer to the implementation specifications for more details.- Returns:
- An
Optionalcontaining a function that creates the replaced recipe, if any replacements have been carried out. If no replacement rule affected the current recipe, the return value should beOptional.empty(). The parameter of the function will be the new ID of the recipe that should be used, as determined by the method caller: the name may correspond to the old one or be a completely new one, implementations are not allowed to make any assumptions on the value of this parameter. It is customary, though not required, that the value returned by the wrapped function is a completely different object fromrecipe(i.e.recipe != result.get().apply(recipe.getId())). - Throws:
IRecipeHandler.ReplacementNotSupportedException- If the current handler does not support replacing for the given recipe class.
-
doesConflict
default <U extends net.minecraft.world.item.crafting.Recipe<?>> boolean doesConflict(IRecipeManager manager, T firstRecipe, U secondRecipe) Checks if the two recipes conflict with each other.In this case, a conflict is defined as the two recipes being made in the exact same way (e.g. with the same shape and the same ingredients if the two recipes are shaped crafting table ones).
Conflicts are also considered symmetrical in this implementation, which means that if
firstRecipeconflicts withsecondRecipe, the opposite is also true.- Type Parameters:
U- The type ofsecondRecipe.- Parameters:
manager- The recipe manager responsible for this kind of recipes.firstRecipe- The recipe which should be checked for conflict.secondRecipe- The other recipe whichfirstRecipeshould be checked against. The recipe may or may not be of the same type offirstRecipe. See the API note section for more details.- Returns:
- Whether the
firstRecipeconflicts withsecondRecipeor not.
-