package net.glowstone.block; import net.glowstone.GlowWorld; import net.glowstone.chunk.GlowChunk; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.material.MaterialData; import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.Plugin; import java.util.List; /** * Represents a state a block could be in as well as any block entities. */ public class GlowBlockState implements BlockState { private final GlowWorld world; private final int x; private final int y; private final int z; private final byte light; protected int type; protected MaterialData data; private boolean flowed; //////////////////////////////////////////////////////////////////////////// // Basics public GlowBlockState(GlowBlock block) { world = block.getWorld(); x = block.getX(); y = block.getY(); z = block.getZ(); type = block.getTypeId(); light = block.getLightLevel(); makeData(block.getData()); } @Override public GlowWorld getWorld() { return world; } @Override public GlowChunk getChunk() { return getBlock().getChunk(); } @Override public GlowBlock getBlock() { return world.getBlockAt(x, y, z); } @Override public int getX() { return x; } @Override public int getY() { return y; } @Override public int getZ() { return z; } @Override public Location getLocation() { return getBlock().getLocation(); } //////////////////////////////////////////////////////////////////////////// // Type and data @Override public Location getLocation(Location loc) { return getBlock().getLocation(loc); } @Override public final Material getType() { return Material.getMaterial(type); } @Override public final void setType(Material type) { setTypeId(type.getId()); } @Override public final int getTypeId() { return type; } @Override public final boolean setTypeId(int type) { this.type = type; makeData((byte) 0); return true; } @Override public final MaterialData getData() { return data; } @Override public final void setData(MaterialData data) { this.data = data; } @Override public final byte getRawData() { return getData().getData(); } @Override public final void setRawData(byte data) { getData().setData(data); } @Override public boolean isPlaced() { return world != null; // TODO: is this sufficient? } //////////////////////////////////////////////////////////////////////////// // Update @Override public final byte getLightLevel() { return light; } @Override public final boolean update() { return update(false, true); } @Override public final boolean update(boolean force) { return update(force, true); } @Override public boolean update(boolean force, boolean applyPhysics) { Block block = getBlock(); return (block.getTypeId() == type || force) && block.setTypeIdAndData(type, getRawData(), applyPhysics); } public boolean getFlowed() { return flowed; } public void setFlowed(boolean flowed) { this.flowed = flowed; } //////////////////////////////////////////////////////////////////////////// // Internals private void makeData(byte data) { Material mat = Material.getMaterial(type); if (mat == null) { this.data = new MaterialData(type, data); } else { this.data = mat.getNewData(data); } } //////////////////////////////////////////////////////////////////////////// // Metadata @Override public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { getBlock().setMetadata(metadataKey, newMetadataValue); } @Override public List<MetadataValue> getMetadata(String metadataKey) { return getBlock().getMetadata(metadataKey); } @Override public boolean hasMetadata(String metadataKey) { return getBlock().hasMetadata(metadataKey); } @Override public void removeMetadata(String metadataKey, Plugin owningPlugin) { getBlock().removeMetadata(metadataKey, owningPlugin); } @Override public int hashCode() { int prime = 31; int result = 1; result = prime * result + (world != null ? world.hashCode() : 0); result = prime * result + x; result = prime * result + y; result = prime * result + z; result = prime * result + type; result = prime * result + (data != null ? data.hashCode() : 0); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; GlowBlockState other = (GlowBlockState) obj; if (data == null) { if (other.data != null) return false; } else if (!data.equals(other.data)) return false; if (type != other.type) return false; if (world == null) { if (other.world != null) return false; } else if (!world.equals(other.world)) return false; return x == other.x && y == other.y && z == other.z; } }