eldhamud/boards/
eldhamud/clans/
eldhamud/classes/
eldhamud/councils/
eldhamud/deity/
eldhamud/doc/
eldhamud/doc/DIKU/
eldhamud/doc/MERC/
eldhamud/doc/mudprogs/
eldhamud/gods/
eldhamud/houses/
eldhamud/lockers/
eldhamud/player/a/
/****************************************************************************
 *   _______  _        ______            _______  _______           ______   *
 *  (  ____ \( \      (  __  \ |\     /|(  ___  )(       )|\     /|(  __  \  *
 *  | (    \/| (      | (  \  )| )   ( || (   ) || () () || )   ( || (  \  ) *
 *  | (__    | |      | |   ) || (___) || (___) || || || || |   | || |   ) | *
 *  |  __)   | |      | |   | ||  ___  ||  ___  || |(_)| || |   | || |   | | *
 *  | (      | |      | |   ) || (   ) || (   ) || |   | || |   | || |   ) | *
 *  | (____/\| (____/\| (__/  )| )   ( || )   ( || )   ( || (___) || (__/  ) *
 *  (_______/(_______/(______/ |/     \||/     \||/     \|(_______)(______/  *
 *              +-+-+-+  +-+-+-+-+-+-+-+  +-+-+-+-+-+-+-+-+-+-+              *
 *              |T|h|e|  |O|a|k|l|a|n|d|  |C|h|r|o|n|i|c|l|e|s|              *
 *              +-+-+-+  +-+-+-+-+-+-+-+  +-+-+-+-+-+-+-+-+-+-+              *
 * ------------------------------------------------------------------------- *
 * EldhaMUD code (C) 2003-2005 by Robert Powell (Tommi)                      *
 * EldhaMUD Team: Celest, Altere and Krelowyn                                *
 * ------------------------------------------------------------------------- *
 *                                                                           *
 ****************************************************************************/
/****************************************************************************
 * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame      |   \\._.//   *
 * -----------------------------------------------------------|   (0...0)   *
 * SMAUG 1.4 (C) 1994, 1995, 1996, 1998  by Derek Snider      |    ).:.(    *
 * -----------------------------------------------------------|    {o o}    *
 * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus,      |   / ' ' \   *
 * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek,      |~'~.VxvxV.~'~*
 * Tricops and Fireblade                                      |             *
 * ------------------------------------------------------------------------ *
 * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael        *
 * Chastain, Michael Quan, and Mitchell Tse.                                *
 * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,          *
 * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.     *
 * ------------------------------------------------------------------------ *
 *			 Online Reset Editing Module			    *
 ****************************************************************************/

/*
 * This file relies heavily on the fact that your linked lists are correct,
 * and that pArea->reset_first is the first reset in pArea.  Likewise,
 * pArea->reset_last *MUST* be the last reset in pArea.  Weird and
 * wonderful things will happen if any of your lists are messed up, none
 * of them good.  The most important are your pRoom->contents,
 * pRoom->people, rch->carrying, obj->contains, and pArea->reset_first ..
 * pArea->reset_last.  -- Altrag
 */

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "./Headers/mud.h"


/* Externals */
extern int top_reset;
char *sprint_reset args( ( CHAR_DATA * ch, RESET_DATA * pReset, short num, bool rlist ) );
RESET_DATA *parse_reset args( ( AREA_DATA * tarea, char *argument, CHAR_DATA * ch ) );
int get_wearloc args( ( char *type ) );
int get_trapflag args( ( char *flag ) );
int get_exflag args( ( char *flag ) );
int get_rflag args( ( char *flag ) );
extern char *const wear_locs[];
extern char *const ex_flags[];


void add_obj_reset args( ( AREA_DATA * pArea, char cm, OBJ_DATA * obj, int v2, int v3 ) );

void instaroom args( ( AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, bool dodoors ) );
#define RID ROOM_INDEX_DATA
RID *find_room args( ( CHAR_DATA * ch, char *argument, ROOM_INDEX_DATA * pRoom ) );
#undef RID
void edit_reset args( ( CHAR_DATA * ch, char *argument, AREA_DATA * pArea, ROOM_INDEX_DATA * aRoom ) );
#define RD RESET_DATA
RD *find_reset args( ( AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, int num ) );
#undef RD
void list_resets args( ( CHAR_DATA * ch, AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, int start, int end ) );



RESET_DATA *find_reset( AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, int numb )
{
   RESET_DATA *pReset;
   int num = 0;

   for( pReset = pArea->first_reset; pReset; pReset = pReset->next )
      if( is_room_reset( pReset, pRoom, pArea ) && ++num >= numb )
         return pReset;
   return NULL;
}

/* This is one loopy function.  Ugh. -- Altrag */
bool is_room_reset( RESET_DATA * pReset, ROOM_INDEX_DATA * aRoom, AREA_DATA * pArea )
{
   ROOM_INDEX_DATA *pRoom;
   RESET_DATA *reset;
   int pr;

   if( !aRoom )
      return TRUE;
   switch ( pReset->command )
   {
      case 'M':
      case 'O':
         pRoom = get_room_index( pReset->arg3 );
         if( !pRoom || pRoom != aRoom )
            return FALSE;
         return TRUE;
      case 'P':
      case 'T':
      case 'H':
         if( pReset->command == 'H' )
            pr = pReset->arg1;
         else
            pr = pReset->arg3;
         for( reset = pReset->prev; reset; reset = reset->prev )
            if( ( reset->command == 'O' || reset->command == 'P' ||
                  reset->command == 'G' || reset->command == 'E' ) &&
                ( !pr || pr == reset->arg1 ) && get_obj_index( reset->arg1 ) )
               break;
         if( reset && is_room_reset( reset, aRoom, pArea ) )
            return TRUE;
         return FALSE;
      case 'B':
         switch ( pReset->arg2 & BIT_RESET_TYPE_MASK )
         {
            case BIT_RESET_DOOR:
            case BIT_RESET_ROOM:
               return ( aRoom->vnum == pReset->arg1 );
            case BIT_RESET_MOBILE:
               for( reset = pReset->prev; reset; reset = reset->prev )
                  if( reset->command == 'M' && get_mob_index( reset->arg1 ) )
                     break;
               if( reset && is_room_reset( reset, aRoom, pArea ) )
                  return TRUE;
               return FALSE;
            case BIT_RESET_OBJECT:
               for( reset = pReset->prev; reset; reset = reset->prev )
                  if( ( reset->command == 'O' || reset->command == 'P' ||
                        reset->command == 'G' || reset->command == 'E' ) &&
                      ( !pReset->arg1 || pReset->arg1 == reset->arg1 ) && get_obj_index( reset->arg1 ) )
                     break;
               if( reset && is_room_reset( reset, aRoom, pArea ) )
                  return TRUE;
               return FALSE;
         }
         return FALSE;
      case 'G':
      case 'E':
         for( reset = pReset->prev; reset; reset = reset->prev )
            if( reset->command == 'M' && get_mob_index( reset->arg1 ) )
               break;
         if( reset && is_room_reset( reset, aRoom, pArea ) )
            return TRUE;
         return FALSE;
      case 'D':
      case 'R':
         pRoom = get_room_index( pReset->arg1 );
         if( !pRoom || pRoom->area != pArea || ( aRoom && pRoom != aRoom ) )
            return FALSE;
         return TRUE;
      default:
         return FALSE;
   }
   return FALSE;
}

ROOM_INDEX_DATA *find_room( CHAR_DATA * ch, char *argument, ROOM_INDEX_DATA * pRoom )
{
   char arg[MAX_INPUT_LENGTH];

   if( pRoom )
      return pRoom;
   one_argument( argument, arg );
   if( !is_number( arg ) && arg[0] != '\0' )
   {
      send_to_char( "Reset to which room?\n\r", ch );
      return NULL;
   }
   if( arg[0] == '\0' )
      pRoom = ch->in_room;
   else
      pRoom = get_room_index( atoi( arg ) );
   if( !pRoom )
   {
      send_to_char( "Room does not exist.\n\r", ch );
      return NULL;
   }
   return pRoom;
}

/* Separate function for recursive purposes */
#define DEL_RESET(area, reset, rprev) \
do { \
  rprev = reset->prev; \
  delete_reset(area, reset); \
  reset = rprev; \
  continue; \
} while(0)
void delete_reset( AREA_DATA * pArea, RESET_DATA * pReset )
{
   RESET_DATA *reset;
   RESET_DATA *reset_prev;

   if( pReset->command == 'M' )
   {
      for( reset = pReset->next; reset; reset = reset->next )
      {
         /*
          * Break when a new mob found 
          */
         if( reset->command == 'M' )
            break;
         /*
          * Delete anything mob is holding 
          */
         if( reset->command == 'G' || reset->command == 'E' )
            DEL_RESET( pArea, reset, reset_prev );
         if( reset->command == 'B' &&
             ( reset->arg2 & BIT_RESET_TYPE_MASK ) == BIT_RESET_MOBILE && ( !reset->arg1 || reset->arg1 == pReset->arg1 ) )
            DEL_RESET( pArea, reset, reset_prev );
      }
   }
   else if( pReset->command == 'O' || pReset->command == 'P' || pReset->command == 'G' || pReset->command == 'E' )
   {
      for( reset = pReset->next; reset; reset = reset->next )
      {
         if( reset->command == 'T' && ( !reset->arg3 || reset->arg3 == pReset->arg1 ) )
            DEL_RESET( pArea, reset, reset_prev );
         if( reset->command == 'H' && ( !reset->arg1 || reset->arg1 == pReset->arg1 ) )
            DEL_RESET( pArea, reset, reset_prev );
         /*
          * Delete nested objects, even if they are the same object. 
          */
         if( reset->command == 'P' && ( reset->arg3 > 0 ||
                                        pReset->command != 'P' || reset->extra - 1 == pReset->extra ) &&
             ( !reset->arg3 || reset->arg3 == pReset->arg1 ) )
            DEL_RESET( pArea, reset, reset_prev );
         if( reset->command == 'B' &&
             ( reset->arg2 & BIT_RESET_TYPE_MASK ) == BIT_RESET_OBJECT && ( !reset->arg1 || reset->arg1 == pReset->arg1 ) )
            DEL_RESET( pArea, reset, reset_prev );

         /*
          * Break when a new object of same type is found 
          */
         if( ( reset->command == 'O' || reset->command == 'P' ||
               reset->command == 'G' || reset->command == 'E' ) && reset->arg1 == pReset->arg1 )
            break;
      }
   }
   if( pReset == pArea->last_mob_reset )
      pArea->last_mob_reset = NULL;
   if( pReset == pArea->last_obj_reset )
      pArea->last_obj_reset = NULL;
   UNLINK( pReset, pArea->first_reset, pArea->last_reset, next, prev );
   DISPOSE( pReset );
   return;
}

#undef DEL_RESET

RESET_DATA *find_oreset( CHAR_DATA * ch, AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, char *name )
{
   RESET_DATA *reset;

   if( !*name )
   {
      for( reset = pArea->last_reset; reset; reset = reset->prev )
      {
         if( !is_room_reset( reset, pRoom, pArea ) )
            continue;
         switch ( reset->command )
         {
            default:
               continue;
            case 'O':
            case 'E':
            case 'G':
            case 'P':
               break;
         }
         break;
      }
      if( !reset )
         send_to_char( "No object resets in list.\n\r", ch );
      return reset;
   }
   else
   {
      char arg[MAX_INPUT_LENGTH];
      int cnt = 0, num = number_argument( name, arg );
      OBJ_INDEX_DATA *pObjTo = NULL;

      for( reset = pArea->first_reset; reset; reset = reset->next )
      {
         if( !is_room_reset( reset, pRoom, pArea ) )
            continue;
         switch ( reset->command )
         {
            default:
               continue;
            case 'O':
            case 'E':
            case 'G':
            case 'P':
               break;
         }
         if( ( pObjTo = get_obj_index( reset->arg1 ) ) && is_name( arg, pObjTo->name ) && ++cnt == num )
            break;
      }
      if( !pObjTo || !reset )
      {
         send_to_char( "To object not in reset list.\n\r", ch );
         return NULL;
      }
   }
   return reset;
}

RESET_DATA *find_mreset( CHAR_DATA * ch, AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, char *name )
{
   RESET_DATA *reset;

   if( !*name )
   {
      for( reset = pArea->last_reset; reset; reset = reset->prev )
      {
         if( !is_room_reset( reset, pRoom, pArea ) )
            continue;
         switch ( reset->command )
         {
            default:
               continue;
            case 'M':
               break;
         }
         break;
      }
      if( !reset )
         send_to_char( "No mobile resets in list.\n\r", ch );
      return reset;
   }
   else
   {
      char arg[MAX_INPUT_LENGTH];
      int cnt = 0, num = number_argument( name, arg );
      MOB_INDEX_DATA *pMob = NULL;

      for( reset = pArea->first_reset; reset; reset = reset->next )
      {
         if( !is_room_reset( reset, pRoom, pArea ) )
            continue;
         switch ( reset->command )
         {
            default:
               continue;
            case 'M':
               break;
         }
         if( ( pMob = get_mob_index( reset->arg1 ) ) && is_name( arg, pMob->player_name ) && ++cnt == num )
            break;
      }
      if( !pMob || !reset )
      {
         send_to_char( "Mobile not in reset list.\n\r", ch );
         return NULL;
      }
   }
   return reset;
}

void edit_reset( CHAR_DATA * ch, char *argument, AREA_DATA * pArea, ROOM_INDEX_DATA * aRoom )
{
   char arg[MAX_INPUT_LENGTH];
   RESET_DATA *pReset = NULL;
   RESET_DATA *reset = NULL;
   MOB_INDEX_DATA *pMob = NULL;
   ROOM_INDEX_DATA *pRoom;
   OBJ_INDEX_DATA *pObj;
   int num = 0;
   int vnum;
   char *origarg = argument;

   argument = one_argument( argument, arg );
   if( !*arg || !str_cmp( arg, "?" ) )
   {
      char *nm = ( ch->substate == SUB_REPEATCMD ? "" : ( aRoom ? "rreset " : "reset " ) );
      char *rn = ( aRoom ? "" : " [room#]" );
      ch_printf( ch, "Syntax: %s<list|edit|delete|add|insert|place%s>\n\r", nm, ( aRoom ? "" : "|area" ) );
      ch_printf( ch, "Syntax: %sremove <#>\n\r", nm );
      ch_printf( ch, "Syntax: %smobile <mob#> [limit]%s\n\r", nm, rn );
      ch_printf( ch, "Syntax: %sobject <obj#> [limit [room%s]]\n\r", nm, rn );
      ch_printf( ch, "Syntax: %sobject <obj#> give <mob name> [limit]\n\r", nm );
      ch_printf( ch, "Syntax: %sobject <obj#> equip <mob name> <location> " "[limit]\n\r", nm );
      ch_printf( ch, "Syntax: %sobject <obj#> put <to_obj name> [limit]\n\r", nm );
      ch_printf( ch, "Syntax: %shide <obj name>\n\r", nm );
      ch_printf( ch, "Syntax: %strap <obj name> <type> <charges> <flags>\n\r", nm );
      ch_printf( ch, "Syntax: %strap room <type> <charges> <flags>\n\r", nm );
      ch_printf( ch, "Syntax: %sbit <set|toggle|remove> door%s <dir> " "<exit flags>\n\r", nm, rn );
      ch_printf( ch, "Syntax: %sbit <set|toggle|remove> object <obj name> " "<extra flags>\n\r", nm );
      ch_printf( ch, "Syntax: %sbit <set|toggle|remove> mobile <mob name> " "<affect flags>\n\r", nm );
      ch_printf( ch, "Syntax: %sbit <set|toggle|remove> room%s <room flags>" "\n\r", nm, rn );
      ch_printf( ch, "Syntax: %srandom <last dir>%s\n\r", nm, rn );
      if( !aRoom )
      {
         send_to_char( "\n\r[room#] will default to the room you are in, " "if unspecified.\n\r", ch );
      }
      return;
   }
   if( !str_cmp( arg, "on" ) )
   {
      ch->substate = SUB_REPEATCMD;
      ch->dest_buf = ( aRoom ? ( void * )aRoom : ( void * )pArea );
      send_to_char( "Reset mode on.\n\r", ch );
      return;
   }
   if( !aRoom && !str_cmp( arg, "area" ) )
   {
      if( !pArea->first_reset )
      {
         send_to_char( "You don't have any resets defined.\n\r", ch );
         return;
      }
      num = pArea->nplayer;
      pArea->nplayer = 0;
      reset_area( pArea );
      pArea->nplayer = num;
      send_to_char( "Done.\n\r", ch );
      return;
   }

   if( !str_cmp( arg, "list" ) )
   {
      int start, end;

      argument = one_argument( argument, arg );
      start = is_number( arg ) ? atoi( arg ) : -1;
      argument = one_argument( argument, arg );
      end = is_number( arg ) ? atoi( arg ) : -1;
      list_resets( ch, pArea, aRoom, start, end );
      return;
   }

   if( !str_cmp( arg, "edit" ) )
   {
      argument = one_argument( argument, arg );
      if( !*arg || !is_number( arg ) )
      {
         send_to_char( "Usage: reset edit <number> <command>\n\r", ch );
         return;
      }
      num = atoi( arg );
      if( !( pReset = find_reset( pArea, aRoom, num ) ) )
      {
         send_to_char( "Reset not found.\n\r", ch );
         return;
      }
      if( !( reset = parse_reset( pArea, argument, ch ) ) )
      {
         send_to_char( "Error in reset.  Reset not changed.\n\r", ch );
         return;
      }
      reset->prev = pReset->prev;
      reset->next = pReset->next;
      if( !pReset->prev )
         pArea->first_reset = reset;
      else
         pReset->prev->next = reset;
      if( !pReset->next )
         pArea->last_reset = reset;
      else
         pReset->next->prev = reset;
      DISPOSE( pReset );
      send_to_char( "Done.\n\r", ch );
      return;
   }
   if( !str_cmp( arg, "add" ) )
   {
      if( ( pReset = parse_reset( pArea, argument, ch ) ) == NULL )
      {
         send_to_char( "Error in reset.  Reset not added.\n\r", ch );
         return;
      }
      add_reset( pArea, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3 );
      DISPOSE( pReset );
      send_to_char( "Done.\n\r", ch );
      return;
   }
   if( !str_cmp( arg, "place" ) )
   {
      if( ( pReset = parse_reset( pArea, argument, ch ) ) == NULL )
      {
         send_to_char( "Error in reset.  Reset not added.\n\r", ch );
         return;
      }
      place_reset( pArea, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3 );
      DISPOSE( pReset );
      send_to_char( "Done.\n\r", ch );
      return;
   }
   if( !str_cmp( arg, "insert" ) )
   {
      argument = one_argument( argument, arg );
      if( !*arg || !is_number( arg ) )
      {
         send_to_char( "Usage: reset insert <number> <command>\n\r", ch );
         return;
      }
      num = atoi( arg );
      if( ( reset = find_reset( pArea, aRoom, num ) ) == NULL )
      {
         send_to_char( "Reset not found.\n\r", ch );
         return;
      }
      if( ( pReset = parse_reset( pArea, argument, ch ) ) == NULL )
      {
         send_to_char( "Error in reset.  Reset not inserted.\n\r", ch );
         return;
      }
      INSERT( pReset, reset, pArea->first_reset, next, prev );
      send_to_char( "Done.\n\r", ch );
      return;
   }
   if( !str_cmp( arg, "delete" ) )
   {
      int start, end;
      bool found;

      if( !*argument )
      {
         send_to_char( "Usage: reset delete <start> [end]\n\r", ch );
         return;
      }
      argument = one_argument( argument, arg );
      start = is_number( arg ) ? atoi( arg ) : -1;
      end = is_number( arg ) ? atoi( arg ) : -1;
      num = 0;
      found = FALSE;
      for( pReset = pArea->first_reset; pReset; pReset = reset )
      {
         reset = pReset->next;
         if( !is_room_reset( pReset, aRoom, pArea ) )
            continue;
         if( start > ++num )
            continue;
         if( ( end != -1 && num > end ) || ( end == -1 && found ) )
            return;
         UNLINK( pReset, pArea->first_reset, pArea->last_reset, next, prev );
         if( pReset == pArea->last_mob_reset )
            pArea->last_mob_reset = NULL;
         DISPOSE( pReset );
         top_reset--;
         found = TRUE;
      }
      if( !found )
         send_to_char( "Reset not found.\n\r", ch );
      else
         send_to_char( "Done.\n\r", ch );
      return;
   }

   if( !str_cmp( arg, "remove" ) )
   {
      int iarg;

      argument = one_argument( argument, arg );
      if( arg[0] == '\0' || !is_number( arg ) )
      {
         send_to_char( "Delete which reset?\n\r", ch );
         return;
      }
      iarg = atoi( arg );
      for( pReset = pArea->first_reset; pReset; pReset = pReset->next )
      {
         if( is_room_reset( pReset, aRoom, pArea ) && ++num == iarg )
            break;
      }
      if( !pReset )
      {
         send_to_char( "Reset does not exist.\n\r", ch );
         return;
      }
      delete_reset( pArea, pReset );
      send_to_char( "Reset deleted.\n\r", ch );
      return;
   }
   if( !str_prefix( arg, "mobile" ) )
   {
      argument = one_argument( argument, arg );
      if( arg[0] == '\0' || !is_number( arg ) )
      {
         send_to_char( "Reset which mobile vnum?\n\r", ch );
         return;
      }
      if( !( pMob = get_mob_index( atoi( arg ) ) ) )
      {
         send_to_char( "Mobile does not exist.\n\r", ch );
         return;
      }
      argument = one_argument( argument, arg );
      if( arg[0] == '\0' )
         num = 1;
      else if( !is_number( arg ) )
      {
         send_to_char( "Reset how many mobiles?\n\r", ch );
         return;
      }
      else
         num = atoi( arg );
      if( !( pRoom = find_room( ch, argument, aRoom ) ) )
         return;
      pReset = make_reset( 'M', 0, pMob->vnum, num, pRoom->vnum );
      LINK( pReset, pArea->first_reset, pArea->last_reset, next, prev );
      send_to_char( "Mobile reset added.\n\r", ch );
      return;
   }
   if( !str_prefix( arg, "object" ) )
   {
      argument = one_argument( argument, arg );
      if( arg[0] == '\0' || !is_number( arg ) )
      {
         send_to_char( "Reset which object vnum?\n\r", ch );
         return;
      }
      if( !( pObj = get_obj_index( atoi( arg ) ) ) )
      {
         send_to_char( "Object does not exist.\n\r", ch );
         return;
      }
      argument = one_argument( argument, arg );
      if( arg[0] == '\0' )
         strcpy( arg, "room" );
      if( !str_prefix( arg, "put" ) )
      {
         argument = one_argument( argument, arg );
         if( !( reset = find_oreset( ch, pArea, aRoom, arg ) ) )
            return;
         pReset = reset;
         /*
          * Put in_objects after hide and trap resets 
          */
         while( reset->next && ( reset->next->command == 'H' ||
                                 reset->next->command == 'T' ||
                                 ( reset->next->command == 'B' &&
                                   ( reset->next->arg2 & BIT_RESET_TYPE_MASK ) == BIT_RESET_OBJECT &&
                                   ( !reset->next->arg1 || reset->next->arg1 == pReset->arg1 ) ) ) )
            reset = reset->next;
         argument = one_argument( argument, arg );
         if( ( num = atoi( arg ) ) < 1 )
            num = 1;
         argument = one_argument( argument, arg );
         if( ( vnum = atoi( arg ) ) < 1 )
            vnum = 1;
         pReset = make_reset( 'P', reset->extra + 1, pObj->vnum, num, vnum );
         /*
          * Grumble.. insert puts pReset before reset, and we need it after,
          * so we make a hackup and reverse all the list params.. :P.. 
          */
         INSERT( pReset, reset, pArea->last_reset, prev, next );
         send_to_char( "Object reset in object created.\n\r", ch );
         return;
      }
      if( !str_prefix( arg, "give" ) )
      {
         argument = one_argument( argument, arg );
         if( !( reset = find_mreset( ch, pArea, aRoom, arg ) ) )
            return;
         pReset = reset;
         while( reset->next && reset->next->command == 'B' &&
                ( reset->next->arg2 & BIT_RESET_TYPE_MASK ) == BIT_RESET_OBJECT &&
                ( !reset->next->arg1 || reset->next->arg1 == pReset->arg1 ) )
            reset = reset->next;
         argument = one_argument( argument, arg );
         if( ( vnum = atoi( arg ) ) < 1 )
            vnum = 1;
         pReset = make_reset( 'G', 1, pObj->vnum, vnum, 0 );
         INSERT( pReset, reset, pArea->last_reset, prev, next );
         send_to_char( "Object reset to mobile created.\n\r", ch );
         return;
      }
      if( !str_prefix( arg, "equip" ) )
      {
         argument = one_argument( argument, arg );
         if( !( reset = find_mreset( ch, pArea, aRoom, arg ) ) )
            return;
         pReset = reset;
         while( reset->next && reset->next->command == 'B' &&
                ( reset->next->arg2 & BIT_RESET_TYPE_MASK ) == BIT_RESET_OBJECT &&
                ( !reset->next->arg1 || reset->next->arg1 == pReset->arg1 ) )
            reset = reset->next;
         num = get_wearloc( argument );
         if( num < 0 )
         {
            send_to_char( "Reset object to which location?\n\r", ch );
            return;
         }
         for( pReset = reset->next; pReset; pReset = pReset->next )
         {
            if( pReset->command == 'M' )
               break;
            if( pReset->command == 'E' && pReset->arg3 == num )
            {
               send_to_char( "Mobile already has an item equipped there.\n\r", ch );
               return;
            }
         }
         argument = one_argument( argument, arg );
         if( ( vnum = atoi( arg ) ) < 1 )
            vnum = 1;
         pReset = make_reset( 'E', 1, pObj->vnum, vnum, num );
         INSERT( pReset, reset, pArea->last_reset, prev, next );
         send_to_char( "Object reset equipped by mobile created.\n\r", ch );
         return;
      }
      if( arg[0] == '\0' || !( num = ( int )str_cmp( arg, "room" ) ) || is_number( arg ) )
      {
         if( !( bool ) num )
            argument = one_argument( argument, arg );
         if( !( pRoom = find_room( ch, argument, aRoom ) ) )
            return;
         if( pRoom->area != pArea )
         {
            send_to_char( "Cannot reset objects to other areas.\n\r", ch );
            return;
         }
         if( ( vnum = atoi( arg ) ) < 1 )
            vnum = 1;
         pReset = make_reset( 'O', 0, pObj->vnum, vnum, pRoom->vnum );
         LINK( pReset, pArea->first_reset, pArea->last_reset, next, prev );
         send_to_char( "Object reset added.\n\r", ch );
         return;
      }
      send_to_char( "Reset object to where?\n\r", ch );
      return;
   }
   if( !str_cmp( arg, "random" ) )
   {
      argument = one_argument( argument, arg );
      vnum = get_dir( arg );
      if( vnum < 0 || vnum > 9 )
      {
         send_to_char( "Reset which random doors?\n\r", ch );
         return;
      }
      if( vnum == 0 )
      {
         send_to_char( "There is no point in randomizing one door.\n\r", ch );
         return;
      }
      pRoom = find_room( ch, argument, aRoom );
      if( pRoom->area != pArea )
      {
         send_to_char( "Cannot randomize doors in other areas.\n\r", ch );
         return;
      }
      pReset = make_reset( 'R', 0, pRoom->vnum, vnum, 0 );
      LINK( pReset, pArea->first_reset, pArea->last_reset, next, prev );
      send_to_char( "Reset random doors created.\n\r", ch );
      return;
   }
   if( !str_cmp( arg, "trap" ) )
   {
      char oname[MAX_INPUT_LENGTH];
      int chrg, value, extra = 0;
      bool isobj;

      argument = one_argument( argument, oname );
      argument = one_argument( argument, arg );
      num = is_number( arg ) ? atoi( arg ) : -1;
      argument = one_argument( argument, arg );
      chrg = is_number( arg ) ? atoi( arg ) : -1;
      isobj = is_name( argument, "obj" );
      if( isobj == is_name( argument, "room" ) )
      {
         send_to_char( "Reset: TRAP: Must specify ROOM or OBJECT\n\r", ch );
         return;
      }
      if( !str_cmp( oname, "room" ) && !isobj )
      {
         vnum = ( aRoom ? aRoom->vnum : ch->in_room->vnum );
         extra = TRAP_ROOM;
      }
      else
      {
         if( is_number( oname ) && !isobj )
         {
            vnum = atoi( oname );
            if( !get_room_index( vnum ) )
            {
               send_to_char( "Reset: TRAP: no such room\n\r", ch );
               return;
            }
            reset = NULL;
            extra = TRAP_ROOM;
         }
         else
         {
            if( !( reset = find_oreset( ch, pArea, aRoom, oname ) ) )
               return;
/*        vnum = reset->arg1;*/
            vnum = 0;
            extra = TRAP_OBJ;
         }
      }
      if( num < 1 || num > MAX_TRAPTYPE )
      {
         send_to_char( "Reset: TRAP: invalid trap type\n\r", ch );
         return;
      }
      if( chrg < 0 || chrg > 10000 )
      {
         send_to_char( "Reset: TRAP: invalid trap charges\n\r", ch );
         return;
      }
      while( *argument )
      {
         argument = one_argument( argument, arg );
         value = get_trapflag( arg );
         if( value < 0 || value > 31 )
         {
            send_to_char( "Reset: TRAP: bad flag\n\r", ch );
            return;
         }
         SET_BIT( extra, 1 << value );
      }
      pReset = make_reset( 'T', extra, num, chrg, vnum );
      if( reset )
         INSERT( pReset, reset, pArea->last_reset, prev, next );
      else
         LINK( pReset, pArea->first_reset, pArea->last_reset, next, prev );
      send_to_char( "Trap created.\n\r", ch );
      return;
   }
   if( !str_cmp( arg, "bit" ) )
   {
      int ( *flfunc ) ( char *type );
      int flags = 0;
      char option[MAX_INPUT_LENGTH];
      char *parg;
      bool ext_bv = FALSE;

      argument = one_argument( argument, option );
      if( !*option )
      {
         send_to_char( "You must specify SET, REMOVE, or TOGGLE.\n\r", ch );
         return;
      }
      num = 0;
      if( !str_prefix( option, "set" ) )
         SET_BIT( num, BIT_RESET_SET );
      else if( !str_prefix( option, "toggle" ) )
         SET_BIT( num, BIT_RESET_TOGGLE );
      else if( str_prefix( option, "remove" ) )
      {
         send_to_char( "You must specify SET, REMOVE, or TOGGLE.\n\r", ch );
         return;
      }
      argument = one_argument( argument, option );
      parg = argument;
      argument = one_argument( argument, arg );
      if( !*option )
      {
         send_to_char( "Must specify OBJECT, MOBILE, ROOM, or DOOR.\n\r", ch );
         return;
      }
      if( !str_prefix( option, "door" ) )
      {
         SET_BIT( num, BIT_RESET_DOOR );
         if( aRoom )
         {
            pRoom = aRoom;
            argument = parg;
         }
         else if( !is_number( arg ) )
         {
            pRoom = ch->in_room;
            argument = parg;
         }
         else if( !( pRoom = find_room( ch, arg, aRoom ) ) )
            return;
         argument = one_argument( argument, arg );
         if( !*arg )
         {
            send_to_char( "Must specify direction.\n\r", ch );
            return;
         }
         vnum = get_dir( arg );
         SET_BIT( num, vnum << BIT_RESET_DOOR_THRESHOLD );
         vnum = pRoom->vnum;
         flfunc = &get_exflag;
         reset = NULL;
      }
      else if( !str_prefix( option, "object" ) )
      {
         SET_BIT( num, BIT_RESET_OBJECT );
         vnum = 0;
         flfunc = &get_oflag;
         if( !( reset = find_oreset( ch, pArea, aRoom, arg ) ) )
            return;
         ext_bv = TRUE;
      }
      else if( !str_prefix( option, "mobile" ) )
      {
         SET_BIT( num, BIT_RESET_MOBILE );
         vnum = 0;
         flfunc = &get_aflag;
         if( !( reset = find_mreset( ch, pArea, aRoom, arg ) ) )
            return;
         ext_bv = TRUE;
      }
      else if( !str_prefix( option, "room" ) )
      {
         SET_BIT( num, BIT_RESET_ROOM );
         if( aRoom )
         {
            pRoom = aRoom;
            argument = parg;
         }
         else if( !is_number( arg ) )
         {
            pRoom = ch->in_room;
            argument = parg;
         }
         else if( !( pRoom = find_room( ch, arg, aRoom ) ) )
            return;
         vnum = pRoom->vnum;
         flfunc = &get_rflag;
         reset = NULL;
      }
      else
      {
         send_to_char( "Must specify OBJECT, MOBILE, ROOM, or DOOR.\n\r", ch );
         return;
      }
      while( *argument )
      {
         int value;
         argument = one_argument( argument, arg );
         value = ( *flfunc ) ( arg );
         if( value < 0 || ( !ext_bv && value > 31 ) )
         {
            send_to_char( "Reset: BIT: bad flag\n\r", ch );
            return;
         }
         if( ext_bv )   /* one per flag for extendeds */
         {
            pReset = make_reset( 'B', 1, vnum, num, flags );
            if( reset )
            {
               INSERT( pReset, reset, pArea->last_reset, prev, next );
               reset = pReset;
            }
            else
               LINK( pReset, pArea->first_reset, pArea->last_reset, next, prev );
         }
         else
            SET_BIT( flags, 1 << value );
      }
      if( !flags )
      {
         send_to_char( "Set which flags?\n\r", ch );
         return;
      }
      if( !ext_bv )
      {
         pReset = make_reset( 'B', 1, vnum, num, flags );
         if( reset )
            INSERT( pReset, reset, pArea->last_reset, prev, next );
         else
            LINK( pReset, pArea->first_reset, pArea->last_reset, next, prev );
      }
      send_to_char( "Bitvector reset created.\n\r", ch );
      return;
   }
   if( !str_cmp( arg, "hide" ) )
   {
      argument = one_argument( argument, arg );
      if( !( reset = find_oreset( ch, pArea, aRoom, arg ) ) )
         return;
/*    pReset = make_reset('H', 1, reset->arg1, 0, 0);*/
      pReset = make_reset( 'H', 1, 0, 0, 0 );
      INSERT( pReset, reset, pArea->last_reset, prev, next );
      send_to_char( "Object hide reset created.\n\r", ch );
      return;
   }
   if( ch->substate == SUB_REPEATCMD )
   {
      ch->substate = SUB_NONE;
      interpret( ch, origarg );
      ch->substate = SUB_REPEATCMD;
      ch->last_cmd = ( aRoom ? do_rreset : do_reset );
   }
   else
      edit_reset( ch, "", pArea, aRoom );
   return;
}

void do_reset( CHAR_DATA * ch, char *argument )
{
   AREA_DATA *pArea = NULL;
   char arg[MAX_INPUT_LENGTH];
   char *parg;

   /*
    * Can't have NPC's doing this.  Bug report sent in by Cronel
    * -- Shaddai
    */
   if( IS_NPC( ch ) )
      return;

   parg = one_argument( argument, arg );
   if( ch->substate == SUB_REPEATCMD )
   {
      pArea = ch->dest_buf;
      if( pArea && pArea != ch->pcdata->area && pArea != ch->in_room->area )
      {
         AREA_DATA *tmp;

         for( tmp = first_build; tmp; tmp = tmp->next )
            if( tmp == pArea )
               break;
         if( !tmp )
            for( tmp = first_area; tmp; tmp = tmp->next )
               if( tmp == pArea )
                  break;
         if( !tmp )
         {
            send_to_char( "Your area pointer got lost.  Reset mode off.\n\r", ch );
            bug( "do_reset: %s's dest_buf points to invalid area", ch->name );   /* why was this cast to an int? */
            ch->substate = SUB_NONE;
            ch->dest_buf = NULL;
            return;
         }
      }
      if( !*arg )
      {
         ch_printf( ch, "Editing resets for area: %s\n\r", pArea->name );
         return;
      }
      if( !str_cmp( arg, "done" ) || !str_cmp( arg, "off" ) )
      {
         send_to_char( "Reset mode off.\n\r", ch );
         ch->substate = SUB_NONE;
         ch->dest_buf = NULL;
         return;
      }
   }
   if( !pArea && get_trust( ch ) > LEVEL_GOD )
   {
      char fname[80];

      sprintf( fname, "%s.are", capitalize( arg ) );
      for( pArea = first_build; pArea; pArea = pArea->next )
         if( !str_cmp( fname, pArea->filename ) )
         {
            argument = parg;
            break;
         }
      if( !pArea )
         pArea = ch->pcdata->area;
      if( !pArea )
         pArea = ch->in_room->area;
   }
   else
      pArea = ch->pcdata->area;
   if( !pArea )
   {
      send_to_char( "You do not have an assigned area.\n\r", ch );
      return;
   }
   edit_reset( ch, argument, pArea, NULL );
   return;
}

void do_rreset( CHAR_DATA * ch, char *argument )
{
   ROOM_INDEX_DATA *pRoom;

   if( ch->substate == SUB_REPEATCMD )
   {
      pRoom = ch->dest_buf;
      if( !pRoom )
      {
         send_to_char( "Your room pointer got lost.  Reset mode off.\n\r", ch );
         bug( "do_rreset: %s's dest_buf points to invalid room", ( int )ch->name );
      }
      ch->substate = SUB_NONE;
      ch->dest_buf = NULL;
      return;
   }
   else
      pRoom = ch->in_room;
   if( !can_rmodify( ch, pRoom ) )
      return;
   edit_reset( ch, argument, pRoom->area, pRoom );
   return;
}

void add_obj_reset( AREA_DATA * pArea, char cm, OBJ_DATA * obj, int v2, int v3 )
{
   OBJ_DATA *inobj;
   static int iNest;

   if( ( cm == 'O' || cm == 'P' ) && obj->pIndexData->vnum == OBJ_VNUM_TRAP )
   {
      if( cm == 'O' )
         add_reset( pArea, 'T', obj->value[3], obj->value[1], obj->value[0], v3 );
      return;
   }
   add_reset( pArea, cm, ( cm == 'P' ? iNest : 1 ), obj->pIndexData->vnum, v2, v3 );
   /*
    * Only add hide for in-room objects that are hidden and cant be moved, as
    * hide is an update reset, not a load-only reset. 
    */
   if( cm == 'O' && IS_OBJ_STAT( obj, ITEM_HIDDEN ) && !IS_SET( obj->wear_flags, ITEM_TAKE ) )
      add_reset( pArea, 'H', 1, 0, 0, 0 );
   for( inobj = obj->first_content; inobj; inobj = inobj->next_content )
      if( inobj->pIndexData->vnum == OBJ_VNUM_TRAP )
         add_obj_reset( pArea, 'O', inobj, 0, 0 );
   if( cm == 'P' )
      iNest++;
   for( inobj = obj->first_content; inobj; inobj = inobj->next_content )
      add_obj_reset( pArea, 'P', inobj, inobj->count, obj->pIndexData->vnum );
   if( cm == 'P' )
      iNest--;
   return;
}

void instaroom( AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, bool dodoors )
{
   CHAR_DATA *rch;
   OBJ_DATA *obj;

   for( rch = pRoom->first_person; rch; rch = rch->next_in_room )
   {
      if( !IS_NPC( rch ) )
         continue;
      add_reset( pArea, 'M', 1, rch->pIndexData->vnum, rch->pIndexData->count, pRoom->vnum );
      for( obj = rch->first_carrying; obj; obj = obj->next_content )
      {
         if( obj->wear_loc == WEAR_NONE )
            add_obj_reset( pArea, 'G', obj, 1, 0 );
         else
            add_obj_reset( pArea, 'E', obj, 1, obj->wear_loc );
      }
   }
   for( obj = pRoom->first_content; obj; obj = obj->next_content )
   {
      add_obj_reset( pArea, 'O', obj, obj->count, pRoom->vnum );
   }
   if( dodoors )
   {
      EXIT_DATA *pexit;

      for( pexit = pRoom->first_exit; pexit; pexit = pexit->next )
      {
         int state = 0;

         if( !IS_SET( pexit->exit_info, EX_ISDOOR ) )
            continue;
         if( IS_SET( pexit->exit_info, EX_CLOSED ) )
         {
            if( IS_SET( pexit->exit_info, EX_LOCKED ) )
               state = 2;
            else
               state = 1;
         }
         add_reset( pArea, 'D', 0, pRoom->vnum, pexit->vdir, state );
      }
   }
   return;
}

void wipe_resets( AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom )
{
   RESET_DATA *pReset;

   for( pReset = pArea->first_reset; pReset; )
   {
      if( pReset->command != 'R' && is_room_reset( pReset, pRoom, pArea ) )
      {
         /*
          * Resets always go forward, so we can safely use the previous reset,
          * providing it exists, or first_reset if it doesnt.  -- Altrag 
          */
         RESET_DATA *prev = pReset->prev;

         delete_reset( pArea, pReset );
         pReset = ( prev ? prev->next : pArea->first_reset );
      }
      else
         pReset = pReset->next;
   }
   return;
}

void do_instaroom( CHAR_DATA * ch, char *argument )
{
   AREA_DATA *pArea;
   ROOM_INDEX_DATA *pRoom;
   bool dodoors;
   char arg[MAX_INPUT_LENGTH];

   if( IS_NPC( ch ) || get_trust( ch ) < LEVEL_SAVIOR || !ch->pcdata || !ch->pcdata->area )
   {
      send_to_char( "You don't have an assigned area to create resets for.\n\r", ch );
      return;
   }
   argument = one_argument( argument, arg );
   if( !str_cmp( argument, "nodoors" ) )
      dodoors = FALSE;
   else
      dodoors = TRUE;
   pArea = ch->pcdata->area;
   if( !( pRoom = find_room( ch, arg, NULL ) ) )
   {
      send_to_char( "Room doesn't exist.\n\r", ch );
      return;
   }
   if( !can_rmodify( ch, pRoom ) )
      return;
   if( pRoom->area != pArea && get_trust( ch ) < LEVEL_GREATER )
   {
      send_to_char( "You cannot reset that room.\n\r", ch );
      return;
   }
   if( pArea->first_reset )
      wipe_resets( pArea, pRoom );
   instaroom( pArea, pRoom, dodoors );
   send_to_char( "Room resets installed.\n\r", ch );
}

void do_instazone( CHAR_DATA * ch, char *argument )
{
   AREA_DATA *pArea;
   int vnum;
   ROOM_INDEX_DATA *pRoom;
   bool dodoors;

   if( IS_NPC( ch ) || get_trust( ch ) < LEVEL_SAVIOR || !ch->pcdata || !ch->pcdata->area )
   {
      send_to_char( "You don't have an assigned area to create resets for.\n\r", ch );
      return;
   }
   if( !str_cmp( argument, "nodoors" ) )
      dodoors = FALSE;
   else
      dodoors = TRUE;
   pArea = ch->pcdata->area;
   if( pArea->first_reset )
      wipe_resets( pArea, NULL );
   for( vnum = pArea->low_r_vnum; vnum <= pArea->hi_r_vnum; vnum++ )
   {
      if( !( pRoom = get_room_index( vnum ) ) || pRoom->area != pArea )
         continue;
      instaroom( pArea, pRoom, dodoors );
   }
   send_to_char( "Area resets installed.\n\r", ch );
   return;
}

int generate_itemlevel( AREA_DATA * pArea, OBJ_INDEX_DATA * pObjIndex )
{
   int olevel;
   int min = UMAX( pArea->low_soft_range, 1 );
   int max = UMIN( pArea->hi_soft_range, min + 15 );

   if( pObjIndex->level > 0 )
      olevel = UMIN( pObjIndex->level, MAX_LEVEL );
   else
      switch ( pObjIndex->item_type )
      {
         default:
            olevel = 0;
            break;
         case ITEM_PILL:
            olevel = number_range( min, max );
            break;
         case ITEM_POTION:
            olevel = number_range( min, max );
            break;
         case ITEM_SCROLL:
            olevel = pObjIndex->value[0];
            break;
         case ITEM_WAND:
            olevel = number_range( min + 4, max + 1 );
            break;
         case ITEM_STAFF:
            olevel = number_range( min + 9, max + 5 );
            break;
         case ITEM_ARMOR:
            olevel = number_range( min + 4, max + 1 );
            break;
         case ITEM_WEAPON:
            olevel = number_range( min + 4, max + 1 );
            break;
      }
   return olevel;
}

/*
 * Reset one area.
 */
void reset_area( AREA_DATA * pArea )
{
   RESET_DATA *pReset;
   CHAR_DATA *mob;
   OBJ_DATA *obj;
   OBJ_DATA *lastobj;
   ROOM_INDEX_DATA *pRoomIndex;
   MOB_INDEX_DATA *pMobIndex;
   OBJ_INDEX_DATA *pObjIndex;
   OBJ_INDEX_DATA *pObjToIndex;
   EXIT_DATA *pexit;
   OBJ_DATA *to_obj;
   char buf[MAX_STRING_LENGTH];
   int level = 0;
   void *plc = NULL;
   bool ext_bv = FALSE;

   if( !pArea )
   {
      bug( "reset_area: NULL pArea", 0 );
      return;
   }

   mob = NULL;
   obj = NULL;
   lastobj = NULL;
   if( !pArea->first_reset )
   {
      bug( "%s: reset_area: no resets", ( int )pArea->filename );
      return;
   }
   level = 0;
   for( pReset = pArea->first_reset; pReset; pReset = pReset->next )
   {
      switch ( pReset->command )
      {
         default:
            sprintf( buf, "%s Reset_area: bad command %c.", pArea->filename, pReset->command );
            bug( buf, 0 );
            break;

         case 'M':
            if( !( pMobIndex = get_mob_index( pReset->arg1 ) ) )
            {
               sprintf( buf, "%s Reset_area: 'M': bad mob vnum %d.", pArea->filename, pReset->arg1 );
               bug( buf, 0 );
               continue;
            }
            if( !( pRoomIndex = get_room_index( pReset->arg3 ) ) )
            {
               sprintf( buf, "%s Reset_area: 'M': bad room vnum %d.", pArea->filename, pReset->arg3 );
               bug( buf, 0 );
               continue;
            }
            if( pMobIndex->count >= pReset->arg2 )
            {
               mob = NULL;
               break;
            }
            mob = create_mobile( pMobIndex );
            {
               ROOM_INDEX_DATA *pRoomPrev = get_room_index( pReset->arg3 - 1 );

               if( pRoomPrev && xIS_SET( pRoomPrev->room_flags, ROOM_PET_SHOP ) )
                  xSET_BIT( mob->act, ACT_PET );
            }
            if( room_is_dark( pRoomIndex ) )
               xSET_BIT( mob->affected_by, AFF_INFRARED );
            char_to_room( mob, pRoomIndex );
            economize_mobgold( mob );
            level = URANGE( 0, mob->level - 2, LEVEL_AVATAR );
            break;

         case 'G':
         case 'E':
            if( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
            {
               sprintf( buf, "%s Reset_area: 'E' or 'G': bad obj vnum %d.", pArea->filename, pReset->arg1 );
               bug( buf, 0 );
               continue;
            }
            if( !mob )
            {
               lastobj = NULL;
               break;
            }
            if( mob->pIndexData->pShop )
            {
               int olevel = generate_itemlevel( pArea, pObjIndex );
               obj = create_object( pObjIndex, olevel );
               xSET_BIT( obj->extra_flags, ITEM_INVENTORY );
            }
            else
               obj = create_object( pObjIndex, number_fuzzy( level ) );
            obj->level = URANGE( 0, obj->level, LEVEL_AVATAR );
            obj = obj_to_char( obj, mob );
            if( pReset->command == 'E' )
            {
               if( obj->carried_by != mob )
               {
                  bug( "'E' reset: can't give object %d to mob %d.", obj->pIndexData->vnum, mob->pIndexData->vnum );
                  break;
               }
               equip_char( mob, obj, pReset->arg3 );
            }
            lastobj = obj;
            break;

         case 'O':
            if( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
            {
/*
	sprintf (buf, "%s Reset_area: 'O': bad obj vnum %d.",
		pArea->filename, pReset->arg1 );
	bug ( buf, 0 );
*/
               continue;
            }
            if( !( pRoomIndex = get_room_index( pReset->arg3 ) ) )
            {
/*
	sprintf ( buf, "%s Reset_area: 'O': bad room vnum %d.", pArea->filename,
	   pReset->arg3 );
	bug ( buf, 0 );
*/
               continue;
            }
            if( pArea->nplayer > 0 || count_obj_list( pObjIndex, pRoomIndex->first_content ) > 0 )
            {
               obj = NULL;
               lastobj = NULL;
               break;
            }
            obj = create_object( pObjIndex, number_fuzzy( generate_itemlevel( pArea, pObjIndex ) ) );
            obj->level = UMIN( obj->level, LEVEL_AVATAR );
            obj->count = pReset->arg2; /* Added to fix object counts */
            obj->cost = 0;
            obj_to_room( obj, pRoomIndex, NULL );
            lastobj = obj;
            break;

         case 'P':
            if( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
            {
/*
	sprintf ( buf, "%s Reset_area: 'P': bad obj vnum %d.", pArea->filename,
	   pReset->arg1 );
	bug ( buf, 0 );
*/
               continue;
            }
            if( pReset->arg3 > 0 )
            {
               if( !( pObjToIndex = get_obj_index( pReset->arg3 ) ) )
               {
/*
	  sprintf(buf,"%s Reset_area: 'P': bad objto vnum %d.",pArea->filename,
		pReset->arg3 );
	  bug( buf, 0 );
*/
                  continue;
               }
               if( pArea->nplayer > 0 ||
                   !( to_obj = get_obj_type( pObjToIndex ) ) ||
                   !to_obj->in_room || count_obj_list( pObjIndex, to_obj->first_content ) > 0 )
               {
                  obj = NULL;
                  break;
               }
               lastobj = to_obj;
            }
            else
            {
               int iNest;

               if( !lastobj )
                  break;
               to_obj = lastobj;
               for( iNest = 0; iNest < pReset->extra; iNest++ )
                  if( !( to_obj = to_obj->last_content ) )
                  {
/*
	    sprintf(buf,"%s Reset_area: 'P': Invalid nesting obj %d."
		,pArea->filename, pReset->arg1 );
	    bug( buf, 0 );
*/
                     iNest = -1;
                     break;
                  }
               if( iNest < 0 )
                  continue;
            }
            obj = create_object( pObjIndex, number_fuzzy( UMAX( generate_itemlevel( pArea, pObjIndex ), to_obj->level ) ) );
            obj->level = UMIN( obj->level, LEVEL_AVATAR );
            obj->count = pReset->arg2; /* Added to fix object counts */
            obj_to_obj( obj, to_obj );
            break;

         case 'T':
            if( IS_SET( pReset->extra, TRAP_OBJ ) )
            {
               /*
                * We need to preserve obj for future 'T' and 'H' checks 
                */
               OBJ_DATA *pobj;

               if( pReset->arg3 > 0 )
               {
                  if( !( pObjToIndex = get_obj_index( pReset->arg3 ) ) )
                  {
/*
	    sprintf (buf,"%s Reset_area: 'T': bad objto vnum %d."
		,pArea->filename, pReset->arg3 );
	    bug ( buf, 0 );
*/
                     continue;
                  }
                  if( pArea->nplayer > 0 ||
                      !( to_obj = get_obj_type( pObjToIndex ) ) ||
                      ( to_obj->carried_by && !IS_NPC( to_obj->carried_by ) ) || is_trapped( to_obj ) )
                     break;
               }
               else
               {
                  if( !lastobj || !obj )
                     break;
                  to_obj = obj;
               }
               pobj = make_trap( pReset->arg2, pReset->arg1, number_fuzzy( to_obj->level ), pReset->extra );
               obj_to_obj( pobj, to_obj );
            }
            else
            {
               if( !( pRoomIndex = get_room_index( pReset->arg3 ) ) )
               {
/*
	  sprintf(buf,"%s Reset_area: 'T': bad room %d.", pArea->filename,
		pReset->arg3 );
	  bug( buf, 0 );
*/
                  continue;
               }
               if( pArea->nplayer > 0 || count_obj_list( get_obj_index( OBJ_VNUM_TRAP ), pRoomIndex->first_content ) > 0 )
                  break;
               to_obj = make_trap( pReset->arg1, pReset->arg1, 10, pReset->extra );
               obj_to_room( to_obj, pRoomIndex, NULL );
            }
            break;

         case 'H':
            if( pReset->arg1 > 0 )
            {
               if( !( pObjToIndex = get_obj_index( pReset->arg1 ) ) )
               {
/*
	  sprintf(buf,"%s Reset_area: 'H': bad objto vnum %d.",pArea->filename,
		pReset->arg1 );
	  bug( buf, 0 );
*/
                  continue;
               }
               if( pArea->nplayer > 0 ||
                   !( to_obj = get_obj_type( pObjToIndex ) ) ||
                   !to_obj->in_room || to_obj->in_room->area != pArea || IS_OBJ_STAT( to_obj, ITEM_HIDDEN ) )
                  break;
            }
            else
            {
               if( !lastobj || !obj )
                  break;
               to_obj = obj;
            }
            xSET_BIT( to_obj->extra_flags, ITEM_HIDDEN );
            break;

         case 'B':
            switch ( pReset->arg2 & BIT_RESET_TYPE_MASK )
            {
               case BIT_RESET_DOOR:
               {
                  int doornum;

                  if( !( pRoomIndex = get_room_index( pReset->arg1 ) ) )
                  {
/*
	  sprintf(buf,"%s Reset_area: 'B': door: bad room vnum %d.",
		pArea->filename, pReset->arg1 );
	  bug( buf, 0 );
*/
                     continue;
                  }
                  doornum = ( pReset->arg2 & BIT_RESET_DOOR_MASK ) >> BIT_RESET_DOOR_THRESHOLD;
                  if( !( pexit = get_exit( pRoomIndex, doornum ) ) )
                     break;
                  plc = &pexit->exit_info;
               }
                  break;
               case BIT_RESET_ROOM:
                  if( !( pRoomIndex = get_room_index( pReset->arg1 ) ) )
                  {
/*
	  sprintf(buf,"%s Reset_area: 'B': room: bad room vnum %d.",
		pArea->filename, pReset->arg1 );
	  bug(buf, 0);
*/
                     continue;
                  }
                  plc = &pRoomIndex->room_flags;
                  break;
               case BIT_RESET_OBJECT:
                  if( pReset->arg1 > 0 )
                  {
                     if( !( pObjToIndex = get_obj_index( pReset->arg1 ) ) )
                     {
/*
	    sprintf(buf,"%s Reset_area: 'B': object: bad objto vnum %d.",
		pArea->filename, pReset->arg1 );
	    bug( buf, 0 );
*/
                        continue;
                     }
                     if( !( to_obj = get_obj_type( pObjToIndex ) ) || !to_obj->in_room || to_obj->in_room->area != pArea )
                        continue;
                  }
                  else
                  {
                     if( !lastobj || !obj )
                        continue;
                     to_obj = obj;
                  }
                  plc = &to_obj->extra_flags;
                  ext_bv = TRUE;
                  break;
               case BIT_RESET_MOBILE:
                  if( !mob )
                     continue;
                  plc = &mob->affected_by;
                  ext_bv = TRUE;
                  break;
               default:
/*
	sprintf(buf, "%s Reset_area: 'B': bad options %d.",
		pArea->filename, pReset->arg2 );
	bug( buf, 0 );
*/
                  continue;
            }
            if( IS_SET( pReset->arg2, BIT_RESET_SET ) )
            {
               if( ext_bv )
                  xSET_BIT( *( EXT_BV * ) plc, pReset->arg3 );
               else
                  SET_BIT( *( int * )plc, pReset->arg3 );
            }
            else if( IS_SET( pReset->arg2, BIT_RESET_TOGGLE ) )
            {
               if( ext_bv )
                  xTOGGLE_BIT( *( EXT_BV * ) plc, pReset->arg3 );
               else
                  TOGGLE_BIT( *( int * )plc, pReset->arg3 );
            }
            else
            {
               if( ext_bv )
                  xREMOVE_BIT( *( EXT_BV * ) plc, pReset->arg3 );
               else
                  REMOVE_BIT( *( int * )plc, pReset->arg3 );
            }
            break;

         case 'D':
            if( !( pRoomIndex = get_room_index( pReset->arg1 ) ) )
            {
/*
	sprintf(buf, "%s Reset_area: 'D': bad room vnum %d.",
		pArea->filename, pReset->arg1 );
	bug(buf, 0);
*/
               continue;
            }
            if( !( pexit = get_exit( pRoomIndex, pReset->arg2 ) ) )
               break;
            switch ( pReset->arg3 )
            {
               case 0:
                  REMOVE_BIT( pexit->exit_info, EX_CLOSED );
                  REMOVE_BIT( pexit->exit_info, EX_LOCKED );
                  break;
               case 1:
                  SET_BIT( pexit->exit_info, EX_CLOSED );
                  REMOVE_BIT( pexit->exit_info, EX_LOCKED );
                  if( IS_SET( pexit->exit_info, EX_xSEARCHABLE ) )
                     SET_BIT( pexit->exit_info, EX_SECRET );
                  break;
               case 2:
                  SET_BIT( pexit->exit_info, EX_CLOSED );
                  SET_BIT( pexit->exit_info, EX_LOCKED );
                  if( IS_SET( pexit->exit_info, EX_xSEARCHABLE ) )
                     SET_BIT( pexit->exit_info, EX_SECRET );
                  break;
            }
            break;

         case 'R':
            if( !( pRoomIndex = get_room_index( pReset->arg1 ) ) )
            {
/*
	sprintf(buf,"%s Reset_area: 'R': bad room vnum %d.",
		pArea->filename, pReset->arg1 );
	bug(buf, 0);
*/
               continue;
            }
            randomize_exits( pRoomIndex, pReset->arg2 - 1 );
            break;
      }
   }
   return;
}

void list_resets( CHAR_DATA * ch, AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, int start, int end )
{
   RESET_DATA *pReset;
   ROOM_INDEX_DATA *room;
   MOB_INDEX_DATA *mob;
   OBJ_INDEX_DATA *obj, *obj2;
   OBJ_INDEX_DATA *lastobj;
   RESET_DATA *lo_reset;
   bool found;
   int num = 0;
   const char *rname = "???", *mname = "???", *oname = "???";
   char buf[256];
   char *pbuf;

   if( !ch || !pArea )
      return;
   room = NULL;
   mob = NULL;
   obj = NULL;
   lastobj = NULL;
   lo_reset = NULL;
   found = FALSE;

   for( pReset = pArea->first_reset; pReset; pReset = pReset->next )
   {
      if( !is_room_reset( pReset, pRoom, pArea ) )
         continue;
      ++num;
      sprintf( buf, "%2d) ", num );
      pbuf = buf + strlen( buf );
      switch ( pReset->command )
      {
         default:
            sprintf( pbuf, "*** BAD RESET: %c %d %d %d %d ***\n\r",
                     pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3 );
            break;
         case 'M':
            if( !( mob = get_mob_index( pReset->arg1 ) ) )
               mname = "Mobile: *BAD VNUM*";
            else
               mname = mob->player_name;
            if( !( room = get_room_index( pReset->arg3 ) ) )
               rname = "Room: *BAD VNUM*";
            else
               rname = room->name;
            sprintf( pbuf, "%s (%d) -> %s (%d) [%d]", mname, pReset->arg1, rname, pReset->arg3, pReset->arg2 );
            if( !room )
               mob = NULL;
            if( ( room = get_room_index( pReset->arg3 - 1 ) ) && xIS_SET( room->room_flags, ROOM_PET_SHOP ) )
               strcat( buf, " (pet)\n\r" );
            else
               strcat( buf, "\n\r" );
            break;
         case 'G':
         case 'E':
            if( !mob )
               mname = "* ERROR: NO MOBILE! *";
            if( !( obj = get_obj_index( pReset->arg1 ) ) )
               oname = "Object: *BAD VNUM*";
            else
               oname = obj->name;
            sprintf( pbuf, "%s (%d) -> %s (%s) [%d]", oname, pReset->arg1, mname,
                     ( pReset->command == 'G' ? "carry" : wear_locs[pReset->arg3] ), pReset->arg2 );
            if( mob && mob->pShop )
               strcat( buf, " (shop)\n\r" );
            else
               strcat( buf, "\n\r" );
            lastobj = obj;
            lo_reset = pReset;
            break;
         case 'O':
            if( !( obj = get_obj_index( pReset->arg1 ) ) )
               oname = "Object: *BAD VNUM*";
            else
               oname = obj->name;
            if( !( room = get_room_index( pReset->arg3 ) ) )
               rname = "Room: *BAD VNUM*";
            else
               rname = room->name;
            sprintf( pbuf, "(object) %s (%d) -> %s (%d) [%d]\n\r", oname, pReset->arg1, rname, pReset->arg3, pReset->arg2 );
            if( !room )
               obj = NULL;
            lastobj = obj;
            lo_reset = pReset;
            break;
         case 'P':
            if( !( obj = get_obj_index( pReset->arg1 ) ) )
               oname = "Object1: *BAD VNUM*";
            else
               oname = obj->name;
            obj2 = NULL;
            if( pReset->arg3 > 0 )
            {
               obj2 = get_obj_index( pReset->arg3 );
               rname = ( obj2 ? obj2->name : "Object2: *BAD VNUM*" );
               lastobj = obj2;
            }
            else if( !lastobj )
               rname = "Object2: *NULL obj*";
            else if( pReset->extra == 0 )
            {
               rname = lastobj->name;
               obj2 = lastobj;
            }
            else
            {
               int iNest;
               RESET_DATA *reset;

               reset = lo_reset->next;
               for( iNest = 0; iNest < pReset->extra; iNest++ )
               {
                  for( ; reset; reset = reset->next )
                     if( reset->command == 'O' || reset->command == 'G' ||
                         reset->command == 'E' || ( reset->command == 'P' && !reset->arg3 && reset->extra == iNest ) )
                        break;
                  if( !reset || reset->command != 'P' )
                     break;
               }
               if( !reset )
                  rname = "Object2: *BAD NESTING*";
               else if( !( obj2 = get_obj_index( reset->arg1 ) ) )
                  rname = "Object2: *NESTED BAD VNUM*";
               else
                  rname = obj2->name;
            }
            sprintf( pbuf, "(Put) %s (%d) -> %s (%d) [%d] {nest %d}\n\r", oname,
                     pReset->arg1, rname, ( obj2 ? obj2->vnum : pReset->arg3 ), pReset->arg2, pReset->extra );
            break;
         case 'T':
            sprintf( pbuf, "TRAP: %d %d %d %d (%s)\n\r", pReset->extra, pReset->arg1,
                     pReset->arg2, pReset->arg3, flag_string( pReset->extra, trap_flags ) );
            break;
         case 'H':
            if( pReset->arg1 > 0 )
               if( !( obj2 = get_obj_index( pReset->arg1 ) ) )
                  rname = "Object: *BAD VNUM*";
               else
                  rname = obj2->name;
            else if( !obj )
               rname = "Object: *NULL obj*";
            else
               rname = oname;
            sprintf( pbuf, "Hide %s (%d)\n\r", rname, ( pReset->arg1 > 0 ? pReset->arg1 : obj ? obj->vnum : 0 ) );
            break;
         case 'B':
         {
            char *const *flagarray;
            bool ext_bv = FALSE;

            strcpy( pbuf, "BIT: " );
            pbuf += 5;
            if( IS_SET( pReset->arg2, BIT_RESET_SET ) )
            {
               strcpy( pbuf, "Set: " );
               pbuf += 5;
            }
            else if( IS_SET( pReset->arg2, BIT_RESET_TOGGLE ) )
            {
               strcpy( pbuf, "Toggle: " );
               pbuf += 8;
            }
            else
            {
               strcpy( pbuf, "Remove: " );
               pbuf += 8;
            }
            switch ( pReset->arg2 & BIT_RESET_TYPE_MASK )
            {
               case BIT_RESET_DOOR:
               {
                  int door;

                  if( !( room = get_room_index( pReset->arg1 ) ) )
                     rname = "Room: *BAD VNUM*";
                  else
                     rname = room->name;
                  door = ( pReset->arg2 & BIT_RESET_DOOR_MASK ) >> BIT_RESET_DOOR_THRESHOLD;
                  door = URANGE( 0, door, MAX_DIR + 1 );
                  sprintf( pbuf, "Exit %s%s (%d), Room %s (%d)", dir_name[door],
                           ( room && get_exit( room, door ) ? "" : " (NO EXIT!)" ), door, rname, pReset->arg1 );
               }
                  flagarray = ex_flags;
                  break;
               case BIT_RESET_ROOM:
                  if( !( room = get_room_index( pReset->arg1 ) ) )
                     rname = "Room: *BAD VNUM*";
                  else
                     rname = room->name;
                  sprintf( pbuf, "Room %s (%d)", rname, pReset->arg1 );
                  flagarray = r_flags;
                  break;
               case BIT_RESET_OBJECT:
                  if( pReset->arg1 > 0 )
                     if( !( obj2 = get_obj_index( pReset->arg1 ) ) )
                        rname = "Object: *BAD VNUM*";
                     else
                        rname = obj2->name;
                  else if( !obj )
                     rname = "Object: *NULL obj*";
                  else
                     rname = oname;
                  sprintf( pbuf, "Object %s (%d)", rname, ( pReset->arg1 > 0 ? pReset->arg1 : obj ? obj->vnum : 0 ) );
                  flagarray = o_flags;
                  ext_bv = TRUE;
                  break;
               case BIT_RESET_MOBILE:
                  if( pReset->arg1 > 0 )
                  {
                     MOB_INDEX_DATA *mob2;

                     if( !( mob2 = get_mob_index( pReset->arg1 ) ) )
                        rname = "Mobile: *BAD VNUM*";
                     else
                        rname = mob2->player_name;
                  }
                  else if( !mob )
                     rname = "Mobile: *NULL mob*";
                  else
                     rname = mname;
                  sprintf( pbuf, "Mobile %s (%d)", rname, ( pReset->arg1 > 0 ? pReset->arg1 : mob ? mob->vnum : 0 ) );
                  flagarray = a_flags;
                  ext_bv = TRUE;
                  break;
               default:
                  sprintf( pbuf, "bad type %d", pReset->arg2 & BIT_RESET_TYPE_MASK );
                  flagarray = NULL;
                  break;
            }
            pbuf += strlen( pbuf );
            if( flagarray )
            {
               if( ext_bv )
               {
                  EXT_BV tmp;

                  tmp = meb( pReset->arg3 );
                  sprintf( pbuf, "; flags: %s [%d]\n\r", ext_flag_string( &tmp, flagarray ), pReset->arg3 );
               }
               else
                  sprintf( pbuf, "; flags: %s [%d]\n\r", flag_string( pReset->arg3, flagarray ), pReset->arg3 );
            }
            else
               sprintf( pbuf, "; flags %d\n\r", pReset->arg3 );
         }
            break;
         case 'D':
         {
            char *ef_name;

            pReset->arg2 = URANGE( 0, pReset->arg2, MAX_DIR + 1 );
            if( !( room = get_room_index( pReset->arg1 ) ) )
               rname = "Room: *BAD VNUM*";
            else
               rname = room->name;
            switch ( pReset->arg3 )
            {
               default:
                  ef_name = "(* ERROR *)";
                  break;
               case 0:
                  ef_name = "Open";
                  break;
               case 1:
                  ef_name = "Close";
                  break;
               case 2:
                  ef_name = "Close and lock";
                  break;
            }
            sprintf( pbuf, "%s [%d] the %s%s [%d] door %s (%d)\n\r", ef_name,
                     pReset->arg3, dir_name[pReset->arg2],
                     ( room && get_exit( room, pReset->arg2 ) ? "" : " (NO EXIT!)" ), pReset->arg2, rname, pReset->arg1 );
         }
            break;
         case 'R':
            if( !( room = get_room_index( pReset->arg1 ) ) )
               rname = "Room: *BAD VNUM*";
            else
               rname = room->name;
            sprintf( pbuf, "Randomize exits 0 to %d -> %s (%d)\n\r", pReset->arg2, rname, pReset->arg1 );
            break;
      }
      if( start == -1 || num >= start )
         send_to_char( buf, ch );
      if( end != -1 && num >= end )
         break;
   }
   if( num == 0 )
      send_to_char( "You don't have any resets defined.\n\r", ch );
   return;
}

/* Setup put nesting levels, regardless of whether or not the resets will
   actually reset, or if they're bugged. */
void renumber_put_resets( AREA_DATA * pArea )
{
   RESET_DATA *pReset, *lastobj = NULL;

   for( pReset = pArea->first_reset; pReset; pReset = pReset->next )
   {
      switch ( pReset->command )
      {
         default:
            break;
         case 'G':
         case 'E':
         case 'O':
            lastobj = pReset;
            break;
         case 'P':
            if( pReset->arg3 == 0 )
            {
               if( !lastobj )
                  pReset->extra = 1000000;
               else if( lastobj->command != 'P' || lastobj->arg3 > 0 )
                  pReset->extra = 0;
               else
                  pReset->extra = lastobj->extra + 1;
               lastobj = pReset;
            }
      }
   }
   return;
}

/*
 * Create a new reset (for online building)			-Thoric
 */
RESET_DATA *make_reset( char letter, int extra, int arg1, int arg2, int arg3 )
{
   RESET_DATA *pReset;

   CREATE( pReset, RESET_DATA, 1 );
   pReset->command = letter;
   pReset->extra = extra;
   pReset->arg1 = arg1;
   pReset->arg2 = arg2;
   pReset->arg3 = arg3;
   top_reset++;
   return pReset;
}

/*
 * Add a reset to an area				-Thoric
 */
RESET_DATA *add_reset( AREA_DATA * tarea, char letter, int extra, int arg1, int arg2, int arg3 )
{
   RESET_DATA *pReset;

   if( !tarea )
   {
      bug( "add_reset: NULL area!", 0 );
      return NULL;
   }

   letter = UPPER( letter );
   pReset = make_reset( letter, extra, arg1, arg2, arg3 );
   switch ( letter )
   {
      case 'M':
         tarea->last_mob_reset = pReset;
         break;
      case 'H':
         if( arg1 > 0 )
            break;
      case 'E':
      case 'G':
      case 'P':
      case 'O':
         tarea->last_obj_reset = pReset;
         break;
      case 'T':
         if( IS_SET( extra, TRAP_OBJ ) && arg1 == 0 )
            tarea->last_obj_reset = pReset;
         break;
   }

   LINK( pReset, tarea->first_reset, tarea->last_reset, next, prev );
   return pReset;
}

/*
 * Place a reset into an area, insert sorting it		-Thoric
 */
RESET_DATA *place_reset( AREA_DATA * tarea, char letter, int extra, int arg1, int arg2, int arg3 )
{
   RESET_DATA *pReset, *tmp, *tmp2;

   if( !tarea )
   {
      bug( "place_reset: NULL area!", 0 );
      return NULL;
   }

   letter = UPPER( letter );
   pReset = make_reset( letter, extra, arg1, arg2, arg3 );
   if( letter == 'M' )
      tarea->last_mob_reset = pReset;

   if( tarea->first_reset )
   {
      switch ( letter )
      {
         default:
            bug( "place_reset: Bad reset type %c", letter );
            return NULL;
         case 'D':
         case 'R':
            for( tmp = tarea->last_reset; tmp; tmp = tmp->prev )
               if( tmp->command == letter )
                  break;
            if( tmp )   /* organize by location */
               for( ; tmp && tmp->command == letter && tmp->arg1 > arg1; tmp = tmp->prev );
            if( tmp )   /* organize by direction */
               for( ; tmp && tmp->command == letter && tmp->arg1 == tmp->arg1 && tmp->arg2 > arg2; tmp = tmp->prev );
            if( tmp )
               INSERT( pReset, tmp, tarea->first_reset, next, prev );
            else
               LINK( pReset, tarea->first_reset, tarea->last_reset, next, prev );
            return pReset;
         case 'M':
         case 'O':
            /*
             * find last reset of same type 
             */
            for( tmp = tarea->last_reset; tmp; tmp = tmp->prev )
               if( tmp->command == letter )
                  break;
            tmp2 = tmp ? tmp->next : NULL;
            /*
             * organize by location 
             */
            for( ; tmp; tmp = tmp->prev )
               if( tmp->command == letter && tmp->arg3 <= arg3 )
               {
                  tmp2 = tmp->next;
                  /*
                   * organize by vnum 
                   */
                  if( tmp->arg3 == arg3 )
                     for( ; tmp; tmp = tmp->prev )
                        if( tmp->command == letter && tmp->arg3 == tmp->arg3 && tmp->arg1 <= arg1 )
                        {
                           tmp2 = tmp->next;
                           break;
                        }
                  break;
               }
            /*
             * skip over E or G for that mob 
             */
            if( tmp2 && letter == 'M' )
            {
               for( ; tmp2; tmp2 = tmp2->next )
                  if( tmp2->command != 'E' && tmp2->command != 'G' )
                     break;
            }
            else
               /*
                * skip over P, T or H for that obj 
                */
            if( tmp2 && letter == 'O' )
            {
               for( ; tmp2; tmp2 = tmp2->next )
                  if( tmp2->command != 'P' && tmp2->command != 'T' && tmp2->command != 'H' )
                     break;
            }
            if( tmp2 )
               INSERT( pReset, tmp2, tarea->first_reset, next, prev );
            else
               LINK( pReset, tarea->first_reset, tarea->last_reset, next, prev );
            return pReset;
         case 'G':
         case 'E':
            /*
             * find the last mob 
             */
            if( ( tmp = tarea->last_mob_reset ) != NULL )
            {
               /*
                * See if there are any resets for this mob yet,
                * put E before G and organize by vnum
                */
               if( tmp->next )
               {
                  tmp = tmp->next;
                  if( tmp && tmp->command == 'E' )
                  {
                     if( letter == 'E' )
                        for( ; tmp && tmp->command == 'E' && tmp->arg1 < arg1; tmp = tmp->next );
                     else
                        for( ; tmp && tmp->command == 'E'; tmp = tmp->next );
                  }
                  else if( tmp && tmp->command == 'G' && letter == 'G' )
                     for( ; tmp && tmp->command == 'G' && tmp->arg1 < arg1; tmp = tmp->next );
                  if( tmp )
                     INSERT( pReset, tmp, tarea->first_reset, next, prev );
                  else
                     LINK( pReset, tarea->first_reset, tarea->last_reset, next, prev );
               }
               else
                  LINK( pReset, tarea->first_reset, tarea->last_reset, next, prev );
               return pReset;
            }
            break;
         case 'P':
         case 'T':
         case 'H':
            /*
             * find the object in question 
             */
            if( ( ( letter == 'P' && arg3 == 0 )
                  || ( letter == 'T' && IS_SET( extra, TRAP_OBJ ) && arg1 == 0 )
                  || ( letter == 'H' && arg1 == 0 ) ) && ( tmp = tarea->last_obj_reset ) != NULL )
            {
               if( ( tmp = tmp->next ) != NULL )
                  INSERT( pReset, tmp, tarea->first_reset, next, prev );
               else
                  LINK( pReset, tarea->first_reset, tarea->last_reset, next, prev );
               return pReset;
            }

            for( tmp = tarea->last_reset; tmp; tmp = tmp->prev )
               if( ( tmp->command == 'O' || tmp->command == 'G'
                     || tmp->command == 'E' || tmp->command == 'P' ) && tmp->arg1 == arg3 )
               {
                  /*
                   * See if there are any resets for this object yet,
                   * put P before H before T and organize by vnum
                   */
                  if( tmp->next )
                  {
                     tmp = tmp->next;
                     if( tmp && tmp->command == 'P' )
                     {
                        if( letter == 'P' && tmp->arg3 == arg3 )
                           for( ; tmp && tmp->command == 'P' && tmp->arg3 == arg3 && tmp->arg1 < arg1; tmp = tmp->next );
                        else if( letter != 'T' )
                           for( ; tmp && tmp->command == 'P' && tmp->arg3 == arg3; tmp = tmp->next );
                     }
                     else if( tmp && tmp->command == 'H' )
                     {
                        if( letter == 'H' && tmp->arg3 == arg3 )
                           for( ; tmp && tmp->command == 'H' && tmp->arg3 == arg3 && tmp->arg1 < arg1; tmp = tmp->next );
                        else if( letter != 'H' )
                           for( ; tmp && tmp->command == 'H' && tmp->arg3 == arg3; tmp = tmp->next );
                     }
                     else if( tmp && tmp->command == 'T' && letter == 'T' )
                        for( ; tmp && tmp->command == 'T' && tmp->arg3 == arg3 && tmp->arg1 < arg1; tmp = tmp->next );
                     if( tmp )
                        INSERT( pReset, tmp, tarea->first_reset, next, prev );
                     else
                        LINK( pReset, tarea->first_reset, tarea->last_reset, next, prev );
                  }
                  else
                     LINK( pReset, tarea->first_reset, tarea->last_reset, next, prev );
                  return pReset;
               }
            break;
      }
      /*
       * likely a bad reset if we get here... add it anyways 
       */
   }
   LINK( pReset, tarea->first_reset, tarea->last_reset, next, prev );
   return pReset;
}