/ circle3.1 / src / act.wizard.c
act.wizard.c
   1  /* ************************************************************************
   2  *   File: act.wizard.c                                  Part of CircleMUD *
   3  *  Usage: Player-level god commands and other goodies                     *
   4  *                                                                         *
   5  *  All rights reserved.  See license.doc for complete information.        *
   6  *                                                                         *
   7  *  Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
   8  *  CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991.               *
   9  ************************************************************************ */
  10  
  11  #include "conf.h"
  12  #include "sysdep.h"
  13  
  14  #include "structs.h"
  15  #include "utils.h"
  16  #include "comm.h"
  17  #include "interpreter.h"
  18  #include "handler.h"
  19  #include "db.h"
  20  #include "spells.h"
  21  #include "house.h"
  22  #include "screen.h"
  23  #include "constants.h"
  24  
  25  /*   external vars  */
  26  extern FILE *player_fl;
  27  extern struct attack_hit_type attack_hit_text[];
  28  extern char *class_abbrevs[];
  29  extern time_t boot_time;
  30  extern int circle_shutdown, circle_reboot;
  31  extern int circle_restrict;
  32  extern int load_into_inventory;
  33  extern int buf_switches, buf_largecount, buf_overflows;
  34  extern int top_of_p_table;
  35  
  36  /* for chars */
  37  extern const char *pc_class_types[];
  38  
  39  /* extern functions */
  40  int level_exp(int chclass, int level);
  41  void show_shops(struct char_data *ch, char *value);
  42  void hcontrol_list_houses(struct char_data *ch);
  43  void do_start(struct char_data *ch);
  44  void appear(struct char_data *ch);
  45  void reset_zone(zone_rnum zone);
  46  void roll_real_abils(struct char_data *ch);
  47  int parse_class(char arg);
  48  void run_autowiz(void);
  49  
  50  /* local functions */
  51  int perform_set(struct char_data *ch, struct char_data *vict, int mode, char *val_arg);
  52  void perform_immort_invis(struct char_data *ch, int level);
  53  ACMD(do_echo);
  54  ACMD(do_send);
  55  room_rnum find_target_room(struct char_data *ch, char *rawroomstr);
  56  ACMD(do_at);
  57  ACMD(do_goto);
  58  ACMD(do_trans);
  59  ACMD(do_teleport);
  60  ACMD(do_vnum);
  61  void do_stat_room(struct char_data *ch);
  62  void do_stat_object(struct char_data *ch, struct obj_data *j);
  63  void do_stat_character(struct char_data *ch, struct char_data *k);
  64  ACMD(do_stat);
  65  ACMD(do_shutdown);
  66  void stop_snooping(struct char_data *ch);
  67  ACMD(do_snoop);
  68  ACMD(do_switch);
  69  ACMD(do_return);
  70  ACMD(do_load);
  71  ACMD(do_vstat);
  72  ACMD(do_purge);
  73  ACMD(do_syslog);
  74  ACMD(do_advance);
  75  ACMD(do_restore);
  76  void perform_immort_vis(struct char_data *ch);
  77  ACMD(do_invis);
  78  ACMD(do_gecho);
  79  ACMD(do_poofset);
  80  ACMD(do_dc);
  81  ACMD(do_wizlock);
  82  ACMD(do_date);
  83  ACMD(do_last);
  84  ACMD(do_force);
  85  ACMD(do_wiznet);
  86  ACMD(do_zreset);
  87  ACMD(do_wizutil);
  88  size_t print_zone_to_buf(char *bufptr, size_t left, zone_rnum zone);
  89  ACMD(do_show);
  90  ACMD(do_set);
  91  void snoop_check(struct char_data *ch);
  92  
  93  
  94  ACMD(do_echo)
  95  {
  96    skip_spaces(&argument);
  97  
  98    if (!*argument)
  99      send_to_char(ch, "Yes.. but what?\r\n");
 100    else {
 101      char buf[MAX_INPUT_LENGTH + 4];
 102  
 103      if (subcmd == SCMD_EMOTE)
 104        snprintf(buf, sizeof(buf), "$n %s", argument);
 105      else
 106        strlcpy(buf, argument, sizeof(buf));
 107  
 108      act(buf, FALSE, ch, 0, 0, TO_ROOM);
 109  
 110      if (PRF_FLAGGED(ch, PRF_NOREPEAT))
 111        send_to_char(ch, "%s", OK);
 112      else
 113        act(buf, FALSE, ch, 0, 0, TO_CHAR);
 114    }
 115  }
 116  
 117  
 118  ACMD(do_send)
 119  {
 120    char arg[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH];
 121    struct char_data *vict;
 122  
 123    half_chop(argument, arg, buf);
 124  
 125    if (!*arg) {
 126      send_to_char(ch, "Send what to who?\r\n");
 127      return;
 128    }
 129    if (!(vict = get_char_vis(ch, arg, NULL, FIND_CHAR_WORLD))) {
 130      send_to_char(ch, "%s", NOPERSON);
 131      return;
 132    }
 133    send_to_char(vict, "%s\r\n", buf);
 134    if (PRF_FLAGGED(ch, PRF_NOREPEAT))
 135      send_to_char(ch, "Sent.\r\n");
 136    else
 137      send_to_char(ch, "You send '%s' to %s.\r\n", buf, GET_NAME(vict));
 138  }
 139  
 140  
 141  
 142  /* take a string, and return an rnum.. used for goto, at, etc.  -je 4/6/93 */
 143  room_rnum find_target_room(struct char_data *ch, char *rawroomstr)
 144  {
 145    room_rnum location = NOWHERE;
 146    char roomstr[MAX_INPUT_LENGTH];
 147  
 148    one_argument(rawroomstr, roomstr);
 149  
 150    if (!*roomstr) {
 151      send_to_char(ch, "You must supply a room number or name.\r\n");
 152      return (NOWHERE);
 153    }
 154  
 155    if (isdigit(*roomstr) && !strchr(roomstr, '.')) {
 156      if ((location = real_room((room_vnum)atoi(roomstr))) == NOWHERE) {
 157        send_to_char(ch, "No room exists with that number.\r\n");
 158        return (NOWHERE);
 159      }
 160    } else {
 161      struct char_data *target_mob;
 162      struct obj_data *target_obj;
 163      char *mobobjstr = roomstr;
 164      int num;
 165  
 166      num = get_number(&mobobjstr);
 167      if ((target_mob = get_char_vis(ch, mobobjstr, &num, FIND_CHAR_WORLD)) != NULL) {
 168        if ((location = IN_ROOM(target_mob)) == NOWHERE) {
 169          send_to_char(ch, "That character is currently lost.\r\n");
 170          return (NOWHERE);
 171        }
 172      } else if ((target_obj = get_obj_vis(ch, mobobjstr, &num)) != NULL) {
 173        if (IN_ROOM(target_obj) != NOWHERE)
 174          location = IN_ROOM(target_obj);
 175        else if (target_obj->carried_by && IN_ROOM(target_obj->carried_by) != NOWHERE)
 176          location = IN_ROOM(target_obj->carried_by);
 177        else if (target_obj->worn_by && IN_ROOM(target_obj->worn_by) != NOWHERE)
 178          location = IN_ROOM(target_obj->worn_by);
 179  
 180        if (location == NOWHERE) {
 181          send_to_char(ch, "That object is currently not in a room.\r\n");
 182          return (NOWHERE);
 183        }
 184      }
 185  
 186      if (location == NOWHERE) {
 187        send_to_char(ch, "Nothing exists by that name.\r\n");
 188        return (NOWHERE);
 189      }
 190    }
 191  
 192    /* a location has been found -- if you're >= GRGOD, no restrictions. */
 193    if (GET_LEVEL(ch) >= LVL_GRGOD)
 194      return (location);
 195  
 196    if (ROOM_FLAGGED(location, ROOM_GODROOM))
 197      send_to_char(ch, "You are not godly enough to use that room!\r\n");
 198    else if (ROOM_FLAGGED(location, ROOM_PRIVATE) && world[location].people && world[location].people->next_in_room)
 199      send_to_char(ch, "There's a private conversation going on in that room.\r\n");
 200    else if (ROOM_FLAGGED(location, ROOM_HOUSE) && !House_can_enter(ch, GET_ROOM_VNUM(location)))
 201      send_to_char(ch, "That's private property -- no trespassing!\r\n");
 202    else
 203      return (location);
 204  
 205    return (NOWHERE);
 206  }
 207  
 208  
 209  
 210  ACMD(do_at)
 211  {
 212    char command[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH];
 213    room_rnum location, original_loc;
 214  
 215    half_chop(argument, buf, command);
 216    if (!*buf) {
 217      send_to_char(ch, "You must supply a room number or a name.\r\n");
 218      return;
 219    }
 220  
 221    if (!*command) {
 222      send_to_char(ch, "What do you want to do there?\r\n");
 223      return;
 224    }
 225  
 226    if ((location = find_target_room(ch, buf)) == NOWHERE)
 227      return;
 228  
 229    /* a location has been found. */
 230    original_loc = IN_ROOM(ch);
 231    char_from_room(ch);
 232    char_to_room(ch, location);
 233    command_interpreter(ch, command);
 234  
 235    /* check if the char is still there */
 236    if (IN_ROOM(ch) == location) {
 237      char_from_room(ch);
 238      char_to_room(ch, original_loc);
 239    }
 240  }
 241  
 242  
 243  ACMD(do_goto)
 244  {
 245    char buf[MAX_STRING_LENGTH];
 246    room_rnum location;
 247  
 248    if ((location = find_target_room(ch, argument)) == NOWHERE)
 249      return;
 250  
 251    snprintf(buf, sizeof(buf), "$n %s", POOFOUT(ch) ? POOFOUT(ch) : "disappears in a puff of smoke.");
 252    act(buf, TRUE, ch, 0, 0, TO_ROOM);
 253  
 254    char_from_room(ch);
 255    char_to_room(ch, location);
 256  
 257    snprintf(buf, sizeof(buf), "$n %s", POOFIN(ch) ? POOFIN(ch) : "appears with an ear-splitting bang.");
 258    act(buf, TRUE, ch, 0, 0, TO_ROOM);
 259  
 260    look_at_room(ch, 0);
 261  }
 262  
 263  
 264  
 265  ACMD(do_trans)
 266  {
 267    char buf[MAX_INPUT_LENGTH];
 268    struct descriptor_data *i;
 269    struct char_data *victim;
 270  
 271    one_argument(argument, buf);
 272    if (!*buf)
 273      send_to_char(ch, "Whom do you wish to transfer?\r\n");
 274    else if (str_cmp("all", buf)) {
 275      if (!(victim = get_char_vis(ch, buf, NULL, FIND_CHAR_WORLD)))
 276        send_to_char(ch, "%s", NOPERSON);
 277      else if (victim == ch)
 278        send_to_char(ch, "That doesn't make much sense, does it?\r\n");
 279      else {
 280        if ((GET_LEVEL(ch) < GET_LEVEL(victim)) && !IS_NPC(victim)) {
 281  	send_to_char(ch, "Go transfer someone your own size.\r\n");
 282  	return;
 283        }
 284        act("$n disappears in a mushroom cloud.", FALSE, victim, 0, 0, TO_ROOM);
 285        char_from_room(victim);
 286        char_to_room(victim, IN_ROOM(ch));
 287        act("$n arrives from a puff of smoke.", FALSE, victim, 0, 0, TO_ROOM);
 288        act("$n has transferred you!", FALSE, ch, 0, victim, TO_VICT);
 289        look_at_room(victim, 0);
 290      }
 291    } else {			/* Trans All */
 292      if (GET_LEVEL(ch) < LVL_GRGOD) {
 293        send_to_char(ch, "I think not.\r\n");
 294        return;
 295      }
 296  
 297      for (i = descriptor_list; i; i = i->next)
 298        if (STATE(i) == CON_PLAYING && i->character && i->character != ch) {
 299  	victim = i->character;
 300  	if (GET_LEVEL(victim) >= GET_LEVEL(ch))
 301  	  continue;
 302  	act("$n disappears in a mushroom cloud.", FALSE, victim, 0, 0, TO_ROOM);
 303  	char_from_room(victim);
 304  	char_to_room(victim, IN_ROOM(ch));
 305  	act("$n arrives from a puff of smoke.", FALSE, victim, 0, 0, TO_ROOM);
 306  	act("$n has transferred you!", FALSE, ch, 0, victim, TO_VICT);
 307  	look_at_room(victim, 0);
 308        }
 309      send_to_char(ch, "%s", OK);
 310    }
 311  }
 312  
 313  
 314  
 315  ACMD(do_teleport)
 316  {
 317    char buf[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH];
 318    struct char_data *victim;
 319    room_rnum target;
 320  
 321    two_arguments(argument, buf, buf2);
 322  
 323    if (!*buf)
 324      send_to_char(ch, "Whom do you wish to teleport?\r\n");
 325    else if (!(victim = get_char_vis(ch, buf, NULL, FIND_CHAR_WORLD)))
 326      send_to_char(ch, "%s", NOPERSON);
 327    else if (victim == ch)
 328      send_to_char(ch, "Use 'goto' to teleport yourself.\r\n");
 329    else if (GET_LEVEL(victim) >= GET_LEVEL(ch))
 330      send_to_char(ch, "Maybe you shouldn't do that.\r\n");
 331    else if (!*buf2)
 332      send_to_char(ch, "Where do you wish to send this person?\r\n");
 333    else if ((target = find_target_room(ch, buf2)) != NOWHERE) {
 334      send_to_char(ch, "%s", OK);
 335      act("$n disappears in a puff of smoke.", FALSE, victim, 0, 0, TO_ROOM);
 336      char_from_room(victim);
 337      char_to_room(victim, target);
 338      act("$n arrives from a puff of smoke.", FALSE, victim, 0, 0, TO_ROOM);
 339      act("$n has teleported you!", FALSE, ch, 0, (char *) victim, TO_VICT);
 340      look_at_room(victim, 0);
 341    }
 342  }
 343  
 344  
 345  
 346  ACMD(do_vnum)
 347  {
 348    char buf[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH];
 349  
 350    half_chop(argument, buf, buf2);
 351  
 352    if (!*buf || !*buf2 || (!is_abbrev(buf, "mob") && !is_abbrev(buf, "obj"))) {
 353      send_to_char(ch, "Usage: vnum { obj | mob } <name>\r\n");
 354      return;
 355    }
 356    if (is_abbrev(buf, "mob"))
 357      if (!vnum_mobile(buf2, ch))
 358        send_to_char(ch, "No mobiles by that name.\r\n");
 359  
 360    if (is_abbrev(buf, "obj"))
 361      if (!vnum_object(buf2, ch))
 362        send_to_char(ch, "No objects by that name.\r\n");
 363  }
 364  
 365  
 366  
 367  void do_stat_room(struct char_data *ch)
 368  {
 369    char buf2[MAX_STRING_LENGTH];
 370    struct extra_descr_data *desc;
 371    struct room_data *rm = &world[IN_ROOM(ch)];
 372    int i, found, column;
 373    struct obj_data *j;
 374    struct char_data *k;
 375  
 376    send_to_char(ch, "Room name: %s%s%s\r\n", CCCYN(ch, C_NRM), rm->name, CCNRM(ch, C_NRM));
 377  
 378    sprinttype(rm->sector_type, sector_types, buf2, sizeof(buf2));
 379    send_to_char(ch, "Zone: [%3d], VNum: [%s%5d%s], RNum: [%5d], Type: %s\r\n",
 380  	  zone_table[rm->zone].number, CCGRN(ch, C_NRM), rm->number,
 381  	  CCNRM(ch, C_NRM), IN_ROOM(ch), buf2);
 382  
 383    sprintbit(rm->room_flags, room_bits, buf2, sizeof(buf2));
 384    send_to_char(ch, "SpecProc: %s, Flags: %s\r\n", rm->func == NULL ? "None" : "Exists", buf2);
 385  
 386    send_to_char(ch, "Description:\r\n%s", rm->description ? rm->description : "  None.\r\n");
 387  
 388    if (rm->ex_description) {
 389      send_to_char(ch, "Extra descs:%s", CCCYN(ch, C_NRM));
 390      for (desc = rm->ex_description; desc; desc = desc->next)
 391        send_to_char(ch, " %s", desc->keyword);
 392      send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM));
 393    }
 394  
 395    send_to_char(ch, "Chars present:%s", CCYEL(ch, C_NRM));
 396    column = 14;	/* ^^^ strlen ^^^ */
 397    for (found = FALSE, k = rm->people; k; k = k->next_in_room) {
 398      if (!CAN_SEE(ch, k))
 399        continue;
 400  
 401      column += send_to_char(ch, "%s %s(%s)", found++ ? "," : "", GET_NAME(k),
 402  		!IS_NPC(k) ? "PC" : (!IS_MOB(k) ? "NPC" : "MOB"));
 403      if (column >= 62) {
 404        send_to_char(ch, "%s\r\n", k->next_in_room ? "," : "");
 405        found = FALSE;
 406        column = 0;
 407      }
 408    }
 409    send_to_char(ch, "%s", CCNRM(ch, C_NRM));
 410  
 411    if (rm->contents) {
 412      send_to_char(ch, "Contents:%s", CCGRN(ch, C_NRM));
 413      column = 9;	/* ^^^ strlen ^^^ */
 414  
 415      for (found = 0, j = rm->contents; j; j = j->next_content) {
 416        if (!CAN_SEE_OBJ(ch, j))
 417  	continue;
 418  
 419        column += send_to_char(ch, "%s %s", found++ ? "," : "", j->short_description);
 420        if (column >= 62) {
 421  	send_to_char(ch, "%s\r\n", j->next_content ? "," : "");
 422  	found = FALSE;
 423          column = 0;
 424        }
 425      }
 426      send_to_char(ch, "%s", CCNRM(ch, C_NRM));
 427    }
 428  
 429    for (i = 0; i < NUM_OF_DIRS; i++) {
 430      char buf1[128];
 431  
 432      if (!rm->dir_option[i])
 433        continue;
 434  
 435      if (rm->dir_option[i]->to_room == NOWHERE)
 436        snprintf(buf1, sizeof(buf1), " %sNONE%s", CCCYN(ch, C_NRM), CCNRM(ch, C_NRM));
 437      else
 438        snprintf(buf1, sizeof(buf1), "%s%5d%s", CCCYN(ch, C_NRM), GET_ROOM_VNUM(rm->dir_option[i]->to_room), CCNRM(ch, C_NRM));
 439  
 440      sprintbit(rm->dir_option[i]->exit_info, exit_bits, buf2, sizeof(buf2));
 441  
 442      send_to_char(ch, "Exit %s%-5s%s:  To: [%s], Key: [%5d], Keywrd: %s, Type: %s\r\n%s",
 443  	CCCYN(ch, C_NRM), dirs[i], CCNRM(ch, C_NRM), buf1, rm->dir_option[i]->key,
 444  	rm->dir_option[i]->keyword ? rm->dir_option[i]->keyword : "None", buf2,
 445  	rm->dir_option[i]->general_description ? rm->dir_option[i]->general_description : "  No exit description.\r\n");
 446    }
 447  }
 448  
 449  
 450  
 451  void do_stat_object(struct char_data *ch, struct obj_data *j)
 452  {
 453    int i, found;
 454    obj_vnum vnum;
 455    struct obj_data *j2;
 456    struct extra_descr_data *desc;
 457    char buf[MAX_STRING_LENGTH];
 458  
 459    vnum = GET_OBJ_VNUM(j);
 460    send_to_char(ch, "Name: '%s%s%s', Aliases: %s\r\n", CCYEL(ch, C_NRM),
 461  	  j->short_description ? j->short_description : "<None>",
 462  	  CCNRM(ch, C_NRM), j->name);
 463  
 464    sprinttype(GET_OBJ_TYPE(j), item_types, buf, sizeof(buf));
 465    send_to_char(ch, "VNum: [%s%5d%s], RNum: [%5d], Type: %s, SpecProc: %s\r\n",
 466  	CCGRN(ch, C_NRM), vnum, CCNRM(ch, C_NRM), GET_OBJ_RNUM(j), buf,
 467  	GET_OBJ_SPEC(j) ? "Exists" : "None");
 468  
 469    if (j->ex_description) {
 470      send_to_char(ch, "Extra descs:%s", CCCYN(ch, C_NRM));
 471      for (desc = j->ex_description; desc; desc = desc->next)
 472        send_to_char(ch, " %s", desc->keyword);
 473      send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM));
 474    }
 475  
 476    sprintbit(GET_OBJ_WEAR(j), wear_bits, buf, sizeof(buf));
 477    send_to_char(ch, "Can be worn on: %s\r\n", buf);
 478  
 479    sprintbit(GET_OBJ_AFFECT(j), affected_bits, buf, sizeof(buf));
 480    send_to_char(ch, "Set char bits : %s\r\n", buf);
 481  
 482    sprintbit(GET_OBJ_EXTRA(j), extra_bits, buf, sizeof(buf));
 483    send_to_char(ch, "Extra flags   : %s\r\n", buf);
 484  
 485    send_to_char(ch, "Weight: %d, Value: %d, Cost/day: %d, Timer: %d\r\n",
 486       GET_OBJ_WEIGHT(j), GET_OBJ_COST(j), GET_OBJ_RENT(j), GET_OBJ_TIMER(j));
 487  
 488    send_to_char(ch, "In room: %d (%s), ", GET_ROOM_VNUM(IN_ROOM(j)),
 489  	IN_ROOM(j) == NOWHERE ? "Nowhere" : world[IN_ROOM(j)].name);
 490  
 491    /*
 492     * NOTE: In order to make it this far, we must already be able to see the
 493     *       character holding the object. Therefore, we do not need CAN_SEE().
 494     */
 495    send_to_char(ch, "In object: %s, ", j->in_obj ? j->in_obj->short_description : "None");
 496    send_to_char(ch, "Carried by: %s, ", j->carried_by ? GET_NAME(j->carried_by) : "Nobody");
 497    send_to_char(ch, "Worn by: %s\r\n", j->worn_by ? GET_NAME(j->worn_by) : "Nobody");
 498  
 499    switch (GET_OBJ_TYPE(j)) {
 500    case ITEM_LIGHT:
 501      if (GET_OBJ_VAL(j, 2) == -1)
 502        send_to_char(ch, "Hours left: Infinite\r\n");
 503      else
 504        send_to_char(ch, "Hours left: [%d]\r\n", GET_OBJ_VAL(j, 2));
 505      break;
 506    case ITEM_SCROLL:
 507    case ITEM_POTION:
 508      send_to_char(ch, "Spells: (Level %d) %s, %s, %s\r\n", GET_OBJ_VAL(j, 0),
 509  	    skill_name(GET_OBJ_VAL(j, 1)), skill_name(GET_OBJ_VAL(j, 2)),
 510  	    skill_name(GET_OBJ_VAL(j, 3)));
 511      break;
 512    case ITEM_WAND:
 513    case ITEM_STAFF:
 514      send_to_char(ch, "Spell: %s at level %d, %d (of %d) charges remaining\r\n",
 515  	    skill_name(GET_OBJ_VAL(j, 3)), GET_OBJ_VAL(j, 0),
 516  	    GET_OBJ_VAL(j, 2), GET_OBJ_VAL(j, 1));
 517      break;
 518    case ITEM_WEAPON:
 519      send_to_char(ch, "Todam: %dd%d, Message type: %d\r\n",
 520  	    GET_OBJ_VAL(j, 1), GET_OBJ_VAL(j, 2), GET_OBJ_VAL(j, 3));
 521      break;
 522    case ITEM_ARMOR:
 523      send_to_char(ch, "AC-apply: [%d]\r\n", GET_OBJ_VAL(j, 0));
 524      break;
 525    case ITEM_TRAP:
 526      send_to_char(ch, "Spell: %d, - Hitpoints: %d\r\n", GET_OBJ_VAL(j, 0), GET_OBJ_VAL(j, 1));
 527      break;
 528    case ITEM_CONTAINER:
 529      sprintbit(GET_OBJ_VAL(j, 1), container_bits, buf, sizeof(buf));
 530      send_to_char(ch, "Weight capacity: %d, Lock Type: %s, Key Num: %d, Corpse: %s\r\n",
 531  	    GET_OBJ_VAL(j, 0), buf, GET_OBJ_VAL(j, 2),
 532  	    YESNO(GET_OBJ_VAL(j, 3)));
 533      break;
 534    case ITEM_DRINKCON:
 535    case ITEM_FOUNTAIN:
 536      sprinttype(GET_OBJ_VAL(j, 2), drinks, buf, sizeof(buf));
 537      send_to_char(ch, "Capacity: %d, Contains: %d, Poisoned: %s, Liquid: %s\r\n",
 538  	    GET_OBJ_VAL(j, 0), GET_OBJ_VAL(j, 1), YESNO(GET_OBJ_VAL(j, 3)), buf);
 539      break;
 540    case ITEM_NOTE:
 541      send_to_char(ch, "Tongue: %d\r\n", GET_OBJ_VAL(j, 0));
 542      break;
 543    case ITEM_KEY:
 544      /* Nothing */
 545      break;
 546    case ITEM_FOOD:
 547      send_to_char(ch, "Makes full: %d, Poisoned: %s\r\n", GET_OBJ_VAL(j, 0), YESNO(GET_OBJ_VAL(j, 3)));
 548      break;
 549    case ITEM_MONEY:
 550      send_to_char(ch, "Coins: %d\r\n", GET_OBJ_VAL(j, 0));
 551      break;
 552    default:
 553      send_to_char(ch, "Values 0-3: [%d] [%d] [%d] [%d]\r\n",
 554  	    GET_OBJ_VAL(j, 0), GET_OBJ_VAL(j, 1),
 555  	    GET_OBJ_VAL(j, 2), GET_OBJ_VAL(j, 3));
 556      break;
 557    }
 558  
 559    /*
 560     * I deleted the "equipment status" code from here because it seemed
 561     * more or less useless and just takes up valuable screen space.
 562     */
 563  
 564    if (j->contains) {
 565      int column;
 566  
 567      send_to_char(ch, "\r\nContents:%s", CCGRN(ch, C_NRM));
 568      column = 9;	/* ^^^ strlen ^^^ */
 569  
 570      for (found = 0, j2 = j->contains; j2; j2 = j2->next_content) {
 571        column += send_to_char(ch, "%s %s", found++ ? "," : "", j2->short_description);
 572        if (column >= 62) {
 573  	send_to_char(ch, "%s\r\n", j2->next_content ? "," : "");
 574  	found = FALSE;
 575          column = 0;
 576        }
 577      }
 578      send_to_char(ch, "%s", CCNRM(ch, C_NRM));
 579    }
 580  
 581    found = FALSE;
 582    send_to_char(ch, "Affections:");
 583    for (i = 0; i < MAX_OBJ_AFFECT; i++)
 584      if (j->affected[i].modifier) {
 585        sprinttype(j->affected[i].location, apply_types, buf, sizeof(buf));
 586        send_to_char(ch, "%s %+d to %s", found++ ? "," : "", j->affected[i].modifier, buf);
 587      }
 588    if (!found)
 589      send_to_char(ch, " None");
 590  
 591    send_to_char(ch, "\r\n");
 592  }
 593  
 594  
 595  void do_stat_character(struct char_data *ch, struct char_data *k)
 596  {
 597    char buf[MAX_STRING_LENGTH];
 598    int i, i2, column, found = FALSE;
 599    struct obj_data *j;
 600    struct follow_type *fol;
 601    struct affected_type *aff;
 602  
 603    sprinttype(GET_SEX(k), genders, buf, sizeof(buf));
 604    send_to_char(ch, "%s %s '%s'  IDNum: [%5ld], In room [%5d]\r\n",
 605  	  buf, (!IS_NPC(k) ? "PC" : (!IS_MOB(k) ? "NPC" : "MOB")),
 606  	  GET_NAME(k), GET_IDNUM(k), GET_ROOM_VNUM(IN_ROOM(k)));
 607  
 608    if (IS_MOB(k))
 609      send_to_char(ch, "Alias: %s, VNum: [%5d], RNum: [%5d]\r\n", k->player.name, GET_MOB_VNUM(k), GET_MOB_RNUM(k));
 610  
 611    send_to_char(ch, "Title: %s\r\n", k->player.title ? k->player.title : "<None>");
 612  
 613    send_to_char(ch, "L-Des: %s", k->player.long_descr ? k->player.long_descr : "<None>\r\n");
 614  
 615    sprinttype(k->player.chclass, IS_NPC(k) ? npc_class_types : pc_class_types, buf, sizeof(buf));
 616    send_to_char(ch, "%sClass: %s, Lev: [%s%2d%s], XP: [%s%7d%s], Align: [%4d]\r\n",
 617  	IS_NPC(k) ? "Monster " : "", buf, CCYEL(ch, C_NRM), GET_LEVEL(k), CCNRM(ch, C_NRM),
 618  	CCYEL(ch, C_NRM), GET_EXP(k), CCNRM(ch, C_NRM), GET_ALIGNMENT(k));
 619  
 620    if (!IS_NPC(k)) {
 621      char buf1[64], buf2[64];
 622  
 623      strlcpy(buf1, asctime(localtime(&(k->player.time.birth))), sizeof(buf1));
 624      strlcpy(buf2, asctime(localtime(&(k->player.time.logon))), sizeof(buf2));
 625      buf1[10] = buf2[10] = '\0';
 626  
 627      send_to_char(ch, "Created: [%s], Last Logon: [%s], Played [%dh %dm], Age [%d]\r\n",
 628  	    buf1, buf2, k->player.time.played / 3600,
 629  	    ((k->player.time.played % 3600) / 60), age(k)->year);
 630  
 631      send_to_char(ch, "Hometown: [%d], Speaks: [%d/%d/%d], (STL[%d]/per[%d]/NSTL[%d])\r\n",
 632  	 k->player.hometown, GET_TALK(k, 0), GET_TALK(k, 1), GET_TALK(k, 2),
 633  	    GET_PRACTICES(k), int_app[GET_INT(k)].learn,
 634  	    wis_app[GET_WIS(k)].bonus);
 635    }
 636    send_to_char(ch, "Str: [%s%d/%d%s]  Int: [%s%d%s]  Wis: [%s%d%s]  "
 637  	  "Dex: [%s%d%s]  Con: [%s%d%s]  Cha: [%s%d%s]\r\n",
 638  	  CCCYN(ch, C_NRM), GET_STR(k), GET_ADD(k), CCNRM(ch, C_NRM),
 639  	  CCCYN(ch, C_NRM), GET_INT(k), CCNRM(ch, C_NRM),
 640  	  CCCYN(ch, C_NRM), GET_WIS(k), CCNRM(ch, C_NRM),
 641  	  CCCYN(ch, C_NRM), GET_DEX(k), CCNRM(ch, C_NRM),
 642  	  CCCYN(ch, C_NRM), GET_CON(k), CCNRM(ch, C_NRM),
 643  	  CCCYN(ch, C_NRM), GET_CHA(k), CCNRM(ch, C_NRM));
 644  
 645    send_to_char(ch, "Hit p.:[%s%d/%d+%d%s]  Mana p.:[%s%d/%d+%d%s]  Move p.:[%s%d/%d+%d%s]\r\n",
 646  	  CCGRN(ch, C_NRM), GET_HIT(k), GET_MAX_HIT(k), hit_gain(k), CCNRM(ch, C_NRM),
 647  	  CCGRN(ch, C_NRM), GET_MANA(k), GET_MAX_MANA(k), mana_gain(k), CCNRM(ch, C_NRM),
 648  	  CCGRN(ch, C_NRM), GET_MOVE(k), GET_MAX_MOVE(k), move_gain(k), CCNRM(ch, C_NRM));
 649  
 650    send_to_char(ch, "Coins: [%9d], Bank: [%9d] (Total: %d)\r\n",
 651  	  GET_GOLD(k), GET_BANK_GOLD(k), GET_GOLD(k) + GET_BANK_GOLD(k));
 652  
 653    send_to_char(ch, "AC: [%d%+d/10], Hitroll: [%2d], Damroll: [%2d], Saving throws: [%d/%d/%d/%d/%d]\r\n",
 654  	  GET_AC(k), dex_app[GET_DEX(k)].defensive, k->points.hitroll,
 655  	  k->points.damroll, GET_SAVE(k, 0), GET_SAVE(k, 1), GET_SAVE(k, 2),
 656  	  GET_SAVE(k, 3), GET_SAVE(k, 4));
 657  
 658    sprinttype(GET_POS(k), position_types, buf, sizeof(buf));
 659    send_to_char(ch, "Pos: %s, Fighting: %s", buf, FIGHTING(k) ? GET_NAME(FIGHTING(k)) : "Nobody");
 660  
 661    if (IS_NPC(k))
 662      send_to_char(ch, ", Attack type: %s", attack_hit_text[(int) k->mob_specials.attack_type].singular);
 663  
 664    if (k->desc) {
 665      sprinttype(STATE(k->desc), connected_types, buf, sizeof(buf));
 666      send_to_char(ch, ", Connected: %s", buf);
 667    }
 668  
 669    if (IS_NPC(k)) {
 670      sprinttype(k->mob_specials.default_pos, position_types, buf, sizeof(buf));
 671      send_to_char(ch, ", Default position: %s\r\n", buf);
 672      sprintbit(MOB_FLAGS(k), action_bits, buf, sizeof(buf));
 673      send_to_char(ch, "NPC flags: %s%s%s\r\n", CCCYN(ch, C_NRM), buf, CCNRM(ch, C_NRM));
 674    } else {
 675      send_to_char(ch, ", Idle Timer (in tics) [%d]\r\n", k->char_specials.timer);
 676  
 677      sprintbit(PLR_FLAGS(k), player_bits, buf, sizeof(buf));
 678      send_to_char(ch, "PLR: %s%s%s\r\n", CCCYN(ch, C_NRM), buf, CCNRM(ch, C_NRM));
 679  
 680      sprintbit(PRF_FLAGS(k), preference_bits, buf, sizeof(buf));
 681      send_to_char(ch, "PRF: %s%s%s\r\n", CCGRN(ch, C_NRM), buf, CCNRM(ch, C_NRM));
 682    }
 683  
 684    if (IS_MOB(k))
 685      send_to_char(ch, "Mob Spec-Proc: %s, NPC Bare Hand Dam: %dd%d\r\n",
 686  	    (mob_index[GET_MOB_RNUM(k)].func ? "Exists" : "None"),
 687  	    k->mob_specials.damnodice, k->mob_specials.damsizedice);
 688  
 689    for (i = 0, j = k->carrying; j; j = j->next_content, i++);
 690    send_to_char(ch, "Carried: weight: %d, items: %d; Items in: inventory: %d, ", IS_CARRYING_W(k), IS_CARRYING_N(k), i);
 691  
 692    for (i = 0, i2 = 0; i < NUM_WEARS; i++)
 693      if (GET_EQ(k, i))
 694        i2++;
 695    send_to_char(ch, "eq: %d\r\n", i2);
 696  
 697    if (!IS_NPC(k))
 698      send_to_char(ch, "Hunger: %d, Thirst: %d, Drunk: %d\r\n", GET_COND(k, FULL), GET_COND(k, THIRST), GET_COND(k, DRUNK));
 699  
 700    column = send_to_char(ch, "Master is: %s, Followers are:", k->master ? GET_NAME(k->master) : "<none>");
 701    if (!k->followers)
 702      send_to_char(ch, " <none>\r\n");
 703    else {
 704      for (fol = k->followers; fol; fol = fol->next) {
 705        column += send_to_char(ch, "%s %s", found++ ? "," : "", PERS(fol->follower, ch));
 706        if (column >= 62) {
 707          send_to_char(ch, "%s\r\n", fol->next ? "," : "");
 708          found = FALSE;
 709          column = 0;
 710        }
 711      }
 712      if (column != 0)
 713        send_to_char(ch, "\r\n");
 714    }
 715  
 716    /* Showing the bitvector */
 717    sprintbit(AFF_FLAGS(k), affected_bits, buf, sizeof(buf));
 718    send_to_char(ch, "AFF: %s%s%s\r\n", CCYEL(ch, C_NRM), buf, CCNRM(ch, C_NRM));
 719  
 720    /* Routine to show what spells a char is affected by */
 721    if (k->affected) {
 722      for (aff = k->affected; aff; aff = aff->next) {
 723        send_to_char(ch, "SPL: (%3dhr) %s%-21s%s ", aff->duration + 1, CCCYN(ch, C_NRM), skill_name(aff->type), CCNRM(ch, C_NRM));
 724  
 725        if (aff->modifier)
 726  	send_to_char(ch, "%+d to %s", aff->modifier, apply_types[(int) aff->location]);
 727  
 728        if (aff->bitvector) {
 729  	if (aff->modifier)
 730  	  send_to_char(ch, ", ");
 731  
 732  	sprintbit(aff->bitvector, affected_bits, buf, sizeof(buf));
 733          send_to_char(ch, "sets %s", buf);
 734        }
 735        send_to_char(ch, "\r\n");
 736      }
 737    }
 738  }
 739  
 740  
 741  ACMD(do_stat)
 742  {
 743    char buf1[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH];
 744    struct char_data *victim;
 745    struct obj_data *object;
 746    struct char_file_u tmp_store;
 747  
 748    half_chop(argument, buf1, buf2);
 749  
 750    if (!*buf1) {
 751      send_to_char(ch, "Stats on who or what?\r\n");
 752      return;
 753    } else if (is_abbrev(buf1, "room")) {
 754      do_stat_room(ch);
 755    } else if (is_abbrev(buf1, "mob")) {
 756      if (!*buf2)
 757        send_to_char(ch, "Stats on which mobile?\r\n");
 758      else {
 759        if ((victim = get_char_vis(ch, buf2, NULL, FIND_CHAR_WORLD)) != NULL)
 760  	do_stat_character(ch, victim);
 761        else
 762  	send_to_char(ch, "No such mobile around.\r\n");
 763      }
 764    } else if (is_abbrev(buf1, "player")) {
 765      if (!*buf2) {
 766        send_to_char(ch, "Stats on which player?\r\n");
 767      } else {
 768        if ((victim = get_player_vis(ch, buf2, NULL, FIND_CHAR_WORLD)) != NULL)
 769  	do_stat_character(ch, victim);
 770        else
 771  	send_to_char(ch, "No such player around.\r\n");
 772      }
 773    } else if (is_abbrev(buf1, "file")) {
 774      if (!*buf2)
 775        send_to_char(ch, "Stats on which player?\r\n");
 776      else if ((victim = get_player_vis(ch, buf2, NULL, FIND_CHAR_WORLD)) != NULL)
 777  	do_stat_character(ch, victim);
 778      else {
 779        CREATE(victim, struct char_data, 1);
 780        clear_char(victim);
 781        if (load_char(buf2, &tmp_store) >= 0) {
 782  	store_to_char(&tmp_store, victim);
 783  	victim->player.time.logon = tmp_store.last_logon;
 784  	char_to_room(victim, 0);
 785  	if (GET_LEVEL(victim) > GET_LEVEL(ch))
 786  	  send_to_char(ch, "Sorry, you can't do that.\r\n");
 787  	else
 788  	  do_stat_character(ch, victim);
 789  	extract_char_final(victim);
 790        } else {
 791  	send_to_char(ch, "There is no such player.\r\n");
 792  	free(victim);
 793        }
 794      }
 795    } else if (is_abbrev(buf1, "object")) {
 796      if (!*buf2)
 797        send_to_char(ch, "Stats on which object?\r\n");
 798      else {
 799        if ((object = get_obj_vis(ch, buf2, NULL)) != NULL)
 800  	do_stat_object(ch, object);
 801        else
 802  	send_to_char(ch, "No such object around.\r\n");
 803      }
 804    } else {
 805      char *name = buf1;
 806      int number = get_number(&name);
 807  
 808      if ((object = get_obj_in_equip_vis(ch, name, &number, ch->equipment)) != NULL)
 809        do_stat_object(ch, object);
 810      else if ((object = get_obj_in_list_vis(ch, name, &number, ch->carrying)) != NULL)
 811        do_stat_object(ch, object);
 812      else if ((victim = get_char_vis(ch, name, &number, FIND_CHAR_ROOM)) != NULL)
 813        do_stat_character(ch, victim);
 814      else if ((object = get_obj_in_list_vis(ch, name, &number, world[IN_ROOM(ch)].contents)) != NULL)
 815        do_stat_object(ch, object);
 816      else if ((victim = get_char_vis(ch, name, &number, FIND_CHAR_WORLD)) != NULL)
 817        do_stat_character(ch, victim);
 818      else if ((object = get_obj_vis(ch, name, &number)) != NULL)
 819        do_stat_object(ch, object);
 820      else
 821        send_to_char(ch, "Nothing around by that name.\r\n");
 822    }
 823  }
 824  
 825  
 826  ACMD(do_shutdown)
 827  {
 828    char arg[MAX_INPUT_LENGTH];
 829  
 830    if (subcmd != SCMD_SHUTDOWN) {
 831      send_to_char(ch, "If you want to shut something down, say so!\r\n");
 832      return;
 833    }
 834    one_argument(argument, arg);
 835  
 836    if (!*arg) {
 837      log("(GC) Shutdown by %s.", GET_NAME(ch));
 838      send_to_all("Shutting down.\r\n");
 839      circle_shutdown = 1;
 840    } else if (!str_cmp(arg, "reboot")) {
 841      log("(GC) Reboot by %s.", GET_NAME(ch));
 842      send_to_all("Rebooting.. come back in a minute or two.\r\n");
 843      touch(FASTBOOT_FILE);
 844      circle_shutdown = circle_reboot = 1;
 845    } else if (!str_cmp(arg, "die")) {
 846      log("(GC) Shutdown by %s.", GET_NAME(ch));
 847      send_to_all("Shutting down for maintenance.\r\n");
 848      touch(KILLSCRIPT_FILE);
 849      circle_shutdown = 1;
 850    } else if (!str_cmp(arg, "pause")) {
 851      log("(GC) Shutdown by %s.", GET_NAME(ch));
 852      send_to_all("Shutting down for maintenance.\r\n");
 853      touch(PAUSE_FILE);
 854      circle_shutdown = 1;
 855    } else
 856      send_to_char(ch, "Unknown shutdown option.\r\n");
 857  }
 858  
 859  
 860  void snoop_check(struct char_data *ch)
 861  {
 862    /*  This short routine is to ensure that characters that happen
 863     *  to be snooping (or snooped) and get advanced/demoted will
 864     *  not be snooping/snooped someone of a higher/lower level (and
 865     *  thus, not entitled to be snooping.
 866     */
 867    if (!ch || !ch->desc)
 868      return;
 869    if (ch->desc->snooping &&
 870       (GET_LEVEL(ch->desc->snooping->character) >= GET_LEVEL(ch))) {
 871      ch->desc->snooping->snoop_by = NULL;
 872      ch->desc->snooping = NULL;
 873    }
 874  
 875    if (ch->desc->snoop_by &&
 876       (GET_LEVEL(ch) >= GET_LEVEL(ch->desc->snoop_by->character))) {
 877      ch->desc->snoop_by->snooping = NULL;
 878      ch->desc->snoop_by = NULL;
 879    }
 880  }
 881  
 882  void stop_snooping(struct char_data *ch)
 883  {
 884    if (!ch->desc->snooping)
 885      send_to_char(ch, "You aren't snooping anyone.\r\n");
 886    else {
 887      send_to_char(ch, "You stop snooping.\r\n");
 888      ch->desc->snooping->snoop_by = NULL;
 889      ch->desc->snooping = NULL;
 890    }
 891  }
 892  
 893  
 894  ACMD(do_snoop)
 895  {
 896    char arg[MAX_INPUT_LENGTH];
 897    struct char_data *victim, *tch;
 898  
 899    if (!ch->desc)
 900      return;
 901  
 902    one_argument(argument, arg);
 903  
 904    if (!*arg)
 905      stop_snooping(ch);
 906    else if (!(victim = get_char_vis(ch, arg, NULL, FIND_CHAR_WORLD)))
 907      send_to_char(ch, "No such person around.\r\n");
 908    else if (!victim->desc)
 909      send_to_char(ch, "There's no link.. nothing to snoop.\r\n");
 910    else if (victim == ch)
 911      stop_snooping(ch);
 912    else if (victim->desc->snoop_by)
 913      send_to_char(ch, "Busy already. \r\n");
 914    else if (victim->desc->snooping == ch->desc)
 915      send_to_char(ch, "Don't be stupid.\r\n");
 916    else {
 917      if (victim->desc->original)
 918        tch = victim->desc->original;
 919      else
 920        tch = victim;
 921  
 922      if (GET_LEVEL(tch) >= GET_LEVEL(ch)) {
 923        send_to_char(ch, "You can't.\r\n");
 924        return;
 925      }
 926      send_to_char(ch, "%s", OK);
 927  
 928      if (ch->desc->snooping)
 929        ch->desc->snooping->snoop_by = NULL;
 930  
 931      ch->desc->snooping = victim->desc;
 932      victim->desc->snoop_by = ch->desc;
 933    }
 934  }
 935  
 936  
 937  
 938  ACMD(do_switch)
 939  {
 940    char arg[MAX_INPUT_LENGTH];
 941    struct char_data *victim;
 942  
 943    one_argument(argument, arg);
 944  
 945    if (ch->desc->original)
 946      send_to_char(ch, "You're already switched.\r\n");
 947    else if (!*arg)
 948      send_to_char(ch, "Switch with who?\r\n");
 949    else if (!(victim = get_char_vis(ch, arg, NULL, FIND_CHAR_WORLD)))
 950      send_to_char(ch, "No such character.\r\n");
 951    else if (ch == victim)
 952      send_to_char(ch, "Hee hee... we are jolly funny today, eh?\r\n");
 953    else if (victim->desc)
 954      send_to_char(ch, "You can't do that, the body is already in use!\r\n");
 955    else if ((GET_LEVEL(ch) < LVL_IMPL) && !IS_NPC(victim))
 956      send_to_char(ch, "You aren't holy enough to use a mortal's body.\r\n");
 957    else if (GET_LEVEL(ch) < LVL_GRGOD && ROOM_FLAGGED(IN_ROOM(victim), ROOM_GODROOM))
 958      send_to_char(ch, "You are not godly enough to use that room!\r\n");
 959    else if (GET_LEVEL(ch) < LVL_GRGOD && ROOM_FLAGGED(IN_ROOM(victim), ROOM_HOUSE)
 960  		&& !House_can_enter(ch, GET_ROOM_VNUM(IN_ROOM(victim))))
 961      send_to_char(ch, "That's private property -- no trespassing!\r\n");
 962    else {
 963      send_to_char(ch, "%s", OK);
 964  
 965      ch->desc->character = victim;
 966      ch->desc->original = ch;
 967  
 968      victim->desc = ch->desc;
 969      ch->desc = NULL;
 970    }
 971  }
 972  
 973  
 974  ACMD(do_return)
 975  {
 976    if (ch->desc && ch->desc->original) {
 977      send_to_char(ch, "You return to your original body.\r\n");
 978  
 979      /*
 980       * If someone switched into your original body, disconnect them.
 981       *   - JE 2/22/95
 982       *
 983       * Zmey: here we put someone switched in our body to disconnect state
 984       * but we must also NULL his pointer to our character, otherwise
 985       * close_socket() will damage our character's pointer to our descriptor
 986       * (which is assigned below in this function). 12/17/99
 987       */
 988      if (ch->desc->original->desc) {
 989        ch->desc->original->desc->character = NULL;
 990        STATE(ch->desc->original->desc) = CON_DISCONNECT;
 991      }
 992  
 993      /* Now our descriptor points to our original body. */
 994      ch->desc->character = ch->desc->original;
 995      ch->desc->original = NULL;
 996  
 997      /* And our body's pointer to descriptor now points to our descriptor. */
 998      ch->desc->character->desc = ch->desc;
 999      ch->desc = NULL;
1000    }
1001  }
1002  
1003  
1004  
1005  ACMD(do_load)
1006  {
1007    char buf[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH];
1008  
1009    two_arguments(argument, buf, buf2);
1010  
1011    if (!*buf || !*buf2 || !isdigit(*buf2)) {
1012      send_to_char(ch, "Usage: load { obj | mob } <number>\r\n");
1013      return;
1014    }
1015    if (!is_number(buf2)) {
1016      send_to_char(ch, "That is not a number.\r\n");
1017      return;
1018    }
1019  
1020    if (is_abbrev(buf, "mob")) {
1021      struct char_data *mob;
1022      mob_rnum r_num;
1023  
1024      if ((r_num = real_mobile(atoi(buf2))) == NOBODY) {
1025        send_to_char(ch, "There is no monster with that number.\r\n");
1026        return;
1027      }
1028      mob = read_mobile(r_num, REAL);
1029      char_to_room(mob, IN_ROOM(ch));
1030  
1031      act("$n makes a quaint, magical gesture with one hand.", TRUE, ch,
1032  	0, 0, TO_ROOM);
1033      act("$n has created $N!", FALSE, ch, 0, mob, TO_ROOM);
1034      act("You create $N.", FALSE, ch, 0, mob, TO_CHAR);
1035    } else if (is_abbrev(buf, "obj")) {
1036      struct obj_data *obj;
1037      obj_rnum r_num;
1038  
1039      if ((r_num = real_object(atoi(buf2))) == NOTHING) {
1040        send_to_char(ch, "There is no object with that number.\r\n");
1041        return;
1042      }
1043      obj = read_object(r_num, REAL);
1044      if (load_into_inventory)
1045        obj_to_char(obj, ch);
1046      else
1047        obj_to_room(obj, IN_ROOM(ch));
1048      act("$n makes a strange magical gesture.", TRUE, ch, 0, 0, TO_ROOM);
1049      act("$n has created $p!", FALSE, ch, obj, 0, TO_ROOM);
1050      act("You create $p.", FALSE, ch, obj, 0, TO_CHAR);
1051    } else
1052      send_to_char(ch, "That'll have to be either 'obj' or 'mob'.\r\n");
1053  }
1054  
1055  
1056  
1057  ACMD(do_vstat)
1058  {
1059    char buf[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH];
1060  
1061    two_arguments(argument, buf, buf2);
1062  
1063    if (!*buf || !*buf2 || !isdigit(*buf2)) {
1064      send_to_char(ch, "Usage: vstat { obj | mob } <number>\r\n");
1065      return;
1066    }
1067    if (!is_number(buf2)) {
1068      send_to_char(ch, "That's not a valid number.\r\n");
1069      return;
1070    }
1071  
1072    if (is_abbrev(buf, "mob")) {
1073      struct char_data *mob;
1074      mob_rnum r_num;
1075  
1076      if ((r_num = real_mobile(atoi(buf2))) == NOBODY) {
1077        send_to_char(ch, "There is no monster with that number.\r\n");
1078        return;
1079      }
1080      mob = read_mobile(r_num, REAL);
1081      char_to_room(mob, 0);
1082      do_stat_character(ch, mob);
1083      extract_char(mob);
1084    } else if (is_abbrev(buf, "obj")) {
1085      struct obj_data *obj;
1086      obj_rnum r_num;
1087  
1088      if ((r_num = real_object(atoi(buf2))) == NOTHING) {
1089        send_to_char(ch, "There is no object with that number.\r\n");
1090        return;
1091      }
1092      obj = read_object(r_num, REAL);
1093      do_stat_object(ch, obj);
1094      extract_obj(obj);
1095    } else
1096      send_to_char(ch, "That'll have to be either 'obj' or 'mob'.\r\n");
1097  }
1098  
1099  
1100  
1101  
1102  /* clean a room of all mobiles and objects */
1103  ACMD(do_purge)
1104  {
1105    char buf[MAX_INPUT_LENGTH];
1106    struct char_data *vict;
1107    struct obj_data *obj;
1108  
1109    one_argument(argument, buf);
1110  
1111    /* argument supplied. destroy single object or char */
1112    if (*buf) {
1113      if ((vict = get_char_vis(ch, buf, NULL, FIND_CHAR_ROOM)) != NULL) {
1114        if (!IS_NPC(vict) && (GET_LEVEL(ch) <= GET_LEVEL(vict))) {
1115  	send_to_char(ch, "Fuuuuuuuuu!\r\n");
1116  	return;
1117        }
1118        act("$n disintegrates $N.", FALSE, ch, 0, vict, TO_NOTVICT);
1119  
1120        if (!IS_NPC(vict)) {
1121  	mudlog(BRF, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "(GC) %s has purged %s.", GET_NAME(ch), GET_NAME(vict));
1122  	if (vict->desc) {
1123  	  STATE(vict->desc) = CON_CLOSE;
1124  	  vict->desc->character = NULL;
1125  	  vict->desc = NULL;
1126  	}
1127        }
1128        extract_char(vict);
1129      } else if ((obj = get_obj_in_list_vis(ch, buf, NULL, world[IN_ROOM(ch)].contents)) != NULL) {
1130        act("$n destroys $p.", FALSE, ch, obj, 0, TO_ROOM);
1131        extract_obj(obj);
1132      } else {
1133        send_to_char(ch, "Nothing here by that name.\r\n");
1134        return;
1135      }
1136  
1137      send_to_char(ch, "%s", OK);
1138    } else {			/* no argument. clean out the room */
1139      int i;
1140  
1141      act("$n gestures... You are surrounded by scorching flames!",
1142  	FALSE, ch, 0, 0, TO_ROOM);
1143      send_to_room(IN_ROOM(ch), "The world seems a little cleaner.\r\n");
1144  
1145      for (vict = world[IN_ROOM(ch)].people; vict; vict = vict->next_in_room) {
1146        if (!IS_NPC(vict))
1147          continue;
1148  
1149        /* Dump inventory. */
1150        while (vict->carrying)
1151          extract_obj(vict->carrying);
1152  
1153        /* Dump equipment. */
1154        for (i = 0; i < NUM_WEARS; i++)
1155          if (GET_EQ(vict, i))
1156            extract_obj(GET_EQ(vict, i));
1157  
1158        /* Dump character. */
1159        extract_char(vict);
1160      }
1161  
1162      /* Clear the ground. */
1163      while (world[IN_ROOM(ch)].contents)
1164        extract_obj(world[IN_ROOM(ch)].contents);
1165    }
1166  }
1167  
1168  
1169  
1170  const char *logtypes[] = {
1171    "off", "brief", "normal", "complete", "\n"
1172  };
1173  
1174  ACMD(do_syslog)
1175  {
1176    char arg[MAX_INPUT_LENGTH];
1177    int tp;
1178  
1179    one_argument(argument, arg);
1180    if (!*arg) {
1181      send_to_char(ch, "Your syslog is currently %s.\r\n",
1182  	logtypes[(PRF_FLAGGED(ch, PRF_LOG1) ? 1 : 0) + (PRF_FLAGGED(ch, PRF_LOG2) ? 2 : 0)]);
1183      return;
1184    }
1185    if (((tp = search_block(arg, logtypes, FALSE)) == -1)) {
1186      send_to_char(ch, "Usage: syslog { Off | Brief | Normal | Complete }\r\n");
1187      return;
1188    }
1189    REMOVE_BIT(PRF_FLAGS(ch), PRF_LOG1 | PRF_LOG2);
1190    SET_BIT(PRF_FLAGS(ch), (PRF_LOG1 * (tp & 1)) | (PRF_LOG2 * (tp & 2) >> 1));
1191  
1192    send_to_char(ch, "Your syslog is now %s.\r\n", logtypes[tp]);
1193  }
1194  
1195  
1196  
1197  ACMD(do_advance)
1198  {
1199    struct char_data *victim;
1200    char name[MAX_INPUT_LENGTH], level[MAX_INPUT_LENGTH];
1201    int newlevel, oldlevel;
1202  
1203    two_arguments(argument, name, level);
1204  
1205    if (*name) {
1206      if (!(victim = get_char_vis(ch, name, NULL, FIND_CHAR_WORLD))) {
1207        send_to_char(ch, "That player is not here.\r\n");
1208        return;
1209      }
1210    } else {
1211      send_to_char(ch, "Advance who?\r\n");
1212      return;
1213    }
1214  
1215    if (GET_LEVEL(ch) <= GET_LEVEL(victim)) {
1216      send_to_char(ch, "Maybe that's not such a great idea.\r\n");
1217      return;
1218    }
1219    if (IS_NPC(victim)) {
1220      send_to_char(ch, "NO!  Not on NPC's.\r\n");
1221      return;
1222    }
1223    if (!*level || (newlevel = atoi(level)) <= 0) {
1224      send_to_char(ch, "That's not a level!\r\n");
1225      return;
1226    }
1227    if (newlevel > LVL_IMPL) {
1228      send_to_char(ch, "%d is the highest possible level.\r\n", LVL_IMPL);
1229      return;
1230    }
1231    if (newlevel > GET_LEVEL(ch)) {
1232      send_to_char(ch, "Yeah, right.\r\n");
1233      return;
1234    }
1235    if (newlevel == GET_LEVEL(victim)) {
1236      send_to_char(ch, "They are already at that level.\r\n");
1237      return;
1238    }
1239    oldlevel = GET_LEVEL(victim);
1240    if (newlevel < GET_LEVEL(victim)) {
1241      do_start(victim);
1242      GET_LEVEL(victim) = newlevel;
1243      send_to_char(victim, "You are momentarily enveloped by darkness!\r\nYou feel somewhat diminished.\r\n");
1244    } else {
1245      act("$n makes some strange gestures.\r\n"
1246  	"A strange feeling comes upon you,\r\n"
1247  	"Like a giant hand, light comes down\r\n"
1248  	"from above, grabbing your body, that\r\n"
1249  	"begins to pulse with colored lights\r\n"
1250  	"from inside.\r\n\r\n"
1251  	"Your head seems to be filled with demons\r\n"
1252  	"from another plane as your body dissolves\r\n"
1253  	"to the elements of time and space itself.\r\n"
1254  	"Suddenly a silent explosion of light\r\n"
1255  	"snaps you back to reality.\r\n\r\n"
1256  	"You feel slightly different.", FALSE, ch, 0, victim, TO_VICT);
1257    }
1258  
1259    send_to_char(ch, "%s", OK);
1260  
1261    if (newlevel < oldlevel)
1262      log("(GC) %s demoted %s from level %d to %d.",
1263  		GET_NAME(ch), GET_NAME(victim), oldlevel, newlevel);
1264    else
1265      log("(GC) %s has advanced %s to level %d (from %d)",
1266  		GET_NAME(ch), GET_NAME(victim), newlevel, oldlevel);
1267  
1268    if (oldlevel >= LVL_IMMORT && newlevel < LVL_IMMORT) {
1269      /* If they are no longer an immortal, let's remove some of the
1270       * nice immortal only flags, shall we?
1271       */
1272      REMOVE_BIT(PRF_FLAGS(victim), PRF_LOG1 | PRF_LOG2);
1273      REMOVE_BIT(PRF_FLAGS(victim), PRF_NOHASSLE | PRF_HOLYLIGHT);
1274      run_autowiz();
1275    }
1276  
1277    gain_exp_regardless(victim,
1278  	 level_exp(GET_CLASS(victim), newlevel) - GET_EXP(victim));
1279    save_char(victim);
1280  }
1281  
1282  ACMD(do_restore)
1283  {
1284    char buf[MAX_INPUT_LENGTH];
1285    struct char_data *vict;
1286    int i;
1287  
1288    one_argument(argument, buf);
1289    if (!*buf)
1290      send_to_char(ch, "Whom do you wish to restore?\r\n");
1291    else if (!(vict = get_char_vis(ch, buf, NULL, FIND_CHAR_WORLD)))
1292      send_to_char(ch, "%s", NOPERSON);
1293    else if (!IS_NPC(vict) && ch != vict && GET_LEVEL(vict) >= GET_LEVEL(ch))
1294      send_to_char(ch, "They don't need your help.\r\n");
1295    else {
1296      GET_HIT(vict) = GET_MAX_HIT(vict);
1297      GET_MANA(vict) = GET_MAX_MANA(vict);
1298      GET_MOVE(vict) = GET_MAX_MOVE(vict);
1299  
1300      if (!IS_NPC(vict) && GET_LEVEL(ch) >= LVL_GRGOD) {
1301        if (GET_LEVEL(vict) >= LVL_IMMORT)
1302          for (i = 1; i <= MAX_SKILLS; i++)
1303            SET_SKILL(vict, i, 100);
1304  
1305        if (GET_LEVEL(vict) >= LVL_GRGOD) {
1306  	vict->real_abils.str_add = 100;
1307  	vict->real_abils.intel = 25;
1308  	vict->real_abils.wis = 25;
1309  	vict->real_abils.dex = 25;
1310  	vict->real_abils.str = 25;
1311  	vict->real_abils.con = 25;
1312  	vict->real_abils.cha = 25;
1313        }
1314      }
1315      update_pos(vict);
1316      affect_total(vict);
1317      send_to_char(ch, "%s", OK);
1318      act("You have been fully healed by $N!", FALSE, vict, 0, ch, TO_CHAR);
1319    }
1320  }
1321  
1322  
1323  void perform_immort_vis(struct char_data *ch)
1324  {
1325    if (GET_INVIS_LEV(ch) == 0 && !AFF_FLAGGED(ch, AFF_HIDE | AFF_INVISIBLE)) {
1326      send_to_char(ch, "You are already fully visible.\r\n");
1327      return;
1328    }
1329     
1330    GET_INVIS_LEV(ch) = 0;
1331    appear(ch);
1332    send_to_char(ch, "You are now fully visible.\r\n");
1333  }
1334  
1335  
1336  void perform_immort_invis(struct char_data *ch, int level)
1337  {
1338    struct char_data *tch;
1339  
1340    for (tch = world[IN_ROOM(ch)].people; tch; tch = tch->next_in_room) {
1341      if (tch == ch)
1342        continue;
1343      if (GET_LEVEL(tch) >= GET_INVIS_LEV(ch) && GET_LEVEL(tch) < level)
1344        act("You blink and suddenly realize that $n is gone.", FALSE, ch, 0,
1345  	  tch, TO_VICT);
1346      if (GET_LEVEL(tch) < GET_INVIS_LEV(ch) && GET_LEVEL(tch) >= level)
1347        act("You suddenly realize that $n is standing beside you.", FALSE, ch, 0,
1348  	  tch, TO_VICT);
1349    }
1350  
1351    GET_INVIS_LEV(ch) = level;
1352    send_to_char(ch, "Your invisibility level is %d.\r\n", level);
1353  }
1354    
1355  
1356  ACMD(do_invis)
1357  {
1358    char arg[MAX_INPUT_LENGTH];
1359    int level;
1360  
1361    if (IS_NPC(ch)) {
1362      send_to_char(ch, "You can't do that!\r\n");
1363      return;
1364    }
1365  
1366    one_argument(argument, arg);
1367    if (!*arg) {
1368      if (GET_INVIS_LEV(ch) > 0)
1369        perform_immort_vis(ch);
1370      else
1371        perform_immort_invis(ch, GET_LEVEL(ch));
1372    } else {
1373      level = atoi(arg);
1374      if (level > GET_LEVEL(ch))
1375        send_to_char(ch, "You can't go invisible above your own level.\r\n");
1376      else if (level < 1)
1377        perform_immort_vis(ch);
1378      else
1379        perform_immort_invis(ch, level);
1380    }
1381  }
1382  
1383  
1384  ACMD(do_gecho)
1385  {
1386    struct descriptor_data *pt;
1387  
1388    skip_spaces(&argument);
1389    delete_doubledollar(argument);
1390  
1391    if (!*argument)
1392      send_to_char(ch, "That must be a mistake...\r\n");
1393    else {
1394      for (pt = descriptor_list; pt; pt = pt->next)
1395        if (STATE(pt) == CON_PLAYING && pt->character && pt->character != ch)
1396  	send_to_char(pt->character, "%s\r\n", argument);
1397  
1398      if (PRF_FLAGGED(ch, PRF_NOREPEAT))
1399        send_to_char(ch, "%s", OK);
1400      else
1401        send_to_char(ch, "%s\r\n", argument);
1402    }
1403  }
1404  
1405  
1406  ACMD(do_poofset)
1407  {
1408    char **msg;
1409  
1410    switch (subcmd) {
1411    case SCMD_POOFIN:    msg = &(POOFIN(ch));    break;
1412    case SCMD_POOFOUT:   msg = &(POOFOUT(ch));   break;
1413    default:    return;
1414    }
1415  
1416    skip_spaces(&argument);
1417  
1418    if (*msg)
1419      free(*msg);
1420  
1421    if (!*argument)
1422      *msg = NULL;
1423    else
1424      *msg = strdup(argument);
1425  
1426    send_to_char(ch, "%s", OK);
1427  }
1428  
1429  
1430  
1431  ACMD(do_dc)
1432  {
1433    char arg[MAX_INPUT_LENGTH];
1434    struct descriptor_data *d;
1435    int num_to_dc;
1436  
1437    one_argument(argument, arg);
1438    if (!(num_to_dc = atoi(arg))) {
1439      send_to_char(ch, "Usage: DC <user number> (type USERS for a list)\r\n");
1440      return;
1441    }
1442    for (d = descriptor_list; d && d->desc_num != num_to_dc; d = d->next);
1443  
1444    if (!d) {
1445      send_to_char(ch, "No such connection.\r\n");
1446      return;
1447    }
1448    if (d->character && GET_LEVEL(d->character) >= GET_LEVEL(ch)) {
1449      if (!CAN_SEE(ch, d->character))
1450        send_to_char(ch, "No such connection.\r\n");
1451      else
1452        send_to_char(ch, "Umm.. maybe that's not such a good idea...\r\n");
1453      return;
1454    }
1455  
1456    /* We used to just close the socket here using close_socket(), but
1457     * various people pointed out this could cause a crash if you're
1458     * closing the person below you on the descriptor list.  Just setting
1459     * to CON_CLOSE leaves things in a massively inconsistent state so I
1460     * had to add this new flag to the descriptor. -je
1461     *
1462     * It is a much more logical extension for a CON_DISCONNECT to be used
1463     * for in-game socket closes and CON_CLOSE for out of game closings.
1464     * This will retain the stability of the close_me hack while being
1465     * neater in appearance. -gg 12/1/97
1466     *
1467     * For those unlucky souls who actually manage to get disconnected
1468     * by two different immortals in the same 1/10th of a second, we have
1469     * the below 'if' check. -gg 12/17/99
1470     */
1471    if (STATE(d) == CON_DISCONNECT || STATE(d) == CON_CLOSE)
1472      send_to_char(ch, "They're already being disconnected.\r\n");
1473    else {
1474      /*
1475       * Remember that we can disconnect people not in the game and
1476       * that rather confuses the code when it expected there to be
1477       * a character context.
1478       */
1479      if (STATE(d) == CON_PLAYING)
1480        STATE(d) = CON_DISCONNECT;
1481      else
1482        STATE(d) = CON_CLOSE;
1483  
1484      send_to_char(ch, "Connection #%d closed.\r\n", num_to_dc);
1485      log("(GC) Connection closed by %s.", GET_NAME(ch));
1486    }
1487  }
1488  
1489  
1490  
1491  ACMD(do_wizlock)
1492  {
1493    char arg[MAX_INPUT_LENGTH];
1494    int value;
1495    const char *when;
1496  
1497    one_argument(argument, arg);
1498    if (*arg) {
1499      value = atoi(arg);
1500      if (value < 0 || value > GET_LEVEL(ch)) {
1501        send_to_char(ch, "Invalid wizlock value.\r\n");
1502        return;
1503      }
1504      circle_restrict = value;
1505      when = "now";
1506    } else
1507      when = "currently";
1508  
1509    switch (circle_restrict) {
1510    case 0:
1511      send_to_char(ch, "The game is %s completely open.\r\n", when);
1512      break;
1513    case 1:
1514      send_to_char(ch, "The game is %s closed to new players.\r\n", when);
1515      break;
1516    default:
1517      send_to_char(ch, "Only level %d and above may enter the game %s.\r\n", circle_restrict, when);
1518      break;
1519    }
1520  }
1521  
1522  
1523  ACMD(do_date)
1524  {
1525    char *tmstr;
1526    time_t mytime;
1527    int d, h, m;
1528  
1529    if (subcmd == SCMD_DATE)
1530      mytime = time(0);
1531    else
1532      mytime = boot_time;
1533  
1534    tmstr = (char *) asctime(localtime(&mytime));
1535    *(tmstr + strlen(tmstr) - 1) = '\0';
1536  
1537    if (subcmd == SCMD_DATE)
1538      send_to_char(ch, "Current machine time: %s\r\n", tmstr);
1539    else {
1540      mytime = time(0) - boot_time;
1541      d = mytime / 86400;
1542      h = (mytime / 3600) % 24;
1543      m = (mytime / 60) % 60;
1544  
1545      send_to_char(ch, "Up since %s: %d day%s, %d:%02d\r\n", tmstr, d, d == 1 ? "" : "s", h, m);
1546    }
1547  }
1548  
1549  
1550  
1551  ACMD(do_last)
1552  {
1553    char arg[MAX_INPUT_LENGTH];
1554    struct char_file_u chdata;
1555  
1556    one_argument(argument, arg);
1557    if (!*arg) {
1558      send_to_char(ch, "For whom do you wish to search?\r\n");
1559      return;
1560    }
1561    if (load_char(arg, &chdata) < 0) {
1562      send_to_char(ch, "There is no such player.\r\n");
1563      return;
1564    }
1565    if ((chdata.level > GET_LEVEL(ch)) && (GET_LEVEL(ch) < LVL_IMPL)) {
1566      send_to_char(ch, "You are not sufficiently godly for that!\r\n");
1567      return;
1568    }
1569    send_to_char(ch, "[%5ld] [%2d %s] %-12s : %-18s : %-20s\r\n",
1570  	  chdata.char_specials_saved.idnum, chdata.level,
1571  	  class_abbrevs[(int) chdata.chclass], chdata.name, chdata.host,
1572  	  ctime(&chdata.last_logon));
1573  }
1574  
1575  
1576  ACMD(do_force)
1577  {
1578    struct descriptor_data *i, *next_desc;
1579    struct char_data *vict, *next_force;
1580    char arg[MAX_INPUT_LENGTH], to_force[MAX_INPUT_LENGTH], buf1[MAX_INPUT_LENGTH + 32];
1581  
1582    half_chop(argument, arg, to_force);
1583  
1584    snprintf(buf1, sizeof(buf1), "$n has forced you to '%s'.", to_force);
1585  
1586    if (!*arg || !*to_force)
1587      send_to_char(ch, "Whom do you wish to force do what?\r\n");
1588    else if ((GET_LEVEL(ch) < LVL_GRGOD) || (str_cmp("all", arg) && str_cmp("room", arg))) {
1589      if (!(vict = get_char_vis(ch, arg, NULL, FIND_CHAR_WORLD)))
1590        send_to_char(ch, "%s", NOPERSON);
1591      else if (!IS_NPC(vict) && GET_LEVEL(ch) <= GET_LEVEL(vict))
1592        send_to_char(ch, "No, no, no!\r\n");
1593      else {
1594        send_to_char(ch, "%s", OK);
1595        act(buf1, TRUE, ch, NULL, vict, TO_VICT);
1596        mudlog(NRM, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "(GC) %s forced %s to %s", GET_NAME(ch), GET_NAME(vict), to_force);
1597        command_interpreter(vict, to_force);
1598      }
1599    } else if (!str_cmp("room", arg)) {
1600      send_to_char(ch, "%s", OK);
1601      mudlog(NRM, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "(GC) %s forced room %d to %s",
1602  		GET_NAME(ch), GET_ROOM_VNUM(IN_ROOM(ch)), to_force);
1603  
1604      for (vict = world[IN_ROOM(ch)].people; vict; vict = next_force) {
1605        next_force = vict->next_in_room;
1606        if (!IS_NPC(vict) && GET_LEVEL(vict) >= GET_LEVEL(ch))
1607  	continue;
1608        act(buf1, TRUE, ch, NULL, vict, TO_VICT);
1609        command_interpreter(vict, to_force);
1610      }
1611    } else { /* force all */
1612      send_to_char(ch, "%s", OK);
1613      mudlog(NRM, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "(GC) %s forced all to %s", GET_NAME(ch), to_force);
1614  
1615      for (i = descriptor_list; i; i = next_desc) {
1616        next_desc = i->next;
1617  
1618        if (STATE(i) != CON_PLAYING || !(vict = i->character) || (!IS_NPC(vict) && GET_LEVEL(vict) >= GET_LEVEL(ch)))
1619  	continue;
1620        act(buf1, TRUE, ch, NULL, vict, TO_VICT);
1621        command_interpreter(vict, to_force);
1622      }
1623    }
1624  }
1625  
1626  
1627  
1628  ACMD(do_wiznet)
1629  {
1630    char buf1[MAX_INPUT_LENGTH + MAX_NAME_LENGTH + 32],
1631  	buf2[MAX_INPUT_LENGTH + MAX_NAME_LENGTH + 32];
1632    struct descriptor_data *d;
1633    char emote = FALSE;
1634    char any = FALSE;
1635    int level = LVL_IMMORT;
1636  
1637    skip_spaces(&argument);
1638    delete_doubledollar(argument);
1639  
1640    if (!*argument) {
1641      send_to_char(ch, "Usage: wiznet <text> | #<level> <text> | *<emotetext> |\r\n        wiznet @<level> *<emotetext> | wiz @\r\n");
1642      return;
1643    }
1644    switch (*argument) {
1645    case '*':
1646      emote = TRUE;
1647    case '#':
1648      one_argument(argument + 1, buf1);
1649      if (is_number(buf1)) {
1650        half_chop(argument+1, buf1, argument);
1651        level = MAX(atoi(buf1), LVL_IMMORT);
1652        if (level > GET_LEVEL(ch)) {
1653  	send_to_char(ch, "You can't wizline above your own level.\r\n");
1654  	return;
1655        }
1656      } else if (emote)
1657        argument++;
1658      break;
1659  
1660    case '@':
1661      send_to_char(ch, "God channel status:\r\n");
1662      for (any = 0, d = descriptor_list; d; d = d->next) {
1663        if (STATE(d) != CON_PLAYING || GET_LEVEL(d->character) < LVL_IMMORT)
1664          continue;
1665        if (!CAN_SEE(ch, d->character))
1666          continue;
1667  
1668        send_to_char(ch, "  %-*s%s%s%s\r\n", MAX_NAME_LENGTH, GET_NAME(d->character),
1669  		PLR_FLAGGED(d->character, PLR_WRITING) ? " (Writing)" : "",
1670  		PLR_FLAGGED(d->character, PLR_MAILING) ? " (Writing mail)" : "",
1671  		PRF_FLAGGED(d->character, PRF_NOWIZ) ? " (Offline)" : "");
1672      }
1673      return;
1674  
1675    case '\\':
1676      ++argument;
1677      break;
1678    default:
1679      break;
1680    }
1681    if (PRF_FLAGGED(ch, PRF_NOWIZ)) {
1682      send_to_char(ch, "You are offline!\r\n");
1683      return;
1684    }
1685    skip_spaces(&argument);
1686  
1687    if (!*argument) {
1688      send_to_char(ch, "Don't bother the gods like that!\r\n");
1689      return;
1690    }
1691    if (level > LVL_IMMORT) {
1692      snprintf(buf1, sizeof(buf1), "%s: <%d> %s%s\r\n", GET_NAME(ch), level, emote ? "<--- " : "", argument);
1693      snprintf(buf2, sizeof(buf1), "Someone: <%d> %s%s\r\n", level, emote ? "<--- " : "", argument);
1694    } else {
1695      snprintf(buf1, sizeof(buf1), "%s: %s%s\r\n", GET_NAME(ch), emote ? "<--- " : "", argument);
1696      snprintf(buf2, sizeof(buf1), "Someone: %s%s\r\n", emote ? "<--- " : "", argument);
1697    }
1698  
1699    for (d = descriptor_list; d; d = d->next) {
1700      if ((STATE(d) == CON_PLAYING) && (GET_LEVEL(d->character) >= level) &&
1701  	(!PRF_FLAGGED(d->character, PRF_NOWIZ)) &&
1702  	(!PLR_FLAGGED(d->character, PLR_WRITING | PLR_MAILING))
1703  	&& (d != ch->desc || !(PRF_FLAGGED(d->character, PRF_NOREPEAT)))) {
1704        send_to_char(d->character, "%s", CCCYN(d->character, C_NRM));
1705        if (CAN_SEE(d->character, ch))
1706  	send_to_char(d->character, "%s", buf1);
1707        else
1708  	send_to_char(d->character, "%s", buf2);
1709        send_to_char(d->character, "%s", CCNRM(d->character, C_NRM));
1710      }
1711    }
1712  
1713    if (PRF_FLAGGED(ch, PRF_NOREPEAT))
1714      send_to_char(ch, "%s", OK);
1715  }
1716  
1717  
1718  
1719  ACMD(do_zreset)
1720  {
1721    char arg[MAX_INPUT_LENGTH];
1722    zone_rnum i;
1723    zone_vnum j;
1724  
1725    one_argument(argument, arg);
1726    if (!*arg) {
1727      send_to_char(ch, "You must specify a zone.\r\n");
1728      return;
1729    }
1730    if (*arg == '*') {
1731      for (i = 0; i <= top_of_zone_table; i++)
1732        reset_zone(i);
1733      send_to_char(ch, "Reset world.\r\n");
1734      mudlog(NRM, MAX(LVL_GRGOD, GET_INVIS_LEV(ch)), TRUE, "(GC) %s reset entire world.", GET_NAME(ch));
1735      return;
1736    } else if (*arg == '.')
1737      i = world[IN_ROOM(ch)].zone;
1738    else {
1739      j = atoi(arg);
1740      for (i = 0; i <= top_of_zone_table; i++)
1741        if (zone_table[i].number == j)
1742  	break;
1743    }
1744    if (i <= top_of_zone_table) {
1745      reset_zone(i);
1746      send_to_char(ch, "Reset zone %d (#%d): %s.\r\n", i, zone_table[i].number, zone_table[i].name);
1747      mudlog(NRM, MAX(LVL_GRGOD, GET_INVIS_LEV(ch)), TRUE, "(GC) %s reset zone %d (%s)", GET_NAME(ch), i, zone_table[i].name);
1748    } else
1749      send_to_char(ch, "Invalid zone number.\r\n");
1750  }
1751  
1752  
1753  /*
1754   *  General fn for wizcommands of the sort: cmd <player>
1755   */
1756  ACMD(do_wizutil)
1757  {
1758    char arg[MAX_INPUT_LENGTH];
1759    struct char_data *vict;
1760    long result;
1761  
1762    one_argument(argument, arg);
1763  
1764    if (!*arg)
1765      send_to_char(ch, "Yes, but for whom?!?\r\n");
1766    else if (!(vict = get_char_vis(ch, arg, NULL, FIND_CHAR_WORLD)))
1767      send_to_char(ch, "There is no such player.\r\n");
1768    else if (IS_NPC(vict))
1769      send_to_char(ch, "You can't do that to a mob!\r\n");
1770    else if (GET_LEVEL(vict) > GET_LEVEL(ch))
1771      send_to_char(ch, "Hmmm...you'd better not.\r\n");
1772    else {
1773      switch (subcmd) {
1774      case SCMD_REROLL:
1775        send_to_char(ch, "Rerolled...\r\n");
1776        roll_real_abils(vict);
1777        log("(GC) %s has rerolled %s.", GET_NAME(ch), GET_NAME(vict));
1778        send_to_char(ch, "New stats: Str %d/%d, Int %d, Wis %d, Dex %d, Con %d, Cha %d\r\n",
1779  	      GET_STR(vict), GET_ADD(vict), GET_INT(vict), GET_WIS(vict),
1780  	      GET_DEX(vict), GET_CON(vict), GET_CHA(vict));
1781        break;
1782      case SCMD_PARDON:
1783        if (!PLR_FLAGGED(vict, PLR_THIEF | PLR_KILLER)) {
1784  	send_to_char(ch, "Your victim is not flagged.\r\n");
1785  	return;
1786        }
1787        REMOVE_BIT(PLR_FLAGS(vict), PLR_THIEF | PLR_KILLER);
1788        send_to_char(ch, "Pardoned.\r\n");
1789        send_to_char(vict, "You have been pardoned by the Gods!\r\n");
1790        mudlog(BRF, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "(GC) %s pardoned by %s", GET_NAME(vict), GET_NAME(ch));
1791        break;
1792      case SCMD_NOTITLE:
1793        result = PLR_TOG_CHK(vict, PLR_NOTITLE);
1794        mudlog(NRM, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "(GC) Notitle %s for %s by %s.",
1795  		ONOFF(result), GET_NAME(vict), GET_NAME(ch));
1796        send_to_char(ch, "(GC) Notitle %s for %s by %s.\r\n", ONOFF(result), GET_NAME(vict), GET_NAME(ch));
1797        break;
1798      case SCMD_SQUELCH:
1799        result = PLR_TOG_CHK(vict, PLR_NOSHOUT);
1800        mudlog(BRF, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "(GC) Squelch %s for %s by %s.",
1801  		ONOFF(result), GET_NAME(vict), GET_NAME(ch));
1802        send_to_char(ch, "(GC) Squelch %s for %s by %s.\r\n", ONOFF(result), GET_NAME(vict), GET_NAME(ch));
1803        break;
1804      case SCMD_FREEZE:
1805        if (ch == vict) {
1806  	send_to_char(ch, "Oh, yeah, THAT'S real smart...\r\n");
1807  	return;
1808        }
1809        if (PLR_FLAGGED(vict, PLR_FROZEN)) {
1810  	send_to_char(ch, "Your victim is already pretty cold.\r\n");
1811  	return;
1812        }
1813        SET_BIT(PLR_FLAGS(vict), PLR_FROZEN);
1814        GET_FREEZE_LEV(vict) = GET_LEVEL(ch);
1815        send_to_char(vict, "A bitter wind suddenly rises and drains every erg of heat from your body!\r\nYou feel frozen!\r\n");
1816        send_to_char(ch, "Frozen.\r\n");
1817        act("A sudden cold wind conjured from nowhere freezes $n!", FALSE, vict, 0, 0, TO_ROOM);
1818        mudlog(BRF, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "(GC) %s frozen by %s.", GET_NAME(vict), GET_NAME(ch));
1819        break;
1820      case SCMD_THAW:
1821        if (!PLR_FLAGGED(vict, PLR_FROZEN)) {
1822  	send_to_char(ch, "Sorry, your victim is not morbidly encased in ice at the moment.\r\n");
1823  	return;
1824        }
1825        if (GET_FREEZE_LEV(vict) > GET_LEVEL(ch)) {
1826  	send_to_char(ch, "Sorry, a level %d God froze %s... you can't unfreeze %s.\r\n",
1827  		GET_FREEZE_LEV(vict), GET_NAME(vict), HMHR(vict));
1828  	return;
1829        }
1830        mudlog(BRF, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "(GC) %s un-frozen by %s.", GET_NAME(vict), GET_NAME(ch));
1831        REMOVE_BIT(PLR_FLAGS(vict), PLR_FROZEN);
1832        send_to_char(vict, "A fireball suddenly explodes in front of you, melting the ice!\r\nYou feel thawed.\r\n");
1833        send_to_char(ch, "Thawed.\r\n");
1834        act("A sudden fireball conjured from nowhere thaws $n!", FALSE, vict, 0, 0, TO_ROOM);
1835        break;
1836      case SCMD_UNAFFECT:
1837        if (vict->affected) {
1838  	while (vict->affected)
1839  	  affect_remove(vict, vict->affected);
1840  	send_to_char(vict, "There is a brief flash of light!\r\nYou feel slightly different.\r\n");
1841  	send_to_char(ch, "All spells removed.\r\n");
1842        } else {
1843  	send_to_char(ch, "Your victim does not have any affections!\r\n");
1844  	return;
1845        }
1846        break;
1847      default:
1848        log("SYSERR: Unknown subcmd %d passed to do_wizutil (%s)", subcmd, __FILE__);
1849        break;
1850      }
1851      save_char(vict);
1852    }
1853  }
1854  
1855  
1856  /* single zone printing fn used by "show zone" so it's not repeated in the
1857     code 3 times ... -je, 4/6/93 */
1858  
1859  /* FIXME: overflow possible */
1860  size_t print_zone_to_buf(char *bufptr, size_t left, zone_rnum zone)
1861  {
1862    return snprintf(bufptr, left,
1863  	"%3d %-30.30s Age: %3d; Reset: %3d (%1d); Range: %5d-%5d\r\n",
1864  	zone_table[zone].number, zone_table[zone].name,
1865  	zone_table[zone].age, zone_table[zone].lifespan,
1866  	zone_table[zone].reset_mode,
1867  	zone_table[zone].bot, zone_table[zone].top);
1868  }
1869  
1870  
1871  ACMD(do_show)
1872  {
1873    struct char_file_u vbuf;
1874    int i, j, k, l, con, nlen;		/* i, j, k to specifics? */
1875    size_t len;
1876    zone_rnum zrn;
1877    zone_vnum zvn;
1878    byte self = FALSE;
1879    struct char_data *vict;
1880    struct obj_data *obj;
1881    struct descriptor_data *d;
1882    char field[MAX_INPUT_LENGTH], value[MAX_INPUT_LENGTH],
1883  	arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
1884  
1885    struct show_struct {
1886      const char *cmd;
1887      const char level;
1888    } fields[] = {
1889      { "nothing",	0  },				/* 0 */
1890      { "zones",		LVL_IMMORT },			/* 1 */
1891      { "player",		LVL_GOD },
1892      { "rent",		LVL_GOD },
1893      { "stats",		LVL_IMMORT },
1894      { "errors",		LVL_IMPL },			/* 5 */
1895      { "death",		LVL_GOD },
1896      { "godrooms",	LVL_GOD },
1897      { "shops",		LVL_IMMORT },
1898      { "houses",		LVL_GOD },
1899      { "snoop",		LVL_GRGOD },			/* 10 */
1900      { "\n", 0 }
1901    };
1902  
1903    skip_spaces(&argument);
1904  
1905    if (!*argument) {
1906      send_to_char(ch, "Show options:\r\n");
1907      for (j = 0, i = 1; fields[i].level; i++)
1908        if (fields[i].level <= GET_LEVEL(ch))
1909  	send_to_char(ch, "%-15s%s", fields[i].cmd, (!(++j % 5) ? "\r\n" : ""));
1910      send_to_char(ch, "\r\n");
1911      return;
1912    }
1913  
1914    strcpy(arg, two_arguments(argument, field, value));	/* strcpy: OK (argument <= MAX_INPUT_LENGTH == arg) */
1915  
1916    for (l = 0; *(fields[l].cmd) != '\n'; l++)
1917      if (!strncmp(field, fields[l].cmd, strlen(field)))
1918        break;
1919  
1920    if (GET_LEVEL(ch) < fields[l].level) {
1921      send_to_char(ch, "You are not godly enough for that!\r\n");
1922      return;
1923    }
1924    if (!strcmp(value, "."))
1925      self = TRUE;
1926    buf[0] = '\0';
1927  
1928    switch (l) {
1929    /* show zone */
1930    case 1:
1931      /* tightened up by JE 4/6/93 */
1932      if (self)
1933        print_zone_to_buf(buf, sizeof(buf), world[IN_ROOM(ch)].zone);
1934      else if (*value && is_number(value)) {
1935        for (zvn = atoi(value), zrn = 0; zone_table[zrn].number != zvn && zrn <= top_of_zone_table; zrn++);
1936        if (zrn <= top_of_zone_table)
1937  	print_zone_to_buf(buf, sizeof(buf), zrn);
1938        else {
1939  	send_to_char(ch, "That is not a valid zone.\r\n");
1940  	return;
1941        }
1942      } else
1943        for (len = zrn = 0; zrn <= top_of_zone_table; zrn++) {
1944  	nlen = print_zone_to_buf(buf + len, sizeof(buf) - len, zrn);
1945          if (len + nlen >= sizeof(buf) || nlen < 0)
1946            break;
1947          len += nlen;
1948        }
1949      page_string(ch->desc, buf, TRUE);
1950      break;
1951  
1952    /* show player */
1953    case 2:
1954      if (!*value) {
1955        send_to_char(ch, "A name would help.\r\n");
1956        return;
1957      }
1958  
1959      if (load_char(value, &vbuf) < 0) {
1960        send_to_char(ch, "There is no such player.\r\n");
1961        return;
1962      }
1963  
1964      send_to_char(ch, "Player: %-12s (%s) [%2d %s]\r\n", vbuf.name,
1965  	genders[(int) vbuf.sex], vbuf.level, class_abbrevs[(int) vbuf.chclass]);
1966      send_to_char(ch, "Au: %-8d  Bal: %-8d  Exp: %-8d  Align: %-5d  Lessons: %-3d\r\n",
1967  	vbuf.points.gold, vbuf.points.bank_gold, vbuf.points.exp,
1968  	vbuf.char_specials_saved.alignment, vbuf.player_specials_saved.spells_to_learn);
1969      /* ctime() uses static buffer: do not combine. */
1970      send_to_char(ch, "Started: %-20.16s  ", ctime(&vbuf.birth));
1971      send_to_char(ch, "Last: %-20.16s  Played: %3dh %2dm\r\n", ctime(&vbuf.last_logon), vbuf.played / 3600, vbuf.played / 60 % 60);
1972      break;
1973  
1974    /* show rent */
1975    case 3:
1976      if (!*value) {
1977        send_to_char(ch, "A name would help.\r\n");
1978        return;
1979      }
1980      Crash_listrent(ch, value);
1981      break;
1982  
1983    /* show stats */
1984    case 4:
1985      i = 0;
1986      j = 0;
1987      k = 0;
1988      con = 0;
1989      for (vict = character_list; vict; vict = vict->next) {
1990        if (IS_NPC(vict))
1991  	j++;
1992        else if (CAN_SEE(ch, vict)) {
1993  	i++;
1994  	if (vict->desc)
1995  	  con++;
1996        }
1997      }
1998      for (obj = object_list; obj; obj = obj->next)
1999        k++;
2000      send_to_char(ch,
2001  	"Current stats:\r\n"
2002  	"  %5d players in game  %5d connected\r\n"
2003  	"  %5d registered\r\n"
2004  	"  %5d mobiles          %5d prototypes\r\n"
2005  	"  %5d objects          %5d prototypes\r\n"
2006  	"  %5d rooms            %5d zones\r\n"
2007  	"  %5d large bufs\r\n"
2008  	"  %5d buf switches     %5d overflows\r\n",
2009  	i, con,
2010  	top_of_p_table + 1,
2011  	j, top_of_mobt + 1,
2012  	k, top_of_objt + 1,
2013  	top_of_world + 1, top_of_zone_table + 1,
2014  	buf_largecount,
2015  	buf_switches, buf_overflows
2016  	);
2017      break;
2018  
2019    /* show errors */
2020    case 5:
2021      len = strlcpy(buf, "Errant Rooms\r\n------------\r\n", sizeof(buf));
2022      for (i = 0, k = 0; i <= top_of_world; i++)
2023        for (j = 0; j < NUM_OF_DIRS; j++)
2024  	if (world[i].dir_option[j] && world[i].dir_option[j]->to_room == 0) {
2025  	  nlen = snprintf(buf + len, sizeof(buf) - len, "%2d: [%5d] %s\r\n", ++k, GET_ROOM_VNUM(i), world[i].name);
2026            if (len + nlen >= sizeof(buf) || nlen < 0)
2027              break;
2028            len += nlen;
2029          }
2030      page_string(ch->desc, buf, TRUE);
2031      break;
2032  
2033    /* show death */
2034    case 6:
2035      len = strlcpy(buf, "Death Traps\r\n-----------\r\n", sizeof(buf));
2036      for (i = 0, j = 0; i <= top_of_world; i++)
2037        if (ROOM_FLAGGED(i, ROOM_DEATH)) {
2038          nlen = snprintf(buf + len, sizeof(buf) - len, "%2d: [%5d] %s\r\n", ++j, GET_ROOM_VNUM(i), world[i].name);
2039          if (len + nlen >= sizeof(buf) || nlen < 0)
2040            break;
2041          len += nlen;
2042        }
2043      page_string(ch->desc, buf, TRUE);
2044      break;
2045  
2046    /* show godrooms */
2047    case 7:
2048      len = strlcpy(buf, "Godrooms\r\n--------------------------\r\n", sizeof(buf));
2049      for (i = 0, j = 0; i <= top_of_world; i++)
2050        if (ROOM_FLAGGED(i, ROOM_GODROOM)) {
2051          nlen = snprintf(buf + len, sizeof(buf) - len, "%2d: [%5d] %s\r\n", ++j, GET_ROOM_VNUM(i), world[i].name);
2052          if (len + nlen >= sizeof(buf) || nlen < 0)
2053            break;
2054          len += nlen;
2055        }
2056      page_string(ch->desc, buf, TRUE);
2057      break;
2058  
2059    /* show shops */
2060    case 8:
2061      show_shops(ch, value);
2062      break;
2063  
2064    /* show houses */
2065    case 9:
2066      hcontrol_list_houses(ch);
2067      break;
2068  
2069    /* show snoop */
2070    case 10:
2071      i = 0;
2072      send_to_char(ch, "People currently snooping:\r\n--------------------------\r\n");
2073      for (d = descriptor_list; d; d = d->next) {
2074        if (d->snooping == NULL || d->character == NULL)
2075  	continue;
2076        if (STATE(d) != CON_PLAYING || GET_LEVEL(ch) < GET_LEVEL(d->character))
2077  	continue;
2078        if (!CAN_SEE(ch, d->character) || IN_ROOM(d->character) == NOWHERE)
2079  	continue;
2080        i++;
2081        send_to_char(ch, "%-10s - snooped by %s.\r\n", GET_NAME(d->snooping->character), GET_NAME(d->character));
2082      }
2083      if (i == 0)
2084        send_to_char(ch, "No one is currently snooping.\r\n");
2085      break;
2086  
2087    /* show what? */
2088    default:
2089      send_to_char(ch, "Sorry, I don't understand that.\r\n");
2090      break;
2091    }
2092  }
2093  
2094  
2095  /***************** The do_set function ***********************************/
2096  
2097  #define PC   1
2098  #define NPC  2
2099  #define BOTH 3
2100  
2101  #define MISC	0
2102  #define BINARY	1
2103  #define NUMBER	2
2104  
2105  #define SET_OR_REMOVE(flagset, flags) { \
2106  	if (on) SET_BIT(flagset, flags); \
2107  	else if (off) REMOVE_BIT(flagset, flags); }
2108  
2109  #define RANGE(low, high) (value = MAX((low), MIN((high), (value))))
2110  
2111  
2112  /* The set options available */
2113    struct set_struct {
2114      const char *cmd;
2115      const char level;
2116      const char pcnpc;
2117      const char type;
2118    } set_fields[] = {
2119     { "brief",		LVL_GOD, 	PC, 	BINARY },  /* 0 */
2120     { "invstart", 	LVL_GOD, 	PC, 	BINARY },  /* 1 */
2121     { "title",		LVL_GOD, 	PC, 	MISC },
2122     { "nosummon", 	LVL_GRGOD, 	PC, 	BINARY },
2123     { "maxhit",		LVL_GRGOD, 	BOTH, 	NUMBER },
2124     { "maxmana", 	LVL_GRGOD, 	BOTH, 	NUMBER },  /* 5 */
2125     { "maxmove", 	LVL_GRGOD, 	BOTH, 	NUMBER },
2126     { "hit", 		LVL_GRGOD, 	BOTH, 	NUMBER },
2127     { "mana",		LVL_GRGOD, 	BOTH, 	NUMBER },
2128     { "move",		LVL_GRGOD, 	BOTH, 	NUMBER },
2129     { "align",		LVL_GOD, 	BOTH, 	NUMBER },  /* 10 */
2130     { "str",		LVL_GRGOD, 	BOTH, 	NUMBER },
2131     { "stradd",		LVL_GRGOD, 	BOTH, 	NUMBER },
2132     { "int", 		LVL_GRGOD, 	BOTH, 	NUMBER },
2133     { "wis", 		LVL_GRGOD, 	BOTH, 	NUMBER },
2134     { "dex", 		LVL_GRGOD, 	BOTH, 	NUMBER },  /* 15 */
2135     { "con", 		LVL_GRGOD, 	BOTH, 	NUMBER },
2136     { "cha",		LVL_GRGOD, 	BOTH, 	NUMBER },
2137     { "ac", 		LVL_GRGOD, 	BOTH, 	NUMBER },
2138     { "gold",		LVL_GOD, 	BOTH, 	NUMBER },
2139     { "bank",		LVL_GOD, 	PC, 	NUMBER },  /* 20 */
2140     { "exp", 		LVL_GRGOD, 	BOTH, 	NUMBER },
2141     { "hitroll", 	LVL_GRGOD, 	BOTH, 	NUMBER },
2142     { "damroll", 	LVL_GRGOD, 	BOTH, 	NUMBER },
2143     { "invis",		LVL_IMPL, 	PC, 	NUMBER },
2144     { "nohassle", 	LVL_GRGOD, 	PC, 	BINARY },  /* 25 */
2145     { "frozen",		LVL_FREEZE, 	PC, 	BINARY },
2146     { "practices", 	LVL_GRGOD, 	PC, 	NUMBER },
2147     { "lessons", 	LVL_GRGOD, 	PC, 	NUMBER },
2148     { "drunk",		LVL_GRGOD, 	BOTH, 	MISC },
2149     { "hunger",		LVL_GRGOD, 	BOTH, 	MISC },    /* 30 */
2150     { "thirst",		LVL_GRGOD, 	BOTH, 	MISC },
2151     { "killer",		LVL_GOD, 	PC, 	BINARY },
2152     { "thief",		LVL_GOD, 	PC, 	BINARY },
2153     { "level",		LVL_IMPL, 	BOTH, 	NUMBER },
2154     { "room",		LVL_IMPL, 	BOTH, 	NUMBER },  /* 35 */
2155     { "roomflag", 	LVL_GRGOD, 	PC, 	BINARY },
2156     { "siteok",		LVL_GRGOD, 	PC, 	BINARY },
2157     { "deleted", 	LVL_IMPL, 	PC, 	BINARY },
2158     { "class",		LVL_GRGOD, 	BOTH, 	MISC },
2159     { "nowizlist", 	LVL_GOD, 	PC, 	BINARY },  /* 40 */
2160     { "quest",		LVL_GOD, 	PC, 	BINARY },
2161     { "loadroom", 	LVL_GRGOD, 	PC, 	MISC },
2162     { "color",		LVL_GOD, 	PC, 	BINARY },
2163     { "idnum",		LVL_IMPL, 	PC, 	NUMBER },
2164     { "passwd",		LVL_IMPL, 	PC, 	MISC },    /* 45 */
2165     { "nodelete", 	LVL_GOD, 	PC, 	BINARY },
2166     { "sex", 		LVL_GRGOD, 	BOTH, 	MISC },
2167     { "age",		LVL_GRGOD,	BOTH,	NUMBER },
2168     { "height",		LVL_GOD,	BOTH,	NUMBER },
2169     { "weight",		LVL_GOD,	BOTH,	NUMBER },  /* 50 */
2170     { "\n", 0, BOTH, MISC }
2171    };
2172  
2173  
2174  int perform_set(struct char_data *ch, struct char_data *vict, int mode,
2175  		char *val_arg)
2176  {
2177    int i, on = 0, off = 0, value = 0;
2178    room_rnum rnum;
2179    room_vnum rvnum;
2180  
2181    /* Check to make sure all the levels are correct */
2182    if (GET_LEVEL(ch) != LVL_IMPL) {
2183      if (!IS_NPC(vict) && GET_LEVEL(ch) <= GET_LEVEL(vict) && vict != ch) {
2184        send_to_char(ch, "Maybe that's not such a great idea...\r\n");
2185        return (0);
2186      }
2187    }
2188    if (GET_LEVEL(ch) < set_fields[mode].level) {
2189      send_to_char(ch, "You are not godly enough for that!\r\n");
2190      return (0);
2191    }
2192  
2193    /* Make sure the PC/NPC is correct */
2194    if (IS_NPC(vict) && !(set_fields[mode].pcnpc & NPC)) {
2195      send_to_char(ch, "You can't do that to a beast!\r\n");
2196      return (0);
2197    } else if (!IS_NPC(vict) && !(set_fields[mode].pcnpc & PC)) {
2198      send_to_char(ch, "That can only be done to a beast!\r\n");
2199      return (0);
2200    }
2201  
2202    /* Find the value of the argument */
2203    if (set_fields[mode].type == BINARY) {
2204      if (!strcmp(val_arg, "on") || !strcmp(val_arg, "yes"))
2205        on = 1;
2206      else if (!strcmp(val_arg, "off") || !strcmp(val_arg, "no"))
2207        off = 1;
2208      if (!(on || off)) {
2209        send_to_char(ch, "Value must be 'on' or 'off'.\r\n");
2210        return (0);
2211      }
2212      send_to_char(ch, "%s %s for %s.\r\n", set_fields[mode].cmd, ONOFF(on), GET_NAME(vict));
2213    } else if (set_fields[mode].type == NUMBER) {
2214      value = atoi(val_arg);
2215      send_to_char(ch, "%s's %s set to %d.\r\n", GET_NAME(vict), set_fields[mode].cmd, value);
2216    } else
2217      send_to_char(ch, "%s", OK);
2218  
2219    switch (mode) {
2220    case 0:
2221      SET_OR_REMOVE(PRF_FLAGS(vict), PRF_BRIEF);
2222      break;
2223    case 1:
2224      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_INVSTART);
2225      break;
2226    case 2:
2227      set_title(vict, val_arg);
2228      send_to_char(ch, "%s's title is now: %s\r\n", GET_NAME(vict), GET_TITLE(vict));
2229      break;
2230    case 3:
2231      SET_OR_REMOVE(PRF_FLAGS(vict), PRF_SUMMONABLE);
2232      send_to_char(ch, "Nosummon %s for %s.\r\n", ONOFF(!on), GET_NAME(vict));
2233      break;
2234    case 4:
2235      vict->points.max_hit = RANGE(1, 5000);
2236      affect_total(vict);
2237      break;
2238    case 5:
2239      vict->points.max_mana = RANGE(1, 5000);
2240      affect_total(vict);
2241      break;
2242    case 6:
2243      vict->points.max_move = RANGE(1, 5000);
2244      affect_total(vict);
2245      break;
2246    case 7:
2247      vict->points.hit = RANGE(-9, vict->points.max_hit);
2248      affect_total(vict);
2249      break;
2250    case 8:
2251      vict->points.mana = RANGE(0, vict->points.max_mana);
2252      affect_total(vict);
2253      break;
2254    case 9:
2255      vict->points.move = RANGE(0, vict->points.max_move);
2256      affect_total(vict);
2257      break;
2258    case 10:
2259      GET_ALIGNMENT(vict) = RANGE(-1000, 1000);
2260      affect_total(vict);
2261      break;
2262    case 11:
2263      if (IS_NPC(vict) || GET_LEVEL(vict) >= LVL_GRGOD)
2264        RANGE(3, 25);
2265      else
2266        RANGE(3, 18);
2267      vict->real_abils.str = value;
2268      vict->real_abils.str_add = 0;
2269      affect_total(vict);
2270      break;
2271    case 12:
2272      vict->real_abils.str_add = RANGE(0, 100);
2273      if (value > 0)
2274        vict->real_abils.str = 18;
2275      affect_total(vict);
2276      break;
2277    case 13:
2278      if (IS_NPC(vict) || GET_LEVEL(vict) >= LVL_GRGOD)
2279        RANGE(3, 25);
2280      else
2281        RANGE(3, 18);
2282      vict->real_abils.intel = value;
2283      affect_total(vict);
2284      break;
2285    case 14:
2286      if (IS_NPC(vict) || GET_LEVEL(vict) >= LVL_GRGOD)
2287        RANGE(3, 25);
2288      else
2289        RANGE(3, 18);
2290      vict->real_abils.wis = value;
2291      affect_total(vict);
2292      break;
2293    case 15:
2294      if (IS_NPC(vict) || GET_LEVEL(vict) >= LVL_GRGOD)
2295        RANGE(3, 25);
2296      else
2297        RANGE(3, 18);
2298      vict->real_abils.dex = value;
2299      affect_total(vict);
2300      break;
2301    case 16:
2302      if (IS_NPC(vict) || GET_LEVEL(vict) >= LVL_GRGOD)
2303        RANGE(3, 25);
2304      else
2305        RANGE(3, 18);
2306      vict->real_abils.con = value;
2307      affect_total(vict);
2308      break;
2309    case 17:
2310      if (IS_NPC(vict) || GET_LEVEL(vict) >= LVL_GRGOD)
2311        RANGE(3, 25);
2312      else
2313        RANGE(3, 18);
2314      vict->real_abils.cha = value;
2315      affect_total(vict);
2316      break;
2317    case 18:
2318      vict->points.armor = RANGE(-100, 100);
2319      affect_total(vict);
2320      break;
2321    case 19:
2322      GET_GOLD(vict) = RANGE(0, 100000000);
2323      break;
2324    case 20:
2325      GET_BANK_GOLD(vict) = RANGE(0, 100000000);
2326      break;
2327    case 21:
2328      vict->points.exp = RANGE(0, 50000000);
2329      break;
2330    case 22:
2331      vict->points.hitroll = RANGE(-20, 20);
2332      affect_total(vict);
2333      break;
2334    case 23:
2335      vict->points.damroll = RANGE(-20, 20);
2336      affect_total(vict);
2337      break;
2338    case 24:
2339      if (GET_LEVEL(ch) < LVL_IMPL && ch != vict) {
2340        send_to_char(ch, "You aren't godly enough for that!\r\n");
2341        return (0);
2342      }
2343      GET_INVIS_LEV(vict) = RANGE(0, GET_LEVEL(vict));
2344      break;
2345    case 25:
2346      if (GET_LEVEL(ch) < LVL_IMPL && ch != vict) {
2347        send_to_char(ch, "You aren't godly enough for that!\r\n");
2348        return (0);
2349      }
2350      SET_OR_REMOVE(PRF_FLAGS(vict), PRF_NOHASSLE);
2351      break;
2352    case 26:
2353      if (ch == vict && on) {
2354        send_to_char(ch, "Better not -- could be a long winter!\r\n");
2355        return (0);
2356      }
2357      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_FROZEN);
2358      break;
2359    case 27:
2360    case 28:
2361      GET_PRACTICES(vict) = RANGE(0, 100);
2362      break;
2363    case 29:
2364    case 30:
2365    case 31:
2366      if (!str_cmp(val_arg, "off")) {
2367        GET_COND(vict, (mode - 29)) = -1; /* warning: magic number here */
2368        send_to_char(ch, "%s's %s now off.\r\n", GET_NAME(vict), set_fields[mode].cmd);
2369      } else if (is_number(val_arg)) {
2370        value = atoi(val_arg);
2371        RANGE(0, 24);
2372        GET_COND(vict, (mode - 29)) = value; /* and here too */
2373        send_to_char(ch, "%s's %s set to %d.\r\n", GET_NAME(vict), set_fields[mode].cmd, value);
2374      } else {
2375        send_to_char(ch, "Must be 'off' or a value from 0 to 24.\r\n");
2376        return (0);
2377      }
2378      break;
2379    case 32:
2380      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_KILLER);
2381      break;
2382    case 33:
2383      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_THIEF);
2384      break;
2385    case 34:
2386      if (value > GET_LEVEL(ch) || value > LVL_IMPL) {
2387        send_to_char(ch, "You can't do that.\r\n");
2388        return (0);
2389      }
2390      RANGE(0, LVL_IMPL);
2391      vict->player.level = value;
2392      break;
2393    case 35:
2394      if ((rnum = real_room(value)) == NOWHERE) {
2395        send_to_char(ch, "No room exists with that number.\r\n");
2396        return (0);
2397      }
2398      if (IN_ROOM(vict) != NOWHERE)	/* Another Eric Green special. */
2399        char_from_room(vict);
2400      char_to_room(vict, rnum);
2401      break;
2402    case 36:
2403      SET_OR_REMOVE(PRF_FLAGS(vict), PRF_ROOMFLAGS);
2404      break;
2405    case 37:
2406      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_SITEOK);
2407      break;
2408    case 38:
2409      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_DELETED);
2410      break;
2411    case 39:
2412      if ((i = parse_class(*val_arg)) == CLASS_UNDEFINED) {
2413        send_to_char(ch, "That is not a class.\r\n");
2414        return (0);
2415      }
2416      GET_CLASS(vict) = i;
2417      break;
2418    case 40:
2419      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_NOWIZLIST);
2420      break;
2421    case 41:
2422      SET_OR_REMOVE(PRF_FLAGS(vict), PRF_QUEST);
2423      break;
2424    case 42:
2425      if (!str_cmp(val_arg, "off")) {
2426        REMOVE_BIT(PLR_FLAGS(vict), PLR_LOADROOM);
2427      } else if (is_number(val_arg)) {
2428        rvnum = atoi(val_arg);
2429        if (real_room(rvnum) != NOWHERE) {
2430          SET_BIT(PLR_FLAGS(vict), PLR_LOADROOM);
2431  	GET_LOADROOM(vict) = rvnum;
2432  	send_to_char(ch, "%s will enter at room #%d.", GET_NAME(vict), GET_LOADROOM(vict));
2433        } else {
2434  	send_to_char(ch, "That room does not exist!\r\n");
2435  	return (0);
2436        }
2437      } else {
2438        send_to_char(ch, "Must be 'off' or a room's virtual number.\r\n");
2439        return (0);
2440      }
2441      break;
2442    case 43:
2443      SET_OR_REMOVE(PRF_FLAGS(vict), (PRF_COLOR_1 | PRF_COLOR_2));
2444      break;
2445    case 44:
2446      if (GET_IDNUM(ch) != 1 || !IS_NPC(vict))
2447        return (0);
2448      GET_IDNUM(vict) = value;
2449      break;
2450    case 45:
2451      if (GET_IDNUM(ch) > 1) {
2452        send_to_char(ch, "Please don't use this command, yet.\r\n");
2453        return (0);
2454      }
2455      if (GET_LEVEL(vict) >= LVL_GRGOD) {
2456        send_to_char(ch, "You cannot change that.\r\n");
2457        return (0);
2458      }
2459      strncpy(GET_PASSWD(vict), CRYPT(val_arg, GET_NAME(vict)), MAX_PWD_LENGTH);	/* strncpy: OK (G_P:MAX_PWD_LENGTH) */
2460      *(GET_PASSWD(vict) + MAX_PWD_LENGTH) = '\0';
2461      send_to_char(ch, "Password changed to '%s'.\r\n", val_arg);
2462      break;
2463    case 46:
2464      SET_OR_REMOVE(PLR_FLAGS(vict), PLR_NODELETE);
2465      break;
2466    case 47:
2467      if ((i = search_block(val_arg, genders, FALSE)) < 0) {
2468        send_to_char(ch, "Must be 'male', 'female', or 'neutral'.\r\n");
2469        return (0);
2470      }
2471      GET_SEX(vict) = i;
2472      break;
2473    case 48:	/* set age */
2474      if (value < 2 || value > 200) {	/* Arbitrary limits. */
2475        send_to_char(ch, "Ages 2 to 200 accepted.\r\n");
2476        return (0);
2477      }
2478      /*
2479       * NOTE: May not display the exact age specified due to the integer
2480       * division used elsewhere in the code.  Seems to only happen for
2481       * some values below the starting age (17) anyway. -gg 5/27/98
2482       */
2483      vict->player.time.birth = time(0) - ((value - 17) * SECS_PER_MUD_YEAR);
2484      break;
2485  
2486    case 49:	/* Blame/Thank Rick Glover. :) */
2487      GET_HEIGHT(vict) = value;
2488      affect_total(vict);
2489      break;
2490  
2491    case 50:
2492      GET_WEIGHT(vict) = value;
2493      affect_total(vict);
2494      break;
2495  
2496    default:
2497      send_to_char(ch, "Can't set that!\r\n");
2498      return (0);
2499    }
2500  
2501    return (1);
2502  }
2503  
2504  
2505  ACMD(do_set)
2506  {
2507    struct char_data *vict = NULL, *cbuf = NULL;
2508    struct char_file_u tmp_store;
2509    char field[MAX_INPUT_LENGTH], name[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH];
2510    int mode, len, player_i = 0, retval;
2511    char is_file = 0, is_player = 0;
2512  
2513    half_chop(argument, name, buf);
2514  
2515    if (!strcmp(name, "file")) {
2516      is_file = 1;
2517      half_chop(buf, name, buf);
2518    } else if (!str_cmp(name, "player")) {
2519      is_player = 1;
2520      half_chop(buf, name, buf);
2521    } else if (!str_cmp(name, "mob"))
2522      half_chop(buf, name, buf);
2523  
2524    half_chop(buf, field, buf);
2525  
2526    if (!*name || !*field) {
2527      send_to_char(ch, "Usage: set <victim> <field> <value>\r\n");
2528      return;
2529    }
2530  
2531    /* find the target */
2532    if (!is_file) {
2533      if (is_player) {
2534        if (!(vict = get_player_vis(ch, name, NULL, FIND_CHAR_WORLD))) {
2535  	send_to_char(ch, "There is no such player.\r\n");
2536  	return;
2537        }
2538      } else { /* is_mob */
2539        if (!(vict = get_char_vis(ch, name, NULL, FIND_CHAR_WORLD))) {
2540  	send_to_char(ch, "There is no such creature.\r\n");
2541  	return;
2542        }
2543      }
2544    } else if (is_file) {
2545      /* try to load the player off disk */
2546      CREATE(cbuf, struct char_data, 1);
2547      clear_char(cbuf);
2548      if ((player_i = load_char(name, &tmp_store)) > -1) {
2549        store_to_char(&tmp_store, cbuf);
2550        if (GET_LEVEL(cbuf) >= GET_LEVEL(ch)) {
2551  	free_char(cbuf);
2552  	send_to_char(ch, "Sorry, you can't do that.\r\n");
2553  	return;
2554        }
2555        vict = cbuf;
2556      } else {
2557        free(cbuf);
2558        send_to_char(ch, "There is no such player.\r\n");
2559        return;
2560      }
2561    }
2562  
2563    /* find the command in the list */
2564    len = strlen(field);
2565    for (mode = 0; *(set_fields[mode].cmd) != '\n'; mode++)
2566      if (!strncmp(field, set_fields[mode].cmd, len))
2567        break;
2568  
2569    /* perform the set */
2570    retval = perform_set(ch, vict, mode, buf);
2571  
2572    /* save the character if a change was made */
2573    if (retval) {
2574      if (!is_file && !IS_NPC(vict))
2575        save_char(vict);
2576      if (is_file) {
2577        char_to_store(vict, &tmp_store);
2578        fseek(player_fl, (player_i) * sizeof(struct char_file_u), SEEK_SET);
2579        fwrite(&tmp_store, sizeof(struct char_file_u), 1, player_fl);
2580        send_to_char(ch, "Saved in file.\r\n");
2581      }
2582    }
2583  
2584    /* free the memory if we allocated it earlier */
2585    if (is_file)
2586      free_char(cbuf);
2587  }
2588