55import com .google .gson .JsonObject ;
66import com .google .gson .JsonParseException ;
77import net .darkhax .bookshelf .api .util .JSONHelper ;
8+ import net .darkhax .bookshelf .mixin .util .random .AccessorWeightedRandomList ;
89import net .minecraft .nbt .CompoundTag ;
910import net .minecraft .nbt .Tag ;
1011import net .minecraft .network .FriendlyByteBuf ;
12+ import net .minecraft .util .random .SimpleWeightedRandomList ;
13+ import net .minecraft .util .random .WeightedEntry ;
1114
1215import javax .annotation .Nullable ;
1316import java .util .ArrayList ;
@@ -449,4 +452,146 @@ default T fromJSONString(String jsonString) {
449452
450453 return this .fromJSON (JSONHelper .getAsElement (jsonString ));
451454 }
455+
456+ /**
457+ * Reads a wrapped weighted entry from a JSON element. The weight is taken from a JSON Object property named
458+ * "weight". If the JSON is not an Object or the property does not exist a weight of 0 will be used.
459+ *
460+ * @param element The JSON element to read from.
461+ * @return The weighted wrapper.
462+ */
463+ default WeightedEntry .Wrapper <T > fromJSONWeighted (JsonElement element ) {
464+
465+ if (element instanceof JsonObject obj ) {
466+
467+ final T value = this .fromJSON (obj , "value" );
468+ final int weight = Serializers .INT .fromJSON (obj , "weight" , 0 );
469+ return WeightedEntry .wrap (value , weight );
470+ }
471+
472+ return WeightedEntry .wrap (this .fromJSON (element ), 0 );
473+ }
474+
475+ /**
476+ * Writes a weighted entry to a JSON element. The value and weight are stored as separate properties.
477+ *
478+ * @param weightedEntry The weighted entry to write.
479+ * @return The serialized JSON.
480+ */
481+ default JsonElement toJSONWeighted (WeightedEntry .Wrapper <T > weightedEntry ) {
482+
483+ final JsonObject obj = new JsonObject ();
484+ obj .add ("value" , this .toJSON (weightedEntry .getData ()));
485+ obj .addProperty ("weight" , weightedEntry .getWeight ().asInt ());
486+ return obj ;
487+ }
488+
489+ /**
490+ * Writes a weighted wrapped value to a byte buffer.
491+ *
492+ * @param buffer The buffer to write to.
493+ * @param toWrite The data to write.
494+ */
495+ default void toByteBufWeighted (FriendlyByteBuf buffer , WeightedEntry .Wrapper <T > toWrite ) {
496+
497+ this .toByteBuf (buffer , toWrite .getData ());
498+ Serializers .INT .toByteBuf (buffer , toWrite .getWeight ().asInt ());
499+ }
500+
501+ /**
502+ * Reads a weighted wrapped value from a byte buffer.
503+ *
504+ * @param buffer The buffer to read from.
505+ * @return The value that was read from the buffer.
506+ */
507+ default WeightedEntry .Wrapper <T > fromByteBufWeighted (FriendlyByteBuf buffer ) {
508+
509+ final T value = this .fromByteBuf (buffer );
510+ final int weight = Serializers .INT .fromByteBuf (buffer );
511+ return WeightedEntry .wrap (value , weight );
512+ }
513+
514+ /**
515+ * Reads a list of weighted wrapped values from the json.
516+ *
517+ * @param json The JSON data to read from.
518+ * @return A list of weighted wrapped values.
519+ */
520+ default SimpleWeightedRandomList <T > fromJSONWeightedList (JsonElement json ) {
521+
522+ final SimpleWeightedRandomList .Builder <T > list = SimpleWeightedRandomList .builder ();
523+
524+ if (json instanceof JsonArray array ) {
525+
526+ for (JsonElement element : array ) {
527+
528+ final WeightedEntry .Wrapper <T > wrapped = this .fromJSONWeighted (element );
529+ list .add (wrapped .getData (), wrapped .getWeight ().asInt ());
530+ }
531+ }
532+
533+ else {
534+
535+ final WeightedEntry .Wrapper <T > wrapped = this .fromJSONWeighted (json );
536+ list .add (wrapped .getData (), wrapped .getWeight ().asInt ());
537+ }
538+
539+ return list .build ();
540+ }
541+
542+ /**
543+ * Writes a list of weighted wrapped entries to JSON.
544+ *
545+ * @param list The list to write.
546+ * @return The JSON output.
547+ */
548+ default JsonElement toJSONWeightedList (SimpleWeightedRandomList <T > list ) {
549+
550+ final JsonArray array = new JsonArray ();
551+ final AccessorWeightedRandomList <WeightedEntry .Wrapper <T >> accessor = ((AccessorWeightedRandomList <WeightedEntry .Wrapper <T >>) list );
552+
553+ for (WeightedEntry .Wrapper <T > entry : accessor .bookshelf$getEntries ()) {
554+
555+ array .add (this .toJSONWeighted (entry ));
556+ }
557+
558+ return array ;
559+ }
560+
561+ /**
562+ * Reads a list of weighted wrapped entries from a byte buffer.
563+ *
564+ * @param buffer The buffer to read from.
565+ * @return The list of weighted wrapped entries.
566+ */
567+ default SimpleWeightedRandomList <T > fromByteBufWeightedList (FriendlyByteBuf buffer ) {
568+
569+ final SimpleWeightedRandomList .Builder <T > list = SimpleWeightedRandomList .builder ();
570+ final int size = buffer .readInt ();
571+
572+ for (int i = 0 ; i < size ; i ++) {
573+
574+ final WeightedEntry .Wrapper <T > wrapped = this .fromByteBufWeighted (buffer );
575+ list .add (wrapped .getData (), wrapped .getWeight ().asInt ());
576+ }
577+
578+ return list .build ();
579+ }
580+
581+ /**
582+ * Writes a list of weighted wrapped entries to a byte buffer.
583+ *
584+ * @param buffer The buffer to write to.
585+ * @param list The list of entries to write.
586+ */
587+ default void toByteBufWeightedList (FriendlyByteBuf buffer , SimpleWeightedRandomList <T > list ) {
588+
589+ final AccessorWeightedRandomList <WeightedEntry .Wrapper <T >> accessor = ((AccessorWeightedRandomList <WeightedEntry .Wrapper <T >>) list );
590+ buffer .writeInt (accessor .bookshelf$getEntries ().size ());
591+
592+ for (WeightedEntry .Wrapper <T > entry : accessor .bookshelf$getEntries ()) {
593+
594+ this .toByteBufWeighted (buffer , entry );
595+ }
596+ }
452597}
0 commit comments