/
VariableFormulaLoadable.java
104 lines (96 loc) · 4.53 KB
/
VariableFormulaLoadable.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
package slimeknights.tconstruct.library.json.variable;
import com.google.common.collect.ImmutableList;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.mojang.datafixers.util.Function3;
import io.netty.handler.codec.EncoderException;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.util.GsonHelper;
import slimeknights.mantle.data.loadable.record.RecordLoadable;
import slimeknights.mantle.data.registry.GenericLoaderRegistry;
import slimeknights.mantle.data.registry.GenericLoaderRegistry.IHaveLoader;
import slimeknights.mantle.util.LogicHelper;
import slimeknights.tconstruct.library.json.math.ModifierFormula;
import slimeknights.tconstruct.library.json.math.ModifierFormula.FallbackFormula;
import slimeknights.tconstruct.library.json.math.PostFixFormula;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
/** Loadable for a variable formula */
public record VariableFormulaLoadable<V extends IHaveLoader<V>, F extends VariableFormula<V>>(
GenericLoaderRegistry<V> variableLoader, String[] defaultNames,
FallbackFormula boostFallback, FallbackFormula percentFallback,
Function3<ModifierFormula,List<V>,Boolean,F> constructor
) implements RecordLoadable<F> {
public VariableFormulaLoadable(GenericLoaderRegistry<V> variableLoader, String[] defaultNames, Function3<ModifierFormula,List<V>,Boolean,F> constructor) {
this(variableLoader, defaultNames, FallbackFormula.BOOST, FallbackFormula.PERCENT, constructor);
}
/** Gets the fallback formula given percent */
private FallbackFormula fallback(boolean percent) {
return percent ? percentFallback : boostFallback;
}
@Override
public F deserialize(JsonObject json) {
boolean percent = GsonHelper.getAsBoolean(json, "percent", false);
if (json.has("variables")) {
if (!json.has("formula")) {
throw new JsonSyntaxException("Cannot set variables when not using formula");
}
ImmutableList.Builder<V> variables = ImmutableList.builder();
int index = defaultNames.length;
JsonObject variableObj = GsonHelper.getAsJsonObject(json, "variables");
String[] newNames = Arrays.copyOf(defaultNames, index + variableObj.size());
for (Entry<String,JsonElement> entry : variableObj.entrySet()) {
String key = entry.getKey();
if (LogicHelper.isInList(defaultNames, key)) {
throw new JsonSyntaxException("Variable " + key + " is already defined for this module");
}
newNames[index] = key;
variables.add(variableLoader.convert(entry.getValue(), key));
index++;
}
// we only store the variable names in the VariableFormula during datagen, any other time its an empty list as we don't need it at runtime
// we do need them to parse the post fix formula though
return constructor.apply(PostFixFormula.deserialize(json, newNames), variables.build(), percent);
}
// no variables? use the standard loading logic
return constructor.apply(ModifierFormula.deserialize(json, defaultNames, fallback(percent)), List.of(), percent);
}
@Override
public void serialize(F object, JsonObject json) {
json.addProperty("percent", object.percent());
List<V> variables = object.variables();
if (!variables.isEmpty()) {
JsonObject variablesObject = new JsonObject();
GenericLoaderRegistry<V> loader = variableLoader();
String[] variableNames = object.variableNames();
for (int i = 0; i < variableNames.length; i++) {
variablesObject.add(variableNames[i], loader.serialize(variables.get(i)));
}
json.add("variables", variablesObject);
}
object.formula().serialize(json, defaultNames);
}
@Override
public F fromNetwork(FriendlyByteBuf buffer) {
boolean percent = buffer.readBoolean();
ImmutableList.Builder<V> builder = ImmutableList.builder();
int size = buffer.readVarInt();
for (int i = 0; i < size; i++) {
builder.add(variableLoader.fromNetwork(buffer));
}
List<V> variables = builder.build();
return constructor.apply(ModifierFormula.fromNetwork(buffer, defaultNames.length + variables.size(), fallback(percent)), variables, percent);
}
@Override
public void toNetwork(F object, FriendlyByteBuf buffer) throws EncoderException {
buffer.writeBoolean(object.percent());
List<V> variables = object.variables();
buffer.writeVarInt(variables.size());
for (V variable : variables) {
variableLoader.toNetwork(variable, buffer);
}
object.formula().toNetwork(buffer);
}
}