1 package com.irtimaled.bbor.client.interop;
3 import com.irtimaled.bbor.client.models.Point;
4 import com.irtimaled.bbor.common.models.BoundingBoxSpawningSphere;
5 import com.irtimaled.bbor.common.models.Coords;
6 import net.minecraft.block.Block;
7 import net.minecraft.block.state.IBlockState;
8 import net.minecraft.client.Minecraft;
9 import net.minecraft.client.multiplayer.WorldClient;
10 import net.minecraft.entity.EnumCreatureType;
11 import net.minecraft.init.Blocks;
12 import net.minecraft.tags.BlockTags;
13 import net.minecraft.util.EnumFacing;
14 import net.minecraft.util.math.BlockPos;
15 import net.minecraft.world.EnumLightType;
16 import net.minecraft.world.biome.Biome;
18 public class SpawningSphereHelper {
19 public static int findSpawnableSpaces(Point center, Coords coords, int width, int height, BlockProcessor blockProcessor) {
20 int blockX = coords.getX();
21 int minX = blockX - width;
22 int maxX = blockX + width;
24 int blockZ = coords.getZ();
25 int minZ = blockZ - width;
26 int maxZ = blockZ + width;
28 int blockY = coords.getY();
29 int minY = blockY - height;
30 if (minY < 1) minY = 1;
31 int maxY = blockY + height;
32 if (maxY > 255) maxY = 255;
35 for (int x = minX; x < maxX; x++) {
36 for (int z = minZ; z < maxZ; z++) {
37 for (int y = minY; y < maxY; y++) {
38 if (isWithinSpawnSphere(x, y, z, center) && isSpawnable(x, y, z) && blockProcessor.process(x, y, z)) {
47 private static boolean isWithinSpawnSphere(int x, int y, int z, Point center) {
51 int closestX = Math.abs(center.getX()-x) < Math.abs(center.getX()-x1) ? x : x1;
52 int closestY = Math.abs(center.getY()-y) < Math.abs(center.getY()-y1) ? y : y1;
53 int closestZ = Math.abs(center.getZ()-z) < Math.abs(center.getZ()-z1) ? z : z1;
54 double distance = center.getDistance(new Point(closestX, closestY, closestZ));
55 return distance <= BoundingBoxSpawningSphere.SPAWN_RADIUS && distance >= (BoundingBoxSpawningSphere.SAFE_RADIUS-1);
58 private static boolean isSpawnable(int x, int y, int z) {
59 WorldClient world = Minecraft.getInstance().world;
60 BlockPos pos = new BlockPos(x, y, z);
61 Biome biome = world.getBiome(pos);
62 return biome.getSpawningChance() > 0 &&
63 !biome.getSpawnableList(EnumCreatureType.MONSTER).isEmpty() &&
64 isSpawnable(pos, world);
67 private static boolean isSpawnable(BlockPos pos, WorldClient world) {
68 IBlockState spawnBlockState = world.getBlockState(pos.down());
69 Block spawnBlock = spawnBlockState.getBlock();
70 IBlockState upperBlockState = world.getBlockState(pos);
72 return spawnBlock != Blocks.AIR &&
73 spawnBlock != Blocks.BEDROCK &&
74 spawnBlock != Blocks.BARRIER &&
75 spawnBlockState.isTopSolid() &&
76 !upperBlockState.isBlockNormalCube() &&
77 !upperBlockState.canProvidePower() &&
78 !upperBlockState.isIn(BlockTags.RAILS) &&
79 upperBlockState.getCollisionShape(world, pos).getEnd(EnumFacing.Axis.Y) <= 0 &&
80 upperBlockState.getFluidState().isEmpty() &&
81 (world.dimension.isNether() || world.getLightFor(EnumLightType.BLOCK, pos) <= 7);