TeleportCommand.java

net.minecraft.server.commands.TeleportCommand

信息

  • 全限定名:net.minecraft.server.commands.TeleportCommand
  • 类型:public class
  • 包:net.minecraft.server.commands
  • 源码路径:src/main/java/net/minecraft/server/commands/TeleportCommand.java
  • 起始行号:L32
  • 职责:

    TODO

字段/常量

  • INVALID_POSITION
    • 类型: SimpleCommandExceptionType
    • 修饰符: private static final
    • 源码定位: L33
    • 说明:

      TODO

内部类/嵌套类型

构造器

方法

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

public static void register(CommandDispatcher<CommandSourceStack> dispatcher) @ L37

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

参数:

  • dispatcher: CommandDispatcher

说明:

TODO

private static int teleportToEntity(CommandSourceStack source, Collection<?extends Entity> entities, Entity destination) @ L151

  • 方法名:teleportToEntity
  • 源码定位:L151
  • 返回类型:int
  • 修饰符:private static

参数:

  • source: CommandSourceStack
  • entities: Collection<?extends Entity>
  • destination: Entity

说明:

TODO

private static int teleportToPos(CommandSourceStack source, Collection<?extends Entity> entities, ServerLevel level, Coordinates destination, Coordinates rotation, LookAt lookAt) @ L181

  • 方法名:teleportToPos
  • 源码定位:L181
  • 返回类型:int
  • 修饰符:private static

参数:

  • source: CommandSourceStack
  • entities: Collection<?extends Entity>
  • level: ServerLevel
  • destination: Coordinates
  • rotation: Coordinates
  • lookAt: LookAt

说明:

TODO

private static Set<Relative> getRelatives(Coordinates destination, Coordinates rotation, boolean sameDimension) @ L224

  • 方法名:getRelatives
  • 源码定位:L224
  • 返回类型:Set
  • 修饰符:private static

参数:

  • destination: Coordinates
  • rotation: Coordinates
  • sameDimension: boolean

说明:

TODO

private static String formatDouble(double value) @ L231

  • 方法名:formatDouble
  • 源码定位:L231
  • 返回类型:String
  • 修饰符:private static

参数:

  • value: double

说明:

TODO

private static void performTeleport(CommandSourceStack source, Entity victim, ServerLevel level, double x, double y, double z, Set<Relative> relatives, float yRot, float xRot, LookAt lookAt) @ L235

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

参数:

  • source: CommandSourceStack
  • victim: Entity
  • level: ServerLevel
  • x: double
  • y: double
  • z: double
  • relatives: Set
  • yRot: float
  • xRot: float
  • lookAt: LookAt

说明:

TODO

代码

public class TeleportCommand {
    private static final SimpleCommandExceptionType INVALID_POSITION = new SimpleCommandExceptionType(
        Component.translatable("commands.teleport.invalidPosition")
    );
 
    public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
        LiteralCommandNode<CommandSourceStack> teleport = dispatcher.register(
            Commands.literal("teleport")
                .requires(Commands.hasPermission(Commands.LEVEL_GAMEMASTERS))
                .then(
                    Commands.argument("location", Vec3Argument.vec3())
                        .executes(
                            c -> teleportToPos(
                                c.getSource(),
                                Collections.singleton(c.getSource().getEntityOrException()),
                                c.getSource().getLevel(),
                                Vec3Argument.getCoordinates(c, "location"),
                                null,
                                null
                            )
                        )
                )
                .then(
                    Commands.argument("destination", EntityArgument.entity())
                        .executes(
                            c -> teleportToEntity(
                                c.getSource(), Collections.singleton(c.getSource().getEntityOrException()), EntityArgument.getEntity(c, "destination")
                            )
                        )
                )
                .then(
                    Commands.argument("targets", EntityArgument.entities())
                        .then(
                            Commands.argument("location", Vec3Argument.vec3())
                                .executes(
                                    c -> teleportToPos(
                                        c.getSource(),
                                        EntityArgument.getEntities(c, "targets"),
                                        c.getSource().getLevel(),
                                        Vec3Argument.getCoordinates(c, "location"),
                                        null,
                                        null
                                    )
                                )
                                .then(
                                    Commands.argument("rotation", RotationArgument.rotation())
                                        .executes(
                                            c -> teleportToPos(
                                                c.getSource(),
                                                EntityArgument.getEntities(c, "targets"),
                                                c.getSource().getLevel(),
                                                Vec3Argument.getCoordinates(c, "location"),
                                                RotationArgument.getRotation(c, "rotation"),
                                                null
                                            )
                                        )
                                )
                                .then(
                                    Commands.literal("facing")
                                        .then(
                                            Commands.literal("entity")
                                                .then(
                                                    Commands.argument("facingEntity", EntityArgument.entity())
                                                        .executes(
                                                            c -> teleportToPos(
                                                                c.getSource(),
                                                                EntityArgument.getEntities(c, "targets"),
                                                                c.getSource().getLevel(),
                                                                Vec3Argument.getCoordinates(c, "location"),
                                                                null,
                                                                new LookAt.LookAtEntity(
                                                                    EntityArgument.getEntity(c, "facingEntity"), EntityAnchorArgument.Anchor.FEET
                                                                )
                                                            )
                                                        )
                                                        .then(
                                                            Commands.argument("facingAnchor", EntityAnchorArgument.anchor())
                                                                .executes(
                                                                    c -> teleportToPos(
                                                                        c.getSource(),
                                                                        EntityArgument.getEntities(c, "targets"),
                                                                        c.getSource().getLevel(),
                                                                        Vec3Argument.getCoordinates(c, "location"),
                                                                        null,
                                                                        new LookAt.LookAtEntity(
                                                                            EntityArgument.getEntity(c, "facingEntity"),
                                                                            EntityAnchorArgument.getAnchor(c, "facingAnchor")
                                                                        )
                                                                    )
                                                                )
                                                        )
                                                )
                                        )
                                        .then(
                                            Commands.argument("facingLocation", Vec3Argument.vec3())
                                                .executes(
                                                    c -> teleportToPos(
                                                        c.getSource(),
                                                        EntityArgument.getEntities(c, "targets"),
                                                        c.getSource().getLevel(),
                                                        Vec3Argument.getCoordinates(c, "location"),
                                                        null,
                                                        new LookAt.LookAtPosition(Vec3Argument.getVec3(c, "facingLocation"))
                                                    )
                                                )
                                        )
                                )
                        )
                        .then(
                            Commands.argument("destination", EntityArgument.entity())
                                .executes(
                                    c -> teleportToEntity(c.getSource(), EntityArgument.getEntities(c, "targets"), EntityArgument.getEntity(c, "destination"))
                                )
                        )
                )
        );
        dispatcher.register(Commands.literal("tp").requires(Commands.hasPermission(Commands.LEVEL_GAMEMASTERS)).redirect(teleport));
    }
 
    private static int teleportToEntity(CommandSourceStack source, Collection<? extends Entity> entities, Entity destination) throws CommandSyntaxException {
        for (Entity entity : entities) {
            performTeleport(
                source,
                entity,
                (ServerLevel)destination.level(),
                destination.getX(),
                destination.getY(),
                destination.getZ(),
                EnumSet.noneOf(Relative.class),
                destination.getYRot(),
                destination.getXRot(),
                null
            );
        }
 
        if (entities.size() == 1) {
            source.sendSuccess(
                () -> Component.translatable(
                    "commands.teleport.success.entity.single", entities.iterator().next().getDisplayName(), destination.getDisplayName()
                ),
                true
            );
        } else {
            source.sendSuccess(() -> Component.translatable("commands.teleport.success.entity.multiple", entities.size(), destination.getDisplayName()), true);
        }
 
        return entities.size();
    }
 
    private static int teleportToPos(
        CommandSourceStack source,
        Collection<? extends Entity> entities,
        ServerLevel level,
        Coordinates destination,
        @Nullable Coordinates rotation,
        @Nullable LookAt lookAt
    ) throws CommandSyntaxException {
        Vec3 pos = destination.getPosition(source);
        Vec2 rot = rotation == null ? null : rotation.getRotation(source);
 
        for (Entity entity : entities) {
            Set<Relative> relatives = getRelatives(destination, rotation, entity.level().dimension() == level.dimension());
            if (rot == null) {
                performTeleport(source, entity, level, pos.x, pos.y, pos.z, relatives, entity.getYRot(), entity.getXRot(), lookAt);
            } else {
                performTeleport(source, entity, level, pos.x, pos.y, pos.z, relatives, rot.y, rot.x, lookAt);
            }
        }
 
        if (entities.size() == 1) {
            source.sendSuccess(
                () -> Component.translatable(
                    "commands.teleport.success.location.single",
                    entities.iterator().next().getDisplayName(),
                    formatDouble(pos.x),
                    formatDouble(pos.y),
                    formatDouble(pos.z)
                ),
                true
            );
        } else {
            source.sendSuccess(
                () -> Component.translatable(
                    "commands.teleport.success.location.multiple", entities.size(), formatDouble(pos.x), formatDouble(pos.y), formatDouble(pos.z)
                ),
                true
            );
        }
 
        return entities.size();
    }
 
    private static Set<Relative> getRelatives(Coordinates destination, @Nullable Coordinates rotation, boolean sameDimension) {
        Set<Relative> dir = Relative.direction(destination.isXRelative(), destination.isYRelative(), destination.isZRelative());
        Set<Relative> pos = sameDimension ? Relative.position(destination.isXRelative(), destination.isYRelative(), destination.isZRelative()) : Set.of();
        Set<Relative> rot = rotation == null ? Relative.ROTATION : Relative.rotation(rotation.isYRelative(), rotation.isXRelative());
        return Relative.union(dir, pos, rot);
    }
 
    private static String formatDouble(double value) {
        return String.format(Locale.ROOT, "%f", value);
    }
 
    private static void performTeleport(
        CommandSourceStack source,
        Entity victim,
        ServerLevel level,
        double x,
        double y,
        double z,
        Set<Relative> relatives,
        float yRot,
        float xRot,
        @Nullable LookAt lookAt
    ) throws CommandSyntaxException {
        BlockPos blockPos = BlockPos.containing(x, y, z);
        if (!Level.isInSpawnableBounds(blockPos)) {
            throw INVALID_POSITION.create();
        } else {
            double relativeOrAbsoluteX = relatives.contains(Relative.X) ? x - victim.getX() : x;
            double relativeOrAbsoluteY = relatives.contains(Relative.Y) ? y - victim.getY() : y;
            double relativeOrAbsoluteZ = relatives.contains(Relative.Z) ? z - victim.getZ() : z;
            float relativeOrAbsoluteYRot = relatives.contains(Relative.Y_ROT) ? yRot - victim.getYRot() : yRot;
            float relativeOrAbsoluteXRot = relatives.contains(Relative.X_ROT) ? xRot - victim.getXRot() : xRot;
            float newYRot = Mth.wrapDegrees(relativeOrAbsoluteYRot);
            float newXRot = Mth.wrapDegrees(relativeOrAbsoluteXRot);
            if (victim.teleportTo(level, relativeOrAbsoluteX, relativeOrAbsoluteY, relativeOrAbsoluteZ, relatives, newYRot, newXRot, true)) {
                if (lookAt != null) {
                    lookAt.perform(source, victim);
                }
 
                if (!(victim instanceof LivingEntity living && living.isFallFlying())) {
                    victim.setDeltaMovement(victim.getDeltaMovement().multiply(1.0, 0.0, 1.0));
                    victim.setOnGround(true);
                }
 
                if (victim instanceof PathfinderMob mob) {
                    mob.getNavigation().stop();
                }
            }
        }
    }
}

引用的其他类

  • CommandSourceStack

    • 引用位置: 参数
  • Commands

    • 引用位置: 方法调用
    • 关联成员: Commands.argument(), Commands.hasPermission(), Commands.literal()
  • EntityAnchorArgument

    • 引用位置: 方法调用
    • 关联成员: EntityAnchorArgument.anchor(), EntityAnchorArgument.getAnchor()
  • EntityArgument

    • 引用位置: 方法调用
    • 关联成员: EntityArgument.entities(), EntityArgument.entity(), EntityArgument.getEntities(), EntityArgument.getEntity()
  • Coordinates

    • 引用位置: 参数
  • RotationArgument

    • 引用位置: 方法调用
    • 关联成员: RotationArgument.getRotation(), RotationArgument.rotation()
  • Vec3Argument

    • 引用位置: 方法调用
    • 关联成员: Vec3Argument.getCoordinates(), Vec3Argument.getVec3(), Vec3Argument.vec3()
  • BlockPos

    • 引用位置: 方法调用
    • 关联成员: BlockPos.containing()
  • Component

    • 引用位置: 方法调用
    • 关联成员: Component.translatable()
  • LookAt

    • 引用位置: 参数/方法调用/构造调用
    • 关联成员: LookAt.LookAtEntity(), LookAt.LookAtPosition(), LookAtEntity(), LookAtPosition()
  • ServerLevel

    • 引用位置: 参数
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.wrapDegrees()
  • Entity

    • 引用位置: 参数
  • Relative

    • 引用位置: 参数/方法调用/返回值
    • 关联成员: Relative.direction(), Relative.position(), Relative.rotation(), Relative.union()
  • Level

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