EntityEquipmentToArmorAndHandFix.java

net.minecraft.util.datafix.fixes.EntityEquipmentToArmorAndHandFix

信息

  • 全限定名:net.minecraft.util.datafix.fixes.EntityEquipmentToArmorAndHandFix
  • 类型:public class
  • 包:net.minecraft.util.datafix.fixes
  • 源码路径:src/main/java/net/minecraft/util/datafix/fixes/EntityEquipmentToArmorAndHandFix.java
  • 起始行号:L19
  • 继承:DataFix
  • 职责:

    TODO

字段/常量

内部类/嵌套类型

构造器

public EntityEquipmentToArmorAndHandFix(Schema outputSchema) @ L20

  • 构造器名:EntityEquipmentToArmorAndHandFix
  • 源码定位:L20
  • 修饰符:public

参数:

  • outputSchema: Schema

说明:

TODO

方法

下面的方法块按源码顺序生成。

public TypeRewriteRule makeRule() @ L24

  • 方法名:makeRule
  • 源码定位:L24
  • 返回类型:TypeRewriteRule
  • 修饰符:public

参数:

说明:

TODO

private <ItemStackOld,ItemStackNew> TypeRewriteRule cap(Type<ItemStackOld> oldItemStackType, Type<ItemStackNew> newItemStackType) @ L29

  • 方法名:cap
  • 源码定位:L29
  • 返回类型:<ItemStackOld,ItemStackNew> TypeRewriteRule
  • 修饰符:private

参数:

  • oldItemStackType: Type
  • newItemStackType: Type

说明:

TODO

private static Dynamic<?> fixDropChances(Dynamic<?> tag) @ L89

  • 方法名:fixDropChances
  • 源码定位:L89
  • 返回类型:Dynamic<?>
  • 修饰符:private static

参数:

  • tag: Dynamic<?>

说明:

TODO

代码

public class EntityEquipmentToArmorAndHandFix extends DataFix {
    public EntityEquipmentToArmorAndHandFix(Schema outputSchema) {
        super(outputSchema, true);
    }
 
    @Override
    public TypeRewriteRule makeRule() {
        return this.cap(this.getInputSchema().getTypeRaw(References.ITEM_STACK), this.getOutputSchema().getTypeRaw(References.ITEM_STACK));
    }
 
    private <ItemStackOld, ItemStackNew> TypeRewriteRule cap(Type<ItemStackOld> oldItemStackType, Type<ItemStackNew> newItemStackType) {
        Type<Pair<String, Either<List<ItemStackOld>, Unit>>> oldEquipmentType = DSL.named(
            References.ENTITY_EQUIPMENT.typeName(), DSL.optional(DSL.field("Equipment", DSL.list(oldItemStackType)))
        );
        Type<Pair<String, Pair<Either<List<ItemStackNew>, Unit>, Pair<Either<List<ItemStackNew>, Unit>, Pair<Either<ItemStackNew, Unit>, Either<ItemStackNew, Unit>>>>>> newEquipmentType = DSL.named(
            References.ENTITY_EQUIPMENT.typeName(),
            DSL.and(
                DSL.optional(DSL.field("ArmorItems", DSL.list(newItemStackType))),
                DSL.optional(DSL.field("HandItems", DSL.list(newItemStackType))),
                DSL.optional(DSL.field("body_armor_item", newItemStackType)),
                DSL.optional(DSL.field("saddle", newItemStackType))
            )
        );
        if (!oldEquipmentType.equals(this.getInputSchema().getType(References.ENTITY_EQUIPMENT))) {
            throw new IllegalStateException("Input entity_equipment type does not match expected");
        } else if (!newEquipmentType.equals(this.getOutputSchema().getType(References.ENTITY_EQUIPMENT))) {
            throw new IllegalStateException("Output entity_equipment type does not match expected");
        } else {
            return TypeRewriteRule.seq(
                this.fixTypeEverywhereTyped(
                    "EntityEquipmentToArmorAndHandFix - drop chances",
                    this.getInputSchema().getType(References.ENTITY),
                    typed -> typed.update(DSL.remainderFinder(), EntityEquipmentToArmorAndHandFix::fixDropChances)
                ),
                this.fixTypeEverywhere(
                    "EntityEquipmentToArmorAndHandFix - equipment",
                    oldEquipmentType,
                    newEquipmentType,
                    ops -> {
                        ItemStackNew emptyStack = newItemStackType.read(new Dynamic<>(ops).emptyMap())
                            .result()
                            .orElseThrow(() -> new IllegalStateException("Could not parse newly created empty itemstack."))
                            .getFirst();
                        Either<ItemStackNew, Unit> noItem = Either.right(DSL.unit());
                        return named -> named.mapSecond(equipmentField -> {
                            List<ItemStackOld> items = equipmentField.map(Function.identity(), ignored -> List.of());
                            Either<List<ItemStackNew>, Unit> handItems = Either.right(DSL.unit());
                            Either<List<ItemStackNew>, Unit> armorItems = Either.right(DSL.unit());
                            if (!items.isEmpty()) {
                                handItems = Either.left(Lists.newArrayList((ItemStackNew[])(new Object[]{items.getFirst(), emptyStack})));
                            }
 
                            if (items.size() > 1) {
                                List<ItemStackNew> armor = Lists.newArrayList(emptyStack, emptyStack, emptyStack, emptyStack);
 
                                for (int i = 1; i < Math.min(items.size(), 5); i++) {
                                    armor.set(i - 1, (ItemStackNew)items.get(i));
                                }
 
                                armorItems = Either.left(armor);
                            }
 
                            return Pair.of(armorItems, Pair.of(handItems, Pair.of(noItem, noItem)));
                        });
                    }
                )
            );
        }
    }
 
    private static Dynamic<?> fixDropChances(Dynamic<?> tag) {
        Optional<? extends Stream<? extends Dynamic<?>>> dropChances = tag.get("DropChances").asStreamOpt().result();
        tag = tag.remove("DropChances");
        if (dropChances.isPresent()) {
            Iterator<Float> chances = Stream.concat(dropChances.get().map(value -> value.asFloat(0.0F)), Stream.generate(() -> 0.0F)).iterator();
            float handChance = chances.next();
            if (tag.get("HandDropChances").result().isEmpty()) {
                tag = tag.set("HandDropChances", tag.createList(Stream.of(handChance, 0.0F).map(tag::createFloat)));
            }
 
            if (tag.get("ArmorDropChances").result().isEmpty()) {
                tag = tag.set(
                    "ArmorDropChances", tag.createList(Stream.of(chances.next(), chances.next(), chances.next(), chances.next()).map(tag::createFloat))
                );
            }
        }
 
        return tag;
    }
}

引用的其他类