Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
at master 182 lines 7.8 kB view raw
1package net.lerariemann.infinity.util.config; 2 3import net.lerariemann.infinity.InfinityMod; 4import net.lerariemann.infinity.dimensions.RandomNoisePreset; 5import net.lerariemann.infinity.util.VersionMethods; 6import net.lerariemann.infinity.util.core.CommonIO; 7import net.lerariemann.infinity.util.core.NbtUtils; 8import net.minecraft.core.Registry; 9import net.minecraft.core.registries.Registries; 10import net.minecraft.nbt.*; 11import net.minecraft.server.MinecraftServer; 12import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; 13import org.jspecify.annotations.Nullable; 14 15import java.util.*; 16 17public interface SurfaceRuleScanner { 18 static void scan(MinecraftServer server) { 19 Map<String, CompoundTag> map = new HashMap<>(); 20 Registry<NoiseGeneratorSettings> registry = VersionMethods.getRegistry(server.registryAccess(), Registries.NOISE_SETTINGS); 21 registry.registryKeySet().forEach(key -> { 22 if (!key.location().getNamespace().contains("infinity")) { 23 Optional<NoiseGeneratorSettings> o = registry.getOptional(key); 24 o.ifPresent(settings -> { 25 Optional<Tag> c = NoiseGeneratorSettings.DIRECT_CODEC.encodeStart(NbtOps.INSTANCE, settings).result(); 26 c.ifPresent(e -> { 27 Tree t = new Tree(NbtUtils.getCompound(((CompoundTag) e), "surface_rule")); 28 t.biomeLocations.keySet().forEach(biome -> { 29 if (!map.containsKey(biome)) map.put(biome, t.wrappedRule(biome)); 30 }); 31 }); 32 }); 33 } 34 }); 35 map.forEach((biome, value) -> { 36 String biomename = biome.substring(biome.lastIndexOf(":") + 1) + ".json"; 37 String modname = biome.substring(0, biome.lastIndexOf(":")); 38 String path = "config/infinity/modular/" + modname + "/surface_rule"; 39 CommonIO.writeSurfaceRule(value, path, biomename); 40 }); 41 DataCollection.loggerOutput(map.size(), "surface rules"); 42 } 43 44 class Tree{ 45 ArrayList<TreeLeaf> registry; 46 HashMap<String, ArrayList<Integer>> biomeLocations; 47 48 Tree(CompoundTag surfaceRule) { 49 registry = new ArrayList<>(); 50 biomeLocations = new HashMap<>(); 51 TreeLeaf root = new TreeLeaf(new CompoundTag(), -1, null, false); 52 add(surfaceRule, root); 53 } 54 55 static CompoundTag conditionCase(CompoundTag if_true, CompoundTag then_run) { 56 CompoundTag c = new CompoundTag(); 57 c.put("if_true", if_true); 58 c.put("then_run", then_run); 59 c.putString("type", "minecraft:condition"); 60 return c; 61 } 62 63 void addBiomeLoc(String s, Integer i) { 64 if (!biomeLocations.containsKey(s)) biomeLocations.put(s, new ArrayList<>()); 65 biomeLocations.get(s).add(i); 66 } 67 68 TreeLeaf addOfRule(CompoundTag rule, TreeLeaf where, boolean terminal) { 69 TreeLeaf l = new TreeLeaf(rule, registry.size(), where, terminal); 70 registry.add(l); 71 return l; 72 } 73 74 void add(CompoundTag rule, TreeLeaf where) { 75 switch(NbtUtils.getString(rule,"type", "")) { 76 case "condition", "minecraft:condition" -> { 77 CompoundTag next = NbtUtils.getCompound(rule,"then_run"); 78 CompoundTag c = NbtUtils.getCompound(rule, "if_true"); 79 if (NbtUtils.getString(c, "type").contains("above_preliminary_surface")) { 80 add(next, where); 81 } 82 else if (!NbtUtils.getString(c, "type").contains("biome")) { 83 TreeLeaf l = addOfRule(c, where, false); 84 add(next, l); 85 } 86 else { 87 TreeLeaf l = addOfRule(next, where, true); 88 if(Objects.requireNonNull(c.get("biome_is")).getType().equals(ListTag.TYPE)) { 89 NbtUtils.getList(c, "biome_is", Tag.TAG_STRING).forEach(e -> addBiomeLoc(NbtUtils.getAsString(e), l.i)); 90 } 91 } 92 } 93 case "sequence", "minecraft:sequence" -> { 94 ListTag sq = NbtUtils.getList(rule, "sequence", Tag.TAG_COMPOUND); 95 sq.forEach(e -> add((CompoundTag)e, where)); 96 } 97 default -> { 98 if (!checkUnneededParts(rule)) { 99 TreeLeaf l = addOfRule(rule, where, true); 100 addBiomeLoc("minecraft:default", l.i); 101 } 102 } 103 } 104 } 105 106 static boolean checkUnneededParts(CompoundTag rule) { 107 return NbtUtils.getString(rule, "type", "").contains("block") 108 && (rule.toString().contains("minecraft:bedrock") 109 || rule.toString().contains("minecraft:deepslate")); 110 } 111 112 public CompoundTag wrappedRule(String biome) { 113 CompoundTag c = new CompoundTag(); 114 ListTag l = new ListTag(); 115 l.add(StringTag.valueOf(biome)); 116 c.put("biomes", l); 117 c.put("rule", extractRule(biome)); 118 return c; 119 } 120 121 public CompoundTag extractRule(String biome) { 122 if (!biomeLocations.containsKey(biome)) return null; 123 else { 124 CompoundTag comp = RandomNoisePreset.startingRule("sequence"); 125 ListTag l = new ListTag(); 126 try { 127 biomeLocations.get(biome).forEach(i -> l.add(extractRule(i))); 128 if (biomeLocations.containsKey("minecraft:default")) 129 biomeLocations.get("minecraft:default").forEach(i -> l.add(extractRule(i))); 130 else { 131 InfinityMod.LOGGER.warn("Default locations unexpectedly missing when processing surface rules for biome {}", biome); 132 } 133 comp.put("sequence", l); 134 } catch (Exception e) { 135 throw new RuntimeException("Encountered an unexpected exception when processing surface rules for biome " + biome + "\n" + e.getMessage()); 136 } 137 biomeLocations.get(biome).forEach(i -> l.add(extractRule(i))); 138 if (biomeLocations.containsKey("minecraft:default")) 139 biomeLocations.get("minecraft:default").forEach(i -> l.add(extractRule(i))); 140 comp.put("sequence", l); 141 return comp; 142 } 143 } 144 145 TreeLeaf getParent(TreeLeaf l) { 146 if (l.i_parent == -1) return l; 147 return registry.get(l.i_parent); 148 } 149 150 CompoundTag extractRule(int i) { 151 TreeLeaf l = registry.get(i); 152 assert l.is_terminal; 153 if (l.i_parent == -1) return l.data; 154 return extractRule(getParent(l), l.data); 155 } 156 157 CompoundTag extractRule(TreeLeaf l, CompoundTag data) { 158 CompoundTag newdata = conditionCase(l.data, data); 159 if (l.i_parent == -1) return newdata; 160 return extractRule(getParent(l), newdata); 161 } 162 163 static class TreeLeaf{ 164 CompoundTag data; 165 int i; 166 int i_parent; 167 boolean is_terminal; 168 169 TreeLeaf(CompoundTag c, int num, @Nullable TreeLeaf where, boolean e) { 170 data = c; 171 i = num; 172 if (where == null) { 173 i_parent = -1; 174 } 175 else { 176 i_parent = where.i; 177 } 178 is_terminal = e; 179 } 180 } 181 } 182}