package net.minecraft.server.commands; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import com.mojang.brigadier.tree.LiteralCommandNode; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.Locale; import java.util.Set; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.EntityAnchorArgument; import net.minecraft.commands.arguments.EntityArgument; import net.minecraft.commands.arguments.EntityAnchorArgument.Anchor; import net.minecraft.commands.arguments.coordinates.Coordinates; import net.minecraft.commands.arguments.coordinates.RotationArgument; import net.minecraft.commands.arguments.coordinates.Vec3Argument; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.PathfinderMob; import net.minecraft.world.entity.Relative; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; public class TeleportCommand { private static final SimpleCommandExceptionType INVALID_POSITION = new SimpleCommandExceptionType(Component.translatable("commands.teleport.invalidPosition")); public static void register(CommandDispatcher dispatcher) { LiteralCommandNode literalCommandNode = dispatcher.register( Commands.literal("teleport") .requires(commandSourceStack -> commandSourceStack.hasPermission(2)) .then( Commands.argument("location", Vec3Argument.vec3()) .executes( commandContext -> teleportToPos( commandContext.getSource(), Collections.singleton(commandContext.getSource().getEntityOrException()), commandContext.getSource().getLevel(), Vec3Argument.getCoordinates(commandContext, "location"), null, null ) ) ) .then( Commands.argument("destination", EntityArgument.entity()) .executes( commandContext -> teleportToEntity( commandContext.getSource(), Collections.singleton(commandContext.getSource().getEntityOrException()), EntityArgument.getEntity(commandContext, "destination") ) ) ) .then( Commands.argument("targets", EntityArgument.entities()) .then( Commands.argument("location", Vec3Argument.vec3()) .executes( commandContext -> teleportToPos( commandContext.getSource(), EntityArgument.getEntities(commandContext, "targets"), commandContext.getSource().getLevel(), Vec3Argument.getCoordinates(commandContext, "location"), null, null ) ) .then( Commands.argument("rotation", RotationArgument.rotation()) .executes( commandContext -> teleportToPos( commandContext.getSource(), EntityArgument.getEntities(commandContext, "targets"), commandContext.getSource().getLevel(), Vec3Argument.getCoordinates(commandContext, "location"), RotationArgument.getRotation(commandContext, "rotation"), null ) ) ) .then( Commands.literal("facing") .then( Commands.literal("entity") .then( Commands.argument("facingEntity", EntityArgument.entity()) .executes( commandContext -> teleportToPos( commandContext.getSource(), EntityArgument.getEntities(commandContext, "targets"), commandContext.getSource().getLevel(), Vec3Argument.getCoordinates(commandContext, "location"), null, new LookAt.LookAtEntity(EntityArgument.getEntity(commandContext, "facingEntity"), Anchor.FEET) ) ) .then( Commands.argument("facingAnchor", EntityAnchorArgument.anchor()) .executes( commandContext -> teleportToPos( commandContext.getSource(), EntityArgument.getEntities(commandContext, "targets"), commandContext.getSource().getLevel(), Vec3Argument.getCoordinates(commandContext, "location"), null, new LookAt.LookAtEntity( EntityArgument.getEntity(commandContext, "facingEntity"), EntityAnchorArgument.getAnchor(commandContext, "facingAnchor") ) ) ) ) ) ) .then( Commands.argument("facingLocation", Vec3Argument.vec3()) .executes( commandContext -> teleportToPos( commandContext.getSource(), EntityArgument.getEntities(commandContext, "targets"), commandContext.getSource().getLevel(), Vec3Argument.getCoordinates(commandContext, "location"), null, new LookAt.LookAtPosition(Vec3Argument.getVec3(commandContext, "facingLocation")) ) ) ) ) ) .then( Commands.argument("destination", EntityArgument.entity()) .executes( commandContext -> teleportToEntity( commandContext.getSource(), EntityArgument.getEntities(commandContext, "targets"), EntityArgument.getEntity(commandContext, "destination") ) ) ) ) ); dispatcher.register(Commands.literal("tp").requires(commandSourceStack -> commandSourceStack.hasPermission(2)).redirect(literalCommandNode)); } private static int teleportToEntity(CommandSourceStack source, Collection targets, Entity destination) throws CommandSyntaxException { for (Entity entity : targets) { performTeleport( source, entity, (ServerLevel)destination.level(), destination.getX(), destination.getY(), destination.getZ(), EnumSet.noneOf(Relative.class), destination.getYRot(), destination.getXRot(), null ); } if (targets.size() == 1) { source.sendSuccess( () -> Component.translatable("commands.teleport.success.entity.single", ((Entity)targets.iterator().next()).getDisplayName(), destination.getDisplayName()), true ); } else { source.sendSuccess(() -> Component.translatable("commands.teleport.success.entity.multiple", targets.size(), destination.getDisplayName()), true); } return targets.size(); } private static int teleportToPos( CommandSourceStack commandSourceStack, Collection collection, ServerLevel serverLevel, Coordinates coordinates, @Nullable Coordinates coordinates2, @Nullable LookAt lookAt ) throws CommandSyntaxException { Vec3 vec3 = coordinates.getPosition(commandSourceStack); Vec2 vec2 = coordinates2 == null ? null : coordinates2.getRotation(commandSourceStack); for (Entity entity : collection) { Set set = getRelatives(coordinates, coordinates2, entity.level().dimension() == serverLevel.dimension()); if (vec2 == null) { performTeleport(commandSourceStack, entity, serverLevel, vec3.x, vec3.y, vec3.z, set, entity.getYRot(), entity.getXRot(), lookAt); } else { performTeleport(commandSourceStack, entity, serverLevel, vec3.x, vec3.y, vec3.z, set, vec2.y, vec2.x, lookAt); } } if (collection.size() == 1) { commandSourceStack.sendSuccess( () -> Component.translatable( "commands.teleport.success.location.single", ((Entity)collection.iterator().next()).getDisplayName(), formatDouble(vec3.x), formatDouble(vec3.y), formatDouble(vec3.z) ), true ); } else { commandSourceStack.sendSuccess( () -> Component.translatable( "commands.teleport.success.location.multiple", collection.size(), formatDouble(vec3.x), formatDouble(vec3.y), formatDouble(vec3.z) ), true ); } return collection.size(); } private static Set getRelatives(Coordinates coordinates, @Nullable Coordinates coordinates2, boolean bl) { Set set = EnumSet.noneOf(Relative.class); if (coordinates.isXRelative()) { set.add(Relative.DELTA_X); if (bl) { set.add(Relative.X); } } if (coordinates.isYRelative()) { set.add(Relative.DELTA_Y); if (bl) { set.add(Relative.Y); } } if (coordinates.isZRelative()) { set.add(Relative.DELTA_Z); if (bl) { set.add(Relative.Z); } } if (coordinates2 == null || coordinates2.isXRelative()) { set.add(Relative.X_ROT); } if (coordinates2 == null || coordinates2.isYRelative()) { set.add(Relative.Y_ROT); } return set; } private static String formatDouble(double value) { return String.format(Locale.ROOT, "%f", value); } private static void performTeleport( CommandSourceStack commandSourceStack, Entity entity, ServerLevel serverLevel, double d, double e, double f, Set set, float g, float h, @Nullable LookAt lookAt ) throws CommandSyntaxException { BlockPos blockPos = BlockPos.containing(d, e, f); if (!Level.isInSpawnableBounds(blockPos)) { throw INVALID_POSITION.create(); } else { double i = set.contains(Relative.X) ? d - entity.getX() : d; double j = set.contains(Relative.Y) ? e - entity.getY() : e; double k = set.contains(Relative.Z) ? f - entity.getZ() : f; float l = set.contains(Relative.Y_ROT) ? g - entity.getYRot() : g; float m = set.contains(Relative.X_ROT) ? h - entity.getXRot() : h; float n = Mth.wrapDegrees(l); float o = Mth.wrapDegrees(m); if (entity.teleportTo(serverLevel, i, j, k, set, n, o, true)) { if (lookAt != null) { lookAt.perform(commandSourceStack, entity); } if (!(entity instanceof LivingEntity livingEntity && livingEntity.isFallFlying())) { entity.setDeltaMovement(entity.getDeltaMovement().multiply(1.0, 0.0, 1.0)); entity.setOnGround(true); } if (entity instanceof PathfinderMob pathfinderMob) { pathfinderMob.getNavigation().stop(); } } } } }