Block refactoring, documentation, bugfixes, minor enhancements, Schematic support.

This commit is contained in:
Justin Aquadro 2011-07-24 06:08:31 +00:00
parent 7d6e80db1e
commit 37c9e1aabc
18 changed files with 1235 additions and 448 deletions

View file

@ -53,11 +53,15 @@ namespace Substrate
/// <param name="lx">The local X-coordinate of a block within the collection.</param> /// <param name="lx">The local X-coordinate of a block within the collection.</param>
/// <param name="ly">The local Y-coordinate of a block within the collection.</param> /// <param name="ly">The local Y-coordinate of a block within the collection.</param>
/// <param name="lz">The local Z-coordinate of a block within the collection.</param> /// <param name="lz">The local Z-coordinate of a block within the collection.</param>
public AlphaBlock (IAlphaBlockCollection chunk, int lx, int ly, int lz) public AlphaBlock (AlphaBlockCollection chunk, int lx, int ly, int lz)
{ {
_id = chunk.GetID(lx, ly, lz); _id = chunk.GetID(lx, ly, lz);
_data = chunk.GetData(lx, ly, lz); _data = chunk.GetData(lx, ly, lz);
_tileEntity = chunk.GetTileEntity(lx, ly, lz).Copy();
TileEntity te = chunk.GetTileEntity(lx, ly, lz);
if (te != null) {
_tileEntity = te.Copy();
}
} }

View file

@ -35,6 +35,71 @@ namespace Substrate
public delegate AlphaBlockCollection NeighborLookupHandler (int relx, int rely, int relz); public delegate AlphaBlockCollection NeighborLookupHandler (int relx, int rely, int relz);
/// <summary>
/// Creates a new <see cref="AlphaBlockCollection"/> of a given dimension.
/// </summary>
/// <param name="xdim">The length of the X-dimension of the collection.</param>
/// <param name="ydim">The length of the Y-dimension of the collection.</param>
/// <param name="zdim">The length of the Z-dimension of the collection.</param>
public AlphaBlockCollection (int xdim, int ydim, int zdim)
{
_blocks = new XZYByteArray(xdim, ydim, zdim);
_data = new XZYNibbleArray(xdim, ydim, zdim);
_blockLight = new XZYNibbleArray(xdim, ydim, zdim);
_skyLight = new XZYNibbleArray(xdim, ydim, zdim);
_heightMap = new ZXByteArray(xdim, zdim);
_tileEntities = new TagNodeList(TagType.TAG_COMPOUND);
_xdim = xdim;
_ydim = ydim;
_zdim = zdim;
Refresh();
}
/// <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;
_xdim = _blocks.XDim;
_ydim = _blocks.YDim;
_zdim = _blocks.ZDim;
Refresh();
}
/// <summary>
/// Updates internal managers if underlying data, such as TileEntities, have been modified outside of the container.
/// </summary>
public void Refresh ()
{
_lightManager = new BlockLight(this);
_fluidManager = new BlockFluid(this);
_tileEntityManager = new BlockTileEntities(_blocks, _tileEntities);
}
#region Events
public event NeighborLookupHandler ResolveNeighbor public event NeighborLookupHandler ResolveNeighbor
{ {
add add
@ -61,6 +126,8 @@ namespace Substrate
remove { _tileEntityManager.TranslateCoordinates -= value; } remove { _tileEntityManager.TranslateCoordinates -= value; }
} }
#endregion
/// <summary> /// <summary>
/// Gets or sets a value indicating whether changes to blocks will trigger automatic lighting updates. /// Gets or sets a value indicating whether changes to blocks will trigger automatic lighting updates.
/// </summary> /// </summary>
@ -94,38 +161,7 @@ namespace Substrate
set { _dirty = value; } set { _dirty = value; }
} }
/// <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;
_xdim = _blocks.XDim;
_ydim = _blocks.YDim;
_zdim = _blocks.ZDim;
_lightManager = new BlockLight(this);
_fluidManager = new BlockFluid(this);
_tileEntityManager = new BlockTileEntities(_blocks, _tileEntities);
}
/// <summary> /// <summary>
/// Returns a new <see cref="AlphaBlock"/> object from local coordinates relative to this collection. /// Returns a new <see cref="AlphaBlock"/> object from local coordinates relative to this collection.
@ -473,12 +509,6 @@ namespace Substrate
} }
/// <inheritdoc/> /// <inheritdoc/>
/// <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>
public void UpdateBlockLight (int x, int y, int z) public void UpdateBlockLight (int x, int y, int z)
{ {
_lightManager.UpdateBlockLight(x, y, z); _lightManager.UpdateBlockLight(x, y, z);
@ -486,127 +516,69 @@ namespace Substrate
} }
/// <inheritdoc/> /// <inheritdoc/>
/// <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>
public void UpdateSkyLight (int x, int y, int z) public void UpdateSkyLight (int x, int y, int z)
{ {
_lightManager.UpdateBlockSkyLight(x, y, z); _lightManager.UpdateBlockSkyLight(x, y, z);
_dirty = true; _dirty = true;
} }
/// <summary> /// <inheritdoc/>
/// Resets the block-source light value to 0 for all blocks in this <see cref="AlphaBlockCollection"/>.
/// </summary>
public void ResetBlockLight () public void ResetBlockLight ()
{ {
_blockLight.Clear(); _blockLight.Clear();
_dirty = true; _dirty = true;
} }
/// <summary> /// <inheritdoc/>
/// Resets the sky-source light value to 0 for all blocks in this <see cref="AlphaBlockCollection"/>.
/// </summary>
public void ResetSkyLight () public void ResetSkyLight ()
{ {
_skyLight.Clear(); _skyLight.Clear();
_dirty = true; _dirty = true;
} }
/// <summary> /// <inheritdoc/>
/// 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"/>
public void RebuildBlockLight () public void RebuildBlockLight ()
{ {
_lightManager.RebuildBlockLight(); _lightManager.RebuildBlockLight();
_dirty = true; _dirty = true;
} }
/// <summary> /// <inheritdoc/>
/// 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"/>
public void RebuildSkyLight () public void RebuildSkyLight ()
{ {
_lightManager.RebuildBlockSkyLight(); _lightManager.RebuildBlockSkyLight();
_dirty = true; _dirty = true;
} }
/// <summary> /// <inheritdoc/>
/// Reconstructs the height-map for this <see cref="AlphaBlockCollection"/>.
/// </summary>
public void RebuildHeightMap () public void RebuildHeightMap ()
{ {
_lightManager.RebuildHeightMap(); _lightManager.RebuildHeightMap();
_dirty = true; _dirty = true;
} }
/// <summary> /// <inheritdoc/>
/// 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"/>
public void StitchBlockLight () public void StitchBlockLight ()
{ {
_lightManager.StitchBlockLight(); _lightManager.StitchBlockLight();
_dirty = true; _dirty = true;
} }
/// <summary> /// <inheritdoc/>
/// 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"/>
public void StitchSkyLight () public void StitchSkyLight ()
{ {
_lightManager.StitchBlockSkyLight(); _lightManager.StitchBlockSkyLight();
_dirty = true; _dirty = true;
} }
/// <summary> /// <inheritdoc/>
/// 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"/>
public void StitchBlockLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge) public void StitchBlockLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge)
{ {
_lightManager.StitchBlockLight(blockset, edge); _lightManager.StitchBlockLight(blockset, edge);
_dirty = true; _dirty = true;
} }
/// <summary> /// <inheritdoc/>
/// 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"/>
public void StitchSkyLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge) public void StitchSkyLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge)
{ {
_lightManager.StitchBlockSkyLight(blockset, edge); _lightManager.StitchBlockSkyLight(blockset, edge);
@ -735,7 +707,7 @@ namespace Substrate
#region Unbounded Container Implementations #region Unbounded Container Implementations
IBlock IBlockCollection.GetBlock (int x, int y, int z) /*IBlock IBlockCollection.GetBlock (int x, int y, int z)
{ {
if (x >= 0 && x < _xdim && y >= 0 && y < _ydim && z >= 0 && z < ZDim) { if (x >= 0 && x < _xdim && y >= 0 && y < _ydim && z >= 0 && z < ZDim) {
return GetBlock(x, y, z); return GetBlock(x, y, z);
@ -986,7 +958,7 @@ namespace Substrate
SetBlock(x, y, z, block); SetBlock(x, y, z, block);
} }
throw new ArgumentOutOfRangeException(x < 0 || x >= _xdim ? "x" : y < 0 || y >= _ydim ? "y" : "z"); throw new ArgumentOutOfRangeException(x < 0 || x >= _xdim ? "x" : y < 0 || y >= _ydim ? "y" : "z");
} }*/
#endregion #endregion

View file

@ -104,305 +104,6 @@ namespace Substrate.Core
bool IsValid { get; } bool IsValid { get; }
} }
/// <summary>
/// A basic unconstrained container of blocks.
/// </summary>
/// <remarks>The scope of coordinates is undefined for unconstrained block containers.</remarks>
public interface IBlockCollection
{
/// <summary>
/// Gets a basic block from a block container..
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>A basic <see cref="IBlock"/> from the collection at the given coordinates.</returns>
IBlock GetBlock (int x, int y, int z);
/// <summary>
/// Gets a reference object to a basic within a block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>A basic <see cref="IBlock"/> acting as a reference directly into the container at the given coordinates.</returns>
IBlock GetBlockRef (int x, int y, int z);
/// <summary>
/// Updates a block in a block container with data from an existing <see cref="IBlock"/> object.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="block">The <see cref="IBlock"/> to copy basic data from.</param>
void SetBlock (int x, int y, int z, IBlock block);
/// <summary>
/// Gets a block's id (type) from a block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>The block id (type) from the block container at the given coordinates.</returns>
int GetID (int x, int y, int z);
/// <summary>
/// Sets a block's id (type) within a block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="id">The id (type) to assign to a block at the given coordinates.</param>
void SetID (int x, int y, int z, int id);
/// <summary>
/// Gets info and attributes on a block's type within a block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>A <see cref="BlockInfo"/> instance for the block's type.</returns>
BlockInfo GetInfo (int x, int y, int z);
}
/// <summary>
/// A container of blocks with set dimensions.
/// </summary>
public interface IBoundedBlockCollection : IBlockCollection
{
/// <summary>
/// Gets the length of the X-dimension of the container.
/// </summary>
int XDim { get; }
/// <summary>
/// Gets the length of the Y-dimension of the container.
/// </summary>
int YDim { get; }
/// <summary>
/// Gets the length of the Z-dimension of the container.
/// </summary>
int ZDim { get; }
/// <summary>
/// Counts all instances of a block with the given type in the container.
/// </summary>
/// <param name="id">The id (type) of the block to count.</param>
/// <returns>The count of blocks in the container matching the given id (type).</returns>
int CountByID (int id);
#region Local Overrides
/// <summary>
/// Gets a basic block from a block container..
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>A basic <see cref="IBlock"/> from the collection at the given coordinates.</returns>
new IBlock GetBlock (int x, int y, int z);
/// <summary>
/// Gets a reference object to a basic within a block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>A basic <see cref="IBlock"/> acting as a reference directly into the container at the given coordinates.</returns>
new IBlock GetBlockRef (int x, int y, int z);
/// <summary>
/// Updates a block in a block container with data from an existing <see cref="IBlock"/> object.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="block">The <see cref="IBlock"/> to copy basic data from.</param>
new void SetBlock (int x, int y, int z, IBlock block);
/// <summary>
/// Gets a block's id (type) from a block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>The block id (type) from the block container at the given coordinates.</returns>
new int GetID (int x, int y, int z);
/// <summary>
/// Sets a block's id (type) within a block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="id">The id (type) to assign to a block at the given coordinates.</param>
new void SetID (int x, int y, int z, int id);
/// <summary>
/// Gets info and attributes on a block's type within a block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>A <see cref="BlockInfo"/> instance for the block's type.</returns>
new BlockInfo GetInfo (int x, int y, int z);
#endregion
}
/// <summary>
/// An unbounded container of blocks supporting data fields.
/// </summary>
public interface IDataBlockCollection : IBlockCollection
{
new IDataBlock GetBlock (int x, int y, int z);
new IDataBlock GetBlockRef (int x, int y, int z);
void SetBlock (int x, int y, int z, IDataBlock block);
int GetData (int x, int y, int z);
void SetData (int x, int y, int z, int data);
}
/// <summary>
/// A bounded version of the <see cref="IDataBlockCollection"/> interface.
/// </summary>
public interface IBoundedDataBlockCollection : IDataBlockCollection, IBoundedBlockCollection
{
new IDataBlock GetBlock (int x, int y, int z);
new IDataBlock GetBlockRef (int x, int y, int z);
new void SetBlock (int x, int y, int z, IDataBlock block);
new int GetData (int x, int y, int z);
new void SetData (int x, int y, int z, int data);
int CountByData (int id, int data);
}
/// <summary>
/// An unbounded container of blocks supporting dual-source lighting.
/// </summary>
public interface ILitBlockCollection : IBlockCollection
{
new ILitBlock GetBlock (int x, int y, int z);
new ILitBlock GetBlockRef (int x, int y, int z);
void SetBlock (int x, int y, int z, ILitBlock block);
// Local Light
int GetBlockLight (int x, int y, int z);
int GetSkyLight (int x, int y, int z);
void SetBlockLight (int x, int y, int z, int light);
void SetSkyLight (int x, int y, int z, int light);
int GetHeight (int x, int z);
void SetHeight (int x, int z, int height);
// Update and propagate light at a single block
void UpdateBlockLight (int x, int y, int z);
void UpdateSkyLight (int x, int y, int z);
}
/// <summary>
/// A bounded version of the <see cref="ILitBlockCollection"/> interface.
/// </summary>
public interface IBoundedLitBlockCollection : ILitBlockCollection, IBoundedBlockCollection
{
new ILitBlock GetBlock (int x, int y, int z);
new ILitBlock GetBlockRef (int x, int y, int z);
new void SetBlock (int x, int y, int z, ILitBlock block);
// Local Light
new int GetBlockLight (int x, int y, int z);
new int GetSkyLight (int x, int y, int z);
new void SetBlockLight (int x, int y, int z, int light);
new void SetSkyLight (int x, int y, int z, int light);
new int GetHeight (int x, int z);
new void SetHeight (int x, int z, int height);
// Update and propagate light at a single block
new void UpdateBlockLight (int x, int y, int z);
new void UpdateSkyLight (int x, int y, int z);
// Zero out light in entire collection
void ResetBlockLight ();
void ResetSkyLight ();
// Recalculate light in entire collection
void RebuildBlockLight ();
void RebuildSkyLight ();
void RebuildHeightMap ();
// Reconcile inconsistent lighting between the edges of two containers of same size
void StitchBlockLight ();
void StitchSkyLight ();
void StitchBlockLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge);
void StitchSkyLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge);
}
/// <summary>
/// An unbounded container for blocks supporting additional properties.
/// </summary>
public interface IPropertyBlockCollection : IBlockCollection
{
new IPropertyBlock GetBlock (int x, int y, int z);
new IPropertyBlock GetBlockRef (int x, int y, int z);
void SetBlock (int x, int y, int z, IPropertyBlock block);
TileEntity GetTileEntity (int x, int y, int z);
void SetTileEntity (int x, int y, int z, TileEntity te);
void CreateTileEntity (int x, int y, int z);
void ClearTileEntity (int x, int y, int z);
}
/// <summary>
/// A bounded version of the <see cref="IPropertyBlockCollection"/> interface.
/// </summary>
public interface IBoundedPropertyBlockCollection : IPropertyBlockCollection, IBoundedBlockCollection
{
new IPropertyBlock GetBlock (int x, int y, int z);
new IPropertyBlock GetBlockRef (int x, int y, int z);
new void SetBlock (int x, int y, int z, IPropertyBlock block);
new TileEntity GetTileEntity (int x, int y, int z);
new void SetTileEntity (int x, int y, int z, TileEntity te);
new void CreateTileEntity (int x, int y, int z);
new void ClearTileEntity (int x, int y, int z);
}
/// <summary>
/// An unbounded container of blocks supporting data, lighting, and properties.
/// </summary>
public interface IAlphaBlockCollection : IDataBlockCollection, ILitBlockCollection, IPropertyBlockCollection
{
new AlphaBlock GetBlock (int x, int y, int z);
new AlphaBlockRef GetBlockRef (int x, int y, int z);
void SetBlock (int x, int y, int z, AlphaBlock block);
}
/// <summary>
/// A bounded version of the <see cref="IAlphaBlockCollection"/> interface.
/// </summary>
public interface IBoundedAlphaBlockCollection : IAlphaBlockCollection, IBoundedDataBlockCollection, IBoundedLitBlockCollection, IBoundedPropertyBlockCollection
{
new AlphaBlock GetBlock (int x, int y, int z);
new AlphaBlockRef GetBlockRef (int x, int y, int z);
new void SetBlock (int x, int y, int z, AlphaBlock block);
}
/// <summary> /// <summary>
/// Provides a common interface for block containers that provide global management. /// Provides a common interface for block containers that provide global management.
/// </summary> /// </summary>

View file

@ -0,0 +1,451 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Substrate.Core
{
/// <summary>
/// A container of blocks with set dimensions.
/// </summary>
public interface IBoundedBlockCollection
{
/// <summary>
/// Gets the length of the X-dimension of the container.
/// </summary>
int XDim { get; }
/// <summary>
/// Gets the length of the Y-dimension of the container.
/// </summary>
int YDim { get; }
/// <summary>
/// Gets the length of the Z-dimension of the container.
/// </summary>
int ZDim { get; }
/// <summary>
/// Counts all instances of a block with the given type in the bounded block container.
/// </summary>
/// <param name="id">The id (type) of the block to count.</param>
/// <returns>The count of blocks in the container matching the given id (type).</returns>
int CountByID (int id);
/// <summary>
/// Gets a basic block from a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>A basic <see cref="IBlock"/> from the collection at the given coordinates.</returns>
IBlock GetBlock (int x, int y, int z);
/// <summary>
/// Gets a reference object to a basic within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>A basic <see cref="IBlock"/> acting as a reference directly into the container at the given coordinates.</returns>
IBlock GetBlockRef (int x, int y, int z);
/// <summary>
/// Updates a block in a bounded block container with data from an existing <see cref="IBlock"/> object.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="block">The <see cref="IBlock"/> to copy basic data from.</param>
void SetBlock (int x, int y, int z, IBlock block);
/// <summary>
/// Gets a block's id (type) from a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>The block id (type) from the block container at the given coordinates.</returns>
int GetID (int x, int y, int z);
/// <summary>
/// Sets a block's id (type) within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="id">The id (type) to assign to a block at the given coordinates.</param>
void SetID (int x, int y, int z, int id);
/// <summary>
/// Gets info and attributes on a block's type within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>A <see cref="BlockInfo"/> instance for the block's type.</returns>
BlockInfo GetInfo (int x, int y, int z);
}
/// <summary>
/// A bounded container of blocks supporting data fields.
/// </summary>
/// <seealso cref="IDataBlockCollection"/>
public interface IBoundedDataBlockCollection : IBoundedBlockCollection
{
/// <summary>
/// Gets a block with data field from a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>An <see cref="IDataBlock"/> from the collection at the given coordinates.</returns>
new IDataBlock GetBlock (int x, int y, int z);
/// <summary>
/// Gets a reference object to a block with data field within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>An <see cref="IDataBlock"/> acting as a reference directly into the container at the given coordinates.</returns>
new IDataBlock GetBlockRef (int x, int y, int z);
/// <summary>
/// Updates a block in a bounded block container with data from an existing <see cref="IDataBlock"/> object.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="block">The <see cref="IDataBlock"/> to copy data from.</param>
void SetBlock (int x, int y, int z, IDataBlock block);
/// <summary>
/// Gets a block's data field from a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>The data field of a block at the given coordinates.</returns>
int GetData (int x, int y, int z);
/// <summary>
/// Sets a block's data field within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="data">The data field to assign to a block at the given coordinates.</param>
void SetData (int x, int y, int z, int data);
/// <summary>
/// Counts all blocks within a bounded container set to a given id (type) and data value.
/// </summary>
/// <param name="id">The id (type) of blocks to match.</param>
/// <param name="data">The data value of blocks to match.</param>
/// <returns>A count of all blocks in the container matching both conditions.</returns>
int CountByData (int id, int data);
}
/// <summary>
/// A bounded container of blocks supporting dual-source lighting.
/// </summary>
/// <seealso cref="ILitBlockCollection"/>
public interface IBoundedLitBlockCollection : IBoundedBlockCollection
{
/// <summary>
/// Gets a block with lighting information from a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>An <see cref="ILitBlock"/> from the collection at the given coordinates.</returns>
new ILitBlock GetBlock (int x, int y, int z);
/// <summary>
/// Gets a reference object to a block with lighting information within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>An <see cref="ILitBlock"/> acting as a reference directly into the container at the given coordinates.</returns>
new ILitBlock GetBlockRef (int x, int y, int z);
/// <summary>
/// Updates a block in a bounded block container with data from an existing <see cref="ILitBlock"/> object.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="block">The <see cref="ILitBlock"/> to copy data from.</param>
void SetBlock (int x, int y, int z, ILitBlock block);
/// <summary>
/// Gets a block's block-source light value from a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>The block-source light value of a block at the given coordinates.</returns>
int GetBlockLight (int x, int y, int z);
/// <summary>
/// Gets a block's sky-source light value from a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>The sky-source light value of a block at the given coordinates.</returns>
int GetSkyLight (int x, int y, int z);
/// <summary>
/// Sets a block's block-source light value within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="light">The block-source light value to assign to a block at the given coordinates.</param>
void SetBlockLight (int x, int y, int z, int light);
/// <summary>
/// Sets a block's sky-source light value within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="light">The sky-source light value to assign to a block at the given coordinates.</param>
void SetSkyLight (int x, int y, int z, int light);
/// <summary>
/// Gets the Y-coordinate of the lowest block with unobstructed view of the sky at the given coordinates within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>The height value of an X-Z coordinate pair in the block container.</returns>
/// <remarks>The height value represents the lowest block with an unobstructed view of the sky. This is the lowest block with
/// a maximum-value sky-light value. Fully transparent blocks, like glass, do not count as an obstruction.</remarks>
int GetHeight (int x, int z);
/// <summary>
/// Sets the Y-coordinate of the lowest block with unobstructed view of the sky at the given coordinates within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="height">The height value of an X-Z coordinate pair in the block container.</param>
/// <remarks>Minecraft lighting algorithms rely heavily on this value being correct. Setting this value too low may result in
/// rooms that can never get dark, for example.</remarks>
void SetHeight (int x, int z, int height);
/// <summary>
/// Recalculates the block-source light value of a single block within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-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="ILitBlockCollection"/> objects, if they can be resolved.</para>
/// <para>This function assumes that the entire <see cref="ILitBlockCollection"/> and neighboring <see cref="ILitBlockCollection"/>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>
void UpdateBlockLight (int x, int y, int z);
/// <summary>
/// Recalculates the sky-source light value of a single block within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-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="ILitBlockCollection"/> objects, if they can be resolved.</para>
/// <para>This function assumes that the entire <see cref="ILitBlockCollection"/> and neighboring <see cref="ILitBlockCollection"/>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>
void UpdateSkyLight (int x, int y, int z);
/// <summary>
/// Resets the block-source light value to 0 for all blocks within a bounded block container.
/// </summary>
void ResetBlockLight ();
/// <summary>
/// Resets the sky-source light value to 0 for all blocks within a bounded block container.
/// </summary>
void ResetSkyLight ();
/// <summary>
/// Reconstructs the block-source lighting for all blocks within a bounded block container.
/// </summary>
/// <remarks><para>This function should only be called after the lighting has been reset in this <see cref="IBoundedLitBlockCollection"/>
/// and all neighboring <see cref="IBoundedLitBlockCollection"/>s, or lighting may fail to converge correctly.
/// This function cannot reset the lighting on its own, due to interactions between <see cref="IBoundedLitBlockCollection"/>s.</para>
/// <para>If many light source or block opacity values will be modified in this <see cref="IBoundedLitBlockCollection"/>, 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"/>
void RebuildBlockLight ();
/// <summary>
/// Reconstructs the sky-source lighting for all blocks within a bounded block container.
/// </summary>
/// <remarks><para>This function should only be called after the lighting has been reset in this <see cref="IBoundedLitBlockCollection"/>
/// and all neighboring <see cref="IBoundedLitBlockCollection"/>s, or lighting may fail to converge correctly.
/// This function cannot reset the lighting on its own, due to interactions between <see cref="IBoundedLitBlockCollection"/>s.</para>
/// <para>If many light source or block opacity values will be modified in this <see cref="IBoundedLitBlockCollection"/>, 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"/>
void RebuildSkyLight ();
/// <summary>
/// Reconstructs the height-map for a bounded block container.
/// </summary>
void RebuildHeightMap ();
/// <summary>
/// Reconciles any block-source lighting inconsistencies between this <see cref="IBoundedLitBlockCollection"/> and any of its neighbors.
/// </summary>
/// <remarks>It will be necessary to call this function if an <see cref="IBoundedLitBlockCollection"/> is reset and rebuilt, but
/// some of its neighbors are not. A rebuilt <see cref="IBoundedLitBlockCollection"/> will spill lighting updates into its neighbors,
/// but will not see lighting that should be propagated back from its neighbors.</remarks>
/// <seealso cref="RebuildBlockLight"/>
void StitchBlockLight ();
/// <summary>
/// Reconciles any sky-source lighting inconsistencies between this <see cref="IBoundedLitBlockCollection"/> and any of its neighbors.
/// </summary>
/// <remarks>It will be necessary to call this function if an <see cref="IBoundedLitBlockCollection"/> is reset and rebuilt, but
/// some of its neighbors are not. A rebuilt <see cref="IBoundedLitBlockCollection"/> will spill lighting updates into its neighbors,
/// but will not see lighting that should be propagated back from its neighbors.</remarks>
/// <seealso cref="RebuildSkyLight"/>
void StitchSkyLight ();
/// <summary>
/// Reconciles any block-source lighting inconsistencies between this <see cref="IBoundedLitBlockCollection"/> 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="IBoundedLitBlockCollection"/>.</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="IBoundedLitBlockCollection"/> is reset and rebuilt, but
/// some of its neighbors are not. A rebuilt <see cref="IBoundedLitBlockCollection"/> will spill lighting updates into its neighbors,
/// but will not see lighting that should be propagated back from its neighbors.</remarks>
/// <seealso cref="RebuildBlockLight"/>
void StitchBlockLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge);
/// <summary>
/// Reconciles any sky-source lighting inconsistencies between this <see cref="IBoundedLitBlockCollection"/> 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="IBoundedLitBlockCollection"/>.</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="IBoundedLitBlockCollection"/> is reset and rebuilt, but
/// some of its neighbors are not. A rebuilt <see cref="IBoundedLitBlockCollection"/> will spill lighting updates into its neighbors,
/// but will not see lighting that should be propagated back from its neighbors.</remarks>
/// <seealso cref="RebuildSkyLight"/>
void StitchSkyLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge);
}
/// <summary>
/// A bounded container for blocks supporting additional properties.
/// </summary>
/// <seealso cref="IPropertyBlockCollection"/>
public interface IBoundedPropertyBlockCollection : IBoundedBlockCollection
{
/// <summary>
/// Gets a block supporting extra properties from a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>An <see cref="IPropertyBlock"/> from the collection at the given coordinates.</returns>
new IPropertyBlock GetBlock (int x, int y, int z);
/// <summary>
/// Gets a reference object to a block supporting extra properties within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>An <see cref="IPropertyBlock"/> acting as a reference directly into the container at the given coordinates.</returns>
new IPropertyBlock GetBlockRef (int x, int y, int z);
/// <summary>
/// Updates a block in a bounded block container with data from an existing <see cref="IPropertyBlock"/> object.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="block">The <see cref="IPropertyBlock"/> to copy data from.</param>
void SetBlock (int x, int y, int z, IPropertyBlock block);
/// <summary>
/// Gets the <see cref="TileEntity"/> record of a block within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>A <see cref="TileEntity"/> record attached to a block at the given coordinates, or null if no tile entity is set.</returns>
TileEntity GetTileEntity (int x, int y, int z);
/// <summary>
/// Sets a <see cref="TileEntity"/> record to a block within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="te">The <see cref="TileEntity"/> record to assign to the given block.</param>
/// <exception cref="ArgumentException">Thrown when an incompatible <see cref="TileEntity"/> is added to a block.</exception>
/// <exception cref="InvalidOperationException">Thrown when a <see cref="TileEntity"/> is added to a block that does not use tile entities.</exception>
void SetTileEntity (int x, int y, int z, TileEntity te);
/// <summary>
/// Creates a new default <see cref="TileEntity"/> record for a block within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <exception cref="InvalidOperationException">Thrown when a <see cref="TileEntity"/> is created for a block that does not use tile entities.</exception>
/// <exception cref="UnknownTileEntityException">Thrown when the tile entity type associated with the given block has not been registered with <see cref="TileEntityFactory"/>.</exception>
void CreateTileEntity (int x, int y, int z);
/// <summary>
/// Deletes a <see cref="TileEntity"/> record associated with a block within a bounded block container, if it exists.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
void ClearTileEntity (int x, int y, int z);
}
/// <summary>
/// A bounded container of blocks supporting data, lighting, and properties.
/// </summary>
/// <seealso cref="IAlphaBlockCollection"/>
public interface IBoundedAlphaBlockCollection : IBoundedDataBlockCollection, IBoundedLitBlockCollection, IBoundedPropertyBlockCollection
{
/// <summary>
/// Gets a context-sensitive Alpha-compatible block from a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>An <see cref="AlphaBlock"/> from the collection at the given coordinates.</returns>
new AlphaBlock GetBlock (int x, int y, int z);
/// <summary>
/// Gets a reference object to a context-sensitive Alpha-compatible block within a bounded block container.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <returns>An <see cref="AlphaBlockRef"/> acting as a reference directly into the container at the given coordinates.</returns>
new AlphaBlockRef GetBlockRef (int x, int y, int z);
/// <summary>
/// Updates a block in a bounded block container with data from an existing <see cref="AlphaBlock"/> object.
/// </summary>
/// <param name="x">The container-local X-coordinate of a block.</param>
/// <param name="y">The container-local Y-coordinate of a block.</param>
/// <param name="z">The container-local Z-coordinate of a block.</param>
/// <param name="block">The <see cref="AlphaBlock"/> to copy data from.</param>
void SetBlock (int x, int y, int z, AlphaBlock block);
}
}

View file

@ -0,0 +1,15 @@
using System;
namespace Substrate.Core
{
/// <summary>
/// An interface that exposes an <see cref="ItemCollection"/> for the object.
/// </summary>
public interface IItemContainer
{
/// <summary>
/// Gets an <see cref="ItemCollection"/> associated with the object.
/// </summary>
ItemCollection Items { get; }
}
}

View file

@ -11,7 +11,7 @@ namespace Substrate.Core
public NibbleArray (int length) public NibbleArray (int length)
{ {
_data = new byte[length / 2]; _data = new byte[(int)Math.Ceiling(length / 2.0)];
} }
public NibbleArray (byte[] data) public NibbleArray (byte[] data)

View file

@ -0,0 +1,343 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Substrate.Core
{
/// <summary>
/// A basic unconstrained container of blocks.
/// </summary>
/// <remarks>The scope of coordinates is undefined for unconstrained block containers.</remarks>
public interface IBlockCollection
{
/// <summary>
/// Gets a basic block from an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>A basic <see cref="IBlock"/> from the collection at the given coordinates.</returns>
IBlock GetBlock (int x, int y, int z);
/// <summary>
/// Gets a reference object to a basic block within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>A basic <see cref="IBlock"/> acting as a reference directly into the container at the given coordinates.</returns>
IBlock GetBlockRef (int x, int y, int z);
/// <summary>
/// Updates a block in an unbounded block container with data from an existing <see cref="IBlock"/> object.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="block">The <see cref="IBlock"/> to copy basic data from.</param>
void SetBlock (int x, int y, int z, IBlock block);
/// <summary>
/// Gets a block's id (type) from an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>The block id (type) from the block container at the given coordinates.</returns>
int GetID (int x, int y, int z);
/// <summary>
/// Sets a block's id (type) within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="id">The id (type) to assign to a block at the given coordinates.</param>
void SetID (int x, int y, int z, int id);
/// <summary>
/// Gets info and attributes on a block's type within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>A <see cref="BlockInfo"/> instance for the block's type.</returns>
BlockInfo GetInfo (int x, int y, int z);
}
/// <summary>
/// An unbounded container of blocks supporting data fields.
/// </summary>
/// <seealso cref="IBoundedDataBlockCollection"/>
public interface IDataBlockCollection : IBlockCollection
{
/// <summary>
/// Gets a block with data field from an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>An <see cref="IDataBlock"/> from the collection at the given coordinates.</returns>
new IDataBlock GetBlock (int x, int y, int z);
/// <summary>
/// Gets a reference object to a block with data field within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>An <see cref="IDataBlock"/> acting as a reference directly into the container at the given coordinates.</returns>
new IDataBlock GetBlockRef (int x, int y, int z);
/// <summary>
/// Updates a block in an unbounded block container with data from an existing <see cref="IDataBlock"/> object.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="block">The <see cref="IDataBlock"/> to copy data from.</param>
void SetBlock (int x, int y, int z, IDataBlock block);
/// <summary>
/// Gets a block's data field from an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>The data field of a block at the given coordinates.</returns>
int GetData (int x, int y, int z);
/// <summary>
/// Sets a block's data field within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="data">The data field to assign to a block at the given coordinates.</param>
void SetData (int x, int y, int z, int data);
}
/// <summary>
/// An unbounded container of blocks supporting dual-source lighting.
/// </summary>
/// <seealso cref="IBoundedLitBlockCollection"/>
public interface ILitBlockCollection : IBlockCollection
{
/// <summary>
/// Gets a block with lighting information from an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>An <see cref="ILitBlock"/> from the collection at the given coordinates.</returns>
new ILitBlock GetBlock (int x, int y, int z);
/// <summary>
/// Gets a reference object to a block with lighting information within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>An <see cref="ILitBlock"/> acting as a reference directly into the container at the given coordinates.</returns>
new ILitBlock GetBlockRef (int x, int y, int z);
/// <summary>
/// Updates a block in an unbounded block container with data from an existing <see cref="ILitBlock"/> object.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="block">The <see cref="ILitBlock"/> to copy data from.</param>
void SetBlock (int x, int y, int z, ILitBlock block);
/// <summary>
/// Gets a block's block-source light value from an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>The block-source light value of a block at the given coordinates.</returns>
int GetBlockLight (int x, int y, int z);
/// <summary>
/// Gets a block's sky-source light value from an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>The sky-source light value of a block at the given coordinates.</returns>
int GetSkyLight (int x, int y, int z);
/// <summary>
/// Sets a block's block-source light value within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="light">The block-source light value to assign to a block at the given coordinates.</param>
void SetBlockLight (int x, int y, int z, int light);
/// <summary>
/// Sets a block's sky-source light value within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="light">The sky-source light value to assign to a block at the given coordinates.</param>
void SetSkyLight (int x, int y, int z, int light);
/// <summary>
/// Gets the Y-coordinate of the lowest block with unobstructed view of the sky at the given coordinates within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>The height value of an X-Z coordinate pair in the block container.</returns>
/// <remarks>The height value represents the lowest block with an unobstructed view of the sky. This is the lowest block with
/// a maximum-value sky-light value. Fully transparent blocks, like glass, do not count as an obstruction.</remarks>
int GetHeight (int x, int z);
/// <summary>
/// Sets the Y-coordinate of the lowest block with unobstructed view of the sky at the given coordinates within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="height">The height value of an X-Z coordinate pair in the block container.</param>
/// <remarks>Minecraft lighting algorithms rely heavily on this value being correct. Setting this value too low may result in
/// rooms that can never get dark, for example.</remarks>
void SetHeight (int x, int z, int height);
/// <summary>
/// Recalculates the block-source light value of a single block within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global 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="ILitBlockCollection"/> objects, if they can be resolved.</para>
/// <para>This function assumes that the entire <see cref="ILitBlockCollection"/> and neighboring <see cref="ILitBlockCollection"/>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>
void UpdateBlockLight (int x, int y, int z);
/// <summary>
/// Recalculates the sky-source light value of a single block within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global 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="ILitBlockCollection"/> objects, if they can be resolved.</para>
/// <para>This function assumes that the entire <see cref="ILitBlockCollection"/> and neighboring <see cref="ILitBlockCollection"/>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>
void UpdateSkyLight (int x, int y, int z);
}
/// <summary>
/// An unbounded container for blocks supporting additional properties.
/// </summary>
/// <seealso cref="IBoundedPropertyBlockCollection"/>
public interface IPropertyBlockCollection : IBlockCollection
{
/// <summary>
/// Gets a block supporting extra properties from an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>An <see cref="IPropertyBlock"/> from the collection at the given coordinates.</returns>
new IPropertyBlock GetBlock (int x, int y, int z);
/// <summary>
/// Gets a reference object to a block supporting extra properties within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>An <see cref="IPropertyBlock"/> acting as a reference directly into the container at the given coordinates.</returns>
new IPropertyBlock GetBlockRef (int x, int y, int z);
/// <summary>
/// Updates a block in an unbounded block container with data from an existing <see cref="IPropertyBlock"/> object.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="block">The <see cref="IPropertyBlock"/> to copy data from.</param>
void SetBlock (int x, int y, int z, IPropertyBlock block);
/// <summary>
/// Gets the <see cref="TileEntity"/> record of a block within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>A <see cref="TileEntity"/> record attached to a block at the given coordinates, or null if no tile entity is set.</returns>
TileEntity GetTileEntity (int x, int y, int z);
/// <summary>
/// Sets a <see cref="TileEntity"/> record to a block within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="te">The <see cref="TileEntity"/> record to assign to the given block.</param>
/// <exception cref="ArgumentException">Thrown when an incompatible <see cref="TileEntity"/> is added to a block.</exception>
/// <exception cref="InvalidOperationException">Thrown when a <see cref="TileEntity"/> is added to a block that does not use tile entities.</exception>
void SetTileEntity (int x, int y, int z, TileEntity te);
/// <summary>
/// Creates a new default <see cref="TileEntity"/> record for a block within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <exception cref="InvalidOperationException">Thrown when a <see cref="TileEntity"/> is created for a block that does not use tile entities.</exception>
/// <exception cref="UnknownTileEntityException">Thrown when the tile entity type associated with the given block has not been registered with <see cref="TileEntityFactory"/>.</exception>
void CreateTileEntity (int x, int y, int z);
/// <summary>
/// Deletes a <see cref="TileEntity"/> record associated with a block within an unbounded block container, if it exists.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
void ClearTileEntity (int x, int y, int z);
}
/// <summary>
/// An unbounded container of blocks supporting data, lighting, and properties.
/// </summary>
/// <seealso cref="IBoundedAlphaBlockCollection"/>
public interface IAlphaBlockCollection : IDataBlockCollection, ILitBlockCollection, IPropertyBlockCollection
{
/// <summary>
/// Gets a context-insensitive Alpha-compatible block from an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>An <see cref="AlphaBlock"/> from the collection at the given coordinates.</returns>
new AlphaBlock GetBlock (int x, int y, int z);
/// <summary>
/// Gets a reference object to a context-insensitive Alpha-compatible block within an unbounded block container.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <returns>An <see cref="AlphaBlockRef"/> acting as a reference directly into the container at the given coordinates.</returns>
new AlphaBlockRef GetBlockRef (int x, int y, int z);
/// <summary>
/// Updates a block in an unbounded block container with data from an existing <see cref="AlphaBlock"/> object.
/// </summary>
/// <param name="x">The global X-coordinate of a block.</param>
/// <param name="y">The global Y-coordinate of a block.</param>
/// <param name="z">The global Z-coordinate of a block.</param>
/// <param name="block">The <see cref="AlphaBlock"/> to copy data from.</param>
void SetBlock (int x, int y, int z, AlphaBlock block);
}
}

View file

@ -13,7 +13,7 @@ namespace Substrate.Entities
new SchemaNodeString("id", "Item"), new SchemaNodeString("id", "Item"),
new SchemaNodeScaler("Health", TagType.TAG_SHORT), new SchemaNodeScaler("Health", TagType.TAG_SHORT),
new SchemaNodeScaler("Age", TagType.TAG_SHORT), new SchemaNodeScaler("Age", TagType.TAG_SHORT),
new SchemaNodeCompound("Item", Item.ItemSchema), new SchemaNodeCompound("Item", Item.Schema),
}); });
private short _health; private short _health;

View file

@ -1,16 +1,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using Substrate.Core;
using Substrate.Nbt;
namespace Substrate.Entities namespace Substrate.Entities
{ {
using Substrate.Nbt;
public class EntityMinecartChest : EntityMinecart, IItemContainer public class EntityMinecartChest : EntityMinecart, IItemContainer
{ {
public static readonly SchemaNodeCompound MinecartChestSchema = MinecartSchema.MergeInto(new SchemaNodeCompound("") public static readonly SchemaNodeCompound MinecartChestSchema = MinecartSchema.MergeInto(new SchemaNodeCompound("")
{ {
new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.InventorySchema), new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.Schema),
}); });
private static int _CAPACITY = 27; private static int _CAPACITY = 27;

View file

@ -0,0 +1,195 @@
using System;
using System.Collections.Generic;
using System.IO;
using Substrate.Core;
using Substrate.Nbt;
namespace Substrate.ImportExport
{
public class Schematic
{
private static SchemaNodeCompound _schema = new SchemaNodeCompound()
{
new SchemaNodeScaler("Width", TagType.TAG_SHORT),
new SchemaNodeScaler("Length", TagType.TAG_SHORT),
new SchemaNodeScaler("Height", TagType.TAG_SHORT),
new SchemaNodeString("Materials", "Alpha"),
new SchemaNodeArray("Blocks"),
new SchemaNodeArray("Data"),
new SchemaNodeList("Entities", TagType.TAG_COMPOUND, Entity.Schema),
new SchemaNodeList("TileEntities", TagType.TAG_COMPOUND, TileEntity.Schema),
};
private XZYByteArray _blocks;
private XZYNibbleArray _data;
private XZYNibbleArray _blockLight;
private XZYNibbleArray _skyLight;
private ZXByteArray _heightMap;
private TagNodeList _entities;
private TagNodeList _tileEntities;
private AlphaBlockCollection _blockset;
private EntityCollection _entityset;
private Schematic ()
{
}
public Schematic (AlphaBlockCollection blocks, EntityCollection entities)
{
_blockset = blocks;
_entityset = entities;
}
public Schematic (int xdim, int ydim, int zdim)
{
_blocks = new XZYByteArray(xdim, ydim, zdim);
_data = new XZYNibbleArray(xdim, ydim, zdim);
_blockLight = new XZYNibbleArray(xdim, ydim, zdim);
_skyLight = new XZYNibbleArray(xdim, ydim, zdim);
_heightMap = new ZXByteArray(xdim, zdim);
_entities = new TagNodeList(TagType.TAG_COMPOUND);
_tileEntities = new TagNodeList(TagType.TAG_COMPOUND);
_blockset = new AlphaBlockCollection(_blocks, _data, _blockLight, _skyLight, _heightMap, _tileEntities);
_entityset = new EntityCollection(_entities);
}
#region Properties
public AlphaBlockCollection Blocks
{
get { return _blockset; }
set { _blockset = value; }
}
public EntityCollection Entities
{
get { return _entityset; }
set { _entityset = value; }
}
#endregion
public static Schematic Import (string path)
{
NBTFile schematicFile = new NBTFile(path);
if (!schematicFile.Exists()) {
return null;
}
Stream nbtStream = schematicFile.GetDataInputStream();
if (nbtStream == null) {
return null;
}
NbtTree tree = new NbtTree(nbtStream);
NbtVerifier v = new NbtVerifier(tree.Root, _schema);
if (!v.Verify()) {
return null;
}
//TagNodeCompound schematic = tree.Root["Schematic"] as TagNodeCompound;
TagNodeCompound schematic = tree.Root;
int xdim = schematic["Width"].ToTagShort();
int zdim = schematic["Length"].ToTagShort();
int ydim = schematic["Height"].ToTagShort();
Schematic self = new Schematic(xdim, ydim, zdim);
// Damnit, schematic is YZX ordering.
YZXByteArray schemaBlocks = new YZXByteArray(xdim, ydim, zdim, schematic["Blocks"].ToTagByteArray());
YZXByteArray schemaData = new YZXByteArray(xdim, ydim, zdim, schematic["Data"].ToTagByteArray());
for (int x = 0; x < xdim; x++) {
for (int y = 0; y < ydim; y++) {
for (int z = 0; z < zdim; z++) {
self._blocks[x, y, z] = schemaBlocks[x, y, z];
self._data[x, y, z] = schemaData[x, y, z];
}
}
}
TagNodeList entities = schematic["Entities"] as TagNodeList;
foreach (TagNode e in entities) {
self._entities.Add(e);
}
TagNodeList tileEntities = schematic["TileEntities"] as TagNodeList;
foreach (TagNode te in tileEntities) {
self._tileEntities.Add(te);
}
self._blockset.Refresh();
return self;
}
public void Export (string path)
{
int xdim = _blockset.XDim;
int ydim = _blockset.YDim;
int zdim = _blockset.ZDim;
byte[] blockData = new byte[xdim * ydim * zdim];
byte[] dataData = new byte[xdim * ydim * zdim];
YZXByteArray schemaBlocks = new YZXByteArray(_blockset.XDim, _blockset.YDim, _blockset.ZDim, blockData);
YZXByteArray schemaData = new YZXByteArray(_blockset.XDim, _blockset.YDim, _blockset.ZDim, dataData);
TagNodeList entities = new TagNodeList(TagType.TAG_COMPOUND);
TagNodeList tileEntities = new TagNodeList(TagType.TAG_COMPOUND);
for (int x = 0; x < xdim; x++) {
for (int z = 0; z < zdim; z++) {
for (int y = 0; y < ydim; y++) {
AlphaBlock block = _blockset.GetBlock(x, y, z);
schemaBlocks[x, y, z] = (byte)block.ID;
schemaData[x, y, z] = (byte)block.Data;
TileEntity te = block.GetTileEntity();
if (te != null) {
te.X = x;
te.Y = y;
te.Z = z;
tileEntities.Add(te.BuildTree());
}
}
}
}
foreach (EntityTyped e in _entityset) {
entities.Add(e.BuildTree());
}
TagNodeCompound schematic = new TagNodeCompound();
schematic["Width"] = new TagNodeShort((short)xdim);
schematic["Length"] = new TagNodeShort((short)zdim);
schematic["Height"] = new TagNodeShort((short)ydim);
schematic["Entities"] = entities;
schematic["TileEntities"] = tileEntities;
schematic["Materials"] = new TagNodeString("Alpha");
schematic["Blocks"] = new TagNodeByteArray(blockData);
schematic["Data"] = new TagNodeByteArray(dataData);
NBTFile schematicFile = new NBTFile(path);
Stream nbtStream = schematicFile.GetDataOutputStream();
if (nbtStream == null) {
return;
}
NbtTree tree = new NbtTree(schematic, "Schematic");
tree.WriteTo(nbtStream);
nbtStream.Close();
}
}
}

View file

@ -6,14 +6,12 @@ using Substrate.Nbt;
namespace Substrate namespace Substrate
{ {
public interface IItemContainer /// <summary>
{ /// Represents an item (or item stack) within an item slot.
ItemCollection Items { get; } /// </summary>
}
public class Item : INbtObject<Item>, ICopyable<Item> public class Item : INbtObject<Item>, ICopyable<Item>
{ {
public static readonly SchemaNodeCompound ItemSchema = new SchemaNodeCompound("") private static readonly SchemaNodeCompound _schema = new SchemaNodeCompound("")
{ {
new SchemaNodeScaler("id", TagType.TAG_SHORT), new SchemaNodeScaler("id", TagType.TAG_SHORT),
new SchemaNodeScaler("Damage", TagType.TAG_SHORT), new SchemaNodeScaler("Damage", TagType.TAG_SHORT),
@ -24,40 +22,73 @@ namespace Substrate
private byte _count; private byte _count;
private short _damage; private short _damage;
/// <summary>
/// Constructs an empty <see cref="Item"/> instance.
/// </summary>
public Item ()
{
}
/// <summary>
/// Constructs an <see cref="Item"/> instance representing the given item id.
/// </summary>
/// <param name="id">An item id.</param>
public Item (int id)
{
_id = (short)id;
}
#region Properties
/// <summary>
/// Gets an <see cref="ItemInfo"/> entry for this item's type.
/// </summary>
public ItemInfo Info public ItemInfo Info
{ {
get { return ItemInfo.ItemTable[_id]; } get { return ItemInfo.ItemTable[_id]; }
} }
/// <summary>
/// Gets or sets the current type (id) of the item.
/// </summary>
public int ID public int ID
{ {
get { return _id; } get { return _id; }
set { _id = (short)value; } set { _id = (short)value; }
} }
/// <summary>
/// Gets or sets the damage value of the item.
/// </summary>
/// <remarks>The damage value may represent a generic data value for some items.</remarks>
public int Damage public int Damage
{ {
get { return _damage; } get { return _damage; }
set { _damage = (short)value; } set { _damage = (short)value; }
} }
/// <summary>
/// Gets or sets the number of this item stacked together in an item slot.
/// </summary>
public int Count public int Count
{ {
get { return _count; } get { return _count; }
set { _count = (byte)value; } set { _count = (byte)value; }
} }
public Item () /// <summary>
/// Gets a <see cref="SchemaNode"/> representing the schema of an item.
/// </summary>
public static SchemaNodeCompound Schema
{ {
get { return _schema; }
} }
public Item (int id) #endregion
{
_id = (short)id;
}
#region ICopyable<Item> Members #region ICopyable<Item> Members
/// <inheritdoc/>
public Item Copy () public Item Copy ()
{ {
Item item = new Item(); Item item = new Item();
@ -72,6 +103,7 @@ namespace Substrate
#region INBTObject<Item> Members #region INBTObject<Item> Members
/// <inheritdoc/>
public Item LoadTree (TagNode tree) public Item LoadTree (TagNode tree)
{ {
TagNodeCompound ctree = tree as TagNodeCompound; TagNodeCompound ctree = tree as TagNodeCompound;
@ -86,6 +118,7 @@ namespace Substrate
return this; return this;
} }
/// <inheritdoc/>
public Item LoadTreeSafe (TagNode tree) public Item LoadTreeSafe (TagNode tree)
{ {
if (!ValidateTree(tree)) { if (!ValidateTree(tree)) {
@ -95,6 +128,7 @@ namespace Substrate
return LoadTree(tree); return LoadTree(tree);
} }
/// <inheritdoc/>
public TagNode BuildTree () public TagNode BuildTree ()
{ {
TagNodeCompound tree = new TagNodeCompound(); TagNodeCompound tree = new TagNodeCompound();
@ -105,42 +139,66 @@ namespace Substrate
return tree; return tree;
} }
/// <inheritdoc/>
public bool ValidateTree (TagNode tree) public bool ValidateTree (TagNode tree)
{ {
return new NbtVerifier(tree, ItemSchema).Verify(); return new NbtVerifier(tree, _schema).Verify();
} }
#endregion #endregion
} }
/// <summary>
/// Represents a collection of items, such as a chest or an inventory.
/// </summary>
/// <remarks>ItemCollections have a limited number of slots that depends on where they are used.</remarks>
public class ItemCollection : INbtObject<ItemCollection>, ICopyable<ItemCollection> public class ItemCollection : INbtObject<ItemCollection>, ICopyable<ItemCollection>
{ {
public static readonly SchemaNodeCompound InventorySchema = Item.ItemSchema.MergeInto(new SchemaNodeCompound("") private static readonly SchemaNodeCompound _schema = Item.Schema.MergeInto(new SchemaNodeCompound("")
{ {
new SchemaNodeScaler("Slot", TagType.TAG_BYTE), new SchemaNodeScaler("Slot", TagType.TAG_BYTE),
}); });
public static readonly SchemaNodeList ListSchema = new SchemaNodeList("", TagType.TAG_COMPOUND, InventorySchema); private static readonly SchemaNodeList _listSchema = new SchemaNodeList("", TagType.TAG_COMPOUND, _schema);
protected Dictionary<int, Item> _items; private Dictionary<int, Item> _items;
protected int _capacity; private int _capacity;
/// <summary>
/// Constructs an <see cref="ItemCollection"/> with at most <paramref name="capacity"/> item slots.
/// </summary>
/// <param name="capacity">The upper bound on item slots available.</param>
/// <remarks>The <paramref name="capacity"/> parameter does not necessarily indicate the true capacity of an item collection.
/// The player object, for example, contains a conventional inventory, a range of invalid slots, and then equipment. Capacity in
/// this case would refer to the highest equipment slot.</remarks>
public ItemCollection (int capacity) public ItemCollection (int capacity)
{ {
_capacity = capacity; _capacity = capacity;
_items = new Dictionary<int, Item>(); _items = new Dictionary<int, Item>();
} }
#region Properties
/// <summary>
/// Gets the capacity of the item collection.
/// </summary>
public int Capacity public int Capacity
{ {
get { return _capacity; } get { return _capacity; }
} }
/// <summary>
/// Gets the current number of item slots actually used in the collection.
/// </summary>
public int Count public int Count
{ {
get { return _items.Count; } get { return _items.Count; }
} }
/// <summary>
/// Gets or sets an item in a given item slot.
/// </summary>
/// <param name="slot">The item slot to query or insert an item or item stack into.</param>
public Item this [int slot] public Item this [int slot]
{ {
get get
@ -159,16 +217,39 @@ namespace Substrate
} }
} }
/// <summary>
/// Gets a <see cref="SchemaNode"/> representing the schema of an item collection.
/// </summary>
public static SchemaNodeCompound Schema
{
get { return _schema; }
}
#endregion
/// <summary>
/// Checks if an item exists in the given item slot.
/// </summary>
/// <param name="slot">The item slot to check.</param>
/// <returns>True if an item or stack of items exists in the given slot.</returns>
public bool ItemExists (int slot) public bool ItemExists (int slot)
{ {
return _items.ContainsKey(slot); return _items.ContainsKey(slot);
} }
/// <summary>
/// Removes an item from the given item slot, if it exists.
/// </summary>
/// <param name="slot">The item slot to clear.</param>
/// <returns>True if an item was removed; false otherwise.</returns>
public bool Clear (int slot) public bool Clear (int slot)
{ {
return _items.Remove(slot); return _items.Remove(slot);
} }
/// <summary>
/// Removes all items from the item collection.
/// </summary>
public void ClearAllItems () public void ClearAllItems ()
{ {
_items.Clear(); _items.Clear();
@ -176,6 +257,7 @@ namespace Substrate
#region ICopyable<ItemCollection> Members #region ICopyable<ItemCollection> Members
/// <inheritdoc/>
public ItemCollection Copy () public ItemCollection Copy ()
{ {
ItemCollection ic = new ItemCollection(_capacity); ItemCollection ic = new ItemCollection(_capacity);
@ -189,6 +271,7 @@ namespace Substrate
#region INBTObject<ItemCollection> Members #region INBTObject<ItemCollection> Members
/// <inheritdoc/>
public ItemCollection LoadTree (TagNode tree) public ItemCollection LoadTree (TagNode tree)
{ {
TagNodeList ltree = tree as TagNodeList; TagNodeList ltree = tree as TagNodeList;
@ -204,6 +287,7 @@ namespace Substrate
return this; return this;
} }
/// <inheritdoc/>
public ItemCollection LoadTreeSafe (TagNode tree) public ItemCollection LoadTreeSafe (TagNode tree)
{ {
if (!ValidateTree(tree)) { if (!ValidateTree(tree)) {
@ -213,6 +297,7 @@ namespace Substrate
return LoadTree(tree); return LoadTree(tree);
} }
/// <inheritdoc/>
public TagNode BuildTree () public TagNode BuildTree ()
{ {
TagNodeList list = new TagNodeList(TagType.TAG_COMPOUND); TagNodeList list = new TagNodeList(TagType.TAG_COMPOUND);
@ -226,9 +311,10 @@ namespace Substrate
return list; return list;
} }
/// <inheritdoc/>
public bool ValidateTree (TagNode tree) public bool ValidateTree (TagNode tree)
{ {
return new NbtVerifier(tree, ListSchema).Verify(); return new NbtVerifier(tree, _listSchema).Verify();
} }
#endregion #endregion

View file

@ -19,6 +19,7 @@ namespace Substrate.Nbt
{ {
private Stream _stream = null; private Stream _stream = null;
private TagNodeCompound _root = null; private TagNodeCompound _root = null;
private string _rootName = "";
private static TagNodeNull _nulltag = new TagNodeNull(); private static TagNodeNull _nulltag = new TagNodeNull();
@ -30,6 +31,15 @@ namespace Substrate.Nbt
get { return _root; } get { return _root; }
} }
/// <summary>
/// Gets or sets the name of the tree's root node.
/// </summary>
public string Name
{
get { return _rootName; }
set { _rootName = value; }
}
/// <summary> /// <summary>
/// Constructs a wrapper around a new NBT tree with an empty root node. /// Constructs a wrapper around a new NBT tree with an empty root node.
/// </summary> /// </summary>
@ -47,6 +57,17 @@ namespace Substrate.Nbt
_root = tree; _root = tree;
} }
/// <summary>
/// Constructs a wrapper around another NBT tree and gives it a name.
/// </summary>
/// <param name="tree">The root node of an NBT tree.</param>
/// <param name="name">The name for the root node.</param>
public NbtTree (TagNodeCompound tree, string name)
{
_root = tree;
_rootName = name;
}
/// <summary> /// <summary>
/// Constructs and wrapper around a new NBT tree parsed from a source data stream. /// Constructs and wrapper around a new NBT tree parsed from a source data stream.
/// </summary> /// </summary>
@ -79,7 +100,7 @@ namespace Substrate.Nbt
_stream = s; _stream = s;
if (_root != null) { if (_root != null) {
WriteTag("", _root); WriteTag(_rootName, _root);
} }
_stream = null; _stream = null;

View file

@ -20,7 +20,7 @@ namespace Substrate
new SchemaNodeScaler("Health", TagType.TAG_SHORT), new SchemaNodeScaler("Health", TagType.TAG_SHORT),
new SchemaNodeScaler("HurtTime", TagType.TAG_SHORT), new SchemaNodeScaler("HurtTime", TagType.TAG_SHORT),
new SchemaNodeScaler("Dimension", TagType.TAG_INT), new SchemaNodeScaler("Dimension", TagType.TAG_INT),
new SchemaNodeList("Inventory", TagType.TAG_COMPOUND, ItemCollection.InventorySchema), new SchemaNodeList("Inventory", TagType.TAG_COMPOUND, ItemCollection.Schema),
new SchemaNodeScaler("World", TagType.TAG_STRING, SchemaOptions.OPTIONAL), new SchemaNodeScaler("World", TagType.TAG_STRING, SchemaOptions.OPTIONAL),
new SchemaNodeScaler("Sleeping", TagType.TAG_BYTE, SchemaOptions.CREATE_ON_MISSING), new SchemaNodeScaler("Sleeping", TagType.TAG_BYTE, SchemaOptions.CREATE_ON_MISSING),
new SchemaNodeScaler("SleepTimer", TagType.TAG_SHORT, SchemaOptions.CREATE_ON_MISSING), new SchemaNodeScaler("SleepTimer", TagType.TAG_SHORT, SchemaOptions.CREATE_ON_MISSING),

View file

@ -1,17 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using Substrate.Core;
using Substrate.Nbt;
namespace Substrate.TileEntities namespace Substrate.TileEntities
{ {
using Substrate.Nbt;
public class TileEntityChest : TileEntity, IItemContainer public class TileEntityChest : TileEntity, IItemContainer
{ {
public static readonly SchemaNodeCompound ChestSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") public static readonly SchemaNodeCompound ChestSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("")
{ {
new SchemaNodeString("id", "Chest"), new SchemaNodeString("id", "Chest"),
new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.InventorySchema), new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.Schema),
}); });
private const int _CAPACITY = 27; private const int _CAPACITY = 27;

View file

@ -1,11 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using Substrate.Core;
using Substrate.Nbt;
namespace Substrate.TileEntities namespace Substrate.TileEntities
{ {
using Substrate.Nbt;
public class TileEntityFurnace : TileEntity, IItemContainer public class TileEntityFurnace : TileEntity, IItemContainer
{ {
public static readonly SchemaNodeCompound FurnaceSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") public static readonly SchemaNodeCompound FurnaceSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("")
@ -13,7 +12,7 @@ namespace Substrate.TileEntities
new SchemaNodeString("id", "Furnace"), new SchemaNodeString("id", "Furnace"),
new SchemaNodeScaler("BurnTime", TagType.TAG_SHORT), new SchemaNodeScaler("BurnTime", TagType.TAG_SHORT),
new SchemaNodeScaler("CookTime", TagType.TAG_SHORT), new SchemaNodeScaler("CookTime", TagType.TAG_SHORT),
new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.InventorySchema), new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.Schema),
}); });
private const int _CAPACITY = 3; private const int _CAPACITY = 3;

View file

@ -66,7 +66,7 @@ namespace Substrate.TileEntities
} }
_delay = ctree["Delay"].ToTagShort(); _delay = ctree["Delay"].ToTagShort();
_entityID = ctree["EntityID"].ToTagString(); _entityID = ctree["EntityId"].ToTagString();
return this; return this;
} }
@ -74,7 +74,7 @@ namespace Substrate.TileEntities
public override TagNode BuildTree () public override TagNode BuildTree ()
{ {
TagNodeCompound tree = base.BuildTree() as TagNodeCompound; TagNodeCompound tree = base.BuildTree() as TagNodeCompound;
tree["EntityID"] = new TagNodeString(_entityID); tree["EntityId"] = new TagNodeString(_entityID);
tree["Delay"] = new TagNodeShort(_delay); tree["Delay"] = new TagNodeShort(_delay);
return tree; return tree;

View file

@ -1,17 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using Substrate.Core;
using Substrate.Nbt;
namespace Substrate.TileEntities namespace Substrate.TileEntities
{ {
using Substrate.Nbt;
public class TileEntityTrap : TileEntity, IItemContainer public class TileEntityTrap : TileEntity, IItemContainer
{ {
public static readonly SchemaNodeCompound TrapSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") public static readonly SchemaNodeCompound TrapSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("")
{ {
new SchemaNodeString("id", "Trap"), new SchemaNodeString("id", "Trap"),
new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.InventorySchema), new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.Schema),
}); });
private const int _CAPACITY = 8; private const int _CAPACITY = 8;

View file

@ -65,9 +65,12 @@
<Compile Include="Source\AlphaWorld.cs" /> <Compile Include="Source\AlphaWorld.cs" />
<Compile Include="Source\BetaChunkManager.cs" /> <Compile Include="Source\BetaChunkManager.cs" />
<Compile Include="Source\BetaWorld.cs" /> <Compile Include="Source\BetaWorld.cs" />
<Compile Include="Source\Core\BoundedBlockInterface.cs" />
<Compile Include="Source\Core\ItemInterface.cs" />
<Compile Include="Source\Core\OpenWorldEvent.cs" /> <Compile Include="Source\Core\OpenWorldEvent.cs" />
<Compile Include="Source\Core\RegionInterface.cs" /> <Compile Include="Source\Core\RegionInterface.cs" />
<Compile Include="Source\IO\Schematic.cs" /> <Compile Include="Source\Core\UnboundedBlockInterface.cs" />
<Compile Include="Source\ImportExport\Schematic.cs" />
<Compile Include="Source\LevelIOException.cs" /> <Compile Include="Source\LevelIOException.cs" />
<Compile Include="Source\AlphaBlock.cs" /> <Compile Include="Source\AlphaBlock.cs" />
<Compile Include="Source\AlphaBlockRef.cs" /> <Compile Include="Source\AlphaBlockRef.cs" />