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 java.util.HashSet;
6import java.util.List;
7import java.util.Set;
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.Block;
13import net.minecraft.world.level.block.state.BlockState;
14import net.minecraft.world.level.levelgen.feature.Feature;
15import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
16import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
17import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
18
19public class RandomCeilingBlobFeature extends Feature<RandomCeilingBlobFeature.Config> {
20 public RandomCeilingBlobFeature(Codec<Config> codec) {
21 super(codec);
22 }
23
24 @Override
25 public boolean place(FeaturePlaceContext<Config> context) {
26 WorldGenLevel structureWorldAccess = context.level();
27 BlockPos blockPos = context.origin();
28 RandomSource random = context.random();
29 if (!structureWorldAccess.isEmptyBlock(blockPos)) {
30 return false;
31 }
32 BlockState blockState = structureWorldAccess.getBlockState(blockPos.above());
33 Set<Block> blocks = new HashSet<>();
34 Config config = context.config();
35 for (BlockState b : config.target_blocks()) blocks.add(b.getBlock());
36 if (!blocks.contains(blockState.getBlock())) {
37 return false;
38 }
39 BlockState state = context.config().block().getState(random, blockPos);
40 structureWorldAccess.setBlock(blockPos, state, Block.UPDATE_CLIENTS);
41 for (int i = 0; i < 1500; ++i) {
42 BlockPos blockPos2 = blockPos.offset(random.nextInt(config.size_xz()) - random.nextInt(config.size_xz()),
43 -random.nextInt(config.size_y()), random.nextInt(config.size_xz()) - random.nextInt(config.size_xz()));
44 if (!structureWorldAccess.getBlockState(blockPos2).isAir()) continue;
45 int j = 0;
46 for (Direction direction : Direction.values()) {
47 if (structureWorldAccess.getBlockState(blockPos2.relative(direction)).is(state.getBlock())) {
48 ++j;
49 }
50 if (j > 1) break;
51 }
52 if (j == 0) continue;
53 structureWorldAccess.setBlock(blockPos2, state, Block.UPDATE_CLIENTS);
54 }
55 return true;
56 }
57
58 public record Config(BlockStateProvider block, List<BlockState> target_blocks, int size_xz, int size_y) implements FeatureConfiguration {
59 public static final Codec<Config> CODEC = RecordCodecBuilder.create(instance -> instance.group(
60 (BlockStateProvider.CODEC.fieldOf("block")).forGetter(a -> a.block),
61 (Codec.list(BlockState.CODEC).fieldOf("targets")).forGetter(a -> a.target_blocks),
62 (Codec.INT.fieldOf("size_xz")).forGetter(a -> a.size_xz),
63 (Codec.INT.fieldOf("size_y")).forGetter(a -> a.size_y)).apply(
64 instance, Config::new));
65 }
66}