Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
at create-6.0 248 lines 12 kB view raw
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}