/
roa/
roa/lib/boards/
roa/lib/config/
roa/lib/edits/
roa/lib/help/
roa/lib/misc/
roa/lib/plrobjs/
roa/lib/quests/
roa/lib/socials/
roa/lib/www/
roa/lib/www/LEDSign/
roa/lib/www/LEDSign/fonts/
roa/lib/www/LEDSign/scripts/
roa/src/s_inc/
roa/src/sclient/
roa/src/sclient/binary/
roa/src/sclient/text/
roa/src/util/
/************************************************************************
Realms of Aurealis 		James Rhone aka Vall of RoA

wiz.c				Code dealing with various immortal commands
				and utilities.

		******** Heavily modified and expanded ********
		*** BE AWARE OF ALL RIGHTS AND RESERVATIONS ***
		******** Heavily modified and expanded ********
		        All rights reserved henceforth. 

    Please note that no guarantees are associated with any code from
Realms of Aurealis.  All code which has been released to the general
public has been done so with an 'as is' pretense.  RoA is based on both
Diku and CircleMUD and ALL licenses from both *MUST* be adhered to as well
as the RoA license.   *** Read, Learn, Understand, Improve ***
*************************************************************************/
#include "conf.h"
#include "sysdep.h"

#include <signal.h>

#include "structures.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "acmd.h"
#include "handler.h"
#include "db.h"
#include "magic.h"
#include "mudlimits.h"
#include "screen.h"
#include "affect.h"
#include "lists.h"
#include "objsave.h"
#include "shaman.h"
#include "global.h"
#include "roaolc.h"
#include "htown.h"
#include "clicomm.h"
#include "exshell.h"
#include "darkenelf.h"

/*   external vars  */
extern struct player_index_element *player_table;
extern FILE *player_fl;
extern struct chart_type mob_chart[MAX_LEVELS];
extern int	restrict;
extern char	zlock_reset;
extern int	zone_levels[];
extern int	exp_table[NUM_CLASSES][MAX_LEVELS];
extern struct htown_data htowns[];

/* for objects */
extern char	*item_types[];
extern char     *grant_bits[];
extern char	*wear_bits[];
extern char	*extra_bits[];
extern char	*extra_bits2[];
extern char	*drinks[];

/* for rooms */
extern char	*dirs[];
extern char	*room_bits[];
extern char	*room_bits2[];
extern char	*exit_bits[];
extern char	*terrain_types[];
extern char	*alter_types[];
extern char *precip_names[];
extern char *precip_names_ing[];
extern char	*zone_bits[];

/* for chars */
extern char	*where[];
extern char	*affected_bits[];
extern char	*affected2_bits[];
extern char	*char_bits[];
extern char	*spc_bits[];
extern char	*mob2_bits[];
extern char	*apply_types[];
extern char	*npc_class_names[];
extern char	*size_types[];
extern char	*action_bits[];
extern char	*player_bits[];
extern char	*player2_bits[];
extern char	*preference_bits[];
extern char	*class_abbrevs[];
extern char	*preference2_bits[];
extern char	*position_types[];
extern char	*clpid_bits[];

/* external functs */
void	reset_roazone(int zone);
int 	purge_zone(int zone);
char	*get_name_by_id(long idnum);
int 	is_empty(int zone);
void 	free_room_affects(struct room_affect_type *head);
int	IdListMember(IdList * member, long idnum);
int 	get_command(char *comm);

// allow imps to restart router  8/4/98 -jtrhone
ACMD(do_restartrouter)
{
  if (cli_router_pid > 0)
  {
    sprintf(buf, "Killing cli_router %d.\n\r", cli_router_pid);
    S2C();
    kill(cli_router_pid, SIGTERM);
  }
  else
    start_cli_router();
}

// allow imps to record and playback commands for debugging purposes...
ACMD(do_record)
{
  if (IS_NPC(ch)) return;

  if (CHAR_FLAGGED(ch, CH_PLAYBACK))
  {
    send_to_char("You cannot record while in playback mode.\n\r",ch);
    return;
  }

  if (CHAR_FLAGGED(ch, CH_RECORD))
  {
    fclose(ch->fp);
    ch->fp = NULL;
    REMOVE_BIT(CHAR_FLAGS(ch), CH_RECORD);
    send_to_char("%B%7Finished Recording...%0\n\r",ch);
    return;
  }

  // construct file name
  sprintf(buf, "misc/%s.rec", GET_NAME(ch));

  // open file pointer
  if (!(ch->fp = fopen(buf, "wt")))
  {
    send_to_char("Error opening file.\n\r",ch);
    return;
  }

  // now set flag
  SET_BIT(CHAR_FLAGS(ch), CH_RECORD);
  send_to_char("%B%1Recording...%0\n\r",ch);
}

// actually open file, read and do commands...
void playback_file(chdata *ch)
{
  FILE *fp;
  char buf[MAX_STRING_LENGTH];

  // construct file name
  sprintf(buf, "misc/%s.rec", GET_NAME(ch));

  // open file pointer
  if (!(fp = fopen(buf, "rt")))
  {
    send_to_char("Error opening file.\n\r",ch);
    return;
  }

  while (fgets(buf, 120, fp))
  {
    // skip newline...
    if (*buf)
      buf[strlen(buf)-1] = '\0';
    S2C();
    send_to_char("\n\r",ch);
    command_interpreter(ch, buf);
  }

  fclose(fp);
}

ACMD(do_playback)
{
  char *argu = argument;
  int num;

  if (IS_NPC(ch)) return;

  skip_spaces(&argu);
  if (!*argu)
  {
    playback_file(ch);
    send_to_char("%B%7Playback Complete.%0\n\r",ch);
    return;
  }

  num = atoi(argu);
  num = MIN(100, MAX(1,num));

  while (num > 0)
  {
    num--;
    playback_file(ch);
  }

  send_to_char("%B%7Playback Complete.%0\n\r",ch);
}

// allows builders to set their trap level for setting traps while building
// 4/26/98 -jtrhone
ACMD(do_traplevel)
{
  char *argu = argument;
  int num;

  if (IS_NPC(ch))
    return;

  skip_spaces(&argu);
  if (!*argu)
  {
    sprintf(buf, "Current traplevel: %d.\n\r", GET_TRAP_LEVEL(ch));
    S2C();
    return;
  }

  if (!is_number(argu))
  {
    send_to_char("Usage: traplevel < level >.\n\r",ch);
    return;
  }

  num = atoi(argu);
  if (num < 1 || num >= LEV_IMM)
  {
    sprintf(buf, "Traplevel must be in range from 1 - %d.\n\r",LEV_IMM);
    S2C();
    return;
  }

  ch->specials.traplevel = num;
  sprintf(buf, "Traplevel set to %d.\n\r", num);
  S2C();
}

// Allows immortals to be selectively invisible. 03/20/98 -callahan
ACMD(do_conceal)
{
  CharFileU tch;
  IdList *con, *temp;
  int sortpos = 0, count = 0;
  extern char *num_to_word[];
      
  *buf = '\0';
  *buf2 = '\0';

  one_argument(argument, arg);
   
  if (!*arg) {
    send_to_char("%6You are currently concealed from:%0\r\n", ch);
  
    if (!ch->concealed)
      send_to_char("  No-one.\r\n", ch);
    else {
      for (con = ch->concealed; con; con = con->next) {
        strcpy(buf2, get_name_by_id(con->idnum));
        sprintf(buf, "%s%-12.12s", buf, CAP(buf2));
        sortpos++;
        count++;   
  
        if (sortpos == 6) {  
          sortpos = 0;
          strcat(buf, "\r\n");
        }
      }
      send_to_char(tprintf("%s\r\n%%6Total:%%0 %s\r\n", buf,
                           num_to_word[count]), ch);
    }
    return;
  }
  if (load_char(arg, &tch) < 0) {
    send_to_char("There is no such player.\r\n", ch);
    return;
  }
  if (!strcmp(Name(ch), tch.name)) {
    send_to_char("You cannot be concealed from yourself!\r\n", ch);
    return;
  }
  for (con = ch->concealed; con; con = con->next)
    if (tch.saved.idnum == con->idnum)
      break;
          
  if (!con) {
    if (Shade(ch) && (tch.level < Level(ch))) {
      strcpy(buf2, tch.name);
      send_to_char(tprintf("You are now concealed from %s.\r\n", CAP(buf2)),
                   ch);

      CREATE(con, IdList, 1);
      con->idnum = tch.saved.idnum;
      con->next = ch->concealed;
      ch->concealed = con;

      if (IdListMember(ch->revealed, con->idnum))
        do_reveal(ch, tch.name, 0, 0);
    
    } else
      send_to_char(tprintf("You are not powerful enough to be concealed from "
                           "%s!\r\n", tch.name), ch);
    return;
  }
      
  // Remove from conceal list
  send_to_char(tprintf("You are no longer concealed from %s.\r\n", tch.name), ch);
  REMOVE_FROM_LIST(con, ch->concealed, next);

  FREENULL(con);
  return;
}

// Allows immortals to be selectively visible. 03/20/98 -callahan
ACMD(do_reveal)
{
  CharFileU tch;
  IdList *rev, *temp;
  int sortpos = 0, count = 0;
  extern char *num_to_word[];
      
  *buf = '\0';
  *buf2 = '\0';

  one_argument(argument, arg);
   
  if (!*arg) {
    send_to_char("%6You are currently revealed to:%0\r\n", ch);
  
    if (!ch->revealed)
      send_to_char("  No-one.\r\n", ch);
    else {
      for (rev = ch->revealed; rev; rev = rev->next) {
        strcpy(buf2, get_name_by_id(rev->idnum));
        sprintf(buf, "%s%-12.12s", buf, CAP(buf2));
        sortpos++;
        count++;
  
        if (sortpos == 6) {  
          sortpos = 0;
          strcat(buf, "\r\n");
        }
      }
      send_to_char(tprintf("%s\r\n%%6Total:%%0 %s\r\n", buf,
                           num_to_word[count]), ch);
    }
    return;
  }
  if (load_char(arg, &tch) < 0) {
    send_to_char("There is no such player.\r\n", ch);
    return;
  }
  if (!strcmp(Name(ch), tch.name)) {
    send_to_char("You can already see yourself...\r\n", ch);
    return;
  }
  for (rev = ch->revealed; rev; rev = rev->next)
    if (tch.saved.idnum == rev->idnum)
      break;
          
  if (!rev) {
    if (Shade(ch) && (tch.level < Level(ch))) {
      strcpy(buf2, tch.name);
      send_to_char(tprintf("You are now revealed to %s.\r\n", CAP(buf2)),
                   ch);

      CREATE(rev, IdList, 1);
      rev->idnum = tch.saved.idnum;
      rev->next = ch->revealed;
      ch->revealed = rev;

      if (IdListMember(ch->concealed, rev->idnum))
        do_conceal(ch, tch.name, 0, 0);
    
    } else
      send_to_char(tprintf("You are not powerful enough to be revealed to %s!\r\n", tch.name), ch);
    return;
  }

  // Remove from reveal list
  send_to_char(tprintf("You are no longer revealed to %s.\r\n", tch.name), ch);
  REMOVE_FROM_LIST(rev, ch->revealed, next);

  FREENULL(rev);
  return;
}

// show immortal list of forked client processes... 2/21/98 -jtrhone
ACMD(do_clpidlist)
{
  clpid_info *cl;
  BOOL found;

#ifndef CLIENT_FORK
  send_to_char("CLIENT_FORK not compiled into binary... clpid support disabled.\n\r",ch);
  return;
#endif

  if (IS_NPC(ch))
    return;

  strcpy(buf, "%B%6Forked Client Processes%0\n\r");
  strcat(buf, "%B%6-=-=-=-=-=-=-=-=-=-=-=-%0\n\r");
  for (cl = cl_pids; cl; cl=cl->next)
  {
    sprintbit(cl->bitvector, clpid_bits, buf2);
    sprintf(buf+strlen(buf), "%%5%d%%0 (%s) - %%5%s%%0\n\r",cl->pid, 
            cl->ch ? GET_NAME(cl->ch) : "<Unknown>", buf2);
    found = TRUE;
  } 

  if (!found)
    strcat(buf, "None.\n\r");

  page_string(ch->desc, buf, 1);
}

// basically fork off an ls
ACMD(do_soundlist)
{
  if (IS_NPC(ch) || !ch->desc)
    return;

  switch (fork()) {
    case -1:
      sprintf(buf, "SYSERR: %s soundilst forking error.", GET_NAME(ch));
      mudlog(buf, BRF, LEV_IMM, TRUE);
      break;

    case 0: // child
      // now, the child signals to get... 3/6/98 -jtrhone
      default_sigs();

      // ok, we wanna dupe our descriptor into stdin AND stdout 
      close(0);
      close(1);
      if(dup(ch->desc->descriptor) != 0 || dup(ch->desc->descriptor) != 1 )
      {
        sprintf(buf, "SYSERR: %s soundilst duping error.", GET_NAME(ch));
        mudlog(buf, BRF, LEV_IMM, TRUE);
        exit(-1);
      }
      execl("/bin/ls", "ls", "-l", "sound", (char *)0);
      break;

    default: // parent...
      break;
  }
}

// basically fork off an ls
ACMD(do_piclist)
{
  if (IS_NPC(ch) || !ch->desc)
    return;

  switch (fork()) {
    case -1:
      sprintf(buf, "SYSERR: %s piclist forking error.", GET_NAME(ch));
      mudlog(buf, BRF, LEV_IMM, TRUE);
      break;

    case 0: // child
      // now, the child signals to get... 3/6/98 -jtrhone
      default_sigs();

      // ok, we wanna dupe our descriptor into stdin AND stdout
      close(0);
      close(1);
      if(dup(ch->desc->descriptor) != 0 || dup(ch->desc->descriptor) != 1 )
      {
        sprintf(buf, "SYSERR: %s piclist duping error.", GET_NAME(ch));
        mudlog(buf, BRF, LEV_IMM, TRUE);
        exit(-1);
      }
      execl("/bin/ls", "ls", "-l", "graphics", (char *)0);
      break;

    default: // parent...
      break;
  }
}

ACMD(do_flagtog)
{
  char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
  char arg3[MAX_INPUT_LENGTH];
  chdata *vict;
  long *bitv;
  int flag;

  if (IS_NPC(ch)) return;

  half_chop(argument, arg1, arg);
  half_chop(arg, arg2, arg3);
  if (!*arg1 || !*arg2 || !*arg3)
  {
    send_to_char("Usage: flagtog < player > < bitvector > < flag >.\n\r",ch);
    return;
  }

  if (!(vict = get_char_vis(ch, arg1)))
  {
    send_to_char("Unable to locate that character.\n\r",ch);
    return;
  }
  
  if (ch != vict && GET_LEVEL(vict) >= GET_LEVEL(ch))
  {
    send_to_char("Permission denied.\n\r",ch);
    return;
  }

  if (!str_cmp(arg2, "plr"))
  {
    if (IS_NPC(vict))
    {
      send_to_char("Unable to set that bitvector on an NPC.\n\r",ch);
      return;
    }
    bitv = &PLR_FLAGS(vict);  
    if ((flag = search_block(arg3, player_bits, TRUE)) < 0)
    {
      send_to_char("Unable to locate flag.\n\r",ch);
      return;
    }
  }
  else
  if (!str_cmp(arg2, "plr2"))
  {
    if (IS_NPC(vict))
    {
      send_to_char("Unable to set that bitvector on an NPC.\n\r",ch);
      return;
    }
    bitv = &PLR2_FLAGS(vict);  
    if ((flag = search_block(arg3, player2_bits, TRUE)) < 0)
    {
      send_to_char("Unable to locate flag.\n\r",ch);
      return;
    }
  }
  else
  if (!str_cmp(arg2, "prf"))
  {
    if (IS_NPC(vict))
    {
      send_to_char("Unable to set that bitvector on an NPC.\n\r",ch);
      return;
    }
    bitv = &PRF_FLAGS(vict);  
    if ((flag = search_block(arg3, preference_bits, TRUE)) < 0)
    {
      send_to_char("Unable to locate flag.\n\r",ch);
      return;
    }
  }
  else
  if (!str_cmp(arg2, "prf2"))
  {
    if (IS_NPC(vict))
    {
      send_to_char("Unable to set that bitvector on an NPC.\n\r",ch);
      return;
    }

    bitv = &PRF2_FLAGS(vict);  
    if ((flag = search_block(arg3, preference2_bits, TRUE)) < 0)
    {
      send_to_char("Unable to locate flag.\n\r",ch);
      return;
    }
  }
  else
  if (!str_cmp(arg2, "grant"))
  {
    if (IS_NPC(vict))
    {
      send_to_char("Unable to set that bitvector on an NPC.\n\r",ch);
      return;
    }

    bitv = &GRNT_FLAGS(vict);  
    if ((flag = search_block(arg3, grant_bits, TRUE)) < 0)
    {
      send_to_char("Unable to locate flag.\n\r",ch);
      return;
    }
  }
  else
  {
    send_to_char("Unknown bitvector (prf, prf2, plr, plr2, grant).\n\r",ch);
    return;
  }

  TOGGLE_BIT(*bitv, (1 << flag));

  sprintf(buf, "Flag is now %s.\n\r", ONOFF(IS_SET(*bitv, (1 << flag))));
  S2C();
}

ACMD(do_soundsend)
{
  char *argu = argument;
  chdata *vict = NULL;
  char buf[MAX_INPUT_LENGTH];
  char buf2[MAX_INPUT_LENGTH];
  void send_soundfile_to_client(dsdata *d, char *sname);

  skip_spaces(&argu);
  if (!*argu)
  {
    send_to_char("Usage: soundsend <plrname> <sound file>.\n\r",ch);
    return;
  }

  half_chop(argu, buf, buf2);
  if (!*buf2)
  {
    send_to_char("Usage: soundsend <plrname> <sound file>.\n\r",ch);
    return;
  }

  if (!(vict = get_char_vis(ch, buf)))
  {
    send_to_char("Target not found.\n\r",ch);
    return;
  }

  if (!HAS_CLIENT(vict->desc))
  {
    send_to_char("Victim doesn't have client connection.\n\r",ch);
    return;
  }

  if (!IS_AIMP(ch))
    if (!IS_IMMORTAL(vict))
    {
      send_to_char("You cannot soundsend to mortals.\n\r",ch);
      return;
    }

  if (GET_LEVEL(ch) < GET_LEVEL(vict))
  {
    send_to_char("Access denied.\n\r",ch);
    return;
  }

  send_soundfile_to_client(vict->desc, buf2);
  send_to_char("Ok.\n\r",ch);
}

ACMD(do_goldfix)
{
  int i;
  obdata *obj;
  chdata *mob;

  send_to_char("Hard code removal required to do this again.  -Vall\n\r",ch);
  return;

  for (i = 0; i < top_of_objt; i++)
  {
    obj = &obj_proto[i];
    obj->cost -= (int)(obj->cost * 0.90);
  }

  for (i = 0; i < top_of_mobt; i++)
  {
    mob = &mob_proto[i];
    GET_GOLD(mob) -= (int)(GET_GOLD(mob) * 0.90);
    GET_GOLD(mob) -= (int)(GET_GOLD(mob) * 0.50);
  }

  send_to_char("Complete.  Wldsave obj || mob to save changes.\n\r",ch);
}

ACMD(do_minlevelfix)
{
  int i;
  obdata *obj;

  send_to_char("Hard code removal required to do this again.  -Vall\n\r",ch);
  return;

  for (i = 0; i < top_of_objt; i++)
  {
    obj = &obj_proto[i];
    obj->min_level -= 5;	// adjust all minlevels 5 down
    obj->min_level = MAX(0, obj->min_level);
  }

  send_to_char("Complete.  Objsave to save changes.\n\r",ch);
}

// update all existing objects to work with new slot code
// 5/28/98 -jtrhone
ACMD(do_slotupdate)
{
  int i;
  obdata *obj;

  for (i = 0; i < top_of_objt; i++)
  {
    obj = &obj_proto[i];

    // no more wear shield, so make wear shields now holdable
    if (IS_SET(OBJ_WEARS(obj), (1 << 9)))
    {
      REMOVE_BIT(OBJ_WEARS(obj), (1 << 9));
      SET_BIT(OBJ_WEARS(obj), ITEM_HOLD);
    }

    // flag all LIGHTs item_hold 
    if (OBJ_LIGHT(obj))
      SET_BIT(OBJ_WEARS(obj), ITEM_HOLD);

    // remove (1 << 15) and (1 << 16) (umm throw and light-source wear positions)
    REMOVE_BIT(OBJ_WEARS(obj), (1 << 15));
    REMOVE_BIT(OBJ_WEARS(obj), (1 << 16));

    // update for use with wherevectors...?
  }

  // now update objs in game
  for (obj = object_list; obj; obj=obj->next)
  {
    // no more wear shield, so make wear shields now holdable
    if (IS_SET(OBJ_WEARS(obj), (1 << 9)))
    {
      REMOVE_BIT(OBJ_WEARS(obj), (1 << 9));
      SET_BIT(OBJ_WEARS(obj), ITEM_HOLD);
    }

    // flag all LIGHTs item_hold 
    if (OBJ_LIGHT(obj))
      SET_BIT(OBJ_WEARS(obj), ITEM_HOLD);

    // remove (1 << 15) and (1 << 16) (umm throw and light-source wear positions)
    REMOVE_BIT(OBJ_WEARS(obj), (1 << 15));
    REMOVE_BIT(OBJ_WEARS(obj), (1 << 16));

    // update for use with wherevectors...?
  }

  send_to_char("Complete.  Objsave to save changes.\n\r",ch);
}

ACMD(do_config)
{
  char *argu = argument;

  if (IS_NPC(ch)) return;

  skip_spaces(&argu);
  if (!*argu)
  {
    send_to_char("Usage: config <load | save>.\n\r",ch);
    return;
  }
  
  if (str_cmp(argu, "load") && str_cmp(argu, "save"))
  {
    send_to_char("Usage: config <load | save>.\n\r",ch);
    return;
  }

  if (!str_cmp(argu, "load"))
  {
    if (load_configuration(FALSE))
      send_to_char("Configuration loaded.\n\r",ch);
    else
      send_to_char("Configuration load failed.\n\r",ch);
  }
  else
  {
    if (save_configuration())
      send_to_char("Configuration saved.\n\r",ch);
    else
      send_to_char("Configuration save failed.\n\r",ch);
  }
}

ACMD(do_wldupdate)
{
  int zone;
  BOOL mob = FALSE, wld = FALSE, obj = FALSE, all = FALSE;
  char *argu = argument;

  if (IS_NPC(ch)) return;
  skip_spaces(&argu);

  if (!*argu || !str_cmp(argu, "all"))
    all = TRUE;
  else
  if (*argu && !str_cmp(argu, "mob"))
    mob = TRUE;
  else
  if (*argu && !str_cmp(argu, "wld"))
    wld = TRUE;
  else
  if (*argu && !str_cmp(argu, "obj"))
    obj = TRUE;
  else
  {
    send_to_char("Usage: wldupdate < all | mob | obj | wld >\n\r",ch);
    return;
  }

  for (zone = 0; zone < NUM_ZONES; zone++)
    if (REAL_ZONE(zone))
    {
     sprintf(buf, "%d", zone);
     if (all)
     {
      do_zlock(ch, buf, 0, 0);
      sprintf(buf, "-save %d", zone);
      do_zunlock(ch, buf, 0, 0);
     }
     else
     if (mob) do_mobsave(ch, buf, 0, 0);
     else
     if (wld) do_wldsave(ch, buf, 0, 0);
     else
     if (obj) do_objsave(ch, buf, 0, 0);
     else
       send_to_char("Nothing updated.\n\r",ch);
    } 
}

static char	*logtypes[] = {
   "off", "brief", "normal", "complete", "\n" };

ACMD(do_logall)
{
  if (!PLR_FLAGGED(ch, PLR_LOGALL))
    SET_BIT(PLR_FLAGS(ch), PLR_LOGALL);
  else
    REMOVE_BIT(PLR_FLAGS(ch), PLR_LOGALL);

  sprintf(buf, "%%5Logall%%0: %s.\n\r", PLR_FLAGGED(ch, PLR_LOGALL) ?
	  "activated" : "off");
  S2C();
}

ACMD(do_cliedit)
{
  if (IS_NPC(ch)) return;

  if (!PLR2_FLAGGED(ch, PLR2_CLIEDIT))
  {
    SET_BIT(PLR2_FLAGS(ch), PLR2_CLIEDIT);
    REMOVE_BIT(PLR_FLAGS(ch), PLR_EXEDIT);
  }
  else
    REMOVE_BIT(PLR2_FLAGS(ch), PLR2_CLIEDIT);

  sprintf(buf, "%%5Client Editor%%0: %s.\n\r", PLR2_FLAGGED(ch,PLR2_CLIEDIT) ?
          "activated" : "off");
  S2C();
}

ACMD(do_exedit)
{
  if (IS_NPC(ch)) return;

  if (!PLR_FLAGGED(ch, PLR_EXEDIT))
  {
    SET_BIT(PLR_FLAGS(ch), PLR_EXEDIT);
    REMOVE_BIT(PLR2_FLAGS(ch), PLR2_CLIEDIT);
  }
  else
    REMOVE_BIT(PLR_FLAGS(ch), PLR_EXEDIT);

  sprintf(buf, "%%5External Editor%%0: %s.\n\r", PLR_FLAGGED(ch,PLR_EXEDIT) ?
	  "activated" : "off");
  S2C();
}

ACMD(do_syslog)
{
   int	tp;

   if (IS_NPC(ch))
      return;

   one_argument (argument, arg);

   if (!*arg) {
      tp = ((PRF_FLAGGED(ch, PRF_LOG1) ? 1 : 0) +
	    (PRF_FLAGGED(ch, PRF_LOG2) ? 2 : 0));
      sprintf(buf, "Your syslog is currently %s.\n\r", logtypes[tp]);
      S2C();
      return;
   }

   if (((tp = search_block(arg, logtypes, FALSE)) == -1)) {
      send_to_char ("Usage: syslog { Off | Brief | Normal | Complete }\n\r", ch);
      return;
   }

   REMOVE_BIT(PRF_FLAGS(ch), PRF_LOG1 | PRF_LOG2);
   SET_BIT(PRF_FLAGS(ch), (PRF_LOG1 * (tp & 1)) | (PRF_LOG2 * (tp & 2) >> 1));

   sprintf(buf, "Your syslog is now %s.\n\r", logtypes[tp]);
   S2C();
   send_to_char("Use %BLogall%0 for complete debugging logs.\n\r",ch);
}

// shell out, note this IS in experimental stages -roa
// send our shell guy in comm.c any args needed
ACMD(do_exec)
{
  char editor[MAX_INPUT_LENGTH];
  char filename[MAX_INPUT_LENGTH];
  int startshell(dsdata *d, char* x, char* y);

  send_to_char("Exec for debugging puropses only, currently disabled.\n\r",ch);
  return;

  if (IS_NPC(ch)) return;
  
  // spico is default editor for now
  sprintf(editor, "/local/mud2/test/bin/spico");

  // set up a temporary text file for them to edit
  sprintf(filename, "%s.edit",GET_NAME(ch));

  SET_BIT(PLR_FLAGS(ch), PLR_BUILDING);
  startshell(ch->desc, "", filename);
}

/* reward players exp for good RP granted command */
/* -jtrhone -roa */
ACMD(do_award)
{
  int gain_exp(chdata *ch, int gain);
  chdata *vict;
  int amount;
  char *argu = argument;

  if (IS_NPC(ch)) return;

  skip_spaces(&argu);

  if (!*argu)
  {
    send_to_char("Usage: award <player> <amount of exp>.\n\r",ch);
    return;
  }

  half_chop(argu, arg, buf1);

  if (!(vict = get_char_vis(ch, arg))) {
    send_to_char("No such person around.\n\r", ch);
    return;
  }

  if (vict == ch)
  {
    send_to_char("You cannot award yourself experience.\n\r",ch);
    return;
  }

  if (IS_NPC(vict))
  {
    send_to_char("PC's only :)\n\r",ch);
    return;
  }

  if (!is_number(buf1))
  {
    send_to_char("Usage: award <player> <amount of exp>.\n\r",ch);
    return;
  }

  amount = atoi(buf1);
  amount = MAX(0, MIN(500000, amount));
  gain_exp(vict, amount);

  sprintf(buf, "You award %s %d experience points.\n\r",GET_NAME(vict),
	  amount);
  S2C();
  sprintf(buf, "%s has awarded you %d experience points for good role playing.\n\r",
	  GET_NAME(ch), amount);
  send_to_char(buf, vict);

  sprintf(buf, "IMMUPD: %s awarded %s %d exp for RP", GET_NAME(ch), GET_NAME(vict),
	  amount);
  mudlog(buf, NRM, LEV_AIMP, FALSE);
}

ACMD(do_timeshift)
{
  int hrs, i, dtime = 0;
  void check_idle_passwords();
  void zone_update();
  void zone_activity();
  void magical_activity(); // in mobact.c for now -roa
  void room_activity(BOOL dtime);
  void mobile_activity(BOOL dtime);
  void perform_violence();
  void update_vt100_bars();
  void another_hour();
  void affect_update();
  void point_update();
  int  update_who_html();
  void update_stats_html();
  void update_goss_html();
  void do_auction_update();
  void do_arena_update();
  void info_broadcast();
  void mortal_save();
  void House_save_all();
  void room_save_all();
  void record_usage();
  void save_board_config();
  void save_plshops();
  int max_on;

  if (IS_NPC(ch)) return;

  one_argument(argument, arg);

  if (!is_number(arg))
  {
    send_to_char("Usage: warp < 1 - 99 >.\n\r",ch);
    return;
  }

  hrs = atoi(arg);

  if (hrs < 1 || hrs > 99)
  {
    send_to_char("Usage: warp < 1 - 99 >.\n\r",ch);
    return;
  }

  sprintf(buf, "Advancing time %%5%%B%d%%0 hours.\n\r",hrs);
  S2C();

  for (i = 0; i < hrs; i++)
  {
    check_idle_passwords();
    zone_update();
    zone_activity();
    magical_activity(); // in mobact.c for now -roa
    room_activity(dtime);
    mobile_activity(dtime);
    dtime = !dtime;
    perform_violence();
    update_vt100_bars();
    another_hour();
    affect_update();
    point_update();
    fflush(player_fl);
    max_on = MAX(max_on, update_who_html());
    update_stats_html();
    update_goss_html();
    do_auction_update();
    do_arena_update();
    info_broadcast();
    mortal_save();
    House_save_all();
    room_save_all();
    record_usage();
    save_configuration();
    save_board_config();
    save_plshops();
  }
}

ACMD(do_prename)
{
  char *argu = argument;

  if (IS_NPC(ch)) return;

  if (strlen(argument) > MAX_CLAN_LENGTH-1)
  {
    send_to_char("Argument too long.\n\r",ch);
    return;
  }  

  skip_spaces(&argu);
  strcpy(GET_PRENAME(ch), argu);
  sprintf(buf, "Prename changed to: %s\n\r",argu);
  S2C();
}

ACMD(do_page)
{
   dsdata *d;
   chdata *vict;

   if (IS_NPC(ch)) {
      send_to_char("Monsters can't page.. go away.\n\r", ch);
      return;
   }

   if (!*argument) {
      send_to_char("Whom do you wish to page?\n\r", ch);
      return;
   }
   half_chop(argument, buf, buf2);
   if (!str_cmp(buf, "all")) 
   {
      if (GET_LEVEL(ch) > LEV_GOD) 
      {
	 sprintf(buf, "\007\007*%s* %s\n\r", GET_NAME(ch), buf2);
	 for (d = descriptor_list; d; d = d->next)
	    if (!d->connected)
	    {
	       send_to_q(buf, d);
	    }
      } else
	 send_to_char("You will never be godly enough to do that!\n\r", ch);
      return;
   }

   if ((vict = get_char_vis(ch, buf))) {
      sprintf(buf, "\007\007*%s* %s\n\r", GET_NAME(ch), buf2);
      send_to_char(buf, vict);
      if (PRF_FLAGGED(ch, PRF_NOREPEAT))
	 send_to_char("Ok.\n\r", ch);
      else
	 S2C();
      return;
   } else
      send_to_char("There is no such person in the game!\n\r", ch);
}

ACMD(do_send)
{
   chdata *vict;

   if (IS_NPC(ch)) {
      send_to_char("Umm.... no.\n\r", ch );
      return;
   }

   half_chop(argument, arg, buf);

   if (!*arg) {
      send_to_char("Send what to who?\n\r", ch);
      return;
   }

   if (!(vict = get_char_vis(ch, arg))) {
      send_to_char("No such person around.\n\r", ch);
      return;
   }

   send_to_char(buf, vict);
   send_to_char("\n\r", vict);

   if (PRF_FLAGGED(ch, PRF_NOREPEAT))
      send_to_char("Sent.\n\r", ch);
   else
   {
      sprintf(buf2, "You send '%s' to %s.\n\r", buf, GET_NAME(vict));
      send_to_char(buf2, ch);
   }
}

// for sending to a client connection...
ACMD(do_csend)
{
   void send_msg_to_client(char *buf, dsdata *d);
   chdata *vict;

   if (IS_NPC(ch)) {
      send_to_char("Umm.... no.\n\r", ch );
      return;
   }

   half_chop(argument, arg, buf);

   if (!*arg) {
      send_to_char("Send what to who?\n\r", ch);
      return;
   }

   if (!(vict = get_char_vis(ch, arg))) {
      send_to_char("No such person around.\n\r", ch);
      return;
   }

   if (!vict->desc || !HAS_CLIENT(vict->desc))
   {
     send_to_char("Victim does not have a client connection.\n\r",ch);
     return;
   }

   send_msg_to_client(buf, vict->desc);

   if (PRF_FLAGGED(ch, PRF_NOREPEAT))
      send_to_char("Sent to client.\n\r", ch);
   else
   {
      sprintf(buf2, "You client-send '%s' to %s.\n\r", buf, GET_NAME(vict));
      send_to_char(buf2, ch);
   }
}

ACMD(do_echo)
{
   char *argu = argument;

   // externals used in this function
   void send_to_room_except(char *buf, int room, chdata *ch);

   skip_spaces(&argu);

   if (IS_PC(ch) && !IS_IMMORTAL(ch))
   {
     send_to_char("Huh?!?\n\r",ch);
     return;
   }

   if (!*argu)
      send_to_char("Emote what?\n\r", ch);
   else
   {
      sprintf(buf, "%s\n\r", argu);
      send_to_room_except(buf, ch->in_room, ch);
      if (IS_PC(ch) && PRF_FLAGGED(ch, PRF_NOREPEAT))
	 send_to_char("Ok.\n\r", ch);
      else
	 S2C();
   }
}

/* take a string, and return an rnum.. used for goto, at, etc.  -je 4/6/93 */
sh_int find_target_room(chdata *ch, char *rawroomstr)
{
   int	tmp;
   sh_int location;
   chdata *target_mob;
   obdata *target_obj;
   char	roomstr[MAX_INPUT_LENGTH];

   // externals used in this
   int House_can_enter(chdata *ch, int num);

   one_argument(rawroomstr, roomstr);

   if (!*roomstr)
   {
      send_to_char("You must supply a room number or name.\n\r", ch);
      return NOWHERE;
   }

   if (isdigit(*roomstr) && !strchr(roomstr, '.'))
   {
      tmp = atoi(roomstr);
      if ((location = real_room(tmp)) < 0)
      {
	 send_to_char("No room exists with that number.\n\r", ch);
	 return NOWHERE;
      }
   }
   else
   if ((target_mob = get_char_vis(ch, roomstr)))
      location = target_mob->in_room;
   else
   if ((target_obj = get_obj_vis(ch, roomstr)))
   {
      if (target_obj->in_room != NOWHERE)
	 location = target_obj->in_room;
      else
      {
	 send_to_char("That object is not available.\n\r", ch);
	 return NOWHERE;
      }
   }
   else
   {
      send_to_char("No such creature or object around.\n\r", ch);
      return NOWHERE;
   }

   /* a location has been found. */
   if (ROOM_FLAGGED(location, GODROOM) && GET_LEVEL(ch) < LEV_CIMP) 
   {
      send_to_char("Powerful forces prevent you from going there.\n\r", ch);
      return NOWHERE;
   }

   if (ROOM_FLAGGED(location, PRIVATE) && GET_LEVEL(ch) < LEV_CIMP)
      if (world[location].people && world[location].people->next_in_room) 
      {
         send_to_char("That area is designated private and it's full.\n\r", ch);
	 return NOWHERE;
      }

     if (GET_LEVEL(ch) < LEV_AIMP)
     if (ROOM_FLAGGED2(location, HOUSE) && !House_can_enter(ch, world[location].number))
     { 
	send_to_char("House: You're not invited to enter that room.\n\r",ch);
	return NOWHERE;
     }
   return location;
}

ACMD(do_at)
{
   char	command[MAX_INPUT_LENGTH];
   int	location, original_loc;

   if (IS_NPC(ch))
      return;

   half_chop(argument, buf, command);
   if (!*buf)
   {
     send_to_char("You must supply a room number or a name.\n\r", ch);
     return;
   }

   // 03/22/98 -callahan
   if (!*command) {
     send_to_char("What do you want to do there?\r\n", ch);
     return;
   }

   if ((location = find_target_room(ch, buf)) < 0)
     return;

   if (ZONE_FREED(world[location].zone))
   {
     send_to_char("Unable to find room in memory database.\n\r",ch);
     return;
   }

   /* a location has been found. */
   original_loc = ch->in_room;
   char_from_room(ch);
   char_to_room(ch, location);
   command_interpreter(ch, command);

   /* check if the guy's still there */
   if (ch->in_room == location)
   {
      char_from_room(ch);
      char_to_room(ch, original_loc);
   }
}

ACMD(do_goto)
{
  sh_int location, was_in;
  FollowType *k, *next;

  if (IS_NPC(ch))
    return;

  if ((location = find_target_room(ch, argument)) < 0)
    return;

  /* roa jtrhone */
  if (location == InRoom(ch)) {
    send_to_char("You're already where you want to go.\r\n",ch);
    return;
  }

  if (Poofout(ch))
    sprintf(buf, "$n %s", Poofout(ch));
  else
    sprintf(buf, "$n disappears in a puff of smoke.");

  act(buf, TRUE, ch, 0, 0, TO_ROOM);
  was_in = InRoom(ch);		// Added for following. 03/22/98 -callahan
  char_from_room(ch);
  char_to_room(ch, location);

  if (IS_PC(ch) && Poofin(ch))
    sprintf(buf, "$n %s", Poofin(ch));
  else
    sprintf(buf, "$n appears with an ear-splitting bang.");

  act(buf, TRUE, ch, 0, 0, TO_ROOM);
  do_look_at_room(ch, 0, 0);

  // Immorts who are following will goto as well. 03/22/98 -callahan
  if (ch->followers)
    for (k = ch->followers; k; k = next) {
      next = k->next;
      if (Shade(k->follower) && (InRoom(k->follower) == was_in)) {
        if (Poofout(k->follower))
          sprintf(buf, "$n %s", Poofout(k->follower));
        else
          strcpy(buf, "$n disappears in a puff of smoke.");
  
        act("You follow $N.\r\n", FALSE, k->follower, 0, ch, TO_CHAR);
        act(buf, TRUE, k->follower, 0, 0, TO_ROOM);
        char_from_room(k->follower);
        char_to_room(k->follower, location);
  
        if (Poofin(k->follower))
          sprintf(buf, "$n %s", Poofin(k->follower));
        else
          strcpy(buf, "$n appears with an ear-splitting bang.");
   
        act(buf, TRUE, k->follower, 0, 0, TO_ROOM);
        do_look_at_room(k->follower, 0, 0);
      }
    }
}

ACMD(do_trans)
{
   dsdata *i;
   chdata *victim;

   if (IS_NPC(ch))
      return;

   one_argument(argument, buf);
   if (!*buf)
     send_to_char("Whom do you wish to transfer?\n\r", ch);
   else
   if (str_cmp("all", buf))
   {
      if (!(victim = get_char_vis(ch, buf)))
	 send_to_char("No-one by that name around.\n\r", ch);
      else
      if (victim == ch)
	 send_to_char("That doesn't make much sense, does it?\n\r", ch);
      else
      {
	 if ((GET_LEVEL(ch) <= GET_LEVEL(victim)) && IS_PC(victim))
         {
            act("You are unable to transfer $M.", FALSE, ch, 0, victim, TO_CHAR);
	    return;
	 }
         if (InRoom(victim) == InRoom(ch)) {	// 03/22/98 -callahan
           act("$N is already with you.", FALSE, ch, 0, victim, TO_CHAR);
           return;
         }
         act("$n disappears amidst a darkened cloud.", FALSE, victim, 0, 0, TO_ROOM);
	 char_from_room(victim);
	 char_to_room(victim, ch->in_room);
         act("$n arrives amidst a darkened cloud.", FALSE, victim, 0, 0, TO_ROOM);
	 act("$n has transferred you!", FALSE, ch, 0, victim, TO_VICT);
         do_look_at_room(victim, 0, 0);
      }
   }
   else
   { /* Trans All */
      for (i = descriptor_list; i; i = i->next)
	 if (D_CHECK(i) && i->character != ch)
         {
	    victim = i->character;
            act("$n disappears amidst a darkened cloud.", FALSE, victim, 0, 0, TO_ROOM);
	    char_from_room(victim);
	    char_to_room(victim, ch->in_room);
            act("$n arrives amidst a darkened cloud.", FALSE, victim, 0, 0, TO_ROOM);
	    act("$n has transferred you!", FALSE, ch, 0, victim, TO_VICT);
            do_look_at_room(victim, 0, 0);
	 }
      send_to_char("Ok.\n\r", ch);
   }
}

ACMD(do_teleport)
{
   chdata *victim;
   sh_int target;

   if (IS_NPC(ch))
      return;

   half_chop(argument, buf, buf2);

   if (!*buf)
      send_to_char("Who do you wish to teleport?\n\r", ch);
   else
   if (!(victim = get_char_vis(ch, buf)))
      send_to_char("No-one by that name around.\n\r", ch);
   else
   if (victim == ch)
      send_to_char("Use 'goto' to teleport yourself.\n\r", ch);
   else
   if (GET_LEVEL(ch) <= GET_LEVEL(victim) && IS_PC(victim))
      send_to_char("Teleport someone your own size.\n\r",ch);
   else
   if (!*buf2)
      send_to_char("Where do you wish to send this person?\n\r", ch);
   else
   if ((target = find_target_room(ch, buf2)) >= 0)
   {
      act("$n disappears amidst a darkened cloud.", FALSE, victim, 0, 0, TO_ROOM);
      char_from_room(victim);
      char_to_room(victim, target);
      act("$n arrives amidst a darkened cloud.", FALSE, victim, 0, 0, TO_ROOM);
      act("$n has teleported you!", FALSE, ch, 0, (char *)victim, TO_VICT);
      do_look_at_room(victim, 0, 0);
   }
}

ACMD(do_vnum)
{
  char *argu = argument;
  char names[MAX_INPUT_LENGTH];

  if (IS_NPC(ch))
  {
     send_to_char("What would a monster do with a vnum?\n\r", ch);
     return;
  }

  half_chop(argu, buf, names);

  if (!*buf || !*names || (!is_abbrev(buf, "mob") && !is_abbrev(buf, "obj")))
  {
     send_to_char("Usage: vnum { obj | mob } <name1 [name2]>\n\r", ch);
     return;
  }

  if (is_abbrev(buf, "mob"))
  {
     if (!vnum_mobile(names, ch))
       send_to_char("No mobiles by that name.\n\r", ch);
  }
  else
  if (is_abbrev(buf, "obj"))
  {
     if (!vnum_object(names, ch))
       send_to_char("No objects by that name.\n\r", ch);
  }
}

#define NAME(x) ((temp = get_name_by_id(x)) == NULL ? "<UNDEF>" : temp)

void	do_stat_room(chdata *ch)
{
   exdescdata *desc;
   rmdata *rm = &world[ch->in_room];
   int	i, found = 0;
   obdata *j = 0;
   chdata *k = 0;
   rmdirdata *dir;
   struct room_affect_type *raf;
   char *temp;

   if (IS_NPC(ch))
   {
      send_to_char("Umm.... no.\n\r", ch );
      return;
   }

   sprintf(buf, "Room name: %%6%s%%0  (%%5%d%%0 light)\n\r",rm->name,rm->light);
   S2C();

   if (rm->owner >= 0)
   {
     sprintf(buf, "%%B%%6Owned by%%0: (%%5%d%%0) %%5%s%%0.\n\r",rm->owner,
	     NAME(rm->owner));
     S2C();
   }

   sprinttype(rm->terrain_type, terrain_types, buf2);
   sprintf(buf, "Zone: [%3d], VNum: [%%3%5d%%0], RNum: [%5d], Type: %s\n\r",
       rm->zone, rm->number, ch->in_room, buf2);
   S2C();

   sprintbit((long) rm->room_flags, room_bits, buf2);
   sprintf(buf, "SpecProc: %s\n\rRFlags : %s\n\r",
           (rm->funct) ? "Exists" : "No", buf2);
   S2C();

   sprintbit((long) rm->room_flags2, room_bits2, buf2);
   sprintf(buf, "RFlags2: %s\n\r", buf2);
   S2C();

   sprintf(buf,"Max Contains: %d, Number Present: %d\n\r",
           rm->max_contains, rm->num_present);
   S2C();

   if (IS_SET(rm->room_flags, ALTERHIT | ALTERMANA | ALTERMOVE | DEATH | FLY_DEATH))
   {
     sprinttype(rm->alter_type, alter_types, buf2);
     sprintf(buf, "%%6Alter stats%%0: %dd%d %%B%s%%0\n\r",
	     rm->numdice,rm->sizedice,buf2);
     S2C();
   }

   if (rm->trans_present > 0)
   {
     sprintf(buf, "Transport %%B#%d%%0 present.\n\r",rm->trans_present);
     S2C();
   }

   if (IS_SET(rm->room_flags2, TRANSPORT))
   {
	sprintf(buf, "Transport location: %%6%d%%0, destination: %%6%d%%0.\n\r",
		rm->location, rm->portals[(int)rm->to_port]);
	S2C();
   }

   sprintf(buf, "%%5Description Status%%0: %s\n\r", (rm->description)?"OK" :"NONE!" );
   S2C();

   if (rm->exdesc) 
   {
      sprintf(buf, "%%5Extra descs%%0:%%6 ");
      for (desc = rm->exdesc; desc; desc = desc->next)
      {
	 strcat(buf, " ");
	 strcat(buf, desc->keyword);
      }
      strcat(buf, "%0\n\r");
      S2C();
   }

   sprintf(buf, "%%5Chars present%%0:%%2 ");
   for (found = 0, k = rm->people; k; k = k->next_in_room) 
   {
      if (!can_see(ch, k))
	 continue;
      sprintf(buf2, "%s %s(%s)", found++ ? "," : "", GET_NAME(k),
	 (IS_PC(k) ? "PC" : (!IS_MOB(k) ? "NPC" : "MOB")));
      strcat(buf, buf2);
      if (strlen(buf) >= 62) 
      {
	 if (k->next_in_room)
	    send_to_char(strcat(buf, ",\n\r"), ch);
	 else
	    send_to_char(strcat(buf, "\n\r"), ch);
	 *buf = found = 0;
      }
   }

   if (*buf)
      send_to_char(strcat(buf, "%0\n\r"), ch);

   if (rm->contents) 
   {
      sprintf(buf, "%%5Contents%%0:%%3 ");
      for (found = 0, j = rm->contents; j; j = j->next_content) 
      {
	 if (!CAN_SEE_OBJ(ch, j))
	    continue;
	 sprintf(buf2, "%s %s", found++ ? "," : "", j->shdesc);
	 strcat(buf, buf2);
	 if (strlen(buf) >= 62)
         {
	    if (j->next_content)
	       send_to_char(strcat(buf, ",\n\r"), ch);
	    else
	       send_to_char(strcat(buf, "\n\r"), ch);
	    *buf = found = 0;
	 }
      }
      if (*buf)
	 send_to_char(strcat(buf, "%0\n\r"), ch);
   }

   for (i = 0; i < NUM_OF_DIRS; i++) 
   {
      dir = rm->dir_option[i];
      if (dir) 
      {
	 if (dir->to_room == NOWHERE)
	    sprintf(buf1, " %%1NOWHERE%%0");
	 else
	    sprintf(buf1, "%%6%5d%%0", world[dir->to_room].number);

	 sprintbit(dir->exinfo, exit_bits, buf2);
	 sprintf(buf, "%%5Exit%%0 %%6%-5s%%0:  To: [%s], Key: [%5d], Keywrd: %s, Type: %s\n\r ", 
                 dirs[i], buf1, dir->key,
             ((dir->keyword) ? dir->keyword : "None"), buf2);
	 S2C();

	 if (dir->exit_descr)
	    strcpy(buf, dir->exit_descr);
	 else
	    strcpy(buf, "  No exit description.\n\r");
	 S2C();
      }
   }

  for (raf = rm->room_affects; raf; raf = raf->next)
  {
    sprintf(buf, "%%6Room affect%%0: %s  %%6Ticks Left%%0: %d  (%s).\n\r", skill_names[raf->spell], raf->duration, 
	(raf->caster ? GET_NAME(raf->caster) : "ABSENT"));
    S2C();
  }

}

void do_stat_object(chdata *ch, obdata *j)
{
   BOOL found;
   int	i;
   obdata *j2;
   exdescdata *desc;
   int	vnum;

   vnum = GET_OBJ_VNUM(j);
   sprintf(buf, "Name: '%%2%s%%0', Aliases: %s\n\r",
      ((j->shdesc) ? j->shdesc : "<None>"), j->name);
   S2C();
   sprinttype(ITEM_TYPE(j), item_types, buf1);
   if (j->item_number >= 0)
      strcpy(buf2, (obj_index[j->item_number].func ? "Exists" : "None"));
   else
      strcpy(buf2, "None");
   sprintf(buf, "VNum: [%%6%5d%%0], RNum: [%5d], Type: %s, SpecProc: %s\n\r",
           vnum, j->item_number, buf1, buf2);
   S2C();
   sprintf(buf, "L-Des: %s\n\r", ((j->description) ? j->description : "None"));
   S2C();

   if (j->exdesc)
   {
      sprintf(buf, "Extra descs:%%6");
      for (desc = j->exdesc; desc; desc = desc->next)
      {
	 strcat(buf, " ");
	 strcat(buf, desc->keyword);
      }
      send_to_char(strcat(buf, "%0\n\r"), ch);
   }

   send_to_char("Can be worn on: %5", ch);
   sprintbit(OBJ_WEARS(j), wear_bits, buf);
   strcat(buf, "%0\n\r");
   S2C();

   send_to_char("Set char AFF_XXXX:%5 ", ch);
   sprintbit(j->eqaffbit, affected_bits, buf);
   strcat(buf, "%0\n\r");
   S2C();

   send_to_char("Set char AFF2_XXX:%5 ", ch);
   sprintbit(j->eqaff2bit, affected2_bits, buf);
   strcat(buf, "%0\n\r");
   S2C();

   send_to_char("Extra flags   :%5 ", ch);
   sprintbit(OBJ_EXTRAS(j), extra_bits, buf);
   strcat(buf, "%0\n\r");
   S2C();

   send_to_char("Extra flags2  :%5 ", ch);
   sprintbit(OBJ_EXTRAS2(j), extra_bits2, buf);
   strcat(buf, "%0\n\r");
   S2C();

   sprintf(buf, "Weight: %d, Value: %d, Timer: %d\n\r",j->weight, j->cost, j->timer);
   S2C();

   sprintf(buf, "Load prob: %d, Alternate load: %d, Max_in_game: %d\n\r",
           j->percent_load, j->alternate_load, j->total_game_limit);
   S2C();

   sprintf(buf, "Number in %%6existence%%0: %d\n\r", obj_index[GET_OBJ_RNUM(j)].number);
   if (j->total_game_limit > 0 && (obj_index[GET_OBJ_RNUM(j)].number > j->total_game_limit))
     strcat(buf, "%1WARNING%0: Number in existence exceed total_game_limit!\n\r");
   S2C();

   sprintf(buf, "Minimum level: %d, %%BHits%%0: %d/%d, Plr_Num: %d\n\r",
	   j->min_level, OBJ_HITS(j), MAX_OBJ_HITS(j), j->plr_num);
   S2C();

   if (THROWABLE(j))
   {
     sprintf(buf, "%%B%%6Throwable%%0: %%6ToHit%%0: %d, "
	   	  "%%6ToDam%%0: %dd%d + %d\n\r", j->throw_plushit, 
		  j->throw_numdam, j->throw_sizedam, j->throw_plusdam);
     S2C();
   }

   strcpy(buf, "In room: ");
   if (j->in_room == NOWHERE)
      strcat(buf, "Nowhere");
   else 
   {
      sprintf(buf2, "%d", world[j->in_room].number);
      strcat(buf, buf2);
   }
   strcat(buf, ", In object: ");
   strcat(buf, j->in_obj ? j->in_obj->shdesc: "None");
   strcat(buf, ", Carried by: ");
   strcat(buf, j->carried_by ? GET_NAME(j->carried_by) : "Nobody");
   strcat(buf, "\n\r");
   S2C();

   switch (j->type_flag)
   {
   case ITEM_LIGHT :
      sprintf(buf, "Color: [%d], Type: [%d], Hours: [%d]",j->value[0], j->value[1], j->value[2]);
      break;

   case ITEM_SCROLL :
   case ITEM_POTION :
      sprintf(buf, "Spells: %s, %s, %s", 
		(j->value[1] > 0) ? skill_names[j->value[1]]: "NULL",
		(j->value[2] > 0) ? skill_names[j->value[2]]: "NULL",
		(j->value[3] > 0) ? skill_names[j->value[3]]: "NULL");
      break;

   case ITEM_WAND :
   case ITEM_STAFF :
      sprintf(buf, "%%6Spell%%0: %%B%s%%0, slevel: %d, charges: %d/%d", 
		(j->value[3] > 0) ? skill_names[j->value[3]]: "NULL", j->value[0], j->value[2], j->value[1]);
      break;

   case ITEM_WEAPON :
      sprintf(buf, "Tohit: %d, Todam: %dd%d, Type: %d", j->value[0],j->value[1], j->value[2], j->value[3]);
      break;

   case ITEM_ARMOR :
      sprintf(buf, "AC-apply: [%d]", j->value[0]);
      break;

   case ITEM_TRAP :
      sprintf(buf, "Spell: %d, - Hitpoints: %d",j->value[0], j->value[1]);
      break;

   case ITEM_CONTAINER :
      sprintf(buf, "Max-contains: %d, Locktype: %d, Corpse: %s",j->value[0], 
	      j->value[1], j->value[3] ? "Yes" : "No");
      break;

   case ITEM_DRINKCON :
   case ITEM_FOUNTAIN :
      sprinttype(j->value[2], drinks, buf2);
      sprintf(buf, "Max-contains: %d, Contains: %d, Poisoned: %s, Liquid: %s",
          j->value[0], j->value[1],j->value[3] ? "Yes" : "No", buf2);
      break;

   case ITEM_NOTE :
      sprintf(buf, "Tounge: %d", j->value[0]);
      break;

   case ITEM_KEY :
      sprintf(buf, "Keytype: %d", j->value[0]);
      break;

   case ITEM_FOOD :
      sprintf(buf, "Makes full: %d, Poisoned: %d", j->value[0], j->value[3]);
      break;
   default :
      sprintf(buf, "Values 0-3: [%d] [%d] [%d] [%d]",j->value[0], j->value[1],
	      j->value[2], j->value[3]);
      break;
   }
   S2C();

   strcpy(buf, "\n\rEquipment Status: ");
   if (!j->carried_by)
      strcat(buf, "None");
   else 
   {
      found = FALSE;
      for (i = 0; i < MAX_WEAR; i++)
      {
	 if (EQ(j->carried_by, i) == j)
         {
	    sprinttype(i, where, buf2);
	    strcat(buf, buf2);
	    found = TRUE;
	 }
      }
      if (!found)
	 strcat(buf, "Inventory");
   }
   send_to_char(strcat(buf, "\n\r"), ch);

   if (j->contains)
   {
      sprintf(buf, "Contents:%%3");
      for (found = 0, j2 = j->contains; j2; j2 = j2->next_content)
      {
	 sprintf(buf2, "%s %s", found++ ? "," : "", j2->shdesc);
	 strcat(buf, buf2);
	 if (strlen(buf) >= 62)
         {
	    if (j2->next_content)
	       send_to_char(strcat(buf, ",\n\r"), ch);
	    else
	       send_to_char(strcat(buf, "\n\r"), ch);
	    *buf = found = 0;
	 }
      }

      if (*buf)
	 send_to_char(strcat(buf, "%0\n\r"), ch);
   }

   send_to_char("Affections:", ch);
   for (found = 0, i = 0; i < MAX_OBJ_AFFECT; i++)
     if (j->affected[i].location)
     {
       sprinttype(j->affected[i].location, apply_types, buf2);
       sprintf(buf, "%s %+d to %s", found++ ? "," : "",
               j->affected[i].modifier, buf2);
       S2C();
     }

   if (!found)
      send_to_char(" None", ch);
   send_to_char("\n\r", ch);
}

/* return the total number of objects a player is carrying */
/* might not work for containers though :) */
/* JTRHONE */
int total_carrying(chdata *k)
{
   int i;
   int total;
   obdata *j;
   
   for (total = 0, j = k->carrying; j; j = j->next_content, total++)
      ;
   for (i = 0; i < MAX_WEAR; i++)
    if (EQ(k, i)) total++;

   return total;
}

void do_stat_character(chdata *ch, chdata *k)
{
   int	i, i2, found = 0;
   obdata *j;
   chdata *l;
   struct affected_type *aff;
   char buf3[MAX_INPUT_LENGTH];

   switch (k->player.sex)
   {
     case SEX_NEUTRAL	: strcpy(buf, "NEUTRAL-SEX "); break;
     case SEX_MALE	: strcpy(buf, "Male "); break;
     case SEX_FEMALE	: strcpy(buf, "Female "); break;
     case SEX_RANDOM	: strcpy(buf, "Random "); break;
     default		: strcpy(buf, "ILLEGAL-SEX!! "); break;
   }

  if (IS_PC(k))
    strcat(buf, rcarray[GET_RACE(k)].race_name);

  sprintf(buf2, " %s '%s'  IDNum: [%5ld], ", (IS_PC(k) ? "PC" : (!IS_MOB(k) ? "NPC" : "MOB")),
          GET_NAME(k), GET_IDNUM(k));
  strcat(buf, buf2);

  /* make sure we are in bounds for stat, caused crashes in minmud */
  if (IN_NOWHERE(k)) strcat(buf, "InRoom: [NOWHERE]\n\r");
  else
  if (k->in_room >= top_of_world)
    strcat(buf, "InRoom: [OUTOFBOUNDS]\n\r");
  else
  {
    sprintf(buf2, "InRoom: [%5d]\n\r",world[k->in_room].number);
    strcat(buf, buf2);
  }
  S2C();

  if (IS_NPC(k))
  {
    sprintf(buf, "Alias: %s, VNum: [%5d], RNum: [%5d]\n\r",
            k->player.name, mob_index[k->nr].vnum, k->nr);
    strcat(buf, "Size/Class: ");
    sprinttype(k->npc_specials.mob_size, size_types, buf2);
    strcat(buf, buf2);
    strcat(buf, " %5");

    sprintbit(MOB_CLASS_FLAGS(k), npc_class_names, buf2);
    strcat(buf, buf2);
    strcat(buf, "%0\n\r");
    S2C();

    if (IS_MOUNTED(k))
    {
      sprintf(buf, "Mounter_id: %d.\n\r",k->npc_specials.mounter_id);
      S2C();
    }
  }

   if (IS_PC(k))
   {
     sprintf(buf, "Title: %s\n\r", (k->player.title ? k->player.title : "<None>"));
     S2C();

     sprintf(buf, "Class: %s, ", clarray[(int) GET_CLASS(k)].class_name);
   }
   else
     *buf = '\0';

   sprintf(buf2, "Lev: [%%6%2d%%0], XP: [%%6%7d%%0], Align: [%%6%4d%%0]\n\r",
           GET_LEVEL(k), GET_EXP(k), GET_ALIGNMENT(k));
   strcat(buf, buf2);
   S2C();

   if (IS_PC(k)) 
   {
      strcpy(buf1, (char *)asctime(localtime(&(k->player.time.birth))));
      strcpy(buf2, (char *)asctime(localtime(&(k->player.time.logon))));
      buf1[10] = buf2[10] = '\0';

      sprintf(buf, "Created: [%s], Last Logon: [%s], Played [%dh %dm], Age [%d]\n\r", 
	 buf1, buf2, k->player.time.played / 3600,
	 ((k->player.time.played / 3600) % 60), age(k).year);
      S2C();

      if (GET_HTOWN(k) < 0 || GET_HTOWN(k) >= MAX_HTOWNS)
	sprintf(buf, "%%B%%1Invalid Hometown%%0\n\r");
      else
        sprintf(buf, "Hometown: %%6%s%%0\n\r",htowns[GET_HTOWN(k)].name);
      S2C();

      sprintf(buf, "%%BArena Wins%%0: [%d], STL: [%d], InAp: [%d], PL: %d\n\r",
	 k->pc_specials->saved.arena_wins, SPELLS_TO_LEARN(k), 
	 ((2*GET_INT(k))-6), PAGE_LENGTH(k));
      S2C();
   }

   sprintf(buf, "Str: [%%6%d/%d%%0]  Int: [%%6%d%%0]  Wis: [%%6%d%%0]  Dex: [%%6%d%%0]  Con: [%%6%d%%0]\n\r",
           GET_STR(k),GET_ADD(k),GET_INT(k),GET_WIS(k),GET_DEX(k),GET_CON(k));
   S2C();

   sprintf(buf, "Hit:[%%3%d/%d+%d%%0]  Mana:[%%3%d/%d+%d%%0]  Move:[%%3%d/%d+%d%%0]\n\r",
       GET_HIT(k), GET_MAX_HIT(k), hit_gain(k),
       GET_MANA(k), GET_MAX_MANA(k), mana_gain(k),
       GET_MOVE(k), GET_MAX_MOVE(k), move_gain(k));
   S2C();

   sprintf(buf, "Coins: [%9d], Bank: [%9d] (Total: %d)\n\r",
       GET_GOLD(k), GET_BANK_GOLD(k), GET_GOLD(k) + GET_BANK_GOLD(k));
   S2C();

   sprintf(buf, "AC: [%%6%d%%0], Hitroll: [%%6%2d%%0], Damroll: [%%6%2d%%0], Saving throws: [%%6%d/%d/%d/%d/%d%%0]\n\r",
	GET_AC(k), k->points.hitroll, k->points.damroll,
	SAVING_THROW(k, 0), SAVING_THROW(k, 1), SAVING_THROW(k, 2), 
	SAVING_THROW(k, 3), SAVING_THROW(k, 4));
   S2C();

   sprinttype(GET_POS(k), position_types, buf2);

   if (IS_NPC(k))
     sprinttype((k->npc_specials.default_pos), position_types, buf3);

   sprintf(buf, "Pos: %%6%s%%0 (def: %%6%s%%0), Fighting: %%5%s%%0\n\r", buf2,
	(IS_NPC(k) ? buf3 : ""), ((FIGHTING(k)) ? GET_NAME(FIGHTING(k)) : "Nobody") );
   S2C();

   if (IS_PC(k))
   {
     sprintf(buf, "Idle Timer (in tics) [%d]\n\r", k->specials.timer);
     S2C();

     // Added checks for empty. If so, don't display. 04/07/98 -callahan
     if (PLR_FLAGS(k)) {
       sprintbit(PLR_FLAGS(k), player_bits, buf2);
       sprintf(buf, "PLR: %%6%s%%0\n\r",buf2);
       S2C();
     }

     if (PLR_FLAGS(k)) {
       sprintbit(PLR2_FLAGS(k), player2_bits, buf2);
       sprintf(buf, "PLR2: %%6%s%%0\n\r",buf2);
       S2C();

     }

     if (PRF_FLAGS(k)) {
       sprintbit(PRF_FLAGS(k), preference_bits, buf2);
       sprintf(buf, "PRF: %%6%s%%0\n\r",buf2);
       S2C();
     }

     if (PRF2_FLAGS(k)) {
       sprintbit(PRF2_FLAGS(k), preference2_bits, buf2);
       sprintf(buf, "PRF2: %%6%s%%0\n\r",buf2);
       S2C();
     }

     if (GRNT_FLAGS(k)) {
       sprintbit(GRNT_FLAGS(k), grant_bits, buf2);
       sprintf(buf, "GRANT: %%6%s%%0\n\r",buf2);
       S2C();
     }
   }
   else  // is_npc
   {
      sprintbit(MOB_FLAGS(k), action_bits, buf2);
      sprintf(buf, "MFlags1: %%6%s%%0\n\r",buf2);
      S2C();

      sprintbit(SPC_FLAGS(k), spc_bits, buf2);
      sprintf(buf, "MFlags2: %%6%s%%0\n\r",buf2);
      S2C();

      sprintbit(MOB2_FLAGS(k), mob2_bits, buf2);
      sprintf(buf, "MFlags3: %%6%s%%0\n\r",buf2);
      S2C();

      sprintf(buf, "Mob Spec-Proc(hard-wired): %s, NPC Bare Hand Dam: %dd%d\n\r",
              (mob_index[k->nr].func ? "%4Exists%0" : "None"),
              k->npc_specials.damnodice, k->npc_specials.damsizedice);
      S2C();
   }

   sprintf(buf, "Carried: weight: %d, items: %d; ",IS_CARRYING_W(k), 
	   IS_CARRYING_N(k));

   for (i = 0, j = k->carrying; j; j = j->next_content, i++)
      ;
   sprintf(buf, "%sItems in: inventory: %d, ", buf, i);
   for (i = 0, i2 = 0; i < MAX_WEAR; i++)
    if (EQ(k, i)) i2++;
   sprintf(buf2, "eq: %d\n\r", i2);
   strcat(buf, buf2);
   S2C();

   if (IS_PC(k))
   {
     sprintf(buf, "Hunger: %d, Thirst: %d, Drunk: %d\n\r",
         GET_COND(k, FULL), GET_COND(k, THIRST), GET_COND(k, DRUNK));
     S2C();
   }

   if (IS_AFFECTED(ch, AFF_GROUP))
   {
     l = group_leader(k);
     sprintf(buf, "Master is: %s, followers are:", l ? GET_NAME(l) : "<none>");

     while ((l = group_member(k, FALSE)))
     {
       sprintf(buf2, "%s %s", found++ ? "," : "", PERS(l, ch));
       strcat(buf, buf2);
     }
     send_to_char(strcat(buf, "\n\r"), ch);
   }

   /* Showing the bitvector */
   // Added checks for empty. If so, don't display. 04/07/98 -callahan
   if (AFF_FLAGS(k)) {
     sprintbit(AFF_FLAGS(k), affected_bits, buf2);
     sprintf(buf, "AFF: %%2%s%%0\n\r",buf2);
     S2C();
   }

   if (AFF2_FLAGS(k)) {
     sprintbit(AFF2_FLAGS(k), affected2_bits, buf2);
     sprintf(buf, "AFF2: %%2%s%%0\n\r",buf2);
     S2C();
   }

   if (CHAR_FLAGS(k)) {
     sprintbit(CHAR_FLAGS(k), char_bits, buf2);
     sprintf(buf, "CHAR: %%2%s%%0\n\r",buf2);
     S2C();
   }

   if (IS_PC(k) && PSTR1(k) && !PLR_FLAGGED(k, PLR_BUILDING))
   {
     send_to_char("%1WARNING%0: PSTR1 allocated for this char.\n\r",ch);
     send_to_char(PSTR1(k), ch);
   }
   if (IS_PC(k) && PSTR2(k) && !PLR_FLAGGED(k, PLR_BUILDING))
   {
     send_to_char("%1WARNING%0: PSTR2 allocated for this char.\n\r",ch);
     send_to_char(PSTR2(k), ch);
   }

   if (IS_NPC(k))
   {
     if (SPC_FLAGGED(k, SPC_GMASTER))
     {
	sprintf(buf, "MinTrainLevel: %2d, MaxTrainLevel: %2d.\n\r",
		k->npc_specials.min_train_level, k->npc_specials.max_train_level);
	S2C();
     }

     if (SPC_FLAGGED(k, SPC_SHOPKEEP))
     {
	if (k->npc_specials.shop_data)
	  sprintf(buf, "%%6Shopkeep Data%%0: Vhome: %d  Vshop: %d  Open: %d  Close: %d  (%s)\n\r",
		  k->npc_specials.shop_data->vhome,
		  k->npc_specials.shop_data->vshop,
		  k->npc_specials.shop_data->open,
		  k->npc_specials.shop_data->close, 
		  (SHOPKEEP_OPEN(k) ? "OPEN":"CLOSED"));
	else
	  strcpy(buf, "%1WARNING%0: Shopkeep declared without shop_data.\n\r");
       S2C();
     }

   }

   /* Routine to show what spells a char is affected by */
   if (k->affected)
   {
      for (aff = k->affected; aff; aff = aff->next)
      {
	 *buf2 = '\0';
	 sprintf(buf, "SPL: (%3dhr) %%6%-21s%%0 ", aff->duration,
	         skill_names[aff->type] ? skill_names[aff->type] : "Unknown");
	 if (aff->modifier)
         {
	    sprintf(buf2, "%+d to %s", aff->modifier, apply_types[(int)aff->location]);
	    strcat(buf, buf2);
	 }
	 if (aff->bitvector)
         {
	    if (*buf2)
	       strcat(buf, ", sets ");
	    else
	       strcat(buf, "sets ");
	    sprintbit(aff->bitvector, affected_bits, buf2);
	    strcat(buf, buf2);
	 }
	 send_to_char(strcat(buf, "\n\r"), ch);
      }
   }
}


// scan the pfile for various attributes, mainly used to locate
// buggy players so we can fix them (ex: str bug)  RoA
ACMD(do_pfile_scan)
{
  chdata *victim;
  struct char_file_u tmp_store;
  int i;

  CREATE(victim, chdata, 1);
  clear_char(victim);
  for (i = 0, *buf = '\0'; i <= top_of_p_table; i++)
    if (load_char(player_table[i].name, &tmp_store) > -1)
    {
      store_to_char(&tmp_store, victim);
      if (*GET_NAME(victim) && GET_STR(victim) <= 0)
	sprintf(buf +strlen(buf), "%%B%s%%0: Str:%d StrAdd:%d\n\r",
		GET_NAME(victim), GET_STR(victim), GET_ADD(victim));
      clear_char(victim);
    }
  free_char(victim);

  if (*buf)
    page_string(ch->desc, buf, 1);
  else
    send_to_char("No players with 0 strength found.\n\r",ch);
}

void do_stat_zone(chdata *ch, int zone)
{
  zndata *z = &zone_table[zone];
  char *resets[] = {
    "No reset.",
    "Reset iff no PCs within.",
    "Reset regardless."};

  sprintf(buf, "%%6Zone #%%0: %d\n\r",zone);
  sprintf(buf+strlen(buf), "%%6Zone Name%%0: %s.\n\r",z->name);
  sprintf(buf+strlen(buf),"%%6Lifespan%%0: %3d, %%6Current Age%%0: %3d\n\r",
	  z->lifespan, z->age);
  sprintf(buf+strlen(buf),"%%6Reset Mode%%0: %s\n\r",resets[z->reset_mode]);
  sprintf(buf+strlen(buf),"%%6Idle Time%%0: %3d\n\r",z->idle_time);
  sprintf(buf+strlen(buf),"%%6Current Weather Status%%0: %s.\n\r",
	  precip_names_ing[z->current_status]);
  sprintf(buf+strlen(buf),"%%6Accum%%0: %d, %%6Type%%0: %s, %%6Today%%0: %s.\n\r",
	  z->accum, precip_names[z->accum_type], YESNO(z->has_rained));
  sprintf(buf+strlen(buf),"%%6Current Gtemp%%0: %3d, %%6Current Atemp%%0: %3d.\n\r",
	z->current_gtemp, z->current_atemp);
  sprintbit(z->bitvector, zone_bits, buf2);
  sprintf(buf+strlen(buf),"%%6Zone Flags%%0: %%5%s%%0\n\r",buf2);
  sprintf(buf+strlen(buf),"%%6Max PCs%%0: %d, %%6PC Deaths%%0: %d.\n\r",
	  z->max_pcs, z->pc_deaths);
  page_string(ch->desc, buf, TRUE);
}

ACMD(do_stat)
{
   chdata *victim = 0;
   obdata *object = 0;
   struct char_file_u tmp_store;
   int znum;

   if (IS_NPC(ch))
      return;

   half_chop(argument, buf1, buf2);

   if (!*buf1)
   {
      send_to_char("Usage: stat < room | mob <name> | obj <name> | player <name> | file <name> >.\n\r", ch);
      send_to_char("       stat < zone <num> >.\n\r",ch);
      return;
   }
   else
   if (is_abbrev(buf1, "room"))
      do_stat_room(ch);
   else
   if (is_abbrev(buf1, "zone"))
   {
      if (!*buf2)
	 send_to_char("Stats on which zone?\n\r", ch);
      else
      {
	if (!is_number(buf2) || (znum = atoi(buf2)) < 0 || !REAL_ZONE(znum))
	  send_to_char("Usage: stat zone #.\n\r",ch);
	else
	  do_stat_zone(ch, znum);
      }
   }
   else
   if (is_abbrev(buf1, "mob"))
   {
      if (!*buf2)
	 send_to_char("Stats on which mobile?\n\r", ch);
      else
      {
	 if ((victim = get_char_vis(ch, buf2)))
	    do_stat_character(ch, victim);
	 else
	    send_to_char("No such mobile around.\n\r", ch);
      }
   }
   else
   if (is_abbrev(buf1, "player"))
   {
      if (!*buf2)
	 send_to_char("Stats on which player?\n\r", ch);
      else
      {
	 // Updated get_player_vis() for 0.playername, 03/22/98 -callahan
	 if ((victim = get_player_vis(ch, buf2, FALSE)))
	    do_stat_character(ch, victim);
	 else
	    send_to_char("No such player around.\n\r", ch);
      }
   }
   else
   if (is_abbrev(buf1, "file"))
   {
      if (!*buf2)
	 send_to_char("Stats on which player?\n\r", ch);
      else
      {
	 CREATE(victim, chdata, 1);
	 clear_char(victim);
	 if (load_char(buf2, &tmp_store) > -1)
         {
	    store_to_char(&tmp_store, victim);
	    if (GET_LEVEL(victim) > GET_LEVEL(ch))
	       send_to_char("Sorry, you can't do that.\n\r", ch);
	    else
	       do_stat_character(ch, victim);
	    free_char(victim);
	 }
         else
         {
	    send_to_char("There is no such player.\n\r", ch);
	    free(victim);
	    victim = NULL;
	 }
      }
   }
   else
   if (is_abbrev(buf1, "object"))
   {
      if (!*buf2)
	 send_to_char("Stats on which object?\n\r", ch);
      else
      {
	 if ((object = get_obj_vis(ch, buf2)))
	    do_stat_object(ch, object);
	 else
	    send_to_char("No such object around.\n\r", ch);
      }
   }
   else
   {
      if ((victim = get_char_vis(ch, buf1)))
	 do_stat_character(ch, victim);
      else
      if ((object = get_obj_vis(ch, buf1)))
	 do_stat_object(ch, object);
      else
	 send_to_char("Nothing around by that name.\n\r", ch);
   }
}

/* takes a mob and returns its suggested level based on stats and flags */
/* RoA */
int get_mob_chart_level(chdata *mob)
{
   float flag_percentage = 1.0;
   float mob_dam = 0.0;
   int mob_level, mob_hit, hit_level, ac_level, hitroll_level, dam_level;

   /* start calculations based on mob_chart */
   /* hit point level */
   mob_hit = ((mob->npc_specials.mob_num_hit *
	       mob->npc_specials.mob_size_hit) / 2) + 
	       mob->npc_specials.mob_add_hit;
   for (hit_level = 0; mob_hit > mob_chart[hit_level].hit; hit_level++)
     ;

   /* ac level */
   for (ac_level = 0; GET_AC(mob) < mob_chart[ac_level].ac; ac_level++)
     ;

   /* hitroll level */
   for (hitroll_level = 0; 
        mob->points.hitroll > mob_chart[hitroll_level].hitroll;
        hitroll_level++)
     ;

   /* damage level */
   mob_dam = (((float) mob->npc_specials.damnodice * 
               (float) mob->npc_specials.damsizedice) / 2.0) + 
             (float) mob->points.damroll;
   for (dam_level = 0; mob_dam > mob_chart[dam_level].damage; dam_level++)
     ;
     
   /* sum em up using corresponding weights for each level */
   mob_level = (int) (((float) hit_level     * 0.4) +
                      ((float) dam_level     * 0.3) +
                      ((float) hitroll_level * 0.2) +
                      ((float) ac_level      * 0.1));

   /* spc flags on mob */
   if (SPC_FLAGGED(mob, SPC_HUNTER))
     flag_percentage += 0.05;
   if (SPC_FLAGGED(mob, SPC_MAGIC_USER))
     flag_percentage += 0.15;
   if (SPC_FLAGGED(mob, SPC_WARRIOR))
     flag_percentage += 0.10;
   if (SPC_FLAGGED(mob, SPC_CLERIC))
     flag_percentage += 0.15;
   if (SPC_FLAGGED(mob, SPC_UNDEAD))
     flag_percentage += 0.10;
   if (SPC_FLAGGED(mob, SPC_SNAKE))
     flag_percentage += 0.05;
   if (SPC_FLAGGED(mob, SPC_FIREBREATH))
     flag_percentage += 0.15;
   if (SPC_FLAGGED(mob, SPC_ACIDBREATH))
     flag_percentage += 0.15;
   if (SPC_FLAGGED(mob, SPC_ICEBREATH))
     flag_percentage += 0.15;
   if (SPC_FLAGGED(mob, SPC_GASBREATH))
     flag_percentage += 0.15;
   if (SPC_FLAGGED(mob, SPC_LIGHTBREATH))
     flag_percentage += 0.15;

   /* affections on mob */
   if (IS_AFFECTED(mob, AFF_BLIND))
     flag_percentage -= 0.20;
   if (IS_AFFECTED(mob, AFF_INVISIBLE))
     flag_percentage += 0.05;
   if (IS_AFFECTED(mob, AFF_DETECT_EVIL))
     flag_percentage += 0.03;
   if (IS_AFFECTED(mob, AFF_DETECT_INVISIBLE))
     flag_percentage += 0.03;
   if (IS_AFFECTED(mob, AFF_DETECT_MAGIC))
     flag_percentage += 0.03;
   if (IS_AFFECTED(mob, AFF_SENSE_LIFE))
     flag_percentage += 0.05;
   if (IS_AFFECTED(mob, AFF_SANCTUARY))
     flag_percentage += 0.30;
   if (IS_AFFECTED(mob, AFF_CURSE))
     flag_percentage -= 0.10;
   if (IS_AFFECTED(mob, AFF_POISON))
     flag_percentage -= 0.10;
   if (IS_AFFECTED(mob, AFF_PROTECT_EVIL))
     flag_percentage += 0.03;
   if (IS_AFFECTED(mob, AFF_PARRY))
     flag_percentage += 0.05;
   if (IS_AFFECTED(mob, AFF_SLEEP))
     flag_percentage -= 0.05;
   if (IS_AFFECTED(mob, AFF_DODGE))
     flag_percentage += 0.05;
   if (IS_AFFECTED(mob, AFF_SNEAK))
     flag_percentage += 0.05;
   if (IS_AFFECTED(mob, AFF_HIDE))
     flag_percentage += 0.05;
   if (IS_AFFECTED(mob, AFF_HASTE))
     flag_percentage += 0.10;
   if (IS_AFFECTED(mob, AFF_TRUCE))
     flag_percentage += 0.20;

   /* mob flags */
   if (MOB_FLAGGED(mob, MOB_AGGR))
     {
	if (!MOB_FLAGGED(mob, MOB_AGGR_EVIL) &&
	    !MOB_FLAGGED(mob, MOB_AGGR_GOOD) &&
	    !MOB_FLAGGED(mob, MOB_AGGR_NEUTRAL))
          flag_percentage += 0.15;
        else
        {
	  if (MOB_FLAGGED(mob, MOB_AGGR_EVIL))
            flag_percentage += 0.05;
	  if (MOB_FLAGGED(mob, MOB_AGGR_GOOD))
            flag_percentage += 0.05;
	  if (MOB_FLAGGED(mob, MOB_AGGR_NEUTRAL))
            flag_percentage += 0.05;
        }
     }
   if (MOB_FLAGGED(mob, MOB_HELPER))
     flag_percentage += 0.03;
   if (MOB_FLAGGED(mob, MOB_MH0))
     flag_percentage += 0.10;
   if (MOB_FLAGGED(mob, MOB_MH1))
     flag_percentage += 0.20;
   if (MOB_FLAGGED(mob, MOB_MH2))
     flag_percentage += 0.30;
   if (MOB_FLAGGED(mob, MOB_QHEAL))
     flag_percentage += 0.10;
   if (MOB_FLAGGED(mob, MOB_SMART))
     flag_percentage += 0.05;
   if (MOB_FLAGGED(mob, MOB_MEMORY))
     flag_percentage += 0.05;

   mob_level = (int) ((float) mob_level * flag_percentage);
   return mob_level;
}

/* do_chart - - RoA Innovations, builder tool to check created mob
		versus mob_chart standards/calculations James Rhone */
ACMD(do_chart)
{
   chdata *mob;
   int r_num, number, mob_level;

   if (IS_NPC(ch)) return;

   one_argument(argument, arg);
   
   if (!arg || !is_number(arg))
   {
     send_to_char("Usage:  chart <mob vnum>.\n\r",ch);
     return;
   }

   if ((number = atoi(arg)) < 0) 
   {
      send_to_char("Vnum must be a positive integer.\n\r", ch);
      return;
   }

   if ((r_num = real_mobile(number)) < 0) 
   {
     send_to_char("There is no MOB with that vnum.\n\r", ch);
     return;
   }

   if (!olc_perms(ch, LEV_CIMP, number/100))
     return;

   mob = &mob_proto[r_num];
   mob_level = get_mob_chart_level(mob);
   sprintf(buf, "Mob Chart Comparisons: %s (#%d)\n\r",GET_NAME(mob),number);
   strcat(buf,  "-=-=-=-=-=-=-=-=-=-=-=\n\r");
   S2C();
   sprintf(buf, "Actual level: %%B%d%%0, Suggested level: %%B%d%%0\n\r",
	   GET_LEVEL(mob), mob_level);
   S2C();
   sprintf(buf, "Actual Exper: %%B%d%%0, Suggested Exper: %%B%ld%%0\n\r",
	   GET_EXP(mob), (mob_level <= LEV_IMPL) ? mob_chart[mob_level].exp :
           (mob_chart[LEV_IMPL].exp + ((mob_level - LEV_IMPL) * 10000)));
   S2C();

   if (mob_level <= LEV_IMPL)
   {
     sprintf(buf, "Actual %s: %%B%d%%0, Suggested %s : %%B%ld%%0\n\r",
	     currency_name_plural, GET_GOLD(mob), currency_name_plural, mob_chart[mob_level].gold);
     S2C();
   }
   else
     send_to_char("Accurate currency data not available.\n\r",ch);
}

ACMD(do_adjust)
{
   chdata *mob;
   int r_num, number, mob_level;
   int mob_exp;

   if (IS_NPC(ch)) return;

   one_argument(argument, arg);
   
   if (!arg || !is_number(arg))
   {
     send_to_char("Usage:  adjust <mobile vnum>.\n\r",ch);
     return;
   }

   if ((number = atoi(arg)) < 0) 
   {
      send_to_char("Vnum must be a positive integer.\n\r", ch);
      return;
   }

   if ((r_num = real_mobile(number)) < 0) 
   {
     send_to_char("There is no MOB with that vnum.\n\r", ch);
     return;
   }

   if (!olc_perms(ch, LEV_CIMP, number/100))
     return;

   /* set mob pointing to the PROTO, cause thats what we wanna edit */
   mob = &mob_proto[r_num];
   mob_level = get_mob_chart_level(mob);
   mob_exp = (mob_level <= LEV_IMPL) ? mob_chart[mob_level].exp :
           (mob_chart[LEV_IMPL].exp + ((mob_level - LEV_IMPL) * 10000));

   sprintf(buf, "Level adjusted: %s (#%d)\n\r",GET_NAME(mob), number);
   strcat(buf,  "-=-=-=-=-=-=-=-\n\r");
   S2C();
   sprintf(buf, "Previous level: %%B%d%%0, Adjusted level: %%B%d%%0\n\r",
	   GET_LEVEL(mob), MIN(mob_level, LEV_IMPL));
   S2C();
   sprintf(buf, "Previous Exper: %%B%d%%0, Adjusted Exper: %%B%d%%0\n\r",
	   GET_EXP(mob), mob_exp);
   S2C();
   
   GET_LEVEL(mob) = MIN(mob_level, LEV_IMPL);
   GET_EXP(mob) = mob_exp;
   mob->points.armor = MAX(-490, mob->points.armor);
}

// actual calculations for obj minlevel -roa
int get_suggested_minlevel(obdata *obj)
{
  int avdam, i, lev;

  avdam = (obj->value[1] + (obj->value[1] * obj->value[2])) / 2; 

  if (avdam <= 5)
    lev = 1;
  else 
  if (avdam <= 15)
    lev = avdam;
  else 
  if (avdam <= 16)
    lev = 20;
  else 
  if (avdam <= 18)
    lev = 40;
  else
  if (avdam <= 20)
    lev = 60;
  else
    lev = 70;

  if (OBJ_FLAGGED(obj, ITEM_ANTI_MAGE))
    lev--;
  if (OBJ_FLAGGED(obj, ITEM_ANTI_CLERIC))
    lev--;
  if (OBJ_FLAGGED(obj, ITEM_ANTI_WARRIOR))
    lev--;
  if (OBJ_FLAGGED(obj, ITEM_ANTI_THIEF))
    lev--;
  if (OBJ_FLAGGED(obj, ITEM_ANTI_SHAMAN))
    lev--;
  if (OBJ_FLAGGED(obj, ITEM_ANTI_BARD))
    lev--;
  if (OBJ_FLAGGED(obj, ITEM_ANTI_RANGER))
    lev--;
  if (OBJ_FLAGGED(obj, ITEM_ANTI_WARLOCK))
    lev--;
  if (OBJ_FLAGGED(obj, ITEM_ANTI_MONK))
    lev--;
  if (OBJ_FLAGGED2(obj, ITEM_ANTI_HUMAN))
    lev--;
  if (OBJ_FLAGGED2(obj, ITEM_ANTI_ELF) )
    lev--;
  if (OBJ_FLAGGED2(obj, ITEM_ANTI_HALF_ELF) )
    lev--;
  if (OBJ_FLAGGED2(obj, ITEM_ANTI_ORC) )
    lev--;
  if (OBJ_FLAGGED2(obj, ITEM_ANTI_OGRE) )
    lev--;
  if (OBJ_FLAGGED2(obj, ITEM_ANTI_DROW) )
    lev--;
  if (OBJ_FLAGGED2(obj, ITEM_ANTI_DWARF) )
    lev--;
  if (OBJ_FLAGGED2(obj, ITEM_ANTI_PIXIE) )
    lev--;
  if (OBJ_FLAGGED2(obj, ITEM_ANTI_NIXIE) )
    lev--;
  if (OBJ_FLAGGED2(obj, ITEM_ANTI_DRAGON) )
    lev--;
   
  for (i = 0; i < MAX_OBJ_AFFECT; i++)
    switch (obj->affected[i].location) 
    {
      case APPLY_HIT:  case APPLY_MOVE:  case APPLY_MANA:
        lev += (obj->affected[i].modifier / 10);
	continue; break;

      case APPLY_RITUALS:
        lev += (obj->affected[i].modifier / 2);
        continue; break;

      case APPLY_HIT_REGEN: case APPLY_MANA_REGEN:
      case APPLY_MOVE_REGEN:
      case APPLY_STR:  case APPLY_INT:  case APPLY_WIS:
      case APPLY_DEX:  case APPLY_CON:  case APPLY_HITROLL:
      case APPLY_DAMROLL:
        lev += obj->affected[i].modifier;
	continue; break;

      default: continue; break;
    }

  if (OBJ_HITS(obj) <= 100) lev -= 6;
  else
  if (OBJ_HITS(obj) <= 500) lev -= 3;
  else
  if (OBJ_HITS(obj) <= 1500) lev -= 2;
  else
  if (OBJ_HITS(obj) <= 3000) lev -= 1;
  else
  if (OBJ_HITS(obj) <= 6000) lev = lev;
  else
  if (OBJ_HITS(obj) <= 12000) lev += 1;
  else
  if (OBJ_HITS(obj) <= 22000) lev += 2;
  else
  if (OBJ_HITS(obj) <= 30000) lev += 3;
  else
    lev += 6;

  return MAX(0, MIN(70, lev));
}

// chart objects for acceptable minlevel based on stats
ACMD(do_object_chart)
{
  char *argu = argument;
  int ovnum, ornum;
  obdata *obj;
  int lev;

  if (IS_NPC(ch)) return;

  skip_spaces(&argu);
  if (!*argu)
  {
    send_to_char("Usage: objchart <obj vnum>.\n\r",ch);
    return;
  }

  if (!(ovnum = atoi(argu)) || ((ornum = real_object(ovnum)) <= 0))
  {
    send_to_char("Invalid argument.  Object does not exist.\n\r",ch);
    return;
  }
  
  if (!olc_perms(ch, LEV_CIMP, ovnum/100))
    return;

  obj = &obj_proto[ornum];
  
  if (!IS_WEAPON(obj))
  {
    send_to_char("Only weapons may be charted at this time.\n\r",ch);
    return;
  }

  lev = get_suggested_minlevel(obj); 

  sprintf(buf, "Obj Chart Comparisons: %s (#%d)\n\r",obj->shdesc,ovnum);
  strcat(buf,  "-=-=-=-=-=-=-=-=-=-=-=\n\r");
  S2C();
  sprintf(buf, "Actual minlevel: %%B%d%%0, Suggested minlevel: %%B%d%%0\n\r",
	  obj->min_level, lev);
  S2C();
}

/* 
   simple proc adjusts terrain types as related to previous flags used
   here on RoA   jtrhone
*/
ACMD(do_room_terrain)
{
   int r_num, number;
   rmdata *r;

   if (IS_NPC(ch)) return;

   one_argument(argument, arg);
   
   if (!arg || !is_number(arg))
   {
     send_to_char("Usage:  terrain <room vnum>.\n\r",ch);
     return;
   }

   if ((number = atoi(arg)) < 0) 
   {
      send_to_char("Vnum must be a positive integer.\n\r", ch);
      return;
   }

   if (!olc_perms(ch, LEV_CIMP, number/100))
     return;

   if ((r_num = real_room(number)) < 0) 
   {
     send_to_char("There is no ROOM with that vnum.\n\r", ch);
     return;
   }

   r = &world[r_num];

   if (ROOM_FLAGGED(r_num, UWATER))
   {
     REMOVE_BIT(ROOM_FLAGS(r_num), UWATER);
     r->terrain_type = TERRAIN_UWATER;
     sprintf(buf, "Room #%d changed to terrain_uwater.\n\r", number);
     S2C();
   }
   else
   if (ROOM_FLAGGED(r_num, FLIGHT))
   {
     REMOVE_BIT(ROOM_FLAGS(r_num), FLIGHT);
     r->terrain_type = TERRAIN_AIR;
     sprintf(buf, "Room #%d changed to terrain_air.\n\r", number);
     S2C();
   }
}

ACMD(do_zone_terrain)
{
  int zone = 0;
  int i, top;
  char *argu = argument;

  if (IS_NPC(ch)) return;
  
  skip_spaces(&argu);
  if (!*argu || !is_number(argu))
  {
    send_to_char("Usage:  terrain <zone number>.\n\r",ch);
    return;
  }

  zone = atoi(argu);

  if (!olc_perms(ch, LEV_IMPL, zone))
    return;
    
    if (!REAL_ZONE(zone))
    {
	send_to_char("Invalid zone number.\n\r", ch);
	return;
    }

    if (ZONE_FLAGGED(zone, Z_LOCKED) && !ch->pc_specials->saved.zone_locked &&
 	GET_IDNUM(ch) != zone_table[zone].locked_id)
    {
	sprintf(buf, "Zone %3d already locked by %s\n\r",
		zone, get_name_by_id(zone_table[zone].locked_id));
	S2C();
	return;
    }

    if ((zone == 30 && GET_LEVEL(ch) < LEV_IMPL) || zone == 0)
    {
	send_to_char("Mesraht and Limbo cannot be adjusted!\n\r", ch);
	return;
    }

    if (ch->pc_specials->saved.zone_locked && ch->pc_specials->saved.zone_locked != zone)
    {
	send_to_char("You already have another zone locked.\n\r", ch);
	return;
    }

  if (!ch->pc_specials->saved.zone_locked && GET_LEVEL(ch) < LEV_IMPL)
    {
      send_to_char("You must lock that zone.\n\r",ch);
      return;
    }
   
   top = zone*100+99;
   for (i = zone * 100; i <= top; i++)
     if (real_room(i) >= 0)
     {
       sprintf(buf, "%d", i);
       do_room_terrain(ch, buf, 0, 0);
     }
   send_to_char("Ok.  Zone editted.\n\r",ch);
}

/* RoA - - balances every mob in a zone according to chart levels and exp*/
ACMD(do_adjust_zone)
{
   int zone, i, top;

   if (IS_NPC(ch)) return;
   one_argument(argument, arg);
   if (!arg || !is_number(arg))
   {
     send_to_char("Usage:  zoneadjust <zone num>.\n\r",ch);
     return;
   }
   zone = atoi(arg);
    
   if (!olc_perms(ch, LEV_IMPL, zone))
     return;
    
    if (!REAL_ZONE(zone))
    {
	send_to_char("Invalid zone number.\n\r", ch);
	return;
    }

    if (ZONE_FLAGGED(zone, Z_LOCKED) && !ch->pc_specials->saved.zone_locked &&
 	GET_IDNUM(ch) != zone_table[zone].locked_id)
    {
	sprintf(buf, "Zone %3d already locked by %s\n\r",
		zone, get_name_by_id(zone_table[zone].locked_id));
	S2C();
	return;
    }

    if ((zone == 30 && GET_LEVEL(ch) < LEV_IMPL) || zone == 0)
    {
	send_to_char("Mesraht and Limbo cannot be adjusted!\n\r", ch);
	return;
    }

    if (ch->pc_specials->saved.zone_locked && ch->pc_specials->saved.zone_locked != zone)
    {
	send_to_char("You already have another zone locked.\n\r", ch);
	return;
    }

  if (!ch->pc_specials->saved.zone_locked && GET_LEVEL(ch) < LEV_IMPL)
    {
      send_to_char("You must lock that zone.\n\r",ch);
      return;
    }
   
   top = zone*100+99;
   for (i = zone * 100; i <= top; i++)
     if (real_mobile(i) >= 0)
     {
       sprintf(buf, "%d", i);
       do_adjust(ch, buf, 0, 0);
       send_to_char("\n\r",ch);
     }
}

ACMD(do_calc_zones)
{
  int zone, i, levels, mobs, top;
  int rnum;
  chdata *mob;

  if (!ch)  /* called from db.c on bootup */
  {
    for (zone = 1; zone < NUM_ZONES; zone++)
      if (REAL_ZONE(zone))
      {
        top = zone*100+99;
        levels = mobs = 0;
        for (i = zone * 100; i <= top; i++)
          if ((rnum = real_mobile(i)) >= 0)
          {
  	    mob = &mob_proto[rnum];
	    levels += get_mob_chart_level(mob);
	    mobs++;
          }
        if (mobs)
	  zone_levels[zone] = (levels/mobs);
      }
    return;
  }

   if (IS_NPC(ch)) return;

   one_argument(argument, arg);

   if (!arg || !is_number(arg))
   {
     send_to_char("Usage:  average <zone num>.\n\r",ch);
     return;
   }

    zone = atoi(arg);    
    if (!REAL_ZONE(zone))
    {
	send_to_char("Invalid zone number.\n\r", ch);
	return;
    }

   top = zone*100+99;
   levels = mobs = 0;
   for (i = zone * 100; i <= top; i++)
     if ((rnum = real_mobile(i)) >= 0)
     {
	mob = &mob_proto[rnum];
	levels += get_mob_chart_level(mob);
	mobs++;
     }

   if (!mobs)
   {
     send_to_char("There are no mobs in that zone.\n\r",ch);
     return;
   }

   sprintf(buf, "Zone: %s\n\rAverage MOB level: %%B%d%%0.\n\r",
	   zone_table[zone].name, (levels/mobs));
   S2C();
}

ACMD(do_shutdown)
{
   extern int	circle_shutdown, circle_reboot;
   chdata *tmp;

   if (IS_NPC(ch))
      return;

   if (subcmd != SCMD_SHUTDOWN)
   {
      send_to_char("Type %Bshutdown%0 completely to shutdown.\n\r", ch);
      return;
   }
   one_argument(argument, arg);
   if (!*arg)
   {
      sprintf(buf, "IMMUPD: Shutdown by %s.", GET_NAME(ch));
      send_to_all(buf);
      log(buf);
      circle_shutdown = 1;
   }
   else
   if (!str_cmp(arg, "reboot"))
   {
      sprintf(buf, "IMMUPD: Reboot by %s.", GET_NAME(ch));
      log(buf);
      send_to_all("Rebooting.. come back in a minute or two.");
      roa_system("touch ../.fastboot");
      circle_shutdown = circle_reboot = 1;
   }
   else
   if (!str_cmp(arg, "die"))
   {
      sprintf(buf, "IMMUPD: Shutdown by %s.", GET_NAME(ch));
      send_to_all(buf);
      log(buf);
      roa_system("touch ../.killscript");
      circle_shutdown = 1;
   }
   else
   if (!str_cmp(arg, "pause"))
   {
      sprintf(buf, "IMMUPD: Shutdown by %s.", GET_NAME(ch));
      send_to_all(buf);
      log(buf);
      roa_system("touch ../pause");
      circle_shutdown = 1;
   }
   else
      send_to_char("Unknown shutdown option.\n\r", ch);

   if (circle_shutdown)
     for(tmp = character_list; tmp; tmp=tmp->next)
       if (IS_PC(tmp) && VT100(tmp))
 	 resetscr(tmp);
}

ACMD(do_rsnoop)
{
  char *argu = argument;
  int rnum;

  if (!ch->desc || INVALID_ROOM(ch->in_room))
    return;

//  if (ROOM_FLAGGED(ch->in_room, NO_SNOOP))
//  {
//    send_to_char("This room is protected from being snooped.\n\r",ch);
//    return;
//  }

  skip_spaces(&argu);
  if (!*argu)
  {
    if (!ch->desc->room_snooping)
      send_to_char("You aren't snooping any room.\n\r",ch);
    else
    {
      remove_room_snooper(&world[ch->desc->room_snooping], ch->desc);
      send_to_char("You stop snooping the room.\n\r",ch);
    }
    return;
  }

  if (*argu == '.')
    rnum = ch->in_room;
  else
  if (!is_number(argu))
  {
    send_to_char("Usage: rsnoop < . || room vnum >\n\r",ch);
    return;
  }
  else
  if ((rnum = real_room(atoi(argu))) <= 0)
  {
    send_to_char("Invalid room.\n\r",ch);
    return;
  }

  if (ch->desc->room_snooping)
    remove_room_snooper(&world[ch->desc->room_snooping], ch->desc);
  add_room_snooper(&world[rnum], ch->desc);
  sprintf(buf, "You begin snooping room %%B%%6#%d%%0.\n\r",
	  world[rnum].number);
  S2C();
}

void stop_snooping(chdata *ch)
{
  if (!ch->desc->snooping)
    send_to_char("You aren't snooping anyone.\r\n", ch);
  else {
    send_to_char("You stop snooping.\r\n", ch);
    ch->desc->snooping->snoop_by = NULL;
    ch->desc->snooping = NULL;
  }
}

ACMD(do_snoop)
{
  chdata *victim;
  chdata *tch;

  if (!ch->desc)
    return;

  one_argument(argument, arg);

  if (!*arg)
  {
   stop_snooping(ch);
   return;
  }

  if (!(victim = get_char_vis(ch, arg)))
  {
     send_to_char("No such person around.\n\r", ch);
     return;
  }

  if (!victim->desc)
  {
     send_to_char("There's no link.. nothing to snoop.\n\r", ch);
     return;
  }

  if (victim == ch)
  {
    stop_snooping(ch);
    return;
  }

  if (victim->desc->snoop_by)
  {
     send_to_char("Busy already. \n\r", ch);
     return;
  }

  if (victim->desc->snooping == ch->desc)
  {
    send_to_char("Cannot snoop in circles.\n\r",ch);
    return;
  }

  if (victim->desc->original)
    tch = victim->desc->original;
  else
    tch = victim;

  if (GET_LEVEL(tch) >= GET_LEVEL(ch)) {
    send_to_char("You can't.\r\n", ch);
    return;
  }
  send_to_char("Ok.\n\r", ch);

  if (ch->desc->snooping)
    ch->desc->snooping->snoop_by = NULL;

  ch->desc->snooping = victim->desc;
  victim->desc->snoop_by = ch->desc;
}

ACMD(do_checksnoop)
{
  chdata *snooper;

  if (IS_NPC(ch) || !ch->desc) return;

  if (!ch->desc->snoop_by)
  {
    send_to_char("You are not being snooped.\n\r",ch);
    return;
  }

  snooper = ch->desc->snoop_by->character;
  if (!snooper || (GET_LEVEL(snooper) >= LEV_CIMP && 
      !snooper->pc_specials->saved.snooptell))
  {
    send_to_char("You are not being snooped.\n\r",ch);
    return;
  }

  send_to_char("You are currently being snooped.\n\r",ch);
  return;
}

ACMD(do_snooptell)
{
  if (IS_NPC(ch)) return;
  if (GET_LEVEL(ch) < LEV_CIMP) return;

  if (ch->pc_specials->saved.snooptell)
   ch->pc_specials->saved.snooptell = FALSE;
  else
   ch->pc_specials->saved.snooptell = TRUE;

  if (ch->pc_specials->saved.snooptell)
    send_to_char("Your snooptell is now ON.\n\r",ch);
  else
    send_to_char("Your snooptell is now OFF. (Nobody will know if you snoop.)\n\r",ch); 
  return;
}

ACMD(do_switch)
{
   chdata *victim;

   if (IS_NPC(ch))
      return;

   one_argument(argument, arg);

   if (!*arg)
      send_to_char("Switch with who?\n\r", ch);
   else
   {
      if (!(victim = get_char(arg)))
	 send_to_char("They aren't here.\n\r", ch);
      else
      {
	 if (ch == victim)
         {
            send_to_char("You switch with yourself... oook.\n\r", ch);
	    return;
	 }

	 if (victim->desc || (IS_PC(victim))) {
	    send_to_char("You can't do that, the body is already in use!\n\r", ch);
	 } else {
	    send_to_char("Ok.\n\r", ch);

	    ch->desc->character = victim;
	    ch->desc->original = ch;

	    victim->desc = ch->desc;
	    ch->desc = 0;
	 }
      }
   }
}

ACMD(do_zswitch)
{
  chdata *vict;
  int privnum;

  if (IS_NPC(ch)) return;

  if(!*argument)
  {
    send_to_char("Switch with who?\r\n", ch);
    return;
  }

  one_argument(argument, arg);
  vict = get_char_room_vis(ch, arg);
  if (!vict)
  {
    send_to_char("No such mob in this room.\n\r", ch);
    return;
  }
    
  if( IS_PC(vict))
  {
    send_to_char("Yeah, right.\n\r", ch);
    return;
  }

  if (vict->desc)
  {
    send_to_char("This body is already in use!\r\n", ch);
    return;
  }

  privnum = GET_MOB_VNUM(vict) / 100;
  if (!privnum) return;

  if (!olc_perms(ch, LEV_AIMP, privnum))
    return;

  do_switch(ch, argument, 0, 0);
}

void unswitch(chdata *ch)
{
  send_to_char("You return to your original body.\n\r", ch);
  ch->desc->character = ch->desc->original;
  ch->desc->original = 0;
  ch->desc->character->desc = ch->desc;
  ch->desc = 0;
}

void unbecome(chdata *ch)
{
  act("$n's eyes suddenly turn %4dark%0 for a moment.",TRUE,ch,0,0,TO_ROOM);
  act("You begin to transform into your original form.",FALSE,ch,0,0,TO_CHAR);
  REMOVE_BIT(CHAR_FLAGS(ch), CH_BECAME);
  unswitch(ch);
}


ACMD(do_return)
{
   if (!ch->desc)
      return;

   if (!ch->desc->original)
   {
      send_to_char("That simply is not possible...\n\r", ch);
      return;
   }
   else
   {
      // rangers and others can be pseudo switched by affect -roa 
      // affect_modify will call unbecome() to 'return' them
      if (CHAR_FLAGGED(ch, CH_BECAME))
	affect_from_char(ch, SKILL_BECOME);
      else
        unswitch(ch);
   }
}

ACMD(do_reimb)
{
  chdata *victim;
  obdata *obj;
  int	number, r_num;

  BOOL reimburse(chdata *ch);

  if (IS_NPC(ch))
    return;

  two_arguments(argument, buf, buf2);

  if (!*buf || !*buf2)
  {
    send_to_char("Usage: reimb <playername> <(vnum) || all>\n\r", ch);
    return;
  }

  if (*buf)
  {
    if (!(victim = get_char_vis(ch, buf)))
    {
      send_to_char("That player is not here.\n\r", ch);
      return;
    }
  }
  else
  {
    send_to_char("Reimburse who?\n\r", ch);
    return;
  }

  if (is_number(buf2))
  {
    number = atoi(buf2);
    if (!olc_perms(ch, LEV_AIMP, number/100))
      return;

    if ((r_num = real_object(number)) < 0)
    {
      send_to_char("There is no object with that number.\n\r", ch);
      return;
    }

    obj = read_object(r_num, REAL);
    obj_to_char(obj, victim);
    act("$n makes a strange magical gesture.", TRUE, ch, 0, 0, TO_ROOM);
    act("$n has created $p!", FALSE, ch, obj, 0, TO_ROOM);
    act("You create $p.", FALSE, ch, obj, 0, TO_CHAR);
    sprintf(buf, "IMMUPD: %s reimbursed %s (#%d) to %s", GET_NAME(ch), 
	    obj->shdesc, GET_OBJ_VNUM(obj), GET_NAME(victim));
    mudlog(buf, NRM, GET_LEVEL(ch), TRUE);
  }
  else
  if (str_cmp(buf2, "all") == 0)
  {
     if (!reimburse(victim))
     {
	send_to_char("Reimbursement file not found.\n\r",ch);
	return;
     }
     else
     {
      act("$n makes a strange magical gesture.", TRUE, ch, 0, 0, TO_ROOM);
      send_to_char("You have been reimbursed.  Good Hunting.\n\r",victim);
      send_to_char("Ok.\n\r",ch);
      sprintf(buf, "IMMUPD: %s reimbursed %%B%%6ALL%%0 to %s", GET_NAME(ch), 
	      GET_NAME(victim));
      mudlog(buf, NRM, GET_LEVEL(ch), TRUE);
     }
  }
  else
  {
     send_to_char("Usage: reimb <playername> <(vnum) || all>\n\r", ch);
     return;
  }
}

// Heavily re-written to allow loading by name. 03/23/98 -callahan
ACMD(do_load)
{
  chdata *mob;
  obdata *obj;
  char type[100], num[100];
  int number;
  char *any_one_arg(char *argument, char *first_arg);
  extern int top_of_mobt;
  extern int top_of_objt;

  if (IS_NPC(ch))
    return;
    
  argument = one_argument(argument, type);

  any_one_arg(argument, num);
      
  if (isdigit(*num))
    number = atoi(num);
  else
    number = -1;

  if (is_abbrev(type, "mobile")) {

    if (!(number < 0))
      if (!olc_perms(ch, LEV_CIMP, number/100))
        return;

    if (number < 0) {
      for (number = 0; number <= top_of_mobt; number++)
        if (isname(num, mob_proto[number].player.name))
          break;
      if (number > top_of_mobt)
        number = -1;
    } else
      number = real_mobile(number);
        
    if (number < 0 || number > top_of_mobt) {
      send_to_char("There is no such monster.\n\r", ch);
      return;
    }
 
    if (!(mob = read_mobile(number, REAL))) {
      send_to_char("Unable to load that mobile.\n\r", ch);
      return;
    }

    char_to_room(mob, ch->in_room);

    act("$n makes a quaint, magical gesture with one hand.", TRUE, ch,
        0, 0, TO_ROOM);
    act("$n has created $N!", FALSE, ch, 0, mob, TO_ROOM);
    act("You create $N.", FALSE, ch, 0, mob, TO_CHAR);
    sprintf(buf, "IMMUPD: %s loaded %s (#%d) at %d", GET_NAME(ch), 
            GET_NAME(mob), GET_MOB_VNUM(mob), world[ch->in_room].number);
    mudlog(buf, NRM, GET_LEVEL(ch), TRUE);
  } else if (is_abbrev(type, "object")) {

    if (!(number < 0))
      if (!olc_perms(ch, LEV_CIMP, number/100))
        return;

    if (number < 0) {
      for (number = 0; number <= top_of_objt; number++)
        if (isname(num, obj_proto[number].name))
          break;
      if (number > top_of_objt)
        number = -1;
    } else
      number = real_object(number);
      
    if ( number < 0 || number > top_of_objt) {
      send_to_char("There is no such object.\n\r", ch);
      return;
    }

    obj = read_object(number, REAL);

    if (ITEM_TYPE(obj) == ITEM_BOARD)
      obj_to_room(obj, ch->in_room);
    else
      obj_to_char(obj, ch);

    act("$n makes a strange magical gesture.", TRUE, ch, 0, 0, TO_ROOM);
    act("$n has created $p!", FALSE, ch, obj, 0, TO_ROOM);
    act("You create $p.", FALSE, ch, obj, 0, TO_CHAR);
    sprintf(buf, "IMMUPD: %s loaded %s (#%d) at %d", GET_NAME(ch), 
            obj->shdesc, GET_OBJ_VNUM(obj), world[ch->in_room].number);
    mudlog(buf, NRM, GET_LEVEL(ch), TRUE);
  } else
    send_to_char("Usage: load { obj | mob } { <vnum> | <name> }\n\r", ch);
}

/* clean r room of all mobiles and objects */
ACMD(do_purge)
{
   chdata *vict, *next_v;
   obdata *obj, *next_o;

   if (IS_NPC(ch))
      return;

   if (GET_LEVEL (ch) < LEV_GOD &&
       (ch->pc_specials->saved.zone_locked == 0 || 
	ch->pc_specials->saved.zone_locked < ch->pc_specials->saved.olc_min_zone ||
	ch->pc_specials->saved.zone_locked > ch->pc_specials->saved.olc_max_zone ||
	world[ch->in_room].zone != ch->pc_specials->saved.zone_locked))
   {
       send_to_char("You don't have privileges to edit this zone.\n\r", ch);
       return;
   }
    
   one_argument(argument, buf);

   if (*buf)  /* argument supplied. destroy single object or char */
   {
      if ((vict = get_char_room_vis(ch, buf)))
      {
	 if (IS_PC(vict) && (GET_LEVEL(ch) <= GET_LEVEL(vict)))
         {
	    send_to_char("Fuuuuuuuuu!\n\r", ch);
	    return;
	 }
	 act("$n disintegrates $N.", FALSE, ch, 0, vict, TO_NOTVICT);
	 if (IS_NPC(vict))
	    extract_char(vict);
         else
         {
	    sprintf(buf, "IMMUPD: %s purged %s.", GET_NAME(ch), GET_NAME(vict));
	    mudlog(buf, BRF, LEV_GOD, TRUE);
	    if (vict->desc)
            {
	       close_socket(vict->desc);
	       vict->desc = 0;
	    }
	    extract_char(vict);
	 }
      }
      else
      if ((obj = get_obj_in_list_vis(ch, buf, world[ch->in_room].contents)))
      {
	 act("$n destroys $p.", FALSE, ch, obj, 0, TO_ROOM);
	 extract_obj(obj);
      }
      else
      if (GET_LEVEL(ch) == LEV_IMPL && !str_cmp(buf, "zone"))
        purge_zone(world[ch->in_room].zone);
      else
      if (is_abbrev(buf, "affects"))
      {
	free_room_affects(world[ch->in_room].room_affects);
	world[ch->in_room].room_affects = NULL;
	send_to_char("Room affects purged.\n\r",ch);
      }
      else
      {
         send_to_char("Purge target not found.\n\r", ch);
	 return;
      }
      send_to_char("Ok.\n\r", ch);
   }
   else
   { /* no argument. clean out the room */
      if (IS_NPC(ch))
      {
	 send_to_char("Don't... You would only kill yourself..\n\r", ch);
	 return;
      }
      act("$n gestures... You are surrounded by %B%3scorching%0 flames!", 
          FALSE, ch, 0, 0, TO_ROOM);
      for (vict = world[ch->in_room].people; vict; vict = next_v)
      {
	 next_v = vict->next_in_room;
	 if (IS_NPC(vict))
	    extract_char(vict);
      }
      for (obj = world[ch->in_room].contents; obj; obj = next_o)
      {
	 next_o = obj->next_content;
	 extract_obj(obj);
      }
      free_room_affects(world[ch->in_room].room_affects);
      world[ch->in_room].room_affects = NULL;
      send_to_char("Room purged.\n\r",ch);
   }
}

ACMD(do_vstat)
{
   chdata *mob;
   obdata *obj;
   int	number, r_num;

   if (IS_NPC(ch))
      return;

   two_arguments(argument, buf, buf2);

   if (!*buf || !*buf2 || !isdigit(*buf2))
   {
      send_to_char("Usage: vstat { obj | mob } <vnum>\n\r", ch);
      return;
   }

   if ((number = atoi(buf2)) < 0)
   {
      send_to_char("Vnum must be a positive integer.\n\r", ch);
      return;
   }
   if (is_abbrev(buf, "mob"))
   {
      if ((r_num = real_mobile(number)) < 0)
      {
         send_to_char("There is no mobile with that vnum.\n\r", ch);
	 return;
      }

      if (!(mob = read_mobile(r_num, REAL)))
      {
	send_to_char("Unable to load that mobile.\n\r", ch);
	return;
      }

      char_to_room(mob,0);
      do_stat_character(ch, mob);
      extract_char(mob);
   }
   else
   if (is_abbrev(buf, "obj"))
   {
      if ((r_num = real_object(number)) < 0)
      {
         send_to_char("There is no object with that vnum.\n\r", ch);
	 return;
      }
      obj = read_object(r_num, REAL);
      do_stat_object(ch, obj);
    
      extract_obj(obj);
   }
   else
     send_to_char("Usage: vstat <obj | mob> <vnum>\n\r", ch);
}


/* Give pointers to the five abilities AND give em a language (ROA) */
// debug log tables, function overhaul  12/3/97 -jtrhone
// now update for new gskills array... 6/28/98 -jtrhone
void	roll_real_abils(chdata *ch)
{
  int	i, j, k, temp, max;
  ubyte table[5], rolls[4];
  int   test, cnt = 0;

  int num_remorts(chdata *ch);

  // if implementor, run a little test and report results via debug
  test = (GET_LEVEL(ch) >= LEV_IMPL);
  do 
  {
    // clear out table and rolls
    memset((char *)&table, 0, sizeof(table));
    memset((char *)&rolls, 0, sizeof(rolls));

    for (i = 0; i < 5; i++) 
    {
      for (j = 0; j < 4; j++)
        rolls[j] = number(1, 6);

      temp = rolls[0] + rolls[1] + rolls[2] + rolls[3] - MIN(rolls[0], MIN(rolls[1], MIN(rolls[2], rolls[3])));

      for (k = 0; k < 5; k++)
        if (table[k] < temp)
          SWITCH(temp, table[k]);
    }
    
    if ((table[0] >= 18 && table[1] >= 18 && table[2] >= 18) || (cnt++ >= 32767))
      break;

  } while (test);

// mudlog to bug the rolled table now... if you want...
//  sprintf(buf, "PLRUPD: %s rolled [ %d | %d | %d | %d | %d ].", GET_NAME(ch),
//          table[0], table[1], table[2], table[3], table[4]);
//  mudlog(buf, BUG, LEV_IMM, TRUE);

  if (test)
  {
    sprintf(buf, "PLRUPD: Previous roll took roughly %d attempts.", cnt);
    mudlog(buf, BUG, LEV_IMM, TRUE);
  }

  // now calculate regular stats based on clarray attribute table 
  // and rolled table above (uses clarray now, 7/30/98 -jtrhone)
  ch->real_abils.str     = table[clarray[(int)GET_CLASS(ch)].str];
  ch->real_abils.intel   = table[clarray[(int)GET_CLASS(ch)].intel];
  ch->real_abils.wis     = table[clarray[(int)GET_CLASS(ch)].wis];
  ch->real_abils.dex     = table[clarray[(int)GET_CLASS(ch)].dex];
  ch->real_abils.con     = table[clarray[(int)GET_CLASS(ch)].con];
  ch->real_abils.str_add = 0;

  // apply racial mods...
  ch->real_abils.str     += rcarray[GET_RACE(ch)].str;
  ch->real_abils.str_add += rcarray[GET_RACE(ch)].stradd;
  ch->real_abils.intel   += rcarray[GET_RACE(ch)].intel;
  ch->real_abils.wis     += rcarray[GET_RACE(ch)].wis;
  ch->real_abils.dex     += rcarray[GET_RACE(ch)].dex;
  ch->real_abils.con     += rcarray[GET_RACE(ch)].con;
  ch->real_abils.cha      = MAX(3, MIN(ch->real_abils.cha, max));

  // calculate STRADD (moved after racial calcs)...
  switch (GET_CLASS(ch)) 
  {
    case CLASS_THIEF:
    case CLASS_RANGER:
    case CLASS_MONK:
    case CLASS_WARRIOR:
    case CLASS_BARD:
      if (ch->real_abils.str >= 18)
	 ch->real_abils.str_add += number(0, 100);
      break;
  }

  // no longer just madepts...6/28/98 -jtrhone
  // set learn flag on all languages up front...
  for (i = 0; i < MAX_GSKILLS; i++)
    if (GSKILL_FLAGGED(i, G_DIALECT))
      ch->gskills[i].learned = TRUE;

  // everybody knows of runic... 7/8/98 -jtrhone
  ch->gskills[GSKILL_RUNIC].learned = TRUE;

  // initial language abilities based on race...
  set_gskill(ch, LANG_COMMON, number(20, 40));
  set_gskill(ch, rcarray[GET_RACE(ch)].lang, number(70, 99));

  // if implementor, can have a max of 25, else max is 18
  max = (GET_LEVEL(ch) == LEV_IMPL) ? 25 : 18;

  // make sure all stats are in range (just in case...)
  ch->real_abils.str     = MAX(3, MIN(ch->real_abils.str,     max));
  ch->real_abils.str_add = MAX(0, MIN(ch->real_abils.str_add, 100));
  ch->real_abils.intel   = MAX(3, MIN(ch->real_abils.intel,   max));
  ch->real_abils.wis     = MAX(3, MIN(ch->real_abils.wis,     max));
  ch->real_abils.dex     = MAX(3, MIN(ch->real_abils.dex,     max));
  ch->real_abils.con     = MAX(3, MIN(ch->real_abils.con,     max));
  ch->real_abils.cha     = MAX(3, MIN(ch->real_abils.cha,     max));

  // now dupe reals into affs
  ch->aff_abils = ch->real_abils;
}

// fresh start a player, in case of advance or remort -roa
void	do_start(chdata *ch, BOOL remort)
{
   void	advance_level(chdata *ch);

   if (IS_NPC(ch)) 
   {
      send_to_char("Umm.... no.\n\r", ch );
      return;
   }

   if (GET_LEVEL(ch) != LEV_IMPL)
     GET_LEVEL(ch) = GET_EXP(ch) = 1;

   roll_real_abils(ch);
   ch->points.max_hit  = 10;  /* These are BASE numbers   */

   switch (GET_CLASS(ch)) {
   case CLASS_THIEF :
      set_skill(ch, SKILL_SNEAK, 10);
      set_skill(ch, SKILL_HIDE, 5);
      set_skill(ch, SKILL_STEAL, 15);
      set_skill(ch, SKILL_BACKSTAB, 10);
      set_skill(ch, SKILL_PICK_LOCK, 10);
      break;
   case CLASS_WARRIOR:
      set_skill(ch, SKILL_KICK, 5);
      break; 
    default: break;
   }

   advance_level(ch);

   GET_HIT(ch) = GET_MAX_HIT(ch);
   GET_MANA(ch) = GET_MAX_MANA(ch);
   GET_MOVE(ch) = GET_MAX_MOVE(ch);

  if (!remort)
  {
    set_title(ch);
    GET_COND(ch, THIRST) = 24;
    GET_COND(ch, FULL) = 24;
    GET_COND(ch, DRUNK) = 0;

    ch->player.time.played = 0;
    ch->player.time.logon = time(0);
  }
  else
  {
    ch->points.max_move  = number(50, 100); 
    ch->points.max_mana  = number(50, 100);
  }
}

ACMD(do_advance)
{
   int	gain_exp(chdata *ch, int gain);
   chdata *victim;
   char	name[100], level[100];
   int	adv, newlevel = 1;

   if (IS_NPC(ch))
      return;

   half_chop(argument, name, buf);
   one_argument(buf, level);

   if (*name)
   {
      if (!(victim = get_char_vis(ch, name)))
      {
	 send_to_char("That player is not here.\n\r", ch);
	 return;
      }
   }
   else
   {
      send_to_char("Advance who?\n\r", ch);
      return;
   }

   if (ch == victim)
   {
      send_to_char("You cannot advance yourself.\n\r", ch);
      return;
   }

   if (IS_NPC(victim))
   {
      send_to_char("You cannot advance NPCs.\n\r", ch);
      return;
   }

   if (!GET_LEVEL(victim))
      adv = 1;
   else 
   if (!*level) 
   {
      send_to_char("You must supply a level number.\n\r", ch);
      return;
   } 
   else 
   {
      if (!isdigit(*level)) 
      {
	 send_to_char("Second argument must be a positive integer.\n\r", ch);
	 return;
      }
      newlevel = atoi(level);
      if (newlevel == GET_LEVEL(victim))
      {
	send_to_char("Advance to the same level??\n\r",ch);
	return;
      }
      if (newlevel < GET_LEVEL(victim)) 
      {
	 do_start(victim, FALSE);
	 GET_LEVEL(victim) = newlevel;
      }

      adv = newlevel - GET_LEVEL(victim);
   }

   if (((adv + GET_LEVEL(victim)) > 1) && (GET_LEVEL(ch) < LEV_IMPL)) 
   {
      send_to_char("Access Denied.\n\r", ch);
      return;
   }

   if ((adv + GET_LEVEL(victim)) > LEV_IMPL) 
   {
      send_to_char("Level out of range.\n\r",ch);
      return;
   }

   act("$n makes some strange gestures.\n\rA strange feeling comes upon you,"
       "\n\rLike a giant hand, light comes down from\n\rabove, grabbing your"
       "body, that begins\n\rto pulse with colored lights from inside.\n\rYo"
       "ur head seems to be filled with demons\n\rfrom another plane as your"
       " body dissolves\n\rto the elements of time and space itself.\n\rSudde"
       "nly a silent explosion of light snaps\n\ryou back to reality.  You fee"
       "l slightly\n\rdifferent.", FALSE, ch, 0, victim, TO_VICT);

   send_to_char("Ok.\n\r", ch);

   if (!GET_LEVEL(victim)) 
     do_start(victim, FALSE);
   else 
   {
      if (GET_LEVEL(victim) < LEV_IMPL) 
      {
	 sprintf(buf, "IMMUPD: %s advanced %s to level %d (from %d)",
	     GET_NAME(ch), GET_NAME(victim), newlevel, GET_LEVEL(victim));
	 log(buf);
	 gain_exp_regardless(victim, (exp_table[GET_CLASS(victim)-1]
	     [GET_LEVEL(victim)+adv]) - GET_EXP(victim));
	 save_char(victim, NOWHERE);
      } 
      else 
      {
	 send_to_char("Some idiot just tried to advance your level.\n\r", victim);
	 send_to_char("IMPOSSIBLE!  IDIOTIC!\n\r", ch);
      }
   }
}

ACMD(do_restore)
{
   chdata *victim;
   int	i;
   dsdata *d;

   void	update_pos( chdata *victim );

   if (IS_NPC(ch))
      return;

   one_argument(argument, buf);
   if (!*buf)
      send_to_char("Usage: restore <plr name>.\n\r", ch);
   else
   if (!str_cmp(buf, "all") && (GET_LEVEL(ch) >= LEV_CIMP))
   {
      send_to_char("You restore the world!\n\r",ch);
      sprintf(buf, "IMMUPD: %s restored all.", GET_NAME(ch));
      mudlog(buf, CMP, MAX(LEV_IMM, GET_INVIS_LEV(ch)), FALSE); 
      for (d = descriptor_list; d; d = d->next)
        if (D_CHECK(d) && IS_PC(d->character) && (d->character != ch))
        {
          act("You have been %B%6restored%0 by $n!", FALSE, ch, 0, d->character, TO_VICT);
          if (GET_HIT(d->character) < GET_MAX_HIT(d->character))
            GET_HIT(d->character) = GET_MAX_HIT(d->character);
          if (GET_MANA(d->character) < GET_MAX_MANA(d->character))
            GET_MANA(d->character) = GET_MAX_MANA(d->character);
          if (GET_MOVE(d->character) < GET_MAX_MOVE(d->character))
            GET_MOVE(d->character) = GET_MAX_MOVE(d->character);
        }
   }
   else
   if (!(victim = get_char(buf)))
      send_to_char("No-one by that name in the world.\n\r", ch);
   else
   {
      GET_MANA(victim) = GET_MAX_MANA(victim);
      GET_HIT(victim) = GET_MAX_HIT(victim);
      GET_MOVE(victim) = GET_MAX_MOVE(victim);

      // start from skill 1(armor) now  1/18/98 -jtrhone
      if ((GET_LEVEL(ch) >= LEV_CIMP) && (GET_LEVEL(victim) >= LEV_IMM)) 
      {
	 for (i = 1; i < MAX_SKILLS; i++)
	    set_skill(victim, i, 100);

	 for (i = 0; i < MAX_GSKILLS; i++)
	    set_gskill(victim, i, 100);

	 GET_WLEVEL(victim) = LEV_IMM;

	 if (GET_LEVEL(victim) >= LEV_IMPL)
         {
	    victim->real_abils.str_add = 100;
	    victim->real_abils.intel = 25;
	    victim->real_abils.wis = 25;
	    victim->real_abils.dex = 25;
	    victim->real_abils.str = 25;
	    victim->real_abils.con = 25;
            victim->real_abils.cha = 25;
	 }
	 victim->aff_abils = victim->real_abils;
      }
      update_pos(victim);
      send_to_char("Done.\n\r", ch);
      act("You have been fully restored by $N!", FALSE, victim, 0, ch, TO_CHAR);
   }
}

ACMD(do_invis)
{
   int	level;

   if (IS_NPC(ch)) 
   {
      send_to_char("Yeah.. like a mob knows how to bend light.\n\r", ch);
      return;
   }

   one_argument (argument, arg);
   if (!*arg)
   {
      if (GET_INVIS_LEV(ch) > 0)
      {
	 GET_INVIS_LEV(ch) = 0;
	 sprintf(buf, "You are now fully visible.\n\r");
      }
      else
      {
	 GET_INVIS_LEV(ch) = GET_LEVEL(ch);
	 sprintf(buf, "Your invisibility level is %d.\n\r", GET_LEVEL(ch));
      }
   }
   else
   {
      level = atoi(arg);
      if (level > GET_LEVEL(ch))
      {
	 send_to_char("You can't go invisible above your own level.\n\r", ch);
	 return;
      }
      else
      if (level < 1)
      {
	 GET_INVIS_LEV(ch) = 0;
	 sprintf(buf, "You are now fully visible.\n\r");
      }
      else
      {
	 GET_INVIS_LEV(ch) = level;
         sprintf(buf, "Invisibility level: %%6%d%%0.\n\r", level);
      }
   }
   S2C();
}

// updated for new cmd_info structure 4/9/98 -jtrhone
ACMD(do_grant)
{
  chdata *victim;
  char *argu = argument; 
  char name[MAX_INPUT_LENGTH];
  char ccmd[MAX_INPUT_LENGTH];
  int cmdnum, i, l = 0;

  if (IS_NPC(ch))
  {
     send_to_char("Umm.... no.\n\r", ch );
     return;
  }

  skip_spaces(&argu);
  if (!*argu)
  {
    send_to_char("Grants available to you:\n\r",ch);
    for (*buf = '\0', i = 1; i < top_of_cmds; i++)
      if (CMD_GFLAGS(i) && GET_LEVEL(ch) >= cmd_info[i].glevel) 
      {
         sprintf(buf + strlen(buf), "%%6%10.10s%%0 ",cmd_info[i].comm);
         if (!(++l % 6)) 
           strcat(buf, "\n\r");
      }
    strcat(buf, "\n\r");
    page_string(ch->desc, buf, 1);
    return;
  }

  half_chop(argu, name, argu);
  half_chop(argu, ccmd, argu); 

  if (!*name || !*ccmd)
  {
    send_to_char("Usage: grant <victim> <command>.\n\r", ch);
    return;
  }

  // Updated get_player_vis() for 0.playername, 03/22/98 -callahan
  if (!(victim = get_player_vis(ch, name, FALSE)))
  {
    send_to_char("There is no such player.\n\r",ch);
    return;
  }

  cmdnum = get_command(ccmd);
  if (cmdnum < 0 || !CMD_GFLAGS(cmdnum))
  {
    send_to_char("That command is not grantable.\n\r",ch);
    return;
  }

  if (GET_LEVEL(ch) < cmd_info[cmdnum].glevel)
  {
    send_to_char("You're unable to grant that command.\n\r", ch);
    return;
  }

  if (!IS_IMMORTAL(victim))
  {
    send_to_char("You can't grant commands to mortals.\n\r",ch);
    return;
  }

  if (!GRNT_FLAGGED(victim, CMD_GFLAGS(cmdnum)))
  {
    SET_BIT(GRNT_FLAGS(victim), CMD_GFLAGS(cmdnum));
    send_to_char("Okay, command granted.\n\r",ch);
    sprintf(buf, "You have been granted: %%3%s%%0\n\r", cmd_info[cmdnum].comm);
    send_to_char(buf, victim);
    return;
  }
  else
  {
    REMOVE_BIT(GRNT_FLAGS(victim), CMD_GFLAGS(cmdnum));
    send_to_char("Okay, command ungranted.\n\r",ch);
    sprintf(buf, "Command %%3%s%%0 ungranted.\n\r", cmd_info[cmdnum].comm);
    send_to_char(buf, victim);
    return;
  }
}

ACMD(do_gecho)
{
   dsdata *pt;
   char *argu = argument;

   if (IS_NPC(ch))
      return;

   skip_spaces(&argu);

   if (!*argu)
      send_to_char("Usage: gecho <argument>.\n\r", ch);
   else
   {
      sprintf(buf, "%s\n\r", argu);
      for (pt = descriptor_list; pt; pt = pt->next)
	 if (D_CHECK(pt) && pt->character != ch)
	    act(buf, FALSE, ch, 0, pt->character, TO_VICT);
      if (PRF_FLAGGED(ch, PRF_NOREPEAT))
	 send_to_char("Ok.\n\r", ch);
      else
	 S2C();
      sprintf(buf2, " IMMUPD: %s gechoed: %s ",GET_NAME(ch),buf);
      mudlog(buf2, CMP, MAX(LEV_IMM, GET_INVIS_LEV(ch)), FALSE);
   }
}

ACMD(do_loadset)
{
  if (IS_NPC(ch)) 
    return;

  if (strlen(argument) > MAX_INPUT_LENGTH)
    return;

  one_argument(argument, arg);

  if (!*arg)
  {
    sprintf(buf, "LoadRoom is: %%6%d%%0 \n\r",ch->pc_specials->saved.load_room);
    S2C();
    return;
  }
  
  if (!is_number(arg))
  {
    send_to_char("Usage: loadset <room vnum>.\n\r",ch);
    return;
  } 
  else
  {
    ch->pc_specials->saved.load_room = atoi(arg);
    sprintf(buf, "Loadroom set to %%6#%d%%0.\n\r",ch->pc_specials->saved.load_room); 
    S2C();
  }
}

ACMD(do_poofset)
{
   char	msg[MAX_POOFIN_LENGTH];
   char *argu = argument;

   if (IS_NPC(ch)) return;

   skip_spaces(&argu);

   if (strlen(argu) > MAX_POOFIN_LENGTH -1)
   {
      send_to_char("That poofin/out is too long...please shorten it.\n\r",ch);
      return;
   }

   if (!*argu)
      strcpy(msg, "");
   else
      strcpy(msg, argu);

   switch (subcmd)
   {
   case SCMD_POOFIN : 
     if (*msg) 
       strcpy(ch->pc_specials->saved.poofIn, msg);
     else
     {
       sprintf(buf, "Your poofin is: %s\n\r", ch->pc_specials->saved.poofIn);
       S2C();
     }
     break;
   case SCMD_POOFOUT: 
     if (*msg)
       strcpy(ch->pc_specials->saved.poofOut, msg);
     else
     {
       sprintf(buf, "Your poofout is: %s\n\r", ch->pc_specials->saved.poofOut);
       S2C();
     }
     break;
   default: 
     break;
   }
   send_to_char("Ok.\n\r", ch);
}

ACMD(do_dc)
{
   dsdata *d;
   int	num_to_dc;

   if (IS_NPC(ch))
   {
      send_to_char("Mobiles cannot cut connections...\n\r", ch);
      return;
   }

   if (!(num_to_dc = atoi(argument))) {
      send_to_char("Usage: DC <connection number> (type USERS for a list)\n\r", ch);
      return;
   }

   for (d = descriptor_list; d && d->desc_num != num_to_dc; d = d->next)
      ;

   if (!d)
   {
      send_to_char("No such connection.\n\r", ch);
      return;
   }

   if (d->character && GET_LEVEL(d->character) >= GET_LEVEL(ch)) {
      send_to_char("Unable to cut a higher connection priority...\n\r", ch);
      return;
   }

   close_socket(d);
   sprintf(buf, "Connection #%d closed.\n\r", num_to_dc);
   S2C();
   sprintf(buf, "IMMUPD: Connection closed by %s.", GET_NAME(ch));
   log(buf);
}

ACMD(do_wizlock)
{
   int	value;
   char *when;

   if (IS_NPC(ch)) return;

   one_argument(argument, arg);
   if (*arg) {
      value = atoi(arg);
      if (value < 0 || (value > LEV_IMPL+1) || (value > GET_LEVEL(ch))) {
         send_to_char("Invalid wizlock value.\n\r", ch);
         return;
      }
      restrict = value;
      when = "now";
   } else
      when = "currently";

   switch (restrict) {
   case 0 :
      sprintf(buf, "The game is %s completely open.\n\r", when);
      break;
   case 1 :
      sprintf(buf, "The game is %s closed to new players.\n\r", when);
      break;
   default :
      sprintf(buf, "Only level %d and above may enter the game %s.\n\r",
          restrict, when);
      break;
   }
   S2C();
}

void date_to_buf(char *buf)
{
   long	ct;
   char	*tmstr;

   ct = time(0);
   tmstr = (char *)asctime(localtime(&ct));
   *(tmstr + strlen(tmstr) - 1) = '\0';
   strcpy(buf, tmstr);
}

ACMD(do_date)
{
   char tmstr[1024];

   date_to_buf(tmstr);
   sprintf(buf, "Current machine time: %s\n\r", tmstr);
   S2C();
}

void uptime_to_buf(char *buf)
{
   char	*tmstr;
   long	uptime;
   int	d, h, m;
   extern long	boot_time;

   tmstr = (char *)asctime(localtime(&boot_time));
   *(tmstr + strlen(tmstr) - 1) = '\0';

   uptime = time(0) - boot_time;
   d = uptime / 86400;
   h = (uptime / 3600) % 24;
   m = (uptime / 60) % 60;

   sprintf(buf, "%%5%%bUp since%%0 %%6%s%%0: %%B%d%%0 day%s, %%B%d:%02d%%0\n\r", tmstr, d,
       ((d == 1) ? "" : "s"), h, m);
}

ACMD(do_uptime)
{
   uptime_to_buf(buf);
   S2C();
}

ACMD(do_last)
{
   struct char_file_u chdat;

   if (IS_NPC(ch))
      return;

   if (!*argument) {
      send_to_char("For whom do you wish to search?\n\r", ch);
      return;
   }

   one_argument(argument, arg);
   if (load_char(arg, &chdat) < 0) {
      send_to_char("Player not found.\n\r", ch);
      return;
   }
   if (chdat.level > GET_LEVEL(ch)) 
   {
      send_to_char("Access Denied.\n\r", ch);
      return;
   }

   if (chdat.level >= LEV_IMPL)
     sprintf(buf, "Access Denied.\n\r");
   else
   sprintf(buf, "[%5ld] [%2d %s] %-12s : %-18s : %-20s\n\r",
       chdat.saved.idnum, chdat.level, clarray[(int)chdat.cls].class_abbrev,
       chdat.name, chdat.host, ctime(&chdat.last_logon));

   S2C();
}

ACMD(do_force)
{
   dsdata *i;
   chdata *vict;
   char	name[100], to_force[MAX_INPUT_LENGTH+2];
   char buf[MAX_INPUT_LENGTH];

   if (IS_NPC(ch)) {
      send_to_char("Umm.... no.\n\r", ch );
      return;
   }

   half_chop(argument, name, to_force);

   sprintf(buf1, "%s has forced you to %s.\n\r", GET_NAME(ch), to_force);
   sprintf(buf2, "Someone has forced you to %s.\n\r", to_force);

   if (!*name || !*to_force)
      send_to_char("Whom do you wish to force do what?\n\r", ch);
   else if (str_cmp("all", name) && str_cmp("room", name)) {
      if (!(vict = get_char_vis(ch, name)) || !can_see(ch, vict))
	 send_to_char("No-one by that name here...\n\r", ch);
      else {
	 if (GET_LEVEL(ch) > GET_LEVEL(vict)) {
	    send_to_char("Ok.\n\r", ch);
	    if (can_see(vict, ch) && GET_LEVEL(ch) < LEV_IMPL)
	       send_to_char(buf1, vict);
	    else if (GET_LEVEL(ch) < LEV_IMPL) {
	       send_to_char(buf2, vict);
	    }
	    if (GET_LEVEL(ch) < LEV_IMPL)
	    {
	      sprintf(buf, "IMMUPD: %s forced %s: %s", GET_NAME(ch), name, to_force);
	      mudlog(buf, CMP, MAX(LEV_IMM, GET_INVIS_LEV(ch)), TRUE);
	    }
	    command_interpreter(vict, to_force);
	 } else
	    send_to_char("No, no, no!\n\r", ch);
      }
   } else if (str_cmp("room", name)) {
      send_to_char("Okay.\n\r", ch);
      if (GET_LEVEL(ch) < LEV_IMPL) {
	 sprintf(buf, "IMMUPD: %s forced %s to %s", GET_NAME(ch), name, to_force);
	 mudlog(buf, CMP, MAX(LEV_IMM, GET_INVIS_LEV(ch)), TRUE);
      }

      for (i = descriptor_list; i; i = i->next)
	 if (D_CHECK(i) && i->character != ch)
	 {
	    vict = i->character;
	    if (GET_LEVEL(ch) > GET_LEVEL(vict)) {
	       if (can_see(vict, ch) && GET_LEVEL(ch) < LEV_IMPL)
		  send_to_char(buf1, vict);
	       else if (GET_LEVEL(ch) < LEV_IMPL)
		  send_to_char(buf2, vict);
	       command_interpreter(vict, to_force);
	    }
	 }
   } else {
      send_to_char("Okay.\n\r", ch);
      if (GET_LEVEL(ch) < LEV_IMPL) {
	 sprintf(buf, "IMMUPD: %s forced %s to %s", GET_NAME(ch), name, to_force);
	 mudlog(buf, CMP, MAX(LEV_IMM, GET_INVIS_LEV(ch)), TRUE);
      }

      for (i = descriptor_list; i; i = i->next)
	 if (D_CHECK(i) && i->character != ch && SAME_ROOM(i->character, ch))
	 {
	    vict = i->character;
	    if (GET_LEVEL(ch) > GET_LEVEL(vict)) {
	       if (can_see(vict, ch) && GET_LEVEL(ch) < LEV_IMPL)
		  send_to_char(buf1, vict);
	       else if (GET_LEVEL(ch) < LEV_IMPL)
		  send_to_char(buf2, vict);
	       command_interpreter(vict, to_force);
	    }
	 }
   }
}

ACMD(do_low_force)
{
  chdata *vict;
  int privnum;

  if (IS_NPC(ch)) return;
  
  if(!*argument) {
    send_to_char("Force who to what?\r\n", ch);
    return;
  }
  if (strlen(argument) >= MAX_STRING_LENGTH) return;

   half_chop(argument, arg, buf);
   vict = get_char_room_vis(ch, arg);
   if(!vict) {
      send_to_char("No such mob in this room.\n\r", ch);
      return;
    }
    
    if(IS_PC(vict))
    {
      send_to_char("Access Denied.  Attempted to force PC.\n\r", ch);
      return;
    }

    privnum = (GET_MOB_VNUM(vict)) / 100;
    if (!privnum) return;

    if (!olc_perms(ch, LEV_CIMP, privnum))
      return;

   if (!*buf)
   {
     send_to_char("Usage: fxxxx <mobilename> <item>.\n\r",ch);
     return;
   }

   switch(subcmd)
   {
    case SCMD_FGET:
      do_get(vict, buf, 0, 0);
      break;
    case SCMD_FGRAB:
      do_grab(vict, buf, 0, 0);
      break;
    case SCMD_FWIELD:
      do_wield(vict, buf, 0, 0);
      break;
    case SCMD_FWEAR:
      do_wear(vict, buf, 0, 0);
      break;
    case SCMD_FREMOVE:
      do_unequip(vict, buf, 0, 0);
      break;
    case SCMD_FDROP:
      do_drop(vict, buf, 0, 0);
      break;
    default: break;
   }
}
  
/* Freebie--> do_accept accepts a mortal into the immortal world */
ACMD(do_accept)
{
  chdata *vict;
  long exp_to_imm;

  if (IS_NPC(ch)) return;

  one_argument(argument, arg);
  if(!*arg) {
    send_to_char("Accept Who?\r\n", ch);
    return;
  }
  vict = get_char_vis(ch, arg);
  if(!vict) {
    send_to_char("That player isn't around.\r\n", ch);
    return;
  } 
  if(IS_NPC(vict)) {
    send_to_char("You expect a mobile to work on improving the mud?\r\n", ch);
    return;
  }
  if(GET_LEVEL(vict) >= LEV_IMM) {
    act("$N is already an immortal.", FALSE, ch, 0, vict, TO_CHAR);
    return;
  } 
  exp_to_imm = exp_table[GET_CLASS(ch)-1][LEV_IMM];
  if((GET_EXP(vict) < exp_to_imm-100) || (GET_LEVEL(vict) != LEV_IMM-1)) {
    act("But $N is not ready to immort yet!", FALSE, ch, 0, vict, TO_CHAR);
    return;
  }
  GET_LEVEL(vict) += 1;
  advance_level(vict);
  act("OK, $N is now an immortal.", FALSE, ch, 0, vict, TO_CHAR);
  send_to_char("Congratulations, you have achieved immortality!\r\n", vict);
}  

// Modified to change look, as well as add emote support to level wiznet
// 04/02/98 -callahan

ACMD(do_wiznet)
{
  dsdata *d;
  char	emote = FALSE, any = FALSE, *argu = argument, said[MAX_STRING_LENGTH];
  int	level = LEV_IMM;
  char *delete_doubledollar(char *string);

  skip_spaces(&argu);
  delete_doubledollar(argu);	// Was needed! 03/18/98 -callahan

  if (!*argu) {
      send_to_char("Usage: wiznet <text> | #<level> <text> | *<emotetext> |\n\r "
                   "       wiz @ | wiz - | wiz +\n\r", ch);
      return;
  }

  if (*argu == '*') {
    argu++;
    emote = TRUE;
  }

  strcpy(said, argu);
  switch (*argu) {
  case '*':
    emote = TRUE;
    argu++;
  case '#':
    one_argument(argu + 1, buf1);
    if (is_number(buf1)) {
      half_chop(argu + 1, buf1, said);
      level = MAX(atoi(buf1), LEV_IMM);

      if (level > Level(ch)) {
        send_to_char("You can't wizline above your own level.\n\r", ch);
        return;
      }

      switch (*said) {
      case '*':
        emote = TRUE;
      default:
        break;
      }
    }
      else
      if (emote)
         argu++;
      break;
  case '@':
    Descriptors(d) {
      if (D_CHECK(d) && IS_IMMORTAL(d->character) && 
          !PRF_FLAGGED(d->character, PRF_NOWIZ) && 
          (can_see(ch, d->character) || Level(ch) == LEV_IMPL)) {
	    if (!any) {
              sprintf(buf1, "Gods online:\n\r");
              any = TRUE;
	    }

	    sprintf(buf1, "%s  %s", buf1, Name(d->character));

	    if (PLR_FLAGGED(d->character, PLR_WRITING))
	       sprintf(buf1, "%s (Writing)\n\r", buf1);
	    else if (PLR_FLAGGED(d->character, PLR_MAILING))
	       sprintf(buf1, "%s (Writing mail)\n\r", buf1);
	    else if (PLR_FLAGGED(d->character, PLR_BUILDING))
	       sprintf(buf1, "%s (Building)\n\r", buf1);
	    else
	       sprintf(buf1, "%s\n\r", buf1);
      }
    }
    any = FALSE;

    Descriptors(d) {
      if (D_CHECK(d) && IS_IMMORTAL(d->character) && 
          PRF_FLAGGED(d->character, PRF_NOWIZ) && can_see(ch, d->character)) {
	    if (!any) {
              sprintf(buf1, "%sGods offline:\n\r", buf1);
	      any = TRUE;
	    }
	    sprintf(buf1, "%s  %s\n\r", buf1, Name(d->character));
      }
    }
    send_to_char(buf1, ch);
    return;
    break;
  case '-':
    if (PRF_FLAGGED(ch, PRF_NOWIZ))
      send_to_char("You are already offline!\n\r", ch);
    else {
      send_to_char("You will no longer hear the wizline.\n\r", ch);
      SET_BIT(PRF_FLAGS(ch), PRF_NOWIZ);
    }

    return;
    break;
  case '+':
    if (!PRF_FLAGGED(ch, PRF_NOWIZ))
      send_to_char("You are already online!\n\r", ch);
    else {
      send_to_char("You can now hear the wizline again.\n\r", ch);
      REMOVE_BIT(PRF_FLAGS(ch), PRF_NOWIZ);
    }
    return;
    break;
  case '\\':
    ++argu;
    break;
  default:
    break;
  }

  // let switched mobs talk to wiznet
  if (IS_PC(ch) && PRF_FLAGGED(ch, PRF_NOWIZ)) {
    send_to_char("You are offline!\n\r", ch);
    return;
  }
  argu = said;
  skip_spaces(&argu);

  if (!*argu) {
    send_to_char("Don't bother the gods like that!\n\r", ch);
    return;
  }

  if (level > LEV_IMM) {
    if (emote) {
      argu++;
      sprintf(buf1, "%%6(%%b%d+%%0%%6) %s %s\n\r", level, Name(ch), argu);
      sprintf(buf2, "%%6(%%b%d+%%0%%6) Someone %s\n\r", level, argu);
    } else {
      sprintf(buf1, "%%6(%%b%d+%%0%%6) %s: %s\n\r", level, Name(ch), argu);
      sprintf(buf2, "%%6(%%b%d+%%0%%6) Someone: %s\n\r", level, argu);
    }
  } else {
    if (emote) {
      sprintf(buf1, "%%6(Imm) %s %s\n\r", Name(ch), argu);
      sprintf(buf2, "%%6(Imm) Someone %s\n\r", argu);
    } else {
      sprintf(buf1, "%%6(Imm) %s: %s\n\r", Name(ch), argu);
      sprintf(buf2, "%%6(Imm) Someone: %s\n\r", argu);
    }
  }

  Descriptors(d) {
    if (D_CHECK(d) && (Level(d->character) >= level) &&
        (!PRF_FLAGGED(d->character, PRF_NOWIZ)) &&
        (!PLR_FLAGGED(d->character, PLR_WRITING | PLR_MAILING | PLR_BUILDING))
         && (d != ch->desc || !(NoRepeat(d->character)))) {
      if (can_see(d->character, ch))
        send_to_char(buf1, d->character);
      else
       send_to_char(buf2, d->character);

      send_to_char("%0", d->character);
    }
  }

  if (NoRepeat(ch))
    send_to_char("Ok.\n\r", ch);
}


// Added 04/03/98 -callahan
ACMD(do_home)
{ 
  int i;

  one_argument(argument, arg);

  if (*arg && !strcmp(arg, "set")) {
    if (GodRoom(InRoom(ch)) && !Ulutiu(ch)) {
      send_to_char("You can't set your home here. This is a God room.", ch);
      return;
    }
    send_to_char("You have selected this place as your new home.\r\n", ch);

    if (!LoadInRoom(ch)) 
      SET_BIT(PLR_FLAGS(ch), PLR_LOADROOM);

    Loadroom(ch) = world[InRoom(ch)].number;
    save_char(ch, InRoom(ch));
    return;
  }
  
  for (i = 0; i < 3; i++)
    send_to_char("There's no place like home...\r\n", ch);
  
  do_goto(ch, tprintf("%d", Loadroom(ch)), 0, 0);
}


ACMD(do_zreset)
{
   void natural_reset(int zone);
   void unnatural_reset(int zone);
   int j;
   BOOL natural;

   if IS_NPC(ch) {
      send_to_char("Homie don't play that!\n\r", ch);
      return;
   }

   if (!*argument) 
   {
      send_to_char("You must specify a zone.\n\r", ch);
      return;
   }
   one_argument(argument, arg);

   if (*arg == '.')
    j = world[ch->in_room].zone;
   else 
    j = atoi(arg);

   if (!REAL_ZONE(j))
   {
     send_to_char("Invalid zone.\n\r",ch);
     return;
   }
   natural = (GET_LEVEL(ch) < LEV_CIMP);
   if (natural) natural_reset(j);
   else unnatural_reset(j);

   sprintf(buf, "Reset zone %d (%s): %s.\n\r", j, 
	   (natural?"natural":"unnatural"),zone_table[j].name);
   S2C();
   sprintf(buf, "IMMUPD: %s reset zone %d (%s)", GET_NAME(ch), j, 
	   zone_table[j].name);
   mudlog(buf, NRM, MAX(LEV_IMM, GET_INVIS_LEV(ch)), FALSE);
}

ACMD(do_idle_zone)
{
   int i, zone;
   char buf[20000];

   if (IS_NPC(ch)) return;
   
   if (!*argument || GET_LEVEL(ch) < LEV_IMPL)
   {
      strcpy(buf, "");
      send_to_char("%BCurrent IDLE zones%0:\n\r",ch);
      for (i=0; i < NUM_ZONES; i++)
        if (REAL_ZONE(i) && ZONE_FLAGGED(i, Z_IDLE))
        {
          sprintf(buf1, "Zone %d: %s\n\r",i,zone_table[i].name);
   	  strcat(buf, buf1);
        }
      page_string(ch->desc, buf, 1);
      return;
   }

   one_argument(argument, arg);
   if (!is_number(arg))
   {
      send_to_char("Usage: idle <zone_num>\n\r",ch);
      return;
   }

   zone = atoi(arg);
   if (!REAL_ZONE(zone))
   {
     send_to_char("Invalid zone number.\n\r",ch);
     return;
   }
   
   if (!is_empty(zone))
   {
     send_to_char("There are players in that zone.\n\r",ch);
     return;
   }

   if (ZONE_FLAGGED(zone, Z_SYSTEM))
   {
     send_to_char("Unable to idle a system zone.\n\r",ch);
     return;
   }

   sprintf(buf,"Idling zone: %s\n\r",zone_table[zone].name);
   S2C();
   sprintf(buf, "%s setting zone IDLE: %s",GET_NAME(ch),zone_table[zone].name);
   mudlog(buf, NRM, MAX(LEV_GOD, GET_INVIS_LEV(ch)), TRUE);
   SET_BIT(ZONE_FLAGS(zone), Z_IDLE);
   zone_table[zone].age = 0;
   zone_table[zone].idle_time = 0;
   zlock_reset = 1;
   purge_zone(zone);
   zlock_reset = 0;
}

ACMD(do_free_zone)
{
   int i, zone;
   char buf[20000];
   int free_this_zone(int zone);

   if (IS_NPC(ch)) return;
   
   if (!*argument || GET_LEVEL(ch) < LEV_IMPL)
   {
      send_to_char("%BCurrent FREED zones%0:\n\r",ch);
      for (i=0, *buf = '\0'; i < NUM_ZONES; i++)
        if (REAL_ZONE(i) && ZONE_FREED(i))
          sprintf(buf+strlen(buf), "Zone %d: %s\n\r",i,zone_table[i].name);
      if (*buf)
        page_string(ch->desc, buf, 1);
      else send_to_char("None.\n\r",ch);
      return;
   }

   one_argument(argument, arg);
   if (!is_number(arg))
   {
      send_to_char("Usage: free <zone_num>\n\r",ch);
      return;
   }

   zone = atoi(arg);
   if (!REAL_ZONE(zone))
   {
     send_to_char("Invalid zone number.\n\r",ch);
     return;
   }
   
   if (!is_empty(zone))
   {
     send_to_char("There are players in that zone.\n\r",ch);
     return;
   }

   if (ZONE_FLAGGED(zone, Z_SYSTEM))
   {
     send_to_char("Unable to free a system zone.\n\r",ch);
     return;
   }

   if (!ZONE_IDLE(zone))
   {
     send_to_char("You must idle the zone first.\n\r",ch);
     return;
   }

   free_this_zone(zone);
   sprintf(buf,"Freeing zone: %s\n\r",zone_table[zone].name);
   S2C();
   sprintf(buf, "%s setting zone FREED: %s",GET_NAME(ch),zone_table[zone].name);
   mudlog(buf, NRM, MAX(LEV_GOD, GET_INVIS_LEV(ch)), TRUE);
}

/* 
  General fn for wizcommands of the sort: cmd <player>
*/

ACMD(do_wizutil)
{
   chdata *vict;
   char	name[40];
   long	result;
   dsdata *d;

   void add_arena_player(chdata *ch);
   void remove_arena_player(chdata *ch, BOOL award);

   if (IS_NPC(ch)) {
      send_to_char("You're just an unfrozen caveman NPC.\n\r", ch);
      return;
   }
   one_argument(argument, name);

   if ((GET_LEVEL(ch) <= 1) && (!*name))
   {
      send_to_char("You must use yourself as an argument.\n\r", ch);
      return;
   }
   if (!*name) {
      send_to_char("Yes, but for whom?!?\n\r", ch);
      return;
   }
   if (!(vict = get_char_vis(ch, name)))
   {
      send_to_char("There is no such player.\n\r", ch);
      return;
   }
   if (IS_NPC(vict))
   {
      send_to_char("You can't do that to a mob!\n\r", ch);
      return;
   }
   if (GET_LEVEL(vict) > GET_LEVEL(ch))
   {
      send_to_char("Hmmm...you'd better not.\n\r", ch);
      return;
   }

   switch (subcmd) {
   case SCMD_ASSASSIN:
      if (PRF_FLAGGED(vict, PRF_ASSASSIN)) 
      {
         sprintf(buf,"A force beyond comprehension has removed you from the Circle of Assassins. \n\r");
         send_to_char(buf, vict);
         REMOVE_BIT(PRF_FLAGS(vict), PRF_ASSASSIN);
         send_to_char("You remove that player from the assassin circle.\n\r",ch);
         sprintf(buf, "IMMUPD: %s dis assassined by %s", GET_NAME(vict), GET_NAME(ch));
         mudlog(buf, BRF, MAX(LEV_GOD, GET_INVIS_LEV(ch)), TRUE);
         break;
      }
      if (!PRF_FLAGGED(vict, PRF_REQASS)) {
         send_to_char("That player is not requesting assassin status.\n\r",ch);
         return;
         break;
      }
      REMOVE_BIT(PRF_FLAGS(vict), PRF_REQASS);
      SET_BIT(PRF_FLAGS(vict), PRF_ASSASSIN);
      sprintf(buf,"You are now a member of the Circle of Assassins!\n\r");
      strcat(buf,"You must always remember keep an eye over your shoulder,\n\r");
      strcat(buf,"because at ANY time a fellow assassin may choose you as\n\r");
      strcat(buf,"their next target.  Be wary...and Enjoy.\n\r");
      send_to_char(buf, vict);
      send_to_char("You accept that player into the Circle of Assassins.\n\r",ch);
      /* send to all assassins who has been accepted JRhone */
      for (d = descriptor_list; d; d = d->next)
        if (D_CHECK(d) && IS_PC(d->character) &&
            (d != vict->desc) && PRF_FLAGGED(d->character, PRF_ASSASSIN) &&
            !PLR_FLAGGED(d->character, PLR_WRITING | PLR_MAILING | PLR_BUILDING))      
          act("$N has joined the circle of assassins!",
              FALSE, d->character, 0, vict, TO_CHAR);
      break;

   case SCMD_ARENA:
      if (IS_NPC(vict))
      {
	send_to_char("No mobs allowed.\n\r",ch);
	return;
      }
      if (IN_ARENA(vict))  // remove em if flagged
      {
        remove_arena_player(vict, TRUE);
	return;
      }
      if (IS_IMMORTAL(vict)) // else we adding them
      { 
        send_to_char("Immortals no be allowed to be ARENA mon.\n\r",ch);
        return;
      }
      add_arena_player(vict);
      send_to_char("Player entered into arena.  Check and make sure.\n\r",ch);
      return;
      break;

   case SCMD_NOTITLE:
      result = PLR_TOG_CHK(vict, PLR_NOTITLE);
      sprintf(buf, "IMMUPD: Notitle %s for %s by %s.", ONOFF(result),
          GET_NAME(vict), GET_NAME(ch));
      mudlog(buf, NRM, MAX(LEV_GOD, GET_INVIS_LEV(ch)), TRUE);
      strcat(buf, "\n\r");
      S2C();
      break;

   case SCMD_SQUELCH:
      result = PLR_TOG_CHK(vict, PLR_MUTE);
      sprintf(buf, "IMMUPD: Squelch %s for %s by %s.", ONOFF(result),
          GET_NAME(vict), GET_NAME(ch));
      mudlog(buf, BRF, MAX(LEV_GOD, GET_INVIS_LEV(ch)), TRUE);
      strcat(buf, "\n\r");
      S2C();
      break;

   case SCMD_NOEMOTE:
      result = PLR_TOG_CHK(vict, PLR_NOEMOTE);
      sprintf(buf, "IMMUPD: NoEmote %s for %s by %s.", ONOFF(result),
          GET_NAME(vict), GET_NAME(ch));
      mudlog(buf, BRF, MAX(LEV_GOD, GET_INVIS_LEV(ch)), TRUE);
      strcat(buf, "\n\r");
      S2C();
      break;

   case SCMD_FREEZE:
      if (ch == vict) {
	 send_to_char("Oh, yeah, THAT'S real smart...\n\r", ch);
	 return;
      }
      if (PLR_FLAGGED(vict, PLR_FROZEN)) {
	 send_to_char("Your victim is already pretty cold.\n\r", ch);
	 return;
      }

      if (IS_NPC(vict)) return;

      SET_BIT(PLR_FLAGS(vict), PLR_FROZEN);
      vict->pc_specials->saved.freeze_level = GET_LEVEL(ch);
      send_to_char("A bitter wind suddenly rises and drains every erg of heat from your body!\n\rYou feel frozen!\n\r",vict);
      send_to_char("Frozen.\n\r", ch);
      act("A sudden cold wind conjured from nowhere freezes $n!", FALSE, vict, 0, 0, TO_ROOM);
      sprintf(buf, "IMMUPD: %s frozen by %s.", GET_NAME(vict), GET_NAME(ch));
      mudlog(buf, BRF, MAX(LEV_GOD, GET_INVIS_LEV(ch)), TRUE);
      break;
   case SCMD_THAW:
      if (!PLR_FLAGGED(vict, PLR_FROZEN)) {
	 send_to_char("Sorry, your victim is not morbidly encased in ice at the moment.\n\r", ch);
	 return;
      }

      if (IS_NPC(vict)) return;

      if (vict->pc_specials->saved.freeze_level > GET_LEVEL(ch)) {
	 sprintf(buf, "Sorry, a level %d God froze %s... you can't unfreeze %s.\n\r",
	     vict->pc_specials->saved.freeze_level,
	     GET_NAME(vict),
	     HMHR(vict));
	 S2C();
	 return;
      }
      sprintf(buf, "IMMUPD: %s thawed by %s.", GET_NAME(vict), GET_NAME(ch));
      mudlog(buf, BRF, MAX(LEV_GOD, GET_INVIS_LEV(ch)), TRUE);
      REMOVE_BIT(PLR_FLAGS(vict), PLR_FROZEN);
      send_to_char("A fireball suddenly explodes in front of you, melting the ice!\n\rYou feel thawed.\n\r", vict);
      send_to_char("Thawed.\n\r", ch);
      act("A sudden fireball conjured from nowhere thaws $n!", FALSE, vict, 0, 0, TO_ROOM);
      break;
   case SCMD_UNAFFECT:
      while (vict->affected)
	affect_remove(vict, vict->affected);
      affect_total(vict);

      send_to_char("All affects removed.\n\r", ch);
      send_to_char("There is a brief flash of light!\n\r"
	           "Your character has been cleansed.\n\r", vict);
      break;
   case SCMD_REROLL:
    if (GET_LEVEL(ch) >= LEV_CIMP) 
    {
      send_to_char("Rerolled...\n\r", ch);
      roll_real_abils(vict);
      affect_total(vict);
      sprintf(buf, "IMMUPD: %s rerolled %s.", GET_NAME(ch), GET_NAME(vict));
      mudlog(buf, CMP, MAX(LEV_IMM, GET_INVIS_LEV(ch)), TRUE);
      break;
    } 
    else 
    if (GET_LEVEL(ch) <= 1) 
    {
      send_to_char("You reroll your abilities.\n\r", ch);
      roll_real_abils(ch);
      affect_total(ch);
      sprintf(buf, "Your new abilities are: ");
      sprintf(buf, "Str:%d/%d Int:%d Wis:%d Dex:%d Con:%d.\n\r",
              GET_STR(ch), GET_ADD(ch), GET_INT(ch), GET_WIS(ch), GET_DEX(ch), GET_CON(ch));
      S2C();
      break;
    } else {
      send_to_char("You do not posess that ability.\n\r", ch);
      break;
    }
   }
   save_char(vict, NOWHERE);
}

/*
   single zone printing fn used by "show zone" so it's not repeated in the
   code 3 times ... -je, 4/6/93
   minor adjustments roa jtrhone
*/
/* Old function
void	print_zone_to_buf(char *bufptr, int zone)
{
   sprintf(bufptr, 
       "%s%3d %-27s Age: %3d; Reset: %3d (%1d); Top: %5d; %%B%%6%c%%7%c%c%c%c%c%%0\n\r",
       bufptr, 	zone_table[zone].number, zone_table[zone].name,
       zone_table[zone].age, zone_table[zone].lifespan,
       zone_table[zone].reset_mode, zone_table[zone].top,
       ZONE_FLAGGED(zone, Z_ON_Q) ? 'Q' : ' ',
       ZONE_FLAGGED(zone, Z_FREED)  ? 'F' : ' ',
       ZONE_FLAGGED(zone, Z_LOCKED) ? 'L' : ' ',
       ZONE_FLAGGED(zone, Z_IDLE) ? 'I' : ' ',
       ZONE_FLAGGED(zone, Z_SYSTEM) ? 'S' : ' ',
       ZONE_FLAGGED(zone, Z_CLOSED) ? 'C' : ' ');
}
*/

void	print_zone_to_buf(char *bufptr, int zone)
{
   sprintf(bufptr, 
       "%s%3d %-50.50s %3d %3d %-8s %%B%%6%c%%7%c%c%c%c%c%%0\r\n",
       bufptr, 	zone_table[zone].number, zone_table[zone].name,
       zone_table[zone].age, zone_table[zone].lifespan,
       zone_table[zone].reset_mode ?
       ((zone_table[zone].reset_mode == 1) ?
        "(!PCs)" : "(Rgdlss)") : "(Never)",
       ZONE_FLAGGED(zone, Z_ON_Q) ? 'Q' : '-',
       ZONE_FLAGGED(zone, Z_FREED)  ? 'F' : '-',
       ZONE_FLAGGED(zone, Z_LOCKED) ? 'L' : '-',
       ZONE_FLAGGED(zone, Z_IDLE) ? 'I' : '-',
       ZONE_FLAGGED(zone, Z_SYSTEM) ? 'S' : '-',
       ZONE_FLAGGED(zone, Z_CLOSED) ? 'C' : '-');
}


void update_stats(char *buf, chdata *ch)
{
   char timebuf[1024];
   int	j, k, i, con, idlecount, closedcount, zone, zonecount, doncount,
	freedcount;
   chdata *vict;
   obdata *obj;
   extern int buf_switches, buf_largecount, buf_overflows, max_on,
     socialcount, helpcount, wspellcount;

   /* added stats for ROA  jtrhone */
   i = j = k = con = doncount = idlecount = closedcount = 
				zonecount = freedcount = 0;

   /* use zone as counter */
   for (zone = 0; zone < top_of_world; zone++)
     if (ROOM_FLAGGED2(zone, DONATION))
       doncount++;

   for (zone = 0; zone < NUM_ZONES; zone++)
     if (REAL_ZONE(zone))
     {
       zonecount++;

       if (ZONE_FLAGGED(zone, Z_CLOSED))
         closedcount++;

       if (ZONE_IDLE(zone))
         idlecount++;

       if (ZONE_FREED(zone))
	 freedcount++;
     }

   for (vict = character_list; vict; vict = vict->next)
   {
     if (IS_NPC(vict))
       j++;
     else
     if (ch && can_see(ch, vict))
     {
       i++;
       if (vict->desc)
         con++;
     }
   }

   for (obj = object_list; obj; obj = obj->next)
     k++;
     
   *buf = '\0';
   sprintf(buf, "Current %%B%%6%s%%0 statistics:\n\r", shortmudname);
   sprintf(buf, "%s  %5d players in game  %5d connected\n\r", buf, i, con);
   sprintf(buf, "%s  %5d mortals %%Bmax%%0 this session\n\r", buf, max_on);
   sprintf(buf, "%s  %5d total registered players\n\n\r", buf, top_of_p_table + 1);
   sprintf(buf, "%s  %5d mobiles          %5d prototypes\n\r",
           buf, j, top_of_mobt);
   sprintf(buf, "%s  %5d objects          %5d prototypes\n\r",
           buf, k, top_of_objt);
   sprintf(buf, "%s  %5d rooms            %5d donations\n\r", 
           buf, top_of_world, doncount);
   sprintf(buf, "%s  %5d total zones  (%d freed, %d idle, %d closed)\n\n\r",
           buf, zonecount, freedcount, idlecount, closedcount);
   sprintf(buf, "%s  %5d socials,         %5d help files\n\r",
           buf, socialcount, helpcount);
   sprintf(buf, "%s  %5d warlock spells\n\n\r", buf, wspellcount);
   sprintf(buf, "%s  %5d large bufs\n\r", buf, buf_largecount);
   sprintf(buf, "%s  %5d buf switches     %5d overflows\n\r", buf,
           buf_switches, buf_overflows);
   uptime_to_buf(timebuf);
   strcat(buf, timebuf);
}

void update_mortal_stats(char *buf, chdata *ch)
{
   char timebuf[1024];
   int	j, k, i, con, idlecount, closedcount, zone, zonecount, doncount,
	freedcount;
   chdata *vict;
   obdata *obj;
   extern int max_on, socialcount, helpcount;

   /* added stats for ROA  jtrhone */
   i = j = k = con = doncount = idlecount = closedcount = 
				zonecount = freedcount = 0;

   /* use zone as counter */
   for (zone = 0; zone < top_of_world; zone++)
     if (ROOM_FLAGGED2(zone, DONATION))
       doncount++;

   for (zone = 0; zone < NUM_ZONES; zone++)
     if (REAL_ZONE(zone))
     {
       zonecount++;

       if (ZONE_FLAGGED(zone, Z_CLOSED))
         closedcount++;

       if (ZONE_IDLE(zone))
         idlecount++;

       if (ZONE_FREED(zone))
	 freedcount++;
     }

   for (vict = character_list; vict; vict = vict->next)
   {
     if (IS_NPC(vict))
       j++;
     else
     if (ch && can_see(ch, vict))
     {
       i++;
       if (vict->desc)
         con++;
     }
   }

   for (obj = object_list; obj; obj = obj->next)
     k++;
     
   *buf = '\0';
   sprintf(buf, "\n\rCurrent %%B%%6%s%%0 statistics:\n\r", shortmudname);
   sprintf(buf, "%s  %5d players in game  %5d connected\n\r", buf, i, con);
   sprintf(buf, "%s  %5d mortals %%Bmax%%0 this session\n\r", buf, max_on);
   sprintf(buf, "%s  %5d total registered players\n\n\r", buf, top_of_p_table + 1);
   sprintf(buf, "%s  %5d mobiles          %5d prototypes\n\r",
           buf, j, top_of_mobt);
   sprintf(buf, "%s  %5d objects          %5d prototypes\n\r",
           buf, k, top_of_objt);
   sprintf(buf, "%s  %5d rooms            %5d donations\n\r", 
           buf, top_of_world, doncount);
   sprintf(buf, "%s  %5d total zones  (%d freed, %d idle, %d closed)\n\n\r",
           buf, zonecount, freedcount, idlecount, closedcount);
   sprintf(buf, "%s  %5d socials,         %5d help files\n\n\r",
           buf, socialcount, helpcount);
   uptime_to_buf(timebuf);
   strcat(buf, timebuf);
}

void scan_pindex_for_name(chdata *ch, char *str)
{
  int i, count;
  char buf[20000];

  one_argument(str, buf2);
  for (i = count = 0, *buf = '\0'; i <= top_of_p_table; i++)
    if (strstr(player_table[i].name, buf2))
    {
      sprintf(buf + strlen(buf), "%%6[%%0%5ld%%6]%%0 %-15.15s %-30.30s\n\r",
 	      player_table[i].id, player_table[i].name,
	      player_table[i].last_ip);
      count++; if (count >= 75) break;
    }

  if (count) page_string(ch->desc, buf, TRUE);
  else send_to_char("No matches found.\n\r",ch);
}

void scan_pindex_for_ip(chdata *ch, char *str)
{
  int i, count;
  char buf[20000];

  one_argument(str, buf2);
  for (i = count = 0, *buf = '\0'; i <= top_of_p_table; i++)
    if (strstr(player_table[i].last_ip, buf2))
    {
      sprintf(buf + strlen(buf), "%%6[%%0%5ld%%6]%%0 %-15.15s %-30.30s\n\r",
 	      player_table[i].id, player_table[i].name,
	      player_table[i].last_ip);
      count++; if (count >= 75) break;
    }

  if (count) page_string(ch->desc, buf, TRUE);
  else send_to_char("No matches found.\n\r",ch);
}

ACMD(do_show)
{
   struct char_file_u vbuf;
   int	i, j, l;
   char	self = 0;
   char	field[40], value[40], birth[80];
   char buf[20000];
   extern char	*genders[];

   struct show_struct {
      char	*cmd;
      char	level;
   } fields[] = {
      { "nothing", 	0 },
      { "zones", 	LEV_IMM },
      { "player", 	LEV_GOD },
      { "rent", 	LEV_GOD },
      { "stats", 	LEV_IMM },
      { "unused", 	LEV_IMPL },
      { "death", 	LEV_GOD },
      { "unused",       LEV_GOD },
      { "reimb", 	LEV_GOD },
      { "\n", 0 }
   };   

   if IS_NPC(ch) {
      send_to_char("Oh no!  None of that stuff!\n\r", ch);
      return;
   }
   if (!*argument) {
      strcpy(buf, "Show options:\n\r");
      for (j = 0, i = 1; fields[i].level; i++)
	 if (fields[i].level <= GET_LEVEL(ch))
	    sprintf(buf, "%s%-15s%s", buf, fields[i].cmd, (!(++j % 5) ? "\n\r" : ""));
      strcat(buf, "\n\r");
      S2C();
      return;
   }
   half_chop(argument, field, arg);
   half_chop(arg, value, arg);

   for (l = 0; *(fields[l].cmd) != '\n'; l++)
      if (!strncmp(field, fields[l].cmd, strlen(field)))
	 break;

   if (GET_LEVEL(ch) < fields[l].level) {
      send_to_char("Access Denied.\n\r", ch);
      return;
   }
   if (!str_cmp(value, "."))
      self = 1;
   *buf = '\0';

  strcpy(buf, "%6"
"Num Zone Name                                          Age Reset (When) Status%5\r\n"
"=-= =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -=- -=-=-=-=-=-= =-=-=-%0\r\n"
         );

   switch (l) {
   case 1: /* zone */
      if (self)
        print_zone_to_buf(buf, world[ch->in_room].zone);
      else 
      if (is_number(value)) 
      {
	 if (REAL_ZONE((i=atoi(value))))
         {
	    print_zone_to_buf(buf, i);
	    S2C();
         }
	 else 
	 {
	    send_to_char("That is not a valid zone.\n\r", ch);
	    return;
	 }
      } 
      else
      {
         SendChar(buf, ch);
	 for (i = 0, *buf='\0'; i < NUM_ZONES; i++)
           if (REAL_ZONE(i))
	     print_zone_to_buf(buf, i);
	 if (*buf)
           page_string(ch->desc, buf, 1);
      }
         break;
   case 2: /* player -additions to scan pfile -roa*/
      if (*value && *arg && !str_cmp(value, "name"))
      {
        scan_pindex_for_name(ch, arg);
	return;
      }
      else 
      if (*value && *arg && !str_cmp(value, "ip"))
      {
        scan_pindex_for_ip(ch, arg);
	return;
      }

      if (load_char(value, &vbuf) < 0) {
	 send_to_char("There is no such player.\n\r", ch);
	 return;
      }

      sprintf(buf, "Player: %-12s (%s) [%2d %s]\n\r", vbuf.name,
              genders[(int)vbuf.sex], vbuf.level, clarray[(int)vbuf.cls].class_abbrev);

      sprintf(buf, "%s%s: %-8d  Bank: %-8d  Exp: %-8d  Align: %-5d  Lessons: %-3d\n\r",
              buf, currency_name_plural, vbuf.points.gold, vbuf.points.bank_gold, vbuf.points.exp,
              vbuf.saved.alignment, vbuf.saved.spells_to_learn);

      strcpy(birth, ctime(&vbuf.birth));

      sprintf(buf, "%sStarted: %-20.16s  Last: %-20.16s  Played: %3dh %2dm\n\r",
              buf, birth, ctime(&vbuf.last_logon), (int)(vbuf.played / 3600),
	      (int)(vbuf.played / 60 % 60));

      if (vbuf.level == LEV_IMPL)
        send_to_char("Access Denied.\n\r",ch);
      else
        S2C();
      break;
   case 3:
      listrent(ch, value);
      break;
   case 4:
      /* send the info to a string */
      update_stats(buf, ch);
      page_string(ch->desc, buf, 1);
      break;
   case 5:
      break;
   case 6:
    strcpy(buf, "%B%6Death Traps\n\r-=-=-=-=-=-%0\n\r");
    for (i = 0, j = 0; i < top_of_world; i++)
      if (ROOM_FLAGGED(i, DEATH | FLY_DEATH))
      {
	sprintf(buf+strlen(buf),"[%%B%%6%5d%%0] %-30.30s %%B%%1%s%s%%0\n\r", 
                ROOM_VNUM(i), 
                ROOM_NAME(i) ? ROOM_NAME(i) : "Currently idle.",
                ROOM_FLAGGED(i, DEATH) ? "DEATH " : "",
                ROOM_FLAGGED(i, FLY_DEATH) ? "FLY_DEATH" : "");
      }
      page_string(ch->desc, buf, 1);
      break;
   case 7:
      break;
   case 8:
      listreimb(ch, value);
      break;
   default:
      send_to_char("Unknown show option.\n\r", ch);
      break;
   }
}

#define PC   1
#define NPC  2
#define BOTH 3

#define MISC	0
#define BINARY	1
#define NUMBER	2

#define SET_OR_REMOVE(flagset, flags) { \
	if (on) SET_BIT(flagset, flags); \
	else if (off) REMOVE_BIT(flagset, flags); }

#define RANGE(low, high) (value = MAX((low), MIN((high), (value))))
#define RETURN if(is_file)free_char(cbuf); return

ACMD(do_bankset)
{
  chdata *vict = NULL;
  chdata *cbuf = NULL;
  struct char_file_u tmp_store;
  int	player_i = -1;
  char name[MAX_INPUT_LENGTH];
  long gold = 0;

  half_chop(argument, name, buf);
  if (!*name || !*buf)
  {
    send_to_char("Usage: bankset <char> <amount>.\n\r",ch);
    return;
  }

  gold = atoi(buf);
  if (!is_number(buf) || gold < 0)
  {
    sprintf(buf, "%s amount must be greater than 0.\n\r", currency_name);
    CAP(buf); S2C();
    return;
  }

  // Updated get_player_vis() for 0.playername, 03/22/98 -callahan
  if ((vict = get_player_vis(ch, name, FALSE)))
  {
    GET_BANK_GOLD(vict) = gold;
    save_char(vict, NOWHERE);
    sprintf(buf, "%s amount set.\n\r", currency_name);
    CAP(buf); S2C();
    return;
  }

  CREATE(cbuf, chdata, 1);
  clear_char(cbuf);
  if ((player_i = load_char(name, &tmp_store)) > -1)
  {
    store_to_char(&tmp_store, cbuf);
    if (GET_LEVEL(cbuf) >= GET_LEVEL(ch))
    {
      free_char(cbuf);
      send_to_char("Access Denied.\n\r", ch);
      return;
    }
    vict = cbuf;
  }
  else
  {
    free_char(cbuf);
    send_to_char("Victim not found.\n\r", ch);
    return;
  }

  GET_BANK_GOLD(vict) = gold;

  char_to_store(vict, &tmp_store);
  fseek(player_fl, (player_i) * sizeof(struct char_file_u), SEEK_SET);
  if (fwrite(&tmp_store, sizeof(struct char_file_u), 1, player_fl) < 1)
    mudlog("SYSWAR: Fwrite failure, do_bankset, wiz.c", BRF, LEV_IMM, TRUE);
  free_char(vict);

  sprintf(buf, "%s amount saved in file.\n\r", currency_name);
  CAP(buf); S2C();
}

ACMD(do_set)
{
   int	i, l;
   chdata *vict = NULL;
   chdata *cbuf = NULL;
   struct char_file_u tmp_store;
   char	field[MAX_INPUT_LENGTH], name[MAX_INPUT_LENGTH],
   val_arg[MAX_INPUT_LENGTH];
   int	on = 0, off = 0;
   long value = 0;
   char	is_file = 0, is_mob = 0, is_player = 0, is_self = 0;
   int	player_i = -1;

   struct set_struct {
      char	*cmd;
      char	level;
      char	pcnpc;
      char	type;
   } fields[] = 
    {
      { "brief", 	LEV_GOD, 	PC, 	BINARY },
      { "invstart", 	LEV_IMM, 	PC, 	BINARY },
      { "title", 	LEV_GOD, 	PC, 	MISC },
      { "nosummon", 	LEV_GOD, 	PC, 	BINARY },
      { "maxhit", 	LEV_IMPL, 	BOTH, 	NUMBER },
      { "maxmana", 	LEV_IMPL, 	BOTH, 	NUMBER },
      { "maxmove", 	LEV_IMPL, 	BOTH, 	NUMBER },
      { "hit", 		LEV_IMPL, 	BOTH, 	NUMBER },
      { "mana", 	LEV_IMPL, 	BOTH, 	NUMBER },
      { "move", 	LEV_IMPL, 	BOTH, 	NUMBER },
      { "align", 	LEV_GOD, 	BOTH, 	NUMBER },
      { "str", 		LEV_AIMP, 	BOTH, 	NUMBER },
      { "stradd", 	LEV_AIMP, 	BOTH, 	NUMBER },
      { "int", 		LEV_CIMP, 	BOTH, 	NUMBER },
      { "wis", 		LEV_CIMP, 	BOTH, 	NUMBER },
      { "dex", 		LEV_CIMP, 	BOTH, 	NUMBER },
      { "con", 		LEV_CIMP, 	BOTH, 	NUMBER },
      { "sex", 		LEV_AIMP, 	BOTH, 	MISC },
      { "ac", 		LEV_CIMP, 	BOTH, 	NUMBER },
      { "gold", 	LEV_IMPL, 	BOTH, 	NUMBER },
      { "bank", 	LEV_IMPL, 	PC, 	NUMBER },
      { "exp", 		LEV_IMPL, 	BOTH, 	NUMBER },
      { "hitroll", 	LEV_IMPL, 	BOTH, 	NUMBER },
      { "damroll", 	LEV_IMPL, 	BOTH, 	NUMBER },
      { "invis", 	LEV_CIMP, 	PC, 	NUMBER },
      { "nohassle", 	LEV_GOD, 	PC, 	BINARY },
      { "frozen", 	LEV_FREEZE, 	PC, 	BINARY },
      { "practices", 	LEV_CIMP, 	PC, 	NUMBER },
      { "lessons", 	LEV_CIMP, 	PC, 	NUMBER },
      { "drunk", 	LEV_GOD, 	BOTH, 	MISC },
      { "hunger", 	LEV_GOD, 	BOTH, 	MISC },
      { "thirst", 	LEV_GOD, 	BOTH, 	MISC },
      { "tag", 		LEV_IMM, 	PC, 	BINARY },
      { "thief", 	LEV_IMPL, 	PC, 	BINARY },
      { "level", 	LEV_IMPL, 	BOTH, 	NUMBER },
      { "roomflag", 	LEV_GOD, 	PC, 	BINARY },
      { "room", 	LEV_IMPL, 	BOTH, 	NUMBER },
      { "siteok", 	LEV_CIMP, 	PC, 	BINARY },
      { "deleted", 	LEV_AIMP, 	PC, 	BINARY },
      { "class", 	LEV_IMPL, 	BOTH, 	MISC },
      { "nowizlist", 	LEV_GOD, 	PC, 	BINARY },
      { "quest", 	LEV_GOD, 	PC, 	BINARY },
      { "loadroom", 	LEV_IMM, 	PC, 	MISC },
      { "color", 	LEV_CIMP, 	PC, 	BINARY },
      { "idnum", 	LEV_IMPL, 	PC, 	NUMBER },
      { "passwd", 	LEV_IMPL, 	PC, 	MISC },
      { "nodelete", 	LEV_IMPL, 	PC, 	BINARY },
      { "race",		LEV_AIMP,	PC,     NUMBER },
      { "leader",	LEV_GOD,	PC,     BINARY },
      { "ambass",	LEV_IMPL,	PC,     BINARY },
      { "plrname",      LEV_IMPL,	PC,	MISC },
      { "trusted",      LEV_AIMP,	PC,	MISC },
      { "hometown",     LEV_AIMP,	PC,	NUMBER },
      { "infoch",       LEV_AIMP,	PC,	BINARY },
      { "mentor",       LEV_GOD,	PC,	BINARY },
      { "timer", 	LEV_IMPL, 	PC, 	NUMBER },
      { "rituals", 	LEV_CIMP, 	PC, 	NUMBER },
      { "chosen", 	LEV_CIMP, 	PC, 	BINARY },
      { "\n", 0, BOTH, MISC }
   };   

   if (IS_NPC(ch)) {
      send_to_char("Umm.... no.\n\r", ch );
      return;
   }

   if (!*argument)
   {
     send_to_char("Sets available to you:\n\r",ch);
     i = l = 0;
     *buf = '\0';
     while (*fields[i].cmd != '\n')
     {
       if (GET_LEVEL(ch) >= fields[i].level)
       {
         sprintf(buf + strlen(buf), "%%6%10.10s%%0 ",fields[i].cmd);
	 l++;
         if (!(l % 6)) strcat(buf, "\n\r");
       }
       i++;
     }
     strcat(buf, "\n\r");
     page_string(ch->desc, buf, 1);
     return;
   }

   half_chop(argument, name, buf);
   if (!str_cmp(name, "file")) {
      is_file = 1;
      half_chop(buf, name, buf);
   } else if (!str_cmp(name, "player")) {
      is_player = 1;
      half_chop(buf, name, buf);
   } else if (!str_cmp(name, "self")) {
      is_self = 1;
      half_chop(buf, name, buf);
   } else if (!str_cmp(name, "mob")) {
      is_mob = 1;
      half_chop(buf, name, buf);
   }

   half_chop(buf, field, buf);
   strcpy(val_arg, buf);

   if (!*name || !*field) {
      send_to_char("Usage: set <victim> <field> <value>\n\r", ch);
      return;
   }

   if (IS_NPC(ch))
   {
      send_to_char("None of that!\n\r", ch);
      return;
   }

   if (!is_file)
   {
      if (is_player)
      {

	 // Updated get_player_vis() for 0.playername, 03/22/98 -callahan
	 if (!(vict = get_player_vis(ch, name, FALSE)))
         {
	    send_to_char("There is no such player.\n\r", ch);
	    return;
	 }
      }
      else
      if (is_self && !(vict = ch))
      {
        send_to_char("There is no such creature.\n\r", ch);
        return;
      }
      else
      if (!(vict = get_char_vis(ch, name)))
      {
        send_to_char("There is no such creature.\n\r", ch);
        return;
      }
   }
   else
   if (is_file)
   {
      CREATE(cbuf, chdata, 1);
      clear_char(cbuf);
      if ((player_i = load_char(name, &tmp_store)) > -1)
      {
	 store_to_char(&tmp_store, cbuf);
	 if (GET_LEVEL(cbuf) >= GET_LEVEL(ch))
         {
	    free_char(cbuf);
	    send_to_char("Access Denied.\n\r", ch);
	    return;
	 }
	 vict = cbuf;
      }
      else
      {
	 free_char(cbuf);
	 send_to_char("Victim not found.\n\r", ch);
	 return;
      }
   }

   if (GET_LEVEL(ch) != LEV_IMPL)
   {
      if (IS_PC(vict) && GET_LEVEL(ch) <= GET_LEVEL(vict) && vict != ch)
      {
	 send_to_char("Access Denied.  Victim same or higher level.\n\r", ch);
	 return;
      }
   }

   for (l = 0; *(fields[l].cmd) != '\n'; l++)
      if (!strncmp(field, fields[l].cmd, strlen(field)))
	 break;

   if (GET_LEVEL(ch) < fields[l].level) {
      send_to_char("Access Denied.\n\r", ch);
      return;
   }
   if (IS_NPC(vict) && (!fields[l].pcnpc && NPC)) {
      send_to_char("PC only.\n\r", ch);
      return;
   } else if (IS_PC(vict) && (!fields[l].pcnpc && PC)) {
      send_to_char("NPC only.\n\r", ch);
      return;
   }

   if (fields[l].type == BINARY)
   {
      if (!str_cmp(val_arg, "on") || !str_cmp(val_arg, "yes"))
	 on = 1;
      else if (!str_cmp(val_arg, "off") || !str_cmp(val_arg, "no"))
	 off = 1;
      if (!(on || off))
      {
	 send_to_char("Value must be on or off.\n\r", ch);
	 return;
      }
   }
   else
   if (fields[l].type == NUMBER)
     value = atoi(val_arg);

   strcpy(buf, "Okay.");
   switch (l)
   {
   case 0:
      if (IS_NPC(vict)) break;
      SET_OR_REMOVE(PRF_FLAGS(vict), PRF_BRIEF);
      break;
   case 1:
      if (IS_NPC(vict)) break;
      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_INVSTART);
      break;
   case 2:
      if (GET_TITLE(vict))
	 RECREATE(GET_TITLE(vict), char, strlen(val_arg) + 1);
      else
	 CREATE(GET_TITLE(vict), char, strlen(val_arg) + 1);
      strcpy(GET_TITLE(vict), val_arg);
      sprintf(buf, "%s's title is now: %s", GET_NAME(vict), GET_TITLE(vict));
      break;
   case 3:
      if (IS_NPC(vict)) break;
      SET_OR_REMOVE(PRF_FLAGS(vict), PRF_SUMMONABLE);
      on = !on; /* so output will be correct */
      break;
   case 4:
      vict->points.max_hit = RANGE(1, 5000);
      affect_total(vict);
      break;
   case 5:
      vict->points.max_mana = RANGE(1, 5000);
      affect_total(vict);
      break;
   case 6:
      vict->points.max_move = RANGE(1, 5000);
      affect_total(vict);
      break;
   case 7:
      vict->points.hit = RANGE(-9, vict->points.max_hit);
      affect_total(vict);
      break;
   case 8:
      vict->points.mana = RANGE(0, vict->points.max_mana);
      affect_total(vict);
      break;
   case 9:
      vict->points.move = RANGE(0, vict->points.max_move);
      affect_total(vict);
      break;
   case 10:
      GET_ALIGNMENT(vict) = RANGE(-1000, 1000);
      affect_total(vict);
      break;
   case 11:
      if (IS_NPC(vict) || GET_LEVEL(vict) >= LEV_CIMP)
	 RANGE(3, 25);
      else
	 RANGE(3, 18);
      vict->real_abils.str = value;
      vict->real_abils.str_add = 0;
      vict->aff_abils.str = value;
      vict->aff_abils.str_add = 0;
      affect_total(vict);
      break;
   case 12:
      vict->real_abils.str_add = vict->aff_abils.str_add = RANGE(0, 100);
      if (value > 0)
      {
	 vict->real_abils.str = 18;
	 vict->aff_abils.str = 18;
      }
      affect_total(vict);
      break;
   case 13:
      if (IS_NPC(vict) || GET_LEVEL(vict) >= LEV_CIMP)
	 RANGE(3, 25);
      else
	 RANGE(3, 18);
      vict->real_abils.intel = value;
      affect_total(vict);
      break;
   case 14:
      if (IS_NPC(vict) || GET_LEVEL(vict) >= LEV_CIMP)
	 RANGE(3, 25);
      else
	 RANGE(3, 18);
      vict->real_abils.wis = value;
      affect_total(vict);
      break;
   case 15:
      if (IS_NPC(vict) || GET_LEVEL(vict) >= LEV_CIMP)
	 RANGE(3, 25);
      else
	 RANGE(3, 18);
      vict->real_abils.dex = value;
      affect_total(vict);
      break;
   case 16:
      if (IS_NPC(vict) || GET_LEVEL(vict) >= LEV_CIMP)
	 RANGE(3, 25);
      else
	 RANGE(3, 18);
      vict->real_abils.con = value;
      affect_total(vict);
      break;
   case 17:
      if (!str_cmp(val_arg, "male"))
	 vict->player.sex = SEX_MALE;
      else if (!str_cmp(val_arg, "female"))
	 vict->player.sex = SEX_FEMALE;
      else if (!str_cmp(val_arg, "neutral"))
	 vict->player.sex = SEX_NEUTRAL;
      else {
	 send_to_char("Must be 'male', 'female', or 'neutral'.\n\r", ch);
	 RETURN;
      }
      break;
   case 18:
      vict->points.armor = RANGE(-400, 400);
      affect_total(vict);
      break;
   case 19:
      GET_GOLD(vict) = RANGE(0, 100000000);
      break;
   case 20:
      GET_BANK_GOLD(vict) = RANGE(0, 100000000);
      break;
   case 21:
      vict->points.exp = RANGE(0, 500000000);
      break;
   case 22:
      vict->points.hitroll = RANGE(-20, 50);
      affect_total(vict);
      break;
   case 23:
      vict->points.damroll = RANGE(-20, 50);
      affect_total(vict);
      break;
   case 24:
      if (GET_LEVEL(ch) < LEV_IMPL && ch != vict) {
	 send_to_char("Access Denied.\n\r", ch);
	 RETURN;
      }
      GET_INVIS_LEV(vict) = RANGE(0, GET_LEVEL(vict));
      break;
   case 25:
      if (GET_LEVEL(ch) < LEV_IMPL && ch != vict) {
	 send_to_char("Access Denied.\n\r", ch);
	 RETURN;
      }
      if (IS_NPC(vict)) break;
      SET_OR_REMOVE(PRF_FLAGS(vict), PRF_NOHASSLE);
      break;
   case 26:
      if (ch == vict) {
	 send_to_char("Better not -- could be a long winter!\n\r", ch);
	 RETURN;
      }
      if (IS_NPC(vict)) break;
      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_FROZEN);
      break;
   case 27:
   case 28:
      SPELLS_TO_LEARN(vict) = RANGE(0, 100);
      break;
   case 29:
   case 30:
   case 31: if (IS_NPC(vict)) break;
      if (!str_cmp(val_arg, "off")) {
	 GET_COND(vict, (l - 29)) = (char) -1;
	 sprintf(buf, "%s's %s now off.", GET_NAME(vict),
	     fields[l].cmd);
      } else if (is_number(val_arg)) {
	 value = atoi(val_arg);
	 RANGE(0, 24);
	 GET_COND(vict, (l - 29)) = (char) value;
	 sprintf(buf, "%s's %s set to %ld.", GET_NAME(vict),
	     fields[l].cmd, value);
      } else {
	 send_to_char("Must be 'off' or a value from 0 to 24.\n\r", ch);
	 RETURN;
      }
      break;
   case 32:
	if (!PLR_FLAGGED(vict, PLR_INTAG))
	{
	  send_to_char("But, they are not playing tag!\n\r",ch);
	  return;
	}
	SET_OR_REMOVE(PLR_FLAGS(vict), PLR_TAGGED);
      break;

   case 33:
      break;

   case 34:
      if (GET_LEVEL(ch) < LEV_IMPL && value > GET_LEVEL(ch)) {
	 send_to_char("You cannot raise someone above your own level!\n\r", ch);
	 RETURN;
      }
      // let all imps set level once more  3/27/98 -jtrhone
      vict->player.level = (byte) value;
      break;

   case 35:
      if (IS_NPC(vict)) break;
      SET_OR_REMOVE(PRF_FLAGS(vict), PRF_ROOMFLAGS);
      break;

   case 36:
      if ((i = real_room(value)) < 0) {
	 send_to_char("No room exists with that number.\n\r", ch);
	 RETURN;
      }
      char_from_room(vict);
      char_to_room(vict, i);
      break;
   case 37:
      if (IS_NPC(vict)) break;
      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_SITEOK);
      break;
   case 38:
      if (IS_NPC(vict)) break;
      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_DELETED);
      break;
   case 39:
      /* class */
      break;
   case 40:
      if (IS_NPC(vict)) break;
      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_NOWIZLIST);
      break;
   case 41:
      if (IS_NPC(vict)) break;
      SET_OR_REMOVE(PRF_FLAGS(vict), PRF_QUEST);
      break;
   case 42:
      if (IS_NPC(vict)) break;
      if (!str_cmp(val_arg, "on"))
	 SET_BIT(PLR_FLAGS(vict), PLR_LOADROOM);
      else if (!str_cmp(val_arg, "off"))
	 REMOVE_BIT(PLR_FLAGS(vict), PLR_LOADROOM);
      else {
	 if (real_room(i = atoi(val_arg)) > -1) {
	    GET_LOADROOM(vict) = i;
	    sprintf(buf, "%s will enter at %d.", GET_NAME(vict),
	        GET_LOADROOM(vict));
	 } else
	    sprintf(buf, "That room does not exist!");
      }
      break;
   case 43:
      if (IS_NPC(vict)) break;
      SET_OR_REMOVE(PRF_FLAGS(vict), PRF_COLOR);
      break;
   case 44:
      if (IS_NPC(vict)) break;
      if (GET_IDNUM(ch) != 1 || IS_PC(vict))
	 RETURN;
      vict->pc_specials->saved.idnum = value;
      break;
   case 45:
      if (!is_file)
	{  send_to_char("Didn't get past is_file check...\n\r",ch);
      	   RETURN;
	}
      if (GET_LEVEL(vict) >= LEV_CIMP) {
	 send_to_char("You cannot change that.\n\r", ch);
	 RETURN;
      }
      strncpy(tmp_store.pwd, CRYPT(val_arg, val_arg), MAX_PWD_LENGTH);
      tmp_store.pwd[MAX_PWD_LENGTH] = '\0';
      sprintf(buf, "Password changed to '%s'.", val_arg);
      break;
   case 46:
      if (IS_NPC(vict)) break;
      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_NODELETE);
      break;
   case 47:
      if (IS_NPC(vict)) break;
      if ((value < 1) || (value > 10)) {
        sprintf(buf, "Available Race #'s : \n\r");
        S2C();
        for (i=0; *rcarray[i].race_name; i++)
        {
          sprintf(buf, "[%d] %s\n\r",i, rcarray[i].race_name);
          S2C();
        }
  	RETURN;
        break;
      } else {
        vict->pc_specials->saved.race = value;
        roll_real_abils(vict);
        send_to_char("Ok.  Race has been changed.\n\r",ch);
        send_to_char("Race changed -- check your stats. \n\r",vict);
        break;
      }
   case 48:
      if (IS_NPC(vict)) break;
      if (!str_cmp(val_arg, "on"))
      {
	 vict->pc_specials->saved.clanleader = 1;
         vict->pc_specials->saved.in_clan = 1;
         strcpy(vict->pc_specials->saved.clan, "");
         vict->pc_specials->saved.clan_num = number(1, 101);  /* some random # */
         send_to_char("You are qualified to be a leader of a clan.\n\r",vict);
         send_to_char("Please use CLANNAME to name your clan.\n\r",vict);
      }
      else if (!str_cmp(val_arg, "off"))
      {
	 vict->pc_specials->saved.clanleader = 0;
         vict->pc_specials->saved.in_clan = 0;
         vict->pc_specials->saved.clan_num = 0;
         strcpy(vict->pc_specials->saved.clan, "");
         send_to_char("You are no longer a clan leader.\n\r",vict);
      }
      break;
   case 49:
      if (IS_NPC(vict)) break;
      if (!str_cmp(val_arg, "on"))
      {
        if (GET_LEVEL(vict) != LEV_IMM)
        {
          sprintf(buf, "%s must be level %d to be an ambassador.\n\r",GET_NAME(vict),LEV_IMM);
          S2C();
          RETURN;
        }
        if (PLR_FLAGGED(vict, PLR_AMBASS))
        { send_to_char("Already an Ambassador.\n\r",ch);
          RETURN;
        }
        SET_BIT(PLR_FLAGS(vict), PLR_AMBASS);
        sprintf(buf,"You are now an Ambassador to %s.\n\r",shortmudname);
        send_to_char(buf, vict);
      }
      else
      {
        if (!PLR_FLAGGED(vict, PLR_AMBASS))
        { send_to_char("Not an Ambassador.\n\r",ch);
          RETURN;
        }
        REMOVE_BIT(PLR_FLAGS(vict), PLR_AMBASS);
        send_to_char("Sorry, you are no longer an Ambassador.\n\r",vict);
      }
      break;
   case 50:
      // update player index first
      strcpy(buf, GET_NAME(vict));
      for (i = 0; *(buf + i); i++)
        *(buf + i) = LOWER(*(buf + i));

      for (i = 0; i <= top_of_p_table; i++) 
	if (!str_cmp((player_table + i)->name, buf))
	  break;

      if (i > top_of_p_table || !player_table[i].name)
      {
	send_to_char("Unable to locate entry in player index.\n\r",ch);
	return;
      }
      else
      {
         RECREATE(player_table[i].name, char, strlen(val_arg) + 1);
         strcpy(player_table[i].name, val_arg);
      }

      if (GET_NAME(vict))
	 RECREATE(GET_NAME(vict), char, strlen(val_arg) + 1);
      else
	 CREATE(GET_NAME(vict), char, strlen(val_arg) + 1);
      strcpy(GET_NAME(vict), val_arg);
      sprintf(buf, "NOTICE:  Name changed to %s", GET_NAME(vict));
      break;

   case 51:
      if (IS_NPC(vict)) break;
      if (!str_cmp(val_arg, "on"))
      {
        if (GET_LEVEL(vict) < LEV_IMM)
        {
          sprintf(buf, "%s must be level %d to be trusted.\n\r",
		  GET_NAME(vict), LEV_IMM);
          S2C();
          RETURN;
        }
        if (PLR_FLAGGED(vict, PLR_TRUSTED))
        { send_to_char("Already trusted.\n\r",ch);
          RETURN;
        }
        SET_BIT(PLR_FLAGS(vict), PLR_TRUSTED);
        send_to_char("You are now a trusted Avatar.\n\r",vict);
      }
      else
      {
        if (!PLR_FLAGGED(vict, PLR_TRUSTED))
        { send_to_char("That player is not trusted.\n\r",ch);
          RETURN;
        }
        REMOVE_BIT(PLR_FLAGS(vict), PLR_TRUSTED);
        send_to_char("Sorry, you no longer have trusted status.\n\r",vict);
      }
      break;

   case 52:
      if (IS_NPC(vict)) break;
      if ((value < 0) || (value >= MAX_HTOWNS) || !htowns[value].name) 
      {
        sprintf(buf, "Available Hometown #'s : \n\r");
        S2C();

        for (i=0; i < MAX_HTOWNS && htowns[i].name; i++)
        {
          sprintf(buf, "[%d] %s\n\r",i, htowns[i].name);
          S2C();
        }
  	RETURN;
        break;
      } 
      else 
      {
        if (value < 0 || value >= MAX_HTOWNS || !htowns[value].name)
	{
	  send_to_char("Invalid hometown.\n\r",ch);
	  return;
	}
        GET_HTOWN(vict) = value;
	GET_LOADROOM(vict) = htowns[value].rvnum; 
	send_to_char("Hometown changed, check score.\n\r",vict);
	send_to_char("Ok.\n\r",ch);
        break;
      }
	break;

   case 53:
      if (IS_NPC(vict)) break;
      if (!str_cmp(val_arg, "on"))
      {
        if (PLR_FLAGGED(vict, PLR_INFOCH))
        { send_to_char("Info channel already on.\n\r",ch);
          RETURN;
        }
        SET_BIT(PLR_FLAGS(vict), PLR_INFOCH);
        send_to_char("Your [%B%5Info%0] channel has been turned on.\n\r",vict);
      }
      else
      {
        if (!PLR_FLAGGED(vict, PLR_INFOCH))
        { send_to_char("Info channel not on.\n\r",ch);
          RETURN;
        }
        REMOVE_BIT(PLR_FLAGS(vict), PLR_INFOCH);
        send_to_char("Your [%B%5Info%0] channel has been turned off.\n\r",vict);
      }
      break;
   case 54:
      SET_OR_REMOVE(PLR2_FLAGS(vict), PLR2_MENTOR);
      break;

   case 55:
        vict->specials.timer = value;
      break;

   case 56:
        RITES(ch) = value;
      break;

   case 57:
      SET_OR_REMOVE(PRF2_FLAGS(vict), PRF2_CHOSEN);
      break;

   default:
      sprintf(buf, "Can't set that!");
      break;
   }

   if (fields[l].type == BINARY) {
      sprintf(buf, "%s %s for %s.\n\r", fields[l].cmd, ONOFF(on), GET_NAME(vict));
      CAP(buf);
   } else if (fields[l].type == NUMBER) {
      sprintf(buf, "%s's %s set to %ld.\n\r", GET_NAME(vict), fields[l].cmd, value);
   } else
      strcat(buf, "\n\r");
   S2C();

   if (!is_file && IS_PC(vict))
     save_char(vict, NOWHERE);

   if (is_file) {
     char_to_store(vict, &tmp_store);
     fseek(player_fl, (player_i) * sizeof(struct char_file_u), SEEK_SET);
     if (fwrite(&tmp_store, sizeof(struct char_file_u), 1, player_fl) < 1)
       log("SYSERR: Fwrite failure, do_set, wiz.c");
     free_char(vict);
     send_to_char("Saved in file.\n\r", ch);
   }
}

/* flag a zone immort or test  not saving this info yet */
ACMD(do_zimmort)
{
  char zstr[MAX_INPUT_LENGTH];
  int zone;

  if (IS_NPC(ch)) return;

  if (strlen(argument) > MAX_CLAN_LENGTH)
    return;

  if (!*argument)
  {
     send_to_char("Current zones flagged IMMORT:\n\r",ch);
     for(zone = 1; zone < NUM_ZONES; zone++)
       if(REAL_ZONE(zone) && ZONE_FLAGGED(zone, Z_IMMORT))
       {
         sprintf(buf,"(%d) %s\n\r",
                 zone_table[zone].number, zone_table[zone].name);
         S2C();
	 return;
       }
  }

  half_chop(argument, zstr, buf);

  
  if (!is_number(zstr))
  {
    send_to_char("Usage:  zimmort <zone_num> < 'on' || 'off' >.\n\r",ch);
    return;
  }

  zone = atoi(zstr);
  if (!REAL_ZONE(zone) || ZONE_FLAGGED(zone, Z_CLOSED))
  {
    send_to_char("Zone doesn't exist or it's closed.\n\r",ch);
    return;
  }
  
  if (str_cmp(buf, "on") && str_cmp(buf, "off"))
  {
    send_to_char("Usage:  zimmort <zone_num> < 'on' || 'off' >.\n\r",ch);
    return;
  }

  if (GET_LEVEL(ch) < LEV_AIMP)
  {
     send_to_char("Only AIMP+ may designate an IMMORTAL ZONE.\n\r",ch);
     return;
  }

  if (!olc_perms(ch, LEV_IMPL, zone))
    return;

  if (!str_cmp(buf, "on"))
  {
    SET_BIT(ZONE_FLAGS(zone), Z_IMMORT);
    send_to_char("Ok.  That zone is now flagged IMMORT.\n\r",ch);
    return;
  }
  else
  {
    REMOVE_BIT(ZONE_FLAGS(zone), Z_IMMORT);
    send_to_char("Ok.  That zone is no longer flagged IMMORT.\n\r",ch);
    return;
  }
}

ACMD(do_ztest)
{

  char zstr[MAX_INPUT_LENGTH];
  int zone;

  if (IS_NPC(ch)) return;

  if (strlen(argument) > MAX_CLAN_LENGTH)
    return;

  if (!*argument)
  {
     send_to_char("Current zones flagged TEST:\n\r",ch);
     for(zone = 1; zone < NUM_ZONES; zone++)
       if(REAL_ZONE(zone) && ZONE_FLAGGED(zone, Z_TEST))
       {
         sprintf(buf,"(%d) %s\n\r",
                 zone_table[zone].number, zone_table[zone].name);
         S2C();
	 return;
       }
  }

  half_chop(argument, zstr, buf);

  
  if (!is_number(zstr))
  {
    send_to_char("Usage:  ztest <zone_num> < 'on' || 'off' >.\n\r",ch);
    return;
  }

  zone = atoi(zstr);
  if (!REAL_ZONE(zone) || ZONE_FLAGGED(zone, Z_CLOSED))
  {
    send_to_char("Zone doesn't exist or it's closed.\n\r",ch);
    return;
  }
  
  if (str_cmp(buf, "on") && str_cmp(buf, "off"))
  {
    send_to_char("Usage:  ztest <zone_num> < 'on' || 'off' >.\n\r",ch);
    return;
  }

  if (GET_LEVEL(ch) < LEV_GOD)
  {
     send_to_char("Only GOD+ may designate an Test Zone.\n\r",ch);
     return;
  }

  if (!olc_perms(ch, LEV_IMPL, zone))
    return;

  if (!str_cmp(buf, "on"))
  {
    SET_BIT(ZONE_FLAGS(zone), Z_TEST);
    send_to_char("Ok.  That zone is now flagged TEST.\n\r",ch);
    return;
  }
  else
  {
    REMOVE_BIT(ZONE_FLAGS(zone), Z_TEST);
    send_to_char("Ok.  That zone is no longer flagged TEST.\n\r",ch);
    return;
  }
}

/* for ascii text conversion to ANSI color codes */
/* reads in a file from disk, converts it using the RoA standard color codes
   and then writes it back to a different file   RoA Innovations*/ 
ACMD(do_convert)
{
  FILE *fp;
  char *text;
  char inname[MAX_INPUT_LENGTH];
  char outname[MAX_INPUT_LENGTH];
  char cstr[MAX_STRING_LENGTH];

  int file_to_string_alloc(char *name, char **buf);

  if (IS_NPC(ch)) return;

  if (!ANSI(ch))
  {
    send_to_char("You must have ANSI color on to convert.\n\r",ch);
    return;
  }

  half_chop(argument, arg, buf2);
  if (!*arg || !*buf2 || !(str_cmp(arg, buf2)))
  {
    send_to_char("Usage: convert <file1> <file2>.  (note: file1 != file2)\n\r",ch);
    return;
  }

  strcpy(inname, "../lib/convert/");
  strcat(inname, arg);
  strcpy(outname, "../lib/convert/");
  strcat(outname, buf2);

  sprintf(buf, "Reading [%s].\n\r",inname);
  S2C();

  if (file_to_string_alloc(inname, &text) < 0)
  {
    send_to_char("Error in file allocation and/or location.\n\r",ch);
    return;
  }

  color_decode(ch, text, cstr);
  killr(cstr);

  sprintf(buf, "Writing [%s].\n\r",outname);
  S2C();

  /* open , write, close */
  if (!(fp = fopen(outname, "wt")))
  {
    send_to_char("Error opening outfile for writing.\n\r",ch);
    return;
  }

  fputs(cstr,fp);
  fclose(fp);
}