Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
1package net.lerariemann.infinity.util.config;
2
3import net.lerariemann.infinity.InfinityMod;
4import net.lerariemann.infinity.util.VersionMethods;
5import net.lerariemann.infinity.util.core.CommonIO;
6import net.lerariemann.infinity.util.core.ConfigType;
7import net.lerariemann.infinity.util.core.NbtUtils;
8import net.lerariemann.infinity.util.platform.InfinityPlatform;
9import net.minecraft.core.registries.Registries;
10import net.minecraft.nbt.CompoundTag;
11import net.minecraft.nbt.ListTag;
12import net.minecraft.nbt.StringTag;
13import net.minecraft.nbt.Tag;
14import net.minecraft.tags.TagKey;
15import net.minecraft.world.level.block.Block;
16
17import java.util.*;
18import java.util.concurrent.atomic.AtomicInteger;
19
20public record Amendment(ConfigType area, ModSelector modSelector, Selector selector, Results results) {
21 public static Amendment of(CompoundTag data) {
22 String prereqMod = NbtUtils.getString(data, "load_if_mod", "");
23 if (!prereqMod.isEmpty() && !InfinityPlatform.INSTANCE.isModLoaded(prereqMod)) return null;
24
25 String areaName = NbtUtils.getString(data, "area", "");
26 ConfigType area = ConfigType.byName(areaName);
27 if (area == null) {
28 InfinityMod.LOGGER.warn("Unknown amendment area: {}", areaName);
29 return null;
30 }
31
32 String mod = NbtUtils.getString(data, "mod", "");
33 ModSelector modSelector;
34 if (mod.equals("all")) {
35 modSelector = new UniversalModSelector();
36 }
37 else if (mod.equals("any_of")) {
38 modSelector = new MatchingAnyModSelector(listTransform(NbtUtils.getList(data, "mods", Tag.TAG_STRING)));
39 }
40 else if (mod.startsWith("!")) {
41 String notMod = mod.substring(1);
42 if (!InfinityPlatform.INSTANCE.isModLoaded(notMod)) modSelector = new UniversalModSelector();
43 else modSelector = new ExceptModSelector(notMod);
44 }
45 else if (!InfinityPlatform.INSTANCE.isModLoaded(mod)) return null;
46 else modSelector = new MatchingModSelector(mod);
47
48 String selectorType = NbtUtils.getString(data,"selector", "");
49 Selector selector = switch(selectorType) {
50 case "all" -> new UniversalSelector();
51 case "containing" -> new ContainingSelector(NbtUtils.getString(data, "containing"));
52 case "matching" -> new MatchingSelector(NbtUtils.getString(data, "matching"));
53 case "matching_block_tag" -> new MatchingBlockTagSelector(NbtUtils.getString(data, "matching_block_tag"));
54 case "matching_any" -> new MatchingAnySelector(listTransform(NbtUtils.getList(data, "matching_any", Tag.TAG_STRING)));
55 default -> {
56 InfinityMod.LOGGER.warn("Unknown amendment selector type: {}", selectorType);
57 yield null;
58 }
59 };
60
61 String resultType = NbtUtils.getString(data, "results", "");
62 Results results = switch (resultType) {
63 case "set_value" -> new SetValue(NbtUtils.getDouble(data, "value"));
64 case "erase" -> new SetValue(0);
65 case "set_field" -> new SetField(NbtUtils.getString(data, "field_name"), data.get("field"));
66 default -> {
67 InfinityMod.LOGGER.warn("Unknown amendment result type: {}", resultType);
68 yield null;
69 }
70 };
71
72 if (selector == null || results == null) return null;
73 return new Amendment(area, modSelector, selector, results);
74 }
75
76 public static List<String> listTransform(ListTag tag) {
77 return tag.stream().map(e->(StringTag)e).map(NbtUtils::getAsString).toList();
78 }
79
80 public static Map<ConfigType, List<Amendment>> getAmendmentList() {
81 Map<ConfigType, List<Amendment>> data = new HashMap<>();
82 CompoundTag rawData = CommonIO.read(InfinityMod.amendmentPath);
83 AtomicInteger i = new AtomicInteger();
84 for (Tag e : NbtUtils.getList(rawData,"elements", Tag.TAG_COMPOUND)) {
85 Amendment amd = Amendment.of((CompoundTag)e);
86 if (amd == null) continue;
87 i.getAndIncrement();
88 ConfigType type = amd.area;
89 if (!data.containsKey(type)) data.put(type, new ArrayList<>());
90 data.get(type).add(amd);
91 }
92 InfinityMod.LOGGER.info("Registered {} valid amendments", i.get());
93 return data;
94 }
95
96 public boolean applies(String modId, String key) {
97 return modSelector.applies(modId) && selector.applies(key);
98 }
99 public double apply() {
100 return results.apply();
101 }
102 public CompoundTag apply(CompoundTag data) {
103 return results.apply(data);
104 }
105
106 public interface ModSelector {
107 boolean applies(String modId);
108 }
109 public static class UniversalModSelector implements ModSelector {
110 @Override
111 public boolean applies(String modId) {
112 return true;
113 }
114 }
115 public record MatchingModSelector(String mod) implements ModSelector {
116 @Override
117 public boolean applies(String modId) {
118 return modId.equals(this.mod);
119 }
120 }
121 public record MatchingAnyModSelector(List<String> mods) implements ModSelector {
122 @Override
123 public boolean applies(String modId) {
124 return mods.contains(modId);
125 }
126 }
127 public record ExceptModSelector(String mod) implements ModSelector {
128 @Override
129 public boolean applies(String modId) {
130 return !modId.equals(this.mod);
131 }
132 }
133
134 public interface Selector {
135 boolean applies(String key);
136 }
137 public static class UniversalSelector implements Selector {
138 public boolean applies(String key) {
139 return true;
140 }
141 }
142 public record MatchingSelector(String key) implements Selector {
143 public boolean applies(String key) {
144 return key.equals(this.key);
145 }
146 }
147 public record MatchingBlockTagSelector(TagKey<Block> tag) implements Selector {
148 public MatchingBlockTagSelector(String key) {
149 this(TagKey.create(Registries.BLOCK, VersionMethods.id(key)));
150 }
151
152 public boolean applies(String key) {
153 Block b = VersionMethods.getBlock((key));
154 if (b != null) {
155 return b.defaultBlockState().is(this.tag);
156 }
157 return false;
158 }
159 }
160 public record MatchingAnySelector(List<String> lst) implements Selector {
161 public boolean applies(String key) {
162 return this.lst.contains(key);
163 }
164 }
165 public record ContainingSelector(String key) implements Selector {
166 public boolean applies(String key) {
167 return key.contains(this.key);
168 }
169 }
170
171 public interface Results{
172 default double apply() {
173 return 1.0;
174 }
175 default CompoundTag apply(CompoundTag data) {
176 return data;
177 }
178 }
179 public record SetValue(double value) implements Results {
180 @Override
181 public double apply() {
182 return value;
183 }
184 }
185 public record SetField(String key, Tag value) implements Results {
186 @Override
187 public CompoundTag apply(CompoundTag data) {
188 if (data == null) data = new CompoundTag();
189 data.put(key, value);
190 return data;
191 }
192 }
193}