From f664301683043f76f9bf628d9a3706dec68c6bd7 Mon Sep 17 00:00:00 2001 From: Alvinn8 <42838560+Alvinn8@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:23:09 +0200 Subject: [PATCH] Add command to change viewed dimension in mch-viewer --- .../mch/viewer/fabric/HistoryCommand.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/mch-viewer/fabric/src/main/java/ca/bkaw/mch/viewer/fabric/HistoryCommand.java b/mch-viewer/fabric/src/main/java/ca/bkaw/mch/viewer/fabric/HistoryCommand.java index fd8ec4b..508c83a 100644 --- a/mch-viewer/fabric/src/main/java/ca/bkaw/mch/viewer/fabric/HistoryCommand.java +++ b/mch-viewer/fabric/src/main/java/ca/bkaw/mch/viewer/fabric/HistoryCommand.java @@ -4,6 +4,8 @@ import ca.bkaw.mch.object.ObjectStorageTypes; import ca.bkaw.mch.object.Reference20; import ca.bkaw.mch.object.commit.Commit; +import ca.bkaw.mch.object.dimension.Dimension; +import ca.bkaw.mch.object.world.World; import ca.bkaw.mch.repository.MchRepository; import ca.bkaw.mch.repository.TrackedWorld; import com.mojang.brigadier.CommandDispatcher; @@ -21,12 +23,15 @@ import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; +import net.minecraft.commands.arguments.ResourceLocationArgument; import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; import org.joml.Vector4d; @@ -47,6 +52,9 @@ public class HistoryCommand { public static final SimpleCommandExceptionType NO_DEFAULT_REPO = new SimpleCommandExceptionType(net.minecraft.network.chat.Component.literal( "No default repo has configured, please specify which repo to view with /history view " )); + public static final DynamicCommandExceptionType NO_DIMENSION = new DynamicCommandExceptionType(dimension -> net.minecraft.network.chat.Component.literal( + "No dimension '" + dimension + "' was found in the repository." + )); private final MchViewerFabric mchViewer; @@ -147,6 +155,22 @@ public void register(CommandDispatcher dispatcher) { }) ) ) + .then( + Commands.literal("dimension") + .then( + Commands.argument("key", ResourceLocationArgument.id()) + .suggests(this::suggestDimensions) + .executes(ctx -> { + try { + return changeDimension(ctx, ResourceLocationArgument.getId(ctx, "key")); + } catch (IOException e) { + ctx.getSource().sendFailure(Component.text(e.toString())); + e.printStackTrace(); + return 0; + } + }) + ) + ) ); } @@ -398,4 +422,48 @@ private int commit(CommandContext ctx, Sha1 sha1) throws Com return 1; } + private CompletableFuture suggestDimensions(CommandContext ctx, SuggestionsBuilder builder) { + return CompletableFuture.supplyAsync(() -> { + try { + HistoryView historyView = getHistoryView(ctx); + World world = historyView.getWorld(); + for (String key : world.getDimensions().keySet()) { + if (key.toLowerCase(Locale.ROOT).startsWith(builder.getRemainingLowerCase())) { + builder.suggest(key); + } + } + return builder.build(); + } catch (IOException | CommandSyntaxException e) { + // Suggest nothing + return builder.build(); + } + }); + } + + private int changeDimension(CommandContext ctx, ResourceLocation key) throws CommandSyntaxException, IOException { + HistoryView historyView = getHistoryView(ctx); + World world = historyView.getWorld(); + CommandSourceStack source = ctx.getSource(); + + Reference20 dimension = world.getDimension(key.toString()); + if (dimension == null) { + throw NO_DIMENSION.create(key); + } + + DimensionView toDimension = historyView.viewDimension(key); + double fromScale = source.getLevel().dimensionType().coordinateScale(); + double toScale = toDimension.getLevel().dimensionType().coordinateScale(); + double scale = fromScale / toScale; + + Vec3 pos = source.getPosition().multiply(scale, 1, scale); + + ServerPlayer player = source.getPlayerOrException(); + player.teleportTo( + toDimension.getLevel(), pos.x(), pos.y(), pos.z(), + player.getYRot(), player.getXRot() + ); + + return 1; + } + }