Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.*;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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.
* <p>
* 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<Boolean> 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.
* <p>
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
* <p>
* 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<Boolean> shapeCanOccludeNeighbor(BlockGetter level, BlockPos pos, BlockState state, BlockPos neighborPos, Direction dir) {
return Optional.empty();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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<Boolean> 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);
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -29,6 +31,7 @@ public class BlockMixin {
)
private static boolean canCopycatOcclude(BlockState instance,
Operation<Boolean> original,
@Share("copycat$blockState") LocalRef<BlockState> stateRef,
@Local(argsOnly = true) BlockGetter level,
@Local(argsOnly = true, ordinal = 1) BlockPos pos) {
if (AllBlocks.COPYCAT_BASE.has(instance)) {
Expand All @@ -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);
}
Expand All @@ -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<Boolean> 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<Boolean> cir, @Share("copycat$blockState") LocalRef<BlockState> stateRef) {
BlockState blockState = stateRef.get();
if (blockState != null && blockState.getBlock() instanceof ICopycatCullable copycatBlock) {
Optional<Boolean> result = copycatBlock.shapeCanOccludeNeighbor(level, pos, blockState, offset, face.getOpposite()).map(b -> !b);
result.ifPresent(cir::setReturnValue);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions common/src/main/resources/copycats-common.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down