diff --git a/gradle.properties b/gradle.properties index 416b7db..9e29c03 100644 --- a/gradle.properties +++ b/gradle.properties @@ -35,7 +35,7 @@ mod_name=Rivencraft # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=LGPL-3.0-or-later # The mod version. Rivencraft uses the x.y.z.b policy documented in README.md. -mod_version=0.2.16.9 +mod_version=0.2.16.10 immersive_portals_version=6.0.7 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. diff --git a/src/main/java/net/dnorberg/rivencraft/book/LinkingService.java b/src/main/java/net/dnorberg/rivencraft/book/LinkingService.java index 96c1696..605e724 100644 --- a/src/main/java/net/dnorberg/rivencraft/book/LinkingService.java +++ b/src/main/java/net/dnorberg/rivencraft/book/LinkingService.java @@ -28,6 +28,12 @@ public final class LinkingService { return travel(player, target, false); } + public static Optional resolveDestination(ServerLevel level, BlockPos origin, boolean ageArrival) { + return ageArrival + ? findFootedAgeDestination(level, origin) + : findSafeDestination(level, origin, false); + } + /** Travels to an Age-style destination, which must have solid footing. */ public static LinkResult travelWithFooting(ServerPlayer player, LinkTarget target) { ServerLevel destinationLevel = player.getServer().getLevel(target.location().dimension()); @@ -35,7 +41,7 @@ public final class LinkingService { return LinkResult.MISSING_DIMENSION; } - Optional destination = findFootedAgeDestination(destinationLevel, target.location().pos()); + Optional destination = resolveDestination(destinationLevel, target.location().pos(), true); if (destination.isEmpty()) { return LinkResult.NO_SAFE_DESTINATION; } @@ -52,7 +58,7 @@ public final class LinkingService { return LinkResult.MISSING_DIMENSION; } - Optional destination = findSafeDestination(destinationLevel, target.location().pos(), requiresFooting); + Optional destination = resolveDestination(destinationLevel, target.location().pos(), requiresFooting); if (destination.isEmpty()) { return LinkResult.NO_SAFE_DESTINATION; } diff --git a/src/main/java/net/dnorberg/rivencraft/client/ClientBookExploreOverlay.java b/src/main/java/net/dnorberg/rivencraft/client/ClientBookExploreOverlay.java index ca9ce1f..049f5b1 100644 --- a/src/main/java/net/dnorberg/rivencraft/client/ClientBookExploreOverlay.java +++ b/src/main/java/net/dnorberg/rivencraft/client/ClientBookExploreOverlay.java @@ -4,6 +4,8 @@ import com.mojang.blaze3d.platform.InputConstants; import net.dnorberg.rivencraft.client.screen.ExplorableBookScreen; import net.dnorberg.rivencraft.network.LinkPreviewPayload; import net.minecraft.client.Minecraft; +import net.minecraft.client.KeyMapping; +import net.minecraft.world.phys.Vec3; import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.InputEvent; import net.neoforged.neoforge.client.event.RenderGuiEvent; @@ -11,12 +13,15 @@ import org.lwjgl.glfw.GLFW; public final class ClientBookExploreOverlay { private static ExplorableBookScreen bookScreen; + private static Vec3 playerPosition; private ClientBookExploreOverlay() { } public static void open(ExplorableBookScreen screen) { bookScreen = screen; + Minecraft minecraft = Minecraft.getInstance(); + playerPosition = minecraft.player == null ? null : minecraft.player.position(); } public static boolean acceptPreview(LinkPreviewPayload payload) { @@ -27,7 +32,27 @@ public final class ClientBookExploreOverlay { return true; } - public static void onClientTick(ClientTickEvent.Post event) { + public static void onClientTickPre(ClientTickEvent.Pre event) { + if (bookScreen == null) { + return; + } + Minecraft minecraft = Minecraft.getInstance(); + if (minecraft.player != null) { + minecraft.options.keyUp.setDown(false); + minecraft.options.keyDown.setDown(false); + minecraft.options.keyLeft.setDown(false); + minecraft.options.keyRight.setDown(false); + minecraft.options.keyJump.setDown(false); + minecraft.options.keyShift.setDown(false); + minecraft.options.keySprint.setDown(false); + minecraft.player.input.forwardImpulse = 0.0F; + minecraft.player.input.leftImpulse = 0.0F; + minecraft.player.input.jumping = false; + minecraft.player.input.shiftKeyDown = false; + } + } + + public static void onClientTickPost(ClientTickEvent.Post event) { if (bookScreen == null) { return; } @@ -35,8 +60,13 @@ public final class ClientBookExploreOverlay { if (minecraft.player == null || minecraft.level == null) { bookScreen.abandonExploreOverlay(); bookScreen = null; + playerPosition = null; return; } + if (playerPosition != null) { + minecraft.player.setPos(playerPosition); + minecraft.player.setDeltaMovement(Vec3.ZERO); + } bookScreen.tickExploreOverlay(); } @@ -57,6 +87,8 @@ public final class ClientBookExploreOverlay { event.setCanceled(true); ExplorableBookScreen screen = bookScreen; bookScreen = null; + playerPosition = null; + KeyMapping.setAll(); screen.returnFromExploreOverlay(); } } diff --git a/src/main/java/net/dnorberg/rivencraft/client/ClientEvents.java b/src/main/java/net/dnorberg/rivencraft/client/ClientEvents.java index 46a3cc6..6673ae6 100644 --- a/src/main/java/net/dnorberg/rivencraft/client/ClientEvents.java +++ b/src/main/java/net/dnorberg/rivencraft/client/ClientEvents.java @@ -23,7 +23,8 @@ public final class ClientEvents { public static void clientSetup(FMLClientSetupEvent event) { NeoForge.EVENT_BUS.addListener(ClientBookInteractionHandler::onRightClickItem); NeoForge.EVENT_BUS.addListener(ClientBookInteractionHandler::onRightClickBlock); - NeoForge.EVENT_BUS.addListener(ClientBookExploreOverlay::onClientTick); + NeoForge.EVENT_BUS.addListener(ClientBookExploreOverlay::onClientTickPre); + NeoForge.EVENT_BUS.addListener(ClientBookExploreOverlay::onClientTickPost); NeoForge.EVENT_BUS.addListener(ClientBookExploreOverlay::onRenderGui); NeoForge.EVENT_BUS.addListener(ClientBookExploreOverlay::onMouseButton); } diff --git a/src/main/java/net/dnorberg/rivencraft/client/preview/ImmersivePortalsDestinationPreviewRenderer.java b/src/main/java/net/dnorberg/rivencraft/client/preview/ImmersivePortalsDestinationPreviewRenderer.java index c2ce8a6..0a4c246 100644 --- a/src/main/java/net/dnorberg/rivencraft/client/preview/ImmersivePortalsDestinationPreviewRenderer.java +++ b/src/main/java/net/dnorberg/rivencraft/client/preview/ImmersivePortalsDestinationPreviewRenderer.java @@ -24,8 +24,6 @@ public final class ImmersivePortalsDestinationPreviewRenderer implements Destina private final Minecraft minecraft = Minecraft.getInstance(); private LinkPreviewPayload destination; private Vec3 cameraPosition; - private Vec3 explorationPlayerOrigin; - private Vec3 explorationCameraOrigin; private float explorationPlayerYaw; private float explorationPlayerPitch; private float explorationCameraYaw; @@ -54,8 +52,7 @@ public final class ImmersivePortalsDestinationPreviewRenderer implements Destina if (!exploring || cameraPosition == null) { return; } - if (minecraft.player != null && explorationPlayerOrigin != null && explorationCameraOrigin != null) { - cameraPosition = explorationCameraOrigin.add(minecraft.player.position().subtract(explorationPlayerOrigin)); + if (minecraft.player != null) { yaw = explorationCameraYaw + Mth.wrapDegrees(minecraft.player.getYRot() - explorationPlayerYaw); pitch = Mth.clamp(explorationCameraPitch + minecraft.player.getXRot() - explorationPlayerPitch, -89.0F, 89.0F); @@ -131,17 +128,17 @@ public final class ImmersivePortalsDestinationPreviewRenderer implements Destina @Override public void setExploring(boolean exploring) { this.exploring = exploring; - if (exploring && minecraft.player != null) { - explorationPlayerOrigin = minecraft.player.position(); - explorationCameraOrigin = cameraPosition; + if (exploring && minecraft.player != null && destination != null) { + cameraPosition = Vec3.atBottomCenterOf(destination.origin()) + .add(0.0D, minecraft.player.getEyeHeight(), 0.0D); + yaw = destination.yaw(); + pitch = destination.pitch(); explorationPlayerYaw = minecraft.player.getYRot(); explorationPlayerPitch = minecraft.player.getXRot(); explorationCameraYaw = yaw; explorationCameraPitch = pitch; } else { clearMovement(); - explorationPlayerOrigin = null; - explorationCameraOrigin = null; } } @@ -226,8 +223,6 @@ public final class ImmersivePortalsDestinationPreviewRenderer implements Destina public void resetView() { exploring = false; clearMovement(); - explorationPlayerOrigin = null; - explorationCameraOrigin = null; if (destination != null) { cameraPosition = Vec3.atCenterOf(destination.origin()).add(0.0D, 2.0D, ORBIT_RADIUS); yaw = destination.yaw(); diff --git a/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java b/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java index d9dad1c..025361f 100644 --- a/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java +++ b/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java @@ -1,6 +1,7 @@ package net.dnorberg.rivencraft.network; import net.dnorberg.rivencraft.book.LinkTarget; +import net.dnorberg.rivencraft.book.LinkingService; import net.dnorberg.rivencraft.book.AgeReference; import net.dnorberg.rivencraft.book.AgeRegistrySavedData; import net.dnorberg.rivencraft.book.AgeDimensionService; @@ -224,7 +225,10 @@ public final class ModNetworking { return; } - BlockPos origin = target.location().pos(); + BlockPos origin = LinkingService.resolveDestination( + level, target.location().pos(), payload.descriptiveBook()) + .map(BlockPos::containing) + .orElse(target.location().pos()); List blocks = new ArrayList<>(); // The cubic footprint survives every angle of the orbit. The target is // kept at the preview camera's current center point.