Handle teleporting within the same dimension better. ()

(cherry picked from commit 72da3b3d5e)
This commit is contained in:
modmuss50 2022-05-24 15:10:52 +01:00
parent d8d7804af0
commit ffb2c71e55
2 changed files with 68 additions and 0 deletions
fabric-dimensions-v1/src
main/java/net/fabricmc/fabric/impl/dimension
testmod/java/net/fabricmc/fabric/test/dimension

View file

@ -19,6 +19,7 @@ package net.fabricmc.fabric.impl.dimension;
import com.google.common.base.Preconditions;
import net.minecraft.entity.Entity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.world.TeleportTarget;
@ -48,6 +49,21 @@ public final class FabricDimensionInternals {
try {
currentTarget = target;
// Fast path for teleporting within the same dimension.
if (teleported.getWorld() == dimension) {
if (teleported instanceof ServerPlayerEntity serverPlayerEntity) {
serverPlayerEntity.networkHandler.requestTeleport(target.position.x, target.position.y, target.position.z, target.yaw, teleported.getPitch());
} else {
teleported.refreshPositionAndAngles(target.position.x, target.position.y, target.position.z, target.yaw, teleported.getPitch());
}
teleported.setVelocity(target.velocity);
teleported.setHeadYaw(target.yaw);
return teleported;
}
return (E) teleported.moveToWorld(dimension);
} finally {
currentTarget = null;

View file

@ -102,6 +102,14 @@ public class FabricDimensionTest implements ModInitializer {
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) ->
dispatcher.register(literal("fabric_dimension_test").executes(FabricDimensionTest.this::swapTargeted))
);
// Used to test https://github.com/FabricMC/fabric/issues/2239
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(literal("fabric_dimension_test_desync")
.executes(FabricDimensionTest.this::testDesync)));
// Used to test https://github.com/FabricMC/fabric/issues/2238
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(literal("fabric_dimension_test_entity")
.executes(FabricDimensionTest.this::testEntityTeleport)));
}
private int swapTargeted(CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
@ -128,6 +136,50 @@ public class FabricDimensionTest implements ModInitializer {
return 1;
}
private int testDesync(CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
ServerPlayerEntity player = context.getSource().getPlayer();
if (player == null) {
context.getSource().sendFeedback(new LiteralText("You must be a player to execute this command."), false);
return 1;
}
if (!context.getSource().getServer().isDedicated()) {
context.getSource().sendFeedback(new LiteralText("This command can only be executed on dedicated servers."), false);
return 1;
}
TeleportTarget target = new TeleportTarget(player.getPos().add(5, 0, 0), player.getVelocity(), player.getYaw(), player.getPitch());
FabricDimensions.teleport(player, (ServerWorld) player.world, target);
return 1;
}
private int testEntityTeleport(CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
ServerPlayerEntity player = context.getSource().getPlayer();
if (player == null) {
context.getSource().sendFeedback(new LiteralText("You must be a player to execute this command."), false);
return 1;
}
Entity entity = player.world
.getOtherEntities(player, player.getBoundingBox().expand(100, 100, 100))
.stream()
.findFirst()
.orElse(null);
if (entity == null) {
context.getSource().sendFeedback(new LiteralText("No entities found."), false);
return 1;
}
TeleportTarget target = new TeleportTarget(player.getPos(), player.getVelocity(), player.getYaw(), player.getPitch());
FabricDimensions.teleport(entity, (ServerWorld) entity.world, target);
return 1;
}
private ServerWorld getModWorld(CommandContext<ServerCommandSource> context) {
return getWorld(context, WORLD_KEY);
}