forked from mirrors/NBTExplorer
Added replace tool, added new oregen options
This commit is contained in:
parent
d022fa0abe
commit
0ef9409f99
8 changed files with 451 additions and 106 deletions
|
@ -1,4 +1,4 @@
|
||||||
all: windows
|
all: linux
|
||||||
|
|
||||||
libnbt.a:
|
libnbt.a:
|
||||||
gcc -g -I./cnbt -c cnbt/nbt.c -o cnbt/nbt.o
|
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
|
ar -rcs cnbt/libnbt.a cnbt/nbt.o cnbt/endianness.o
|
||||||
|
|
||||||
windows: libnbt.a
|
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
|
linux: libnbt.a
|
||||||
gcc -g oregen.c chunk.c main.c -o oregen -I./cnbt -L./cnbt -lnbt -lz -lm
|
gcc -g oregen.c replace. chunk.c main.c -o nbtoolkit -I./cnbt -L./cnbt -lnbt -lz -lm
|
|
@ -182,6 +182,19 @@ void chunk_to_coords (char * str, struct chunk_coords * cc) {
|
||||||
cc->y /= 36;
|
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) {
|
int update_chunk (char * file, char * name, pf_type pf, struct options * opt, void * pf_opt) {
|
||||||
nbt_file *nf;
|
nbt_file *nf;
|
||||||
int i;
|
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);
|
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);
|
pf(nf, opt, pf_opt);
|
||||||
|
|
||||||
nbt_write(nf, file);
|
nbt_write(nf, file);
|
||||||
|
|
|
@ -37,21 +37,32 @@ THE SOFTWARE.
|
||||||
|
|
||||||
#include "cnbt/nbt.h"
|
#include "cnbt/nbt.h"
|
||||||
|
|
||||||
#define OPT_C_TIME 0x0001
|
#define OPT_C_TIME 0x000001
|
||||||
#define OPT_M_TIME 0x0002
|
#define OPT_M_TIME 0x000002
|
||||||
#define OPT_ROUNDS 0x0004
|
#define OPT_ROUNDS 0x000004
|
||||||
#define OPT_MIN 0x0008
|
#define OPT_MIN 0x000008
|
||||||
#define OPT_MAX 0x0010
|
#define OPT_MAX 0x000010
|
||||||
#define OPT_SIZE 0x0020
|
#define OPT_SIZE 0x000020
|
||||||
#define OPT_OV_ORE 0x0040
|
#define OPT_OV_ORE 0x000040
|
||||||
#define OPT_OV_ALL 0x0080
|
#define OPT_OV_ALL 0x000080
|
||||||
#define OPT_C_AFT 0x0100
|
#define OPT_C_AFT 0x000100
|
||||||
#define OPT_M_AFT 0x0200
|
#define OPT_M_AFT 0x000200
|
||||||
#define OPT_OV_BLK 0x0400
|
#define OPT_OV_BLK 0x000400
|
||||||
#define OPT_BBOX 0x0800
|
#define OPT_BBOX 0x000800
|
||||||
#define OPT_DATA 0x1000
|
#define OPT_DATA 0x001000
|
||||||
#define OPT_V 0x2000
|
#define OPT_V 0x002000
|
||||||
#define OPT_VV 0x4000
|
#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 {
|
struct options {
|
||||||
unsigned long set;
|
unsigned long set;
|
||||||
|
@ -66,6 +77,8 @@ struct options {
|
||||||
int x2;
|
int x2;
|
||||||
int y2;
|
int y2;
|
||||||
int data;
|
int data;
|
||||||
|
struct data_list * includes;
|
||||||
|
struct data_list * excludes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chunk_coords {
|
struct chunk_coords {
|
||||||
|
|
282
NBToolkit/main.c
282
NBToolkit/main.c
|
@ -22,15 +22,29 @@ THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "oregen.h"
|
#include "oregen.h"
|
||||||
|
#include "replace.h"
|
||||||
#include "chunk.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) {
|
void print_usage (const char *name) {
|
||||||
fprintf(stderr, "Usage: %s <world dir> <tool> <ore_id> [options]\n", name);
|
fprintf(stderr, "Usage: %s <world dir> <tool> <ore_id> [options]\n", basename(name));
|
||||||
fprintf(stderr, "Available tools:\n");
|
fprintf(stderr, "Available tools:\n");
|
||||||
fprintf(stderr, " oregen : Generate new ore deposits\n");
|
fprintf(stderr, " oregen : Generate new ore deposits\n");
|
||||||
fprintf(stderr, " replace : Replace one block type with another\n\n");
|
fprintf(stderr, " replace : Replace one block type with another\n\n");
|
||||||
fprintf(stderr, "Usage and options for 'oregen':\n");
|
fprintf(stderr, "Usage and options for 'oregen':\n");
|
||||||
fprintf(stderr, " %s <world_dir> oregen <ore_id> [options]\n", name);
|
fprintf(stderr, " %s <world_dir> oregen <ore_id> [options]\n\n", basename(name));
|
||||||
fprintf(stderr, " Ore IDs:\n");
|
fprintf(stderr, " Ore IDs:\n");
|
||||||
fprintf(stderr, " 16 = Coal, 15 = Iron, 14 = Gold, 73 = Redstone, 56 = Diamond, 21 = Lapis\n");
|
fprintf(stderr, " 16 = Coal, 15 = Iron, 14 = Gold, 73 = Redstone, 56 = Diamond, 21 = Lapis\n");
|
||||||
fprintf(stderr, " Options:\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, " -oa : Take precedence over all existing blocks (including air)\n");
|
||||||
fprintf(stderr, " -oi <id> : Take precedence over a specific block type\n\n");
|
fprintf(stderr, " -oi <id> : Take precedence over a specific block type\n\n");
|
||||||
fprintf(stderr, "Usage and options for 'replace':\n");
|
fprintf(stderr, "Usage and options for 'replace':\n");
|
||||||
fprintf(stderr, " %s <world_dir> replace <block_id_1> <block_id_2> [options]\n", name);
|
fprintf(stderr, " %s <world_dir> replace <block_id_1> <block_id_2> [options]\n\n", basename(name));
|
||||||
fprintf(stderr, " Options:\n");
|
fprintf(stderr, " Options:\n");
|
||||||
fprintf(stderr, " -mn <num> : Minimum depth ore is generated (0-127)\n");
|
fprintf(stderr, " -mn <num> : Minimum depth ore is generated (0-127)\n");
|
||||||
fprintf(stderr, " -mx <num> : Maximum depth ore is generated (0-127)\n");
|
fprintf(stderr, " -mx <num> : Maximum depth ore is generated (0-127)\n");
|
||||||
fprintf(stderr, " -p <num> : Probability that an individual block is replaced (0.0 - 1.0)\n\n");
|
fprintf(stderr, " -p <num> : Probability that an individual block is replaced (0.0-1.0)\n");
|
||||||
fprintf(stderr, "Common Options:\n");
|
fprintf(stderr, "Common Options:\n");
|
||||||
/*fprintf(stderr, " -cb <time> : Only update chunks created before time (as unix timestamp)\n");
|
/*fprintf(stderr, " -cb <time> : Only update chunks created before time (as unix timestamp)\n");
|
||||||
fprintf(stderr, " -ca <time> : Only update chunks created after time (as unix timestamp)\n");*/
|
fprintf(stderr, " -ca <time> : Only update chunks created after time (as unix timestamp)\n");*/
|
||||||
|
@ -64,14 +78,102 @@ void print_usage (const char *name) {
|
||||||
fprintf(stderr, " -vv : Very verbose output\n");
|
fprintf(stderr, " -vv : Very verbose output\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_options (int argc, char **argv, struct options *opt, struct options_gen_ore * ore_opt) {
|
void parse_options (int argc, char **argv, struct options *opt) {
|
||||||
int i;
|
int i;
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
|
opt->includes = 0;
|
||||||
|
opt->excludes = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
if (strcmp(argv[i], "-cb") == 0) {
|
||||||
|
opt->set |= OPT_C_TIME;
|
||||||
|
sscanf(argv[i+1], "%lu", &opt->c_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[i], "-ca") == 0) {
|
||||||
|
opt->set |= OPT_C_TIME;
|
||||||
|
opt->set |= OPT_C_AFT;
|
||||||
|
sscanf(argv[i+1], "%lu", &opt->c_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[i], "-mb") == 0) {
|
||||||
|
opt->set |= OPT_M_TIME;
|
||||||
|
sscanf(argv[i+1], "%lu", &opt->m_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[i], "-ma") == 0) {
|
||||||
|
opt->set |= OPT_M_TIME;
|
||||||
|
opt->set |= OPT_M_AFT;
|
||||||
|
sscanf(argv[i+1], "%lu", &opt->m_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[i], "-bb") == 0) {
|
||||||
|
opt->set |= OPT_BBOX;
|
||||||
|
sscanf(argv[i+1], "%d", &opt->x1);
|
||||||
|
sscanf(argv[i+2], "%d", &opt->y1);
|
||||||
|
sscanf(argv[i+3], "%d", &opt->x2);
|
||||||
|
sscanf(argv[i+4], "%d", &opt->y2);
|
||||||
|
|
||||||
|
if (opt->x1 > opt->x2) {
|
||||||
|
t = opt->x1;
|
||||||
|
opt->x1 = opt->x2;
|
||||||
|
opt->x2 = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt->y1 > opt->y2) {
|
||||||
|
t = opt->y1;
|
||||||
|
opt->y1 = opt->y2;
|
||||||
|
opt->y2 = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[i], "-v") == 0) {
|
||||||
|
opt->set |= OPT_V;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[i], "-vv") == 0) {
|
||||||
|
opt->set |= OPT_V;
|
||||||
|
opt->set |= OPT_VV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[i], "-e") == 0) {
|
||||||
|
struct data_list * node = (struct data_list *)malloc(sizeof(struct data_list));
|
||||||
|
sscanf(argv[i+1], "%d", &node->data);
|
||||||
|
if (opt->set & OPT_INCLUDE) {
|
||||||
|
node->next = opt->includes;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
opt->set |= OPT_INCLUDE;
|
||||||
|
node->next = 0;
|
||||||
|
}
|
||||||
|
opt->includes = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[i], "-ne") == 0) {
|
||||||
|
struct data_list * node = (struct data_list *)malloc(sizeof(struct data_list));
|
||||||
|
sscanf(argv[i+1], "%d", &node->data);
|
||||||
|
if (opt->set & OPT_EXCLUDE) {
|
||||||
|
node->next = opt->excludes;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
opt->set |= OPT_EXCLUDE;
|
||||||
|
node->next = 0;
|
||||||
|
}
|
||||||
|
opt->excludes = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void parse_oregen_options (int argc, char **argv, struct options_gen_ore * ore_opt) {
|
||||||
|
int i;
|
||||||
|
int t;
|
||||||
|
|
||||||
ore_opt->rounds = 0;
|
ore_opt->rounds = 0;
|
||||||
ore_opt->min_depth = 0;
|
ore_opt->min_depth = 0;
|
||||||
ore_opt->max_depth = 0;
|
ore_opt->max_depth = 0;
|
||||||
ore_opt->size = 0;
|
ore_opt->size = 0;
|
||||||
|
ore_opt->override = 0;
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
if (strcmp(argv[i], "-r") == 0) {
|
if (strcmp(argv[i], "-r") == 0) {
|
||||||
|
@ -97,28 +199,6 @@ void parse_options (int argc, char **argv, struct options *opt, struct options_g
|
||||||
ore_opt->size %= 64;
|
ore_opt->size %= 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[i], "-cb") == 0) {
|
|
||||||
opt->set |= OPT_C_TIME;
|
|
||||||
sscanf(argv[i+1], "%ud", &opt->c_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(argv[i], "-ca") == 0) {
|
|
||||||
opt->set |= OPT_C_TIME;
|
|
||||||
opt->set |= OPT_C_AFT;
|
|
||||||
sscanf(argv[i+1], "%ud", &opt->c_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(argv[i], "-mb") == 0) {
|
|
||||||
opt->set |= OPT_M_TIME;
|
|
||||||
sscanf(argv[i+1], "%ud", &opt->m_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(argv[i], "-ma") == 0) {
|
|
||||||
opt->set |= OPT_M_TIME;
|
|
||||||
opt->set |= OPT_M_AFT;
|
|
||||||
sscanf(argv[i+1], "%ud", &opt->m_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(argv[i], "-oo") == 0) {
|
if (strcmp(argv[i], "-oo") == 0) {
|
||||||
ore_opt->set |= OPT_OV_ORE;
|
ore_opt->set |= OPT_OV_ORE;
|
||||||
}
|
}
|
||||||
|
@ -131,24 +211,17 @@ void parse_options (int argc, char **argv, struct options *opt, struct options_g
|
||||||
ore_opt->set |= OPT_OV_BLK;
|
ore_opt->set |= OPT_OV_BLK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[i], "-bb") == 0) {
|
if (strcmp(argv[i], "-oi") == 0) {
|
||||||
opt->set |= OPT_BBOX;
|
struct data_list * node = (struct data_list *)malloc(sizeof(struct data_list));
|
||||||
sscanf(argv[i+1], "%d", &opt->x1);
|
sscanf(argv[i+1], "%d", &node->data);
|
||||||
sscanf(argv[i+2], "%d", &opt->y1);
|
if (ore_opt->set & OPT_OV_I) {
|
||||||
sscanf(argv[i+3], "%d", &opt->x2);
|
node->next = ore_opt->override;
|
||||||
sscanf(argv[i+4], "%d", &opt->y2);
|
|
||||||
|
|
||||||
if (opt->x1 > opt->x2) {
|
|
||||||
t = opt->x1;
|
|
||||||
opt->x1 = opt->x2;
|
|
||||||
opt->x2 = t;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if (opt->y1 > opt->y2) {
|
ore_opt->set |= OPT_OV_I;
|
||||||
t = opt->y1;
|
node->next = 0;
|
||||||
opt->y1 = opt->y2;
|
|
||||||
opt->y2 = t;
|
|
||||||
}
|
}
|
||||||
|
ore_opt->override = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[i], "-d") == 0) {
|
if (strcmp(argv[i], "-d") == 0) {
|
||||||
|
@ -156,14 +229,37 @@ void parse_options (int argc, char **argv, struct options *opt, struct options_g
|
||||||
sscanf(argv[i+1], "%d", &ore_opt->data);
|
sscanf(argv[i+1], "%d", &ore_opt->data);
|
||||||
ore_opt->data %= 16;
|
ore_opt->data %= 16;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (strcmp(argv[i], "-v") == 0) {
|
}
|
||||||
opt->set |= OPT_V;
|
|
||||||
|
void parse_replace_options (int argc, char **argv, struct options_replace * opt) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
opt->min_depth = 0;
|
||||||
|
opt->max_depth = 127;
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
if (strcmp(argv[i], "-mn") == 0) {
|
||||||
|
opt->set |= OPT_MIN;
|
||||||
|
sscanf(argv[i+1], "%d", &opt->min_depth);
|
||||||
|
opt->min_depth %= 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[i], "-vv") == 0) {
|
if (strcmp(argv[i], "-mx") == 0) {
|
||||||
opt->set |= OPT_V;
|
opt->set |= OPT_MAX;
|
||||||
opt->set |= OPT_VV;
|
sscanf(argv[i+1], "%d", &opt->max_depth);
|
||||||
|
opt->max_depth %= 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[i], "-d") == 0) {
|
||||||
|
opt->set |= OPT_DATA;
|
||||||
|
sscanf(argv[i+1], "%d", &opt->data);
|
||||||
|
opt->data %= 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[i], "-p") == 0) {
|
||||||
|
opt->set |= OPT_RANDOM;
|
||||||
|
sscanf(argv[i+1], "%f", &opt->p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,9 +268,11 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct options opt;
|
struct options opt;
|
||||||
struct options_gen_ore ore_opt;
|
struct options_gen_ore ore_opt;
|
||||||
|
struct options_replace rep_opt;
|
||||||
|
|
||||||
opt.set = 0;
|
opt.set = 0;
|
||||||
ore_opt.set = 0;
|
ore_opt.set = 0;
|
||||||
|
rep_opt.set = 0;
|
||||||
|
|
||||||
/* argv[1] == chunk file
|
/* argv[1] == chunk file
|
||||||
* argv[2] == ore id
|
* argv[2] == ore id
|
||||||
|
@ -184,6 +282,8 @@ int main(int argc, char **argv)
|
||||||
int ore_id = -1; /* No valid minecraft ID */
|
int ore_id = -1; /* No valid minecraft ID */
|
||||||
|
|
||||||
srand ( time(NULL) );
|
srand ( time(NULL) );
|
||||||
|
|
||||||
|
parse_options(argc, argv, &opt);
|
||||||
|
|
||||||
/* Validate arguments */
|
/* Validate arguments */
|
||||||
if ((argc < 3))
|
if ((argc < 3))
|
||||||
|
@ -194,38 +294,62 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Parse the parameters */
|
char command[256];
|
||||||
if (sscanf(argv[2], "%d", &ore_id))
|
sscanf(argv[1], "%s", &command);
|
||||||
{
|
|
||||||
ore_id %= 256; /* Make sure it's 8-bit sized */
|
if (strcmp(command, "oregen") == 0) {
|
||||||
ore_opt.ore_id = ore_id;
|
/* Parse the parameters */
|
||||||
}
|
if (sscanf(argv[3], "%d", &ore_id))
|
||||||
else
|
{
|
||||||
{
|
ore_id %= 256; /* Make sure it's 8-bit sized */
|
||||||
fprintf(stderr, "Ore ID has to be a number\n");
|
ore_opt.ore_id = ore_id;
|
||||||
|
}
|
||||||
return EXIT_FAILURE;
|
else
|
||||||
}
|
{
|
||||||
|
fprintf(stderr, "Ore ID has to be a number\n");
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
parse_options(argc, argv, &opt, &ore_opt);
|
parse_oregen_options(argc, argv, &ore_opt);
|
||||||
|
|
||||||
for (i = 0; i < ORE_COUNT; i++) {
|
for (i = 0; i < ORE_COUNT; i++) {
|
||||||
if (ore_list[i].block_id == ore_id) {
|
if (ore_list[i].block_id == ore_id) {
|
||||||
if (!(ore_opt.set & OPT_ROUNDS)) {
|
if (!(ore_opt.set & OPT_ROUNDS)) {
|
||||||
ore_opt.rounds = ore_list[i].rounds;
|
ore_opt.rounds = ore_list[i].rounds;
|
||||||
}
|
}
|
||||||
if (!(ore_opt.set & OPT_MIN)) {
|
if (!(ore_opt.set & OPT_MIN)) {
|
||||||
ore_opt.min_depth = ore_list[i].min_depth;
|
ore_opt.min_depth = ore_list[i].min_depth;
|
||||||
}
|
}
|
||||||
if (!(ore_opt.set & OPT_MAX)) {
|
if (!(ore_opt.set & OPT_MAX)) {
|
||||||
ore_opt.max_depth = ore_list[i].max_depth;
|
ore_opt.max_depth = ore_list[i].max_depth;
|
||||||
}
|
}
|
||||||
if (!(ore_opt.set & OPT_SIZE)) {
|
if (!(ore_opt.set & OPT_SIZE)) {
|
||||||
ore_opt.size = ore_list[i].size;
|
ore_opt.size = ore_list[i].size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return update_all_chunks(argv[1], pf_gen_ore, &opt, &ore_opt);
|
return update_all_chunks(argv[2], pf_gen_ore, &opt, &ore_opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (strcmp(command, "replace") == 0) {
|
||||||
|
/* Parse the parameters */
|
||||||
|
if (sscanf(argv[3], "%d", &rep_opt.old_id) && sscanf(argv[4], "%d", &rep_opt.new_id))
|
||||||
|
{
|
||||||
|
rep_opt.old_id %= 256; /* Make sure it's 8-bit sized */
|
||||||
|
rep_opt.new_id %= 256;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Block ID has to be a number\n");
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_replace_options(argc, argv, &rep_opt);
|
||||||
|
|
||||||
|
return update_all_chunks(argv[2], pf_replace, &opt, &rep_opt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,12 +24,12 @@ THE SOFTWARE.
|
||||||
#include "oregen.h"
|
#include "oregen.h"
|
||||||
|
|
||||||
const struct ore_record ore_list[] = {
|
const struct ore_record ore_list[] = {
|
||||||
{ "Coal", BLOCK_COAL, 20, 0, 128, 16 },
|
{ "Coal", BLOCK_COAL, 20, 0, 127, 16 },
|
||||||
{ "Iron", BLOCK_IRON, 20, 0, 64, 8 },
|
{ "Iron", BLOCK_IRON, 20, 0, 63, 8 },
|
||||||
{ "Gold", BLOCK_GOLD, 2, 0, 32, 8 },
|
{ "Gold", BLOCK_GOLD, 2, 0, 31, 8 },
|
||||||
{ "Redstone", BLOCK_REDSTONE, 8, 0, 16, 7 },
|
{ "Redstone", BLOCK_REDSTONE, 8, 0, 15, 7 },
|
||||||
{ "Diamond", BLOCK_DIAMOND, 1, 0, 16, 7 },
|
{ "Diamond", BLOCK_DIAMOND, 1, 0, 15, 7 },
|
||||||
{ "Lapis", BLOCK_LAPIS, 1, 0, 32, 7 },
|
{ "Lapis", BLOCK_LAPIS, 1, 0, 31, 7 },
|
||||||
};
|
};
|
||||||
|
|
||||||
void update_block (nbt_byte_array *arr, nbt_byte_array *dat, int x, int y, int z, short ore_id, struct options *opt, struct options_gen_ore * ore_opt) {
|
void update_block (nbt_byte_array *arr, nbt_byte_array *dat, int x, int y, int z, short ore_id, struct options *opt, struct options_gen_ore * ore_opt) {
|
||||||
|
@ -46,8 +46,23 @@ void update_block (nbt_byte_array *arr, nbt_byte_array *dat, int x, int y, int z
|
||||||
arr->content[index] == BLOCK_DIAMOND || arr->content[index] == BLOCK_LAPIS ||
|
arr->content[index] == BLOCK_DIAMOND || arr->content[index] == BLOCK_LAPIS ||
|
||||||
arr->content[index] == BLOCK_DIRT || arr->content[index] == BLOCK_GRAVEL) && (arr->content[index] != ore_opt->ore_id)) ||
|
arr->content[index] == BLOCK_DIRT || arr->content[index] == BLOCK_GRAVEL) && (arr->content[index] != ore_opt->ore_id)) ||
|
||||||
((ore_opt->set & OPT_OV_BLK) && (arr->content[index] != BLOCK_AIR) && (arr->content[index] != ore_opt->ore_id)) ||
|
((ore_opt->set & OPT_OV_BLK) && (arr->content[index] != BLOCK_AIR) && (arr->content[index] != ore_opt->ore_id)) ||
|
||||||
|
(ore_opt->set & OPT_OV_I) ||
|
||||||
(arr->content[index] == BLOCK_STONE)
|
(arr->content[index] == BLOCK_STONE)
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
// If overriding list of ores, check membership
|
||||||
|
if (ore_opt->set & OPT_OV_I) {
|
||||||
|
struct data_list * node;
|
||||||
|
for (node = ore_opt->override; node != 0; node = node->next) {
|
||||||
|
if (arr->content[index] == node->data) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (node->next == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
arr->content[index] = ore_opt->ore_id;
|
arr->content[index] = ore_opt->ore_id;
|
||||||
|
|
||||||
if (opt->set & OPT_VV) {
|
if (opt->set & OPT_VV) {
|
||||||
|
|
|
@ -38,8 +38,6 @@ THE SOFTWARE.
|
||||||
#include "cnbt/nbt.h"
|
#include "cnbt/nbt.h"
|
||||||
#include "chunk.h"
|
#include "chunk.h"
|
||||||
|
|
||||||
#define INDEXAT(x,y,z) ((y) + ((z) * 128 + (x) * 128 * 16))
|
|
||||||
|
|
||||||
#define BLOCK_AIR 0
|
#define BLOCK_AIR 0
|
||||||
#define BLOCK_STONE 1
|
#define BLOCK_STONE 1
|
||||||
#define BLOCK_DIRT 3
|
#define BLOCK_DIRT 3
|
||||||
|
@ -68,11 +66,12 @@ struct options_gen_ore {
|
||||||
int max_depth;
|
int max_depth;
|
||||||
int size;
|
int size;
|
||||||
int data;
|
int data;
|
||||||
|
struct data_list * override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ORE_COUNT 6
|
#define ORE_COUNT 6
|
||||||
|
|
||||||
const struct ore_record ore_list[ORE_COUNT];
|
extern const struct ore_record ore_list[ORE_COUNT];
|
||||||
|
|
||||||
/* Attempt to update single block in chunk */
|
/* Attempt to update single block in chunk */
|
||||||
void update_block (nbt_byte_array *arr, nbt_byte_array *dat, int x, int y, int z, short ore_id, struct options *opt, struct options_gen_ore * ore_opt);
|
void update_block (nbt_byte_array *arr, nbt_byte_array *dat, int x, int y, int z, short ore_id, struct options *opt, struct options_gen_ore * ore_opt);
|
||||||
|
|
74
NBToolkit/replace.c
Normal file
74
NBToolkit/replace.c
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/* OreGen - MineCraft Ore Generator */
|
||||||
|
/*
|
||||||
|
Copyright (C) 2011 by Justin Aquadro
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "replace.h"
|
||||||
|
|
||||||
|
int pf_replace (nbt_file * nf, struct options * opt, void * pf_opt) {
|
||||||
|
int x, y, z;
|
||||||
|
struct options_replace * rep_opt = (struct options_replace *)pf_opt;
|
||||||
|
|
||||||
|
nbt_byte_array *arr;
|
||||||
|
nbt_byte_array *dat;
|
||||||
|
nbt_tag *blocks = nbt_find_tag_by_name("Blocks", nbt_find_tag_by_name("Level", nf->root));
|
||||||
|
nbt_tag *data = nbt_find_tag_by_name("Data", nbt_find_tag_by_name("Level", nf->root));
|
||||||
|
|
||||||
|
/* 'blocks' cannot be NULL as we already confirmed a valid file */
|
||||||
|
assert(blocks != NULL);
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
arr = nbt_cast_byte_array(blocks);
|
||||||
|
dat = nbt_cast_byte_array(data);
|
||||||
|
|
||||||
|
for (y = rep_opt->min_depth; y <= rep_opt->max_depth; y++) {
|
||||||
|
for (x = 0; x < 16; x++) {
|
||||||
|
for (z = 0; z < 16; z++) {
|
||||||
|
if (rep_opt->set & OPT_RANDOM) {
|
||||||
|
float c = (rand() % 1000) / 1000.0;
|
||||||
|
if (c > rep_opt->p) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = INDEXAT(x, y, z);
|
||||||
|
if (arr->content[index] == rep_opt->old_id) {
|
||||||
|
arr->content[index] = rep_opt->new_id;
|
||||||
|
|
||||||
|
if (opt->set & OPT_VV) {
|
||||||
|
fprintf(stderr, "Replaced block at %d,%d,%d\n", x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rep_opt->set & OPT_DATA) {
|
||||||
|
if (index % 2 == 0) {
|
||||||
|
dat->content[index / 2] = (dat->content[index / 2] & 0xF0) | rep_opt->data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dat->content[index / 2] = (dat->content[index / 2] & 0x0F) | (rep_opt->data << 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
55
NBToolkit/replace.h
Normal file
55
NBToolkit/replace.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/* OreGen - MineCraft Ore Generator */
|
||||||
|
/*
|
||||||
|
Copyright (C) 2011 by Justin Aquadro
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REPLACE_H_
|
||||||
|
#define REPLACE_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "cnbt/nbt.h"
|
||||||
|
#include "chunk.h"
|
||||||
|
|
||||||
|
struct options_replace {
|
||||||
|
unsigned long set;
|
||||||
|
int old_id;
|
||||||
|
int new_id;
|
||||||
|
int min_depth;
|
||||||
|
int max_depth;
|
||||||
|
int data;
|
||||||
|
float p;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Callback function to chunk API */
|
||||||
|
int pf_replace (nbt_file * nf, struct options * opt, void * pf_opt);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue