/
Crimson2/alias/
Crimson2/area.tmp/
Crimson2/area.tmp/AnomalySpaceDock/
Crimson2/area.tmp/AnomalyStation/
Crimson2/area.tmp/AntHill/
Crimson2/area.tmp/ArcticTerrarium/
Crimson2/area.tmp/BuilderCity/
Crimson2/area.tmp/Dungeon/
Crimson2/area.tmp/MiningDock/
Crimson2/area.tmp/PipeSystem/
Crimson2/area.tmp/RattArea/
Crimson2/area.tmp/RobotFactory/
Crimson2/area.tmp/SilverDale/
Crimson2/area.tmp/StarshipFearless/
Crimson2/area.tmp/StationConduits/
Crimson2/area.tmp/TerrariumAlpha/
Crimson2/area.tmp/TerrariumBeta/
Crimson2/area.tmp/TestArea/
Crimson2/area.tmp/Void/
Crimson2/area/
Crimson2/area/AnomalySpaceDock/
Crimson2/area/AnomalyStation/
Crimson2/area/MiningDock/
Crimson2/area/PipeSystem/
Crimson2/area/SilverDale/
Crimson2/area/StationConduits/
Crimson2/area/Void/
Crimson2/board/
Crimson2/clone/
Crimson2/lib/
Crimson2/mole/
Crimson2/mole/mole_src/HELP/
Crimson2/player/
Crimson2/util/
Crimson2/wldedit/
Crimson2/wldedit/res/
/* Crimson2 Mud Server
 * All source written/copyright Ryan Haksi 1995 *
 * This source code is proprietary. Use in whole or in part without
 * explicity permission by the author is strictly prohibited
 *
 * Current email address(es): cryogen@infoserve.net
 * Phone number: (604) 591-5295
 *
 * C4 Script Language written/copyright Cam Lesiuk 1995
 * Email: clesiuk@engr.uvic.ca
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

#include "crimson2.h"
#include "macro.h"
#include "queue.h"
#include "log.h"
#include "str.h"
#include "ini.h"
#include "extra.h"
#include "code.h"
#include "file.h"
#include "thing.h"
#include "exit.h"
#include "index.h"
#include "social.h"
#include "help.h"
#include "area.h"
#include "world.h"
#include "edit.h"
#include "history.h"
#include "socket.h"
#include "alias.h"
#include "send.h"
#include "base.h"
#include "char.h"
#include "player.h"
#include "moledefs.h"
#include "cmd_move.h"
#include "cmd_talk.h"
#include "cmd_inv.h"
#include "cmd_cbt.h"
#include "cmd_misc.h"
#include "cmd_god.h"
#include "cmd_area.h"
#include "cmd_wld.h"
#include "cmd_mob.h"
#include "cmd_obj.h"
#include "cmd_rst.h"
#include "cmd_help.h"
#include "cmd_code.h"
#include "cmd_brd.h" /* board stuff */
#include "cmd_mole.h"
#include "parse.h"



BYTE *commandFlagList[] = {
  "MOVE",
  "TALK",
  "MISC",
  "GOD",
  "AREAEDIT",
  "INVENTORY",
  "COMBAT",
  "HELPEDIT",
  "AREA",
  "WLD",
  "MOB",
  "OBJ",
  "RST",
  "BRD",
  "VNUMARG",
  "C4CODING",
  ""
};



/* text, proc, min_pos, min_lev, log, cmd flags */
const COMMANDLIST commandList[] = {
/* Movement */
  { "go",         CmdGo,       POS_FIGHTING,  1,            LOG_NEVER,  CF_MOVE },
  { "north",      CmdNorth,    POS_FIGHTING,  1,            LOG_NEVER,  CF_MOVE },
  { "east",       CmdEast,     POS_FIGHTING,  1,            LOG_NEVER,  CF_MOVE },
  { "south",      CmdSouth,    POS_FIGHTING,  1,            LOG_NEVER,  CF_MOVE },
  { "west",       CmdWest,     POS_FIGHTING,  1,            LOG_NEVER,  CF_MOVE },
  { "up",         CmdUp,       POS_FIGHTING,  1,            LOG_NEVER,  CF_MOVE },
  { "down",       CmdDown,     POS_FIGHTING,  1,            LOG_NEVER,  CF_MOVE },
  { "out",        CmdOut,      POS_FIGHTING,  1,            LOG_NEVER,  CF_MOVE },
  { "enter",      CmdGo,       POS_FIGHTING,  1,            LOG_NEVER,  CF_MOVE },
  { "exits",      CmdExit,     POS_RESTING,   1,            LOG_NEVER,  CF_MOVE },
  { "look",       CmdLook,     POS_RESTING,   1,            LOG_NEVER,  CF_MOVE },
  { "examine",    CmdLook,     POS_RESTING,   1,            LOG_NEVER,  CF_MOVE },
  { "scan",       CmdScan,     POS_SITTING,   1,            LOG_NEVER,  CF_MOVE },
  { "open",       CmdOpen,     POS_SITTING,   1,            LOG_NEVER,  CF_MOVE },
  { "close",      CmdClose,    POS_SITTING,   1,            LOG_NEVER,  CF_MOVE },
  { "unlock",     CmdUnlock,   POS_SITTING,   1,            LOG_NEVER,  CF_MOVE },
  { "lock",       CmdLock,     POS_SITTING,   1,            LOG_NEVER,  CF_MOVE },
  { "picklock",   CmdPicklock, POS_SITTING,   1,            LOG_NEVER,  CF_MOVE },
  { "hack",       CmdHack,     POS_SITTING,   1,            LOG_NEVER,  CF_MOVE },
  { "stand",      CmdStand,    POS_SLEEPING,  1,            LOG_NEVER,  CF_MOVE },
  { "sit",        CmdSit,      POS_SLEEPING,  1,            LOG_NEVER,  CF_MOVE },
  { "rest",       CmdRest,     POS_SITTING,   1,            LOG_NEVER,  CF_MOVE },
  { "sleep",      CmdSleep,    POS_RESTING,   1,            LOG_NEVER,  CF_MOVE },
  { "wake",       CmdWake,     POS_SLEEPING,  1,            LOG_NEVER,  CF_MOVE },
  { "track",      CmdTrack,    POS_STANDING,  1,            LOG_NEVER,  CF_MOVE },
  { "sneak",      CmdSneak,    POS_STANDING,  1,            LOG_NEVER,  CF_MOVE },
/* Combat */
  { "hit",        CmdHit,      POS_STANDING,  1,            LOG_NORMAL, CF_CBT  },
  { "kill",       CmdHit,      POS_STANDING,  1,            LOG_NORMAL, CF_CBT  },
  { "shoot",      CmdHit,      POS_STANDING,  1,            LOG_NORMAL, CF_CBT  },
  { "group",      CmdGroup,    POS_SITTING,   1,            LOG_NEVER,  CF_CBT  },
  { "follow",     CmdFollow,   POS_STANDING,  1,            LOG_NEVER,  CF_CBT  },
  { "concentrate",CmdConcentrate,POS_FIGHTING,1,            LOG_NORMAL, CF_CBT  },
  { "practice",   CmdPractice, POS_STANDING,  1,            LOG_NORMAL, CF_CBT  },
  { "consider",   CmdConsider, POS_STANDING,  1,            LOG_NEVER,  CF_CBT  },
  { "flee",       CmdFlee,     POS_FIGHTING,  1,            LOG_NORMAL, CF_CBT  },
  { "rescue",     CmdRescue,   POS_FIGHTING,  1,            LOG_NORMAL, CF_CBT  },
  { "hide",       CmdHide,     POS_STANDING,  1,            LOG_NORMAL, CF_CBT  },
  { "peek",       CmdPeek,     POS_STANDING,  1,            LOG_NEVER,  CF_CBT  },
  { "steal",      CmdSteal,    POS_STANDING,  1,            LOG_NORMAL, CF_CBT  },
  { "pickpocket", CmdPickpocket,POS_STANDING, 1,            LOG_NORMAL, CF_CBT  },
/* Inventory */
  { "drop",       CmdDrop,     POS_SITTING,   1,            LOG_NORMAL, CF_INV  },
  { "get",        CmdGet,      POS_SITTING,   1,            LOG_NORMAL, CF_INV  },
  { "take",       CmdGet,      POS_SITTING,   1,            LOG_NORMAL, CF_INV  },
  { "pickup",     CmdGet,      POS_SITTING,   1,            LOG_NORMAL, CF_INV  },
  { "junk",       CmdJunk,     POS_SITTING,   1,            LOG_NORMAL, CF_INV  },
  { "put",        CmdPut,      POS_SITTING,   1,            LOG_NEVER,  CF_INV  },
  { "give",       CmdGive,     POS_SITTING,   1,            LOG_NORMAL, CF_INV  },
  { "equip",      CmdEquip,    POS_SITTING,   1,            LOG_NEVER,  CF_INV  },
  { "wear",       CmdEquip,    POS_SITTING,   1,            LOG_NEVER,  CF_INV  },
  { "wield",      CmdEquip,    POS_SITTING,   1,            LOG_NEVER,  CF_INV  },
  { "hold",       CmdEquip,    POS_SITTING,   1,            LOG_NEVER,  CF_INV  },
  { "unequip",    CmdUnEquip,  POS_SITTING,   1,            LOG_NEVER,  CF_INV  },
  { "remove",     CmdUnEquip,  POS_SITTING,   1,            LOG_NEVER,  CF_INV  },
  { "inventory",  CmdInventory,POS_DEAD,      1,            LOG_NEVER,  CF_INV  },
  { "use",        CmdUse,      POS_SITTING,   1,            LOG_NORMAL, CF_INV  },
  { "eat",        CmdEat,      POS_SITTING,   1,            LOG_NORMAL, CF_INV  },
  { "drink",      CmdDrink,    POS_SITTING,   1,            LOG_NORMAL, CF_INV  },
  { "fill",       CmdFill,     POS_SITTING,   1,            LOG_NORMAL, CF_INV  },
  { "empty",      CmdEmpty,    POS_SITTING,   1,            LOG_NORMAL, CF_INV  },
  { "read",       CmdRead,     POS_RESTING,   1,            LOG_NORMAL, CF_INV  },
  { "write",      CmdWrite,    POS_RESTING,   1,            LOG_NORMAL, CF_INV  },
  { "reply",      CmdReply,    POS_RESTING,   1,            LOG_NORMAL, CF_INV  },
  { "edit",       CmdEdit,     POS_RESTING,   1,            LOG_NORMAL, CF_INV  },
  { "erase",      CmdErase,    POS_RESTING,   1,            LOG_NORMAL, CF_INV  },
/* Talking */
  { "gossip",     CmdGossip,   POS_SLEEPING,  1,            LOG_NORMAL, CF_TALK },
  { ".",          CmdGossip,   POS_SLEEPING,  1,            LOG_NORMAL, CF_TALK },
  { "auction",    CmdAuction,  POS_SLEEPING,  1,            LOG_NORMAL, CF_TALK },
  { "godtalk",    CmdGodtalk,  POS_SLEEPING,  LEVEL_GOD,    LOG_NORMAL, CF_TALK |CF_AREAEDIT},
  { "emote",      CmdEmote,    POS_SLEEPING,  1,            LOG_NORMAL, CF_TALK },
  { ":",          CmdEmote,    POS_SLEEPING,  1,            LOG_NORMAL, CF_TALK },
  { "say",        CmdSay,      POS_RESTING,   1,            LOG_NORMAL, CF_TALK },
  { "ask",        CmdSay,      POS_RESTING,   1,            LOG_NORMAL, CF_TALK },
  { "tell",       CmdTell,     POS_RESTING,   1,            LOG_NORMAL, CF_TALK },
  { "respond",    CmdRespond,  POS_RESTING,   1,            LOG_NORMAL, CF_TALK },
  { "order",      CmdOrder,    POS_RESTING,   1,            LOG_NORMAL, CF_TALK },
  { "gtell",      CmdGTell,    POS_SLEEPING,  1,            LOG_NORMAL, CF_TALK },
  { ";",          CmdGTell,    POS_RESTING,   1,            LOG_NORMAL, CF_TALK },
  { "rainbow",    CmdRainbow,  POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_TALK },
  { "chhistory",  CmdChHistory,POS_SLEEPING,  1,            LOG_NEVER,  CF_TALK },
  { "beep",       CmdBeep,     POS_SLEEPING,  1,            LOG_NORMAL, CF_TALK },
/* Miscellaneous */
  { "set",        CmdSet,      POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "setcolor",   CmdSetColor, POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "score",      CmdScore,    POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "title",      CmdTitle,    POS_DEAD,      1,            LOG_NORMAL, CF_MISC },
  { "socials",    NULL,        POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "alias",      CmdAlias,    POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "unalias",    CmdUnAlias,  POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "who",        CmdWho,      POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "where",      CmdWhere,    POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "time",       CmdTime,     POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "entermsg",   CmdEnterMsg, POS_SLEEPING,  1,            LOG_NEVER,  CF_MISC },
  { "exitmsg",    CmdExitMsg,  POS_SLEEPING,  1,            LOG_NEVER,  CF_MISC },
  { "prompt",     CmdPrompt,   POS_SLEEPING,  1,            LOG_NEVER,  CF_MISC },
  { "finger",     CmdFinger,   POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "levels",     CmdLevels,   POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "skillmax",   CmdSkillMax, POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "affects",    CmdAffects,  POS_DEAD,      1,            LOG_NEVER,  CF_MISC },
  { "stop",       CmdStop,     POS_RESTING,   1,            LOG_NEVER,  CF_MISC },
  { "area",       CmdArea,     POS_RESTING,   1,            LOG_NEVER,  CF_MISC },
/* God */
  { "heal",       CmdHeal,     POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_GOD|CF_AREAEDIT  },
  { "purge",      CmdPurge,    POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_GOD|CF_AREAEDIT  },
  { "transfer",   CmdTransfer, POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_GOD  },
  { "setskill",   CmdSetSkill, POS_DEAD,      LEVEL_ADMIN,  LOG_ALLWAYS,CF_GOD  },
  { "setstat",    CmdSetStat,  POS_DEAD,      LEVEL_ADMIN,  LOG_ALLWAYS,CF_GOD  },
  { "setprop",    CmdSetProp,  POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_GOD|CF_AREAEDIT  },
  { "goto",       CmdGoto,     POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_GOD  },
  { "vnum",       CmdVNum,     POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_GOD|CF_AREAEDIT  },
  { "stat",       CmdStat,     POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_GOD|CF_AREAEDIT  },
  { "at",         CmdAt,       POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_GOD  },
  { "force",      CmdForce,    POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_GOD  },
  { "cutconn",    CmdCutConn,  POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_GOD  },
  { "delplayer",  CmdDelPlayer,POS_DEAD,      LEVEL_ADMIN,  LOG_ALLWAYS,CF_GOD  },
  { "undelplayer",CmdUnDelPlayer,POS_DEAD,    LEVEL_ADMIN,  LOG_ALLWAYS,CF_GOD  },
  { "snoop",      CmdSnoop,    POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_GOD  },
  { "site",       CmdSite,     POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_GOD  },
  { "system",     CmdSystem,   POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_GOD  },
  { "users",      CmdUsers,    POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_GOD  },
  { "switch",     CmdSwitch,   POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_GOD  },
  { "resetskill", CmdResetSkill,POS_DEAD,     LEVEL_GOD,    LOG_ALLWAYS,CF_GOD  },
/*
  { "shutdown",   CmdShutdown, POS_DEAD,      LEVEL_ADMIN,  LOG_ALLWAYS,CF_GOD  },
*/
  { "reboot",     CmdReboot,   POS_DEAD,      LEVEL_ADMIN,  LOG_ALLWAYS,CF_GOD  },

/* Coding commands */
  { "compile",    CmdComp,     POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_C4CODING|CF_AREAEDIT  },
  { "disass",     CmdDisass,   POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_C4CODING|CF_AREAEDIT  },
  { "decompile",  CmdDecomp,   POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_C4CODING|CF_AREAEDIT  },
  { "dump",       CmdDump,     POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_C4CODING|CF_AREAEDIT  },
  { "c4snoop",    CmdC4Snoop,  POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_C4CODING|CF_AREAEDIT },
  { "flist",      CmdFList,    POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_C4CODING|CF_AREAEDIT },

/* Area Editing */
  { "alist",      CmdAList,    POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_AREA|CF_AREAEDIT },
  { "astat",      CmdAStat,    POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_AREA|CF_AREAEDIT|CF_VNUMARG},
  { "adesc",      CmdADesc,    POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_AREA|CF_AREAEDIT|CF_VNUMARG},
  { "aflag",      CmdAFlag,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_AREA|CF_VNUMARG},
  { "adelay",     CmdADelay,   POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_AREA|CF_AREAEDIT },
  { "areset",     CmdAReset,   POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_AREA|CF_AREAEDIT|CF_VNUMARG },
  { "areboot",    CmdAReboot,  POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_AREA|CF_AREAEDIT|CF_VNUMARG },
  { "aproperty",  CmdAProperty,POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_AREA|CF_AREAEDIT },
  { "acompile",   CmdACompile, POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_AREA|CF_AREAEDIT },
  { "adecomp",    CmdADecomp,  POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_AREA|CF_AREAEDIT },
  { "asave",      CmdASave,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_AREA|CF_AREAEDIT|CF_VNUMARG },

/* World Editing */
  { "wstat",      CmdWStat,    POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wgoto",      CmdWGoto,    POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wlist",      CmdWList,    POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wcreate",    CmdWCreate,  POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT },
  { "wcopy",      CmdWCopy,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wname",      CmdWName,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wdesc",      CmdWDesc,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wexit",      CmdWExit,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wedesc",     CmdWEDesc,   POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wekey",      CmdWEKey,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wekeyobj",   CmdWEKeyObj, POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "weflag",     CmdWEFlag,   POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wextra",     CmdWExtra,   POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wproperty",  CmdWProperty,POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wset",       CmdWSet,     POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wcompile",   CmdWCompile, POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wdecomp",    CmdWDecomp,  POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_WLD|CF_AREAEDIT|CF_VNUMARG },
  { "wsave",      CmdWSave,    POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_WLD|CF_AREAEDIT|CF_VNUMARG },

/* Mob Editing */
  { "mstat",      CmdMStat,    POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_MOB|CF_AREAEDIT|CF_VNUMARG },
  { "mlist",      CmdMList,    POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_MOB|CF_AREAEDIT|CF_VNUMARG },
  { "mcreate",    CmdMCreate,  POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_MOB|CF_AREAEDIT },
  { "mname",      CmdMName,    POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_MOB|CF_AREAEDIT|CF_VNUMARG },
  { "mkey",       CmdMKey,     POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_MOB|CF_AREAEDIT|CF_VNUMARG },
  { "mldesc",     CmdMLDesc,   POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_MOB|CF_AREAEDIT|CF_VNUMARG },
  { "mdesc",      CmdMDesc,    POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_MOB|CF_AREAEDIT|CF_VNUMARG },
  { "mextra",     CmdMExtra,   POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_MOB|CF_AREAEDIT|CF_VNUMARG },
  { "mproperty",  CmdMProperty,POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_MOB|CF_AREAEDIT|CF_VNUMARG },
  { "mset",       CmdMSet,     POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_MOB|CF_AREAEDIT|CF_VNUMARG },
  { "mcompile",   CmdMCompile, POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_MOB|CF_AREAEDIT|CF_VNUMARG },
  { "mdecomp",    CmdMDecomp,  POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_MOB|CF_AREAEDIT|CF_VNUMARG },
  { "mload",      CmdMLoad,    POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_MOB|CF_AREAEDIT },
  { "msave",      CmdMSave,    POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_MOB|CF_AREAEDIT|CF_VNUMARG },

/* Obj Editing */
  { "ostat",      CmdOStat,    POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
  { "olist",      CmdOList,    POS_DEAD,      LEVEL_GOD,    LOG_NEVER,  CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
  { "ocreate",    CmdOCreate,  POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
  { "oclear",     CmdOClear,   POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
  { "oname",      CmdOName,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
  { "okey",       CmdOKey,     POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
  { "oldesc",     CmdOLDesc,   POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
  { "odesc",      CmdODesc,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
  { "oextra",     CmdOExtra,   POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
  { "oproperty",  CmdOProperty,POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
  { "oset",       CmdOSet,     POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
/* - Called by OSet now... 
  { "osetfield",  CmdOSetField,POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_OBJ|CF_AREAEDIT },
*/
  { "ocompile",   CmdOCompile, POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
  { "odecomp",    CmdODecomp,  POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_OBJ|CF_AREAEDIT|CF_VNUMARG },
  { "oload",      CmdOLoad,    POS_DEAD,      LEVEL_GOD,    LOG_NORMAL, CF_OBJ|CF_AREAEDIT },
  { "osave",      CmdOSave,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_OBJ|CF_AREAEDIT|CF_VNUMARG },

/* Reset Editing */
  { "rshow",      CmdRShow,    POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_RST|CF_AREAEDIT },
  { "rcreate",    CmdRCreate,  POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_RST|CF_AREAEDIT },
  { "rset",       CmdRSet,     POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_RST|CF_AREAEDIT },
  { "rfirst",     CmdRFirst,   POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_RST|CF_AREAEDIT },
  { "rupdate",    CmdRUpdate,  POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_RST|CF_AREAEDIT },
  { "rhide",      CmdRHide,    POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_RST|CF_AREAEDIT },
  { "rsave",      CmdRSave,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_RST|CF_AREAEDIT },

/* HelpFile Editing */
  { "hlist",      CmdHList,    POS_DEAD,      1,            LOG_NEVER,  CF_HELPEDIT },
  { "hcreate",    CmdHCreate,  POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_HELPEDIT },
  { "hkey",       CmdHKey,     POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_HELPEDIT },
  { "hdesc",      CmdHDesc,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_HELPEDIT },
  { "hdelete",    CmdHDelete,  POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_HELPEDIT },
  { "hsave",      CmdHSave,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_HELPEDIT },

/* Board Editing */
  { "blist",      CmdBList,    POS_DEAD,      LEVEL_ADMIN,  LOG_NEVER,  CF_BRD },
  { "bcreate",    CmdBCreate,  POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_BRD },
  { "beditor",    CmdBEditor,  POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_BRD },
  { "bname",      CmdBName,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_BRD },
  { "bedit",      CmdBEdit,    POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_BRD },
  { "bwrite",     CmdBWrite,   POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_BRD },
  { "breply",     CmdBReply,   POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_BRD },
  { "berase",     CmdBErase,   POS_DEAD,      LEVEL_ADMIN,  LOG_NORMAL, CF_BRD },

/* MOLE support */
  { MOLE_HDR,     CmdMOLE,     POS_DEAD,      LEVEL_NEWBIE,  LOG_NEVER, CF_MISC },

/* And Finally... */
  { "quit",       CmdQuit,     POS_DEAD,      1,            LOG_NEVER,  CF_MISC     },

  { "",           NULL,        0,             0,            0,          0 }
};

LWORD PARSE_COMMAND_OSTAT;
LWORD PARSE_COMMAND_WGOTO;
LWORD PARSE_COMMAND_WCREATE;
LWORD PARSE_COMMAND_MSTAT;
LWORD PARSE_COMMAND_RCREATE;
LWORD PARSE_COMMAND_WEXIT;

void ParseInit(void) {
  PARSE_COMMAND_OSTAT   = TYPEFIND("ostat", commandList);
  PARSE_COMMAND_WGOTO   = TYPEFIND("wgoto", commandList);
  PARSE_COMMAND_WCREATE = TYPEFIND("wcreate", commandList);
  PARSE_COMMAND_MSTAT   = TYPEFIND("mstat", commandList);
  PARSE_COMMAND_RCREATE = TYPEFIND("rcreate", commandList);
  PARSE_COMMAND_WEXIT   = TYPEFIND("wexit", commandList);
}

/* find a word that means something to the interpreter */
BYTE *ParseGetWord(BYTE *cmd, BYTE *word) {
  LWORD i;
  BYTE *ignoreList[] = {
    "into",
    "in",
    "inside",
    "from"
    "of",
    "to",
    "the",
    "a",
    "an",
    "at",
    "",
  };

  /* find the first non-ignored word */
  do {
    cmd = StrOneWord(cmd, word); /* strip off one word */
    if (!*cmd) return cmd; /* return if there arent any more words */

    /* ignore the word if its ignorable */
    for(i=0; *ignoreList[i] && STRICMP(ignoreList[i], word); i++);
  } while(*ignoreList[i]);
  return cmd;
}

/* sets num in the event of 1, 2 etc
   sets offset in the event of 1st,2nd,3rd,4th etc
   will only change num if num was previously 0
   ditto for offset
   will return TRUE if there was a match of some kind
*/
BYTE ParseOffset(BYTE *word, LWORD *offset, LWORD *num) {
  LWORD i;
  LWORD sLen;

  /* well this cant possibly be right can it */
  if (!*word) return FALSE;

  /* this could be an offset ie as in get the 3rd bread */
  sLen = strlen(word);
  if (sLen >= 3) { /* otherwise cant be a offset specifier */
    if (!STRICMP(&word[sLen-2], "st") /* ie 1st */
      ||!STRICMP(&word[sLen-2], "nd") /* ie 2nd */
      ||!STRICMP(&word[sLen-2], "rd") /* ie 3rd */
      ||!STRICMP(&word[sLen-2], "th") /* ie 4th */
    ) {
      for (i=0; i<sLen-2 && isdigit(word[i]); i++);
      if (i==sLen-2) { /* all numeric digits */
        word[sLen-2] = '\0';
        if (offset && *offset==0) *offset = atol(word);
        return TRUE;
      }
    }
  }

  /* this could be a # ie as in get 3 bread */
  for (i=0; i<sLen && isdigit(word[i]); i++);
  if (i==sLen) { /* all numeric digits */
    if (num && *num==0) *num =  atol(word);
    return TRUE;
  }

  return FALSE;
}

/* sets offset to 0 for no match, or whatever they picked
   it will only change offset if offset was previously 0
   it will only change num if num was previously 0
   in the event of all.keyword, num will be set to TF_ALLMATCH(ie -1)
*/
BYTE *ParseEmbeddedOffset(BYTE *word, LWORD *offset, LWORD *num) {
  LWORD i;
  LWORD sLen;

  sLen = strlen(word);
  if (sLen < 3) {
    return word; /* cant be a offset specifier */
  }
  for (i=0; i<sLen && word[i]!='.'; i++);
  if (word[i] == '.') {
    word[i] = '\0';
    if (!STRICMP(word, "all")) {
      if(num && *num==0) *num = TF_ALLMATCH;
    } else {
      if(offset && *offset==0) *offset = atol(word);
    }
    return &word[i+1];
  }
  return word; /* cant be a offset specifier */
}

/* will give you everything you need to know, takes apart a line
   and looks for get 2.bread, get all.bread, drop the 4th bread etc etc
 */
BYTE *ParseFind(BYTE *cmd, BYTE *srcKey, LWORD *srcOffset, LWORD *srcNum, BYTE *dstKey, LWORD *dstOffset) {
  BYTE  word[256];
  BYTE *str;

  if (!srcKey || !srcOffset || !srcNum) return cmd;

  *srcKey    = '\0';
  *srcNum    = 0;
  *srcOffset = 0;

  /* find the first non-ignored word */
  cmd = ParseGetWord(cmd, word); /* get the first word */

  /* find a offset like 1st 2nd etc */
  while(ParseOffset(word, srcOffset, srcNum)) cmd=ParseGetWord(cmd, word);

  /* look for standard diku kind of offset & key */
  str = ParseEmbeddedOffset(word, srcOffset, srcNum);
  strcpy(srcKey, str);

  /* if something hasnt been chosen by now, fill in defaults */
  if (*srcNum==0) *srcNum = 1;
  if (!STRICMP(srcKey, "all")) {
    *srcNum = TF_ALLMATCH;
    if (!dstKey) {
      cmd = StrOneWord(cmd, NULL);
      if (*cmd) strcpy(srcKey, cmd);
    }
  }
  if (*srcOffset==0) *srcOffset = 1;

  /* Should we try to find dest key and offset? */
  if (!dstOffset || !dstKey) return cmd;

  *dstKey    = '\0';
  *dstOffset = 0;

  /* find a offset like 1st 2nd etc */
  while(ParseOffset(word, dstOffset, NULL)) cmd=ParseGetWord(cmd, word);

  /* look for standard diku kind of offset & key */
  cmd = ParseGetWord(cmd, word); /* get the next word */
  str = ParseEmbeddedOffset(word, dstOffset, NULL);
  if (dstKey) strcpy(dstKey, str);

  /* if something hasnt been chosen by now, fill in defaults */
  if (*dstOffset==0) *dstOffset = 1;

  return cmd;
}

BYTE ParseCommandCheck(LWORD i, SOCK *sock, BYTE *cmd) {
  BYTE buf[256];
  WORD numScan;
  WORD virtual;
  WORD area;

  /* guard against mobs */
  if (!sock) {
    if (commandList[i].cLevel >= LEVEL_GOD)
      return FALSE;
    else
      return TRUE;
  }

  /* level check */
  if (Character(sock->sHomeThing)->cLevel >= commandList[i].cLevel)
    return TRUE;

  /* special flags check, ie areaedit */
  if (BITANY(commandList[i].cFlag, CF_AREAEDIT)) {
    numScan = 0;
    if (BITANY(commandList[i].cFlag, CF_VNUMARG)) {
      cmd = StrOneWord(cmd, NULL); /* ignore command */
      StrOneWord(cmd, buf); /* get first arg */
      numScan = sscanf(buf, " %hd", &virtual);
    }
    if (numScan < 1) {
      if (Base(sock->sHomeThing)->bInside 
       && Base(sock->sHomeThing)->bInside->tType == TTYPE_WLD)
        virtual = Wld(Base(sock->sHomeThing)->bInside)->wVirtual;
      else
        virtual = -1;
    }
    if (virtual < 0) return FALSE;
    area = AreaOf(virtual);
    if (area < 0) return FALSE;
    if (AreaIsEditor(area,sock->sHomeThing)==2) {
      return TRUE;
    }
  }

  /* fallthru to here */
  return FALSE;
}

BYTE ParsePositionCheck(LWORD i, THING *thing) {
  if (Character(thing)->cPos >= commandList[i].cPos)
    return TRUE;

  switch (Character(thing)->cPos) {
  case POS_DEAD:
    SendThing("^wI'm afraid you're quite dead, so that's out of the question\n", thing);
    break;
  case POS_MORTAL:
    SendThing("^wRight at the moment it's all you can do to lie there and bleed\n", thing);
    break;
  case POS_INCAP:
    SendThing("^wTry again later, right now you're completely incapacitated\n", thing);
    break;
  case POS_STUNNED:
    SendThing("^wWhoa, maybe I'll wait for everything to stop spinning around me first\n", thing);
    break;
  case POS_SLEEPING:
    SendThing("^wWhat and ruin a perfectly good nap?\n", thing);
    break;
  case POS_RESTING:
    SendThing("^wBut its just so comfortable lying down right here\n", thing);
    break;
  case POS_SITTING:
    SendThing("^wPerchance it might be easier to do that if you werent sitting down\n", thing);
    break;
  case POS_FIGHTING:
    SendThing("^wConcentrating on your current battle might be a good idea...\n", thing);
    break;
  default:
    SendThing("^wAlas and alack, that command is not within your powers\n", thing);
  }
  return FALSE;
}

LWORD ParseCommand(THING *thing, BYTE *cmd) {
  LWORD     i;
  BYTE     *word;
  BYTE      wordBuf[256];
  BYTE      buf[256];
  SOCK     *sock;
  BASELINK *link;

  word = wordBuf;
  StrOneWord(cmd, word);
  if (!*cmd)
    return FALSE;
  sock = BaseControlFind(thing);

  if (sock) {
    /* Translate 'message to say message for Realmers */
    if (sock && cmd[0] == '\'') {
      QInsert(sock->sIn, "\n");
      QInsert(sock->sIn, cmd+1);
      QInsert(sock->sIn, "say ");
      return TRUE;
    }
    /* Translate 'message to say message for Realmers */
    if (sock && cmd[0] == ':') {
      QInsert(sock->sIn, "\n");
      QInsert(sock->sIn, cmd+1);
      QInsert(sock->sIn, "emote ");
      return TRUE;
    }
    /* Expand aliases */
    if (AliasParse(sock, cmd)) return TRUE;
  }

  /* to prevent aliases from recursing when we do something like
   * alias wake = wake; stand - it embeds ##ALIAS in front
   * that way we'll get past Alias parse above without
   * expanding the internal wake command infinitely
   */
  if (!strncmp(word, ALIAS_COMMAND_STR, strlen(ALIAS_COMMAND_STR))) {
    word = &(word[strlen(ALIAS_COMMAND_STR)]);
  }

  /* Tell us what they did if we are snooping */
  if (strncmp(MOLE_HDR, cmd, strlen(MOLE_HDR))) {
    if (Base(thing)->bInside->tType==TTYPE_WLD) {
      if (!BIT(Wld(Base(thing)->bInside)->wFlag,WF_PRIVATE)) {
        for (link = Base(thing)->bLink; link; link=link->lNext) {
          if (link->lType == BL_TELEPATHY_SND) {
            SEND("^w%", BaseControlFind(link->lDetail.lThing));
            SEND(cmd, BaseControlFind(link->lDetail.lThing));
            SEND("\n", BaseControlFind(link->lDetail.lThing));
          }
        }
      }
    }
  }

  i = TYPEFIND(word, commandList);
  if (i!=-1 && commandList[i].cProc) { /* well, well, well, this *IS* a valid command, whaddya know */

    /* Choke if they are too weeny */
    if (!ParseCommandCheck(i, sock, cmd)){
      if (sock)
        SEND("^wAlas and alack, that command is not within your powers\n", sock);
      return FALSE;
    }

    /* make sure they are not sleeping etc */
    if (!ParsePositionCheck(i, thing)){
      return FALSE;
    }

    if (sock) {
      /* Log Player if its an interesting command and log flag set */
      if( (commandList[i].cLog == LOG_ALLWAYS)
        ||( (BIT(Plr(sock->sHomeThing)->pSystem, PS_LOG))
          &&(commandList[i].cLog == LOG_NORMAL) )
        ) {
        LogStr(sock->sHomeThing->tSDesc->sText, cmd);
        LogStrPrintf(sock->sHomeThing->tSDesc->sText, "\n");
      }
    }

    /* Log area editing to area channel */
    if( (commandList[i].cLog >= LOG_NORMAL)
      &&(BIT(commandList[i].cFlag, CF_AREAEDIT)) ) {
      Log(LOG_AREA, sock->sHomeThing->tSDesc->sText);
      if (Base(thing)->bInside && Base(thing)->bInside->tType == TTYPE_WLD) {
        sprintf(buf, " [%ld]", Wld(Base(thing)->bInside)->wVirtual);
        LogPrintf(LOG_AREA, buf);
      }
      LogPrintf(LOG_AREA, ": ");
      LogPrintf(LOG_AREA, cmd);
      LogPrintf(LOG_AREA, "\n");
    }

    /* Log god commands to god channel */
    if( (commandList[i].cLog >= LOG_NORMAL)
      &&(BIT(commandList[i].cFlag, CF_GOD)) ) {
      Log(LOG_GOD, sock->sHomeThing->tSDesc->sText);
      LogPrintf(LOG_GOD, ": ");
      LogPrintf(LOG_GOD, cmd);
      LogPrintf(LOG_GOD, "\n");
    }

    /* Guess the command is valid */
    (*commandList[i].cProc)(thing, cmd);
    return TRUE;

  } else { /* return that we did zip... */
    /* Socials - yes/no/maybe they did one , ditto for help */
    if (sock && !SocialParse(thing, cmd) && !HelpParse(thing, cmd, NULL)) {
      SEND("I'm sure you meant something by that, the question is what...\n", sock);
    }
    return FALSE;
  }
}


void ParseSock(SOCK *sock, BYTE *cmd) {
  LWORD  i;
  LWORD  j;
  LWORD  count;
  BYTE   buf[256];
  BYTE   newCmd[256];
  BYTE  *next;
  LWORD  headingSent = FALSE;

  struct cmdListType {
    BYTE *cType;
    FLAG  cFlag;
  };

  struct cmdListType cmdList[] = {
    { "*Movement*"         , CF_MOVE     },
    { "*Combat*"           , CF_CBT      },
    { "*Inventory*"        , CF_INV      },
    { "*Communication*"    , CF_TALK     },
    { "*Miscellaneous*"    , CF_MISC     },
    { "*God-Commands*"     , CF_GOD      },
    { "*Help-Editing*"     , CF_HELPEDIT },
    { "*Area-Editing*"     , CF_AREA     },
    { "*World-Editing*"    , CF_WLD      },
    { "*Mobile-Editing*"   , CF_MOB      },
    { "*Object-Editing*"   , CF_OBJ      },
    { "*Reset-Editing*"    , CF_RST      },
    { "*Board-Editing*"    , CF_BRD      },
    { "*C4-Coding*"        , CF_C4CODING },
    { ""                   , 0           }
  };

  /* Any action at all will prevent their Char from Idling */
  Plr(sock->sHomeThing)->pIdleTick = 0;
  if (Plr(sock->sHomeThing)->pIdleRoom) {
    ThingTo(sock->sHomeThing, Plr(sock->sHomeThing)->pIdleRoom);
    Plr(sock->sHomeThing)->pIdleRoom = NULL;
    SendAction("$n rejoins you from the void\n",
      sock->sHomeThing, NULL, SEND_ROOM|SEND_VISIBLE|SEND_AUDIBLE|SEND_CAPFIRST);
  }

  /* history stuff - whew! (capture input commands in text buffer) */
  if (HistoryParse(&sock->sHistory, sock, cmd)) return;

  if (*cmd && !strcmp(cmd, HistoryGetLast(&sock->sHistory))) {
    sock->sLastRepeat++;
  } else {
    sock->sLastRepeat = 0;
  }

  if (strncmp(MOLE_HDR, cmd, strlen(MOLE_HDR))) 
    HistoryAdd(&sock->sHistory, cmd);

  /* get one word from the command */
  next = StrOneWord(cmd, buf);

  /******************************************************
   * command listing - intercept default help
   ******************************************************/
    
  if (StrAbbrev("?",buf) || StrAbbrev("help",buf)) {

    /******************************************************
     * check to see if they want a listing of command categories 
     ******************************************************/
    
    if (!*next) { /* give 'em the list of help topics */
      SEND("^yYou have access to commands belonging to the following categories:\n", sock);

      /* put "? <virtual#>" into newCmd so we can see if areaEditing is authorized */
      if (Base(sock->sHomeThing)->bInside->tType == TTYPE_WLD)
        sprintf(newCmd, "? %ld", Wld(Base(sock->sHomeThing)->bInside)->wVirtual);
      else
        sprintf(newCmd, "? -1");

      /* init counter */
      i=0;
      while (cmdList[i].cType[0]) {
        j=0;
        while (commandList[j].cText[0]) {
          if (BITANY(commandList[j].cFlag, cmdList[i].cFlag)
              && ParseCommandCheck(j,sock,newCmd)) {
            SEND("^G<^g", sock);
            SEND(cmdList[i].cType, sock);
            SEND("^G>\n", sock);
            break;
          }
          j++;
        }
        i++;
      }
      SEND("\n^yTo list commands in a given category, Try ^whelp <category>\n", sock);
      SEND("^ye.g. ^whelp *move\n", sock);
      return;
    }
    
    /******************************************************
     * check to see if they want help on a specific topic 
     ******************************************************/
    
    i = TYPEFIND(next, cmdList);
    if (i>=0) {
      SEND("^pYou can have access to the following ^w", sock);
      SEND(cmdList[i].cType, sock);
      SEND("^p commands\n", sock);

      /* put "? <virtual#>" into newCmd so we can see if areaEditing is authorized */
      if (Base(sock->sHomeThing)->bInside->tType == TTYPE_WLD)
        sprintf(newCmd, "? %ld", Wld(Base(sock->sHomeThing)->bInside)->wVirtual);
      else
        sprintf(newCmd, "? -1");

      /* init counter */
      headingSent = FALSE;
      count=0; j=0;
      while (commandList[j].cText[0]) {
        if (BITANY(commandList[j].cFlag, cmdList[i].cFlag)
            && ParseCommandCheck(j,sock,newCmd)) {
          if (!headingSent) {
            if (i>0)
              SEND("\n", sock);
            SEND("^G<^g", sock);
            SEND(cmdList[i].cType, sock);
            SEND("^G>\n", sock);
            headingSent = TRUE;
          }
          if (count%3 == 2)
            sprintf(buf, "^c%-25s\n", commandList[j].cText);
          else
            sprintf(buf, "^c%-25s", commandList[j].cText);
          SEND(buf, sock);
          count++;
        }
        j++;
      }
      if (headingSent && count%3)
        SEND("\n", sock);
      return;
    }
  }

  /* cant hurt */
  if (!sock->sControlThing) return;

  ParseCommandStub(sock->sControlThing, cmd);
}

LWORD ParseCommandStub(THING *event, BYTE *cmd) { 
  LWORD  processed = FALSE;
  THING *code;
  THING *inside;
  THING *newInside;

  inside = newInside = Base(event)->bInside;
  ThingSetEvent(event);

  /* Let attached code properties have first crack at it */
  if ((CodeParseCommand(event, inside, cmd))) {
    processed = TRUE;
  } else {
    for (code = inside->tContain; code; code=code->tNext) 
      BITSET(code->tFlag, TF_CODETHING);
    while( (code = ThingFindFlag(inside->tContain, TF_CODETHING)) ) {
      BITCLR(code->tFlag, TF_CODETHING);
      if (event && !ThingIsEvent(event)) event = NULL;
      if (event) { /* if they've been turfed, nothing to do */
        if ((CodeParseCommand(event, code, cmd))) {
          processed = TRUE;
          break;
        }
      }
    }
  }
  /* Check Area Event */
  if (!processed && inside->tType == TTYPE_WLD) {
    if (event && !ThingIsEvent(event)) event = NULL;
    if (event) { /* if they've been turfed, nothing to do */
      if (CodeParseCommand(event, &areaList[Wld(inside)->wArea].aResetThing, cmd))
        processed = TRUE;
    }
  }

  /* Commands */
  if (!processed) {
    if (event && !ThingIsEvent(event)) event = NULL;
    if (event) processed = ParseCommand(event, cmd);
  }
    
  /* Let after code properties execute */
  if (event && !ThingIsEvent(event)) event = NULL;
  if (event) CodeParseAfterCommand(event, inside, cmd);

  if (inside) {
    for (code = inside->tContain; code; code=code->tNext) 
      BITSET(code->tFlag, TF_CODETHING);
    while( (code = ThingFindFlag(inside->tContain, TF_CODETHING)) ) {
      BITCLR(code->tFlag, TF_CODETHING);
      if (event && !ThingIsEvent(event)) event = NULL;
      if (event) CodeParseAfterCommand(event, code, cmd);
    }
  }
  /* Check area-wide script */
  if (event && !ThingIsEvent(event)) event = NULL;
  if (event && inside->tType == TTYPE_WLD)
    CodeParseAfterCommand(event, &areaList[Wld(inside)->wArea].aResetThing, cmd);

  /* Clean up */
  ThingDeleteEvent(event);

  return processed;
}