blob: 2fbeb2f1b3e79280ba5290594547d8594e708ed5 [file] [log] [blame] [raw]
package net.glowstone.block;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
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;
/**
* Represents a state a block could be in as well as any block entities.
*/
public class GlowBlockState implements BlockState {
@Getter
private final GlowWorld world;
@Getter
private final int x;
@Getter
private final int y;
@Getter
private final int z;
@Getter
private final byte lightLevel;
@Getter
protected int typeId;
@Getter
@Setter
protected MaterialData data;
@Getter
@Setter
private boolean flowed;
////////////////////////////////////////////////////////////////////////////
// Basics
/**
* Creates a BlockState object to track the given block's state.
*
* @param block the block
*/
public GlowBlockState(GlowBlock block) {
world = block.getWorld();
x = block.getX();
y = block.getY();
z = block.getZ();
typeId = block.getTypeId();
lightLevel = block.getLightLevel();
makeData(block.getData());
}
@Override
public GlowChunk getChunk() {
return getBlock().getChunk();
}
@Override
public GlowBlock getBlock() {
return world.getBlockAt(x, y, 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(typeId);
}
@Override
public final void setType(Material type) {
setTypeId(type.getId());
}
@Override
public final boolean setTypeId(int type) {
if (this.typeId == type) {
return false;
}
Material oldType = Material.getMaterial(typeId);
Material newType = Material.getMaterial(type);
this.typeId = type;
if (oldType.getData().equals(newType.getData())) {
setRawData((byte) 0);
} else {
makeData((byte) 0);
}
return true;
}
@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 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() == typeId || force)
&& block.setTypeIdAndData(typeId, getRawData(), applyPhysics);
}
////////////////////////////////////////////////////////////////////////////
// Internals
private void makeData(byte data) {
Material mat = Material.getMaterial(typeId);
if (mat == null) {
this.data = new MaterialData(typeId, 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 + typeId;
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 (typeId != other.typeId) {
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;
}
}