From 1e029325bca192d14936b0cb00d9e81030b67fc4 Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Fri, 8 Apr 2011 02:16:06 +0000 Subject: [PATCH] Major Block interface factoring to ease support of alternative block containers such as Classic Meps or MCSchematic files. --- Substrate/SubstrateCS/Source/Block.cs | 120 ++++++- .../SubstrateCS/Source/BlockInterface.cs | 87 ++++- Substrate/SubstrateCS/Source/BlockManager.cs | 284 +++++++++++++++- Substrate/SubstrateCS/Source/BlockRef.cs | 111 ++++++- Substrate/SubstrateCS/Source/Chunk.cs | 309 ++++++++++++------ .../SubstrateCS/Source/ChunkInterface.cs | 2 +- Substrate/SubstrateCS/Source/ChunkRef.cs | 204 ++++++++---- Substrate/SubstrateCS/Substrate.csproj | 39 +++ Substrate/SubstrateCS/Substrate.sln | 2 +- 9 files changed, 993 insertions(+), 165 deletions(-) diff --git a/Substrate/SubstrateCS/Source/Block.cs b/Substrate/SubstrateCS/Source/Block.cs index 635c927..3b52c07 100644 --- a/Substrate/SubstrateCS/Source/Block.cs +++ b/Substrate/SubstrateCS/Source/Block.cs @@ -7,7 +7,123 @@ namespace Substrate using NBT; using Utility; - public class Block : IBlock, ICopyable + public class Block : IPropertyBlock, ICopyable + { + private int _id; + private int _data; + + private TileEntity _tileEntity; + + public Block (int id) + { + _id = id; + } + + public Block (int id, int data) + { + _id = id; + _data = data; + } + + public Block (IChunk chunk, int lx, int ly, int lz) + { + _id = chunk.GetBlockID(lx, ly, lz); + _data = chunk.GetBlockData(lx, ly, lz); + _tileEntity = chunk.GetTileEntity(lx, ly, lz).Copy(); + } + + + #region IBlock Members + + public BlockInfo Info + { + get { return BlockInfo.BlockTable[_id]; } + } + + public int ID + { + get { return _id; } + set + { + BlockInfoEx info1 = BlockInfo.BlockTable[_id] as BlockInfoEx; + BlockInfoEx info2 = BlockInfo.BlockTable[value] as BlockInfoEx; + + if (info1 != info2) { + if (info1 != null) { + _tileEntity = null; + } + + if (info2 != null) { + _tileEntity = TileEntityFactory.Create(info2.TileEntityName); + } + } + + _id = value; + } + } + + public int Data + { + get { return _data; } + set + { + /*if (BlockManager.EnforceDataLimits && BlockInfo.BlockTable[_id] != null) { + if (!BlockInfo.BlockTable[_id].TestData(value)) { + return; + } + }*/ + _data = value; + } + } + + #endregion + + + #region IPropertyBlock Members + + public TileEntity GetTileEntity () + { + return _tileEntity; + } + + public bool SetTileEntity (TileEntity te) + { + BlockInfoEx info = BlockInfo.BlockTable[_id] as BlockInfoEx; + if (info == null) { + return false; + } + + if (te.GetType() != TileEntityFactory.Lookup(info.TileEntityName)) { + return false; + } + + _tileEntity = te; + return true; + } + + public bool ClearTileEntity () + { + _tileEntity = null; + return true; + } + + #endregion + + + #region ICopyable Members + + public Block Copy () + { + Block block = new Block(_id, _data); + block._tileEntity = _tileEntity.Copy(); + + return block; + } + + #endregion + } + + /*public class Block : IBlock, ICopyable { private int _id; private int _data; @@ -128,5 +244,5 @@ namespace Substrate } #endregion - } + }*/ } diff --git a/Substrate/SubstrateCS/Source/BlockInterface.cs b/Substrate/SubstrateCS/Source/BlockInterface.cs index f5adaab..3a5cb54 100644 --- a/Substrate/SubstrateCS/Source/BlockInterface.cs +++ b/Substrate/SubstrateCS/Source/BlockInterface.cs @@ -4,8 +4,91 @@ using System.Text; namespace Substrate { - public interface IBlock + { + BlockInfo Info { get; } + int ID { get; set; } + int Data { get; set; } + } + + public interface ILitBlock : IBlock + { + int BlockLight { get; set; } + int SkyLight { get; set; } + } + + public interface IPropertyBlock : IBlock + { + TileEntity GetTileEntity (); + bool SetTileEntity (TileEntity te); + bool ClearTileEntity (); + } + + public interface IBlockContainer + { + IBlock GetBlock (int x, int y, int z); + IBlock GetBlockRef (int x, int y, int z); + + void SetBlock (int x, int y, int z, IBlock block); + + BlockInfo GetBlockInfo (int x, int y, int z); + + int GetBlockID (int x, int y, int z); + int GetBlockData (int x, int y, int z); + + bool SetBlockID (int x, int y, int z, int id); + bool SetBlockData (int x, int y, int z, int data); + } + + public interface IBoundedBlockContainer : IBlockContainer + { + int XDim { get; } + int YDim { get; } + int ZDim { get; } + } + + public interface IResizableBlockContainer : IBoundedBlockContainer + { + new int XDim { get; set; } + new int YDim { get; set; } + new int ZDim { get; set; } + } + + public interface ILitBlockContainer : IBlockContainer + { + 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); + + int GetBlockLight (int x, int y, int z); + int GetBlockSkyLight (int x, int y, int z); + + bool SetBlockLight (int x, int y, int z, int light); + bool SetBlockSkyLight (int x, int y, int z, int light); + } + + public interface IPropertyBlockContainer : IBlockContainer + { + 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); + bool SetTileEntity (int x, int y, int z, TileEntity te); + bool ClearTileEntity (int x, int y, int z); + } + + public interface IAlphaBlockContainer : ILitBlockContainer, IPropertyBlockContainer + { + } + + public interface IBlockManager : IAlphaBlockContainer + { + } + + /*public interface IBlock { BlockInfo Info { get; } int ID { get; set; } @@ -53,5 +136,5 @@ namespace Substrate public interface IBlockManager : IBlockContainer { - } + }*/ } diff --git a/Substrate/SubstrateCS/Source/BlockManager.cs b/Substrate/SubstrateCS/Source/BlockManager.cs index 1ec42d4..29587d3 100644 --- a/Substrate/SubstrateCS/Source/BlockManager.cs +++ b/Substrate/SubstrateCS/Source/BlockManager.cs @@ -4,6 +4,286 @@ using System.Text; namespace Substrate { + + public class BlockManager : IBlockManager + { + public const int MIN_X = -32000000; + public const int MAX_X = 32000000; + public const int MIN_Y = 0; + public const int MAX_Y = 128; + public const int MIN_Z = -32000000; + public const int MAX_Z = 32000000; + + protected int _chunkXDim; + protected int _chunkYDim; + protected int _chunkZDim; + protected int _chunkXMask; + protected int _chunkYMask; + protected int _chunkZMask; + protected int _chunkXLog; + protected int _chunkYLog; + protected int _chunkZLog; + + protected IChunkManager _chunkMan; + + protected ChunkRef _cache; + + public BlockManager (IChunkManager cm) + { + _chunkMan = cm; + + Chunk c = new Chunk(0, 0); + + _chunkXDim = c.XDim; + _chunkYDim = c.YDim; + _chunkZDim = c.ZDim; + _chunkXMask = _chunkXDim - 1; + _chunkYMask = _chunkYDim - 1; + _chunkZMask = _chunkZDim - 1; + _chunkXLog = Log2(_chunkXDim); + _chunkYLog = Log2(_chunkYDim); + _chunkZLog = Log2(_chunkZDim); + } + + public Block GetBlock (int x, int y, int z) + { + _cache = GetChunk(x, y, z); + if (_cache == null || !Check(x, y, z)) { + return null; + } + + return _cache.GetBlock(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask); + } + + public BlockRef GetBlockRef (int x, int y, int z) + { + _cache = GetChunk(x, y, z); + if (_cache == null || !Check(x, y, z)) { + return null; + } + + return _cache.GetBlockRef(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask); + } + + public void SetBlock (int x, int y, int z, Block block) + { + _cache = GetChunk(x, y, z); + if (_cache == null || !Check(x, y, z)) { + return; + } + + _cache.SetBlock(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask, block); + } + + protected ChunkRef GetChunk (int x, int y, int z) + { + x >>= _chunkXLog; + z >>= _chunkZLog; + return _chunkMan.GetChunkRef(x, z); + } + + private int Log2 (int x) + { + int c = 0; + while (x > 1) { + x >>= 1; + c++; + } + return c; + } + + /// + /// Called by other block-specific 'get' and 'set' functions to filter + /// out operations on some blocks. Override this method in derrived + /// classes to filter the entire BlockManager. + /// + protected virtual bool Check (int x, int y, int z) + { + return (x >= MIN_X) && (x < MAX_X) && + (y >= MIN_Y) && (y < MAX_Y) && + (z >= MIN_Z) && (z < MAX_Z); + } + + #region IBlockContainer Members + + IBlock IBlockContainer.GetBlock (int x, int y, int z) + { + return GetBlock(x, y, z); + } + + IBlock IBlockContainer.GetBlockRef (int x, int y, int z) + { + return GetBlockRef(x, y, z); + } + + public void SetBlock (int x, int y, int z, IBlock block) + { + _cache.SetBlock(x, y, z, block); + } + + public BlockInfo GetBlockInfo (int x, int y, int z) + { + _cache = GetChunk(x, y, z); + if (_cache == null || !Check(x, y, z)) { + return null; + } + + return _cache.GetBlockInfo(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask); + } + + public int GetBlockID (int x, int y, int z) + { + _cache = GetChunk(x, y, z); + if (_cache == null) { + return 0; + } + + return _cache.GetBlockID(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask); + } + + public int GetBlockData (int x, int y, int z) + { + _cache = GetChunk(x, y, z); + if (_cache == null) { + return 0; + } + + return _cache.GetBlockData(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask); + } + + public bool SetBlockID (int x, int y, int z, int id) + { + _cache = GetChunk(x, y, z); + if (_cache == null || !Check(x, y, z)) { + return false; + } + + return _cache.SetBlockID(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask, id); + } + + public bool SetBlockData (int x, int y, int z, int data) + { + _cache = GetChunk(x, y, z); + if (_cache == null || !Check(x, y, z)) { + return false; + } + + return _cache.SetBlockData(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask, data); + } + + #endregion + + + #region ILitBlockContainer Members + + ILitBlock ILitBlockContainer.GetBlock (int x, int y, int z) + { + throw new NotImplementedException(); + } + + ILitBlock ILitBlockContainer.GetBlockRef (int x, int y, int z) + { + return GetBlockRef(x, y, z); + } + + public void SetBlock (int x, int y, int z, ILitBlock block) + { + _cache.SetBlock(x, y, z, block); + } + + public int GetBlockLight (int x, int y, int z) + { + _cache = GetChunk(x, y, z); + if (_cache == null) { + return 0; + } + + return _cache.GetBlockLight(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask); + } + + public int GetBlockSkyLight (int x, int y, int z) + { + _cache = GetChunk(x, y, z); + if (_cache == null) { + return 0; + } + + return _cache.GetBlockSkyLight(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask); + } + + public bool SetBlockLight (int x, int y, int z, int light) + { + _cache = GetChunk(x, y, z); + if (_cache == null || !Check(x, y, z)) { + return false; + } + + return _cache.SetBlockID(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask, light); + } + + public bool SetBlockSkyLight (int x, int y, int z, int light) + { + _cache = GetChunk(x, y, z); + if (_cache == null || !Check(x, y, z)) { + return false; + } + + return _cache.SetBlockSkyLight(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask, light); + } + + #endregion + + + #region IPropertyBlockContainer Members + + IPropertyBlock IPropertyBlockContainer.GetBlock (int x, int y, int z) + { + return GetBlock(x, y, z); + } + + IPropertyBlock IPropertyBlockContainer.GetBlockRef (int x, int y, int z) + { + return GetBlockRef(x, y, z); + } + + public void SetBlock (int x, int y, int z, IPropertyBlock block) + { + _cache.SetBlock(x, y, z, block); + } + + public TileEntity GetTileEntity (int x, int y, int z) + { + _cache = GetChunk(x, y, z); + if (_cache == null || !Check(x, y, z)) { + return null; + } + + return _cache.GetTileEntity(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask); + } + + public bool SetTileEntity (int x, int y, int z, TileEntity te) + { + _cache = GetChunk(x, y, z); + if (_cache == null || !Check(x, y, z)) { + return false; + } + + return _cache.SetTileEntity(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask, te); + } + + public bool ClearTileEntity (int x, int y, int z) + { + _cache = GetChunk(x, y, z); + if (_cache == null || !Check(x, y, z)) { + return false; + } + + return _cache.ClearTileEntity(x & _chunkXMask, y & _chunkYMask, z & _chunkZMask); + } + + #endregion + } + /*public interface IBlockManager : IBlockContainer { Block GetBlock (int x, int y, int z); @@ -13,7 +293,7 @@ namespace Substrate bool SetBlock (int x, int y, int z, Block block); }*/ - public class BlockManager : IBlockManager + /*public class BlockManager : IBlockManager { public const int MIN_X = -32000000; public const int MAX_X = 32000000; @@ -247,5 +527,5 @@ namespace Substrate (y >= MIN_Y) && (y < MAX_Y) && (z >= MIN_Z) && (z < MAX_Z); } - } + }*/ } diff --git a/Substrate/SubstrateCS/Source/BlockRef.cs b/Substrate/SubstrateCS/Source/BlockRef.cs index 747a313..3cae2b1 100644 --- a/Substrate/SubstrateCS/Source/BlockRef.cs +++ b/Substrate/SubstrateCS/Source/BlockRef.cs @@ -4,7 +4,114 @@ using System.Text; namespace Substrate { - public class BlockRef : IBlock + public class BlockRef : IPropertyBlock, ILitBlock + { + protected IAlphaBlockContainer _container; + + protected int _x; + protected int _y; + protected int _z; + + /*public int X + { + get { return _container.BlockGlobalX(_x); } + } + + public int Y + { + get { return _container.BlockGlobalY(_y); } + } + + public int Z + { + get { return _container.BlockGlobalZ(_z); } + } + + public int LocalX + { + get { return _container.BlockLocalX(_x); } + } + + public int LocalY + { + get { return _container.BlockLocalZ(_z); } + } + + public int LocalZ + { + get { return _z; } + }*/ + + + public BlockRef (IAlphaBlockContainer container, int x, int y, int z) + { + _container = container; + _x = x; + _y = y; + _z = z; + } + + + #region IBlock Members + + public BlockInfo Info + { + get { return BlockInfo.BlockTable[_container.GetBlockID(_x, _y, _z)]; } + } + + public int ID + { + get { return _container.GetBlockID(_x, _y, _z); } + set { _container.SetBlockID(_x, _y, _z, value); } + } + + public int Data + { + get { return _container.GetBlockData(_x, _y, _z); } + set { _container.SetBlockData(_x, _y, _z, value); } + } + + #endregion + + + #region ILitBlock Members + + public int BlockLight + { + get { return _container.GetBlockLight(_x, _y, _z); } + set { _container.SetBlockLight(_x, _y, _z, value); } + } + + public int SkyLight + { + get { return _container.GetBlockSkyLight(_x, _y, _z); } + set { _container.SetBlockSkyLight(_x, _y, _z, value); } + } + + #endregion + + + #region IPropertyBlock Members + + public TileEntity GetTileEntity () + { + return _container.GetTileEntity(_x, _y, _z); + } + + public bool SetTileEntity (TileEntity te) + { + return _container.SetTileEntity(_x, _y, _z, te); + } + + public bool ClearTileEntity () + { + return _container.ClearTileEntity(_x, _y, _z); + } + + #endregion + } + + /*public class BlockRef : IBlock { protected IBlockContainer _container; @@ -103,7 +210,7 @@ namespace Substrate { return _container.ClearTileEntity(_x, _y, _z); } - } + }*/ /*public class BlockRef : IBlock { diff --git a/Substrate/SubstrateCS/Source/Chunk.cs b/Substrate/SubstrateCS/Source/Chunk.cs index 115df41..7a5921d 100644 --- a/Substrate/SubstrateCS/Source/Chunk.cs +++ b/Substrate/SubstrateCS/Source/Chunk.cs @@ -83,8 +83,8 @@ namespace Substrate private void BuildNBTTree () { - int elements2 = BlockManager.CHUNK_XLEN * BlockManager.CHUNK_ZLEN; - int elements3 = elements2 * BlockManager.CHUNK_YLEN; + int elements2 = XDim * ZDim; + int elements3 = elements2 *YDim; _blocks = new NBT_ByteArray(new byte[elements3]); NBT_ByteArray data = new NBT_ByteArray(new byte[elements3 >> 1]); @@ -117,7 +117,7 @@ namespace Substrate public int BlockGlobalX (int x) { - return _cx * BlockManager.CHUNK_XLEN + x; + return _cx * XDim + x; } public int BlockGlobalY (int y) @@ -127,7 +127,7 @@ namespace Substrate public int BlockGlobalZ (int z) { - return _cz * BlockManager.CHUNK_ZLEN + z; + return _cz * XDim + z; } public int BlockLocalX (int x) @@ -167,11 +167,6 @@ namespace Substrate return new BlockRef(this, lx, ly, lz); } - public BlockInfo GetBlockInfo (int lx, int ly, int lz) - { - return BlockInfo.BlockTable[GetBlockID(lx, ly, lz)]; - } - public void SetBlock (int lx, int ly, int lz, Block block) { int index = lx << 11 | lz << 7 | ly; @@ -179,12 +174,149 @@ namespace Substrate SetBlockID(lx, ly, lz, block.ID); SetBlockData(lx, ly, lz, block.Data); - _blockLight[index] = block.BlockLight; - _skyLight[index] = block.SkyLight; - SetTileEntity(lx, ly, lz, block.GetTileEntity().Copy()); } + public int CountBlockID (int id) + { + int c = 0; + for (int i = 0; i < _blocks.Length; i++) { + if (_blocks[i] == id) { + c++; + } + } + + return c; + } + + public int CountBlockData (int id, int data) + { + int c = 0; + for (int i = 0; i < _blocks.Length; i++) { + if (_blocks[i] == id && _data[i] == data) { + c++; + } + } + + return c; + } + + public int CountEntities () + { + return _entities.Count; + } + + public int GetHeight (int lx, int lz) + { + return _heightMap[lz << 4 | lx]; + } + + private void CreateTileEntity (int lx, int ly, int lz) + { + BlockInfoEx info = GetBlockInfo(lx, ly, lz) as BlockInfoEx; + if (info == null) { + return; + } + + TileEntity te = TileEntityFactory.Create(info.TileEntityName); + if (te == null) { + return; + } + + te.X = BlockGlobalX(lx); + te.Y = BlockGlobalY(ly); + te.Z = BlockGlobalZ(lz); + + _tileEntities.Add(te.BuildTree()); + } + + public virtual void SetLocation (int x, int z) + { + int diffx = x - _cx; + int diffz = z - _cz; + + _cx = x; + _cz = z; + + BuildTileEntityCache(); + } + + private void BuildTileEntityCache () + { + _tileEntityTable = new Dictionary(); + + foreach (NBT_Compound te in _tileEntities) { + int tex = te["x"].ToNBTInt(); + int tey = te["y"].ToNBTInt(); + int tez = te["z"].ToNBTInt(); + + BlockKey key = new BlockKey(tex, tey, tez); + _tileEntityTable[key] = te; + } + } + + + #region IBoundedBlockContainer Members + + public int XDim + { + get { return 16; } + } + + public int YDim + { + get { return 128; } + } + + public int ZDim + { + get { return 16; } + } + + #endregion + + + #region IBlockContainer Members + + IBlock IBlockContainer.GetBlock (int lx, int ly, int lz) + { + return GetBlock(lx, ly, lz); + } + + IBlock IBlockContainer.GetBlockRef (int lx, int ly, int lz) + { + return GetBlockRef(lx, ly, lz); + } + + public void SetBlock (int lx, int ly, int lz, IBlock block) + { + int index = lx << 11 | lz << 7 | ly; + int oldid = _blocks.Data[index]; + + SetBlockID(lx, ly, lz, block.ID); + SetBlockData(lx, ly, lz, block.Data); + + // Update tile entities + + BlockInfoEx info1 = BlockInfo.BlockTable[oldid] as BlockInfoEx; + BlockInfoEx info2 = BlockInfo.BlockTable[block.ID] as BlockInfoEx; + + if (info1 != info2) { + if (info1 != null) { + ClearTileEntity(lx, ly, lz); + } + + if (info2 != null) { + CreateTileEntity(lx, ly, lz); + } + } + } + + public BlockInfo GetBlockInfo (int lx, int ly, int lz) + { + return BlockInfo.BlockTable[GetBlockID(lx, ly, lz)]; + } + public int GetBlockID (int lx, int ly, int lz) { return _blocks.Data[lx << 11 | lz << 7 | ly]; @@ -195,16 +327,6 @@ namespace Substrate return _data[lx << 11 | lz << 7 | ly]; } - public int GetBlockLight (int lx, int ly, int lz) - { - return _blockLight[lx << 11 | lz << 7 | ly]; - } - - public int GetBlockSkyLight (int lx, int ly, int lz) - { - return _skyLight[lx << 11 | lz << 7 | ly]; - } - public bool SetBlockID (int lx, int ly, int lz, int id) { int index = lx << 11 | lz << 7 | ly; @@ -262,16 +384,65 @@ namespace Substrate return false; } - if (BlockManager.EnforceDataLimits && BlockInfo.BlockTable[_blocks[index]] != null) { + /*if (BlockManager.EnforceDataLimits && BlockInfo.BlockTable[_blocks[index]] != null) { if (!BlockInfo.BlockTable[_blocks[index]].TestData(data)) { return false; } - } + }*/ _data[index] = data; return true; } + #endregion + + + #region ILitBlockContainer Members + + ILitBlock ILitBlockContainer.GetBlock (int lx, int ly, int lz) + { + throw new NotImplementedException(); + } + + ILitBlock ILitBlockContainer.GetBlockRef (int lx, int ly, int lz) + { + return GetBlockRef(lx, ly, lz); + } + + public void SetBlock (int lx, int ly, int lz, ILitBlock block) + { + int index = lx << 11 | lz << 7 | ly; + int oldid = _blocks.Data[index]; + + SetBlockID(lx, ly, lz, block.ID); + SetBlockData(lx, ly, lz, block.Data); + + // Update tile entities + + BlockInfoEx info1 = BlockInfo.BlockTable[oldid] as BlockInfoEx; + BlockInfoEx info2 = BlockInfo.BlockTable[block.ID] as BlockInfoEx; + + if (info1 != info2) { + if (info1 != null) { + ClearTileEntity(lx, ly, lz); + } + + if (info2 != null) { + CreateTileEntity(lx, ly, lz); + } + } + } + + public int GetBlockLight (int lx, int ly, int lz) + { + return _blockLight[lx << 11 | lz << 7 | ly]; + } + + public int GetBlockSkyLight (int lx, int ly, int lz) + { + return _skyLight[lx << 11 | lz << 7 | ly]; + } + public bool SetBlockLight (int lx, int ly, int lz, int light) { int index = lx << 11 | lz << 7 | ly; @@ -294,57 +465,29 @@ namespace Substrate return true; } - public int CountBlockID (int id) - { - int c = 0; - for (int i = 0; i < _blocks.Length; i++) { - if (_blocks[i] == id) { - c++; - } - } + #endregion - return c; + + #region IPropertyBlockContainer Members + + IPropertyBlock IPropertyBlockContainer.GetBlock (int lx, int ly, int lz) + { + return GetBlock(lx, ly, lz); } - public int CountBlockData (int id, int data) + IPropertyBlock IPropertyBlockContainer.GetBlockRef (int lx, int ly, int lz) { - int c = 0; - for (int i = 0; i < _blocks.Length; i++) { - if (_blocks[i] == id && _data[i] == data) { - c++; - } - } - - return c; + return GetBlockRef(lx, ly, lz); } - public int CountEntities () + public void SetBlock (int lx, int ly, int lz, IPropertyBlock block) { - return _entities.Count; - } + int index = lx << 11 | lz << 7 | ly; - public int GetHeight (int lx, int lz) - { - return _heightMap[lz << 4 | lx]; - } + SetBlockID(lx, ly, lz, block.ID); + SetBlockData(lx, ly, lz, block.Data); - private void CreateTileEntity (int lx, int ly, int lz) - { - BlockInfoEx info = GetBlockInfo(lx, ly, lz) as BlockInfoEx; - if (info == null) { - return; - } - - TileEntity te = TileEntityFactory.Create(info.TileEntityName); - if (te == null) { - return; - } - - te.X = BlockGlobalX(lx); - te.Y = BlockGlobalY(ly); - te.Z = BlockGlobalZ(lz); - - _tileEntities.Add(te.BuildTree()); + SetTileEntity(lx, ly, lz, block.GetTileEntity().Copy()); } public TileEntity GetTileEntity (int lx, int ly, int lz) @@ -392,7 +535,7 @@ namespace Substrate NBT_Compound tree = te.BuildTree() as NBT_Compound; _tileEntities.Add(tree); - _tileEntityTable[key] = tree; + _tileEntityTable[key] = tree; return true; } @@ -416,30 +559,8 @@ namespace Substrate return true; } - public virtual void SetLocation (int x, int z) - { - int diffx = x - _cx; - int diffz = z - _cz; + #endregion - _cx = x; - _cz = z; - - BuildTileEntityCache(); - } - - private void BuildTileEntityCache () - { - _tileEntityTable = new Dictionary(); - - foreach (NBT_Compound te in _tileEntities) { - int tex = te["x"].ToNBTInt(); - int tey = te["y"].ToNBTInt(); - int tez = te["z"].ToNBTInt(); - - BlockKey key = new BlockKey(tex, tey, tez); - _tileEntityTable[key] = te; - } - } #region ICopyable Members @@ -559,10 +680,10 @@ namespace Substrate public bool AddEntity (Entity ent) { - double xlow = _cx * BlockManager.CHUNK_XLEN; - double xhigh = xlow + BlockManager.CHUNK_XLEN; - double zlow = _cz * BlockManager.CHUNK_ZLEN; - double zhigh = zlow + BlockManager.CHUNK_ZLEN; + double xlow = _cx * XDim; + double xhigh = xlow + XDim; + double zlow = _cz * ZDim; + double zhigh = zlow + ZDim; Entity.Vector3 pos = ent.Position; if (!(pos.X >= xlow && pos.X < xhigh && pos.Z >= zlow && pos.Z < zhigh)) { diff --git a/Substrate/SubstrateCS/Source/ChunkInterface.cs b/Substrate/SubstrateCS/Source/ChunkInterface.cs index 859144a..9fdc51e 100644 --- a/Substrate/SubstrateCS/Source/ChunkInterface.cs +++ b/Substrate/SubstrateCS/Source/ChunkInterface.cs @@ -6,7 +6,7 @@ using System.IO; namespace Substrate { - public interface IChunk : IBlockContainer, IEntityContainer + public interface IChunk : IBoundedBlockContainer, IAlphaBlockContainer, IEntityContainer { int X { get; } int Z { get; } diff --git a/Substrate/SubstrateCS/Source/ChunkRef.cs b/Substrate/SubstrateCS/Source/ChunkRef.cs index 85a3de6..a041a8d 100644 --- a/Substrate/SubstrateCS/Source/ChunkRef.cs +++ b/Substrate/SubstrateCS/Source/ChunkRef.cs @@ -28,6 +28,8 @@ namespace Substrate get { return _container.ChunkGlobalZ(_cz); } } + + public int LocalX { get { return _container.ChunkLocalX(_cx); } @@ -52,7 +54,7 @@ namespace Substrate public int BlockGlobalX (int x) { - return _container.ChunkGlobalX(_cx) * BlockManager.CHUNK_XLEN + x; + return _container.ChunkGlobalX(_cx) * XDim + x; } public int BlockGlobalY (int y) @@ -62,7 +64,7 @@ namespace Substrate public int BlockGlobalZ (int z) { - return _container.ChunkGlobalZ(_cz) * BlockManager.CHUNK_ZLEN + z; + return _container.ChunkGlobalZ(_cz) * ZDim + z; } public int BlockLocalX (int x) @@ -185,62 +187,6 @@ namespace Substrate GetChunk().SetBlock(lx, ly, lz, block); } - public int GetBlockID (int lx, int ly, int lz) - { - return GetChunk().GetBlockID(lx, ly, lz); - } - - public int GetBlockData (int lx, int ly, int lz) - { - return GetChunk().GetBlockData(lx, ly, lz); - } - - public int GetBlockLight (int lx, int ly, int lz) - { - return GetChunk().GetBlockSkyLight(lx, ly, lz); - } - - public int GetBlockSkyLight (int lx, int ly, int lz) - { - return GetChunk().GetBlockSkyLight(lx, ly, lz); - } - - public bool SetBlockID (int lx, int ly, int lz, int id) - { - if (GetChunk().SetBlockID(lx, ly, lz, id)) { - MarkDirty(); - return true; - } - return false; - } - - public bool SetBlockData (int lx, int ly, int lz, int data) - { - if (GetChunk().SetBlockData(lx, ly, lz, data)) { - MarkDirty(); - return true; - } - return false; - } - - public bool SetBlockLight (int lx, int ly, int lz, int light) - { - if (GetChunk().SetBlockLight(lx, ly, lz, light)) { - MarkDirty(); - return true; - } - return false; - } - - public bool SetBlockSkyLight (int lx, int ly, int lz, int light) - { - if (GetChunk().SetBlockSkyLight(lx, ly, lz, light)) { - MarkDirty(); - return true; - } - return false; - } - public int CountBlockID (int id) { return GetChunk().CountBlockID(id); @@ -261,14 +207,150 @@ namespace Substrate return GetChunk().GetHeight(lx, lz); } + #endregion + + + #region IBoundedBlockContainer Members + + public int XDim + { + get { return _chunk.XDim; } + } + + public int YDim + { + get { return _chunk.YDim; } + } + + public int ZDim + { + get { return _chunk.ZDim; } + } + + #endregion + + + #region IBlockContainer Members + + IBlock IBlockContainer.GetBlock (int lx, int ly, int lz) + { + return new Block(this, lx, ly, lz); + } + + IBlock IBlockContainer.GetBlockRef (int lx, int ly, int lz) + { + return new BlockRef(this, lx, ly, lz); + } + + public void SetBlock (int lx, int ly, int lz, IBlock block) + { + GetChunk().SetBlock(lx, ly, lz, block); + } + + public int GetBlockID (int lx, int ly, int lz) + { + return GetChunk().GetBlockID(lx, ly, lz); + } + + public int GetBlockData (int lx, int ly, int lz) + { + return GetChunk().GetBlockData(lx, ly, lz); + } + + public bool SetBlockID (int lx, int ly, int lz, int id) + { + if (GetChunk().SetBlockID(lx, ly, lz, id)) { + MarkDirty(); + return true; + } + return false; + } + + public bool SetBlockData (int lx, int ly, int lz, int data) + { + if (GetChunk().SetBlockData(lx, ly, lz, data)) { + MarkDirty(); + return true; + } + return false; + } + + #endregion + + + #region ILitBlockContainer Members + + ILitBlock ILitBlockContainer.GetBlock (int lx, int ly, int lz) + { + throw new NotImplementedException(); + } + + ILitBlock ILitBlockContainer.GetBlockRef (int lx, int ly, int lz) + { + return new BlockRef(this, lx, ly, lz); + } + + public void SetBlock (int lx, int ly, int lz, ILitBlock block) + { + GetChunk().SetBlock(lx, ly, lz, block); + } + + public int GetBlockLight (int lx, int ly, int lz) + { + return GetChunk().GetBlockSkyLight(lx, ly, lz); + } + + public int GetBlockSkyLight (int lx, int ly, int lz) + { + return GetChunk().GetBlockSkyLight(lx, ly, lz); + } + + public bool SetBlockLight (int lx, int ly, int lz, int light) + { + if (GetChunk().SetBlockLight(lx, ly, lz, light)) { + MarkDirty(); + return true; + } + return false; + } + + public bool SetBlockSkyLight (int lx, int ly, int lz, int light) + { + if (GetChunk().SetBlockSkyLight(lx, ly, lz, light)) { + MarkDirty(); + return true; + } + return false; + } + + #endregion + + + #region IPropertyBlockContainer Members + + IPropertyBlock IPropertyBlockContainer.GetBlock (int lx, int ly, int lz) + { + return new Block(this, lx, ly, lz); + } + + IPropertyBlock IPropertyBlockContainer.GetBlockRef (int lx, int ly, int lz) + { + return new BlockRef(this, lx, ly, lz); + } + + public void SetBlock (int lx, int ly, int lz, IPropertyBlock block) + { + GetChunk().SetBlock(lx, ly, lz, block); + } + public TileEntity GetTileEntity (int lx, int ly, int lz) { - return GetChunk().GetTileEntity(lx, ly, lz); + return GetChunk().GetTileEntity(lx, ly, lz); } public bool SetTileEntity (int lx, int ly, int lz, TileEntity te) { - if (GetChunk().SetTileEntity(lx, ly, lz, te)) { + if (GetChunk().SetTileEntity(lx, ly, lz, te)) { MarkDirty(); return true; } @@ -277,7 +359,7 @@ namespace Substrate public bool ClearTileEntity (int lx, int ly, int lz) { - if (GetChunk().ClearTileEntity(lx, ly, lz)) { + if (GetChunk().ClearTileEntity(lx, ly, lz)) { MarkDirty(); return true; } diff --git a/Substrate/SubstrateCS/Substrate.csproj b/Substrate/SubstrateCS/Substrate.csproj index f3efc1b..f9358d5 100644 --- a/Substrate/SubstrateCS/Substrate.csproj +++ b/Substrate/SubstrateCS/Substrate.csproj @@ -63,6 +63,9 @@ + + + @@ -78,18 +81,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Substrate/SubstrateCS/Substrate.sln b/Substrate/SubstrateCS/Substrate.sln index 62d340a..5c12077 100644 --- a/Substrate/SubstrateCS/Substrate.sln +++ b/Substrate/SubstrateCS/Substrate.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual C# Express 2008 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NBToolkit", "NBToolkit.csproj", "{AFE30E14-3F2F-4461-9F7D-147AB4DCA4C3}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Substrate", "Substrate.csproj", "{AFE30E14-3F2F-4461-9F7D-147AB4DCA4C3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution