mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 08:17:35 +00:00
[1.18.x] Allow blocks to hide faces on a neighboring block (#8300)
* Allow blocks to hide faces on a neighboring block * Allow blocks to opt-out of external face hiding
This commit is contained in:
1 parent
9bf227afeb
commit
57d6f31adb
11 files changed
+271
No files matched your search
@@ -1074,4 +1074,9 @@ public class ForgeHooksClient
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
return event.getResult();
|
||||
}
|
||||
|
||||
public static boolean isBlockInSolidLayer(BlockState state)
|
||||
{
|
||||
return ItemBlockRenderTypes.canRenderInLayer(state, RenderType.solid());
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.common.IPlantable;
|
||||
|
||||
@@ -44,6 +45,7 @@ import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.ToolAction;
|
||||
import net.minecraftforge.common.ToolActions;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public interface IForgeBlock
|
||||
@@ -749,4 +751,43 @@ public interface IForgeBlock
|
||||
return state.isSignalSource() && direction != null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this block hides the neighbors face pointed towards by the given direction.
|
||||
* <p>
|
||||
* This method should only be used for blocks you don't control, for your own blocks override
|
||||
* {@link Block#skipRendering(BlockState, BlockState, Direction)} on the respective block instead
|
||||
* <p>
|
||||
* WARNING: This method is likely to be called from a worker thread! If you want to retrieve a
|
||||
* {@link net.minecraft.world.level.block.entity.BlockEntity} from the given level, make sure to use
|
||||
* {@link net.minecraftforge.common.extensions.IForgeBlockGetter#getExistingBlockEntity(BlockPos)} to not
|
||||
* accidentally create a new or delete an old {@link net.minecraft.world.level.block.entity.BlockEntity}
|
||||
* off of the main thread as this would cause a write operation to the given {@link BlockGetter} and cause
|
||||
* a CME in the process. Any other direct or indirect write operation to the {@link BlockGetter} will have
|
||||
* the same outcome.
|
||||
*
|
||||
* @param level The world
|
||||
* @param pos The blocks position in the world
|
||||
* @param state The blocks {@link BlockState}
|
||||
* @param neighborState The neighboring blocks {@link BlockState}
|
||||
* @param dir The direction towards the neighboring block
|
||||
*/
|
||||
default boolean hidesNeighborFace(BlockGetter level, BlockPos pos, BlockState state, BlockState neighborState, Direction dir)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this block allows a neighboring block to hide the face of this block it touches.
|
||||
* If this returns true, {@link IForgeBlockState#hidesNeighborFace(BlockGetter, BlockPos, BlockState, Direction)}
|
||||
* will be called on the neighboring block.
|
||||
*/
|
||||
default boolean supportsExternalFaceHiding(BlockState state)
|
||||
{
|
||||
if (FMLEnvironment.dist.isClient())
|
||||
{
|
||||
return !ForgeHooksClient.isBlockInSolidLayer(state);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Minecraft Forge - Forge Development LLC
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.extensions;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.chunk.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface IForgeBlockGetter
|
||||
{
|
||||
private BlockGetter self() { return (BlockGetter) this; }
|
||||
|
||||
/**
|
||||
* Get the {@link BlockEntity} at the given position if it exists.
|
||||
* <p>
|
||||
* {@link Level#getBlockEntity(BlockPos)} would create a new {@link BlockEntity} if the
|
||||
* {@link net.minecraft.world.level.block.Block} has one, but it has not been placed in the world yet
|
||||
* (This can happen on world load).
|
||||
* @return The BlockEntity at the given position or null if it doesn't exist
|
||||
*/
|
||||
@Nullable
|
||||
default BlockEntity getExistingBlockEntity(BlockPos pos)
|
||||
{
|
||||
if (this instanceof Level level)
|
||||
{
|
||||
if (!level.hasChunk(pos.getX(), pos.getZ()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return level.getChunk(pos).getExistingBlockEntity(pos);
|
||||
}
|
||||
else if (this instanceof LevelChunk chunk)
|
||||
{
|
||||
return chunk.getBlockEntities().get(pos);
|
||||
}
|
||||
else if (this instanceof ImposterProtoChunk chunk)
|
||||
{
|
||||
return chunk.getWrapped().getExistingBlockEntity(pos);
|
||||
}
|
||||
return self().getBlockEntity(pos);
|
||||
}
|
||||
}
|
||||
@@ -646,4 +646,31 @@ public interface IForgeBlockState
|
||||
{
|
||||
return self().getBlock().canConnectRedstone(self(), level, pos, direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this block hides the neighbors face pointed towards by the given direction.
|
||||
* <p>
|
||||
* This method should only be used for blocks you don't control, for your own blocks override
|
||||
* {@link net.minecraft.world.level.block.Block#skipRendering(BlockState, BlockState, Direction)}
|
||||
* on the respective block instead
|
||||
*
|
||||
* @param level The world
|
||||
* @param pos The blocks position in the world
|
||||
* @param neighborState The neighboring blocks {@link BlockState}
|
||||
* @param dir The direction towards the neighboring block
|
||||
*/
|
||||
default boolean hidesNeighborFace(BlockGetter level, BlockPos pos, BlockState neighborState, Direction dir)
|
||||
{
|
||||
return self().getBlock().hidesNeighborFace(level, pos, self(), neighborState, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this block allows a neighboring block to hide the face of this block it touches.
|
||||
* If this returns true, {@link IForgeBlockState#hidesNeighborFace(BlockGetter, BlockPos, BlockState, Direction)}
|
||||
* will be called on the neighboring block.
|
||||
*/
|
||||
default boolean supportsExternalFaceHiding()
|
||||
{
|
||||
return self().getBlock().supportsExternalFaceHiding(self());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user