Painted mountains adaptation

This commit is contained in:
paulevsGitch 2021-02-06 05:05:33 +03:00
parent d7161e5904
commit 7ef23332fc
5 changed files with 196 additions and 264 deletions

View file

@ -20,14 +20,14 @@ import ru.betterend.world.structures.features.StructureMountain;
import ru.betterend.world.structures.features.StructurePaintedMountain;
import ru.betterend.world.structures.piece.CavePiece;
import ru.betterend.world.structures.piece.LakePiece;
import ru.betterend.world.structures.piece.MountainPiece;
import ru.betterend.world.structures.piece.CrystalMountainPiece;
import ru.betterend.world.structures.piece.NBTPiece;
import ru.betterend.world.structures.piece.PaintedMountainPiece;
import ru.betterend.world.structures.piece.VoxelPiece;
public class EndStructures {
public static final StructurePieceType VOXEL_PIECE = register("voxel", VoxelPiece::new);
public static final StructurePieceType MOUNTAIN_PIECE = register("mountain_piece", MountainPiece::new);
public static final StructurePieceType MOUNTAIN_PIECE = register("mountain_piece", CrystalMountainPiece::new);
public static final StructurePieceType CAVE_PIECE = register("cave_piece", CavePiece::new);
public static final StructurePieceType LAKE_PIECE = register("lake_piece", LakePiece::new);
public static final StructurePieceType PAINTED_MOUNTAIN_PIECE = register("painted_mountain_piece", PaintedMountainPiece::new);

View file

@ -11,7 +11,7 @@ import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.feature.StructureFeature;
import ru.betterend.util.MHelper;
import ru.betterend.world.structures.piece.MountainPiece;
import ru.betterend.world.structures.piece.CrystalMountainPiece;
public class StructureMountain extends StructureFeatureBase {
@Override
@ -32,7 +32,7 @@ public class StructureMountain extends StructureFeatureBase {
if (y > 5) {
float radius = MHelper.randRange(50, 100, random);
float height = radius * MHelper.randRange(0.8F, 1.2F, random);
MountainPiece piece = new MountainPiece(new BlockPos(x, y, z), radius, height, random, biome);
CrystalMountainPiece piece = new CrystalMountainPiece(new BlockPos(x, y, z), radius, height, random, biome);
this.children.add(piece);
}
this.setBoundingBoxFromChildren();

View file

@ -0,0 +1,167 @@
package ru.betterend.world.structures.piece;
import java.util.Random;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.structure.StructureManager;
import net.minecraft.util.math.BlockBox;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.Mutable;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.Heightmap;
import net.minecraft.world.Heightmap.Type;
import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.StructureAccessor;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import ru.betterend.registry.EndBiomes;
import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndStructures;
import ru.betterend.registry.EndTags;
import ru.betterend.util.MHelper;
public class CrystalMountainPiece extends MountainPiece {
private BlockState top;
public CrystalMountainPiece(BlockPos center, float radius, float height, Random random, Biome biome) {
super(EndStructures.MOUNTAIN_PIECE, center, radius, height, random, biome);
top = biome.getGenerationSettings().getSurfaceConfig().getTopMaterial();
}
public CrystalMountainPiece(StructureManager manager, CompoundTag tag) {
super(EndStructures.MOUNTAIN_PIECE, manager, tag);
}
@Override
protected void fromNbt(CompoundTag tag) {
super.fromNbt(tag);
top = EndBiomes.getBiome(biomeID).getBiome().getGenerationSettings().getSurfaceConfig().getTopMaterial();
}
@Override
public boolean generate(StructureWorldAccess world, StructureAccessor arg, ChunkGenerator chunkGenerator, Random random, BlockBox blockBox, ChunkPos chunkPos, BlockPos blockPos) {
int sx = chunkPos.getStartX();
int sz = chunkPos.getStartZ();
Mutable pos = new Mutable();
Chunk chunk = world.getChunk(chunkPos.x, chunkPos.z);
Heightmap map = chunk.getHeightmap(Type.WORLD_SURFACE);
Heightmap map2 = chunk.getHeightmap(Type.WORLD_SURFACE_WG);
for (int x = 0; x < 16; x++) {
int px = x + sx;
int px2 = px - center.getX();
px2 *= px2;
pos.setX(x);
for (int z = 0; z < 16; z++) {
int pz = z + sz;
int pz2 = pz - center.getZ();
pz2 *= pz2;
float dist = px2 + pz2;
if (dist < r2) {
pos.setZ(z);
dist = 1 - (float) Math.pow(dist / r2, 0.3);
int minY = map.get(x, z);
if (minY < 10) {
continue;
}
pos.setY(minY);
while (!chunk.getBlockState(pos).isIn(EndTags.GEN_TERRAIN) && pos.getY() > 56 && !chunk.getBlockState(pos.down()).isOf(Blocks.CAVE_AIR)) {
pos.setY(pos.getY() - 1);
}
minY = pos.getY();
minY = Math.max(minY, map2.get(x, z));
if (minY > center.getY() - 8) {
float maxY = dist * height * getHeightClamp(world, 12, px, pz);
if (maxY > 0) {
maxY *= (float) noise1.eval(px * 0.05, pz * 0.05) * 0.3F + 0.7F;
maxY *= (float) noise1.eval(px * 0.1, pz * 0.1) * 0.1F + 0.8F;
maxY += center.getY();
int maxYI = (int) (maxY);
int cover = maxYI - 1;
boolean needCover = (noise1.eval(px * 0.1, pz * 0.1) + MHelper.randRange(-0.4, 0.4, random) - (center.getY() + 14) * 0.1) > 0;
for (int y = minY - 1; y < maxYI; y++) {
pos.setY(y);
chunk.setBlockState(pos, needCover && y == cover ? top : Blocks.END_STONE.getDefaultState(), false);
}
}
}
}
}
}
map = chunk.getHeightmap(Type.WORLD_SURFACE);
// Big crystals
int count = (map.get(8, 8) - (center.getY() + 24)) / 7;
count = MathHelper.clamp(count, 0, 8);
for (int i = 0; i < count; i++) {
int radius = MHelper.randRange(2, 3, random);
float fill = MHelper.randRange(0F, 1F, random);
int x = MHelper.randRange(radius, 15 - radius, random);
int z = MHelper.randRange(radius, 15 - radius, random);
int y = map.get(x, z);
if (y > 80) {
pos.set(x, y, z);
if (chunk.getBlockState(pos.down()).isOf(Blocks.END_STONE)) {
int height = MHelper.floor(radius * MHelper.randRange(1.5F, 3F, random) + (y - 80) * 0.3F);
crystal(chunk, pos, radius, height, fill, random);
}
}
}
// Small crystals
count = (map.get(8, 8) - (center.getY() + 24)) / 2;
count = MathHelper.clamp(count, 4, 8);
for (int i = 0; i < count; i++) {
int radius = MHelper.randRange(1, 2, random);
float fill = random.nextBoolean() ? 0 : 1;
int x = MHelper.randRange(radius, 15 - radius, random);
int z = MHelper.randRange(radius, 15 - radius, random);
int y = map.get(x, z);
if (y > 80) {
pos.set(x, y, z);
if (chunk.getBlockState(pos.down()).getBlock() == Blocks.END_STONE) {
int height = MHelper.floor(radius * MHelper.randRange(1.5F, 3F, random) + (y - 80) * 0.3F);
crystal(chunk, pos, radius, height, fill, random);
}
}
}
return true;
}
private void crystal(Chunk chunk, BlockPos pos, int radius, int height, float fill, Random random) {
Mutable mut = new Mutable();
int max = MHelper.floor(fill * radius + radius + 0.5F);
height += pos.getY();
Heightmap map = chunk.getHeightmap(Type.WORLD_SURFACE);
int coefX = MHelper.randRange(-1, 1, random);
int coefZ = MHelper.randRange(-1, 1, random);
for (int x = -radius; x <= radius; x++) {
mut.setX(x + pos.getX());
if (mut.getX() >= 0 && mut.getX() < 16) {
int ax = Math.abs(x);
for (int z = -radius; z <= radius; z++) {
mut.setZ(z + pos.getZ());
if (mut.getZ() >= 0 && mut.getZ() < 16) {
int az = Math.abs(z);
if (ax + az < max) {
int minY = map.get(mut.getX(), mut.getZ()) - MHelper.randRange(3, 7, random);
if (pos.getY() - minY > 8) {
minY = pos.getY() - 8;
}
int h = coefX * x + coefZ * z + height;
for (int y = minY; y < h; y++) {
mut.setY(y);
chunk.setBlockState(mut, EndBlocks.AURORA_CRYSTAL.getDefaultState(), false);
}
}
}
}
}
}
}
}

View file

@ -5,46 +5,36 @@ import java.util.Random;
import com.google.common.collect.Maps;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtHelper;
import net.minecraft.structure.StructureManager;
import net.minecraft.structure.StructurePieceType;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockBox;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.Mutable;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.Heightmap;
import net.minecraft.world.Heightmap.Type;
import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.StructureAccessor;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import ru.betterend.noise.OpenSimplexNoise;
import ru.betterend.registry.EndBiomes;
import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndStructures;
import ru.betterend.registry.EndTags;
import ru.betterend.util.MHelper;
public class MountainPiece extends BasePiece {
private Map<Integer, Integer> heightmap = Maps.newHashMap();
private OpenSimplexNoise noise1;
private OpenSimplexNoise noise2;
private BlockPos center;
private float radius;
private float height;
private float r2;
private Identifier biomeID;
private BlockState top;
private int seed1;
private int seed2;
public abstract class MountainPiece extends BasePiece {
protected Map<Integer, Integer> heightmap = Maps.newHashMap();
protected OpenSimplexNoise noise1;
protected OpenSimplexNoise noise2;
protected BlockPos center;
protected float radius;
protected float height;
protected float r2;
protected Identifier biomeID;
protected int seed1;
protected int seed2;
public MountainPiece(BlockPos center, float radius, float height, Random random, Biome biome) {
super(EndStructures.MOUNTAIN_PIECE, random.nextInt());
public MountainPiece(StructurePieceType type, BlockPos center, float radius, float height, Random random, Biome biome) {
super(type, random.nextInt());
this.center = center;
this.radius = radius;
this.height = height;
@ -54,12 +44,11 @@ public class MountainPiece extends BasePiece {
this.noise1 = new OpenSimplexNoise(this.seed1);
this.noise2 = new OpenSimplexNoise(this.seed2);
this.biomeID = EndBiomes.getBiomeID(biome);
top = biome.getGenerationSettings().getSurfaceConfig().getTopMaterial();
makeBoundingBox();
}
public MountainPiece(StructureManager manager, CompoundTag tag) {
super(EndStructures.MOUNTAIN_PIECE, tag);
public MountainPiece(StructurePieceType type, StructureManager manager, CompoundTag tag) {
super(type, tag);
makeBoundingBox();
}
@ -84,98 +73,6 @@ public class MountainPiece extends BasePiece {
seed2 = tag.getInt("seed2");
noise1 = new OpenSimplexNoise(seed1);
noise2 = new OpenSimplexNoise(seed2);
top = EndBiomes.getBiome(biomeID).getBiome().getGenerationSettings().getSurfaceConfig().getTopMaterial();
}
@Override
public boolean generate(StructureWorldAccess world, StructureAccessor arg, ChunkGenerator chunkGenerator, Random random, BlockBox blockBox, ChunkPos chunkPos, BlockPos blockPos) {
int sx = chunkPos.getStartX();
int sz = chunkPos.getStartZ();
Mutable pos = new Mutable();
Chunk chunk = world.getChunk(chunkPos.x, chunkPos.z);
Heightmap map = chunk.getHeightmap(Type.WORLD_SURFACE);
Heightmap map2 = chunk.getHeightmap(Type.WORLD_SURFACE_WG);
for (int x = 0; x < 16; x++) {
int px = x + sx;
int px2 = px - center.getX();
px2 *= px2;
pos.setX(x);
for (int z = 0; z < 16; z++) {
int pz = z + sz;
int pz2 = pz - center.getZ();
pz2 *= pz2;
float dist = px2 + pz2;
if (dist < r2) {
pos.setZ(z);
dist = 1 - (float) Math.pow(dist / r2, 0.3);
int minY = map.get(x, z);
if (minY < 10) {
continue;
}
pos.setY(minY);
while (!chunk.getBlockState(pos).isIn(EndTags.GEN_TERRAIN) && pos.getY() > 56 && !chunk.getBlockState(pos.down()).isOf(Blocks.CAVE_AIR)) {
pos.setY(pos.getY() - 1);
}
minY = pos.getY();
minY = Math.max(minY, map2.get(x, z));
if (minY > center.getY() - 8) {
float maxY = dist * height * getHeightClamp(world, 12, px, pz);
if (maxY > 0) {
maxY *= (float) noise1.eval(px * 0.05, pz * 0.05) * 0.3F + 0.7F;
maxY *= (float) noise1.eval(px * 0.1, pz * 0.1) * 0.1F + 0.8F;
maxY += center.getY();
int maxYI = (int) (maxY);
int cover = maxYI - 1;
boolean needCover = (noise1.eval(px * 0.1, pz * 0.1) + MHelper.randRange(-0.4, 0.4, random) - (center.getY() + 14) * 0.1) > 0;
for (int y = minY - 1; y < maxYI; y++) {
pos.setY(y);
chunk.setBlockState(pos, needCover && y == cover ? top : Blocks.END_STONE.getDefaultState(), false);
}
}
}
}
}
}
map = chunk.getHeightmap(Type.WORLD_SURFACE);
// Big crystals
int count = (map.get(8, 8) - (center.getY() + 24)) / 7;
count = MathHelper.clamp(count, 0, 8);
for (int i = 0; i < count; i++) {
int radius = MHelper.randRange(2, 3, random);
float fill = MHelper.randRange(0F, 1F, random);
int x = MHelper.randRange(radius, 15 - radius, random);
int z = MHelper.randRange(radius, 15 - radius, random);
int y = map.get(x, z);
if (y > 80) {
pos.set(x, y, z);
if (chunk.getBlockState(pos.down()).isOf(Blocks.END_STONE)) {
int height = MHelper.floor(radius * MHelper.randRange(1.5F, 3F, random) + (y - 80) * 0.3F);
crystal(chunk, pos, radius, height, fill, random);
}
}
}
// Small crystals
count = (map.get(8, 8) - (center.getY() + 24)) / 2;
count = MathHelper.clamp(count, 4, 8);
for (int i = 0; i < count; i++) {
int radius = MHelper.randRange(1, 2, random);
float fill = random.nextBoolean() ? 0 : 1;
int x = MHelper.randRange(radius, 15 - radius, random);
int z = MHelper.randRange(radius, 15 - radius, random);
int y = map.get(x, z);
if (y > 80) {
pos.set(x, y, z);
if (chunk.getBlockState(pos.down()).getBlock() == Blocks.END_STONE) {
int height = MHelper.floor(radius * MHelper.randRange(1.5F, 3F, random) + (y - 80) * 0.3F);
crystal(chunk, pos, radius, height, fill, random);
}
}
}
return true;
}
private int getHeight(StructureWorldAccess world, BlockPos pos) {
@ -209,7 +106,7 @@ public class MountainPiece extends BasePiece {
return h;
}
private float getHeightClamp(StructureWorldAccess world, int radius, int posX, int posZ) {
protected float getHeightClamp(StructureWorldAccess world, int radius, int posX, int posZ) {
Mutable mut = new Mutable();
float height = 0;
float max = 0;
@ -237,36 +134,4 @@ public class MountainPiece extends BasePiece {
int maxZ = MHelper.floor(center.getZ() + radius + 1);
this.boundingBox = new BlockBox(minX, minZ, maxX, maxZ);
}
private void crystal(Chunk chunk, BlockPos pos, int radius, int height, float fill, Random random) {
Mutable mut = new Mutable();
int max = MHelper.floor(fill * radius + radius + 0.5F);
height += pos.getY();
Heightmap map = chunk.getHeightmap(Type.WORLD_SURFACE);
int coefX = MHelper.randRange(-1, 1, random);
int coefZ = MHelper.randRange(-1, 1, random);
for (int x = -radius; x <= radius; x++) {
mut.setX(x + pos.getX());
if (mut.getX() >= 0 && mut.getX() < 16) {
int ax = Math.abs(x);
for (int z = -radius; z <= radius; z++) {
mut.setZ(z + pos.getZ());
if (mut.getZ() >= 0 && mut.getZ() < 16) {
int az = Math.abs(z);
if (ax + az < max) {
int minY = map.get(mut.getX(), mut.getZ()) - MHelper.randRange(3, 7, random);
if (pos.getY() - minY > 8) {
minY = pos.getY() - 8;
}
int h = coefX * x + coefZ * z + height;
for (int y = minY; y < h; y++) {
mut.setY(y);
chunk.setBlockState(mut, EndBlocks.AURORA_CRYSTAL.getDefaultState(), false);
}
}
}
}
}
}
}
}

View file

@ -1,21 +1,16 @@
package ru.betterend.world.structures.piece;
import java.util.Map;
import java.util.Random;
import com.google.common.collect.Maps;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtHelper;
import net.minecraft.structure.StructureManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockBox;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.Mutable;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.Heightmap;
import net.minecraft.world.Heightmap.Type;
import net.minecraft.world.StructureWorldAccess;
@ -23,53 +18,23 @@ import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.StructureAccessor;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import ru.betterend.noise.OpenSimplexNoise;
import ru.betterend.registry.EndBiomes;
import ru.betterend.registry.EndStructures;
import ru.betterend.util.MHelper;
public class PaintedMountainPiece extends BasePiece {
private Map<Integer, Integer> heightmap = Maps.newHashMap();
private OpenSimplexNoise noise1;
private OpenSimplexNoise noise2;
private BlockPos center;
private float radius;
private float height;
private float r2;
private Identifier biomeID;
public class PaintedMountainPiece extends MountainPiece {
private BlockState[] slises;
private int seed1;
private int seed2;
public PaintedMountainPiece(BlockPos center, float radius, float height, Random random, Biome biome, BlockState[] slises) {
super(EndStructures.PAINTED_MOUNTAIN_PIECE, random.nextInt());
this.center = center;
this.radius = radius;
this.height = height;
this.r2 = radius * radius;
this.seed1 = random.nextInt();
this.seed2 = random.nextInt();
this.noise1 = new OpenSimplexNoise(this.seed1);
this.noise2 = new OpenSimplexNoise(this.seed2);
this.biomeID = EndBiomes.getBiomeID(biome);
super(EndStructures.PAINTED_MOUNTAIN_PIECE, center, radius, height, random, biome);
this.slises = slises;
makeBoundingBox();
}
public PaintedMountainPiece(StructureManager manager, CompoundTag tag) {
super(EndStructures.PAINTED_MOUNTAIN_PIECE, tag);
makeBoundingBox();
super(EndStructures.PAINTED_MOUNTAIN_PIECE, manager, tag);
}
@Override
protected void toNbt(CompoundTag tag) {
tag.put("center", NbtHelper.fromBlockPos(center));
tag.putFloat("radius", radius);
tag.putFloat("height", height);
tag.putString("biome", biomeID.toString());
tag.putInt("seed1", seed1);
tag.putInt("seed2", seed2);
super.toNbt(tag);
ListTag slise = new ListTag();
for (BlockState state: slises) {
slise.add(NbtHelper.fromBlockState(state));
@ -79,15 +44,7 @@ public class PaintedMountainPiece extends BasePiece {
@Override
protected void fromNbt(CompoundTag tag) {
center = NbtHelper.toBlockPos(tag.getCompound("center"));
radius = tag.getFloat("radius");
height = tag.getFloat("height");
biomeID = new Identifier(tag.getString("biome"));
r2 = radius * radius;
seed1 = tag.getInt("seed1");
seed2 = tag.getInt("seed2");
noise1 = new OpenSimplexNoise(seed1);
noise2 = new OpenSimplexNoise(seed2);
super.fromNbt(tag);
ListTag slise = tag.getList("slises", 10);
slises = new BlockState[slise.size()];
for (int i = 0; i < slises.length; i++) {
@ -123,12 +80,12 @@ public class PaintedMountainPiece extends BasePiece {
}
minY = pos.getY();
minY = Math.max(minY, map2.get(x, z));
if (minY > 56) {
float maxY = dist * height * getHeightClamp(world, 8, px, pz);
if (minY > center.getY() - 8) {
float maxY = dist * height * getHeightClamp(world, 10, px, pz);
if (maxY > 0) {
maxY *= (float) noise1.eval(px * 0.05, pz * 0.05) * 0.3F + 0.7F;
maxY *= (float) noise1.eval(px * 0.1, pz * 0.1) * 0.1F + 0.9F;
maxY += 56;
maxY += center.getY();
float offset = (float) (noise1.eval(px * 0.07, pz * 0.07) * 5 + noise1.eval(px * 0.2, pz * 0.2) * 2 + 7);
for (int y = minY - 1; y < maxY; y++) {
pos.setY(y);
@ -143,61 +100,4 @@ public class PaintedMountainPiece extends BasePiece {
return true;
}
private int getHeight(StructureWorldAccess world, BlockPos pos) {
int p = ((pos.getX() & 2047) << 11) | (pos.getZ() & 2047);
int h = heightmap.getOrDefault(p, Integer.MIN_VALUE);
if (h > Integer.MIN_VALUE) {
return h;
}
if (!EndBiomes.getBiomeID(world.getBiome(pos)).equals(biomeID)) {
heightmap.put(p, -4);
return -4;
}
h = world.getTopY(Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ());
if (h < 57) {
heightmap.put(p, -4);
return -4;
}
h = MHelper.floor(noise2.eval(pos.getX() * 0.005, pos.getZ() * 0.005) * noise2.eval(pos.getX() * 0.001, pos.getZ() * 0.001) * 8 + 8);
if (h < 0) {
heightmap.put(p, 0);
return 0;
}
heightmap.put(p, h);
return h;
}
private float getHeightClamp(StructureWorldAccess world, int radius, int posX, int posZ) {
Mutable mut = new Mutable();
float height = 0;
float max = 0;
for (int x = -radius; x <= radius; x++) {
mut.setX(posX + x);
int x2 = x * x;
for (int z = -radius; z <= radius; z++) {
mut.setZ(posZ + z);
int z2 = z * z;
float mult = 1 - (float) Math.sqrt(x2 + z2) / radius;
if (mult > 0) {
max += mult;
height += getHeight(world, mut) * mult;
}
}
}
height /= max;
return MathHelper.clamp(height / radius, 0, 1);
}
private void makeBoundingBox() {
int minX = MHelper.floor(center.getX() - radius);
int minZ = MHelper.floor(center.getZ() - radius);
int maxX = MHelper.floor(center.getX() + radius + 1);
int maxZ = MHelper.floor(center.getZ() + radius + 1);
this.boundingBox = new BlockBox(minX, minZ, maxX, maxZ);
}
}