@@ -214,25 +214,74 @@ record Reference(@NotNull List<LootPredicate> predicates, @NotNull NamespaceID n
214
214
215
215
record ApplyBonus (@ NotNull List <LootPredicate > predicates , @ NotNull DynamicRegistry .Key <Enchantment > enchantment , @ NotNull Formula formula ) implements LootFunction {
216
216
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
+ };
223
261
224
262
public sealed interface Formula {
225
263
226
264
int calculate (@ NotNull Random random , int count , int level );
227
265
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
+
229
273
@ Override
230
274
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 );
232
276
}
233
277
}
234
278
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
+
236
285
@ Override
237
286
public int calculate (@ NotNull Random random , int count , int level ) {
238
287
if (level <= 0 ) return count ;
@@ -241,10 +290,17 @@ public int calculate(@NotNull Random random, int count, int level) {
241
290
}
242
291
}
243
292
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
+
245
301
@ Override
246
302
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 ++) {
248
304
if (random .nextFloat () < probability ) {
249
305
count ++;
250
306
}
0 commit comments