/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * _TwyliteMud_ by Rv. Based on CircleMud3.0bpl9 * * * * OasisOLC - redit.c * * * * Copyright 1996 Harvey Gilpin. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /*. Original authors unknown .*/ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "comm.h" #include "utils.h" #include "db.h" #include "boards.h" #include "olc.h" /*------------------------------------------------------------------------*/ /*. External data .*/ extern int top_of_world; extern struct room_data *world; extern struct obj_data *obj_proto; extern struct char_data *mob_proto; extern char *room_bits[]; extern char *sector_types[]; extern char *exit_bits[]; extern struct zone_data *zone_table; extern sh_int r_mortal_start_room; extern sh_int r_immort_start_room; extern sh_int r_frozen_start_room; extern sh_int mortal_start_room; extern sh_int immort_start_room; extern sh_int frozen_start_room; extern int top_of_zone_table; /*------------------------------------------------------------------------*/ /* function protos */ void redit_disp_extradesc_menu(struct descriptor_data * d); void redit_disp_exit_menu(struct descriptor_data * d); void redit_disp_exit_flag_menu(struct descriptor_data * d); void redit_disp_flag_menu(struct descriptor_data * d); void redit_disp_sector_menu(struct descriptor_data * d); void redit_disp_menu(struct descriptor_data * d); void redit_parse(struct descriptor_data * d, char *arg); void redit_setup_new(struct descriptor_data *d); void redit_setup_existing(struct descriptor_data *d, int real_num); void redit_save_to_disk(struct descriptor_data *d); void redit_save_internally(struct descriptor_data *d); void free_room(struct room_data *room); /*------------------------------------------------------------------------*/ #define W_EXIT(room, num) (world[(room)].dir_option[(num)]) /*------------------------------------------------------------------------*\ Utils and exported functions. \*------------------------------------------------------------------------*/ void redit_setup_new(struct descriptor_data *d) { CREATE(OLC_ROOM(d), struct room_data, 1); OLC_ROOM(d)->name = str_dup("An unfinished room"); OLC_ROOM(d)->description = str_dup("You are in an unfinished room.\r\n"); redit_disp_menu(d); OLC_VAL(d) = 0; } /*------------------------------------------------------------------------*/ void redit_setup_existing(struct descriptor_data *d, int real_num) { struct room_data *room; int counter; /*. Build a copy of the room .*/ CREATE (room, struct room_data, 1); *room = world[real_num]; /* allocate space for all strings */ if (world[real_num].name) room->name = str_dup (world[real_num].name); if (world[real_num].description) room->description = str_dup (world[real_num].description); /* exits - alloc only if necessary */ for (counter = 0; counter < NUM_OF_DIRS; counter++) { if (world[real_num].dir_option[counter]) { CREATE(room->dir_option[counter], struct room_direction_data, 1); /* copy numbers over */ *room->dir_option[counter] = *world[real_num].dir_option[counter]; /* malloc strings */ if (world[real_num].dir_option[counter]->general_description) room->dir_option[counter]->general_description = str_dup(world[real_num].dir_option[counter]->general_description); if (world[real_num].dir_option[counter]->keyword) room->dir_option[counter]->keyword = str_dup(world[real_num].dir_option[counter]->keyword); } } /*. Extra descriptions if necessary .*/ if (world[real_num].ex_description) { struct extra_descr_data *this, *temp, *temp2; CREATE (temp, struct extra_descr_data, 1); room->ex_description = temp; for (this = world[real_num].ex_description; this; this = this->next) { if (this->keyword) temp->keyword = str_dup (this->keyword); if (this->description) temp->description = str_dup (this->description); if (this->next) { CREATE (temp2, struct extra_descr_data, 1); temp->next = temp2; temp = temp2; } else temp->next = NULL; } } /*. Attatch room copy to players descriptor .*/ OLC_ROOM(d) = room; OLC_VAL(d) = 0; redit_disp_menu(d); } /*------------------------------------------------------------------------*/ #define ZCMD (zone_table[zone].cmd[cmd_no]) void redit_save_internally(struct descriptor_data *d) { int i, j, room_num, found = 0, zone, cmd_no; struct room_data *new_world; struct char_data *temp_ch; struct obj_data *temp_obj; room_num = real_room(OLC_NUM(d)); if (room_num > 0) { /*. Room exits: move contents over then free and replace it .*/ OLC_ROOM(d)->contents = world[room_num].contents; OLC_ROOM(d)->people = world[room_num].people; free_room(world + room_num); world[room_num] = *OLC_ROOM(d); } else { /*. Room doesn't exist, hafta add it .*/ CREATE(new_world, struct room_data, top_of_world + 2); /* count thru world tables */ for (i = 0; i <= top_of_world + 1; i++) { if (!found) { /*. Is this the place? .*/ if ((i > top_of_world) || (world[i].number > OLC_NUM(d))) { found = 1; new_world[i] = *(OLC_ROOM(d)); new_world[i].number = OLC_NUM(d); new_world[i].func = NULL; room_num = i; /* copy from world to new_world + 1 */ if (i <= top_of_world) { new_world[i + 1] = world[i]; /* people in this room must have their numbers moved */ for (temp_ch = world[i].people; temp_ch; temp_ch = temp_ch->next_in_room) if (temp_ch->in_room != -1) temp_ch->in_room = i + 1; /* move objects */ for (temp_obj = world[i].contents; temp_obj; temp_obj = temp_obj->next_content) if (temp_obj->in_room != -1) temp_obj->in_room = i + 1; } } else { /*. Not yet placed, copy straight over .*/ new_world[i] = world[i]; } } else { /*. Already been found .*/ /* people in this room must have their in_rooms moved */ for (temp_ch = world[i].people; temp_ch; temp_ch = temp_ch->next_in_room) if (temp_ch->in_room != -1) temp_ch->in_room = i + 1; /* move objects */ for (temp_obj = world[i].contents; temp_obj; temp_obj = temp_obj->next_content) if (temp_obj->in_room != -1) temp_obj->in_room = i + 1; new_world[i + 1] = world[i]; } } /* copy world table over */ free(world); world = new_world; top_of_world++; /*. Update zone table .*/ for (zone = 0; zone <= top_of_zone_table; zone++) for (cmd_no = 0; ZCMD.command != 'S'; cmd_no++) switch (ZCMD.command) { case 'M': case 'O': if (ZCMD.arg3 >= room_num) ZCMD.arg3++; break; case 'D': case 'R': if (ZCMD.arg1 >= room_num) ZCMD.arg1++; case 'G': case 'P': case 'E': case '*': break; default: mudlog("SYSERR: OLC: redit_save_internally: Unknown comand", BRF, LVL_GOD, TRUE); } /* update load rooms, to fix creeping load room problem */ if (room_num <= r_mortal_start_room) r_mortal_start_room++; if (room_num <= r_immort_start_room) r_immort_start_room++; if (room_num <= r_frozen_start_room) r_frozen_start_room++; /*. Update world exits .*/ for (i = 0; i < top_of_world + 1; i++) for (j = 0; j < NUM_OF_DIRS; j++) if (W_EXIT(i, j)) if (W_EXIT(i, j)->to_room >= room_num) W_EXIT(i, j)->to_room++; } olc_add_to_save_list(zone_table[OLC_ZNUM(d)].number, OLC_SAVE_ROOM); } /*------------------------------------------------------------------------*/ void redit_save_to_disk(struct descriptor_data *d) { int counter, counter2, realcounter; FILE *fp; struct room_data *room; struct extra_descr_data *ex_desc; sprintf(buf, "%s/%d.wld", WLD_PREFIX, zone_table[OLC_ZNUM(d)].number); if (!(fp = fopen(buf, "w+"))) { mudlog("SYSERR: OLC: Cannot open room file!", BRF, LVL_GOD, TRUE); return; } for (counter = zone_table[OLC_ZNUM(d)].number * 100; counter <= zone_table[OLC_ZNUM(d)].top; counter++) { realcounter = real_room(counter); if (realcounter >= 0) { room = (world + realcounter); /*. Remove the '\r\n' sequences from description .*/ strcpy(buf1, room->description); strip_string(buf1); /*. Build a buffer ready to save .*/ sprintf(buf, "#%d\n%s~\n%s~\n%d %d %d\n", counter, room->name, buf1, zone_table[room->zone].number, room->room_flags, room->sector_type ); /*. Save this section .*/ fputs(buf, fp); /*. Handle exits .*/ for (counter2 = 0; counter2 < NUM_OF_DIRS; counter2++) { if (room->dir_option[counter2]) { int temp_door_flag; /*. Again, strip out the crap .*/ if (room->dir_option[counter2]->general_description) { strcpy(buf1, room->dir_option[counter2]->general_description); strip_string(buf1); } else *buf1 = 0; /*. Figure out door flag .*/ if (IS_SET(room->dir_option[counter2]->exit_info, EX_ISDOOR)) { if (IS_SET(room->dir_option[counter2]->exit_info, EX_PICKPROOF)) temp_door_flag = 2; else temp_door_flag = 1; } else temp_door_flag = 0; /*. Check for keywords .*/ if(room->dir_option[counter2]->keyword) strcpy(buf2, room->dir_option[counter2]->keyword); else *buf2 = 0; /*. Ok, now build a buffer to output to file .*/ sprintf(buf, "D%d\n%s~\n%s~\n%d %d %d\n", counter2, buf1, buf2, temp_door_flag, room->dir_option[counter2]->key, world[room->dir_option[counter2]->to_room].number ); /*. Save this door .*/ fputs(buf, fp); } } if (room->ex_description) { for (ex_desc = room->ex_description; ex_desc; ex_desc = ex_desc->next) { /*. Home straight, just deal with extras descriptions..*/ strcpy(buf1, ex_desc->description); strip_string(buf1); sprintf(buf, "E\n%s~\n%s~\n", ex_desc->keyword,buf1); fputs(buf, fp); } } fprintf(fp, "S\n"); } } /* write final line and close */ fprintf(fp, "$~\n"); fclose(fp); olc_remove_from_save_list(zone_table[OLC_ZNUM(d)].number, OLC_SAVE_ROOM); } /*------------------------------------------------------------------------*/ void free_room(struct room_data *room) { int i; struct extra_descr_data *this, *next; if (room->name) free(room->name); if (room->description) free(room->description); /*. Free exits .*/ for (i = 0; i < NUM_OF_DIRS; i++) { if (room->dir_option[i]) { if (room->dir_option[i]->general_description) free(room->dir_option[i]->general_description); if (room->dir_option[i]->keyword) free(room->dir_option[i]->keyword); } free(room->dir_option[i]); } /*. Free extra descriptions .*/ for (this = room->ex_description; this; this = next) { next = this->next; if (this->keyword) free(this->keyword); if (this->description) free(this->description); free(this); } } /************************************************************************** Menu functions **************************************************************************/ /* For extra descriptions */ void redit_disp_extradesc_menu(struct descriptor_data * d) { struct extra_descr_data *extra_desc = OLC_DESC(d); sprintf(buf, "[H[J" "%s1%s) Keyword: %s%s\r\n" "%s2%s) Description:\r\n%s%s\r\n" "%s3%s) Goto next description: ", grn, nrm, yel, extra_desc->keyword ? extra_desc->keyword : "<NONE>", grn, nrm, yel, extra_desc->description ? extra_desc->description : "<NONE>", grn, nrm ); if (!extra_desc->next) strcat(buf, "<NOT SET>\r\n"); else strcat(buf, "Set.\r\n"); strcat(buf, "Enter choice (0 to quit) : "); send_to_char(buf, d->character); OLC_MODE(d) = REDIT_EXTRADESC_MENU; } /* For exits */ void redit_disp_exit_menu(struct descriptor_data * d) { /* if exit doesn't exist, alloc/create it */ if(!OLC_EXIT(d)) CREATE(OLC_EXIT(d), struct room_direction_data, 1); /* weird door handling! */ if (IS_SET(OLC_EXIT(d)->exit_info, EX_ISDOOR)) { if (IS_SET(OLC_EXIT(d)->exit_info, EX_PICKPROOF)) strcpy(buf2, "Pickproof"); else strcpy(buf2, "Is a door"); } else strcpy(buf2, "No door"); get_char_cols(d->character); sprintf(buf, "[H[J" "%s1%s) Exit to : %s%d\r\n" "%s2%s) Description : %s%s\r\n" "%s3%s) Door name : %s%s\r\n" "%s4%s) Key : %s%d\r\n" "%s5%s) Door flags : %s%s\r\n" "%s6%s) Purge exit.\r\n" "Enter choice, 0 to quit : ", grn, nrm, cyn, world[OLC_EXIT(d)->to_room].number, grn, nrm, yel, OLC_EXIT(d)->general_description ? OLC_EXIT(d)->general_description : "<NONE>", grn, nrm, yel, OLC_EXIT(d)->keyword ? OLC_EXIT(d)->keyword : "<NONE>", grn, nrm, cyn, OLC_EXIT(d)->key, grn, nrm, cyn, buf2, grn, nrm ); send_to_char(buf, d->character); OLC_MODE(d) = REDIT_EXIT_MENU; } /* For exit flags */ void redit_disp_exit_flag_menu(struct descriptor_data * d) { get_char_cols(d->character); sprintf(buf, "%s0%s) No door\r\n" "%s1%s) Closeable door\r\n" "%s2%s) Pickproof\r\n" "Enter choice : ", grn, nrm, grn, nrm, grn, nrm ); send_to_char(buf, d->character); } /* For room flags */ void redit_disp_flag_menu(struct descriptor_data * d) { int counter, columns = 0; get_char_cols(d->character); send_to_char("[H[J", d->character); for (counter = 0; counter < NUM_ROOM_FLAGS; counter++) { sprintf(buf, "%s%2d%s) %-20.20s ", grn, counter + 1, nrm, room_bits[counter]); if(!(++columns % 2)) strcat(buf, "\r\n"); send_to_char(buf, d->character); } sprintbit(OLC_ROOM(d)->room_flags, room_bits, buf1); sprintf(buf, "\r\nRoom flags: %s%s%s\r\n" "Enter room flags, 0 to quit : ", cyn, buf1, nrm ); send_to_char(buf, d->character); OLC_MODE(d) = REDIT_FLAGS; } /* for sector type */ void redit_disp_sector_menu(struct descriptor_data * d) { int counter, columns = 0; send_to_char("[H[J", d->character); for (counter = 0; counter < NUM_ROOM_SECTORS; counter++) { sprintf(buf, "%s%2d%s) %-20.20s ", grn, counter, nrm, sector_types[counter]); if(!(++columns % 2)) strcat(buf, "\r\n"); send_to_char(buf, d->character); } send_to_char("\r\nEnter sector type : ", d->character); OLC_MODE(d) = REDIT_SECTOR; } /* the main menu */ void redit_disp_menu(struct descriptor_data * d) { struct room_data *room; get_char_cols(d->character); room = OLC_ROOM(d); sprintbit((long) room->room_flags, room_bits, buf1); sprinttype(room->sector_type, sector_types, buf2); sprintf(buf, "[H[J" "-- Room number : [%s%d%s] Room zone: [%s%d%s]\r\n" "%s1%s) Name : %s%s\r\n" "%s2%s) Description :\r\n%s%s" "%s3%s) Room flags : %s%s\r\n" "%s4%s) Sector type : %s%s\r\n" "%s5%s) Exit north : %s%d\r\n" "%s6%s) Exit east : %s%d\r\n" "%s7%s) Exit south : %s%d\r\n" "%s8%s) Exit west : %s%d\r\n" "%s9%s) Exit up : %s%d\r\n" "%sA%s) Exit down : %s%d\r\n" "%sB%s) Extra descriptions menu\r\n" "%sQ%s) Quit\r\n" "Enter choice : ", cyn, OLC_NUM(d), nrm, cyn, zone_table[OLC_ZNUM(d)].number, nrm, grn, nrm, yel, room->name, grn, nrm, yel, room->description, grn, nrm, cyn, buf1, grn, nrm, cyn, buf2, grn, nrm, cyn, room->dir_option[NORTH] ? world[room->dir_option[NORTH]->to_room].number : -1, grn, nrm, cyn, room->dir_option[EAST] ? world[room->dir_option[EAST]->to_room].number : -1, grn, nrm, cyn, room->dir_option[SOUTH] ? world[room->dir_option[SOUTH]->to_room].number : -1, grn, nrm, cyn, room->dir_option[WEST] ? world[room->dir_option[WEST]->to_room].number : -1, grn, nrm, cyn, room->dir_option[UP] ? world[room->dir_option[UP]->to_room].number : -1, grn, nrm, cyn, room->dir_option[DOWN] ? world[room->dir_option[DOWN]->to_room].number : -1, grn, nrm, grn, nrm ); send_to_char(buf, d->character); OLC_MODE(d) = REDIT_MAIN_MENU; } /************************************************************************** The main loop **************************************************************************/ void redit_parse(struct descriptor_data * d, char *arg) { extern struct room_data *world; int number; switch (OLC_MODE(d)) { case REDIT_CONFIRM_SAVESTRING: switch (*arg) { case 'y': case 'Y': redit_save_internally(d); sprintf(buf, "OLC: %s edits room %d", GET_NAME(d->character), OLC_NUM(d)); mudlog(buf, CMP, LVL_GOD, TRUE); /*. Do NOT free strings! just the room structure .*/ cleanup_olc(d, CLEANUP_STRUCTS); send_to_char("Room saved to memory.\r\n", d->character); break; case 'n': case 'N': /* free everything up, including strings etc */ cleanup_olc(d, CLEANUP_ALL); break; default: send_to_char("Invalid choice!\r\n", d->character); send_to_char("Do you wish to save this room internally? : ", d->character); break; } return; case REDIT_MAIN_MENU: switch (*arg) { case 'q': case 'Q': if (OLC_VAL(d)) { /*. Something has been modified .*/ send_to_char("Do you wish to save this room internally? : ", d->character); OLC_MODE(d) = REDIT_CONFIRM_SAVESTRING; } else cleanup_olc(d, CLEANUP_ALL); return; case '1': send_to_char("Enter room name:-\r\n| ", d->character); OLC_MODE(d) = REDIT_NAME; break; case '2': send_to_char("Enter room description:-\r\n", d->character); OLC_MODE(d) = REDIT_DESC; d->str = (char **) malloc(sizeof(char *)); *(d->str) = NULL; d->max_str = MAX_ROOM_DESC; d->mail_to = 0; break; case '3': redit_disp_flag_menu(d); break; case '4': redit_disp_sector_menu(d); break; case '5': OLC_VAL(d) = NORTH; redit_disp_exit_menu(d); break; case '6': OLC_VAL(d) = EAST; redit_disp_exit_menu(d); break; case '7': OLC_VAL(d) = SOUTH; redit_disp_exit_menu(d); break; case '8': OLC_VAL(d) = WEST; redit_disp_exit_menu(d); break; case '9': OLC_VAL(d) = UP; redit_disp_exit_menu(d); break; case 'a': case 'A': OLC_VAL(d) = DOWN; redit_disp_exit_menu(d); break; case 'b': case 'B': /* if extra desc doesn't exist . */ if (!OLC_ROOM(d)->ex_description) { CREATE(OLC_ROOM(d)->ex_description, struct extra_descr_data, 1); OLC_ROOM(d)->ex_description->next = NULL; } OLC_DESC(d) = OLC_ROOM(d)->ex_description; redit_disp_extradesc_menu(d); break; default: send_to_char("Invalid choice!", d->character); redit_disp_menu(d); break; } return; case REDIT_NAME: if (OLC_ROOM(d)->name) free(OLC_ROOM(d)->name); if (strlen(arg) > MAX_ROOM_NAME) arg[MAX_ROOM_NAME -1] = 0; OLC_ROOM(d)->name = str_dup(arg); break; case REDIT_DESC: /* we will NEVER get here */ mudlog("SYSERR: Reached REDIT_DESC case in parse_redit",BRF,LVL_GOD,TRUE); break; case REDIT_FLAGS: number = atoi(arg); if ((number < 0) || (number > NUM_ROOM_FLAGS)) { send_to_char("That's not a valid choice!\r\n", d->character); redit_disp_flag_menu(d); } else { if (number == 0) break; else { /* toggle bits */ if (IS_SET(OLC_ROOM(d)->room_flags, 1 << (number - 1))) REMOVE_BIT(OLC_ROOM(d)->room_flags, 1 << (number - 1)); else SET_BIT(OLC_ROOM(d)->room_flags, 1 << (number - 1)); redit_disp_flag_menu(d); } } return; case REDIT_SECTOR: number = atoi(arg); if (number < 0 || number >= NUM_ROOM_SECTORS) { send_to_char("Invalid choice!", d->character); redit_disp_sector_menu(d); return; } else OLC_ROOM(d)->sector_type = number; break; case REDIT_EXIT_MENU: switch (*arg) { case '0': break; case '1': OLC_MODE(d) = REDIT_EXIT_NUMBER; send_to_char("Exit to room number : ", d->character); return; case '2': OLC_MODE(d) = REDIT_EXIT_DESCRIPTION; d->str = (char **) malloc(sizeof(char *)); *(d->str) = NULL; d->max_str = MAX_EXIT_DESC; d->mail_to = 0; send_to_char("Enter exit description:-\r\n", d->character); return; case '3': OLC_MODE(d) = REDIT_EXIT_KEYWORD; send_to_char("Enter keywords : ", d->character); return; case '4': OLC_MODE(d) = REDIT_EXIT_KEY; send_to_char("Enter key number : ", d->character); return; case '5': redit_disp_exit_flag_menu(d); OLC_MODE(d) = REDIT_EXIT_DOORFLAGS; return; case '6': /* delete exit */ if (OLC_EXIT(d)->keyword) free(OLC_EXIT(d)->keyword); if (OLC_EXIT(d)->general_description) free(OLC_EXIT(d)->general_description); free(OLC_EXIT(d)); OLC_EXIT(d) = NULL; break; default: send_to_char("Try again : ", d->character); return; } break; case REDIT_EXIT_NUMBER: number = real_room(atoi(arg)); if (number < 0) send_to_char("That room does not exist, try again : ", d->character); else { OLC_EXIT(d)->to_room = number; redit_disp_exit_menu(d); } return; case REDIT_EXIT_DESCRIPTION: /* we should NEVER get here */ mudlog("SYSERR: Reached REDIT_EXIT_DESC case in parse_redit",BRF,LVL_GOD,TRUE); break; case REDIT_EXIT_KEYWORD: if (OLC_EXIT(d)->keyword) free(OLC_EXIT(d)->keyword); OLC_EXIT(d)->keyword = str_dup(arg); redit_disp_exit_menu(d); return; case REDIT_EXIT_KEY: number = atoi(arg); OLC_EXIT(d)->key = number; redit_disp_exit_menu(d); return; case REDIT_EXIT_DOORFLAGS: number = atoi(arg); if ((number < 0) || (number > 2)) { send_to_char("That's not a valid choice!\r\n", d->character); redit_disp_exit_flag_menu(d); } else { /* doors are a bit idiotic, don't you think? :) */ if (number == 0) OLC_EXIT(d)->exit_info = 0; else if (number == 1) OLC_EXIT(d)->exit_info = EX_ISDOOR; else if (number == 2) OLC_EXIT(d)->exit_info = EX_ISDOOR | EX_PICKPROOF; /* jump out to menu */ redit_disp_exit_menu(d); } return; case REDIT_EXTRADESC_KEY: OLC_DESC(d)->keyword = str_dup(arg); redit_disp_extradesc_menu(d); return; case REDIT_EXTRADESC_MENU: number = atoi(arg); switch (number) { case 0: { /* if something got left out, delete the extra desc when backing out to menu */ if (!OLC_DESC(d)->keyword || !OLC_DESC(d)->description) { struct extra_descr_data **tmp_desc; if (OLC_DESC(d)->keyword) free(OLC_DESC(d)->keyword); if (OLC_DESC(d)->description) free(OLC_DESC(d)->description); /*. Clean up pointers .*/ for(tmp_desc = &(OLC_ROOM(d)->ex_description); *tmp_desc; tmp_desc = &((*tmp_desc)->next)) { if(*tmp_desc == OLC_DESC(d)) { *tmp_desc = NULL; break; } } free(OLC_DESC(d)); } } break; case 1: OLC_MODE(d) = REDIT_EXTRADESC_KEY; send_to_char("Enter keywords, separated by spaces : ", d->character); return; case 2: OLC_MODE(d) = REDIT_EXTRADESC_DESCRIPTION; send_to_char("Enter extra description:-\r\n", d->character); /* send out to modify.c */ d->str = (char **) malloc(sizeof(char *)); *(d->str) = NULL; d->max_str = MAX_EXTRA_DESC; d->mail_to = 0; return; case 3: if (!OLC_DESC(d)->keyword || !OLC_DESC(d)->description) { send_to_char("You can't edit the next extra desc without completing this one.\r\n", d->character); redit_disp_extradesc_menu(d); } else { struct extra_descr_data *new_extra; if (OLC_DESC(d)->next) OLC_DESC(d) = OLC_DESC(d)->next; else { /* make new extra, attach at end */ CREATE(new_extra, struct extra_descr_data, 1); OLC_DESC(d)->next = new_extra; OLC_DESC(d) = new_extra; } redit_disp_extradesc_menu(d); } return; } break; default: /* we should never get here */ mudlog("SYSERR: Reached default case in parse_redit",BRF,LVL_GOD,TRUE); break; } /*. If we get this far, something has be changed .*/ OLC_VAL(d) = 1; redit_disp_menu(d); }