Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
1package net.lerariemann.infinity.structure;
2
3import com.mojang.serialization.Codec;
4import com.mojang.serialization.MapCodec;
5import com.mojang.serialization.codecs.RecordCodecBuilder;
6import net.lerariemann.infinity.util.var.TextData;
7import net.minecraft.core.BlockPos;
8import net.minecraft.core.Direction;
9import net.minecraft.world.level.levelgen.Heightmap;
10import net.minecraft.world.level.levelgen.WorldGenerationContext;
11import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
12import net.minecraft.world.level.levelgen.heightproviders.HeightProvider;
13import net.minecraft.world.level.levelgen.structure.Structure;
14import net.minecraft.world.level.levelgen.structure.StructureType;
15import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
16import net.lerariemann.infinity.registry.core.ModStructureTypes;
17import java.util.List;
18import java.util.Optional;
19
20public class TextStructure extends Structure {
21 public static final MapCodec<TextStructure> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
22 TextStructure.settingsCodec(instance),
23 (Codec.STRING.fieldOf("text")).forGetter(a -> a.text),
24 (BlockStateProvider.CODEC.fieldOf("block")).forGetter(a -> a.block),
25 (Codec.INT.fieldOf("polarization")).orElse(2).forGetter(a -> a.pol.id),
26 (Codec.STRING.fieldOf("direction")).orElse("random").forGetter(a -> a.dir),
27 (Codec.INT.fieldOf("char_spacing")).orElse(1).forGetter(a -> a.char_spacing),
28 (Codec.INT.fieldOf("line_spacing")).orElse(1).forGetter(a -> a.line_spacing),
29 (HeightProvider.CODEC.fieldOf("y")).forGetter(a -> a.y_provider)).apply(instance, TextStructure::new));
30 String text;
31 BlockStateProvider block;
32 String dir;
33 int line_spacing;
34 int char_spacing;
35 HeightProvider y_provider;
36 TextData.Polarization pol;
37
38
39 TextStructure(StructureSettings config, String text, BlockStateProvider block, int pol, String dir,
40 int line_spacing, int char_spacing, HeightProvider y_provider) {
41 super(config);
42 this.text = text;
43 this.block = block;
44 this.dir = dir;
45 this.pol = TextData.Polarization.of(pol);
46 this.line_spacing = line_spacing;
47 this.char_spacing = char_spacing;
48 this.y_provider = y_provider;
49 }
50
51 public Direction getDir(GenerationContext context) {
52 return switch (dir) {
53 case "N" -> Direction.NORTH;
54 case "S" -> Direction.SOUTH;
55 case "W" -> Direction.WEST;
56 case "E" -> Direction.EAST;
57 default -> Direction.Plane.HORIZONTAL.getRandomDirection(context.random());
58 };
59 }
60
61 @Override
62 public Optional<GenerationStub> findGenerationPoint(GenerationContext context) {
63 return onTopOfChunkCenter(context, Heightmap.Types.WORLD_SURFACE_WG, collector -> addPieces(collector, context));
64 }
65
66 @Override
67 public StructureType<?> type() {
68 return ModStructureTypes.TEXT.get();
69 }
70
71 private void addPieces(StructurePiecesBuilder collector, GenerationContext context) {
72 BlockPos centerPos = context.chunkPos().getWorldPosition().offset(8, 0, 8);
73 int new_y = y_provider.sample(context.random(), new WorldGenerationContext(context.chunkGenerator(), context.heightAccessor()));
74 centerPos = centerPos.above(new_y - centerPos.getY());
75 int maxsize = 119;
76 TextData data = TextData.genData(char_spacing, 2*maxsize, text);
77
78 int line_height = 8+line_spacing;
79 int length = Math.min(2*maxsize, data.longest_line());
80 int height = Math.min(2*maxsize, line_height*data.getLineCount());
81
82 Direction dir = getDir(context);
83 int ori = TextData.getOri(pol, dir);
84 for (int i = 0; i < data.getLineCount(); i++) {
85 for (int j = 0; j < data.getLineLen(i); j++) {
86 int line = -height/2 + i*line_height;
87 if (line > maxsize) {
88 break;
89 }
90 int len = -length/2 + data.offsetMap().get(i).get(j);
91 List<Integer> lst = TextData.storage.get(data.charMap().get(i).get(j));
92 if (lst == null) {
93 continue;
94 }
95 BlockPos letterOrigin = TextData.mutate(centerPos, ori, line, len);
96 collector.addPiece(LetterPiece.of(letterOrigin, ori, lst, block));
97 }
98 }
99 }
100}