diff --git a/NBToolkit/Makefile b/NBToolkit/Makefile index acba37f..a7c3bab 100644 --- a/NBToolkit/Makefile +++ b/NBToolkit/Makefile @@ -1,4 +1,4 @@ -all: windows +all: linux libnbt.a: gcc -g -I./cnbt -c cnbt/nbt.c -o cnbt/nbt.o @@ -6,7 +6,7 @@ libnbt.a: ar -rcs cnbt/libnbt.a cnbt/nbt.o cnbt/endianness.o windows: libnbt.a - gcc -g oregen.c chunk.c main.c -o oregen.exe -I./cnbt -L./cnbt -lnbt /mingw/lib/libz.a + gcc -g oregen.c replace.c chunk.c main.c -o nbtoolkit.exe -I./cnbt -L./cnbt -lnbt /mingw/lib/libz.a linux: libnbt.a - gcc -g oregen.c chunk.c main.c -o oregen -I./cnbt -L./cnbt -lnbt -lz -lm \ No newline at end of file + gcc -g oregen.c replace. chunk.c main.c -o nbtoolkit -I./cnbt -L./cnbt -lnbt -lz -lm \ No newline at end of file diff --git a/NBToolkit/chunk.c b/NBToolkit/chunk.c index feb9ae8..b7f9781 100644 --- a/NBToolkit/chunk.c +++ b/NBToolkit/chunk.c @@ -182,6 +182,19 @@ void chunk_to_coords (char * str, struct chunk_coords * cc) { cc->y /= 36; } +int scan_byte_array (nbt_byte_array * arr, int value) { + int len = 16 * 16 * 128; + int i, count = 0; + + for (i = 0; i < len; i++) { + if (arr->content[i] == value) { + count++; + } + } + + return count; +} + int update_chunk (char * file, char * name, pf_type pf, struct options * opt, void * pf_opt) { nbt_file *nf; int i; @@ -223,6 +236,58 @@ int update_chunk (char * file, char * name, pf_type pf, struct options * opt, vo gen_ore(arr, dat, ore_id, opt); }*/ + // Check if chunk satisfies required block options + if (opt->set & OPT_INCLUDE) { + struct data_list * node; + nbt_byte_array * arr; + nbt_tag * blocks = nbt_find_tag_by_name("Blocks", nbt_find_tag_by_name("Level", nf->root)); + + assert (blocks != 0); + arr = nbt_cast_byte_array(blocks); + + for (node = opt->includes; node != 0; node = node->next) { + int count = scan_byte_array(arr, node->data); + if (count == 0) { + if (opt->set & OPT_V) { + fprintf(stderr, "Required block %d not found, skipping chunk\n", node->data); + } + nbt_free(nf); + return EXIT_SUCCESS; + } + else { + if (opt->set & OPT_VV) { + fprintf(stderr, "Found %d instances of required block %d\n", count, node->data); + } + } + } + } + + // Check if chunk satisfies forbiddon block options + if (opt->set & OPT_EXCLUDE) { + struct data_list * node; + nbt_byte_array * arr; + nbt_tag * blocks = nbt_find_tag_by_name("Blocks", nbt_find_tag_by_name("Level", nf->root)); + + assert (blocks != 0); + arr = nbt_cast_byte_array(blocks); + + for (node = opt->excludes; node != 0; node = node->next) { + int count = scan_byte_array(arr, node->data); + if (count > 0) { + if (opt->set & OPT_V) { + fprintf(stderr, "Found %d instances of forbiddon block %d, skipping chunk\n", count, node->data); + } + nbt_free(nf); + return EXIT_SUCCESS; + } + else { + if (opt->set & OPT_VV) { + fprintf(stderr, "Found 0 instances of forbiddon block %d\n", node->data); + } + } + } + } + pf(nf, opt, pf_opt); nbt_write(nf, file); diff --git a/NBToolkit/chunk.h b/NBToolkit/chunk.h index 15b013b..e8a36ab 100644 --- a/NBToolkit/chunk.h +++ b/NBToolkit/chunk.h @@ -37,21 +37,32 @@ THE SOFTWARE. #include "cnbt/nbt.h" -#define OPT_C_TIME 0x0001 -#define OPT_M_TIME 0x0002 -#define OPT_ROUNDS 0x0004 -#define OPT_MIN 0x0008 -#define OPT_MAX 0x0010 -#define OPT_SIZE 0x0020 -#define OPT_OV_ORE 0x0040 -#define OPT_OV_ALL 0x0080 -#define OPT_C_AFT 0x0100 -#define OPT_M_AFT 0x0200 -#define OPT_OV_BLK 0x0400 -#define OPT_BBOX 0x0800 -#define OPT_DATA 0x1000 -#define OPT_V 0x2000 -#define OPT_VV 0x4000 +#define OPT_C_TIME 0x000001 +#define OPT_M_TIME 0x000002 +#define OPT_ROUNDS 0x000004 +#define OPT_MIN 0x000008 +#define OPT_MAX 0x000010 +#define OPT_SIZE 0x000020 +#define OPT_OV_ORE 0x000040 +#define OPT_OV_ALL 0x000080 +#define OPT_C_AFT 0x000100 +#define OPT_M_AFT 0x000200 +#define OPT_OV_BLK 0x000400 +#define OPT_BBOX 0x000800 +#define OPT_DATA 0x001000 +#define OPT_V 0x002000 +#define OPT_VV 0x004000 +#define OPT_INCLUDE 0x008000 +#define OPT_EXCLUDE 0x010000 +#define OPT_OV_I 0x020000 +#define OPT_RANDOM 0x040000 + +#define INDEXAT(x,y,z) ((y) + ((z) * 128 + (x) * 128 * 16)) + +struct data_list { + int data; + struct data_list * next; +}; struct options { unsigned long set; @@ -66,6 +77,8 @@ struct options { int x2; int y2; int data; + struct data_list * includes; + struct data_list * excludes; }; struct chunk_coords { diff --git a/NBToolkit/main.c b/NBToolkit/main.c index 55b4cf3..df6dcc1 100644 --- a/NBToolkit/main.c +++ b/NBToolkit/main.c @@ -22,15 +22,29 @@ THE SOFTWARE. */ #include "oregen.h" +#include "replace.h" #include "chunk.h" +// Returns an interior reference to the same object! +const char * basename (const char *path) { + int i; + + for (i = strlen(path); i >= 0; i--) { + if (path[i] == '\\' || path[i] == '/') { + return &path[i+1]; + } + } + + return path; +} + void print_usage (const char *name) { - fprintf(stderr, "Usage: %s [options]\n", name); + fprintf(stderr, "Usage: %s [options]\n", basename(name)); fprintf(stderr, "Available tools:\n"); fprintf(stderr, " oregen : Generate new ore deposits\n"); fprintf(stderr, " replace : Replace one block type with another\n\n"); fprintf(stderr, "Usage and options for 'oregen':\n"); - fprintf(stderr, " %s oregen [options]\n", name); + fprintf(stderr, " %s oregen [options]\n\n", basename(name)); fprintf(stderr, " Ore IDs:\n"); fprintf(stderr, " 16 = Coal, 15 = Iron, 14 = Gold, 73 = Redstone, 56 = Diamond, 21 = Lapis\n"); fprintf(stderr, " Options:\n"); @@ -44,11 +58,11 @@ void print_usage (const char *name) { fprintf(stderr, " -oa : Take precedence over all existing blocks (including air)\n"); fprintf(stderr, " -oi : Take precedence over a specific block type\n\n"); fprintf(stderr, "Usage and options for 'replace':\n"); - fprintf(stderr, " %s replace [options]\n", name); + fprintf(stderr, " %s replace [options]\n\n", basename(name)); fprintf(stderr, " Options:\n"); fprintf(stderr, " -mn : Minimum depth ore is generated (0-127)\n"); fprintf(stderr, " -mx : Maximum depth ore is generated (0-127)\n"); - fprintf(stderr, " -p : Probability that an individual block is replaced (0.0 - 1.0)\n\n"); + fprintf(stderr, " -p : Probability that an individual block is replaced (0.0-1.0)\n"); fprintf(stderr, "Common Options:\n"); /*fprintf(stderr, " -cb