toc/
toc/account/a/
toc/area/backup/
toc/area/imc/
toc/caste/
toc/caste/backup/
toc/clans/
toc/classes/
toc/crash/
toc/gods/
toc/guilds/
toc/lname/s/
toc/maps/backup/
toc/player/a/
toc/src/
toc/system/backup/
toc/tableprog/
/****************************************************************************
 * [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 "mud.h"


/* Externals */
extern int top_reset;
char *sprint_reset args((CHAR_DATA * ch, RESET_DATA * pReset, sh_int 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[];

#define MAX_OBJ 50
int put_index, obj_index;
int obj_array[MAX_OBJ][2];
int put_array[MAX_OBJ][3];

#define IS_OBJ_TYPE(obj) ( obj->item_type == ITEM_KEYRING \
                         ||obj->item_type == ITEM_QUIVER \
                         ||obj->item_type == ITEM_CONTAINER \
			 ||obj->item_type == ITEM_SHEATH)

#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));

#define RID ROOM_INDEX_DATA
RID *find_room args((CHAR_DATA * ch, char *argument, ROOM_INDEX_DATA * pRoom));

#undef RID


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;
}

/* Finds the mobs in the Reset Area and puts their limits on in acending order --Xerves*/
int fmob_count(AREA_DATA * pArea, int vnum)
{
   RESET_DATA *pReset;
   int count = 1;

   for (pReset = pArea->first_reset; pReset; pReset = pReset->next)
   {
      if (pReset->arg1 == vnum && pReset->command == 'M')
      {
         pReset->arg2 = count;
         count++;
      }
   }
   return count;
}

/* 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[MIL];

   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);
         if (reset->command == 'A')
            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[MIL];
      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) || !str_cmp(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[MIL];
      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;
}

bool can_mapmodify(CHAR_DATA * ch, ROOM_INDEX_DATA * room)
{
   sh_int vnum = room->vnum;
   AREA_DATA *pArea;

   if (IS_NPC(ch))
      return FALSE;

   if (get_trust(ch) >= sysdata.level_modify_proto)
      return TRUE;
   if (!xIS_SET(room->room_flags, ROOM_PROTOTYPE))
   {
      send_to_char("You cannot modify this room.\n\r", ch);
      return FALSE;
   }
   if (!ch->pcdata || !(pArea = ch->pcdata->area))
   {
      send_to_char("You must have an assigned area to modify this room.\n\r", ch);
      return FALSE;
   }
   if (vnum >= pArea->low_r_vnum && vnum <= pArea->hi_r_vnum)
      return TRUE;

   send_to_char("That room is not in your allocated range.\n\r", ch);
   return FALSE;
}

void edit_reset(CHAR_DATA * ch, char *argument, AREA_DATA * pArea, ROOM_INDEX_DATA * aRoom)
{
   char arg[MIL];
   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: %stime <#> <time to pop>\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, 0);
      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)) == NULL)
      {
         send_to_char("Error in reset.  Reset not changed.\n\r", ch);
         return;
      }
      reset->serial = pReset->serial;
      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;
      }  
      reset = add_reset(pArea, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3, pReset->arg4, pReset->arg5, pReset->arg6, -1, 0, 0);
      reset->serial = ++serialmobsloaded;
      serial_list[reset->serial] = FALSE; 
      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;
      }
      pReset->serial = ++serialmobsloaded;
      serial_list[pReset->serial] = FALSE;  
      reset = place_reset(pArea, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3, pReset->arg4, pReset->arg5, pReset->arg6, -1, 0, 0);
      reset->serial = ++serialmobsloaded;
      serial_list[reset->serial] = FALSE; 
      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;
      }
      pReset->serial = ++serialmobsloaded;
      serial_list[pReset->serial] = FALSE;  
      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, "time"))
   {   
      int tleft;
      int ttime = time(0);
      int sec, hour, min, days, rtime;
      char time[256];
      
      argument = one_argument(argument, arg);
      if (!*arg || (!is_number(arg) && str_cmp(arg, "left") && str_cmp(arg, "forcereset")))
      {
         send_to_char("Usage: reset time <number> <time to reset>\n\r", ch);
         send_to_char("Usage: reset time left <number>  --Shows Time Left till Reset\n\r", ch);
         send_to_char("Usage: reset time forcereset <number>  --Sets the time to reset to now, will reset next reset area tick\n\r", ch);
         send_to_char("Time to reset is in seconds.  60 seconds in a minute, 3600 seconds in an hour, 86,400 seconds in a day\n\r", ch);
         return;
      }
      if (!str_cmp(arg, "forcereset"))
      {
         num = atoi(argument);
         if (!(pReset = find_reset(pArea, aRoom, num)))
         {
            send_to_char("Reset not found.\n\r", ch);
            return;
         }
         if (pReset->resetlast < 1)
         {
            send_to_char("That reset is not a time based Reset.\n\r", ch);
            return;
         }
         pReset->resetlast = ttime-pReset->resettime;
         send_to_char("Done.\n\r", ch);
         return;
      }
      if (!str_cmp(arg, "left"))
      {
         num = atoi(argument);
         if (!(pReset = find_reset(pArea, aRoom, num)))
         {
            send_to_char("Reset not found.\n\r", ch);
            return;
         }
         if (pReset->resetlast < 1)
         {
            send_to_char("That reset is not a time based Reset.\n\r", ch);
            return;
         }
         tleft = pReset->resetlast + pReset->resettime - ttime;
         if (tleft < 1)
         {
            send_to_char("The Reset will load next time a Reset Area is issued.\n\r", ch);
            return;
         }
         if (tleft > 86400)
         {
            days = pReset->resettime / 86400;
            rtime = pReset->resettime % 86400;
         }
         else
         {
            days = 0;
            rtime = tleft;
         }
         sec = rtime % 60;
         hour = rtime / 3600;
         if (rtime > 60)
         {
            min = rtime / 60;
            min = min % 60;
         }
         else
         {
            min = 0;
         }
         sprintf(time, "&w&WTime Left:  D:%d H:%d M:%d S:%d\n\r", days, hour, min, sec);
         send_to_char(time, ch);
         return;
      }  
      num = atoi(arg);
      if (!(pReset = find_reset(pArea, aRoom, num)))
      {
         send_to_char("Reset not found.\n\r", ch);
         return;
      }
      num = atoi(argument);
      if (num < -1 || num > 300000000)
      {
         send_to_char("Range is -1 (Resets once), 0 (Resets every tick) to 300mil (resets every 10 years or so)\n\r", ch);
         return;
      }
      pReset->resettime = num;
      pReset->resetlast = 0;
      ch_printf(ch, "Time of %d added.\n\r", num);
      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, 0, pRoom->vnum, -1, -1, -1, -1, 0, 0);
      pReset->serial = ++serialmobsloaded;
      pReset->arg2 = 1;
      serial_list[pReset->serial] = FALSE;
      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;
/*      pReset = make_reset('P', 1, pObj->vnum, num, reset->arg1);*/
         argument = one_argument(argument, arg);
         if ((vnum = atoi(arg)) < 1)
            vnum = 1;
         pReset = make_reset('P', reset->extra + 1, pObj->vnum, vnum, 0, -1, -1, -1, -1, 0, 0);
         /* 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, -1, -1, -1, -1, 0, 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, -1, -1, -1, -1, 0, 0);
         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, -1, -1, -1, -1, 0, 0);
         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, -1, -1, -1, -1, 0, 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[MIL];
      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("obj", argument);
      if (isobj == is_name("room", argument))
      {
         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, -1, -1, -1, -1, 0, 0);
      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[MIL];
      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, -1, -1, -1, -1, 0, 0);
            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, -1, -1, -1, -1, 0, 0);
         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, -1, -1, -1, -1, 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[MIL];
   char *parg;

   parg = one_argument(argument, arg);

   /* Mset/Oset/Redit On Mode check -- Stop most building crashes -- Xerves 8/7/99 */
   if ((xIS_SET(ch->act, PLR_MSET)) || (xIS_SET(ch->act, PLR_OSET)) || (xIS_SET(ch->act, PLR_REDIT)))
   {
      send_to_char("You need to turn mset/oset/redit off\n\r", ch);
      return;
   }

   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_STAFF) /* Tracker1 */
   {
      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;
   RESET_DATA *pReset;
   static int iNest;
   int obj_loop, value_loop;
   int reset_count = 0;
   bool found;
   int v4 = -1;
   int v7 = -1;
   
   if (obj->value[6] > 99 && (obj->item_type == ITEM_WEAPON || obj->item_type == ITEM_ARMOR) && xIS_SET(obj->extra_flags, ITEM_FORGEABLE))
   {
      if (cm == '0')   
         v7 = obj->value[6];
      else if (cm == 'E' || cm == 'P')
         v4 = obj->value[6];
      else if (cm == 'G')
      {
         v3 = obj->value[6];
         v4 = obj->value[11];
      }
   }

   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, v4, -1, -1, v7, 0, 0);
      return;
   }
   if (cm == 'O' && IS_OBJ_STAT(obj, ITEM_ONMAP))
   {
      add_reset(pArea, cm, 1, obj->pIndexData->vnum, v2, v3, obj->coord->x, obj->coord->y, obj->map, v7, 0, 0);
   }
   else
   {
      add_reset(pArea, cm, (cm == 'P' ? iNest : 1), obj->pIndexData->vnum, v2, v3, v4, -1, -1, v7, 0, 0);
   }
   /* 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, -1, -1, -1, -1, 0, 0);
   if (obj->trap)
   {
      pReset = make_reset('A', 1, obj->trap->uid, 0, 0, -1, -1, -1, -1, 0, 0);
      LINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
   }
   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++;

   if (put_index == 0)
      for (obj_loop = 0; obj_loop < MAX_OBJ; obj_loop++)
         for (value_loop = 0; value_loop < 3; value_loop++)
            put_array[obj_loop][value_loop] = 0;

   for (inobj = obj->first_content; inobj; inobj = inobj->next_content)
   {
      if (IS_OBJ_TYPE(inobj))
      {
         found = FALSE;
         for (obj_loop = 0; obj_loop <= obj_index; obj_loop++)
         {
            if ((put_array[obj_loop][0] == inobj->pIndexData->vnum) && (put_array[obj_loop][2] == iNest))
            {
               reset_count = inobj->count + put_array[obj_loop][1];
               put_array[obj_loop][1] = reset_count;
               found = TRUE;
            }
         }
         if (!found)
         {
            reset_count = inobj->count;
            put_array[put_index][0] = inobj->pIndexData->vnum;
            put_array[put_index][1] = inobj->count;
            put_array[put_index][2] = iNest;
            put_index++;
         }
      }
      else
         reset_count = count_obj_list(get_obj_index(inobj->pIndexData->vnum), obj->first_content);

      add_obj_reset(pArea, 'P', inobj, reset_count, 0);
      if (inobj->trap)
      {
         pReset = make_reset('A', 1, obj->trap->uid, 0, 0, -1, -1, -1, -1, 0, 0);
         LINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
      }
   }
   if (cm == 'P')
      iNest--;
   return;
}

int get_reset_equiped(OBJ_DATA *obj, OBJ_DATA *fobj)
{
   int count = 0;
   
   for (; fobj; fobj = fobj->next_content)
   if (fobj->pIndexData->vnum == obj->pIndexData->vnum && fobj->wear_loc != WEAR_NONE && obj->wear_loc != WEAR_NONE)
   {
      count++;
      if (fobj->wear_loc == obj->wear_loc)
         return count;
   }
      
   return 1;
}    

int count_obj_list_inv(OBJ_INDEX_DATA * pObjIndex, OBJ_DATA * list)
{
   OBJ_DATA *obj;
   int nMatch = 0;

   for (obj = list; obj; obj = obj->next_content)
   {
      if (obj->pIndexData == pObjIndex && obj->wear_loc == WEAR_NONE)
      {
         if (obj->count > 1)
            nMatch += obj->count;
         else
            nMatch++;
      }
   }

   return nMatch;
}

void instaroom(CHAR_DATA * ch, AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, bool dodoors, bool allmap)
{
   CHAR_DATA *rch;
   OBJ_DATA *obj;
   RESET_DATA *reset;
   int obj_loop, value_loop, reset_count;
   int count;
   int x;
   bool found;

   for (rch = pRoom->first_person; rch; rch = rch->next_in_room)
   {
      if (!IS_NPC(rch))
         continue;

      if (pRoom->vnum == OVERLAND_SOLAN)
         if (allmap == FALSE)
            if ((rch->coord->x != ch->coord->x) || (rch->coord->y != ch->coord->y) || (rch->map != ch->map))
               continue;
      /* Updates the Mob count according to the current mob list, will Make sure mobs go up in
         ascending order..1, 2, 3, 4, 5, etc -- Xerves */

      reset_count = fmob_count(pArea, rch->pIndexData->vnum);
      reset = add_reset(pArea, 'M', 1, rch->pIndexData->vnum, 1, pRoom->vnum, rch->coord->x, rch->coord->y, rch->map, -1, 0, 0);
      reset->serial = rch->serial;
      serial_list[reset->serial] = TRUE;


      obj_index = 0;
      reset_count = 0;
      for (obj_loop = 0; obj_loop < MAX_OBJ; obj_loop++)
         for (value_loop = 0; value_loop < 2; value_loop++)
            obj_array[obj_loop][value_loop] = 0;

      for (obj = rch->first_carrying; obj; obj = obj->next_content)
      {
         if (obj->wear_loc == WEAR_NONE)
         {
            if (IS_OBJ_TYPE(obj))
            {
               found = FALSE;
               for (obj_loop = 0; obj_loop <= obj_index; obj_loop++)
               {
                  if (obj_array[obj_loop][0] == obj->pIndexData->vnum)
                  {
                     reset_count = obj->count + obj_array[obj_loop][1];
                     obj_array[obj_loop][1] = reset_count;
                     found = TRUE;
                  }
               }
               if (!found)
               {
                  reset_count = obj->count;
                  obj_array[obj_index][0] = obj->pIndexData->vnum;
                  obj_array[obj_index][1] = obj->count;
                  obj_index++;
               }
            }
            else
               reset_count = count_obj_list_inv(get_obj_index(obj->pIndexData->vnum), rch->first_carrying);
            put_index = 0;
            count = obj->count;
            for (x = 1; x <= count; x++)
               add_obj_reset(pArea, 'G', obj, reset_count, 0);
         }
         else
         {
            reset_count = get_reset_equiped(obj, rch->first_carrying);
            add_obj_reset(pArea, 'E', obj, reset_count, obj->wear_loc);
         }
      }
   }

   obj_index = 0;
   reset_count = 0;
   for (obj_loop = 0; obj_loop < MAX_OBJ; obj_loop++)
      for (value_loop = 0; value_loop < 2; value_loop++)
         obj_array[obj_loop][value_loop] = 0;

   for (obj = pRoom->first_content; obj; obj = obj->next_content)
   {
      if (IS_OBJ_TYPE(obj))
      {
         found = FALSE;
         for (obj_loop = 0; obj_loop <= obj_index; obj_loop++)
         {
            if (obj_array[obj_loop][0] == obj->pIndexData->vnum)
            {
               reset_count = obj->count + obj_array[obj_loop][1];
               obj_array[obj_loop][1] = reset_count;
               found = TRUE;
            }
         }
         if (!found)
         {
            reset_count = obj->count;
            obj_array[obj_index][0] = obj->pIndexData->vnum;
            obj_array[obj_index][1] = obj->count;
            obj_index++;
         }
      }
      else
         reset_count = count_obj_list(get_obj_index(obj->pIndexData->vnum), pRoom->first_content);

      if (pRoom->vnum == OVERLAND_SOLAN)
         if (allmap == FALSE)
            if ((obj->coord->x != ch->coord->x) || (obj->coord->y != ch->coord->y) || (obj->map != ch->map))
               continue;
      put_index = 0;
      add_obj_reset(pArea, 'O', obj, reset_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, -1, -1, -1, -1, 0, 0);
      }
   }
   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 wipe_map_resets(CHAR_DATA * ch, AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, int x, int y, int map)
{
   RESET_DATA *pReset;
   RESET_DATA *prev;

   for (pReset = pArea->first_reset; pReset;)
   {
      if (pReset->command == 'M' || pReset->command == 'O')
      {
         if ((pReset->arg4 == ch->coord->x) && (pReset->arg5 == ch->coord->y) && (pReset->arg6 == ch->map))
         {
            prev = pReset->prev;
            delete_reset(pArea, pReset);
            pReset = (prev ? prev->next : pArea->first_reset);
         }
         else
         {
            pReset = pReset->next;
         }
      }
      else
      {
         pReset = pReset->next;
      }
   }
   return;
}

void do_instaroom(CHAR_DATA * ch, char *argument)
{
   AREA_DATA *pArea;
   ROOM_INDEX_DATA *pRoom;
   bool dodoors;
   bool allmap = FALSE;
   char arg[MIL];
   int x, y, map;

   if (IS_NPC(ch) || get_trust(ch) < LEVEL_IMM || !ch->pcdata || /* Tracker1 */
      !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;
   if (!str_cmp(argument, "allmap"))
      allmap = 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_mapmodify(ch, pRoom))
      return;
   if (pRoom->area != pArea && get_trust(ch) < LEVEL_STAFF) /* Tracker1 */
   {
      send_to_char("You cannot reset that room.\n\r", ch);
      return;
   }
   /* Defaults only to change the coords, will not add an actual reset */
   if (pRoom->vnum == OVERLAND_SOLAN)
   {
      if (allmap == FALSE)
      {
         x = ch->coord->x;
         y = ch->coord->y;
         map = ch->map;
         wipe_map_resets(ch, pArea, pRoom, x, y, map);
         instaroom(ch, pArea, pRoom, FALSE, allmap);
         send_to_char("Mob coords changed (instaroom allmap to add resets to Wilderness).\n\r", ch);
         return;
      }
   }
   if (pArea->first_reset)
      wipe_resets(pArea, pRoom);
   instaroom(ch, pArea, pRoom, dodoors, allmap);
   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_IMM || !ch->pcdata || /* Tracker1 */
      !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(ch, pArea, pRoom, dodoors, 1);
   }
   send_to_char("Area resets installed.\n\r", ch);
   return;
}

int generate_itemlevel(AREA_DATA * pArea, OBJ_INDEX_DATA * pObjIndex)
{
   return 1;
}

int mob_in_area_count(int mvnum, int count, int vnum)
{
   CHAR_DATA *victim;
   AREA_DATA *tarea;
   int cnt = 0;
   
   for (tarea = first_area; tarea; tarea = tarea->next)
   {
       if (vnum >= tarea->low_r_vnum && vnum <= tarea->hi_r_vnum)
          break;
   }
   if (!tarea)
   {
      for (tarea = first_build; tarea; tarea = tarea->next)
      {
         if (vnum >= tarea->low_r_vnum && vnum <= tarea->hi_r_vnum)
            break;
      }
   }     
   if (!tarea)
   {
      bug("mob_in_area_count:  Could not find the area for some reason, vnum %d", vnum);
      return FALSE;
   }
   for (victim = first_char; victim; victim = victim->next)
   {
      if (IS_NPC(victim) && victim->pIndexData->vnum == mvnum)
         if (victim->in_room->area == tarea)
         {
            cnt++;  
            if (count <= cnt)
               break;
         }
   }
   if (count <= cnt)
      return FALSE;
   else
      return TRUE;
}

int count_obj_list_eq(OBJ_INDEX_DATA * pObjIndex, OBJ_DATA * list)
{
   OBJ_DATA *obj;
   int nMatch = 0;

   for (obj = list; obj; obj = obj->next_content)
   {
      if (obj->pIndexData == pObjIndex && obj->wear_loc != WEAR_NONE)
      {
         if (obj->count > 1)
            nMatch += obj->count;
         else
            nMatch++;
      }
   }

   return nMatch;
}

/*
 * Reset one area.
 */

//ttype 0 - Regular area reset 1 - Time check reset
void reset_area(AREA_DATA * pArea, int ttype)
{
   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;
   SLAB_DATA *slab;
   EXIT_DATA *pexit;
   OBJ_DATA *to_obj;
   int fvnum;
   int crace = 0;
   char buf[MSL];
   int level = 0;
   int race;
   int currentserial;
   int change = 0;
   void *plc = NULL;
   int timemob = 0;
   bool ext_bv = FALSE;
   TRAP_DATA *trap;

   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", pArea->filename);
      return;
   }
   level = 0;
   for (pReset = pArea->first_reset; pReset; pReset = pReset->next)
   {
      if (ttype == 1)
      {
         if (timemob && pReset->command != 'G' && pReset->command != 'E')
            timemob = 0;
         if (!timemob && pReset->resettime <= 0 && pReset->resetlast <= 0)
            continue;
         if (!timemob && pReset->resetlast + pReset->resettime > time(0))
            continue; 
      }
      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 (pReset->resettime > 0 && pReset->resetlast > 0)
            {
               if (pReset->resetlast + pReset->resettime > time(0))
               {
                  mob = NULL;
                  break;
               }
            }
            if (pReset->serial == 0)
            {
               mob = create_mobile(pMobIndex);
               pReset->serial = serialmobsloaded;
               serial_list[pReset->serial] = TRUE;
            }
            else
            {
               if (serial_list[pReset->serial] == FALSE)
               {
                  currentserial = serialmobsloaded;
                  serialmobsloaded = pReset->serial-1;
                  mob = create_mobile(pMobIndex);
                  serialmobsloaded = currentserial;
                  serial_list[pReset->serial] = TRUE;
               }
               else
               {
                  mob = NULL;
                  break;
               }
            }               
            if (pReset->resettime == -1)
               xSET_BIT(mob->act, ACT_NORESET);
            if (pReset->resettime > 0)
               xSET_BIT(mob->act, ACT_TIMERESET); 
         /*   if (!mob_in_area_count(pMobIndex->vnum, pReset->arg2, pReset->arg3))
            {
               mob = NULL;
               break;
            }*/
            {
               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 (pRoomPrev && xIS_SET(pRoomPrev->room_flags, ROOM_MOUNT_SHOP))
                  xSET_BIT(mob->act, ACT_MOUNTSAVE);
            }
            if (room_is_dark(pRoomIndex))
               xSET_BIT(mob->affected_by, AFF_INFRARED);
            char_to_room(mob, pRoomIndex);
            economize_mobgold(mob);
            level = 0;
            if (pRoomIndex->vnum == OVERLAND_SOLAN)
            {
               mob->coord->x = pReset->arg4;
               mob->coord->y = pReset->arg5;
               mob->map = pReset->arg6;
               SET_ONMAP_FLAG(mob);
            }
            if (ttype == 1)
               timemob = 1;
            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 (pReset->resettime > 0 && pReset->resetlast > 0)
            {
               if (pReset->resetlast + pReset->resettime > time(0))
               {
                  obj = NULL;
                  lastobj = NULL;
                  break;
               }
            }
            if ((pReset->command == 'G' && count_obj_list_inv(pObjIndex, mob->first_carrying) >= pReset->arg2)
            ||  (pReset->command == 'E' && count_obj_list_eq(pObjIndex, mob->first_carrying) >= pReset->arg2))
            {
               obj = NULL;
               lastobj = NULL;
               break;
            }
            if (mob->pIndexData->pShop)
            {
               int olevel = generate_itemlevel(pArea, pObjIndex);

               obj = create_object(pObjIndex, olevel);
               if (!xIS_SET(mob->act, ACT_CASTEMOB))
                  xSET_BIT(obj->extra_flags, ITEM_INVENTORY);
            }
            else
            {
               obj = create_object(pObjIndex, 1);
            }
            if (pReset->resettime == -1)
               xSET_BIT(obj->extra_flags, ITEM_NORESET);
            if (pReset->resettime > 0)
               xSET_BIT(obj->extra_flags, ITEM_TIMERESET); 
            obj->level = 0;
            /*       obj->count = (pReset->arg2 - count_obj_list(pObjIndex, mob->first_carrying)); */
            obj = obj_to_char(obj, mob);
            if (pReset->command == 'E')
               fvnum = pReset->arg4;
            else
               fvnum = pReset->arg3;
            if (fvnum > 100)
            {
               OBJ_DATA *oslab;
               for (slab = first_slab; slab; slab = slab->next)
               {
                  if (slab->vnum == fvnum)
                     break;
               }
               if (!slab)
               {
                  bug("%s Reset_area: 'G' or 'E': bad slab vnum %d.", pArea->filename, fvnum);
               }
               else
               {         
                  race = mob->race;
                  if (mob->race < 0 || mob->race >= MAX_RACE)
                     mob->race = 0; //Needs a valid race      
                  if (pReset->command == 'G' && pReset->arg4 > 0)
                  {
                     mob->race = pReset->arg4-1;
                     crace = pReset->arg4;
                  }
                  oslab = create_object(get_obj_index(slab->vnum), 1);
                  alter_forge_obj(mob, obj, oslab, slab);	
                  extract_obj(oslab);
                  obj->value[6] = fvnum;
                  obj->value[11] = crace;
                  mob->race = race;
               }
            }               
            if (pReset->command == 'E')
               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 (pReset->resettime > 0 && pReset->resetlast > 0)
            {
               if (pReset->resetlast + pReset->resettime > time(0))
               {
                  obj = NULL;
                  lastobj = NULL;
                  break;
               }
            }
            /* With objects it is important to load only the amount alouted the that obj */
            if ((count_obj_list(pObjIndex, pRoomIndex->first_content) >= pReset->arg2))
            {
               obj = NULL;
               lastobj = NULL;
               break;
            }
            obj = create_object(pObjIndex, 1);
            if (pReset->resettime == -1)
               xSET_BIT(obj->extra_flags, ITEM_NORESET);
            if (pReset->resettime > 0)
               xSET_BIT(obj->extra_flags, ITEM_TIMERESET);
            obj->level = 0;
/*      obj->count = ( pReset->arg2 - count_obj_list(pObjIndex, pRoomIndex->first_content)); */
            if (pRoomIndex->vnum == OVERLAND_SOLAN) // Make sure it doesn't group -- Xerves
            {
               obj->coord->x = pReset->arg4;
               obj->coord->y = pReset->arg5;
               obj->map = pReset->arg6;
               SET_OBJ_STAT(obj, ITEM_ONMAP);
            }
            obj_to_room(obj, pRoomIndex, NULL);
            if (pRoomIndex->vnum == OVERLAND_SOLAN) // Put the values back in after obj_to_room -- Xerves
            {
               obj->coord->x = pReset->arg4;
               obj->coord->y = pReset->arg5;
               obj->map = pReset->arg6;
               SET_OBJ_STAT(obj, ITEM_ONMAP);
            }
            if (pReset->arg7 > 100)
            {
               for (slab = first_slab; slab; slab = slab->next)
               {
                  if (slab->vnum == pReset->arg7)
                     break;
               }
               if (!slab)
               {
                  bug("%s Reset_area: 'G' or 'E': bad slab vnum %d.", pArea->filename, pReset->arg7);
               }
               else
               {         
                  race = mob->race;
                  if (mob->race < 0 || mob->race >= MAX_RACE)
                     mob->race = 0; //Needs a valid race      
                  alter_forge_obj(mob, obj, create_object(get_obj_index(slab->vnum), 1), slab);	
                  obj->value[6] = pReset->arg7;
                  mob->race = race;
               }
            }  
            lastobj = obj;
            break;

         //New Trap format, store only the uid here.
         case 'A': 
            for (trap = first_trap; trap; trap = trap->next)
            {
               if (trap->uid == pReset->arg1)
                  break;
            }
            if (!trap)
            {
               bug("%s Reset_area: 'A': bad trap uid of %d", pArea->filename, pReset->arg1);
               continue;
            }
            if (trap->resetvalue > 0)
            {
               trap->charges = trap->maxcharges;
            }
            if (!lastobj)
               continue;
            if (lastobj->trap)
               continue;
            if (trap->obj)
               continue;
            lastobj->trap = trap;
            trap->obj = lastobj;
            trap->area = pArea;
            trap->charges = trap->maxcharges;
            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 (pReset->resettime > 0 && pReset->resetlast > 0)
               {
                  if (pReset->resetlast + pReset->resettime > time(0))
                  {
                     obj = NULL;
                     break;
                  }
               }    
               if (pArea->nplayer > 0
                  || !(to_obj = get_obj_type(pObjToIndex)) || !to_obj->in_room || (count_obj_list(pObjIndex, to_obj->first_content) >= pReset->arg2))
               {
                  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, 1);
            if (pReset->resettime == -1)
               xSET_BIT(obj->extra_flags, ITEM_NORESET);
            if (pReset->resettime > 0)
               xSET_BIT(obj->extra_flags, ITEM_TIMERESET);
            obj->level = 0;
            /*   obj->count = ( pReset->arg2 - count_obj_list(pObjIndex, to_obj->first_content));   */
            obj_to_obj(obj, to_obj);
            if (pReset->arg4 > 100)
            {
               for (slab = first_slab; slab; slab = slab->next)
               {
                  if (slab->vnum == pReset->arg4)
                     break;
               }
               if (!slab)
               {
                  bug("%s Reset_area: 'P': bad slab vnum %d.", pArea->filename, pReset->arg4);
               }
               else
               {         
                  race = mob->race;
                  if (mob->race < 0 || mob->race >= MAX_RACE)
                     mob->race = 0; //Needs a valid race      
                  alter_forge_obj(mob, obj, create_object(get_obj_index(slab->vnum), 1), slab);	
                  obj->value[6] = pReset->arg4;
                  mob->race = race;
               }
            }    
            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, 1, 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;
      }
   }
   if (change == 1)
      fold_area(pArea, pArea->filename, FALSE, 1); 
   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 time[256];
   char *pbuf;
   int sec, hour, min, days, rtime;
   TRAP_DATA *trap;

   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, "%s%3d) ", char_color_str(AT_PURPLE, ch), num);
      pbuf = buf + strlen(buf);
      
      if (pReset->resettime > 0)
      {
         if (pReset->resettime > 86400)
         {
            days = pReset->resettime / 86400;
            rtime = pReset->resettime % 86400;
         }
         else
         {
            days = 0;
            rtime = pReset->resettime;
         }
         sec = rtime % 60;
         hour = rtime / 3600;
         if (rtime > 60)
         {
            min = rtime / 60;
            min = min % 60;
         }
         else
         {
            min = 0;
         }
         sprintf(time, "D:%d H:%d M:%d S:%d", days, hour, min, sec);
      }
      if (pReset->resettime == -1)
         sprintf(time, "*****ONE RESET*****");
      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;
            if (pReset->resettime > 0 || pReset->resettime == -1)
               sprintf(pbuf, "%s%s (%d) -> %s (%d) (%d %d %d) [%d] &w&W<%s>", char_color_str(AT_GREEN, ch), mname, pReset->arg1, rname,
                  pReset->arg3, pReset->arg4, pReset->arg5, pReset->arg6, pReset->serial, time);
            else
               sprintf(pbuf, "%s%s (%d) -> %s (%d) (%d %d %d) [%d]", char_color_str(AT_GREEN, ch), mname, pReset->arg1, rname,
                  pReset->arg3, pReset->arg4, pReset->arg5, pReset->arg6, pReset->serial);
            
            if (!room)
               mob = NULL;
            if ((room = get_room_index(pReset->arg3 - 1)) && xIS_SET(room->room_flags, ROOM_PET_SHOP))
               strcat(buf, "&w&c (pet)\n\r");
            else if ((room = get_room_index(pReset->arg3 - 1)) && xIS_SET(room->room_flags, ROOM_MOUNT_SHOP))
               strcat(buf, "&w&C (mount)\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;
            if (pReset->resettime > 0 || pReset->resettime == -1)
               sprintf(pbuf, "%s%s (%d) -> %s (%s) [%d] &w&W<%s>", pReset->command == 'G' ? char_color_str(AT_ORANGE, ch) : char_color_str(AT_YELLOW, ch),
                  oname, pReset->arg1, mname, (pReset->command == 'G' ? "carry" : wear_locs[pReset->arg3]), pReset->arg2, time);
            else
               sprintf(pbuf, "%s%s (%d) -> %s (%s) [%d]", pReset->command == 'G' ? char_color_str(AT_ORANGE, ch) : char_color_str(AT_YELLOW, ch), 
                  oname, pReset->arg1, mname, (pReset->command == 'G' ? "carry" : wear_locs[pReset->arg3]), pReset->arg2);
            if (mob && mob->pShop)
               strcat(buf, "&w&R (shop)\n\r");
            else
               strcat(buf, "\n\r");
            lastobj = obj;
            lo_reset = pReset;
            break;
         case 'A':
            for (trap = first_trap; trap; trap = trap->next)
            {
               if (trap->uid == pReset->arg1)
                  break;
            }
            if (!trap)
               sprintf(pbuf, "*INVALID TRAP UID*\n\r");
            else
               sprintf(pbuf, "%s(TRAP) %d uid %d lowdam %d hidam\n\r", char_color_str(AT_RED, ch), trap->uid, trap->damlow, trap->damhigh);
            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;
            if (pReset->resettime > 0 || pReset->resettime == -1)
               sprintf(pbuf, "%s(object) %s (%d) -> %s (%d) (%d %d %d) [%d] &w&W<%s>\n\r", char_color_str(AT_PINK, ch), oname,
                  pReset->arg1, rname, pReset->arg3, pReset->arg4, pReset->arg5, pReset->arg6, pReset->arg2, time);
            else
               sprintf(pbuf, "%s(object) %s (%d) -> %s (%d) (%d %d %d) [%d]\n\r", char_color_str(AT_PINK, ch), oname,
                  pReset->arg1, rname, pReset->arg3, pReset->arg4, pReset->arg5, pReset->arg6, 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 && (get_obj_index(reset->arg1)->item_type == ITEM_CONTAINER)))
                        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;
            }
            if (pReset->resettime > 0 || pReset->resettime == -1)
               sprintf(pbuf, "%s(Put) %s (%d) -> %s (%d) [%d] {nest %d} &w&W<%s>\n\r", char_color_str(AT_DGREEN, ch), oname,
                  pReset->arg1, rname, (obj2 ? obj2->vnum : pReset->arg3), pReset->arg2, pReset->extra, time);
            else  
               sprintf(pbuf, "%s(Put) %s (%d) -> %s (%d) [%d] {nest %d}\n\r", char_color_str(AT_DGREEN, ch), oname,
                  pReset->arg1, rname, (obj2 ? obj2->vnum : pReset->arg3), pReset->arg2, pReset->extra);
            break;
         case 'T':
            sprintf(pbuf, "%sTRAP: %d %d %d %d (%s)\n\r", char_color_str(AT_BLOOD, ch), 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, "%sHide %s (%d)\n\r", char_color_str(AT_DGREY, ch), 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%s [%d] the %s%s [%d] door %s (%d)\n\r", char_color_str(AT_GREY, ch), 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, "%sRandomize exits 0 to %d -> %s (%d)\n\r", char_color_str(AT_BLUE, ch), 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;
   OBJ_INDEX_DATA *putobj;

   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
               {
                  if ((putobj = get_obj_index(lastobj->arg1)) != NULL)
                  {
                     if ((putobj->item_type == ITEM_CONTAINER) || (putobj->item_type == ITEM_FURNITURE) || (putobj->item_type == ITEM_QUIVER))
                        pReset->extra = lastobj->extra + 1;
                     else
                        pReset->extra = UMAX((lastobj->extra - 1), 0);
                  }
               }
               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, int arg4, int arg5, int arg6, int arg7, int resetlast, int resettime)
{
   RESET_DATA *pReset;

   CREATE(pReset, RESET_DATA, 1);
   pReset->command = letter;
   pReset->extra = extra;
   pReset->arg1 = arg1;
   pReset->arg2 = arg2;
   pReset->arg3 = arg3;
   pReset->arg4 = arg4;
   pReset->arg5 = arg5;
   pReset->arg6 = arg6;
   pReset->arg7 = arg7;
   pReset->resetlast = resetlast;
   pReset->resettime = resettime;
   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, int arg4, int arg5, int arg6, int arg7, int resetlast, int resettime)
{
   RESET_DATA *pReset;

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

   letter = UPPER(letter);
   pReset = make_reset(letter, extra, arg1, arg2, arg3, arg4, arg5, arg6, arg7, resetlast, resettime);
   
   switch (letter)
   {
      case 'M':
         tarea->last_mob_reset = pReset;
         pReset->arg2 = 1;
         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, int arg4, int arg5, int arg6, int arg7, int resetlast, int resettime)
{
   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, arg4, arg5, arg6, arg7, resetlast, resettime);
   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;
}

void rsmob(AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom)
{
   CHAR_DATA *rch;
   OBJ_DATA *obj;
   RESET_DATA *reset;

   if (pArea->first_reset)
      wipe_resets(pArea, pRoom);
   for (rch = pRoom->first_person; rch; rch = rch->next_in_room)
   {
      /* Small note, Xerves screwed up here *grins* -- Xerves self-note */
      if (!IS_NPC(rch))
         continue;
      reset = add_reset(pArea, 'M', 1, rch->pIndexData->vnum, 1, pRoom->vnum, rch->coord->x, rch->coord->y, rch->map, -1, 0, 0);
      reset->serial = rch->serial;
      serial_list[reset->serial] = TRUE;
      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);
         }
      }
   }
   return;
}

void kupkeep(AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom)
{
   CHAR_DATA *rch;
   OBJ_DATA *obj;
   RESET_DATA *reset;

   if (pArea->first_reset)
      wipe_resets(pArea, pRoom);
   for (rch = pRoom->first_person; rch; rch = rch->next_in_room)
   {
      /* Small note, Xerves screwed up here *grins* -- Xerves self-note */
      if (!IS_NPC(rch))
         continue;
      if (!xIS_SET(rch->act, ACT_CASTEMOB))
         continue;
      reset = add_reset(pArea, 'M', 1, rch->pIndexData->vnum, 1, pRoom->vnum, rch->coord->x, rch->coord->y, rch->map, -1, 0, 0);
      reset->serial = rch->serial;
      serial_list[reset->serial] = TRUE;
      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);
         }
      }
   }
   return;
}

void do_resetkeeper(CHAR_DATA * ch, char *argument)
{
   AREA_DATA *pArea;
   ROOM_INDEX_DATA *pRoom;
   char arg[MIL];

   if (IS_NPC(ch))
   {
      send_to_char("Mobs cannot reset other mobs.  Sorry :-)\n\r", ch);
      return;
   }
   if (!ch->pcdata || !ch->pcdata->keeper || (ch->pcdata->caste < 7))
   {
      send_to_char("You need to have a shop keeper to reset him/her.\n\r", ch);
      return;
   }
   argument = one_argument(argument, arg);
   if (!(pRoom = find_room(ch, arg, NULL)))
   {
      send_to_char("Room doesn't exsist.\n\r", ch);
      return;
   }
   pArea = pRoom->area;
   if (!can_kmodify(ch, pRoom))
      return;
   if (pRoom->vnum != ch->pcdata->keeper) /* Tracker1 */
   {
      send_to_char("You cannot reset that room.\n\r", ch);
      return;
   }
   if (pArea->first_reset)
      wipe_resets(pArea, pRoom);
   resetkeeper(pArea, pRoom, FALSE);
   send_to_char("ShopKeeper is Reset.\n\r", ch);
}

bool can_kmodify(CHAR_DATA * ch, ROOM_INDEX_DATA * room)
{
   sh_int vnum = room->vnum;

   if (IS_NPC(ch))
      return FALSE;
   if (!xIS_SET(room->room_flags, ROOM_PROTOTYPE))
   {
      send_to_char("You cannot modify this room.\n\r", ch);
      return FALSE;
   }
   if (!ch->pcdata || !(ch->pcdata->keeper))
   {
      send_to_char("You must have an assigned shop keeper to modify him/her.\n\r", ch);
      return FALSE;
   }
   if (vnum == ch->pcdata->keeper)
      return TRUE;

   send_to_char("What are you trying to modify?\n\r", ch);
   return FALSE;
}

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

   for (rch = pRoom->first_person; rch; rch = rch->next_in_room)
   {
      if (!IS_NPC(rch) || !xIS_SET(rch->act, ACT_CASTEMOB))
         continue;
      reset = add_reset(pArea, 'M', 1, rch->pIndexData->vnum, 1, pRoom->vnum, rch->coord->x, rch->coord->y, rch->map, -1, 0, 0);
      reset->serial = rch->serial;
      serial_list[reset->serial] = TRUE;
      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);
      }
   }
   fdarea(rch, pArea->filename);
   return;
}