#include #include "structs.h" #include "interpreter.h" #include "comm.h" #include "spells.h" #include "utils.h" #include "db.h" #include #include "boards.h" #include "screen.h" #include #include "olc.h" #include "arena.h" #include "handler.h" extern sh_int r_mortal_start_room; extern sh_int r_immort_start_room; extern sh_int r_frozen_start_room; extern int top_of_world; extern struct room_data *full_rooms; extern struct room_data *world; extern OBJ_DATA *obj_proto; extern CHAR_DATA *mob_proto; extern char *room_bits[]; extern char *sector_types[]; extern char *exit_bits[]; extern char *room_damage_types[]; extern struct zone_data *zone_table; extern int rev_dir[]; extern int top_of_zone_table; extern const char *dirs[]; extern int uvfprintf (FILE * stream, const char *format,...); extern void init_text (DESCRIPTOR * d); static void redit_disp_extension_menu (DESCRIPTOR * d); static void redit_disp_damage_menu (DESCRIPTOR * d); static void redit_disp_exit_flag_menu (DESCRIPTOR * d); static void redit_disp_flag_menu (DESCRIPTOR * d); static void redit_disp_sector_menu (DESCRIPTOR * d); static void insert_room (struct room_data *newroom, int room_vnum); void write_zone_rooms (int zone); #define DROOM d->edit_room #define DEXIT dir_option[d->edit_number2] /************************************************************************** Menu functions **************************************************************************/ /* For extension */ static void redit_disp_extension_menu (DESCRIPTOR * d) { if (!DROOM->extended) { CREATE (DROOM->extended, struct extended_room_info, 1); } send_to_char (DCH, "%s0%s) Quit\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s1%s) Damage/tick : %s%d%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DROOM->extended->damage_per_tick, CCNRM (DCH)); sprinttype (DROOM->extended->damage_type, room_damage_types, buf2); send_to_char (DCH, "%s2%s) Damage type : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf2, CCNRM (DCH)); send_to_char (DCH, "%s3%s) Heal regen : %s%d%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DROOM->extended->heal_regen, CCNRM (DCH)); send_to_char (DCH, "%s4%s) Mana regen : %s%d%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DROOM->extended->mana_regen, CCNRM (DCH)); send_to_char (DCH, "%s5%s) Move regen : %s%d%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DROOM->extended->move_regen, CCNRM (DCH)); send_to_char (DCH, "Enter your choice:"); d->edit_mode = REDIT_EXTENSION_SELECT; return; } static void redit_disp_damage_menu (DESCRIPTOR * d) { int i; for (i = 0; i < MAX_ROOM_DAMAGE; i++) { send_to_char (DCH, "%s%2d%s) %20.20s ", HLMAG (DCH), i, CCNRM (DCH), room_damage_types[i]); if (i % 2 == 1) { send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); send_to_char (DCH, "Enter room damage type:"); } /* For extra descriptions */ void redit_disp_extradesc_menu (DESCRIPTOR * d) { struct extra_descr_data *extra_desc = (struct extra_descr_data *) *d->misc_data; send_to_char (DCH, "%s0%s) Quit\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s1%s) Keyword : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), extra_desc->keyword ? extra_desc->keyword : "", CCNRM (DCH)); send_to_char (DCH, "%s2%s) Description:\r\n%s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), extra_desc->description ? extra_desc->description : "", CCNRM (DCH)); if (!extra_desc->next) { send_to_char (DCH, "%s3%s) \r\n", HLMAG (DCH), CCNRM (DCH)); } else { send_to_char (DCH, "%s3%s) Set. \r\n", HLMAG (DCH), CCNRM (DCH)); } send_to_char (DCH, "Enter choice:\r\n"); d->edit_mode = REDIT_EXTRADESC_MENU; } /* For exits */ void redit_disp_exit_menu (DESCRIPTOR * d) { /* if exit doesn't exist, alloc/create it */ if (!DROOM->DEXIT) { CREATE (DROOM->DEXIT, struct room_direction_data, 1); } send_to_char (DCH, "%s1%s) Exit to : %s%d%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DROOM->DEXIT->to_room_vnum, CCNRM (DCH)); send_to_char (DCH, "%s2%s) Description : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DROOM->DEXIT->general_description ? DROOM->DEXIT->general_description : "", CCNRM (DCH)); send_to_char (DCH, "%s3%s) Door name : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DROOM->DEXIT->keyword ? DROOM->DEXIT->keyword : "", CCNRM (DCH)); send_to_char (DCH, "%s4%s) Key : %s%d%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DROOM->DEXIT->key, CCNRM (DCH)); /* weird door handling! */ sprintbit (DROOM->DEXIT->exit_info, exit_bits, buf2); send_to_char (DCH, "%s5%s) Door flags : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf2, CCNRM (DCH)); send_to_char (DCH, "%s6%s) Exit string\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%s7%s) Purge exit\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "Enter choice, 0 to quit:"); d->edit_mode = REDIT_EXIT_MENU; } /* For exit flags */ static void redit_disp_exit_flag_menu (DESCRIPTOR * d) { int i; for (i = 0; i < NUM_EXIT_FLAGS; i++) { send_to_char (DCH, "%s%2d%s) %20.20s ", HLMAG (DCH), i + 1, CCNRM (DCH), exit_bits[i]); if (i % 2 == 1) { send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); sprintbit (DROOM->DEXIT->exit_info, exit_bits, buf1); send_to_char (DCH, "Exit flags: %s%s%s\r\n", HLCYN (DCH), buf1, CCNRM (DCH)); send_to_char (DCH, "Enter exit flags, 0 to quit:"); } /* For room flags */ static void redit_disp_flag_menu (DESCRIPTOR * d) { int i; send_to_char (DCH, ""); for (i = 0; i < NUM_ROOM_FLAGS; i++) { send_to_char (DCH, "%s%2d%s) %20.20s ", HLMAG (DCH), i + 1, CCNRM (DCH), room_bits[i]); if (i % 2 == 1) { send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); sprintbit (DROOM->room_flags, room_bits, buf1); send_to_char (DCH, "Room flags: %s%s%s\r\n", HLCYN (DCH), buf1, CCNRM (DCH)); send_to_char (DCH, "Enter room flags, 0 to quit:"); d->edit_mode = REDIT_FLAGS; } /* for sector type */ static void redit_disp_sector_menu (DESCRIPTOR * d) { int i; send_to_char (DCH, ""); for (i = 0; i < NUM_ROOM_SECTORS; i++) { send_to_char (DCH, "%s%2d%s) %20.20s ", HLMAG (DCH), i, CCNRM (DCH), sector_types[i]); if (i % 2 == 1) { send_to_char (DCH, "\r\n"); } } send_to_char (DCH, "\r\n"); send_to_char (DCH, "Enter sector type:"); d->edit_mode = REDIT_SECTOR; } static void insert_room (struct room_data *newroom, int room_vnum) { /* hm, we can't just copy.. gotta insert a new room */ int i; int j; int found = 0; int room_rnum; /* make a new world table with one more spot */ struct room_data *new_world; CREATE (new_world, struct room_data, top_of_world + 2); /* silverfox says: why +2? */ /* levork says: top_of_world is actually the real number of the _top_of_world_ - if there are 999 rooms then top_of_world is 999 and not 1000 like we normally do arrays in C. So we add 1, and add 1 again for the new room */ /* count thru world tables */ for (i = 0; i < top_of_world + 1; i++) { /* if we haven't found place to insert */ if (!found) { CHAR_DATA *temp_ch; OBJ_DATA *temp_obj; /* check if current virtual is bigger than our virtual */ if (world[i].number > room_vnum) { /* a new bug, which I think I fixed on nov 19 - Julian first of all, the people/objects must be incr'ed, FIRST */ 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; } /* Now, I can let new world at this pos become the NEW room */ new_world[i] = *(newroom); new_world[i].number = room_vnum; new_world[i].func = null; found = 1; /* and then copy from world to new_world + 1, which in the process will correctly move people / objects. */ new_world[i + 1] = world[i]; /* There! */ } else { /* just copy everything over if current virtual is not bigger */ new_world[i] = world[i]; } } else { /* we have already found it */ /* people in this room must have their in_rooms moved */ CHAR_DATA *temp_ch; OBJ_DATA *temp_obj; 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]; } } /* if place not found, insert at end */ if (!found) { new_world[top_of_world + 1] = *newroom; new_world[top_of_world + 1].number = room_vnum; new_world[top_of_world + 1].func = null; } top_of_world++; /* copy world table over */ free (world); world = new_world; /* now this is the *real* room_num */ room_rnum = real_room (room_vnum); for (i = 0; i <= top_of_zone_table; i++) for (j = 0; zone_table[i].cmd[j].command != 'S'; j++) { switch (zone_table[i].cmd[j].command) { case 'O': case 'M': if (zone_table[i].cmd[j].arg3 >= room_rnum) { zone_table[i].cmd[j].arg3++; } break; case 'T': case 'R': case 'D': if (zone_table[i].cmd[j].arg1 >= room_rnum) { zone_table[i].cmd[j].arg1++; } break; } } /* update load rooms, to fix creeping load room problem */ if (room_rnum <= r_mortal_start_room) { r_mortal_start_room++; } if (room_rnum <= r_immort_start_room) { r_immort_start_room++; } if (room_rnum <= r_frozen_start_room) { r_frozen_start_room++; } /* go through the world. if any of the old rooms indicated an exit * to our new room, we have to change it */ full_rooms = null; for (i = 0; i < top_of_world + 1; i++) { /* silverfox's patch for full_room dilemma: since insert_room gets medieval on the world array, we have to rebuild the full_rooms list */ if (world[i].people) { world[i].next = full_rooms; full_rooms = &world[i]; } else { world[i].next = null; } for (j = 0; j < NUM_OF_DIRS; j++) { /* if exit exists */ if (world[i].dir_option[j]) { /* increment r_nums for rooms bigger than or equal to new one * because we inserted room */ if (world[i].dir_option[j]->to_room >= room_rnum) { world[i].dir_option[j]->to_room = world[i].dir_option[j]->to_room + 1; } /* if an exit to the new room is indicated, change to_room */ if (world[i].dir_option[j]->to_room_vnum == room_vnum) { world[i].dir_option[j]->to_room = room_rnum; } } } } /* resolve all vnum doors to rnum doors in the newly edited room */ for (j = 0; j < NUM_OF_DIRS; j++) { if (world[room_rnum].dir_option[j]) { world[room_rnum].dir_option[j]->to_room = real_room (world[room_rnum].dir_option[j]->to_room_vnum); } } } void write_zone_rooms (int zone) { int i, j, k; FILE *fp, *fp2; struct room_data *room; struct extra_descr_data *ex_desc; /* not really necessary, but I"m lazy :) */ CREATE (room, struct room_data, 1); sprintf (buf, "%s/%d.wld.bak", WLD_PREFIX, zone_table[zone].number); fp = fopen (buf, "w+"); sprintf (buf, "%s/%d.wld.ept", WLD_PREFIX, zone_table[zone].number); fp2 = fopen (buf, "w+"); for (i = zone_table[zone].number * 100; i <= zone_table[zone].top; i++) { k = real_room (i); /* don't write out deleted rooms */ if (k >= 0 && !ROOM_DELETED (k)) { *room = world[k]; uvfprintf(fp2, "StartRoom\n"); uvfprintf(fp2, " StartEntity\n"); uvfprintf(fp2, " Name %s\n", room->name); uvfprintf(fp2, " Description\n%s~\n", room->description); uvfprintf(fp2, " EndEntity\n"); uvfprintf(fp2, " ID %d\n", i); /* Kerfuffling. */ if (IS_SET(room->room_flags, ROOM_INDOORS) && room->sector_type == SECT_CITY) { fprintf(fp2, " Sector building\n"); } else if (!IS_SET(room->room_flags, ROOM_INDOORS) && room->sector_type == SECT_CITY) { fprintf(fp2, " Sector city\n"); } else { fprintf(fp2, " Sector %s\n", sector_types[room->sector_type]); } uvfprintf(fp2, " Attributes "); uvfprintf(fp2, "%d", IS_SET(room->room_flags, ROOM_DARK) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->room_flags, ROOM_DEATH) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->room_flags, ROOM_NOMOB) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->room_flags, ROOM_PEACEFUL) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->room_flags, ROOM_SOUNDPROOF) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->room_flags, ROOM_NOTRACK) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->room_flags, ROOM_NOMAGIC) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->room_flags, ROOM_TUNNEL) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->room_flags, ROOM_NOFLOOR) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->room_flags, ROOM_NOSEEXIT) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->room_flags, ROOM_NORADIO) ? 1 : 0); uvfprintf(fp2, "\n"); uvfprintf (fp, "#%d\n", i); uvfprintf (fp, "%s~\n", room->name); uvfprintf (fp, "%s~\n", room->description); uvfprintf (fp, "%d %d %d\n", zone_table[room->zone].number, room->room_flags, room->sector_type); for (j = 0; j < NUM_OF_DIRS; j++) { if (room->dir_option[j]) { int temp_door_flag; uvfprintf(fp2, " Exit %s\n", dirs[j]); uvfprintf(fp2, " StartExit\n"); uvfprintf(fp2, " ExitID %d\n", room->dir_option[j]->to_room_vnum); if (room->dir_option[j]->general_description) uvfprintf(fp2, " Description\n%s~\n", room->dir_option[j]->general_description); if (room->dir_option[j]->exit_string) { uvfprintf(fp2, " ActionDescription %s\n", room->dir_option[j]->exit_string); } /* Door */ if (IS_SET(room->dir_option[j]->exit_info, EX_ISDOOR) && room->dir_option[j]->keyword) { uvfprintf(fp2, " Door\n"); uvfprintf(fp2, " StartDoor\n"); if (room->dir_option[j]->keyword) { uvfprintf(fp2, " Name "); uvfprintf(fp2, "the %s\n", fname(room->dir_option[j]->keyword)); uvfprintf(fp2, " Aliases %s\n", room->dir_option[j]->keyword); } uvfprintf(fp2, " Attributes "); uvfprintf(fp2, "%d", IS_SET(room->dir_option[j]->exit_info, EX_PICKPROOF) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->dir_option[j]->exit_info, EX_HIDDEN) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->dir_option[j]->exit_info, EX_UNOPENABLE) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->dir_option[j]->exit_info, EX_AUTOCLOSE) ? 1 : 0); uvfprintf(fp2, "%d", IS_SET(room->dir_option[j]->exit_info, EX_AUTOLOCK) ? 1 : 0); uvfprintf(fp2, "\n"); uvfprintf(fp2, " EndDoor\n"); } uvfprintf(fp2, " EndExit\n"); uvfprintf (fp, "D%c\n", dirs[j][0]); uvfprintf (fp, "%s~\n", room->dir_option[j]->general_description ? room->dir_option[j]->general_description : ""); uvfprintf (fp, "%s~\n", room->dir_option[j]->keyword ? room->dir_option[j]->keyword : ""); if (room->dir_option[j]->exit_string) { uvfprintf (fp, "X\n%s~\n", room->dir_option[j]->exit_string); } /* door flags need special handling, unfortunately. argh! */ temp_door_flag = room->dir_option[j]->exit_info; /* take out closed, locked, and all that bull shit */ REMOVE_BIT (temp_door_flag, EX_CLOSED & EX_LOCKED); /* this fixed up the mess I made earlier. Hopefully builders aren't stupid enough to exploit this DELIBERATE bug. */ if (IS_SET (temp_door_flag, EX_CLOSED | EX_LOCKED | EX_PICKPROOF | EX_HIDDEN | EX_UNOPENABLE | EX_AUTOCLOSE | EX_AUTOLOCK)) { SET_BIT (temp_door_flag, EX_ISDOOR); } uvfprintf (fp, "%d %d %d\n", /* change */ temp_door_flag, room->dir_option[j]->key, room->dir_option[j]->to_room_vnum); } } if (room->ex_description) { int count = 0; for (ex_desc = room->ex_description; ex_desc; ex_desc = ex_desc->next) { if (ex_desc && ex_desc->keyword && ex_desc->description) { count++; fprintf (fp, "E\n"); fprintf (fp, "%s~\n", ex_desc->keyword); uvfprintf (fp, "%s~\n", ex_desc->description); } } if (count) { uvfprintf(fp2, "ExtraDescriptions %d\n", count); for (ex_desc = room->ex_description; ex_desc; ex_desc = ex_desc->next) { if (ex_desc && ex_desc->keyword && ex_desc->description) { uvfprintf(fp2, "StartExtraDescription\n"); uvfprintf(fp2, "Aliases %s\n", ex_desc->keyword); uvfprintf(fp2, "Description\n%s~\n", ex_desc->description); uvfprintf(fp2, "EndExtraDescription\n"); } } } } if (room->extended && (room->extended->damage_per_tick || room->extended->heal_regen || room->extended->mana_regen || room->extended->move_regen)) { fprintf (fp, "X\n"); fprintf (fp, "%d %d %d %d %d\n", room->extended->damage_per_tick, room->extended->damage_type, room->extended->heal_regen, room->extended->mana_regen, room->extended->move_regen); } uvfprintf (fp, "S\n"); uvfprintf(fp2, "EndRoom\n"); } } /* free temporary */ free (room); /* write final line and close */ uvfprintf (fp, "$~\n"); fclose (fp); fclose (fp2); } /************************************************************************** The main loop **************************************************************************/ /* the main menu */ void redit_disp_menu (DESCRIPTOR * d) { send_to_char (DCH, ""); d->edit_mode = REDIT_MAIN_MENU; send_to_char (DCH, "Room number : %s%d%s\r\n", HLCYN (DCH), d->edit_number, CCNRM (DCH)); send_to_char (DCH, "%s1%s) Name : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DROOM->name, CCNRM (DCH)); send_to_char (DCH, "%s2%s) Description :\r\n%s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), DROOM->description, CCNRM (DCH)); /* sprintf (buf, "Room zone: %s%d%s\r\n", HLCYN (DCH), zone_table[DROOM->zone].number, CCNRM (DCH)); send_to_char ( DCH,buf); */ sprintbit ((long) DROOM->room_flags, room_bits, buf2); send_to_char (DCH, "%s3%s) Flags : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf2, CCNRM (DCH)); sprinttype (DROOM->sector_type, sector_types, buf2); send_to_char (DCH, "%s4%s) Sector type : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf2, CCNRM (DCH)); if (DROOM->dir_option[NORTH]) { sprintf (buf2, "%d", DROOM->dir_option[NORTH]->to_room_vnum); } else { strcpy (buf2, ""); } send_to_char (DCH, "%s5%s) Exit north to: %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf2, CCNRM (DCH)); if (DROOM->dir_option[EAST]) { sprintf (buf2, "%d", DROOM->dir_option[EAST]->to_room_vnum); } else { strcpy (buf2, ""); } send_to_char (DCH, "%s6%s) Exit east to : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf2, CCNRM (DCH)); if (DROOM->dir_option[SOUTH]) { sprintf (buf2, "%d", DROOM->dir_option[SOUTH]->to_room_vnum); } else { strcpy (buf2, ""); } send_to_char (DCH, "%s7%s) Exit south to: %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf2, CCNRM (DCH)); if (DROOM->dir_option[WEST]) { sprintf (buf2, "%d", DROOM->dir_option[WEST]->to_room_vnum); } else { strcpy (buf2, ""); } send_to_char (DCH, "%s8%s) Exit west to : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf2, CCNRM (DCH)); if (DROOM->dir_option[UP]) { sprintf (buf2, "%d", DROOM->dir_option[UP]->to_room_vnum); } else { strcpy (buf2, ""); } send_to_char (DCH, "%s9%s) Exit up to : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf2, CCNRM (DCH)); if (DROOM->dir_option[DOWN]) { sprintf (buf2, "%d", DROOM->dir_option[DOWN]->to_room_vnum); } else { strcpy (buf2, ""); } send_to_char (DCH, "%sa%s) Exit down to : %s%s%s\r\n", HLMAG (DCH), CCNRM (DCH), HLCYN (DCH), buf2, CCNRM (DCH)); send_to_char (DCH, "%sb%s) Extra descriptions\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%sc%s) Extended information\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "%sq%s) Quit\r\n", HLMAG (DCH), CCNRM (DCH)); send_to_char (DCH, "Enter your choice:\r\n"); } void redit_parse (DESCRIPTOR * d, char *arg) { extern struct room_data *world; int i, j; int room_num; switch (d->edit_mode) { case REDIT_CONFIRM_EDIT: switch (*arg) { case 'y': case 'Y': redit_disp_menu (d); break; case 'n': case 'N': /* player doesn't want to edit, free entire temp room */ sprintf (buf, "%s has exited redit.", GET_NAME (DCH)); mudlog (buf, CMP, MAX (LVL_GOD, GET_INVIS_LEV (DCH)), true); STATE (d) = CON_PLAYING; if (DROOM) /* So far, free_room here is kosher. */ { free_room (DROOM); } DROOM = null; REMOVE_BIT (PLR_FLAGS (DCH), PLR_EDITING); break; default: send_to_char (DCH, "That's not a valid choice!\r\n"); send_to_char (DCH, "Do you wish to edit it?\r\n"); break; } break; /* end of REDIT_CONFIRM_EDIT */ case REDIT_CONFIRM_SAVESTRING: switch (*arg) { case 'y': case 'Y': /* use REAL_ROOM_REGARDLESS!!! */ room_num = real_room_regardless (d->edit_number); /* room deletion code will write over this so I don't have to worry about anything. :) */ if (room_num >= 0) { int deleted = false; struct extra_descr_data *this, *next_one; /* copy people/object pointers over to the new room already */ DROOM->contents = world[room_num].contents; DROOM->people = world[room_num].people; /* don't forget place in full_room list */ DROOM->next = world[room_num].next; /* find the original room, and free all strings/pointers */ if (world[room_num].name) { free (world[room_num].name); } if (world[room_num].description) { free (world[room_num].description); } for (i = 0; i < NUM_OF_DIRS; i++) { if (world[room_num].dir_option[i]) { if (world[room_num].dir_option[i]->general_description) { free (world[room_num].dir_option[i]->general_description); } if (world[room_num].dir_option[i]->keyword) { free (world[room_num].dir_option[i]->keyword); } if (world[room_num].dir_option[i]->exit_string) { free (world[room_num].dir_option[i]->exit_string); } free (world[room_num].dir_option[i]); } } if (world[room_num].ex_description) for (this = world[room_num].ex_description; this; this = next_one) { next_one = this->next; if (this->keyword) { free (this->keyword); } if (this->description) { free (this->description); } free (this); } if (world[room_num].extended) { free (world[room_num].extended); } /* we need to save this, because the next assignment obliterates the delete flag in world */ deleted = ROOM_DELETED (room_num); /* now copy everything over! */ world[room_num] = *DROOM; if (deleted) { /* Make sure the room is not flagged deleted */ world[room_num].deleted = false; /* The number must be corrected */ world[room_num].number = d->edit_number; /* Update any rooms in the world which had exits to this room */ for (i = 0; i < top_of_world + 1; i++) { #ifdef ARGLEBARGLE /* hey big jeff - I don't know how arena shit works (and frankly I don't want to know..) - does something perverted need to be done to full_rooms? You may also need to take a gander at rdel code in olc.c */ #endif for (j = 0; j < NUM_OF_DIRS; j++) { /* if exit exists */ if (world[i].dir_option[j]) { if (world[i].dir_option[j]->to_room_vnum == d->edit_number) { world[i].dir_option[j]->to_room = room_num; } } } } } /* resolve all vnum doors to rnum doors in the newly edited room */ for (i = 0; i < NUM_OF_DIRS; i++) { if (world[room_num].dir_option[i]) { world[room_num].dir_option[i]->to_room = real_room (world[room_num].dir_option[i]->to_room_vnum); } } } else { insert_room (DROOM, d->edit_number); } room_num = real_room (d->edit_number); /* save room */ send_to_char (DCH, "Writing room to disk.\r\n"); send_to_char (DCH, "Saved.\r\n"); /* do NOT free strings! just the room structure, since we did a memberwise copy on the room. */ free (DROOM); DROOM = null; /*************************************************************/ /* now for the auto link code */ for (d->edit_number2 = NORTH; d->edit_number2 <= DOWN; d->edit_number2++) { /* if the exit exists */ if (world[room_num].DEXIT) { /* if exit is to a room not in your zone, continue */ if (world[room_num].DEXIT->to_room_vnum < zone_table[d->edit_zone].number * 100 || world[room_num].DEXIT->to_room_vnum > zone_table[d->edit_zone].top) { continue; } /* if the room that the exit goes to doesn't exit .. */ if ((world[room_num].DEXIT->to_room < 0) || /* room EXISTS, but reverse exit doesn't exist or goes to wrong place */ (world[room_num].DEXIT->to_room > -1 && (!world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]] || world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]]->to_room != room_num))) { break; } } } if (d->edit_number2 > DOWN) { write_zone_rooms (d->edit_zone); rebuild_arena_list (zone_table[d->edit_zone].number); REMOVE_BIT (PLR_FLAGS (DCH), PLR_EDITING); sprintf (buf, "%s has exited redit.", GET_NAME (DCH)); mudlog (buf, CMP, MAX (LVL_GOD, GET_INVIS_LEV (DCH)), true); STATE (d) = CON_PLAYING; send_to_char (DCH, "Done.\r\n"); d->edit_number = 0; return; } else if (world[room_num].DEXIT->to_room < 0 && world[room_num].DEXIT->to_room_vnum >= 0 && world[room_num].DEXIT->to_room_vnum >= zone_table[d->edit_zone].number * 100 && world[room_num].DEXIT->to_room_vnum <= zone_table[d->edit_zone].top) { send_to_char (DCH, "There is an exit %s to room %d, which doesn't exist.\r\nShould that room be created?\r\n", dirs[d->edit_number2], world[room_num].DEXIT->to_room_vnum); } else if (world[room_num].DEXIT->to_room > -1 && world[room_num].DEXIT->to_room_vnum >= zone_table[d->edit_zone].number * 100 && world[room_num].DEXIT->to_room_vnum <= zone_table[d->edit_zone].top) if (!world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]] || world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]]->to_room != room_num) { send_to_char (DCH, "There is an exit %s to room %d, but the %s exit in that room\r\n does not lead here. Should it be changed?\r\n", dirs[d->edit_number2], world[room_num].DEXIT->to_room_vnum, dirs[rev_dir[d->edit_number2]]); } d->edit_mode = REDIT_CONFIRM_ATTACHROOM; break; case 'n': case 'N': send_to_char (DCH, "Room not saved, aborting.\r\n"); sprintf (buf, "%s has exited redit.", GET_NAME (DCH)); mudlog (buf, CMP, MAX (LVL_GOD, GET_INVIS_LEV (DCH)), true); STATE (d) = CON_PLAYING; REMOVE_BIT (PLR_FLAGS (DCH), PLR_EDITING); /* free everything up, including strings etc */ if (DROOM) /* free room here is OK too. */ { free_room (DROOM); } DROOM = null; d->edit_number = 0; break; default: send_to_char (DCH, "Invalid choice!\r\n"); send_to_char (DCH, "Do you wish to save this room?"); break; } break; /* end of REDIT_CONFIRM_SAVESTRING */ case REDIT_CONFIRM_ATTACHROOM: room_num = real_room (d->edit_number); switch (*arg) { case 'y': case 'Y': if (world[room_num].DEXIT->to_room < 0) { struct room_data *temproom; CREATE (temproom, struct room_data, 1); temproom->zone = d->edit_zone; temproom->name = strdup ("An unfinished room"); temproom->description = strdup ("You are in an unfinished room.\r\n"); CREATE (temproom->dir_option[rev_dir[d->edit_number2]], struct room_direction_data, 1); temproom->dir_option[rev_dir[d->edit_number2]]->to_room_vnum = d->edit_number; insert_room (temproom, world[room_num].DEXIT->to_room_vnum); /* Free the room (but don't free the elements!) */ free (temproom); } else if (world[room_num].DEXIT->to_room > -1) if (!world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]] || world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]]->to_room != room_num) { if (world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]]) { free (world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]]); } CREATE (world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]], struct room_direction_data, 1); world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]]->to_room_vnum = d->edit_number; world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]]->to_room = room_num; } /* FALL THROUGH */ default: /* now for the auto link code */ for (d->edit_number2 = d->edit_number2 + 1; d->edit_number2 <= DOWN; d->edit_number2++) { /* if the exit exists */ if (world[room_num].DEXIT) { /* if exit is to a room not in your zone, continue */ if (world[room_num].DEXIT->to_room_vnum < zone_table[d->edit_zone].number * 100 || world[room_num].DEXIT->to_room_vnum > zone_table[d->edit_zone].top) { continue; } /* if the room that the exit goes to doesn't exit .. */ if ((world[room_num].DEXIT->to_room < 0) || /* room EXISTS, but reverse exit doesn't exist or goes to wrong place */ (world[room_num].DEXIT->to_room > -1 && (!world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]] || world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]]->to_room != room_num))) { break; } } } if (d->edit_number2 > DOWN) { write_zone_rooms (d->edit_zone); REMOVE_BIT (PLR_FLAGS (DCH), PLR_EDITING); sprintf (buf, "%s has exited redit.", GET_NAME (DCH)); mudlog (buf, CMP, MAX (LVL_GOD, GET_INVIS_LEV (DCH)), true); STATE (d) = CON_PLAYING; send_to_char (DCH, "Done.\r\n"); d->edit_number = 0; return; } /* oooops hehehe bug fixed jan 8 julian - <= changed to >= */ else if (world[room_num].DEXIT->to_room < 0 && world[room_num].DEXIT->to_room_vnum >= 0 && world[room_num].DEXIT->to_room_vnum >= zone_table[d->edit_zone].number * 100 && world[room_num].DEXIT->to_room_vnum <= zone_table[d->edit_zone].top) { send_to_char (DCH, "There is an exit %s to room %d, which doesn't exist.\r\nShould that room be created?\r\n", dirs[d->edit_number2], world[room_num].DEXIT->to_room_vnum); } else if (world[room_num].DEXIT->to_room > -1 && world[room_num].DEXIT->to_room_vnum >= zone_table[d->edit_zone].number * 100 && world[room_num].DEXIT->to_room_vnum <= zone_table[d->edit_zone].top) if (!world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]] || world[world[room_num].DEXIT->to_room].dir_option[rev_dir[d->edit_number2]]->to_room != room_num) { send_to_char (DCH, "There is an exit %s to room %d, but the %s exit in that room\r\n does not lead here. Should it be changed?\r\n", dirs[d->edit_number2], world[room_num].DEXIT->to_room_vnum, dirs[rev_dir[d->edit_number2]]); } d->edit_mode = REDIT_CONFIRM_ATTACHROOM; break; } break; case REDIT_MAIN_MENU: switch (*arg) { case 'q': case 'Q': send_to_char ( DCH, "Do you wish to save this room?\r\n"); d->edit_mode = REDIT_CONFIRM_SAVESTRING; break; case '1': send_to_char (DCH, "Enter room name:"); d->edit_mode = REDIT_NAME; break; case '2': send_to_char (DCH, "Edit room description:\r\n"); d->edit_mode = REDIT_DESC; d->str = (char **) malloc (sizeof (char *)); if (DROOM->description) { *(d->str) = strdup (DROOM->description); init_text (d); } else { *d->str = null; } d->max_str = MAX_MESSAGE_LENGTH; d->mail_to = 0; break; case '3': redit_disp_flag_menu (d); break; case '4': redit_disp_sector_menu (d); break; case '5': d->edit_number2 = NORTH; redit_disp_exit_menu (d); break; case '6': d->edit_number2 = EAST; redit_disp_exit_menu (d); break; case '7': d->edit_number2 = SOUTH; redit_disp_exit_menu (d); break; case '8': d->edit_number2 = WEST; redit_disp_exit_menu (d); break; case '9': d->edit_number2 = UP; redit_disp_exit_menu (d); break; case 'a': case 'A': d->edit_number2 = DOWN; redit_disp_exit_menu (d); break; case 'b': case 'B': /* if extra desc doesn't exist . */ if (!DROOM->ex_description) { CREATE (DROOM->ex_description, struct extra_descr_data, 1); DROOM->ex_description->next = null; } d->misc_data = (void **) &(DROOM->ex_description); redit_disp_extradesc_menu (d); break; case 'c': case 'C': redit_disp_extension_menu (d); break; default: send_to_char (DCH, "Invalid choice!"); redit_disp_menu (d); break; } break; case REDIT_EXTENSION_SELECT: i = atoi (arg); if ((i < 0) || (i > 5)) { send_to_char (DCH, "That's not a valid choice!\r\n"); redit_disp_extension_menu (d); return; } d->edit_number2 = i; switch (i) { case 0: /* if nothing was changed, free up */ if (DROOM->extended->damage_per_tick == 0 && DROOM->extended->heal_regen == 0 && DROOM->extended->mana_regen == 0 && DROOM->extended->move_regen == 0) { free (DROOM->extended); DROOM->extended = null; } redit_disp_menu (d); break; case 1: send_to_char (DCH, "Enter damage per tick:"); d->edit_mode = REDIT_EXTENSION_INPUT; break; case 2: /* MENU MENU MENU */ redit_disp_damage_menu (d); d->edit_mode = REDIT_EXTENSION_INPUT; break; case 3: send_to_char (DCH, "Enter heal regen rate as % diff from normal (ie -50 is half rate:)"); d->edit_mode = REDIT_EXTENSION_INPUT; break; case 4: send_to_char (DCH, "Enter mana regen rate as % diff from normal (ie -50 is half rate:)"); d->edit_mode = REDIT_EXTENSION_INPUT; break; case 5: send_to_char (DCH, "Enter move regen rate as % diff from normal (ie -50 is half rate:)"); d->edit_mode = REDIT_EXTENSION_INPUT; break; } break; case REDIT_EXTENSION_INPUT: i = atoi (arg); switch (d->edit_number2) { case 1: DROOM->extended->damage_per_tick = i; break; case 2: if (i < 0 || i >= MAX_ROOM_DAMAGE) { send_to_char (DCH, "Invalid choice!\r\n"); redit_disp_damage_menu (d); } DROOM->extended->damage_type = i; case 3: DROOM->extended->heal_regen = i; break; case 4: DROOM->extended->mana_regen = i; break; case 5: DROOM->extended->move_regen = i; break; } redit_disp_extension_menu (d); break; case REDIT_NAME: if (!*arg) { send_to_char (DCH, "Invalid room name!\r\nEnter room name:"); return; } if (DROOM->name) { free (DROOM->name); } DROOM->name = strdup (arg); redit_disp_menu (d); break; case REDIT_DESC: /* we will NEVER get here */ break; case REDIT_FLAGS: i = atoi (arg); if ((i < 0) || (i > NUM_ROOM_FLAGS)) { send_to_char (DCH, "That's not a valid choice!\r\n"); redit_disp_flag_menu (d); } else { if (i == 0) /* back out */ { redit_disp_menu (d); } else { /* toggle bits */ if (IS_SET (DROOM->room_flags, 1 << (i - 1))) { REMOVE_BIT (DROOM->room_flags, 1 << (i - 1)); } else { SET_BIT (DROOM->room_flags, 1 << (i - 1)); } redit_disp_flag_menu (d); } } break; case REDIT_SECTOR: i = atoi (arg); if (i < 0 || i >= NUM_ROOM_SECTORS) { send_to_char (DCH, "Invalid choice!"); redit_disp_sector_menu (d); } else { DROOM->sector_type = i; redit_disp_menu (d); } break; case REDIT_EXIT_MENU: switch (*arg) { case '0': redit_disp_menu (d); break; case '1': d->edit_mode = REDIT_EXIT_NUMBER; send_to_char (DCH, "Exit to room number:"); break; case '2': d->edit_mode = REDIT_EXIT_DESCRIPTION; send_to_char (DCH, "Edit exit description:\r\n"); d->str = (char **) malloc (sizeof (char *)); if (DROOM->DEXIT->general_description) { *(d->str) = strdup (DROOM->DEXIT->general_description); init_text (d); } else { *(d->str) = null; } d->max_str = MAX_MESSAGE_LENGTH; d->mail_to = 0; break; case '3': d->edit_mode = REDIT_EXIT_KEYWORD; send_to_char (DCH, "Enter keywords:"); break; case '4': d->edit_mode = REDIT_EXIT_KEY; send_to_char (DCH, "Enter key number:"); break; case '5': redit_disp_exit_flag_menu (d); d->edit_mode = REDIT_EXIT_DOORFLAGS; break; case '6': send_to_char (DCH, "Enter exit string:"); d->edit_mode = REDIT_EXIT_STRING; break; case '7': /* delete exit */ if (DROOM->DEXIT->keyword) { free (DROOM->DEXIT->keyword); } if (DROOM->DEXIT->general_description) { free (DROOM->DEXIT->general_description); } if (DROOM->DEXIT->exit_string) { free (DROOM->DEXIT->exit_string); } free (DROOM->DEXIT); DROOM->DEXIT = null; redit_disp_menu (d); break; default: send_to_char (DCH, "Invalid choice!\r\n"); break; } break; case REDIT_EXIT_NUMBER: i = atoi (arg); if (i < -1) { send_to_char (DCH, "Invalid choice!\r\nExit to room number:"); } else { DROOM->DEXIT->to_room_vnum = i; redit_disp_exit_menu (d); } break; case REDIT_EXIT_DESCRIPTION: /* we should NEVER get here */ break; case REDIT_EXIT_STRING: if (DROOM->DEXIT->exit_string) { free (DROOM->DEXIT->exit_string); } delete_doubledollar (arg); DROOM->DEXIT->exit_string = strdup (arg); redit_disp_exit_menu (d); break; case REDIT_EXIT_KEYWORD: if (!*arg) { send_to_char (DCH, "Invalid keywords!\r\nEnter keywords:"); break; } if (DROOM->DEXIT->keyword) { free (DROOM->DEXIT->keyword); } DROOM->DEXIT->keyword = strdup (arg); redit_disp_exit_menu (d); break; case REDIT_EXIT_KEY: i = atoi (arg); DROOM->DEXIT->key = i; redit_disp_exit_menu (d); break; case REDIT_EXIT_DOORFLAGS: i = atoi (arg); if ((i < 0) || (i > NUM_EXIT_FLAGS)) { send_to_char (DCH, "That's not a valid choice!\r\n"); redit_disp_exit_flag_menu (d); } else if (i == 2 || i == 3) { send_to_char (DCH, "You cannot set that for doors in the room editor.\r\n"); redit_disp_exit_flag_menu (d); } else { if (i == 0) /* back out */ { redit_disp_exit_menu (d); } else { /* toggle bits */ if (IS_SET (DROOM->DEXIT->exit_info, 1 << (i - 1))) { REMOVE_BIT (DROOM->DEXIT->exit_info, 1 << (i - 1)); } else { SET_BIT (DROOM->DEXIT->exit_info, 1 << (i - 1)); } redit_disp_exit_flag_menu (d); } } break; case REDIT_EXTRADESC_KEY: if (!*arg) { send_to_char (DCH, "Invalid keyword list!\r\nEnter keywords, separated by spaces:"); return; } if (((struct extra_descr_data *) *d->misc_data)->keyword) { free (((struct extra_descr_data *) *d->misc_data)->keyword); } ((struct extra_descr_data *) *d->misc_data)->keyword = strdup (arg); redit_disp_extradesc_menu (d); break; case REDIT_EXTRADESC_MENU: i = atoi (arg); switch (i) { case 0: { /* if something got left out, delete the extra desc when backing out to menu */ if (!((struct extra_descr_data *) *d->misc_data)->keyword || !((struct extra_descr_data *) *d->misc_data)->description) { if (((struct extra_descr_data *) *d->misc_data)->keyword) { free (((struct extra_descr_data *) *d->misc_data)->keyword); } if (((struct extra_descr_data *) *d->misc_data)->description) { free (((struct extra_descr_data *) *d->misc_data)->description); } free (*d->misc_data); *d->misc_data = null; } /* else, we don't need to do anything.. jump to menu */ redit_disp_menu (d); } break; case 1: d->edit_mode = REDIT_EXTRADESC_KEY; send_to_char (DCH, "Enter keywords, separated by spaces:"); break; case 2: d->edit_mode = REDIT_EXTRADESC_DESCRIPTION; send_to_char (DCH, "Edit extra description:\r\n"); /* send out to modify.c */ d->str = (char **) malloc (sizeof (char *)); if (((struct extra_descr_data *) *d->misc_data)->description) { *(d->str) = strdup (((struct extra_descr_data *) *d->misc_data)->description); init_text (d); } else { *(d->str) = null; } d->max_str = MAX_MESSAGE_LENGTH; d->mail_to = 0; break; case 3: if (!((struct extra_descr_data *) *d->misc_data)->keyword || !((struct extra_descr_data *) *d->misc_data)->description) { send_to_char (DCH, "You can't edit the next extra desc without completing this one.\r\n"); redit_disp_extradesc_menu (d); } else { struct extra_descr_data *new_extra; if (((struct extra_descr_data *) *d->misc_data)->next) { d->misc_data = (void **) &((struct extra_descr_data *) *d->misc_data)->next; } else { /* make new extra, attach at end */ CREATE (new_extra, struct extra_descr_data, 1); ((struct extra_descr_data *) *d->misc_data)->next = new_extra; d->misc_data = (void **) &((struct extra_descr_data *) *d->misc_data)->next; } redit_disp_extradesc_menu (d); } } break; default: /* we should never get here */ break; } }