diff --git a/client-mod/src/main/java/net/momirealms/craftengine/fabric/CraftEngineFabricMod.java b/client-mod/src/main/java/net/momirealms/craftengine/fabric/CraftEngineFabricMod.java index 1b599bc5d..c83839921 100644 --- a/client-mod/src/main/java/net/momirealms/craftengine/fabric/CraftEngineFabricMod.java +++ b/client-mod/src/main/java/net/momirealms/craftengine/fabric/CraftEngineFabricMod.java @@ -4,6 +4,8 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.block.BlockState; import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.shape.VoxelShape; import net.momirealms.craftengine.fabric.client.config.ModConfig; import net.momirealms.craftengine.fabric.util.BlockUtils; import net.momirealms.craftengine.fabric.util.LoggerFilter; @@ -37,7 +39,8 @@ public class CraftEngineFabricMod implements ModInitializer { BlockState blockState = YamlUtils.createBlockData("minecraft:" + replacedBlockId.getPath()); RegisterBlocks.register( replacedBlockId.getPath() + "_" + i, - BlockUtils.canPassThrough(blockState) + BlockUtils.canPassThrough(blockState), + BlockUtils.getShape(blockState) ); } } diff --git a/client-mod/src/main/java/net/momirealms/craftengine/fabric/util/BlockUtils.java b/client-mod/src/main/java/net/momirealms/craftengine/fabric/util/BlockUtils.java index 3dc205eae..70b6ee011 100644 --- a/client-mod/src/main/java/net/momirealms/craftengine/fabric/util/BlockUtils.java +++ b/client-mod/src/main/java/net/momirealms/craftengine/fabric/util/BlockUtils.java @@ -1,7 +1,12 @@ package net.momirealms.craftengine.fabric.util; import net.minecraft.block.AbstractBlock; +import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -43,4 +48,20 @@ public class BlockUtils { throw new RuntimeException("Failed to access 'collidable' field", e); } } + + + public static VoxelShape getShape(BlockState state) { + if (state == null) return VoxelShapes.fullCube(); + Block block = state.getBlock(); + VoxelShape combinedShape = VoxelShapes.empty(); + try { + for (BlockState possibleState : block.getStateManager().getStates()) { + VoxelShape currentShape = possibleState.getOutlineShape(null, BlockPos.ORIGIN); + combinedShape = VoxelShapes.union(combinedShape, currentShape); + } + return combinedShape.isEmpty() ? VoxelShapes.fullCube() : combinedShape; + } catch (Throwable ignored) { + return VoxelShapes.fullCube(); + } + } } diff --git a/client-mod/src/main/java/net/momirealms/craftengine/fabric/util/RegisterBlocks.java b/client-mod/src/main/java/net/momirealms/craftengine/fabric/util/RegisterBlocks.java index f53152557..33234b3aa 100644 --- a/client-mod/src/main/java/net/momirealms/craftengine/fabric/util/RegisterBlocks.java +++ b/client-mod/src/main/java/net/momirealms/craftengine/fabric/util/RegisterBlocks.java @@ -2,21 +2,33 @@ package net.momirealms.craftengine.fabric.util; import net.minecraft.block.AbstractBlock; import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; import net.momirealms.craftengine.fabric.CraftEngineFabricMod; import java.util.function.Function; public class RegisterBlocks { @SuppressWarnings("UnusedReturnValue") - public static Block register(String name, boolean canPassThrough) { + public static Block register(String name, boolean canPassThrough, VoxelShape outlineShape) { AbstractBlock.Settings settings = Block.Settings.create().nonOpaque().strength(-1.0F, 3600000.0F); - if (canPassThrough) settings.noCollision(); - return register(name, Block::new, settings); + VoxelShape collisionShape; + if (canPassThrough) { + collisionShape = VoxelShapes.empty(); + settings.noCollision(); + } else { + collisionShape = outlineShape; + } + return register(name, (settingsParam) -> new CustomBlock(settingsParam, outlineShape, collisionShape), settings); } public static Block register(String name, Function blockFactory, AbstractBlock.Settings settings) { @@ -31,3 +43,24 @@ public class RegisterBlocks { } } + +class CustomBlock extends Block { + private final VoxelShape outlineShape; + private final VoxelShape collisionShape; + + public CustomBlock(Settings settings, VoxelShape outlineShape, VoxelShape collisionShape) { + super(settings); + this.outlineShape = outlineShape; + this.collisionShape = collisionShape; + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return this.outlineShape; + } + + @Override + public VoxelShape getCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return this.collisionShape; + } +}