Region functions can now delegate operations on out-of-range coordinates to other regions. Used by relighting code.

This commit is contained in:
Justin Aquadro 2011-04-11 08:40:48 +00:00
parent de21e4d94c
commit b3ee8e76d7

View file

@ -10,6 +10,13 @@ namespace Substrate
public class Region : IDisposable, IChunkContainer, IChunkCache public class Region : IDisposable, IChunkContainer, IChunkCache
{ {
private const int XDIM = 32;
private const int ZDIM = 32;
private const int XMASK = XDIM - 1;
private const int ZMASK = ZDIM - 1;
private const int XLOG = 5;
private const int ZLOG = 5;
protected int _rx; protected int _rx;
protected int _rz; protected int _rz;
protected bool _disposed = false; protected bool _disposed = false;
@ -33,6 +40,16 @@ namespace Substrate
get { return _rz; } get { return _rz; }
} }
public int XDim
{
get { return XDIM; }
}
public int ZDim
{
get { return ZDIM; }
}
public Region (RegionManager rm, int rx, int rz) public Region (RegionManager rm, int rx, int rz)
{ {
_regionMan = rm; _regionMan = rm;
@ -137,6 +154,11 @@ namespace Substrate
public NBT_Tree GetChunkTree (int lcx, int lcz) public NBT_Tree GetChunkTree (int lcx, int lcz)
{ {
if (!LocalBoundsCheck(lcx, lcz)) {
Region alt = GetForeignRegion(lcx, lcz);
return (alt == null) ? null : alt.GetChunkTree(ForeignX(lcx), ForeignZ(lcz));
}
RegionFile rf = GetRegionFile(); RegionFile rf = GetRegionFile();
Stream nbtstr = rf.GetChunkDataInputStream(lcx, lcz); Stream nbtstr = rf.GetChunkDataInputStream(lcx, lcz);
if (nbtstr == null) { if (nbtstr == null) {
@ -151,6 +173,11 @@ namespace Substrate
public bool SaveChunkTree (int lcx, int lcz, NBT_Tree tree) public bool SaveChunkTree (int lcx, int lcz, NBT_Tree tree)
{ {
if (!LocalBoundsCheck(lcx, lcz)) {
Region alt = GetForeignRegion(lcx, lcz);
return (alt == null) ? false : alt.SaveChunkTree(ForeignX(lcx), ForeignZ(lcz), tree);
}
RegionFile rf = GetRegionFile(); RegionFile rf = GetRegionFile();
Stream zipstr = rf.GetChunkDataOutputStream(lcx, lcz); Stream zipstr = rf.GetChunkDataOutputStream(lcx, lcz);
if (zipstr == null) { if (zipstr == null) {
@ -165,6 +192,11 @@ namespace Substrate
public Stream GetChunkOutStream (int lcx, int lcz) public Stream GetChunkOutStream (int lcx, int lcz)
{ {
if (!LocalBoundsCheck(lcx, lcz)) {
Region alt = GetForeignRegion(lcx, lcz);
return (alt == null) ? null : alt.GetChunkOutStream(ForeignX(lcx), ForeignZ(lcz));
}
RegionFile rf = GetRegionFile(); RegionFile rf = GetRegionFile();
return rf.GetChunkDataOutputStream(lcx, lcz); return rf.GetChunkDataOutputStream(lcx, lcz);
} }
@ -187,9 +219,9 @@ namespace Substrate
public ChunkRef GetChunkRef (int lcx, int lcz, IChunkCache cache) public ChunkRef GetChunkRef (int lcx, int lcz, IChunkCache cache)
{ {
if (lcx < 0 || lcx >= 32 || lcz < 0 || lcz >= 32) { if (!LocalBoundsCheck(lcx, lcz)) {
Region alt = _regionMan.GetRegion(_rx + (lcx >> 5), _rz + (lcz >> 5)); Region alt = GetForeignRegion(lcx, lcz);
return alt.GetChunkRef((lcx + 3200) % 32, (lcz + 3200) % 32, cache); return (alt == null) ? null : alt.GetChunkRef(ForeignX(lcx), ForeignZ(lcz), cache);
} }
ChunkKey k = new ChunkKey(lcx, lcz); ChunkKey k = new ChunkKey(lcx, lcz);
@ -225,6 +257,11 @@ namespace Substrate
public ChunkRef CreateChunk (int lcx, int lcz, IChunkCache cache) public ChunkRef CreateChunk (int lcx, int lcz, IChunkCache cache)
{ {
if (!LocalBoundsCheck(lcx, lcz)) {
Region alt = GetForeignRegion(lcx, lcz);
return (alt == null) ? null : alt.CreateChunk(ForeignX(lcx), ForeignZ(lcz), cache);
}
DeleteChunk(lcx, lcz); DeleteChunk(lcx, lcz);
Chunk c = new Chunk(ChunkGlobalX(lcx), ChunkGlobalZ(lcz)); Chunk c = new Chunk(ChunkGlobalX(lcx), ChunkGlobalZ(lcz));
@ -262,6 +299,11 @@ namespace Substrate
public Chunk GetChunk (int lcx, int lcz) public Chunk GetChunk (int lcx, int lcz)
{ {
if (!LocalBoundsCheck(lcx, lcz)) {
Region alt = GetForeignRegion(lcx, lcz);
return (alt == null) ? null : alt.GetChunk(ForeignX(lcx), ForeignZ(lcz));
}
if (!ChunkExists(lcx, lcz)) { if (!ChunkExists(lcx, lcz)) {
return null; return null;
} }
@ -276,8 +318,9 @@ namespace Substrate
public bool ChunkExists (int lcx, int lcz) public bool ChunkExists (int lcx, int lcz)
{ {
if (lcx < 0 || lcx >= 32 || lcz < 0 || lcz >= 32) { if (!LocalBoundsCheck(lcx, lcz)) {
return false; Region alt = GetForeignRegion(lcx, lcz);
return (alt == null) ? false : alt.ChunkExists(ForeignX(lcx), ForeignZ(lcz));
} }
RegionFile rf = GetRegionFile(); RegionFile rf = GetRegionFile();
@ -286,6 +329,11 @@ namespace Substrate
public bool DeleteChunk (int lcx, int lcz) public bool DeleteChunk (int lcx, int lcz)
{ {
if (!LocalBoundsCheck(lcx, lcz)) {
Region alt = GetForeignRegion(lcx, lcz);
return (alt == null) ? false : alt.DeleteChunk(ForeignX(lcx), ForeignZ(lcz));
}
RegionFile rf = GetRegionFile(); RegionFile rf = GetRegionFile();
if (!rf.HasChunk(lcx, lcz)) { if (!rf.HasChunk(lcx, lcz)) {
return false; return false;
@ -361,5 +409,25 @@ namespace Substrate
} }
#endregion #endregion
private bool LocalBoundsCheck (int lcx, int lcz)
{
return (lcx >= 0 && lcx < XDIM && lcz >= 0 && lcz < ZDIM);
}
private Region GetForeignRegion (int lcx, int lcz)
{
return _regionMan.GetRegion(_rx + (lcx >> XLOG), _rz + (lcz >> ZLOG));
}
private int ForeignX (int lcx)
{
return (lcx + XDIM * 10000) & XMASK;
}
private int ForeignZ (int lcz)
{
return (lcz + ZDIM * 10000) & ZMASK;
}
} }
} }