Skip to content

Commit

Permalink
Improve cutout impl
Browse files Browse the repository at this point in the history
  • Loading branch information
Gaming32 committed Jun 4, 2023
1 parent eee3b59 commit 9b32938
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 214 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.fusionflux.portalcubed.accessor;

import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockCollisions;
import net.minecraft.world.phys.shapes.VoxelShape;

public interface BlockCollisionsExt {
static Iterable<VoxelShape> wrapBlockCollisions(Iterable<VoxelShape> original, Entity entity) {
final VoxelShape cutout = CalledValues.getPortalCutout(entity);
return () -> ((BlockCollisionsExt)original.iterator()).setPortalCutout(cutout);
}

BlockCollisions setPortalCutout(VoxelShape cutout);
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.fusionflux.portalcubed.mixin;

import com.fusionflux.portalcubed.accessor.BlockCollisionsExt;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockCollisions;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
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;

@Mixin(BlockCollisions.class)
public class BlockCollisionsMixin implements BlockCollisionsExt {
@Unique
private VoxelShape pc$portalCutout = Shapes.empty();

@Override
public BlockCollisions setPortalCutout(VoxelShape cutout) {
pc$portalCutout = cutout;
return (BlockCollisions)(Object)this;
}

@WrapOperation(
method = "computeNext",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/block/state/BlockState;getCollisionShape(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/phys/shapes/CollisionContext;)Lnet/minecraft/world/phys/shapes/VoxelShape;"
)
)
private VoxelShape applyCollisionShape(
BlockState instance, BlockGetter level, BlockPos pos, CollisionContext context,
Operation<VoxelShape> original,
@Local(ordinal = 0) int x, @Local(ordinal = 1) int y, @Local(ordinal = 2) int z
) {
return Shapes.joinUnoptimized(
original.call(instance, level, pos, context),
pc$portalCutout.move(-x, -y, -z),
BooleanOp.ONLY_FIRST
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.fusionflux.portalcubed.mixin;

import com.fusionflux.portalcubed.accessor.BlockCollisionsExt;
import com.fusionflux.portalcubed.accessor.CalledValues;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockCollisions;
import net.minecraft.world.level.CollisionGetter;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;

@Mixin(CollisionGetter.class)
public interface CollisionGetterMixin {
@WrapOperation(
method = "noCollision(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/AABB;)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/CollisionGetter;getBlockCollisions(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/AABB;)Ljava/lang/Iterable;"
)
)
default Iterable<VoxelShape> supportCutout(CollisionGetter instance, Entity entity, AABB collisionBox, Operation<Iterable<VoxelShape>> original) {
return BlockCollisionsExt.wrapBlockCollisions(original.call(instance, entity, collisionBox), entity);
}

@ModifyVariable(
method = "collidesWithSuffocatingBlock",
at = @At("STORE"),
ordinal = 0
)
@SuppressWarnings("InvalidInjectorMethodSignature")
default BlockCollisions supportCutout(BlockCollisions value, @Local Entity entity) {
return ((BlockCollisionsExt)value).setPortalCutout(CalledValues.getPortalCutout(entity));
}
}
79 changes: 33 additions & 46 deletions src/main/java/com/fusionflux/portalcubed/mixin/EntityMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,19 @@

import com.fusionflux.gravity_api.api.GravityChangerAPI;
import com.fusionflux.gravity_api.util.RotationUtil;
import com.fusionflux.portalcubed.accessor.BlockCollisionTrigger;
import com.fusionflux.portalcubed.accessor.CalledValues;
import com.fusionflux.portalcubed.accessor.ClientTeleportCheck;
import com.fusionflux.portalcubed.accessor.EntityPortalsAccess;
import com.fusionflux.portalcubed.accessor.*;
import com.fusionflux.portalcubed.blocks.PortalCubedBlocks;
import com.fusionflux.portalcubed.client.packet.PortalCubedClientPackets;
import com.fusionflux.portalcubed.compat.rayon.RayonIntegration;
import com.fusionflux.portalcubed.entity.CorePhysicsEntity;
import com.fusionflux.portalcubed.entity.EntityAttachments;
import com.fusionflux.portalcubed.entity.ExperimentalPortal;
import com.fusionflux.portalcubed.entity.GelBlobEntity;
import com.fusionflux.portalcubed.listeners.CustomCollisionView;
import com.fusionflux.portalcubed.listeners.WentThroughPortalListener;
import com.fusionflux.portalcubed.mechanics.CrossPortalInteraction;
import com.fusionflux.portalcubed.util.IPQuaternion;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.FriendlyByteBuf;
Expand All @@ -26,7 +24,6 @@
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Level;
Expand All @@ -35,22 +32,20 @@
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec2;
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.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;
import org.quiltmc.qsl.networking.api.PacketByteBufs;
import org.quiltmc.qsl.networking.api.ServerPlayNetworking;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArgs;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.invoke.arg.Args;

import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -433,47 +428,39 @@ public int getGelTimer() {
return this.gelTransferTimer;
}


@ModifyArgs(
method = "collideBoundingBox",
at = @At(
target = "Lcom/google/common/collect/ImmutableList$Builder;addAll(Ljava/lang/Iterable;)Lcom/google/common/collect/ImmutableList$Builder;",
value = "INVOKE",
ordinal = 1,
remap = false
)
@WrapOperation(
method = "collideBoundingBox",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/Level;getBlockCollisions(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/AABB;)Ljava/lang/Iterable;"
)
)
private static void addAllModifyArg(Args args, @Nullable Entity entity, Vec3 movement, AABB entityBoundingBox, Level world, List<VoxelShape> collisions) {
VoxelShape portalBox = CalledValues.getPortalCutout(entity);
if (portalBox != Shapes.empty())
args.set(0, ((CustomCollisionView) world).getPortalBlockCollisions(entity, entityBoundingBox.expandTowards(movement), portalBox));
}

@Inject(method = "isFree(Lnet/minecraft/world/phys/AABB;)Z", at = @At("RETURN"), cancellable = true)
private void doesNotCollide(AABB box, CallbackInfoReturnable<Boolean> cir) {
VoxelShape portalBox = CalledValues.getPortalCutout(((Entity) (Object) this));
if (portalBox != Shapes.empty())
cir.setReturnValue(true);
private static Iterable<VoxelShape> supportCutout(Level instance, Entity entity, AABB collisionBox, Operation<Iterable<VoxelShape>> original) {
return BlockCollisionsExt.wrapBlockCollisions(original.call(instance, entity, collisionBox), entity);
}

@Inject(method = "canEnterPose", at = @At("RETURN"), cancellable = true)
public void wouldPoseNotCollide(Pose pose, CallbackInfoReturnable<Boolean> cir) {
VoxelShape portalBox = CalledValues.getPortalCutout(((Entity) (Object) this));
if (portalBox != Shapes.empty())
cir.setReturnValue(true);
}

@Inject(method = "isInWall", at = @At("HEAD"), cancellable = true)
public void isInsideWall(CallbackInfoReturnable<Boolean> cir) {
VoxelShape portalBox = CalledValues.getPortalCutout(((Entity) (Object) this));
if (portalBox != Shapes.empty()) cir.setReturnValue(false);
@ModifyArg(
method = "method_30022",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/phys/shapes/Shapes;joinIsNotEmpty(Lnet/minecraft/world/phys/shapes/VoxelShape;Lnet/minecraft/world/phys/shapes/VoxelShape;Lnet/minecraft/world/phys/shapes/BooleanOp;)Z"
),
index = 0
)
private VoxelShape cutoutForIsInWall(VoxelShape shape) {
return Shapes.joinUnoptimized(shape, CalledValues.getPortalCutout(((Entity)(Object)this)), BooleanOp.ONLY_FIRST);
}

@Inject(method = "isColliding", at = @At("HEAD"), cancellable = true)
public void collidesWithStateAtPos(BlockPos pos, BlockState state, CallbackInfoReturnable<Boolean> cir) {
VoxelShape portalBox = CalledValues.getPortalCutout(((Entity) (Object) this));
if (portalBox != Shapes.empty())
cir.setReturnValue(false);
@ModifyArg(
method = "isColliding",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/phys/shapes/Shapes;joinIsNotEmpty(Lnet/minecraft/world/phys/shapes/VoxelShape;Lnet/minecraft/world/phys/shapes/VoxelShape;Lnet/minecraft/world/phys/shapes/BooleanOp;)Z"
),
index = 0
)
private VoxelShape cutoutForIsColliding(VoxelShape shape) {
return Shapes.joinUnoptimized(shape, CalledValues.getPortalCutout(((Entity)(Object)this)), BooleanOp.ONLY_FIRST);
}

@Inject(method = "checkInsideBlocks", at = @At("HEAD"))
Expand Down

This file was deleted.

Loading

0 comments on commit 9b32938

Please sign in to comment.