dbt/cnf/
dbt/lib/
dbt/lib/house/
dbt/lib/text/help/
dbt/lib/world/
dbt/lib/world/qst/
dbt/src/
dbt/src/copyover/
/****************************************************************************
*   File: interpreter.c                                 Part of CircleMUD *
*  Usage: parse user commands, search for specials, call ACMD functions   *
*                                                                         *
*  All rights reserved.  See license.doc for complete information.        *
*                                                                         *
*  Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
*  CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991.               *
************************************************************************ */

#define __INTERPRETER_C__

#include "conf.h"
#include "sysdep.h"

#include "structs.h"
#include "comm.h"
#include "interpreter.h"
#include "db.h"
#include "utils.h"
#include "spells.h"
#include "handler.h"
#include "mail.h"
#include "screen.h"
#include "olc.h"
#include "dg_scripts.h"

/* (FIDO) New commands here */
ACMD(do_swho);
ACMD(do_slast);
ACMD(do_grep);
ACMD(do_sps);
ACMD(do_showadd);

extern sh_int r_mortal_start_room;
extern sh_int r_hell_room;
extern sh_int r_saiyan_start_room;
extern sh_int r_demon_start_room;
extern sh_int r_majin_start_room;
extern sh_int r_konack_start_room;
extern sh_int r_icer_start_room;
extern sh_int r_truffle_start_room;
extern sh_int r_namek_start_room;
extern sh_int r_vegeta_start_room;
extern sh_int r_immort_start_room;
extern sh_int r_frozen_start_room;
extern sh_int r_pk1_room;
extern sh_int r_pk2_room;
extern sh_int r_pk3_room;
extern sh_int r_pk4_room;
extern sh_int r_death_start_room;
extern sh_int r_ctf_start_room;
extern const char *class_menu;
extern char *motd;
extern char *imotd;
extern char *background;
extern char *MENU;
extern char *WELC_MESSG;
extern char *START_MESSG;
extern struct char_data *character_list;
extern struct descriptor_data *descriptor_list;
extern struct player_index_element *player_table;
extern int top_of_p_table;
extern int circle_restrict;
extern int no_specials;
extern int max_bad_pws;
extern struct index_data *mob_index;
extern struct index_data *obj_index;
extern struct room_data *world;

/* external functions */
void do_newbie(struct char_data *vict);
void echo_on(struct descriptor_data *d);
void echo_off(struct descriptor_data *d);
void do_start(struct char_data *ch);
int parse_class(char arg);
int special(struct char_data *ch, int cmd, char *arg);
int isbanned(char *hostname);
int Valid_Name(char *newname);
void oedit_parse(struct descriptor_data *d, char *arg);
void redit_parse(struct descriptor_data *d, char *arg);
void hedit_parse(struct descriptor_data *d, char *arg);
void zedit_parse(struct descriptor_data *d, char *arg);
void medit_parse(struct descriptor_data *d, char *arg);
void sedit_parse(struct descriptor_data *d, char *arg);
void trigedit_parse(struct descriptor_data *d, char *arg);
void aedit_parse(struct descriptor_data *d, char *arg);

/* local functions */
int perform_dupe_check(struct descriptor_data *d);
struct alias *find_alias(struct alias *alias_list, char *str);
void free_alias(struct alias *a);
void perform_complex_alias(struct txt_q *input_q, char *orig, struct alias *a);
int perform_alias(struct descriptor_data *d, char *orig);
int reserved_word(char *argument);
int find_name(char *name);
int _parse_name(char *arg, char *name);

/* prototypes for all do_x functions. */
ACMD(do_lag);
ACMD(do_poof);
ACMD(do_poofin);
ACMD(do_poofout);
//ACMD(do_contact);
ACMD(do_wizupdate);
ACMD(do_linkload);
ACMD(do_omni);
ACMD(do_system);
ACMD(do_chown);
ACMD(do_zap);
ACMD(do_saiyan);
ACMD(do_players);
ACMD(do_file);
ACMD(do_rlist);
ACMD(do_mlist);
ACMD(do_olist);
ACMD(do_snamek);
ACMD(do_whois);
ACMD(do_wish);
ACMD(do_compare);
ACMD(do_xname);
ACMD(do_glance);
ACMD(do_shuman);
ACMD(do_namechange);

ACMD(do_absorb);
ACMD(do_arestore);
ACMD(do_azap);
ACMD(do_amute);
ACMD(do_afreeze);
ACMD(do_interest);
ACMD(do_tax);
ACMD(do_asave);
ACMD(do_action);
ACMD(do_advance);
ACMD(do_afk);
ACMD(do_auction);
ACMD(do_augment);
ACMD(do_bid);
ACMD(do_spar);
ACMD(do_sparkick);
ACMD(do_sparpunch);
ACMD(do_sparknee);
ACMD(do_sparelbow);
ACMD(do_sparkiblast);
ACMD(do_alias);
ACMD(do_assist);
ACMD(do_orevert);
ACMD(do_at);
ACMD(do_backstab);
ACMD(do_ban);
ACMD(do_bigbang);
ACMD(do_sweep);
ACMD(do_knee);
ACMD(do_kousen);
ACMD(do_kishot);
ACMD(do_havoc);
ACMD(do_crusher);
ACMD(do_eraser);
ACMD(do_bakuhatsuha);
ACMD(do_honoo);
ACMD(do_galikgun);
ACMD(do_beam);
ACMD(do_tsuihidan);
ACMD(do_shogekiha);
ACMD(do_kikoho);
ACMD(do_elbow);
ACMD(do_roundhouse);
ACMD(do_recall);
ACMD(do_relevel);
ACMD(do_focus);
ACMD(do_choukame);
ACMD(do_burning);
ACMD(do_genki);
ACMD(do_chikyuu);
ACMD(do_genocide);
ACMD(do_bbk);
ACMD(do_yoiko);
ACMD(do_spirit);
ACMD(do_scatter);
ACMD(do_hellspear);
ACMD(do_gigabeam);
ACMD(do_twin);
ACMD(do_dragon);
ACMD(do_color);
ACMD(do_commands);
ACMD(do_consider);
ACMD(do_copyover);
ACMD(do_acopyover);
ACMD(do_stealth);
ACMD(do_copy);
ACMD(do_charge);
ACMD(do_credits);
ACMD(do_date);
ACMD(do_dball);
ACMD(do_dball2);
ACMD(do_kakusanha);
ACMD(do_pheonix);
ACMD(do_eclipse);
ACMD(do_hydro);
ACMD(do_dc);
ACMD(do_diagnose);
ACMD(do_disk);
ACMD(do_pk);
ACMD(do_powerup);
ACMD(do_powerdown);
ACMD(do_display);
ACMD(do_scan);
ACMD(do_drink);
ACMD(do_drop);
ACMD(do_eat);
ACMD(do_echo);
ACMD(do_enter);
ACMD(do_equipment);
ACMD(do_examine);
ACMD(do_powersense);
ACMD(do_exit);
ACMD(do_exits);
ACMD(do_jog);
ACMD(do_finalflash);
ACMD(do_flee);
ACMD(do_fly);
ACMD(do_land);
ACMD(do_follow);
ACMD(do_selfdestruct);
ACMD(do_force);
ACMD(do_gecho);
ACMD(do_gen_comm);
ACMD(do_gen_door);
ACMD(do_gen_ps);
ACMD(do_gen_tog);
ACMD(do_gen_write);
ACMD(do_get);
ACMD(do_give);
ACMD(do_package);
ACMD(do_gold);
ACMD(do_goto);
ACMD(do_grab);
ACMD(do_group);
ACMD(do_gsay);
ACMD(do_osay);
ACMD(do_hcontrol);
ACMD(do_hellf);
ACMD(do_help);
ACMD(do_lp);
ACMD(do_training);
ACMD(do_potential);
ACMD(do_majinize);
ACMD(do_mindread);
ACMD(do_majinyes);
ACMD(do_heal);
ACMD(do_heal2);
ACMD(do_hide);
ACMD(do_hit);
ACMD(do_house);
ACMD(do_info);
ACMD(do_insult);
ACMD(do_ingest);
ACMD(do_deflect);
ACMD(do_inventory);
ACMD(do_invis);
ACMD(do_kaioken);
ACMD(do_kyodaika);
ACMD(do_kamehame);
ACMD(do_kick);
ACMD(do_regenerate);
ACMD(do_kill);
ACMD(do_last);
ACMD(do_leave);
ACMD(do_learn);
ACMD(do_learned);
ACMD(do_mystic);
ACMD(do_mutate);
ACMD(do_shadow);
ACMD(do_skanassan);
ACMD(do_sangel);
ACMD(do_makanko);
ACMD(do_masenko);
ACMD(do_load);
ACMD(do_look);
ACMD(do_halt);
ACMD(do_upgrade);
/* ACMD(do_move); -- interpreter.h */
/*ACMD(do_namechange);*/
ACMD(do_not_here);
ACMD(do_offer);
ACMD(do_olc);
ACMD(do_order);
ACMD(do_page);
ACMD(do_peace);
ACMD(do_perfection);
//ACMD(do_poofset);
ACMD(do_pour);
ACMD(do_purge);
ACMD(do_hell);
ACMD(do_hell2);
ACMD(do_push);
ACMD(do_password);
ACMD(do_trade);
ACMD(do_calc);
ACMD(do_suicide);
ACMD(do_pushup);
ACMD(do_meditate);
ACMD(do_put);
ACMD(do_qcomm);
ACMD(do_quit);
ACMD(do_reboot);
ACMD(do_remove);
ACMD(do_rent);
ACMD(do_repair);
ACMD(do_reply);
ACMD(do_report);
ACMD(do_rescue);
ACMD(do_rest);
ACMD(do_restore);
ACMD(do_restore);
ACMD(do_return);
ACMD(do_rlink);
ACMD(do_save);
ACMD(do_say);
ACMD(do_score);
ACMD(do_status);
ACMD(do_send);
ACMD(do_set);
ACMD(do_ftick);
ACMD(do_show);
ACMD(do_shutdown);
ACMD(do_sit);
ACMD(do_situp);
ACMD(do_skillset);
ACMD(do_sleep);
ACMD(do_SWIFTNESS);
ACMD(do_snoop);
ACMD(do_spec_comm);
ACMD(do_ssj);
ACMD(do_innerfire);
ACMD(do_transform);
ACMD(do_majinmorph);
ACMD(do_renzo);
ACMD(do_split);
ACMD(do_stand);
ACMD(do_stat);
ACMD(do_mug);
ACMD(do_camp);
ACMD(do_switch);
ACMD(do_syslog);
ACMD(do_tailwhip);
ACMD(do_forelock);
ACMD(do_tedit);
ACMD(do_teleport);
ACMD(do_tell);
ACMD(do_time);
ACMD(do_title);
ACMD(do_toggle);
ACMD(do_sense);
ACMD(do_trans);
ACMD(do_unban);
ACMD(do_ungroup);
ACMD(do_use);
ACMD(do_scouter);
ACMD(do_clan);
ACMD(do_quote);
ACMD(do_bounty);
ACMD(do_race);
ACMD(do_roleplay);
ACMD(do_users);
ACMD(do_visible);
ACMD(do_finger);
ACMD(do_vnum);
ACMD(do_vstat);
ACMD(do_wake);
ACMD(do_wear);
ACMD(do_weather);
ACMD(do_where);
ACMD(do_who);
ACMD(do_wield);
ACMD(do_wimpy);
ACMD(do_wizlock);
ACMD(do_wiznet);
ACMD(do_wizutil);
ACMD(do_write);
ACMD(do_zanelb);
ACMD(do_zreset);

/* DG Script ACMD's */
ACMD(do_attach);
ACMD(do_detach);
ACMD(do_tlist);
ACMD(do_tstat);
ACMD(do_masound);
ACMD(do_mkill);
ACMD(do_mjunk);
ACMD(do_mechoaround);
ACMD(do_msend);
ACMD(do_mecho);
ACMD(do_mload);
ACMD(do_mpurge);
ACMD(do_mgoto);
ACMD(do_mat);
ACMD(do_mteleport);
ACMD(do_mforce);
ACMD(do_mexp);
ACMD(do_mgold);
ACMD(do_mhunt);
ACMD(do_mremember);
ACMD(do_mforget);
ACMD(do_mtransform);

cpp_extern struct command_info *complete_cmd_info;

/* This is the Master Command List(tm).

 * You can put new commands in, take commands out, change the order
 * they appear in, etc.  You can adjust the "priority" of commands
 * simply by changing the order they appear in the command list.
 * (For example, if you want "as" to mean "assist" instead of "ask",
 * just put "assist" above "ask" in the Master Command List(tm).
 *
 * In general, utility commands such as "at" should have high priority;
 * infrequently used and dangerously destructive commands should have low
 * priority.
 */

cpp_extern const struct command_info cmd_info[] = {
  { "RESERVED" , "RESERVED", 0, 0, 0, 0 },	/* this must be first -- for specprocs */

  /* directions must come before other commands but after RESERVED */
  { "north"    , "n"    , POS_STANDING, do_move     , 0, SCMD_NORTH },
  { "east"     , "e"	, POS_STANDING, do_move     , 0, SCMD_EAST },
  { "south"    , "s"	, POS_STANDING, do_move     , 0, SCMD_SOUTH },
  { "west"     , "w"	, POS_STANDING, do_move     , 0, SCMD_WEST },
  { "up"       , "u"	, POS_STANDING, do_move     , 0, SCMD_UP },
  { "down"     , "d"	, POS_STANDING, do_move     , 0, SCMD_DOWN },
  
  { "stat"     , "stat"	, POS_DEAD    , do_stat     , 0, 0 },
  { "look"     , "l"	, POS_RESTING , do_look     , 0, SCMD_LOOK },
  { "score"    , "sco"	, POS_DEAD    , do_score    , 0, 0 },
  { "status"   , "stat"	, POS_DEAD    , do_status   , 0, 0 },
  { "kill"     , "k"	, POS_FIGHTING, do_kill     , 0, 0 },
  { "inventory", "i"	, POS_DEAD    , do_inventory, 0, 0 },
  { "halt"     , "hal"	, POS_DEAD    , do_halt     , 999999, 0 },
  
  /* now, the main list */
  { "at"       , "at"	, POS_DEAD    , do_at       , LVL_IMMORT, 0 },
  { "advance"  , "adv"	, POS_DEAD    , do_advance  , LVL_GOD, 0 },
  { "afk"      , "afk"  , POS_DEAD    , do_gen_tog  , 0, SCMD_AFK },
  { "away"      , "away"  , POS_DEAD    , do_gen_tog  , 0, SCMD_AFK },
  { "augment"  , "aug"  , POS_DEAD    , do_augment  , 1, 0 },
  { "spar"     , "spa"  , POS_STANDING    , do_spar     , 0, 0 },
  { "sparkick"      , "sparkic"  , POS_STANDING    , do_sparkick      , 0, 0 },
  { "sparpunch"     , "sparp"    , POS_STANDING    , do_sparpunch     , 0, 0 },
  { "sparelbow"     , "spare"    , POS_STANDING    , do_sparelbow     , 0, 0 },
  { "sparknee"      , "sparkn"   , POS_STANDING    , do_sparknee      , 0, 0 },
  { "sparkiblast"   , "sparkib"  , POS_STANDING    , do_sparkiblast   , 0, 0 },



  { "aedit"    , "aed"	, POS_DEAD    , do_olc      , LVL_IMMORT, SCMD_OLC_AEDIT },
  { "alias"    , "ali"	, POS_DEAD    , do_alias    , 0, 0 },
  { "powersense" , "ps"	, POS_DEAD    , do_powersense , 0, 0 },
  { "absorb"   , "abs"	, POS_FIGHTING    , do_absorb   , 0, 0 },
  { "interest" , "inter" , POS_DEAD    , do_interest , LVL_LSSRGOD, 0 },
  { "tax" , "tax" , POS_DEAD    , do_tax , 1000000, 0 },
  { "amute" , "amut" , POS_DEAD    , do_amute , 1000000, 0 },
  { "afreeze" , "afree" , POS_DEAD    , do_afreeze , 1000008, 0 },
  { "arestore" , "ares" , POS_DEAD    , do_arestore , 1000000, 0 },
  { "azap" , "aza" , POS_DEAD    , do_azap , 1000000, 0 },
  { "asave"    , "asa"  , POS_DEAD    , do_asave    , 1000000, 0 },
  { "assist"   , "ass"	, POS_FIGHTING, do_assist   , 1, 0 },
  { "ask"      , "ask"	, POS_RESTING , do_spec_comm, 999999, SCMD_ASK },
  { "auction"  , "auc"  , POS_SLEEPING, do_auction  , 0, 0 },
  { "ooc"      , "oo"	, POS_SLEEPING, do_gen_comm , 0, SCMD_ooc },
  { "autoexit" , "autoe", POS_DEAD    , do_gen_tog  , 999999, SCMD_AUTOEXIT },
  { "music"    , "mus"  , POS_SLEEPING, do_gen_comm , 0, SCMD_MUSIC },
  {"autosplit", "autos" , POS_DEAD, do_gen_tog, 0, SCMD_AUTOSPLIT},
  {"autoloot", "autol" , POS_DEAD, do_gen_tog, 0, SCMD_AUTOLOOT},

  { "backstab" , "bac"	, POS_STANDING, do_backstab , 1, 0 },
  { "ban"      , "ban"	, POS_DEAD    , do_ban      , LVL_GRGOD, 0 },
  { "orevert"  , "orev"	, POS_DEAD    , do_orevert  , 1, 0 },
  { "balance"  , "bal"	, POS_STANDING, do_not_here , 999999, 0 },
  { "bid"      , "bi"   , POS_SLEEPING, do_bid    , 0, 0 },
  { "sweep"    , "bas"	, POS_FIGHTING, do_sweep     , 1, 0 },
  { "bigbang"  , "big"   , POS_FIGHTING, do_bigbang     , 1, 0 },
  { "brief"    , "br"   , POS_DEAD    , do_gen_tog  , 999999, SCMD_BRIEF },
  { "buy"      , "b"    , POS_STANDING, do_not_here , 0, 0 },
  { "bug"      , "bug"  , POS_DEAD    , do_gen_write, 1000, SCMD_BUG },

  { "focus"    , "f"    , POS_FIGHTING , do_focus    , 1, 0 },
  { "calculator"    , "calc"   , POS_STANDING, do_calc , 1, 0 },
  { "check"    , "ch"   , POS_STANDING, do_not_here , 999999, 0 },
  { "choukamehameha" , "chou" , POS_FIGHTING, do_choukame , 1, 0 },
  { "burningattack" , "burn" , POS_FIGHTING, do_burning , 1, 0 },
  { "genkidama" , "genki" , POS_FIGHTING, do_genki , 1, 0 },
  { "chikyuugekigama" , "chikyuu" , POS_FIGHTING, do_chikyuu , 1, 0 },
  { "genocide" , "geno" , POS_FIGHTING, do_genocide , 0, 0 },
  { "bbk" , "bbk" , POS_FIGHTING, do_bbk , 1, 0 },
  { "yoikominminken" , "yoik" , POS_FIGHTING , do_yoiko , 1, 0 },
  { "twinblade" , "twin" , POS_FIGHTING, do_twin , 1, 0 },
  { "gigasbeam" , "giga" , POS_FIGHTING, do_gigabeam , 1, 0 },
  { "hellspear" , "hells" , POS_FIGHTING, do_hellspear , 1, 0 },
  { "spiritball" , "spirit" , POS_FIGHTING, do_spirit , 1, 0 }, 
  { "scattershot" , "scatter" , POS_FIGHTING, do_scatter , 1, 0 },
  { "sevendragon" , "dragon" , POS_FIGHTING, do_dragon , 1, 0},
  { "clear"    , "cle"	, POS_DEAD    , do_gen_ps   , 999999, SCMD_CLEAR },
  { "close"    , "clo"	, POS_SITTING , do_gen_door , 0, SCMD_CLOSE },
  { "clone"    , "clon" , POS_DEAD    , do_copy     , LVL_IMMORT, 0 },
  { "cls"      , "cls"	, POS_DEAD    , do_gen_ps   , 999999, SCMD_CLEAR },
  { "consider" , "con"	, POS_RESTING , do_consider , 0, 0 },
  { "congrat"  , "cong" , POS_SLEEPING, do_gen_comm , 0, SCMD_GRATZ },
  { "color"    , "col"	, POS_DEAD    , do_color    , 0, 0 },
  { "commands" , "comm"	, POS_DEAD    , do_commands , 0, SCMD_COMMANDS },
  { "compact"  , "comp"	, POS_DEAD    , do_gen_tog  , 999999, SCMD_COMPACT },
  { "copyover" , "copyo", POS_DEAD    , do_copyover , 1000009, 0 },
  { "acopyover" , "acopyo", POS_DEAD    , do_acopyover , 1000009, 0 },
  { "charge"   , "ch"	, POS_STANDING , do_charge  , 1, 0 },
  { "credits"  , "cre"	, POS_DEAD    , do_gen_ps   , 0, SCMD_CREDITS },

  { "lag"      , "lag"  , POS_DEAD    , do_lag      , 1000012, LVL_1000012 },
  { "poof"     , "poof" , POS_DEAD    , do_poof     , LVL_IMMORT, 0 },
  { "poofin"   , "poofi", POS_DEAD    , do_poofin   , LVL_IMMORT, 0 },
  { "poofout"  , "oiifo", POS_DEAD    , do_poofout  , LVL_IMMORT, 0 },
//  { "contact"  , "cont" , POS_RESTING , do_contact  , 0, 0 },
  { "wizupdate", "wizup", POS_DEAD    , do_wizupdate  , LVL_IMPL, 0},
  { "system", "syste", POS_DEAD    , do_system  , LVL_IMPL, 0},
  { "zap", "zap", POS_DEAD    , do_zap  , 1000000, 0},
  { "saiyan", "saiya", POS_DEAD    , do_saiyan  , 1000009, 0},
  { "chown", "chown", POS_DEAD    , do_chown  , LVL_IMPL, 0},
  { "linkload" , "linkl" , POS_DEAD    , do_linkload , 1000010, 0 },
  { "omni"     , "omni"  , POS_DEAD    , do_omni     , LVL_COIMP, 0 },
  { "players"  , "player", POS_DEAD    , do_players  , 1000012, 0 },
  { "file"     , "fi"   , POS_DEAD    , do_file     , LVL_COIMP, 0 },
  { "rlist"    , "rlist", POS_DEAD    , do_rlist    , LVL_IMMORT, 0 },
  { "olist"    , "olist", POS_DEAD    , do_olist    , LVL_IMMORT, 0 },
  { "mlist"    , "mlist", POS_DEAD    , do_mlist   , LVL_IMMORT, 0 },
  { "snamek"   , "sname", POS_STANDING, do_snamek   , 0, 0 },
  { "compare"  , "comp" , POS_STANDING, do_compare  , 0, 0 },
  { "xname"    , "xname", POS_DEAD    , do_xname    , LVL_IMPL, 0 },
  { "glance"   , "glan" , POS_RESTING , do_glance   , 999999, 0 },
  { "swho"    ,  "swho" , POS_DEAD   , do_swho      , LVL_IMPL, 0},
  { "slast"   , "slast" , POS_DEAD   , do_slast     , LVL_IMPL, 0 },
  { "sps"     , "sps"   , POS_DEAD   , do_sps       , LVL_IMPL, 0 },
  { "grep"    , "grep"  , POS_DEAD   , do_grep      , LVL_IMPL, 0 },
  { "shuman"  , "shuma" , POS_STANDING, do_shuman   , 0, 0 },
  { "namechange", "nam" , POS_DEAD    , do_namechange, LVL_IMPL, 0 },

  { "date"     , "date"	, POS_DEAD    , do_date     , LVL_IMMORT, SCMD_DATE },
  { "deathball", "dea"  , POS_FIGHTING, do_dball    , 1, 0},
  { "death2", "dea2"  , POS_FIGHTING, do_dball2    , 1, 0},
  { "kakusanha", "kaku"  , POS_FIGHTING, do_kakusanha    , 1, 0},
  { "pheonix", "pheon"  , POS_FIGHTING, do_pheonix    , 1, 0},
  { "eclipse", "eclip"  , POS_FIGHTING, do_eclipse    , 1, 0},
  { "hydroblade", "hydro"  , POS_FIGHTING, do_hydro    , 1, 0},
  { "dc"       , "dc"	, POS_DEAD    , do_dc       , LVL_GOD, 0 },
  { "deposit"  , "dep"	, POS_STANDING, do_not_here , 1, 0 },
  { "destructo", "des"  , POS_FIGHTING, do_disk , 1, 0 },
  { "diagnose" , "dia"	, POS_RESTING , do_diagnose , 999999, 0 },
  { "disk"     , "disk" , POS_FIGHTING, do_disk , 1, 0 },
  { "display"  , "dis"	, POS_DEAD    , do_display  , 999999, 0 },
  { "donate"   , "don"	, POS_RESTING , do_drop     , 0, SCMD_DONATE },
  { "drink"    , "dr"	, POS_RESTING , do_drink    , 0, SCMD_DRINK },
  { "drop"     , "dro"	, POS_RESTING , do_drop     , 0, SCMD_DROP },

  { "eat"      , "ea"	, POS_RESTING , do_eat      , 0, SCMD_EAT },
  { "echo"     , "echo"	, POS_SLEEPING, do_echo     , LVL_IMMORT, SCMD_ECHO },
  { "elbow"    , "elb"	, POS_FIGHTING, do_elbow    , 1, 0 },
  { "emote"    , "em"	, POS_RESTING , do_echo     , 1, SCMD_EMOTE },
  { ":"        , ":"	, POS_RESTING, do_echo      , 999999, SCMD_EMOTE },
  { "enter"    , "en"	, POS_STANDING, do_enter    , 0, 0 },
  { "equipment", "eq"	, POS_SLEEPING, do_equipment, 0, 0 },
  { "innerfire", "inn"  , POS_STANDING, do_innerfire, 1, 0 },
  { "exits"    , "exi"	, POS_RESTING , do_exits    , 999999, 0 },
  { "examine"  , "exa"	, POS_SITTING , do_examine  , 0, 0 },

  { "force"    , "for"	, POS_SLEEPING, do_force    , LVL_GOD, 0 },
  { "fill"     , "fil"	, POS_STANDING, do_pour     , 0, SCMD_FILL },
  { "finalflash" , "final" , POS_FIGHTING, do_finalflash , 1, 0 },
  { "flee"     , "fl"	, POS_FIGHTING, do_flee     , 1, 0 },
  { "follow"   , "fol"	, POS_RESTING , do_follow   , 0, 0 },
  { "selfdestruct" , "selfdest"	, POS_RESTING , do_selfdestruct , 0, 0 },
  { "fly"      , "fly"	, POS_RESTING , do_fly      , 1, 0 },
  { "freeze"   , "free" , POS_DEAD    , do_wizutil  , 1000006, SCMD_FREEZE },

  { "get"      , "g"	, POS_RESTING , do_get      , 0, 0 },
  { "gecho"    , "gech"	, POS_DEAD    , do_gecho    , LVL_GOD, 0 },
  { "give"     , "giv"	, POS_RESTING , do_give     , 0, 0 },
  { "goto"     , "got"	, POS_SLEEPING, do_goto     , 1000000, 0 },
  { "gold"     , "gol"	, POS_RESTING , do_gold     , 999999, 0 },
  { "group"    , "gro"  , POS_RESTING , do_group    , 1, 0 },
  { "grab"     , "gra"  , POS_RESTING , do_grab     , 999999, 0 },
  { "grats"    , "grat" , POS_SLEEPING, do_gen_comm , 0, SCMD_GRATZ },
  { "gsay"     , "gs"   , POS_SLEEPING, do_gsay     , 0, 0 },
  { "gtell"    , "gt"   , POS_SLEEPING, do_gsay     , 0, 0 },

  { "help"     , "he"	, POS_DEAD    , do_help     , 0, 0 },
  { "lp"     , "lp"   , POS_DEAD    , do_lp     , 0, 0 },
  { "potential"     , "potent"   , POS_DEAD    , do_potential     , 0, 0 },
  { "mindread"     , "mind"   , POS_DEAD    , do_mindread     , 0, 0 },
  { "majinize"     , "majin"   , POS_DEAD    , do_majinize     , 0, 0 },
  { "allow"     , "allo"   , POS_DEAD    , do_majinyes     , 0, 0 },
  { "hellsflash", "hel" , POS_FIGHTING, do_hellf    , 0, 0 },
  { "heal"     , "hea"  , POS_RESTING , do_heal     , 0, 0 },
  { "2health"     , "2heal"  , POS_FIGHTING , do_heal2     , 0, 0 },
  { "hedit"    , "hedit", POS_DEAD    , do_olc	   , 1000014, SCMD_OLC_HEDIT },
  { "handbook" , "hand"	, POS_DEAD    , do_gen_ps   , LVL_IMMORT, SCMD_HANDBOOK },
  { "hcontrol" , "hcon"	, POS_DEAD    , do_hcontrol , LVL_IMMORT, 0 },
  { "hide"     , "hid"  , POS_RESTING , do_hide     , 1000000, 0 },
  { "hit"      , "h"	, POS_FIGHTING, do_hit      , 0, SCMD_HIT },
  { "hold"     , "ho"	, POS_RESTING , do_grab     , 1, 0 },
  { "holler"   , "hol"	, POS_RESTING , do_gen_comm , 1, SCMD_HOLLER },
  { "holylight", "holy"	, POS_DEAD    , do_gen_tog  , LVL_IMMORT, SCMD_HOLYLIGHT },
  { "house"    , "hou"	, POS_RESTING , do_house    , 0, 0 },

  { "idea"     , "id"	, POS_DEAD    , do_gen_write, 1000, SCMD_IDEA },
  { "imotd"    , "imo"	, POS_DEAD    , do_gen_ps   , LVL_IMMORT, SCMD_IMOTD },
  { "logs"     , "log"  , POS_DEAD    , do_gen_ps   , 1000007, SCMD_LOG },
  { "immlist"  , "imm"	, POS_DEAD    , do_gen_ps   , 999999, SCMD_IMMLIST },
  { "info"     , "inf"	, POS_SLEEPING, do_gen_ps   , 0, SCMD_INFO },
  { "insult"   , "ins"	, POS_RESTING , do_insult   , 999999, 0 },
  { "invis"    , "inv"	, POS_DEAD    , do_invis    , 1000000, 0 },

  { "junk"     , "j"	, POS_RESTING , do_drop     , 0, SCMD_JUNK }, 

  { "kaioken"  , "kaio"	, POS_STANDING, do_kaioken  , 1, 0 },
  { "kyodaika"  , "kyo" , POS_STANDING, do_kyodaika  , 1, 0 },
  { "kamehameha" , "kame" , POS_FIGHTING, do_kamehame , 1, 0 },
/* { "kick"     , "kic"	, POS_FIGHTING, do_kick     ,  LVL_IMMORT, 0 },*/
  { "kikoho"   , "kik"  , POS_FIGHTING, do_kikoho, 1, 0 },
  { "kishot"   , "kish" , POS_FIGHTING, do_kishot, 1, 0 },
  { "havoc"   , "havo" , POS_FIGHTING, do_havoc, 1, 0 },
  { "eraser"   , "eras" , POS_FIGHTING, do_eraser, 1, 0 },
  { "crusher"   , "crush" , POS_FIGHTING, do_crusher, 1, 0 },
  { "baku"    , "bak"  , POS_FIGHTING, do_bakuhatsuha, 1, 0 },
  { "honoo"   , "hono" , POS_FIGHTING, do_honoo, 1, 0 },
  { "galik"   , "gali" , POS_FIGHTING, do_galikgun, 1, 0 },
  { "tsuihidan"   , "tsui" , POS_FIGHTING, do_tsuihidan, 1, 0 },
  { "shogekiha"   , "shog" , POS_FIGHTING, do_shogekiha, 1, 0 },
  { "beam"   , "bea" , POS_FIGHTING, do_beam, 0, 0 },
  { "regenerate" , "regen" , POS_STANDING, do_regenerate  , 1, 0 },
  { "knee"     , "kn"	, POS_FIGHTING, do_knee     , 1, 0 },
  { "kousengan" , "kou"   , POS_FIGHTING, do_kousen     , 1, 0 },

  { "scan"     , "sca"	, POS_RESTING , do_scan     , 0, 0 },
  { "stealth"  , "stealt" , POS_RESTING , do_stealth  , 0, 0 },
  { "upgrade"  , "upg"	, POS_RESTING , do_upgrade  , 0, 0 },
  { "last"     , "la"	, POS_DEAD    , do_last     , LVL_1000012, 0 },
  { "land"     , "lan"  , POS_STANDING  , do_land     , 0, 0 },
  { "learn"    , "lear" , POS_RESTING , do_learn    , 1, 0 },
  { "learned"  , "learne" , POS_RESTING, do_learned , 1, 0 },
  { "leave"    , "lea"	, POS_STANDING, do_leave    , 0, 0 },
  { "list"     , "li"	, POS_STANDING, do_not_here , 0, 0 },
  { "lock"     , "loc"	, POS_SITTING , do_gen_door , 0, SCMD_LOCK },
  { "load"     , "loa"	, POS_DEAD    , do_load     , LVL_IMMORT, 0 },

  { "medit"    , "med"	, POS_DEAD    , do_olc      , 1000000, SCMD_OLC_MEDIT },
  { "makankosappo"  , "maka" , POS_FIGHTING, do_makanko , 0, 0 },
  { "masenko"  , "mase" , POS_FIGHTING, do_masenko , 1, 0 },
  { "morph"    , "mor"  , POS_STANDING, do_majinmorph    , 1, 0 },
  { "motd"     , "motd" , POS_DEAD    , do_gen_ps   , 0, SCMD_MOTD },
  { "mail"     , "mail"	, POS_STANDING, do_not_here , 100, 0 },
  { "mute"     , "mut"	, POS_DEAD    , do_wizutil  , LVL_IMMORT, SCMD_SQUELCH },
  { "murder"   , "mur"	, POS_FIGHTING, do_hit      , 999999, SCMD_MURDER },
  { "mystic"   , "mys"  , POS_DEAD    , do_mystic   , 1, 0 },
  { "shadow"   , "shado" , POS_DEAD    , do_shadow   , 1, 0 },
  { "skanassan"   , "skana" , POS_DEAD    , do_skanassan   , 1, 0 },
  { "sangel"   , "sange" , POS_DEAD    , do_sangel   , 1, 0 },
  { "mutate"   , "muta" , POS_DEAD    , do_mutate   , 1, 0 },  

//  { "namechange", "nam" , POS_DEAD    , do_namechange, LVL_IMPL, 0 },
  { "topplayers"     , "toppla" , POS_SLEEPING, do_gen_ps   , 0, SCMD_NEWS },
  { "noooc", "noa"	, POS_DEAD    , do_gen_tog  , 0, SCMD_NOooc },
  { "training", "train"      , POS_DEAD    , do_training  , 0, 0 },
  { "nohassle" , "noh"	, POS_DEAD    , do_gen_tog  , LVL_IMMORT, SCMD_NOHASSLE },
  { "norepeat" , "nor"	, POS_DEAD    , do_gen_tog  , 0, SCMD_NOREPEAT },
  { "norole" , "noro"   , POS_DEAD    , do_gen_tog  , 0, SCMD_NOGOSSIP },
  { "noshout"  , "nosh"	, POS_SLEEPING, do_gen_tog  , 1, SCMD_DEAF },
  { "notell"   , "note"	, POS_DEAD    , do_gen_tog  , 1, SCMD_NOTELL },
  { "notitle"  , "noti"	, POS_DEAD    , do_wizutil  , LVL_GOD, SCMD_NOTITLE },
  { "nowiz"    , "now"	, POS_DEAD    , do_gen_tog  , LVL_IMMORT, SCMD_NOWIZ },

  { "order"    , "ord"	, POS_RESTING , do_order    , 1, 0 },
  { "offer"    , "off"	, POS_STANDING, do_not_here , 999999, 0 },
  { "open"     , "op"	, POS_SITTING , do_gen_door , 0, SCMD_OPEN },
  { "olc"      , "olc"	, POS_DEAD    , do_olc      , 1000000, SCMD_OLC_SAVEINFO },
  { "oedit"    , "oed"	, POS_DEAD    , do_olc      , 1000000, SCMD_OLC_OEDIT},

  { "put"      , "p"	, POS_RESTING , do_put      , 0, 0 },
  { "package"     , "pack"  , POS_DEAD    , do_package     , 1, 0 },
  { "page"     , "pag"	, POS_DEAD    , do_page     , 100, 0 },
  { "pardon"   , "par"	, POS_DEAD    , do_wizutil  , LVL_GOD, SCMD_PARDON },
  { "peace"    , "pea"	, POS_DEAD    , do_peace     , 1000001, 0 },
  { "perfection"  , "per" , POS_STANDING, do_perfection , 1, 0 },
  { "pick"     , "pi"	, POS_STANDING, do_gen_door , 1, SCMD_PICK },
  { "pk"       , "pk"   , POS_STANDING, do_pk       , 1 , 0 },
  { "policy"   , "pol"	, POS_DEAD    , do_gen_ps   , 999999, SCMD_POLICIES },
  { "scouter"     , "scout" , POS_STANDING, do_scouter     , 0, 0 },
  { "clan"     , "cla" , POS_STANDING, do_clan     , 0, 0 },
  { "quote"     , "quo" , POS_STANDING, do_quote     , 0, 0 },
  { "bounty"     , "boun" , POS_STANDING, do_bounty     , 0, 0 },
  { "race"     , "rac" , POS_STANDING, do_race     , 0, 0 },
//  { "poofin"   , "poofi", POS_DEAD    , do_poofset  , LVL_IMMORT, SCMD_POOFIN },
//  { "poofout"  , "poofo", POS_DEAD    , do_poofset  , LVL_IMMORT, SCMD_POOFOUT },
  { "password"     , "passw" , POS_STANDING, do_password     , 0, 0 },
  { "pour"     , "pour" , POS_STANDING, do_pour     , 0, SCMD_POUR },
  { "powerup"  , "pow"  , POS_STANDING, do_powerup  , 0, 0 },
  { "powerdown" , "powerd"  , POS_STANDING, do_powerdown  , 0, 0 },
  { "prompt"   , "promp", POS_DEAD    , do_display  , 999999, 0 },
  { "push"   ,"pus" , POS_STANDING, do_push , 1, 0 },
  { "pushup"   ,"pushu" , POS_STANDING, do_pushup , 1, 0 },
  { "meditate"   ,"medit" , POS_DEAD, do_meditate , 1, 0 },
  { "jog"      ,"jo"    , POS_STANDING, do_jog    , 1, 0 },
  { "hell2"    , "hell2"  , POS_DEAD    , do_hell2    , 1000000, 0 },
  { "purge"    , "pur"	, POS_DEAD    , do_purge    , 1000000, 0 },

  { "plant"    , "pl"	, POS_RESTING , do_use      , 0, SCMD_PLANT },
  { "qui"      , "qui"	, POS_DEAD    , do_quit     , 0, 0 },
  { "quit"     , "quit"	, POS_DEAD    , do_quit     , 0, SCMD_QUIT },
  { "qsay"     , "qsay"	, POS_RESTING , do_qcomm    , 0, SCMD_QSAY },

  { "renzokou" , "renzo" , POS_FIGHTING, do_renzo , 1, 0 },
  { "reply"    , "r"	, POS_SLEEPING, do_reply    , 0, 0 },
  { "rest"     , "res"	, POS_RESTING , do_rest     , 0, 0 },
  { "read"     , "rea"	, POS_RESTING , do_look     , 0, SCMD_READ },
  { "reload"   , "rel"	, POS_DEAD    , do_reboot   , LVL_IMPL, 0 },
  { "swallow"  , "swal"	, POS_RESTING , do_use      , 0, SCMD_SWALLOW },
  { "receive"  , "rece"	, POS_STANDING, do_not_here , 1, 0 },
  { "remove"   , "rem"	, POS_STANDING , do_remove   , 0, 0 },
  { "rent"     , "ren"	, POS_STANDING, do_not_here , 999999, 0 },
  { "repair"   , "repa" , POS_SITTING , do_repair   , 1, 0 },
  { "ingest"   , "ing"  , POS_SITTING , do_ingest   , 1, 0 },
  { "deflect"   , "defl"  , POS_SITTING , do_deflect   , 1, 0 },
  { "report"   , "rep"	, POS_RESTING , do_report   , 0, 0 },
  { "reroll"   , "rer"	, POS_DEAD    , do_wizutil  , LVL_GRGOD, SCMD_REROLL },
  { "rescue"   , "resc"	, POS_FIGHTING, do_rescue   , 1, 0 },
  { "restore"  , "resto", POS_DEAD    , do_restore  , LVL_IMMORT, 0 },
  { "return"   , "ret"	, POS_DEAD    , do_return   , 1, 0 },
  { "recall"   , "rec"  , POS_SLEEPING, do_recall   , 0, 0 },
  { "relevel"  , "rel"  , POS_DEAD    , do_relevel  , 999999, 0 },
  { "redit"    , "redit", POS_DEAD    , do_olc      , 1000000, SCMD_OLC_REDIT},
  { "rlink"    , "rlink", POS_DEAD    , do_rlink    , LVL_IMMORT, 0 },
  { "roleplay" , "role"  , POS_SLEEPING, do_roleplay , 0, 0 },
  { "roomflags", "roomf", POS_DEAD    , do_gen_tog  , LVL_IMMORT, SCMD_ROOMFLAGS },
  { "roundhouse", "rou"	, POS_FIGHTING, do_roundhouse , 1, 0 },
  { "rp"       , "rp"   , POS_DEAD    , do_gen_tog  , 0, SCMD_QUEST },
  { "rpecho"   , "rpec"	, POS_DEAD    , do_qcomm    , LVL_IMMORT, SCMD_QECHO },

  { "say"      , "say"	, POS_RESTING , do_say      , 0, 0 },
  { "osay"     , "osay"	, POS_RESTING , do_osay     , 0, 0 },
  { "'"        , "'"	, POS_RESTING , do_say      , 999999, 0 },
  { "save"     , "save"	, POS_SLEEPING, do_save     , 0, 0 },
  { "sell"     , "sel"	, POS_STANDING, do_not_here , 0, 0 },
  { "send"     , "sen"	, POS_SLEEPING, do_send     , LVL_GOD, 0 },
  { "set"      , "set"	, POS_DEAD    , do_set      , 1000000, 0 },
  { "ftick"    , "ftick", POS_DEAD    , do_ftick    , LVL_GOD, 0 },
  { "sedit"    , "sedi"	, POS_DEAD    , do_olc      , LVL_IMMORT, SCMD_OLC_SEDIT},
  { "shout"    , "sho"	, POS_RESTING , do_gen_comm , 0, SCMD_SHOUT },
  { "shake"    , "sha"	, POS_RESTING , do_action   , 999999, 0 },
  { "shiver"   , "shiv"	, POS_RESTING , do_action   , 999999, 0 },
  { "show"     , "sho"	, POS_DEAD    , do_show     , LVL_IMMORT, 0 },
  { "showadd" , "showadd", POS_DEAD   , do_showadd  , LVL_IMPL, 0 },
  { "shutdow"  , "shutdow", POS_DEAD    , do_shutdown , LVL_GRGOD, 0 },
  { "shutdown" , "shutdown", POS_DEAD    , do_shutdown , LVL_GRGOD, SCMD_SHUTDOWN },
  { "sip"      , "sip"	, POS_RESTING , do_drink    , 0, SCMD_SIP },
  { "sit"      , "sit"	, POS_RESTING , do_sit      , 0, 0 },
  { "situp"    ,"situ"  , POS_STANDING, do_situp , 1, 0 },
  { "skillset" , "skillse" , POS_SLEEPING, do_skillset , 1000007, 0 },
  { "sleep"    , "sl"	, POS_SLEEPING, do_sleep    , 0, 0 },
  { "slowns"   , "slown", POS_DEAD    , do_gen_tog  , LVL_IMPL, SCMD_SLOWNS },
  { "swiftness", "swift", POS_STANDING, do_SWIFTNESS    , 1, 0 },
  { "snoop"    , "sno"	, POS_DEAD    , do_snoop    , LVL_GOD, 0 },
  { "socials"  , "soc"	, POS_DEAD    , do_commands , 0, SCMD_SOCIALS },
  { "split"    , "spl"	, POS_SITTING , do_split    , 1, 0 },
  { "suicide"    , "suicide"	, POS_RESTING , do_suicide    , 0, 0 },
  { "stand"    , "st"   , POS_RESTING , do_stand    , 0, 0 },
  { "mug"    , "mu" , POS_STANDING, do_mug    , 1, 0 },
  { "camp"     , "cam"  , POS_STANDING, do_gen_tog  , 1, SCMD_CAMP },
  { "switch"   , "sw"	, POS_DEAD    , do_switch   , LVL_GRGOD, 0 },
  { "ssj"      , "ssj"  , POS_DEAD    , do_ssj      , 1, 0 },
  { "syslog"   , "sys"	, POS_DEAD    , do_syslog   , LVL_IMMORT, 0 },

  { "tedit"    , "ted"	, POS_DEAD    , do_tedit    , LVL_IMPL, 0 },
  { "tell"     , "tel"	, POS_DEAD    , do_tell     , 1, 0 },
  { "take"     , "ta"	, POS_RESTING , do_get      , 1, 0 },
  { "tailwhip" , "tail"	, POS_FIGHTING, do_tailwhip , 1, 0 },  
  { "forelockwhip" , "fore" , POS_FIGHTING, do_forelock , 1, 0 },
  { "taste"    , "tas"	, POS_RESTING , do_eat      , 999999, SCMD_TASTE },
  { "teleport" , "tel"	, POS_DEAD    , do_teleport , LVL_LSSRGOD, 0 },
  { "thaw"     , "thaw"	, POS_DEAD    , do_wizutil  , 1000006, SCMD_THAW },
  { "title"    , "tit"	, POS_DEAD    , do_title    , 0, 0 },
  { "time"     , "tim"	, POS_DEAD    , do_time     , 0, 0 },
  { "toggle"   , "tog"	, POS_DEAD    , do_toggle   , 999999, 0 },
  { "sense"    , "sen"	, POS_STANDING, do_sense    , 0, 0 },
  { "trade" , "tra" , POS_SLEEPING, do_trade    , 1, 0 },
  { "transfer" , "tran"	, POS_SLEEPING, do_trans    , LVL_IMMORT, 0 },
  { "transform", "transfo" , POS_STANDING, do_transform , 1, 0 },
  { "trigedit" , "trig"	, POS_DEAD    , do_olc      , 1000000, SCMD_OLC_TRIGEDIT},
  { "typo"     , "typ"	, POS_DEAD    , do_gen_write, 1000, SCMD_TYPO },

  { "unlock"   , "unl"	, POS_SITTING , do_gen_door , 0, SCMD_UNLOCK },
  { "ungroup"  , "ung"	, POS_DEAD    , do_ungroup  , 999999, 0 },
  { "unban"    , "unb"	, POS_DEAD    , do_unban    , LVL_GRGOD, 0 },
  { "unaffect" , "una"	, POS_DEAD    , do_wizutil  , LVL_GOD, SCMD_UNAFFECT },
  { "uptime"   , "upt"	, POS_DEAD    , do_date     , LVL_IMMORT, SCMD_UPTIME },
  { "use"      , "us"	, POS_SITTING , do_use      , 1000013, SCMD_USE },
  { "users"    , "user"	, POS_DEAD    , do_users    , LVL_IMMORT, 0 },

  { "value"    , "val"	, POS_STANDING, do_not_here , 0, 0 },
  { "visible"  , "vis"	, POS_RESTING , do_visible  , 1, 0 },
  { "vnum"     , "vnum"	, POS_DEAD    , do_vnum     , LVL_IMMORT, 0 },
  { "vstat"    , "vsta"	, POS_DEAD    , do_vstat    , LVL_IMMORT, 0 },

  { "wake"     , "wak"	, POS_SLEEPING, do_wake     , 0, 0 },
  { "wear"     , "wea"	, POS_RESTING , do_wear     , 0, 0 },
  { "weather"  , "weat" , POS_RESTING , do_weather  , 999999, 0 },
  { "wish"      , "wis"  , POS_STANDING    , do_wish      , 0, 0 },
  { "who"      , "who"	, POS_DEAD    , do_who      , 0, 0 },
  { "whois"    , "whois" , POS_DEAD   , do_whois    , 0, 0 },
  { "finger"   , "fin"	, POS_DEAD    , do_finger   , 999999, 0 },
  { "whoami"   , "whoa"	, POS_DEAD    , do_gen_ps   , 999999, SCMD_WHOAMI },
  { "where"    , "whe"	, POS_RESTING , do_where    , 1, 0 },
  { "whisper"  , "whis"	, POS_RESTING , do_spec_comm, 0, SCMD_WHISPER },
  { "wield"    , "wie"	, POS_RESTING , do_wield    , 0, 0 },
  { "wimpy"    , "wim"	, POS_DEAD    , do_wimpy    , 0, 0 },
  { "withdraw" , "with"	, POS_STANDING, do_not_here , 1, 0 },
  { "wiznet"   , "wiz"	, POS_DEAD    , do_wiznet   , LVL_IMMORT, 0 },
  { ";"        , ";"	, POS_DEAD    , do_wiznet   , LVL_IMMORT, 0 },
  { "wizhelp"  , "wizh"	, POS_SLEEPING, do_commands , LVL_IMMORT, SCMD_WIZHELP },
  { "wizlist"  , "wizl"	, POS_DEAD    , do_gen_ps   , 0, SCMD_WIZLIST },
  { "wizlock"  , "wizlo", POS_DEAD    , do_wizlock  , 1000007, 0 },
  { "write"    , "wr"	, POS_STANDING, do_write    , 100, 0 },
  { "zanzokenelbow", "zan", POS_FIGHTING, do_zanelb , 0, 0 },

  { "zedit"    , "zed"	, POS_DEAD    , do_olc      , LVL_IMMORT, SCMD_OLC_ZEDIT},
  { "zreset"   , "zre"	, POS_DEAD    , do_zreset   , LVL_IMMORT, 0 },


  /* DG trigger commands */
  { "attach"   , "att"	, POS_DEAD    , do_attach   , LVL_IMPL, 0 },
  { "detach"   , "det"	, POS_DEAD    , do_detach   , LVL_IMPL, 0 },
  { "tlist"    , "tli"	, POS_DEAD    , do_tlist    , LVL_GOD, 0 },
  { "tstat"    , "tst"	, POS_DEAD    , do_tstat    , LVL_GOD, 0 },
  { "masound"  , "masound"	, POS_DEAD    , do_masound  , 0, 0 },
  { "mkill"    , "mkill"	, POS_STANDING, do_mkill    , 0, 0 },
  { "mjunk"    , "mjunk"	, POS_SITTING , do_mjunk    , 0, 0 },
  { "mecho"    , "mecho"	, POS_DEAD    , do_mecho    , 0, 0 },
  { "mechoaround", "mechoaround",POS_DEAD , do_mechoaround    , 0, 0 },
  { "msend"    , "msend"	, POS_DEAD    , do_msend    , 0, 0 },
  { "mload"    , "mload"	, POS_DEAD    , do_mload    , 0, 0 },
  { "mpurge"   , "mpurge"	, POS_DEAD    , do_mpurge    , 0, 0 },
  { "mgoto"    , "mgoto"	, POS_DEAD    , do_mgoto    , 0, 0 },
  { "mat"      , "mat"		, POS_DEAD    , do_mat      , 0, 0 },
  { "mteleport", "mteleport"	, POS_DEAD    , do_mteleport, 0, 0 },
  { "mforce"   , "mforce"	, POS_DEAD    , do_mforce   , 0, 0 },
  { "mexp"     , "mexp"		, POS_DEAD    , do_mexp     , 0, 0 },
  { "mgold"    , "mgold"	, POS_DEAD    , do_mgold    , 0, 0 },
  { "mhunt"    , "mhunt"	, POS_DEAD    , do_mhunt    , 0, 0 },
  { "mremember", "mremember"	, POS_DEAD    , do_mremember, 0, 0 },
  { "mforget"  , "mforget"	, POS_DEAD    , do_mforget  , 0, 0 },
  { "mtransform","mtransform"	, POS_DEAD    , do_mtransform, 0, 0 },


  { "\n", "zzzzzzz", 0, 0, 0, 0 } };	/* this must be last */


const char *fill[] =
{
  "in",
  "from",
  "with",
  "the",
  "on",
  "at",
  "to",
  "\n"
};

const char *reserved[] =
{
  "a",
  "an",
  "self",
  "me",
  "all",
  "room",
  "someone",
  "something",
  "\n"
};

/*
 * This is the actual command interpreter called from game_loop() in comm.c
 * It makes sure you are the proper level and position to execute the command,
 * then calls the appropriate function.
 */

void command_interpreter(struct char_data *ch, char *argument)
{
  int cmd, length;
  char *line;

  REMOVE_BIT(AFF_FLAGS(ch), AFF_HIDE);

  /* just drop to next line for hitting CR */
  skip_spaces(&argument);
  if (!*argument)
    return;

  if (!isalpha(*argument)) {
    arg[0] = argument[0];
    arg[1] = '\0';
    line = argument + 1;
  } else
    line = any_one_arg(argument, arg);

  /* otherwise, find the command */
  if ((GET_LEVEL(ch)<LVL_IMMORT) &&
      (command_wtrigger(ch, arg, line) ||
       command_mtrigger(ch, arg, line) ||
       command_otrigger(ch, arg, line)))
    return; /* command trigger took over */
  for (length = strlen(arg), cmd = 0; *complete_cmd_info[cmd].command != '\n'; cmd++)
    if (!strncmp(complete_cmd_info[cmd].command, arg, length))
      if (GET_LEVEL(ch) >= complete_cmd_info[cmd].minimum_level) {
        if (GET_ADD(ch) <= 49 && !IS_NPC(ch)) {
         GET_ADD(ch) += 1;
        }
	break;
       }
  if (*complete_cmd_info[cmd].command == '\n') {
    send_to_char("Huh?  (Type 'commands' for a list of commands.)\r\n", ch);
    if (GET_ADD(ch) <= 49 && !IS_NPC(ch)) {
         GET_ADD(ch) += 1;
        }
  }
  else if (PLR_FLAGGED(ch, PLR_FROZEN) && GET_LEVEL(ch) < 1000012) {
    send_to_char("You try, but the mind-numbing cold prevents you...\r\n", ch);
    if (GET_ADD(ch) <= 49 && !IS_NPC(ch)) {
         GET_ADD(ch) += 1;
        }
  }
  else if (!IS_NPC(ch) && GET_ADD(ch) >= 50) {
   if (GET_BUILD(ch) >= 3) {
    sprintf(buf2, "&16[&14FROZEN&16] &12%s &15has been frozen for REPEATED spamming&00.\r\n", GET_NAME(ch));
    send_to_all(buf2);
    SET_BIT(PLR_FLAGS(ch), PLR_FROZEN);
    GET_FREEZE_LEV(ch) = 1000000;
    GET_BUILD(ch) = 0;
    GET_ADD(ch) = 0;
    return;
   }
   else {
   sprintf(buf, "&16[&09SPAMMING&16] &14%s&15 was disconnected for spamming&16!&00\r\n", GET_NAME(ch));
   send_to_all(buf);
   GET_ADD(ch) = 0;
   GET_BUILD(ch) += 1;
   STATE(ch->desc) = CON_DISCONNECT;
   return;
   }
  }
/*  else if (complete_cmd_info[cmd].command_pointer == NULL)
send_to_char("Sorry, that command hasn't been implemented yet.\r\n", ch);*/
  else if (IS_NPC(ch) && complete_cmd_info[cmd].minimum_level >= LVL_IMMORT) {
    send_to_char("You can't use immortal commands while switched.\r\n", ch);
    if (GET_ADD(ch) <= 49 && !IS_NPC(ch)) {
         GET_ADD(ch) += 1;
        }
  }
  else if (GET_POS(ch) < complete_cmd_info[cmd].minimum_position)
    switch (GET_POS(ch)) {
    case POS_DEAD:
      send_to_char("Lie still; you are DEAD!!! :-(\r\n", ch);
      if (GET_ADD(ch) <= 49 && !IS_NPC(ch)) {
         GET_ADD(ch) += 1;
        }
      break;
    case POS_INCAP:
    case POS_MORTALLYW:
      send_to_char("You are in a pretty bad shape, unable to do anything!\r\n", ch);
      if (GET_ADD(ch) <= 49 && !IS_NPC(ch)) {
         GET_ADD(ch) += 1;
        }
      break;
    case POS_STUNNED:
      send_to_char("All you can do right now is think about the stars!\r\n", ch);
      if (GET_ADD(ch) <= 49 && !IS_NPC(ch)) {
         GET_ADD(ch) += 1;
        }
      break;
    case POS_SLEEPING:
      send_to_char("In your dreams, or what?\r\n", ch);
      if (GET_ADD(ch) <= 49 && !IS_NPC(ch)) {
         GET_ADD(ch) += 1;
        }
      break;
    case POS_RESTING:
      send_to_char("Nah... You feel too relaxed to do that..\r\n", ch);
      if (GET_ADD(ch) <= 49 && !IS_NPC(ch)) {
         GET_ADD(ch) += 1;
        }
      break;
    case POS_SITTING:
      send_to_char("Maybe you should get on your feet first?\r\n", ch);
      if (GET_ADD(ch) <= 49 && !IS_NPC(ch)) {
         GET_ADD(ch) += 1;
        }
      break;
    case POS_FIGHTING:
      send_to_char("No way!  You're fighting for your life!\r\n", ch);
      if (GET_ADD(ch) <= 49 && !IS_NPC(ch)) {
         GET_ADD(ch) += 1;
        }
      break;
  } else if (no_specials || !special(ch, cmd, line))
    ((*complete_cmd_info[cmd].command_pointer) (ch, line, cmd, complete_cmd_info[cmd].subcmd));
     if (GET_ADD(ch) <= 49 && !IS_NPC(ch)) {
         GET_ADD(ch) += 1;
        }
}


/**************************************************************************
 * Routines to handle aliasing                                             *
  **************************************************************************/


struct alias *find_alias(struct alias *alias_list, char *str)
{
  while (alias_list != NULL) {
    if (*str == *alias_list->alias)	/* hey, every little bit counts :-) */
      if (!strcmp(str, alias_list->alias))
	return alias_list;

    alias_list = alias_list->next;
  }

  return NULL;
}


void free_alias(struct alias *a)
{
  if (a->alias)
    free(a->alias);
  if (a->replacement)
    free(a->replacement);
  free(a);
}

/* The interface to the outside world: do_alias */
ACMD(do_alias)
{
  char *repl;
  struct alias *a, *temp;

  if (IS_NPC(ch))
    return;

  repl = any_one_arg(argument, arg);

  if (!*arg) {			/* no argument specified -- list currently defined aliases */
    send_to_char("Currently defined aliases:\r\n", ch);
    if ((a = GET_ALIASES(ch)) == NULL)
      send_to_char(" None.\r\n", ch);
    else {
      while (a != NULL) {
	sprintf(buf, "%-15s %s\r\n", a->alias, a->replacement);
	send_to_char(buf, ch);
	a = a->next;
      }
    }
  } else {			/* otherwise, add or remove aliases */
    /* is this an alias we've already defined? */
    if ((a = find_alias(GET_ALIASES(ch), arg)) != NULL) {
      REMOVE_FROM_LIST(a, GET_ALIASES(ch), next);
      free_alias(a);
    }
    /* if no replacement string is specified, assume we want to delete */
    if (!*repl) {
      if (a == NULL)
	send_to_char("No such alias.\r\n", ch);
      else
	send_to_char("Alias deleted.\r\n", ch);
    } else {			/* otherwise, either add or redefine an alias */
      if (!str_cmp(arg, "alias")) {
	send_to_char("You can't alias 'alias'.\r\n", ch);
	return;
      }
      CREATE(a, struct alias, 1);
      a->alias = str_dup(arg);
      delete_doubledollar(repl);
      a->replacement = str_dup(repl);
      if (strchr(repl, ALIAS_SEP_CHAR) || strchr(repl, ALIAS_VAR_CHAR))
	a->type = ALIAS_COMPLEX;
      else
	a->type = ALIAS_SIMPLE;
      a->next = GET_ALIASES(ch);
      GET_ALIASES(ch) = a;
      send_to_char("Alias added.\r\n", ch);
    }
  }
}

/*
 * Valid numeric replacements are only $1 .. $9 (makes parsing a little
 * easier, and it's not that much of a limitation anyway.)  Also valid
 * is "$*", which stands for the entire original line after the alias.
 * ";" is used to delimit commands.
 */
#define NUM_TOKENS       9

void perform_complex_alias(struct txt_q *input_q, char *orig, struct alias *a)
{
  struct txt_q temp_queue;
  char *tokens[NUM_TOKENS], *temp, *write_point;
  int num_of_tokens = 0, num;

  /* First, parse the original string */
  temp = strtok(strcpy(buf2, orig), " ");
  while (temp != NULL && num_of_tokens < NUM_TOKENS) {
    tokens[num_of_tokens++] = temp;
    temp = strtok(NULL, " ");
  }

  /* initialize */
  write_point = buf;
  temp_queue.head = temp_queue.tail = NULL;

  /* now parse the alias */
  for (temp = a->replacement; *temp; temp++) {
    if (*temp == ALIAS_SEP_CHAR) {
      *write_point = '\0';
      buf[MAX_INPUT_LENGTH - 1] = '\0';
      write_to_q(buf, &temp_queue, 1);
      write_point = buf;
    } else if (*temp == ALIAS_VAR_CHAR) {
      temp++;
      if ((num = *temp - '1') < num_of_tokens && num >= 0) {
	strcpy(write_point, tokens[num]);
	write_point += strlen(tokens[num]);
      } else if (*temp == ALIAS_GLOB_CHAR) {
	strcpy(write_point, orig);
	write_point += strlen(orig);
      } else if ((*(write_point++) = *temp) == '$')	/* redouble $ for act safety */
	*(write_point++) = '$';
    } else
      *(write_point++) = *temp;
  }

  *write_point = '\0';
  buf[MAX_INPUT_LENGTH - 1] = '\0';
  write_to_q(buf, &temp_queue, 1);

  /* push our temp_queue on to the _front_ of the input queue */
  if (input_q->head == NULL)
    *input_q = temp_queue;
  else {
    temp_queue.tail->next = input_q->head;
    input_q->head = temp_queue.head;
  }
}


/*
 * Given a character and a string, perform alias replacement on it.
 *
 * Return values:
 *   0: String was modified in place; call command_interpreter immediately.
 *   1: String was _not_ modified in place; rather, the expanded aliases
 *      have been placed at the front of the character's input queue.
 */
int perform_alias(struct descriptor_data *d, char *orig)
{
  char first_arg[MAX_INPUT_LENGTH], *ptr;
  struct alias *a, *tmp;

  /* Mobs don't have alaises. */
  if (IS_NPC(d->character))
    return 0;

  /* bail out immediately if the guy doesn't have any aliases */
  if ((tmp = GET_ALIASES(d->character)) == NULL)
    return 0;

  /* find the alias we're supposed to match */
  ptr = any_one_arg(orig, first_arg);

  /* bail out if it's null */
  if (!*first_arg)
    return 0;

  /* if the first arg is not an alias, return without doing anything */
  if ((a = find_alias(tmp, first_arg)) == NULL)
    return 0;

  if (a->type == ALIAS_SIMPLE) {
    strcpy(orig, a->replacement);
    return 0;
  } else {
    perform_complex_alias(&d->input, ptr, a);
    return 1;
  }
}



/***************************************************************************
 * Various other parsing utilities                                         *
 **************************************************************************/

/*
 * searches an array of strings for a target string.  "exact" can be
 * 0 or non-0, depending on whether or not the match must be exact for
 * it to be returned.  Returns -1 if not found; 0..n otherwise.  Array
 * must be terminated with a '\n' so it knows to stop searching.
 */
int search_block(char *arg, const char **list, int exact)
{
  register int i, l;

  /* Make into lower case, and get length of string */
  for (l = 0; *(arg + l); l++)
    *(arg + l) = LOWER(*(arg + l));

  if (exact) {
    for (i = 0; **(list + i) != '\n'; i++)
      if (!strcmp(arg, *(list + i)))
	return (i);
  } else {
    if (!l)
      l = 1;			/* Avoid "" to match the first available
				 * string */
    for (i = 0; **(list + i) != '\n'; i++)
      if (!strncmp(arg, *(list + i), l))
	return (i);
  }

  return -1;
}


int is_number(const char *str)
{
  while (*str)
    if (!isdigit(*(str++)))
      return 0;

  return 1;
}

/*
 * Function to skip over the leading spaces of a string.
 */
void skip_spaces(char **string)
{
  for (; **string && isspace(**string); (*string)++);
}


/*
 * Given a string, change all instances of double dollar signs ($$) to
 * single dollar signs ($).  When strings come in, all $'s are changed
 * to $$'s to avoid having users be able to crash the system if the
 * inputted string is eventually sent to act().  If you are using user
 * input to produce screen output AND YOU ARE SURE IT WILL NOT BE SENT
 * THROUGH THE act() FUNCTION (i.e., do_gecho, do_title, but NOT do_say),
 * you can call delete_doubledollar() to make the output look correct.
 *
 * Modifies the string in-place.
 */
char *delete_doubledollar(char *string)
{
  char *read, *write;

  /* If the string has no dollar signs, return immediately */
  if ((write = strchr(string, '$')) == NULL)
    return string;

  /* Start from the location of the first dollar sign */
  read = write;


  while (*read)   /* Until we reach the end of the string... */
    if ((*(write++) = *(read++)) == '$') /* copy one char */
      if (*read == '$')
	read++; /* skip if we saw 2 $'s in a row */

  *write = '\0';

  return string;
}


int fill_word(char *argument)
{
  return (search_block(argument, fill, TRUE) >= 0);
}


int reserved_word(char *argument)
{
  return (search_block(argument, reserved, TRUE) >= 0);
}


/*
 * copy the first non-fill-word, space-delimited argument of 'argument'
 * to 'first_arg'; return a pointer to the remainder of the string.
 */
char *one_argument(char *argument, char *first_arg)
{
  char *begin = first_arg;

  if (!argument) {
    log("SYSERR: one_argument received a NULL pointer!");
    *first_arg = '\0';
    return NULL;
  }

  do {
    skip_spaces(&argument);

    first_arg = begin;
    while (*argument && !isspace(*argument)) {
      *(first_arg++) = LOWER(*argument);
      argument++;
    }

    *first_arg = '\0';
  } while (fill_word(begin));

  return argument;
}


/*
 * one_word is like one_argument, except that words in quotes ("") are
 * considered one word.
 */
char *one_word(char *argument, char *first_arg)
{
  char *begin = first_arg;

  do {
    skip_spaces(&argument);

    first_arg = begin;

    if (*argument == '\"') {
      argument++;
      while (*argument && *argument != '\"') {
        *(first_arg++) = LOWER(*argument);
        argument++;
      }
      argument++;
    } else {
      while (*argument && !isspace(*argument)) {
        *(first_arg++) = LOWER(*argument);
        argument++;
      }
    }

    *first_arg = '\0';
  } while (fill_word(begin));

  return argument;
}


/* same as one_argument except that it doesn't ignore fill words */
char *any_one_arg(char *argument, char *first_arg)
{
  skip_spaces(&argument);

  while (*argument && !isspace(*argument)) {
    *(first_arg++) = LOWER(*argument);
    argument++;
  }

  *first_arg = '\0';

  return argument;
}


/*
 * Same as one_argument except that it takes two args and returns the rest;
 * ignores fill words
 */
char *two_arguments(char *argument, char *first_arg, char *second_arg)
{
  return one_argument(one_argument(argument, first_arg), second_arg); /* :-) */
}
char *three_arguments(char *argument, char *first_arg, char *second_arg, char *third_arg)
{
  return one_argument(one_argument(one_argument(argument, first_arg), second_arg), third_arg); /* :-) */
}


/*
 * determine if a given string is an abbreviation of another
 * (now works symmetrically -- JE 7/25/94)
 *
 * that was dumb.  it shouldn't be symmetrical.  JE 5/1/95
 * 
 * returnss 1 if arg1 is an abbreviation of arg2
 */
int is_abbrev(const char *arg1, const char *arg2)
{
  if (!*arg1)
    return 0;

  for (; *arg1 && *arg2; arg1++, arg2++)
    if (LOWER(*arg1) != LOWER(*arg2))
      return 0;

  if (!*arg1)
    return 1;
  else
    return 0;
}



/* return first space-delimited token in arg1; remainder of string in arg2 */
void half_chop(char *string, char *arg1, char *arg2)
{
  char *temp;

  temp = any_one_arg(string, arg1);
  skip_spaces(&temp);
  strcpy(arg2, temp);
}



/* Used in specprocs, mostly.  (Exactly) matches "command" to cmd number */
int find_command(const char *command)
{
  int cmd;

  for (cmd = 0; *complete_cmd_info[cmd].command != '\n'; cmd++)
    if (!strcmp(complete_cmd_info[cmd].command, command))
      return cmd;

  return -1;
}


int special(struct char_data *ch, int cmd, char *arg)
{
  register struct obj_data *i;
  register struct char_data *k;
  int j;

  /* special in room? */
  if (GET_ROOM_SPEC(ch->in_room) != NULL)
    if (GET_ROOM_SPEC(ch->in_room) (ch, world + ch->in_room, cmd, arg))
      return 1;

  /* special in equipment list? */
  for (j = 0; j < NUM_WEARS; j++)
    if (GET_EQ(ch, j) && GET_OBJ_SPEC(GET_EQ(ch, j)) != NULL)
      if (GET_OBJ_SPEC(GET_EQ(ch, j)) (ch, GET_EQ(ch, j), cmd, arg))
	return 1;

  /* special in inventory? */
  for (i = ch->carrying; i; i = i->next_content)
    if (GET_OBJ_SPEC(i) != NULL)
      if (GET_OBJ_SPEC(i) (ch, i, cmd, arg))
	return 1;

  /* special in mobile present? */
  for (k = world[ch->in_room].people; k; k = k->next_in_room)
    if (GET_MOB_SPEC(k) != NULL)
      if (GET_MOB_SPEC(k) (ch, k, cmd, arg))
	return 1;

  /* special in object present? */
  for (i = world[ch->in_room].contents; i; i = i->next_content)
    if (GET_OBJ_SPEC(i) != NULL)
      if (GET_OBJ_SPEC(i) (ch, i, cmd, arg))
	return 1;

  return 0;
}

/* load the player, put them in the right room - used by copyover_recover too */
/* load the player, put them in the right room - used by copyover_recover too */
int enter_player_game (struct descriptor_data *d)
{
    extern sh_int r_mortal_start_room;
    extern sh_int r_hell_room;
    extern sh_int r_immort_start_room;
    extern sh_int r_frozen_start_room;
    
    sh_int load_room;
    int load_result;
    
    reset_char(d->character);
    if (PLR_FLAGGED(d->character, PLR_INVSTART))
        GET_INVIS_LEV(d->character) = GET_LEVEL(d->character);
    if ((load_result = Crash_load(d->character) && GET_LOADROOM(d->character) == NOWHERE))
        d->character->in_room = NOWHERE;
    save_char(d->character, NOWHERE);

    d->character->next = character_list;
    character_list = d->character;
    
    if ((load_room = GET_LOADROOM(d->character)) != NOWHERE)
        load_room = real_room(load_room);
    /* If char was saved with NOWHERE, or real_room above failed... */
    else if (load_room == NOWHERE) {
         if (PRF_FLAGGED(d->character, PRF_NOGRATZ)) {
            load_room = r_hell_room;
            GET_CLAN(d->character) = 0;
            GET_MAX_MOVE(d->character) = 5;
            GET_ADD(d->character) = 0;
            GET_MOVE(d->character) = 0;
         }
         else if (PLR_FLAGGED(d->character, PLR_KILLER)) {
          switch (number(1, 4)) {
         case 1:
           load_room = r_pk1_room;
           break;
         case 2:
           load_room = r_pk2_room;
           break;
         case 3:
           load_room = r_pk3_room;
           break;
         case 4:
           load_room = r_pk4_room;
           break;
         default:
           load_room = r_pk1_room;
           break;
          }
          GET_MAX_MOVE(d->character) = 4;
          GET_MOVE(d->character) = 0;
          GET_CLAN(d->character) = 0;
          GET_ADD(d->character) = 0;
         }
         else if (GET_LEVEL(d->character) >= 1000000) {
            load_room = r_immort_start_room;
            GET_CLAN(d->character) = 0;
            GET_MAX_MOVE(d->character) = 5;
            GET_ADD(d->character) = 0;
          GET_MOVE(d->character) = 0;
         }
         else if (IS_icer(d->character) || IS_MUTANT(d->character)) {
            load_room = r_icer_start_room;
            GET_CLAN(d->character) = 0;
            GET_MAX_MOVE(d->character) = 5;
            GET_MOVE(d->character) = 0;
            GET_ADD(d->character) = 0;
            }
         else if (IS_KONATSU(d->character)) {
            load_room = r_konack_start_room;
            GET_CLAN(d->character) = 0;
            GET_ADD(d->character) = 0;
            }
         else if (IS_saiyan(d->character)) {
            load_room = r_saiyan_start_room;
            GET_CLAN(d->character) = 0;
            GET_MAX_MOVE(d->character) = 5;
            GET_MOVE(d->character) = 0;
            GET_ADD(d->character) = 0;
            }
         else if (IS_demon(d->character)) {
            load_room = r_demon_start_room;
            GET_CLAN(d->character) = 0;
            GET_MAX_MOVE(d->character) = 5;
            GET_MOVE(d->character) = 0;
            GET_ADD(d->character) = 0;
            }
         else if (IS_MAJIN(d->character)) {
            load_room = r_majin_start_room;
            GET_CLAN(d->character) = 0;
            GET_MAX_MOVE(d->character) = 5;
            GET_MOVE(d->character) = 0;
            GET_ADD(d->character) = 0;
            }
         else if (IS_TRUFFLE(d->character)) {
            load_room = r_truffle_start_room;
            GET_CLAN(d->character) = 0;
            GET_MAX_MOVE(d->character) = 5;
            GET_MOVE(d->character) = 0;
            GET_ADD(d->character) = 0;
            }
         else if (IS_Namek(d->character)) {
            GET_SEX(d->character) = SEX_NEUTRAL;
            load_room = r_namek_start_room;
            GET_CLAN(d->character) = 0;
            GET_MAX_MOVE(d->character) = 5;
            GET_MOVE(d->character) = 0;
            GET_ADD(d->character) = 0;
            }
          else {
            load_room = r_mortal_start_room;
            GET_CLAN(d->character) = 0;
            GET_MAX_MOVE(d->character) = 5;
            GET_MOVE(d->character) = 0;
            GET_ADD(d->character) = 0;
        }
    }
    
    if (PLR_FLAGGED(d->character, PLR_FROZEN))
        load_room = r_frozen_start_room;
    if (PRF_FLAGGED(d->character, PRF_NOGRATZ))
            load_room = r_hell_room;
    char_to_room(d->character, load_room);

    return load_result;

}


/* *************************************************************************
*  Stuff for controlling the non-playing sockets (get name, pwd etc)       *
************************************************************************* */


/* locate entry in p_table with entry->name == name. -1 mrks failed search */
int find_name(char *name)
{
  int i;

  for (i = 0; i <= top_of_p_table; i++) {
    if (!str_cmp((player_table + i)->name, name))
      return i;
  }

  return -1;
}


int _parse_name(char *arg, char *name)
{
  int i;

  /* skip whitespaces */
  for (; isspace(*arg); arg++);

  for (i = 0; (*name = *arg); arg++, i++, name++)
    if (!isalpha(*arg))
      return 1;

  if (!i)
    return 1;

  return 0;
}

#define RECON		1
#define USURP		2
#define UNSWITCH	3

/*
 * XXX: Make immortals 'return' instead of being disconnected when switched
 *      into person returns.  This function seems a bit over-extended too.
 */
int perform_dupe_check(struct descriptor_data *d)
{
  struct descriptor_data *k, *next_k;
  struct char_data *target = NULL, *ch, *next_ch;
  int mode = 0;

  int id = GET_IDNUM(d->character);

  /*
   * Now that this descriptor has successfully logged in, disconnect all
   * other descriptors controlling a character with the same ID number.
   */

  for (k = descriptor_list; k; k = next_k) {
    next_k = k->next;

    if (k == d)
      continue;

    if (k->original && (GET_IDNUM(k->original) == id)) {    /* switched char */
      SEND_TO_Q("\r\nMultiple login detected -- disconnecting.\r\n", k);
      STATE(k) = CON_CLOSE;
      if (!target) {
	target = k->original;
	mode = UNSWITCH;
      }
      if (k->character)
	k->character->desc = NULL;
      k->character = NULL;
      k->original = NULL;
    } else if (k->character && (GET_IDNUM(k->character) == id)) {
      if (!target && STATE(k) == CON_PLAYING) {
	SEND_TO_Q("\r\nThis body has been usurped!\r\n", k);
	target = k->character;
	mode = USURP;
      }
      k->character->desc = NULL;
      k->character = NULL;
      k->original = NULL;
      SEND_TO_Q("\r\nMultiple login detected -- disconnecting.\r\n", k);
      STATE(k) = CON_CLOSE;
    }
  }

 /*
  * now, go through the character list, deleting all characters that
  * are not already marked for deletion from the above step (i.e., in the
  * CON_HANGUP state), and have not already been selected as a target for
  * switching into.  In addition, if we haven't already found a target,
  * choose one if one is available (while still deleting the other
  * duplicates, though theoretically none should be able to exist).
  */

  for (ch = character_list; ch; ch = next_ch) {
    next_ch = ch->next;

    if (IS_NPC(ch))
      continue;
    if (GET_IDNUM(ch) != id)
      continue;

    /* ignore chars with descriptors (already handled by above step) */
    if (ch->desc)
      continue;

    /* don't extract the target char we've found one already */
    if (ch == target)
      continue;

    /* we don't already have a target and found a candidate for switching */
    if (!target) {
      target = ch;
      mode = RECON;
      continue;
    }

    /* we've found a duplicate - blow him away, dumping his eq in limbo. */
    if (ch->in_room != NOWHERE)
      char_from_room(ch);
    char_to_room(ch, 1);
    extract_char(ch);
  }

  /* no target for swicthing into was found - allow login to continue */
  if (!target)
    return 0;

  /* Okay, we've found a target.  Connect d to target. */
  free_char(d->character); /* get rid of the old char */
  d->character = target;
  d->character->desc = d;
  d->original = NULL;
  d->character->char_specials.timer = 0;
  REMOVE_BIT(PLR_FLAGS(d->character), PLR_MAILING | PLR_WRITING);
  STATE(d) = CON_PLAYING;

  switch (mode) {
  case RECON:
    SEND_TO_Q("Reconnecting.\r\n", d);
    sprintf(buf2, "%s has reconnected.", GET_NAME(d->character));
    send_to_room(buf2, d->character->in_room);
    /*act("$n has reconnected.", TRUE, d->character, 0, 0, TO_ROOM);*/
    sprintf(buf, "%s [%s] has reconnected.", GET_NAME(d->character), d->host);
    mudlog(buf, NRM, MAX(LVL_IMMORT, GET_INVIS_LEV(d->character)), TRUE);
    break;
  case USURP:
    SEND_TO_Q("You take over your own body, already in use!\r\n", d);
    act("$n suddenly keels over in pain, surrounded by a white aura...\r\n"
	"$n's body has been taken over by a new spirit!",
	TRUE, d->character, 0, 0, TO_ROOM);
    sprintf(buf, "%s has re-logged in ... disconnecting old socket.",
	    GET_NAME(d->character));
    mudlog(buf, NRM, MAX(LVL_IMMORT, GET_INVIS_LEV(d->character)), TRUE);
    break;
  case UNSWITCH:
    SEND_TO_Q("Reconnecting to unswitched char.", d);
    sprintf(buf, "%s [%s] has reconnected.", GET_NAME(d->character), d->host);
    mudlog(buf, NRM, MAX(LVL_IMMORT, GET_INVIS_LEV(d->character)), TRUE);
    break;
  }

  return 1;
}



/* deal with newcomers and other non-playing sockets */
void nanny(struct descriptor_data *d, char *arg)
{
  char buf[128];
  int player_i, load_result;
  char tmp_name[MAX_INPUT_LENGTH];
  struct char_file_u tmp_store;

  int load_char(char *name, struct char_file_u *char_element);
   int parse_class(char arg);


  switch (STATE(d)) {

  /*. OLC states .*/
  case CON_HEDIT:
    hedit_parse(d, arg);
    break;
  case CON_OEDIT: 
    oedit_parse(d, arg);
    break;
  case CON_REDIT: 
    redit_parse(d, arg);
    break;
  case CON_ZEDIT: 
    zedit_parse(d, arg);
    break;
  case CON_MEDIT: 
    medit_parse(d, arg);
    break;
  case CON_SEDIT: 
    sedit_parse(d, arg);
    break;
  case CON_AEDIT:
    aedit_parse(d, arg);
    break;
  case CON_TRIGEDIT:
    trigedit_parse(d, arg);
    break;
  /*. End of OLC states .*/

  case CON_GET_NAME:		/* wait for input of name */
    if (d->character == NULL) {
      CREATE(d->character, struct char_data, 1);
      clear_char(d->character);
      CREATE(d->character->player_specials, struct player_special_data, 1);
      d->character->desc = d;
    }
    if (!*arg)
      STATE(d) = CON_CLOSE;
    else {
      if ((_parse_name(arg, tmp_name)) || strlen(tmp_name) < 2 ||
	  strlen(tmp_name) > MAX_NAME_LENGTH || !Valid_Name(tmp_name) ||
	  fill_word(strcpy(buf, tmp_name)) || reserved_word(buf)) {
	SEND_TO_Q("Invalid name, please try another.\r\n"
		  "Name: ", d);
	return;
      }
      if ((player_i = load_char(tmp_name, &tmp_store)) > -1) {
	store_to_char(&tmp_store, d->character);
	GET_PFILEPOS(d->character) = player_i;

	if (PLR_FLAGGED(d->character, PLR_DELETED)) {
	  /* We get a false positive from the original deleted character. */
	  free_char(d->character);
	  d->character = NULL;
	  /* Check for multiple creations... */
	  if (!Valid_Name(tmp_name)) {
	    SEND_TO_Q("Invalid name, please try another.\r\nName: ", d);
	    return;
	  }
	  CREATE(d->character, struct char_data, 1);
	  clear_char(d->character);
	  CREATE(d->character->player_specials, struct player_special_data, 1);
	  d->character->desc = d;
	  CREATE(d->character->player.name, char, strlen(tmp_name) + 1);
	  strcpy(d->character->player.name, CAP(tmp_name));
	  GET_PFILEPOS(d->character) = player_i;
	  sprintf(buf, "Are you sure you want %s (Y/N)? ", tmp_name);
	  SEND_TO_Q(buf, d);
	  STATE(d) = CON_NAME_CNFRM;
	} else {
	  /* undo it just in case they are set */
	  REMOVE_BIT(PLR_FLAGS(d->character),
		     PLR_WRITING | PLR_MAILING | PLR_CRYO);

          sprintf(buf, "Enter %s's Password: ", GET_NAME(d->character));
	  SEND_TO_Q(buf, d);
	  echo_off(d);
	  d->idle_tics = 0;
	  STATE(d) = CON_PASSWORD;
	}
      } else {
	/* player unknown -- make new character */

	/* Check for multiple creations of a character. */
	if (!Valid_Name(tmp_name)) {
	  SEND_TO_Q("Invalid name, please try another.\r\nName: ", d);
	  return;
	}
	CREATE(d->character->player.name, char, strlen(tmp_name) + 1);
	strcpy(d->character->player.name, CAP(tmp_name));

	sprintf(buf, "Did I get that right, %s (Y/N)? ", tmp_name);
	SEND_TO_Q(buf, d);
	STATE(d) = CON_NAME_CNFRM;
      }
    }
    break;
  case CON_NAME_CNFRM:		/* wait for conf. of new name    */
    if (UPPER(*arg) == 'Y') {
      if (isbanned(d->host) >= BAN_NEW) {
	sprintf(buf, "Request for new char %s denied from [%s] (siteban)",
		GET_NAME(d->character), d->host);
	mudlog(buf, NRM, LVL_GOD, TRUE);
	SEND_TO_Q("Sorry, new characters are not allowed from your site!\r\n", d);
	STATE(d) = CON_CLOSE;
	return;
      }
      if (circle_restrict >= 1) {
	SEND_TO_Q("Sorry, new players can't be created at the moment.\r\n", d);
	sprintf(buf, "Request for new char %s denied from [%s] (wizlock)",
		GET_NAME(d->character), d->host);
	mudlog(buf, NRM, LVL_GOD, TRUE);
	STATE(d) = CON_CLOSE;
	return;
      }
      SEND_TO_Q("New character.\r\n", d);
      sprintf(buf, "Give me a password for %s: ", GET_NAME(d->character));
      SEND_TO_Q(buf, d);
      echo_off(d);
      STATE(d) = CON_NEWPASSWD;
    } else if (*arg == 'n' || *arg == 'N') {
      SEND_TO_Q("Okay, what IS it, then? ", d);
      free(d->character->player.name);
      d->character->player.name = NULL;
      STATE(d) = CON_GET_NAME;
    } else {
      SEND_TO_Q("Please type Yes or No: ", d);
    }
    break;
  case CON_PASSWORD:		/* get pwd for known player      */
    /*
     * To really prevent duping correctly, the player's record should
     * be reloaded from disk at this point (after the password has been
     * typed).  However I'm afraid that trying to load a character over
     * an already loaded character is going to cause some problem down the
     * road that I can't see at the moment.  So to compensate, I'm going to
     * (1) add a 15 or 20-second time limit for entering a password, and (2)
     * re-add the code to cut off duplicates when a player quits.  JE 6 Feb 96
     */

    echo_on(d);    /* turn echo back on */

    if (!*arg)
      STATE(d) = CON_CLOSE;
    else {
      if (strncmp(CRYPT(arg, GET_PASSWD(d->character)), GET_PASSWD(d->character), MAX_PWD_LENGTH)) {
	sprintf(buf, "Bad PW: %s [%s]", GET_NAME(d->character), d->host);
	mudlog(buf, BRF, LVL_GOD, TRUE);
	GET_BAD_PWS(d->character)++;
	save_char(d->character, NOWHERE);
	if (++(d->bad_pws) >= max_bad_pws) {	/* 3 strikes and you're out. */
	  SEND_TO_Q("Wrong password... disconnecting.\r\n", d);
	  STATE(d) = CON_CLOSE;
	} else {
          sprintf(buf, "Wrong password.\r\nEnter %s's Password:", GET_NAME(d->character));
	  SEND_TO_Q(buf, d);
	  echo_off(d);
	}
	return;
      }

      /* Password was correct. */
      load_result = GET_BAD_PWS(d->character);
      GET_BAD_PWS(d->character) = 0;
      d->bad_pws = 0;

      if (isbanned(d->host) == BAN_SELECT &&
	  !PLR_FLAGGED(d->character, PLR_SITEOK)) {
	SEND_TO_Q("Sorry, this char has not been cleared for login from your site!\r\n", d);
	STATE(d) = CON_CLOSE;
	sprintf(buf, "Connection attempt for %s denied from %s",
		GET_NAME(d->character), d->host);
	mudlog(buf, NRM, LVL_GOD, TRUE);
	return;
      }
      if (circle_restrict > GET_LEVEL(d->character) && GET_LEVEL(d->character) < 1000000) {
	SEND_TO_Q("The game is temporarily restricted.. try again later.\r\n", d);
	STATE(d) = CON_CLOSE;
	sprintf(buf, "Request for login denied for %s [%s] (wizlock)",
		GET_NAME(d->character), d->host);
	mudlog(buf, NRM, LVL_GOD, TRUE);
	return;
      }
      /* check and make sure no other copies of this player are logged in */
      if (perform_dupe_check(d))
	return;

      if (GET_LEVEL(d->character) >= LVL_IMMORT)
	SEND_TO_Q(imotd, d);
      else
	SEND_TO_Q(motd, d);

      sprintf(buf, "%s [%s] has connected.", GET_NAME(d->character), d->host);
      mudlog(buf, BRF, MAX(LVL_IMMORT, GET_INVIS_LEV(d->character)), TRUE);
/*    if (GET_LEVEL(d->character) < LVL_IMMORT) {
    sprintf(buf2, "&16[&09Player Login&16] &15%s has joined &11Drag&12(&09*&12)&11n Ball
 - &12T&00&07r&00&06u&00&07t&12h&10!&00\r\n", 
GET_NAME(d->character));
    send_to_all(buf2);
}*/

      if (load_result) {
	sprintf(buf, "\r\n\r\n\007\007\007"
		"%s%d LOGIN FAILURE%s SINCE LAST SUCCESSFUL LOGIN.%s\r\n",
		CCRED(d->character, C_SPR), load_result,
		(load_result > 1) ? "S" : "", CCNRM(d->character, C_SPR));
	SEND_TO_Q(buf, d);
	GET_BAD_PWS(d->character) = 0;
      }
      SEND_TO_Q("\r\n\n*** PRESS RETURN: ", d);
      STATE(d) = CON_RMOTD;
    }
    break;

  case CON_NEWPASSWD:
  case CON_CHPWD_GETNEW:
    if (!*arg || strlen(arg) > MAX_PWD_LENGTH || strlen(arg) < 3 ||
	!str_cmp(arg, GET_NAME(d->character))) {
      SEND_TO_Q("\r\nIllegal password.\r\n", d);
      SEND_TO_Q("Password: ", d);
      return;
    }
    strncpy(GET_PASSWD(d->character), CRYPT(arg, GET_NAME(d->character)), MAX_PWD_LENGTH);
    *(GET_PASSWD(d->character) + MAX_PWD_LENGTH) = '\0';

    sprintf(buf, "Please retype %s's password: ", GET_NAME(d->character));
    SEND_TO_Q(buf, d);
    if (STATE(d) == CON_NEWPASSWD)
      STATE(d) = CON_CNFPASSWD;
    else
      STATE(d) = CON_CHPWD_VRFY;

    break;

  case CON_CNFPASSWD:
  case CON_CHPWD_VRFY:
    if (strncmp(CRYPT(arg, GET_PASSWD(d->character)), GET_PASSWD(d->character),
		MAX_PWD_LENGTH)) {
      SEND_TO_Q("\r\nPasswords don't match... start over.\r\n", d);
      sprintf(buf, "Enter %s's Password: ", GET_NAME(d->character));
      SEND_TO_Q(buf, d);
      if (STATE(d) == CON_CNFPASSWD)
	STATE(d) = CON_NEWPASSWD;
      else
	STATE(d) = CON_CHPWD_GETNEW;
      return;
    }
    echo_on(d);

    STATE(d) = CON_QSEX;
    SEND_TO_Q("What is your sex (\x1B[1;34mM\x1B[0;0m/\x1B[1;35mF\x1B[0;0m/\x1B[1;30mN\x1B[0;0m)?\r\n", d);
    break;
    
 case CON_QSEX:
    switch (*arg) {
    case 'm':
    case 'M':
      d->character->player.sex = SEX_MALE;
      break;
    case 'f':
    case 'F':
      d->character->player.sex = SEX_FEMALE;
      break;
    case 'n':
    case 'N':
      d->character->player.sex = SEX_NEUTRAL;
      break;
    default:
      SEND_TO_Q("That is not a sex..\r\n"
		"What IS your sex? ", d);
      return;
    }
    STATE(d) = CON_QEYE;
    SEND_TO_Q("\x1b[1;34m<>\x1b[0;37m=======================================\x1b[1;34m<>\x1B[0;0m\r\n"
              "       \x1B[1;37mWhat color eyes do you have?\x1B[0;0m\r\n"
              "\x1b[1;34m<>\x1b[0;37m=======================================\x1b[1;34m<>\x1B[0;0m\r\n"
              "\x1b[1;34m(\x1b[0;32m1\x1b[1;34m)\x1B[0;0m I have \x1B[1;30mblack\x1B[0;0m eyes.\r\n"
              "\x1b[1;34m(\x1b[0;32m2\x1b[1;34m)\x1B[0;0m I have \x1B[1;37mwhite\x1B[0;0m eyes.\r\n"
              "\x1b[1;34m(\x1b[0;32m3\x1b[1;34m)\x1B[0;0m I have \x1B[1;34mblue\x1B[0;0m eyes.\r\n"
              "\x1b[1;34m(\x1b[0;32m4\x1b[1;34m)\x1B[0;0m I have \x1B[1;32mgreen\x1B[0;0m eyes.\r\n"
              "\x1b[1;34m(\x1b[0;32m5\x1b[1;34m)\x1B[0;0m I have \x1B[33mbrown\x1B[0;0m eyes.\r\n"
              "\x1b[1;34m(\x1b[0;32m6\x1b[1;34m)\x1B[0;0m I have \x1B[1;35mpurple\x1B[0;0m eyes.\r\n"
              "\x1b[1;34m(\x1b[0;32m7\x1b[1;34m)\x1B[0;0m I have \x1B[1;31mred\x1B[0;0m eyes.\r\n"
              "\x1b[1;34m(\x1b[0;32m8\x1b[1;34m)\x1B[0;0m I have \x1B[1;33myellow\x1B[0;0m eyes.\r\n"
              "\x1b[1;34m(\x1b[0;32m9\x1b[1;34m)\x1B[0;0m I have \x1B[1;36micy blue\x1B[0;0m eyes.\r\n"
              "\x1B[36mEye Color\x1B[0;0m:\r\n", d);
    break;

 case CON_QEYE:		
    switch (*arg) {
    case '1':
      d->character->player.eye = EYE_BLACK;
      break;
    case '2':
      d->character->player.eye = EYE_WHITE;
      break;
    case '3':
      d->character->player.eye = EYE_BLUE;
      break;
    case '4':
      d->character->player.eye = EYE_GREEN;  
      break;
    case '5':
      d->character->player.eye = EYE_BROWN;
      break;
    case '6':
      d->character->player.eye = EYE_PURPLE;
      break;
    case '7':
      d->character->player.eye = EYE_RED;
      break;
    case '8':
      d->character->player.eye = EYE_YELLOW;
      break;                
    case '9':
      d->character->player.eye = EYE_ICYBLUE;
      break;
    default:
      SEND_TO_Q("That is not an eye color.\r\n", d);
      return;
    }
    
     STATE(d) = CON_QHAIRL;
    SEND_TO_Q("\x1b[1;34m<>\x1b[0;37m=======================================\x1b[1;34m<>\x1B[0;0m\r\n"
              "       \x1B[1;37mWhat is your hair length?\x1B[0;0m\r\n"
              "\x1b[1;34m<>\x1b[0;37m=======================================\x1b[1;34m<>\x1B[0;0m\r\n"
              "\x1b[1;34m(\x1b[0;32m1\x1b[1;34m)\x1B[0;0m I have very short hair.\r\n"
              "\x1b[1;34m(\x1b[0;32m2\x1b[1;34m)\x1B[0;0m I have short hair.     \r\n"
              "\x1b[1;34m(\x1b[0;32m3\x1b[1;34m)\x1B[0;0m I have medium length hair. \r\n"
              "\x1b[1;34m(\x1b[0;32m4\x1b[1;34m)\x1B[0;0m I have long hair.      \r\n"
              "\x1b[1;34m(\x1b[0;32m5\x1b[1;34m)\x1B[0;0m I have very long hair. \r\n"
              "\x1b[1;34m(\x1b[0;32m6\x1b[1;34m)\x1B[0;0m I have no hair. \r\n"
              "\x1b[1;34m(\x1b[0;32m7\x1b[1;34m)\x1B[0;0m I have short spikey hair. \r\n"
              "\x1b[1;34m(\x1b[0;32m8\x1b[1;34m)\x1B[0;0m I have medium spikey hair. \r\n"
              "\x1b[1;34m(\x1b[0;32m9\x1b[1;34m)\x1B[0;0m I have long spikey hair. \r\n"
              "\x1B[36mHair Length\x1B[0;0m:\r\n", d);
    break;
    
 case CON_QHAIRL:
    switch (*arg) {
    case '1':
      d->character->player.hairl = HAIRL_V_SHORT;
      break;
    case '2':
      d->character->player.hairl = HAIRL_SHORT;
      break;
    case '3':
      d->character->player.hairl = HAIRL_MEDIUM;
      break;
    case '4':
      d->character->player.hairl = HAIRL_LONG;
      break;
    case '5':
      d->character->player.hairl = HAIRL_V_LONG;
      break;      
    case '6':
      d->character->player.hairl = HAIRL_BALD;
      break;
    case '7':
      d->character->player.hairl = HAIRL_SSPIKE;
      break;
    case '8':
      d->character->player.hairl = HAIRL_MSPIKE;
      break;
    case '9':
      d->character->player.hairl = HAIRL_LSPIKE;
      break;
    default:
      SEND_TO_Q("That is not a hair length.\r\n", d);
      return;
    }
    
    STATE(d) = CON_QHAIRC;
    SEND_TO_Q("\x1b[1;34m<>\x1b[0;37m=======================================\x1b[1;34m<>\x1B[0;0m\r\n"
              "       \x1B[1;37mWhat is your hair color?\x1B[0;0m\r\n"
              "\x1b[1;34m<>\x1b[0;37m=======================================\x1b[1;34m<>\x1B[0;0m\r\n"
              "\x1b[1;34m(\x1b[0;32m1\x1b[1;34m)\x1B[0;0m I have \x1B[1;30mblack\x1B[0;0m hair\r\n"
              "\x1b[1;34m(\x1b[0;32m2\x1b[1;34m)\x1B[0;0m I have \x1B[1;37msilver\x1B[0;0m hair\r\n"
              "\x1b[1;34m(\x1b[0;32m3\x1b[1;34m)\x1B[0;0m I have \x1B[1;34mblue\x1B[0;0m hair\r\n"
              "\x1b[1;34m(\x1b[0;32m4\x1b[1;34m)\x1B[0;0m I have \x1B[1;32mgreen\x1B[0;0m hair\r\n"
              "\x1b[1;34m(\x1b[0;32m5\x1b[1;34m)\x1B[0;0m I have \x1B[33mbrown\x1B[0;0m hair\r\n"
              "\x1b[1;34m(\x1b[0;32m6\x1b[1;34m)\x1B[0;0m I have \x1B[1;35mpurple\x1B[0;0m hair\r\n"
              "\x1b[1;34m(\x1b[0;32m7\x1b[1;34m)\x1B[0;0m I have \x1B[1;31mred\x1B[0;0m hair\r\n"
              "\x1b[1;34m(\x1b[0;32m8\x1b[1;34m)\x1B[0;0m I have \x1B[1;33myellow\x1B[0;0m hair\r\n"
              "\x1b[1;34m(\x1b[0;32m9\x1b[1;34m)\x1B[0;0m I have \x1B[0;0mno hair\r\n"
              "\x1B[36mHair Color\x1B[0;0m:\r\n", d);
    break;

 case CON_QHAIRC:		
    switch (*arg) {
    case '1':
      d->character->player.hairc = HAIRC_BLACK;
      break;
    case '2':
      d->character->player.hairc = HAIRC_WHITE;
      break;
    case '3':
      d->character->player.hairc = HAIRC_BLUE;
      break;
    case '4':
      d->character->player.hairc = HAIRC_GREEN;  
      break;
    case '5':
      d->character->player.hairc = HAIRC_BROWN;
      break;
    case '6':
      d->character->player.hairc = HAIRC_PURPLE;
      break;
    case '7':
      d->character->player.hairc = HAIRC_RED;
      break;
    case '8':
      d->character->player.hairc = HAIRC_YELLOW;
      break;
    case '9':
      d->character->player.hairc = HAIRC_NONE;
      break;
    default:
      SEND_TO_Q("That is not a hair color.\r\n", d);
      return;
    }


    STATE(d) = CON_QAURA;
    SEND_TO_Q("\x1b[1;34m<>\x1b[0;37m=======================================\x1b[1;34m<>\x1B[0;0m\r\n"
              "       \x1B[1;37mWhat is your skin color?\x1B[0;0m\r\n"
              "\x1b[1;34m<>\x1b[0;37m=======================================\x1b[1;34m<>\x1B[0;0m\r\n"
              "\x1b[1;34m(\x1b[0;32m1\x1b[1;34m)\x1B[0;0m I have \x1B[1;30mblack\x1B[0;0m skin\r\n"
              "\x1b[1;34m(\x1b[0;32m2\x1b[1;34m)\x1B[0;0m I have \x1B[1;37mwhite\x1B[0;0m skin\r\n"
              "\x1b[1;34m(\x1b[0;32m3\x1b[1;34m)\x1B[0;0m I have \x1B[1;34mblue\x1B[0;0m skin\r\n"
              "\x1b[1;34m(\x1b[0;32m4\x1b[1;34m)\x1B[0;0m I have \x1B[1;32mgreen\x1B[0;0m skin\r\n"
              "\x1b[1;34m(\x1b[0;32m5\x1b[1;34m)\x1B[0;0m I have \x1B[1;35mpink\x1B[0;0m skin\r\n"
              "\x1b[1;34m(\x1b[0;32m6\x1b[1;34m)\x1B[0;0m I have \x1B[1;31mred\x1B[0;0m skin\r\n"
              "\x1b[1;34m(\x1b[0;32m7\x1b[1;34m)\x1B[0;0m I have \x1B[1;33mtan\x1B[0;0m skin\r\n"
              "\x1b[1;34m(\x1b[0;32m8\x1b[1;34m)\x1B[0;0m I have \x1B[1;35mpurple\x1B[0;0m skin\r\n"
              "\x1B[36mSkin Color\x1B[0;0m:\r\n", d);
    break;
 case CON_QAURA:               
    switch (*arg) {
    case '1':
      d->character->player.aura = AURA_BLACK;
      break;
    case '2':
      d->character->player.aura = AURA_WHITE;
      break;
    case '3':
      d->character->player.aura = AURA_BLUE;
      break;
    case '4':
      d->character->player.aura = AURA_GREEN;
      break;
    case '5':
      d->character->player.aura = AURA_PURPLE;
      break;
    case '6':
      d->character->player.aura = AURA_RED;
      break;
    case '7':
      d->character->player.aura = AURA_YELLOW;
      break;
    case '8':
      d->character->player.aura = AURA_PINK;
      break;
    default:
      SEND_TO_Q("That is not a skin color.\r\n", d);
      return;
    }

    STATE(d) = CON_QGOD;
    SEND_TO_Q("\x1b[1;34m<>\x1b[0;37m=======================================\x1b[1;34m<>\x1B[0;0m\r\n"
              "       \x1B[1;37mNo REMAKING at all.\x1B[0;0m\r\n"
              "\x1b[1;34m<>\x1b[0;37m=======================================\x1b[1;34m<>\x1B[0;0m\r\n"
              "\x1b[1;34m(\x1b[0;32m1\x1b[1;34m)\x1B[0;0m I understand, no remaking.\r\n"
              "\x1B[36mOk?\x1B[0;0m:\r\n", d);
    break;
 case CON_QGOD:               
    switch (*arg) {
    case '1':
      d->character->player.god = GOD_NONE;
      break;
    default:
      SEND_TO_Q("Agree to no remaking punk!\r\n", d);
      return;
    }
    
    SEND_TO_Q(class_menu, d);
    SEND_TO_Q("\r\nPick a Race: ", d);
    STATE(d) = CON_QCLASS;
    break;

  case CON_QCLASS:
    load_result = parse_class(*arg);
    if (load_result == CLASS_UNDEFINED) {
      SEND_TO_Q("\r\nThat's not a race.\r\nPick a Race: ", d);
      return;
    } else
      GET_CLASS(d->character) = load_result;

    if (GET_PFILEPOS(d->character) < 0)
      GET_PFILEPOS(d->character) = create_entry(GET_NAME(d->character));
    init_char(d->character);
    save_char(d->character, NOWHERE);
    SEND_TO_Q(motd, d);
    SEND_TO_Q("\r\n\n&12Please Enjoy your stay on &11Drag&12(&09*&12)&11nBall &12T&00&07r&00&06u&00&07t&12h&11!&00 ", d);
    SEND_TO_Q("\r\n\n*** PRESS RETURN: ", d);
    STATE(d) = CON_RMOTD;

    sprintf(buf, "%s [%s] new player.", GET_NAME(d->character), d->host);
    mudlog(buf, NRM, LVL_IMMORT, TRUE);
    sprintf(buf2, "&16[&12Welcome&16] &14%s &15is a new player&09!&00\r\n", GET_NAME(d->character));
    send_to_all(buf2);
    break;
    
  case CON_RMOTD:		/* read CR after printing motd   */
    SEND_TO_Q(MENU, d);
    STATE(d) = CON_MENU;
    break;

  case CON_MENU:		/* get selection from main menu  */
    switch (*arg) {
    case '0':
      SEND_TO_Q("Goodbye.\r\n", d);
      STATE(d) = CON_CLOSE;
      break;

    case '1':
 load_result = enter_player_game(d);
      send_to_char(WELC_MESSG, d->character);
  
      STATE(d) = CON_PLAYING;
      if (!GET_LEVEL(d->character)) {
	do_start(d->character);
	send_to_char(START_MESSG, d->character);
          do_newbie(d->character);
      }
      look_at_room(d->character, 0);
      if (GET_LEVEL(d->character) < LVL_IMMORT) {
      sprintf(buf2, "&16[&09Player Login&16] &15%s has joined &11Drag&12(&09*&12)&11n Ball - &12T&00&07r&00&06u&00&07t&12h&10!&00\r\n", GET_NAME(d->character));
      send_to_all(buf2);
      }
      if (GET_LEVEL(d->character) >= 1000000)
        send_to_char("\r\n\r\n&16[&10I&00&02m&10m&00&02o&10r&00&02t&10a&00&02l &09A&00&01l&09e&00&01r&09t &14S&00&06y&14s&00&06t&14e&00&06m&16] &15Report to the main imm board and the coder board and\r\nread both everytime you log on&11!&00\r\n\r\n", d->character);
      if (has_mail(GET_IDNUM(d->character)))
	send_to_char("&09You have mail waiting!&11!&09!&11!&09!&11!\r\n&10YES &09You really have mail waiting!&11!&09!&11!&09!&11!\r\n&09You &10had &09better check your mail already!&11!&09!&11!&09!&11!\r\n", d->character);
      if (load_result == 2) {	/* rented items lost */
	send_to_char("\r\n\007You could not afford your rent!\r\n"
	  "Your possesions have been donated to the Salvation Army!\r\n",
		     d->character);
      }
      d->has_prompt = 0;
      break;

    case '2':
      if (GET_MAX_HIT(d->character) <= 1499999) {
       SEND_TO_Q("Your character must be at least 1500000 pl to make a description.\r\n", d);
       SEND_TO_Q(MENU, d);
       break;
      }         
      if (d->character->player.description) {
	SEND_TO_Q("Current description:\r\n", d);
	SEND_TO_Q(d->character->player.description, d);
	/*
	 * Don't free this now... so that the old description gets loaded
	 * as the current buffer in the editor.  Do setup the ABORT buffer
	 * here, however.
	 *
	 * free(d->character->player.description);
	 * d->character->player.description = NULL;
	 */
	d->backstr = str_dup(d->character->player.description);
      }
      SEND_TO_Q("Enter the new text you'd like others to see when they look at you.\r\n", d);
      SEND_TO_Q("(/s saves /h for help)\r\n", d);
      d->str = &d->character->player.description;
      d->max_str = EXDSCR_LENGTH;
      STATE(d) = CON_EXDESC;
      break;

    case '3':
      page_string(d, background, 0);
      WAIT_STATE(d->character, PULSE_VIOLENCE * .5);
      STATE(d) = CON_RMOTD;
      break;

    case '4':
      SEND_TO_Q("\r\nEnter your password for verification: ", d);
      echo_off(d);
      STATE(d) = CON_DELCNF1;
      break;

    default:
      SEND_TO_Q("\r\nThat's not a menu choice!\r\n", d);
      WAIT_STATE(d->character, PULSE_VIOLENCE * .5);
      SEND_TO_Q(MENU, d);
      break;
    }

    break;

  case CON_CHPWD_GETOLD:
    if (strncmp(CRYPT(arg, GET_PASSWD(d->character)), GET_PASSWD(d->character), MAX_PWD_LENGTH)) {
      echo_on(d);
      SEND_TO_Q("\r\nIncorrect password.\r\n", d);
      SEND_TO_Q(MENU, d);
      STATE(d) = CON_MENU;
    } else {
      SEND_TO_Q("\r\nEnter a new password: ", d);
      STATE(d) = CON_CHPWD_GETNEW;
    }
    return;

  case CON_DELCNF1:
    echo_on(d);
    if (strncmp(CRYPT(arg, GET_PASSWD(d->character)), GET_PASSWD(d->character), MAX_PWD_LENGTH)) {
      SEND_TO_Q("\r\nIncorrect password.\r\n", d);
      SEND_TO_Q(MENU, d);
      STATE(d) = CON_MENU;
    } else {
      SEND_TO_Q("\r\nYOU ARE ABOUT TO DELETE THIS CHARACTER PERMANENTLY.\r\n"
		"ARE YOU ABSOLUTELY SURE?\r\n\r\n"
		"Please type \"yes\" to confirm: ", d);
      STATE(d) = CON_DELCNF2;
    }
    break;

  case CON_DELCNF2:
    if (!strcmp(arg, "yes") || !strcmp(arg, "YES")) {
      if (PLR_FLAGGED(d->character, PLR_FROZEN)) {
	SEND_TO_Q("You try to kill yourself, but the ice stops you.\r\n", d);
	SEND_TO_Q("Character not deleted.\r\n\r\n", d);
	STATE(d) = CON_CLOSE;
	return;
      }
      if (GET_LEVEL(d->character) < LVL_GRGOD)
	SET_BIT(PLR_FLAGS(d->character), PLR_DELETED);
      save_char(d->character, NOWHERE);
      Crash_delete_file(GET_NAME(d->character));
      sprintf(buf, "Character '%s' deleted!\r\n"
	      "Goodbye.\r\n", GET_NAME(d->character));
      SEND_TO_Q(buf, d);
      sprintf(buf, "%s (lev %Ld) has self-deleted.", GET_NAME(d->character),
	      GET_LEVEL(d->character));
      mudlog(buf, NRM, LVL_GOD, TRUE);
      STATE(d) = CON_CLOSE;
      return;
    } else {
      SEND_TO_Q("\r\nCharacter not deleted.\r\n", d);
      SEND_TO_Q(MENU, d);
      STATE(d) = CON_MENU;
    }
    break;

/*	Taken care of in game_loop()
  case CON_CLOSE:
    close_socket(d);
    break;
*/

  default:
    log("SYSERR: Nanny: illegal state of con'ness (%d) for '%s'; closing connection.",
	STATE(d), d->character ? GET_NAME(d->character) : "<unknown>");
    STATE(d) = CON_DISCONNECT;	/* Safest to do. */
    break;
  }
}