Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
1package net.lerariemann.infinity.item.function;
2
3import com.google.gson.JsonObject;
4import com.mojang.datafixers.util.Function3;
5import com.mojang.datafixers.util.Function4;
6import com.mojang.serialization.MapCodec;
7import com.mojang.serialization.codecs.RecordCodecBuilder;
8import net.lerariemann.infinity.registry.core.ModItemFunctions;
9import net.lerariemann.infinity.util.VersionMethods;
10import net.minecraft.MethodsReturnNonnullByDefault;
11import net.minecraft.core.registries.BuiltInRegistries;
12import net.minecraft.util.ExtraCodecs;
13import net.minecraft.world.item.ItemStack;
14import net.minecraft.world.item.crafting.*;
15//? if >1.21 {
16import net.minecraft.world.item.crafting.SingleRecipeInput;
17import net.minecraft.core.HolderLookup;
18import net.minecraft.network.RegistryFriendlyByteBuf;
19import net.minecraft.network.codec.ByteBufCodecs;
20import net.minecraft.network.codec.StreamCodec;
21//?} else {
22/*import net.minecraft.world.ticks.ContainerSingleItem;
23import net.minecraft.core.RegistryAccess;
24import net.minecraft.util.GsonHelper;
25import net.minecraft.network.FriendlyByteBuf;
26import net.minecraft.resources.ResourceLocation;
27*///?}
28import net.minecraft.world.level.Level;
29
30public abstract class CollisionCraftingRecipe
31 //? if >1.21 {
32 implements Recipe<SingleRecipeInput>
33 //?} else {
34 /*implements Recipe<ContainerSingleItem>
35 *///?}
36 {
37 //? if =1.20.1 {
38 /*protected final ResourceLocation id;
39 *///?}
40 protected final Ingredient input;
41 protected final ItemStack output;
42 protected final String lore;
43
44 public CollisionCraftingRecipe(
45 //? if =1.20.1 {
46 /*ResourceLocation id,
47 *///?}
48 Ingredient input, ItemStack output, String lore) {
49 //? if =1.20.1 {
50 /*this.id = id;
51 *///?}
52 this.input = input;
53 this.output = output;
54 this.lore = lore;
55 }
56
57 @Override
58 public boolean matches(
59 //? if >1.21 {
60 SingleRecipeInput
61 //?} else {
62 /*ContainerSingleItem
63 *///?}
64 input, Level world) {
65 if (world.isClientSide()) return false;
66 return this.input.test(input.
67 //? if >1.21 {
68 item
69 //?} else {
70 /*getFirstItem
71 *///?}
72 ());
73 }
74
75 @Override
76 public ItemStack assemble(
77 //? if >1.21 {
78 SingleRecipeInput
79 //?} else {
80 /*ContainerSingleItem
81 *///?}
82 input,
83 //? if >1.21 {
84 HolderLookup.Provider
85 //?} else {
86 /*RegistryAccess
87 *///?}
88 lookup) {
89 return output;
90 }
91
92 //? if <1.21.2 {
93 /*@Override
94 public boolean canCraftInDimensions(int width, int height) {
95 return true;
96 }
97 *///?}
98
99 //? if <1.21.2
100 /*@Override*/
101 public ItemStack getResultItem(
102 //? if =1.21.1 {
103 /*HolderLookup.Provider registriesLookup
104 *///?} else if =1.20.1 {
105 /*RegistryAccess registryAccess
106 *///?}
107 ) {
108 return output.copy();
109 }
110
111 public Ingredient getInput() {
112 return input;
113 }
114 public String getLore() { return lore; }
115
116 public enum Type implements RecipeType<CollisionCraftingRecipe> {
117 PORTAL,
118 IRIDESCENCE
119 }
120
121 public record Serializer(
122 //? if =1.20.1 {
123 /*Function4<ResourceLocation, Ingredient, ItemStack, String, CollisionCraftingRecipe> func
124 *///?} else {
125 Function3<Ingredient, ItemStack, String, CollisionCraftingRecipe> func
126 //?}
127 ) implements RecipeSerializer<CollisionCraftingRecipe> {
128
129 //? if >1.21 {
130 @Override
131 public MapCodec<CollisionCraftingRecipe> codec() {
132 return RecordCodecBuilder.mapCodec(instance -> instance.group(
133 //? if >1.21.2 {
134 Ingredient.CODEC
135 //?} else {
136 /*Ingredient.CODEC_NONEMPTY
137 *///?}
138 .fieldOf("input").forGetter(recipe -> recipe.input),
139 ItemStack.STRICT_CODEC.fieldOf("output").forGetter(recipe -> recipe.output),
140 ExtraCodecs.NON_EMPTY_STRING.fieldOf("lore").forGetter(recipe -> recipe.lore))
141 .apply(instance, func));
142 }
143
144 @Override
145 public StreamCodec<RegistryFriendlyByteBuf, CollisionCraftingRecipe> streamCodec() {
146 return StreamCodec.of(this::write, this::read);
147 }
148
149 private CollisionCraftingRecipe read(RegistryFriendlyByteBuf buf) {
150 Ingredient input = Ingredient.CONTENTS_STREAM_CODEC.decode(buf);
151 ItemStack output = ItemStack.STREAM_CODEC.decode(buf);
152 String str = ByteBufCodecs.STRING_UTF8.decode(buf);
153 return func.apply(input, output, str);
154 }
155
156 private void write(RegistryFriendlyByteBuf buf, CollisionCraftingRecipe recipe) {
157 Ingredient.CONTENTS_STREAM_CODEC.encode(buf, recipe.input);
158 ItemStack.STREAM_CODEC.encode(buf, recipe.output);
159 ByteBufCodecs.STRING_UTF8.encode(buf, recipe.lore);
160 }
161 //?} else {
162 /*@Override
163 public CollisionCraftingRecipe fromJson(ResourceLocation id, JsonObject json) {
164 Ingredient input = Ingredient.fromJson(GsonHelper.getNonNull(json, "input"));
165 ItemStack output = ShapedRecipe.itemStackFromJson(GsonHelper.getAsJsonObject(json, "output"));
166 String lore;
167 try {
168 lore = GsonHelper.getAsString(json, "lore");
169 } catch (Throwable e) {
170 lore = "";
171 }
172 return func.apply(id, input, output, lore);
173 }
174
175 @Override
176 public CollisionCraftingRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buf) {
177 ResourceLocation id2 = buf.readResourceLocation();
178 Ingredient input = Ingredient.fromNetwork(buf);
179 ItemStack output = buf.readItem();
180 String lore = buf.readUtf();
181 return func.apply(id2, input, output, lore);
182 }
183
184 @Override
185 public void toNetwork(FriendlyByteBuf buf, CollisionCraftingRecipe recipe) {
186 buf.writeResourceLocation(recipe.id);
187 recipe.input.toNetwork(buf);
188 buf.writeItem(recipe.output);
189 buf.writeUtf(recipe.lore);
190 }
191 *///?}
192 }
193
194 public static class OfPortal extends CollisionCraftingRecipe {
195 public OfPortal(
196 //? if =1.20.1 {
197 /*ResourceLocation id,
198 *///?}
199 Ingredient input, ItemStack output, String lore) {
200 super(
201 //? if =1.20.1 {
202 /*id,
203 *///?}
204 input, output, lore);
205 }
206
207 //? if <1.21 {
208 /*@Override
209 public ResourceLocation getId() {
210 return this.id;
211 }
212 *///?}
213
214 @Override
215 public RecipeSerializer<? extends Recipe<
216 //? if >1.21 {
217 SingleRecipeInput
218 //?} else {
219 /*ContainerSingleItem
220 *///?}
221 >> getSerializer() {
222 return ModItemFunctions.PORTAL_CRAFTING.get();
223 }
224 @Override
225 public RecipeType<? extends Recipe<
226 //? if >1.21 {
227 SingleRecipeInput
228 //?} else {
229 /*ContainerSingleItem
230 *///?}
231 >> getType() {
232 return ModItemFunctions.PORTAL_CRAFTING_TYPE.get();
233 }
234 //? if >1.21.2 {
235 @Override
236 public PlacementInfo placementInfo() {
237 return PlacementInfo.create(getInput());
238 }
239
240 @Override
241 public RecipeBookCategory recipeBookCategory() {
242 return RecipeBookCategories.CRAFTING_MISC;
243 }
244 @Override
245 public boolean isSpecial() {
246 return true;
247 }
248 //?}
249 }
250
251 public static class OfIridescence extends CollisionCraftingRecipe {
252 public OfIridescence(
253 //? if =1.20.1 {
254 /*ResourceLocation id,
255 *///?}
256 Ingredient input, ItemStack output, String lore) {
257 super(
258 //? if =1.20.1 {
259 /*id,
260 *///?}
261 input, output, lore);
262 }
263
264 //? if <1.21 {
265 /*@Override
266 public ResourceLocation getId() {
267 return this.id;
268 }
269 *///?}
270
271 @Override
272 public RecipeSerializer<CollisionCraftingRecipe> getSerializer() {
273 return ModItemFunctions.IRIDESCENCE_CRAFTING.get();
274 }
275 @Override
276 public RecipeType<CollisionCraftingRecipe> getType() {
277 return ModItemFunctions.IRIDESCENCE_CRAFTING_TYPE.get();
278 }
279
280 //? if >1.21.2 {
281 @Override
282 public PlacementInfo placementInfo() {
283 return PlacementInfo.create(getInput());
284 }
285
286 @Override
287 public RecipeBookCategory recipeBookCategory() {
288 return RecipeBookCategories.CRAFTING_MISC;
289 }
290
291 @Override
292 public boolean isSpecial() {
293 return true;
294 }
295
296 //?}
297 }
298}