mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-16 22:43:14 +01:00
Update chunk handling.
By: Erik Broes <erikbroes@grum.nl>
This commit is contained in:
parent
defe56d4a9
commit
db46d059ce
3 changed files with 58 additions and 171 deletions
|
@ -1,49 +1,51 @@
|
||||||
|
|
||||||
package org.bukkit.craftbukkit;
|
package org.bukkit.craftbukkit;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import net.minecraft.server.WorldServer;
|
||||||
|
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||||
|
|
||||||
public class CraftChunk implements Chunk {
|
public class CraftChunk implements Chunk {
|
||||||
private final CraftWorld world;
|
private final net.minecraft.server.Chunk chunk;
|
||||||
private final int x;
|
private final HashMap<Integer, Block> cache = new HashMap<Integer, Block>();
|
||||||
private final int z;
|
|
||||||
|
|
||||||
protected CraftChunk(final CraftWorld world, final int x, final int z) {
|
public CraftChunk(net.minecraft.server.Chunk chunk) {
|
||||||
this.world = world;
|
this.chunk = chunk;
|
||||||
this.x = x;
|
|
||||||
this.z = z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the world containing this chunk
|
|
||||||
*
|
|
||||||
* @return World
|
|
||||||
*/
|
|
||||||
public World getWorld() {
|
public World getWorld() {
|
||||||
return world;
|
return ((WorldServer) chunk.d).getWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
public net.minecraft.server.Chunk getHandle() {
|
||||||
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the X-coordinate of this chunk
|
|
||||||
*
|
|
||||||
* @return X-coordinate
|
|
||||||
*/
|
|
||||||
public int getX() {
|
public int getX() {
|
||||||
return x;
|
return chunk.j;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Z-coordinate of this chunk
|
|
||||||
*
|
|
||||||
* @return Z-coordinate
|
|
||||||
*/
|
|
||||||
public int getZ() {
|
public int getZ() {
|
||||||
return z;
|
return chunk.k;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "CraftChunk{" + "x=" + x + "z=" + z + '}';
|
return "CraftChunk{" + "x=" + getX() + "z=" + getZ() + '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getBlock(int x, int y, int z) {
|
||||||
|
int pos = (x & 0xF) << 11 | (z & 0xF) << 7 | (y & 0x7F);
|
||||||
|
Block block = this.cache.get( pos );
|
||||||
|
if (block == null) {
|
||||||
|
block = new CraftBlock( this, (getX() << 4) | (x & 0xF), y & 0x7F, (getZ() << 4) | (z & 0xF) );
|
||||||
|
this.cache.put( pos, block );
|
||||||
|
}
|
||||||
|
return block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.bukkit.craftbukkit;
|
package org.bukkit.craftbukkit;
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.block.CraftBlock;
|
|
||||||
import org.bukkit.craftbukkit.entity.*;
|
import org.bukkit.craftbukkit.entity.*;
|
||||||
import org.bukkit.entity.*;
|
import org.bukkit.entity.*;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
@ -24,8 +23,6 @@ import org.bukkit.TreeType;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
public class CraftWorld implements World {
|
public class CraftWorld implements World {
|
||||||
private final Map<ChunkCoordinate, CraftChunk> chunkCache = new HashMap<ChunkCoordinate, CraftChunk>();
|
|
||||||
private final Map<BlockCoordinate, CraftBlock> blockCache = new HashMap<BlockCoordinate, CraftBlock>();
|
|
||||||
private final WorldServer world;
|
private final WorldServer world;
|
||||||
|
|
||||||
private static final Random rand = new Random();
|
private static final Random rand = new Random();
|
||||||
|
@ -35,17 +32,7 @@ public class CraftWorld implements World {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block getBlockAt(int x, int y, int z) {
|
public Block getBlockAt(int x, int y, int z) {
|
||||||
BlockCoordinate loc = new BlockCoordinate(x, y, z);
|
return getChunkAt(x >> 4, z >> 4).getBlock(x & 0xF, y & 0x7F, z & 0xF);
|
||||||
CraftBlock block = blockCache.get(loc);
|
|
||||||
|
|
||||||
if (block == null) {
|
|
||||||
block = new CraftBlock(this, x, y, z, world.getTypeId(x, y, z), (byte)world.getData(x, y, z));
|
|
||||||
blockCache.put(loc, block);
|
|
||||||
} else {
|
|
||||||
block.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
return block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBlockTypeIdAt(int x, int y, int z) {
|
public int getBlockTypeIdAt(int x, int y, int z) {
|
||||||
|
@ -61,60 +48,28 @@ public class CraftWorld implements World {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Chunk getChunkAt(int x, int z) {
|
public Chunk getChunkAt(int x, int z) {
|
||||||
ChunkCoordinate loc = new ChunkCoordinate(x, z);
|
return this.world.A.d(x,z).bukkitChunk;
|
||||||
CraftChunk chunk = chunkCache.get(loc);
|
|
||||||
|
|
||||||
if (chunk == null) {
|
|
||||||
chunk = new CraftChunk(this, x, z);
|
|
||||||
chunkCache.put(loc, chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
return chunk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Chunk getChunkAt(Block block) {
|
public Chunk getChunkAt(Block block) {
|
||||||
return getChunkAt(block.getX() >> 4, block.getZ() >> 4);
|
return getChunkAt(block.getX() >> 4, block.getZ() >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isChunkLoaded(int x, int z) {
|
||||||
|
return world.A.a( x, z );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadChunk(int x, int z) {
|
||||||
|
world.A.d(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isChunkLoaded(Chunk chunk) {
|
public boolean isChunkLoaded(Chunk chunk) {
|
||||||
return world.A.a(chunk.getX(), chunk.getZ());
|
return isChunkLoaded(chunk.getX(), chunk.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadChunk(Chunk chunk) {
|
public void loadChunk(Chunk chunk) {
|
||||||
world.A.d(chunk.getX(), chunk.getZ());
|
loadChunk(chunk.getX(), chunk.getZ());
|
||||||
}
|
((CraftChunk) getChunkAt(chunk.getX(), chunk.getZ())).getHandle().bukkitChunk = chunk;
|
||||||
|
|
||||||
|
|
||||||
public void updateBlock(int x, int y, int z, Integer type, Integer data) {
|
|
||||||
BlockCoordinate loc = new BlockCoordinate(x, y, z);
|
|
||||||
CraftBlock block = (CraftBlock) blockCache.get(loc);
|
|
||||||
|
|
||||||
if (block == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == null) {
|
|
||||||
type = world.getTypeId(x, y, z);
|
|
||||||
}
|
|
||||||
if (data == null) {
|
|
||||||
data = world.getData(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
block.update(type, data.byteValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
public CraftChunk updateChunk(int x, int z) {
|
|
||||||
ChunkCoordinate loc = new ChunkCoordinate(x, z);
|
|
||||||
CraftChunk chunk = chunkCache.get(loc);
|
|
||||||
|
|
||||||
if (chunk == null) {
|
|
||||||
chunk = new CraftChunk(this, x, z);
|
|
||||||
chunkCache.put(loc, chunk);
|
|
||||||
} else {
|
|
||||||
// TODO: Chunk stuff
|
|
||||||
}
|
|
||||||
|
|
||||||
return chunk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WorldServer getHandle() {
|
public WorldServer getHandle() {
|
||||||
|
@ -299,48 +254,6 @@ public class CraftWorld implements World {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class BlockCoordinate {
|
|
||||||
public final int x;
|
|
||||||
public final int y;
|
|
||||||
public final int z;
|
|
||||||
|
|
||||||
public BlockCoordinate(final int x, final int y, final int z) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final BlockCoordinate other = (BlockCoordinate) obj;
|
|
||||||
if (this.x != other.x) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (this.y != other.y) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (this.z != other.z) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int hash = 7;
|
|
||||||
hash = 37 * hash + this.x;
|
|
||||||
hash = 37 * hash + this.y;
|
|
||||||
hash = 37 * hash + this.z;
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Entity> getEntities() {
|
public List<Entity> getEntities() {
|
||||||
List<Entity> list = new ArrayList<Entity>();
|
List<Entity> list = new ArrayList<Entity>();
|
||||||
|
|
||||||
|
|
|
@ -10,41 +10,20 @@ import net.minecraft.server.BiomeBase;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.craftbukkit.CraftChunk;
|
import org.bukkit.craftbukkit.CraftChunk;
|
||||||
import org.bukkit.craftbukkit.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.block.CraftBlockState;
|
import org.bukkit.craftbukkit.block.CraftBlockState;
|
||||||
import org.bukkit.craftbukkit.block.CraftSign;
|
import org.bukkit.craftbukkit.block.CraftSign;
|
||||||
|
|
||||||
public class CraftBlock implements Block {
|
public class CraftBlock implements Block {
|
||||||
private final CraftWorld world;
|
|
||||||
private final CraftChunk chunk;
|
private final CraftChunk chunk;
|
||||||
private final int x;
|
private final int x;
|
||||||
private final int y;
|
private final int y;
|
||||||
private final int z;
|
private final int z;
|
||||||
protected int type;
|
|
||||||
protected byte data;
|
|
||||||
protected byte light;
|
|
||||||
|
|
||||||
public CraftBlock(final CraftWorld world, final int x, final int y, final int z, final int type, final byte data) {
|
public CraftBlock(CraftChunk chunk, int x, int y, int z) {
|
||||||
this.world = world;
|
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
this.type = type;
|
this.chunk = chunk;
|
||||||
this.data = data;
|
|
||||||
this.light = (byte)world.getHandle().j(x, y, z);
|
|
||||||
this.chunk = (CraftChunk)world.getChunkAt(x >> 4, z >> 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected CraftBlock(final CraftWorld world, final int x, final int y,
|
|
||||||
final int z, final int type, final byte data, final byte light) {
|
|
||||||
this.world = world;
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.z = z;
|
|
||||||
this.type = type;
|
|
||||||
this.data = data;
|
|
||||||
this.light = light;
|
|
||||||
this.chunk = (CraftChunk)world.getChunkAt(x >> 4, z >> 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,7 +32,7 @@ public class CraftBlock implements Block {
|
||||||
* @return World containing this block
|
* @return World containing this block
|
||||||
*/
|
*/
|
||||||
public World getWorld() {
|
public World getWorld() {
|
||||||
return world;
|
return chunk.getWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,7 +41,7 @@ public class CraftBlock implements Block {
|
||||||
* @return Location of the block
|
* @return Location of the block
|
||||||
*/
|
*/
|
||||||
public Location getLocation() {
|
public Location getLocation() {
|
||||||
return new Location(world, x, y, z);
|
return new Location(getWorld(), x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,8 +86,7 @@ public class CraftBlock implements Block {
|
||||||
* @param data New block specific metadata
|
* @param data New block specific metadata
|
||||||
*/
|
*/
|
||||||
public void setData(final byte data) {
|
public void setData(final byte data) {
|
||||||
this.data = data;
|
chunk.getHandle().d.c(x, y, z, data);
|
||||||
world.getHandle().c(x, y, z, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,7 +95,7 @@ public class CraftBlock implements Block {
|
||||||
* @return block specific metadata
|
* @return block specific metadata
|
||||||
*/
|
*/
|
||||||
public byte getData() {
|
public byte getData() {
|
||||||
return data;
|
return (byte) chunk.getHandle().b(this.x & 0xF, this.y & 0x7F, this.z & 0xF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,8 +114,7 @@ public class CraftBlock implements Block {
|
||||||
* @return whether the block was changed
|
* @return whether the block was changed
|
||||||
*/
|
*/
|
||||||
public boolean setTypeId(final int type) {
|
public boolean setTypeId(final int type) {
|
||||||
this.type = type;
|
return chunk.getHandle().d.e(x, y, z, type);
|
||||||
return world.getHandle().e(x, y, z, type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,7 +132,7 @@ public class CraftBlock implements Block {
|
||||||
* @return block type-id
|
* @return block type-id
|
||||||
*/
|
*/
|
||||||
public int getTypeId() {
|
public int getTypeId() {
|
||||||
return type;
|
return chunk.getHandle().a(this.x & 0xF, this.y & 0x7F, this.z & 0xF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,7 +141,7 @@ public class CraftBlock implements Block {
|
||||||
* @return light level
|
* @return light level
|
||||||
*/
|
*/
|
||||||
public byte getLightLevel() {
|
public byte getLightLevel() {
|
||||||
return light;
|
return (byte) chunk.getHandle().d.j(this.x, this.y, this.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -253,7 +230,7 @@ public class CraftBlock implements Block {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "CraftBlock{" + "world=" + world + "x=" + x + "y=" + y + "z=" + z + "type=" + type + "data=" + data + '}';
|
return "CraftBlock{" + "chunk=" + chunk + "x=" + x + "y=" + y + "z=" + z + '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -307,7 +284,7 @@ public class CraftBlock implements Block {
|
||||||
|
|
||||||
public Biome getBiome() {
|
public Biome getBiome() {
|
||||||
// TODO: This may not be 100% accurate; investigate into getting per-block instead of per-chunk
|
// TODO: This may not be 100% accurate; investigate into getting per-block instead of per-chunk
|
||||||
BiomeBase base = world.getHandle().a().a(chunk.getX(), chunk.getZ());
|
BiomeBase base = chunk.getHandle().d.a().a(chunk.getX(), chunk.getZ());
|
||||||
|
|
||||||
if (base == BiomeBase.RAINFOREST) {
|
if (base == BiomeBase.RAINFOREST) {
|
||||||
return Biome.RAINFOREST;
|
return Biome.RAINFOREST;
|
||||||
|
@ -339,20 +316,15 @@ public class CraftBlock implements Block {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBlockPowered() {
|
public boolean isBlockPowered() {
|
||||||
return world.getHandle().o(x, y, z);
|
return chunk.getHandle().d.o(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBlockIndirectlyPowered() {
|
public boolean isBlockIndirectlyPowered() {
|
||||||
return world.getHandle().p(x, y, z);
|
return chunk.getHandle().d.p(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(int type, byte data) {
|
@Override
|
||||||
this.type = type;
|
public boolean equals( Object o ) {
|
||||||
this.data = data;
|
return this == o;
|
||||||
light = (byte)world.getHandle().j(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update() {
|
|
||||||
this.update( world.getHandle().getTypeId(x, y, z), (byte)world.getHandle().getData(x, y, z));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue