/
Sapphire/bin/
Sapphire/db/
Sapphire/db/OLC_rooms/
Sapphire/db/abi/
Sapphire/db/em_src/
Sapphire/db/helps/
Sapphire/db/helps/emman/ifunc/
Sapphire/db/npcs/Tatt/
Sapphire/db/objects/Tatt/
Sapphire/db/q_data/
Sapphire/db/rooms/Tatt/
Sapphire/doc/
Sapphire/doc/em/
Sapphire/etc/
Sapphire/src/abic/
Sapphire/src/areacon/
Sapphire/src/client/
Sapphire/src/embc/
Sapphire/src/emi/
Sapphire/src/emi/test/
Sapphire/src/include/
Sapphire/src/sapphire/em/
Sapphire/src/tcon/
/*
 * Copyright (C) 1995-1997 Christopher D. Granz
 *
 * This header may not be removed.
 *
 * Refer to the file "License" included in this package for further
 * information and before using any of the following.
 */

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

#include "sapphire.h"
#include "emerald.h"


/*
 * Structures
 */
typedef struct _em_game_cmd
{
    struct _em_game_cmd *                                         pNext;
    short int                                                    siFunc;
    char *                                                         pCmd;
    int                                                          iLevel;
    intt                                                      iPosition;
    intt                                                          iMode;
    STRUCT_BOOL                                           ( bNoPrefix );
} em_game_cmd;


/*
 * Prototypes
 */

#define RID                                              ROOM_INDEX_DATA
#define CD                                                     CHAR_DATA

static int       format_exits                         ( RID *, char * );
static char *    char_pos_str                            ( CD *, CD * );

#undef RID
#undef CD


/*
 * Globals
 */
static em_game_cmd *                                        pEmGameCmds;

extern EM_VALUE *                                                pStack;
extern EM_VALUE *                                             pStackEnd;
extern EM_VALUE *                                       pInterpStackPos;
extern EM_VALUE *                                        pVarStackBegin;
extern EM_VALUE *                                          pVarStackPos;


/*
 * Functions
 */

/*
 * Processes a command for a character (pChar.)
 */
void process_cmd( CHAR_DATA *pChar, char *pArg )
{
    EM_VALUE v;
    CHAR_DATA *pChar2;
    em_game_cmd *pEmCmd;
    char cCommand[MAX_INPUT];
    int i;

    if ( pChar == NULL || next_char( pArg ) == '\0' )
        return;

    if ( pChar->pTerm != NULL && pChar->pTerm->pControlled != NULL )
        pChar2      = pChar->pTerm->pChar;
    else
        pChar2      = pChar;

    if ( !IS_NPC( pChar ) && pChar->iWaitTimer > 0 )
    {
        send_string( pChar, "You cannot do that right now.\n\r" );
        return;
    }

    if ( !isalpha( pArg[0] ) && pArg[0] != '$' )
    {
        cCommand[0] = pArg[0];
        cCommand[1] = '\0';
        pArg++;

        while ( *pArg == ' ' )
            pArg++;
    }
    else
        pArg    = one_arg( pArg, cCommand );

    /*
     * Cut off any trailing whitespace.
     */
    for ( i = ( strlen( pArg ) - 1 ); i >= 0 && isspace( pArg[i] ); i-- )
        pArg[i] = '\0';

    for ( i = 0; cCmdTable[i].pName[0] != '\0'; i++ )
    {
        if ( LOWER( cCommand[0] ) == LOWER( cCmdTable[i].pName[0] )
          && str_prefix( cCommand, cCmdTable[i].pName ) == TRUE
          && cCmdTable[i].iLevel <= pChar2->iLevel
          && ( cCmdTable[i].iMode == iMode
          || cCmdTable[i].iMode == MODE_ALL ) )
        {
            if ( cCmdTable[i].iPosition > pChar->iPosition )
                goto badpos;

            if ( cCmdTable[i].bNoPrefix == TRUE )
            {
                if ( str_compare( cCommand, cCmdTable[i].pName ) != TRUE )
                    continue;
            }

            ( *cCmdTable[i].pCmdFunc ) ( pChar, pArg );
            return;
        }
    }

    if ( cCommand[0] == '$' )
    {
        for ( i = 0; cSysCmdTable[i].pName[0] != '\0'; i++ )
        {
            if ( LOWER( cCommand[1] ) == LOWER( cSysCmdTable[i].pName[0] )
              && str_prefix( &cCommand[1], cSysCmdTable[i].pName ) == TRUE
              && cSysCmdTable[i].iLevel <= pChar2->iLevel
              && ( cSysCmdTable[i].iMode == iMode
              || cSysCmdTable[i].iMode == MODE_ALL ) )
            {
                if ( cSysCmdTable[i].bNoPrefix == TRUE )
                {
                    if ( str_compare( &cCommand[1],
                      cSysCmdTable[i].pName ) != TRUE )
                        continue;
                }

                ( *cSysCmdTable[i].pCmdFunc ) ( pChar, pArg );
                return;
            }
        }

        send_string( pChar, "Unknown system command.\n\r" );
        return;
    }

    for ( pEmCmd = pEmGameCmds; pEmCmd != NULL; pEmCmd = pEmCmd->pNext )
    {
        if ( pEmCmd->iPosition > pChar2->iPosition )
            goto badpos;

        if ( LOWER( cCommand[0] ) == LOWER( pEmCmd->pCmd[0] )
          && str_prefix( cCommand, pEmCmd->pCmd ) == TRUE
          && pChar2->iLevel >= pEmCmd->iLevel
          && ( pEmCmd->iMode == iMode
          || pEmCmd->iMode == MODE_ALL ) )
        {
            if ( pEmCmd->bNoPrefix == TRUE )
            {
                if ( str_compare( cCommand, pEmCmd->pCmd ) != TRUE )
                    continue;
            }

            stack_init( );
            v.iType                  = TYPE_OBJECT;
            init_value( &v );
            v.u.pObject->iObjectType = OBJ_TYPE_CHAR;
            v.u.pObject->pRealObject = pChar;
            interp_stack_push( &v );
            v.iType                  = TYPE_STRING;
            init_value( &v );
            v.u.pString->pString     = str_dup( pArg );
            interp_stack_push( &v );
            em_call_func( pEmCmd->siFunc );
            stack_free( );
            return;
        }
    }

    send_string( pChar, "I do not understand.\n\r" );
    return;

badpos:
    switch ( pChar->iPosition )
    {
      case NUMBER_POSITION_DYING   :
          send_string( pChar, "You best not try that right now.\n\r" );
          break;

      case NUMBER_POSITION_SLEEPING:
          send_string( pChar, "You dream about it.\n\r" );
          break;

      case NUMBER_POSITION_RESTING :
          send_string( pChar,
            "It is a bit hard to doing that while resting.\n\r" );
          break;

      case NUMBER_POSITION_SITTING :
          send_string( pChar, "You should stand up first.\n\r" );
          break;

      case NUMBER_POSITION_STANDING:
          send_string( pChar, "You cannot do that at the moment.\n\r" );
          break;
#ifdef DEBUG
      default                      :
          wcdebug( "Bad character position." );
          break;
#endif
    }
}


/*
 * Function called from emerald.
 */
void _iadd_game_cmd( void )
{
    em_game_cmd *pEmCmd;
    EM_VALUE v;
    char *pParam2;
    long lParam1;
    long lParam3;
    long lParam4;
    long lParam5;
    long lParam6;

    em_get_values( 6, TYPE_INT, &lParam1, TYPE_STRING, &pParam2,
      TYPE_INT, &lParam3, TYPE_INT, &lParam4, TYPE_INT, &lParam5,
      TYPE_INT, &lParam6 );
    v.iType           = TYPE_INT;

    if ( lParam1 < 0 || lParam1 > siTopFuncIndex || pParam2[0] == '\0' )
    {
        v.u.lInt      = 0;
        goto end;
    }

    v.u.lInt          = 1;

    if ( lParam4 != MODE_ALL && lParam4 != MODE_GENERIC
      && lParam4 != MODE_RPG )
        lParam4       = MODE_ALL;

    if ( lParam5 < 0 || lParam5 > MAX_LEVEL )
        lParam5       = 0;

    if ( lParam6 < NUMBER_POSITION_DYING
      || lParam6 > NUMBER_POSITION_STANDING )
        lParam6       = 0;

    pEmCmd            = alloc_mem( sizeof( *pEmCmd ) );
    pEmCmd->siFunc    = lParam1;
    pEmCmd->pCmd      = str_dup( pParam2 );
    pEmCmd->bNoPrefix = ( lParam3 > 0 ? TRUE : FALSE );
    pEmCmd->iMode     = lParam4;
    pEmCmd->iLevel    = lParam5;
    pEmCmd->iPosition = lParam6;
    pEmCmd->pNext     = pEmGameCmds;
    pEmGameCmds       = pEmCmd;

end:
    interp_stack_push( &v );
}


void cmd_north( CHAR_DATA *pChar, char *pArgument )
{
    move_char( pChar, 0 );
}


void cmd_south( CHAR_DATA *pChar, char *pArgument )
{
    move_char( pChar, 1 );
}


void cmd_east( CHAR_DATA *pChar, char *pArgument )
{
    move_char( pChar, 2 );
}


void cmd_west( CHAR_DATA *pChar, char *pArgument )
{
    move_char( pChar, 3 );
}


void cmd_up( CHAR_DATA *pChar, char *pArgument )
{
    move_char( pChar, 4 );
}


void cmd_down( CHAR_DATA *pChar, char *pArgument )
{
    move_char( pChar, 5 );
}


void cmd_northeast( CHAR_DATA *pChar, char *pArgument )
{
    move_char( pChar, 6 );
}


void cmd_southwest( CHAR_DATA *pChar, char *pArgument )
{
    move_char( pChar, 7 );
}


void cmd_northwest( CHAR_DATA *pChar, char *pArgument )
{
    move_char( pChar, 8 );
}


void cmd_southeast( CHAR_DATA *pChar, char *pArgument )
{
    move_char( pChar, 9 );
}


void move_char( CHAR_DATA *pChar, int iDir )
{
    ROOM_INDEX_DATA *pRoom = pChar->pInRoom;

#ifdef DEBUG
    if ( pRoom == NULL )
    {
        wcdebug( "Character not in room." );
        char_to_room( pChar, uDefaultRoom.pRoom );
        pRoom              = pChar->pInRoom;
    }
#endif

    if ( pChar->iPosition != NUMBER_POSITION_STANDING )
    {
        send_string( pChar, "You are not standing.\n\r" );
        return;
    }

    if ( pRoom->eExits[iDir].uRoom.pRoom == NULL
      || IS_SET( pRoom->eExits[iDir].fCurrFlags, FLAG_DOOR_HIDDEN ) )
    {
        send_string( pChar, "Alas, you can not go that way.\n\r" );
        return;
    }

    if ( pRoom->eExits[iDir].iExitType == NUMBER_EXIT_DOOR )
    {
        if ( IS_SET( pRoom->eExits[iDir].fCurrFlags, FLAG_DOOR_CLOSED ) )
        {
            send_string( pChar, "The %s is closed.\n\r",
              pRoom->eExits[iDir].pDoorNames[0] );
            return;
        }
    }

    switch ( iDir )
    {
      case 0:
          send_game_message( "~c leaves north.", MESSAGE_DEST_ROOM, TRUE,
            pChar, NULL, pRoom, TRUE, NUMBER_POSITION_RESTING, pChar );
          char_from_room( pChar );
          char_to_room( pChar, pRoom->eExits[iDir].uRoom.pRoom );
          send_game_message( "~h arrives from the south.",
            MESSAGE_DEST_ROOM, TRUE, pChar, NULL, pChar->pInRoom, TRUE,
            NUMBER_POSITION_RESTING, pChar );
          break;

      case 1:
          send_game_message( "~c leaves south.", MESSAGE_DEST_ROOM, TRUE,
            pChar, NULL, pRoom, TRUE, NUMBER_POSITION_RESTING, pChar );
          char_from_room( pChar );
          char_to_room( pChar, pRoom->eExits[iDir].uRoom.pRoom );
          send_game_message( "~h arrives from the north.",
            MESSAGE_DEST_ROOM, TRUE, pChar, NULL, pChar->pInRoom, TRUE,
            NUMBER_POSITION_RESTING, pChar );
          break;

      case 2:
          send_game_message( "~c leaves east.", MESSAGE_DEST_ROOM, TRUE,
            pChar, NULL, pRoom, TRUE, NUMBER_POSITION_RESTING, pChar );
          char_from_room( pChar );
          char_to_room( pChar, pRoom->eExits[iDir].uRoom.pRoom );
          send_game_message( "~h arrives from the west.",
            MESSAGE_DEST_ROOM, TRUE, pChar, NULL, pChar->pInRoom, TRUE,
            NUMBER_POSITION_RESTING, pChar );
          break;

      case 3:
          send_game_message( "~c leaves west.", MESSAGE_DEST_ROOM, TRUE,
            pChar, NULL, pRoom, TRUE, NUMBER_POSITION_RESTING, pChar );
          char_from_room( pChar );
          char_to_room( pChar, pRoom->eExits[iDir].uRoom.pRoom );
          send_game_message( "~h arrives from the east.",
            MESSAGE_DEST_ROOM, TRUE, pChar, NULL, pChar->pInRoom, TRUE,
            NUMBER_POSITION_RESTING, pChar );
          break;

      case 4:
          send_game_message( "~c leaves up.", MESSAGE_DEST_ROOM, TRUE,
            pChar, NULL, pRoom, TRUE, NUMBER_POSITION_RESTING, pChar );
          char_from_room( pChar );
          char_to_room( pChar, pRoom->eExits[iDir].uRoom.pRoom );
          send_game_message( "~h arrives from below.", MESSAGE_DEST_ROOM,
            TRUE, pChar, NULL, pChar->pInRoom, TRUE,
            NUMBER_POSITION_RESTING, pChar );
          break;

      case 5:
          send_game_message( "~c leaves down.", MESSAGE_DEST_ROOM, TRUE,
            pChar, NULL, pRoom, TRUE, NUMBER_POSITION_RESTING, pChar );
          char_from_room( pChar );
          char_to_room( pChar, pRoom->eExits[iDir].uRoom.pRoom );
          send_game_message( "~h arrives from above.", MESSAGE_DEST_ROOM,
            TRUE, pChar, NULL, pChar->pInRoom, TRUE,
            NUMBER_POSITION_RESTING, pChar );
          break;

      case 6:
          send_game_message( "~c leaves northeast.", MESSAGE_DEST_ROOM,
            TRUE, pChar, NULL, pRoom, TRUE, NUMBER_POSITION_RESTING,
            pChar );
          char_from_room( pChar );
          char_to_room( pChar, pRoom->eExits[iDir].uRoom.pRoom );
          send_game_message( "~h arrives from the southwest.",
            MESSAGE_DEST_ROOM, TRUE, pChar, NULL, pChar->pInRoom, TRUE,
            NUMBER_POSITION_RESTING, pChar );
          break;

      case 7:
          send_game_message( "~c leaves southwest.", MESSAGE_DEST_ROOM,
            TRUE, pChar, NULL, pRoom, TRUE, NUMBER_POSITION_RESTING,
            pChar );
          char_from_room( pChar );
          char_to_room( pChar, pRoom->eExits[iDir].uRoom.pRoom );
          send_game_message( "~h arrives from the northeast.",
            MESSAGE_DEST_ROOM, TRUE, pChar, NULL, pChar->pInRoom, TRUE,
            NUMBER_POSITION_RESTING, pChar );
          break;

      case 8:
          send_game_message( "~c leaves northwest.", MESSAGE_DEST_ROOM,
            TRUE, pChar, NULL, pRoom, TRUE, NUMBER_POSITION_RESTING,
            pChar );
          char_from_room( pChar );
          char_to_room( pChar, pRoom->eExits[iDir].uRoom.pRoom );
          send_game_message( "~h arrives from the southeast.",
            MESSAGE_DEST_ROOM, TRUE, pChar, NULL, pChar->pInRoom, TRUE,
            NUMBER_POSITION_RESTING, pChar );
          break;

      case 9:
          send_game_message( "~c leaves southeast.", MESSAGE_DEST_ROOM,
            TRUE, pChar, NULL, pRoom, TRUE, NUMBER_POSITION_RESTING,
            pChar );
          char_from_room( pChar );
          char_to_room( pChar, pRoom->eExits[iDir].uRoom.pRoom );
          send_game_message( "~h arrives from the northwest.",
            MESSAGE_DEST_ROOM, TRUE, pChar, NULL, pChar->pInRoom, TRUE,
            NUMBER_POSITION_RESTING, pChar );
          break;
    }

    cmd_look( pChar, "" );
}


void cmd_credits( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar, COPYRIGHT_NOTICE );
}


void cmd_help( CHAR_DATA *pChar, char *pArgument )
{
    HELP_DATA *pHelp;

    if ( pChar->pTerm == NULL )
        return;

    if ( pArgument[0] == '\0' )
    {
        send_string( pChar, "What would you like to know about?\n\r" );
        return;
    }

    for ( pHelp = pHelpList; pHelp != NULL; pHelp = pHelp->pNext )
    {
        if ( pChar->iLevel >= pHelp->iLevel
          && multi_compare_2( pArgument, pHelp->pKeywords ) == TRUE )
            break;
    }

    if ( pHelp == NULL )
    {
        send_string( pChar,
          "I do not have any information on that subject.\n\r" );
        return;
    }

    setup_string_pager( pChar->pTerm );
    page_string( pChar->pTerm, pHelp->sText );
    page_string( pChar->pTerm, "\n\r" );
    finish_string_pager( pChar->pTerm );
}


void cmd_quit( CHAR_DATA *pChar, char *pArgument )
{
    TERM_DATA *pTerm = pChar->pTerm;

    if ( IS_NPC( pChar ) )
    {
        send_string( pChar,
          "NPCs may only leave this world by being killed.\n\r" );
        return;
    }

    if ( !IS_GUEST( pChar ) )
        cmd_save( pChar, "" );

    send_game_message( "~c slowly fades out of this world.",
      MESSAGE_DEST_ROOM, TRUE, pChar, NULL, pChar->pInRoom, TRUE,
      NUMBER_POSITION_RESTING, pChar );
    send_string( pChar, pGoodbye );
    lprintf( "%s has left the game.", pChar->pPCData->sName );
    free_char( &pChar );

    if ( pTerm != NULL )
    {
        pTerm->pChar = NULL;
        close_connection( &pTerm );
    }
}


void cmd_who( CHAR_DATA *pChar, char *pArgument )
{
    TERM_DATA *pTerm;
    char cBuf[128];
    int i;

    if ( pChar->pTerm == NULL )
        return;

    for ( i = 0, pTerm = pTermList; pTerm != NULL; pTerm = pTerm->pNext )
    {
        if ( pTerm->pChar != NULL && !IS_GUEST( pTerm->pChar ) )
            i++;
    }

    if ( i == 0 )
    {
        send_string( pChar, "There are no players at the moment.\n\r" );
        return;
    }

    setup_string_pager( pChar->pTerm );
    page_string( pChar->pTerm, "_____ Players _____\n\r\n\r" );

    for ( i = 0, pTerm = pTermList; pTerm != NULL; pTerm = pTerm->pNext )
    {
        if ( pTerm->pChar != NULL
          && ( pTerm->iConState == CON_PLAYING
          || pTerm->iConState == CON_NPC_EDITOR
          || pTerm->iConState == CON_OBJECT_EDITOR
          || pTerm->iConState == CON_ROOM_EDITOR )
          && !IS_GUEST( pTerm->pChar ) )
        {
            snprintf( cBuf, 128, "[%3d] %-36s\n\r", pTerm->pChar->iLevel,
              pTerm->pChar->pPCData->sName );
            page_string( pChar->pTerm, cBuf );
            i++;
        }
    }

    if ( i > 1 )
    {
        sprintf( cBuf, "\n\rThere are currently %d players.\n\r", i );
        page_string( pChar->pTerm, cBuf );
    }
    else if ( i == 1 )
        page_string( pChar->pTerm,
          "\n\rThere is only 1 player at the moment.\n\r" );

    finish_string_pager( pChar->pTerm );
}


void cmd_rwho( CHAR_DATA *pChar, char *pArgument )
{
    MUD_COMM_DATA *pMUDComm;
    GENERIC_DATA *pGen;
    short s;
    byte b;

    if ( pChar->pTerm == NULL )
        return;

    if ( pArgument[0] == '\0' )
    {
        send_string( pChar, "Usage: rwho <MUD name>\n\r" );
        return;
    }

    for ( pMUDComm = pMUDCommList; pMUDComm; pMUDComm = pMUDComm->pNext )
    {
        if ( pMUDComm->iConState == MUD_COMM_CON_READY
          && str_compare( pMUDComm->pMUDName, pArgument ) == TRUE )
            break;
    }

    if ( pMUDComm == NULL )
    {
        send_string( pChar, "No such MUD connected.\n\r" );
        return;
    }

    pGen                    = alloc_mem( sizeof( *pGen ) );
    pGen->pData             = pChar->pTerm;

    pGen->pNext             = pMUDComm->pWaitList;
    pMUDComm->pWaitList     = pGen;

    b                       = MUD_COMM_CMD_WHO;
    s                       = 0;
    write_mudcomm_data_buffer( pMUDComm, &b, 1 );
    write_mudcomm_data_buffer( pMUDComm, (byte *) &s, sizeof( s ) );

    send_string( pChar, "Request sent to %s, waiting for reply.\n\r",
      pMUDComm->pMUDName );
}


void cmd_muds( CHAR_DATA *pChar, char *pArgument )
{
    MUD_COMM_DATA *pMUDComm;
    char cBuf[128];
    int i = 0;

    if ( pChar->pTerm == NULL )
        return;

    for ( pMUDComm = pMUDCommList; pMUDComm; pMUDComm = pMUDComm->pNext )
    {
        if ( pMUDComm->iConState == MUD_COMM_CON_READY )
            i++;
    }

    if ( i == 0 )
    {
        send_string( pChar,
          "There are no connected MUDs at the moment.\n\r" );
        return;
    }

    setup_string_pager( pChar->pTerm );
    page_string( pChar->pTerm, "_____ Connected MUDs _____\n\r\n\r" );

    for ( pMUDComm = pMUDCommList; pMUDComm; pMUDComm = pMUDComm->pNext )
    {
        if ( pMUDComm->iConState == MUD_COMM_CON_READY )
        {
            snprintf( cBuf, 128, "%-36s\n\r", pMUDComm->pMUDName );
            page_string( pChar->pTerm, cBuf );
        }
    }

    finish_string_pager( pChar->pTerm );
}


void cmd_save( CHAR_DATA *pChar, char *pArgument )
{
    if ( IS_NPC( pChar ) )
    {
        send_string( pChar, "NPCs have no need to save.\n\r" );
        return;
    }

    if ( IS_GUEST( pChar ) )
    {
        send_string( pChar, "Guests cannot save.\n\r" );
        return;
    }

    save_pc( pChar );
    send_string( pChar, "%s saved.\n\r", pChar->pPCData->sName );
}


void cmd_look( CHAR_DATA *pChar, char *pArgument )
{
    ROOM_INDEX_DATA *pRoom   = pChar->pInRoom;
    CHAR_DATA *pCharBuf;
    OBJ_DATA *pObj;
    char cBuf[MAX_STRING];
    int iDir                 = -1;
    int i;

    if ( pChar->pTerm == NULL )
        return;

    pArgument                = one_arg( pArgument, cBuf );

#ifdef DEBUG
    if ( pRoom == NULL )
    {
        wcdebug( "Character not in room." );
        char_to_room( pChar, uDefaultRoom.pRoom );
        pRoom                = pChar->pInRoom;
    }
#endif

    if ( has_light( pChar ) == FALSE )
    {
        send_string( pChar, "Darkness surrounds you.\n\r" );
        goto end;
    }

    if ( cBuf[0] != '\0' )
    {
        for ( i = 0; snDirTable[i].pName[0] != '\0'; i++ )
        {
            if ( str_prefix( cBuf, snDirTable[i].pName ) == TRUE )
            {
                iDir         = snDirTable[i].iNumber;
                break;
            }
        }
    }

    if ( iDir > -1 )
    {
        if ( pRoom->sDirDescs[iDir][0] == '\0' )
            send_string( pChar, "You see nothing particularly "
              "interesting in that direction.\n\r" );
        else
            send_string( pChar, "%s\n\r", pRoom->sDirDescs[iDir] );

        if ( pRoom->eExits[iDir].uRoom.pRoom
          && pRoom->eExits[iDir].iExitType == NUMBER_EXIT_DOOR
          && !IS_SET( pRoom->eExits[iDir].fCurrFlags, FLAG_DOOR_HIDDEN ) )
            send_string( pChar, "The %s is %s.\n\r",
              pRoom->eExits[iDir].pDoorNames[0],
              ( IS_SET( pRoom->eExits[iDir].fCurrFlags, FLAG_DOOR_CLOSED )
              ? "closed" : "open" ) );

        return;
    }

    send_string( pChar, "%s\n\r", pRoom->sTitle );
    send_string( pChar, "  %s\n\r", pRoom->sDesc );

    clear_binary_transfer( pChar->pTerm );
    write_file( pChar->pTerm, get_file_type( pRoom->sImageFilename ),
      pRoom->sImageFilename );

    if ( ( i = format_exits( pRoom, cBuf ) ) > 5 )
        send_string( pChar, "%s\n\r", format_string( cBuf ) );
    else if ( i > 0 )
        send_string( pChar, "%s\n\r", cBuf );

end:
    for ( pCharBuf = pRoom->pPeople; pCharBuf != NULL;
      pCharBuf = pCharBuf->pNextInRoom )
    {
        if ( pCharBuf != pChar
          && visable_char( pCharBuf, pChar ) == TRUE )
            send_string( pChar, "%s\n\r",
              char_pos_str( pCharBuf, pChar ) );
    }

    for ( pObj = pRoom->pContents; pObj; pObj = pObj->pNextContent )
    {
        if ( visable_object( pObj, pChar ) == TRUE )
            send_string( pChar, "%s\n\r", pObj->sDesc );
    }
}


void cmd_read( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_write( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_search( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


/*
 * Shows all un-hidden, un-closed, normal exits.
 */
void cmd_exits( CHAR_DATA *pChar, char *pArgument )
{
    char cBuf[MAX_STRING];
#ifdef DEBUG
    if ( pChar->pInRoom == NULL )
    {
        wcdebug( "Character not in room." );
        char_to_room( pChar, uDefaultRoom.pRoom );
    }
#endif
    if ( format_exits( pChar->pInRoom, cBuf ) > 5 )
        send_string( pChar, "%s\n\r", format_string( cBuf ) );
    else
        send_string( pChar, "%s\n\r", cBuf );
}


/*
 * Creates a human readable, formated string from all the exits in a
 * room (pRoom.) 
 */
static int format_exits( ROOM_INDEX_DATA *pRoom, char *pOutBuf )
{
    char cBuf[MAX_STRING]    = "";
    int i, iCount;

    for ( iCount = 0, i = 0; i < 10; i++ )
    {
        if ( pRoom->eExits[i].uRoom.pRoom != NULL )
        {
            if ( pRoom->eExits[i].iExitType == NUMBER_EXIT_DOOR
              && IS_SET( pRoom->eExits[i].fCurrFlags, FLAG_DOOR_CLOSED ) )
                continue;

            strcat( cBuf, uncapit( snDirTable[i].pName ) );
            strcat( cBuf, ", " );
            iCount++;
        }
    }

    cBuf[strlen( cBuf ) - 2] = '\0';

    if ( iCount == 0 )
        strcpy( pOutBuf, "You see no exits here." );
    else if ( iCount == 1 )
        sprintf( pOutBuf, "There is an exit %s.", cBuf );
    else
    {
        char *pBuf           = strrchr( cBuf, ',' );

        *pBuf                = ' ';
        memmove( &pBuf[4], ( pBuf + 1 ), strlen( pBuf ) );
        memcpy( &pBuf[1], "and", 3 );
        sprintf( pOutBuf, "There are exits %s.", cBuf ); 
    }

    return ( iCount );
}


/*
 * Examines a character's (pChar) position and create a formated string
 * out of it.
 */
static char *char_pos_str( CHAR_DATA *pChar, CHAR_DATA *pLooker )
{
    char *pOutput = new_buffer( );

    switch ( pChar->iPosition )
    {
        case NUMBER_POSITION_DYING   :
            if ( IS_NPC( pChar ) )
                return ( pChar->pNPCData->sDescs[0] );
            else
            {
                if ( knows_char( pLooker, pChar ) == TRUE )
                    sprintf( pOutput,
                      "%s is here, lying in a pool of blood.",
                      pChar->pPCData->sName );
                else
                    sprintf( pOutput,
                      "%s is here, lying in a pool of blood.",
                      capit( get_race_string_2( pChar->iRace ) ) );
            }

            break;

        case NUMBER_POSITION_SLEEPING:
            if ( IS_NPC( pChar ) )
                return ( pChar->pNPCData->sDescs[1] );
            else
            {
                if ( knows_char( pLooker, pChar ) == TRUE )
                    sprintf( pOutput,
                      "%s is sleeping here.",
                      pChar->pPCData->sName );
                else
                    sprintf( pOutput,
                      "%s is sleeping here.",
                      capit( get_race_string_2( pChar->iRace ) ) );
            }

            break;

        case NUMBER_POSITION_RESTING :
            if ( IS_NPC( pChar ) )
                return ( pChar->pNPCData->sDescs[2] );
            else
            {
                if ( knows_char( pLooker, pChar ) == TRUE )
                    sprintf( pOutput,
                      "%s is resting here.",
                      pChar->pPCData->sName );
                else
                    sprintf( pOutput,
                      "%s is resting here.",
                      capit( get_race_string_2( pChar->iRace ) ) );
            }

            break;

        case NUMBER_POSITION_SITTING :
            if ( IS_NPC( pChar ) )
                return ( pChar->pNPCData->sDescs[3] );
            else
            {
                if ( knows_char( pLooker, pChar ) == TRUE )
                    sprintf( pOutput,
                      "%s is sitting here.",
                      pChar->pPCData->sName );
                else
                    sprintf( pOutput,
                      "%s is sitting here.",
                      capit( get_race_string_2( pChar->iRace ) ) );
            }

            break;

        case NUMBER_POSITION_STANDING:
            if ( IS_NPC( pChar ) )
                return ( pChar->pNPCData->sDescs[4] );
            else
            {
                if ( knows_char( pLooker, pChar ) == TRUE )
                    sprintf( pOutput,
                      "%s is standing here.",
                      pChar->pPCData->sName );
                else
                    sprintf( pOutput,
                      "%s is standing here.",
                      capit( get_race_string_2( pChar->iRace ) ) );
            }

            break;

#ifdef DEBUG
        default            :
            wcdebug( "Unkown character position." );
            strcpy( pOutput,
              "An unknown creature is here, in an unknown position." );
            pChar->iPosition = NUMBER_POSITION_STANDING;
            break;
#endif
    }

    pOutput[0]               = UPPER( pOutput[0] );
    return ( pOutput );
}


void cmd_emote( CHAR_DATA *pChar, char *pArgument )
{
    if ( pArgument[0] == '\0' )
    {
        send_string( pChar, "What do you wish to emote?\n\r" );
        return;
    }

    send_game_message( "* ~c $s", MESSAGE_DEST_CHAR, pChar,
      NUMBER_POSITION_RESTING, pChar, pArgument );
    send_game_message( "* ~c $s", MESSAGE_DEST_ROOM, FALSE, pChar, NULL, 
      pChar->pInRoom, FALSE, NUMBER_POSITION_RESTING, pChar, pArgument );

    check_char_trigger( NUMBER_NPC_TRIGGER_EMOTE, pChar, pChar->pInRoom,
      NULL, pArgument );
}


void cmd_say( CHAR_DATA *pChar, char *pArgument )
{
#ifdef DEBUG
    if ( pChar->pInRoom == NULL )
    {
        wcdebug( "Character not in room." );
        char_to_room( pChar, uDefaultRoom.pRoom );
    }
#endif

    if ( pArgument[0] == '\0' )
    {
        send_string( pChar, "What do you wish to say?\n\r" );
        return;
    }

    send_string( pChar, "You say, `%s'\n\r", pArgument );
    send_game_message( "~c says, `$s'", MESSAGE_DEST_ROOM, FALSE, pChar,
      NULL, pChar->pInRoom, FALSE, NUMBER_POSITION_RESTING, pChar,
      pArgument );

    check_char_trigger( NUMBER_NPC_TRIGGER_SAY, pChar, pChar->pInRoom,
      NULL, pArgument );
    check_room_trigger( NUMBER_ROOM_TRIGGER_SAY, pChar, pChar->pInRoom,
      pArgument );
}


void cmd_tell( CHAR_DATA *pChar, char *pArgument )
{
    ROOM_INDEX_DATA *pRoom = pChar->pInRoom;
    CHAR_DATA *pToChar;
    char cArg[MAX_INPUT];
    bool bKnowsChar        = FALSE;

#ifdef DEBUG
    if ( pRoom == NULL )
    {
        wcdebug( "Character not in room." );
        char_to_room( pChar, uDefaultRoom.pRoom );
        pRoom = pChar->pInRoom;
    }
#endif

    pArgument = one_arg( pArgument, cArg );

    if ( cArg[0] == '\0' || pArgument[0] == '\0' )
    {
        send_string( pChar, "Tell whom what?\n\r" );
        return;
    }

    for ( pToChar = pRoom->pPeople; pToChar != NULL;
      pToChar = pToChar->pNextInRoom )
    {
        if ( ( bKnowsChar = knows_char( pChar, pToChar ) ) == TRUE )
        {
            if ( IS_NPC( pToChar ) )
            {
                if ( multi_compare_2( cArg, pToChar->pNPCData->pNameList )
                  == TRUE )
                    break;
            }
            else
            {
                if ( multi_compare( cArg, pToChar->pPCData->sName )
                  == TRUE )
                    break;
            }
        }
        else
        {
            if ( str_compare( cArg, get_race_string( pToChar->iRace ) )
              == TRUE )
                break;
        }
    }

    if ( pToChar == NULL )
    {
        send_string( pChar, "That person is not here.\n\r" );
        return;
    }

    if ( pToChar == pChar )
    {
        send_game_message( "You tell yourself, `$s'", MESSAGE_DEST_CHAR,
          pChar, NUMBER_POSITION_RESTING, pArgument );
        send_game_message( "~c tells ~xself something.",
          MESSAGE_DEST_ROOM, FALSE, pChar, NULL, pRoom, FALSE,
          NUMBER_POSITION_RESTING, pChar, pChar );
        return;
    }

    send_game_message( "You tell ~c, `$s'", MESSAGE_DEST_CHAR, pChar,
      NUMBER_POSITION_RESTING, pToChar, pArgument );
    send_game_message( "~c tells you, `$s'", MESSAGE_DEST_VICTOM, FALSE,
      pChar, pToChar, NUMBER_POSITION_RESTING, pChar, pArgument );
    send_game_message( "~c tells ~c something.", MESSAGE_DEST_ROOM, TRUE,
      pChar, pToChar, pRoom, FALSE, NUMBER_POSITION_RESTING, pChar,
      pToChar );

    check_char_trigger( NUMBER_NPC_TRIGGER_TELL, pChar, NULL, pToChar,
      pArgument );
}


void cmd_yell( CHAR_DATA *pChar, char *pArgument )
{
    if ( pArgument[0] == '\0' )
    {
        send_string( pChar, "What do you wish to yell?\n\r" );
        return;
    }

    send_string( pChar, "You yell, `%s'\n\r", pArgument );
    send_game_message( "~c yells, `$s'", MESSAGE_DEST_ROOM, FALSE, pChar,
      NULL, pChar->pInRoom, FALSE, NUMBER_POSITION_RESTING, pChar,
      pArgument );

    check_char_trigger( NUMBER_NPC_TRIGGER_YELL, pChar, pChar->pInRoom,
      NULL, pArgument );
    check_room_trigger( NUMBER_ROOM_TRIGGER_YELL, pChar, pChar->pInRoom,
      pArgument );
}


void cmd_get( CHAR_DATA *pChar, char *pArgument )
{
    ROOM_INDEX_DATA *pRoom   = pChar->pInRoom;
    OBJ_DATA *pObj;
    char cBuf[MAX_INPUT];

#ifdef DEBUG
    if ( pChar->pInRoom == NULL )
    {
        wcdebug( "Character not in room." );
        char_to_room( pChar, uDefaultRoom.pRoom );
        pRoom                = pChar->pInRoom;
    }
#endif

    if ( IS_GUEST( pChar ) )
    {
        send_string( pChar,
          "It is not polite for guests to pick things up.\n\r" );
        return;
    }

    one_arg( pArgument, cBuf );

    if ( cBuf[0] == '\0' )
    {
        send_string( pChar, "What do you wish to get?\n\r" );
        return;
    }

    for ( pObj = pRoom->pContents; pObj; pObj = pObj->pNextContent )
    {
        if ( visable_object( pObj, pChar ) == TRUE
          && multi_compare_2( cBuf, pObj->pNameList ) == TRUE )
            break;
    }

    if ( pObj == NULL )
    {
        send_string( pChar, "You do not see that here.\n\r" );
        return;
    }

    if ( ( carry_weight( pChar ) + pObj->iWeight ) > pChar->iMaxCarry )
    {
        send_string( pChar, "You cannot carry that much weight.\n\r" );
        return;
    }

    if ( pObj->iSize >= NUMBER_SIZE_LARGE )
    {
        send_string( pChar, "That is too large for you to carry.\n\r" );
        return;
    }

    send_game_message( "You get ~b.", MESSAGE_DEST_CHAR, pChar,
      NUMBER_POSITION_RESTING, pObj );
    send_game_message( "~c gets ~o.", MESSAGE_DEST_ROOM, TRUE, pChar, NULL,
      pChar->pInRoom, FALSE, NUMBER_POSITION_RESTING, pChar, pObj );
    obj_from_room( pObj );

    if ( pObj->pReset != NULL )
    {
        pObj->pReset->bAlive = FALSE;
        pObj->pReset         = NULL;
    }

    obj_to_char( pObj, pChar );
    pChar->iWeight          += pObj->iWeight;
}


void cmd_put( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_drop( CHAR_DATA *pChar, char *pArgument )
{
    ROOM_INDEX_DATA *pRoom = pChar->pInRoom;
    OBJ_DATA *pObj;
    char cBuf[MAX_INPUT];

#ifdef DEBUG
    if ( pChar->pInRoom == NULL )
    {
        wcdebug( "Character not in room." );
        char_to_room( pChar, uDefaultRoom.pRoom );
        pRoom              = pChar->pInRoom;
    }
#endif

    one_arg( pArgument, cBuf );

    if ( cBuf[0] == '\0' )
    {
        send_string( pChar, "What do you wish to drop?\n\r" );
        return;
    }

    for ( pObj = pChar->pInven; pObj; pObj = pObj->pNextContent )
    {
        if ( multi_compare_2( cBuf, pObj->pNameList ) == TRUE
          && visable_object( pObj, pChar ) == TRUE )
            break;
    }

    if ( pObj == NULL )
    {
        send_string( pChar, "You do not have that item.\n\r" );
        return;
    }

    send_game_message( "You drop ~b.", MESSAGE_DEST_CHAR, pChar,
      NUMBER_POSITION_RESTING, pObj );
    send_game_message( "~c drops ~o.", MESSAGE_DEST_ROOM, TRUE, pChar,
      NULL, pChar->pInRoom, FALSE, NUMBER_POSITION_RESTING, pChar, pObj );
    obj_from_char( pObj );
    pObj->iWearLoc      = 0;
    pChar->iWeight     -= pObj->iWeight;
    obj_to_room( pObj, pRoom );
}


void cmd_give( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_equip( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_use( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_lock( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_unlock( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_light( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_kill( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_flee( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_stand( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_sit( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_rest( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_sleep( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_wake( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_practice( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_follow( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_add( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_remove( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_introduce( CHAR_DATA *pChar, char *pArgument )
{
    ROOM_INDEX_DATA *pRoom = pChar->pInRoom;
    CHAR_DATA *pToChar;
    char cArg[MAX_INPUT];
    bool bKnowsChar        = FALSE;

#ifdef DEBUG
    if ( pRoom == NULL )
    {
        wcdebug( "Character not in room." );
        char_to_room( pChar, uDefaultRoom.pRoom );
        pRoom = pChar->pInRoom;
    }
#endif

    if ( IS_NPC( pChar ) )
    {
        send_string( pChar,
          "That person already knows who YOU are.\n\r" );
        return;
    }

    pArgument = one_arg( pArgument, cArg );

    if ( cArg[0] == '\0' )
    {
        send_string( pChar,
          "Who would you like to introduce yourself to?\n\r" );
        return;
    }

    for ( pToChar = pRoom->pPeople; pToChar != NULL;
      pToChar = pToChar->pNextInRoom )
    {
        if ( ( bKnowsChar = knows_char( pChar, pToChar ) ) == TRUE )
        {
            if ( IS_NPC( pToChar ) )
            {
                if ( multi_compare_2( cArg, pToChar->pNPCData->pNameList )
                  == TRUE )
                    break;
            }
            else
            {
                if ( multi_compare( cArg, pToChar->pPCData->sName )
                  == TRUE )
                    break;
            }
        }
        else
        {
            if ( str_compare( cArg, get_race_string( pToChar->iRace ) )
              == TRUE )
                break;
        }
    }

    if ( pToChar == NULL )
    {
        send_string( pChar, "That person is not here.\n\r" );
        return;
    }

    if ( pToChar == pChar )
    {
        send_game_message( "You introduce yourself, to yourself.",
          MESSAGE_DEST_CHAR, pChar, NUMBER_POSITION_RESTING );
        send_game_message( "~c introduces ~xself to ~xself.",
          MESSAGE_DEST_ROOM, TRUE, pChar, NULL, pRoom, FALSE,
          NUMBER_POSITION_RESTING, pChar, pChar, pChar );
        return;
    }

    if ( knows_char( pToChar, pChar ) == TRUE )
    {
        send_string( pChar,
          "That person already knows who you are.\n\r" );
        return;
    }

    send_game_message( "You introduce yourself to ~c.",
      MESSAGE_DEST_CHAR, pChar, NUMBER_POSITION_RESTING, pToChar );
    send_game_message( "~c introduces ~xself to you as $s.",
      MESSAGE_DEST_VICTOM, TRUE, pChar, pToChar, NUMBER_POSITION_RESTING,
      pChar, pChar, cap_first( pChar->pPCData->sName ) );
    send_game_message( "~c introduces ~xself to ~c.", MESSAGE_DEST_ROOM,
      TRUE, pChar, pToChar, pRoom, FALSE, NUMBER_POSITION_RESTING, pChar,
      pChar, pToChar );

    introduce_char( pToChar, pChar );
}


void cmd_inventory( CHAR_DATA *pChar, char *pArgument )
{
    OBJ_DATA *pObj;
    char cBuf[MAX_STRING];
    bool bFound    = FALSE;

    if ( pChar->pTerm == NULL )
        return;

    setup_string_pager( pChar->pTerm );
    page_string( pChar->pTerm, "You are carrying:\n\r" );

    for ( pObj = pChar->pInven; pObj; pObj = pObj->pNextContent )
    {
        if ( visable_object( pObj, pChar ) == TRUE
          && pObj->iWearLoc == 0 )
        {
            sprintf( cBuf, "  %s%s\n\r", ( IS_SET( pObj->fObjFlags,
              FLAG_OBJECT_SPECIAL ) ? "" : "a " ), pObj->sShortDesc );
            page_string( pChar->pTerm, cBuf );
            bFound = TRUE;
        }
    }

    if ( bFound != TRUE )
        page_string( pChar->pTerm, "  Nothing.\n\r" );

    finish_string_pager( pChar->pTerm );
}


void cmd_equipment( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_condition( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_compare( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_consider( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_open( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_close( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_eat( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_drink( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_fill( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_empty( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_list( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_buy( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_sell( CHAR_DATA *pChar, char *pArgument )
{
    send_string( pChar,
      "Sorry, this command is not ready for use yet.\n\r" );
}


void cmd_commands( CHAR_DATA *pChar, char *pArgument )
{
    TERM_DATA *pTerm;
    em_game_cmd *pEmCmd;
    char cBuf[128];
    char **ppTable;
    int iTableSize = 0;
    int iCount;
    int i, iPos;
    bool b         = FALSE;

    if ( ( pTerm = pChar->pTerm ) == NULL )
        return;

    if ( pTerm->pControlled != NULL )
        pChar = pTerm->pChar;

    for ( i = 0; cSysCmdTable[i].pName[0] != '\0'; i++ )
    {
        if ( isalpha( cSysCmdTable[i].pName[0] )
          && pChar->iLevel >= cSysCmdTable[i].iLevel
          && ( cSysCmdTable[i].iMode == iMode
          || cSysCmdTable[i].iMode == MODE_ALL ) )
            iTableSize++;
    }

    for ( i = 0; cCmdTable[i].pName[0] != '\0'; i++ )
    {
        if ( isalpha( cCmdTable[i].pName[0] )
          && pChar->iLevel >= cCmdTable[i].iLevel
          && ( cCmdTable[i].iMode == iMode
          || cCmdTable[i].iMode == MODE_ALL ) )
            iTableSize++;
    }

    for ( pEmCmd = pEmGameCmds; pEmCmd != NULL; pEmCmd = pEmCmd->pNext )
    {
        if ( isalpha( pEmCmd->pCmd[0] )
          && pChar->iLevel >= pEmCmd->iLevel
          && ( pEmCmd->iMode == iMode || pEmCmd->iMode == MODE_ALL ) )
            iTableSize++;
    }

    TEMP_ALLOC( ppTable, ( sizeof( char * ) * iTableSize ) );

    for ( i = 0, iPos = 0; cSysCmdTable[i].pName[0] != '\0'; i++ )
    {
        if ( isalpha( cSysCmdTable[i].pName[0] )
          && pChar->iLevel >= cSysCmdTable[i].iLevel
          && ( cSysCmdTable[i].iMode == iMode
          || cSysCmdTable[i].iMode == MODE_ALL ) )
        {
            TEMP_ALLOC( ppTable[iPos],
              ( strlen( cSysCmdTable[i].pName ) + 2 ) );
            ppTable[iPos][0] = '$';
            strcpy( &ppTable[iPos++][1], cSysCmdTable[i].pName );
        }
    }

    for ( i = 0; cCmdTable[i].pName[0] != '\0'; i++ )
    {
        if ( isalpha( cCmdTable[i].pName[0] )
          && pChar->iLevel >= cCmdTable[i].iLevel
          && ( cCmdTable[i].iMode == iMode
          || cCmdTable[i].iMode == MODE_ALL ) )
        {
            TEMP_ALLOC( ppTable[iPos],
              ( strlen( cCmdTable[i].pName ) + 1 ) );
            strcpy( ppTable[iPos++], cCmdTable[i].pName );
        }
    }

    for ( pEmCmd = pEmGameCmds; pEmCmd != NULL; pEmCmd = pEmCmd->pNext )
    {
        if ( isalpha( pEmCmd->pCmd[0] )
          && pChar->iLevel >= pEmCmd->iLevel
          && ( pEmCmd->iMode == iMode || pEmCmd->iMode == MODE_ALL ) )
        {
            TEMP_ALLOC( ppTable[iPos],
              ( strlen( pEmCmd->pCmd ) + 1 ) );
            strcpy( ppTable[iPos++], pEmCmd->pCmd );
        }
    }

    asort( ppTable, iTableSize );
    setup_string_pager( pTerm );

    page_string( pTerm, "System commands:\n\r             " );
    iCount         = 1;

    for ( i = 0; i < iTableSize; i++ )
    {
        if ( b != TRUE && ppTable[i][0] != '$' )
        {
            b      = TRUE;
            page_string( pTerm,
              "\n\r\n\rGame commands:\n\r             " );
            iCount = 1;
        }

        sprintf( cBuf, "%-12.12s ", ppTable[i] );
        page_string( pTerm, cBuf );
        iCount++;

        if ( iCount == 6 )
        {
            page_string( pTerm, "\n\r" );
            iCount = 0;
        }
    }

    if ( iCount > 0 )
        page_string( pTerm, "\n\r" );

    finish_string_pager( pTerm );
}


/*
 * Changes a characters prompt.
 */
void cmd_prompt( CHAR_DATA *pChar, char *pArgument )
{
    CHAR_DATA *pChar2;

    if ( pChar->pTerm != NULL && pChar->pTerm->pControlled != NULL )
        pChar2 = pChar->pTerm->pChar;
    else
        pChar2 = pChar;

    if ( IS_NPC( pChar2 ) )
    {
        send_string( pChar, "NPCs do not need prompts.\n\r" );
        return;
    }

    free_string( &pChar2->pPCData->sPrompt );

    if ( pArgument[0] == '\0' )
        pChar2->pPCData->sPrompt = save_string( ">" );
    else
        pChar2->pPCData->sPrompt = save_string( pArgument );

    send_string( pChar, "Prompt string set.\n\r" );
}


/*
 * End of std_cmd.c
 */