diff --git a/common/src/main/java/com/copycatsplus/copycats/foundation/copycat/ICopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/foundation/copycat/ICopycatBlock.java index 199b0aaa1..6c7ef5366 100644 --- a/common/src/main/java/com/copycatsplus/copycats/foundation/copycat/ICopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/foundation/copycat/ICopycatBlock.java @@ -37,7 +37,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.*; import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; import net.neoforged.neoforge.common.Tags; @@ -46,7 +45,6 @@ import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; -import java.util.Optional; import java.util.stream.IntStream; import static net.minecraft.world.level.block.state.properties.BlockStateProperties.*; @@ -76,7 +74,7 @@ */ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public interface ICopycatBlock extends IWrenchable, IStateType, TransformableBlock { +public interface ICopycatBlock extends IWrenchable, IStateType, TransformableBlock, ICopycatCullable { @Nullable default ICopycatBlockEntity getCopycatBlockEntity(BlockGetter worldIn, BlockPos pos) { @@ -566,37 +564,6 @@ default boolean checkConnection(BlockAndTintGetter reader, BlockPos fromPos, Blo } } - /** - * Whether this copycat can occlude faces of adjacent blocks if their shape is fully covered by the copycat. - * - * @param level The world. - * @param state The state of the copycat block. - * @param pos The position of the copycat block. - * @return Whether the copycat can occlude faces of adjacent blocks. - */ - default boolean canOcclude(BlockGetter level, BlockState state, BlockPos pos) { - BlockState material = getMaterial(level, pos); - if (AllBlocks.COPYCAT_BASE.has(material)) return false; // copycat_base is incorrectly set to occlude - return material.canOcclude(); - } - - /** - * Whether the shape of this copycat can occlude the face of an adjacent block. - *

- * Implementations of this method should not consider occlusion criteria that are based on the material of the copycat. - * Only properties intrinsic to the copycat block, such as its shape, should be considered. - * - * @param level The world. - * @param pos The position of the copycat block. - * @param state The state of the copycat block. - * @param neighborPos The position of the adjacent block. - * @param dir The direction from the copycat block to the adjacent block. - * @return Whether the shape of the copycat can occlude the face of the adjacent block. If empty, the vanilla occlusion logic is used. - */ - default Optional shapeCanOccludeNeighbor(BlockGetter level, BlockPos pos, BlockState state, BlockPos neighborPos, Direction dir) { - return Optional.empty(); - } - /** * Whether this copycat can hide the face of an adjacent block. *

diff --git a/common/src/main/java/com/copycatsplus/copycats/foundation/copycat/ICopycatCullable.java b/common/src/main/java/com/copycatsplus/copycats/foundation/copycat/ICopycatCullable.java new file mode 100644 index 000000000..e0023f3f0 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/foundation/copycat/ICopycatCullable.java @@ -0,0 +1,42 @@ +package com.copycatsplus.copycats.foundation.copycat; + +import com.simibubi.create.AllBlocks; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.Optional; + +public interface ICopycatCullable { + /** + * Whether this copycat can occlude faces of adjacent blocks if their shape is fully covered by the copycat. + * + * @param level The world. + * @param state The state of the copycat block. + * @param pos The position of the copycat block. + * @return Whether the copycat can occlude faces of adjacent blocks. + */ + default boolean canOcclude(BlockGetter level, BlockState state, BlockPos pos) { + BlockState material = ICopycatBlock.getMaterial(level, pos); + if (AllBlocks.COPYCAT_BASE.has(material)) return false; // copycat_base is incorrectly set to occlude + return material.canOcclude(); + } + + /** + * Whether the shape of this copycat can occlude the face of an adjacent block. + *

+ * Implementations of this method should not consider occlusion criteria that are based on the material of the copycat. + * Only properties intrinsic to the copycat block, such as its shape, should be considered. + * + * @param level The world. + * @param pos The position of the copycat block. + * @param state The state of the copycat block. + * @param neighborPos The position of the adjacent block. + * @param dir The direction from the copycat block to the adjacent block. + * @return Whether the shape of the copycat can occlude the face of the adjacent block. If empty, the vanilla occlusion logic is used. + */ + default Optional shapeCanOccludeNeighbor(BlockGetter level, BlockPos pos, BlockState state, BlockPos neighborPos, Direction dir) { + return Optional.empty(); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockOcclusionCacheMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockOcclusionCacheMixin.java deleted file mode 100644 index bb93900fc..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockOcclusionCacheMixin.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.copycatsplus.copycats.mixin.compat.rubidium; - -import com.copycatsplus.copycats.compat.Mods; -import com.copycatsplus.copycats.foundation.annotation.ModMixin; -import com.copycatsplus.copycats.foundation.copycat.ICopycatBlock; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -/** - * Makes sure that copycat blocks are not occluded by Rubidium - */ -@ModMixin(requiredMods = Mods.SODIUM) -@Mixin(targets = "net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.BlockOcclusionCache") -@Pseudo -public class BlockOcclusionCacheMixin { - - //FIXME: Needs to be done more specifically. Or preferably without stopping their culling on us full stop - // but right now nothing i've tried seems to be working that makes sense - // Also need to investigate if this patch is required for Forge, since CopycatModelForge already has a workaround - @Inject(method = "shouldDrawSide", at = @At("HEAD"), cancellable = true, require = 0) - private void copycats$stopCullingUs(BlockState selfState, BlockGetter view, BlockPos pos, Direction facing, CallbackInfoReturnable cir) { - if (selfState.getBlock() instanceof ICopycatBlock) { - cir.setReturnValue(true); - } - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/sodium/BlockOcclusionCacheMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/sodium/BlockOcclusionCacheMixin.java new file mode 100644 index 000000000..7828e4e26 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/sodium/BlockOcclusionCacheMixin.java @@ -0,0 +1,42 @@ +package com.copycatsplus.copycats.mixin.compat.sodium; + +import com.copycatsplus.copycats.compat.Mods; +import com.copycatsplus.copycats.foundation.annotation.ModMixin; +import com.copycatsplus.copycats.foundation.copycat.ICopycatCullable; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; +import com.simibubi.create.AllBlocks; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.injection.At; + +/** + * Makes sure that copycat blocks are not occluded by Rubidium + */ +@ModMixin(requiredMods = Mods.SODIUM) +@Mixin(targets = "net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.BlockOcclusionCache") +@Pseudo +public class BlockOcclusionCacheMixin { + @WrapOperation( + method = "shouldDrawSide", + at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;canOcclude()Z") + ) + private boolean canCopycatOcclude(BlockState instance, Operation original, + @Local(argsOnly = true) BlockGetter level, + @Local BlockPos.MutableBlockPos otherPos) { + if (AllBlocks.COPYCAT_BASE.has(instance)) { + return false; + } + Block block = instance.getBlock(); + if (block instanceof ICopycatCullable copycatBlock) { + // IMultiStateCopycatBlock always returns false + return copycatBlock.canOcclude(level, instance, otherPos); + } + return original.call(instance); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockRendererMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/sodium/BlockRendererMixin.java similarity index 97% rename from common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockRendererMixin.java rename to common/src/main/java/com/copycatsplus/copycats/mixin/compat/sodium/BlockRendererMixin.java index d524604c5..0f33415f2 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockRendererMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/sodium/BlockRendererMixin.java @@ -1,4 +1,4 @@ -package com.copycatsplus.copycats.mixin.compat.rubidium; +package com.copycatsplus.copycats.mixin.compat.sodium; import com.copycatsplus.copycats.compat.Mods; import com.copycatsplus.copycats.foundation.annotation.ModMixin; diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/foundation/copycat/BlockMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/foundation/copycat/BlockMixin.java index 576c1a856..597966730 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/foundation/copycat/BlockMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/foundation/copycat/BlockMixin.java @@ -1,9 +1,11 @@ package com.copycatsplus.copycats.mixin.foundation.copycat; -import com.copycatsplus.copycats.foundation.copycat.ICopycatBlock; +import com.copycatsplus.copycats.foundation.copycat.ICopycatCullable; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.decoration.bracket.BracketBlock; import net.minecraft.core.BlockPos; @@ -29,6 +31,7 @@ public class BlockMixin { ) private static boolean canCopycatOcclude(BlockState instance, Operation original, + @Share("copycat$blockState") LocalRef stateRef, @Local(argsOnly = true) BlockGetter level, @Local(argsOnly = true, ordinal = 1) BlockPos pos) { if (AllBlocks.COPYCAT_BASE.has(instance)) { @@ -37,8 +40,12 @@ private static boolean canCopycatOcclude(BlockState instance, if (instance.getBlock() instanceof BracketBlock) { return false; } - if (instance.getBlock() instanceof ICopycatBlock copycatBlock) { - return copycatBlock.canOcclude(level, instance, pos); + if (instance.getBlock() instanceof ICopycatCullable copycatBlock) { + if (copycatBlock.canOcclude(level, instance, pos)) { + stateRef.set(instance); + return true; + } + return false; } return original.call(instance); } @@ -48,9 +55,10 @@ private static boolean canCopycatOcclude(BlockState instance, at = @At(value = "NEW", target = "net/minecraft/world/level/block/Block$BlockStatePairKey"), cancellable = true ) - private static void calculateOcclusionShape(BlockState state, BlockGetter level, BlockPos offset, Direction face, BlockPos pos, CallbackInfoReturnable cir) { - BlockState blockState = level.getBlockState(pos); - if (blockState.getBlock() instanceof ICopycatBlock copycatBlock) { + private static void calculateOcclusionShape(BlockState state, BlockGetter level, BlockPos offset, Direction face, BlockPos pos, + CallbackInfoReturnable cir, @Share("copycat$blockState") LocalRef stateRef) { + BlockState blockState = stateRef.get(); + if (blockState != null && blockState.getBlock() instanceof ICopycatCullable copycatBlock) { Optional result = copycatBlock.shapeCanOccludeNeighbor(level, pos, blockState, offset, face.getOpposite()).map(b -> !b); result.ifPresent(cir::setReturnValue); } diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/foundation/copycat/BlockStateBaseCacheMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/foundation/copycat/BlockStateBaseCacheMixin.java index b10852d4d..673ec2e0c 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/foundation/copycat/BlockStateBaseCacheMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/foundation/copycat/BlockStateBaseCacheMixin.java @@ -1,7 +1,7 @@ package com.copycatsplus.copycats.mixin.foundation.copycat; import com.copycatsplus.copycats.compat.Mods; -import com.copycatsplus.copycats.foundation.copycat.ICopycatBlock; +import com.copycatsplus.copycats.foundation.copycat.ICopycatCullable; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.simibubi.create.content.decoration.bracket.BracketBlock; @@ -36,7 +36,7 @@ private boolean canCopycatOcclude(BlockState instance, if (instance.getBlock() instanceof BracketBlock) { return false; } - if (instance.getBlock() instanceof ICopycatBlock) { + if (instance.getBlock() instanceof ICopycatCullable) { return true; } return original.call(instance); diff --git a/common/src/main/resources/copycats-common.mixins.json b/common/src/main/resources/copycats-common.mixins.json index 7b87b8682..ced4d5f5f 100644 --- a/common/src/main/resources/copycats-common.mixins.json +++ b/common/src/main/resources/copycats-common.mixins.json @@ -7,8 +7,8 @@ "mixins": [ "compat.diagonalblocks.DiagonalBlockTypeImplMixin", "compat.radium.PathNodeDefaultsMixin", - "compat.rubidium.BlockOcclusionCacheMixin", - "compat.rubidium.BlockRendererMixin", + "compat.sodium.BlockOcclusionCacheMixin", + "compat.sodium.BlockRendererMixin", "compat.verticalslabcompat.CutBlockTypeRegistryMixin", "copycat.SyncedBlockEntityMixin", "copycat.VoxelShapeAccessor",