/*********************************************************** Realms of Aurealis Online Creation System version 2.1 RoAOLCv2.1 - James Rhone aka Vall of RoA roaolc.c (online creation system - mob/room/object/house edit files) Adopted from Realms of Imagination's original version of OLC (7/95) ******** Heavily modified and expanded ******** *** BE AWARE OF ALL RIGHTS AND RESERVATIONS *** ******** Heavily modified and expanded ******** All rights reserved henceforth. Author: James Rhone Original Running Version: 0.5beta Please note that no guarantees are associated with any code from Realms of Aurealis. All code which has been released to the general public has been done so with an 'as is' pretense. Thanks to Jeremy Elson who has provided a stable base for Realms of Aurealis. RoA was originally created from a CircleMUD 2.2 base, back in the dark ages, when even that release was considered new wave. Since RoA is a perpetual BETA MUD, all code from it is also in BETA stages. I personally feel this is the best OLC ever made available for CircleMUD and its derivatives. My experienced builders agree. How you feel depends on how well you can fit into your mud. Good luck. There are no patch files, no step by step instructions, and no hand holders. All code written for Realms of Aurealis, including that contained in this file was written by me, James Rhone, so nobody is very familiar with it except me. Perhaps that will change. :) *** If you do not know C, I suggest getting to know it before you attempt to plug this into your mud. This is not a trivial addition to any mud and without someone there to guide you, you will inevitably get frustrated. ** note: zone OLC can be found in z_olc.c note: room OLC can be found in r_olc.c note: mobile OLC can be found in m_olc.c note: object OLC can be found in o_olc.c **********************************************************/ #include "conf.h" #include "sysdep.h" #include "structures.h" #include "comm.h" #include "interpreter.h" #include "acmd.h" #include "db.h" #include "utils.h" #include "mudlimits.h" #include "handler.h" #include "roaolc.h" #include "magic.h" #include "house.h" #include "lists.h" #include "global.h" /* for chars */ extern char *terrain_types[]; extern char *alter_types[]; extern char *room_bits[]; extern char *room_bits2[]; extern char *exit_bits[]; extern char *dirs[]; extern char *comm_dirs[]; extern const int rev_dir[]; void check_invalid_room(rmdata *r); extern exdescdata *correct_extra_descrips(exdescdata *ths); extern exdescdata *free_extra_descrips(exdescdata *ths); extern exdescdata *dupe_exdesc_over(exdescdata *ths); extern rtrig *free_rtriggers(rtrig *ths); ROA_MENU(redit_top_menu); ROA_MENU(redit_confirm_quit); ROA_MENU(redit_confirm_save); ROA_MENU(hedit_top_menu); ROA_MENU(hedit_confirm_quit); ROA_MENU(hedit_confirm_save); ROA_MENU(confirm_room_wipe); // given a ptr, vnum, and rnum, dont allocate just default it void default_room_out(rmdata *room, int vnum) { room->number = vnum; room->zone = vnum / 100; room->name = STR_DUP("(def)"); room->description = STR_DUP("(def)\n\r"); room->exdesc = NULL; room->max_contains= -1; room->owner = -1; room->alter_type = 0; room->numdice = 0; room->sizedice = 0; room->sound_file = NULL; room->music_timer = -1; FLOATTO(room) = -1; DRIFTTO(room) = -1; DROPTO(room) = -1; RPROC_BEG(room) = NULL; RPROC_CUR(room) = NULL; RTARGET_CHAR(room) = NULL; RTARGET_OBJ(room) = NULL; RTRIGS(room) = NULL; } // wax and null all dirs on a room re: wax room void free_room_dirs(rmdata *trg) { int i; for (i=0; i < NUM_OF_DIRS; i++) if (trg->dir_option[i]) { FREENULL(trg->dir_option[i]->keyword); FREENULL(trg->dir_option[i]->exit_descr); // Nuke all exit messages, as well. 03/24/98 -callahan FREENULL(trg->dir_option[i]->enter); FREENULL(trg->dir_option[i]->oenter); FREENULL(trg->dir_option[i]->drop); FREENULL(trg->dir_option[i]->odrop); FREENULL(trg->dir_option[i]); } } // make another copy of src dirs on trg room void dupe_room_dirs(rmdata *src, rmdata *trg) { int i; for (i=0; i < NUM_OF_DIRS; i++) if (src->dir_option[i]) { CREATE(trg->dir_option[i], rmdirdata, 1); *trg->dir_option[i] = *src->dir_option[i]; if (src->dir_option[i]->keyword) trg->dir_option[i]->keyword = STR_DUP(src->dir_option[i]->keyword); else trg->dir_option[i]->keyword = NULL; if (src->dir_option[i]->exit_descr) trg->dir_option[i]->exit_descr = STR_DUP(src->dir_option[i]->exit_descr); else trg->dir_option[i]->exit_descr = NULL; // Do stuff for exit messages... 03/24/98 -callahan if (src->dir_option[i]->enter) trg->dir_option[i]->enter = STR_DUP(src->dir_option[i]->enter); else trg->dir_option[i]->enter = NULL; if (src->dir_option[i]->oenter) trg->dir_option[i]->oenter = STR_DUP(src->dir_option[i]->oenter); else trg->dir_option[i]->oenter = NULL; if (src->dir_option[i]->drop) trg->dir_option[i]->drop = STR_DUP(src->dir_option[i]->drop); else trg->dir_option[i]->drop = NULL; if (src->dir_option[i]->odrop) trg->dir_option[i]->odrop = STR_DUP(src->dir_option[i]->odrop); else trg->dir_option[i]->odrop = NULL; } else trg->dir_option[i] = NULL; } void free_room_randoms(rmdata *trg) { int i; for (i = 0; i < 5; i++) FREENULL(trg->randoms[i]); } void dupe_room_randoms(rmdata *src, rmdata *trg) { int i; for(i = 0; i < 5; i++) if (src->randoms[i]) trg->randoms[i] = STR_DUP(src->randoms[i]); else trg->randoms[i] = NULL; } // this OBLITERATES a room, it does not (repeat) does not // remove itself from the world array if it is a part of it // this is intended to wax ROOM_EDITTED ptrs on char after // an edit // now also wax sound_file...2/21/98 -jtrhone void wax_room(rmdata *trg) { FREENULL(trg->name); FREENULL(trg->description); FREENULL(trg->sound_file); trg->exdesc = free_extra_descrips(trg->exdesc); free_room_dirs(trg); free_room_randoms(trg); // have to do rprocs/trigs 6/5/98 -jtrhone RTRIGS(trg) = free_rtriggers(RTRIGS(trg)); FREENULL(RPROC_BEG(trg)); RPROC_CUR(trg) = NULL; FREENULL(RTARGET_CHAR(trg)); FREENULL(RTARGET_OBJ(trg)); } // wipe_room is a builder tool to bamph an existing room, it frees everything // and defaults the room out... void wipe_room(chdata *ch, int room) { if (INVALID_ROOM(room)) { send_to_char("Invalid room...\n\r",ch); return; } wax_room(&world[room]); default_room_out(&world[room], world[room].number); } // dupe over an rtrig list to a whole new one // return ptr to new one 6/5/98 -jtrhone rtrig *dupe_rtrigs_over(rtrig *src) { rtrig *e_new, *tmp, *trg = NULL; for (tmp = src; tmp; tmp = tmp->next) { CREATE(e_new, rtrig, 1); e_new->trigger = str_dup(tmp->trigger); e_new->reaction = str_dup(tmp->reaction); e_new->next = trg; trg = e_new; } return trg; } // dupe EVERYTHING over, first the strings from trg get // waxed, and extra descrip list // then it gets a copy of all src's things void dupe_room_over(rmdata *src, rmdata *trg) { chdata *people; obdata *contents; byte light; sh_int num_present; int trans_present; int location; byte to_port; byte wait_time; // MUST save data IN USE on rooms before we transfer // we will set this data back after we're done -roa people = trg->people; contents = trg->contents; light = trg->light; num_present = trg->num_present; trans_present = trg->trans_present; location = trg->location; to_port = trg->to_port; wait_time = trg->wait_time; wax_room(trg); *trg = *src; trg->name = STR_DUP(src->name); trg->description = STR_DUP(src->description); trg->sound_file = STR_DUP(src->sound_file); trg->exdesc = dupe_exdesc_over(src->exdesc); dupe_room_dirs(src, trg); dupe_room_randoms(src, trg); // add rtrigs...rprocs 6/5/98 -jtrhone RTRIGS(trg) = dupe_rtrigs_over(RTRIGS(src)); RPROC_BEG(trg) = STR_DUP(RPROC_BEG(src)); RPROC_CUR(trg) = RPROC_BEG(trg); RTARGET_CHAR(trg) = STR_DUP(RTARGET_CHAR(src)); RTARGET_OBJ(trg) = STR_DUP(RTARGET_OBJ(src)); // now retrieve the saved data we didnt wanna alter trg->people = people; trg->contents = contents; trg->light = light; trg->num_present = num_present; trg->trans_present = trans_present; trg->location = location; trg->to_port = to_port; trg->wait_time = wait_time; } // build another room in current zone_locked if one available // from direction given and room currently in // example: rbuild north, finds next slot in zone, builds room connects // it via a north exit, gives opposite exits from new room to current room ACMD(do_rbuild) { int vroom, rroom, zone; int top; int dir; rmdata *newroom; rmdata *thisroom; if (IS_NPC(ch)) return; if (!ch->pc_specials->saved.zone_locked) { send_to_char("You must lock a zone first.\n\r",ch); return; } zone = world[ch->in_room].zone; if (zone != ch->pc_specials->saved.zone_locked) { send_to_char("You must %6rbuild%0 from the zone you have locked.\n\r",ch); return; } if (ZONE_FREED(zone)) { send_to_char("The rooms from this zone are not stored in memory.\n\r",ch); send_to_char("Use %Bzlock%0 to load them into memory.\n\r",ch); return; } top = zone_table[zone].top; for (vroom = zone * 100; vroom <= top; vroom++) if ((rroom = real_room(vroom)) <= 0) break; if (vroom > top) { send_to_char("No available rooms in this zone.\n\r",ch); return; } if (!WLD_SLOTS_LEFT) { send_to_char("Max room creation for this runtime reached.\n\r",ch); send_to_char("You must wait for reboot to create more protos.\n\r",ch); mudlog("!SYSWAR!: World padding exhausted. Suggest immediate reboot.", BRF, LEV_IMM, TRUE); return; } // parse arg dir and check it against existing exits -roa one_argument(argument, arg); if (!*arg) { send_to_char("Usage: rbuild <direction>.\n\r",ch); return; } if ((dir = search_block(arg, comm_dirs, FALSE)) == -1 || dir >= NUM_OF_DIRS) { send_to_char("Valid dirs: N, S, E, W, NE, NW, SE, SW, U, D.\n\r",ch); return; } if (EXIT(ch, dir)) { send_to_char("That direction exists already.\n\r",ch); return; } newroom = &world[top_of_world]; default_room_out(newroom, vroom); top_of_world++; // make sure all the strings are in there -roa check_invalid_room(newroom); thisroom = &world[ch->in_room]; // create dir to new room CREATE(thisroom->dir_option[dir], rmdirdata, 1); thisroom->dir_option[dir]->keyword = STR_DUP("(def)"); thisroom->dir_option[dir]->exit_descr = STR_DUP("(def)\n\r"); // Exit messages. 03/24/98 -callahan thisroom->dir_option[dir]->enter = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->oenter = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->drop = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->odrop = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->to_room_virtual = vroom; thisroom->dir_option[dir]->to_room = real_room(vroom); // calc opposite dir dir = rev_dir[dir]; // create dir from new room to thisroom CREATE(newroom->dir_option[dir], rmdirdata, 1); newroom->dir_option[dir]->keyword = STR_DUP("(def)"); newroom->dir_option[dir]->exit_descr = STR_DUP("(def)\n\r"); // Exit messages. 03/24/98 -callahan newroom->dir_option[dir]->enter = STR_DUP("(def)\n\r"); newroom->dir_option[dir]->oenter = STR_DUP("(def)\n\r"); newroom->dir_option[dir]->drop = STR_DUP("(def)\n\r"); newroom->dir_option[dir]->odrop = STR_DUP("(def)\n\r"); newroom->dir_option[dir]->to_room_virtual = thisroom->number; newroom->dir_option[dir]->to_room = real_room(thisroom->number); sprintf(buf, "PLRUPD: %s has rbuilt room #%d", GET_NAME(ch), newroom->number); mudlog(buf, NRM, GET_LEVEL(ch), TRUE); } // connect room yer in to another existing room with rev_dir connection ACMD(do_rconnect) { int vroom, rroom, zone; int dir; int rdir; rmdata *otherroom; rmdata *thisroom; BOOL ok = FALSE; if (IS_NPC(ch)) return; if (ROOM_FLAGGED2(ch->in_room, HOUSE)) ok = TRUE; if (!ch->pc_specials->saved.zone_locked && !ok) { send_to_char("You must lock a zone first.\n\r",ch); return; } zone = world[ch->in_room].zone; if (zone != ch->pc_specials->saved.zone_locked && !ok) { send_to_char("You must rconnect from the zone you have locked.\n\r",ch); return; } if (ZONE_FREED(zone)) { send_to_char("The rooms from this zone are not stored in memory.\n\r",ch); send_to_char("Use %Bzlock%0 to load them into memory.\n\r",ch); return; } // parse arg dir and check it against existing exits -roa half_chop(argument, arg, buf2); if (!*arg || !*buf2 || !is_number(buf2)) { send_to_char("Usage: rconnect <direction> <room vnum>.\n\r",ch); return; } if ((dir = search_block(arg, comm_dirs, FALSE)) == -1 || dir >= NUM_OF_DIRS) { send_to_char("Valid dirs: N, S, E, W, NE, NW, SE, SW, U, D.\n\r",ch); return; } if (EXIT(ch, dir)) { send_to_char("That direction exists already.\n\r",ch); return; } vroom = atoi(buf2); // now make sure other room is real and doesnt have that rev_dir if ((rroom = real_room(vroom)) < 0) { send_to_char("That room doesn't exist.\n\r",ch); return; } if (world[rroom].zone != zone && !ok) { send_to_char("Both rooms must be in the locked zone.\n\r",ch); return; } // calc opposite dir rdir = rev_dir[dir]; if (DIR(rroom, rdir)) { send_to_char("Reverse dir exists in target room.\n\r",ch); return; } otherroom = &world[rroom]; thisroom = &world[ch->in_room]; // create dir to new room CREATE(thisroom->dir_option[dir], rmdirdata, 1); thisroom->dir_option[dir]->keyword = STR_DUP("(def)"); thisroom->dir_option[dir]->exit_descr = STR_DUP("(def)\n\r"); // Exit messages. 03/24/98 -callahan thisroom->dir_option[dir]->enter = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->oenter = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->drop = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->odrop = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->to_room_virtual = vroom; thisroom->dir_option[dir]->to_room = rroom; // create dir from new room to thisroom CREATE(otherroom->dir_option[rdir], rmdirdata, 1); otherroom->dir_option[rdir]->keyword = STR_DUP("(def)"); otherroom->dir_option[rdir]->exit_descr = STR_DUP("(def)\n\r"); // Exit messages. 03/24/98 -callahan thisroom->dir_option[dir]->enter = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->oenter = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->drop = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->odrop = STR_DUP("(def)\n\r"); otherroom->dir_option[rdir]->to_room_virtual = thisroom->number; otherroom->dir_option[rdir]->to_room = real_room(thisroom->number); sprintf(buf, "PLRUPD: %s has rconnected room #%d to room #%d", GET_NAME(ch), thisroom->number, otherroom->number); mudlog(buf, NRM, GET_LEVEL(ch), TRUE); if (ok) send_to_char("Remember to %B%6wldsave%0 both zones.\n\r",ch); } /* add extra menu for rproc string 6/5/98 -jtrhone*/ ROA_MENU(redit_rproc_menu) { char buf[20000]; char *p; int field; rmdata *r = ROOM_EDITTED(ch); if (!input_str) { menu_title_send("RoomEdit RoomProc Menu", ch); if (IS_SET(r->room_flags, RPROC)) { send_to_char("%B--NOTE--:%0 Parse commands with CR|LF.\n\r",ch); sprintf(buf, "1.) %%6Room Proc Command list%%0:\n\r%s\n\r", RPROC_BEG(r)); page_string(ch->desc, buf, TRUE); } else send_to_char(" %B%5ROOMPROC rooms only.%0\n\r",ch); send_to_char("\n\r", ch); MENU_PROMPT(ch) = "Enter field number to change or 0 to end: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) field = atoi(p); else field = 0; switch (field) { case 0: menu_back(ch); return; break; case 1: if (IS_SET(r->room_flags, RPROC)) do_var_string_arg(ch, "Enter command list (each command on newline) (@) :\n\r", &RPROC_BEG(r), MAX_STRING_LENGTH - 100); break; default: send_to_char("That field cannot be changed.\n\r", ch); break; } } ROA_MENU(confirm_room_wipe) { char buf[MAX_STRING_LENGTH]; char *p; if (!input_str) { MENU_PROMPT(ch) = "Confirm room wipe (YES/no)? "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (!p || strncasecmp("no", p, strlen(p)) != 0) { send_to_char("Wipe confirmed...\n\r",ch); // room rnum was saved as index2 wipe_room(ch, ch->pc_specials->index2); ch->pc_specials->index2 = -1; } else send_to_char("Wipe not confirmed...\n\r",ch); MENU_PROMPT(ch) = NULL; MENU_HANDLER(ch) = NULL; MENU_DEPTH(ch) = 0; } ACMD(do_wipe_room) { int room = ch->in_room; if (INVALID_ROOM(room)) { send_to_char("Invalid room.\n\r",ch); return; } if (!ZONE_LOCKED(world[room].zone)) { send_to_char("Zone must be locked...\n\r",ch); return; } MENU_HANDLER_ARG(ch) = (void *) 0; ch->pc_specials->index2 = room; menu_jump(ch, confirm_room_wipe); } ACMD(do_redit) { char buf[512]; int vnum, rnum, zone; if (IS_NPC(ch)) return; one_argument(argument, buf); if (!*buf) vnum = world[ch->in_room].number; else vnum = atoi(buf); if (vnum <= 0) { send_to_char("usage: REDIT <room VNUM>\n\r", ch); return; } zone = real_zone(vnum / 100); if (!olc_perms(ch, LEV_CIMP, zone)) return; if (GET_LEVEL(ch) < LEV_AIMP) if (!ZONE_FLAGGED(zone, Z_LOCKED) && zone != HOUSE_ZONE) { send_to_char("You must ZLOCK that zone before you can edit it.\n\r",ch); return; } if (ZONE_FREED(zone)) { send_to_char("That zone is freed from memory. Zlock it first.\n\r",ch); return; } // editting existing room if ((rnum = real_room(vnum)) >= 0) { CREATE(ROOM_EDITTED(ch), rmdata, 1); dupe_room_over(&world[rnum], ROOM_EDITTED(ch)); } else // creating new room { if (!WLD_SLOTS_LEFT) { send_to_char("Max room creation for this runtime reached.\n\r",ch); send_to_char("You must wait for reboot to create more protos.\n\r",ch); mudlog("!SYSWAR!: World padding exhausted. Suggest immediate reboot.", BRF, LEV_IMM, TRUE); return; } CREATE(ROOM_EDITTED(ch), rmdata, 1); default_room_out(ROOM_EDITTED(ch), vnum); } SET_BIT(PLR_FLAGS(ch), PLR_BUILDING); MENU_DEPTH(ch) = 0; ch->pc_specials->field_changed = FALSE; menu_jump(ch, redit_top_menu); } ROA_MENU(redit_add_extradesc_menu) { rmdata *r = ROOM_EDITTED(ch); exdescdata *e; switch ((int) MENU_HANDLER_ARG(ch)) { case 0: // create and insert into list CREATE(e, exdescdata, 1); e->next = r->exdesc; r->exdesc = e; MENU_HANDLER_ARG(ch) = (void *) 1; do_string_arg(ch, "Enter keywords: ", &e->keyword, ""); break; case 1: MENU_HANDLER_ARG(ch) = (void *) 2; do_long_string_arg(ch, "Enter new description (@):\n\r", &r->exdesc->description); break; default: menu_back(ch); break; } } void delete_room_extra(chdata *ch) { rmdata *r = ROOM_EDITTED(ch); exdescdata *e, *temp; int i; /* advance to the one we want to delete */ for (i = 1, e = r->exdesc; (i < (int) MENU_RETURN(ch)) && e; e = e->next, i++) ; if (e) { REMOVE_FROM_LIST(e, r->exdesc, next); FREENULL(e->keyword); FREENULL(e->description); FREENULL(e); } MENU_RETURN(ch) = 0; } ROA_MENU(redit_extradesc_menu) { char buf[MAX_STRING_LENGTH]; rmdata *r = ROOM_EDITTED(ch); exdescdata *e = NULL; char *p; int i; if (!input_str) { /* if we have one to delete from earlier */ if ((int) MENU_RETURN(ch) > 0) delete_room_extra(ch); menu_title_send("Extra Descrip Main Menu", ch); for (i = 1, e = r->exdesc; e; e = e->next, i++) { sprintf(buf, "%2d.) %%6%s%%0\n\r", i, e->keyword); S2C(); sprintf(buf, " %s\n\r", e->description); S2C(); } i--; MENU_PROMPT(ch) = "(D)elete, (A)dd, (Q)uit/<return>: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) { if (!strncasecmp("delete", p, strlen(p))) { if (!r->exdesc) GET_INTEGER_ARG(ch, "No descriptions to delete (hit return): ", MENU_RETURN(ch), 0, 0); else { for (i = 1, e = r->exdesc; e; e = e->next, i++) ; GET_INTEGER_ARG(ch, "Enter desc number to delete (return for none): ", MENU_RETURN(ch), 1, i-1); } } else if (!strncasecmp("add", p, strlen(p))) { menu_push(ch); MENU_HANDLER_ARG(ch) = (void *) 0; menu_jump(ch, redit_add_extradesc_menu); } else if (!strncasecmp("quit", p, strlen(p)) || !p || !atoi(p)) { menu_back(ch); return; } } else if (!p || !atoi(p)) { menu_back(ch); return; } } void validate_exit(rmdirdata *d) { if (!EXIT_ISDOOR(d)) UNFLAG_EXIT(d, EX_CLOSED | EX_LOCKED | EX_PICKPROOF | EX_AUTOSHUT | EX_AUTOLOCK); if (!EXIT_FLAGGED(d, EX_AUTOSHUT)) UNFLAG_EXIT(d, EX_AUTOLOCK); } ROA_MENU(redit_exit_menu) { char buf[MAX_STRING_LENGTH]; char *p; int field; int i; rmdata *r = ROOM_EDITTED(ch); int dir = (int) MENU_HANDLER_ARG(ch); rmdirdata *d = r->dir_option[dir]; if (!input_str) { menu_title_send("Exit Edit Menu", ch); if (d->to_room_virtual >= 0) { if ((i = real_room(d->to_room_virtual)) < 0) { sprintf(buf, "Room %d does not exist.\n\n\r", d->to_room_virtual); S2C(); } d->to_room = i; d->to_room_virtual = -1; } sprintf(buf, "%%6Direction %%B%s%%0\n\r", dirs[dir]); S2C(); sprintf(buf, " 1.) %%6Keyword%%0 : %s\n\r", d->keyword); S2C(); sprintf(buf, " 2.) %%6Description%%0 :\n\r%s", d->exit_descr); S2C(); // Exit messages... 03/24/98 -callahan sprintf(buf, " 3.) %%6Enter Msg%%0 :\n\r%s", d->enter ? d->enter : "None.\n\r"); S2C(); sprintf(buf, " 4.) %%6OEnter Msg%%0 :\n\r%s", d->oenter ? d->oenter : "None.\n\r"); S2C(); sprintf(buf, " 5.) %%6Drop Msg%%0 :\n\r%s", d->drop ? d->drop : "None.\n\r"); S2C(); sprintf(buf, " 6.) %%6ODrop Msg%%0 :\n\r%s", d->odrop ? d->odrop : "None.\n\r"); S2C(); validate_exit(d); sprintbit(d->exinfo, exit_bits, buf2); sprintf(buf, " 7.) %%6Exit Flags%%0 : %%5%s%%0\n\r", buf2); S2C(); sprintf(buf, " 8.) %%6Key VNUM%%0 : %d\n\r", d->key); S2C(); sprintf(buf, " 9.) %%6To Room VNUM%%0: %d\n\r", world[d->to_room].number); S2C(); send_to_char("\n\r10.) %1Delete this exit%0\n\n\r", ch); MENU_PROMPT(ch) = "Enter field number to change or 0 to end: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) field = atoi(p); else field = 0; switch (field) { case 0: menu_back(ch); return; break; case 10: FREENULL(d->keyword); FREENULL(d->exit_descr); // Exit messages. 03/24/98 -callahan FREENULL(d->enter); FREENULL(d->oenter); FREENULL(d->drop); FREENULL(d->odrop); FREENULL(d); r->dir_option[dir] = NULL; menu_back(ch); return; break; case 1: do_string_arg(ch, "Enter exit keyword: ", &d->keyword, ""); break; case 2: do_long_string_arg(ch, "Enter exit description (@):\n\r", &d->exit_descr); break; // Exit messages. 03/24/98 -callahan case 3: do_long_string_arg(ch, "Enter message player sees upon entering the exit (@):\n\r", &d->enter); break; case 4: do_long_string_arg(ch, "Enter message others see when player enters the exit (@):\n\r", &d->oenter); break; case 5: do_long_string_arg(ch, "Enter message player sees when dropped into the next room (@):\n\r", &d->drop); break; case 6: do_long_string_arg(ch, "Enter message others in next room see when player arrives (@):\n\r", &d->odrop); break; case 7: toggle_menu(ch, "Enter exit bit to toggle: ", &d->exinfo, exit_bits); break; case 8: GET_INTEGER_ARG(ch, "Enter Key VNUM: ", d->key, -1, 99999); break; case 9: GET_INTEGER_ARG(ch, "Enter Room VNUM: ", d->to_room_virtual, 0, 99999); break; default: send_to_char("That field cannot be changed, yet.\n\r", ch); break; } } ROA_MENU(redit_string_menu) { char buf[MAX_STRING_LENGTH]; char *p; int field; rmdata *r = ROOM_EDITTED(ch); int i; char *trans_strs[] = { "Keywords", "Short Description", "Long Description", "Movement Message", "Arrival Message" }; if (!input_str) { if (IS_SET(r->room_flags, RANDOM)) { menu_title_send("Room Random Menu", ch); for (i = 0; i < 5; i++) { sprintf(buf, "%d.) %%6Random%d%%0: %s\n\r", i+1, i+1, r->randoms[i]); S2C(); } } else if (IS_SET(r->room_flags2, TRANSPORT)) { menu_title_send("Transport String Menu", ch); for (i = 0; i < 5; i++) { if (i == 3) sprintf(buf, "%d.) %%6%s%%0:\n\r%s <%%Bdir%%0>.\n\r", i+1, trans_strs[i], r->randoms[i]); else sprintf(buf, "%d.) %%6%s%%0:\n\r%s\n\r", i+1, trans_strs[i], r->randoms[i]); S2C(); send_to_char("\n\r",ch); } } else send_to_char(" %B%5Room must be flagged RANDOM or TRANSPORT.%0\n\r",ch); send_to_char("\n\r", ch); MENU_PROMPT(ch) = "Enter field number to change or 0 to end: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) field = atoi(p); else field = 0; switch (field) { case 0: menu_back(ch); return; break; case 1: if (IS_SET(r->room_flags2, TRANSPORT)) do_string_arg(ch, "Enter transport keywords:\n\r", &TRANS_KEYWORDS(r), ""); else do_long_string_arg(ch, "Enter Room Random 1 (@):\n\r", &r->randoms[0]); break; case 2: if (IS_SET(r->room_flags2, TRANSPORT)) do_string_arg(ch, "Enter transport short descr:\n\r", &TRANS_SHDESC(r), ""); else do_long_string_arg(ch, "Enter Room Random 2 (@):\n\r", &r->randoms[1]); break; case 3: if (IS_SET(r->room_flags2, TRANSPORT)) do_long_string_arg(ch, "Enter transport long description (@):\n\r", &TRANS_LDESC(r)); else do_long_string_arg(ch, "Enter Room Random 3 (@):\n\r", &r->randoms[2]); break; case 4: if (IS_SET(r->room_flags2, TRANSPORT)) do_string_arg(ch, "Enter transport movement message:\n\r", &r->randoms[3], ""); else do_long_string_arg(ch, "Enter Room Random 4 (@):\n\r", &r->randoms[3]); break; case 5: if (IS_SET(r->room_flags2, TRANSPORT)) do_long_string_arg(ch, "Enter transport arrival message (@):\n\r", &r->randoms[4]); else do_long_string_arg(ch, "Enter Room Random 5 (@):\n\r", &r->randoms[4]); break; default: send_to_char("That field cannot be changed.\n\r", ch); break; } } ROA_MENU(redit_transport_menu) { char buf[MAX_STRING_LENGTH]; char *p; int field; rmdata *r = ROOM_EDITTED(ch); if (!input_str) { if (IS_SET(r->room_flags2, TRANSPORT)) { menu_title_send("Transport Data Menu", ch); sprintf(buf, "1.) %%6Start Location|Port1%%0: %d\n\r", r->portals[0]); S2C(); sprintf(buf, "2.) %%6Port2%%0: %d\n\r", r->portals[1]); S2C(); sprintf(buf, "3.) %%6Port3%%0: %d\n\r", r->portals[2]); S2C(); sprintf(buf, "4.) %%6Port4%%0: %d\n\r", r->portals[3]); S2C(); sprintf(buf, "5.) %%6TDockWait%%0 : %d\n\r", r->dock_wait); S2C(); sprintf(buf, "6.) %%6TTravelWait%%0: %d\n\r", r->travel_wait); S2C(); sprintf(buf, "7.) %%6TTicketNum%%0 : %d\n\r", r->ticket_num); S2C(); } else send_to_char(" %B%5Room must be flagged TRANSPORT.%0\n\r",ch); send_to_char("\n\r", ch); MENU_PROMPT(ch) = "Enter field number to change or 0 to end: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) field = atoi(p); else field = 0; switch (field) { case 0: menu_back(ch); return; break; case 1: GET_INTEGER_ARG(ch, "Enter VNUM of Starting Location (-1 for none): ", r->portals[0], -1, 99999); break; case 2: GET_INTEGER_ARG(ch, "Enter VNUM of port2 (-1 for none): ", r->portals[1], -1, 99999); break; case 3: GET_INTEGER_ARG(ch, "Enter VNUM of port3 (-1 for none): ", r->portals[2], -1, 99999); break; case 4: GET_INTEGER_ARG(ch, "Enter VNUM of port4 (-1 for none): ", r->portals[3], -1, 99999); break; case 5: GET_INTEGER_ARG(ch, "Enter quarterticks to wait at port: ", r->dock_wait, 0, 127); break; case 6: GET_INTEGER_ARG(ch, "Enter quarterticks to wait during travel: ", r->travel_wait, 0, 127); break; case 7: GET_INTEGER_ARG(ch, "Enter VNUM of boarding pass (-1 for none): ", r->ticket_num, -1, 99999); break; default: send_to_char("That field cannot be changed.\n\r", ch); break; } } ROA_MENU(redit_portal_menu) { char buf[MAX_STRING_LENGTH]; char *p; int field; rmdata *r = ROOM_EDITTED(ch); int i; if (!input_str) { if (IS_SET(r->room_flags, PORTAL)) { menu_title_send("Portal Data Menu", ch); for (i = 0; i < 4; i++) { sprintf(buf, "%d.) %%6Portal %d%%0: %d\n\r",i+1, i+1, r->portals[i]); S2C(); } } else send_to_char(" %B%5Room must be flagged PORTAL.%0\n\r",ch); send_to_char("\n\r", ch); MENU_PROMPT(ch) = "Enter field number to change or 0 to end: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) field = atoi(p); else field = 0; switch (field) { case 0: menu_back(ch); return; break; case 1: GET_INTEGER_ARG(ch, "Enter Room VNUM to teleport to (-1 for none): ", r->portals[0], -1, 99999); break; case 2: GET_INTEGER_ARG(ch, "Enter Room VNUM to teleport to (-1 for none): ", r->portals[1], -1, 99999); break; case 3: GET_INTEGER_ARG(ch, "Enter Room VNUM to teleport to (-1 for none): ", r->portals[2], -1, 99999); break; case 4: GET_INTEGER_ARG(ch, "Enter Room VNUM to teleport to (-1 for none): ", r->portals[3], -1, 99999); break; default: send_to_char("That field cannot be changed.\n\r", ch); break; } } ROA_MENU(redit_alter_menu) { char buf[MAX_STRING_LENGTH]; char *p; int field; rmdata *r = ROOM_EDITTED(ch); if (!input_str) { if (IS_SET(r->room_flags, ALTERHIT | ALTERMOVE | ALTERMANA) || IS_SET(r->room_flags, DEATH | FLY_DEATH)) { menu_title_send("Alteration Data Menu", ch); send_to_char("%B%6Note:%0 If room flagged DEATH or FLY_DEATH:\n\r",ch); send_to_char(" A value of 0 in either %B%6size%0 or %B%6num%0 " "will be instant death.\n\r",ch); send_to_char(" Any other dice roll will deduct that dice roll " "from the character.\n\r",ch); sprintf(buf, "\n\r1.) %%6Num dice%%0 : %d\n\r", r->numdice); S2C(); sprintf(buf, "2.) %%6Size dice%%0: %d\n\r", r->sizedice); S2C(); if (IS_SET(r->room_flags, DEATH) || IS_SET(r->room_flags,FLY_DEATH)) send_to_char("3.) %6Alter Type%0: Decrease, DEATH || FLY_DEATH set.\n\r",ch); else { sprinttype(r->alter_type, alter_types, buf2); sprintf(buf, "3.) %%6Alter Type%%0: %s\n\r",buf2); S2C(); } } else send_to_char(" %B%5Room must be flagged ALTER--- .%0\n\r",ch); send_to_char("\n\r", ch); MENU_PROMPT(ch) = "Enter field number to change or 0 to end: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) field = atoi(p); else field = 0; switch (field) { case 0: menu_back(ch); return; break; case 1: if (IS_SET(r->room_flags, DEATH) || IS_SET(r->room_flags,FLY_DEATH)) GET_INTEGER_ARG(ch, "Enter number of dice: ", r->numdice, 0, 100); else GET_INTEGER_ARG(ch, "Enter number of dice: ", r->numdice, 0, 10); break; case 2: if (IS_SET(r->room_flags, DEATH) || IS_SET(r->room_flags,FLY_DEATH)) GET_INTEGER_ARG(ch, "Enter size of dice: ", r->sizedice, 0, 100); else GET_INTEGER_ARG(ch, "Enter size of dice: ", r->sizedice, 0, 10); break; case 3: if (IS_SET(r->room_flags, DEATH) || IS_SET(r->room_flags,FLY_DEATH)) send_to_char("Room flagged DEATH or FLY_DEATH, auto decrease.\n\r",ch); else get_integer_list(ch, "Enter number of the desired alteration: ", &r->alter_type, sizeof(r->alter_type), alter_types); break; default: send_to_char("That field cannot be changed.\n\r", ch); break; } } ROA_MENU(redit_main_exit_menu) { char buf[MAX_STRING_LENGTH]; char *p; int field; int i; rmdata *r = ROOM_EDITTED(ch); if (!input_str) { menu_title_send("Main Exit Menu", ch); for (i = 0; i < NUM_OF_DIRS; i++) { sprintf(buf, "%2d.) %%6Exit%%0 %%5%5s%%0, ", i + 1, dirs[i]); S2C(); if (r->dir_option[i]) { sprintbit(r->dir_option[i]->exinfo, exit_bits, buf2); sprintf(buf, "To: %%6%d%%0, Key#: %%6%d%%0, \n\r\tExFlags: %%5%s%%0\n\r", world[r->dir_option[i]->to_room].number, r->dir_option[i]->key, buf2); S2C(); } else send_to_char("\n\r", ch); } send_to_char("\n\r", ch); MENU_PROMPT(ch) = "Enter field number to change or 0 to end: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) field = atoi(p); else field = 0; switch (field) { case 0: menu_back(ch); return; break; case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9: case 10: /* directions */ i = field - 1; if (!r->dir_option[i]) { CREATE(r->dir_option[i], rmdirdata, 1); r->dir_option[i]->keyword = STR_DUP("(def)"); r->dir_option[i]->exit_descr = STR_DUP("(def)\n\r"); // Exit messages. 03/24/98 -callahan r->dir_option[i]->enter = STR_DUP("(def)\n\r"); r->dir_option[i]->oenter = STR_DUP("(def)\n\r"); r->dir_option[i]->drop = STR_DUP("(def)\n\r"); r->dir_option[i]->odrop = STR_DUP("(def)\n\r"); r->dir_option[i]->exinfo = 0; // no bitvector } r->dir_option[i]->to_room_virtual = -1; menu_push(ch); MENU_RETURN(ch) = 0; MENU_HANDLER_ARG(ch) = (void *) i; menu_jump(ch, redit_exit_menu); break; default: send_to_char("That field cannot be changed.\n\r", ch); break; } } ROA_MENU(redit_environment_menu) { char buf[MAX_STRING_LENGTH]; char *p; int field; rmdata *r = ROOM_EDITTED(ch); if (!input_str) { menu_title_send("Environment Control Menu", ch); if (r->terrain_type == TERRAIN_UWATER) { if (FLOATTO(r) <= 0) strcpy(buf2,"(none)"); else strcpy(buf2, ""); sprintf(buf, "1.) %%6Float to room%%0: %d (%s)\n\r", FLOATTO(r), buf2); S2C(); } else FLOATTO(r) = -1; if ((r->terrain_type == TERRAIN_UWATER) || (r->terrain_type == TERRAIN_AIR) || (r->terrain_type == TERRAIN_WATER_NOSWIM) || (r->terrain_type == TERRAIN_WATER_SWIM)) { if (DROPTO(r) <= 0) strcpy(buf2,"(none)"); else strcpy(buf2, ""); sprintf(buf, "2.) %%6Drop to room%%0: %d (%s)\n\r",DROPTO(r), buf2); S2C(); } else DROPTO(r) = -1; if (IS_SET(r->room_flags, WINDY) || (r->terrain_type == TERRAIN_UWATER) || (r->terrain_type == TERRAIN_WATER_NOSWIM) || (r->terrain_type == TERRAIN_WATER_SWIM)) { if (DRIFTTO(r) == -1) strcpy(buf2,"(none)"); else if (DRIFTTO(r) == 0) strcpy(buf2,"(random)"); else strcpy(buf2, ""); sprintf(buf, "3.) %%6Drift to room%%0: %d %s\n\r", DRIFTTO(r), buf2); S2C(); } else DRIFTTO(r) = -1; send_to_char("\n\r", ch); MENU_PROMPT(ch) = "Enter field number to change or 0 to end: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) field = atoi(p); else field = 0; switch (field) { case 0: menu_back(ch); return; break; case 1: if (r->terrain_type != TERRAIN_UWATER) break; GET_INTEGER_ARG(ch, "Enter Room VNUM to float to (-1 for none): ", FLOATTO(r), -1, 99999); break; case 2: if ((r->terrain_type != TERRAIN_UWATER) && (r->terrain_type != TERRAIN_AIR) && (r->terrain_type != TERRAIN_WATER_NOSWIM) && (r->terrain_type != TERRAIN_WATER_SWIM)) break; GET_INTEGER_ARG(ch, "Enter Room VNUM to drop to (-1 for none): ", DROPTO(r), -1, 99999); break; case 3: if (!IS_SET(r->room_flags, WINDY) && (r->terrain_type != TERRAIN_UWATER) && (r->terrain_type != TERRAIN_WATER_NOSWIM) && (r->terrain_type != TERRAIN_WATER_SWIM)) break; GET_INTEGER_ARG(ch, "Room VNUM to drift to (-1 = none, 0 = random): ", DRIFTTO(r), -1, 99999); break; default: send_to_char("That field cannot be changed.\n\r", ch); break; } } ROA_MENU(redit_top_menu) { char buf[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char *p; int field; rmdata *r = ROOM_EDITTED(ch); if (!input_str) { menu_title_send("RoomEdit Main Menu", ch); sprintf(buf, " 1.) %%1Nr%%0 : %d\n\r", r->number); S2C(); sprintf(buf, " 2.) %%6Name%%0 : %s\n\r", r->name); S2C(); sprintf(buf, " 3.) %%6Desc%%0 :\n\r%s", r->description); S2C(); sprinttype(r->terrain_type, terrain_types, buf2); sprintf(buf, " 4.) %%6TerrainType%%0: %%B%s%%0\n\r", buf2); S2C(); sprintf(buf, " 5.) %%6Max Contains%%0: %d\n\r",r->max_contains); S2C(); sprintbit(r->room_flags, room_bits, buf2); sprintf(buf, " 6.) %%6RmFlags%%0 : %%5%s%%0\n\r", buf2); S2C(); sprintbit(r->room_flags2, room_bits2, buf2); sprintf(buf, " 7.) %%6RmFlags2%%0: %%5%s%%0\n\r", buf2); S2C(); send_to_char(" 8.) %6Direction Edit Menu...%0\n\r",ch); if ((r->terrain_type == TERRAIN_UWATER) || (r->terrain_type == TERRAIN_AIR) || (r->terrain_type == TERRAIN_WATER_NOSWIM) || (r->terrain_type == TERRAIN_WATER_SWIM) || IS_SET(r->room_flags, WINDY)) send_to_char(" 9.) %6Environment Control Menu...%0\n\r",ch); if (IS_SET(r->room_flags2, TRANSPORT)) send_to_char("10.) %6Transport String Menu...%0\n\r",ch); else if (IS_SET(r->room_flags, RANDOM)) send_to_char("10.) %6Random String Menu...%0\n\r",ch); if (IS_SET(r->room_flags2, TRANSPORT)) send_to_char("11.) %6Transport Data Menu...%0\n\r",ch); if (IS_SET(r->room_flags, PORTAL)) send_to_char("12.) %6Portal Data Menu...%0\n\r",ch); if (IS_SET(r->room_flags, ALTERHIT | ALTERMOVE | ALTERMANA) || IS_SET(r->room_flags, DEATH | FLY_DEATH)) send_to_char("13.) %6Alteration Menu...%0\n\r",ch); send_to_char("14.) %6Xtra Descrip Menu...%0\n\r", ch); if (r->owner >= 0 && GET_LEVEL(ch) >= LEV_AIMP) { sprintf(buf, "15.) %%6Room Owner%%0: %d\n\r",r->owner); S2C(); } sprintf(buf, "16.) %%6Sound file%%0: %s\n\r", r->sound_file); S2C(); sprintf(buf, "17.) %%6Sound replay time%%0: %d\n\r",r->music_timer); S2C(); if (IS_SET(r->room_flags, RPROC)) send_to_char("18.) %6RoomProc CommandList Menu...%0\n\r",ch); send_to_char("\n\r", ch); MENU_PROMPT(ch) = "Enter field number to change or 0 to end: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) field = atoi(p); else field = 0; switch (field) { case 0: menu_jump(ch, redit_confirm_quit); break; case 1: /* builder wants to DUPE the room */ if (ch->pc_specials->field_changed) { send_to_char("That field cannot be changed after another " "field is changed.\n\r", ch); break; } if (GET_LEVEL(ch) >= LEV_CIMP) { get_integer_arg(ch, "Enter room virtual number: ", &r->number, sizeof(r->number), 0, 89999); } else { send_to_char("That field cannot be changed.\n\r", ch); } break; case 2: do_string_arg(ch, "Enter new room name:\n\r", &r->name, ""); break; case 3: do_long_string_arg(ch, "Enter new description (@):\n\r", &r->description); break; case 4: get_integer_list(ch, "Enter number of the desired terrain: ", &r->terrain_type, sizeof(r->terrain_type), terrain_types); break; case 5: GET_INTEGER_ARG(ch, "Enter Max Contains (-1 for no limit) ", r->max_contains, -1, 50); break; case 6: toggle_menu(ch, "Enter room bit to toggle: ", &r->room_flags, room_bits); break; case 7: toggle_menu(ch, "Enter room bit to toggle: ", &r->room_flags2, room_bits2); break; case 8: menu_push(ch); MENU_RETURN(ch) = 0; MENU_HANDLER_ARG(ch) = (void *) 0; menu_jump(ch, redit_main_exit_menu); break; case 9: if ((r->terrain_type != TERRAIN_UWATER) && (r->terrain_type != TERRAIN_AIR) && (r->terrain_type != TERRAIN_WATER_NOSWIM) && (r->terrain_type != TERRAIN_WATER_SWIM) && !IS_SET(r->room_flags, WINDY)) break; menu_push(ch); MENU_RETURN(ch) = 0; MENU_HANDLER_ARG(ch) = (void *) 0; menu_jump(ch, redit_environment_menu); break; case 10: if (!IS_SET(r->room_flags2, TRANSPORT) && !IS_SET(r->room_flags, RANDOM)) break; menu_push(ch); MENU_RETURN(ch) = 0; MENU_HANDLER_ARG(ch) = (void *) 0; menu_jump(ch, redit_string_menu); break; case 11: if (!IS_SET(r->room_flags2, TRANSPORT)) break; menu_push(ch); MENU_RETURN(ch) = 0; MENU_HANDLER_ARG(ch) = (void *) 0; menu_jump(ch, redit_transport_menu); break; case 12: if (!IS_SET(r->room_flags, PORTAL)) break; menu_push(ch); MENU_RETURN(ch) = 0; MENU_HANDLER_ARG(ch) = (void *) 0; menu_jump(ch, redit_portal_menu); break; case 13: if (!IS_SET(r->room_flags, ALTERHIT | ALTERMOVE | ALTERMANA) && !IS_SET(r->room_flags, DEATH | FLY_DEATH)) break; menu_push(ch); MENU_RETURN(ch) = 0; MENU_HANDLER_ARG(ch) = (void *) 0; menu_jump(ch, redit_alter_menu); break; case 14: menu_push(ch); MENU_RETURN(ch) = 0; MENU_HANDLER_ARG(ch) = (void *) 0; menu_jump(ch, redit_extradesc_menu); break; case 15: if (GET_LEVEL(ch) < LEV_AIMP) break; GET_INTEGER_ARG(ch, "Enter IDNUM of room owner (-1 recommended) ", r->owner, -1, 5000); break; case 16: do_string_arg(ch, "Enter sound filename:\n\r", &r->sound_file, ""); break; case 17: GET_INTEGER_ARG(ch, "Enter repeat time (qticks, -1 no repeat) ", r->music_timer, -1, 32000); break; case 18: if (!IS_SET(r->room_flags, RPROC)) break; menu_push(ch); MENU_RETURN(ch) = 0; MENU_HANDLER_ARG(ch) = (void *) 0; menu_jump(ch, redit_rproc_menu); break; default: send_to_char("That field cannot be changed.\n\r", ch); break; } ch->pc_specials->field_changed = TRUE; } ROA_MENU(redit_confirm_quit) { char buf[MAX_STRING_LENGTH]; char *p; if (!input_str) { MENU_PROMPT(ch) = "Quit editting room (yes/NO)? "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p && strncasecmp("yes", p, strlen(p)) == 0) menu_jump(ch, redit_confirm_save); else menu_jump(ch, redit_top_menu); } // simply makes sure no strings on room are invalid // also checks the exdesc list -roa void check_invalid_room(rmdata *r) { BOOL dolog = FALSE; if (!r->name || !*r->name) { r->name = STR_DUP("%1WARNING:%0 Room has no name, report immediately!\n\r"); dolog = TRUE; } if (!r->description || !*r->description) { r->description = STR_DUP("%1WARNING:%0 Room has no description, report immediately!\n\r"); dolog = TRUE; } r->exdesc = correct_extra_descrips(r->exdesc); if (dolog) { sprintf(buf, "SYSERR: Invalid room string detected and fixed: #%d.", r->number); mudlog(buf, BRF, LEV_IMM, TRUE); } } ROA_MENU(redit_confirm_save) { char buf[MAX_STRING_LENGTH]; char *p; int rnum; rmdata *r = ROOM_EDITTED(ch); if (!input_str) { MENU_PROMPT(ch) = "Save editted room (YES/no)? "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (!p || strncasecmp("no", p, strlen(p)) != 0) { r->zone = real_zone(r->number / 100); check_invalid_room(r); if ((rnum = real_room(r->number)) >= 0) { strcpy(buf2, "editted"); dupe_room_over(r, &world[rnum]); } else { strcpy(buf2, "created"); dupe_room_over(r, &world[top_of_world]); top_of_world++; } sprintf(buf, "PLRUPD: %s has %s room #%d", GET_NAME(ch), buf2, r->number); mudlog(buf, NRM, GET_LEVEL(ch), TRUE); } wax_room(ROOM_EDITTED(ch)); FREENULL(ROOM_EDITTED(ch)); MENU_PROMPT(ch) = NULL; MENU_HANDLER(ch) = NULL; MENU_DEPTH(ch) = 0; REMOVE_BIT(PLR_FLAGS(ch), PLR_BUILDING); } ACMD(do_rlist) { rmdata *w; int zone; int i, top; BOOL found = FALSE; char buf[20000]; if (IS_NPC(ch)) return; one_argument(argument, buf); if (!*buf || *buf == '.') zone = world[ch->in_room].zone; else zone = real_zone(atoi(buf)); if (zone < 0) { send_to_char("That zone does not exist.\n\r",ch); return; } if (!olc_perms(ch, LEV_GOD, zone)) return; if (ZONE_FREED(zone)) { send_to_char("The rooms from that zone are not stored in memory.\n\r",ch); send_to_char("Use %Bzlock%0 to load them into memory.\n\r",ch); return; } top = zone_table[zone].top; for (i = zone * 100; i <= top; i++) { if (real_room(i) >= 0) break; } if (i > top) { send_to_char("No rooms in that zone.\n\r",ch); return; } buf[0] = '\0'; while (i <= top) { if (real_room(i) < 0) { i++; continue; } found = TRUE; w = &world[real_room(i)]; sprintf(buf1, "[%5d]\t%-22.22s%%0\t", i, w->name); sprintbit(w->room_flags, room_bits, buf2); strcat(buf1, buf2); strcat(buf1, "\n\r"); strcat(buf, buf1); i++; } if (found) page_string(ch->desc, buf, 1); else send_to_char("No rooms in that zone.\n\r",ch); } /* HEDIT BASICALLY same as REDIT features, except its for PLAYERS (ROA) with many of the room functions/options disabled */ ACMD(do_hedit) { int find_house(int vnum); int vnum; int rnum; int i; BOOL ok; extern struct house_control_rec house_control[MAX_HOUSES]; if (IS_NPC(ch)) return; vnum = world[ch->in_room].number; if (world[ch->in_room].owner == GET_IDNUM(ch)) ok = TRUE; else ok = FALSE; if (!ok && !ROOM_FLAGGED2(ch->in_room, HOUSE)) { send_to_char("You must be in your house to edit it.\r\n", ch); return; } if (!ok && ((i = find_house(vnum)) < 0)) { send_to_char("Your house was not found...seek immortal help.\r\n", ch); return; } if (!ok && GET_IDNUM(ch) != house_control[i].owner) { send_to_char("Only the owner of this house may edit it.\r\n", ch); return; } if ((rnum = real_room(vnum)) >= 0) { CREATE(ROOM_EDITTED(ch), rmdata, 1); dupe_room_over(&world[rnum], ROOM_EDITTED(ch)); } else { send_to_char("House room does not exist. Seek immortal help.\n\r",ch); return; } SET_BIT(PLR_FLAGS(ch), PLR_BUILDING); MENU_DEPTH(ch) = 0; ch->pc_specials->field_changed = FALSE; menu_jump(ch, hedit_top_menu); } // let players add extra descriptions to their rooms ROA_MENU(hedit_add_extradesc_menu) { rmdata *r = ROOM_EDITTED(ch); exdescdata *e; switch ((int) MENU_HANDLER_ARG(ch)) { case 0: CREATE(e, exdescdata, 1); CREATE(e->keyword, char, 1); CREATE(e->description, char, 1); e->next = r->exdesc; r->exdesc = e; MENU_HANDLER_ARG(ch) = (void *) 1; do_string_arg(ch, "Enter keywords: ", &e->keyword, ""); break; case 1: MENU_HANDLER_ARG(ch) = (void *) 2; do_long_string_arg(ch, "Enter new description (@):\n\r", &r->exdesc->description); break; default: menu_back(ch); break; } } ROA_MENU(hedit_extradesc_menu) { char buf[MAX_STRING_LENGTH]; rmdata *r = ROOM_EDITTED(ch); exdescdata *e = NULL; char *p; int i; if (!input_str) { /* if we have one to delete from earlier */ if ((int) MENU_RETURN(ch) > 0) delete_room_extra(ch); menu_title_send("Extra Descrip Main Menu", ch); for (i = 1, e = r->exdesc; e; e = e->next, i++) { sprintf(buf, "%2d.) %%6%s%%0\n\r", i, e->keyword); S2C(); sprintf(buf, " %s\n\r", e->description); S2C(); } i--; MENU_PROMPT(ch) = "(D)elete, (A)dd, (Q)uit/<return>: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) { if (!strncasecmp("delete", p, strlen(p))) { if (!r->exdesc) GET_INTEGER_ARG(ch, "No descriptions to delete (hit return): ", MENU_RETURN(ch), 0, 0); else { for (i = 1, e = r->exdesc; e; e = e->next, i++) ; GET_INTEGER_ARG(ch, "Enter desc number to delete (return for none): ", MENU_RETURN(ch), 1, i-1); } } else if (!strncasecmp("add", p, strlen(p))) { menu_push(ch); MENU_HANDLER_ARG(ch) = (void *) 0; menu_jump(ch, hedit_add_extradesc_menu); } else if (!strncasecmp("quit", p, strlen(p)) || !p || !atoi(p)) { menu_back(ch); return; } } else if (!p || !atoi(p)) { menu_back(ch); return; } } ROA_MENU(hedit_exit_menu) { char buf[MAX_STRING_LENGTH]; char *p; int field; int i; rmdata *r = ROOM_EDITTED(ch); int dir = (int) MENU_HANDLER_ARG(ch); rmdirdata *d = r->dir_option[dir]; if (!input_str) { if (d->to_room_virtual >= 0) { i = real_room(d->to_room_virtual); if (i < 0) { sprintf(buf, "Room %d does not exist.\n\n\r", d->to_room_virtual); S2C(); } d->to_room = i; d->to_room_virtual = -1; } sprintf(buf, "Direction: %%6%s%%0\n\r", dirs[dir]); S2C(); sprintf(buf, " 1.) Keyword : %s\n\r", d->keyword); S2C(); sprintf(buf, " 2.) Desc :\n\r%s\n\r", d->exit_descr); S2C(); MENU_PROMPT(ch) = "Enter field number to change or 0 to end: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) field = atoi(p); else field = 0; switch (field) { case 0: if (world[d->to_room].number <= 0) r->dir_option[dir] = NULL; menu_back(ch); return; break; case 1: do_string_arg(ch, "Enter new exit keyword:\n\r", &d->keyword, ""); break; case 2: do_long_string_arg(ch, "Enter new description (@):\n\r", &d->exit_descr); break; default: send_to_char("That field cannot be changed.\n\r", ch); break; } } // the top house editting menu ROA_MENU(hedit_top_menu) { char buf[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char *p; int field; int i; rmdata *r = ROOM_EDITTED(ch); if (!input_str) { sprintf(buf, " 1.) %%1Nr%%0 : %d\n\r", r->number); S2C(); sprintf(buf, " 2.) %%6Name%%0 : %s\n\r", r->name); S2C(); sprintf(buf, " 3.) %%6Desc%%0 :\n\r%s", r->description); S2C(); sprinttype(r->terrain_type, terrain_types, buf2); sprintf(buf, " 4.) %%6TerrainType%%0: %%B%s%%0\n\r", buf2); S2C(); sprintf(buf, " 6.) %%6Extra Descriptions%%0: %s\n\r", r->exdesc?"Exist":"None"); S2C(); for (i = 0; i < NUM_OF_DIRS; i++) { sprintf(buf, "%2d.) %%6Exit%%0 %%5%5s%%0, ", i + 7, dirs[i]); S2C(); if (r->dir_option[i]) { sprintbit(r->dir_option[i]->exinfo, exit_bits, buf2); sprintf(buf, "To: %%6%d%%0, Key#: %%6%d%%0, \n\r\tExFlags: %%5%s%%0\n\r", world[r->dir_option[i]->to_room].number, r->dir_option[i]->key, buf2); S2C(); } else send_to_char("\n\r", ch); } send_to_char("\n\r", ch); MENU_PROMPT(ch) = "Enter field number to change or 0 to end: "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p) field = atoi(p); else field = 0; switch (field) { case 0: menu_jump(ch, hedit_confirm_quit); break; case 2: do_string_arg(ch, "Enter new room name:\n\r", &r->name, ""); break; case 3: do_long_string_arg(ch, "Enter new description (@):\n\r", &r->description); break; case 4: get_integer_list(ch, "Enter number of the desired terrain: ", &r->terrain_type, sizeof(r->terrain_type), terrain_types); break; case 6: menu_push(ch); MENU_RETURN(ch) = 0; MENU_HANDLER_ARG(ch) = (void *) 0; menu_jump(ch, hedit_extradesc_menu); break; case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: i = field - 7; if (!r->dir_option[i]) { CREATE(r->dir_option[i], rmdirdata, 1); r->dir_option[i]->keyword = STR_DUP("(def)"); r->dir_option[i]->exit_descr = STR_DUP("(def)"); // Exit messages. 03/24/98 -callahan r->dir_option[i]->enter = STR_DUP("(def)"); r->dir_option[i]->oenter = STR_DUP("(def)"); r->dir_option[i]->drop = STR_DUP("(def)"); r->dir_option[i]->odrop = STR_DUP("(def)"); } r->dir_option[i]->to_room_virtual = -1; menu_push(ch); MENU_RETURN(ch) = 0; MENU_HANDLER_ARG(ch) = (void *) i; menu_jump(ch, hedit_exit_menu); break; default: send_to_char("That field cannot be changed.\n\r", ch); break; } ch->pc_specials->field_changed = TRUE; } ROA_MENU(hedit_confirm_quit) { char buf[MAX_STRING_LENGTH]; char *p; if (!input_str) { MENU_PROMPT(ch) = "Quit editting room (yes/NO)? "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (p && strncasecmp("yes", p, strlen(p)) == 0) menu_jump(ch, hedit_confirm_save); else menu_jump(ch, hedit_top_menu); } ROA_MENU(hedit_confirm_save) { char buf[MAX_STRING_LENGTH]; char *p; int rnum; rmdata *r = ROOM_EDITTED(ch); if (!input_str) { MENU_PROMPT(ch) = "Save editted room (YES/no)? "; return; } strcpy(buf, input_str); p = strtok(buf, " \n\r"); if (!p || strncasecmp("no", p, strlen(p)) != 0) { r->zone = real_zone(r->number / 100); if ((rnum = real_room(r->number)) >= 0) { sprintf(buf, "PLRUPD: %s has h_editted room #%d.", GET_NAME(ch), r->number); mudlog(buf, NRM, GET_LEVEL(ch), TRUE); check_invalid_room(r); dupe_room_over(r, &world[rnum]); sprintf(buf, "%d",(r->number / 100)); do_wldsave(ch, buf, 0, 0); } else { sprintf(buf, "SYSERR: %s has H_CREATED room #%d", GET_NAME(ch), r->number); mudlog(buf, BRF, GET_LEVEL(ch), TRUE); } } wax_room(ROOM_EDITTED(ch)); FREENULL(ROOM_EDITTED(ch)); MENU_PROMPT(ch) = NULL; MENU_HANDLER(ch) = NULL; MENU_DEPTH(ch) = 0; REMOVE_BIT(PLR_FLAGS(ch), PLR_BUILDING); } // let a player add a room onto their house for a certain amount of gold // RoA Innovations (yanking slots from zones 3 and 4 for now) // (HBUILD_ZONE1 and HBUILD_ZONE2) ACMD(do_hbuild) { int vroom, rroom, zone; int top; int dir; rmdata *newroom; rmdata *thisroom; BOOL found = FALSE; int unidle_reset_zone(int zon); if (IS_NPC(ch)) return; if (IN_NOWHERE(ch)) return; if (!REAL_ZONE(HBUILD_ZONE1) || !REAL_ZONE(HBUILD_ZONE2)) { send_to_char("Unable to build room. Zones do not exist.\n\r",ch); mudlog("SYSERR: HBUILD zones DNE.", BRF, LEV_IMM, TRUE); return; } if (!WLD_SLOTS_LEFT) { send_to_char("Max room creation for this runtime reached.\n\r",ch); send_to_char("You must wait for reboot to build more rooms.\n\r",ch); mudlog("!SYSWAR!: World padding exhausted. Suggest immediate reboot.", BRF, LEV_IMM, TRUE); return; } if (world[ch->in_room].owner != GET_IDNUM(ch)) { send_to_char("You can only build from rooms which you own.\n\r",ch); return; } if (GET_GOLD(ch) < HBUILD_COST) { sprintf(buf, "Addon rooms cost %%6%d%%0 %s, which you don't have.\n\r", HBUILD_COST, currency_name_plural); S2C(); return; } // first try HBUILD_ZONE1, look for available room slot zone = HBUILD_ZONE1; top = zone_table[zone].top; for (vroom = zone * 100; vroom <= top; vroom++) if ((rroom = real_room(vroom)) <= 0) break; if (vroom <= top) found = TRUE; // ok havent found one in zone1, try next zone if (!found) { zone = HBUILD_ZONE2; top = zone_table[zone].top; for (vroom = zone * 100; vroom <= top; vroom++) if ((rroom = real_room(vroom)) <= 0) break; if (vroom <= top) found = TRUE; } if (!found) { send_to_char("There are no rooms available. Seek immortal help.\n\r",ch); mudlog("SYSUPD: Hbuild unable to locate avail rooms.", BRF, LEV_IMM, FALSE); return; } // lesse if the zone is useable if (ZONE_CLOSED(zone) || ZONE_LOCKED(zone)) { send_to_char("Unable to build room. Zone closed, locked or freed.\n\r",ch); return; } // parse arg dir and check it against existing exits -roa one_argument(argument, arg); if (!*arg) { send_to_char("Usage: hbuild <direction>.\n\r",ch); return; } if ((dir = search_block(arg, comm_dirs, FALSE)) == -1 || dir >= NUM_OF_DIRS) { send_to_char("Valid dirs: N, S, E, W, NE, NW, SE, SW, U, D.\n\r",ch); return; } if (EXIT(ch, dir)) { send_to_char("That direction already exists.\n\r",ch); return; } // 2/5/98 -jtrhone if zone freed, unidle, reset it... if (ZONE_FREED(zone)) unidle_reset_zone(zone); // take gold babe sprintf(buf, "Your house addition costs %%6%d%%0 %s.\n\r", HBUILD_COST, currency_name_plural); S2C(); GET_GOLD(ch) -= HBUILD_COST; newroom = &world[top_of_world]; top_of_world++; default_room_out(newroom, vroom); // make sure all the strings are in there -roa check_invalid_room(newroom); thisroom = &world[ch->in_room]; // create dir to new room CREATE(thisroom->dir_option[dir], rmdirdata, 1); thisroom->dir_option[dir]->keyword = STR_DUP("(def)"); thisroom->dir_option[dir]->exit_descr = STR_DUP("(def)\n\r"); // Exit messages... 03/24/98 -callahan thisroom->dir_option[dir]->enter = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->oenter = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->drop = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->odrop = STR_DUP("(def)\n\r"); thisroom->dir_option[dir]->to_room_virtual = vroom; thisroom->dir_option[dir]->to_room = real_room(vroom); // calc opposite dir dir = rev_dir[dir]; // create dir from new room to thisroom CREATE(newroom->dir_option[dir], rmdirdata, 1); newroom->dir_option[dir]->keyword = STR_DUP("(def)"); newroom->dir_option[dir]->exit_descr = STR_DUP("(def)\n\r"); // Exit messages... 03/24/98 -callahan newroom->dir_option[dir]->enter = STR_DUP("(def)\n\r"); newroom->dir_option[dir]->oenter = STR_DUP("(def)\n\r"); newroom->dir_option[dir]->drop = STR_DUP("(def)\n\r"); newroom->dir_option[dir]->odrop = STR_DUP("(def)\n\r"); newroom->dir_option[dir]->to_room_virtual = thisroom->number; newroom->dir_option[dir]->to_room = real_room(thisroom->number); // assign ownership to new room newroom->owner = GET_IDNUM(ch); sprintf(buf, "PLRUPD: %s has hbuilt room #%d", GET_NAME(ch), newroom->number); mudlog(buf, NRM, GET_LEVEL(ch), TRUE); // now save zone we just connected to... sprintf(buf, "%d", zone); do_wldsave(ch, buf, 0, 0); // 2/5/98 -jtrhone ALSO save house zone... sprintf(buf, "%d", HOUSE_ZONE); do_wldsave(ch, buf, 0, 0); }