-
Notifications
You must be signed in to change notification settings - Fork 81
/
BaseRecipeProvider.java
295 lines (267 loc) · 10.8 KB
/
BaseRecipeProvider.java
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
package com.progwml6.natura.common.data;
import com.progwml6.natura.Natura;
import net.minecraft.advancements.ICriterionInstance;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.IFinishedRecipe;
import net.minecraft.data.RecipeProvider;
import net.minecraft.data.ShapedRecipeBuilder;
import net.minecraft.data.ShapelessRecipeBuilder;
import net.minecraft.data.SingleItemRecipeBuilder;
import net.minecraft.item.Item;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.tags.ITag;
import net.minecraft.tags.ITag.INamedTag;
import net.minecraft.tags.ItemTags;
import net.minecraft.util.IItemProvider;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.crafting.conditions.ICondition;
import net.minecraftforge.common.crafting.conditions.IConditionBuilder;
import net.minecraftforge.common.crafting.conditions.NotCondition;
import net.minecraftforge.common.crafting.conditions.TagEmptyCondition;
import net.minecraftforge.registries.IForgeRegistryEntry;
import slimeknights.mantle.recipe.data.ConsumerWrapperBuilder;
import slimeknights.mantle.registration.object.BuildingBlockObject;
import slimeknights.mantle.registration.object.WallBuildingBlockObject;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* Shared logic for each module's recipe provider
*/
public abstract class BaseRecipeProvider extends RecipeProvider implements IConditionBuilder {
public BaseRecipeProvider(DataGenerator generator) {
super(generator);
}
@Override
protected abstract void registerRecipes(Consumer<IFinishedRecipe> consumer);
@Override
public abstract String getName();
/* Location helpers */
/**
* Gets a resource location for Tinkers
* @param id Location path
* @return Location for Tinkers
*/
protected static ResourceLocation location(String id) {
return new ResourceLocation(Natura.modID, id);
}
/**
* Gets a resource location string for Tinkers
* @param id Location path
* @return Location for Tinkers
*/
protected static String locationString(String id) {
return Natura.modID + ":" + id;
}
/**
* Prefixes the resource location path with the given value
* @param item Item registry name to use
* @param prefix Prefix value
* @return Resource location path
*/
protected static ResourceLocation wrap(IItemProvider item, String prefix, String suffix) {
ResourceLocation loc = Objects.requireNonNull(item.asItem().getRegistryName());
return location(prefix + loc.getPath() + suffix);
}
/**
* Prefixes the resource location path with the given value
* @param entry Item registry name to use
* @param prefix Prefix value
* @return Resource location path
*/
protected static ResourceLocation wrapR(Supplier<? extends IForgeRegistryEntry<?>> entry, String prefix, String suffix) {
ResourceLocation loc = Objects.requireNonNull(entry.get().getRegistryName());
return location(prefix + loc.getPath() + suffix);
}
/**
* Prefixes the resource location path with the given value
* @param item Item registry name to use
* @param prefix Prefix value
* @return Resource location path
*/
protected static ResourceLocation prefix(IItemProvider item, String prefix) {
ResourceLocation loc = Objects.requireNonNull(item.asItem().getRegistryName());
return location(prefix + loc.getPath());
}
/**
* Prefixes the resource location path with the given value
* @param entry Entry registry name to use
* @param prefix Prefix value
* @return Resource location path
*/
protected static ResourceLocation prefixR(Supplier<? extends IForgeRegistryEntry<?>> entry, String prefix) {
ResourceLocation loc = Objects.requireNonNull(entry.get().getRegistryName());
return location(prefix + loc.getPath());
}
/**
* Prefixes the resource location path with the given value
* @param entry Entry registry name to use
* @param prefix Prefix value
* @return Resource location path
*/
protected static ResourceLocation prefixR(IForgeRegistryEntry<?> entry, String prefix) {
ResourceLocation loc = Objects.requireNonNull(entry.getRegistryName());
return location(prefix + loc.getPath());
}
/**
* Gets a tag by name
* @param modId Mod ID for tag
* @param name Tag name
* @return Tag instance
*/
protected static INamedTag<Item> getTag(String modId, String name) {
return ItemTags.makeWrapperTag(modId + ":" + name);
}
/* Recipe helpers */
/**
* Registers generic building block recipes for slabs and stairs
* @param consumer Recipe consumer
* @param building Building object instance
*/
protected void registerSlabStair(Consumer<IFinishedRecipe> consumer, BuildingBlockObject building, String folder, boolean addStonecutter) {
Item item = building.asItem();
ICriterionInstance hasBlock = hasItem(item);
// slab
IItemProvider slab = building.getSlab();
ShapedRecipeBuilder.shapedRecipe(slab, 6)
.key('B', item)
.patternLine("BBB")
.addCriterion("has_item", hasBlock)
.setGroup(Objects.requireNonNull(slab.asItem().getRegistryName()).toString())
.build(consumer, wrap(item, folder, "_slab"));
// stairs
IItemProvider stairs = building.getStairs();
ShapedRecipeBuilder.shapedRecipe(stairs, 4)
.key('B', item)
.patternLine("B ")
.patternLine("BB ")
.patternLine("BBB")
.addCriterion("has_item", hasBlock)
.setGroup(Objects.requireNonNull(stairs.asItem().getRegistryName()).toString())
.build(consumer, wrap(item, folder, "_stairs"));
// only add stonecutter if relevant
if (addStonecutter) {
Ingredient ingredient = Ingredient.fromItems(item);
SingleItemRecipeBuilder.stonecuttingRecipe(ingredient, slab, 2)
.addCriterion("has_item", hasBlock)
.build(consumer, wrap(item, folder, "_slab_stonecutter"));
SingleItemRecipeBuilder.stonecuttingRecipe(ingredient, stairs)
.addCriterion("has_item", hasBlock)
.build(consumer, wrap(item, folder, "_stairs_stonecutter"));
}
}
/**
* Registers generic building block recipes for slabs, stairs, and walls
* @param consumer Recipe consumer
* @param building Building object instance
*/
protected void registerSlabStairWall(Consumer<IFinishedRecipe> consumer, WallBuildingBlockObject building, String folder, boolean addStonecutter) {
registerSlabStair(consumer, building, folder, addStonecutter);
// wall
Item item = building.asItem();
ICriterionInstance hasBlock = hasItem(item);
IItemProvider wall = building.getWall();
ShapedRecipeBuilder.shapedRecipe(wall, 4)
.key('B', item)
.patternLine("BBB")
.patternLine("BBB")
.addCriterion("has_item", hasBlock)
.setGroup(Objects.requireNonNull(wall.asItem().getRegistryName()).toString())
.build(consumer, wrap(item, folder, "_wall"));
// only add stonecutter if relevant
if (addStonecutter) {
Ingredient ingredient = Ingredient.fromItems(item);
SingleItemRecipeBuilder.stonecuttingRecipe(ingredient, wall)
.addCriterion("has_item", hasBlock)
.build(consumer, wrap(item, folder, "_wall_stonecutter"));
}
}
/**
* Registers a recipe packing a small item into a large one
* @param consumer Recipe consumer
* @param large Large item
* @param small Small item
* @param largeName Large name
* @param smallName Small name
* @param folder Recipe folder
*/
protected void registerPackingRecipe(Consumer<IFinishedRecipe> consumer, String largeName, IItemProvider large, String smallName, IItemProvider small, String folder) {
// ingot to block
ShapedRecipeBuilder.shapedRecipe(large)
.key('#', small)
.patternLine("###")
.patternLine("###")
.patternLine("###")
.addCriterion("has_item", hasItem(small))
.setGroup(Objects.requireNonNull(large.asItem().getRegistryName()).toString())
.build(consumer, wrap(large, folder, String.format("_from_%ss", smallName)));
// block to ingot
ShapelessRecipeBuilder.shapelessRecipe(small, 9)
.addIngredient(large)
.addCriterion("has_item", hasItem(large))
.setGroup(Objects.requireNonNull(small.asItem().getRegistryName()).toString())
.build(consumer, wrap(small, folder, String.format("_from_%s", largeName)));
}
/**
* Registers a recipe packing a small item into a large one
* @param consumer Recipe consumer
* @param largeItem Large item
* @param smallItem Small item
* @param smallTag Tag for small item
* @param largeName Large name
* @param smallName Small name
* @param folder Recipe folder
*/
protected void registerPackingRecipe(Consumer<IFinishedRecipe> consumer, String largeName, IItemProvider largeItem, String smallName, IItemProvider smallItem, ITag<Item> smallTag, String folder) {
// ingot to block
// note our item is in the center, any mod allowed around the edges
ShapedRecipeBuilder.shapedRecipe(largeItem)
.key('#', smallTag)
.key('*', smallItem)
.patternLine("###")
.patternLine("#*#")
.patternLine("###")
.addCriterion("has_item", hasItem(smallItem))
.setGroup(Objects.requireNonNull(largeItem.asItem().getRegistryName()).toString())
.build(consumer, wrap(largeItem, folder, String.format("_from_%ss", smallName)));
// block to ingot
ShapelessRecipeBuilder.shapelessRecipe(smallItem, 9)
.addIngredient(largeItem)
.addCriterion("has_item", hasItem(largeItem))
.setGroup(Objects.requireNonNull(smallItem.asItem().getRegistryName()).toString())
.build(consumer, wrap(smallItem, folder, String.format("_from_%s", largeName)));
}
/* conditions */
/**
* Creates a consumer instance with the added conditions
* @param consumer Base consumer
* @param conditions Extra conditions
* @return Wrapped consumer
*/
protected static Consumer<IFinishedRecipe> withCondition(Consumer<IFinishedRecipe> consumer, ICondition... conditions) {
ConsumerWrapperBuilder builder = ConsumerWrapperBuilder.wrap();
for (ICondition condition : conditions) {
builder.addCondition(condition);
}
return builder.build(consumer);
}
/**
* Creates a condition for a tag existing
* @param name Forge tag name
* @return Condition for tag existing
*/
protected static ICondition tagCondition(String name) {
return new NotCondition(new TagEmptyCondition("forge", name));
}
// Forge constructor is private, not sure if there is a public place for this
protected static class CompoundIngredient extends net.minecraftforge.common.crafting.CompoundIngredient {
public CompoundIngredient(List<Ingredient> children) {
super(children);
}
public CompoundIngredient(Ingredient... children) {
this(Arrays.asList(children));
}
}
}