-
Notifications
You must be signed in to change notification settings - Fork 754
/
ModifierModule.java
129 lines (119 loc) · 5.07 KB
/
ModifierModule.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package slimeknights.tconstruct.library.modifiers.modules;
import com.google.common.collect.ImmutableList;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import io.netty.handler.codec.DecoderException;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import slimeknights.mantle.data.registry.GenericLoaderRegistry;
import slimeknights.mantle.data.registry.GenericLoaderRegistry.IHaveLoader;
import slimeknights.mantle.util.JsonHelper;
import slimeknights.tconstruct.library.modifiers.Modifier;
import slimeknights.tconstruct.library.modifiers.ModifierHook;
import slimeknights.tconstruct.library.modifiers.ModifierHooks;
import slimeknights.tconstruct.library.modifiers.util.ModifierHookMap;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
/** Interface for a module in a composable modifier. This is the serializable version of {@link ModifierHookProvider}. */
public interface ModifierModule extends IHaveLoader, ModifierHookProvider {
/** Loader instance to register new modules. Note that loaders should not use the key "hooks" else composable modifiers will not parse */
GenericLoaderRegistry<ModifierModule> LOADER = new GenericLoaderRegistry<>("Modifier Module", false);
/**
* Gets the priority for this module.
* All modules are polled to choose the priority of the final modifier with the following criteria:
* <ol>
* <li>If no modifier sets a priority in its JSON, that is used</li>
* <li>If no module has nonnull priority, then the modifier will use {@link Modifier#DEFAULT_PRIORITY}</li>
* <li>If one module has nonnull priority, that priority will be used</li>
* <li>If two or more modules has nonnull priority, the first will be used and a warning will be logged</li>
* </ol>>
* @return Priority
*/
@Nullable
default Integer getPriority() {
return null;
}
/** Represents a modifier module with a list of hooks */
record ModuleWithHooks(ModifierModule module, List<ModifierHook<?>> hooks) {
/** Gets the list of hooks to use for this module */
public List<ModifierHook<?>> getModuleHooks() {
if (hooks.isEmpty()) {
return module.getDefaultHooks();
}
return hooks;
}
/** Serializes this to a JSON object */
public JsonObject serialize() {
JsonElement json = LOADER.serialize(module);
if (!json.isJsonObject()) {
throw new JsonSyntaxException("Serializers for modifier modules must return json objects");
}
JsonObject object = json.getAsJsonObject();
if (!this.hooks.isEmpty()) {
JsonArray hooks = new JsonArray();
for (ModifierHook<?> hook : this.hooks) {
hooks.add(hook.getName().toString());
}
object.add("hooks", hooks);
}
return object;
}
/** Deserializes a module with hooks from a JSON object */
public static ModuleWithHooks deserialize(JsonObject json) {
// if there are no hooks in JSON, we use the default list from the module
List<ModifierHook<?>> hooks = Collections.emptyList();
if (json.has("hooks")) {
hooks = JsonHelper.parseList(json, "hooks", (element, key) -> {
ResourceLocation name = JsonHelper.convertToResourceLocation(element, key) ;
ModifierHook<?> hook = ModifierHooks.getHook(name);
if (hook == null) {
throw new JsonSyntaxException("Unknown modifier hook " + name);
}
return hook;
});
}
ModifierModule module = LOADER.deserialize(json);
return new ModuleWithHooks(module, hooks);
}
/** Writes this module to the buffer */
public void toNetwork(FriendlyByteBuf buffer) {
buffer.writeVarInt(hooks.size());
for (ModifierHook<?> hook : hooks) {
buffer.writeResourceLocation(hook.getName());
}
LOADER.encode(buffer, module);
}
/** Reads this module from the buffer */
public static ModuleWithHooks fromNetwork(FriendlyByteBuf buffer) {
int hookCount = buffer.readVarInt();
ImmutableList.Builder<ModifierHook<?>> hooks = ImmutableList.builder();
for (int i = 0; i < hookCount; i++) {
ResourceLocation location = buffer.readResourceLocation();
ModifierHook<?> hook = ModifierHooks.getHook(location);
if (hook == null) {
throw new DecoderException("Unknown modifier hook " + location);
}
hooks.add(hook);
}
ModifierModule module = LOADER.decode(buffer);
return new ModuleWithHooks(module, hooks.build());
}
}
/**
* Creates a modifier hook map from the given module list
* @param modules List of modules
* @return Modifier hook map
*/
static ModifierHookMap createMap(List<ModuleWithHooks> modules) {
ModifierHookMap.Builder builder = ModifierHookMap.builder();
for (ModuleWithHooks module : modules) {
for (ModifierHook<?> hook : module.getModuleHooks()) {
builder.addHookChecked(module.module(), hook);
}
}
return builder.build();
}
}