From 0cc05bdaf1340685a3a050aad71c590ac848c462 Mon Sep 17 00:00:00 2001 From: TropheusJ Date: Sat, 18 Nov 2023 06:11:56 -0500 Subject: [PATCH] good progress - most of the process works - need to make it only affect portals on the right surface for each block - need to handle non cubes - caching? --- .../portalcubed/content/portal/Portal.java | 24 +++- .../content/portal/PortalRenderer.java | 8 +- .../portal/collision/CollisionManager.java | 135 ++++++++++++++++-- .../content/portal/manager/PortalManager.java | 4 +- .../portalcubed/framework/Aaaa.java | 91 ------------ .../extension/EntityCollisionContextExt.java | 6 - .../framework/extension/EntityExt.java | 6 + .../framework/shape/VoxelShenanigans.java | 6 +- .../BlockBehavior$BlockStateBaseMixin.java | 28 +--- .../mixin/EntityCollisionContextMixin.java | 23 --- .../portalcubed/mixin/EntityMixin.java | 17 ++- src/main/resources/portalcubed.mixins.json | 1 - 12 files changed, 180 insertions(+), 169 deletions(-) delete mode 100644 src/main/java/io/github/fusionflux/portalcubed/framework/Aaaa.java delete mode 100644 src/main/java/io/github/fusionflux/portalcubed/framework/extension/EntityCollisionContextExt.java create mode 100644 src/main/java/io/github/fusionflux/portalcubed/framework/extension/EntityExt.java delete mode 100644 src/main/java/io/github/fusionflux/portalcubed/mixin/EntityCollisionContextMixin.java diff --git a/src/main/java/io/github/fusionflux/portalcubed/content/portal/Portal.java b/src/main/java/io/github/fusionflux/portalcubed/content/portal/Portal.java index a0391c16..0c64ff18 100644 --- a/src/main/java/io/github/fusionflux/portalcubed/content/portal/Portal.java +++ b/src/main/java/io/github/fusionflux/portalcubed/content/portal/Portal.java @@ -26,14 +26,11 @@ public final class Portal { public static final double WIDTH = 1 - (2 * SIXTEENTH); public static final double THICKNESS = 0; public static final double COLLISION_BOX_SIDE_THICKNESS = 0.01; - public static final double COLLISION_BOX_DEPTH = 2 - (2 * COLLISION_BOX_SIDE_THICKNESS); + public static final double COLLISION_BOX_DEPTH = 4 - (2 * COLLISION_BOX_SIDE_THICKNESS); public final int netId; public final Vec3 origin; public final AABB plane; // technically a box, but really thin on 1 axis - public final VoxelShape hole; // the hole this portal punches in the world to allow walking through - public final AABB collisionArea; // area in front of portal where entities will collide with blocks on the other side - public final AABB blockCollisionArea; // area behind portal where blocks are important to collision public final Vec3 normal; public final FrontAndTop orientation; public final Quaternionf rotation; @@ -43,6 +40,16 @@ public final class Portal { public final int color; public final UUID owner; + // plane-like hole this portal punches in the world to allow walking through + public final VoxelShape hole; + // area in front of portal that an entity must be in for cross-portal collision to apply + public final AABB entityCollisionArea; + // area in front of portal where collision will be matched to behind the other portal + public final AABB collisionCollectionArea; + // area behind portal where collision is modified to match other portal + public final AABB collisionModificationBox; + + private int linkedNetId; @Nullable private Portal linked; @@ -76,11 +83,16 @@ public Portal(int netId, Vec3 origin, FrontAndTop orientation, PortalShape shape AABB holePlane = this.plane.inflate(-0.01); this.hole = Shapes.create(holePlane); - this.collisionArea = this.plane.expandTowards(normal.scale(COLLISION_BOX_DEPTH)) // extend forwards + this.entityCollisionArea = AABB.ofSize( + origin.add(normal.scale(1.5)), // center 1.5 blocks away + 3, 3, 3 // 3x3x3 box + ); + + this.collisionCollectionArea = this.plane.expandTowards(normal.scale(COLLISION_BOX_DEPTH)) // extend forwards .inflate(COLLISION_BOX_SIDE_THICKNESS) // expand bounds by thickness .move(normal.scale(COLLISION_BOX_SIDE_THICKNESS)); // move bounds off supporting wall - this.blockCollisionArea = this.plane.expandTowards(normal.scale(-COLLISION_BOX_DEPTH)) // extend backwards + this.collisionModificationBox = this.plane.expandTowards(normal.scale(-COLLISION_BOX_DEPTH)) // extend backwards .inflate(COLLISION_BOX_SIDE_THICKNESS) // expand bounds by thickness .move(normal.scale(-COLLISION_BOX_SIDE_THICKNESS)); // move bounds fully into supporting wall } diff --git a/src/main/java/io/github/fusionflux/portalcubed/content/portal/PortalRenderer.java b/src/main/java/io/github/fusionflux/portalcubed/content/portal/PortalRenderer.java index 8814be6d..66551e9b 100644 --- a/src/main/java/io/github/fusionflux/portalcubed/content/portal/PortalRenderer.java +++ b/src/main/java/io/github/fusionflux/portalcubed/content/portal/PortalRenderer.java @@ -23,19 +23,18 @@ import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; -import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.VoxelShape; -import org.joml.Quaternionf; import org.joml.Vector3f; import java.util.List; public class PortalRenderer { + public static final Color RED = new Color(1, 0, 0, 1); public static final Color GREEN = new Color(0.5f, 1, 0.5f, 1); public static final Color BLUE = new Color(0, 0, 1, 1); public static final Color ORANGE = new Color(1, 0.5f, 0, 1); @@ -98,8 +97,9 @@ private static void renderPortalDebug(Portal portal, WorldRenderContext ctx, Pos Color planeColor = portal.isActive() ? ACTIVE_PLANE_COLOR : PLANE_COLOR; renderBox(matrices, vertexConsumers, portal.plane, planeColor); // collision bounds - renderBox(matrices, vertexConsumers, portal.collisionArea, PURPLE); - renderBox(matrices, vertexConsumers, portal.blockCollisionArea, CYAN); + renderBox(matrices, vertexConsumers, portal.entityCollisionArea, RED); + renderBox(matrices, vertexConsumers, portal.collisionCollectionArea, PURPLE); + renderBox(matrices, vertexConsumers, portal.collisionModificationBox, CYAN); // cross-portal collision Portal linked = portal.getLinked(); if (linked != null) { diff --git a/src/main/java/io/github/fusionflux/portalcubed/content/portal/collision/CollisionManager.java b/src/main/java/io/github/fusionflux/portalcubed/content/portal/collision/CollisionManager.java index 4dd9c605..e43ed430 100644 --- a/src/main/java/io/github/fusionflux/portalcubed/content/portal/collision/CollisionManager.java +++ b/src/main/java/io/github/fusionflux/portalcubed/content/portal/collision/CollisionManager.java @@ -2,40 +2,139 @@ import io.github.fusionflux.portalcubed.content.portal.Portal; import io.github.fusionflux.portalcubed.content.portal.PortalTeleportHandler; +import io.github.fusionflux.portalcubed.content.portal.manager.PortalManager; +import io.github.fusionflux.portalcubed.data.tags.PortalCubedEntityTags; +import io.github.fusionflux.portalcubed.framework.extension.EntityExt; +import io.github.fusionflux.portalcubed.framework.shape.VoxelShenanigans; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.BooleanOp; +import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.ApiStatus; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; public class CollisionManager { + // thickness of a wall after the other side has been cut out for cross-portal collision + public static final double WALL_THICKNESS = 0.01; + public static final int RECURSION_DEPTH_LIMIT = 1; + + private final PortalManager portals; private final Level level; private final Map patches; - public CollisionManager(Level level) { + public CollisionManager(PortalManager portalManager, Level level) { + this.portals = portalManager; this.level = level; this.patches = new HashMap<>(); } - @Nullable - public ShapePatch getPatchAt(BlockPos pos) { - return patches.get(pos); + // modifying a shape for a portal involves 3 parts: + // - cut out most of the shape to make it non-solid (leave the surface the portal is on intact) + // - add in collision from other side + // - cut a hole directly under the portal + public VoxelShape getPortalModifiedShape(VoxelShape original, BlockPos pos, Entity entity) { + if (getRecursionDepth(entity) > RECURSION_DEPTH_LIMIT) + return original; + if (entity.getType().is(PortalCubedEntityTags.PORTAL_BLACKLIST)) + return original; + List portals = this.getPortalsToUse(pos, entity); + if (portals.isEmpty()) + return original; + incrementRecursionDepth(entity); + // move shape to absolute coords to match found collision shapes + VoxelShape shape = original.move(pos.getX(), pos.getY(), pos.getZ()); + // cut out most of the shape beyond the surface + Vec3 normal = portals.get(0).normal; + Vec3 offsetIntoWall = normal.scale(-WALL_THICKNESS); + VoxelShape cubeAtPos = Shapes.block().move(pos.getX(), pos.getY(), pos.getZ()); + VoxelShape cutBox = cubeAtPos.move(offsetIntoWall.x, offsetIntoWall.y, offsetIntoWall.z); + shape = Shapes.join(shape, cutBox, BooleanOp.ONLY_FIRST); + // first combine all collisions + List relevantPortals = new ArrayList<>(); // portals the entity is interacting with + for (Portal portal : portals) { + Portal linked = portal.getLinked(); + if (linked == null) + continue; + if (!portal.entityCollisionArea.contains(entity.position())) + continue; // out of collision area, don't care + relevantPortals.add(portal); + List shapes = VoxelShenanigans.getShapesBehindPortal(level, entity, portal, linked); + if (shapes.isEmpty()) + continue; // all non-solid + // combine collisions + for (VoxelShape collisionShape : shapes) { + shape = Shapes.or(shape, collisionShape); + } + } + // crop the shape to the specific BlockPos + shape = Shapes.join(shape, cubeAtPos, BooleanOp.AND); + // cut portal holes + for (Portal portal : relevantPortals) { + shape = Shapes.join(shape, portal.hole, BooleanOp.ONLY_FIRST); + } + decrementRecursionDepth(entity); + // translate shape back to relative coords, and we're done here + return shape.move(-pos.getX(), -pos.getY(), -pos.getZ()); + } + + // in most cases, this list will have a size of 1 + // in some cases, maybe 2, both on the same surface + // rarer, 3+ + // in weird cases, the surface of each could potentially be different. + // when that happens, prefer nearest. + // returned list of portals is guaranteed to all have the same normal + private List getPortalsToUse(BlockPos pos, Entity entity) { + Set portals = this.portals.getPortalsAt(pos); + if (portals.isEmpty()) { + return List.of(); + } else if (portals.size() == 1) { + return List.of(portals.iterator().next()); + } else { + Map> byNormal = new HashMap<>(); + for (Portal portal : portals) { + byNormal.computeIfAbsent(portal.normal, $ -> new ArrayList<>()).add(portal); + } + if (byNormal.size() == 1) { + for (List list : byNormal.values()) { + return list; + } + throw new IllegalStateException("This should be impossible to reach"); + } else { + // worst case, sort by distance to entity + Vec3 selectedNormal = null; + double closestSqrDist = Double.MAX_VALUE; + for (Map.Entry> entry : byNormal.entrySet()) { + for (Portal portal : entry.getValue()) { + double distSqr = portal.origin.distanceToSqr(entity.position()); + if (distSqr < closestSqrDist) { + closestSqrDist = distSqr; + selectedNormal = entry.getKey(); + } + } + } + return byNormal.get(selectedNormal); + } + } } + @ApiStatus.Internal public void handlePortalLink(Portal a, Portal b) { this.handleNewPortal(a, b); this.handleNewPortal(b, a); } + @ApiStatus.Internal public void handlePortalUnlink(Portal a, Portal b) { this.removePortal(a); this.removePortal(b); @@ -43,7 +142,7 @@ public void handlePortalUnlink(Portal a, Portal b) { private void handleNewPortal(Portal portal, Portal linked) { // iterate through block positions in front of the output portal - BlockPos.betweenClosedStream(linked.collisionArea).forEach(posInFront -> { + BlockPos.betweenClosedStream(linked.collisionCollectionArea).forEach(posInFront -> { BlockState state = level.getBlockState(posInFront); if (state.isAir()) return; // easy skip, don't care @@ -63,6 +162,24 @@ private void handleNewPortal(Portal portal, Portal linked) { } private void removePortal(Portal portal) { - BlockPos.betweenClosedStream(portal.blockCollisionArea).forEach(this.patches::remove); + BlockPos.betweenClosedStream(portal.collisionModificationBox).forEach(this.patches::remove); + } + + private static int getRecursionDepth(Entity entity) { + return ((EntityExt) entity).pc$getPortalCollisionRecursionDepth(); + } + + private static void setRecursionDepth(Entity entity, int depth) { + ((EntityExt) entity).pc$setPortalCollisionRecursionDepth(depth); + } + + private static void incrementRecursionDepth(Entity entity) { + int depth = getRecursionDepth(entity); + setRecursionDepth(entity, depth + 1); + } + + private static void decrementRecursionDepth(Entity entity) { + int depth = getRecursionDepth(entity); + setRecursionDepth(entity, depth - 1); } } diff --git a/src/main/java/io/github/fusionflux/portalcubed/content/portal/manager/PortalManager.java b/src/main/java/io/github/fusionflux/portalcubed/content/portal/manager/PortalManager.java index 5b320160..676685e4 100644 --- a/src/main/java/io/github/fusionflux/portalcubed/content/portal/manager/PortalManager.java +++ b/src/main/java/io/github/fusionflux/portalcubed/content/portal/manager/PortalManager.java @@ -25,6 +25,7 @@ import java.util.stream.Collectors; public abstract class PortalManager { + private final Level level; protected final PortalStorage storage = new SectionPortalStorage(); protected final CollisionManager collisionManager; @@ -33,7 +34,8 @@ public static PortalManager of(Level level) { } public PortalManager(Level level) { - this.collisionManager = new CollisionManager(level); + this.level = level; + this.collisionManager = new CollisionManager(this, level); } public CollisionManager getCollisionManager() { diff --git a/src/main/java/io/github/fusionflux/portalcubed/framework/Aaaa.java b/src/main/java/io/github/fusionflux/portalcubed/framework/Aaaa.java deleted file mode 100644 index 383ffa7c..00000000 --- a/src/main/java/io/github/fusionflux/portalcubed/framework/Aaaa.java +++ /dev/null @@ -1,91 +0,0 @@ -package io.github.fusionflux.portalcubed.framework; - -import io.github.fusionflux.portalcubed.content.portal.Portal; -import io.github.fusionflux.portalcubed.content.portal.PortalTeleportHandler; -import io.github.fusionflux.portalcubed.content.portal.manager.PortalManager; -import io.github.fusionflux.portalcubed.framework.extension.EntityCollisionContextExt; -import io.github.fusionflux.portalcubed.framework.shape.VoxelShenanigans; -import net.minecraft.core.BlockPos; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.BlockGetter; -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.Vec3; -import net.minecraft.world.phys.shapes.BooleanOp; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.EntityCollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; - -import org.apache.commons.lang3.mutable.MutableObject; - -import java.util.Set; - -public class Aaaa { - public static VoxelShape h(VoxelShape shape, BlockGetter world, BlockPos pos, CollisionContext ctx) { - if (world instanceof Level level && ctx instanceof EntityCollisionContext entityCtx) { - EntityCollisionContextExt ctxExt = (EntityCollisionContextExt) entityCtx; - if (ctxExt.pc$doPortalCollision()) { - Entity entity = entityCtx.getEntity(); - if (entity != null) { - PortalManager manager = PortalManager.of(level); - Set portals = manager.getPortalsAt(pos); - if (!portals.isEmpty()) { - // prevent infinite loop - ctxExt.pc$setPortalCollision(false); - - MutableObject shapeHolder = new MutableObject<>(shape); - for (Portal portal : portals) { - Portal linked = portal.getLinked(); - if (linked == null) - continue; - if (!portal.collisionArea.contains(entity.position())) - continue; - // iterate through blocks behind input portal - BlockPos.betweenClosedStream(portal.blockCollisionArea).forEach(posBehindPortal -> { - AABB blockArea = new AABB(posBehindPortal); - // for each block, teleport the bounds to in front of the output - AABB teleported = PortalTeleportHandler.teleportBoxBetween(blockArea, portal, linked); - Vec3 boxCenter = teleported.getCenter(); - // iterate through blocks in the new bounds - // collect and combine bounds - MutableObject combined = new MutableObject<>(Shapes.empty()); - BlockPos.betweenClosedStream(teleported).forEach(posInFront -> { - BlockState state = level.getBlockState(posInFront); - VoxelShape collisionShape = state.getCollisionShape(level, posInFront, ctx); - if (!collisionShape.isEmpty()) { - Vec3 center = Vec3.atCenterOf(posInFront); - Vec3 offset = center.vectorTo(boxCenter); - VoxelShape moved = collisionShape.move(offset.x, offset.y, offset.z); - - VoxelShape existing = combined.getValue(); - VoxelShape merged = Shapes.or(existing, moved); - combined.setValue(merged); - } - }); - VoxelShape merged = combined.getValue(); - if (!merged.isEmpty()) { - // transform collected collision to be behind the input portal - VoxelShape transformed = VoxelShenanigans.rotateShapeBetween(merged, linked, portal); - // limit to 1x1 - VoxelShape bounded = Shapes.join(transformed, Shapes.block(), BooleanOp.AND); - // slight shift into wall to leave surface intact - Vec3 offset = portal.normal.scale(0.01); - VoxelShape shifted = bounded.move(offset.x, offset.y, offset.z); - shapeHolder.setValue(shifted); - } - }); - } - // reset - ctxExt.pc$setPortalCollision(true); - - VoxelShape otherSideCollision = shapeHolder.getValue(); - return otherSideCollision; - } - } - } - } - return shape; - } -} diff --git a/src/main/java/io/github/fusionflux/portalcubed/framework/extension/EntityCollisionContextExt.java b/src/main/java/io/github/fusionflux/portalcubed/framework/extension/EntityCollisionContextExt.java deleted file mode 100644 index 1ff2581f..00000000 --- a/src/main/java/io/github/fusionflux/portalcubed/framework/extension/EntityCollisionContextExt.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.github.fusionflux.portalcubed.framework.extension; - -public interface EntityCollisionContextExt { - boolean pc$doPortalCollision(); - void pc$setPortalCollision(boolean value); -} diff --git a/src/main/java/io/github/fusionflux/portalcubed/framework/extension/EntityExt.java b/src/main/java/io/github/fusionflux/portalcubed/framework/extension/EntityExt.java new file mode 100644 index 00000000..8b1a0ba8 --- /dev/null +++ b/src/main/java/io/github/fusionflux/portalcubed/framework/extension/EntityExt.java @@ -0,0 +1,6 @@ +package io.github.fusionflux.portalcubed.framework.extension; + +public interface EntityExt { + int pc$getPortalCollisionRecursionDepth(); + void pc$setPortalCollisionRecursionDepth(int depth); +} diff --git a/src/main/java/io/github/fusionflux/portalcubed/framework/shape/VoxelShenanigans.java b/src/main/java/io/github/fusionflux/portalcubed/framework/shape/VoxelShenanigans.java index df5f4dd1..3a755c11 100644 --- a/src/main/java/io/github/fusionflux/portalcubed/framework/shape/VoxelShenanigans.java +++ b/src/main/java/io/github/fusionflux/portalcubed/framework/shape/VoxelShenanigans.java @@ -1,12 +1,8 @@ package io.github.fusionflux.portalcubed.framework.shape; -import com.mojang.blaze3d.vertex.VertexConsumer; - import io.github.fusionflux.portalcubed.content.portal.Portal; import io.github.fusionflux.portalcubed.content.portal.PortalTeleportHandler; import io.github.fusionflux.portalcubed.mixin.CubeVoxelShapeAccessor; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.RenderType; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; @@ -85,7 +81,7 @@ public static VoxelShape rotateShapeBetween(VoxelShape shape, Portal a, Portal b } public static List getShapesBehindPortal(Level level, @Nullable Entity entity, Portal portal, Portal linked) { - Iterable shapes = level.getCollisions(entity, linked.collisionArea); + Iterable shapes = level.getCollisions(entity, linked.collisionCollectionArea); List behindPortal = new ArrayList<>(); for (VoxelShape shape : shapes) { // translate to origin diff --git a/src/main/java/io/github/fusionflux/portalcubed/mixin/BlockBehavior$BlockStateBaseMixin.java b/src/main/java/io/github/fusionflux/portalcubed/mixin/BlockBehavior$BlockStateBaseMixin.java index 08a924a3..c3646ba5 100644 --- a/src/main/java/io/github/fusionflux/portalcubed/mixin/BlockBehavior$BlockStateBaseMixin.java +++ b/src/main/java/io/github/fusionflux/portalcubed/mixin/BlockBehavior$BlockStateBaseMixin.java @@ -2,11 +2,7 @@ import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import io.github.fusionflux.portalcubed.content.portal.Portal; -import io.github.fusionflux.portalcubed.content.portal.collision.CollisionManager; -import io.github.fusionflux.portalcubed.content.portal.collision.ShapePatch; import io.github.fusionflux.portalcubed.content.portal.manager.PortalManager; -import io.github.fusionflux.portalcubed.framework.Aaaa; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.BlockGetter; @@ -14,24 +10,13 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.shapes.BooleanOp; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.EntityCollisionContext; -import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -import io.github.fusionflux.portalcubed.framework.shape.VoxelShenanigans; - -import org.apache.commons.lang3.mutable.MutableObject; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.Set; @Mixin(BlockBehaviour.BlockStateBase.class) public abstract class BlockBehavior$BlockStateBaseMixin { @@ -47,13 +32,12 @@ public abstract class BlockBehavior$BlockStateBaseMixin { at = @At("RETURN") ) private VoxelShape quantumSpaceHole(VoxelShape shape, BlockGetter world, BlockPos pos, CollisionContext context) { -// if (world instanceof Level level && context instanceof EntityCollisionContext entityCtx) { -// CollisionManager collisionManager = PortalManager.of(level).getCollisionManager(); -// ShapePatch patch = collisionManager.getPatchAt(pos); -// if (patch != null) { -// patch.apply(shape, entityCtx); -// } -// } + if (world instanceof Level level && context instanceof EntityCollisionContext entityCtx) { + Entity entity = entityCtx.getEntity(); + if (entity != null) { + return PortalManager.of(level).getCollisionManager().getPortalModifiedShape(shape, pos, entity); + } + } return shape; } } diff --git a/src/main/java/io/github/fusionflux/portalcubed/mixin/EntityCollisionContextMixin.java b/src/main/java/io/github/fusionflux/portalcubed/mixin/EntityCollisionContextMixin.java deleted file mode 100644 index 4bd906db..00000000 --- a/src/main/java/io/github/fusionflux/portalcubed/mixin/EntityCollisionContextMixin.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.fusionflux.portalcubed.mixin; - -import io.github.fusionflux.portalcubed.framework.extension.EntityCollisionContextExt; -import net.minecraft.world.phys.shapes.EntityCollisionContext; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -@Mixin(EntityCollisionContext.class) -public class EntityCollisionContextMixin implements EntityCollisionContextExt { - @Unique - private boolean doPortalCollision = true; - - @Override - public boolean pc$doPortalCollision() { - return doPortalCollision; - } - - @Override - public void pc$setPortalCollision(boolean value) { - this.doPortalCollision = value; - } -} diff --git a/src/main/java/io/github/fusionflux/portalcubed/mixin/EntityMixin.java b/src/main/java/io/github/fusionflux/portalcubed/mixin/EntityMixin.java index dd84de00..7e331905 100644 --- a/src/main/java/io/github/fusionflux/portalcubed/mixin/EntityMixin.java +++ b/src/main/java/io/github/fusionflux/portalcubed/mixin/EntityMixin.java @@ -4,6 +4,7 @@ import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import io.github.fusionflux.portalcubed.content.portal.PortalTeleportHandler; +import io.github.fusionflux.portalcubed.framework.extension.EntityExt; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; @@ -14,11 +15,15 @@ import net.minecraft.world.phys.shapes.VoxelShape; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(Entity.class) -public abstract class EntityMixin { +public abstract class EntityMixin implements EntityExt { + @Unique + private int portalCollisionRecursionDepth; + @WrapOperation( method = "move", at = @At( @@ -40,4 +45,14 @@ private void moveThroughPortals(Entity self, double x, double y, double z, Opera private VoxelShape provideEntityContext(BlockState instance, BlockGetter blockGetter, BlockPos blockPos) { return instance.getCollisionShape(blockGetter, blockPos, CollisionContext.of((Entity) (Object) this)); } + + @Override + public int pc$getPortalCollisionRecursionDepth() { + return portalCollisionRecursionDepth; + } + + @Override + public void pc$setPortalCollisionRecursionDepth(int depth) { + this.portalCollisionRecursionDepth = depth; + } } diff --git a/src/main/resources/portalcubed.mixins.json b/src/main/resources/portalcubed.mixins.json index c849ee9e..702b6861 100644 --- a/src/main/resources/portalcubed.mixins.json +++ b/src/main/resources/portalcubed.mixins.json @@ -7,7 +7,6 @@ "BlockBehavior$BlockStateBaseMixin", "ClientboundTeleportEntityPacketMixin", "CubeVoxelShapeAccessor", - "EntityCollisionContextMixin", "EntityMixin", "ServerLevelMixin", "ThrowableProjectileMixin"