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