Eldhamud_2.5.83/clans/
Eldhamud_2.5.83/classes/
Eldhamud_2.5.83/doc/
Eldhamud_2.5.83/doc/DIKU/
Eldhamud_2.5.83/doc/MERC/
Eldhamud_2.5.83/doc/mudprogs/
Eldhamud_2.5.83/houses/
/****************************************************************************
 *			Eldhamud Codebase V2.0				    *
 * ------------------------------------------------------------------------ *
 * EldhaMUD code (C) 2003-2008 by Robert Powell (Tommi)                     *
 * EldhaMUD Team: Celest, Altere and Krelowyn                               *
 * ------------------------------------------------------------------------ *
 *                                                                          *
 *     OasisOLC II for Smaug 1.40 written by Evan Cortens(Tagith)           *
 *                                                                          *
 *   Based on OasisOLC for CircleMUD3.0bpl9 written by Harvey Gilpin        *
 *                                                                          *
 **************************************************************************** 
 *                                                                          *
 *                      Room editing module (medit.c)                       *
 *                                                                          *
 ****************************************************************************/
#include <stdio.h>
#include <string.h>
#include "./Headers/mud.h"
#include "./Headers/olc.h"
/*------------------------------------------------------------------------*/
/* function prototypes */
int get_rflag args( ( char *flag ) );
DECLARE_DO_FUN( do_redit_reset );
void redit_disp_extradesc_menu args( ( DESCRIPTOR_DATA * d ) );
void redit_disp_exit_menu args( ( DESCRIPTOR_DATA * d ) );
void redit_disp_exit_flag_menu args( ( DESCRIPTOR_DATA * d ) );
void redit_disp_flag_menu args( ( DESCRIPTOR_DATA * d ) );
void redit_disp_sector_menu args( ( DESCRIPTOR_DATA * d ) );
void redit_disp_menu args( ( DESCRIPTOR_DATA * d ) );
void redit_setup_new args( ( DESCRIPTOR_DATA * d ) );
void free_room args( ( ROOM_INDEX_DATA * room ) );
/*-----------------------------------------------------------------------*/
/* Global variable declarations/externals */
/* EXIT_DATA *get_exit_number( ROOM_INDEX_DATA *room, int xit ); */
void oedit_disp_extra_choice args( ( DESCRIPTOR_DATA * d ) );
extern char *const ex_flags[];
extern int top_ed;
/*-----------------------------------------------------------------------*/
void do_oredit( CHAR_DATA * ch, char *argument )
{
   char arg[MAX_INPUT_LENGTH];
   DESCRIPTOR_DATA *d;
   ROOM_INDEX_DATA *room;
   if( IS_NPC( ch ) || !ch->desc )
   {
      send_to_char( "I don't think so...\n\r", ch );
      return;
   }
   argument = one_argument( argument, arg );
   if( argument[0] == STRING_NULL )
      room = ch->in_room;
   else
   {
      if( is_number( arg ) )
      {
         argument = one_argument( argument, arg );
         room = get_room_index( atoi( arg ) );
      }
      else
      {
         send_to_char( "Vnum must be specified in numbers!\n\r", ch );
         return;
      }
   }
   if( !room )
   {
      send_to_char( "That room does not exist!\n\r", ch );
      return;
   }
   /*
    * Make sure the room isnt already being edited 
    */
   for( d = first_descriptor; d; d = d->next )
      if( d->connected == CON_REDIT )
         if( d->olc && OLC_VNUM( d ) == room->vnum )
         {
            ch_printf( ch, "That room is currently being edited by %s.\n\r", d->character->name );
            return;
         }
   if( !can_rmodify( ch, room ) )
      return;
   do_immtalk( ch, "BrB, Going into Oasis OLC" );
   act( AT_ACTION, "$n starts using OLC.", ch, NULL, NULL, TO_ROOM );
   d = ch->desc;
   CREATE( d->olc, OLC_DATA, 1 );
   OLC_VNUM( d ) = room->vnum;
   OLC_CHANGE( d ) = FALSE;
   d->character->dest_buf = room;
   d->connected = CON_REDIT;
   redit_disp_menu( d );
   return;
}
void do_rcopy( CHAR_DATA * ch, char *argument )
{
   return;
}
bool is_inolc( DESCRIPTOR_DATA * d )
{
   /*
    * safeties, not that its necessary really... 
    */
   if( !d || !d->character )
      return FALSE;
   if( IS_NPC( d->character ) )
      return FALSE;
   /*
    * objs 
    */
   if( d->connected == CON_OEDIT )
      return TRUE;
   /*
    * mobs 
    */
   if( d->connected == CON_MEDIT )
      return TRUE;
   /*
    * rooms 
    */
   if( d->connected == CON_REDIT )
      return TRUE;
   return FALSE;
}
/*
 * Log all changes to catch those sneaky bastards =)
 */
/* void olc_log( DESCRIPTOR_DATA *d, char *argument ) */
void olc_log( DESCRIPTOR_DATA * d, char *format, ... )
{
   ROOM_INDEX_DATA *room = d->character->dest_buf;
   OBJ_DATA *obj = d->character->dest_buf;
   CHAR_DATA *victim = d->character->dest_buf;
   char logline[MAX_STRING_LENGTH];
   va_list args;
   if( !d )
   {
      bug( "olc_log: called with null descriptor", 0 );
      return;
   }
   va_start( args, format );
   vsprintf( logline, format, args );
   va_end( args );
   sprintf( log_buf, "Log %s:", d->character->name );
   if( d->connected == CON_REDIT )
      sprintf( log_buf, "%s ROOM(%d): ", log_buf, room->vnum );
   else if( d->connected == CON_OEDIT )
      sprintf( log_buf, "%s OBJ(%d): ", log_buf, obj->pIndexData->vnum );
   else if( d->connected == CON_MEDIT )
   {
      if( IS_NPC( victim ) )
         sprintf( log_buf, "%s MOB(%d): ", log_buf, victim->pIndexData->vnum );
      else
         sprintf( log_buf, "%s PLR(%s): ", log_buf, victim->name );
   }
   else
   {
      bug( "olc_log: called with a bad connected state", 0 );
      return;
   }
   sprintf( log_buf, "%s%s", log_buf, logline );
   log_string_plus( log_buf, LOG_BUILD, get_trust( d->character ) );
   return;
}
/**************************************************************************
  Menu functions 
 **************************************************************************/
/*
 * Nice fancy redone Extra Description stuff :)
 */
void redit_disp_extradesc_prompt_menu( DESCRIPTOR_DATA * d )
{
   char buf[MAX_STRING_LENGTH];
   EXTRA_DESCR_DATA *ed;
   ROOM_INDEX_DATA *room = d->character->dest_buf;
   int counter = 0;
   for( ed = room->first_extradesc; ed; ed = ed->next )
   {
      sprintf( buf, "&P%2d&w) %-40.40s\n\r", counter++, ed->keyword );
      send_to_char_color( buf, d->character );
   }
   send_to_char( "\n\rWhich extra description do you want to edit? ", d->character );
}
void redit_disp_extradesc_menu( DESCRIPTOR_DATA * d )
{
   ROOM_INDEX_DATA *room = d->character->dest_buf;
   int count = 0;
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   ch_printf_color( d->character,"&c Extra Descriptions Menu                                           EldhaMUD OLC\n\r", 0 );
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   if( room->first_extradesc )
   {
      EXTRA_DESCR_DATA *ed;
      for( ed = room->first_extradesc; ed; ed = ed->next )
      {
         ch_printf_color( d->character, "&P%2d&w) Keyword: &O%s\n\r", ++count, ed->keyword );
      }
      send_to_char( "\n\r", d->character );
   }
   ch_printf_color( d->character, "&PA&w) Add a new description\n\r" );
   ch_printf_color( d->character, "&PR&w) Remove a description\n\r" );
   ch_printf_color( d->character, "&PQ&w) Quit\n\r" );
   ch_printf_color( d->character, "\n\rEnter choice: " );
   OLC_MODE( d ) = REDIT_EXTRADESC_MENU;
}
/* For exits */
void redit_disp_exit_menu( DESCRIPTOR_DATA * d )
{
   /*
    * char buf[MAX_STRING_LENGTH]; 
    */
   ROOM_INDEX_DATA *room = d->character->dest_buf;
   EXIT_DATA *pexit;
   int i, cnt, endline;
   OLC_MODE( d ) = REDIT_EXIT_MENU;
   endline = d->character->pcdata->pagerlen;
   for( i = 0; i <= endline; i++ )
   {
      send_to_char( "\n\r", d->character );
   }
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   ch_printf_color( d->character,"&c Exits Menu                                                        EldhaMUD OLC\n\r", 0 );
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   for( cnt = 0, pexit = room->first_exit; pexit; pexit = pexit->next )
   {
      ch_printf_color( d->character,
                       /*
                        * sprintf( buf, 
                        */
                       "&P%2d&w) %-10.10s to %-5d.  Key: %d  Flags: %d  Keywords: %s.\n\r",
                       ++cnt,
                       dir_name[pexit->vdir],
                       pexit->to_room ? pexit->to_room->vnum : 0,
                       pexit->key, pexit->exit_info, pexit->keyword[0] != STRING_NULL ? pexit->keyword : "(none)" );
   }
   if( room->first_exit )
      send_to_char( "\n\r", d->character );
   send_to_char_color( "&PA&w) Add a new exit\n\r", d->character );
   send_to_char_color( "&PR&w) Remove an exit\n\r", d->character );
   send_to_char_color( "&PQ&w) Quit\n\r", d->character );
   send_to_char( "\n\rEnter choice: ", d->character );
   return;
}
void redit_disp_exit_edit( DESCRIPTOR_DATA * d )
{
   /*
    * ROOM_INDEX_DATA *room = d->character->dest_buf; 
    */
   char flags[MAX_STRING_LENGTH];
   EXIT_DATA *pexit = d->character->spare_ptr;
   int i;
   flags[0] = STRING_NULL;
   for( i = 0; i <= MAX_EXFLAG; i++ )
      if( pexit->exit_info && IS_SET( pexit->exit_info, i ) )
      {
         strcat( flags, ex_flags[i] );
         strcat( flags, " " );
      }
   OLC_MODE( d ) = REDIT_EXIT_EDIT;
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   ch_printf_color( d->character,"&c Exits Creation Menu                                               EldhaMUD OLC\n\r", 0 );
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   ch_printf_color( d->character, "&P1&w) Direction  : &c%s\n\r", dir_name[pexit->vdir] );
   ch_printf_color( d->character, "&P2&w) To Vnum    : &c%d\n\r", pexit->to_room ? pexit->to_room->vnum : -1 );
   ch_printf_color( d->character, "&P3&w) Key        : &c%d\n\r", pexit->key );
   ch_printf_color( d->character, "&P4&w) Keyword    : &c%s\n\r",
                    ( pexit->keyword && pexit->keyword[0] != STRING_NULL ) ? pexit->keyword : "(none)" );
   ch_printf_color( d->character, "&P5&w) Flags      : &c%s\n\r", flags[0] != STRING_NULL ? flags : "(none)" );
   ch_printf_color( d->character, "&P6&w) Description: &c%s\n\r",
                    ( pexit->description && pexit->description[0] != STRING_NULL ) ? pexit->description : "(none)" );
   ch_printf_color( d->character, "&PQ&w) Quit\n\r" );
   ch_printf_color( d->character, "\n\rEnter choice: " );
   return;
}
void redit_disp_exit_dirs( DESCRIPTOR_DATA * d )
{
   int i;
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   ch_printf_color( d->character,"&c Exit Directions                                                   EldhaMUD OLC\n\r", 0 );
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   for( i = 0; i <= DIR_SOMEWHERE; i++ )
   {
      ch_printf_color( d->character, "&P%2d&w) %s\n\r", i, dir_name[i] );
   }
   send_to_char( "\n\rChoose a direction: ", d->character );
   return;
}
/* For exit flags */
void redit_disp_exit_flag_menu( DESCRIPTOR_DATA * d )
{
   EXIT_DATA *pexit = d->character->spare_ptr;
   char buf[MAX_STRING_LENGTH];
   char buf1[MAX_STRING_LENGTH];
   int i;
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   ch_printf_color( d->character,"&c Flags Menu                                                        EldhaMUD OLC\n\r", 0 );
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   for( i = 0; i <= MAX_EXFLAG; i++ )
   {
      if( ( i == EX_RES1 ) || ( i == EX_RES2 ) || ( i == EX_PORTAL ) )
         continue;
      ch_printf_color( d->character, "&P%2d&w) %-20.20s\n\r", i + 1, ex_flags[i] );
   }
   buf1[0] = STRING_NULL;
   for( i = 0; i <= MAX_EXFLAG; i++ )
      if( IS_SET( pexit->exit_info, i ) )
      {
         strcat( buf1, ex_flags[i] );
         strcat( buf1, " " );
      }
   sprintf( buf, "\n\rExit flags: &c%s&w\n\r" "Enter room flags, 0 to quit: ", buf1 );
   send_to_char_color( buf, d->character );
   OLC_MODE( d ) = REDIT_EXIT_FLAGS;
}
/* For room flags */
void redit_disp_flag_menu( DESCRIPTOR_DATA * d )
{
   char buf[MAX_STRING_LENGTH];
   ROOM_INDEX_DATA *room = d->character->dest_buf;
   int counter, columns = 0;
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   ch_printf_color( d->character,"&c Flags Menu                                                        EldhaMUD OLC\n\r", 0 );
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   for( counter = 0; counter < ROOM_MAX; counter++ )
   {
      sprintf( buf, "&P%d&w) %-20.20s ", counter + 1, r_flags[counter] );
      if( !( ++columns % 2 ) )
         strcat( buf, "\n\r" );
      send_to_char_color( buf, d->character );
   }
   ch_printf_color( d->character, "\n\rRoom flags: &c%s&w\n\rEnter room flags, 0 to quit : ",
                    ext_flag_string( &room->room_flags, r_flags ) );
   OLC_MODE( d ) = REDIT_FLAGS;
}
char *const asector_names[] = {
   "inside", "city", "field", "forest", "hills", "mountain", "water_swim",
   "water_noswim", "underwater", "air", "desert", "river", "oceanfloor",
   "underground", "jungle", "swamp", "tundra", "ice", "ocean", "lava", "shore"
};
/* for sector type */
void redit_disp_sector_menu( DESCRIPTOR_DATA * d )
{
   char buf[MAX_STRING_LENGTH];
   int counter, columns = 0;
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   ch_printf_color( d->character,"&c Sector Menu                                                       EldhaMUD OLC\n\r", 0 );
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   for( counter = 0; counter < 21; counter++ )
   {
/*	if ( counter == SECT_DUNNO )
	     continue;
*/
      sprintf( buf, "&P%d&w) %-20.20s ", counter, asector_names[counter] );
      if( !( ++columns % 2 ) )
         strcat( buf, "\n\r" );
      send_to_char_color( buf, d->character );
   }
   send_to_char( "\r\nEnter sector type : ", d->character );
   OLC_MODE( d ) = REDIT_SECTOR;
}
/* the main menu */
void redit_disp_menu( DESCRIPTOR_DATA * d )
{
   char buf[MAX_STRING_LENGTH];
   ROOM_INDEX_DATA *room = d->character->dest_buf;
   char *sect;
   switch ( room->sector_type )
   {
      default:
         sect = "?";
         break;
      case SECT_INSIDE:
         sect = "Inside";
         break;
      case SECT_CITY:
         sect = "City";
         break;
      case SECT_FIELD:
         sect = "Field";
         break;
      case SECT_FOREST:
         sect = "Forest";
         break;
      case SECT_HILLS:
         sect = "Hills";
         break;
      case SECT_MOUNTAIN:
         sect = "Mountains";
         break;
      case SECT_WATER_SWIM:
         sect = "Swim";
         break;
      case SECT_WATER_NOSWIM:
         sect = "Noswim";
         break;
      case SECT_UNDERWATER:
         sect = "Underwater";
         break;
      case SECT_AIR:
         sect = "Air";
         break;
      case SECT_DESERT:
         sect = "Desert";
         break;
      case SECT_RIVER:
         sect = "River";
         break;
      case SECT_OCEANFLOOR:
         sect = "Oceanfloor";
         break;
      case SECT_UNDERGROUND:
         sect = "Underground";
         break;
      case SECT_JUNGLE:
         sect = "Jungle";
         break;
      case SECT_SWAMP:
         sect = "Swamp";
         break;
      case SECT_TUNDRA:
         sect = "Tundra";
         break;
      case SECT_ICE:
         sect = "Ice";
         break;
      case SECT_OCEAN:
         sect = "Ocean";
         break;
      case SECT_LAVA:
         sect = "Lava";
         break;
      case SECT_SHORE:
         sect = "Shore";
         break;
   }
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   ch_printf_color( d->character,"&c Main Menu                                                         EldhaMUD OLC\n\r", 0 );
   ch_printf_color( d->character,"&D--------------------------------------------------------------------------------\n\r");
   sprintf( buf,
            "&w   Room Vnum   : [&c%d&w]      Zone Name: [&c%-30.30s&w]\n\r"
            "&P1&w) Name        : &O%s\n\r"
            "&P2&w) Description :\n\r &O%s\n\r"
            "&P3&w) Room flags  : &c%s\n\r"
            "&P4&w) Sector type : &c%s\n\r"
            "&P5&w) Tunnel      : &c%d\n\r"
            "&P6&w) TeleDelay   : &c%d\n\r"
            "&P7&w) TeleVnum    : &c%d\n\r"
            "&PA&w) Exit menu\n\r"
            "&PB&w) Extra descriptions menu\r\n"
            "&PQ&w) Quit\r\n"
            "Enter choice : ",
            OLC_NUM( d ),
            room->area ? room->area->name : "None????",
            room->name,
            room->description,
            ext_flag_string( &room->room_flags, r_flags ), sect, room->tunnel, room->tele_delay, room->tele_vnum );
   set_char_color( AT_PLAIN, d->character );
   send_to_char_color( buf, d->character );
   OLC_MODE( d ) = REDIT_MAIN_MENU;
}
EXTRA_DESCR_DATA *redit_find_extradesc( ROOM_INDEX_DATA * room, int number )
{
   int count = 0;
   EXTRA_DESCR_DATA *ed;
   for( ed = room->first_extradesc; ed; ed = ed->next )
   {
      if( ++count == number )
         return ed;
   }
   return NULL;
}
void do_redit_reset( CHAR_DATA * ch, char *argument )
{
   ROOM_INDEX_DATA *room = ch->dest_buf;
   EXTRA_DESCR_DATA *ed = ch->spare_ptr;
   switch ( ch->substate )
   {
      case SUB_ROOM_DESC:
         if( !ch->dest_buf )
         {
            /*
             * If theres no dest_buf, theres no object, so stick em back as playing 
             */
            send_to_char( "Fatal error, report to Tagith.\n\r", ch );
            bug( "do_redit_reset: sub_obj_extra: NULL ch->dest_buf", 0 );
            ch->substate = SUB_NONE;
            ch->desc->connected = CON_PLAYING;
            return;
         }
         STRFREE( room->description );
         room->description = copy_buffer( ch );
         stop_editing( ch );
         ch->dest_buf = room;
         ch->desc->connected = CON_REDIT;
         ch->substate = SUB_NONE;
         olc_log( ch->desc, "Edited room description" );
         redit_disp_menu( ch->desc );
         return;
      case SUB_ROOM_EXTRA:
         STRFREE( ed->description );
         ed->description = copy_buffer( ch );
         stop_editing( ch );
         ch->dest_buf = room;
         ch->spare_ptr = ed;
         ch->substate = SUB_NONE;
         ch->desc->connected = CON_REDIT;
         oedit_disp_extra_choice( ch->desc );
         OLC_MODE( ch->desc ) = REDIT_EXTRADESC_CHOICE;
         olc_log( ch->desc, "Edit description for exdesc %s", ed->keyword );
         return;
   }
}
/**************************************************************************
  The main loop
 **************************************************************************/
void redit_parse( DESCRIPTOR_DATA * d, char *arg )
{
   ROOM_INDEX_DATA *room = d->character->dest_buf;
   ROOM_INDEX_DATA *tmp;
   EXIT_DATA *pexit = d->character->spare_ptr;
   EXTRA_DESCR_DATA *ed = d->character->spare_ptr;
   char arg1[MAX_INPUT_LENGTH];
   char buf[MAX_STRING_LENGTH];
   int number = 0;
   switch ( OLC_MODE( d ) )
   {
      case REDIT_CONFIRM_SAVESTRING:
         switch ( *arg )
         {
            case 'y':
            case 'Y':
               /*
                * redit_save_internally(d); 
                */
               sprintf( log_buf, "OLC: %s edits room %d", d->character->name, OLC_NUM( d ) );
               log_string_plus( log_buf, LOG_BUILD, d->character->level );
               cleanup_olc( d );
               send_to_char( "Room saved to memory.\r\n", d->character );
               break;
            case 'n':
            case 'N':
               cleanup_olc( d );
               break;
            default:
               send_to_char( "\n\r\n\rInvalid Command Selection!\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_CHANGE(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 );
               return;
            case '1':
               send_to_char( "Enter room name:-\r\n| ", d->character );
               OLC_MODE( d ) = REDIT_NAME;
               break;
            case '2':
               OLC_MODE( d ) = REDIT_DESC;
               d->character->substate = SUB_ROOM_DESC;
               d->character->last_cmd = do_redit_reset;
               send_to_char( "Enter room description:-\r\n", d->character );
               if( !room->description )
                  room->description = STRALLOC( "" );
               start_editing( d->character, room->description );
               break;
            case '3':
               redit_disp_flag_menu( d );
               break;
            case '4':
               redit_disp_sector_menu( d );
               break;
            case '5':
               send_to_char( "How many people can fit in the room? ", d->character );
               OLC_MODE( d ) = REDIT_TUNNEL;
               break;
            case '6':
               send_to_char( "How long before people are teleported out? ", d->character );
               OLC_MODE( d ) = REDIT_TELEDELAY;
               break;
            case '7':
               send_to_char( "Where are they teleported to? ", d->character );
               OLC_MODE( d ) = REDIT_TELEVNUM;
               break;
            case 'a':
            case 'A':
               redit_disp_exit_menu( d );
               break;
            case 'b':
            case 'B':
               redit_disp_extradesc_menu( d );
               break;
            default:
               send_to_char( "\n\r\n\rInvalid Command Selection!\n\r", d->character );
               redit_disp_menu( d );
               break;
         }
         return;
      case REDIT_NAME:
         STRFREE( room->name );
         room->name = STRALLOC( arg );
         olc_log( d, "Changed name to %s", room->name );
         break;
      case REDIT_DESC:
         /*
          * we will NEVER get here 
          */
         bug( "Reached REDIT_DESC case in redit_parse", 0 );
         break;
      case REDIT_FLAGS:
         if( is_number( arg ) )
         {
            number = atoi( arg );
            if( number == 0 )
               break;
            else if( number < 0 || number > ROOM_MAX )
            {
               send_to_char( "Invalid flag, try again:\n\r ", d->character );
               return;
            }
            else
            {
               number -= 1;   /* Offset for 0 */
               xTOGGLE_BIT( room->room_flags, number );
               olc_log( d, "%s the room flag %s",
                        xIS_SET( room->room_flags, number ) ? "Added" : "Removed", r_flags[number] );
            }
         }
         else
         {
            while( arg[0] != STRING_NULL )
            {
               arg = one_argument( arg, arg1 );
               number = get_rflag( arg1 );
               if( number > 0 )
               {
                  xTOGGLE_BIT( room->room_flags, number );
                  olc_log( d, "%s the room flag %s",
                           xIS_SET( room->room_flags, number ) ? "Added" : "Removed", r_flags[number] );
               }
            }
         }
         redit_disp_flag_menu( d );
         return;
      case REDIT_SECTOR:
         number = atoi( arg );
         if( number < 0 || number >= SECT_MAX )
         {
            send_to_char( "\n\r\n\rInvalid Command Selection!\n\r", d->character );
            redit_disp_sector_menu( d );
            return;
         }
         else
            room->sector_type = number;
         olc_log( d, "Changed sector to %s", asector_names[number] );
         break;
      case REDIT_TUNNEL:
         number = atoi( arg );
         room->tunnel = URANGE( 0, number, 1000 );
         olc_log( d, "Changed tunnel amount to %d", room->tunnel );
         break;
      case REDIT_TELEDELAY:
         number = atoi( arg );
         room->tele_delay = number;
         olc_log( d, "Changed teleportation delay to %d", room->tele_delay );
         break;
      case REDIT_TELEVNUM:
         number = atoi( arg );
         room->tele_vnum = URANGE( 1, number, MAX_VNUM );
         olc_log( d, "Changed teleportation vnum to %d", room->tele_vnum );
         break;
      case REDIT_EXIT_MENU:
         switch ( UPPER( arg[0] ) )
         {
            default:
               if( is_number( arg ) )
               {
                  number = atoi( arg );
                  pexit = get_exit_num( room, number );
                  if( pexit )
                  {
                     d->character->spare_ptr = pexit;
                     redit_disp_exit_edit( d );
                     return;
                  }
               }
               redit_disp_exit_menu( d );
               return;
            case '0':
               d->character->spare_ptr = NULL;
               break;
            case 'A':
               OLC_MODE( d ) = REDIT_EXIT_ADD;
               redit_disp_exit_dirs( d );
               return;
            case 'R':
               OLC_MODE( d ) = REDIT_EXIT_DELETE;
               send_to_char( "Delete which exit? ", d->character );
               return;
            case 'Q':
               d->character->spare_ptr = NULL;
               break;
         }
         break;
      case REDIT_EXIT_EDIT:
         switch ( UPPER( arg[0] ) )
         {
            case 'Q':
               d->character->spare_ptr = NULL;
               redit_disp_exit_menu( d );
               return;
            case '1':
               /*
                * OLC_MODE(d) = REDIT_EXIT_DIR;
                * redit_disp_exit_dirs(d); 
                */
               send_to_char( "This option can only be changed by remaking the exit.\n\r", d->character );
               break;
            case '2':
               OLC_MODE( d ) = REDIT_EXIT_VNUM;
               send_to_char( "Which room does this exit go to? ", d->character );
               return;
            case '3':
               OLC_MODE( d ) = REDIT_EXIT_KEY;
               send_to_char( "What is the vnum of the key to this exit? ", d->character );
               return;
            case '4':
               OLC_MODE( d ) = REDIT_EXIT_KEYWORD;
               send_to_char( "What is the keyword to this exit? ", d->character );
               return;
            case '5':
               OLC_MODE( d ) = REDIT_EXIT_FLAGS;
               redit_disp_exit_flag_menu( d );
               return;
            case '6':
               OLC_MODE( d ) = REDIT_EXIT_DESC;
               send_to_char( "Description:\n\r] ", d->character );
               return;
         }
         redit_disp_exit_edit( d );
         return;
      case REDIT_EXIT_DESC:
         if( !arg || arg[0] == STRING_NULL )
            pexit->description = STRALLOC( "" );
         else
         {
            sprintf( buf, "%s\n\r", arg );
            pexit->description = STRALLOC( buf );
         }
         olc_log( d, "Changed %s description to %s", dir_name[pexit->vdir], arg ? arg : "none" );
         redit_disp_exit_edit( d );
         return;
      case REDIT_EXIT_ADD:
         if( is_number( arg ) )
         {
            number = atoi( arg );
            if( number < DIR_NORTH || number > DIR_SOMEWHERE )
            {
               send_to_char( "Invalid direction, try again: ", d->character );
               return;
            }
            d->character->tempnum = number;
         }
         else
         {
            number = get_dir( arg );
            pexit = get_exit( room, number );
            if( pexit )
            {
               send_to_char( "An exit in that direction already exists.\n\r", d->character );
               redit_disp_exit_menu( d );
               return;
            }
            d->character->tempnum = number;
         }
         OLC_MODE( d ) = REDIT_EXIT_ADD_VNUM;
         send_to_char( "Which room does this exit go to? ", d->character );
         return;
      case REDIT_EXIT_ADD_VNUM:
         number = atoi( arg );
         if( ( tmp = get_room_index( number ) ) == NULL )
         {
            send_to_char( "Non-existant room.\n\r", d->character );
            OLC_MODE( d ) = REDIT_EXIT_MENU;
            redit_disp_exit_menu( d );
            return;
         }
         pexit = make_exit( room, tmp, d->character->tempnum );
         pexit->keyword = STRALLOC( "" );
         pexit->description = STRALLOC( "" );
         pexit->key = -1;
         pexit->exit_info = 0;
         act( AT_IMMORT, "$n reveals a hidden passage!", d->character, NULL, NULL, TO_ROOM );
         d->character->spare_ptr = pexit;
         olc_log( d, "Added %s exit to %d", dir_name[pexit->vdir], pexit->vnum );
         OLC_MODE( d ) = REDIT_EXIT_EDIT;
         redit_disp_exit_edit( d );
         return;
      case REDIT_EXIT_DELETE:
         if( !is_number( arg ) )
         {
            send_to_char( "Exit must be specified in a number.\n\r", d->character );
            redit_disp_exit_menu( d );
         }
         number = atoi( arg );
         pexit = get_exit_num( room, number );
         if( !pexit )
         {
            send_to_char( "That exit does not exist.\n\r", d->character );
            redit_disp_exit_menu( d );
         }
         olc_log( d, "Removed %s exit", dir_name[pexit->vdir] );
         extract_exit( room, pexit );
         redit_disp_exit_menu( d );
         return;
      case REDIT_EXIT_VNUM:
         number = atoi( arg );
         if( number < 0 || number > MAX_VNUM )
         {
            send_to_char( "Invalid room number, try again : ", d->character );
            return;
         }
         if( get_room_index( number ) == NULL )
         {
            send_to_char( "That room does not exist, try again: ", d->character );
            return;
         }
         pexit->vnum = number;
         olc_log( d, "%s exit vnum changed to %d", dir_name[pexit->vdir], pexit->vnum );
         redit_disp_exit_menu( d );
         return;
      case REDIT_EXIT_KEYWORD:
         STRFREE( pexit->keyword );
         pexit->keyword = STRALLOC( arg );
         olc_log( d, "Changed %s keyword to %s", dir_name[pexit->vdir], pexit->keyword );
         redit_disp_exit_edit( d );
         return;
      case REDIT_EXIT_KEY:
         number = atoi( arg );
         if( number < 0 || number > MAX_VNUM )
            send_to_char( "Invalid vnum, try again: ", d->character );
         else
         {
            pexit->key = number;
            redit_disp_exit_edit( d );
         }
         olc_log( d, "%s key vnum is now %d", dir_name[pexit->vdir], pexit->key );
         return;
      case REDIT_EXIT_FLAGS:
         number = atoi( arg );
         if( number == 0 )
         {
            redit_disp_exit_edit( d );
            return;
         }
         if( ( number < 0 ) || ( number > MAX_EXFLAG + 1 )
             || ( 1 << ( number - 1 ) == EX_RES1 )
             || ( 1 << ( number - 1 ) == EX_RES2 ) || ( 1 << ( number - 1 ) == EX_PORTAL ) )
         {
            send_to_char( "That's not a valid choice!\r\n", d->character );
            redit_disp_exit_flag_menu( d );
         }
         number -= 1;
         TOGGLE_BIT( pexit->exit_info, 1 << number );
         olc_log( d, "%s %s to %s exit",
                  IS_SET( pexit->exit_info, 1 << number ) ? "Added" : "Removed", ex_flags[number], dir_name[pexit->vdir] );
         redit_disp_exit_flag_menu( d );
         return;
      case REDIT_EXTRADESC_DELETE:
         ed = redit_find_extradesc( room, atoi( arg ) );
         if( !ed )
         {
            send_to_char( "Not found, try again: ", d->character );
            return;
         }
         olc_log( d, "Deleted exdesc %s", ed->keyword );
         UNLINK( ed, room->first_extradesc, room->last_extradesc, next, prev );
         STRFREE( ed->keyword );
         STRFREE( ed->description );
         DISPOSE( ed );
         top_ed--;
         redit_disp_extradesc_menu( d );
         return;
      case REDIT_EXTRADESC_CHOICE:
         switch ( UPPER( arg[0] ) )
         {
            case 'Q':
               if( !ed->keyword || !ed->description )
               {
                  send_to_char( "No keyword and/or description, junking...", d->character );
                  UNLINK( ed, room->first_extradesc, room->last_extradesc, next, prev );
                  STRFREE( ed->keyword );
                  STRFREE( ed->keyword );
                  DISPOSE( ed );
                  top_ed--;
               }
               d->character->spare_ptr = NULL;
               redit_disp_extradesc_menu( d );
               return;
            case '1':
               OLC_MODE( d ) = REDIT_EXTRADESC_KEY;
               send_to_char( "Keywords, seperated by spaces: ", d->character );
               return;
            case '2':
               OLC_MODE( d ) = REDIT_EXTRADESC_DESCRIPTION;
               d->character->substate = SUB_ROOM_EXTRA;
               d->character->last_cmd = do_redit_reset;
               send_to_char( "Enter new extradesc description: \n\r", d->character );
               start_editing( d->character, ed->description );
               return;
         }
         break;
      case REDIT_EXTRADESC_KEY:
         /*
          * if ( SetRExtra( room, arg ) )
          * {
          * send_to_char( "A extradesc with that keyword already exists.\n\r", d->character );
          * redit_disp_extradesc_menu(d);
          * return;
          * } 
          */
         olc_log( d, "Changed exkey %s to %s", ed->keyword, arg );
         STRFREE( ed->keyword );
         ed->keyword = STRALLOC( arg );
         oedit_disp_extra_choice( d );
         OLC_MODE( d ) = REDIT_EXTRADESC_CHOICE;
         return;
      case REDIT_EXTRADESC_MENU:
         switch ( UPPER( arg[0] ) )
         {
            case 'Q':
               break;
            case 'A':
               CREATE( ed, EXTRA_DESCR_DATA, 1 );
               LINK( ed, room->first_extradesc, room->last_extradesc, next, prev );
               ed->keyword = STRALLOC( "" );
               ed->description = STRALLOC( "" );
               top_ed++;
               d->character->spare_ptr = ed;
               olc_log( d, "Added new exdesc" );
               oedit_disp_extra_choice( d );
               OLC_MODE( d ) = REDIT_EXTRADESC_CHOICE;
               return;
            case 'R':
               OLC_MODE( d ) = REDIT_EXTRADESC_DELETE;
               send_to_char( "Delete which extra description? ", d->character );
               return;
            default:
               if( is_number( arg ) )
               {
                  ed = redit_find_extradesc( room, atoi( arg ) );
                  if( !ed )
                  {
                     send_to_char( "Not found, try again: ", d->character );
                     return;
                  }
                  d->character->spare_ptr = ed;
                  oedit_disp_extra_choice( d );
                  OLC_MODE( d ) = REDIT_EXTRADESC_CHOICE;
               }
               else
                  redit_disp_extradesc_menu( d );
               return;
         }
         break;
      default:
         /*
          * we should never get here 
          */
         bug( "Reached default case in parse_redit", 0 );
         break;
   }
   /*
    * Log the changes, so we can keep track of those sneaky bastards 
    */
   /*
    * Don't log on the flags cause it does that above 
    */
   /*
    * if ( OLC_MODE(d) != REDIT_FLAGS )
    * olc_log( d, arg ); 
    */
   /*
    * . If we get this far, something has be changed .
    */
   OLC_CHANGE( d ) = TRUE;
   redit_disp_menu( d );
}