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); } } } } }