Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
at master 113 lines 5.7 kB view raw
1package net.lerariemann.infinity.features; 2 3import com.mojang.serialization.Codec; 4import com.mojang.serialization.codecs.RecordCodecBuilder; 5import net.lerariemann.infinity.registry.core.ModBlocks; 6import net.lerariemann.infinity.block.entity.InfinityPortalBlockEntity; 7import net.lerariemann.infinity.util.InfinityMethods; 8import net.minecraft.core.BlockPos; 9import net.minecraft.core.Direction; 10import net.minecraft.util.RandomSource; 11import net.minecraft.world.level.WorldGenLevel; 12import net.minecraft.world.level.block.Blocks; 13import net.minecraft.world.level.block.NetherPortalBlock; 14import net.minecraft.world.level.block.state.BlockState; 15import net.minecraft.world.level.block.state.properties.BlockStateProperties; 16import net.minecraft.world.level.levelgen.feature.Feature; 17import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; 18import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; 19import java.util.HashSet; 20import java.util.Set; 21 22public class RandomPortalSetupper extends Feature<RandomPortalSetupper.Config> { 23 public RandomPortalSetupper(Codec<Config> configCodec) { 24 super(configCodec); 25 } 26 27 28 public static Set<Integer> tileChunkPositions(int start, int offset) { 29 Set<Integer> ls = new HashSet<>(); 30 int mod = InfinityMethods.properMod(start, offset); 31 int d_start = mod == 0 ? 0 : offset - mod; 32 for (int d_curr = d_start; d_curr < 16; d_curr += offset) ls.add(start + d_curr); 33 return ls; 34 } 35 36 @Override 37 public boolean place(FeaturePlaceContext<Config> context) { 38 WorldGenLevel structureWorldAccess = context.level(); 39 BlockPos blockPos = context.origin(); 40 int y = context.config().y(); 41 RandomSource random = context.random(); 42 boolean axis_x = context.config().axis_x(); 43 44 int width = context.config().width(); 45 int sol = context.config().sign_offset_l(); 46 if (sol == 0) sol = (width + 1) / 2; 47 int height = context.config().height(); 48 int soy = context.config().sign_offset_y(); 49 if (y == 0) soy = height + 1; 50 51 Set<Integer> ls = tileChunkPositions(axis_x ? blockPos.getX() : blockPos.getZ(), context.config().offset_l()); 52 Set<Integer> ts = tileChunkPositions(axis_x ? blockPos.getZ() : blockPos.getX(), context.config().offset_t()); 53 boolean bl = !ls.isEmpty() && !ts.isEmpty(); 54 for (int i : ls) for (int j : ts) { 55 bl = bl && generateOnePortal(structureWorldAccess, 56 axis_x ? new BlockPos(i, y, j) : new BlockPos(j, 0, i), 57 random, axis_x, width, height, sol, soy); 58 59 } 60 return bl; 61 } 62 63 final static BlockState obs = Blocks.OBSIDIAN.defaultBlockState(); 64 final static BlockState sign = Blocks.OAK_HANGING_SIGN.defaultBlockState(); 65 66 public static BlockPos bpadd(BlockPos bp, int l, int y, int t, boolean axis_x) { 67 return axis_x ? bp.offset(l, y, t) : bp.offset(t, y, l); 68 } 69 70 public boolean generateOnePortal(WorldGenLevel structureWorldAccess, BlockPos blockPos, RandomSource random, 71 boolean axis_x, int width, int height, int sol, int soy) { 72 long dim = InfinityMethods.getRandomSeed(random); 73 for (int y = 0; y < height+2; y++) { 74 if (y == 0 || y == height+1) for (int l = 0; l < width+2; l++) { 75 setBlock(structureWorldAccess, bpadd(blockPos, l, y, 0, axis_x), obs); 76 } 77 else { 78 setBlock(structureWorldAccess, blockPos.offset(0, y, 0), obs); 79 setBlock(structureWorldAccess, bpadd(blockPos, width+1, y, 0, axis_x), obs); 80 for (int l = 1; l < width+1; l++) { 81 BlockPos pos = bpadd(blockPos, l, y, 0, axis_x); 82 setBlock(structureWorldAccess, pos, 83 ModBlocks.PORTAL.get().defaultBlockState().setValue( 84 NetherPortalBlock.AXIS, axis_x ? Direction.Axis.X : Direction.Axis.Z)); 85 if (structureWorldAccess.getBlockEntity(pos) instanceof InfinityPortalBlockEntity be) { 86 be.setDimension(dim); 87 be.setOpen(false); 88 be.setChanged(); 89 } 90 else return false; 91 } 92 } 93 } 94 for (int i: Set.of(1, -1)) setBlock(structureWorldAccess, 95 bpadd(blockPos, sol, soy, i, axis_x), 96 axis_x ? sign : sign.setValue(BlockStateProperties.ROTATION_16, 4)); 97 return true; 98 } 99 100 public record Config(boolean axis_x, int width, int height, int offset_l, int offset_t, 101 int sign_offset_l, int sign_offset_y, int y) implements FeatureConfiguration { 102 public static final Codec<Config> CODEC = RecordCodecBuilder.create(instance -> instance.group( 103 (Codec.BOOL.fieldOf("axis_x")).orElse(Boolean.TRUE).forGetter(a -> a.axis_x), 104 (Codec.INT.fieldOf("width")).orElse(2).forGetter(a -> a.width), 105 (Codec.INT.fieldOf("height")).orElse(3).forGetter(a -> a.height), 106 (Codec.INT.fieldOf("offset_l")).orElse(8).forGetter(a -> a.offset_l), 107 (Codec.INT.fieldOf("offset_t")).orElse(8).forGetter(a -> a.offset_t), 108 (Codec.INT.fieldOf("sign_offset_l")).orElse(0).forGetter(a -> a.sign_offset_l), 109 (Codec.INT.fieldOf("sign_offset_y")).orElse(0).forGetter(a -> a.sign_offset_y), 110 (Codec.INT.fieldOf("y")).orElse(16).forGetter(a -> a.y)).apply( 111 instance, Config::new)); 112 } 113}