mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-01-14 16:26:35 +01:00
Connect-a-block
- Properly integrate both copycat blocks and the connected texture system with forge's built-in 'facade' api
This commit is contained in:
parent
f201e26f6b
commit
7b00608744
6 changed files with 179 additions and 126 deletions
|
@ -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<CopycatBlockEntity>, IWrenchable {
|
||||
|
||||
|
@ -244,24 +245,18 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
|
|||
|
||||
// Connected Textures
|
||||
|
||||
@Nullable
|
||||
/**
|
||||
* The wrapped blockstate at toPos. Wrapper guaranteed to be a block of this
|
||||
* type <br>
|
||||
* 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,6 +264,11 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
|
|||
return false;
|
||||
}
|
||||
|
||||
public abstract boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos fromPos, BlockPos toPos,
|
||||
BlockState state);
|
||||
|
||||
//
|
||||
|
||||
public static BlockState getMaterial(BlockGetter reader, BlockPos targetPos) {
|
||||
if (reader.getBlockEntity(targetPos) instanceof CopycatBlockEntity ufte)
|
||||
return ufte.getMaterial();
|
||||
|
|
|
@ -44,13 +44,17 @@ public abstract class CopycatModel extends BakedModelWrapperWithData {
|
|||
|
||||
builder.with(MATERIAL_PROPERTY, material);
|
||||
|
||||
if (!(state.getBlock() instanceof CopycatBlock copycatBlock))
|
||||
return builder;
|
||||
|
||||
OcclusionData occlusionData = new OcclusionData();
|
||||
if (state.getBlock() instanceof CopycatBlock copycatBlock) {
|
||||
gatherOcclusionData(world, pos, state, material, occlusionData, copycatBlock);
|
||||
builder.with(OCCLUSION_PROPERTY, occlusionData);
|
||||
}
|
||||
|
||||
ModelData wrappedData = getModelOf(material).getModelData(world, pos, material, ModelData.EMPTY);
|
||||
ModelData wrappedData = getModelOf(material).getModelData(
|
||||
new FilteredBlockAndTintGetter(world,
|
||||
targetPos -> copycatBlock.canConnectTexturesToward(world, pos, targetPos, state)),
|
||||
pos, material, ModelData.EMPTY);
|
||||
return builder.with(WRAPPED_DATA_PROPERTY, wrappedData);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()))
|
||||
if (!toState.is(this))
|
||||
return true;
|
||||
for (Direction d : Iterate.directions)
|
||||
if (fromPos.relative(d)
|
||||
.equals(toPos) && !canFaceBeOccluded(state, d))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Direction facing = state.getValue(FACING);
|
||||
BlockPos diff = fromPos.subtract(toPos);
|
||||
|
@ -128,6 +86,35 @@ 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)
|
||||
|
|
|
@ -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<BlockPos> filter;
|
||||
|
||||
public FilteredBlockAndTintGetter(BlockAndTintGetter wrapped, Predicate<BlockPos> 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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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,15 +30,16 @@ 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,
|
||||
return connectsTo(state,
|
||||
getCTBlockState(reader, blockState, face.getOpposite(), pos.relative(face), blockingPos), reader, pos,
|
||||
blockingPos, face);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue