Create
                                
                                
                                
                                    Create copied to clipboard
                            
                            
                            
                        [1.21.1] Processing Recipe Rework
Fixes #8048.
Overview
This PR reworked the Processing Recipe system in order to:
- Better adapt the 
Codec/StreamCodecbasedRecipeSerializersystem in 1.21.1 - Remove unavailable recipe id context from 
ProcessingRecipeandProcessingRecipeParams, the recipe id is no longer retrievable upon deserialization so recipes should not ask for its own id upon construction. - Decouple 
AllRecipeTypesfromProcessingRecipeso addons can create their own processing recipe types - Make 
ProcessingRecipegeneric andProcessingRecipeParamsextensible soProcessingRecipewith more context (likeItemApplicationRecipe) can be created without having to injecting extra context to the baseProcessingRecipeParams. 
Usage
To create a custom ProcessingRecipe with custom ProcessingRecipeParams, take ItemApplicationRecipe as an example:
- Create a custom 
ProcessingRecipeParamsclass:ItemApplicationRecipeParams, add your own field (boolean keepHeldItem) to it; - Create a 
MapCodecfor the params class by grouping aMapCodecwith all fields inProcessingRecipeParamshandled and your own fieldMapCodecs, the prior can be created fromProcessingRecipeParams.codec(Supplier<P>): 
public static MapCodec<ItemApplicationRecipeParams> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
		codec(ItemApplicationRecipeParams::new).forGetter(Function.identity()),
		Codec.BOOL.optionalFieldOf("keep_held_item", false).forGetter(ItemApplicationRecipeParams::keepHeldItem)
	).apply(instance, (params, keepHeldItem) -> {
		params.keepHeldItem = keepHeldItem;
		return params;
	}));
- Override the 
encodeanddecodemethods for network (de)serialization, and create aStreamCodecfor the params class usingProcessingRecipeParams.streamCodec(Supplier<P>): 
public static StreamCodec<RegistryFriendlyByteBuf, ItemApplicationRecipeParams> STREAM_CODEC = streamCodec(ItemApplicationRecipeParams::new);
	@Override
	protected void encode(RegistryFriendlyByteBuf buffer) {
		super.encode(buffer);
		ByteBufCodecs.BOOL.encode(buffer, keepHeldItem);
	}
	@Override
	protected void decode(RegistryFriendlyByteBuf buffer) {
		super.decode(buffer);
		keepHeldItem = ByteBufCodecs.BOOL.decode(buffer);
	}
- Create the recipe's 
MapCodecandStreamCodecfrom the params', usingMapCodec#xmapandStreamCodec#map, and create your ownRecipeSerializerwith them. - Create the recipe's builder, extending 
ProcessingRecipeBuilder, you may optionally specify a generic factory interface for input if you wish to use the params for multiple recipes so they can share the builder class: 
@FunctionalInterface
public interface Factory<R extends ItemApplicationRecipe> extends ProcessingRecipe.Factory<ItemApplicationRecipeParams, R> {
	R create(ItemApplicationRecipeParams params);
}
public static class Builder<R extends ItemApplicationRecipe> extends ProcessingRecipeBuilder<ItemApplicationRecipeParams, R, Builder<R>> {
	public Builder(Factory<R> factory, ResourceLocation recipeId) {
		super(factory, recipeId);
	}
	@Override
	protected ItemApplicationRecipeParams createParams() {
		return new ItemApplicationRecipeParams();
	}
	@Override
	public Builder<R> self() {
		return this;
	}
	public Builder<R> toolNotConsumed() {
		params.keepHeldItem = true;
		return this;
	}
}
- You may now register the recipe's 
IRecipeTypeInfo, and use the recipe builder in datagen.