mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-26 23:26:45 +01:00
Begin to implement extended world heights:
- Implemented in Bukkit module (and where required in Core module)
This commit is contained in:
parent
40e1bd9897
commit
f1d9d4bdc7
@ -27,6 +27,7 @@ package com.plotsquared.bukkit.generator;
|
|||||||
|
|
||||||
import com.plotsquared.bukkit.queue.GenChunk;
|
import com.plotsquared.bukkit.queue.GenChunk;
|
||||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||||
|
import com.plotsquared.bukkit.util.BukkitWorld;
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.generator.GeneratorWrapper;
|
import com.plotsquared.core.generator.GeneratorWrapper;
|
||||||
import com.plotsquared.core.generator.IndependentPlotGenerator;
|
import com.plotsquared.core.generator.IndependentPlotGenerator;
|
||||||
@ -159,12 +160,14 @@ public class BukkitPlotGenerator extends ChunkGenerator
|
|||||||
@NonNull BiomeGrid biome
|
@NonNull BiomeGrid biome
|
||||||
) {
|
) {
|
||||||
|
|
||||||
GenChunk result = new GenChunk();
|
int minY = BukkitWorld.getMinWorldHeight(world);
|
||||||
|
int maxY = BukkitWorld.getMaxWorldHeight(world);
|
||||||
|
GenChunk result = new GenChunk(minY, maxY);
|
||||||
if (this.getPlotGenerator() instanceof SingleWorldGenerator) {
|
if (this.getPlotGenerator() instanceof SingleWorldGenerator) {
|
||||||
if (result.getChunkData() != null) {
|
if (result.getChunkData() != null) {
|
||||||
for (int chunkX = 0; chunkX < 16; chunkX++) {
|
for (int chunkX = 0; chunkX < 16; chunkX++) {
|
||||||
for (int chunkZ = 0; chunkZ < 16; chunkZ++) {
|
for (int chunkZ = 0; chunkZ < 16; chunkZ++) {
|
||||||
for (int y = 0; y < world.getMaxHeight(); y++) {
|
for (int y = minY; y < maxY; y++) {
|
||||||
biome.setBiome(chunkX, y, chunkZ, Biome.PLAINS);
|
biome.setBiome(chunkX, y, chunkZ, Biome.PLAINS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -354,7 +354,7 @@ public class BlockEventListener implements Listener {
|
|||||||
Plot plot = area.getPlot(location);
|
Plot plot = area.getPlot(location);
|
||||||
if (plot != null) {
|
if (plot != null) {
|
||||||
BukkitPlayer plotPlayer = BukkitUtil.adapt(player);
|
BukkitPlayer plotPlayer = BukkitUtil.adapt(player);
|
||||||
if (event.getBlock().getY() == 0) {
|
if (event.getBlock().getY() == area.getMinBuildHeight()) {
|
||||||
if (!Permissions
|
if (!Permissions
|
||||||
.hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_DESTROY_GROUNDLEVEL)) {
|
.hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_DESTROY_GROUNDLEVEL)) {
|
||||||
plotPlayer.sendMessage(
|
plotPlayer.sendMessage(
|
||||||
@ -649,7 +649,7 @@ public class BlockEventListener implements Listener {
|
|||||||
event.getBlock().breakNaturally();
|
event.getBlock().breakNaturally();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (location.getY() == 0) {
|
if (location.getY() == area.getMinBuildHeight()) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -111,8 +111,8 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
|
|||||||
public boolean enqueue() {
|
public boolean enqueue() {
|
||||||
final Clipboard regenClipboard;
|
final Clipboard regenClipboard;
|
||||||
if (isRegen()) {
|
if (isRegen()) {
|
||||||
BlockVector3 start = BlockVector3.at(getRegenStart()[0] << 4, 0, getRegenStart()[1] << 4);
|
BlockVector3 start = BlockVector3.at(getRegenStart()[0] << 4, getWorld().getMinY(), getRegenStart()[1] << 4);
|
||||||
BlockVector3 end = BlockVector3.at((getRegenEnd()[0] << 4) + 15, 255, (getRegenEnd()[1] << 4) + 15);
|
BlockVector3 end = BlockVector3.at((getRegenEnd()[0] << 4) + 15, getWorld().getMaxY(), (getRegenEnd()[1] << 4) + 15);
|
||||||
Region region = new CuboidRegion(start, end);
|
Region region = new CuboidRegion(start, end);
|
||||||
regenClipboard = new BlockArrayClipboard(region);
|
regenClipboard = new BlockArrayClipboard(region);
|
||||||
regenClipboard.setOrigin(start);
|
regenClipboard.setOrigin(start);
|
||||||
@ -134,7 +134,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
|
|||||||
int sx = blockVector2.getX() << 4;
|
int sx = blockVector2.getX() << 4;
|
||||||
int sz = blockVector2.getZ() << 4;
|
int sz = blockVector2.getZ() << 4;
|
||||||
if (isRegenChunk) {
|
if (isRegenChunk) {
|
||||||
for (int layer = 0; layer < 16; layer++) {
|
for (int layer = (getWorld().getMinY() >> 4); layer < (getWorld().getMaxY() >> 4); layer++) {
|
||||||
for (int y = 0; y < 16; y++) {
|
for (int y = 0; y < 16; y++) {
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
@ -170,7 +170,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
|
|||||||
int lx = ChunkUtil.getX(j);
|
int lx = ChunkUtil.getX(j);
|
||||||
int lz = ChunkUtil.getZ(j);
|
int lz = ChunkUtil.getZ(j);
|
||||||
int x = sx + lx;
|
int x = sx + lx;
|
||||||
int y = ChunkUtil.getY(layer, j);
|
int y = ChunkUtil.getY(layer + localChunk.getMinSection(), j);
|
||||||
int z = sz + lz;
|
int z = sz + lz;
|
||||||
boolean edge = Settings.QUEUE.UPDATE_EDGES && isEdge(y >> 4, lx, y & 15, lz, blockVector2,
|
boolean edge = Settings.QUEUE.UPDATE_EDGES && isEdge(y >> 4, lx, y & 15, lz, blockVector2,
|
||||||
localChunk
|
localChunk
|
||||||
@ -295,47 +295,48 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEdge(int layer, int x, int y, int z, BlockVector2 blockVector2, LocalChunk localChunk) {
|
private boolean isEdge(int layer, int x, int y, int z, BlockVector2 blockVector2, LocalChunk localChunk) {
|
||||||
if (layer == 0 || layer == localChunk.getBaseblocks().length - 1) {
|
int layerIndex = (layer - localChunk.getMinSection());
|
||||||
|
if (layer == localChunk.getMinSection() || layerIndex == localChunk.getBaseblocks().length - 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (x == 0) {
|
if (x == 0) {
|
||||||
LocalChunk localChunkX = getBlockChunks().get(blockVector2.withX(blockVector2.getX() - 1));
|
LocalChunk localChunkX = getBlockChunks().get(blockVector2.withX(blockVector2.getX() - 1));
|
||||||
if (localChunkX == null || localChunkX.getBaseblocks()[layer] == null ||
|
if (localChunkX == null || localChunkX.getBaseblocks()[layerIndex] == null ||
|
||||||
localChunkX.getBaseblocks()[layer][ChunkUtil.getJ(15, y, z)] != null) {
|
localChunkX.getBaseblocks()[layerIndex][ChunkUtil.getJ(15, y, z)] != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (x == 15) {
|
} else if (x == 15) {
|
||||||
LocalChunk localChunkX = getBlockChunks().get(blockVector2.withX(blockVector2.getX() + 1));
|
LocalChunk localChunkX = getBlockChunks().get(blockVector2.withX(blockVector2.getX() + 1));
|
||||||
if (localChunkX == null || localChunkX.getBaseblocks()[layer] == null ||
|
if (localChunkX == null || localChunkX.getBaseblocks()[layerIndex] == null ||
|
||||||
localChunkX.getBaseblocks()[layer][ChunkUtil.getJ(0, y, z)] != null) {
|
localChunkX.getBaseblocks()[layerIndex][ChunkUtil.getJ(0, y, z)] != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (z == 0) {
|
if (z == 0) {
|
||||||
LocalChunk localChunkZ = getBlockChunks().get(blockVector2.withZ(blockVector2.getZ() - 1));
|
LocalChunk localChunkZ = getBlockChunks().get(blockVector2.withZ(blockVector2.getZ() - 1));
|
||||||
if (localChunkZ == null || localChunkZ.getBaseblocks()[layer] == null ||
|
if (localChunkZ == null || localChunkZ.getBaseblocks()[layerIndex] == null ||
|
||||||
localChunkZ.getBaseblocks()[layer][ChunkUtil.getJ(x, y, 15)] != null) {
|
localChunkZ.getBaseblocks()[layerIndex][ChunkUtil.getJ(x, y, 15)] != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (z == 15) {
|
} else if (z == 15) {
|
||||||
LocalChunk localChunkZ = getBlockChunks().get(blockVector2.withZ(blockVector2.getZ() + 1));
|
LocalChunk localChunkZ = getBlockChunks().get(blockVector2.withZ(blockVector2.getZ() + 1));
|
||||||
if (localChunkZ == null || localChunkZ.getBaseblocks()[layer] == null ||
|
if (localChunkZ == null || localChunkZ.getBaseblocks()[layerIndex] == null ||
|
||||||
localChunkZ.getBaseblocks()[layer][ChunkUtil.getJ(x, y, 0)] != null) {
|
localChunkZ.getBaseblocks()[layerIndex][ChunkUtil.getJ(x, y, 0)] != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (y == 0) {
|
if (y == 0) {
|
||||||
if (localChunk.getBaseblocks()[layer - 1] == null ||
|
if (localChunk.getBaseblocks()[layerIndex - 1] == null ||
|
||||||
localChunk.getBaseblocks()[layer][ChunkUtil.getJ(x, 15, z)] != null) {
|
localChunk.getBaseblocks()[layerIndex][ChunkUtil.getJ(x, 15, z)] != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (y == 15) {
|
} else if (y == 15) {
|
||||||
if (localChunk.getBaseblocks()[layer + 1] == null ||
|
if (localChunk.getBaseblocks()[layerIndex + 1] == null ||
|
||||||
localChunk.getBaseblocks()[layer][ChunkUtil.getJ(x, 0, z)] != null) {
|
localChunk.getBaseblocks()[layerIndex][ChunkUtil.getJ(x, 0, z)] != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BaseBlock[] baseBlocks = localChunk.getBaseblocks()[layer];
|
BaseBlock[] baseBlocks = localChunk.getBaseblocks()[layerIndex];
|
||||||
if (x > 0 && baseBlocks[ChunkUtil.getJ(x - 1, y, z)] == null) {
|
if (x > 0 && baseBlocks[ChunkUtil.getJ(x - 1, y, z)] == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,28 @@ public class GenChunk extends ScopedQueueCoordinator {
|
|||||||
public int chunkZ;
|
public int chunkZ;
|
||||||
private ChunkData chunkData = null;
|
private ChunkData chunkData = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not API. Used as a bridge between P2 and Bukkit {@link Chunk}.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link GenChunk#regenChunk(int, int)} for extended world heights
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "TODO")
|
||||||
public GenChunk() {
|
public GenChunk() {
|
||||||
super(null, Location.at("", 0, 0, 0), Location.at("", 15, 255, 15));
|
this(0, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not API. Used as a bridge between P2 and Bukkit {@link Chunk}.
|
||||||
|
*
|
||||||
|
* @param minY minimum world Y, inclusive
|
||||||
|
* @param maxY maximum world Y, inclusive
|
||||||
|
*
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
public GenChunk(int minY, int maxY) {
|
||||||
|
super(null, Location.at("", 0, minY, 0), Location.at("", 15, maxY, 15));
|
||||||
this.biomes = Biome.values();
|
this.biomes = Biome.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +137,7 @@ public class GenChunk extends ScopedQueueCoordinator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Biome biome = BukkitAdapter.adapt(biomeType);
|
Biome biome = BukkitAdapter.adapt(biomeType);
|
||||||
for (int y = 0; y < 256; y++) {
|
for (int y = getMin().getY(); y <= getMax().getY(); y++) {
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
this.biomeGrid.setBiome(x, y, z, biome);
|
this.biomeGrid.setBiome(x, y, z, biome);
|
||||||
@ -130,7 +150,7 @@ public class GenChunk extends ScopedQueueCoordinator {
|
|||||||
public void setCuboid(@NonNull Location pos1, @NonNull Location pos2, @NonNull BlockState block) {
|
public void setCuboid(@NonNull Location pos1, @NonNull Location pos2, @NonNull BlockState block) {
|
||||||
if (result != null && pos1.getX() == 0 && pos1.getZ() == 0 && pos2.getX() == 15 && pos2.getZ() == 15) {
|
if (result != null && pos1.getX() == 0 && pos1.getZ() == 0 && pos2.getX() == 15 && pos2.getZ() == 15) {
|
||||||
for (int y = pos1.getY(); y <= pos2.getY(); y++) {
|
for (int y = pos1.getY(); y <= pos2.getY(); y++) {
|
||||||
int layer = y >> 4;
|
int layer = (y - getMin().getY()) >> 4;
|
||||||
BlockState[] data = result[layer];
|
BlockState[] data = result[layer];
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
result[layer] = data = new BlockState[4096];
|
result[layer] = data = new BlockState[4096];
|
||||||
@ -164,7 +184,7 @@ public class GenChunk extends ScopedQueueCoordinator {
|
|||||||
*/
|
*/
|
||||||
public boolean setBiome(int x, int z, @NonNull Biome biome) {
|
public boolean setBiome(int x, int z, @NonNull Biome biome) {
|
||||||
if (this.biomeGrid != null) {
|
if (this.biomeGrid != null) {
|
||||||
for (int y = 0; y < 256; y++) {
|
for (int y = getMin().getY(); y < getMax().getY(); y++) {
|
||||||
this.setBiome(x, y, z, biome);
|
this.setBiome(x, y, z, biome);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -197,7 +217,7 @@ public class GenChunk extends ScopedQueueCoordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void storeCache(final int x, final int y, final int z, final @NonNull BlockState id) {
|
private void storeCache(final int x, final int y, final int z, final @NonNull BlockState id) {
|
||||||
int i = y >> 4;
|
int i = (y - getMin().getY()) >> 4;
|
||||||
BlockState[] v = this.result[i];
|
BlockState[] v = this.result[i];
|
||||||
if (v == null) {
|
if (v == null) {
|
||||||
this.result[i] = v = new BlockState[4096];
|
this.result[i] = v = new BlockState[4096];
|
||||||
@ -219,7 +239,7 @@ public class GenChunk extends ScopedQueueCoordinator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable BlockState getBlock(int x, int y, int z) {
|
public @Nullable BlockState getBlock(int x, int y, int z) {
|
||||||
int i = y >> 4;
|
int i = (y - getMin().getY()) >> 4;
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
return BukkitBlockUtil.get(chunkData.getType(x, y, z));
|
return BukkitBlockUtil.get(chunkData.getType(x, y, z));
|
||||||
}
|
}
|
||||||
@ -246,16 +266,16 @@ public class GenChunk extends ScopedQueueCoordinator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull Location getMax() {
|
public @NonNull Location getMax() {
|
||||||
return Location.at(getWorld().getName(), 15 + (getX() << 4), 255, 15 + (getZ() << 4));
|
return Location.at(getWorld().getName(), 15 + (getX() << 4), super.getMax().getY(), 15 + (getZ() << 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull Location getMin() {
|
public @NonNull Location getMin() {
|
||||||
return Location.at(getWorld().getName(), getX() << 4, 0, getZ() << 4);
|
return Location.at(getWorld().getName(), getX() << 4, super.getMin().getY(), getZ() << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull GenChunk clone() {
|
public @NonNull GenChunk clone() {
|
||||||
GenChunk toReturn = new GenChunk();
|
GenChunk toReturn = new GenChunk(getMin().getY(), getMax().getY());
|
||||||
if (this.result != null) {
|
if (this.result != null) {
|
||||||
for (int i = 0; i < this.result.length; i++) {
|
for (int i = 0; i < this.result.length; i++) {
|
||||||
BlockState[] matrix = this.result[i];
|
BlockState[] matrix = this.result[i];
|
||||||
|
@ -276,7 +276,9 @@ public class BukkitRegionManager extends RegionManager {
|
|||||||
PlotLoc plotLoc = new PlotLoc(bx + x1, bz + z1);
|
PlotLoc plotLoc = new PlotLoc(bx + x1, bz + z1);
|
||||||
BaseBlock[] ids = map.allBlocks.get(plotLoc);
|
BaseBlock[] ids = map.allBlocks.get(plotLoc);
|
||||||
if (ids != null) {
|
if (ids != null) {
|
||||||
for (int y = 0; y < Math.min(128, ids.length); y++) {
|
int minY = value.getMin().getY();
|
||||||
|
for (int yIndex = 0; yIndex < Math.min(128 - minY, ids.length); yIndex++) {
|
||||||
|
int y = yIndex + minY;
|
||||||
BaseBlock id = ids[y];
|
BaseBlock id = ids[y];
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
value.setBlock(x1, y, z1, id);
|
value.setBlock(x1, y, z1, id);
|
||||||
@ -284,7 +286,8 @@ public class BukkitRegionManager extends RegionManager {
|
|||||||
value.setBlock(x1, y, z1, BlockTypes.AIR.getDefaultState());
|
value.setBlock(x1, y, z1, BlockTypes.AIR.getDefaultState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int y = Math.min(128, ids.length); y < ids.length; y++) {
|
for (int yIndex = Math.min(128 - minY, ids.length); yIndex < ids.length; yIndex++) {
|
||||||
|
int y = yIndex + minY;
|
||||||
BaseBlock id = ids[y];
|
BaseBlock id = ids[y];
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
value.setBlock(x1, y, z1, id);
|
value.setBlock(x1, y, z1, id);
|
||||||
|
@ -246,7 +246,9 @@ public class BukkitUtil extends WorldUtil {
|
|||||||
final World bukkitWorld = Objects.requireNonNull(getWorld(world));
|
final World bukkitWorld = Objects.requireNonNull(getWorld(world));
|
||||||
// Skip top and bottom block
|
// Skip top and bottom block
|
||||||
int air = 1;
|
int air = 1;
|
||||||
for (int y = bukkitWorld.getMaxHeight() - 1; y >= 0; y--) {
|
int maxY = com.plotsquared.bukkit.util.BukkitWorld.getMaxWorldHeight(bukkitWorld);
|
||||||
|
int minY = com.plotsquared.bukkit.util.BukkitWorld.getMinWorldHeight(bukkitWorld);
|
||||||
|
for (int y = maxY - 1; y >= minY; y--) {
|
||||||
Block block = bukkitWorld.getBlockAt(x, y, z);
|
Block block = bukkitWorld.getBlockAt(x, y, z);
|
||||||
Material type = block.getType();
|
Material type = block.getType();
|
||||||
if (type.isSolid()) {
|
if (type.isSolid()) {
|
||||||
@ -273,7 +275,9 @@ public class BukkitUtil extends WorldUtil {
|
|||||||
final World bukkitWorld = Objects.requireNonNull(getWorld(world));
|
final World bukkitWorld = Objects.requireNonNull(getWorld(world));
|
||||||
// Skip top and bottom block
|
// Skip top and bottom block
|
||||||
int air = 1;
|
int air = 1;
|
||||||
for (int y = bukkitWorld.getMaxHeight() - 1; y >= 0; y--) {
|
int maxY = com.plotsquared.bukkit.util.BukkitWorld.getMaxWorldHeight(bukkitWorld);
|
||||||
|
int minY = com.plotsquared.bukkit.util.BukkitWorld.getMinWorldHeight(bukkitWorld);
|
||||||
|
for (int y = maxY - 1; y >= minY; y--) {
|
||||||
Block block = bukkitWorld.getBlockAt(x, y, z);
|
Block block = bukkitWorld.getBlockAt(x, y, z);
|
||||||
Material type = block.getType();
|
Material type = block.getType();
|
||||||
if (type.isSolid()) {
|
if (type.isSolid()) {
|
||||||
|
@ -36,6 +36,18 @@ import java.util.Objects;
|
|||||||
public class BukkitWorld implements World<org.bukkit.World> {
|
public class BukkitWorld implements World<org.bukkit.World> {
|
||||||
|
|
||||||
private static final Map<String, BukkitWorld> worldMap = Maps.newHashMap();
|
private static final Map<String, BukkitWorld> worldMap = Maps.newHashMap();
|
||||||
|
private static final boolean HAS_MIN_Y;
|
||||||
|
|
||||||
|
static {
|
||||||
|
boolean temp;
|
||||||
|
try {
|
||||||
|
org.bukkit.World.class.getMethod("getMinHeight");
|
||||||
|
temp = true;
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
temp = false;
|
||||||
|
}
|
||||||
|
HAS_MIN_Y = temp;
|
||||||
|
}
|
||||||
|
|
||||||
private final org.bukkit.World world;
|
private final org.bukkit.World world;
|
||||||
|
|
||||||
@ -73,6 +85,24 @@ public class BukkitWorld implements World<org.bukkit.World> {
|
|||||||
return bukkitWorld;
|
return bukkitWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the min world height from a Bukkit {@link org.bukkit.World}. Inclusive
|
||||||
|
*
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
public static int getMinWorldHeight(org.bukkit.World world) {
|
||||||
|
return HAS_MIN_Y ? world.getMinHeight() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the max world height from a Bukkit {@link org.bukkit.World}. Exclusive
|
||||||
|
*
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
public static int getMaxWorldHeight(org.bukkit.World world) {
|
||||||
|
return HAS_MIN_Y ? world.getMaxHeight() : 256;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public org.bukkit.World getPlatformWorld() {
|
public org.bukkit.World getPlatformWorld() {
|
||||||
return this.world;
|
return this.world;
|
||||||
@ -83,6 +113,16 @@ public class BukkitWorld implements World<org.bukkit.World> {
|
|||||||
return this.world.getName();
|
return this.world.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinHeight() {
|
||||||
|
return getMinWorldHeight(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxHeight() {
|
||||||
|
return getMaxWorldHeight(world);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object o) {
|
public boolean equals(final Object o) {
|
||||||
if (this == o) {
|
if (this == o) {
|
||||||
|
@ -70,7 +70,7 @@ public class ContentMap {
|
|||||||
}
|
}
|
||||||
for (int x = x1; x <= x2; x++) {
|
for (int x = x1; x <= x2; x++) {
|
||||||
for (int z = z1; z <= z2; z++) {
|
for (int z = z1; z <= z2; z++) {
|
||||||
saveBlocks(world, 256, x, z, 0, 0);
|
saveBlocks(world, x, z, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,13 +134,11 @@ public class ContentMap {
|
|||||||
this.entities.clear();
|
this.entities.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo optimize maxY
|
private void saveBlocks(BukkitWorld world, int x, int z, int offsetX, int offsetZ) {
|
||||||
void saveBlocks(BukkitWorld world, int maxY, int x, int z, int offsetX, int offsetZ) {
|
BaseBlock[] ids = new BaseBlock[world.getMaxY() - world.getMinY()];
|
||||||
maxY = Math.min(255, maxY);
|
for (short yIndex = 0; yIndex <= world.getMaxY() - world.getMinY(); yIndex++) {
|
||||||
BaseBlock[] ids = new BaseBlock[maxY + 1];
|
BaseBlock block = world.getFullBlock(BlockVector3.at(x, yIndex + world.getMinY(), z));
|
||||||
for (short y = 0; y <= maxY; y++) {
|
ids[yIndex] = block;
|
||||||
BaseBlock block = world.getFullBlock(BlockVector3.at(x, y, z));
|
|
||||||
ids[y] = block;
|
|
||||||
}
|
}
|
||||||
PlotLoc loc = new PlotLoc(x + offsetX, z + offsetZ);
|
PlotLoc loc = new PlotLoc(x + offsetX, z + offsetZ);
|
||||||
this.allBlocks.put(loc, ids);
|
this.allBlocks.put(loc, ids);
|
||||||
|
@ -58,6 +58,21 @@ public interface World<T> {
|
|||||||
*/
|
*/
|
||||||
@NonNull String getName();
|
@NonNull String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the min world height. Inclusive.
|
||||||
|
*
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
int getMinHeight();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the max world height. Exclusive.
|
||||||
|
*
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
int getMaxHeight();
|
||||||
|
|
||||||
class NullWorld<T> implements World<T> {
|
class NullWorld<T> implements World<T> {
|
||||||
|
|
||||||
private NullWorld() {
|
private NullWorld() {
|
||||||
@ -74,6 +89,16 @@ public interface World<T> {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinHeight() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxHeight() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object obj) {
|
public boolean equals(final Object obj) {
|
||||||
return obj instanceof NullWorld;
|
return obj instanceof NullWorld;
|
||||||
|
@ -42,6 +42,7 @@ public class LocalChunk {
|
|||||||
private final QueueCoordinator parent;
|
private final QueueCoordinator parent;
|
||||||
private final int x;
|
private final int x;
|
||||||
private final int z;
|
private final int z;
|
||||||
|
private final int minSection;
|
||||||
|
|
||||||
private final BaseBlock[][] baseblocks;
|
private final BaseBlock[][] baseblocks;
|
||||||
private final BiomeType[][] biomes;
|
private final BiomeType[][] biomes;
|
||||||
@ -52,8 +53,10 @@ public class LocalChunk {
|
|||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
baseblocks = new BaseBlock[16][];
|
this.minSection = parent.getWorld() != null ? (parent.getWorld().getMinY() >> 4) : 0;
|
||||||
biomes = new BiomeType[16][];
|
int sections = parent.getWorld() != null ? (parent.getWorld().getMaxY() >> 4) - minSection : 16;
|
||||||
|
baseblocks = new BaseBlock[sections][];
|
||||||
|
biomes = new BiomeType[sections][];
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull QueueCoordinator getParent() {
|
public @NonNull QueueCoordinator getParent() {
|
||||||
@ -68,6 +71,13 @@ public class LocalChunk {
|
|||||||
return this.z;
|
return this.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the minimum layer position stored (usually -4 or 0).
|
||||||
|
*/
|
||||||
|
public int getMinSection() {
|
||||||
|
return this.minSection;
|
||||||
|
}
|
||||||
|
|
||||||
public @NonNull BaseBlock[][] getBaseblocks() {
|
public @NonNull BaseBlock[][] getBaseblocks() {
|
||||||
return this.baseblocks;
|
return this.baseblocks;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,8 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||||||
*/
|
*/
|
||||||
public class ScopedQueueCoordinator extends DelegateQueueCoordinator {
|
public class ScopedQueueCoordinator extends DelegateQueueCoordinator {
|
||||||
|
|
||||||
|
private final Location min;
|
||||||
|
private final Location max;
|
||||||
private final int minX;
|
private final int minX;
|
||||||
private final int minY;
|
private final int minY;
|
||||||
private final int minZ;
|
private final int minZ;
|
||||||
@ -53,6 +55,8 @@ public class ScopedQueueCoordinator extends DelegateQueueCoordinator {
|
|||||||
|
|
||||||
public ScopedQueueCoordinator(@Nullable QueueCoordinator parent, @NonNull Location min, @NonNull Location max) {
|
public ScopedQueueCoordinator(@Nullable QueueCoordinator parent, @NonNull Location min, @NonNull Location max) {
|
||||||
super(parent);
|
super(parent);
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
this.minX = min.getX();
|
this.minX = min.getX();
|
||||||
this.minY = min.getY();
|
this.minY = min.getY();
|
||||||
this.minZ = min.getZ();
|
this.minZ = min.getZ();
|
||||||
@ -112,11 +116,11 @@ public class ScopedQueueCoordinator extends DelegateQueueCoordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull Location getMin() {
|
public @NonNull Location getMin() {
|
||||||
return Location.at(this.getWorld().getName(), this.minX, this.minY, this.minZ);
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull Location getMax() {
|
public @NonNull Location getMax() {
|
||||||
return Location.at(this.getWorld().getName(), this.maxX, this.maxY, this.maxZ);
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,13 +39,13 @@ public class ChunkUtil {
|
|||||||
* - Used for efficient world generation<br>
|
* - Used for efficient world generation<br>
|
||||||
*/
|
*/
|
||||||
private static final short[] x_loc;
|
private static final short[] x_loc;
|
||||||
private static final short[][] y_loc;
|
private static final short[] y_loc;
|
||||||
private static final short[] z_loc;
|
private static final short[] z_loc;
|
||||||
private static final short[][][] CACHE_J;
|
private static final short[][][] CACHE_J;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
x_loc = new short[4096];
|
x_loc = new short[4096];
|
||||||
y_loc = new short[16][4096];
|
y_loc = new short[4096];
|
||||||
z_loc = new short[4096];
|
z_loc = new short[4096];
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
int i4 = i << 4;
|
int i4 = i << 4;
|
||||||
@ -55,14 +55,14 @@ public class ChunkUtil {
|
|||||||
int z1 = a >> 4;
|
int z1 = a >> 4;
|
||||||
int x1 = a - (z1 << 4);
|
int x1 = a - (z1 << 4);
|
||||||
x_loc[j] = (short) x1;
|
x_loc[j] = (short) x1;
|
||||||
y_loc[i][j] = (short) y;
|
y_loc[j] = (short) y;
|
||||||
z_loc[j] = (short) z1;
|
z_loc[j] = (short) z1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CACHE_J = new short[256][16][16];
|
CACHE_J = new short[16][16][16];
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
for (int y = 0; y < 256; y++) {
|
for (int y = 0; y < 16; y++) {
|
||||||
short j = (short) ((y & 0xF) << 8 | z << 4 | x);
|
short j = (short) ((y & 0xF) << 8 | z << 4 | x);
|
||||||
CACHE_J[y][x][z] = j;
|
CACHE_J[y][x][z] = j;
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ public class ChunkUtil {
|
|||||||
* @return J value for xyz position in Array[4096].
|
* @return J value for xyz position in Array[4096].
|
||||||
*/
|
*/
|
||||||
public static int getJ(int x, int y, int z) {
|
public static int getJ(int x, int y, int z) {
|
||||||
return CACHE_J[y][x][z];
|
return CACHE_J[y & 15][x & 15][z & 15];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,14 +97,14 @@ public class ChunkUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the y coordinate for specific I and J values for a Chunk 16x16x16x16 layerxyz Array[16][4096].
|
* Gets the y coordinate for specific I and J values for a Chunk 16x16x16x16 layerxyz Array[N][4096].
|
||||||
*
|
*
|
||||||
* @param i Relative layer of the position in the layerxyz Array[16][4096].
|
* @param i Relative layer of the position in the layerxyz Array[16][4096]. May be negative.
|
||||||
* @param j Position in the xyz Array[4096].
|
* @param j Position in the xyz Array[4096].
|
||||||
* @return x coordinate within the chunk
|
* @return x coordinate within the chunk
|
||||||
*/
|
*/
|
||||||
public static int getY(int i, int j) {
|
public static int getY(int i, int j) {
|
||||||
return y_loc[i][j];
|
return (i << 4) + y_loc[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user