forked from mirrors/NBTExplorer
Major restructuring in block/chunk/region handling. Abstracted block and chunk interfaces.
This commit is contained in:
parent
d094a3cb47
commit
951e912a57
18 changed files with 1084 additions and 50 deletions
86
NBToolkit/NBToolkit/BlockManager.cs
Normal file
86
NBToolkit/NBToolkit/BlockManager.cs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NBToolkit
|
||||||
|
{
|
||||||
|
public class BlockManager
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
public const int CHUNK_XLEN = 16;
|
||||||
|
public const int CHUNK_YLEN = 128;
|
||||||
|
public const int CHUNK_ZLEN = 16;
|
||||||
|
|
||||||
|
public const int CHUNK_XLOG = 4;
|
||||||
|
public const int CHUNK_YLOG = 7;
|
||||||
|
public const int CHUNK_ZLOG = 4;
|
||||||
|
|
||||||
|
public const int CHUNK_XMASK = 0xF;
|
||||||
|
public const int CHUNK_YMASK = 0x7F;
|
||||||
|
public const int CHUNK_ZMASK = 0xF;
|
||||||
|
|
||||||
|
protected ChunkManager _chunkMan;
|
||||||
|
|
||||||
|
public BlockManager (ChunkManager cm)
|
||||||
|
{
|
||||||
|
_chunkMan = cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetBlockID (int x, int y, int z)
|
||||||
|
{
|
||||||
|
if (x < MIN_X || x >= MAX_X)
|
||||||
|
return 0;
|
||||||
|
if (y < MIN_Y || y >= MAX_Y)
|
||||||
|
return 0;
|
||||||
|
if (z < MIN_Z || z >= MAX_Z)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Chunk c = GetChunk(x, y, z);
|
||||||
|
if (c == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.GetBlockID(x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetBlockData (int x, int y, int z) { return 0; }
|
||||||
|
|
||||||
|
int GetBlockLight (int x, int y, int z) { return 0; }
|
||||||
|
|
||||||
|
int GetBlockSkylight (int x, int y, int z) { return 0; }
|
||||||
|
|
||||||
|
void SetBlock (int x, int y, int z, int id, int data) { }
|
||||||
|
|
||||||
|
public bool SetBlockID (int x, int y, int z, int id)
|
||||||
|
{
|
||||||
|
if (x < MIN_X || x >= MAX_X)
|
||||||
|
return false;
|
||||||
|
if (y < MIN_Y || y >= MAX_Y)
|
||||||
|
return false;
|
||||||
|
if (z < MIN_Z || z >= MAX_Z)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Chunk c = GetChunk(x, y, z);
|
||||||
|
if (c == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.SetBlockID(x & CHUNK_XMASK, y, z & CHUNK_ZMASK, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetBlockData (int x, int y, int z, int data) { }
|
||||||
|
|
||||||
|
public Chunk GetChunk (int x, int y, int z)
|
||||||
|
{
|
||||||
|
x >>= CHUNK_XLOG;
|
||||||
|
z >>= CHUNK_ZLOG;
|
||||||
|
return _chunkMan.GetChunk(x, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
105
NBToolkit/NBToolkit/Chunk.cs
Normal file
105
NBToolkit/NBToolkit/Chunk.cs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using NBT;
|
||||||
|
|
||||||
|
namespace NBToolkit
|
||||||
|
{
|
||||||
|
public class Chunk
|
||||||
|
{
|
||||||
|
protected int _cx;
|
||||||
|
protected int _cz;
|
||||||
|
|
||||||
|
protected NBT_Tree _nbt = null;
|
||||||
|
protected NBT_ByteArray _blocks = null;
|
||||||
|
|
||||||
|
protected bool _dirty = false;
|
||||||
|
|
||||||
|
protected ChunkManager _chunkMan;
|
||||||
|
|
||||||
|
public Chunk (ChunkManager cm, int cx, int cz)
|
||||||
|
{
|
||||||
|
_chunkMan = cm;
|
||||||
|
_cx = cx;
|
||||||
|
_cz = cz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int X
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _cx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Z
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _cz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Save ()
|
||||||
|
{
|
||||||
|
if (_dirty) {
|
||||||
|
if (SaveTree()) {
|
||||||
|
_dirty = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NBT_Tree GetTree ()
|
||||||
|
{
|
||||||
|
if (_nbt != null) {
|
||||||
|
return _nbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
Region r = _chunkMan.GetRegion(_cx, _cz);
|
||||||
|
_nbt = r.GetChunkTree(_cx & ChunkManager.REGION_XMASK, _cz & ChunkManager.REGION_ZMASK);
|
||||||
|
|
||||||
|
return _nbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool SaveTree ()
|
||||||
|
{
|
||||||
|
if (_nbt != null) {
|
||||||
|
_blocks = null;
|
||||||
|
|
||||||
|
Region r = _chunkMan.GetRegion(_cx, _cz);
|
||||||
|
return r.SaveChunkTree(_cx & ChunkManager.REGION_XMASK, _cz & ChunkManager.REGION_ZMASK, _nbt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetBlockID (int x, int y, int z)
|
||||||
|
{
|
||||||
|
if (_blocks == null) {
|
||||||
|
_blocks = GetTree().getRoot().findTagByName("Level").findTagByName("Blocks").value.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _blocks.data[x << 11 | z << 7 | y];
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetBlockID (int x, int y, int z, int id)
|
||||||
|
{
|
||||||
|
if (_blocks == null) {
|
||||||
|
_blocks = GetTree().getRoot().findTagByName("Level").findTagByName("Blocks").value.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = x << 11 | z << 7 | y;
|
||||||
|
if (_blocks.data[index] == id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_blocks.data[index] = (byte)id;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
145
NBToolkit/NBToolkit/ChunkEnumerator.cs
Normal file
145
NBToolkit/NBToolkit/ChunkEnumerator.cs
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace NBToolkit
|
||||||
|
{
|
||||||
|
public class ChunkList : IEnumerable<Chunk>
|
||||||
|
{
|
||||||
|
//private List<Region> _regions;
|
||||||
|
|
||||||
|
private ChunkManager _cm = null;
|
||||||
|
private Region _region = null;
|
||||||
|
|
||||||
|
// Constructor to enumerate a single region
|
||||||
|
public ChunkList (ChunkManager cm, Region region)
|
||||||
|
{
|
||||||
|
_cm = cm;
|
||||||
|
_region = region;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor to enumerate all regions
|
||||||
|
public ChunkList (ChunkManager cm)
|
||||||
|
{
|
||||||
|
_cm = cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator ()
|
||||||
|
{
|
||||||
|
return (IEnumerator)GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator<Chunk> IEnumerable<Chunk>.GetEnumerator ()
|
||||||
|
{
|
||||||
|
return (IEnumerator<Chunk>)GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChunkEnumerator GetEnumerator ()
|
||||||
|
{
|
||||||
|
return new ChunkEnumerator(_cm, _region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ChunkEnumerator : IEnumerator<Chunk>
|
||||||
|
{
|
||||||
|
protected Region _region;
|
||||||
|
protected ChunkManager _cm;
|
||||||
|
|
||||||
|
protected RegionEnumerator _enum = null;
|
||||||
|
protected int _x = 0;
|
||||||
|
protected int _z = -1;
|
||||||
|
|
||||||
|
public ChunkEnumerator (ChunkManager cm, Region region)
|
||||||
|
{
|
||||||
|
_cm = cm;
|
||||||
|
_region = region;
|
||||||
|
|
||||||
|
if (_region == null) {
|
||||||
|
_enum = new RegionEnumerator(_cm.GetRegionManager());
|
||||||
|
_enum.MoveNext();
|
||||||
|
_region = _enum.Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext ()
|
||||||
|
{
|
||||||
|
if (_enum == null) {
|
||||||
|
return MoveNextInRegion();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (true) {
|
||||||
|
if (_x >= ChunkManager.REGION_XLEN) {
|
||||||
|
if (!_enum.MoveNext()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_x = 0;
|
||||||
|
_z = -1;
|
||||||
|
}
|
||||||
|
if (MoveNextInRegion()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool MoveNextInRegion ()
|
||||||
|
{
|
||||||
|
for (; _x < ChunkManager.REGION_XLEN; _x++) {
|
||||||
|
for (_z++; _z < ChunkManager.REGION_ZLEN; _z++) {
|
||||||
|
if (_region.ChunkExists(_x, _z)) {
|
||||||
|
goto FoundNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_z = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FoundNext:
|
||||||
|
|
||||||
|
return (_x < ChunkManager.REGION_XLEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset ()
|
||||||
|
{
|
||||||
|
if (_enum != null) {
|
||||||
|
_enum.Reset();
|
||||||
|
_enum.MoveNext();
|
||||||
|
_region = _enum.Current;
|
||||||
|
}
|
||||||
|
_x = 0;
|
||||||
|
_z = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IDisposable.Dispose () { }
|
||||||
|
|
||||||
|
object IEnumerator.Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Chunk IEnumerator<Chunk>.Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chunk Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_x >= ChunkManager.REGION_XLEN) {
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cm.GetChunkInRegion(_region, _x, _z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
NBToolkit/NBToolkit/ChunkKey.cs
Normal file
28
NBToolkit/NBToolkit/ChunkKey.cs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NBToolkit
|
||||||
|
{
|
||||||
|
public class ChunkKey : IEquatable<ChunkKey>
|
||||||
|
{
|
||||||
|
protected int cx;
|
||||||
|
protected int cz;
|
||||||
|
|
||||||
|
public ChunkKey (int _cx, int _cz)
|
||||||
|
{
|
||||||
|
cx = _cx;
|
||||||
|
cz = _cz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals (ChunkKey ck)
|
||||||
|
{
|
||||||
|
return this.cx == ck.cx && this.cz == ck.cz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode ()
|
||||||
|
{
|
||||||
|
return cx ^ cz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
NBToolkit/NBToolkit/ChunkManager.cs
Normal file
69
NBToolkit/NBToolkit/ChunkManager.cs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NBToolkit
|
||||||
|
{
|
||||||
|
public class ChunkManager
|
||||||
|
{
|
||||||
|
public const int REGION_XLEN = 32;
|
||||||
|
public const int REGION_ZLEN = 32;
|
||||||
|
|
||||||
|
public const int REGION_XLOG = 5;
|
||||||
|
public const int REGION_ZLOG = 5;
|
||||||
|
|
||||||
|
public const int REGION_XMASK = 0x1F;
|
||||||
|
public const int REGION_ZMASK = 0x1F;
|
||||||
|
|
||||||
|
protected RegionManager _regionMan;
|
||||||
|
|
||||||
|
protected Dictionary<ChunkKey, WeakReference> _cache;
|
||||||
|
|
||||||
|
public ChunkManager (RegionManager rm)
|
||||||
|
{
|
||||||
|
_regionMan = rm;
|
||||||
|
_cache = new Dictionary<ChunkKey, WeakReference>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chunk GetChunk (int cx, int cz)
|
||||||
|
{
|
||||||
|
ChunkKey k = new ChunkKey(cx, cz);
|
||||||
|
|
||||||
|
Chunk c = null;
|
||||||
|
if (_cache.ContainsKey(k)) {
|
||||||
|
c = _cache[k].Target as Chunk;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_cache.Add(k, new WeakReference(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c != null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = new Chunk(this, cx, cz);
|
||||||
|
_cache[k].Target = c;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chunk GetChunkInRegion (Region r, int lcx, int lcz)
|
||||||
|
{
|
||||||
|
int cx = r.X * REGION_XLEN + lcx;
|
||||||
|
int cz = r.Z * REGION_ZLEN + lcz;
|
||||||
|
return GetChunk(cx, cz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region GetRegion (int cx, int cz)
|
||||||
|
{
|
||||||
|
cx >>= REGION_XLOG;
|
||||||
|
cz >>= REGION_ZLOG;
|
||||||
|
return _regionMan.GetRegion(cx, cz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegionManager GetRegionManager ()
|
||||||
|
{
|
||||||
|
return _regionMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,22 @@ namespace NBToolkit
|
||||||
class Harness
|
class Harness
|
||||||
{
|
{
|
||||||
public void Run (TKOptions opt, TKFilter filter) {
|
public void Run (TKOptions opt, TKFilter filter) {
|
||||||
string[] regions = RegionFileCache.GetRegionFileList(opt.OPT_WORLD);
|
World world = new World(opt.OPT_WORLD);
|
||||||
|
RegionList regions = new RegionList(world.GetRegionManager());
|
||||||
|
|
||||||
|
foreach (Region region in regions) {
|
||||||
|
Console.WriteLine(region.GetFileName());
|
||||||
|
|
||||||
|
for (int x = 0; x < ChunkManager.REGION_XLEN; x++) {
|
||||||
|
for (int z = 0; z < ChunkManager.REGION_ZLEN; z++) {
|
||||||
|
if (!region.ChunkExists(x, z)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*string[] regions = RegionFileCache.GetRegionFileList(opt.OPT_WORLD);
|
||||||
|
|
||||||
foreach (string p in regions) {
|
foreach (string p in regions) {
|
||||||
Console.WriteLine(p);
|
Console.WriteLine(p);
|
||||||
|
@ -85,7 +100,7 @@ namespace NBToolkit
|
||||||
zipStream.Close();
|
zipStream.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool BlockScan (NBT_Tag level, int val)
|
protected bool BlockScan (NBT_Tag level, int val)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>NBToolkit</RootNamespace>
|
<RootNamespace>NBToolkit</RootNamespace>
|
||||||
<AssemblyName>NBToolkit</AssemblyName>
|
<AssemblyName>NBToolkit</AssemblyName>
|
||||||
<TargetFrameworkVersion>v3.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<PublishUrl>publish\</PublishUrl>
|
<PublishUrl>publish\</PublishUrl>
|
||||||
<Install>true</Install>
|
<Install>true</Install>
|
||||||
|
@ -53,10 +53,17 @@
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="BlockManager.cs" />
|
||||||
|
<Compile Include="Chunk.cs" />
|
||||||
|
<Compile Include="ChunkManager.cs" />
|
||||||
<Compile Include="Harness.cs" />
|
<Compile Include="Harness.cs" />
|
||||||
<Compile Include="NBT.cs" />
|
<Compile Include="NBT.cs" />
|
||||||
<Compile Include="NDesk\Options.cs" />
|
<Compile Include="NDesk\Options.cs" />
|
||||||
<Compile Include="Oregen.cs" />
|
<Compile Include="Oregen.cs" />
|
||||||
|
<Compile Include="Region.cs" />
|
||||||
|
<Compile Include="RegionEnumerator.cs" />
|
||||||
|
<Compile Include="RegionKey.cs" />
|
||||||
|
<Compile Include="RegionManager.cs" />
|
||||||
<Compile Include="Replace.cs" />
|
<Compile Include="Replace.cs" />
|
||||||
<Compile Include="TKFilter.cs" />
|
<Compile Include="TKFilter.cs" />
|
||||||
<Compile Include="TKOptions.cs" />
|
<Compile Include="TKOptions.cs" />
|
||||||
|
@ -64,6 +71,7 @@
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="RegionFile.cs" />
|
<Compile Include="RegionFile.cs" />
|
||||||
<Compile Include="RegionFileCache.cs" />
|
<Compile Include="RegionFileCache.cs" />
|
||||||
|
<Compile Include="World.cs" />
|
||||||
<Compile Include="Zlib\Crc32.cs" />
|
<Compile Include="Zlib\Crc32.cs" />
|
||||||
<Compile Include="Zlib\Deflate.cs" />
|
<Compile Include="Zlib\Deflate.cs" />
|
||||||
<Compile Include="Zlib\DeflateStream.cs" />
|
<Compile Include="Zlib\DeflateStream.cs" />
|
||||||
|
|
Binary file not shown.
|
@ -59,7 +59,7 @@ namespace NBToolkit
|
||||||
{ "max=", "Generates deposits no higher than depth {VAL} (0-127)",
|
{ "max=", "Generates deposits no higher than depth {VAL} (0-127)",
|
||||||
v => OPT_MAX = Convert.ToInt32(v) % 128 },
|
v => OPT_MAX = Convert.ToInt32(v) % 128 },
|
||||||
{ "s|size=", "Generates deposits containing roughly up to {VAL} blocks",
|
{ "s|size=", "Generates deposits containing roughly up to {VAL} blocks",
|
||||||
v => OPT_MIN = Convert.ToInt32(v) % 128 },
|
v => OPT_SIZE = Convert.ToInt32(v) % 128 },
|
||||||
{ "oo=", "Generated deposits can replace other existing ores",
|
{ "oo=", "Generated deposits can replace other existing ores",
|
||||||
v => OPT_OO = true },
|
v => OPT_OO = true },
|
||||||
{ "oa=", "Generated deposits can replace any existing block (incl. air)",
|
{ "oa=", "Generated deposits can replace any existing block (incl. air)",
|
||||||
|
@ -140,6 +140,95 @@ namespace NBToolkit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MathHelper
|
||||||
|
{
|
||||||
|
private static float[] trigTable = new float[65536];
|
||||||
|
|
||||||
|
static MathHelper ()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 65536; i++) {
|
||||||
|
trigTable[i] = (float)Math.Sin(i * Math.PI * 2.0D / 65536.0D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Sin(float angle)
|
||||||
|
{
|
||||||
|
return trigTable[((int)(angle * 10430.378F) & 0xFFFF)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Cos(float angle) {
|
||||||
|
return trigTable[((int)(angle * 10430.378F + 16384.0F) & 0xFFFF)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NativeOreGen {
|
||||||
|
private int _blockId;
|
||||||
|
private int _size;
|
||||||
|
|
||||||
|
private static Random rand = new Random();
|
||||||
|
|
||||||
|
public NativeOreGen(int blockId, int size)
|
||||||
|
{
|
||||||
|
_blockId = blockId;
|
||||||
|
_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GenerateDeposit (NBT_ByteArray blocks, NBT_ByteArray data, int x, int y, int z)
|
||||||
|
{
|
||||||
|
float rpi = (float)(rand.NextDouble() * Math.PI);
|
||||||
|
|
||||||
|
double x1 = x + 8 + MathHelper.Sin(rpi) * _size / 8.0F;
|
||||||
|
double x2 = x + 8 - MathHelper.Sin(rpi) * _size / 8.0F;
|
||||||
|
double z1 = z + 8 + MathHelper.Cos(rpi) * _size / 8.0F;
|
||||||
|
double z2 = z + 8 - MathHelper.Cos(rpi) * _size / 8.0F;
|
||||||
|
|
||||||
|
double y1 = y + rand.Next(3) + 2;
|
||||||
|
double y2 = y + rand.Next(3) + 2;
|
||||||
|
|
||||||
|
for (int i = 0; i <= _size; i++) {
|
||||||
|
double xPos = x1 + (x2 - x1) * i / _size;
|
||||||
|
double yPos = y1 + (y2 - y1) * i / _size;
|
||||||
|
double zPos = z1 + (z2 - z1) * i / _size;
|
||||||
|
|
||||||
|
double fuzz = rand.NextDouble() * _size / 16.0D;
|
||||||
|
double fuzzXZ = (MathHelper.Sin((float)(i * Math.PI / _size)) + 1.0F) * fuzz + 1.0D;
|
||||||
|
double fuzzY = (MathHelper.Sin((float)(i * Math.PI / _size)) + 1.0F) * fuzz + 1.0D;
|
||||||
|
|
||||||
|
int xStart = (int)(xPos - fuzzXZ / 2.0D);
|
||||||
|
int yStart = (int)(yPos - fuzzY / 2.0D);
|
||||||
|
int zStart = (int)(zPos - fuzzXZ / 2.0D);
|
||||||
|
|
||||||
|
int xEnd = (int)(xPos + fuzzXZ / 2.0D);
|
||||||
|
int yEnd = (int)(yPos + fuzzY / 2.0D);
|
||||||
|
int zEnd = (int)(zPos + fuzzXZ / 2.0D);
|
||||||
|
|
||||||
|
for (int ix = xStart; ix <= xEnd; ix++) {
|
||||||
|
double xThresh = (ix + 0.5D - xPos) / (fuzzXZ / 2.0D);
|
||||||
|
if (xThresh * xThresh < 1.0D) {
|
||||||
|
for (int iy = yStart; iy <= yEnd; iy++) {
|
||||||
|
double yThresh = (iy + 0.5D - yPos) / (fuzzY / 2.0D);
|
||||||
|
if (xThresh * xThresh + yThresh * yThresh < 1.0D) {
|
||||||
|
for (int iz = zStart; iz <= zEnd; iz++) {
|
||||||
|
double zThresh = (iz + 0.5D - zPos) / (fuzzXZ / 2.0D);
|
||||||
|
if (xThresh * xThresh + yThresh * yThresh + zThresh * zThresh < 1.0D) {
|
||||||
|
//Apply
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BlockIndex (int x, int y, int z)
|
||||||
|
{
|
||||||
|
return y + (z * 128 + x * 128 * 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class Oregen : TKFilter
|
public class Oregen : TKFilter
|
||||||
{
|
{
|
||||||
public const int BLOCK_STONE = 1;
|
public const int BLOCK_STONE = 1;
|
||||||
|
|
|
@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
|
||||||
[assembly: AssemblyTitle("NBToolkit")]
|
[assembly: AssemblyTitle("NBToolkit")]
|
||||||
[assembly: AssemblyDescription("")]
|
[assembly: AssemblyDescription("")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("Microsoft")]
|
[assembly: AssemblyCompany("")]
|
||||||
[assembly: AssemblyProduct("NBToolkit")]
|
[assembly: AssemblyProduct("NBToolkit")]
|
||||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
|
[assembly: AssemblyCopyright("Copyright © Justin Aquadro 2011")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
|
155
NBToolkit/NBToolkit/Region.cs
Normal file
155
NBToolkit/NBToolkit/Region.cs
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.IO;
|
||||||
|
using NBT;
|
||||||
|
|
||||||
|
namespace NBToolkit
|
||||||
|
{
|
||||||
|
public class Region
|
||||||
|
{
|
||||||
|
protected int _rx;
|
||||||
|
protected int _rz;
|
||||||
|
|
||||||
|
protected RegionManager _regionMan;
|
||||||
|
|
||||||
|
protected static Regex _namePattern = new Regex("r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mcr$");
|
||||||
|
|
||||||
|
protected WeakReference _regionFile;
|
||||||
|
|
||||||
|
public Region (RegionManager rm, int rx, int rz)
|
||||||
|
{
|
||||||
|
_regionMan = rm;
|
||||||
|
_regionFile = new WeakReference(null);
|
||||||
|
_rx = rx;
|
||||||
|
_rz = rz;
|
||||||
|
|
||||||
|
if (!File.Exists(GetFilePath())) {
|
||||||
|
throw new FileNotFoundException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region (RegionManager rm, string filename)
|
||||||
|
{
|
||||||
|
_regionMan = rm;
|
||||||
|
_regionFile = new WeakReference(null);
|
||||||
|
|
||||||
|
ParseFileName(filename, out _rx, out _rz);
|
||||||
|
|
||||||
|
if (!File.Exists(Path.Combine(_regionMan.GetRegionPath(), filename))) {
|
||||||
|
throw new FileNotFoundException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int X
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _rx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Z
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _rz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetFileName ()
|
||||||
|
{
|
||||||
|
return "r." + _rx + "." + _rz + ".mcr";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TestFileName (string filename)
|
||||||
|
{
|
||||||
|
Match match = _namePattern.Match(filename);
|
||||||
|
if (!match.Success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ParseFileName (string filename, out int x, out int z)
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
z = 0;
|
||||||
|
|
||||||
|
Match match = _namePattern.Match(filename);
|
||||||
|
if (!match.Success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = Convert.ToInt32(match.Groups[1].Value);
|
||||||
|
z = Convert.ToInt32(match.Groups[2].Value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetFilePath ()
|
||||||
|
{
|
||||||
|
return System.IO.Path.Combine(_regionMan.GetRegionPath(), GetFileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RegionFile GetRegionFile ()
|
||||||
|
{
|
||||||
|
RegionFile rf = _regionFile.Target as RegionFile;
|
||||||
|
if (rf == null) {
|
||||||
|
rf = new RegionFile(GetFilePath());
|
||||||
|
_regionFile.Target = rf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NBT_Tree GetChunkTree (int lcx, int lcz)
|
||||||
|
{
|
||||||
|
RegionFile rf = GetRegionFile();
|
||||||
|
Stream nbtstr = rf.GetChunkDataInputStream(lcx, lcz);
|
||||||
|
if (nbtstr == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NBT_Tree(nbtstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SaveChunkTree (int lcx, int lcz, NBT_Tree tree)
|
||||||
|
{
|
||||||
|
RegionFile rf = GetRegionFile();
|
||||||
|
Stream zipstr = rf.GetChunkDataOutputStream(lcx, lcz);
|
||||||
|
if (zipstr == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tree.WriteTo(zipstr);
|
||||||
|
zipstr.Close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ChunkExists (int lcx, int lcz)
|
||||||
|
{
|
||||||
|
RegionFile rf = GetRegionFile();
|
||||||
|
return rf.HasChunk(lcx, lcz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ChunkCount ()
|
||||||
|
{
|
||||||
|
RegionFile rf = GetRegionFile();
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
for (int x = 0; x < ChunkManager.REGION_XLEN; x++) {
|
||||||
|
for (int z = 0; z < ChunkManager.REGION_ZLEN; z++) {
|
||||||
|
if (rf.HasChunk(x, z)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
131
NBToolkit/NBToolkit/RegionEnumerator.cs
Normal file
131
NBToolkit/NBToolkit/RegionEnumerator.cs
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace NBToolkit
|
||||||
|
{
|
||||||
|
public class RegionList : IEnumerable<Region>
|
||||||
|
{
|
||||||
|
private List<Region> _regions;
|
||||||
|
|
||||||
|
public RegionList (List<Region> regs)
|
||||||
|
{
|
||||||
|
_regions = regs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegionList (RegionManager rm)
|
||||||
|
{
|
||||||
|
_regions = new List<Region>();
|
||||||
|
|
||||||
|
if (!Directory.Exists(rm.GetRegionPath())) {
|
||||||
|
throw new DirectoryNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] files = Directory.GetFiles(rm.GetRegionPath());
|
||||||
|
_regions.Capacity = files.Length;
|
||||||
|
|
||||||
|
foreach (string file in files) {
|
||||||
|
try {
|
||||||
|
Region r = rm.GetRegion(file);
|
||||||
|
_regions.Add(r);
|
||||||
|
}
|
||||||
|
catch (ArgumentException) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator () {
|
||||||
|
return (IEnumerator)GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator<Region> IEnumerable<Region>.GetEnumerator ()
|
||||||
|
{
|
||||||
|
return (IEnumerator<Region>)GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegionEnumerator GetEnumerator ()
|
||||||
|
{
|
||||||
|
return new RegionEnumerator(_regions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RegionEnumerator : IEnumerator<Region>
|
||||||
|
{
|
||||||
|
protected List<Region> _regions;
|
||||||
|
|
||||||
|
protected int _pos = -1;
|
||||||
|
|
||||||
|
public RegionEnumerator (List<Region> regs)
|
||||||
|
{
|
||||||
|
_regions = regs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegionEnumerator (RegionManager rm)
|
||||||
|
{
|
||||||
|
_regions = new List<Region>();
|
||||||
|
|
||||||
|
if (!Directory.Exists(rm.GetRegionPath())) {
|
||||||
|
throw new DirectoryNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] files = Directory.GetFiles(rm.GetRegionPath());
|
||||||
|
_regions.Capacity = files.Length;
|
||||||
|
|
||||||
|
foreach (string file in files) {
|
||||||
|
try {
|
||||||
|
Region r = rm.GetRegion(file);
|
||||||
|
_regions.Add(r);
|
||||||
|
}
|
||||||
|
catch (ArgumentException) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext ()
|
||||||
|
{
|
||||||
|
_pos++;
|
||||||
|
return (_pos < _regions.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset ()
|
||||||
|
{
|
||||||
|
_pos = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IDisposable.Dispose () { }
|
||||||
|
|
||||||
|
object IEnumerator.Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Region IEnumerator<Region>.Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return _regions[_pos];
|
||||||
|
}
|
||||||
|
catch (IndexOutOfRangeException) {
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,18 +5,25 @@ using System.IO;
|
||||||
|
|
||||||
namespace NBToolkit
|
namespace NBToolkit
|
||||||
{
|
{
|
||||||
public class RegionFileCache
|
/*public class RegionFileCache
|
||||||
{
|
{
|
||||||
private const int MAX_CACHE_SIZE = 256;
|
private const int MAX_CACHE_SIZE = 256;
|
||||||
|
|
||||||
private static Dictionary<string, WeakReference> cache = new Dictionary<string, WeakReference>();
|
private string _regionPath;
|
||||||
|
|
||||||
private RegionFileCache() {
|
private Dictionary<string, WeakReference> cache = new Dictionary<string, WeakReference>();
|
||||||
|
|
||||||
|
public RegionFileCache (string path) {
|
||||||
|
_regionPath = path;
|
||||||
|
|
||||||
|
if (!Directory.Exists(_regionPath)) {
|
||||||
|
throw new DirectoryNotFoundException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegionFile GetRegionFile(string basePath, string fileName) {
|
public RegionFile GetRegionFile (string fileName) {
|
||||||
string regionDir = Path.Combine(basePath, "region");
|
//string regionDir = basePath; // Path.Combine(basePath, "region");
|
||||||
string file = Path.Combine(regionDir, fileName);
|
string file = Path.Combine(_regionPath, fileName);
|
||||||
|
|
||||||
RegionFile rf = null;
|
RegionFile rf = null;
|
||||||
if (cache.ContainsKey(file)) {
|
if (cache.ContainsKey(file)) {
|
||||||
|
@ -27,10 +34,6 @@ namespace NBToolkit
|
||||||
return rf;
|
return rf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Directory.Exists(regionDir)) {
|
|
||||||
Directory.CreateDirectory(regionDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cache.Count >= MAX_CACHE_SIZE) {
|
if (cache.Count >= MAX_CACHE_SIZE) {
|
||||||
RegionFileCache.Clear();
|
RegionFileCache.Clear();
|
||||||
}
|
}
|
||||||
|
@ -40,32 +43,11 @@ namespace NBToolkit
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegionFile GetRegionFile (string basePath, int chunkX, int chunkZ)
|
public RegionFile GetRegionFile (int chunkX, int chunkZ)
|
||||||
{
|
{
|
||||||
string regionDir = Path.Combine(basePath, "region");
|
string fileName = "r." + (chunkX >> 5) + "." + (chunkZ >> 5) + ".mcr";
|
||||||
string fileName = Path.Combine(regionDir, "r." + (chunkX >> 5) + "." + (chunkZ >> 5) + ".mcr");
|
|
||||||
|
|
||||||
return GetRegionFile(basePath, fileName);
|
return GetRegionFile(fileName);
|
||||||
}
|
|
||||||
|
|
||||||
public static string[] GetRegionFileList (string basePath)
|
|
||||||
{
|
|
||||||
string regionDir = Path.Combine(basePath, "region");
|
|
||||||
|
|
||||||
if (!Directory.Exists(regionDir)) {
|
|
||||||
Directory.CreateDirectory(regionDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
string[] files = Directory.GetFiles(regionDir);
|
|
||||||
List<string> valid = new List<string>();
|
|
||||||
|
|
||||||
foreach (string file in files) {
|
|
||||||
if (System.Text.RegularExpressions.Regex.IsMatch(file, "r\\.-?[0-9]+\\.-?[0-9]+\\.mcr$")) {
|
|
||||||
valid.Add(Path.GetFileName(file));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return valid.ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Clear() {
|
public static void Clear() {
|
||||||
|
@ -92,5 +74,5 @@ namespace NBToolkit
|
||||||
RegionFile r = GetRegionFile(basePath, chunkX, chunkZ);
|
RegionFile r = GetRegionFile(basePath, chunkX, chunkZ);
|
||||||
return r.GetChunkDataOutputStream(chunkX & 31, chunkZ & 31);
|
return r.GetChunkDataOutputStream(chunkX & 31, chunkZ & 31);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
28
NBToolkit/NBToolkit/RegionKey.cs
Normal file
28
NBToolkit/NBToolkit/RegionKey.cs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NBToolkit
|
||||||
|
{
|
||||||
|
public class RegionKey : IEquatable<RegionKey>
|
||||||
|
{
|
||||||
|
protected int rx;
|
||||||
|
protected int rz;
|
||||||
|
|
||||||
|
public RegionKey (int _rx, int _rz)
|
||||||
|
{
|
||||||
|
rx = _rx;
|
||||||
|
rz = _rz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals (RegionKey ck)
|
||||||
|
{
|
||||||
|
return this.rx == ck.rx && this.rz == ck.rz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode ()
|
||||||
|
{
|
||||||
|
return rx ^ rz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
NBToolkit/NBToolkit/RegionManager.cs
Normal file
47
NBToolkit/NBToolkit/RegionManager.cs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NBToolkit
|
||||||
|
{
|
||||||
|
public class RegionManager
|
||||||
|
{
|
||||||
|
protected string _regionPath;
|
||||||
|
|
||||||
|
protected Dictionary<RegionKey, Region> _cache;
|
||||||
|
|
||||||
|
public RegionManager (string regionDir)
|
||||||
|
{
|
||||||
|
_regionPath = regionDir;
|
||||||
|
_cache = new Dictionary<RegionKey, Region>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region GetRegion (int rx, int rz)
|
||||||
|
{
|
||||||
|
RegionKey k = new RegionKey(rx, rz);
|
||||||
|
Region r;
|
||||||
|
|
||||||
|
if (_cache.TryGetValue(k, out r) == false) {
|
||||||
|
r = new Region(this, rx, rz);
|
||||||
|
_cache.Add(k, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region GetRegion (string filename)
|
||||||
|
{
|
||||||
|
int rx, rz;
|
||||||
|
if (!Region.ParseFileName(filename, out rx, out rz)) {
|
||||||
|
throw new ArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetRegion(rx, rz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetRegionPath ()
|
||||||
|
{
|
||||||
|
return _regionPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,24 @@ namespace NBToolkit
|
||||||
public int? OPT_DATA = null;
|
public int? OPT_DATA = null;
|
||||||
public double? OPT_PROB = null;
|
public double? OPT_PROB = null;
|
||||||
|
|
||||||
|
// Block coordinate conditions
|
||||||
|
public int? BL_X_GE = null;
|
||||||
|
public int? BL_X_LE = null;
|
||||||
|
public int? BL_Y_GE = null;
|
||||||
|
public int? BL_Y_LE = null;
|
||||||
|
public int? BL_Z_GE = null;
|
||||||
|
public int? BL_Z_LE = null;
|
||||||
|
|
||||||
|
// Neighbor conditions
|
||||||
|
public int? OPT_NEIGHBOR = null;
|
||||||
|
public int? OPT_NEIGHBOR_SIDE = null;
|
||||||
|
public int? OPT_NEIGHBOR_E = null;
|
||||||
|
public int? OPT_NEIGHBOR_W = null;
|
||||||
|
public int? OPT_NEIGHBOR_N = null;
|
||||||
|
public int? OPT_NEIGHBOR_S = null;
|
||||||
|
public int? OPT_NEIGHBOR_T = null;
|
||||||
|
public int? OPT_NEIGHBOR_B = null;
|
||||||
|
|
||||||
public ReplaceOptions (string[] args) : base(args)
|
public ReplaceOptions (string[] args) : base(args)
|
||||||
{
|
{
|
||||||
filterOpt = new OptionSet()
|
filterOpt = new OptionSet()
|
||||||
|
@ -30,6 +48,40 @@ namespace NBToolkit
|
||||||
v => { OPT_PROB = Convert.ToDouble(v);
|
v => { OPT_PROB = Convert.ToDouble(v);
|
||||||
OPT_PROB = Math.Max((double)OPT_PROB, 0.0);
|
OPT_PROB = Math.Max((double)OPT_PROB, 0.0);
|
||||||
OPT_PROB = Math.Min((double)OPT_PROB, 1.0); } },
|
OPT_PROB = Math.Min((double)OPT_PROB, 1.0); } },
|
||||||
|
{ "bxa=", "Update blocks with X-coord equal to or above {VAL}",
|
||||||
|
v => BL_X_GE = Convert.ToInt32(v) },
|
||||||
|
{ "bxb=", "Update blocks with X-coord equal to or below {VAL}",
|
||||||
|
v => BL_X_LE = Convert.ToInt32(v) },
|
||||||
|
{ "bxr=", "Update blocks with X-coord between {0:V1} and {1:V2} [inclusive]",
|
||||||
|
(v1, v2) => { BL_X_GE = Convert.ToInt32(v1); BL_X_LE = Convert.ToInt32(v2); } },
|
||||||
|
{ "bya=", "Update blocks with Y-coord equal to or above {VAL}",
|
||||||
|
v => BL_Y_GE = Convert.ToInt32(v) },
|
||||||
|
{ "byb=", "Update blocks with Y-coord equal to or below {VAL}",
|
||||||
|
v => BL_Y_LE = Convert.ToInt32(v) },
|
||||||
|
{ "byr=", "Update blocks with Y-coord between {0:V1} and {1:V2} [inclusive]",
|
||||||
|
(v1, v2) => { BL_Y_GE = Convert.ToInt32(v1); BL_Y_LE = Convert.ToInt32(v2); } },
|
||||||
|
{ "bza=", "Update blocks with Z-coord equal to or above {VAL}",
|
||||||
|
v => BL_Z_GE = Convert.ToInt32(v) },
|
||||||
|
{ "bzb=", "Update blocks with Z-coord equal to or below {VAL}",
|
||||||
|
v => BL_Z_LE = Convert.ToInt32(v) },
|
||||||
|
{ "bzr=", "Update blocks with Z-coord between {0:V1} and {1:V2} [inclusive]",
|
||||||
|
(v1, v2) => { BL_Z_GE = Convert.ToInt32(v1); BL_Z_LE = Convert.ToInt32(v2); } },
|
||||||
|
{ "nb=", "Update blocks that have block type {ID} as any neighbor",
|
||||||
|
v => OPT_NEIGHBOR = Convert.ToInt32(v) % 256 },
|
||||||
|
{ "nbs=", "Update blocks that have block type {ID} as any x/z neighbor",
|
||||||
|
v => OPT_NEIGHBOR_SIDE = Convert.ToInt32(v) % 256 },
|
||||||
|
{ "nbxa=", "Update blocks that have block type {ID} as their south neighbor",
|
||||||
|
v => OPT_NEIGHBOR_S = Convert.ToInt32(v) % 256 },
|
||||||
|
{ "nbxb=", "Update blocks that have block type {ID} as their north neighbor",
|
||||||
|
v => OPT_NEIGHBOR_N = Convert.ToInt32(v) % 256 },
|
||||||
|
{ "nbya=", "Update blocks that have block type {ID} as their top neighbor",
|
||||||
|
v => OPT_NEIGHBOR_T = Convert.ToInt32(v) % 256 },
|
||||||
|
{ "nbyb=", "Update blocks that have block type {ID} as their bottom neighbor",
|
||||||
|
v => OPT_NEIGHBOR_B = Convert.ToInt32(v) % 256 },
|
||||||
|
{ "nbza=", "Update blocks that have block type {ID} as their west neighbor",
|
||||||
|
v => OPT_NEIGHBOR_W = Convert.ToInt32(v) % 256 },
|
||||||
|
{ "nbzb=", "Update blocks that have block type {ID} as their east neighbor",
|
||||||
|
v => OPT_NEIGHBOR_E = Convert.ToInt32(v) % 256 },
|
||||||
};
|
};
|
||||||
|
|
||||||
filterOpt.Parse(args);
|
filterOpt.Parse(args);
|
||||||
|
@ -94,15 +146,74 @@ namespace NBToolkit
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NBT_Tag xPos = level.findTagByName("xPos");
|
||||||
|
NBT_Tag zPos = level.findTagByName("zPos");
|
||||||
|
if (xPos == null || zPos == null || xPos.type != NBT_Type.TAG_INT || zPos.type != NBT_Type.TAG_INT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xBase = xPos.value.toInt().data * 16;
|
||||||
|
int zBase = zPos.value.toInt().data * 16;
|
||||||
|
|
||||||
NBT_ByteArray blocks_ary = blocks.value.toByteArray();
|
NBT_ByteArray blocks_ary = blocks.value.toByteArray();
|
||||||
NBT_ByteArray data_ary = data.value.toByteArray();
|
NBT_ByteArray data_ary = data.value.toByteArray();
|
||||||
|
|
||||||
|
// Determine X range
|
||||||
|
int xmin = 0;
|
||||||
|
int xmax = 15;
|
||||||
|
|
||||||
|
if (opt.BL_X_GE != null) {
|
||||||
|
xmin = (int)opt.BL_X_GE - xBase;
|
||||||
|
}
|
||||||
|
if (opt.BL_X_LE != null) {
|
||||||
|
xmax = (int)opt.BL_X_LE - xBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmin = (xmin < 0) ? 0 : xmin;
|
||||||
|
xmax = (xmin > 15) ? 15 : xmax;
|
||||||
|
|
||||||
|
if (xmin > 15 || xmax < 0 || xmin > xmax) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine Y range
|
||||||
int ymin = 0;
|
int ymin = 0;
|
||||||
int ymax = 127;
|
int ymax = 127;
|
||||||
|
|
||||||
|
if (opt.BL_Y_GE != null) {
|
||||||
|
ymin = (int)opt.BL_Y_GE;
|
||||||
|
}
|
||||||
|
if (opt.BL_Y_LE != null) {
|
||||||
|
ymax = (int)opt.BL_Y_LE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ymin > ymax) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine X range
|
||||||
|
int zmin = 0;
|
||||||
|
int zmax = 15;
|
||||||
|
|
||||||
|
if (opt.BL_Z_GE != null) {
|
||||||
|
zmin = (int)opt.BL_Z_GE - zBase;
|
||||||
|
}
|
||||||
|
if (opt.BL_Z_LE != null) {
|
||||||
|
zmax = (int)opt.BL_Z_LE - zBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
zmin = (zmin < 0) ? 0 : zmin;
|
||||||
|
zmax = (zmin > 15) ? 15 : zmax;
|
||||||
|
|
||||||
|
if (zmin > 15 || zmax < 0 || zmin > zmax) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process Chunk
|
||||||
for (int y = ymin; y <= ymax; y++) {
|
for (int y = ymin; y <= ymax; y++) {
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = xmin; x <= xmax; x++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = zmin; z <= zmax; z++) {
|
||||||
|
// Probability test
|
||||||
if (opt.OPT_PROB != null) {
|
if (opt.OPT_PROB != null) {
|
||||||
double c = rand.NextDouble();
|
double c = rand.NextDouble();
|
||||||
if (c > opt.OPT_PROB) {
|
if (c > opt.OPT_PROB) {
|
||||||
|
@ -110,6 +221,7 @@ namespace NBToolkit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attempt to replace block
|
||||||
int index = BlockIndex(x, y, z);
|
int index = BlockIndex(x, y, z);
|
||||||
if (blocks_ary.data[index] == opt.OPT_BEFORE) {
|
if (blocks_ary.data[index] == opt.OPT_BEFORE) {
|
||||||
blocks_ary.data[index] = (byte)opt.OPT_AFTER;
|
blocks_ary.data[index] = (byte)opt.OPT_AFTER;
|
||||||
|
|
|
@ -27,12 +27,6 @@ namespace NBToolkit
|
||||||
public int? CH_Z_GE = null;
|
public int? CH_Z_GE = null;
|
||||||
public int? CH_Z_LE = null;
|
public int? CH_Z_LE = null;
|
||||||
|
|
||||||
// Block coordinate conditions
|
|
||||||
public int? BL_X_GE = null;
|
|
||||||
public int? BL_X_LE = null;
|
|
||||||
public int? BL_Z_GE = null;
|
|
||||||
public int? BL_Z_LE = null;
|
|
||||||
|
|
||||||
public TKOptions (string[] args)
|
public TKOptions (string[] args)
|
||||||
{
|
{
|
||||||
commonOpt = new OptionSet()
|
commonOpt = new OptionSet()
|
||||||
|
@ -83,7 +77,7 @@ namespace NBToolkit
|
||||||
throw new TKOptionException();
|
throw new TKOptionException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!File.Exists(Path.Combine(OPT_WORLD, "Level.dat"))) {
|
if (!File.Exists(Path.Combine(OPT_WORLD, "level.dat"))) {
|
||||||
Console.WriteLine("Error: The supplied world path is invalid");
|
Console.WriteLine("Error: The supplied world path is invalid");
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
this.PrintUsage();
|
this.PrintUsage();
|
||||||
|
|
40
NBToolkit/NBToolkit/World.cs
Normal file
40
NBToolkit/NBToolkit/World.cs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace NBToolkit
|
||||||
|
{
|
||||||
|
class World
|
||||||
|
{
|
||||||
|
protected RegionManager _regionMan;
|
||||||
|
protected ChunkManager _chunkMan;
|
||||||
|
protected BlockManager _blockMan;
|
||||||
|
|
||||||
|
protected string _worldPath;
|
||||||
|
|
||||||
|
public World (string world)
|
||||||
|
{
|
||||||
|
_worldPath = world;
|
||||||
|
|
||||||
|
_regionMan = new RegionManager(Path.Combine(world, "region"));
|
||||||
|
_chunkMan = new ChunkManager(_regionMan);
|
||||||
|
_blockMan = new BlockManager(_chunkMan);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegionManager GetRegionManager ()
|
||||||
|
{
|
||||||
|
return _regionMan;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChunkManager GetChunkManager ()
|
||||||
|
{
|
||||||
|
return _chunkMan;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockManager GetBlockManager ()
|
||||||
|
{
|
||||||
|
return _blockMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue