Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
1package net.lerariemann.infinity.dimensions;
2
3import net.lerariemann.infinity.InfinityMod;
4import net.lerariemann.infinity.util.core.CommonIO;
5import net.lerariemann.infinity.util.core.ConfigType;
6import net.lerariemann.infinity.util.core.NbtUtils;
7import net.lerariemann.infinity.util.core.RandomProvider;
8import net.minecraft.nbt.*;
9
10import java.io.IOException;
11import java.nio.file.Path;
12import java.util.*;
13import java.util.stream.Stream;
14
15import static java.nio.file.Files.walk;
16
17public class RandomNoisePreset {
18 private final RandomProvider PROVIDER;
19 public String name;
20 public String fullname;
21 public RandomDimension parent;
22 public String noise_router, surface_rule, spawn_target, type_alike;
23 Map<String,Set<String>> biomeRegistry;
24
25 RandomNoisePreset(RandomDimension dim) {
26 parent = dim;
27 biomeRegistry = new HashMap<>();
28 PROVIDER = dim.PROVIDER;
29 name = "generated_" +dim.numericId;
30 fullname = InfinityMod.MOD_ID + ":" + name;
31 NbtCompound data = new NbtCompound();
32 type_alike = dim.type_alike;
33 String typeshort = type_alike.substring(type_alike.lastIndexOf(":") + 1);
34 if (dim.isOverworldLike()) {
35 noise_router = typeshort;
36 surface_rule = spawn_target = "overworld";
37 data.putBoolean("aquifers_enabled", true);
38 }
39 else {
40 noise_router = surface_rule = typeshort;
41 data.putBoolean("aquifers_enabled", false);
42 spawn_target = "default";
43 switch (type_alike) {
44 case "minecraft:nether", "minecraft:caves" -> noise_router = "caves";
45 }
46 }
47 data.putBoolean("ore_veins_enabled", dim.random.nextBoolean());
48 data.putBoolean("disable_mob_generation", false);
49 data.putBoolean("legacy_random_source", false);
50 data.put("default_block", parent.default_block);
51 data.put("default_fluid", NbtUtils.nameToElement(parent.default_fluid.getString("Name")));
52 data.putInt("sea_level", parent.sea_level);
53 data.put("noise", noise(dim));
54 data.put("noise_router", getRouter(noise_router));
55 data.put("spawn_target", CommonIO.read(InfinityMod.utilPath + "/spawn_target/" + spawn_target + ".json").get("spawn_target"));
56 data.put("surface_rule", buildSurfaceRule());
57 CommonIO.write(data, dim.getStoragePath() + "/worldgen/noise_settings", name + ".json");
58 }
59
60 NbtCompound noise(RandomDimension dim) {
61 NbtCompound noise = new NbtCompound();
62 noise.putInt("height", dim.height);
63 noise.putInt("min_y", dim.min_y);
64 boolean rifts = PROVIDER.roll(dim.random, "rift_world_chance");
65 int s;
66 if (rifts) noise.putInt("size_horizontal", 3);
67 else {
68 s = dim.random.nextInt(1, 4);
69 noise.putInt("size_horizontal", (s == 3 ? 4 : s));
70 }
71 s = dim.random.nextInt(1, 4);
72 noise.putInt("size_vertical", (s == 3 ? 4 : s));
73 return noise;
74 }
75
76 NbtCompound getRouter(String router) {
77 String path = InfinityMod.utilPath + "/noise_router/" + router + ".json";
78 int min = parent.min_y;
79 int max = parent.height + parent.min_y;
80 int softmax = Math.min(max, 256);
81 Random r = parent.random;
82 switch(router) {
83 case "caves" -> {
84 return CommonIO.readAndFormat(path, min - 8, min + 24, max - 24, max);
85 }
86 case "floating_islands" -> {
87 return CommonIO.readAndFormat(path, min + 4, min + 32, max - 72, max + 184);
88 }
89 case "end" -> {
90 return CommonIO.readAndFormat(path, min + 4, min + 32, max - 72, max + 184, min + 4, min + 32, max - 72, max + 184);
91 }
92 case "overworld", "large_biomes" -> {
93 return CommonIO.readAndFormat(path, min, min + 24, softmax - 16, softmax, min, max,
94 (float)(max+1), (float)(min+4), (float)(max+1), (float)(min+4), (float)(max+1), (float)(min+4), (float)(max+1), (float)(min+4),
95 min, min + 24, softmax - 16, softmax);
96 }
97 case "amplified" -> {
98 return CommonIO.readAndFormat(path, min, min + 24, max - 16, max, min, max,
99 (float)(max+1), (float)(min+4), (float)(max+1), (float)(min+4), (float)(max+1), (float)(min+4), (float)(max+1), (float)(min+4),
100 min, min + 24, max - 16, max);
101 }
102 case "whack" -> {
103 double f = r.nextExponential();
104 double a = r.nextDouble(1.0, 8.0);
105 double b = r.nextDouble(1.0, 8.0);
106 return CommonIO.readAndFormat(path,
107 2*f, min, min+8, max-8, -2*f, max,
108 min, parent.sea_level, parent.sea_level, max,
109 f, a, b,
110 min, max,
111 2*f, min, min+8, max-8, -2*f, max,
112 min, parent.sea_level, parent.sea_level, max,
113 f, a, b);
114 }
115 case "tangled" -> {
116 double f = r.nextDouble(0.005, 0.1);
117 double a = r.nextExponential();
118 double b = r.nextExponential();
119 return CommonIO.readAndFormat(path, min+32, min, min, max, a, b, a, b, f, min+16, min, max-16, max);
120 }
121 }
122 return CommonIO.read(path);
123 }
124
125 NbtCompound buildSurfaceRule() {
126 parent.deepslate = parent.randomiseblocks ? PROVIDER.randomElement(parent.random, ConfigType.FULL_BLOCKS_WG) :
127 NbtUtils.nameToElement("minecraft:deepslate");
128 int i = 0;
129 switch (surface_rule) {
130 case "caves", "nether", "tangled" -> i=1;
131 case "floating_islands", "end" -> i=2;
132 }
133 NbtCompound res = startingRule("sequence");
134 NbtList sequence = new NbtList();
135 if (i!=2) sequence.add(CommonIO.read(InfinityMod.utilPath + "/surface_rule/bedrock_floor.json"));
136 if (i==1) sequence.add(CommonIO.read(InfinityMod.utilPath + "/surface_rule/bedrock_roof.json"));
137 sequence.add(getBiomes(i==0));
138 if (i==0) addDeepslate(sequence);
139 res.put("sequence", sequence);
140 return res;
141 }
142
143 void addDeepslate(NbtList base) {
144 base.add(CommonIO.readAndAddCompound(InfinityMod.utilPath + "/surface_rule/deepslate.json", parent.deepslate));
145 parent.additional_blocks.add(parent.deepslate);
146 }
147
148 public static NbtCompound startingRule(String str) {
149 NbtCompound res = new NbtCompound();
150 res.putString("type", "minecraft:" + str);
151 return res;
152 }
153
154 NbtCompound getBiomes(boolean usePreliminarySurface) {
155 if (usePreliminarySurface) {
156 NbtCompound res = startingRule("condition");
157 res.put("if_true", startingRule("above_preliminary_surface"));
158 res.put("then_run", getBiomes(false));
159 return res;
160 }
161 NbtCompound res = startingRule("sequence");
162 NbtList sequence = biomeSequence();
163 res.put("sequence", sequence);
164 return res;
165 }
166
167 NbtCompound randomBlock(ConfigType s) {
168 return PROVIDER.randomElement(parent.random, s);
169 }
170
171 NbtList biomeSequence() {
172 NbtList sequence = new NbtList();
173 try (Stream<Path> files = walk(InfinityMod.configPath.resolve("modular"))) {
174 files.forEach(p -> {
175 if (p.toString().contains("surface_rule") && p.toFile().isFile()) {
176 NbtCompound compound = CommonIO.readSurfaceRule(p.toFile(), parent.sea_level);
177 NbtList biomes = compound.getList("biomes", NbtElement.STRING_TYPE);
178 NbtList biomestoadd = new NbtList();
179 for (NbtElement b : biomes) {
180 if (parent.vanilla_biomes.contains(b.asString())) biomestoadd.add(b);
181 }
182 if (!biomestoadd.isEmpty()) {
183 NbtCompound rule = compound.getCompound("rule");
184 sequence.add(ruleWrap(biomestoadd, rule));
185 }
186 }
187 });
188 } catch (IOException e) {
189 throw new RuntimeException(e);
190 }
191 for (long id: parent.random_biome_ids) {
192 String biome = "infinity:biome_" + id;
193 String root = InfinityMod.utilPath + "/surface_rule/custom/";
194 boolean useRandomBlock = parent.randomiseblocks && PROVIDER.roll(parent.random, "randomise_biome_blocks");
195 NbtCompound top_block = useRandomBlock ? randomBlock(RandomProvider.rule("forceSolidSurface") ? ConfigType.FULL_BLOCKS_WG : ConfigType.TOP_BLOCKS) :
196 NbtUtils.nameToElement(parent.getDefaultBlock("minecraft:grass_block"));
197 parent.top_blocks.put(biome, top_block);
198 NbtCompound block_underwater = useRandomBlock ? randomBlock(ConfigType.FULL_BLOCKS_WG) :
199 NbtUtils.nameToElement(parent.getDefaultBlock("minecraft:dirt"));
200 parent.underwater.put(biome, block_underwater);
201 NbtCompound beach = useRandomBlock ? randomBlock(ConfigType.FULL_BLOCKS_WG) : top_block;
202 NbtCompound rule1 = CommonIO.readAndFormat(root + "ceiling.json",
203 CommonIO.compoundToString(parent.deepslate, 5), CommonIO.compoundToString(parent.default_block, 4));
204 NbtCompound rule2 = CommonIO.readAndFormat(root + "grass.json",
205 parent.sea_level - 1, parent.sea_level, CommonIO.compoundToString(beach, 10),
206 CommonIO.compoundToString(top_block, 8), CommonIO.compoundToString(block_underwater, 5));
207 NbtCompound rule3 = CommonIO.readAndFormat(root + "dirt.json",
208 CommonIO.compoundToString(block_underwater, 7));
209 NbtCompound rule4 = CommonIO.readAndFormat(root + "final.json",
210 CommonIO.compoundToString(parent.deepslate, 5), CommonIO.compoundToString(parent.default_block, 4));
211 NbtCompound rule = startingRule("sequence");
212 NbtList sq = new NbtList();
213 sq.add(rule1);
214 sq.add(rule2);
215 sq.add(rule3);
216 sq.add(rule4);
217 rule.put("sequence", sq);
218 NbtList biomestoadd = new NbtList();
219 biomestoadd.add(NbtString.of(biome));
220 sequence.add(ruleWrap(biomestoadd, rule));
221 }
222 sequence.add(CommonIO.readAndFormat(
223 InfinityMod.utilPath + "/surface_rule/default.json",
224 defaultBlock("minecraft:grass_block"),
225 defaultBlock("minecraft:dirt"),
226 defaultBlock("minecraft:dirt"),
227 defaultBlock("minecraft:stone"),
228 defaultBlock("minecraft:gravel")).getCompound("rule"));
229 return sequence;
230 }
231
232 String defaultBlock(String def) {
233 return switch (type_alike) {
234 case "minecraft:nether" -> "minecraft:netherrack";
235 case "minecraft:end" -> "minecraft:end_stone";
236 default -> def;
237 };
238 }
239
240 NbtCompound ruleWrap(NbtList biomes, NbtCompound rule) {
241 NbtCompound res = startingRule("condition");
242 NbtCompound if_true = startingRule("biome");
243 if_true.put("biome_is", biomes);
244 res.put("if_true", if_true);
245 res.put("then_run", rule);
246 return res;
247 }
248}