Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
at master 122 lines 4.4 kB view raw
1package net.lerariemann.infinity.util.config; 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.WeighedStructure; 8import net.minecraft.nbt.CompoundTag; 9import net.minecraft.nbt.ListTag; 10import net.minecraft.resources.ResourceLocation; 11import org.jspecify.annotations.Nullable; 12 13import java.util.*; 14import java.util.concurrent.atomic.AtomicInteger; 15import java.util.stream.IntStream; 16 17/** A collection of {@link WeighedStructure} objects, used in {@link ConfigGenerator} to auto-sort different types of game content by mod ID. 18 * @author LeraRiemann */ 19public class DataCollection { 20 private final Map<String, List<CompoundTag>> map = new HashMap<>(); 21 public static Map<ConfigType, List<Amendment>> amendmentList = Amendment.getAmendmentList(); 22 ConfigType type; 23 List<Amendment> amendments; 24 25 DataCollection(ConfigType name) { 26 this.type = name; 27 this.amendments = amendmentList.getOrDefault(type, List.of()); 28 } 29 30 void add(String modId, CompoundTag elem) { 31 if (!map.containsKey(modId)) map.put(modId, new ArrayList<>()); 32 map.get(modId).add(elem); 33 } 34 void add(String modId, String key, @Nullable CompoundTag data) { 35 CompoundTag elem = getAmendedEntry(modId, key, data); 36 if (elem == null) return; 37 add(modId, elem); 38 } 39 void add(String modId, String key) { 40 add(modId, key, null); 41 } 42 43 CompoundTag getAmendedEntry(String modId, String key, @Nullable CompoundTag data) { 44 double weight = 1.0; 45 for (Amendment a: amendments) if (a.applies(modId, key)) { 46 weight = a.apply(); 47 data = a.apply(data); 48 break; 49 } 50 if (weight == 0) return null; 51 CompoundTag elem = new CompoundTag(); 52 elem.putString("key", key); 53 if (data != null) elem.put("data", data); 54 elem.putDouble("weight", weight); 55 return elem; 56 } 57 58 public void addIdentifier(ResourceLocation id) { 59 add(id.getNamespace(), id.toString()); 60 } 61 62 /** Writes collected content to the disk, creating a separate file for every collected mod. */ 63 void save() { 64 map.forEach((modId, data) -> CommonIO.write(wrapAndSortByKey(data), 65 InfinityMod.configPath.resolve("modular").resolve(modId), 66 type.getKey() + ".json")); 67 } 68 69 /** 70 * Wraps collected data into a format compatible with {@link CommonIO}, sorting it alphabetically in the process 71 * (this isn't strictly required but makes files much easier to navigate). 72 */ 73 static CompoundTag wrapAndSortByKey(List<CompoundTag> w) { 74 CompoundTag res = new CompoundTag(); 75 ListTag elements = new ListTag(); 76 List<Integer> range = new ArrayList<>(IntStream.rangeClosed(0, w.size() - 1).boxed().toList()); 77 range.sort(new Comparator<Integer>() { 78 public String extract(int i) { 79 CompoundTag compound = w.get(i); 80 return NbtUtils.getString(compound, "key"); 81 } 82 @Override 83 public int compare(Integer i, Integer j) { 84 return extract(i).compareTo(extract(j)); 85 } 86 }); 87 for (int i = 0; i < w.size(); i++) { 88 elements.add(w.get(range.get(i))); 89 } 90 res.put("elements", elements); 91 return res; 92 } 93 94 static void loggerOutput(int count, String type) { 95 InfinityMod.LOGGER.info("Registered {} {}", count, type); 96 } 97 98 /** An implementation of {@link DataCollection} that logs the total amount of stored entries in the {@link InfinityMod#LOGGER}. */ 99 static class Logged extends DataCollection { 100 private final AtomicInteger i = new AtomicInteger(); 101 String loggerName; 102 103 Logged(ConfigType name) { 104 this(name, name.getKey()); 105 } 106 Logged(ConfigType name, String loggerName) { 107 super(name); 108 this.loggerName = loggerName; 109 } 110 111 @Override 112 void add(String modId, CompoundTag elem) { 113 super.add(modId, elem); 114 i.getAndIncrement(); 115 } 116 @Override 117 void save() { 118 super.save(); 119 loggerOutput(i.get(), loggerName); 120 } 121 } 122}