2010-12-27 03:13:03 +01:00
|
|
|
|
|
|
|
package org.bukkit.craftbukkit;
|
|
|
|
|
|
|
|
import org.bukkit.*;
|
|
|
|
|
|
|
|
public class CraftBlock implements Block {
|
2010-12-29 02:07:57 +01:00
|
|
|
private final CraftWorld world;
|
|
|
|
private final CraftChunk chunk;
|
2010-12-27 03:13:03 +01:00
|
|
|
private final int x;
|
|
|
|
private final int y;
|
|
|
|
private final int z;
|
2010-12-29 00:52:29 +01:00
|
|
|
protected int type;
|
|
|
|
protected byte data;
|
2011-01-03 03:30:46 +01:00
|
|
|
protected byte light;
|
2010-12-27 03:13:03 +01:00
|
|
|
|
2010-12-29 02:07:57 +01:00
|
|
|
protected CraftBlock(final CraftWorld world, final int x, final int y, final int z, final int type, final byte data) {
|
2010-12-27 03:13:03 +01:00
|
|
|
this.world = world;
|
|
|
|
this.x = x;
|
|
|
|
this.y = y;
|
|
|
|
this.z = z;
|
|
|
|
this.type = type;
|
|
|
|
this.data = data;
|
2011-01-03 03:30:46 +01:00
|
|
|
this.light = (byte)world.getHandle().i(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;
|
2010-12-29 02:07:57 +01:00
|
|
|
this.chunk = (CraftChunk)world.getChunkAt(x << 4, z << 4);
|
2010-12-27 03:13:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the world which contains this Block
|
|
|
|
*
|
|
|
|
* @return World containing this block
|
|
|
|
*/
|
|
|
|
public World getWorld() {
|
|
|
|
return world;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the x-coordinate of this block
|
|
|
|
*
|
|
|
|
* @return x-coordinate
|
|
|
|
*/
|
|
|
|
public int getX() {
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the y-coordinate of this block
|
|
|
|
*
|
|
|
|
* @return y-coordinate
|
|
|
|
*/
|
|
|
|
public int getY() {
|
|
|
|
return y;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the z-coordinate of this block
|
|
|
|
*
|
|
|
|
* @return z-coordinate
|
|
|
|
*/
|
|
|
|
public int getZ() {
|
|
|
|
return z;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the chunk which contains this block
|
|
|
|
*
|
|
|
|
* @return Containing Chunk
|
|
|
|
*/
|
|
|
|
public Chunk getChunk() {
|
|
|
|
return chunk;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the metadata for this block
|
|
|
|
*
|
|
|
|
* @param data New block specific metadata
|
|
|
|
*/
|
|
|
|
public void setData(final byte data) {
|
|
|
|
this.data = data;
|
2010-12-29 02:07:57 +01:00
|
|
|
world.getHandle().c(x, y, z, data);
|
2010-12-27 03:13:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the metadata for this block
|
|
|
|
*
|
|
|
|
* @return block specific metadata
|
|
|
|
*/
|
|
|
|
public byte getData() {
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2011-01-01 08:05:05 +01:00
|
|
|
/**
|
|
|
|
* Sets the type of this block
|
|
|
|
*
|
|
|
|
* @param type Material to change this block to
|
|
|
|
*/
|
|
|
|
public void setType(final Material type) {
|
|
|
|
setTypeID(type.getID());
|
|
|
|
}
|
|
|
|
|
2010-12-27 03:13:03 +01:00
|
|
|
/**
|
|
|
|
* Sets the type-ID of this block
|
|
|
|
*
|
|
|
|
* @param type Type-ID to change this block to
|
|
|
|
*/
|
2011-01-01 08:05:05 +01:00
|
|
|
public void setTypeID(final int type) {
|
2010-12-27 03:13:03 +01:00
|
|
|
this.type = type;
|
2010-12-29 02:07:57 +01:00
|
|
|
world.getHandle().d(x, y, z, type);
|
2010-12-27 03:13:03 +01:00
|
|
|
}
|
|
|
|
|
2011-01-01 08:05:05 +01:00
|
|
|
/**
|
|
|
|
* Gets the type of this block
|
|
|
|
*
|
|
|
|
* @return block type
|
|
|
|
*/
|
|
|
|
public Material getType() {
|
|
|
|
return Material.getMaterial(getTypeID());
|
|
|
|
}
|
|
|
|
|
2010-12-27 03:13:03 +01:00
|
|
|
/**
|
|
|
|
* Gets the type-ID of this block
|
|
|
|
*
|
|
|
|
* @return block type-ID
|
|
|
|
*/
|
2011-01-01 08:05:05 +01:00
|
|
|
public int getTypeID() {
|
2010-12-27 03:13:03 +01:00
|
|
|
return type;
|
|
|
|
}
|
2011-01-03 03:30:46 +01:00
|
|
|
|
|
|
|
/**
|
2011-01-03 04:25:58 +01:00
|
|
|
* Gets the light level between 0-15
|
2011-01-03 03:30:46 +01:00
|
|
|
*
|
|
|
|
* @return light level
|
|
|
|
*/
|
2011-01-03 04:25:58 +01:00
|
|
|
public byte getLightLevel() {
|
2011-01-03 03:30:46 +01:00
|
|
|
return light;
|
|
|
|
}
|
2010-12-27 03:13:03 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the block at the given face
|
|
|
|
*
|
|
|
|
* @param face Face of this block to return
|
|
|
|
* @return Block at the given face
|
|
|
|
*/
|
|
|
|
public Block getFace(final BlockFace face) {
|
2011-01-07 11:48:09 +01:00
|
|
|
return getFace(face, 1);
|
2010-12-27 03:13:03 +01:00
|
|
|
}
|
|
|
|
|
2011-01-07 11:43:51 +01:00
|
|
|
/**
|
|
|
|
* Gets the block at the given distance of the given face<br />
|
|
|
|
* <br />
|
|
|
|
* For example, the following method places water at 100,102,100; two blocks
|
|
|
|
* above 100,100,100.
|
|
|
|
* <pre>
|
|
|
|
* Block block = world.getBlockAt(100,100,100);
|
|
|
|
* Block shower = block.getFace(BlockFace.Up, 2);
|
|
|
|
* shower.setType(Material.WATER);
|
|
|
|
* </pre>
|
|
|
|
*
|
|
|
|
* @param face Face of this block to return
|
|
|
|
* @param distance Distance to get the block at
|
|
|
|
* @return Block at the given face
|
|
|
|
*/
|
|
|
|
public Block getFace(final BlockFace face, final int distance) {
|
|
|
|
return getRelative(face.getModX() * distance, face.getModY() * distance,
|
|
|
|
face.getModZ() * distance);
|
|
|
|
}
|
|
|
|
|
2010-12-27 03:13:03 +01:00
|
|
|
/**
|
|
|
|
* Gets the block at the given offsets
|
|
|
|
*
|
|
|
|
* @param modX X-coordinate offset
|
|
|
|
* @param modY Y-coordinate offset
|
|
|
|
* @param modZ Z-coordinate offset
|
|
|
|
* @return Block at the given offsets
|
|
|
|
*/
|
|
|
|
public Block getRelative(final int modX, final int modY, final int modZ) {
|
|
|
|
return getWorld().getBlockAt(getX() + modX, getY() + modY, getZ() + modZ);
|
|
|
|
}
|
2010-12-29 01:29:18 +01:00
|
|
|
|
2011-01-07 11:43:51 +01:00
|
|
|
/**
|
|
|
|
* Gets the face relation of this block compared to the given block<br />
|
|
|
|
* <br />
|
|
|
|
* For example:
|
|
|
|
* <pre>
|
|
|
|
* Block current = world.getBlockAt(100, 100, 100);
|
|
|
|
* Block target = world.getBlockAt(100, 101, 100);
|
|
|
|
*
|
|
|
|
* current.getFace(target) == BlockFace.Up;
|
|
|
|
* </pre>
|
|
|
|
* <br />
|
|
|
|
* If the given block is not connected to this block, null may be returned
|
|
|
|
*
|
|
|
|
* @param block Block to compare against this block
|
|
|
|
* @return BlockFace of this block which has the requested block, or null
|
|
|
|
*/
|
|
|
|
public BlockFace getFace(final Block block) {
|
|
|
|
BlockFace[] values = BlockFace.values();
|
|
|
|
|
|
|
|
for (BlockFace face : values) {
|
|
|
|
if (
|
|
|
|
(this.getX() + face.getModX() == block.getX()) &&
|
|
|
|
(this.getY() + face.getModY() == block.getY()) &&
|
|
|
|
(this.getZ() + face.getModZ() == block.getZ())
|
|
|
|
) {
|
|
|
|
return face;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2010-12-29 01:29:18 +01:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return "CraftBlock{" + "world=" + world + "x=" + x + "y=" + y + "z=" + z + "type=" + type + "data=" + data + '}';
|
|
|
|
}
|
2011-01-02 11:29:51 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Notch uses a 0-5 to mean Down, Up, East, West, North, South
|
2011-01-03 04:31:32 +01:00
|
|
|
* in that order all over. This method is convenience to convert for us.
|
2011-01-02 11:29:51 +01:00
|
|
|
*
|
|
|
|
* @return BlockFace the BlockFace represented by this number
|
|
|
|
*/
|
|
|
|
public static BlockFace notchToBlockFace(int notch) {
|
|
|
|
switch (notch) {
|
|
|
|
case 0:
|
|
|
|
return BlockFace.Down;
|
|
|
|
case 1:
|
|
|
|
return BlockFace.Up;
|
|
|
|
case 2:
|
|
|
|
return BlockFace.East;
|
|
|
|
case 3:
|
|
|
|
return BlockFace.West;
|
|
|
|
case 4:
|
|
|
|
return BlockFace.North;
|
|
|
|
case 5:
|
|
|
|
return BlockFace.South;
|
|
|
|
default:
|
|
|
|
return BlockFace.Self;
|
|
|
|
}
|
|
|
|
}
|
2010-12-27 03:13:03 +01:00
|
|
|
}
|