.addDisplayValue(3, "32"))
.section(I18n.format("bbor.features.spawningSpheres"),
(x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.features.spawningSpheres"), BoundingBoxType.AFKSphere),
- (x, width) -> new BoolSettingButton(width, I18n.format("bbor.features.spawningSpheres.spawnableBlocks"), ConfigManager.renderAFKSpawnableBlocks),
- (x, width) -> new IntSettingSlider(width, 1, 3, "bbor.options.distance", ConfigManager.afkSpawnableBlocksRenderDistance)
- .addDisplayValue(1, I18n.format("bbor.options.distance.nearest"))
- .addDisplayValue(2, I18n.format("bbor.options.distance.nearer"))
- .addDisplayValue(3, I18n.format("bbor.options.distance.normal")))
+ (x, width) -> new BoolSettingButton(width, I18n.format("bbor.features.spawnableBlocks"), ConfigManager.renderAFKSpawnableBlocks))
.section(I18n.format("bbor.tabs.structures"),
(x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.desertTemples"), BoundingBoxType.DesertTemple),
(x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.jungleTemples"), BoundingBoxType.JungleTemple),
import com.irtimaled.bbor.client.models.BoundingBoxSpawningSphere;
import com.irtimaled.bbor.common.models.Coords;
import com.irtimaled.bbor.common.models.Point;
-import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
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) {
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;
+ int minY = Math.max(1, blockY - height);
+ int maxY = Math.min(255, blockY + height);
- int centerY = (int) center.getY();
- int centerYby2 = 2 * centerY;
-
- WorldClient world = Minecraft.getInstance().world;
+ World world = Minecraft.getInstance().world;
int processed = 0;
for (int x = minX; x < maxX; x++) {
for (int z = minZ; z < maxZ; z++) {
- if (!isWithinCircle(x, z, center)) continue;
+ 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 (!isBiomeHostileSpawnable(world, new BlockPos(x, 1, z))) continue;
+ if (SpawnableBlocksHelper.isBiomeHostileSpawnProof(world, new BlockPos(x, 1, z))) continue;
- int bottom = centerY;
- for (int y = minY; y < centerY; y++) {
- if (isWithinSpawnSphere(x, y, z, center)) {
- bottom = y;
- break;
- }
- }
- int top = (centerYby2 - bottom);
- if (top > 255) top = 255;
- if (bottom < 1) bottom = 1;
-
- IBlockState upperBlockState = world.getBlockState(new BlockPos(x, bottom - 1, z));
- for (int y = Math.max(1, bottom); y < top; y++) {
+ IBlockState upperBlockState = world.getBlockState(new BlockPos(x, minY - 1, z));
+ for (int y = minY; y < maxY; y++) {
IBlockState spawnBlockState = upperBlockState;
BlockPos pos = new BlockPos(x, y, z);
upperBlockState = world.getBlockState(pos);
- if (isSpawnable(world, pos, spawnBlockState, upperBlockState) &&
+ distance = center.getDistance(new Point(closestX, y, closestZ));
+ if (isWithinSpawnableZone(distance) &&
+ SpawnableBlocksHelper.isSpawnable(world, pos, spawnBlockState, upperBlockState) &&
blockProcessor.process(x, y, z)) {
processed++;
}
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 isWithinCircle(int x, int z, Point center) {
- int x1 = x+1;
- int z1 = z+1;
- int closestX = Math.abs(center.getX()-x) < Math.abs(center.getX()-x1) ? x : x1;
- int closestZ = Math.abs(center.getZ()-z) < Math.abs(center.getZ()-z1) ? z : z1;
- double distance = center.getDistance(new Point(closestX, center.getY(), closestZ));
- return distance <= BoundingBoxSpawningSphere.SPAWN_RADIUS;
- }
-
- private static boolean isBiomeHostileSpawnable(WorldClient world, BlockPos pos) {
- Biome biome = world.getBiome(pos);
- return biome.getSpawningChance() > 0 &&
- !biome.getSpawns(EnumCreatureType.MONSTER).isEmpty();
- }
-
- private static boolean isSpawnable(WorldClient world, BlockPos pos, IBlockState spawnBlockState, IBlockState upperBlockState) {
- Block spawnBlock = spawnBlockState.getBlock();
- 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;
}
}
import com.irtimaled.bbor.common.BoundingBoxType;
import com.irtimaled.bbor.common.models.BoundingBoxSphere;
+import com.irtimaled.bbor.common.models.Coords;
import com.irtimaled.bbor.common.models.Point;
+import java.util.HashSet;
+import java.util.Set;
+
public class BoundingBoxSpawningSphere extends BoundingBoxSphere {
public static final int SAFE_RADIUS = 24;
public static final int SPAWN_RADIUS = 128;
+ private final Set<Coords> blocks = new HashSet<>();
private Integer spawnableCount;
public BoundingBoxSpawningSphere(Point point) {
super(point, SPAWN_RADIUS, BoundingBoxType.AFKSphere);
}
+ public Set<Coords> getBlocks() {
+ return blocks;
+ }
+
public boolean isWithinSphere(Point point) {
return this.getPoint().getDistance(point) <= getRadius() + 0.5D;
}
import com.irtimaled.bbor.client.Player;
import com.irtimaled.bbor.client.config.BoundingBoxTypeHelper;
+import com.irtimaled.bbor.client.config.ConfigManager;
import com.irtimaled.bbor.client.interop.SpawningSphereHelper;
import com.irtimaled.bbor.client.models.BoundingBoxSpawningSphere;
import com.irtimaled.bbor.common.BoundingBoxType;
import com.irtimaled.bbor.common.MathHelper;
+import com.irtimaled.bbor.common.models.Coords;
import com.irtimaled.bbor.common.models.Point;
+import net.minecraft.client.Minecraft;
import java.util.HashSet;
import java.util.Set;
public class SpawningSphereProvider implements IBoundingBoxProvider<BoundingBoxSpawningSphere> {
+ public static final Minecraft minecraft = Minecraft.getInstance();
+ private static Long lastGameTime = null;
+
+ private static Set<BoundingBoxSpawningSphere> lastBoundingBox = null;
private static BoundingBoxSpawningSphere spawningSphere;
private static Integer dimensionId;
dimensionId = Player.getDimensionId();
spawningSphere = new BoundingBoxSpawningSphere(point);
+ lastBoundingBox = null;
}
private static double snapToNearestHalf(double value) {
public static boolean clear() {
if(spawningSphere != null) {
+ lastBoundingBox = null;
spawningSphere = null;
dimensionId = null;
return true;
@Override
public Iterable<BoundingBoxSpawningSphere> get(int dimensionId) {
+ long gameTime = minecraft.world.getGameTime();
+ if (lastBoundingBox == null || (!((Long) gameTime).equals(lastGameTime) && gameTime % 2L == 0L)) {
+ lastGameTime = gameTime;
+ lastBoundingBox = getSpawningSphere();
+ }
+ return lastBoundingBox;
+ }
+
+ private Set<BoundingBoxSpawningSphere> getSpawningSphere() {
+ Set<Coords> blocks = spawningSphere.getBlocks();
+ blocks.clear();
+ if (ConfigManager.renderAFKSpawnableBlocks.get()) {
+ int width = MathHelper.floor(Math.pow(2, 1 + ConfigManager.spawnableBlocksRenderWidth.get()));
+ int height = MathHelper.floor(Math.pow(2, ConfigManager.spawnableBlocksRenderHeight.get()));
+
+ SpawningSphereHelper.findSpawnableSpaces(spawningSphere.getPoint(), Player.getCoords(), width, height,
+ (x, y, z) -> blocks.add(new Coords(x, y, z)));
+ }
Set<BoundingBoxSpawningSphere> boundingBoxes = new HashSet<>();
boundingBoxes.add(spawningSphere);
return boundingBoxes;
import com.irtimaled.bbor.client.Player;
import com.irtimaled.bbor.client.config.ConfigManager;
-import com.irtimaled.bbor.client.interop.SpawningSphereHelper;
import com.irtimaled.bbor.client.models.BoundingBoxSpawningSphere;
-import com.irtimaled.bbor.common.MathHelper;
-import com.irtimaled.bbor.common.models.Point;
import net.minecraft.client.resources.I18n;
import java.awt.*;
public class SpawningSphereRenderer extends AbstractRenderer<BoundingBoxSpawningSphere> {
@Override
public void render(BoundingBoxSpawningSphere boundingBox) {
- Point point = boundingBox.getPoint();
- OffsetPoint sphereCenter = new OffsetPoint(point);
+ OffsetPoint sphereCenter = new OffsetPoint(boundingBox.getPoint());
OffsetBox offsetBox = new OffsetBox(sphereCenter, sphereCenter).grow(0.5, 0, 0.5);
renderCuboid(offsetBox, Color.GREEN);
renderSphere(sphereCenter, BoundingBoxSpawningSphere.SAFE_RADIUS, Color.GREEN, 5, 5);
renderSphere(sphereCenter, BoundingBoxSpawningSphere.SPAWN_RADIUS, Color.RED, 5, 5);
- if(ConfigManager.renderAFKSpawnableBlocks.get()) {
- renderSpawnableSpaces(point);
+ if (ConfigManager.renderAFKSpawnableBlocks.get() && boundingBox.isWithinSphere(Player.getPoint())) {
+ renderSpawnableSpaces(boundingBox);
}
}
- private void renderSpawnableSpaces(Point center) {
- Integer renderDistance = ConfigManager.afkSpawnableBlocksRenderDistance.get();
- int width = MathHelper.floor(Math.pow(2, 2 + renderDistance));
- int height = MathHelper.floor(Math.pow(2, renderDistance));
-
- SpawningSphereHelper.findSpawnableSpaces(center, Player.getCoords(), width, height,
- (x, y, z) -> {
- OffsetBox offsetBox = new OffsetBox(x, y, z, x + 1, y, z + 1);
- renderCuboid(offsetBox, Color.RED);
- return false;
- });
+ private void renderSpawnableSpaces(BoundingBoxSpawningSphere boundingBox) {
+ boundingBox.getBlocks().forEach(c -> {
+ int x = c.getX();
+ int y = c.getY();
+ int z = c.getZ();
+ OffsetBox offsetBox = new OffsetBox(x, y, z, x + 1, y, z + 1);
+ renderCuboid(offsetBox, boundingBox.getColor());
+ });
}
}
"bbor.features.mobSpawners.spawnArea": "Spawn Area",
"bbor.features.mobSpawners.activationLines": "Activation Lines",
"bbor.features.spawningSpheres": "Spawning Spheres",
- "bbor.features.spawningSpheres.spawnableBlocks": "Spawnable Blocks",
"bbor.features.spawnableBlocks": "Spawnable Blocks",
"bbor.features.biomeBorders": "Biome Borders",