2011-05-13 03:09:57 +00:00
using System ;
using System.Collections.Generic ;
using Substrate.Utility ;
using Substrate.NBT ;
namespace Substrate
{
2011-06-27 04:49:29 +00:00
/// <summary>
/// Functions for reading and modifying a bounded-size collection of Alpha-compatible block data.
/// </summary>
/// <remarks>An <see cref="AlphaBlockCollection"/> is a wrapper around existing pieces of data. Although it
/// holds references to data, it does not "own" the data in the same way that a <see cref="Chunk"/> does. An
/// <see cref="AlphaBlockCollection"/> simply overlays a higher-level interface on top of existing data.</remarks>
public class AlphaBlockCollection : IBoundedAlphaBlockCollection
2011-05-13 03:09:57 +00:00
{
2011-06-10 16:08:36 +00:00
private readonly int _xdim ;
private readonly int _ydim ;
private readonly int _zdim ;
2011-05-13 03:09:57 +00:00
private XZYByteArray _blocks ;
private XZYNibbleArray _data ;
private XZYNibbleArray _blockLight ;
private XZYNibbleArray _skyLight ;
private ZXByteArray _heightMap ;
2011-06-20 03:51:40 +00:00
private TagNodeList _tileEntities ;
2011-05-13 03:09:57 +00:00
private BlockLight _lightManager ;
2011-06-07 02:56:07 +00:00
private BlockFluid _fluidManager ;
2011-05-13 03:09:57 +00:00
private BlockTileEntities _tileEntityManager ;
private bool _dirty = false ;
private bool _autoLight = true ;
2011-06-08 01:51:59 +00:00
private bool _autoFluid = false ;
2011-05-13 03:09:57 +00:00
public delegate AlphaBlockCollection NeighborLookupHandler ( int relx , int rely , int relz ) ;
public event NeighborLookupHandler ResolveNeighbor
{
add
{
_lightManager . ResolveNeighbor + = delegate ( int relx , int rely , int relz ) {
return value ( relx , rely , relz ) ;
} ;
2011-06-07 02:56:07 +00:00
_fluidManager . ResolveNeighbor + = delegate ( int relx , int rely , int relz )
{
return value ( relx , rely , relz ) ;
} ;
2011-05-13 03:09:57 +00:00
}
remove
{
_lightManager = new BlockLight ( this ) ;
2011-06-07 02:56:07 +00:00
_fluidManager = new BlockFluid ( this ) ;
2011-05-13 03:09:57 +00:00
}
}
public event BlockCoordinateHandler TranslateCoordinates
{
add { _tileEntityManager . TranslateCoordinates + = value ; }
remove { _tileEntityManager . TranslateCoordinates - = value ; }
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets or sets a value indicating whether changes to blocks will trigger automatic lighting updates.
/// </summary>
/// <remarks>Automatic updates to lighting may spill into neighboring <see cref="AlphaBlockCollection"/> objects, if they can
/// be resolved.</remarks>
2011-05-13 03:09:57 +00:00
public bool AutoLight
{
get { return _autoLight ; }
set { _autoLight = value ; }
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets or sets a value indicating whether changes to blocks will trigger automatic fluid updates.
/// </summary>
/// <remarks>Automatic updates to fluid may cascade through neighboring <see cref="AlphaBlockCollection"/> objects and beyond,
/// if they can be resolved.</remarks>
2011-06-08 01:51:59 +00:00
public bool AutoFluid
{
get { return _autoFluid ; }
set { _autoFluid = value ; }
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets or sets a value indicating whether this <see cref="AlphaBlockCollection"/> needs to be saved.
/// </summary>
/// <remarks>If this <see cref="AlphaBlockCollection"/> is backed by a reference conainer type, set this property to false
/// to prevent any modifications from being saved. The next update will set this property true again, however.</remarks>
2011-05-13 03:09:57 +00:00
public bool IsDirty
{
get { return _dirty ; }
set { _dirty = value ; }
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Creates a new <see cref="AlphaBlockCollection"/> overlay on top of Alpha-specific units of data.
/// </summary>
/// <param name="blocks">An array of Block IDs.</param>
/// <param name="data">An array of data nibbles.</param>
/// <param name="blockLight">An array of block light nibbles.</param>
/// <param name="skyLight">An array of sky light nibbles.</param>
/// <param name="heightMap">An array of height map values.</param>
/// <param name="tileEntities">A list of tile entities corresponding to blocks in this collection.</param>
public AlphaBlockCollection (
XZYByteArray blocks ,
XZYNibbleArray data ,
XZYNibbleArray blockLight ,
XZYNibbleArray skyLight ,
ZXByteArray heightMap ,
TagNodeList tileEntities )
{
_blocks = blocks ;
_data = data ;
_blockLight = blockLight ;
_skyLight = skyLight ;
_heightMap = heightMap ;
_tileEntities = tileEntities ;
2011-05-13 03:09:57 +00:00
2011-06-10 16:08:36 +00:00
_xdim = _blocks . XDim ;
_ydim = _blocks . YDim ;
_zdim = _blocks . ZDim ;
2011-06-10 23:42:17 +00:00
_lightManager = new BlockLight ( this ) ;
_fluidManager = new BlockFluid ( this ) ;
_tileEntityManager = new BlockTileEntities ( _blocks , _tileEntities ) ;
2011-05-13 03:09:57 +00:00
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Returns a new <see cref="Block"/> object from local coordinates relative to this collection.
/// </summary>
/// <param name="x">Local X-coordinate of block.</param>
/// <param name="y">Local Y-coordinate of block.</param>
/// <param name="z">Local Z-coordiante of block.</param>
/// <returns>A new <see cref="Block"/> object representing context-independent data of a single block.</returns>
/// <remarks>Context-independent data excludes data such as lighting. <see cref="Block"/> object actually contain a copy
/// of the data they represent, so changes to the <see cref="Block"/> will not affect this container, and vice-versa.</remarks>
2011-05-13 03:09:57 +00:00
public Block GetBlock ( int x , int y , int z )
{
return new Block ( this , x , y , z ) ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Returns a new <see cref="BlockRef"/> object from local coordaintes relative to this collection.
/// </summary>
/// <param name="x">Local X-coordinate of block.</param>
/// <param name="y">Local Y-coordinate of block.</param>
/// <param name="z">Local Z-coordinate of block.</param>
/// <returns>A new <see cref="BlockRef"/> object representing context-dependent data of a single block.</returns>
/// <remarks>Context-depdendent data includes all data associated with this block. Since a <see cref="BlockRef"/> represents
/// a view of a block within this container, any updates to data in the container will be reflected in the <see cref="BlockRef"/>,
/// and vice-versa for updates to the <see cref="BlockRef"/>.</remarks>
2011-05-13 03:09:57 +00:00
public BlockRef GetBlockRef ( int x , int y , int z )
{
return new BlockRef ( this , x , y , z ) ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Updates a block in this collection with values from a <see cref="Block"/> object.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <param name="block">A <see cref="Block"/> object to copy block data from.</param>
2011-05-13 03:09:57 +00:00
public void SetBlock ( int x , int y , int z , Block block )
{
2011-05-13 03:21:53 +00:00
SetID ( x , y , z , block . ID ) ;
SetData ( x , y , z , block . Data ) ;
2011-05-13 03:09:57 +00:00
SetTileEntity ( x , y , z , block . GetTileEntity ( ) . Copy ( ) ) ;
}
#region IBlockCollection Members
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets the length of this collection's X-dimension.
/// </summary>
2011-05-13 03:09:57 +00:00
public int XDim
{
2011-06-10 16:08:36 +00:00
get { return _xdim ; }
2011-05-13 03:09:57 +00:00
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets the length of this collection's Y-dimension.
/// </summary>
2011-05-13 03:09:57 +00:00
public int YDim
{
2011-06-10 16:08:36 +00:00
get { return _ydim ; }
2011-05-13 03:09:57 +00:00
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets the length of this collection's Z-dimension.
/// </summary>
2011-05-13 03:09:57 +00:00
public int ZDim
{
2011-06-10 16:08:36 +00:00
get { return _zdim ; }
2011-05-13 03:09:57 +00:00
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Returns an object compatible with the <see cref="IBlock"/> interface from local coordinates relative to this collection.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>An <see cref="IBlock"/>-compatible object.</returns>
/// <seealso cref="Block"/>
2011-05-13 03:09:57 +00:00
IBlock IBlockCollection . GetBlock ( int x , int y , int z )
{
return GetBlock ( x , y , z ) ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Returns a reference object compatible with the <see cref="IBlock"/> interface from local coordinates relative to this collection.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>An <see cref="IBlock"/>-compatible reference object.</returns>
/// <seealso cref="BlockRef"/>
2011-05-13 03:09:57 +00:00
IBlock IBlockCollection . GetBlockRef ( int x , int y , int z )
{
return GetBlockRef ( x , y , z ) ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Updates a block in this collection with values from an <see cref="IBlock"/> object.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <param name="block">An <see cref="IBlock"/> object to copy block data from.</param>
2011-05-13 03:09:57 +00:00
public void SetBlock ( int x , int y , int z , IBlock block )
{
2011-05-13 03:21:53 +00:00
SetID ( x , y , z , block . ID ) ;
2011-05-13 03:09:57 +00:00
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets information on the type of a block at the given local coordinates.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>A <see cref="BlockInfo"/> object containing information of a block's type.</returns>
2011-05-13 03:21:53 +00:00
public BlockInfo GetInfo ( int x , int y , int z )
2011-05-13 03:09:57 +00:00
{
return BlockInfo . BlockTable [ _blocks [ x , y , z ] ] ;
}
2011-06-10 16:08:36 +00:00
internal BlockInfo GetInfo ( int index )
{
return BlockInfo . BlockTable [ _blocks [ index ] ] ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets the ID (type) of a block at the given local coordinates.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>The ID (type) of the specified block.</returns>
2011-05-13 03:21:53 +00:00
public int GetID ( int x , int y , int z )
2011-05-13 03:09:57 +00:00
{
return _blocks [ x , y , z ] ;
}
2011-06-10 16:08:36 +00:00
internal int GetID ( int index )
{
return _blocks [ index ] ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Sets the ID (type) of a block at the given local coordinates, maintaining consistency of data.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <param name="id">The new ID of the block.</param>
/// <remarks>Depending on the options set for this <see cref="AlphaBlockCollection"/>, this method can be very
/// heavy-handed in the amount of work it does to maintain consistency of tile entities, lighting, fluid, etc.
/// for the affected block and possibly many other indirectly-affected blocks in the collection or neighboring
/// collections. If many SetID calls are expected to be made, some of this auto-reconciliation behavior should
/// be disabled, and the data should be rebuilt at the <see cref="AlphaBlockCollection"/>-level at the end.</remarks>
2011-05-13 03:21:53 +00:00
public void SetID ( int x , int y , int z , int id )
2011-05-13 03:09:57 +00:00
{
int oldid = _blocks [ x , y , z ] ;
if ( oldid = = id ) {
return ;
}
// Update value
_blocks [ x , y , z ] = ( byte ) id ;
// Update tile entities
2011-05-13 03:44:05 +00:00
BlockInfo info1 = BlockInfo . BlockTable [ oldid ] ;
BlockInfo info2 = BlockInfo . BlockTable [ id ] ;
2011-05-13 03:09:57 +00:00
2011-05-13 03:44:05 +00:00
BlockInfoEx einfo1 = info1 as BlockInfoEx ;
BlockInfoEx einfo2 = info2 as BlockInfoEx ;
if ( einfo1 ! = einfo2 ) {
if ( einfo1 ! = null ) {
2011-05-13 03:09:57 +00:00
ClearTileEntity ( x , y , z ) ;
}
2011-05-13 03:44:05 +00:00
if ( einfo2 ! = null ) {
2011-05-13 03:09:57 +00:00
CreateTileEntity ( x , y , z ) ;
}
}
// Light consistency
if ( _autoLight ) {
2011-06-04 16:16:01 +00:00
if ( info1 . ObscuresLight ! = info2 . ObscuresLight ) {
_lightManager . UpdateHeightMap ( x , y , z ) ;
}
if ( info1 . Luminance ! = info2 . Luminance | | info1 . Opacity ! = info2 . Opacity | | info1 . TransmitsLight ! = info2 . TransmitsLight ) {
2011-05-13 03:09:57 +00:00
UpdateBlockLight ( x , y , z ) ;
}
2011-06-04 16:16:01 +00:00
if ( info1 . Opacity ! = info2 . Opacity | | info1 . TransmitsLight ! = info2 . TransmitsLight ) {
2011-05-13 03:21:53 +00:00
UpdateSkyLight ( x , y , z ) ;
2011-05-13 03:09:57 +00:00
}
}
2011-06-08 01:51:59 +00:00
// Fluid consistency
if ( _autoFluid ) {
if ( info1 . State = = BlockState . FLUID | | info2 . State = = BlockState . FLUID ) {
UpdateFluid ( x , y , z ) ;
}
}
2011-05-13 03:09:57 +00:00
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
internal void SetID ( int index , int id )
{
int yzdim = _ydim * _zdim ;
int x = index / yzdim ;
int zy = index - ( x * yzdim ) ;
int z = zy / _ydim ;
int y = zy - ( z * _ydim ) ;
SetID ( x , y , z , id ) ;
}
/// <summary>
/// Returns a count of all blocks in this <see cref="AlphaBlockCollection"/> with the given ID (type).
/// </summary>
/// <param name="id">The ID of blocks to count.</param>
/// <returns>A count of all matching blocks.</returns>
2011-05-13 03:21:53 +00:00
public int CountByID ( int id )
2011-05-13 03:09:57 +00:00
{
int c = 0 ;
for ( int i = 0 ; i < _blocks . Length ; i + + ) {
if ( _blocks [ i ] = = id ) {
c + + ;
}
}
return c ;
}
#endregion
#region IDataBlockContainer Members
2011-06-27 04:49:29 +00:00
/// <summary>
/// Returns an object compatible with the <see cref="IDataBlock"/> interface from local coordinates relative to this collection.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>An <see cref="IDataBlock"/>-compatible object.</returns>
/// <seealso cref="Block"/>
2011-05-13 03:09:57 +00:00
IDataBlock IDataBlockCollection . GetBlock ( int x , int y , int z )
{
return GetBlock ( x , y , z ) ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Returns a reference object compatible with the <see cref="IDataBlock"/> interface from local coordinates relative to this collection.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>An <see cref="IDataBlock"/>-compatible reference object.</returns>
/// <seealso cref="BlockRef"/>
2011-05-13 03:09:57 +00:00
IDataBlock IDataBlockCollection . GetBlockRef ( int x , int y , int z )
{
return GetBlockRef ( x , y , z ) ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Updates a block in this collection with values from an <see cref="IDataBlock"/> object.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <param name="block">An <see cref="IDataBlock"/> object to copy block data from.</param>
2011-05-13 03:09:57 +00:00
public void SetBlock ( int x , int y , int z , IDataBlock block )
{
2011-05-13 03:21:53 +00:00
SetID ( x , y , z , block . ID ) ;
SetData ( x , y , z , block . Data ) ;
2011-05-13 03:09:57 +00:00
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets the data value of a block at the given local coordinates.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>The data value of the specified block.</returns>
2011-05-13 03:21:53 +00:00
public int GetData ( int x , int y , int z )
2011-05-13 03:09:57 +00:00
{
return _data [ x , y , z ] ;
}
2011-06-10 16:08:36 +00:00
internal int GetData ( int index )
{
return _data [ index ] ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Sets the data value of a block at the given local coordinates.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <param name="data">The new data value of the block.</param>
2011-05-13 03:21:53 +00:00
public void SetData ( int x , int y , int z , int data )
2011-05-13 03:09:57 +00:00
{
if ( _data [ x , y , z ] ! = data ) {
_data [ x , y , z ] = ( byte ) data ;
_dirty = true ;
}
/ * if ( BlockManager . EnforceDataLimits & & BlockInfo . BlockTable [ _blocks [ index ] ] ! = null ) {
if ( ! BlockInfo . BlockTable [ _blocks [ index ] ] . TestData ( data ) ) {
return false ;
}
} * /
}
2011-06-10 16:08:36 +00:00
internal void SetData ( int index , int data )
{
if ( _data [ index ] ! = data ) {
_data [ index ] = ( byte ) data ;
_dirty = true ;
}
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Returns a count of all blocks in this <see cref="AlphaBlockCollection"/> matching the given ID (type) and data value.
/// </summary>
/// <param name="id">The ID of blocks to count.</param>
/// <param name="data">The data value of blocks to count.</param>
/// <returns>A count of all matching blocks.</returns>
2011-05-13 03:21:53 +00:00
public int CountByData ( int id , int data )
2011-05-13 03:09:57 +00:00
{
int c = 0 ;
for ( int i = 0 ; i < _blocks . Length ; i + + ) {
if ( _blocks [ i ] = = id & & _data [ i ] = = data ) {
c + + ;
}
}
return c ;
}
#endregion
#region ILitBlockCollection Members
2011-06-27 04:49:29 +00:00
/// <summary>
/// Not Implemented.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>An <see cref="ILitBlock"/>-compatible object.</returns>
/// <seealso cref="Block"/>
2011-05-13 03:09:57 +00:00
ILitBlock ILitBlockCollection . GetBlock ( int x , int y , int z )
{
throw new NotImplementedException ( ) ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Returns a reference object compatible with the <see cref="ILitBlock"/> interface from local coordinates relative to this collection.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>An <see cref="ILitBlock"/>-compatible reference object.</returns>
/// <seealso cref="BlockRef"/>
2011-05-13 03:09:57 +00:00
ILitBlock ILitBlockCollection . GetBlockRef ( int x , int y , int z )
{
return GetBlockRef ( x , y , z ) ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Updates a block in this collection with values from an <see cref="ILitBlock"/> object.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <param name="block">An <see cref="ILitBlock"/> object to copy block data from.</param>
2011-05-13 03:09:57 +00:00
public void SetBlock ( int x , int y , int z , ILitBlock block )
{
2011-05-13 03:21:53 +00:00
SetID ( x , y , z , block . ID ) ;
2011-05-13 03:09:57 +00:00
SetBlockLight ( x , y , z , block . BlockLight ) ;
2011-05-13 03:21:53 +00:00
SetSkyLight ( x , y , z , block . SkyLight ) ;
2011-05-13 03:09:57 +00:00
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets the block-source light value of a block at the given local coordinates.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>The block-source light value of the specified block.</returns>
2011-05-13 03:09:57 +00:00
public int GetBlockLight ( int x , int y , int z )
{
return _blockLight [ x , y , z ] ;
}
2011-06-10 16:08:36 +00:00
internal int GetBlockLight ( int index )
{
return _blockLight [ index ] ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets the sky-source light value of a block at the given local coordinates.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>The sky-source light value of the specified block.</returns>
2011-05-13 03:21:53 +00:00
public int GetSkyLight ( int x , int y , int z )
2011-05-13 03:09:57 +00:00
{
return _skyLight [ x , y , z ] ;
}
2011-06-10 16:08:36 +00:00
internal int GetSkyLight ( int index )
{
return _skyLight [ index ] ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Sets the blocks-source light value of a block at the given local coordinates.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <param name="light">The new block-source light value of the block.</param>
2011-05-13 03:09:57 +00:00
public void SetBlockLight ( int x , int y , int z , int light )
{
if ( _blockLight [ x , y , z ] ! = light ) {
_blockLight [ x , y , z ] = ( byte ) light ;
_dirty = true ;
}
}
2011-06-10 16:08:36 +00:00
internal void SetBlockLight ( int index , int light )
{
if ( _blockLight [ index ] ! = light ) {
_blockLight [ index ] = ( byte ) light ;
_dirty = true ;
}
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Sets the sky-source light value of a block at the given local coordinates.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <param name="light">The new sky-source light value of the block.</param>
2011-05-13 03:21:53 +00:00
public void SetSkyLight ( int x , int y , int z , int light )
2011-05-13 03:09:57 +00:00
{
if ( _skyLight [ x , y , z ] ! = light ) {
_skyLight [ x , y , z ] = ( byte ) light ;
_dirty = true ;
}
}
2011-06-10 16:08:36 +00:00
internal void SetSkyLight ( int index , int light )
{
if ( _skyLight [ index ] ! = light ) {
_skyLight [ index ] = ( byte ) light ;
_dirty = true ;
}
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets the lowest Y-coordinate of a block at which sky-source light remains unfiltered.
/// </summary>
/// <param name="x">Local X-coordinate of a map location.</param>
/// <param name="z">Local Z-coordinate of a map location.</param>
/// <returns>The height-map value of a map location for calculating sky-source lighting.</returns>
2011-05-13 03:09:57 +00:00
public int GetHeight ( int x , int z )
{
return _heightMap [ x , z ] ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Sets the lowest Y-coordinate of a block at which sky-source light remains unfiltered.
/// </summary>
/// <param name="x">Local X-coordinate of a map location.</param>
/// <param name="z">Local Z-coordinate of a map location.</param>
/// <param name="height">The new height-map value of the given map location.</param>
2011-05-13 03:09:57 +00:00
public void SetHeight ( int x , int z , int height )
{
_heightMap [ x , z ] = ( byte ) height ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Updates the block-source lighting of a block at the given local coordinates to maintain light consistency.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <remarks><para>The lighting of the block will be updated to be consistent with the lighting in neighboring blocks.
/// If the block is itself a light source, many nearby blocks may be updated to maintain consistent lighting. These
/// updates may also touch neighboring <see cref="AlphaBlockCollection"/> objects, if they can be resolved.</para>
/// <para>This function assumes that the entire <see cref="AlphaBlockCollection"/> and neighboring <see cref="AlphaBlockCollection"/>s
/// already have consistent lighting, with the exception of the block being updated. If this assumption is violated,
/// lighting may fail to converge correctly.</para></remarks>
2011-05-13 03:09:57 +00:00
public void UpdateBlockLight ( int x , int y , int z )
{
_lightManager . UpdateBlockLight ( x , y , z ) ;
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Updates the sky-source lighting of a block at the given local coordinates to maintain light consistency.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <remarks><para>The lighting of the block will be updated to be consistent with the lighting in neighboring blocks.
/// If the block is itself a light source, many nearby blocks may be updated to maintain consistent lighting. These
/// updates may also touch neighboring <see cref="AlphaBlockCollection"/> objects, if they can be resolved.</para>
/// <para>This function assumes that the entire <see cref="AlphaBlockCollection"/> and neighboring <see cref="AlphaBlockCollection"/>s
/// already have consistent lighting, with the exception of the block being updated. If this assumption is violated,
/// lighting may fail to converge correctly.</para></remarks>
2011-05-13 03:21:53 +00:00
public void UpdateSkyLight ( int x , int y , int z )
2011-05-13 03:09:57 +00:00
{
_lightManager . UpdateBlockSkyLight ( x , y , z ) ;
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Resets the block-source light value to 0 for all blocks in this <see cref="AlphaBlockCollection"/>.
/// </summary>
2011-05-13 03:09:57 +00:00
public void ResetBlockLight ( )
{
_blockLight . Clear ( ) ;
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Resets the sky-source light value to 0 for all blocks in this <see cref="AlphaBlockCollection"/>.
/// </summary>
2011-05-13 03:21:53 +00:00
public void ResetSkyLight ( )
2011-05-13 03:09:57 +00:00
{
_skyLight . Clear ( ) ;
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Reconstructs the block-source lighting for all blocks in this <see cref="AlphaBlockCollection"/>.
/// </summary>
/// <remarks><para>This function should only be called after the lighting has been reset in this <see cref="AlphaBlockCollection"/>
/// and all neighboring <see cref="AlphaBlockCollection"/>s, or lighting may fail to converge correctly.
/// This function cannot reset the lighting on its own, due to interactions between <see cref="AlphaBlockCollection"/>s.</para>
/// <para>If many light source or block opacity values will be modified in this <see cref="AlphaBlockCollection"/>, it may
/// be preferable to avoid explicit or implicit calls to <see cref="UpdateBlockLight"/> and call this function once when
/// modifications are complete.</para></remarks>
/// /<seealso cref="ResetBlockLight"/>
2011-05-13 03:09:57 +00:00
public void RebuildBlockLight ( )
{
_lightManager . RebuildBlockLight ( ) ;
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Reconstructs the sky-source lighting for all blocks in this <see cref="AlphaBlockCollection"/>.
/// </summary>
/// <remarks><para>This function should only be called after the lighting has been reset in this <see cref="AlphaBlockCollection"/>
/// and all neighboring <see cref="AlphaBlockCollection"/>s, or lighting may fail to converge correctly.
/// This function cannot reset the lighting on its own, due to interactions between <see cref="AlphaBlockCollection"/>s.</para>
/// <para>If many light source or block opacity values will be modified in this <see cref="AlphaBlockCollection"/>, it may
/// be preferable to avoid explicit or implicit calls to <see cref="UpdateSkyLight"/> and call this function once when
/// modifications are complete.</para></remarks>
/// <seealso cref="ResetSkyLight"/>
2011-05-13 03:21:53 +00:00
public void RebuildSkyLight ( )
2011-05-13 03:09:57 +00:00
{
_lightManager . RebuildBlockSkyLight ( ) ;
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Reconstructs the height-map for this <see cref="AlphaBlockCollection"/>.
/// </summary>
2011-05-13 03:09:57 +00:00
public void RebuildHeightMap ( )
{
_lightManager . RebuildHeightMap ( ) ;
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Reconciles any block-source lighting inconsistencies between this <see cref="AlphaBlockCollection"/> and any of its neighbors.
/// </summary>
/// <remarks>It will be necessary to call this function if an <see cref="AlphaBlockCollection"/> is reset and rebuilt, but
/// some of its neighbors are not. A rebuilt <see cref="AlphaBlockCollection"/> will spill lighting updates into its neighbors,
/// but will not see lighting that should be propagated back from its neighbors.</remarks>
/// <seealso cref="RebuildBlockLight"/>
2011-05-13 03:09:57 +00:00
public void StitchBlockLight ( )
{
_lightManager . StitchBlockLight ( ) ;
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Reconciles any sky-source lighting inconsistencies between this <see cref="AlphaBlockCollection"/> and any of its neighbors.
/// </summary>
/// <remarks>It will be necessary to call this function if an <see cref="AlphaBlockCollection"/> is reset and rebuilt, but
/// some of its neighbors are not. A rebuilt <see cref="AlphaBlockCollection"/> will spill lighting updates into its neighbors,
/// but will not see lighting that should be propagated back from its neighbors.</remarks>
/// <seealso cref="RebuildSkyLight"/>
2011-05-13 03:21:53 +00:00
public void StitchSkyLight ( )
2011-05-13 03:09:57 +00:00
{
_lightManager . StitchBlockSkyLight ( ) ;
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Reconciles any block-source lighting inconsistencies between this <see cref="AlphaBlockCollection"/> and another <see cref="IBoundedLitBlockCollection"/> on a given edge.
/// </summary>
/// <param name="blockset">An <see cref="IBoundedLitBlockCollection"/>-compatible object with the same dimensions as this <see cref="AlphaBlockCollection"/>.</param>
/// <param name="edge">The edge that <paramref name="blockset"/> is a neighbor on.</param>
/// <remarks>It will be necessary to call this function if an <see cref="AlphaBlockCollection"/> is reset and rebuilt, but
/// some of its neighbors are not. A rebuilt <see cref="AlphaBlockCollection"/> will spill lighting updates into its neighbors,
/// but will not see lighting that should be propagated back from its neighbors.</remarks>
/// <seealso cref="RebuildBlockLight"/>
2011-05-13 03:09:57 +00:00
public void StitchBlockLight ( IBoundedLitBlockCollection blockset , BlockCollectionEdge edge )
{
_lightManager . StitchBlockLight ( blockset , edge ) ;
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Reconciles any sky-source lighting inconsistencies between this <see cref="AlphaBlockCollection"/> and another <see cref="IBoundedLitBlockCollection"/> on a given edge.
/// </summary>
/// <param name="blockset">An <see cref="IBoundedLitBlockCollection"/>-compatible object with the same dimensions as this <see cref="AlphaBlockCollection"/>.</param>
/// <param name="edge">The edge that <paramref name="blockset"/> is a neighbor on.</param>
/// <remarks>It will be necessary to call this function if an <see cref="AlphaBlockCollection"/> is reset and rebuilt, but
/// some of its neighbors are not. A rebuilt <see cref="AlphaBlockCollection"/> will spill lighting updates into its neighbors,
/// but will not see lighting that should be propagated back from its neighbors.</remarks>
/// <seealso cref="RebuildSkyLight"/>
2011-05-13 03:21:53 +00:00
public void StitchSkyLight ( IBoundedLitBlockCollection blockset , BlockCollectionEdge edge )
2011-05-13 03:09:57 +00:00
{
_lightManager . StitchBlockSkyLight ( blockset , edge ) ;
_dirty = true ;
}
#endregion
#region IPropertyBlockCollection Members
2011-06-27 04:49:29 +00:00
/// <summary>
/// Returns an object compatible with the <see cref="IPropertyBlock"/> interface from local coordinates relative to this collection.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>An <see cref="IPropertyBlock"/>-compatible object.</returns>
/// <seealso cref="Block"/>
2011-05-13 03:09:57 +00:00
IPropertyBlock IPropertyBlockCollection . GetBlock ( int x , int y , int z )
{
return GetBlock ( x , y , z ) ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Returns a reference object compatible with the <see cref="IPropertyBlock"/> interface from local coordinates relative to this collection.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>An <see cref="IPropertyBlock"/>-compatible reference object.</returns>
/// <seealso cref="BlockRef"/>
2011-05-13 03:09:57 +00:00
IPropertyBlock IPropertyBlockCollection . GetBlockRef ( int x , int y , int z )
{
return GetBlockRef ( x , y , z ) ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Updates a block in this collection with values from an <see cref="IPropertyBlock"/> object.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <param name="block">An <see cref="IPropertyBlock"/> object to copy block data from.</param>
2011-05-13 03:09:57 +00:00
public void SetBlock ( int x , int y , int z , IPropertyBlock block )
{
2011-05-13 03:21:53 +00:00
SetID ( x , y , z , block . ID ) ;
2011-05-13 03:09:57 +00:00
SetTileEntity ( x , y , z , block . GetTileEntity ( ) . Copy ( ) ) ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Gets a <see cref="TileEntity"/> record for a block at the given local coordinates, if one exists.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <returns>A <see cref="TileEntity"/> for the given block, or null if the <see cref="TileEntity"/> is missing or the block type does not use a <see cref="TileEntity"/>.</returns>
2011-05-13 03:09:57 +00:00
public TileEntity GetTileEntity ( int x , int y , int z )
{
return _tileEntityManager . GetTileEntity ( x , y , z ) ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Sets a <see cref="TileEntity"/> record for a block at the given local coordinates.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <param name="te">The <see cref="TileEntity"/> to add to the given block.</param>
/// <exception cref="ArgumentException">Thrown when the <see cref="TileEntity"/> being passed is of the wrong type for the given block.</exception>
/// <exception cref="InvalidOperationException">Thrown when the given block is of a type that does not support a <see cref="TileEntity"/> record.</exception>
2011-05-13 03:09:57 +00:00
public void SetTileEntity ( int x , int y , int z , TileEntity te )
{
_tileEntityManager . SetTileEntity ( x , y , z , te ) ;
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Creates a default <see cref="TileEntity"/> record suitable for the block at the given local coordinates.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
/// <exception cref="InvalidOperationException">Thrown when the given block is of a type that does not support a <see cref="TileEntity"/> record.</exception>
/// <exception cref="UnknownTileEntityException">Thrown when the block type requests a <see cref="TileEntity"/> that has not been registered with the <see cref="TileEntityFactory"/>.</exception>
2011-05-13 03:09:57 +00:00
public void CreateTileEntity ( int x , int y , int z )
{
_tileEntityManager . CreateTileEntity ( x , y , z ) ;
_dirty = true ;
}
2011-06-27 04:49:29 +00:00
/// <summary>
/// Clears any <see cref="TileEntity"/> record set for a block at the givne local coordinates, if one exists.
/// </summary>
/// <param name="x">Local X-coordinate of a block.</param>
/// <param name="y">Local Y-coordinate of a block.</param>
/// <param name="z">Local Z-coordinate of a block.</param>
2011-05-13 03:09:57 +00:00
public void ClearTileEntity ( int x , int y , int z )
{
_tileEntityManager . ClearTileEntity ( x , y , z ) ;
_dirty = true ;
}
#endregion
2011-06-08 01:51:59 +00:00
public void ResetFluid ( )
2011-06-07 02:56:07 +00:00
{
2011-06-08 01:51:59 +00:00
_fluidManager . ResetWater ( _blocks , _data ) ;
_fluidManager . ResetLava ( _blocks , _data ) ;
2011-06-07 02:56:07 +00:00
_dirty = true ;
}
2011-05-13 03:09:57 +00:00
2011-06-08 01:51:59 +00:00
public void RebuildFluid ( )
2011-06-07 02:56:07 +00:00
{
_fluidManager . RebuildWater ( ) ;
2011-06-08 01:51:59 +00:00
_fluidManager . RebuildLava ( ) ;
2011-06-07 02:56:07 +00:00
_dirty = true ;
}
2011-06-08 01:51:59 +00:00
public void UpdateFluid ( int x , int y , int z )
{
bool autofluid = _autoFluid ;
_autoFluid = false ;
int blocktype = _blocks [ x , y , z ] ;
if ( blocktype = = BlockType . WATER | | blocktype = = BlockType . STATIONARY_WATER ) {
_fluidManager . UpdateWater ( x , y , z ) ;
_dirty = true ;
}
else if ( blocktype = = BlockType . LAVA | | blocktype = = BlockType . STATIONARY_LAVA ) {
_fluidManager . UpdateLava ( x , y , z ) ;
_dirty = true ;
}
_autoFluid = autofluid ;
}
2011-06-10 16:08:36 +00:00
2011-06-27 04:49:29 +00:00
/ * #region IEnumerable < AlphaBlockRef > Members
2011-06-10 16:08:36 +00:00
public IEnumerator < AlphaBlockRef > GetEnumerator ( )
{
return new AlphaBlockEnumerator ( this ) ;
}
#endregion
#region IEnumerable Members
System . Collections . IEnumerator System . Collections . IEnumerable . GetEnumerator ( )
{
return new AlphaBlockEnumerator ( this ) ;
}
#endregion
public class AlphaBlockEnumerator : IEnumerator < AlphaBlockRef >
{
private AlphaBlockCollection _collection ;
private int _index ;
private int _size ;
public AlphaBlockEnumerator ( AlphaBlockCollection collection )
{
_collection = collection ;
_index = - 1 ;
_size = collection . XDim * collection . YDim * collection . ZDim ;
}
#region IEnumerator < Entity > Members
public AlphaBlockRef Current
{
get
{
if ( _index = = - 1 | | _index = = _size ) {
throw new InvalidOperationException ( ) ;
}
return new AlphaBlockRef ( _collection , _index ) ;
}
}
#endregion
#region IDisposable Members
public void Dispose ( ) { }
#endregion
#region IEnumerator Members
object System . Collections . IEnumerator . Current
{
get { return Current ; }
}
public bool MoveNext ( )
{
if ( + + _index = = _size ) {
return false ;
}
return true ;
}
public void Reset ( )
{
_index = - 1 ;
}
#endregion
2011-06-27 04:49:29 +00:00
} * /
2011-05-13 03:09:57 +00:00
}
}