#include <iostream>
#include <strstream>
#include <string>
#include <iomanip>
#include <algorithm>
#include <fstream>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include "../src/sectors.h"
#include "../src/colors.h"
#include "commands.h"
#define VERSION "1.3"
#define MIL 256
#define MSL 4608
#define MAX_ROOMS 150001
#define DIR_NORTH 0
#define DIR_EAST 1
#define DIR_SOUTH 2
#define DIR_WEST 3
#define DIR_NE 4
#define DIR_NW 5
#define DIR_SE 6
#define DIR_SW 7
#define LOWER(c) ((c) >= 'A' && (c) <= 'Z' ? (c)+'a'-'A' : (c))
#define MAPSIZE 35
#define ROOM_NOWALK 0
#define ROOM_NOFLY 1
#define ROOM_WATER 2
#define MAX_ROOM_FLAGS 3
void cprintf args((const string str));
int get_max_sectors args(());
string header args((const string str, const bool center = false));
string f_str_box args((const string str, const bool line_t = true, const bool line_b = true, const string c_box = "{0"));
void split args((string &args, string &arg));
bool find args((const string str1, const string str2, const bool case_ = false));
struct {
string name;
long room;
bool viewCeiling;
} ch;
struct {
string name, filename, author, version;
int width, height, grav;
bool town, wrap, weather, solo;
} map;
struct {
int x, y;
short sector, ceiling;
bool flags[MAX_ROOM_FLAGS];
unsigned long to[2], up[2], down[2];
} room[MAX_ROOMS];
int max_sectors;
main() {
string input, command;
bool found, running = false;
max_sectors = get_max_sectors();
cprintf(header("DRAGONBALL Z MUD Map Editor v" + (string)VERSION));
cprintf(f_str_box("Email finished maps and suggestions to damdai@hotmail.com. Type '?' for a complete list of commands.", false));
cout << "Name: ";
cin >> ch.name;
char buf[256];
while(1) {
found = false;
if(!running) {
cin.getline(buf, 256);
running = true;
continue;
}
printf("mapeditor> ");
cin.getline(buf, 256);
input = buf + '\0';
split(input, command);
if(command[0] == '\0')
continue;
for(short x = 1; cmd_table[x].cmd; ++x) {
if(find(command, cmd_table[x].cmd)) {
found = true;
(*cmd_table[x].function)(input);
break;
}
}
if(!found)
cout << command << ": ERROR: Command not found. Type '?' for a list of commands.\n";
}
exit(0);
return 0;
}
string colour(const char type) {
switch(type) {
default:
case 'x':
case '0': return CLEAR;
case 'b':
case '4': return C_BLUE;
case 'c':
case '6': return C_CYAN;
case 'g':
case '2': return C_GREEN;
case 'm':
case '5': return C_MAGENTA;
case 'r':
case '1': return C_RED;
case 'w':
case '7': return C_WHITE;
case 'y':
case '3': return C_YELLOW;
case 'B':
case '$': return C_B_BLUE;
case 'C':
case '^': return C_B_CYAN;
case 'G':
case '@': return C_B_GREEN;
case 'M':
case '%': return C_B_MAGENTA;
case 'R':
case '!': return C_B_RED;
case 'W':
case '&': return C_B_WHITE;
case 'Y':
case '#': return C_B_YELLOW;
case 'D':
case '8': return C_D_GREY;
case '{': return "{";
}
}
void cprintf(const string str) {
string new_str = str;
string::size_type pos;
while((pos = new_str.find('{')) != string::npos)
new_str.replace(pos, 2, colour(new_str[pos + 1]));
cout << new_str;
return;
}
void split(string &args, string &arg) {
if(args.empty())
return;
args.erase(0, args.find_first_not_of(' '));
string::size_type pos;
if(args[0] == '"') {
if((pos = args.find('"', 1)) != string::npos) {
arg = args.substr(0, pos);
args.erase(0, pos + 1);
return;
}
}
if((pos = args.find(' ')) == string::npos) {
arg = args;
args = "";
return;
}
arg = args.substr(0, pos);
args.erase(0, pos + 1);
return;
}
bool find(const string str1, const string str2, const bool case_ = false) {
string str_temp = str2, str = str1;
string::size_type pos;
if(!case_) {
transform(str.begin(), str.end(), str.begin(), tolower);
transform(str_temp.begin(), str_temp.end(), str_temp.begin(), tolower);
}
if((pos = str_temp.find(str, 0)) != string::npos && (!pos || str_temp[pos - 1] == ' '))
return true;
return false;
}
bool is_num(const string str) {
if(str.empty())
return false;
for(unsigned short x = 0; x < str.length(); ++x)
if(!isdigit(str[x]))
return false;
return true;
}
int strLen(const string str) {
unsigned int len = 0, x;
for(x = 0; x < str.length(); ++x) {
if(str[x] == '{')
++x;
else
++len;
}
return len;
}
string header(const string str, const bool center = false) {
ostrstream ost;
if(!center)
ost << "+-{#" << str << "{0" << setfill('-') << setw((70 - str.length())) << "-" << CLEAR;
else {
ost << "+";
short len = (70 - strLen(str)) / 2;
for(short x = 0; x < len; ++x)
ost << "-";
ost << C_B_YELLOW << str << CLEAR;
for(short x = 0; x < len; ++x)
ost << "-";
if(len % 2 == 0)
ost << "-";
}
ost << "+\n\r" << ends;
return ost.str();
}
string f_str_box(const string str, const bool line_t = true, const bool line_b = true, const string c_box = "{0") {
ostrstream ost;
string str_temp = str, str_temp2, color;
string::size_type pos;
short cnt;
if(line_t)
ost << c_box << '+' << setfill('-') << setw(71) << "-" << "+\n\r";
ost.fill(' ');
while(!str_temp.empty()) {
if(str_temp.length() > 69) {
str_temp2 = str_temp.substr(0, 69);
str_temp2 = str_temp2.substr(0, str_temp2.rfind(' '));
str_temp.erase(0, str_temp2.length() + 1);
}
else {
str_temp2 = str_temp;
str_temp.erase(str_temp.begin(), str_temp.end());
}
cnt = 0;
pos = 0;
while((pos = str_temp2.find('{', pos + 1)) != string::npos)
cnt += 2;
if(str_temp2[0] == '{')
cnt += 2;
if(!color.empty())
ost << "| " << color << setiosflags(ios::left) << setw(69 + cnt) << str_temp2.c_str() << " {0|\n\r";
else
ost << "| " << setiosflags(ios::left) << setw(69 + cnt) << str_temp2.c_str() << " {0|\n\r";
if((pos = str_temp2.rfind('{')) != string::npos && str_temp2[pos + 1] != '0')
color = str_temp2.substr(pos, 2);
else
color = "";
}
if(line_b)
ost << c_box << '+' << setfill('-') << setw(71) << "-" << "+\n\r{0";
ost << ends;
return ost.str();
}
long number_mm() {
return random() >> 6;
}
int number_percent() {
int percent;
while((percent = number_mm() & (128-1)) > 99)
;
return 1 + percent;
}
long map_room(const long fvnum, const short door) {
long tvnum = 0, size = map.width * map.height;
if(door == DIR_NORTH) tvnum = fvnum - map.width;
else if(door == DIR_SOUTH) tvnum = fvnum + map.width;
else if(door == DIR_EAST) tvnum = fvnum + 1;
else if(door == DIR_WEST) tvnum = fvnum - 1;
if(tvnum > size)
tvnum -= size;
else if(tvnum < 1)
tvnum += size;
return tvnum;
}
string print_sector(const long croom, const bool color) {
if(room[croom].ceiling) {
if(room[ch.room].ceiling && !ch.viewCeiling)
return sector_table[room[croom].sector].print;
else
return sector_table[room[croom].ceiling].print;
}
string str_sector = sector_table[room[croom].sector].print;
return (color ? str_sector : str_sector.substr(2, 2));
}
void print_map() {
short x, y, width = map.width < MAPSIZE ? map.width : MAPSIZE, height = map.height < MAPSIZE ? map.height : MAPSIZE;
long croom = ch.room, lroom;
ostrstream ost;
bool beginning = true, blank, was_blank = false;
cout << "AUTHOR: " << map.author << " / MAP: " << map.name << " (" << map.filename << ".area) / SIZE: " << map.width * map.height << endl;
cout << "TOWN: " << map.town << " / GRAVITY: " << map.grav << " / WRAP: " << map.wrap << " / WEATHER: " << map.weather << " / SOLO: " << map.solo << endl;
for(y = 1; y <= height / 2; ++y)
croom = map_room(croom, DIR_NORTH);
for(x = 1; x <= width / 2; ++x)
croom = map_room(croom, DIR_WEST);
for(y = 1; y <= height; ++y) {
for(x = 1; x <= width; ++x) {
blank = false;
if((abs)(room[croom].x - room[ch.room].x) > width / 2 || (abs)(room[croom].y - room[ch.room].y) > height / 2) {
ost << " ";
blank = true;
}
else if(ch.room == croom)
ost << "{0X ";
else
ost << print_sector(croom, (beginning || croom - 1 == ch.room || was_blank || (lroom && room[croom].sector != room[lroom].sector) || (lroom && room[croom].ceiling != room[lroom].ceiling) ? true : false));
was_blank = blank;
lroom = croom;
croom = map_room(croom, DIR_EAST);
beginning = false;
}
ost << endl;
croom = map_room(croom, DIR_SOUTH);
for(x = 1; x <= width; ++x)
croom = map_room(croom, DIR_WEST);
beginning = true;
}
ost << CLEAR << ends;
cprintf(ost.str());
cout << "LOCATION: " << ch.room << " (" << room[ch.room].x << ", " << room[ch.room].y << ") / SECTOR: " << room[ch.room].sector << " / WIDTH: " << map.width << " / HEIGHT " << map.height << endl;
cout << "NOWALK: " << room[ch.room].flags[ROOM_NOWALK] << " / NOFLY: " << room[ch.room].flags[ROOM_NOFLY] << " / WATER: " << room[ch.room].flags[ROOM_WATER] << " / CEILING: " << room[ch.room].ceiling << endl;
cout << "TO: " << room[ch.room].to[0] << " " << room[ch.room].to[1] << " / UP: " << room[ch.room].up[0] << " " << room[ch.room].up[1] << " / DOWN: " << room[ch.room].down[0] << " " << room[ch.room].down[1] << endl;
return;
}
void createmap(int sector) {
int x = 1, y = 1;
long size = map.width * map.height;
for(long vnum = 1; vnum <= size; ++vnum) {
room[vnum].x = x;
room[vnum].y = y;
room[vnum].sector = sector;
if(++x > map.width) {
++y;
x = 1;
}
}
ch.room = size / 2;
return;
}
void do_quit(string argument = "") {
exit(0);
return;
}
short getCmdID(const string cmd) {
for(short x = 1; cmd_table[x].cmd; ++x)
if(find(cmd, cmd_table[x].cmd))
return x;
}
void do_help(string argument = "") {
short cnt = 0, cmd = 0;
ostrstream ost;
if(argument.empty() || !(cmd = getCmdID(argument))) {
cout << "Usage: ? [command]\n";
set<string> cmd_set;
set<string>::iterator x;
string str;
for(cmd = 1; cmd_table[cmd].cmd; cmd++)
cmd_set.insert(cmd_table[cmd].cmd);
for(x = cmd_set.begin(); x != cmd_set.end(); ++x) {
str = "{@" + *x + "{0*";
ost << setiosflags(ios::left) << setw(16) << str.c_str() << ' ';
if(++cnt % 5 == 0)
ost << endl;
}
if(cnt % 5 != 0)
ost << endl;
ost << ends;
cprintf(ost.str());
return;
}
ost << f_str_box("Keyword: {2" + (string)cmd_table[cmd].cmd + "{0");
if(cmd_table[cmd].usage) {
ost << f_str_box("Usage: {2" + (string)cmd_table[cmd].usage + "{0", false);
ost << f_str_box("Example: {2" + (string)cmd_table[cmd].example + "{0", false);
}
ost << f_str_box(cmd_table[cmd].help, false) << ends;
cprintf(ost.str());
return;
}
void do_newmap(string argument = "") {
string arg1, arg2, arg3;
int width, height, sector;
split(argument, arg1);
split(argument, arg2);
split(argument, arg3);
if(arg1.empty() || arg2.empty() || arg3.empty() || !is_num(arg2) || !is_num(arg3)) {
cout << "Usage: newmap [name] [width] [height] -[default sector]\n";
return;
}
width = atoi(arg2.c_str());
height = atoi(arg3.c_str());
sector = atoi(argument.c_str());
if(arg1.length() > 20) {
printf("name: ERROR: [name] must be less than 20 characters.\n");
return;
}
if(width < 21 || height < 21) {
printf("newmap: ERROR: [#width] and [#height] must be greater than 21.\n");
return;
}
if(width * height > MAX_ROOMS) {
printf("newmap: ERROR: [#width] * [#height] must be less than %ld.\n", MAX_ROOMS);
return;
}
map.author = map.name = arg1;
map.width = width;
map.height = height;
createmap(sector);
print_map();
return;
}
void do_look(string argument = "") {
if(map.name.empty()) {
printf("look: ERROR: No map loaded.\n");
return;
}
print_map();
return;
}
void move_char(const short door) {
short from_door = 0;
long vnum = 0, size = map.width * map.height;
if(door == DIR_NORTH) vnum = ch.room - map.width;
else if(door == DIR_SOUTH) vnum = ch.room + map.width;
else if(door == DIR_EAST) vnum = ch.room + 1;
else if(door == DIR_WEST) vnum = ch.room - 1;
else if(door == DIR_NW) vnum = ch.room - map.width - 1;
else if(door == DIR_NE) vnum = ch.room - map.width + 1;
else if(door == DIR_SW) vnum = ch.room + map.width - 1;
else if(door == DIR_SE) vnum = ch.room + map.width + 1;
if(vnum > size)
vnum -= size;
else if(vnum < 1)
vnum += size;
ch.room = vnum;
return;
}
short get_dir_id(string arg) {
return find(arg, "north") ? DIR_NORTH : find(arg, "south") ? DIR_SOUTH : find(arg, "east") ? DIR_EAST : find(arg, "west") ? DIR_WEST : find(arg, "ne") ? DIR_NE : find(arg, "nw") ? DIR_NW : find(arg, "se") ? DIR_SE : DIR_SW;
}
void do_move(string argument = "") {
string arg;
split(argument, arg);
if(arg.empty() || !find(arg, "n e s w ne nw se sw")) {
cout << "Usage: move [direction] -[distance]\n";
return;
}
short distance = argument.empty() || !is_num(argument) ? 1 : atoi(argument.c_str());
if(distance > 100 || distance < 0) {
cout << "move: ERROR: [distance] must be >= 0 and < 100.\n";
return;
}
for(short x = 0; x < distance; ++x)
move_char(get_dir_id(arg));
do_look();
return;
}
void do_sector(string argument = "") {
short id = 0;
if(map.name.empty()) {
printf("sector: ERROR: No map loaded.\n");
return;
}
if(argument.empty() || (id = atoi(argument.c_str())) < 0 || id > max_sectors) {
int x, cnt = 0;
char buf[256];
printf("Usage: sector [name]\n");
for(x = 0; sector_table[x].print; ++x) {
sprintf(buf, "%3d) %s{0 ", x, sector_table[x].print);
cprintf(buf);
if(++cnt % 8 == 0)
printf("\n");
}
if(cnt % 8 != 0)
printf("\n");
return;
}
room[ch.room].sector = id;
return;
}
void do_ceiling(string argument = "") {
short id = 0;
if(map.name.empty()) {
printf("ceiling: ERROR: No map loaded.\n");
return;
}
if(argument.empty() || (id = atoi(argument.c_str())) < 0 || id > max_sectors) {
int x, cnt = 0;
char buf[256];
printf("Usage: ceiling [name]\n");
for(x = 0; sector_table[x].print; ++x) {
sprintf(buf, "%3d) %s{0 ", x, sector_table[x].print);
cprintf(buf);
if(++cnt % 8 == 0)
printf("\n");
}
if(cnt % 8 != 0)
printf("\n");
return;
}
room[ch.room].ceiling = id;
return;
}
void do_save(string argument = "") {
FILE *fp;
string filename;
long size = map.width * map.height, x;
if(map.name.empty()) {
printf("save: ERROR: No map loaded.\n");
return;
}
if(map.filename.empty() && argument.empty()) {
printf("Usage: save -[filename]\n");
return;
}
if(!argument.empty()) {
if(argument.length() > 20) {
printf("save: ERROR: [filename] must be less than 20 characters.\n");
return;
}
map.filename = argument;
}
filename = map.filename + ".area";
fp = fopen(filename.c_str(), "w");
fprintf(fp, "%s\n%s\n%s\n%d %d %d %d %d %d %d\n", VERSION, map.name.c_str(), map.author.c_str(), map.width, map.height, map.town, map.grav, map.wrap, map.weather, map.solo);
for(x = 1; x <= size; ++x)
fprintf(fp, "%d %d %d %d %ld %ld %ld %ld %ld %ld %d\n", room[x].sector, room[x].flags[ROOM_NOWALK], room[x].flags[ROOM_NOFLY], room[x].flags[ROOM_WATER], room[x].to[0], room[x].to[1], room[x].up[0], room[x].up[1], room[x].down[0], room[x].down[1], room[x].ceiling);
fclose(fp);
return;
}
void do_load(string argument = "") {
FILE *fp;
unsigned long size, x;
char temp_str[5], arg3[3], c;
short arg, cnt;
if(argument.empty()) {
printf("Usage: load [filename]\n");
return;
}
string filename = argument + ".area";
ifstream file(filename.c_str());
if(!file.is_open()) {
cout << "load: ERROR: " << filename << " not found.\n";
return;
}
char c_temp[MIL];
file.getline(c_temp, 10);
map.version = c_temp + '\0';
file.getline(c_temp, 50);
map.name = c_temp + '\0';
if(map.version == "1.1" || map.version == "1.2")
map.author = ch.name;
else {
file.getline(c_temp, 50);
map.author = c_temp + '\0';
}
map.filename = filename.substr(0, filename.length() - 5);
file >> map.width >> map.height >> map.town >> map.grav >> map.wrap >> map.weather >> map.solo;
size = map.width * map.height;
createmap(0);
for(x = 1; x <= size; ++x) {
file >> room[x].sector >> room[x].flags[ROOM_NOWALK] >> room[x].flags[ROOM_NOFLY] >> room[x].flags[ROOM_WATER] >> room[x].to[0] >> room[x].to[1] >> room[x].up[0] >> room[x].up[1] >> room[x].down[0] >> room[x].down[1];
if(map.version == "1.1")
room[x].ceiling = 0;
else
file >> room[x].ceiling;
}
file.close();
print_map();
return;
}
void do_replace(string argument = "") {
string arg1, arg2;
long x, size = map.width * map.height;
short chance;
int sector1, sector2;
if(map.name.empty()) {
printf("replace: ERROR: No map loaded.\n");
return;
}
split(argument, arg1);
split(argument, arg2);
if(arg1.empty() || arg2.empty()) {
cout << "Usage: replace [sector1] [sector2] -[%]\n";
return;
}
sector1 = atoi(arg1.c_str());
sector2 = atoi(arg2.c_str());
chance = argument.empty() || !is_num(argument) ? 100 : atoi(argument.c_str());
for(x = 1; x <= size; ++x)
if(room[x].sector == sector1 && number_percent() <= chance)
room[x].sector = sector2;
return;
}
void do_creplace(string argument = "") {
string arg1, arg2;
long x, size = map.width * map.height;
short chance;
int sector1, sector2;
if(map.name.empty()) {
printf("creplace: ERROR: No map loaded.\n");
return;
}
split(argument, arg1);
split(argument, arg2);
if(arg1.empty() || arg2.empty()) {
cout << "Usage: creplace [ceiling1] [ceiling2] -[%]\n";
return;
}
sector1 = atoi(arg1.c_str());
sector2 = atoi(arg2.c_str());
chance = argument.empty() || !is_num(argument) ? 100 : atoi(argument.c_str());
for(x = 1; x <= size; ++x)
if(room[x].ceiling == sector1 && number_percent() <= chance)
room[x].ceiling = sector2;
return;
}
void do_copy(string argument = "") {
string arg;
if(map.name.empty()) {
printf("copy: ERROR: No map loaded.\n");
return;
}
split(argument, arg);
if(arg.empty() || argument.empty() || !is_num(arg) || !find(argument, "n e s w ne nw se sw")) {
printf("Usage: copy [distance] [direction]\n");
return;
}
short distance = atoi(arg.c_str()), direction = get_dir_id(argument), sector = room[ch.room].sector, ceiling = room[ch.room].ceiling, y, x;
bool flags[MAX_ROOM_FLAGS];
for(x = 0; x < MAX_ROOM_FLAGS; ++x)
flags[x] = room[ch.room].flags[x];
if(distance) {
for(x = 0; x < distance; ++x) {
move_char(direction);
room[ch.room].sector = sector;
room[ch.room].ceiling = ceiling;
for(y = 0; y < MAX_ROOM_FLAGS; ++y)
room[ch.room].flags[y] = flags[y];
}
}
else {
move_char(direction);
while(room[ch.room].sector != sector) {
room[ch.room].sector = sector;
room[ch.room].ceiling = ceiling;
for(y = 0; y < MAX_ROOM_FLAGS; ++y)
room[ch.room].flags[y] = flags[y];
move_char(direction);
}
}
do_look();
return;
}
void do_ccopy(string argument = "") {
string arg;
if(map.name.empty()) {
printf("ccopy: ERROR: No map loaded.\n");
return;
}
split(argument, arg);
if(arg.empty() || argument.empty() || !is_num(arg) || !find(argument, "n e s w ne nw se sw")) {
printf("Usage: ccopy [distance] [direction]\n");
return;
}
short distance = atoi(arg.c_str()), direction = get_dir_id(argument), ceiling = room[ch.room].ceiling;
if(distance) {
for(short x = 0; x < distance; ++x) {
move_char(direction);
room[ch.room].ceiling = ceiling;
}
}
else {
move_char(direction);
while(room[ch.room].ceiling != ceiling) {
room[ch.room].ceiling = ceiling;
move_char(direction);
}
}
do_look();
return;
}
void do_scopy(string argument = "") {
string arg;
if(map.name.empty()) {
printf("scopy: ERROR: No map loaded.\n");
return;
}
split(argument, arg);
if(arg.empty() || argument.empty() || !is_num(arg) || !find(argument, "n e s w ne nw se sw")) {
printf("Usage: scopy [distance] [direction]\n");
return;
}
short distance = atoi(arg.c_str()), direction = get_dir_id(argument), sector = room[ch.room].sector;
if(distance) {
for(short x = 0; x < distance; ++x) {
move_char(direction);
room[ch.room].sector = sector;
}
}
else {
move_char(direction);
while(room[ch.room].sector != sector) {
room[ch.room].sector = sector;
move_char(direction);
}
}
do_look();
return;
}
void do_goto(string argument = "") {
long vnum;
if(map.name.empty()) {
printf("goto: ERROR: No map loaded.\n");
return;
}
if(argument.empty() || !is_num(argument)) {
printf("Usage: goto [#room]\n");
return;
}
vnum = atoi(argument.c_str());
if(vnum < 1 || vnum > map.width * map.height) {
printf("goto: ERROR: [#room] must be between 1 and %ld.\n", map.width * map.height);
return;
}
ch.room = vnum;
do_look();
return;
}
void do_name(string argument = "") {
if(map.name.empty()) {
printf("name: ERROR: No map loaded.\n");
return;
}
if(argument.empty()) {
printf("Usage: name [name]\n");
return;
}
if(argument.length() > 20) {
printf("name: ERROR: [name] must be less than 20 characters.\n");
return;
}
map.name = argument;
return;
}
char *add_html_color(char *string) {
static char buf[MSL];
int x;
buf[0] = '\0';
for(x = 0; x < strlen(string); ++x) {
if(string[x] == '{') {
++x;
switch(string[x]) {
case '1': strcat(buf, "<font color=darkred>"); break;
case '!': strcat(buf, "<font color=red>"); break;
case '2': strcat(buf, "<font color=green>"); break;
case '@': strcat(buf, "<font color=lime>"); break;
case '3': strcat(buf, "<font color=808000>"); break;
case '#': strcat(buf, "<font color=yellow>"); break;
case 'b':
case '4': strcat(buf, "<font color=darkblue>"); break;
case 'B': strcat(buf, "<font color=blue>"); break;
case 'm':
case '5':
case 'M': strcat(buf, "<font color=purple>"); break;
case '6': strcat(buf, "<font color=darkcyan>"); break;
case '^': strcat(buf, "<font color=cyan>"); break;
case '7': strcat(buf, "<font color=lightgrey>"); break;
case '8': strcat(buf, "<font color=gray>"); break;
default: strcat(buf, "<font color=white>"); break;
}
}
else
sprintf(buf + strlen(buf), "%c", string[x]);
}
return buf;
}
void do_savehtml(string argument = "") {
FILE *fp;
char filename[MIL], buf[MSL];
long size = map.width * map.height, x;
bool newline = true;
if(map.name.empty()) {
printf("savehtml: ERROR: No map loaded.\n");
return;
}
if(map.filename.empty() && argument.empty()) {
printf("Usage: savehtml -[filename]\n");
return;
}
if(!argument.empty()) {
if(argument.length() > 12) {
printf("savehtml: ERROR: [filename] must be less than 12 characters.\n");
return;
}
map.filename = argument;
}
sprintf(filename, "%s.html", map.filename.c_str());
fp = fopen(filename, "w");
fprintf(fp, "<html><head><title>DRAGONBALL Z MUD Map Editor v%s : %s</title></head><body bgcolor=black><font size=1><pre>\n", VERSION, map.name.c_str());
for(x = 1; x <= size; ++x) {
if(newline) {
newline = false;
sprintf(buf, "{0%6d %s", x, print_sector(x, true).c_str());//(!(x - 1) || room[x].sector != room[x - 1].sector) ? true : false));
}
else
sprintf(buf + strlen(buf), "%s", print_sector(x, (!(x - 1) || room[x].sector != room[x - 1].sector || room[x].ceiling != room[x - 1].ceiling) ? true : false).c_str());
if(x % map.width == 0) {
newline = true;
fprintf(fp, "%s\n", add_html_color(buf));
}
}
fprintf(fp, "</pre></body></html>");
fclose(fp);
return;
}
int get_max_sectors() {
short x;
for(x = 0; sector_table[x].print; ++x) ;
return x - 1;
}
void reset(const unsigned long id) {
for(short x = 0; x < MAX_ROOM_FLAGS; ++x)
room[id].flags[x] = false;
}
void setRoom(const unsigned long id, string argument) {
string arg, arg2;
split(argument, arg);
if(arg.empty() || !find(arg, "water nofly nowalk reset to up down")) {
printf("Usage: set room [water | nofly | nowalk | reset | [to | up | down] [area] [id | [room]]]\n");
return;
}
split(argument, arg2);
if(find(arg, "water"))
room[id].flags[ROOM_WATER] = true;
else if(find(arg, "nofly"))
room[id].flags[ROOM_NOFLY]= true;
else if(find(arg, "nowalk"))
room[id].flags[ROOM_NOWALK] = true;
else if(find(arg, "reset"))
reset(id);
else if(find(arg, "to")) {
room[id].to[0] = atoi(arg2.c_str());
room[id].to[1] = (argument[0] != '\0' ? atoi(argument.c_str()) : id);
}
else if(find(arg, "up")) {
room[id].up[0] = atoi(arg2.c_str());
room[id].up[1] = (argument[0] != '\0' ? atoi(argument.c_str()) : id);
}
else if(find(arg, "down")) {
room[id].down[0] = atoi(arg2.c_str());
room[id].down[1] = (argument[0] != '\0' ? atoi(argument.c_str()) : id);
}
return;
}
void rset(string argument) {
long x, sector;
string arg, arg2;
int size = map.width * map.height;
split(argument, arg);
if(arg.empty() || !find(arg, "sector id")) {
printf("Usage: set room [sector | id] [water | nofly | nowalk | reset | [to | up | down] [area] [id | [room]]]\n");
return;
}
split(argument, arg2);
if(find(arg, "sector")) {
short sector = atoi(arg2.c_str());
if(!sector) {
printf("ERROR: Invalid sector.\n");
return;
}
for(x = 1; x <= size; ++x)
if(room[x].sector == sector)
setRoom(x, argument);
}
else {
x = atoi(arg2.c_str());
if(!x || x > MAX_ROOMS) {
printf("ERROR: Invalid room ID.\n");
return;
}
setRoom(x, argument);
}
return;
}
void aset(string argument) {
string arg;
split(argument, arg);
if(arg.empty() || !find(arg, "town grav wrap weather solo")) {
printf("Usage: set area [town | grav | wrap | weather | solo]\n");
return;
}
if(find(arg, "town"))
map.town = map.town ? false : true;
else if(find(arg, "grav"))
map.grav = atoi(argument.c_str());
else if(find(arg, "wrap"))
map.wrap = map.wrap ? false : true;
else if(find(arg, "weather"))
map.weather = map.weather ? false : true;
else if(find(arg, "solo"))
map.solo = map.solo ? false : true;
return;
}
void do_set(string argument = "") {
string arg;
int size = map.width * map.height;
split(argument, arg);
if(arg.empty() || !find(arg, "room area")) {
printf("Usage: set [room | area]\n");
return;
}
if(find(arg, "room"))
rset(argument);
else
aset(argument);
return;
}
void do_viewceiling(string argument = "") {
ch.viewCeiling = !ch.viewCeiling;
return;
}