/************************************************************************ * OasisOLC - zedit.c v1.5 * * * * Copyright 1996 Harvey Gilpin. * ************************************************************************/ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "comm.h" #include "utils.h" #include "db.h" #include "olc.h" /* * Turn on zedit debugging. Please mail log results to greerga@van.ml.org * This will attempt to find the problem with replacing other zedit commands * when you add unrelated ones. */ #if 0 #define DEBUG 1 #endif /*-------------------------------------------------------------------*/ /* * External data structures. */ extern struct zone_data *zone_table; extern struct room_data *world; extern int top_of_zone_table; extern struct char_data *mob_proto; extern struct index_data *mob_index; extern struct obj_data *obj_proto; extern struct index_data *obj_index; extern char *equipment_types[]; extern char *dirs[]; /*-------------------------------------------------------------------*/ /* * Function prototypes. */ void zedit_disp_menu(struct descriptor_data *d); void zedit_setup(struct descriptor_data *d, int room_num); void add_cmd_to_list(struct reset_com **list, struct reset_com *newcmd, int pos); void remove_cmd_from_list(struct reset_com **list, int pos); void delete_command(struct descriptor_data *d, int pos); int new_command(struct descriptor_data *d, int pos); int start_change_command(struct descriptor_data *d, int pos); void zedit_disp_comtype(struct descriptor_data *d); void zedit_disp_arg1(struct descriptor_data *d); void zedit_disp_arg2(struct descriptor_data *d); void zedit_disp_arg3(struct descriptor_data *d); void zedit_save_internally(struct descriptor_data *d); void zedit_save_to_disk(int zone_num); void zedit_create_index(int znum, char *type); void zedit_new_zone(struct char_data *ch, int vzone_num); /*-------------------------------------------------------------------*/ /* * Nasty internal macros to clean up the code. */ #define ZCMD (zone_table[OLC_ZNUM(d)].cmd[subcmd]) #define MYCMD (OLC_ZONE(d)->cmd[subcmd]) #define OLC_CMD(d) (OLC_ZONE(d)->cmd[OLC_VAL(d)]) /*-------------------------------------------------------------------*/ /* * Utility functions. */ /*-------------------------------------------------------------------*/ void zedit_setup(struct descriptor_data *d, int room_num) { struct zone_data *zone; int subcmd = 0, count = 0, cmd_room = -1; /* * Allocate one scratch zone structure. */ CREATE(zone, struct zone_data, 1); /* * Copy all the zone header information over. */ zone->name = str_dup(zone_table[OLC_ZNUM(d)].name); zone->builders = str_dup(zone_table[OLC_ZNUM(d)].builders); zone->lifespan = zone_table[OLC_ZNUM(d)].lifespan; zone->top = zone_table[OLC_ZNUM(d)].top; zone->reset_mode = zone_table[OLC_ZNUM(d)].reset_mode; /* * The remaining fields are used as a 'has been modified' flag */ zone->number = 0; /* Header information has changed. */ zone->age = 0; /* The commands have changed. */ /* * Start the reset command list with a terminator. */ CREATE(zone->cmd, struct reset_com, 1); zone->cmd[0].command = 'S'; /* * Add all entries in zone_table that relate to this room. */ while (ZCMD.command != 'S') { switch (ZCMD.command) { case 'M': case 'O': cmd_room = ZCMD.arg3; break; case 'D': case 'R': cmd_room = ZCMD.arg1; break; default: break; } if (cmd_room == room_num) { #if defined(DEBUG) log("zedit_setup called add_cmd_to_list."); #endif add_cmd_to_list(&(zone->cmd), &ZCMD, count); count++; } subcmd++; } OLC_ZONE(d) = zone; /* * Display main menu. */ zedit_disp_menu(d); } /*-------------------------------------------------------------------*/ /* * Create a new zone. */ void zedit_new_zone(struct char_data *ch, int vzone_num) { FILE *fp; struct zone_data *new_table; int i, room; if (vzone_num < 0) { send_to_char("You can't make negative zones.\r\n", ch); return; } else if (vzone_num > 326) { send_to_char("326 is the highest zone allowed.\r\n", ch); return; } /* * Make sure the zone does not exist. */ room = vzone_num * 100; for (i = 0; i <= top_of_zone_table; i++) if ((zone_table[i].number * 100 <= room) && (zone_table[i].top >= room)) { send_to_char("A zone already covers that area.\r\n", ch); return; } /* * Create the zone file. */ sprintf(buf, "%s/%d.zon", ZON_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog("SYSERR: OLC: Can't write new zone file", BRF, LVL_IMPL, TRUE); send_to_char("Could not write zone file.\r\n", ch); return; } fprintf(fp, "#%d\nNew Zone~\n~\n%d 30 2\nS\n$\n", vzone_num, (vzone_num * 100) + 99); fclose(fp); /* * Create the room file. */ sprintf(buf, "%s/%d.wld", WLD_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog("SYSERR: OLC: Can't write new world file", BRF, LVL_IMPL, TRUE); send_to_char("Could not write world file.\r\n", ch); return; } fprintf(fp, "#%d\nThe Beginning~\nNot much here.\n~\n%d 0 0\nS\n$\n", vzone_num * 100, vzone_num); fclose(fp); /* * Create the mobile file. */ sprintf(buf, "%s/%d.mob", MOB_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog("SYSERR: OLC: Can't write new mob file", BRF, LVL_IMPL, TRUE); send_to_char("Could not write mobile file.\r\n", ch); return; } fprintf(fp, "$\n"); fclose(fp); /* * Create the object file. */ sprintf(buf, "%s/%d.obj", OBJ_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog("SYSERR: OLC: Can't write new obj file", BRF, LVL_IMPL, TRUE); send_to_char("Could not write object file.\r\n", ch); return; } fprintf(fp, "$\n"); fclose(fp); /* * Create the shop file. */ sprintf(buf, "%s/%d.shp", SHP_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog("SYSERR: OLC: Can't write new shop file", BRF, LVL_IMPL, TRUE); send_to_char("Could not write shop file.\r\n", ch); return; } fprintf(fp, "$~\n"); fclose(fp); /* * Create the trigger file. */ sprintf(buf, "%s/%d.trg", TRG_PREFIX, vzone_num); if (!(fp = fopen(buf, "w"))) { mudlog("SYSERR: OLC: Can't write new trigger file", BRF, LVL_IMPL, TRUE); send_to_char("Could not write trigger file.\r\n", ch); return; } fprintf(fp, "$~\n"); fclose(fp); /* * Update index files. */ zedit_create_index(vzone_num, "zon"); zedit_create_index(vzone_num, "wld"); zedit_create_index(vzone_num, "mob"); zedit_create_index(vzone_num, "obj"); zedit_create_index(vzone_num, "shp"); zedit_create_index(vzone_num, "trg"); /* * Make a new zone in memory. This was the source of all the zedit new * crashes reported to the CircleMUD list. It was happily overwriting * the stack. This new loop by Andrew Helm fixes that problem and is * more understandable at the same time. * * The variable is 'top_of_zone_table_table + 2' because we need record 0 * through top_of_zone (top_of_zone_table + 1 items) and a new one which * makes it top_of_zone_table + 2 elements large. */ CREATE(new_table, struct zone_data, top_of_zone_table + 2); new_table[top_of_zone_table + 1].number = 32000; if (vzone_num > zone_table[top_of_zone_table].number) { /* * We're adding to the end of the zone table, copy all of the current * top_of_zone_table + 1 items over and set write point to before the * the last record for the for() loop below. */ memcpy(new_table, zone_table, (sizeof (struct zone_data) * (top_of_zone_table + 1))); i = top_of_zone_table + 1; } else /* * Copy over all the zones that are before this zone. */ for (i = 0; vzone_num > zone_table[i].number; i++) new_table[i] = zone_table[i]; /* * Ok, insert the new zone here. */ new_table[i].name = str_dup("New Zone"); new_table[i].number = vzone_num; new_table[i].top = (vzone_num * 100) + 99; new_table[i].lifespan = 30; new_table[i].age = 0; new_table[i].reset_mode = 2; /* * No zone commands, just terminate it with an 'S' */ CREATE(new_table[i].cmd, struct reset_com, 1); new_table[i].cmd[0].command = 'S'; /* * Copy remaining zones into the table one higher, unless of course we * are appending to the end in which case this loop will not be used. */ for (; i <= top_of_zone_table; i++) new_table[i + 1] = zone_table[i]; /* * Look Ma, no memory leak! */ free(zone_table); zone_table = new_table; top_of_zone_table++; /* * Previously, creating a new zone while invisible gave you away. * That quirk has been fixed with the MAX() statement. */ sprintf(buf, "OLC: %s creates new zone #%d", GET_NAME(ch), vzone_num); mudlog(buf, BRF, MAX(LVL_IMMORT, GET_INVIS_LEV(ch)), TRUE); send_to_char("Zone created successfully.\r\n", ch); return; } /*-------------------------------------------------------------------*/ void zedit_create_index(int znum, char *type) { FILE *newfile, *oldfile; char new_name[32], old_name[32], *prefix; int num, found = FALSE; switch (*type) { case 'z': prefix = ZON_PREFIX; break; case 'w': prefix = WLD_PREFIX; break; case 'o': prefix = OBJ_PREFIX; break; case 'm': prefix = MOB_PREFIX; break; case 's': prefix = SHP_PREFIX; break; case 't': prefix = TRG_PREFIX; break; default: /* * Caller messed up */ return; } sprintf(old_name, "%s/index", prefix); sprintf(new_name, "%s/newindex", prefix); if (!(oldfile = fopen(old_name, "r"))) { sprintf(buf, "SYSERR: OLC: Failed to open %s", buf); mudlog(buf, BRF, LVL_IMPL, TRUE); return; } else if (!(newfile = fopen(new_name, "w"))) { sprintf(buf, "SYSERR: OLC: Failed to open %s", buf); mudlog(buf, BRF, LVL_IMPL, TRUE); return; } /* * Index contents must be in order: search through the old file for the * right place, insert the new file, then copy the rest over. */ sprintf(buf1, "%d.%s", znum, type); while (get_line(oldfile, buf)) { if (*buf == '$') { fprintf(newfile, "%s\n$\n", (!found ? buf1 : "")); break; } else if (!found) { sscanf(buf, "%d", &num); if (num > znum) { found = TRUE; fprintf(newfile, "%s\n", buf1); } } fprintf(newfile, "%s\n", buf); } fclose(newfile); fclose(oldfile); /* * Out with the old, in with the new. */ remove(old_name); rename(new_name, old_name); } /*-------------------------------------------------------------------*/ /* * Save all the information in the player's temporary buffer back into * the current zone table. */ void zedit_save_internally(struct descriptor_data *d) { int subcmd = 0, cmd_room = -2, room_num = real_room(OLC_NUM(d)); /* * Delete all entries in zone_table that relate to this room so we * can add all the ones we have in their place. */ while (ZCMD.command != 'S') { switch (ZCMD.command) { case 'M': case 'O': cmd_room = ZCMD.arg3; break; case 'D': case 'R': cmd_room = ZCMD.arg1; break; default: break; } if (cmd_room == room_num) { #if defined(DEBUG) log("zedit_save_internally called remove_cmd_from_list."); #endif remove_cmd_from_list(&(zone_table[OLC_ZNUM(d)].cmd), subcmd); } else subcmd++; } /* * Now add all the entries in the players descriptor list */ subcmd = 0; while (MYCMD.command != 'S') { #if defined(DEBUG) log("zedit_save_internally called add_cmd_to_list."); #endif add_cmd_to_list(&(zone_table[OLC_ZNUM(d)].cmd), &MYCMD, subcmd); subcmd++; } /* * Finally, if zone headers have been changed, copy over */ if (OLC_ZONE(d)->number) { free(zone_table[OLC_ZNUM(d)].name); zone_table[OLC_ZNUM(d)].name = str_dup(OLC_ZONE(d)->name); zone_table[OLC_ZNUM(d)].builders = str_dup(OLC_ZONE(d)->builders); zone_table[OLC_ZNUM(d)].top = OLC_ZONE(d)->top; zone_table[OLC_ZNUM(d)].reset_mode = OLC_ZONE(d)->reset_mode; zone_table[OLC_ZNUM(d)].lifespan = OLC_ZONE(d)->lifespan; } olc_add_to_save_list(zone_table[OLC_ZNUM(d)].number, OLC_SAVE_ZONE); } /*-------------------------------------------------------------------*/ /* * Save all the zone_table for this zone to disk. This function now * writes simple comments in the form of (<name>) to each record. A * header for each field is also there. */ #undef ZCMD #define ZCMD (zone_table[zone_num].cmd[subcmd]) void zedit_save_to_disk(int zone_num) { int subcmd, arg1 = -1, arg2 = -1, arg3 = -1, arg4 = -1; char fname[64]; const char *comment = NULL; FILE *zfile; sprintf(fname, "%s/%d.new", ZON_PREFIX, zone_table[zone_num].number); if (!(zfile = fopen(fname, "w"))) { sprintf(buf, "SYSERR: OLC: zedit_save_to_disk: Can't write zone %d.", zone_table[zone_num].number); mudlog(buf, BRF, LVL_IMMORT, TRUE); return; } /* * Print zone header to file */ fprintf(zfile, "#%d\n" "%s~\n" "%s~\n" "%d %d %d\n", zone_table[zone_num].number, (zone_table[zone_num].name && *zone_table[zone_num].name) ? zone_table[zone_num].name : "undefined", (zone_table[zone_num].builders && *zone_table[zone_num].builders) ? zone_table[zone_num].builders : "<NONE!>", zone_table[zone_num].top, zone_table[zone_num].lifespan, zone_table[zone_num].reset_mode ); #if defined(ZEDIT_HELP_IN_FILE) fprintf(zfile,"* Field #1 Field #3 Field #4 Field #5\n" "* M (Mobile) Mob-Vnum Wld-Max Room-Vnum\n" "* O (Object) Obj-Vnum Wld-Max Room-Vnum\n" "* G (Give) Obj-Vnum Wld-Max Unused\n" "* E (Equip) Obj-Vnum Wld-Max EQ-Position\n" "* P (Put) Obj-Vnum Wld-Max Target-Obj-Vnum\n" "* D (Door) Room-Vnum Door-Dir Door-State\n" "* R (Remove) Room-Vnum Obj-Vnum Unused\n" ); #endif for (subcmd = 0; ZCMD.command != 'S'; subcmd++) { switch (ZCMD.command) { case 'M': arg1 = mob_index[ZCMD.arg1].vnum; arg2 = ZCMD.arg2; arg3 = world[ZCMD.arg3].number; arg4 = ZCMD.arg4; comment = mob_proto[ZCMD.arg1].player.short_descr; break; case 'O': arg1 = obj_index[ZCMD.arg1].vnum; arg2 = ZCMD.arg2; arg3 = world[ZCMD.arg3].number; arg4 = ZCMD.arg4; comment = obj_proto[ZCMD.arg1].short_description; break; case 'G': arg1 = obj_index[ZCMD.arg1].vnum; arg2 = ZCMD.arg2; arg3 = ZCMD.arg3; arg4 = -1; comment = obj_proto[ZCMD.arg1].short_description; break; case 'E': arg1 = obj_index[ZCMD.arg1].vnum; arg2 = ZCMD.arg2; arg3 = ZCMD.arg3; arg4 = ZCMD.arg4; comment = obj_proto[ZCMD.arg1].short_description; break; case 'P': arg1 = obj_index[ZCMD.arg1].vnum; arg2 = ZCMD.arg2; arg3 = obj_index[ZCMD.arg3].vnum; arg4 = ZCMD.arg4; comment = obj_proto[ZCMD.arg1].short_description; break; case 'D': arg1 = world[ZCMD.arg1].number; arg2 = ZCMD.arg2; arg3 = ZCMD.arg3; arg4 = -1; comment = world[ZCMD.arg1].name; break; case 'R': arg1 = world[ZCMD.arg1].number; arg2 = obj_index[ZCMD.arg2].vnum; arg3 = -1; arg4 = -1; comment = obj_proto[ZCMD.arg2].short_description; break; case '*': /* * Invalid commands are replaced with '*' - Ignore them. */ continue; default: sprintf(buf, "SYSERR: OLC: z_save_to_disk(): Unknown cmd '%c' - NOT saving", ZCMD.command); mudlog(buf, BRF, LVL_IMMORT, TRUE); continue; } fprintf(zfile, "%c %d %d %d %d %d\n", ZCMD.command, ZCMD.if_flag, arg1, arg2, arg3, arg4); } fprintf(zfile, "S\n$\n"); fclose(zfile); sprintf(buf2, "%s/%d.zon", ZON_PREFIX, zone_table[zone_num].number); /* * We're fubar'd if we crash between the two lines below. */ remove(buf2); rename(fname, buf2); olc_remove_from_save_list(zone_table[zone_num].number, OLC_SAVE_ZONE); } /*-------------------------------------------------------------------*/ /* * Some common code to count the number of comands in the list. */ int count_commands(struct reset_com *list) { int count = 0; while (list[count].command != 'S') count++; return count; } /*-------------------------------------------------------------------*/ /* * Adds a new reset command into a list. Takes a pointer to the list * so that it may play with the memory locations. */ void add_cmd_to_list(struct reset_com **list, struct reset_com *newcmd, int pos) { int count, i, l; struct reset_com *newlist; /* * Count number of commands (not including terminator). */ count = count_commands(*list); /* * Value is +2 for the terminator and new field to add. */ CREATE(newlist, struct reset_com, count + 2); /* * Even tighter loop to copy the old list and insert a new command. */ for (i = 0, l = 0; i <= count; i++) { newlist[i] = ((i == pos) ? *newcmd : (*list)[l++]); #if defined(DEBUG) sprintf(buf, "add_cmd_to_list: added %c %d %d %d %d", newlist[i].command, newlist[i].arg1, newlist[i].arg2, newlist[i].arg3, newlist[i].line); log(buf); #endif } /* * Add terminator, then insert new list. */ newlist[count + 1].command = 'S'; free(*list); *list = newlist; } /*-------------------------------------------------------------------*/ /* * Remove a reset command from a list. Takes a pointer to the list * so that it may play with the memory locations. */ void remove_cmd_from_list(struct reset_com **list, int pos) { int count, i, l; struct reset_com *newlist; /* * Count number of commands (not including terminator) */ count = count_commands(*list); /* * Value is 'count' because we didn't include the terminator above * but since we're deleting one thing anyway we want one less. */ CREATE(newlist, struct reset_com, count); /* * Even tighter loop to copy old list and skip unwanted command. */ for (i = 0, l = 0; i < count; i++) { if (i != pos) { #if defined(DEBUG) sprintf(buf, "remove_cmd_from_list: kept %c %d %d %d %d", (*list)[i].command, (*list)[i].arg1, (*list)[i].arg2, (*list)[i].arg3, (*list)[i].line); #endif newlist[l++] = (*list)[i]; } #if defined(DEBUG) else sprintf(buf, "remove_cmd_from_list: deleted %c %d %d %d %d", (*list)[i].command, (*list)[i].arg1, (*list)[i].arg2, (*list)[i].arg3, (*list)[i].line); log(buf); #endif } /* * Add the terminator, then insert the new list. */ newlist[count - 1].command = 'S'; free(*list); *list = newlist; } /*-------------------------------------------------------------------*/ /* * Error check user input and then add new (blank) command */ int new_command(struct descriptor_data *d, int pos) { int subcmd = 0; struct reset_com *new_com; /* * Error check to ensure users hasn't given too large an index */ while (MYCMD.command != 'S') subcmd++; if ((pos > subcmd) || (pos < 0)) return 0; /* * Ok, let's add a new (blank) command */ CREATE(new_com, struct reset_com, 1); new_com->command = 'N'; #if defined(DEBUG) log("new_command called add_cmd_to_list."); #endif add_cmd_to_list(&OLC_ZONE(d)->cmd, new_com, pos); return 1; } /*-------------------------------------------------------------------*/ /* * Error check user input and then remove command */ void delete_command(struct descriptor_data *d, int pos) { int subcmd = 0; /* * Error check to ensure users hasn't given too large an index */ while (MYCMD.command != 'S') subcmd++; if ((pos >= subcmd) || (pos < 0)) return; /* * Ok, let's zap it */ #if defined(DEBUG) log("delete_command called remove_cmd_from_list."); #endif remove_cmd_from_list(&OLC_ZONE(d)->cmd, pos); } /*-------------------------------------------------------------------*/ /* * Error check user input and then setup change */ int start_change_command(struct descriptor_data *d, int pos) { int subcmd = 0; /* * Error check to ensure users hasn't given too large an index */ while (MYCMD.command != 'S') subcmd++; if ((pos >= subcmd) || (pos < 0)) return 0; /* * Ok, let's get editing */ OLC_VAL(d) = pos; return 1; } /************************************************************************** Menu functions **************************************************************************/ /* * the main menu */ void zedit_disp_menu(struct descriptor_data *d) { int subcmd = 0, room, counter = 0; get_char_cols(d->character); room = real_room(OLC_NUM(d)); /* * Menu header */ sprintf(buf, #if defined(CLEAR_SCREEN) "[H[J" #endif "Room number: %s%d%s Room zone: %s%d\r\n" "%sB%s) Builders : %s%s\r\n" "%sZ%s) Zone name : %s%s\r\n" "%sL%s) Lifespan : %s%d minutes\r\n" "%sT%s) Top of zone : %s%d\r\n" "%sR%s) Reset Mode : %s%s%s\r\n" "[Command list]\r\n", cyn, OLC_NUM(d), nrm, cyn, zone_table[OLC_ZNUM(d)].number, grn, nrm, yel, OLC_ZONE(d)->builders ? OLC_ZONE(d)->builders : "<NONE!>", grn, nrm, yel, OLC_ZONE(d)->name ? OLC_ZONE(d)->name : "<NONE!>", grn, nrm, yel, OLC_ZONE(d)->lifespan, grn, nrm, yel, OLC_ZONE(d)->top, grn, nrm, yel, OLC_ZONE(d)->reset_mode ? ((OLC_ZONE(d)->reset_mode == 1) ? "Reset when no players are in zone." : "Normal reset.") : "Never reset", nrm ); /* * Print the commands for this room into display buffer. */ while (MYCMD.command != 'S') { /* * Translate what the command means. */ switch (MYCMD.command) { case 'M': sprintf(buf2, "%sLoad %s [%s%d%s], Chance %d%% , Max : %d", MYCMD.if_flag ? " then " : "", mob_proto[MYCMD.arg1].player.short_descr, cyn, mob_index[MYCMD.arg1].vnum, yel, MYCMD.arg4 ? (101 - MYCMD.arg4): 100, MYCMD.arg2 ); break; case 'G': sprintf(buf2, "%sGive it %s [%s%d%s], Chance %d%%, Max : %d", MYCMD.if_flag ? " then " : "", obj_proto[MYCMD.arg1].short_description, cyn, obj_index[MYCMD.arg1].vnum, yel, MYCMD.arg3 ? (101 - MYCMD.arg3): 100, MYCMD.arg2 ); break; case 'O': sprintf(buf2, "%sLoad %s [%s%d%s], Chance %d%%, Max : %d", MYCMD.if_flag ? " then " : "", obj_proto[MYCMD.arg1].short_description, cyn, obj_index[MYCMD.arg1].vnum, yel, MYCMD.arg4 ? (101 - MYCMD.arg4): 100, MYCMD.arg2 ); break; case 'E': sprintf(buf2, "%sEquip with %s [%s%d%s], %s, Chance %d%%, Max : %d", MYCMD.if_flag ? " then " : "", obj_proto[MYCMD.arg1].short_description, cyn, obj_index[MYCMD.arg1].vnum, yel, equipment_types[MYCMD.arg3], MYCMD.arg4 ? (101 - MYCMD.arg4): 100, MYCMD.arg2 ); break; case 'P': sprintf(buf2, "%sPut %s [%s%d%s] in %s [%s%d%s], Chance %d%%, Max : %d", MYCMD.if_flag ? " then " : "", obj_proto[MYCMD.arg1].short_description, cyn, obj_index[MYCMD.arg1].vnum, yel, obj_proto[MYCMD.arg3].short_description, cyn, obj_index[MYCMD.arg3].vnum, yel, MYCMD.arg4 ? (101 - MYCMD.arg4): 100, MYCMD.arg2 ); break; case 'R': sprintf(buf2, "%sRemove %s [%s%d%s] from room.", MYCMD.if_flag ? " then " : "", obj_proto[MYCMD.arg2].short_description, cyn, obj_index[MYCMD.arg2].vnum, yel ); break; case 'D': sprintf(buf2, "%sSet door %s as %s.", MYCMD.if_flag ? " then " : "", dirs[MYCMD.arg2], MYCMD.arg3 ? ((MYCMD.arg3 == 1) ? "closed" : "locked") : "open" ); break; default: strcpy(buf2, "<Unknown Command>"); break; } /* * Build the display buffer for this command */ sprintf(buf1, "%s%d - %s%s\r\n", nrm, counter++, yel, buf2); strcat(buf, buf1); subcmd++; } /* * Finish off menu */ sprintf(buf1, "%s%d - <END OF LIST>\r\n" "%sN%s) New command. %sE%s) Edit a command.\r\n" "%sD%s) Delete a command. %sC%s) Change a command's chance of happening.\r\n" "%sQ%s) Quit\r\nEnter your choice : ", nrm, counter, grn, nrm, grn, nrm, grn, nrm, grn, nrm, grn, nrm ); strcat(buf, buf1); send_to_char(buf, d->character); OLC_MODE(d) = ZEDIT_MAIN_MENU; } /*-------------------------------------------------------------------*/ /* * Print the command type menu and setup response catch. */ void zedit_disp_comtype(struct descriptor_data *d) { get_char_cols(d->character); sprintf(buf, #if defined(CLEAR_SCREEN) "[H[J" #endif "%sM%s) Load Mobile to room %sO%s) Load Object to room\r\n" "%sE%s) Equip mobile with object %sG%s) Give an object to a mobile\r\n" "%sP%s) Put object in another object %sD%s) Open/Close/Lock a Door\r\n" "%sR%s) Remove an object from the room\r\n" "What sort of command will this be? : ", grn, nrm, grn, nrm, grn, nrm, grn, nrm, grn, nrm, grn, nrm, grn, nrm ); send_to_char(buf, d->character); OLC_MODE(d) = ZEDIT_COMMAND_TYPE; } /*-------------------------------------------------------------------*/ /* * Print the appropriate message for the command type for arg1 and set * up the input catch clause */ void zedit_disp_arg1(struct descriptor_data *d) { switch (OLC_CMD(d).command) { case 'M': send_to_char("Input mob's vnum : ", d->character); OLC_MODE(d) = ZEDIT_ARG1; break; case 'O': case 'E': case 'P': case 'G': send_to_char("Input object vnum : ", d->character); OLC_MODE(d) = ZEDIT_ARG1; break; case 'D': case 'R': /* * Arg1 for these is the room number, skip to arg2 */ OLC_CMD(d).arg1 = real_room(OLC_NUM(d)); zedit_disp_arg2(d); break; default: /* * We should never get here . */ cleanup_olc(d, CLEANUP_ALL); mudlog("SYSERR: OLC: zedit_disp_arg1(): Help!", BRF, LVL_IMMORT, TRUE); send_to_char("Oops...\r\n", d->character); return; } } /*-------------------------------------------------------------------*/ /* * Print the appropriate message for the command type for arg2 and set * up the input catch clause. */ void zedit_disp_arg2(struct descriptor_data *d) { int i = 0; switch (OLC_CMD(d).command) { case 'M': case 'O': case 'E': case 'P': case 'G': send_to_char("Input the maximum number that can exist on the mud : ", d->character); break; case 'D': while (*dirs[i] != '\n') { sprintf(buf, "%d) Exit %s.\r\n", i, dirs[i]); send_to_char(buf, d->character); i++; } send_to_char("Enter exit number for door : ", d->character); break; case 'R': send_to_char("Input object's vnum : ", d->character); break; default: /* * We should never get here, but just in case... */ cleanup_olc(d, CLEANUP_ALL); mudlog("SYSERR: OLC: zedit_disp_arg2(): Help!", BRF, LVL_IMMORT, TRUE); send_to_char("Oops...\r\n", d->character); return; } OLC_MODE(d) = ZEDIT_ARG2; } /*-------------------------------------------------------------------*/ /* * Print the appropriate message for the command type for arg3 and set * up the input catch clause. */ void zedit_disp_arg3(struct descriptor_data *d) { int i = 0; switch (OLC_CMD(d).command) { case 'E': while (*equipment_types[i] != '\n') { sprintf(buf, "%2d) %26.26s %2d) %26.26s\r\n", i, equipment_types[i], i + 1, (*equipment_types[i + 1] != '\n') ? equipment_types[i + 1] : ""); send_to_char(buf, d->character); if (*equipment_types[i + 1] != '\n') i += 2; else break; } send_to_char("Location to equip : ", d->character); break; case 'P': send_to_char("Vnum of the container : ", d->character); break; case 'D': send_to_char("0) Door open\r\n" "1) Door closed\r\n" "2) Door locked\r\n" "Enter state of the door : ", d->character); break; case 'G': send_to_char("Give the percentage chance that this event should happen: ", d->character); break; case 'M': case 'O': case 'R': default: /* * We should never get here, just in case. */ cleanup_olc(d, CLEANUP_ALL); mudlog("SYSERR: OLC: zedit_disp_arg3(): Help!", BRF, LVL_IMMORT, TRUE); send_to_char("Oops...\r\n", d->character); return; } OLC_MODE(d) = ZEDIT_ARG3; } /*-------------------------------------------------------------------*/ /*. Print the appropriate message for the command type for arg4 and set up the input catch clause .*/ void zedit_disp_arg4(struct descriptor_data *d) { switch(OLC_CMD(d).command) { case 'E': case 'M': case 'O': case 'P': send_to_char("Give the percentage chance that this event should happen: ", d->character); break; case 'G': case 'D': case 'R': default: /*. We should never get here .*/ cleanup_olc(d, CLEANUP_ALL); mudlog("SYSERR: OLC: zedit_disp_arg3(): Help!", BRF, LVL_GOD, TRUE); return; } OLC_MODE(d) = ZEDIT_ARG4; } /*-------------------------------------------------------------------*/ /************************************************************************** The GARGANTAUN event handler **************************************************************************/ void zedit_parse(struct descriptor_data *d, char *arg) { int pos, i = 0; switch (OLC_MODE(d)) { /*-------------------------------------------------------------------*/ case ZEDIT_CONFIRM_SAVESTRING: switch (*arg) { case 'y': case 'Y': /* * Save the zone in memory, hiding invisible people. */ send_to_char("Saving zone info in memory.\r\n", d->character); zedit_save_internally(d); sprintf(buf, "OLC: %s edits zone info for room %d.", GET_NAME(d->character), OLC_NUM(d)); mudlog(buf, CMP, MAX(LVL_IMMORT, GET_INVIS_LEV(d->character)), TRUE); /* FALL THROUGH */ case 'n': case 'N': cleanup_olc(d, CLEANUP_ALL); break; default: send_to_char("Invalid choice!\r\n", d->character); send_to_char("Do you wish to save the zone info? : ", d->character); break; } break; /* End of ZEDIT_CONFIRM_SAVESTRING */ /*-------------------------------------------------------------------*/ case ZEDIT_MAIN_MENU: switch (*arg) { case 'q': case 'Q': if (OLC_ZONE(d)->age || OLC_ZONE(d)->number) { send_to_char("Do you wish to save the changes to the zone info? (y/n) : ", d->character); OLC_MODE(d) = ZEDIT_CONFIRM_SAVESTRING; } else { send_to_char("No changes made.\r\n", d->character); cleanup_olc(d, CLEANUP_ALL); } break; case 'n': case 'N': /* * New entry. */ send_to_char("What number in the list should the new command be? : ", d->character); OLC_MODE(d) = ZEDIT_NEW_ENTRY; break; case 'e': case 'E': /* * Change an entry. */ send_to_char("Which command do you wish to change? : ", d->character); OLC_MODE(d) = ZEDIT_CHANGE_ENTRY; break; case 'd': case 'D': /* * Delete an entry. */ send_to_char("Which command do you wish to delete? : ", d->character); OLC_MODE(d) = ZEDIT_DELETE_ENTRY; break; case 'z': case 'Z': /* * Edit zone name. */ send_to_char("Enter new zone name : ", d->character); OLC_MODE(d) = ZEDIT_ZONE_NAME; break; case 't': case 'T': /* * Edit top of zone. */ if (GET_LEVEL(d->character) < LVL_IMPL) zedit_disp_menu(d); else { send_to_char("Enter new top of zone : ", d->character); OLC_MODE(d) = ZEDIT_ZONE_TOP; } break; case 'l': case 'L': /* * Edit zone lifespan. */ send_to_char("Enter new zone lifespan : ", d->character); OLC_MODE(d) = ZEDIT_ZONE_LIFE; break; case 'r': case 'R': /* * Edit zone reset mode. */ send_to_char("\r\n" "0) Never reset\r\n" "1) Reset only when no players in zone\r\n" "2) Normal reset\r\n" "Enter new zone reset type : ", d->character); OLC_MODE(d) = ZEDIT_ZONE_RESET; break; case 'b': case 'B': if (GET_LEVEL(d->character) < LVL_IMPL) { send_to_char("Only Implementors can modify the builder list.\r\n", d->character); zedit_disp_menu(d); } else { /* * Edit zone builder list. */ send_to_char("Enter new zone builders : ", d->character); OLC_MODE(d) = ZEDIT_ZONE_BUILDERS; } break; case 'c': case 'C': /* * Change loadchance */ send_to_char("Which command? ", d->character); OLC_MODE(d) = ZEDIT_PROB; break; default: zedit_disp_menu(d); break; } break; /* End of ZEDIT_MAIN_MENU */ /*-------------------------------------------------------------------*/ case ZEDIT_NEW_ENTRY: /* * Get the line number and insert the new line. */ pos = atoi(arg); if (isdigit(*arg) && new_command(d, pos)) { if (start_change_command(d, pos)) { zedit_disp_comtype(d); OLC_ZONE(d)->age = 1; } } else zedit_disp_menu(d); break; /*-------------------------------------------------------------------*/ case ZEDIT_DELETE_ENTRY: /* * Get the line number and delete the line. */ pos = atoi(arg); if (isdigit(*arg)) { delete_command(d, pos); OLC_ZONE(d)->age = 1; } zedit_disp_menu(d); break; /*-------------------------------------------------------------------*/ case ZEDIT_CHANGE_ENTRY: /* * Parse the input for which line to edit, and goto next quiz. */ pos = atoi(arg); if (isdigit(*arg) && start_change_command(d, pos)) { zedit_disp_comtype(d); OLC_ZONE(d)->age = 1; } else zedit_disp_menu(d); break; /*-------------------------------------------------------------------*/ case ZEDIT_COMMAND_TYPE: /* * Parse the input for which type of command this is, and goto next * quiz. */ OLC_CMD(d).command = toupper(*arg); if (!OLC_CMD(d).command || (strchr("MOPEDGR", OLC_CMD(d).command) == NULL)) { send_to_char("Invalid choice, try again : ", d->character); } else { if (OLC_VAL(d)) { /* If there was a previous command. */ send_to_char("Is this command dependent on the success of the previous one? (y/n)\r\n", d->character); OLC_MODE(d) = ZEDIT_IF_FLAG; } else { /* 'if-flag' not appropriate. */ OLC_CMD(d).if_flag = 0; zedit_disp_arg1(d); } } break; /*-------------------------------------------------------------------*/ case ZEDIT_IF_FLAG: /* * Parse the input for the if flag, and goto next quiz. */ switch (*arg) { case 'y': case 'Y': OLC_CMD(d).if_flag = 1; break; case 'n': case 'N': OLC_CMD(d).if_flag = 0; break; default: send_to_char("Try again : ", d->character); return; } zedit_disp_arg1(d); break; /*-------------------------------------------------------------------*/ case ZEDIT_PROB: /* * Which command to change loadchance for? :/ */ pos = atoi(arg); if (isdigit(*arg) && start_change_command(d, pos)) { OLC_MODE(d) = ZEDIT_PROB2; OLC_ZONE(d)->age = 1; send_to_char("Chance of loading (0-100) : ", d->character); break; } else send_to_char("Invalid choice.\r\n", d->character); zedit_disp_menu(d); break; /*-------------------------------------------------------------------*/ case ZEDIT_PROB2: /* * Change the loadchance */ OLC_CMD(d).arg4 = MAX(0, MIN(100, atoi(arg))); OLC_MODE(d) = ZEDIT_MAIN_MENU; zedit_disp_menu(d); break; /*-------------------------------------------------------------------*/ case ZEDIT_ARG1: /* * Parse the input for arg1, and goto next quiz. */ if (!isdigit(*arg)) { send_to_char("Must be a numeric value, try again : ", d->character); return; } switch (OLC_CMD(d).command) { case 'M': if ((pos = real_mobile(atoi(arg))) >= 0) { OLC_CMD(d).arg1 = pos; zedit_disp_arg2(d); } else send_to_char("That mobile does not exist, try again : ", d->character); break; case 'O': case 'P': case 'E': case 'G': if ((pos = real_object(atoi(arg))) >= 0) { OLC_CMD(d).arg1 = pos; zedit_disp_arg2(d); } else send_to_char("That object does not exist, try again : ", d->character); break; case 'D': case 'R': default: /* * We should never get here. */ cleanup_olc(d, CLEANUP_ALL); mudlog("SYSERR: OLC: zedit_parse(): case ARG1: Ack!", BRF, LVL_IMMORT, TRUE); send_to_char("Oops...\r\n", d->character); break; } break; /*-------------------------------------------------------------------*/ case ZEDIT_ARG2: /* * Parse the input for arg2, and goto next quiz. */ if (!isdigit(*arg)) { send_to_char("Must be a numeric value, try again : ", d->character); return; } switch (OLC_CMD(d).command) { case 'M': case 'O': OLC_CMD(d).arg2 = atoi(arg); OLC_CMD(d).arg3 = real_room(OLC_NUM(d)); zedit_disp_arg4(d); break; case 'G': OLC_CMD(d).arg2 = atoi(arg); zedit_disp_arg3(d); break; case 'P': case 'E': OLC_CMD(d).arg2 = atoi(arg); zedit_disp_arg3(d); break; case 'D': pos = atoi(arg); /* * Count directions. */ while (*dirs[i] != '\n') i++; if ((pos < 0) || (pos > i)) send_to_char("Try again : ", d->character); else { OLC_CMD(d).arg2 = pos; zedit_disp_arg3(d); } break; case 'R': if ((pos = real_object(atoi(arg))) >= 0) { OLC_CMD(d).arg2 = pos; zedit_disp_arg4(d); } else send_to_char("That object does not exist, try again : ", d->character); break; default: /* * We should never get here, but just in case... */ cleanup_olc(d, CLEANUP_ALL); mudlog("SYSERR: OLC: zedit_parse(): case ARG2: Ack!", BRF, LVL_IMMORT, TRUE); send_to_char("Oops...\r\n", d->character); break; } break; /*-------------------------------------------------------------------*/ case ZEDIT_ARG3: /* * Parse the input for arg3, and go back to main menu. */ if (!isdigit(*arg)) { send_to_char("Must be a numeric value, try again : ", d->character); return; } switch (OLC_CMD(d).command) { case 'E': pos = atoi(arg); /* * Count number of wear positions. We could use NUM_WEARS, this is * more reliable. */ while (*equipment_types[i] != '\n') i++; if ((pos < 0) || (pos > i)) send_to_char("Try again : ", d->character); else { OLC_CMD(d).arg3 = pos; zedit_disp_menu(d); } break; case 'P': if ((pos = real_object(atoi(arg))) >= 0) { OLC_CMD(d).arg3 = pos; zedit_disp_arg4(d); } else send_to_char("That object does not exist, try again : ", d->character); break; case 'D': pos = atoi(arg); if ((pos < 0) || (pos > 2)) send_to_char("Try again : ", d->character); else { OLC_CMD(d).arg3 = pos; zedit_disp_menu(d); } break; case 'M': case 'O': case 'G': pos = atoi(arg); if (pos == 100) { OLC_CMD(d).arg3 = 0; zedit_disp_menu(d); } else if (pos > 0 && pos < 100) { OLC_CMD(d).arg3 = pos; zedit_disp_menu(d); } else send_to_char("Give a number between 0 and 100. Try again: ", d->character); break; case 'R': default: /* * We should never get here, but just in case... */ cleanup_olc(d, CLEANUP_ALL); mudlog("SYSERR: OLC: zedit_parse(): case ARG3: Ack!", BRF, LVL_IMMORT, TRUE); send_to_char("Oops...\r\n", d->character); break; } break; /*-------------------------------------------------------------------*/ case ZEDIT_ARG4: /*. Parse the input for arg4, and go back to main menu. */ if (!isdigit(*arg)) { send_to_char("Must be a numeric value, try again : ", d->character); return; } switch(OLC_CMD(d).command) { case 'E': case 'M': case 'O': case 'P': pos = atoi(arg); if (pos == 100) { OLC_CMD(d).arg4 = 0; zedit_disp_menu(d); } else if (pos > 0 && pos < 100) { OLC_CMD(d).arg4 = 101 - pos; zedit_disp_menu(d); } else send_to_char("Give a number between 1 and 100. Try again: ", d->character); break; case 'R': case 'D': default: /*. We should never get here .*/ cleanup_olc(d, CLEANUP_ALL); mudlog("SYSERR: OLC: zedit_parse(): case ARG3: Ack!", BRF, LVL_GOD, TRUE); break; } break; /*-------------------------------------------------------------------*/ case ZEDIT_ZONE_NAME: /* * Add new name and return to main menu. */ if (OLC_ZONE(d)->name) free(OLC_ZONE(d)->name); else log("SYSERR: OLC: ZEDIT_ZONE_NAME: no name to free!"); OLC_ZONE(d)->name = str_dup(arg); OLC_ZONE(d)->number = 1; zedit_disp_menu(d); break; /*-------------------------------------------------------------------*/ case ZEDIT_ZONE_BUILDERS: /* * Add new builders and return to main menu. */ if (OLC_ZONE(d)->builders) free(OLC_ZONE(d)->builders); OLC_ZONE(d)->builders = str_dup(arg); OLC_ZONE(d)->number = 1; zedit_disp_menu(d); break; /*-------------------------------------------------------------------*/ case ZEDIT_ZONE_RESET: /* * Parse and add new reset_mode and return to main menu. */ pos = atoi(arg); if (!isdigit(*arg) || (pos < 0) || (pos > 2)) send_to_char("Try again (0-2) : ", d->character); else { OLC_ZONE(d)->reset_mode = pos; OLC_ZONE(d)->number = 1; zedit_disp_menu(d); } break; /*-------------------------------------------------------------------*/ case ZEDIT_ZONE_LIFE: /* * Parse and add new lifespan and return to main menu. */ pos = atoi(arg); if (!isdigit(*arg) || (pos < 0) || (pos > 240)) send_to_char("Try again (0-240) : ", d->character); else { OLC_ZONE(d)->lifespan = pos; OLC_ZONE(d)->number = 1; zedit_disp_menu(d); } break; /*-------------------------------------------------------------------*/ case ZEDIT_ZONE_TOP: /* * Parse and add new top room in zone and return to main menu. */ if (OLC_ZNUM(d) == top_of_zone_table) OLC_ZONE(d)->top = MAX(OLC_ZNUM(d) * 100, MIN(32000, atoi(arg))); else OLC_ZONE(d)->top = MAX(OLC_ZNUM(d) * 100, MIN(zone_table[OLC_ZNUM(d) + 1].number * 100, atoi(arg))); zedit_disp_menu(d); break; /*-------------------------------------------------------------------*/ default: /* * We should never get here, but just in case... */ cleanup_olc(d, CLEANUP_ALL); mudlog("SYSERR: OLC: zedit_parse(): Reached default case!", BRF, LVL_IMMORT, TRUE); send_to_char("Oops...\r\n", d->character); break; } } /* * End of parse_zedit() */