]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/interop/SpawnableBlocksHelper.java
Port to 1.19
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / interop / SpawnableBlocksHelper.java
1 package com.irtimaled.bbor.client.interop;
2
3 import com.irtimaled.bbor.common.models.Coords;
4 import net.minecraft.block.Block;
5 import net.minecraft.block.BlockState;
6 import net.minecraft.client.MinecraftClient;
7 import net.minecraft.entity.EntityType;
8 import net.minecraft.entity.SpawnGroup;
9 import net.minecraft.tag.BiomeTags;
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.registry.RegistryEntry;
14 import net.minecraft.util.shape.VoxelShape;
15 import net.minecraft.world.LightType;
16 import net.minecraft.world.World;
17 import net.minecraft.world.biome.Biome;
18 import net.minecraft.world.biome.BiomeKeys;
19
20 public class SpawnableBlocksHelper {
21     private static final EntityType entityType = EntityType.Builder.create(SpawnGroup.MONSTER)
22             .setDimensions(0f, 0f).disableSaving().build(null);
23
24     public static void findSpawnableBlocks(Coords coords, int width, int height, BlockProcessor blockProcessor) {
25         int blockX = coords.getX();
26         int minX = blockX - width;
27         int maxX = blockX + width + 1;
28
29         int blockZ = coords.getZ();
30         int minZ = blockZ - width;
31         int maxZ = blockZ + width + 1;
32
33         int blockY = coords.getY();
34         int minY = Math.max(1, blockY - height);
35         int maxY = Math.min(255, blockY + height);
36
37         World world = MinecraftClient.getInstance().world;
38         for (int x = minX; x < maxX; x++) {
39             for (int z = minZ; z < maxZ; z++) {
40                 BlockState upperBlockState = world.getBlockState(new BlockPos(x, minY - 1, z));
41                 for (int y = Math.max(1, minY); y < maxY; y++) {
42                     BlockState spawnBlockState = upperBlockState;
43                     BlockPos pos = new BlockPos(x, y, z);
44                     upperBlockState = world.getBlockState(pos);
45                     if (isSpawnable(world, pos, spawnBlockState, upperBlockState)) {
46                         blockProcessor.process(pos);
47                     }
48                 }
49             }
50         }
51     }
52
53     static boolean isSpawnable(World world, BlockPos pos, BlockState spawnBlockState, BlockState upperBlockState) {
54         VoxelShape collisionShape = upperBlockState.getCollisionShape(world, pos);
55         RegistryEntry<Biome> entry = world.getBiome(pos);
56         Biome biome = entry.value();
57         boolean isNether = entry.isIn(BiomeTags.IS_NETHER);
58         return entry == BiomeKeys.MUSHROOM_FIELDS &&
59                 spawnBlockState.allowsSpawning(world, pos.down(), isNether ? EntityType.ZOMBIFIED_PIGLIN : entityType) &&
60                 !Block.isFaceFullSquare(collisionShape, Direction.UP) &&
61                 !upperBlockState.emitsRedstonePower() &&
62                 !upperBlockState.isIn(BlockTags.RAILS) &&
63                 collisionShape.getMax(Direction.Axis.Y) <= 0 &&
64                 upperBlockState.getFluidState().isEmpty() &&
65                 (isNether || world.getLightLevel(LightType.BLOCK, pos) <= 7);
66     }
67 }