diff --git a/src/org/bukkit/craftbukkit/CraftBlock.java b/src/org/bukkit/craftbukkit/CraftBlock.java new file mode 100644 index 0000000000..0f40dd78ed --- /dev/null +++ b/src/org/bukkit/craftbukkit/CraftBlock.java @@ -0,0 +1,127 @@ + +package org.bukkit.craftbukkit; + +import org.bukkit.*; + +public class CraftBlock implements Block { + private final World world; + private final Chunk chunk; + private final int x; + private final int y; + private final int z; + private int type; + private byte data; + + protected CraftBlock(final World world, final int x, final int y, final int z, final int type, final byte data) { + this.world = world; + this.x = x; + this.y = y; + this.z = z; + this.type = type; + this.data = data; + this.chunk = world.getChunkAt(x << 4, z << 4); + } + + /** + * 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; + } + + /** + * Gets the metadata for this block + * + * @return block specific metadata + */ + public byte getData() { + return data; + } + + /** + * Sets the type-ID of this block + * + * @param type Type-ID to change this block to + */ + public void setType(final int type) { + this.type = type; + } + + /** + * Gets the type-ID of this block + * + * @return block type-ID + */ + public int getType() { + return type; + } + + /** + * 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) { + return getRelative(face.getModX(), face.getModY(), face.getModZ()); + } + + /** + * 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); + } +} diff --git a/src/org/bukkit/craftbukkit/CraftChunk.java b/src/org/bukkit/craftbukkit/CraftChunk.java new file mode 100644 index 0000000000..2fe28212ce --- /dev/null +++ b/src/org/bukkit/craftbukkit/CraftChunk.java @@ -0,0 +1,32 @@ + +package org.bukkit.craftbukkit; + +import org.bukkit.Chunk; + +public class CraftChunk implements Chunk { + private final int x; + private final int z; + + protected CraftChunk(final int x, final int z) { + this.x = x; + this.z = z; + } + + /** + * Gets the X-coordinate of this chunk + * + * @return X-coordinate + */ + public int getX() { + return x; + } + + /** + * Gets the Z-coordinate of this chunk + * + * @return Z-coordinate + */ + public int getZ() { + return z; + } +} diff --git a/src/org/bukkit/craftbukkit/CraftPlayer.java b/src/org/bukkit/craftbukkit/CraftPlayer.java index 643dea160f..9e720c5a1a 100644 --- a/src/org/bukkit/craftbukkit/CraftPlayer.java +++ b/src/org/bukkit/craftbukkit/CraftPlayer.java @@ -2,7 +2,9 @@ package org.bukkit.craftbukkit; import net.minecraft.server.EntityPlayerMP; +import org.bukkit.Location; import org.bukkit.Player; +import org.bukkit.World; public class CraftPlayer implements Player { private EntityPlayerMP player; @@ -22,4 +24,12 @@ public class CraftPlayer implements Player { public boolean isOnline() { return server.server.g(name); } + + public Location getLocation() { + return new Location(getWorld(), player.p, player.q, player.r); + } + + public World getWorld() { + return server.getWorld(player.b.e); + } } diff --git a/src/org/bukkit/craftbukkit/CraftServer.java b/src/org/bukkit/craftbukkit/CraftServer.java index c6aaec7e7a..db3f119bd5 100644 --- a/src/org/bukkit/craftbukkit/CraftServer.java +++ b/src/org/bukkit/craftbukkit/CraftServer.java @@ -6,9 +6,11 @@ import java.util.HashMap; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import net.minecraft.server.EntityPlayerMP; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.ServerConfigurationManager; +import net.minecraft.server.WorldServer; import org.bukkit.*; -import net.minecraft.server.*; -import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.SimplePluginManager; import org.bukkit.plugin.java.JavaPluginLoader; @@ -17,6 +19,7 @@ public final class CraftServer implements Server { private final String serverName = "Craftbukkit"; private final String serverVersion; private final HashMap playerCache = new HashMap(); + private final HashMap worldCache = new HashMap(); private final PluginManager pluginManager = new SimplePluginManager(this); protected final MinecraftServer console; @@ -82,4 +85,19 @@ public final class CraftServer implements Server { public PluginManager getPluginManager() { return pluginManager; } + + public World[] getWorlds() { + return new World[] { getWorld(console.e) }; + } + + public World getWorld(WorldServer world) { + World result = worldCache.get(world); + + if (result == null) { + result = new CraftWorld(world); + worldCache.put(world, result); + } + + return result; + } } diff --git a/src/org/bukkit/craftbukkit/CraftWorld.java b/src/org/bukkit/craftbukkit/CraftWorld.java new file mode 100644 index 0000000000..304f307985 --- /dev/null +++ b/src/org/bukkit/craftbukkit/CraftWorld.java @@ -0,0 +1,129 @@ + +package org.bukkit.craftbukkit; + +import java.util.HashMap; +import java.util.Map; +import net.minecraft.server.WorldServer; +import org.bukkit.Block; +import org.bukkit.Chunk; +import org.bukkit.World; + +public class CraftWorld implements World { + private final Map chunkCache = new HashMap(); + private final Map blockCache = new HashMap(); + private final WorldServer world; + + protected CraftWorld(WorldServer world) { + this.world = world; + } + + public Block getBlockAt(int x, int y, int z) { + BlockCoordinate loc = new BlockCoordinate(x, y, z); + Block block = blockCache.get(loc); + + if (block == null) { + block = new CraftBlock(this, x, y, z, world.a(x, y, z), (byte)world.b(x, y, z)); + blockCache.put(loc, block); + } + + return block; + } + + public Chunk getChunkAt(int x, int z) { + ChunkCoordinate loc = new ChunkCoordinate(x, z); + Chunk chunk = chunkCache.get(loc); + + if (chunk == null) { + chunk = new CraftChunk(x, z); + chunkCache.put(loc, chunk); + } + + return chunk; + } + + public Chunk getChunkAt(Block block) { + return getChunkAt(block.getX() << 4, block.getZ() << 4); + } + + public boolean isChunkLoaded() { + throw new UnsupportedOperationException("Not supported yet."); + } + + private final class ChunkCoordinate { + public final int x; + public final int z; + + public ChunkCoordinate(final int x, final int z) { + this.x = x; + this.z = z; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ChunkCoordinate other = (ChunkCoordinate) obj; + if (this.x != other.x) { + return false; + } + if (this.z != other.z) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 53 * hash + this.x; + hash = 53 * hash + this.z; + return hash; + } + } + + 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; + } + } +}