package com.irtimaled.bbor.client.interop;
-import com.irtimaled.bbor.client.models.Point;
-import com.irtimaled.bbor.common.models.BoundingBoxSpawningSphere;
+import com.irtimaled.bbor.client.models.BoundingBoxSpawningSphere;
import com.irtimaled.bbor.common.models.Coords;
-import net.minecraft.block.Block;
-import net.minecraft.block.state.IBlockState;
+import com.irtimaled.bbor.common.models.Point;
+import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.multiplayer.WorldClient;
-import net.minecraft.entity.EnumCreatureType;
-import net.minecraft.init.Blocks;
-import net.minecraft.tags.BlockTags;
-import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
-import net.minecraft.world.EnumLightType;
-import net.minecraft.world.biome.Biome;
+import net.minecraft.world.World;
public class SpawningSphereHelper {
- public static int findSpawnableSpaces(Point center, Coords coords, int width, int height, BlockProcessor blockProcessor) {
+ public static void findSpawnableSpaces(Point center, Coords coords, int width, int height, BlockProcessor blockProcessor) {
int blockX = coords.getX();
int minX = blockX - width;
- int maxX = blockX + width;
+ int maxX = blockX + width + 1;
int blockZ = coords.getZ();
int minZ = blockZ - width;
- int maxZ = blockZ + width;
+ int maxZ = blockZ + width + 1;
int blockY = coords.getY();
- int minY = blockY - height;
- if (minY < 1) minY = 1;
- int maxY = blockY + height;
- if (maxY > 255) maxY = 255;
+ int minY = Math.max(1, blockY - height);
+ int maxY = Math.min(255, blockY + height);
- int processed = 0;
+ World world = Minecraft.getInstance().world;
for (int x = minX; x < maxX; x++) {
for (int z = minZ; z < maxZ; z++) {
+ double closestX = x + 0.5D;
+ double closestZ = z + 0.5D;
+ double distance = center.getDistance(new Point(closestX, center.getY(), closestZ));
+ if (distance > BoundingBoxSpawningSphere.SPAWN_RADIUS) continue;
+
+ if (SpawnableBlocksHelper.isBiomeHostileSpawnProof(world, new BlockPos(x, 1, z))) continue;
+
+ BlockState upperBlockState = world.getBlockState(new BlockPos(x, minY - 1, z));
for (int y = minY; y < maxY; y++) {
- if (isWithinSpawnSphere(x, y, z, center) && isSpawnable(x, y, z) && blockProcessor.process(x, y, z)) {
- processed++;
+ BlockState spawnBlockState = upperBlockState;
+ BlockPos pos = new BlockPos(x, y, z);
+ upperBlockState = world.getBlockState(pos);
+ distance = center.getDistance(new Point(closestX, y, closestZ));
+ if (isWithinSpawnableZone(distance) &&
+ SpawnableBlocksHelper.isSpawnable(world, pos, spawnBlockState, upperBlockState)) {
+ blockProcessor.process(pos);
}
}
}
}
- return processed;
- }
-
- private static boolean isWithinSpawnSphere(int x, int y, int z, Point center) {
- int x1 = x+1;
- int z1 = z+1;
- int y1 = y+1;
- int closestX = Math.abs(center.getX()-x) < Math.abs(center.getX()-x1) ? x : x1;
- int closestY = Math.abs(center.getY()-y) < Math.abs(center.getY()-y1) ? y : y1;
- int closestZ = Math.abs(center.getZ()-z) < Math.abs(center.getZ()-z1) ? z : z1;
- double distance = center.getDistance(new Point(closestX, closestY, closestZ));
- return distance <= BoundingBoxSpawningSphere.SPAWN_RADIUS && distance >= (BoundingBoxSpawningSphere.SAFE_RADIUS-1);
}
- private static boolean isSpawnable(int x, int y, int z) {
- WorldClient world = Minecraft.getInstance().world;
- BlockPos pos = new BlockPos(x, y, z);
- Biome biome = world.getBiome(pos);
- return biome.getSpawningChance() > 0 &&
- !biome.getSpawnableList(EnumCreatureType.MONSTER).isEmpty() &&
- isSpawnable(pos, world);
- }
-
- private static boolean isSpawnable(BlockPos pos, WorldClient world) {
- IBlockState spawnBlockState = world.getBlockState(pos.down());
- Block spawnBlock = spawnBlockState.getBlock();
- IBlockState upperBlockState = world.getBlockState(pos);
-
- return spawnBlock != Blocks.AIR &&
- spawnBlock != Blocks.BEDROCK &&
- spawnBlock != Blocks.BARRIER &&
- spawnBlockState.isTopSolid() &&
- !upperBlockState.isBlockNormalCube() &&
- !upperBlockState.canProvidePower() &&
- !upperBlockState.isIn(BlockTags.RAILS) &&
- upperBlockState.getCollisionShape(world, pos).getEnd(EnumFacing.Axis.Y) <= 0 &&
- upperBlockState.getFluidState().isEmpty() &&
- (world.dimension.isNether() || world.getLightFor(EnumLightType.BLOCK, pos) <= 7);
+ private static boolean isWithinSpawnableZone(double distance) {
+ return distance <= BoundingBoxSpawningSphere.SPAWN_RADIUS &&
+ distance > BoundingBoxSpawningSphere.SAFE_RADIUS;
}
}