using System;
using Substrate.Core;
namespace Substrate
{
///
/// A single Alpha-compatible block with context-independent data.
///
/// In general, you should prefer other types for accessing block data including ,
/// , and the property of and .
/// You should use the type when you need to copy individual blocks into a custom collection or
/// container, and context-depdendent data such as coordinates and lighting have no well-defined meaning.
/// offers a relatively compact footprint for storing the unique identity of a block's manifestation in the world.
/// A single object may also provide a convenient way to paste a block into many locations in
/// a block collection type.
public class AlphaBlock : IDataBlock, IPropertyBlock, IActiveBlock, ICopyable
{
private int _id;
private int _data;
private TileEntity _tileEntity;
private TileTick _tileTick;
///
/// Create a new instance of the given type with default data.
///
/// The id (type) of the block.
/// If the specified block type requires a Tile Entity as part of its definition, a default
/// of the appropriate type will automatically be created.
public AlphaBlock (int id)
{
_id = id;
UpdateTileEntity(0, id);
}
///
/// Create a new instance of the given type and data value.
///
/// The id (type) of the block.
/// The block's supplementary data value, currently limited to the range [0-15].
/// If the specified block type requires a Tile Entity as part of its definition, a default
/// of the appropriate type will automatically be created.
public AlphaBlock (int id, int data)
{
_id = id;
_data = data;
UpdateTileEntity(0, id);
}
///
/// Crrates a new from a given block in an existing .
///
/// The block collection to reference.
/// The local X-coordinate of a block within the collection.
/// The local Y-coordinate of a block within the collection.
/// The local Z-coordinate of a block within the collection.
public AlphaBlock (AlphaBlockCollection chunk, int lx, int ly, int lz)
{
_id = chunk.GetID(lx, ly, lz);
_data = chunk.GetData(lx, ly, lz);
TileEntity te = chunk.GetTileEntity(lx, ly, lz);
if (te != null) {
_tileEntity = te.Copy();
}
}
#region IBlock Members
///
/// Gets information on the type of the block.
///
public BlockInfo Info
{
get { return BlockInfo.BlockTable[_id]; }
}
///
/// Gets or sets the id (type) of the block.
///
/// If the new or old type have non-matching Tile Entity requirements, the embedded Tile Entity data
/// will be updated to keep consistent with the new block type.
public int ID
{
get { return _id; }
set
{
UpdateTileEntity(_id, value);
_id = value;
}
}
#endregion
#region IDataBlock Members
///
/// Gets or sets the supplementary data value of the block.
///
public int Data
{
get { return _data; }
set
{
/*if (BlockManager.EnforceDataLimits && BlockInfo.BlockTable[_id] != null) {
if (!BlockInfo.BlockTable[_id].TestData(value)) {
return;
}
}*/
_data = value;
}
}
#endregion
#region IPropertyBlock Members
///
/// Gets the Tile Entity record of the block if it has one.
///
/// The attached to this block, or null if the block type does not require a Tile Entity.
public TileEntity GetTileEntity ()
{
return _tileEntity;
}
///
/// Sets a new Tile Entity record for the block.
///
/// A Tile Entity record compatible with the block's type.
/// Thrown when an incompatible is added to a block.
/// Thrown when a is added to a block that does not use tile entities.
public void SetTileEntity (TileEntity te)
{
BlockInfoEx info = BlockInfo.BlockTable[_id] as BlockInfoEx;
if (info == null) {
throw new InvalidOperationException("The current block type does not accept a Tile Entity");
}
if (te.GetType() != TileEntityFactory.Lookup(info.TileEntityName)) {
throw new ArgumentException("The current block type is not compatible with the given Tile Entity", "te");
}
_tileEntity = te;
}
///
/// Creates a default Tile Entity record appropriate for the block.
///
public void CreateTileEntity ()
{
BlockInfoEx info = BlockInfo.BlockTable[_id] as BlockInfoEx;
if (info == null) {
throw new InvalidOperationException("The given block is of a type that does not support TileEntities.");
}
TileEntity te = TileEntityFactory.Create(info.TileEntityName);
if (te == null) {
throw new UnknownTileEntityException("The TileEntity type '" + info.TileEntityName + "' has not been registered with the TileEntityFactory.");
}
_tileEntity = te;
}
///
/// Removes any Tile Entity currently attached to the block.
///
public void ClearTileEntity ()
{
_tileEntity = null;
}
#endregion
#region IActiveBlock Members
public int TileTickValue
{
get
{
if (_tileTick == null)
return 0;
return _tileTick.Ticks;
}
set
{
if (_tileTick == null)
CreateTileTick();
_tileTick.Ticks = value;
}
}
///
/// Gets the record of the block if it has one.
///
/// The attached to this block, or null if the block type does not require a Tile Entity.
public TileTick GetTileTick ()
{
return _tileTick;
}
///
/// Sets a new record for the block.
///
/// A record compatible with the block's type.
public void SetTileTick (TileTick tt)
{
_tileTick = tt;
}
///
/// Creates a default record appropriate for the block.
///
public void CreateTileTick ()
{
_tileTick = new TileTick()
{
ID = _id,
};
}
///
/// Removes any currently attached to the block.
///
public void ClearTileTick ()
{
_tileTick = null;
}
#endregion
#region ICopyable Members
///
/// Creates a deep copy of the .
///
/// A new representing the same data.
public AlphaBlock Copy ()
{
AlphaBlock block = new AlphaBlock(_id, _data);
if (_tileEntity != null) {
block._tileEntity = _tileEntity.Copy();
}
return block;
}
#endregion
private void UpdateTileEntity (int old, int value)
{
BlockInfoEx info1 = BlockInfo.BlockTable[old] as BlockInfoEx;
BlockInfoEx info2 = BlockInfo.BlockTable[value] as BlockInfoEx;
if (info1 != info2) {
if (info1 != null) {
_tileEntity = null;
}
if (info2 != null) {
_tileEntity = TileEntityFactory.Create(info2.TileEntityName);
}
}
}
}
}