diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/TeleportTracker.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/TeleportTracker.java index 8f4c5699c..647d715f7 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/TeleportTracker.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/TeleportTracker.java @@ -26,6 +26,7 @@ import org.vivecraft.client_vr.render.helpers.RenderHelper; import org.vivecraft.common.utils.MathUtils; import org.vivecraft.data.BlockTags; +import org.vivecraft.mod_compat_vr.immersiveportals.ImmersivePortalsHelper; import java.util.Random; @@ -305,6 +306,16 @@ private void updateTeleportArc(LocalPlayer player) { ClipContext.Fluid.ANY, player)); + if (ImmersivePortalsHelper.isLoaded()) { + if (ImmersivePortalsHelper.positionContainsPortalBlock(this.mc.level, newPos)) { + break; + } + Vec3 lastPos = i == 0 ? null : this.movementTeleportArc[i - 1]; + if (lastPos != null && ImmersivePortalsHelper.rayIntersectsPortal(this.mc.level, lastPos, newPos)) { + break; + } + } + if (blockhitresult.getType() != HitResult.Type.MISS) { this.movementTeleportArc[i] = blockhitresult.getLocation(); diff --git a/common/src/main/java/org/vivecraft/client_vr/render/helpers/VREffectsHelper.java b/common/src/main/java/org/vivecraft/client_vr/render/helpers/VREffectsHelper.java index b43ea85e8..f3e5efd51 100644 --- a/common/src/main/java/org/vivecraft/client_vr/render/helpers/VREffectsHelper.java +++ b/common/src/main/java/org/vivecraft/client_vr/render/helpers/VREffectsHelper.java @@ -24,6 +24,7 @@ import net.minecraft.util.Mth; import net.minecraft.util.profiling.Profiler; import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; @@ -95,14 +96,17 @@ public static boolean isInsideOpaqueBlock(Vec3 pos) { * BlockState and BlockPos of the blocking block */ public static Triple getNearOpaqueBlock(Vec3 pos, double dist) { - if (MC.level == null) { + // Use player's level, since Immersive Portals likes to set Minecraft#level to be the level the player isn't + // necessarily in. + Level level = MC.player != null && !MC.player.isRemoved() ? MC.player.level() : MC.level; + if (level == null) { return null; } else { AABB aabb = new AABB(pos.subtract(dist, dist, dist), pos.add(dist, dist, dist)); Stream stream = BlockPos.betweenClosedStream(aabb).filter((bp) -> - MC.level.getBlockState(bp).isSolidRender()); + level.getBlockState(bp).isSolidRender()); Optional optional = stream.findFirst(); - return optional.map(blockPos -> Triple.of(1.0F, MC.level.getBlockState(blockPos), blockPos)).orElse(null); + return optional.map(blockPos -> Triple.of(1.0F, level.getBlockState(blockPos), blockPos)).orElse(null); } } diff --git a/common/src/main/java/org/vivecraft/mod_compat_vr/immersiveportals/ImmersivePortalsHelper.java b/common/src/main/java/org/vivecraft/mod_compat_vr/immersiveportals/ImmersivePortalsHelper.java index 55cd2397d..3a0043987 100644 --- a/common/src/main/java/org/vivecraft/mod_compat_vr/immersiveportals/ImmersivePortalsHelper.java +++ b/common/src/main/java/org/vivecraft/mod_compat_vr/immersiveportals/ImmersivePortalsHelper.java @@ -1,7 +1,12 @@ package org.vivecraft.mod_compat_vr.immersiveportals; import org.vivecraft.Xloader; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; import qouteall.imm_ptl.core.IPGlobal; +import qouteall.imm_ptl.core.IPMcHelper; +import qouteall.imm_ptl.core.portal.PortalPlaceholderBlock; import qouteall.imm_ptl.core.render.context_management.PortalRendering; public class ImmersivePortalsHelper { @@ -23,4 +28,12 @@ public static boolean isRenderingPortal() { public static boolean shouldRenderSelf() { return IPGlobal.renderYourselfInPortal && isRenderingPortal(); } + + public static boolean rayIntersectsPortal(Level level, Vec3 start, Vec3 end) { + return !IPMcHelper.rayTracePortals(level, start, end, true, p -> true).isEmpty(); + } + + public static boolean positionContainsPortalBlock(Level level, Vec3 pos) { + return level.getBlockState(BlockPos.containing(pos)).is(PortalPlaceholderBlock.instance); + } } diff --git a/common/src/main/java/org/vivecraft/mod_compat_vr/immersiveportals/mixin/McHelperMixin.java b/common/src/main/java/org/vivecraft/mod_compat_vr/immersiveportals/mixin/McHelperMixin.java new file mode 100644 index 000000000..2c7f3525a --- /dev/null +++ b/common/src/main/java/org/vivecraft/mod_compat_vr/immersiveportals/mixin/McHelperMixin.java @@ -0,0 +1,34 @@ +package org.vivecraft.mod_compat_vr.immersiveportals.mixin; + +import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.Vec3; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.vivecraft.client_vr.gameplay.VRPlayer; +import qouteall.imm_ptl.core.McHelper; + +@Mixin(McHelper.class) +public class McHelperMixin { + + @WrapMethod(method = "setEyePos") + private static void vivecraft$adjustRoomOriginOnEyePosUpdate(Entity entity, Vec3 eyePos, Vec3 lastTickEyePos, Operation original) { + if (entity instanceof Player p && p.isLocalPlayer() && VRPlayer.get() != null) { + // Move the room origin after the player portal teleport to be in the same position relative to the player + // as before + Vec3 oldPos = entity.position(); + Vec3 oldRoomOrigin = VRPlayer.get().roomOrigin; + Vec3 offset = oldRoomOrigin.subtract(oldPos); + original.call(entity, eyePos, lastTickEyePos); + Vec3 newPos = entity.position(); + Vec3 newRoomOrigin = newPos.add(offset); + VRPlayer.get().setRoomOrigin(newRoomOrigin.x, newRoomOrigin.y, newRoomOrigin.z, true); + } else { + original.call(entity, eyePos, lastTickEyePos); + } + } +} diff --git a/common/src/main/resources/vivecraft.immersiveportals.mixins.json b/common/src/main/resources/vivecraft.immersiveportals.mixins.json new file mode 100644 index 000000000..2f2cc3f84 --- /dev/null +++ b/common/src/main/resources/vivecraft.immersiveportals.mixins.json @@ -0,0 +1,10 @@ +{ + "required": false, + "package": "org.vivecraft.mod_compat_vr.immersiveportals.mixin", + "plugin": "org.vivecraft.MixinConfig", + "compatibilityLevel": "JAVA_17", + "client": [ + "McHelperMixin" + ], + "minVersion": "0.8.4" +} diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index eafd5b5eb..a261b30ae 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -39,6 +39,7 @@ "vivecraft.cataclysm.mixins.json", "vivecraft.dynamicfps.mixins.json", "vivecraft.emf.mixins.json", + "vivecraft.immersiveportals.mixins.json", "vivecraft.iris.mixins.json", "vivecraft.mca.mixins.json", "vivecraft.modmenu.mixins.json", diff --git a/forge/build.gradle b/forge/build.gradle index 9d114b3a4..e8945f872 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -23,6 +23,7 @@ loom { mixinConfig "vivecraft.cataclysm.mixins.json" mixinConfig "vivecraft.dynamicfps.mixins.json" mixinConfig "vivecraft.emf.mixins.json" + mixinConfig "vivecraft.immersiveportals.mixins.json" mixinConfig "vivecraft.iris.mixins.json" mixinConfig "vivecraft.mca.mixins.json" mixinConfig "vivecraft.optifine.mixins.json" diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index 98bb3ecf6..58dea26f7 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -54,6 +54,8 @@ config = "vivecraft.dynamicfps.mixins.json" [[mixins]] config = "vivecraft.emf.mixins.json" [[mixins]] +config = "vivecraft.immersiveportals.mixins.json" +[[mixins]] config = "vivecraft.iris.mixins.json" [[mixins]] config = "vivecraft.mca.mixins.json"