package net.minecraft.util.datafix.fixes; import com.mojang.datafixers.DSL; import com.mojang.datafixers.DataFix; import com.mojang.datafixers.OpticFinder; import com.mojang.datafixers.TypeRewriteRule; import com.mojang.datafixers.Typed; import com.mojang.datafixers.schemas.Schema; import com.mojang.datafixers.types.Type; import com.mojang.datafixers.util.Either; import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Unit; import com.mojang.serialization.Dynamic; import java.util.List; import java.util.function.Function; import java.util.function.Predicate; public class EquipmentFormatFix extends DataFix { public EquipmentFormatFix(Schema outputSchema) { super(outputSchema, true); } @Override protected TypeRewriteRule makeRule() { Type type = this.getInputSchema().getTypeRaw(References.ITEM_STACK); Type type2 = this.getOutputSchema().getTypeRaw(References.ITEM_STACK); OpticFinder opticFinder = type.findField("id"); return this.fix(type, type2, opticFinder); } private TypeRewriteRule fix(Type oldItemStackType, Type newItemStackType, OpticFinder optic) { Type, Unit>, Pair, Unit>, Pair, Either>>>>> type = DSL.named( References.ENTITY_EQUIPMENT.typeName(), DSL.and( DSL.optional(DSL.field("ArmorItems", DSL.list(oldItemStackType))), DSL.optional(DSL.field("HandItems", DSL.list(oldItemStackType))), DSL.optional(DSL.field("body_armor_item", oldItemStackType)), DSL.optional(DSL.field("saddle", oldItemStackType)) ) ); Type, Pair, Pair, Pair, Pair, Pair, Pair, Pair, Dynamic>>>>>>>>, Unit>>> type2 = DSL.named( References.ENTITY_EQUIPMENT.typeName(), DSL.optional( DSL.field( "equipment", DSL.and( DSL.optional(DSL.field("mainhand", newItemStackType)), DSL.optional(DSL.field("offhand", newItemStackType)), DSL.optional(DSL.field("feet", newItemStackType)), DSL.and( DSL.optional(DSL.field("legs", newItemStackType)), DSL.optional(DSL.field("chest", newItemStackType)), DSL.optional(DSL.field("head", newItemStackType)), DSL.and(DSL.optional(DSL.field("body", newItemStackType)), DSL.optional(DSL.field("saddle", newItemStackType)), DSL.remainderType()) ) ) ) ) ); if (!type.equals(this.getInputSchema().getType(References.ENTITY_EQUIPMENT))) { throw new IllegalStateException("Input entity_equipment type does not match expected"); } else if (!type2.equals(this.getOutputSchema().getType(References.ENTITY_EQUIPMENT))) { throw new IllegalStateException("Output entity_equipment type does not match expected"); } else { return this.fixTypeEverywhere( "EquipmentFormatFix", type, type2, dynamicOps -> { Predicate predicate = object -> { Typed typed = new Typed<>(oldItemStackType, dynamicOps, (ItemStackOld)object); return typed.getOptional(optic).isEmpty(); }; return pair -> { String string = (String)pair.getFirst(); Pair, Unit>, Pair, Unit>, Pair, Either>>> pair2 = (Pair, Unit>, Pair, Unit>, Pair, Either>>>)pair.getSecond(); List list = pair2.getFirst().map(Function.identity(), unit -> List.of()); List list2 = pair2.getSecond().getFirst().map(Function.identity(), unit -> List.of()); Either either = pair2.getSecond().getSecond().getFirst(); Either either2 = pair2.getSecond().getSecond().getSecond(); Either either3 = getItemFromList(0, list, predicate); Either either4 = getItemFromList(1, list, predicate); Either either5 = getItemFromList(2, list, predicate); Either either6 = getItemFromList(3, list, predicate); Either either7 = getItemFromList(0, list2, predicate); Either either8 = getItemFromList(1, list2, predicate); return areAllEmpty(either, either2, either3, either4, either5, either6, either7, either8) ? Pair.of(string, Either.right(Unit.INSTANCE)) : Pair.of( string, Either.left( Pair.of( either7, Pair.of(either8, Pair.of(either3, Pair.of(either4, Pair.of(either5, Pair.of(either6, Pair.of(either, Pair.of(either2, new Dynamic(dynamicOps)))))))) ) ) ); }; } ); } } @SafeVarargs private static boolean areAllEmpty(Either... items) { for (Either either : items) { if (either.right().isEmpty()) { return false; } } return true; } private static Either getItemFromList(int index, List list, Predicate predicate) { if (index >= list.size()) { return Either.right(Unit.INSTANCE); } else { ItemStack object = (ItemStack)list.get(index); return predicate.test(object) ? Either.right(Unit.INSTANCE) : Either.left(object); } } }