From 7b00608744a7de343621ee3e8fa6c30851f64f69 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue, 9 May 2023 17:40:55 +0200 Subject: [PATCH] Connect-a-block - Properly integrate both copycat blocks and the connected texture system with forge's built-in 'facade' api --- .../curiosities/frames/CopycatBlock.java | 40 +++++----- .../curiosities/frames/CopycatModel.java | 16 ++-- .../curiosities/frames/CopycatPanelBlock.java | 53 ++++++------- .../curiosities/frames/CopycatStepBlock.java | 77 ++++++++----------- .../frames/FilteredBlockAndTintGetter.java | 74 ++++++++++++++++++ .../connected/ConnectedTextureBehaviour.java | 45 +++++------ 6 files changed, 179 insertions(+), 126 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/curiosities/frames/FilteredBlockAndTintGetter.java diff --git a/src/main/java/com/simibubi/create/content/curiosities/frames/CopycatBlock.java b/src/main/java/com/simibubi/create/content/curiosities/frames/CopycatBlock.java index 1d28699c9..9e1647a10 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/frames/CopycatBlock.java +++ b/src/main/java/com/simibubi/create/content/curiosities/frames/CopycatBlock.java @@ -48,6 +48,7 @@ import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.model.data.ModelDataManager; public abstract class CopycatBlock extends Block implements IBE, IWrenchable { @@ -161,7 +162,7 @@ public abstract class CopycatBlock extends Block implements IBE - * Return null if the 'from' state shouldn't connect to this block/face - * - * @param from - * @param reader - * @param targetPos - * @param face - * @return - */ - public abstract BlockState getConnectiveMaterial(BlockAndTintGetter reader, BlockState otherState, Direction face, - BlockPos fromPos, BlockPos toPos); + @Override + @OnlyIn(Dist.CLIENT) + public BlockState getAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, + BlockState queryState, BlockPos queryPos) { - public boolean isUnblockableConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, - BlockPos fromPos, BlockPos toPos) { - return false; + if (isIgnoredConnectivitySide(level, state, side, pos, queryPos)) + return state; + + ModelDataManager modelDataManager = level.getModelDataManager(); + if (modelDataManager == null) + return getMaterial(level, pos); + return CopycatModel.getMaterial(modelDataManager.getAt(pos)); } public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, @@ -269,8 +264,13 @@ public abstract class CopycatBlock extends Block implements IBE copycatBlock.canConnectTexturesToward(world, pos, targetPos, state)), + pos, material, ModelData.EMPTY); return builder.with(WRAPPED_DATA_PROPERTY, wrappedData); } diff --git a/src/main/java/com/simibubi/create/content/curiosities/frames/CopycatPanelBlock.java b/src/main/java/com/simibubi/create/content/curiosities/frames/CopycatPanelBlock.java index 4a1d07672..31e7d33f2 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/frames/CopycatPanelBlock.java +++ b/src/main/java/com/simibubi/create/content/curiosities/frames/CopycatPanelBlock.java @@ -88,12 +88,6 @@ public class CopycatPanelBlock extends WaterloggedCopycatBlock { return super.use(state, world, pos, player, hand, ray); } - @Override - public boolean isUnblockableConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, - BlockPos fromPos, BlockPos toPos) { - return true; - } - @Override public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, BlockPos fromPos, BlockPos toPos) { @@ -112,6 +106,31 @@ public class CopycatPanelBlock extends WaterloggedCopycatBlock { .getStep()); } + @Override + public boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos fromPos, BlockPos toPos, + BlockState state) { + Direction facing = state.getValue(FACING); + BlockState toState = reader.getBlockState(toPos); + + if (toPos.equals(fromPos.relative(facing))) + return false; + + BlockPos diff = fromPos.subtract(toPos); + int coord = facing.getAxis() + .choose(diff.getX(), diff.getY(), diff.getZ()); + + if (!toState.is(this)) + return coord != -facing.getAxisDirection() + .getStep(); + + if (isOccluded(state, toState, facing)) + return true; + if (toState.setValue(WATERLOGGED, false) == state.setValue(WATERLOGGED, false) && coord == 0) + return true; + + return false; + } + @Override public boolean canFaceBeOccluded(BlockState state, Direction face) { return state.getValue(FACING) @@ -123,28 +142,6 @@ public class CopycatPanelBlock extends WaterloggedCopycatBlock { return canFaceBeOccluded(state, face.getOpposite()); } - @Override - public BlockState getConnectiveMaterial(BlockAndTintGetter reader, BlockState otherState, Direction face, - BlockPos fromPos, BlockPos toPos) { - BlockState panelState = reader.getBlockState(toPos); - Direction facing = panelState.getValue(FACING); - - if (!otherState.is(this)) - return facing == face.getOpposite() ? getMaterial(reader, toPos) : null; - - if (isOccluded(panelState, otherState, facing)) - return getMaterial(reader, toPos); - - BlockPos diff = fromPos.subtract(toPos); - int coord = facing.getAxis() - .choose(diff.getX(), diff.getY(), diff.getZ()); - - if (otherState.setValue(WATERLOGGED, false) == panelState.setValue(WATERLOGGED, false) && coord == 0) - return getMaterial(reader, toPos); - - return null; - } - @Override public BlockState getStateForPlacement(BlockPlaceContext pContext) { BlockState stateForPlacement = super.getStateForPlacement(pContext); diff --git a/src/main/java/com/simibubi/create/content/curiosities/frames/CopycatStepBlock.java b/src/main/java/com/simibubi/create/content/curiosities/frames/CopycatStepBlock.java index 375aa4061..4ac193e9f 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/frames/CopycatStepBlock.java +++ b/src/main/java/com/simibubi/create/content/curiosities/frames/CopycatStepBlock.java @@ -4,7 +4,6 @@ import java.util.function.Predicate; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; -import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.VoxelShaper; import com.simibubi.create.foundation.utility.placement.IPlacementHelper; import com.simibubi.create.foundation.utility.placement.PlacementHelpers; @@ -64,54 +63,13 @@ public class CopycatStepBlock extends WaterloggedCopycatBlock { return super.use(state, world, pos, player, hand, ray); } - @Override - public BlockState getConnectiveMaterial(BlockAndTintGetter reader, BlockState otherState, Direction face, - BlockPos fromPos, BlockPos toPos) { - if (!otherState.is(this)) - return null; - - BlockState stepState = reader.getBlockState(toPos); - Direction facing = stepState.getValue(FACING); - BlockPos diff = fromPos.subtract(toPos); - - if (diff.getY() != 0) { - if (isOccluded(stepState, otherState, diff.getY() > 0 ? Direction.UP : Direction.DOWN)) - return getMaterial(reader, toPos); - return null; - } - - if (isOccluded(stepState, otherState, facing)) - return getMaterial(reader, toPos); - - int coord = facing.getAxis() - .choose(diff.getX(), diff.getY(), diff.getZ()); - - if (otherState.setValue(WATERLOGGED, false) == stepState.setValue(WATERLOGGED, false) && coord == 0) - return getMaterial(reader, toPos); - - return null; - } - - @Override - public boolean isUnblockableConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, - BlockPos fromPos, BlockPos toPos) { - return true; - } - @Override public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, BlockPos fromPos, BlockPos toPos) { BlockState toState = reader.getBlockState(toPos); - if (!toState.is(this)) { - if (!canFaceBeOccluded(state, face.getOpposite())) - return true; - for (Direction d : Iterate.directions) - if (fromPos.relative(d) - .equals(toPos) && !canFaceBeOccluded(state, d)) - return true; - return false; - } + if (!toState.is(this)) + return true; Direction facing = state.getValue(FACING); BlockPos diff = fromPos.subtract(toPos); @@ -128,13 +86,42 @@ public class CopycatStepBlock extends WaterloggedCopycatBlock { .getStep()); } + @Override + public boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos fromPos, BlockPos toPos, + BlockState state) { + Direction facing = state.getValue(FACING); + BlockState toState = reader.getBlockState(toPos); + BlockPos diff = fromPos.subtract(toPos); + + if (fromPos.equals(toPos.relative(facing))) + return false; + if (!toState.is(this)) + return false; + + if (diff.getY() != 0) { + if (isOccluded(toState, state, diff.getY() > 0 ? Direction.UP : Direction.DOWN)) + return true; + return false; + } + + if (isOccluded(state, toState, facing)) + return true; + + int coord = facing.getAxis() + .choose(diff.getX(), diff.getY(), diff.getZ()); + if (state.setValue(WATERLOGGED, false) == toState.setValue(WATERLOGGED, false) && coord == 0) + return true; + + return false; + } + @Override public boolean canFaceBeOccluded(BlockState state, Direction face) { if (face.getAxis() == Axis.Y) return (state.getValue(HALF) == Half.TOP) == (face == Direction.UP); return state.getValue(FACING) == face; } - + @Override public boolean shouldFaceAlwaysRender(BlockState state, Direction face) { return canFaceBeOccluded(state, face.getOpposite()); diff --git a/src/main/java/com/simibubi/create/content/curiosities/frames/FilteredBlockAndTintGetter.java b/src/main/java/com/simibubi/create/content/curiosities/frames/FilteredBlockAndTintGetter.java new file mode 100644 index 000000000..6649f06bf --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/frames/FilteredBlockAndTintGetter.java @@ -0,0 +1,74 @@ +package com.simibubi.create.content.curiosities.frames; + +import java.util.function.Predicate; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.ColorResolver; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraftforge.client.model.data.ModelDataManager; + +public class FilteredBlockAndTintGetter implements BlockAndTintGetter { + + private BlockAndTintGetter wrapped; + private Predicate filter; + + public FilteredBlockAndTintGetter(BlockAndTintGetter wrapped, Predicate filter) { + this.wrapped = wrapped; + this.filter = filter; + } + + @Override + public BlockEntity getBlockEntity(BlockPos pPos) { + return filter.test(pPos) ? wrapped.getBlockEntity(pPos) : null; + } + + @Override + public BlockState getBlockState(BlockPos pPos) { + return filter.test(pPos) ? wrapped.getBlockState(pPos) : Blocks.AIR.defaultBlockState(); + } + + @Override + public FluidState getFluidState(BlockPos pPos) { + return filter.test(pPos) ? wrapped.getFluidState(pPos) : Fluids.EMPTY.defaultFluidState(); + } + + @Override + public int getHeight() { + return wrapped.getHeight(); + } + + @Override + public int getMinBuildHeight() { + return wrapped.getMinBuildHeight(); + } + + @Override + public float getShade(Direction pDirection, boolean pShade) { + return wrapped.getShade(pDirection, pShade); + } + + @Override + public LevelLightEngine getLightEngine() { + return wrapped.getLightEngine(); + } + + @Override + public int getBlockTint(BlockPos pBlockPos, ColorResolver pColorResolver) { + return wrapped.getBlockTint(pBlockPos, pColorResolver); + } + + @Override + public @Nullable ModelDataManager getModelDataManager() { + return wrapped.getModelDataManager(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/block/connected/ConnectedTextureBehaviour.java b/src/main/java/com/simibubi/create/foundation/block/connected/ConnectedTextureBehaviour.java index 19ab70b89..14ddabc41 100644 --- a/src/main/java/com/simibubi/create/foundation/block/connected/ConnectedTextureBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/block/connected/ConnectedTextureBehaviour.java @@ -3,14 +3,13 @@ package com.simibubi.create.foundation.block.connected; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import com.simibubi.create.content.curiosities.frames.CopycatBlock; - import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.AxisDirection; import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; public abstract class ConnectedTextureBehaviour { @@ -31,17 +30,18 @@ public abstract class ConnectedTextureBehaviour { Direction face) { BlockPos blockingPos = otherPos.relative(face); BlockState blockState = reader.getBlockState(pos); + BlockState blockingState = reader.getBlockState(blockingPos); - if (blockState.getBlock() instanceof CopycatBlock ufb - && ufb.isUnblockableConnectivitySide(reader, blockState, face, pos, otherPos)) + if (!Block.isFaceFull(blockingState.getShape(reader, blockingPos), face.getOpposite())) + return false; + if (face.getAxis() + .choose(pos.getX(), pos.getY(), pos.getZ()) != face.getAxis() + .choose(otherPos.getX(), otherPos.getY(), otherPos.getZ())) return false; - return face.getAxis() - .choose(pos.getX(), pos.getY(), pos.getZ()) == face.getAxis() - .choose(otherPos.getX(), otherPos.getY(), otherPos.getZ()) - && connectsTo(state, - getCTBlockState(reader, blockState, face.getOpposite(), pos.relative(face), blockingPos), reader, pos, - blockingPos, face); + return connectsTo(state, + getCTBlockState(reader, blockState, face.getOpposite(), pos.relative(face), blockingPos), reader, pos, + blockingPos, face); } public boolean connectsTo(BlockState state, BlockState other, BlockAndTintGetter reader, BlockPos pos, @@ -54,17 +54,14 @@ public abstract class ConnectedTextureBehaviour { return !isBeingBlocked(state, reader, pos, otherPos, face) && state.getBlock() == other.getBlock(); } - private boolean testConnection(BlockAndTintGetter reader, BlockPos pos, BlockState state, Direction face, - final Direction horizontal, final Direction vertical, int sh, int sv) { - BlockPos p = pos.relative(horizontal, sh) + private boolean testConnection(BlockAndTintGetter reader, BlockPos currentPos, BlockState connectiveCurrentState, + Direction textureSide, final Direction horizontal, final Direction vertical, int sh, int sv) { + BlockState trueCurrentState = reader.getBlockState(currentPos); + BlockPos targetPos = currentPos.relative(horizontal, sh) .relative(vertical, sv); - BlockState blockState = reader.getBlockState(pos); - - if (blockState.getBlock() instanceof CopycatBlock ufb - && ufb.isIgnoredConnectivitySide(reader, blockState, face, pos, p)) - return false; - - return connectsTo(state, getCTBlockState(reader, blockState, face, pos, p), reader, pos, p, face, + BlockState connectiveTargetState = + getCTBlockState(reader, trueCurrentState, textureSide, currentPos, targetPos); + return connectsTo(connectiveCurrentState, connectiveTargetState, reader, currentPos, targetPos, textureSide, sh == 0 ? null : sh == -1 ? horizontal.getOpposite() : horizontal, sv == 0 ? null : sv == -1 ? vertical.getOpposite() : vertical); } @@ -72,13 +69,7 @@ public abstract class ConnectedTextureBehaviour { public BlockState getCTBlockState(BlockAndTintGetter reader, BlockState reference, Direction face, BlockPos fromPos, BlockPos toPos) { BlockState blockState = reader.getBlockState(toPos); - - if (blockState.getBlock() instanceof CopycatBlock ufb) { - BlockState connectiveMaterial = ufb.getConnectiveMaterial(reader, reference, face, fromPos, toPos); - return connectiveMaterial == null ? blockState : connectiveMaterial; - } - - return blockState; + return blockState.getAppearance(reader, toPos, face, reference, fromPos); } protected boolean reverseUVs(BlockState state, Direction face) {