Skip to content

Commit 919b7ff

Browse files
committed
Serialize Formula
1 parent 9cf56f6 commit 919b7ff

File tree

1 file changed

+67
-11
lines changed

1 file changed

+67
-11
lines changed

src/main/java/net/goldenstack/loot/LootFunction.java

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -214,25 +214,74 @@ record Reference(@NotNull List<LootPredicate> predicates, @NotNull NamespaceID n
214214

215215
record ApplyBonus(@NotNull List<LootPredicate> predicates, @NotNull DynamicRegistry.Key<Enchantment> enchantment, @NotNull Formula formula) implements LootFunction {
216216

217-
public static final @NotNull BinaryTagSerializer<ApplyBonus> SERIALIZER = Template.template(
218-
"conditions", Serial.lazy(() -> LootPredicate.SERIALIZER).list().optional(List.of()), ApplyBonus::predicates,
219-
"enchantment", Serial.key(), ApplyBonus::enchantment,
220-
"formula", Template.todo("formula"), ApplyBonus::formula,
221-
ApplyBonus::new
222-
);
217+
private static final @NotNull BinaryTagSerializer<List<LootPredicate>> PREDICATES = Serial.lazy(() -> LootPredicate.SERIALIZER).list().optional(List.of());
218+
private static final @NotNull BinaryTagSerializer<DynamicRegistry.Key<Enchantment>> KEY = Serial.key();
219+
220+
public static final @NotNull BinaryTagSerializer<ApplyBonus> SERIALIZER = new BinaryTagSerializer<>() {
221+
@Override
222+
public @NotNull BinaryTag write(@NotNull Context context, @NotNull ApplyBonus value) {
223+
CompoundBinaryTag.Builder nbt = CompoundBinaryTag.builder();
224+
nbt.put("conditions", PREDICATES.write(context, value.predicates()));
225+
nbt.put("enchantment", KEY.write(context, value.enchantment()));
226+
227+
return (switch (value.formula()) {
228+
case Formula.UniformBonusCount uniform -> nbt
229+
.put("formula", StringBinaryTag.stringBinaryTag("minecraft:uniform_bonus_count"))
230+
.put("parameters", Formula.UniformBonusCount.SERIALIZER.write(context, uniform));
231+
case Formula.OreDrops drops -> nbt
232+
.put("formula", StringBinaryTag.stringBinaryTag("minecraft:ore_drops"))
233+
.put("parameters", Formula.OreDrops.SERIALIZER.write(context, drops));
234+
case Formula.BinomialWithBonusCount binomial -> nbt
235+
.put("formula", StringBinaryTag.stringBinaryTag("minecraft:binomial_with_bonus_count"))
236+
.put("parameters", Formula.BinomialWithBonusCount.SERIALIZER.write(context, binomial));
237+
}).build();
238+
}
239+
240+
@SuppressWarnings("DataFlowIssue")
241+
@Override
242+
public @NotNull ApplyBonus read(@NotNull Context context, @NotNull BinaryTag raw) {
243+
if (!(raw instanceof CompoundBinaryTag tag)) throw new IllegalArgumentException("Expected a compound tag");
244+
245+
List<LootPredicate> predicates = PREDICATES.read(context, tag.get("conditions"));
246+
DynamicRegistry.Key<Enchantment> enchantment = KEY.read(context, tag.get("enchantments"));
247+
248+
String type = BinaryTagSerializer.STRING.read(context, tag.get("formula"));
249+
BinaryTag parameters = tag.get("parameters");
250+
251+
Formula formula = switch (type) {
252+
case "minecraft:uniform_bonus_count" -> Formula.UniformBonusCount.SERIALIZER.read(context, parameters);
253+
case "minecraft:ore_drops" -> Formula.OreDrops.SERIALIZER.read(context, parameters);
254+
case "minecraft:binomial_with_bonus_count" -> Formula.BinomialWithBonusCount.SERIALIZER.read(context, parameters);
255+
default -> throw new IllegalArgumentException("Invalid formula '" + type + "'");
256+
};
257+
258+
return new ApplyBonus(predicates, enchantment, formula);
259+
}
260+
};
223261

224262
public sealed interface Formula {
225263

226264
int calculate(@NotNull Random random, int count, int level);
227265

228-
record Uniform(int multiplier) implements Formula {
266+
record UniformBonusCount(int bonusMultiplier) implements Formula {
267+
268+
public static final @NotNull BinaryTagSerializer<UniformBonusCount> SERIALIZER = Template.template(
269+
"bonusMultiplier", BinaryTagSerializer.INT, UniformBonusCount::bonusMultiplier,
270+
UniformBonusCount::new
271+
);
272+
229273
@Override
230274
public int calculate(@NotNull Random random, int count, int level) {
231-
return count + random.nextInt(multiplier * level + 1);
275+
return count + random.nextInt(bonusMultiplier * level + 1);
232276
}
233277
}
234278

235-
record Ore() implements Formula {
279+
record OreDrops() implements Formula {
280+
281+
public static final @NotNull BinaryTagSerializer<OreDrops> SERIALIZER = Template.template(
282+
OreDrops::new
283+
);
284+
236285
@Override
237286
public int calculate(@NotNull Random random, int count, int level) {
238287
if (level <= 0) return count;
@@ -241,10 +290,17 @@ public int calculate(@NotNull Random random, int count, int level) {
241290
}
242291
}
243292

244-
record Binomial(float probability, int minTrials) implements Formula {
293+
record BinomialWithBonusCount(float probability, int extra) implements Formula {
294+
295+
public static final @NotNull BinaryTagSerializer<BinomialWithBonusCount> SERIALIZER = Template.template(
296+
"probability", BinaryTagSerializer.FLOAT, BinomialWithBonusCount::probability,
297+
"extra", BinaryTagSerializer.INT, BinomialWithBonusCount::extra,
298+
BinomialWithBonusCount::new
299+
);
300+
245301
@Override
246302
public int calculate(@NotNull Random random, int count, int level) {
247-
for (int i = 0; i < minTrials + level; i++) {
303+
for (int i = 0; i < extra + level; i++) {
248304
if (random.nextFloat() < probability) {
249305
count++;
250306
}

0 commit comments

Comments
 (0)