#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; }