]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/interop/SpawnableBlocksHelper.java
Upgrade to 1.14.2
[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.Minecraft;
7 import net.minecraft.entity.EntityClassification;
8 import net.minecraft.entity.EntityType;
9 import net.minecraft.tags.BlockTags;
10 import net.minecraft.util.Direction;
11 import net.minecraft.util.math.BlockPos;
12 import net.minecraft.util.math.shapes.VoxelShape;
13 import net.minecraft.world.LightType;
14 import net.minecraft.world.World;
15 import net.minecraft.world.biome.Biome;
16
17 public class SpawnableBlocksHelper {
18     private static final EntityType entityType = EntityType.Builder.create(EntityClassification.MONSTER)
19             .size(0f, 0f).disableSerialization().build(null);
20
21     public static void findSpawnableBlocks(Coords coords, int width, int height, BlockProcessor blockProcessor) {
22         int blockX = coords.getX();
23         int minX = blockX - width;
24         int maxX = blockX + width + 1;
25
26         int blockZ = coords.getZ();
27         int minZ = blockZ - width;
28         int maxZ = blockZ + width + 1;
29
30         int blockY = coords.getY();
31         int minY = Math.max(1, blockY - height);
32         int maxY = Math.min(255, blockY + height);
33
34         World world = Minecraft.getInstance().world;
35         for (int x = minX; x < maxX; x++) {
36             for (int z = minZ; z < maxZ; z++) {
37                 if (isBiomeHostileSpawnProof(world, new BlockPos(x, 1, z))) continue;
38
39                 BlockState upperBlockState = world.getBlockState(new BlockPos(x, minY - 1, z));
40                 for (int y = Math.max(1, minY); y < maxY; y++) {
41                     BlockState spawnBlockState = upperBlockState;
42                     BlockPos pos = new BlockPos(x, y, z);
43                     upperBlockState = world.getBlockState(pos);
44                     if (isSpawnable(world, pos, spawnBlockState, upperBlockState)) {
45                         blockProcessor.process(pos);
46                     }
47                 }
48             }
49         }
50     }
51
52     static boolean isBiomeHostileSpawnProof(World world, BlockPos pos) {
53         Biome biome = world.getBiome(pos);
54         return biome.getSpawningChance() == 0 ||
55                 biome.getSpawns(EntityClassification.MONSTER).isEmpty();
56     }
57
58     static boolean isSpawnable(World world, BlockPos pos, BlockState spawnBlockState, BlockState upperBlockState) {
59         VoxelShape collisionShape = upperBlockState.getCollisionShape(world, pos);
60         boolean isNether = world.dimension.isNether();
61         return spawnBlockState.canEntitySpawn(world, pos.down(), isNether ? EntityType.ZOMBIE_PIGMAN : entityType) &&
62                 !Block.doesSideFillSquare(collisionShape, Direction.UP) &&
63                 !upperBlockState.canProvidePower() &&
64                 !upperBlockState.isIn(BlockTags.RAILS) &&
65                 collisionShape.getEnd(Direction.Axis.Y) <= 0 &&
66                 upperBlockState.getFluidState().isEmpty() &&
67                 (isNether || world.getLightFor(LightType.BLOCK, pos) <= 7);
68     }
69 }