Генерация рецептов 26.1.2
Гайд для настройки рецептов с помощью datagen.
ТРЕБОВАНИЯ
Сначала убедитесь, что вы установили datagen.
Установка
Во-первых, нам понадобится провайдер. Создайте класс, который расширяет FabricRecipeProvider. Вся генерация рецептов будет происходить внутри метода buildRecipes нашего провайдера.
java
import java.util.List;
import java.util.concurrent.CompletableFuture;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.recipes.RecipeCategory;
import net.minecraft.data.recipes.RecipeOutput;
import net.minecraft.data.recipes.RecipeProvider;
import net.minecraft.data.recipes.SimpleCookingRecipeBuilder;
import net.minecraft.resources.Identifier;
import net.minecraft.tags.ItemTags;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.CookingBookCategory;
import net.minecraft.world.item.crafting.Ingredient;
import net.fabricmc.fabric.api.datagen.v1.FabricPackOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.fabricmc.fabric.api.resource.conditions.v1.ResourceConditions;
import com.example.docs.ExampleMod;
import com.example.docs.item.ModItems;
public class ExampleModRecipeProvider extends FabricRecipeProvider {
public ExampleModRecipeProvider(FabricPackOutput output, CompletableFuture<HolderLookup.Provider> registriesFuture) {
super(output, registriesFuture);
}
@Override
protected RecipeProvider createRecipeProvider(HolderLookup.Provider registryLookup, RecipeOutput exporter) {
return new RecipeProvider(registryLookup, exporter) {
@Override
public void buildRecipes() {
HolderLookup.RegistryLookup<Item> itemLookup = registries.lookupOrThrow(Registries.ITEM);
}
};
}
@Override
public String getName() {
return "ExampleModRecipeProvider";
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Чтобы завершить настройку, добавьте этот провайдер к вашей DataGeneratorEntrypoint в методе onInitializeDataGenerator.
java
pack.addProvider(ExampleModRecipeProvider::new);1
Бесформенные рецепты
Рецепты бесформенных крафтов довольно просты. Просто добавьте их в метод buildRecipes вашего провайдера:
java
shapeless(RecipeCategory.BUILDING_BLOCKS, Items.DIRT) // You can also specify an int to produce more than one
.requires(Items.COARSE_DIRT) // You can also specify an int to require more than one, or a tag to accept multiple things
// Create an advancement that gives you the recipe
.unlockedBy(getHasName(Items.COARSE_DIRT), has(Items.COARSE_DIRT))
.save(output);1
2
3
4
5
6
2
3
4
5
6
Рецепты окрашивания
Рецепты окрашивания используются для покраски предметов в вашем инвентаре в определённый цвет.
java
dyedItem(ModItems.LEATHER_GLOVES, "leather_gloves");1
Рецепты по форме
Для рецепта с формой вы определяете форму с помощью String, а затем определяете, что представляет собой каждый символ в String.
java
shaped(RecipeCategory.MISC, Items.CRAFTING_TABLE, 4)
.pattern("ll")
.pattern("ll")
.define('l', ItemTags.LOGS) // 'l' means "any log"
.group("multi_bench") // Put it in a group called "multi_bench" - groups are shown in one slot in the recipe book
.unlockedBy(getHasName(Items.CRAFTING_TABLE), has(Items.CRAFTING_TABLE))
.save(output);
shaped(RecipeCategory.MISC, Items.LOOM, 4)
.pattern("ww")
.pattern("ll")
.define('w', ItemTags.WOOL) // 'w' means "any wool"
.define('l', ItemTags.LOGS)
.group("multi_bench")
.unlockedBy(getHasName(Items.LOOM), has(Items.LOOM))
.save(output);
doorBuilder(Items.OAK_DOOR, Ingredient.of(Items.OAK_BUTTON)) // Using a helper method!
.unlockedBy(getHasName(Items.OAK_BUTTON), has(Items.OAK_BUTTON))
.save(output);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
TIP
Здесь есть множество вспомогательных методов для создания обычных рецептов. Посмотрите, что может предложить RecipeProvider! Нажмите Alt+7 в IntelliJ, чтобы открыть структуру класса вместе со списком его методов.
Другие рецепты
Другие рецепты работают аналогично, но требуют нескольких дополнительных параметров. Например, для рецептов плавки необходимо знать, сколько опыта нужно присудить.
java
oreSmelting(
List.of(Items.GLASS_BOTTLE), // Inputs
RecipeCategory.MISC, // Category
CookingBookCategory.MISC, // Category
Items.GLASS, // Output
0.1f, // Experience
300, // Cooking time
"glass_bottle_to_glass" // group
);1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
Рецепты внутри Коптильни (Smoker) регистрируются отлично от рецептов в печах остальных видов – они используют SimpleCookingRecipeBuilder.smoking:
java
SimpleCookingRecipeBuilder.smoking(
Ingredient.of(Items.WATER_BUCKET), // Input
RecipeCategory.MISC, // Category (MISC for smoking recipes)
Items.BUCKET, // Output
0.35f, // Experience
100 // Cooking Time
)
.unlockedBy(getHasName(Items.WATER_BUCKET), has(Items.WATER_BUCKET)) // You can specify how this recipe is unlocked here.
.save(output, Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, "water_bucket_to_bucket").toString()); // Then save the recipe with your modid and the recipe name.1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
Условная загрузка ресурсов
Чтобы применить условную загрузку ресурсов к динамически генерируемому рецепту, оберните выходной результат методом withConditions и укажите любые условия ресурсов, которые вы хотите применить. В результате будут созданы рецепт и достижение с примененными условиями ресурсов:
java
shapeless(RecipeCategory.BUILDING_BLOCKS, Items.SAND)
.requires(ItemTags.SAND)
.unlockedBy(getHasName(Items.SAND), has(Items.SAND))
.save(withConditions(output, ResourceConditions.tagsPopulated(ItemTags.DIRT))); // Instead of providing the output directly, wrap it with withConditions1
2
3
4
2
3
4




