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