Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
at master 465 lines 20 kB view raw
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}