TrappedChestBlockEntityFix.java

net.minecraft.util.datafix.fixes.TrappedChestBlockEntityFix

信息

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

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L23
    • 说明:

      TODO

  • SIZE

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L24
    • 说明:

      TODO

  • SIZE_BITS

    • 类型: short
    • 修饰符: private static final
    • 源码定位: L25
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.util.datafix.fixes.TrappedChestBlockEntityFix.TrappedChestSection
    • 类型: class
    • 修饰符: public static final
    • 源码定位: L112
    • 说明:

      TODO

构造器

public TrappedChestBlockEntityFix(Schema outputSchema, boolean changesType) @ L27

  • 构造器名:TrappedChestBlockEntityFix
  • 源码定位:L27
  • 修饰符:public

参数:

  • outputSchema: Schema
  • changesType: boolean

说明:

TODO

方法

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

public TypeRewriteRule makeRule() @ L31

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

参数:

说明:

TODO

代码

public class TrappedChestBlockEntityFix extends DataFix {
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final int SIZE = 4096;
    private static final short SIZE_BITS = 12;
 
    public TrappedChestBlockEntityFix(Schema outputSchema, boolean changesType) {
        super(outputSchema, changesType);
    }
 
    @Override
    public TypeRewriteRule makeRule() {
        Type<?> chunkType = this.getOutputSchema().getType(References.CHUNK);
        Type<?> levelType = chunkType.findFieldType("Level");
        if (!(levelType.findFieldType("TileEntities") instanceof ListType<?> tileEntityListType)) {
            throw new IllegalStateException("Tile entity type is not a list type.");
        } else {
            OpticFinder<? extends List<?>> tileEntitiesF = DSL.fieldFinder("TileEntities", (Type<? extends List<?>>)tileEntityListType);
            Type<?> chunkType1 = this.getInputSchema().getType(References.CHUNK);
            OpticFinder<?> levelFinder = chunkType1.findField("Level");
            OpticFinder<?> sectionsFinder = levelFinder.type().findField("Sections");
            Type<?> sectionsType = sectionsFinder.type();
            if (!(sectionsType instanceof ListType)) {
                throw new IllegalStateException("Expecting sections to be a list.");
            } else {
                Type<?> sectionType = ((ListType)sectionsType).getElement();
                OpticFinder<?> sectionFinder = DSL.typeFinder(sectionType);
                return TypeRewriteRule.seq(
                    new AddNewChoices(this.getOutputSchema(), "AddTrappedChestFix", References.BLOCK_ENTITY).makeRule(),
                    this.fixTypeEverywhereTyped(
                        "Trapped Chest fix",
                        chunkType1,
                        chunk -> chunk.updateTyped(
                            levelFinder,
                            level -> {
                                Optional<? extends Typed<?>> sections = level.getOptionalTyped(sectionsFinder);
                                if (sections.isEmpty()) {
                                    return level;
                                } else {
                                    List<? extends Typed<?>> sectionList = sections.get().getAllTyped(sectionFinder);
                                    IntSet chestLocations = new IntOpenHashSet();
 
                                    for (Typed<?> section : sectionList) {
                                        TrappedChestBlockEntityFix.TrappedChestSection trappedChestSection = new TrappedChestBlockEntityFix.TrappedChestSection(
                                            section, this.getInputSchema()
                                        );
                                        if (!trappedChestSection.isSkippable()) {
                                            for (int i = 0; i < 4096; i++) {
                                                int block = trappedChestSection.getBlock(i);
                                                if (trappedChestSection.isTrappedChest(block)) {
                                                    chestLocations.add(trappedChestSection.getIndex() << 12 | i);
                                                }
                                            }
                                        }
                                    }
 
                                    Dynamic<?> levelTag = level.get(DSL.remainderFinder());
                                    int chunkX = levelTag.get("xPos").asInt(0);
                                    int chunkZ = levelTag.get("zPos").asInt(0);
                                    TaggedChoiceType<String> tileEntityChoiceType = (TaggedChoiceType<String>)this.getInputSchema()
                                        .findChoiceType(References.BLOCK_ENTITY);
                                    return level.updateTyped(
                                        tileEntitiesF,
                                        tileEntities -> tileEntities.updateTyped(
                                            tileEntityChoiceType.finder(),
                                            tileEntity -> {
                                                Dynamic<?> tag = tileEntity.getOrCreate(DSL.remainderFinder());
                                                int x = tag.get("x").asInt(0) - (chunkX << 4);
                                                int y = tag.get("y").asInt(0);
                                                int z = tag.get("z").asInt(0) - (chunkZ << 4);
                                                return chestLocations.contains(LeavesFix.getIndex(x, y, z))
                                                    ? tileEntity.update(tileEntityChoiceType.finder(), stringPair -> stringPair.mapFirst(s -> {
                                                        if (!Objects.equals(s, "minecraft:chest")) {
                                                            LOGGER.warn("Block Entity was expected to be a chest");
                                                        }
 
                                                        return "minecraft:trapped_chest";
                                                    }))
                                                    : tileEntity;
                                            }
                                        )
                                    );
                                }
                            }
                        )
                    )
                );
            }
        }
    }
 
    public static final class TrappedChestSection extends LeavesFix.Section {
        private @Nullable IntSet chestIds;
 
        public TrappedChestSection(Typed<?> section, Schema inputSchema) {
            super(section, inputSchema);
        }
 
        @Override
        protected boolean skippable() {
            this.chestIds = new IntOpenHashSet();
 
            for (int i = 0; i < this.palette.size(); i++) {
                Dynamic<?> paletteTag = this.palette.get(i);
                String blockName = paletteTag.get("Name").asString("");
                if (Objects.equals(blockName, "minecraft:trapped_chest")) {
                    this.chestIds.add(i);
                }
            }
 
            return this.chestIds.isEmpty();
        }
 
        public boolean isTrappedChest(int block) {
            return this.chestIds.contains(block);
        }
    }
}

引用的其他类

  • Schema

    • 引用位置: 参数
  • AddNewChoices

    • 引用位置: 构造调用
    • 关联成员: AddNewChoices()
  • LeavesFix

    • 引用位置: 方法调用
    • 关联成员: LeavesFix.getIndex()