StructureUtils.java

net.minecraft.gametest.framework.StructureUtils

信息

  • 全限定名:net.minecraft.gametest.framework.StructureUtils
  • 类型:public class
  • 包:net.minecraft.gametest.framework
  • 源码路径:src/main/java/net/minecraft/gametest/framework/StructureUtils.java
  • 起始行号:L33
  • 职责:

    TODO

字段/常量

  • DEFAULT_Y_SEARCH_RADIUS

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

      TODO

  • testStructuresTargetDir

    • 类型: Path
    • 修饰符: public static
    • 源码定位: L35
    • 说明:

      TODO

  • testStructuresSourceDir

    • 类型: Path
    • 修饰符: public static
    • 源码定位: L36
    • 说明:

      TODO

内部类/嵌套类型

构造器

方法

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

public static Rotation getRotationForRotationSteps(int rotationSteps) @ L38

  • 方法名:getRotationForRotationSteps
  • 源码定位:L38
  • 返回类型:Rotation
  • 修饰符:public static

参数:

  • rotationSteps: int

说明:

TODO

public static int getRotationStepsForRotation(Rotation rotation) @ L53

  • 方法名:getRotationStepsForRotation
  • 源码定位:L53
  • 返回类型:int
  • 修饰符:public static

参数:

  • rotation: Rotation

说明:

TODO

public static TestInstanceBlockEntity createNewEmptyTest(Identifier id, BlockPos structurePos, Vec3i size, Rotation rotation, ServerLevel level) @ L68

  • 方法名:createNewEmptyTest
  • 源码定位:L68
  • 返回类型:TestInstanceBlockEntity
  • 修饰符:public static

参数:

  • id: Identifier
  • structurePos: BlockPos
  • size: Vec3i
  • rotation: Rotation
  • level: ServerLevel

说明:

TODO

public static void clearSpaceForStructure(BoundingBox structureBoundingBox, ServerLevel level) @ L78

  • 方法名:clearSpaceForStructure
  • 源码定位:L78
  • 返回类型:void
  • 修饰符:public static

参数:

  • structureBoundingBox: BoundingBox
  • level: ServerLevel

说明:

TODO

public static BlockPos getTransformedFarCorner(BlockPos structurePosition, Vec3i size, Rotation rotation) @ L88

  • 方法名:getTransformedFarCorner
  • 源码定位:L88
  • 返回类型:BlockPos
  • 修饰符:public static

参数:

  • structurePosition: BlockPos
  • size: Vec3i
  • rotation: Rotation

说明:

TODO

public static BoundingBox getStructureBoundingBox(BlockPos northWestCorner, Vec3i size, Rotation rotation) @ L93

  • 方法名:getStructureBoundingBox
  • 源码定位:L93
  • 返回类型:BoundingBox
  • 修饰符:public static

参数:

  • northWestCorner: BlockPos
  • size: Vec3i
  • rotation: Rotation

说明:

TODO

public static Optional<BlockPos> findTestContainingPos(BlockPos pos, int searchRadius, ServerLevel level) @ L101

  • 方法名:findTestContainingPos
  • 源码定位:L101
  • 返回类型:Optional
  • 修饰符:public static

参数:

  • pos: BlockPos
  • searchRadius: int
  • level: ServerLevel

说明:

TODO

public static Optional<BlockPos> findNearestTest(BlockPos relativeToPos, int searchRadius, ServerLevel level) @ L105

  • 方法名:findNearestTest
  • 源码定位:L105
  • 返回类型:Optional
  • 修饰符:public static

参数:

  • relativeToPos: BlockPos
  • searchRadius: int
  • level: ServerLevel

说明:

TODO

public static Stream<BlockPos> findTestBlocks(BlockPos centerPos, int searchRadius, ServerLevel level) @ L110

  • 方法名:findTestBlocks
  • 源码定位:L110
  • 返回类型:Stream
  • 修饰符:public static

参数:

  • centerPos: BlockPos
  • searchRadius: int
  • level: ServerLevel

说明:

TODO

public static Stream<BlockPos> lookedAtTestPos(BlockPos pos, Entity camera, ServerLevel level) @ L116

  • 方法名:lookedAtTestPos
  • 源码定位:L116
  • 返回类型:Stream
  • 修饰符:public static

参数:

  • pos: BlockPos
  • camera: Entity
  • level: ServerLevel

说明:

TODO

private static void clearBlock(int airIfAboveThisY, BlockPos pos, ServerLevel level) @ L129

  • 方法名:clearBlock
  • 源码定位:L129
  • 返回类型:void
  • 修饰符:private static

参数:

  • airIfAboveThisY: int
  • pos: BlockPos
  • level: ServerLevel

说明:

TODO

private static boolean doesStructureContain(BlockPos testInstanceBlockPos, BlockPos pos, ServerLevel level) @ L142

  • 方法名:doesStructureContain
  • 源码定位:L142
  • 返回类型:boolean
  • 修饰符:private static

参数:

  • testInstanceBlockPos: BlockPos
  • pos: BlockPos
  • level: ServerLevel

说明:

TODO

代码

public class StructureUtils {
    public static final int DEFAULT_Y_SEARCH_RADIUS = 10;
    public static @Nullable Path testStructuresTargetDir;
    public static @Nullable Path testStructuresSourceDir;
 
    public static Rotation getRotationForRotationSteps(int rotationSteps) {
        switch (rotationSteps) {
            case 0:
                return Rotation.NONE;
            case 1:
                return Rotation.CLOCKWISE_90;
            case 2:
                return Rotation.CLOCKWISE_180;
            case 3:
                return Rotation.COUNTERCLOCKWISE_90;
            default:
                throw new IllegalArgumentException("rotationSteps must be a value from 0-3. Got value " + rotationSteps);
        }
    }
 
    public static int getRotationStepsForRotation(Rotation rotation) {
        switch (rotation) {
            case NONE:
                return 0;
            case CLOCKWISE_90:
                return 1;
            case CLOCKWISE_180:
                return 2;
            case COUNTERCLOCKWISE_90:
                return 3;
            default:
                throw new IllegalArgumentException("Unknown rotation value, don't know how many steps it represents: " + rotation);
        }
    }
 
    public static TestInstanceBlockEntity createNewEmptyTest(Identifier id, BlockPos structurePos, Vec3i size, Rotation rotation, ServerLevel level) {
        BoundingBox structureBoundingBox = getStructureBoundingBox(TestInstanceBlockEntity.getStructurePos(structurePos), size, rotation);
        clearSpaceForStructure(structureBoundingBox, level);
        level.setBlockAndUpdate(structurePos, Blocks.TEST_INSTANCE_BLOCK.defaultBlockState());
        TestInstanceBlockEntity test = (TestInstanceBlockEntity)level.getBlockEntity(structurePos);
        ResourceKey<GameTestInstance> key = ResourceKey.create(Registries.TEST_INSTANCE, id);
        test.set(new TestInstanceBlockEntity.Data(Optional.of(key), size, rotation, false, TestInstanceBlockEntity.Status.CLEARED, Optional.empty()));
        return test;
    }
 
    public static void clearSpaceForStructure(BoundingBox structureBoundingBox, ServerLevel level) {
        int groundHeight = structureBoundingBox.minY() - 1;
        BlockPos.betweenClosedStream(structureBoundingBox).forEach(pos -> clearBlock(groundHeight, pos, level));
        level.getBlockTicks().clearArea(structureBoundingBox);
        level.clearBlockEvents(structureBoundingBox);
        AABB bounds = AABB.of(structureBoundingBox);
        List<Entity> livingEntities = level.getEntitiesOfClass(Entity.class, bounds, mob -> !(mob instanceof Player));
        livingEntities.forEach(Entity::discard);
    }
 
    public static BlockPos getTransformedFarCorner(BlockPos structurePosition, Vec3i size, Rotation rotation) {
        BlockPos farCornerBeforeTransform = structurePosition.offset(size).offset(-1, -1, -1);
        return StructureTemplate.transform(farCornerBeforeTransform, Mirror.NONE, rotation, structurePosition);
    }
 
    public static BoundingBox getStructureBoundingBox(BlockPos northWestCorner, Vec3i size, Rotation rotation) {
        BlockPos farCorner = getTransformedFarCorner(northWestCorner, size, rotation);
        BoundingBox boundingBox = BoundingBox.fromCorners(northWestCorner, farCorner);
        int currentNorthWestCornerX = Math.min(boundingBox.minX(), boundingBox.maxX());
        int currentNorthWestCornerZ = Math.min(boundingBox.minZ(), boundingBox.maxZ());
        return boundingBox.move(northWestCorner.getX() - currentNorthWestCornerX, 0, northWestCorner.getZ() - currentNorthWestCornerZ);
    }
 
    public static Optional<BlockPos> findTestContainingPos(BlockPos pos, int searchRadius, ServerLevel level) {
        return findTestBlocks(pos, searchRadius, level).filter(testBlockPosToCheck -> doesStructureContain(testBlockPosToCheck, pos, level)).findFirst();
    }
 
    public static Optional<BlockPos> findNearestTest(BlockPos relativeToPos, int searchRadius, ServerLevel level) {
        Comparator<BlockPos> distanceToPlayer = Comparator.comparingInt(pos -> pos.distManhattan(relativeToPos));
        return findTestBlocks(relativeToPos, searchRadius, level).min(distanceToPlayer);
    }
 
    public static Stream<BlockPos> findTestBlocks(BlockPos centerPos, int searchRadius, ServerLevel level) {
        return level.getPoiManager()
            .findAll(p -> p.is(PoiTypes.TEST_INSTANCE), p -> true, centerPos, searchRadius, PoiManager.Occupancy.ANY)
            .map(BlockPos::immutable);
    }
 
    public static Stream<BlockPos> lookedAtTestPos(BlockPos pos, Entity camera, ServerLevel level) {
        int radius = 250;
        Vec3 start = camera.getEyePosition();
        Vec3 end = start.add(camera.getLookAngle().scale(250.0));
        return findTestBlocks(pos, 250, level)
            .map(blockPos -> level.getBlockEntity(blockPos, BlockEntityType.TEST_INSTANCE_BLOCK))
            .flatMap(Optional::stream)
            .filter(blockEntity -> blockEntity.getStructureBounds().clip(start, end).isPresent())
            .map(BlockEntity::getBlockPos)
            .sorted(Comparator.comparing(pos::distSqr))
            .limit(1L);
    }
 
    private static void clearBlock(int airIfAboveThisY, BlockPos pos, ServerLevel level) {
        BlockState blockState;
        if (pos.getY() < airIfAboveThisY) {
            blockState = Blocks.STONE.defaultBlockState();
        } else {
            blockState = Blocks.AIR.defaultBlockState();
        }
 
        BlockInput blockInput = new BlockInput(blockState, Collections.emptySet(), null);
        blockInput.place(level, pos, 818);
        level.updateNeighborsAt(pos, blockState.getBlock());
    }
 
    private static boolean doesStructureContain(BlockPos testInstanceBlockPos, BlockPos pos, ServerLevel level) {
        return level.getBlockEntity(testInstanceBlockPos) instanceof TestInstanceBlockEntity blockEntity
            ? blockEntity.getStructureBoundingBox().isInside(pos)
            : false;
    }
}

引用的其他类

  • BlockInput

    • 引用位置: 构造调用
    • 关联成员: BlockInput()
  • BlockPos

    • 引用位置: 参数/方法调用/返回值
    • 关联成员: BlockPos.betweenClosedStream()
  • Vec3i

    • 引用位置: 参数
  • Identifier

    • 引用位置: 参数
  • ResourceKey

    • 引用位置: 方法调用
    • 关联成员: ResourceKey.create()
  • ServerLevel

    • 引用位置: 参数
  • Entity

    • 引用位置: 参数
  • Rotation

    • 引用位置: 参数/返回值
  • TestInstanceBlockEntity

    • 引用位置: 方法调用/构造调用/返回值
    • 关联成员: Data(), TestInstanceBlockEntity.Data(), TestInstanceBlockEntity.getStructurePos()
  • BoundingBox

    • 引用位置: 参数/方法调用/返回值
    • 关联成员: BoundingBox.fromCorners()
  • StructureTemplate

    • 引用位置: 方法调用
    • 关联成员: StructureTemplate.transform()
  • AABB

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