forked from mirrors/NBTExplorer
NBToolkit ready for another maintenance release
This commit is contained in:
parent
c33b616ae8
commit
8234589043
5 changed files with 125 additions and 89 deletions
|
@ -29,6 +29,8 @@ namespace NBToolkit
|
||||||
bool IncludeMatchAll { get; }
|
bool IncludeMatchAll { get; }
|
||||||
bool ExcludeMatchAny { get; }
|
bool ExcludeMatchAny { get; }
|
||||||
bool ExcludeMatchAll { get; }
|
bool ExcludeMatchAll { get; }
|
||||||
|
|
||||||
|
double? ProbMatch { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChunkFilter : IOptions, IChunkFilter
|
public class ChunkFilter : IOptions, IChunkFilter
|
||||||
|
@ -46,110 +48,78 @@ namespace NBToolkit
|
||||||
protected bool _includeAny = true;
|
protected bool _includeAny = true;
|
||||||
protected bool _excludeAny = true;
|
protected bool _excludeAny = true;
|
||||||
|
|
||||||
|
protected double? _prob = null;
|
||||||
|
|
||||||
protected OptionSet _options;
|
protected OptionSet _options;
|
||||||
|
|
||||||
public int? XAboveEq
|
public int? XAboveEq
|
||||||
{
|
{
|
||||||
get
|
get { return _xAboveEq; }
|
||||||
{
|
|
||||||
return _xAboveEq;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int? XBelowEq
|
public int? XBelowEq
|
||||||
{
|
{
|
||||||
get
|
get { return _xBelowEq; }
|
||||||
{
|
|
||||||
return _xBelowEq;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int? ZAboveEq
|
public int? ZAboveEq
|
||||||
{
|
{
|
||||||
get
|
get { return _zAboveEq; }
|
||||||
{
|
|
||||||
return _zAboveEq;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int? ZBelowEq
|
public int? ZBelowEq
|
||||||
{
|
{
|
||||||
get
|
get { return _zBelowEq; }
|
||||||
{
|
|
||||||
return _zBelowEq;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool InvertXZ
|
public bool InvertXZ
|
||||||
{
|
{
|
||||||
get
|
get { return _invertXZ; }
|
||||||
{
|
|
||||||
return _invertXZ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<int> IncludedBlocks
|
public IEnumerable<int> IncludedBlocks
|
||||||
{
|
{
|
||||||
get
|
get { return _includedBlocks; }
|
||||||
{
|
|
||||||
return _includedBlocks;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<int> ExcludedBlocks
|
public IEnumerable<int> ExcludedBlocks
|
||||||
{
|
{
|
||||||
get
|
get { return _excludedBlocks; }
|
||||||
{
|
|
||||||
return _excludedBlocks;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int IncludedBlockCount
|
public int IncludedBlockCount
|
||||||
{
|
{
|
||||||
get
|
get { return _includedBlocks.Count; }
|
||||||
{
|
|
||||||
return _includedBlocks.Count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ExcludedBlockCount
|
public int ExcludedBlockCount
|
||||||
{
|
{
|
||||||
get
|
get { return _excludedBlocks.Count; }
|
||||||
{
|
|
||||||
return _excludedBlocks.Count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IncludeMatchAny
|
public bool IncludeMatchAny
|
||||||
{
|
{
|
||||||
get
|
get { return _includeAny; }
|
||||||
{
|
|
||||||
return _includeAny;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IncludeMatchAll
|
public bool IncludeMatchAll
|
||||||
{
|
{
|
||||||
get
|
get { return !_includeAny; }
|
||||||
{
|
|
||||||
return !_includeAny;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ExcludeMatchAny
|
public bool ExcludeMatchAny
|
||||||
{
|
{
|
||||||
get
|
get { return _excludeAny; }
|
||||||
{
|
|
||||||
return _excludeAny;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ExcludeMatchAll
|
public bool ExcludeMatchAll
|
||||||
{
|
{
|
||||||
get
|
get { return !_excludeAny; }
|
||||||
{
|
}
|
||||||
return !_excludeAny;
|
|
||||||
}
|
public double? ProbMatch
|
||||||
|
{
|
||||||
|
get { return _prob; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkFilter ()
|
public ChunkFilter ()
|
||||||
|
@ -179,6 +149,8 @@ namespace NBToolkit
|
||||||
v => _includeAny = false },
|
v => _includeAny = false },
|
||||||
{ "cxy|ChunkExcludeAny", "If multiple --cx options, chunk can match any of them to be excluded. (default)",
|
{ "cxy|ChunkExcludeAny", "If multiple --cx options, chunk can match any of them to be excluded. (default)",
|
||||||
v => _includeAny = true },
|
v => _includeAny = true },
|
||||||
|
{ "cp|ChunkProbability=", "Selects a matching chunk with probability {VAL} (0.0-1.0)",
|
||||||
|
v => _prob = Convert.ToDouble(v) },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,8 @@ namespace NBToolkit
|
||||||
|
|
||||||
private IEnumerator<ChunkRef> _enum;
|
private IEnumerator<ChunkRef> _enum;
|
||||||
|
|
||||||
|
private static Random _rand = new Random();
|
||||||
|
|
||||||
public ChunkEnumerator (IChunkManager cm, IChunkFilter filter)
|
public ChunkEnumerator (IChunkManager cm, IChunkFilter filter)
|
||||||
{
|
{
|
||||||
_cm = cm;
|
_cm = cm;
|
||||||
|
@ -144,6 +146,14 @@ namespace NBToolkit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter out randomly matching chunks (according to probability value)
|
||||||
|
if (_filter.ProbMatch != null) {
|
||||||
|
double r = _rand.NextDouble();
|
||||||
|
if (r > _filter.ProbMatch) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,6 +224,11 @@ namespace NBToolkit
|
||||||
return _cm.SaveChunk(chunk);
|
return _cm.SaveChunk(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ChunkRef SetChunk (int cx, int cz, Chunk chunk)
|
||||||
|
{
|
||||||
|
return _cm.SetChunk(cx, cz, chunk);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="BlockFilter.cs" />
|
||||||
<Compile Include="Dump.cs" />
|
<Compile Include="Dump.cs" />
|
||||||
<Compile Include="ChunkFilter.cs" />
|
<Compile Include="ChunkFilter.cs" />
|
||||||
<Compile Include="FilteredChunkManager.cs" />
|
<Compile Include="FilteredChunkManager.cs" />
|
||||||
|
|
|
@ -139,10 +139,10 @@ namespace NBToolkit
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.BlockLight) {
|
if (opt.BlockLight) {
|
||||||
//chunk.UpdateEdgeBlockLight();
|
chunk.Blocks.StitchBlockLight();
|
||||||
}
|
}
|
||||||
if (opt.SkyLight) {
|
if (opt.SkyLight) {
|
||||||
//chunk.UpdateEdgeSkyLight();
|
chunk.Blocks.StitchSkyLight();
|
||||||
}
|
}
|
||||||
fcm.Save();
|
fcm.Save();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,11 @@ using Substrate;
|
||||||
|
|
||||||
namespace NBToolkit
|
namespace NBToolkit
|
||||||
{
|
{
|
||||||
public class ReplaceOptions : TKOptions, IChunkFilterable
|
public class ReplaceOptions : TKOptions, IChunkFilterable, IBlockFilterable
|
||||||
{
|
{
|
||||||
private OptionSet _filterOpt = null;
|
private OptionSet _filterOpt = null;
|
||||||
private ChunkFilter _chunkFilter = null;
|
private ChunkFilter _chunkFilter = null;
|
||||||
|
private BlockFilter _blockFilter = null;
|
||||||
|
|
||||||
public int? OPT_BEFORE = null;
|
public int? OPT_BEFORE = null;
|
||||||
public int? OPT_AFTER = null;
|
public int? OPT_AFTER = null;
|
||||||
|
@ -41,13 +42,13 @@ namespace NBToolkit
|
||||||
{
|
{
|
||||||
_filterOpt = new OptionSet()
|
_filterOpt = new OptionSet()
|
||||||
{
|
{
|
||||||
{ "b|before=", "Replace instances of block type {ID} with another block type",
|
/*{ "b|before=", "Replace instances of block type {ID} with another block type. This option is repeatable.",
|
||||||
v => OPT_BEFORE = Convert.ToInt32(v) % 256 },
|
v => _includedBlocks.Add(Convert.ToInt32(v) % 256) },*/
|
||||||
{ "a|after=", "Replace the selected blocks with block type {ID}",
|
{ "a|after=", "Replace the selected blocks with block type {ID}",
|
||||||
v => OPT_AFTER = Convert.ToInt32(v) % 256 },
|
v => OPT_AFTER = Convert.ToInt32(v) % 256 },
|
||||||
{ "d|data=", "Set the new block's data value to {VAL} (0-15)",
|
{ "d|data=", "Set the new block's data value to {VAL} (0-15)",
|
||||||
v => OPT_DATA = Convert.ToInt32(v) % 16 },
|
v => OPT_DATA = Convert.ToInt32(v) % 16 },
|
||||||
{ "p|prob=", "Replace any matching block with probability {VAL} (0.0-1.0)",
|
/*{ "p|prob=", "Replace any matching block with probability {VAL} (0.0-1.0)",
|
||||||
v => { OPT_PROB = Convert.ToDouble(v, new CultureInfo("en-US"));
|
v => { OPT_PROB = Convert.ToDouble(v, new CultureInfo("en-US"));
|
||||||
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); } },
|
||||||
|
@ -65,7 +66,7 @@ namespace NBToolkit
|
||||||
(v1, v2) => {
|
(v1, v2) => {
|
||||||
try { BL_Z_GE = Convert.ToInt32(v1); } catch (FormatException) { }
|
try { BL_Z_GE = Convert.ToInt32(v1); } catch (FormatException) { }
|
||||||
try { BL_Z_LE = Convert.ToInt32(v2); } catch (FormatException) { }
|
try { BL_Z_LE = Convert.ToInt32(v2); } catch (FormatException) { }
|
||||||
} },
|
} },*/
|
||||||
/*{ "nb=", "Update blocks that have block type {ID} as any neighbor",
|
/*{ "nb=", "Update blocks that have block type {ID} as any neighbor",
|
||||||
v => OPT_NEIGHBOR = Convert.ToInt32(v) % 256 },
|
v => OPT_NEIGHBOR = Convert.ToInt32(v) % 256 },
|
||||||
{ "nbs=", "Update blocks that have block type {ID} as any x/z neighbor",
|
{ "nbs=", "Update blocks that have block type {ID} as any x/z neighbor",
|
||||||
|
@ -85,6 +86,7 @@ namespace NBToolkit
|
||||||
};
|
};
|
||||||
|
|
||||||
_chunkFilter = new ChunkFilter();
|
_chunkFilter = new ChunkFilter();
|
||||||
|
_blockFilter = new BlockFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReplaceOptions (string[] args)
|
public ReplaceOptions (string[] args)
|
||||||
|
@ -99,11 +101,12 @@ namespace NBToolkit
|
||||||
|
|
||||||
_filterOpt.Parse(args);
|
_filterOpt.Parse(args);
|
||||||
_chunkFilter.Parse(args);
|
_chunkFilter.Parse(args);
|
||||||
|
_blockFilter.Parse(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void PrintUsage ()
|
public override void PrintUsage ()
|
||||||
{
|
{
|
||||||
Console.WriteLine("Usage: nbtoolkit replace -b <id> -a <id> [options]");
|
Console.WriteLine("Usage: nbtoolkit replace -a <id> [options]");
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.WriteLine("Options for command 'replace':");
|
Console.WriteLine("Options for command 'replace':");
|
||||||
|
|
||||||
|
@ -112,6 +115,9 @@ namespace NBToolkit
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
_chunkFilter.PrintUsage();
|
_chunkFilter.PrintUsage();
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
_blockFilter.PrintUsage();
|
||||||
|
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
base.PrintUsage();
|
base.PrintUsage();
|
||||||
}
|
}
|
||||||
|
@ -121,8 +127,8 @@ namespace NBToolkit
|
||||||
base.SetDefaults();
|
base.SetDefaults();
|
||||||
|
|
||||||
// Check for required parameters
|
// Check for required parameters
|
||||||
if (OPT_BEFORE == null || OPT_AFTER == null) {
|
if (OPT_AFTER == null) {
|
||||||
Console.WriteLine("Error: You must specify a before and after Block ID");
|
Console.WriteLine("Error: You must specify a replacement Block ID");
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
PrintUsage();
|
PrintUsage();
|
||||||
|
|
||||||
|
@ -134,6 +140,11 @@ namespace NBToolkit
|
||||||
{
|
{
|
||||||
return _chunkFilter;
|
return _chunkFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IBlockFilter GetBlockFilter ()
|
||||||
|
{
|
||||||
|
return _blockFilter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Replace : TKFilter
|
public class Replace : TKFilter
|
||||||
|
@ -167,6 +178,8 @@ namespace NBToolkit
|
||||||
|
|
||||||
public void ApplyChunk (INBTWorld world, ChunkRef chunk)
|
public void ApplyChunk (INBTWorld world, ChunkRef chunk)
|
||||||
{
|
{
|
||||||
|
IBlockFilter opt_b = opt.GetBlockFilter();
|
||||||
|
|
||||||
int xBase = chunk.X * chunk.Blocks.XDim;
|
int xBase = chunk.X * chunk.Blocks.XDim;
|
||||||
int zBase = chunk.Z * chunk.Blocks.ZDim;
|
int zBase = chunk.Z * chunk.Blocks.ZDim;
|
||||||
|
|
||||||
|
@ -174,11 +187,11 @@ namespace NBToolkit
|
||||||
int xmin = 0;
|
int xmin = 0;
|
||||||
int xmax = 15;
|
int xmax = 15;
|
||||||
|
|
||||||
if (opt.BL_X_GE != null) {
|
if (opt_b.XAboveEq != null) {
|
||||||
xmin = (int)opt.BL_X_GE - xBase;
|
xmin = (int)opt_b.XAboveEq - xBase;
|
||||||
}
|
}
|
||||||
if (opt.BL_X_LE != null) {
|
if (opt_b.XBelowEq != null) {
|
||||||
xmax = (int)opt.BL_X_LE - xBase;
|
xmax = (int)opt_b.XBelowEq - xBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmin = (xmin < 0) ? 0 : xmin;
|
xmin = (xmin < 0) ? 0 : xmin;
|
||||||
|
@ -192,11 +205,11 @@ namespace NBToolkit
|
||||||
int ymin = 0;
|
int ymin = 0;
|
||||||
int ymax = 127;
|
int ymax = 127;
|
||||||
|
|
||||||
if (opt.BL_Y_GE != null) {
|
if (opt_b.YAboveEq != null) {
|
||||||
ymin = (int)opt.BL_Y_GE;
|
ymin = (int)opt_b.YAboveEq;
|
||||||
}
|
}
|
||||||
if (opt.BL_Y_LE != null) {
|
if (opt_b.YBelowEq != null) {
|
||||||
ymax = (int)opt.BL_Y_LE;
|
ymax = (int)opt_b.YBelowEq;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ymin > ymax) {
|
if (ymin > ymax) {
|
||||||
|
@ -207,11 +220,11 @@ namespace NBToolkit
|
||||||
int zmin = 0;
|
int zmin = 0;
|
||||||
int zmax = 15;
|
int zmax = 15;
|
||||||
|
|
||||||
if (opt.BL_Z_GE != null) {
|
if (opt_b.ZAboveEq != null) {
|
||||||
zmin = (int)opt.BL_Z_GE - zBase;
|
zmin = (int)opt_b.ZAboveEq - zBase;
|
||||||
}
|
}
|
||||||
if (opt.BL_Z_LE != null) {
|
if (opt_b.ZBelowEq != null) {
|
||||||
zmax = (int)opt.BL_Z_LE - zBase;
|
zmax = (int)opt_b.ZBelowEq - zBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
zmin = (zmin < 0) ? 0 : zmin;
|
zmin = (zmin < 0) ? 0 : zmin;
|
||||||
|
@ -221,35 +234,70 @@ namespace NBToolkit
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int xdim = chunk.Blocks.XDim;
|
||||||
|
int ydim = chunk.Blocks.YDim;
|
||||||
|
int zdim = chunk.Blocks.ZDim;
|
||||||
|
|
||||||
// Process Chunk
|
// Process Chunk
|
||||||
for (int y = ymin; y <= ymax; y++) {
|
for (int y = ymin; y <= ymax; y++) {
|
||||||
for (int x = xmin; x <= xmax; x++) {
|
for (int x = xmin; x <= xmax; x++) {
|
||||||
for (int z = zmin; z <= zmax; z++) {
|
for (int z = zmin; z <= zmax; z++) {
|
||||||
// Probability test
|
// Probability test
|
||||||
if (opt.OPT_PROB != null) {
|
if (opt_b.ProbMatch != null) {
|
||||||
double c = rand.NextDouble();
|
double c = rand.NextDouble();
|
||||||
if (c > opt.OPT_PROB) {
|
if (c > opt_b.ProbMatch) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int lx = x & (chunk.Blocks.XDim - 1);
|
int lx = x % xdim;
|
||||||
int ly = y & (chunk.Blocks.YDim - 1);
|
int ly = y % ydim;
|
||||||
int lz = z & (chunk.Blocks.ZDim - 1);
|
int lz = z % zdim;
|
||||||
|
|
||||||
// Attempt to replace block
|
// Get the old block
|
||||||
int oldBlock = chunk.Blocks.GetID(lx , ly, lz);
|
int oldBlock = chunk.Blocks.GetID(lx , ly, lz);
|
||||||
if (oldBlock == opt.OPT_BEFORE) {
|
|
||||||
chunk.Blocks.SetID(lx, ly, lz, (int)opt.OPT_AFTER);
|
|
||||||
|
|
||||||
/*if (opt.OPT_VV) {
|
// Skip block if it doesn't match the inclusion list
|
||||||
Console.WriteLine("Replaced block at {0},{1},{2}",
|
if (opt_b.IncludedBlockCount > 0) {
|
||||||
chunk.BlockGlobalX(lx), chunk.BlockGlobalY(ly), chunk.BlockGlobalZ(lz));
|
bool match = false;
|
||||||
}*/
|
foreach (int ib in opt_b.IncludedBlocks) {
|
||||||
|
if (oldBlock == ib) {
|
||||||
if (opt.OPT_DATA != null) {
|
match = true;
|
||||||
chunk.Blocks.SetData(lx, ly, lz, (int)opt.OPT_DATA);
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip block if it does match the exclusion list
|
||||||
|
if (opt_b.ExcludedBlockCount > 0) {
|
||||||
|
bool match = false;
|
||||||
|
foreach (int xb in opt_b.ExcludedBlocks) {
|
||||||
|
if (oldBlock == xb) {
|
||||||
|
match = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the block
|
||||||
|
chunk.Blocks.SetID(lx, ly, lz, (int)opt.OPT_AFTER);
|
||||||
|
|
||||||
|
if (opt.OPT_VV) {
|
||||||
|
int gx = chunk.X * xdim + lx;
|
||||||
|
int gz = chunk.Z * zdim + lz;
|
||||||
|
Console.WriteLine("Replaced block at {0},{1},{2}", gx, ly, gz);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt.OPT_DATA != null) {
|
||||||
|
chunk.Blocks.SetData(lx, ly, lz, (int)opt.OPT_DATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue