1 package com.irtimaled.bbor.client.interop;
3 import com.irtimaled.bbor.common.models.Coords;
4 import com.irtimaled.bbor.mixin.access.IBiome;
5 import net.minecraft.block.Block;
6 import net.minecraft.block.BlockState;
7 import net.minecraft.client.MinecraftClient;
8 import net.minecraft.entity.EntityType;
9 import net.minecraft.entity.SpawnGroup;
10 import net.minecraft.tag.BlockTags;
11 import net.minecraft.util.math.BlockPos;
12 import net.minecraft.util.math.Direction;
13 import net.minecraft.util.shape.VoxelShape;
14 import net.minecraft.world.LightType;
15 import net.minecraft.world.World;
16 import net.minecraft.world.biome.Biome;
18 public class SpawnableBlocksHelper {
19 private static final EntityType entityType = EntityType.Builder.create(SpawnGroup.MONSTER)
20 .setDimensions(0f, 0f).disableSaving().build(null);
22 public static void findSpawnableBlocks(Coords coords, int width, int height, BlockProcessor blockProcessor) {
23 int blockX = coords.getX();
24 int minX = blockX - width;
25 int maxX = blockX + width + 1;
27 int blockZ = coords.getZ();
28 int minZ = blockZ - width;
29 int maxZ = blockZ + width + 1;
31 int blockY = coords.getY();
32 int minY = Math.max(1, blockY - height);
33 int maxY = Math.min(255, blockY + height);
35 World world = MinecraftClient.getInstance().world;
36 for (int x = minX; x < maxX; x++) {
37 for (int z = minZ; z < maxZ; z++) {
38 BlockState upperBlockState = world.getBlockState(new BlockPos(x, minY - 1, z));
39 for (int y = Math.max(1, minY); y < maxY; y++) {
40 BlockState spawnBlockState = upperBlockState;
41 BlockPos pos = new BlockPos(x, y, z);
42 upperBlockState = world.getBlockState(pos);
43 if (isSpawnable(world, pos, spawnBlockState, upperBlockState)) {
44 blockProcessor.process(pos);
51 static boolean isSpawnable(World world, BlockPos pos, BlockState spawnBlockState, BlockState upperBlockState) {
52 VoxelShape collisionShape = upperBlockState.getCollisionShape(world, pos);
53 Biome biome = world.getBiome(pos).value();
54 boolean isNether = ((IBiome) biome).bbor$getCategory() == Biome.Category.NETHER;
55 return ((IBiome) biome).bbor$getCategory() != Biome.Category.MUSHROOM &&
56 spawnBlockState.allowsSpawning(world, pos.down(), isNether ? EntityType.ZOMBIFIED_PIGLIN : entityType) &&
57 !Block.isFaceFullSquare(collisionShape, Direction.UP) &&
58 !upperBlockState.emitsRedstonePower() &&
59 !upperBlockState.isIn(BlockTags.RAILS) &&
60 collisionShape.getMax(Direction.Axis.Y) <= 0 &&
61 upperBlockState.getFluidState().isEmpty() &&
62 (isNether || world.getLightLevel(LightType.BLOCK, pos) <= 7);