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 CompoundTag data = new CompoundTag();
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(NbtUtils.getString(parent.default_fluid, "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 CompoundTag noise(RandomDimension dim) {
61 CompoundTag noise = new CompoundTag();
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 CompoundTag 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 CompoundTag 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 CompoundTag res = startingRule("sequence");
134 ListTag sequence = new ListTag();
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(ListTag 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 CompoundTag startingRule(String str) {
149 CompoundTag res = new CompoundTag();
150 res.putString("type", "minecraft:" + str);
151 return res;
152 }
153
154 CompoundTag getBiomes(boolean usePreliminarySurface) {
155 if (usePreliminarySurface) {
156 CompoundTag res = startingRule("condition");
157 res.put("if_true", startingRule("above_preliminary_surface"));
158 res.put("then_run", getBiomes(false));
159 return res;
160 }
161 CompoundTag res = startingRule("sequence");
162 ListTag sequence = biomeSequence();
163 res.put("sequence", sequence);
164 return res;
165 }
166
167 CompoundTag randomBlock(ConfigType s) {
168 return PROVIDER.randomElement(parent.random, s);
169 }
170
171 ListTag biomeSequence() {
172 ListTag sequence = new ListTag();
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 CompoundTag compound = CommonIO.readSurfaceRule(p.toFile(), parent.sea_level);
177 ListTag biomes = NbtUtils.getList(compound, "biomes", Tag.TAG_STRING);
178 ListTag biomestoadd = new ListTag();
179 for (Tag b : biomes) {
180 if (parent.vanilla_biomes.contains(NbtUtils.getAsString(b))) biomestoadd.add(b);
181 }
182 if (!biomestoadd.isEmpty()) {
183 CompoundTag rule = NbtUtils.getCompound(compound, "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 CompoundTag top_block = useRandomBlock ?
196 randomBlock(RandomProvider.rule("forceSolidSurface") ? ConfigType.FULL_BLOCKS_WG : ConfigType.TOP_BLOCKS) :
197 NbtUtils.nameToElement(parent.getDefaultBlock("minecraft:grass_block"));
198 parent.top_blocks.put(biome, top_block);
199 CompoundTag block_underwater = useRandomBlock ? randomBlock(ConfigType.FULL_BLOCKS_WG) :
200 NbtUtils.nameToElement(parent.getDefaultBlock("minecraft:dirt"));
201 parent.underwater.put(biome, block_underwater);
202 CompoundTag beach = useRandomBlock ? randomBlock(ConfigType.FULL_BLOCKS_WG) : top_block;
203 CompoundTag rule1 = CommonIO.readAndFormat(root + "ceiling.json",
204 CommonIO.compoundToString(parent.deepslate, 5), CommonIO.compoundToString(parent.default_block, 4));
205 CompoundTag rule2 = CommonIO.readAndFormat(root + "grass.json",
206 parent.sea_level - 1, parent.sea_level, CommonIO.compoundToString(beach, 10),
207 CommonIO.compoundToString(top_block, 8), CommonIO.compoundToString(block_underwater, 5));
208 CompoundTag rule3 = CommonIO.readAndFormat(root + "dirt.json",
209 CommonIO.compoundToString(block_underwater, 7));
210 CompoundTag rule4 = CommonIO.readAndFormat(root + "final.json",
211 CommonIO.compoundToString(parent.deepslate, 5), CommonIO.compoundToString(parent.default_block, 4));
212 CompoundTag rule = startingRule("sequence");
213 ListTag sq = new ListTag();
214 sq.add(rule1);
215 sq.add(rule2);
216 sq.add(rule3);
217 sq.add(rule4);
218 rule.put("sequence", sq);
219 ListTag biomestoadd = new ListTag();
220 biomestoadd.add(StringTag.valueOf(biome));
221 sequence.add(ruleWrap(biomestoadd, rule));
222 }
223 sequence.add(NbtUtils.getCompound(CommonIO.readAndFormat(
224 InfinityMod.utilPath + "/surface_rule/default.json",
225 defaultBlock("minecraft:grass_block"),
226 defaultBlock("minecraft:dirt"),
227 defaultBlock("minecraft:dirt"),
228 defaultBlock("minecraft:stone"),
229 defaultBlock("minecraft:gravel")), "rule"));
230 return sequence;
231 }
232
233 String defaultBlock(String def) {
234 return switch (type_alike) {
235 case "minecraft:nether" -> "minecraft:netherrack";
236 case "minecraft:end" -> "minecraft:end_stone";
237 default -> def;
238 };
239 }
240
241 CompoundTag ruleWrap(ListTag biomes, CompoundTag rule) {
242 CompoundTag res = startingRule("condition");
243 CompoundTag if_true = startingRule("biome");
244 if_true.put("biome_is", biomes);
245 res.put("if_true", if_true);
246 res.put("then_run", rule);
247 return res;
248 }
249}