Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
1package net.lerariemann.infinity.registry.var;
2
3import com.mojang.serialization.Codec;
4import com.mojang.serialization.MapCodec;
5import com.mojang.serialization.codecs.RecordCodecBuilder;
6import dev.architectury.registry.registries.DeferredRegister;
7import net.lerariemann.infinity.InfinityMod;
8import net.lerariemann.infinity.iridescence.Iridescence;
9import net.lerariemann.infinity.registry.core.ModBlocks;
10import net.lerariemann.infinity.util.InfinityMethods;
11import net.lerariemann.infinity.util.VersionMethods;
12import net.lerariemann.infinity.util.core.ConfigType;
13import net.lerariemann.infinity.util.core.RandomProvider;
14import net.minecraft.MethodsReturnNonnullByDefault;
15import net.minecraft.core.Direction;
16import net.minecraft.core.registries.BuiltInRegistries;
17import net.minecraft.core.registries.Registries;
18import net.minecraft.util.KeyDispatchDataCodec;
19import net.minecraft.util.Mth;
20import net.minecraft.world.level.block.Blocks;
21import net.minecraft.world.level.block.LadderBlock;
22import net.minecraft.world.level.block.NoteBlock;
23import net.minecraft.world.level.block.RedstoneLampBlock;
24import net.minecraft.world.level.block.state.BlockState;
25import net.minecraft.world.level.block.state.properties.BlockStateProperties;
26import net.minecraft.world.level.block.state.properties.Half;
27import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
28import net.minecraft.world.level.levelgen.SurfaceRules;
29import org.jspecify.annotations.Nullable;
30
31import static net.lerariemann.infinity.InfinityMod.MOD_ID;
32
33public class ModMaterialRules {
34 static int normalize(int x, int size) {
35 int a = Math.abs(x < 0 ? x+1 : x) % size;
36 return (x < 0) ? size - 1 - a : a;
37 }
38
39 public record RandomBlockStateRule(RandomProvider prov) implements SurfaceRules.SurfaceRule
40 {
41 @Override
42 public BlockState tryApply(int i, int j, int k) {
43 long seed = Mth.getSeed(i, j, k);
44 double d = (seed & 0xFFFL) / (double)0xFFFL;
45 d = d - Math.floor(d);
46 BlockState st = VersionMethods.getBlock(VersionMethods.id(prov.randomName(d, ConfigType.FULL_BLOCKS_WG))).defaultBlockState();
47 if(st.hasProperty(BlockStateProperties.PERSISTENT)) st = st.setValue(BlockStateProperties.PERSISTENT, Boolean.TRUE);
48 return st;
49 }
50 }
51
52 public enum RandomBlockMaterialRule implements SurfaceRules.RuleSource
53 {
54 INSTANCE;
55 static final KeyDispatchDataCodec<RandomBlockMaterialRule> CODEC = KeyDispatchDataCodec.of(MapCodec.unit(INSTANCE));
56 static RandomProvider PROVIDER;
57 public static void setProvider(RandomProvider p) {
58 PROVIDER = p;
59 }
60
61 @Override
62 public KeyDispatchDataCodec<? extends SurfaceRules.RuleSource> codec() {
63 return CODEC;
64 }
65
66 @Override
67 public SurfaceRules.SurfaceRule apply(SurfaceRules.Context materialRuleContext) {
68 return new RandomBlockStateRule(PROVIDER);
69 }
70 }
71
72 public record RandomColoredBlock(String str) implements SurfaceRules.SurfaceRule
73 {
74 @Override
75 public BlockState tryApply(int i, int j, int k) {
76 double d = InfinityMethods.sampler.getValue(i, j, k);
77 d = d - Math.floor(d);
78 BlockState st = Iridescence.getRandomColorBlock(d, str).defaultBlockState();
79 if(st.hasProperty(BlockStateProperties.PERSISTENT)) st = st.setValue(BlockStateProperties.PERSISTENT, Boolean.TRUE);
80 return st;
81 }
82
83 record Rule(String str) implements SurfaceRules.RuleSource
84 {
85 static final KeyDispatchDataCodec<Rule> CODEC = KeyDispatchDataCodec.of(RecordCodecBuilder.mapCodec(instance -> instance.group(
86 Codec.STRING.fieldOf("block_type").orElse("concrete").forGetter(a -> a.str)).apply(instance, Rule::new)));
87
88 @Override
89 public KeyDispatchDataCodec<? extends SurfaceRules.RuleSource> codec() {
90 return CODEC;
91 }
92
93 @Override
94 public SurfaceRules.SurfaceRule apply(SurfaceRules.Context materialRuleContext) {
95 return new RandomColoredBlock(str);
96 }
97 }
98 }
99
100 public static class Notes implements SurfaceRules.SurfaceRule {
101 @Override
102 public @Nullable BlockState tryApply(int i, int j, int k) {
103 NoteBlockInstrument instr = InfinityMethods.getRandomInstrument();
104 BlockState bs = Blocks.NOTE_BLOCK.defaultBlockState().setValue(NoteBlock.INSTRUMENT, instr);
105 if (instr.isTunable()) bs = bs.setValue(NoteBlock.NOTE, InfinityMod.random.nextInt(24));
106 return bs;
107 }
108
109 enum Rule implements SurfaceRules.RuleSource {
110 INSTANCE;
111 static final KeyDispatchDataCodec<Rule> CODEC = KeyDispatchDataCodec.of(MapCodec.unit(INSTANCE));
112 @Override
113 public KeyDispatchDataCodec<? extends SurfaceRules.RuleSource> codec() {
114 return CODEC;
115 }
116 @Override
117 public SurfaceRules.SurfaceRule apply(SurfaceRules.Context materialRuleContext) {
118 return new Notes();
119 }
120 }
121 }
122
123 public static class Lamps implements SurfaceRules.SurfaceRule {
124 @Override
125 public @Nullable BlockState tryApply(int i, int j, int k) {
126 return Blocks.REDSTONE_LAMP.defaultBlockState().setValue(RedstoneLampBlock.LIT, InfinityMod.random.nextBoolean());
127 }
128
129 enum Rule implements SurfaceRules.RuleSource {
130 INSTANCE;
131 static final KeyDispatchDataCodec<Rule> CODEC = KeyDispatchDataCodec.of(MapCodec.unit(INSTANCE));
132 @Override
133 public KeyDispatchDataCodec<? extends SurfaceRules.RuleSource> codec() {
134 return CODEC;
135 }
136 @Override
137 public SurfaceRules.SurfaceRule apply(SurfaceRules.Context materialRuleContext) {
138 return new Lamps();
139 }
140 }
141 }
142
143
144 public static class Library implements SurfaceRules.SurfaceRule
145 {
146 static final BlockState floor = Blocks.OAK_SLAB.defaultBlockState();
147 static final BlockState wall = ModBlocks.BOOK_BOX.get().defaultBlockState();
148 static final BlockState decor = Blocks.GLOWSTONE.defaultBlockState();
149 static final BlockState glass = Blocks.OAK_TRAPDOOR.defaultBlockState();
150 static final BlockState column = Blocks.OAK_PLANKS.defaultBlockState();
151 static final BlockState air = Blocks.AIR.defaultBlockState();
152 @Override
153 public BlockState tryApply(int i, int j, int k) {
154 int x = normalize(i, 15);
155 int y = normalize(j, 16);
156 int z = normalize(k, 15);
157 int max_xz = Math.max(Math.abs(7 - x), Math.abs(7 - z));
158 int min_xz = Math.min(Math.abs(7 - x), Math.abs(7 - z));
159 if (max_xz == 7) {
160 if (min_xz < 2) {
161 if (y == 0) return floor;
162 if (y < 4) return air; //corridors
163 }
164 return wall; //walls
165 }
166 if (max_xz < 2) {
167 return ((x + z) % 2 == 1) ? wall : column; //central column
168 }
169 if (max_xz == 2 && min_xz == 1) {
170 if (j == 0) return floor;
171 Direction d = (x == 5 ? Direction.WEST : x == 9 ? Direction.EAST : z == 5 ? Direction.NORTH : Direction.SOUTH);
172 return Blocks.LADDER.defaultBlockState().setValue(LadderBlock.FACING, d); //ladders
173 }
174 if (y == 0) {
175 if (max_xz == 4) {
176 if (min_xz == 4) return decor;
177 if (min_xz == 0 && j > 0) return glass; //lighting
178 }
179 return floor; //floor
180 }
181 return air;
182 }
183
184 enum Rule implements SurfaceRules.RuleSource {
185 INSTANCE;
186 static final KeyDispatchDataCodec<Rule> CODEC = KeyDispatchDataCodec.of(MapCodec.unit(INSTANCE));
187 @Override
188 public KeyDispatchDataCodec<? extends SurfaceRules.RuleSource> codec() {
189 return CODEC;
190 }
191 @Override
192 public SurfaceRules.SurfaceRule apply(SurfaceRules.Context materialRuleContext) {
193 return new Library();
194 }
195 }
196 }
197
198 public static class Backrooms implements SurfaceRules.SurfaceRule {
199 static final BlockState floor = Blocks.MUSHROOM_STEM.defaultBlockState();
200 static final BlockState wall = Blocks.SMOOTH_SANDSTONE.defaultBlockState();
201 static final BlockState light = Blocks.OCHRE_FROGLIGHT.defaultBlockState();
202 static final BlockState ceiling = Blocks.SMOOTH_SANDSTONE.defaultBlockState();
203 static final BlockState air = Blocks.AIR.defaultBlockState();
204 static final BlockState filler = Blocks.OBSIDIAN.defaultBlockState();
205 static int anti_normalize(int x, int size) {
206 return Math.abs(x < 0 ? x+1 : x) / size;
207 }
208 @Override
209 public BlockState tryApply(int i, int j, int k) {
210 int size_xz = 15;
211 int halfsize_xz = 7;
212 int x = normalize(i, size_xz);
213 int y = normalize(j-1, 16);
214 int z = normalize(k, size_xz);
215 int xrel = Math.abs(halfsize_xz - x);
216 int zrel = Math.abs(halfsize_xz - z);
217 int max_xz = Math.max(xrel, zrel);
218 int min_xz = Math.min(xrel, zrel);
219 boolean isXMax = max_xz == xrel;
220 boolean isOpen = (max_xz >= 3) && (min_xz <= 3) && (y <= 6) && ((double) (Mth.getSeed(
221 2*anti_normalize(i, size_xz) - Mth.sign(i)*Mth.sign(halfsize_xz - x)*(isXMax ? 1 : 0),
222 anti_normalize(j-1, 16),
223 2*anti_normalize(k, size_xz) - Mth.sign(k)*Mth.sign(halfsize_xz - z)*(isXMax ? 0 : 1))
224 & 0xFL) / 15.0 > 0.3);
225 if (isOpen || (min_xz <=3 && y <= 6 && (i==0 || k==0))) {
226 if (min_xz == 3) return wall;
227 if (y == 0) return floor;
228 if (y == 6) {
229 if (min_xz == 0 && max_xz%3 == 0) return light;
230 return ceiling;
231 }
232 return air;
233 }
234 else if (max_xz <= 3 && y <= 6) {
235 if (max_xz == 3) return wall;
236 if (y == 0) return floor;
237 if (y == 6) {
238 if (max_xz == 0) return light;
239 return ceiling;
240 }
241 return air;
242 }
243 return filler;
244 }
245
246 enum Rule implements SurfaceRules.RuleSource {
247 INSTANCE;
248 static final KeyDispatchDataCodec<Rule> CODEC = KeyDispatchDataCodec.of(MapCodec.unit(INSTANCE));
249 @Override
250 public KeyDispatchDataCodec<? extends SurfaceRules.RuleSource> codec() {
251 return CODEC;
252 }
253 @Override
254 public SurfaceRules.SurfaceRule apply(SurfaceRules.Context materialRuleContext) {
255 return new Backrooms();
256 }
257 }
258 }
259
260 public static class Nexus implements SurfaceRules.SurfaceRule
261 {
262 static final BlockState floor = Blocks.SMOOTH_STONE.defaultBlockState();
263 static final BlockState wall = Blocks.OAK_PLANKS.defaultBlockState();
264 static final BlockState column1 = Blocks.OAK_LOG.defaultBlockState();
265 static final BlockState column2 = Blocks.OAK_LOG.defaultBlockState().setValue(BlockStateProperties.AXIS, Direction.Axis.X);
266 static final BlockState stair1 = Blocks.OAK_STAIRS.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.NORTH);
267 static final BlockState stair2 = Blocks.OAK_STAIRS.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.SOUTH);
268 static final BlockState stair3 = Blocks.OAK_STAIRS.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.NORTH).setValue(BlockStateProperties.HALF, Half.TOP);
269 static final BlockState stair4 = Blocks.OAK_STAIRS.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.SOUTH).setValue(BlockStateProperties.HALF, Half.TOP);
270 static final BlockState light1 = Blocks.JACK_O_LANTERN.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.SOUTH);
271 static final BlockState light2 = Blocks.JACK_O_LANTERN.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.NORTH);
272 static final BlockState light3 = Blocks.GLOWSTONE.defaultBlockState();
273 static final BlockState air = Blocks.AIR.defaultBlockState();
274 @Override
275 public BlockState tryApply(int i, int j, int k) {
276 int x = normalize(i, 8);
277 int y = j - 50;
278 int z = normalize(k, 16);
279 if (y==-2) return Blocks.BEDROCK.defaultBlockState();
280 switch (y) {
281 case -1, 9 -> {
282 if ((z == 10 || z == 6) && (x == 0 || x == 4)) return light3;
283 return (y == -1) ? floor : wall;
284 }
285 case 0 -> {
286 return switch (z) {
287 case 0, 1, 2, 14, 15 -> wall;
288 case 3 -> stair1;
289 case 13 -> stair2;
290 default -> air;
291 };
292 }
293 case 1, 2, 3, 4, 5 -> {
294 if (z == 0) return wall;
295 if (z == 1 || z == 15) {
296 if (x == 5 || x == 7) return column1;
297 if (x==6) {
298 if (y != 3) return wall;
299 return (z == 1) ? light1 : light2;
300 }
301 }
302 return air;
303 }
304 case 6 -> {
305 if (z == 0) return wall;
306 return (z == 1 || z == 15) ? column2 : air;
307 }
308 case 7 -> {
309 return switch (z) {
310 case 2 -> stair3;
311 case 14 -> stair4;
312 case 0, 1, 15 -> wall;
313 default -> air;
314 };
315 }
316 case 8 -> {
317 return switch (z) {
318 case 0, 1, 2, 3, 13, 14, 15 -> wall;
319 case 4 -> stair3;
320 case 12 -> stair4;
321 default -> air;
322 };
323 }
324 default -> {
325 return air;
326 }
327 }
328 }
329
330 enum Rule implements SurfaceRules.RuleSource {
331 INSTANCE;
332 static final KeyDispatchDataCodec<Rule> CODEC = KeyDispatchDataCodec.of(MapCodec.unit(INSTANCE));
333 @Override
334 public KeyDispatchDataCodec<? extends SurfaceRules.RuleSource> codec() {
335 return CODEC;
336 }
337 @Override
338 public SurfaceRules.SurfaceRule apply(SurfaceRules.Context materialRuleContext) {
339 return new Nexus();
340 }
341 }
342 }
343
344 public static class Perfection implements SurfaceRules.SurfaceRule
345 {
346 static final BlockState cobblestone = Blocks.COBBLESTONE.defaultBlockState();
347 static final BlockState lightNorth = Blocks.WALL_TORCH.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.NORTH);
348 static final BlockState lightSouth = Blocks.WALL_TORCH.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.SOUTH);
349 static final BlockState lightEast = Blocks.WALL_TORCH.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.EAST);
350 static final BlockState lightWest = Blocks.WALL_TORCH.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.WEST);
351 static final BlockState glass = Blocks.GLASS.defaultBlockState();
352 static final BlockState air = Blocks.AIR.defaultBlockState();
353 @Override
354 public BlockState tryApply(int i, int j, int k) {
355 int x = normalize(i, 10);
356 int y = j - 50;
357 int z = normalize(k, 10);
358 if (y==-2) return Blocks.BEDROCK.defaultBlockState();
359 switch (y) {
360 case -1 -> {
361 return cobblestone;
362 }
363 case 4 -> {
364 //Skylights
365 if ((z == 7 || z == 6 || z == 0 || z == 9) && (x == 0 || x == 9 || x == 2 || x == 3)) return glass;
366 return cobblestone;
367 }
368 case 3 -> {
369 // Crossroad overhang, North/South
370 if (z == 2 || z == 3 || z == 4) {
371 return cobblestone;
372 }
373 //Crossroad torch - South (North facing)
374 else if (z == 1) {
375 if (x == 1) {
376 return lightNorth;
377 }
378 }
379 //Crossroad torch - North (South facing)
380 else if (z == 5) {
381 if (x == 1) {
382 return lightSouth;
383 }
384 }
385 // Crossroad overhang, East/West
386 if (x == 7 || x == 6 || x == 5) {
387 return cobblestone;
388 }
389 //Crossroad torch - West (East facing)
390 else if (x == 8) {
391 if (z == 8) {
392 return lightEast;
393 }
394 }
395 //Crossroad torch - East (West facing)
396 else if (x == 4) {
397 if (z == 8) {
398 return lightWest;
399 }
400 }
401 return air;
402 }
403 case 0, 1, 2 -> {
404 //Crossroad walls, East/West
405 if (x == 7 || x == 6 || x == 5) {
406 if (z == 7 || z == 8 || z == 9) {
407 return air;
408 }
409 return cobblestone;
410 }
411 //Crossroad walls, North/South
412 if (z == 2 || z == 3 || z == 4 || z == 12 || z == 13 || z == 14) {
413 if (x == 0 || x == 2 || x == 1) {
414 return air;
415 }
416 return cobblestone;
417 }
418
419 return air;
420 }
421 default -> {
422 return air;
423 }
424 }
425 }
426
427 enum Rule implements SurfaceRules.RuleSource {
428 INSTANCE;
429 static final KeyDispatchDataCodec<Rule> CODEC = KeyDispatchDataCodec.of(MapCodec.unit(INSTANCE));
430 @Override
431 public KeyDispatchDataCodec<? extends SurfaceRules.RuleSource> codec() {
432 return CODEC;
433 }
434 @Override
435 public SurfaceRules.SurfaceRule apply(SurfaceRules.Context materialRuleContext) {
436 return new Perfection();
437 }
438 }
439 }
440
441 public static final DeferredRegister<
442 //? if >1.21 {
443 MapCodec
444 //?} else {
445 /*Codec
446 *///?}
447 <? extends SurfaceRules.RuleSource>> MATERIAL_RULES =
448 DeferredRegister.create(MOD_ID, Registries.MATERIAL_RULE);
449
450 public static <R extends SurfaceRules.RuleSource, T extends KeyDispatchDataCodec<R>> void register(String name, T holder) {
451 MATERIAL_RULES.register(name, holder::codec);
452 }
453
454 public static void registerRules() {
455 register("chaos", RandomBlockMaterialRule.CODEC);
456 register("colored_chaos", RandomColoredBlock.Rule.CODEC);
457 register("notes", Notes.Rule.CODEC);
458 register("lamps", Lamps.Rule.CODEC);
459 register("library", Library.Rule.CODEC);
460 register("backrooms", Backrooms.Rule.CODEC);
461 register("nexus", Nexus.Rule.CODEC);
462 register("perfection", Perfection.Rule.CODEC);
463 MATERIAL_RULES.register();
464 }
465}