/
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.
 */

/*
 * This code seemed to get really "fat" after I started working on it
 * seriously.  I just hope this code doesn't bog down the server too
 * much...
 */

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

#include "sapphire.h"


/*
 * Prototypes
 */

#define GD                                                  GENERIC_DATA
#define CD                                                     CHAR_DATA
#define QVD                                               QUEST_VAR_DATA

static char *    shrink_str                                  ( char * );
static QVD *     get_var      ( char *, GD *, QVD *, intt, void *, CD *,
                                                                 CD * );
static QVD *     parse_expr   ( char *, intt, GD *, QVD *, intt, void *,
                                                           CD *, CD * );
static char *    _parse_expr                                 ( char * );
static char *    get_next_arg                           ( char *, int );

#undef GD
#undef CD
#undef QVD


/*
 * Globals
 */

/*
 * We use global variables when parsing because we have lots of
 * recursive calls and it's easier to use global variables rather then
 * passing them down each level ... It's also a slight bit faster :)
 */
static GENERIC_DATA *                                      pTempGenList;
static QUEST_VAR_DATA *                                   pQuestVarList;
static intt                                                  iThisType_;
static void *                                                    pThis_;
static CHAR_DATA *                                              pActor_;
static CHAR_DATA *                                              pThird_;
static QUEST_VAR_DATA                                          qvResult;
static intt                                                 iForcedType;
static intt                                                  iExprError;
/* Gotta be careful with these ... */
static char                                           cGBuf[MAX_STRING];
static char                                          cGBuf2[MAX_STRING];


/*
 * Functions
 */
long npc_script_translate( SCRIPT_DATA *pScript, char *pStr )
{
    char cBuf[MAX_STRING];
    char cBuf2[MAX_STRING];
    char *pStrPos   = pStr;
    char *pBuf2;
    byte *pBuf      = alloc_mem( ( strlen( pStr ) + 1 ) );
    long l, l2;

    for ( l = 0; *pStrPos != '\0'; pStrPos = remove_char_2( pStrPos ) )
    {
        pStrPos     = edit_str( pStrPos, cBuf, ' ', ";(\n\r\t " );

        if ( *pStrPos == '\0' )
            break;

        if ( strcmp( cBuf, "if" ) == 0 )
        {
            if ( next_char( pStrPos ) != '(' )
            {
                l   = -3;
                goto end;
            }

            pStrPos = edit_str_plus( pStrPos, cBuf, '(', ')' );

            if ( next_char( pStrPos ) != ')' )
            {
                l   = -4;
                goto end;
            }

            pStrPos   = remove_char_2( pStrPos );
            pBuf[l++] = NUMBER_NPC_COMMAND_IF;
            pBuf2     = shrink_str( cBuf );

            for ( l2 = 0; ( pBuf2[l2] != '=' || ( pBuf2[l2 + 1] != '\0'
              && pBuf2[l2 + 1] != '=' ) ) && pBuf2[l2] != '!'
              && pBuf2[l2] != '>' && pBuf2[l2] != '<'
              && pBuf2[l2] != '\0'; )
                pBuf[l++]       = pBuf2[l2++];

            pBuf[l++]           = '\0';

            switch ( pBuf2[l2] )
            {
              case '=' :
                  if ( pBuf2[++l2] != '=' )
                  {
                      l         = -5;
                      goto end;
                  }

                  pBuf[l++]     = NUMBER_SCRIPT_CMP_EQUAL;
                  l2++;
                  break;

              case '!' :
                  if ( pBuf2[++l2] != '=' )
                  {
                      l         = -6;
                      goto end;
                  }

                  pBuf[l++]     = NUMBER_SCRIPT_CMP_NOT_EQUAL;
                  l2++;
                  break;

              case '>' :
                  if ( pBuf2[++l2] != '=' )
                      pBuf[l++] = NUMBER_SCRIPT_CMP_GREATER;
                  else
                  {
                      pBuf[l++] = NUMBER_SCRIPT_CMP_GREATER_EQUAL;
                      l2++;
                  }

                  break;

              case '<' :
                  if ( pBuf2[++l2] != '=' )
                      pBuf[l++] = NUMBER_SCRIPT_CMP_LESS;
                  else
                  {
                      pBuf[l++] = NUMBER_SCRIPT_CMP_LESS_EQUAL;
                      l2++;
                  }

                  break;

              default  :
                  l             = -7;
                  goto end;
            }

            while ( pBuf2[l2] != '\0' )
                pBuf[l++] = pBuf2[l2++];

            pBuf[l++]     = '\0';

            if ( next_char( pStrPos ) != '{' )
            {
                pStrPos = edit_str( pStrPos, cBuf, ' ', ";" );

                if ( next_char( pStrPos ) != ';' )
                {
                    l   = -9;
                    goto end;
                }

                if ( ( ( l2 = strlen( cBuf ) ) + 1 ) < MAX_STRING )
                {
                    cBuf[l2]     = ';';
                    cBuf[l2 + 1] = '\0';
                }
            }
            else
            {
                pStrPos = edit_str_plus( pStrPos, cBuf, '{', '}' );

                if ( next_char( pStrPos ) != '}' )
                {
                    l   = -9;
                    goto end;
                }
            }

            l2      = ( npc_script_translate( pScript, cBuf ) - 1 );

            if ( l2 < 0 )
            {
                l   = ( l2 + 1 );
                goto end;
            }

            *( (intl *) &pBuf[l] ) = ( l2 + sizeof( intl ) + 2 );
            l      += ( sizeof( intl ) + 1 );

            memcpy( &pBuf[l], cBuf, l2 );
            l      += l2;

            pBuf2   = remove_char_2( pStrPos );
            pBuf2   = edit_str( pBuf2, cBuf, ' ', "{;\n\r\t " );

            if ( strcmp( cBuf, "else" ) == 0 )
            {
                pStrPos     = pBuf2;

                if ( next_char( pStrPos ) != '{' )
                {
                    pStrPos = edit_str( pStrPos, cBuf, ' ', ";" );

                    if ( next_char( pStrPos ) != ';' )
                    {
                        l   = -9;
                        goto end;
                    }

                    if ( ( ( l2 = strlen( cBuf ) ) + 1 ) < MAX_STRING )
                    {
                        cBuf[l2]     = ';';
                        cBuf[l2 + 1] = '\0';
                    }
                }
                else
                {
                    pStrPos = edit_str_plus( pStrPos, cBuf, '{', '}' );

                    if ( next_char( pStrPos ) != '}' )
                    {
                        l   = -9;
                        goto end;
                    }
                }

                l2          = ( npc_script_translate( pScript, cBuf )
                              - 1 );

                if ( l2 < 0 )
                {
                    l       = ( l2 + 1 );
                    goto end;
                }

                pBuf[l++]              = NUMBER_NPC_COMMAND_GOTO;
                *( (intl *) &pBuf[l] ) = l2;
                l          += ( sizeof( intl ) + 1 );

                memcpy( &pBuf[l], cBuf, l2 );
                l          += l2;
            }
            else
            {
                pBuf[l++]              = NUMBER_NPC_COMMAND_GOTO;
                *( (intl *) &pBuf[l] ) = 0;
                l          += ( sizeof( intl ) + 1 );
            }

            continue;
        }
        else if ( next_char( pStrPos ) == '=' )
        {
            pBuf[l++]   = NUMBER_NPC_COMMAND_SET;
            pBuf2       = shrink_str( cBuf );

            for ( l2 = 0; pBuf2[l2] != '\0'; l2++, l++ )
                pBuf[l] = pBuf2[l2];

            pBuf[l++]   = '\0';

            pStrPos     = edit_str( pStrPos, cBuf, '=', ";" );

            if ( *pStrPos != ';' )
            {
                l       = -10;
                goto end;
            }

            pBuf2       = shrink_str( cBuf );

            for ( l2 = 0; pBuf2[l2] != '\0'; l2++, l++ )
                pBuf[l] = pBuf2[l2];

            pBuf[l++]   = '\0';

            continue;
        }

        for ( l2 = 0; snNPCScriptCommandTable[l2].pName[0] != '\0'; l2++ )
        {
            if ( str_compare( cBuf, snNPCScriptCommandTable[l2].pName )
              == TRUE )
                break;
        }

        if ( snNPCScriptCommandTable[l2].pName[0] == '\0' )
        {
            l       = -11;
            goto end;
        }

        pBuf[l++]   = snNPCScriptCommandTable[l2].iNumber;

        if ( next_char( pStrPos ) != '(' )
        {
            l       = -12;
            goto end;
        }

        pStrPos     = edit_str_plus( pStrPos, cBuf, '(', ')' );

        if ( *pStrPos != ')' )
        {
            l       = -13;
            goto end;
        }

        pStrPos     = remove_char_2( pStrPos );

        if ( *pStrPos != ';' )
        {
            l       = -14;
            goto end;
        }

        pBuf2       = shrink_str( cBuf );

        switch ( snNPCScriptCommandTable[l2].iNumber )
        {
          case NUMBER_NPC_COMMAND_END      :
              break;

          case NUMBER_NPC_COMMAND_WAIT     :
              *( (ints *) &pBuf[l] ) = atoi( pBuf2 );
              l                     += ( sizeof( ints ) + 1 );
              break;

          case NUMBER_NPC_COMMAND_SET      :
              pBuf2       = edit_str( pBuf2, cBuf2, ' ', ",\n\r\t " );

              if ( next_char( pBuf2 ) != ',' )
              {
                  l       = -15;
                  goto end;
              }

              pBuf2       = remove_char_2( pBuf2 );

              for ( l2 = 0; cBuf2[l2] != '\0'; l2++, l++ )
                  pBuf[l] = cBuf2[l2];

              pBuf[l++]   = '\0';
              goto copy_all;

          default                          :
copy_all:
              for ( l2 = 0; pBuf2[l2] != '\0'; l2++, l++ )
                  pBuf[l] = pBuf2[l2];

              pBuf[l++]   = '\0';
              break;
        }
    }

    pBuf[l++]       = NUMBER_NPC_COMMAND_END;
    memcpy( pStr, pBuf, l );

end:
    free_mem( (void **) &pBuf );
    return ( l );
}


long obj_script_translate( SCRIPT_DATA *pScript, char *pStr )
{
    return ( strlen( pStr ) + 1 );
}


long room_script_translate( SCRIPT_DATA *pScript, char *pStr )
{
    char cBuf[MAX_STRING];
    char cBuf2[MAX_STRING];
    char *pStrPos   = pStr;
    char *pBuf2;
    byte *pBuf      = alloc_mem( ( strlen( pStr ) + 1 ) );
    long l, l2;

    for ( l = 0; *pStrPos != '\0'; pStrPos = remove_char_2( pStrPos ) )
    {
        pStrPos     = edit_str( pStrPos, cBuf, ' ', ";(\n\r\t " );

        if ( *pStrPos == '\0' )
            break;

        if ( strcmp( cBuf, "if" ) == 0 )
        {
            if ( next_char( pStrPos ) != '(' )
            {
                l   = -3;
                goto end;
            }

            pStrPos = edit_str_plus( pStrPos, cBuf, '(', ')' );

            if ( next_char( pStrPos ) != ')' )
            {
                l   = -4;
                goto end;
            }

            pStrPos   = remove_char_2( pStrPos );
            pBuf[l++] = NUMBER_ROOM_COMMAND_IF;
            pBuf2     = shrink_str( cBuf );

            for ( l2 = 0; ( pBuf2[l2] != '=' || ( pBuf2[l2 + 1] != '\0'
              && pBuf2[l2 + 1] != '=' ) ) && pBuf2[l2] != '!'
              && pBuf2[l2] != '>' && pBuf2[l2] != '<'
              && pBuf2[l2] != '\0'; )
                pBuf[l++]       = pBuf2[l2++];

            pBuf[l++]           = '\0';

            switch ( pBuf2[l2] )
            {
              case '=' :
                  if ( pBuf2[++l2] != '=' )
                  {
                      l         = -5;
                      goto end;
                  }

                  pBuf[l++]     = NUMBER_SCRIPT_CMP_EQUAL;
                  l2++;
                  break;

              case '!' :
                  if ( pBuf2[++l2] != '=' )
                  {
                      l         = -6;
                      goto end;
                  }

                  pBuf[l++]     = NUMBER_SCRIPT_CMP_NOT_EQUAL;
                  l2++;
                  break;

              case '>' :
                  if ( pBuf2[++l2] != '=' )
                      pBuf[l++] = NUMBER_SCRIPT_CMP_GREATER;
                  else
                  {
                      pBuf[l++] = NUMBER_SCRIPT_CMP_GREATER_EQUAL;
                      l2++;
                  }

                  break;

              case '<' :
                  if ( pBuf2[++l2] != '=' )
                      pBuf[l++] = NUMBER_SCRIPT_CMP_LESS;
                  else
                  {
                      pBuf[l++] = NUMBER_SCRIPT_CMP_LESS_EQUAL;
                      l2++;
                  }

                  break;

              default  :
                  l             = -7;
                  goto end;
            }

            while ( pBuf2[l2] != '\0' )
                pBuf[l++] = pBuf2[l2++];

            pBuf[l++]     = '\0';

            if ( next_char( pStrPos ) != '{' )
            {
                pStrPos = edit_str( pStrPos, cBuf, ' ', ";" );

                if ( next_char( pStrPos ) != ';' )
                {
                    l   = -9;
                    goto end;
                }

                if ( ( ( l2 = strlen( cBuf ) ) + 1 ) < MAX_STRING )
                {
                    cBuf[l2]     = ';';
                    cBuf[l2 + 1] = '\0';
                }
            }
            else
            {
                pStrPos = edit_str_plus( pStrPos, cBuf, '{', '}' );

                if ( next_char( pStrPos ) != '}' )
                {
                    l   = -9;
                    goto end;
                }
            }

            l2      = ( room_script_translate( pScript, cBuf ) - 1 );

            if ( l2 < 0 )
            {
                l   = ( l2 + 1 );
                goto end;
            }

            *( (intl *) &pBuf[l] ) = ( l2 + sizeof( intl ) + 2 );
            l      += ( sizeof( intl ) + 1 );

            memcpy( &pBuf[l], cBuf, l2 );
            l      += l2;

            pBuf2   = remove_char_2( pStrPos );
            pBuf2   = edit_str( pBuf2, cBuf, ' ', "{;\n\r\t " );

            if ( strcmp( cBuf, "else" ) == 0 )
            {
                pStrPos     = pBuf2;

                if ( next_char( pStrPos ) != '{' )
                {
                    pStrPos = edit_str( pStrPos, cBuf, ' ', ";" );

                    if ( next_char( pStrPos ) != ';' )
                    {
                        l   = -9;
                        goto end;
                    }

                    if ( ( ( l2 = strlen( cBuf ) ) + 1 ) < MAX_STRING )
                    {
                        cBuf[l2]     = ';';
                        cBuf[l2 + 1] = '\0';
                    }
                }
                else
                {
                    pStrPos = edit_str_plus( pStrPos, cBuf, '{', '}' );

                    if ( next_char( pStrPos ) != '}' )
                    {
                        l   = -9;
                        goto end;
                    }
                }

                l2          = ( room_script_translate( pScript, cBuf )
                              - 1 );

                if ( l2 < 0 )
                {
                    l       = ( l2 + 1 );
                    goto end;
                }

                pBuf[l++]              = NUMBER_ROOM_COMMAND_GOTO;
                *( (intl *) &pBuf[l] ) = l2;
                l          += ( sizeof( intl ) + 1 );

                memcpy( &pBuf[l], cBuf, l2 );
                l          += l2;
            }
            else
            {
                pBuf[l++]              = NUMBER_ROOM_COMMAND_GOTO;
                *( (intl *) &pBuf[l] ) = 0;
                l          += ( sizeof( intl ) + 1 );
            }

            continue;
        }
        else if ( next_char( pStrPos ) == '=' )
        {
            pBuf[l++]   = NUMBER_ROOM_COMMAND_SET;
            pBuf2       = shrink_str( cBuf );

            for ( l2 = 0; pBuf2[l2] != '\0'; l2++, l++ )
                pBuf[l] = pBuf2[l2];

            pBuf[l++]   = '\0';

            pStrPos     = edit_str( pStrPos, cBuf, '=', ";" );

            if ( *pStrPos != ';' )
            {
                l       = -10;
                goto end;
            }

            pBuf2       = shrink_str( cBuf );

            for ( l2 = 0; pBuf2[l2] != '\0'; l2++, l++ )
                pBuf[l] = pBuf2[l2];

            pBuf[l++]   = '\0';

            continue;
        }

        for ( l2 = 0; snRoomScriptCommandTable[l2].pName[0] != '\0'; l2++ )
        {
            if ( str_compare( cBuf, snRoomScriptCommandTable[l2].pName )
              == TRUE )
                break;
        }

        if ( snRoomScriptCommandTable[l2].pName[0] == '\0' )
        {
            l       = -11;
            goto end;
        }

        pBuf[l++]   = snRoomScriptCommandTable[l2].iNumber;

        if ( next_char( pStrPos ) != '(' )
        {
            l       = -12;
            goto end;
        }

        pStrPos     = edit_str_plus( pStrPos, cBuf, '(', ')' );

        if ( *pStrPos != ')' )
        {
            l       = -13;
            goto end;
        }

        pStrPos     = remove_char_2( pStrPos );

        if ( *pStrPos != ';' )
        {
            l       = -14;
            goto end;
        }

        pBuf2       = shrink_str( cBuf );

        switch ( snRoomScriptCommandTable[l2].iNumber )
        {
          case NUMBER_ROOM_COMMAND_END       :
              break;

          case NUMBER_ROOM_COMMAND_WAIT      :
              *( (ints *) &pBuf[l] ) = atoi( pBuf2 );
              l                     += ( sizeof( ints ) + 1 );
              break;

          case NUMBER_ROOM_COMMAND_SET       :
          case NUMBER_ROOM_COMMAND_CREATE_NPC:
              pBuf2       = edit_str( pBuf2, cBuf2, ' ', ",\n\r\t " );

              if ( next_char( pBuf2 ) != ',' )
              {
                  l       = -15;
                  goto end;
              }

              pBuf2       = remove_char_2( pBuf2 );

              for ( l2 = 0; cBuf2[l2] != '\0'; l2++, l++ )
                  pBuf[l] = cBuf2[l2];

              pBuf[l++]   = '\0';
              goto copy_all;

          default                            :
copy_all:
              for ( l2 = 0; pBuf2[l2] != '\0'; l2++, l++ )
                  pBuf[l] = pBuf2[l2];

              pBuf[l++]   = '\0';
              break;
        }
    }

    pBuf[l++]       = NUMBER_ROOM_COMMAND_END;
    memcpy( pStr, pBuf, l );

end:
    free_mem( (void **) &pBuf );
    return ( l );
}


static char *shrink_str( char *pStr )
{
    char *pBak  = pStr;
    char *pPos  = pStr;
    bool b      = FALSE;

    while ( *pStr != '\0' )
    {
        if ( b != TRUE )
            while ( isspace( *pStr ) )
                pStr++;

        if ( *pStr == '"' )
            b   = ( b == TRUE ? FALSE : TRUE );

        if ( b == TRUE )
        {
            if ( *pStr == '\\' )
                *pPos++ = *pStr++;
        }

        if ( *pStr == '\0' )
            break;

        *pPos++ = *pStr++;
    }

    *pPos       = '\0';

    return ( pBak );
}


static QUEST_VAR_DATA *get_var( char *pName, GENERIC_DATA *pGen,
                                QUEST_VAR_DATA *pVars, intt iThisType,
                                void *pThis, CHAR_DATA *pActor,
                                CHAR_DATA *pThird )
{
    QUEST_DATA *pQuestData;
    QUEST_VAR_DATA *pVar = NULL;
    char *p              = pName;
    int i;

    for ( i = 0; *p != '\0' && *p != '.'; i++, p++ )
        cGBuf2[i]        = *p;

    cGBuf2[i]            = '\0';

    if ( strcmp( cGBuf2, "null" ) == 0 )
        pVar             = NULL;
    else if ( strcmp( cGBuf2, "null_character" ) == 0 )
    {
        qvResult.iType   = NUMBER_VAR_POINTER_CHAR;
        qvResult.uData.p = NULL;

        pVar             = &qvResult;
    }
    else if ( strcmp( cGBuf2, "null_object" ) == 0 )
    {
        qvResult.iType   = NUMBER_VAR_POINTER_OBJ;
        qvResult.uData.p = NULL;

        pVar             = &qvResult;
    }
    else if ( strcmp( cGBuf2, "null_room" ) == 0 )
    {
        qvResult.iType   = NUMBER_VAR_POINTER_ROOM;
        qvResult.uData.p = NULL;

        pVar             = &qvResult;
    }
    else if ( strcmp( cGBuf2, "this" ) == 0
      || strcmp( cGBuf2, "self" ) == 0 )
    {
        qvResult.iType   = iThisType;
        qvResult.uData.p = pThis;

        pVar             = &qvResult;
    }
    else if ( strcmp( cGBuf2, "actor" ) == 0 )
    {
        qvResult.iType   = NUMBER_VAR_POINTER_CHAR;
        qvResult.uData.p = pActor;

        pVar             = &qvResult;
    }
    else if ( strcmp( cGBuf2, "third" ) == 0
      || strcmp( cGBuf2, "third_person" ) == 0 )
    {
        qvResult.iType   = NUMBER_VAR_POINTER_CHAR;
        qvResult.uData.p = pThird;

        pVar             = &qvResult;
    }
    else
    {
        for ( pVar = pVars; pVar != NULL; pVar = pVar->pNext )
        {
            if ( strcmp( pVar->sName, cGBuf2 ) == 0 )
                break;
        }

        if ( pVar == NULL && *p == '.' && *( ++p ) != '\0' )
        {
            for ( ; pGen != NULL; pGen = pGen->pNext )
            {
                pQuestData    = pGen->pData;

                if ( strcmp( pQuestData->sName, cGBuf2 ) != 0 )
                    continue;

                for ( i = 0; *p != '\0' && *p != '.'; i++, p++ )
                    cGBuf2[i] = *p;

                cGBuf2[i]     = '\0';

                for ( pVar = pQuestData->pVars; pVar; pVar = pVar->pNext )
                {
                    if ( strcmp( pVar->sName, cGBuf2 ) == 0 )
                        break;
                }

                break;
            }
        }
    }

    for ( ; ; )
    {
        if ( pVar == NULL || *p != '.' )
            break;

        for ( i = 0, p++; *p != '\0' && *p != '.'; i++, p++ )
            cGBuf2[i]    = *p;

        cGBuf2[i]        = '\0';

        switch ( pVar->iType )
        {
          case NUMBER_VAR_NUMBER      :
          case NUMBER_VAR_STRING      :
              pVar       = NULL;
              break;

          case NUMBER_VAR_POINTER_CHAR:
              {
                  CHAR_DATA *pChar     = (CHAR_DATA *) pVar->uData.p;

                  if ( pChar == NULL )
                  {
                      pVar             = NULL;
                      break;
                  }

                  if ( strcmp( cGBuf2, "in_room" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_POINTER_ROOM;
                      qvResult.uData.p = pChar->pInRoom;
                  }
                  else if ( strcmp( cGBuf2, "leader" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_POINTER_CHAR;
                      qvResult.uData.p = pChar->pLeader;
                  }
                  else if ( strcmp( cGBuf2, "fighting" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_POINTER_CHAR;
                      qvResult.uData.p = pChar->pFighting;
                  }
                  else if ( strcmp( cGBuf2, "char_type" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iCharType;
                  }
                  else if ( strcmp( cGBuf2, "name" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_STRING;
                      qvResult.uData.s = ( IS_NPC( pChar )
                                         ? pChar->pNPCData->pNameList[0]
                                         : pChar->pPCData->sName );
                  }
                  else if ( strcmp( cGBuf2, "short_desc" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_STRING;
                      qvResult.uData.s = ( IS_NPC( pChar )
                                         ? pChar->pNPCData->sShortDesc
                                         : EMPTY_STRING );
                  }
                  else if ( strcmp( cGBuf2, "desc1" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_STRING;
                      qvResult.uData.s = ( IS_NPC( pChar )
                                         ? pChar->pNPCData->sDescs[0]
                                         : EMPTY_STRING );
                  }
                  else if ( strcmp( cGBuf2, "desc2" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_STRING;
                      qvResult.uData.s = ( IS_NPC( pChar )
                                         ? pChar->pNPCData->sDescs[1]
                                         : EMPTY_STRING );
                  }
                  else if ( strcmp( cGBuf2, "desc3" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_STRING;
                      qvResult.uData.s = ( IS_NPC( pChar )
                                         ? pChar->pNPCData->sDescs[2]
                                         : EMPTY_STRING );
                  }
                  else if ( strcmp( cGBuf2, "desc4" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_STRING;
                      qvResult.uData.s = ( IS_NPC( pChar )
                                         ? pChar->pNPCData->sDescs[3]
                                         : EMPTY_STRING );
                  }
                  else if ( strcmp( cGBuf2, "desc5" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_STRING;
                      qvResult.uData.s = ( IS_NPC( pChar )
                                         ? pChar->pNPCData->sDescs[4]
                                         : EMPTY_STRING );
                  }
                  else if ( strcmp( cGBuf2, "long_desc" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_STRING;
                      qvResult.uData.s = pChar->sLongDesc;
                  }
                  else if ( strcmp( cGBuf2, "stat_str" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->pStats->iStatStr;
                  }
                  else if ( strcmp( cGBuf2, "stat_int" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->pStats->iStatInt;
                  }
                  else if ( strcmp( cGBuf2, "stat_wis" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->pStats->iStatWis;
                  }
                  else if ( strcmp( cGBuf2, "stat_dex" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->pStats->iStatDex;
                  }
                  else if ( strcmp( cGBuf2, "stat_con" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->pStats->iStatCon;
                  }
                  else if ( strcmp( cGBuf2, "stat_cha" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->pStats->iStatCha;
                  }
                  else if ( strcmp( cGBuf2, "stat_luc" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->pStats->iStatLuc;
                  }
                  else if ( strcmp( cGBuf2, "stat_hp" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->pStats->iStatHP;
                  }
                  else if ( strcmp( cGBuf2, "stat_mp" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->pStats->iStatMP;
                  }
                  else if ( strcmp( cGBuf2, "stat_mv" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->pStats->iStatMV;
                  }
                  else if ( strcmp( cGBuf2, "part_flags" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->fPartFlags;
                  }
                  else if ( strcmp( cGBuf2, "act_flags" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->fActFlags;
                  }
                  else if ( strcmp( cGBuf2, "npc_flags" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = ( IS_NPC( pChar )
                                         ? pChar->pNPCData->fNPCFlags
                                         : 0 );
                  }
                  else if ( strcmp( cGBuf2, "position" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iPosition;
                  }
                  else if ( strcmp( cGBuf2, "level" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iLevel;
                  }
                  else if ( strcmp( cGBuf2, "magic_level" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iMagicLevel;
                  }
                  else if ( strcmp( cGBuf2, "alignment" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iAlignment;
                  }
                  else if ( strcmp( cGBuf2, "race" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_STRING;
                      qvResult.uData.s = get_race_string( pChar->iRace );
                  }
                  else if ( strcmp( cGBuf2, "sex" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_STRING;
                      qvResult.uData.s = get_sex_string( pChar->iSex );
                  }
                  else if ( strcmp( cGBuf2, "hair_color" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_STRING;
                      qvResult.uData.s = get_hair_color_string(
                                           pChar->iHairColor );
                  }
                  else if ( strcmp( cGBuf2, "eye_color" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_STRING;
                      qvResult.uData.s = get_eye_color_string(
                                           pChar->iEyeColor );
                  }
                  else if ( strcmp( cGBuf2, "height" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iHeight;
                  }
                  else if ( strcmp( cGBuf2, "weight" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iWeight;
                  }
                  else if ( strcmp( cGBuf2, "max_carry" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iMaxCarry;
                  }
                  else if ( strcmp( cGBuf2, "hit_points" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iHP;
                  }
                  else if ( strcmp( cGBuf2, "magic_points" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iMP;
                  }
                  else if ( strcmp( cGBuf2, "movement_points" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iMV;
                  }
                  else if ( strcmp( cGBuf2, "gold" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iGold;
                  }
                  else if ( strcmp( cGBuf2, "hit_roll" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iHitRoll;
                  }
                  else if ( strcmp( cGBuf2, "armor_class1" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iAC[0];
                  }
                  else if ( strcmp( cGBuf2, "armor_class2" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iAC[1];
                  }
                  else if ( strcmp( cGBuf2, "armor_class3" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iAC[2];
                  }
                  else if ( strcmp( cGBuf2, "armor_class4" ) == 0 )
                  {
                      qvResult.iType   = NUMBER_VAR_NUMBER;
                      qvResult.uData.i = pChar->iAC[3];
                  }
                  else
                  {
                      pVar             = NULL;
                      break;
                  }

                  pVar                 = &qvResult;
              }

              break;

          case NUMBER_VAR_POINTER_OBJ :
              break;

          case NUMBER_VAR_POINTER_ROOM:
              break;
        }
    }

    return ( pVar );
}


void execute_npc_script( PROGRAM_DATA *pProgram, SCRIPT_DATA *pScript,
                         RUNNING_SCRIPT_DATA *pRunning, CHAR_DATA *pNPC,
                         CHAR_DATA *pActor, CHAR_DATA *pThird )
{
    SCRIPT_DATA *pScript2;
    QUEST_VAR_DATA qvVar;
    QUEST_VAR_DATA *pVar;
    QUEST_VAR_DATA *pVar2;
    long l;
    byte *pScriptPos;

    if ( pRunning != NULL )
    {
        if ( pRunning->iWaitTimer < pRunning->iWaitTime )
        {
            pRunning->iWaitTimer++;
            pRunning->pScript->bRunning = TRUE;
            return;
        }

        pProgram      = pRunning->pProgram;
        pScript       = pRunning->pScript;

        pScriptPos    = pRunning->pScriptPos;

        pNPC          = pRunning->pThis;
        pActor        = pRunning->pActor;
        pThird        = pRunning->pThird;
    }
    else
        pScriptPos    = pScript->pScript;

    pScript->bRunning = TRUE;

    for ( ; ; )
    {
        switch ( *pScriptPos++ )
        {
          case NUMBER_NPC_COMMAND_END      :
              if ( pRunning != NULL )
              {
                  if ( pRunning == pRunningScriptList )
                      pRunningScriptList   = pRunning->pNext;
                  else
                  {
                      RUNNING_SCRIPT_DATA *pPrev;

                      for ( pPrev = pRunningScriptList; pPrev != NULL;
                        pPrev = pPrev->pNext )
                      {
                          if ( pPrev->pNext == pRunning )
                          {
                              pPrev->pNext = pRunning->pNext;
                              break;
                          }
                      }
#ifdef DEBUG
                      if ( pPrev == NULL )
                          wcdebug( "Running script not found." );
#endif
                  }

                  free_mem( (void **) &pRunning );
              }

              pScript->bRunning = FALSE;
              return;

          case NUMBER_NPC_COMMAND_IF       :
              pVar                 = parse_expr( pScriptPos,
                                       NUMBER_VAR_NUMBER,
                                       pProgram->pQuestDataList,
                                       pProgram->pQuestVars,
                                       NUMBER_VAR_POINTER_CHAR, pNPC,
                                       pActor, pThird );
              pScriptPos          += ( strlen( pScriptPos ) + 1 );

              qvVar.iType          = pVar->iType;
              qvVar.uData          = pVar->uData;

              l                    = *pScriptPos++;

              pVar                 = parse_expr( pScriptPos,
                                       NUMBER_VAR_NUMBER,
                                       pProgram->pQuestDataList,
                                       pProgram->pQuestVars,
                                       NUMBER_VAR_POINTER_CHAR, pNPC,
                                       pActor, pThird );
              pScriptPos          += ( strlen( pScriptPos ) + 1 );

              switch ( l )
              {
                case NUMBER_SCRIPT_CMP_EQUAL        :
                    switch ( qvVar.iType )
                    {
                      case NUMBER_VAR_NUMBER      :
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( qvVar.uData.i == pVar->uData.i ? 1
                                    : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( qvVar.uData.i == atol(
                                    pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_STRING      :
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                snprintf( cGBuf, MAX_STRING, "%ld",
                                  pVar->uData.i );
                                l = ( strcmp( qvVar.uData.s, cGBuf ) == 0
                                    ? 1 : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( strcmp( qvVar.uData.s,
                                    pVar->uData.s ) == 0 ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          free_string( &qvVar.uData.s );
                          break;

                      case NUMBER_VAR_POINTER_CHAR:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_POINTER_CHAR:
                                l = ( qvVar.uData.p == pVar->uData.p ? 1
                                    : 0 );
                                break;

                            default                     :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_POINTER_OBJ :
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_POINTER_OBJ:
                                l = ( qvVar.uData.p == pVar->uData.p ? 1
                                    : 0 );
                                break;

                            default                    :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_POINTER_ROOM:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_POINTER_ROOM:
                                l = ( qvVar.uData.p == pVar->uData.p ? 1
                                    : 0 );
                                break;

                            default                     :
                                l = 0;
                                break;
                          }

                          break;
                    }

                    break;

                case NUMBER_SCRIPT_CMP_NOT_EQUAL    :
                    switch ( qvVar.iType )
                    {
                      case NUMBER_VAR_NUMBER      :
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( qvVar.uData.i != pVar->uData.i ? 1
                                    : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( qvVar.uData.i != atol(
                                    pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_STRING      :
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                snprintf( cGBuf, MAX_STRING, "%ld",
                                  pVar->uData.i );
                                l = ( strcmp( qvVar.uData.s, cGBuf ) != 0
                                    ? 1 : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( strcmp( qvVar.uData.s,
                                    pVar->uData.s ) != 0 ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          free_string( &qvVar.uData.s );
                          break;

                      case NUMBER_VAR_POINTER_CHAR:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_POINTER_CHAR:
                                l = ( qvVar.uData.p != pVar->uData.p ? 1
                                    : 0 );
                                break;

                            default                     :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_POINTER_OBJ :
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_POINTER_OBJ:
                                l = ( qvVar.uData.p != pVar->uData.p ? 1
                                    : 0 );
                                break;

                            default                    :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_POINTER_ROOM:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_POINTER_ROOM:
                                l = ( qvVar.uData.p != pVar->uData.p ? 1
                                    : 0 );
                                break;

                            default                     :
                                l = 0;
                                break;
                          }

                          break;
                    }

                    break;

                case NUMBER_SCRIPT_CMP_GREATER      :
                    switch ( qvVar.iType )
                    {
                      case NUMBER_VAR_NUMBER:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( qvVar.uData.i > pVar->uData.i ? 1
                                    : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( qvVar.uData.i > atol(
                                    pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_STRING:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( atol( qvVar.uData.s )
                                    > pVar->uData.i ? 1 : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( atol( qvVar.uData.s )
                                    > atol( pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          free_string( &qvVar.uData.s );
                          break;

                      default               :
                          l       = 0;
                          break;
                    }

                    break;

                case NUMBER_SCRIPT_CMP_LESS         :
                    switch ( qvVar.iType )
                    {
                      case NUMBER_VAR_NUMBER:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( qvVar.uData.i < pVar->uData.i ? 1
                                    : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( qvVar.uData.i < atol(
                                    pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_STRING:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( atol( qvVar.uData.s )
                                    < pVar->uData.i ? 1 : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( atol( qvVar.uData.s )
                                    < atol( pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          free_string( &qvVar.uData.s );
                          break;

                      default               :
                          l       = 0;
                          break;
                    }

                    break;

                case NUMBER_SCRIPT_CMP_GREATER_EQUAL:
                    switch ( qvVar.iType )
                    {
                      case NUMBER_VAR_NUMBER:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( qvVar.uData.i >= pVar->uData.i ? 1
                                    : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( qvVar.uData.i >= atol(
                                    pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_STRING:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( atol( qvVar.uData.s )
                                    >= pVar->uData.i ? 1 : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( atol( qvVar.uData.s )
                                    >= atol( pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          free_string( &qvVar.uData.s );
                          break;

                      default               :
                          l       = 0;
                          break;
                    }

                    break;

                case NUMBER_SCRIPT_CMP_LESS_EQUAL   :
                    switch ( qvVar.iType )
                    {
                      case NUMBER_VAR_NUMBER:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( qvVar.uData.i <= pVar->uData.i ? 1
                                    : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( qvVar.uData.i <= atol(
                                    pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_STRING:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( atol( qvVar.uData.s )
                                    <= pVar->uData.i ? 1 : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( atol( qvVar.uData.s )
                                    <= atol( pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          free_string( &qvVar.uData.s );
                          break;

                      default               :
                          l       = 0;
                          break;
                    }

                    break;
              }

              if ( l == 0 )
                  pScriptPos          += *( (intl *) pScriptPos );

              pScriptPos += ( sizeof( intl ) + 1 );
              break;

          case NUMBER_NPC_COMMAND_GOTO     :
              pScriptPos += *( (intl *) pScriptPos );
              pScriptPos += ( sizeof( intl ) + 1 );
              break;

          case NUMBER_NPC_COMMAND_ENABLE   :
              if ( str_compare( pScriptPos, "all" ) == TRUE )
              {
                  for ( pScript2 = pProgram->pScripts; pScript2 != NULL;
                    pScript2 = pScript2->pNext )
                      pScript2->bDisabled     = FALSE;
              }
              else
              {
                  for ( pScript2 = pProgram->pScripts; pScript2 != NULL;
                    pScript2 = pScript2->pNext )
                  {
                      if ( str_compare( pScript2->pName, pScriptPos )
                        == TRUE )
                      {
                          pScript2->bDisabled = FALSE;
                          break;
                      }
                  }
              }

              pScriptPos += ( strlen( pScriptPos ) + 1 );
              break;

          case NUMBER_NPC_COMMAND_DISABLE  :
              if ( str_compare( pScriptPos, "all" ) == TRUE )
              {
                  for ( pScript2 = pProgram->pScripts; pScript2 != NULL;
                    pScript2 = pScript2->pNext )
                      pScript2->bDisabled     = TRUE;
              }
              else
              {
                  for ( pScript2 = pProgram->pScripts; pScript2 != NULL;
                    pScript2 = pScript2->pNext )
                  {
                      if ( str_compare( pScript2->pName, pScriptPos )
                        == TRUE )
                      {
                          pScript2->bDisabled = TRUE;
                          break;
                      }
                  }
              }

              pScriptPos += ( strlen( pScriptPos ) + 1 );
              break;

          case NUMBER_NPC_COMMAND_WAIT     :
              if ( pRunning == NULL )
              {
                  pRunning           = alloc_mem( sizeof( *pRunning ) );

                  pRunning->pNext    = pRunningScriptList;
                  pRunningScriptList = pRunning;
              }

              pRunning->pProgram     = pProgram;
              pRunning->pScript      = pScript;

              pRunning->iWaitTime    = *( (ints *) pScriptPos );
              pRunning->iWaitTimer   = 0;
              pRunning->iThisType    = NUMBER_VAR_POINTER_CHAR;
              pRunning->pThis        = pNPC;
              pRunning->pActor       = pActor;
              pRunning->pThird       = pThird;

              pScriptPos += ( sizeof( ints ) + 1 );
              pRunning->pScriptPos   = pScriptPos;
              return;

          case NUMBER_NPC_COMMAND_SET      :
              if ( ( pVar = get_var( pScriptPos,
                pProgram->pQuestDataList, pProgram->pQuestVars,
                NUMBER_VAR_POINTER_CHAR, pNPC, pActor, pThird ) ) == NULL )
              {
                  pScriptPos += ( strlen( pScriptPos ) + 1 );
                  pScriptPos += ( strlen( pScriptPos ) + 1 );
                  break;
              }

              pScriptPos     += ( strlen( pScriptPos ) + 1 );

              switch ( pVar->iType )
              {
                case NUMBER_VAR_NUMBER      :
                    pVar2 = parse_expr( pScriptPos, NUMBER_VAR_NUMBER,
                              pProgram->pQuestDataList,
                              pProgram->pQuestVars,
                              NUMBER_VAR_POINTER_CHAR, pNPC, pActor,
                              pThird );

                    switch ( pVar2->iType )
                    {
                      case NUMBER_VAR_NUMBER:
                          pVar->uData.i = pVar2->uData.i;
                          break;

                      case NUMBER_VAR_STRING:
                          pVar->uData.i = atol( pVar2->uData.s );
                          free_string( &pVar2->uData.s );
                          break;

                      default               :
                          pVar->uData.i = 0;
                          break;
                    }

                    break;

                case NUMBER_VAR_STRING      :
                    free_string( &pVar->uData.s );
                    pVar2 = parse_expr( pScriptPos, NUMBER_VAR_STRING,
                              pProgram->pQuestDataList,
                              pProgram->pQuestVars,
                              NUMBER_VAR_POINTER_CHAR, pNPC, pActor,
                              pThird );

                    switch ( pVar2->iType )
                    {
                      case NUMBER_VAR_NUMBER:
                          snprintf( cGBuf, MAX_STRING, "%ld",
                            pVar2->uData.i );
                          pVar->uData.s = save_string( cGBuf );
                          break;

                      case NUMBER_VAR_STRING:
                          pVar->uData.s = pVar2->uData.s;
                          break;

                      default               :
                          pVar->uData.s = EMPTY_STRING;
                          break;
                    }

                    break;

                case NUMBER_VAR_POINTER_CHAR:
                    pVar2 = parse_expr( pScriptPos, NUMBER_VAR_STRING,
                              pProgram->pQuestDataList,
                              pProgram->pQuestVars,
                              NUMBER_VAR_POINTER_CHAR, pNPC, pActor,
                              pThird );

                    switch ( pVar2->iType )
                    {
                      case NUMBER_VAR_POINTER_CHAR:
                          pVar->uData.p = pVar2->uData.p;
                          break;

                      default                     :
                          pVar->uData.p = NULL;
                          break;
                    }

                    break;

                case NUMBER_VAR_POINTER_OBJ :
                    pVar2 = parse_expr( pScriptPos, NUMBER_VAR_STRING,
                              pProgram->pQuestDataList,
                              pProgram->pQuestVars,
                              NUMBER_VAR_POINTER_CHAR, pNPC, pActor,
                              pThird );

                    switch ( pVar2->iType )
                    {
                      case NUMBER_VAR_POINTER_OBJ:
                          pVar->uData.p = pVar2->uData.p;
                          break;

                      default                    :
                          pVar->uData.p = NULL;
                          break;
                    }

                    break;

                case NUMBER_VAR_POINTER_ROOM:
                    pVar2 = parse_expr( pScriptPos, NUMBER_VAR_NUMBER,
                              pProgram->pQuestDataList,
                              pProgram->pQuestVars,
                              NUMBER_VAR_POINTER_CHAR, pNPC, pActor,
                              pThird );

                    switch ( pVar2->iType )
                    {
                      case NUMBER_VAR_POINTER_ROOM:
                          pVar->uData.p = pVar2->uData.p;
                          break;

                      default                     :
                          pVar->uData.p = NULL;
                          break;
                    }

                    break;
              }

              pScriptPos += ( strlen( pScriptPos ) + 1 );
              break;

          case NUMBER_NPC_COMMAND_GAME_CMD :
              pVar                 = parse_expr( pScriptPos,
                                       NUMBER_VAR_STRING,
                                       pProgram->pQuestDataList,
                                       pProgram->pQuestVars,
                                       NUMBER_VAR_POINTER_CHAR, pNPC,
                                       pActor, pThird );

              switch ( pVar->iType )
              {
                case NUMBER_VAR_NUMBER:
                    snprintf( cGBuf, MAX_STRING, "%ld", pVar->uData.i );
                    break;

                case NUMBER_VAR_STRING:
                    strcpy( cGBuf, pVar->uData.s );
                    free_string( &pVar->uData.s );
                    break;

                default               :
                    cGBuf[0]        = '\0';
                    break;
              }

              process_cmd( pNPC, cGBuf );
              pScriptPos += ( strlen( pScriptPos ) + 1 );
              break;
        }
    }
}


void execute_obj_script( PROGRAM_DATA *pProgram, SCRIPT_DATA *pScript,
                         OBJ_DATA *pChar )
{

}


void execute_room_script( PROGRAM_DATA *pProgram, SCRIPT_DATA *pScript,
                          RUNNING_SCRIPT_DATA *pRunning,
                          ROOM_INDEX_DATA *pRoom, CHAR_DATA *pActor,
                          CHAR_DATA *pThird )
{
    SCRIPT_DATA *pScript2;
    QUEST_VAR_DATA qvVar;
    QUEST_VAR_DATA *pVar;
    QUEST_VAR_DATA *pVar2;
    long l;
    byte *pScriptPos;

    if ( pRunning != NULL )
    {
        if ( pRunning->iWaitTimer < pRunning->iWaitTime )
        {
            pRunning->iWaitTimer++;
            pRunning->pScript->bRunning = TRUE;
            return;
        }

        pProgram      = pRunning->pProgram;
        pScript       = pRunning->pScript;

        pScriptPos    = pRunning->pScriptPos;

        pRoom         = pRunning->pThis;
        pActor        = pRunning->pActor;
        pThird        = pRunning->pThird;
    }
    else
        pScriptPos    = pScript->pScript;

    pScript->bRunning = TRUE;

    for ( ; ; )
    {
        switch ( *pScriptPos++ )
        {
          case NUMBER_ROOM_COMMAND_END       :
              if ( pRunning != NULL )
              {
                  if ( pRunning == pRunningScriptList )
                      pRunningScriptList   = pRunning->pNext;
                  else
                  {
                      RUNNING_SCRIPT_DATA *pPrev;

                      for ( pPrev = pRunningScriptList; pPrev != NULL;
                        pPrev = pPrev->pNext )
                      {
                          if ( pPrev->pNext == pRunning )
                          {
                              pPrev->pNext = pRunning->pNext;
                              break;
                          }
                      }
#ifdef DEBUG
                      if ( pPrev == NULL )
                          wcdebug( "Running script not found." );
#endif
                  }

                  free_mem( (void **) &pRunning );
              }

              pScript->bRunning = FALSE;
              return;

          case NUMBER_ROOM_COMMAND_IF        :
              pVar                 = parse_expr( pScriptPos,
                                       NUMBER_VAR_NUMBER,
                                       pProgram->pQuestDataList,
                                       pProgram->pQuestVars,
                                       NUMBER_VAR_POINTER_ROOM, pRoom,
                                       pActor, pThird );
              pScriptPos          += ( strlen( pScriptPos ) + 1 );

              qvVar.iType          = pVar->iType;
              qvVar.uData          = pVar->uData;

              l                    = *pScriptPos++;

              pVar                 = parse_expr( pScriptPos,
                                       NUMBER_VAR_NUMBER,
                                       pProgram->pQuestDataList,
                                       pProgram->pQuestVars,
                                       NUMBER_VAR_POINTER_ROOM, pRoom,
                                       pActor, pThird );
              pScriptPos          += ( strlen( pScriptPos ) + 1 );

              switch ( l )
              {
                case NUMBER_SCRIPT_CMP_EQUAL        :
                    switch ( qvVar.iType )
                    {
                      case NUMBER_VAR_NUMBER      :
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( qvVar.uData.i == pVar->uData.i ? 1
                                    : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( qvVar.uData.i == atol(
                                    pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_STRING      :
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                snprintf( cGBuf, MAX_STRING, "%ld",
                                  pVar->uData.i );
                                l = ( strcmp( qvVar.uData.s, cGBuf ) == 0
                                    ? 1 : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( strcmp( qvVar.uData.s,
                                    pVar->uData.s ) == 0 ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          free_string( &qvVar.uData.s );
                          break;

                      case NUMBER_VAR_POINTER_CHAR:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_POINTER_CHAR:
                                l = ( qvVar.uData.p == pVar->uData.p ? 1
                                    : 0 );
                                break;

                            default                     :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_POINTER_OBJ :
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_POINTER_OBJ:
                                l = ( qvVar.uData.p == pVar->uData.p ? 1
                                    : 0 );
                                break;

                            default                    :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_POINTER_ROOM:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_POINTER_ROOM:
                                l = ( qvVar.uData.p == pVar->uData.p ? 1
                                    : 0 );
                                break;

                            default                     :
                                l = 0;
                                break;
                          }

                          break;
                    }

                    break;

                case NUMBER_SCRIPT_CMP_NOT_EQUAL    :
                    switch ( qvVar.iType )
                    {
                      case NUMBER_VAR_NUMBER      :
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( qvVar.uData.i != pVar->uData.i ? 1
                                    : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( qvVar.uData.i != atol(
                                    pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_STRING      :
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                snprintf( cGBuf, MAX_STRING, "%ld",
                                  pVar->uData.i );
                                l = ( strcmp( qvVar.uData.s, cGBuf ) != 0
                                    ? 1 : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( strcmp( qvVar.uData.s,
                                    pVar->uData.s ) != 0 ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          free_string( &qvVar.uData.s );
                          break;

                      case NUMBER_VAR_POINTER_CHAR:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_POINTER_CHAR:
                                l = ( qvVar.uData.p != pVar->uData.p ? 1
                                    : 0 );
                                break;

                            default                     :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_POINTER_OBJ :
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_POINTER_OBJ:
                                l = ( qvVar.uData.p != pVar->uData.p ? 1
                                    : 0 );
                                break;

                            default                    :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_POINTER_ROOM:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_POINTER_ROOM:
                                l = ( qvVar.uData.p != pVar->uData.p ? 1
                                    : 0 );
                                break;

                            default                     :
                                l = 0;
                                break;
                          }

                          break;
                    }

                    break;

                case NUMBER_SCRIPT_CMP_GREATER      :
                    switch ( qvVar.iType )
                    {
                      case NUMBER_VAR_NUMBER:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( qvVar.uData.i > pVar->uData.i ? 1
                                    : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( qvVar.uData.i > atol(
                                    pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_STRING:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( atol( qvVar.uData.s )
                                    > pVar->uData.i ? 1 : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( atol( qvVar.uData.s )
                                    > atol( pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          free_string( &qvVar.uData.s );
                          break;

                      default               :
                          l       = 0;
                          break;
                    }

                    break;

                case NUMBER_SCRIPT_CMP_LESS         :
                    switch ( qvVar.iType )
                    {
                      case NUMBER_VAR_NUMBER:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( qvVar.uData.i < pVar->uData.i ? 1
                                    : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( qvVar.uData.i < atol(
                                    pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_STRING:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( atol( qvVar.uData.s )
                                    < pVar->uData.i ? 1 : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( atol( qvVar.uData.s )
                                    < atol( pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          free_string( &qvVar.uData.s );
                          break;

                      default               :
                          l       = 0;
                          break;
                    }

                    break;

                case NUMBER_SCRIPT_CMP_GREATER_EQUAL:
                    switch ( qvVar.iType )
                    {
                      case NUMBER_VAR_NUMBER:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( qvVar.uData.i >= pVar->uData.i ? 1
                                    : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( qvVar.uData.i >= atol(
                                    pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_STRING:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( atol( qvVar.uData.s )
                                    >= pVar->uData.i ? 1 : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( atol( qvVar.uData.s )
                                    >= atol( pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          free_string( &qvVar.uData.s );
                          break;

                      default               :
                          l       = 0;
                          break;
                    }

                    break;

                case NUMBER_SCRIPT_CMP_LESS_EQUAL   :
                    switch ( qvVar.iType )
                    {
                      case NUMBER_VAR_NUMBER:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( qvVar.uData.i <= pVar->uData.i ? 1
                                    : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( qvVar.uData.i <= atol(
                                    pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          break;

                      case NUMBER_VAR_STRING:
                          switch ( pVar->iType )
                          {
                            case NUMBER_VAR_NUMBER:
                                l = ( atol( qvVar.uData.s )
                                    <= pVar->uData.i ? 1 : 0 );
                                break;

                            case NUMBER_VAR_STRING:
                                l = ( atol( qvVar.uData.s )
                                    <= atol( pVar->uData.s ) ? 1 : 0 );
                                free_string( &pVar->uData.s );
                                break;

                            default               :
                                l = 0;
                                break;
                          }

                          free_string( &qvVar.uData.s );
                          break;

                      default               :
                          l       = 0;
                          break;
                    }

                    break;
              }

              if ( l == 0 )
                  pScriptPos          += *( (intl *) pScriptPos );

              pScriptPos += ( sizeof( intl ) + 1 );
              break;

          case NUMBER_ROOM_COMMAND_GOTO      :
              pScriptPos += *( (intl *) pScriptPos );
              pScriptPos += ( sizeof( intl ) + 1 );
              break;

          case NUMBER_ROOM_COMMAND_ENABLE    :
              if ( str_compare( pScriptPos, "all" ) == TRUE )
              {
                  for ( pScript2 = pProgram->pScripts; pScript2 != NULL;
                    pScript2 = pScript2->pNext )
                      pScript2->bDisabled     = FALSE;
              }
              else
              {
                  for ( pScript2 = pProgram->pScripts; pScript2 != NULL;
                    pScript2 = pScript2->pNext )
                  {
                      if ( str_compare( pScript2->pName, pScriptPos )
                        == TRUE )
                      {
                          pScript2->bDisabled = FALSE;
                          break;
                      }
                  }
              }

              pScriptPos += ( strlen( pScriptPos ) + 1 );
              break;

          case NUMBER_ROOM_COMMAND_DISABLE   :
              if ( str_compare( pScriptPos, "all" ) == TRUE )
              {
                  for ( pScript2 = pProgram->pScripts; pScript2 != NULL;
                    pScript2 = pScript2->pNext )
                      pScript2->bDisabled     = TRUE;
              }
              else
              {
                  for ( pScript2 = pProgram->pScripts; pScript2 != NULL;
                    pScript2 = pScript2->pNext )
                  {
                      if ( str_compare( pScript2->pName, pScriptPos )
                        == TRUE )
                      {
                          pScript2->bDisabled = TRUE;
                          break;
                      }
                  }
              }

              pScriptPos += ( strlen( pScriptPos ) + 1 );
              break;

          case NUMBER_ROOM_COMMAND_WAIT      :
              if ( pRunning == NULL )
              {
                  pRunning           = alloc_mem( sizeof( *pRunning ) );

                  pRunning->pNext    = pRunningScriptList;
                  pRunningScriptList = pRunning;
              }

              pRunning->pProgram     = pProgram;
              pRunning->pScript      = pScript;

              pRunning->iWaitTime    = *( (ints *) pScriptPos );
              pRunning->iWaitTimer   = 0;
              pRunning->iThisType    = NUMBER_VAR_POINTER_ROOM;
              pRunning->pThis        = pRoom;
              pRunning->pActor       = pActor;
              pRunning->pThird       = pThird;

              pScriptPos += ( sizeof( ints ) + 1 );
              pRunning->pScriptPos   = pScriptPos;
              return;

          case NUMBER_ROOM_COMMAND_SET       :
              if ( ( pVar = get_var( pScriptPos,
                pProgram->pQuestDataList, pProgram->pQuestVars,
                NUMBER_VAR_POINTER_ROOM, pRoom, pActor, pThird ) )
                == NULL )
              {
                  pScriptPos += ( strlen( pScriptPos ) + 1 );
                  pScriptPos += ( strlen( pScriptPos ) + 1 );
                  break;
              }

              pScriptPos     += ( strlen( pScriptPos ) + 1 );

              switch ( pVar->iType )
              {
                case NUMBER_VAR_NUMBER      :
                    pVar2 = parse_expr( pScriptPos, NUMBER_VAR_NUMBER,
                              pProgram->pQuestDataList,
                              pProgram->pQuestVars,
                              NUMBER_VAR_POINTER_ROOM, pRoom, pActor,
                              pThird );

                    switch ( pVar2->iType )
                    {
                      case NUMBER_VAR_NUMBER:
                          pVar->uData.i = pVar2->uData.i;
                          break;

                      case NUMBER_VAR_STRING:
                          pVar->uData.i = atol( pVar2->uData.s );
                          free_string( &pVar2->uData.s );
                          break;

                      default               :
                          pVar->uData.i = 0;
                          break;
                    }

                    break;

                case NUMBER_VAR_STRING      :
                    free_string( &pVar->uData.s );
                    pVar2 = parse_expr( pScriptPos, NUMBER_VAR_STRING,
                              pProgram->pQuestDataList,
                              pProgram->pQuestVars,
                              NUMBER_VAR_POINTER_ROOM, pRoom, pActor,
                              pThird );

                    switch ( pVar2->iType )
                    {
                      case NUMBER_VAR_NUMBER:
                          snprintf( cGBuf, MAX_STRING, "%ld",
                            pVar2->uData.i );
                          pVar->uData.s = save_string( cGBuf );
                          break;

                      case NUMBER_VAR_STRING:
                          pVar->uData.s = pVar2->uData.s;
                          break;

                      default               :
                          pVar->uData.s = EMPTY_STRING;
                          break;
                    }

                    break;

                case NUMBER_VAR_POINTER_CHAR:
                    pVar2 = parse_expr( pScriptPos, NUMBER_VAR_STRING,
                              pProgram->pQuestDataList,
                              pProgram->pQuestVars,
                              NUMBER_VAR_POINTER_ROOM, pRoom, pActor,
                              pThird );

                    switch ( pVar2->iType )
                    {
                      case NUMBER_VAR_POINTER_CHAR:
                          pVar->uData.p = pVar2->uData.p;
                          break;

                      default                     :
                          pVar->uData.p = NULL;
                          break;
                    }

                    break;

                case NUMBER_VAR_POINTER_OBJ :
                    pVar2 = parse_expr( pScriptPos, NUMBER_VAR_STRING,
                              pProgram->pQuestDataList,
                              pProgram->pQuestVars,
                              NUMBER_VAR_POINTER_ROOM, pRoom, pActor,
                              pThird );

                    switch ( pVar2->iType )
                    {
                      case NUMBER_VAR_POINTER_OBJ:
                          pVar->uData.p = pVar2->uData.p;
                          break;

                      default                    :
                          pVar->uData.p = NULL;
                          break;
                    }

                    break;

                case NUMBER_VAR_POINTER_ROOM:
                    pVar2 = parse_expr( pScriptPos, NUMBER_VAR_NUMBER,
                              pProgram->pQuestDataList,
                              pProgram->pQuestVars,
                              NUMBER_VAR_POINTER_ROOM, pRoom, pActor,
                              pThird );

                    switch ( pVar2->iType )
                    {
                      case NUMBER_VAR_POINTER_ROOM:
                          pVar->uData.p = pVar2->uData.p;
                          break;

                      default                     :
                          pVar->uData.p = NULL;
                          break;
                    }

                    break;
              }

              pScriptPos += ( strlen( pScriptPos ) + 1 );
              break;

          case NUMBER_ROOM_COMMAND_CREATE_NPC:
              {
                  NPC_INDEX_DATA *pNPCIndex;
                  CHAR_DATA *pChar;

                  pVar             = parse_expr( pScriptPos,
                                       NUMBER_VAR_NUMBER,
                                       pProgram->pQuestDataList,
                                       pProgram->pQuestVars,
                                       NUMBER_VAR_POINTER_ROOM, pRoom,
                                       pActor, pThird );

                  switch ( pVar->iType )
                  {
                    case NUMBER_VAR_NUMBER:
                        l          = pVar->uData.i;
                        break;

                    case NUMBER_VAR_STRING:
                        l          = atol( pVar->uData.s );
                        free_string( &pVar->uData.s );
                        break;

                    default               :
                        l          = 0;
                        break;
                  }

                  pScriptPos += ( strlen( pScriptPos ) + 1 );

                  pVar             = parse_expr( pScriptPos,
                                       NUMBER_VAR_NUMBER,
                                       pProgram->pQuestDataList,
                                       pProgram->pQuestVars,
                                       NUMBER_VAR_POINTER_ROOM, pRoom,
                                       pActor, pThird );

                  switch ( pVar->iType )
                  {
                    case NUMBER_VAR_POINTER_CHAR:
                        pChar      = pVar->uData.p;
                        break;

                    case NUMBER_VAR_STRING:
                        pChar      = NULL;
                        free_string( &pVar->uData.s );
                        break;

                    default                     :
                        pChar      = NULL;
                        break;
                  }

                  if ( l > 5 && l <= MAX_INDEX_NUMBER
                    && ( pNPCIndex = get_npc_index( l ) ) != NULL )
                      char_to_room( new_npc( pNPCIndex, pChar ), pRoom );

                  pScriptPos += ( strlen( pScriptPos ) + 1 );
              }

              break;
        }
    }
}


static QUEST_VAR_DATA *parse_expr( char *pStr, intt iType,
                                   GENERIC_DATA *pGenList,
                                   QUEST_VAR_DATA *pQuestVars,
                                   intt iThisType, void *pThis,
                                   CHAR_DATA *pActor, CHAR_DATA *pThird )
{
    pTempGenList         = pGenList;
    pQuestVarList        = pQuestVars;
    iThisType_           = iThisType;
    pThis_               = pThis;
    pActor_              = pActor;
    pThird_              = pThird;

    iForcedType          = iType;
    iExprError           = 0;
    _parse_expr( pStr );

    if ( iExprError != 0 )
    {
        sap_warning( "Parse error %d.", iExprError );
        qvResult.iType   = 0;
        qvResult.uData.p = NULL;
    }

    return ( &qvResult );
}


static char *_parse_expr( char *pStr )
{
    QUEST_VAR_DATA qvVar;
    char c;
    int i;

    if ( ( c = next_char( pStr ) ) == '\0' )
        return ( pStr );
    else if ( c == '(' )
    {
        char *pBuf   = new_buffer( );

        pStr         = edit_str_plus( pStr, pBuf, '(', ')' );
        _parse_expr( pBuf );

        if ( iExprError != 0 )
        {
            if ( qvResult.iType == NUMBER_VAR_STRING )
                free_string( &qvResult.uData.s );

            return ( EMPTY_STRING );
        }

        if ( next_char( pStr ) != ')' )
        {
            if ( qvResult.iType == NUMBER_VAR_STRING )
                free_string( &qvResult.uData.s );

            iExprError = -1;
            return ( EMPTY_STRING );
        }

        pStr         = remove_char_2( pStr );

        qvVar.iType  = qvResult.iType;
        qvVar.uData  = qvResult.uData;
    }
    else if ( isdigit( c ) )
    {
        while ( isspace( *pStr ) )
            pStr++;

        for ( i = 0; isdigit( *pStr ); pStr++, i++ )
            cGBuf[i] = *pStr;

        cGBuf[i]     = '\0';

        qvVar.iType         = NUMBER_VAR_NUMBER;
        qvVar.uData.i       = atol( cGBuf );
    }
    else if ( isalpha( c ) || c == '_' )
    {
        QUEST_VAR_DATA *pVar;

        while ( isspace( *pStr ) )
            pStr++;

        for ( i = 0; isalnum( *pStr ) || *pStr == '_' || *pStr == '.';
          pStr++, i++ )
            cGBuf[i] = *pStr;

        cGBuf[i]     = '\0';

        if ( next_char( pStr ) == '(' )
        {
            char *pBuf  = new_buffer( );

            for ( i = 0; sfScriptFunctionTable[i].pName[0] != '\0'; i++ )
            {
                if ( strcmp( sfScriptFunctionTable[i].pName, cGBuf ) == 0 )
                    break;
            }

            if ( sfScriptFunctionTable[i].pName[0] == '\0' )
                goto no_fun;

            pStr        = edit_str_plus( pStr, pBuf, '(', ')' );

            if ( next_char( pStr ) != ')' )
            {
                iExprError      = -2;
                return ( EMPTY_STRING );
            }

            pStr        = remove_char_2( pStr );

            ( *sfScriptFunctionTable[i].pFunc ) ( pBuf );

            if ( iExprError != 0 )
            {
                if ( qvResult.iType == NUMBER_VAR_STRING )
                    free_string( &qvResult.uData.s );

                return ( EMPTY_STRING );
            }

            qvVar.iType = qvResult.iType;
            qvVar.uData = qvResult.uData;
        }
        else
        {
            pVar                = get_var( cGBuf, pTempGenList,
                                    pQuestVarList, iThisType_, pThis_,
                                    pActor_, pThird_ );

            if ( next_char( pStr ) == '=' )
            {
                pStr            = remove_char_2( pStr );
                pStr            = _parse_expr( pStr );

                if ( iExprError != 0 )
                {
                    if ( qvResult.iType == NUMBER_VAR_STRING )
                        free_string( &qvResult.uData.s );

                    return ( EMPTY_STRING );
                }

                if ( pVar == NULL )
                    goto no_fun;

                qvVar.iType       = pVar->iType;

                switch ( pVar->iType )
                {
                  case NUMBER_VAR_NUMBER      :
                      switch ( qvResult.iType )
                      {
                        case NUMBER_VAR_NUMBER:
                            pVar->uData.i = qvResult.uData.i;
                            break;

                        case NUMBER_VAR_STRING:
                            pVar->uData.i = atol( qvResult.uData.s );
                            free_string( &qvResult.uData.s );
                            break;

                        default               :
                            pVar->uData.i = 0;
                            break;
                      }

                      qvVar.uData         = pVar->uData;
                      break;

                  case NUMBER_VAR_STRING      :
                      free_string( &pVar->uData.s );

                      switch ( qvResult.iType )
                      {
                        case NUMBER_VAR_NUMBER:
                            snprintf( cGBuf, MAX_STRING, "%ld",
                              qvResult.uData.i );
                            pVar->uData.s = save_string( cGBuf );
                            break;

                        case NUMBER_VAR_STRING:
                            pVar->uData.s = qvResult.uData.s;
                            break;

                        default               :
                            pVar->uData.s = EMPTY_STRING;
                            break;
                      }

                      qvVar.uData.s       = save_string( pVar->uData.s );
                      break;

                  case NUMBER_VAR_POINTER_CHAR:
                      switch ( qvResult.iType )
                      {
                        case NUMBER_VAR_POINTER_CHAR:
                            pVar->uData.p = qvResult.uData.p;
                            break;

                        default                     :
                            pVar->uData.p = NULL;
                            break;
                      }

                      qvVar.uData         = pVar->uData;
                      break;

                  case NUMBER_VAR_POINTER_OBJ :
                      switch ( qvResult.iType )
                      {
                        case NUMBER_VAR_POINTER_OBJ:
                            pVar->uData.p = qvResult.uData.p;
                            break;

                        default                    :
                            pVar->uData.p = NULL;
                            break;
                      }

                      qvVar.uData         = pVar->uData;
                      break;

                  case NUMBER_VAR_POINTER_ROOM:
                      switch ( qvResult.iType )
                      {
                        case NUMBER_VAR_POINTER_ROOM:
                            pVar->uData.p = qvResult.uData.p;
                            break;

                        default                     :
                            pVar->uData.p = NULL;
                            break;
                      }

                      qvVar.uData         = pVar->uData;
                      break;
                }
            }
            else
            {
                if ( pVar == NULL )
                    goto no_fun;

                qvVar.iType         = pVar->iType;

                switch ( pVar->iType )
                {
                  case NUMBER_VAR_STRING:
                      qvVar.uData.s = save_string( pVar->uData.s );
                      break;

                  default               :
                      qvVar.uData   = pVar->uData;
                      break;
                }
            }

            if ( pVar == NULL )
            {
no_fun:
                qvVar.iType         = NUMBER_VAR_NUMBER;
                qvVar.uData.i       = 0;
            }
        }
    }
    else if ( c == '"' )
    {
        qvVar.iType         = NUMBER_VAR_STRING;
        pStr        = make_string( pStr, cGBuf );

        if ( *pStr == '"' )
            pStr++;

        qvVar.uData.s       = save_string( cGBuf );
    }
    else
    {
        iExprError  = -3;
        return ( EMPTY_STRING );
    }

    if ( ( c = next_char( pStr ) ) == '\0' )
    {
        qvResult.iType         = qvVar.iType;
        qvResult.uData         = qvVar.uData;
    }
    else if ( c == '+' )
    {
        pStr        = remove_char_2( pStr );

        if ( next_char( pStr ) == '\0' )
        {
            if ( qvVar.iType == NUMBER_VAR_STRING )
                free_string( &qvVar.uData.s );

            iExprError = -4;
            return ( EMPTY_STRING );
        }

        pStr        = _parse_expr( pStr );

        if ( iExprError != 0 )
        {
            if ( qvVar.iType == NUMBER_VAR_STRING )
                free_string( &qvVar.uData.s );

            return ( EMPTY_STRING );
        }

        switch ( qvVar.iType )
        {
          case NUMBER_VAR_NUMBER      :
          case NUMBER_VAR_STRING      :
              break;

          case NUMBER_VAR_POINTER_CHAR:
              qvVar.iType           = NUMBER_VAR_STRING;

              if ( qvVar.uData.p != NULL )
              {
                  CHAR_DATA *pChar  = (CHAR_DATA *) qvVar.uData.p;

                  if ( IS_NPC( pChar ) )
                      qvVar.uData.s = save_string(
                                        pChar->pNPCData->pNameList[0] );
                  else
                      qvVar.uData.s = save_string( pChar->pPCData->sName );
              }
              else
                  qvVar.uData.s     = EMPTY_STRING;

              break;

          case NUMBER_VAR_POINTER_OBJ :
              qvVar.iType           = NUMBER_VAR_STRING;

              if ( qvVar.uData.p != NULL )
              {
                  OBJ_DATA *pObj    = (OBJ_DATA *) qvVar.uData.p;
                  qvVar.uData.s     = save_string( pObj->pNameList[0] );
              }
              else
                  qvVar.uData.s     = EMPTY_STRING;

              break;

          case NUMBER_VAR_POINTER_ROOM:
              qvVar.iType           = NUMBER_VAR_NUMBER;

              if ( qvVar.uData.p != NULL )
              {
                  ROOM_INDEX_DATA *pRoom;

                  pRoom             = (ROOM_INDEX_DATA *) qvVar.uData.p;
                  qvVar.uData.i     = pRoom->iNumber;
              }
              else
                  qvVar.uData.i     = 0;

              break;
        }

        switch ( qvResult.iType )
        {
          case NUMBER_VAR_NUMBER      :
          case NUMBER_VAR_STRING      :
              break;

          case NUMBER_VAR_POINTER_CHAR:
              qvResult.iType           = NUMBER_VAR_STRING;

              if ( qvResult.uData.p != NULL )
              {
                  CHAR_DATA *pChar     = (CHAR_DATA *) qvResult.uData.p;

                  if ( IS_NPC( pChar ) )
                      qvResult.uData.s = save_string(
                                           pChar->pNPCData->pNameList[0] );
                  else
                      qvResult.uData.s = save_string(
                                           pChar->pPCData->sName );
              }
              else
                  qvResult.uData.s     = EMPTY_STRING;

              break;

          case NUMBER_VAR_POINTER_OBJ :
              qvResult.iType           = NUMBER_VAR_STRING;

              if ( qvResult.uData.p != NULL )
              {
                  OBJ_DATA *pObj       = (OBJ_DATA *) qvResult.uData.p;
                  qvResult.uData.s     = save_string( pObj->pNameList[0] );
              }
              else
                  qvResult.uData.s     = EMPTY_STRING;

              break;

          case NUMBER_VAR_POINTER_ROOM:
              qvResult.iType           = NUMBER_VAR_NUMBER;

              if ( qvResult.uData.p != NULL )
              {
                  ROOM_INDEX_DATA *pRoom;

                  pRoom             = (ROOM_INDEX_DATA *) qvResult.uData.p;
                  qvResult.uData.i     = pRoom->iNumber;
              }
              else
                  qvResult.uData.i     = 0;

              break;
        }

        if ( qvVar.iType != iForcedType && qvVar.iType != qvResult.iType )
        {
            string sBuf;

            switch ( iForcedType )
            {
              case NUMBER_VAR_NUMBER:
                  qvVar.iType       = NUMBER_VAR_NUMBER;
                  sBuf              = qvVar.uData.s;
                  qvVar.uData.i     = atol( sBuf );
                  free_string( &sBuf );
                  break;

              case NUMBER_VAR_STRING:
                  snprintf( cGBuf, MAX_STRING, "%ld", qvVar.uData.i );

                  qvVar.iType       = NUMBER_VAR_STRING;
                  qvVar.uData.s     = save_string( cGBuf );
                  break;

              default               :
                  break;
            }
        }

        switch ( qvVar.iType )
        {
          case NUMBER_VAR_NUMBER:
              switch ( qvResult.iType )
              {
                case NUMBER_VAR_NUMBER:
                    qvResult.uData.i += qvVar.uData.i;
                    break;

                case NUMBER_VAR_STRING:
                    qvVar.uData.i    += atol( qvResult.uData.s );
                    free_string( &qvResult.uData.s );

                    qvResult.iType    = NUMBER_VAR_NUMBER;
                    qvResult.uData.i  = qvVar.uData.i;
                    break;

                default               :
                    if ( qvVar.iType == NUMBER_VAR_STRING )
                        free_string( &qvVar.uData.s );

                    iExprError        = -5;
                    return ( EMPTY_STRING );
              }

              break;

          case NUMBER_VAR_STRING:
              switch ( qvResult.iType )
              {
                case NUMBER_VAR_NUMBER:
                    snprintf( cGBuf, MAX_STRING, "%s%ld", qvVar.uData.s,
                      qvResult.uData.i );
                    free_string( &qvVar.uData.s );

                    qvResult.iType    = NUMBER_VAR_STRING;
                    qvResult.uData.s  = save_string( cGBuf );
                    break;

                case NUMBER_VAR_STRING:
                    snprintf( cGBuf, MAX_STRING, "%s%s", qvVar.uData.s,
                      qvResult.uData.s );
                    free_string( &qvVar.uData.s );
                    free_string( &qvResult.uData.s );

                    qvResult.uData.s  = save_string( cGBuf );
                    break;

                default               :
                    if ( qvVar.iType == NUMBER_VAR_STRING )
                        free_string( &qvVar.uData.s );

                    iExprError        = -6;
                    return ( EMPTY_STRING );
              }

              break;
        }
    }
    else if ( c == '-' || c == '*' || c == '/' )
    {
        pStr        = remove_char_2( pStr );

        if ( next_char( pStr ) == '\0' )
        {
            if ( qvVar.iType == NUMBER_VAR_STRING )
                free_string( &qvVar.uData.s );

            iExprError = -7;
            return ( EMPTY_STRING );
        }

        pStr        = _parse_expr( pStr );

        if ( iExprError != 0 )
        {
            if ( qvVar.iType == NUMBER_VAR_STRING )
                free_string( &qvVar.uData.s );

            return ( EMPTY_STRING );
        }

        switch ( qvVar.iType )
        {
          case NUMBER_VAR_NUMBER      :
          case NUMBER_VAR_STRING      :
              break;

          case NUMBER_VAR_POINTER_CHAR:
              qvVar.iType           = NUMBER_VAR_STRING;

              if ( qvVar.uData.p != NULL )
              {
                  CHAR_DATA *pChar  = (CHAR_DATA *) qvVar.uData.p;

                  if ( IS_NPC( pChar ) )
                      qvVar.uData.s = save_string(
                                        pChar->pNPCData->pNameList[0] );
                  else
                      qvVar.uData.s = save_string( pChar->pPCData->sName );
              }
              else
                  qvVar.uData.s     = EMPTY_STRING;

              break;

          case NUMBER_VAR_POINTER_OBJ :
              qvVar.iType           = NUMBER_VAR_STRING;

              if ( qvVar.uData.p != NULL )
              {
                  OBJ_DATA *pObj    = (OBJ_DATA *) qvVar.uData.p;
                  qvVar.uData.s     = save_string( pObj->pNameList[0] );
              }
              else
                  qvVar.uData.s     = EMPTY_STRING;

              break;

          case NUMBER_VAR_POINTER_ROOM:
              qvVar.iType           = NUMBER_VAR_NUMBER;

              if ( qvVar.uData.p != NULL )
              {
                  ROOM_INDEX_DATA *pRoom;

                  pRoom             = (ROOM_INDEX_DATA *) qvVar.uData.p;
                  qvVar.uData.i     = pRoom->iNumber;
              }
              else
                  qvVar.uData.i     = 0;

              break;
        }

        switch ( qvResult.iType )
        {
          case NUMBER_VAR_NUMBER      :
          case NUMBER_VAR_STRING      :
              break;

          case NUMBER_VAR_POINTER_CHAR:
              qvResult.iType           = NUMBER_VAR_STRING;

              if ( qvResult.uData.p != NULL )
              {
                  CHAR_DATA *pChar     = (CHAR_DATA *) qvResult.uData.p;

                  if ( IS_NPC( pChar ) )
                      qvResult.uData.s = save_string(
                                           pChar->pNPCData->pNameList[0] );
                  else
                      qvResult.uData.s = save_string(
                                           pChar->pPCData->sName );
              }
              else
                  qvResult.uData.s     = EMPTY_STRING;

              break;

          case NUMBER_VAR_POINTER_OBJ :
              qvResult.iType           = NUMBER_VAR_STRING;

              if ( qvResult.uData.p != NULL )
              {
                  OBJ_DATA *pObj       = (OBJ_DATA *) qvResult.uData.p;
                  qvResult.uData.s     = save_string( pObj->pNameList[0] );
              }
              else
                  qvResult.uData.s     = EMPTY_STRING;

              break;

          case NUMBER_VAR_POINTER_ROOM:
              qvResult.iType           = NUMBER_VAR_NUMBER;

              if ( qvResult.uData.p != NULL )
              {
                  ROOM_INDEX_DATA *pRoom;

                  pRoom             = (ROOM_INDEX_DATA *) qvResult.uData.p;
                  qvResult.uData.i     = pRoom->iNumber;
              }
              else
                  qvResult.uData.i     = 0;

              break;
        }

        if ( qvVar.iType != NUMBER_VAR_NUMBER )
        {
            string sBuf;

            qvVar.iType             = NUMBER_VAR_NUMBER;
            sBuf                    = qvVar.uData.s;
            qvVar.uData.i           = atol( sBuf );
            free_string( &sBuf );
        }

        switch ( qvResult.iType )
        {
          case NUMBER_VAR_NUMBER:
              switch ( c )
              {
                case '-':
                    qvVar.uData.i -= qvResult.uData.i;
                    break;

                case '*':
                    qvVar.uData.i *= qvResult.uData.i;
                    break;

                case '/':
                    qvVar.uData.i /= qvResult.uData.i;
                    break;
              }

              qvResult.uData.i     = qvVar.uData.i;
              break;

          case NUMBER_VAR_STRING:
              switch ( c )
              {
                case '-':
                    qvVar.uData.i -= atol( qvResult.uData.s );
                    break;

                case '*':
                    qvVar.uData.i *= atol( qvResult.uData.s );
                    break;

                case '/':
                    qvVar.uData.i /= atol( qvResult.uData.s );
                    break;
              }

              free_string( &qvResult.uData.s );

              qvResult.iType        = NUMBER_VAR_NUMBER;
              qvResult.uData.i      = qvVar.uData.i;
              break;

          default               :
              if ( qvVar.iType == NUMBER_VAR_STRING )
                  free_string( &qvVar.uData.s );

              iExprError            = -8;
              return ( EMPTY_STRING );
        }
    }
    else
    {
        if ( qvVar.iType == NUMBER_VAR_STRING )
            free_string( &qvVar.uData.s );

        iExprError  = -9;
        return ( EMPTY_STRING );
    }

    return ( pStr );
}


void check_char_trigger( int iType, CHAR_DATA *pChar,
                         ROOM_INDEX_DATA *pRoom, CHAR_DATA *pChar2,
                         char *pCmp )
{
    PROGRAM_DATA *pProgram;
    SCRIPT_DATA *pScript;
    TRIGGER_DATA *pTrigger;
    TRIGGER_ARG_DATA *pTriggerArg;

    if ( pChar == NULL || IS_NPC( pChar ) )
        return;

    if ( pRoom == NULL )
    {
        if ( !IS_NPC( pChar2 ) || pChar2 == pChar
          || ( pProgram = pChar2->pNPCData->pProgram ) == NULL )
            return;

        for ( pScript = pProgram->pScripts; pScript != NULL;
          pScript = pScript->pNext )
        {
            bool b                      = FALSE;

            if ( pScript->bDisabled == TRUE
              /* || pScript->bRunning == TRUE */ )
                continue;

            for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
              pTrigger = pTrigger->pNext )
            {
                if ( pTrigger->iTrigger != iType )
                    continue;

                for ( pTriggerArg = pTrigger->pArgs; pTriggerArg != NULL;
                  pTriggerArg = pTriggerArg->pNext )
                {
                    if ( pTriggerArg->iType == 1
                      || ( pTriggerArg->iType == 2
                      && str_compare( pTriggerArg->pArg, pCmp ) == TRUE )
                      || ( pTriggerArg->iType == 3
                      && str_prefix( pTriggerArg->pArg, pCmp ) == TRUE )
                      || ( pTriggerArg->iType == 4
                      && str_infix( pTriggerArg->pArg, pCmp ) == TRUE )
                      || ( pTriggerArg->iType == 5
                      && str_suffix( pTriggerArg->pArg, pCmp ) == TRUE ) )
                    {
                        execute_npc_script( pProgram, pScript, NULL,
                          pChar2, pChar, NULL );
                        b               = TRUE;
                        break;
                    }
                }

                if ( b == TRUE )
                    break;
            }
        }

        return;
    }

    for ( pChar2 = pRoom->pPeople; pChar2; pChar2 = pChar2->pNextInRoom )
    {
        if ( !IS_NPC( pChar2 ) || pChar2 == pChar
          || ( pProgram = pChar2->pNPCData->pProgram ) == NULL )
            continue;

        for ( pScript = pProgram->pScripts; pScript != NULL;
          pScript = pScript->pNext )
        {
            bool b                      = FALSE;

            if ( pScript->bDisabled == TRUE
              /* || pScript->bRunning == TRUE */ )
                continue;

            for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
              pTrigger = pTrigger->pNext )
            {
                if ( pTrigger->iTrigger != iType )
                    continue;

                for ( pTriggerArg = pTrigger->pArgs; pTriggerArg != NULL;
                  pTriggerArg = pTriggerArg->pNext )
                {
                    if ( pTriggerArg->iType == 1
                      || ( pTriggerArg->iType == 2
                      && str_compare( pTriggerArg->pArg, pCmp ) == TRUE )
                      || ( pTriggerArg->iType == 3
                      && str_prefix( pTriggerArg->pArg, pCmp ) == TRUE )
                      || ( pTriggerArg->iType == 4
                      && str_infix( pTriggerArg->pArg, pCmp ) == TRUE )
                      || ( pTriggerArg->iType == 5
                      && str_suffix( pTriggerArg->pArg, pCmp ) == TRUE ) )
                    {
                        execute_npc_script( pProgram, pScript, NULL,
                          pChar2, pChar, NULL );
                        b               = TRUE;
                        break;
                    }
                }

                if ( b == TRUE )
                    break;
            }
        }
    }
}


void check_room_trigger( int iType, CHAR_DATA *pChar,
                         ROOM_INDEX_DATA *pRoom, char *pCmp )
{
    PROGRAM_DATA *pProgram;
    SCRIPT_DATA *pScript;
    TRIGGER_DATA *pTrigger;
    TRIGGER_ARG_DATA *pTriggerArg;

    if ( pChar == NULL || IS_NPC( pChar )
      || ( pProgram = pRoom->pProgram ) == NULL )
        return;

    for ( pScript = pProgram->pScripts; pScript; pScript = pScript->pNext )
    {
        bool b                      = FALSE;

        if ( pScript->bDisabled == TRUE
          /* || pScript->bRunning == TRUE */ )
            continue;

        for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
          pTrigger = pTrigger->pNext )
        {
            if ( pTrigger->iTrigger != iType )
                continue;

            for ( pTriggerArg = pTrigger->pArgs; pTriggerArg != NULL;
              pTriggerArg = pTriggerArg->pNext )
            {
                if ( pTriggerArg->iType == 1
                  || ( pTriggerArg->iType == 2
                  && str_compare( pTriggerArg->pArg, pCmp ) == TRUE )
                  || ( pTriggerArg->iType == 3
                  && str_prefix( pTriggerArg->pArg, pCmp ) == TRUE )
                  || ( pTriggerArg->iType == 4
                  && str_infix( pTriggerArg->pArg, pCmp ) == TRUE )
                  || ( pTriggerArg->iType == 5
                  && str_suffix( pTriggerArg->pArg, pCmp ) == TRUE ) )
                {
                    execute_room_script( pProgram, pScript, NULL,
                      pRoom, pChar, NULL );
                    b               = TRUE;
                    break;
                }
            }
                
            if ( b == TRUE )
                break;
        }
    }
}


static char *get_next_arg( char *pStr, int iType )
{
    char *pBuf         = new_buffer( );
    char c;
    int i              = iForcedType;

    pStr               = edit_str( pStr, pBuf, ' ', "," );

    if ( ( c = next_char( pStr ) ) != ',' )
    {
        if ( c != '\0' )
        {
            iExprError = -10;
            return ( EMPTY_STRING );
        }
    }
    else
        pStr           = remove_char_2( pStr );

    iForcedType        = iType;
    _parse_expr( pBuf );
    iForcedType        = i;

    if ( iExprError != 0 )
        return ( EMPTY_STRING );

    return ( pStr );
}


void script_func_capitialize( char *pArgs )
{
    get_next_arg( pArgs, NUMBER_VAR_STRING );

    if ( iExprError != 0 )
        return;

    if ( qvResult.iType == NUMBER_VAR_NUMBER )
    {
        char cBuf[128];

        snprintf( cBuf, 128, "%ld", qvResult.uData.i );

        qvResult.iType   = NUMBER_VAR_STRING;
        qvResult.uData.s = save_string( cBuf );
        return;
    }

    if ( qvResult.iType == NUMBER_VAR_STRING )
    {
        string s         = qvResult.uData.s;

        qvResult.uData.s = save_string( capit( s ) );
        free_string( &s );

        return;
    }

    qvResult.iType       = NUMBER_VAR_STRING;
    qvResult.uData.p     = EMPTY_STRING;
}


void script_func_uncapitialize( char *pArgs )
{
    get_next_arg( pArgs, NUMBER_VAR_STRING );

    if ( iExprError != 0 )
        return;

    if ( qvResult.iType == NUMBER_VAR_NUMBER )
    {
        char cBuf[128];

        snprintf( cBuf, 128, "%ld", qvResult.uData.i );

        qvResult.iType   = NUMBER_VAR_STRING;
        qvResult.uData.s = save_string( cBuf );
        return;
    }

    if ( qvResult.iType == NUMBER_VAR_STRING )
    {
        string s         = qvResult.uData.s;

        qvResult.uData.s = save_string( uncapit( s ) );
        free_string( &s );

        return;
    }

    qvResult.iType       = NUMBER_VAR_STRING;
    qvResult.uData.p     = EMPTY_STRING;
}


void script_func_capitialize_first( char *pArgs )
{
    get_next_arg( pArgs, NUMBER_VAR_STRING );

    if ( iExprError != 0 )
        return;

    if ( qvResult.iType == NUMBER_VAR_NUMBER )
    {
        char cBuf[128];

        snprintf( cBuf, 128, "%ld", qvResult.uData.i );

        qvResult.iType   = NUMBER_VAR_STRING;
        qvResult.uData.s = save_string( cBuf );
        return;
    }

    if ( qvResult.iType == NUMBER_VAR_STRING )
    {
        string s         = qvResult.uData.s;

        qvResult.uData.s = save_string( cap_first( s ) );
        free_string( &s );

        return;
    }

    qvResult.iType       = NUMBER_VAR_STRING;
    qvResult.uData.p     = EMPTY_STRING;
}


void script_func_is_npc( char *pArgs )
{
    get_next_arg( pArgs, NUMBER_VAR_NUMBER );

    if ( iExprError != 0 )
        return;

    if ( qvResult.iType == NUMBER_VAR_POINTER_CHAR )
    {
        qvResult.iType       = NUMBER_VAR_NUMBER;

        if ( qvResult.uData.p == NULL )
            qvResult.uData.i = -1;
        else if ( IS_NPC( (CHAR_DATA *) qvResult.uData.p ) )
            qvResult.uData.i = 1;
        else
            qvResult.uData.i = 0;

        return;
    }
    else if ( qvResult.iType == NUMBER_VAR_STRING )
        free_string( &qvResult.uData.s );

    qvResult.iType           = NUMBER_VAR_NUMBER;
    qvResult.uData.i         = -2;
}


void script_func_is_guest( char *pArgs )
{
    get_next_arg( pArgs, NUMBER_VAR_NUMBER );

    if ( iExprError != 0 )
        return;

    if ( qvResult.iType == NUMBER_VAR_POINTER_CHAR )
    {
        qvResult.iType       = NUMBER_VAR_NUMBER;

        if ( qvResult.uData.p == NULL )
            qvResult.uData.i = -1;
        else if ( !IS_NPC( (CHAR_DATA *) qvResult.uData.p )
          && IS_GUEST( (CHAR_DATA *) qvResult.uData.p ) )
            qvResult.uData.i = 1;
        else
            qvResult.uData.i = 0;

        return;
    }
    else if ( qvResult.iType == NUMBER_VAR_STRING )
        free_string( &qvResult.uData.s );

    qvResult.iType           = NUMBER_VAR_NUMBER;
    qvResult.uData.i         = -2;
}


void script_func_get_char( char *pArgs )
{
    get_next_arg( pArgs, NUMBER_VAR_STRING );

    if ( iExprError != 0 )
        return;

    if ( qvResult.iType == NUMBER_VAR_NUMBER )
    {
        char cBuf[128];

        snprintf( cBuf, 128, "%ld", qvResult.uData.i );

        qvResult.iType   = NUMBER_VAR_STRING;
        qvResult.uData.s = save_string( cBuf );
    }

    if ( qvResult.iType == NUMBER_VAR_STRING )
    {
        CHAR_DATA *pChar = NULL;
        int i;

        for ( i = 0; i < iHashListSize; i++ )
        {
            for ( pChar = ppCharList[i]; pChar; pChar = pChar->pNext )
            {
                if ( IS_NPC( pChar ) )
                {
                    if ( multi_compare_2( qvResult.uData.s,
                      pChar->pNPCData->pNameList ) == TRUE )
                        goto done;
                }
                else
                {
                    if ( multi_compare( qvResult.uData.s,
                      pChar->pPCData->sName ) == TRUE )
                        goto done;
                }
            }
        }

done:
        free_string( &qvResult.uData.s );
        qvResult.iType   = NUMBER_VAR_POINTER_CHAR;
        qvResult.uData.p = pChar;
        return;
    }

    qvResult.iType       = NUMBER_VAR_POINTER_CHAR;
    qvResult.uData.p     = NULL;
}


void script_func_get_pc( char *pArgs )
{
    get_next_arg( pArgs, NUMBER_VAR_STRING );

    if ( iExprError != 0 )
        return;

    if ( qvResult.iType == NUMBER_VAR_NUMBER )
    {
        char cBuf[128];

        snprintf( cBuf, 128, "%ld", qvResult.uData.i );

        qvResult.iType   = NUMBER_VAR_STRING;
        qvResult.uData.s = save_string( cBuf );
    }

    if ( qvResult.iType == NUMBER_VAR_STRING )
    {
        CHAR_DATA *pChar;

        for ( pChar = ppCharList[0]; pChar; pChar = pChar->pNext )
        {
            if ( !IS_NPC( pChar ) && multi_compare( qvResult.uData.s,
              pChar->pPCData->sName ) == TRUE )
                break;
        }

        free_string( &qvResult.uData.s );
        qvResult.iType   = NUMBER_VAR_POINTER_CHAR;
        qvResult.uData.p = pChar;
        return;
    }

    qvResult.iType       = NUMBER_VAR_POINTER_CHAR;
    qvResult.uData.p     = NULL;
}


void script_func_get_npc( char *pArgs )
{
    get_next_arg( pArgs, NUMBER_VAR_STRING );

    if ( iExprError != 0 )
        return;

    if ( qvResult.iType == NUMBER_VAR_NUMBER )
    {
        char cBuf[128];

        snprintf( cBuf, 128, "%ld", qvResult.uData.i );

        qvResult.iType   = NUMBER_VAR_STRING;
        qvResult.uData.s = save_string( cBuf );
    }

    if ( qvResult.iType == NUMBER_VAR_STRING )
    {
        CHAR_DATA *pChar;
        int i;

        for ( pChar = ppCharList[0]; pChar; pChar = pChar->pNext )
        {
            if ( IS_NPC( pChar ) && multi_compare_2( qvResult.uData.s,
              pChar->pNPCData->pNameList ) == TRUE )
                goto done;
        }

        for ( i = 1; i < iHashListSize; i++ )
        {
            for ( pChar = ppCharList[i]; pChar; pChar = pChar->pNext )
            {
                if ( multi_compare_2( qvResult.uData.s,
                  pChar->pNPCData->pNameList ) == TRUE )
                    goto done;
            }
        }

done:
        free_string( &qvResult.uData.s );
        qvResult.iType   = NUMBER_VAR_POINTER_CHAR;
        qvResult.uData.p = pChar;
        return;
    }

    qvResult.iType       = NUMBER_VAR_POINTER_CHAR;
    qvResult.uData.p     = NULL;
}


void script_func_get_char_in_room( char *pArgs )
{
    pArgs                = get_next_arg( pArgs, NUMBER_VAR_STRING );

    if ( iExprError != 0 )
        return;

    if ( qvResult.iType == NUMBER_VAR_NUMBER )
    {
        char cBuf[128];

        snprintf( cBuf, 128, "%ld", qvResult.uData.i );

        qvResult.iType   = NUMBER_VAR_STRING;
        qvResult.uData.s = save_string( cBuf );
    }

    if ( qvResult.iType == NUMBER_VAR_STRING )
    {
        ROOM_INDEX_DATA *pRoom;
        CHAR_DATA *pChar;
        string s         = qvResult.uData.s;

        get_next_arg( pArgs, NUMBER_VAR_NUMBER );

        if ( iExprError != 0 || qvResult.iType != NUMBER_VAR_POINTER_ROOM
          || ( pRoom = qvResult.uData.p ) == NULL )
        {
            free_string( &s );
            goto end;
        }

        for ( pChar = pRoom->pPeople; pChar; pChar = pChar->pNextInRoom )
        {
            if ( IS_NPC( pChar ) )
            {
                if ( multi_compare_2( s, pChar->pNPCData->pNameList )
                  == TRUE )
                    break;
            }
            else
            {
                if ( multi_compare( s, pChar->pPCData->sName ) == TRUE )
                    break;
            }
        }

        free_string( &s );
        qvResult.iType   = NUMBER_VAR_POINTER_CHAR;
        qvResult.uData.p = pChar;
        return;
    }

end:
    qvResult.iType       = NUMBER_VAR_POINTER_CHAR;
    qvResult.uData.p     = NULL;
}


void script_func_get_pc_in_room( char *pArgs )
{
    pArgs                = get_next_arg( pArgs, NUMBER_VAR_STRING );

    if ( iExprError != 0 )
        return;

    if ( qvResult.iType == NUMBER_VAR_NUMBER )
    {
        char cBuf[128];

        snprintf( cBuf, 128, "%ld", qvResult.uData.i );

        qvResult.iType   = NUMBER_VAR_STRING;
        qvResult.uData.s = save_string( cBuf );
    }

    if ( qvResult.iType == NUMBER_VAR_STRING )
    {
        ROOM_INDEX_DATA *pRoom;
        CHAR_DATA *pChar;
        string s         = qvResult.uData.s;

        get_next_arg( pArgs, NUMBER_VAR_NUMBER );

        if ( iExprError != 0 || qvResult.iType != NUMBER_VAR_POINTER_ROOM
          || ( pRoom = qvResult.uData.p ) == NULL )
        {
            free_string( &s );
            goto end;
        }

        for ( pChar = pRoom->pPeople; pChar; pChar = pChar->pNextInRoom )
        {
            if ( !IS_NPC( pChar )
              && multi_compare( s, pChar->pPCData->sName ) == TRUE )
                    break;
        }

        free_string( &s );
        qvResult.iType   = NUMBER_VAR_POINTER_CHAR;
        qvResult.uData.p = pChar;
        return;
    }

end:
    qvResult.iType       = NUMBER_VAR_POINTER_CHAR;
    qvResult.uData.p     = NULL;
}


void script_func_get_npc_in_room( char *pArgs )
{
    pArgs                = get_next_arg( pArgs, NUMBER_VAR_STRING );

    if ( iExprError != 0 )
        return;

    if ( qvResult.iType == NUMBER_VAR_NUMBER )
    {
        char cBuf[128];

        snprintf( cBuf, 128, "%ld", qvResult.uData.i );

        qvResult.iType   = NUMBER_VAR_STRING;
        qvResult.uData.s = save_string( cBuf );
    }

    if ( qvResult.iType == NUMBER_VAR_STRING )
    {
        ROOM_INDEX_DATA *pRoom;
        CHAR_DATA *pChar;
        string s         = qvResult.uData.s;

        get_next_arg( pArgs, NUMBER_VAR_NUMBER );

        if ( iExprError != 0 || qvResult.iType != NUMBER_VAR_POINTER_ROOM
          || ( pRoom = qvResult.uData.p ) == NULL )
        {
            free_string( &s );
            goto end;
        }

        for ( pChar = pRoom->pPeople; pChar; pChar = pChar->pNextInRoom )
        {
            if ( IS_NPC( pChar )
              && multi_compare_2( s, pChar->pNPCData->pNameList ) == TRUE )
                break;
        }

        free_string( &s );
        qvResult.iType   = NUMBER_VAR_POINTER_CHAR;
        qvResult.uData.p = pChar;
        return;
    }

end:
    qvResult.iType       = NUMBER_VAR_POINTER_CHAR;
    qvResult.uData.p     = NULL;
}


void script_func_get_room( char *pArgs )
{
    get_next_arg( pArgs, NUMBER_VAR_NUMBER );

    if ( iExprError != 0 )
        return;

    if ( qvResult.iType == NUMBER_VAR_STRING )
    {
        string s             = qvResult.uData.s;

        qvResult.iType       = NUMBER_VAR_NUMBER;
        qvResult.uData.i     = atol( s );
        free_string( &s );
    }

    if ( qvResult.iType == NUMBER_VAR_NUMBER )
    {
        qvResult.iType       = NUMBER_VAR_POINTER_ROOM;

        if ( qvResult.uData.i > 5 && qvResult.uData.i <= MAX_INDEX_NUMBER )
            qvResult.uData.p = get_room_index( qvResult.uData.i );
        else
            qvResult.uData.p = NULL;

        return;
    }
    else if ( qvResult.iType == NUMBER_VAR_STRING )
        free_string( &qvResult.uData.s );

    qvResult.iType           = NUMBER_VAR_POINTER_ROOM;
    qvResult.uData.p         = NULL;
}


/*
 * End of script.c
 */