Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
at master 249 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 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}