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.util.var.TextData;
6import net.minecraft.core.BlockPos;
7import net.minecraft.util.RandomSource;
8import net.minecraft.world.level.WorldGenLevel;
9import net.minecraft.world.level.block.state.BlockState;
10import net.minecraft.world.level.levelgen.feature.Feature;
11import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
12import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
13import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
14import java.util.List;
15
16public class TextFeature extends Feature<TextFeature.Config> {
17 public TextFeature(Codec<Config> codec) {
18 super(codec);
19 }
20
21 @Override
22 public boolean place(FeaturePlaceContext<Config> context) {
23 WorldGenLevel structureWorldAccess = context.level();
24 RandomSource random = context.random();
25 BlockPos blockPos = context.origin();
26 blockPos = TextData.mutate(blockPos, context.config().orientation(), 0, -16);
27 String text = context.config().text();
28 int i2 = 8 + random.nextInt(16);
29 if (text.length() > i2) {
30 int i1 = random.nextInt(text.length() - i2);
31 text = text.substring(i1, i1 + i2);
32 }
33 int i, j, k;
34 int len = 0;
35 for (i = 0; i < text.length(); i++) {
36 List<Integer> lst = TextData.storage.get(text.charAt(i));
37 if (lst != null) {
38 if (!structureWorldAccess.hasChunkAt(TextData.mutate(blockPos, context.config().orientation(), 0, len + lst.size() - 1))) break;
39 for (j = 0; j < lst.size(); j++) {
40 for (k = 0; k < 8; k++) {
41 if ((lst.get(j) >> k)%2 == 1) {
42 BlockPos blockPos1 = TextData.mutate(blockPos, context.config().orientation(), -k, len + j);
43 if ((structureWorldAccess.isEmptyBlock(blockPos1) || context.config().replaceable().contains(structureWorldAccess.getBlockState(blockPos1))))
44 this.setBlock(structureWorldAccess, blockPos1, context.config().blockProvider().getState(random, blockPos1));
45 }
46 }
47 }
48 len += lst.size() + context.config().spacing();
49 }
50 }
51 return true;
52 }
53
54 public record Config(BlockStateProvider blockProvider, List<BlockState> replaceable, int orientation, int spacing, String text) implements FeatureConfiguration {
55 public static final Codec<Config> CODEC = RecordCodecBuilder.create(instance -> instance.group(
56 (BlockStateProvider.CODEC.fieldOf("block_provider")).forGetter(a -> a.blockProvider),
57 (Codec.list(BlockState.CODEC).fieldOf("replaceable")).forGetter(a -> a.replaceable),
58 (Codec.INT.fieldOf("orientation")).orElse(2).forGetter(a -> a.orientation),
59 (Codec.INT.fieldOf("spacing")).orElse(1).forGetter(a -> a.spacing),
60 (Codec.STRING.fieldOf("text")).forGetter(a -> a.text)).apply(instance, Config::new));
61 }
62}