NBTExplorer/Substrate/SubstrateCS/Source/ChunkRef.cs
2011-04-06 04:43:54 +00:00

328 lines
8.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace NBToolkit.Map
{
using NBT;
public class ChunkRef : IChunk
{
private IChunkContainer _container;
private IChunkCache _cache;
private Chunk _chunk;
private int _cx;
private int _cz;
private bool _dirty;
public int X
{
get { return _container.ChunkGlobalX(_cx); }
}
public int Z
{
get { return _container.ChunkGlobalZ(_cz); }
}
public int LocalX
{
get { return _container.ChunkLocalX(_cx); }
}
public int LocalZ
{
get { return _container.ChunkLocalZ(_cz); }
}
public ChunkRef (IChunkContainer container, IChunkCache cache, int cx, int cz)
{
_container = container;
_cache = cache;
_cx = cx;
_cz = cz;
if (!_container.ChunkExists(cx, cz)) {
throw new MissingChunkException();
}
}
public int BlockGlobalX (int x)
{
return _container.ChunkGlobalX(_cx) * BlockManager.CHUNK_XLEN + x;
}
public int BlockGlobalY (int y)
{
return y;
}
public int BlockGlobalZ (int z)
{
return _container.ChunkGlobalZ(_cz) * BlockManager.CHUNK_ZLEN + z;
}
public int BlockLocalX (int x)
{
return x;
}
public int BlockLocalY (int y)
{
return y;
}
public int BlockLocalZ (int z)
{
return z;
}
private Chunk GetChunk ()
{
if (_chunk == null) {
_chunk = _container.GetChunk(_cx, _cz);
}
return _chunk;
}
private bool MarkDirty ()
{
if (_dirty) {
return false;
}
_dirty = true;
_cache.MarkChunkDirty(this);
return true;
}
public ChunkRef GetNorthNeighbor ()
{
return _container.GetChunkRef(_cx - 1, _cz);
}
public ChunkRef GetSouthNeighbor ()
{
return _container.GetChunkRef(_cx + 1, _cz);
}
public ChunkRef GetEastNeighbor ()
{
return _container.GetChunkRef(_cx, _cz - 1);
}
public ChunkRef GetWestNeighbor ()
{
return _container.GetChunkRef(_cx, _cz + 1);
}
public Chunk GetChunkCopy ()
{
return GetChunk().Copy();
}
public Chunk GetChunkRef ()
{
Chunk chunk = GetChunk();
_chunk = null;
return chunk;
}
public void SetChunkRef (Chunk chunk)
{
_chunk = chunk;
_chunk.SetLocation(_cx, _cz);
MarkDirty();
}
#region IChunk Members
public bool IsTerrainPopulated
{
get { return GetChunk().IsTerrainPopulated; }
set
{
if (GetChunk().IsTerrainPopulated != value) {
GetChunk().IsTerrainPopulated = value;
MarkDirty();
}
}
}
public bool Save (Stream outStream)
{
if (_dirty) {
if (GetChunk().Save(outStream)) {
_dirty = false;
return true;
}
return false;
}
return true;
}
public Block GetBlock (int lx, int ly, int lz)
{
return new Block(this, lx, ly, lz);
}
public BlockRef GetBlockRef (int lx, int ly, int lz)
{
return new BlockRef(this, lx, ly, lz);
}
public BlockInfo GetBlockInfo (int lx, int ly, int lz)
{
return GetChunk().GetBlockInfo(lx, ly, lz);
}
public void SetBlock (int lx, int ly, int lz, Block 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 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);
}
public int CountBlockData (int id, int data)
{
return GetChunk().CountBlockData(id, data);
}
public int GetHeight (int lx, int lz)
{
return GetChunk().GetHeight(lx, lz);
}
public TileEntity GetTileEntity (int lx, int ly, int 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)) {
MarkDirty();
return true;
}
return false;
}
public bool ClearTileEntity (int lx, int ly, int lz)
{
if (GetChunk().ClearTileEntity(lx, ly, lz)) {
MarkDirty();
return true;
}
return false;
}
#endregion
}
/*public bool VerifyTileEntities ()
{
bool pass = true;
NBT_List telist = GetTree().Root["Level"].ToNBTCompound()["TileEntities"].ToNBTList();
foreach (NBT_Value val in telist) {
NBT_Compound tree = val as NBT_Compound;
if (tree == null) {
pass = false;
continue;
}
if (new NBTVerifier(tree, TileEntity.BaseSchema).Verify() == false) {
pass = false;
continue;
}
int x = tree["x"].ToNBTInt() & BlockManager.CHUNK_XMASK;
int y = tree["y"].ToNBTInt() & BlockManager.CHUNK_YMASK;
int z = tree["z"].ToNBTInt() & BlockManager.CHUNK_ZMASK;
int id = GetBlockID(x, y, z);
NBTCompoundNode schema = BlockInfo.SchemaTable[id];
if (schema == null) {
pass = false;
continue;
}
pass = new NBTVerifier(tree, schema).Verify() && pass;
}
return pass;
}
private static bool LocalBounds (int lx, int ly, int lz)
{
return lx >= 0 && lx < BlockManager.CHUNK_XLEN &&
ly >= 0 && ly < BlockManager.CHUNK_YLEN &&
lz >= 0 && lz < BlockManager.CHUNK_ZLEN;
}*/
public class MalformedNBTTreeException : Exception { }
}