/*
* 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.
*/
/*
* My NPC/object/room loading system is a bit slow, as you might have
* noticed, this is because I did not put a high priority on bootup
* speed but rather on ease of adding fields to NPC/object/room files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "sapphire.h"
/*
* Prototypes
*/
static bool load_dir_desc ( ROOM_INDEX_DATA *, FILE *, int );
static bool load_exit ( ROOM_INDEX_DATA *, FILE *, int );
static int get_obj_reset_list ( char **, OBJ_RESET_DATA ** );
/*
* Functions
*/
bool npc_load_inherit( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
pNPCIndex->iInherit = fget_number_2( pFile );
if ( pNPCIndex->iInherit <= 5
|| pNPCIndex->iInherit > MAX_INDEX_NUMBER )
sap_fatal( "NPC %d: Illegal NPC number `%d' for inherit.",
pNPCIndex->iNumber, pNPCIndex->iInherit );
return ( FALSE );
}
bool npc_load_imagefilename( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
return ( FALSE );
}
bool npc_load_names( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
int i;
for ( i = 0; pNPCIndex->pNameList[i] != NULL; i++ )
free_string( &pNPCIndex->pNameList[i] );
free_mem( (void **) &pNPCIndex->pNameList );
pNPCIndex->pNameList = alloc_mem( ( sizeof( string ) * 2 ) );
pNPCIndex->pNameList[0] = save_string( fget_string( pFile ) );
pNPCIndex->pNameList[1] = NULL;
return ( FALSE );
}
bool npc_load_shortdesc( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
free_string( &pNPCIndex->sShortDesc );
pNPCIndex->sShortDesc = save_string( fget_string( pFile ) );
return ( FALSE );
}
bool npc_load_desc( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
free_string( &pNPCIndex->sDescs[0] );
free_string( &pNPCIndex->sDescs[1] );
free_string( &pNPCIndex->sDescs[2] );
free_string( &pNPCIndex->sDescs[3] );
free_string( &pNPCIndex->sDescs[4] );
pNPCIndex->sDescs[0] = save_string( fget_string( pFile ) );
pNPCIndex->sDescs[1] = save_string( pNPCIndex->sDescs[0] );
pNPCIndex->sDescs[2] = save_string( pNPCIndex->sDescs[0] );
pNPCIndex->sDescs[3] = save_string( pNPCIndex->sDescs[0] );
pNPCIndex->sDescs[4] = save_string( pNPCIndex->sDescs[0] );
return ( FALSE );
}
bool npc_load_desc1( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
free_string( &pNPCIndex->sDescs[0] );
pNPCIndex->sDescs[0] = save_string( fget_string( pFile ) );
return ( FALSE );
}
bool npc_load_desc2( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
free_string( &pNPCIndex->sDescs[1] );
pNPCIndex->sDescs[1] = save_string( fget_string( pFile ) );
return ( FALSE );
}
bool npc_load_desc3( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
free_string( &pNPCIndex->sDescs[2] );
pNPCIndex->sDescs[2] = save_string( fget_string( pFile ) );
return ( FALSE );
}
bool npc_load_desc4( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
free_string( &pNPCIndex->sDescs[3] );
pNPCIndex->sDescs[3] = save_string( fget_string( pFile ) );
return ( FALSE );
}
bool npc_load_desc5( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
free_string( &pNPCIndex->sDescs[4] );
pNPCIndex->sDescs[4] = save_string( fget_string( pFile ) );
return ( FALSE );
}
bool npc_load_longdesc( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
char cBuf[MAX_INPUT];
char *pString;
char *pBuf;
bool bWarn = FALSE;
pString = fget_string( pFile );
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
if ( str_compare( cBuf, "FORMAT" ) == TRUE )
pString = format_string( pString );
else
{
sap_warning( "NPC %d: Unknown string flag `%s'.",
pNPCIndex->iNumber, cBuf );
bWarn = TRUE;
}
}
free_string( &pNPCIndex->sLongDesc );
pNPCIndex->sLongDesc = save_string( pString );
return ( bWarn );
}
bool npc_load_npcflags( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
char cBuf[MAX_STRING];
char *pBuf;
int i;
bool bWarn = FALSE;
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
for ( i = 0; snNPCFlagsTable[i].pName[0] != '\0'; i++ )
{
if ( str_compare( snNPCFlagsTable[i].pName, cBuf ) == TRUE )
{
SET_FLAG( pNPCIndex->fNPCFlags,
snNPCFlagsTable[i].iNumber );
break;
}
}
if ( snNPCFlagsTable[i].pName[0] == '\0' )
{
sap_warning( "NPC %d: Unknown NPC flag `%s'.",
pNPCIndex->iNumber, cBuf );
bWarn = TRUE;
}
}
return ( bWarn );
}
bool npc_load_partflags( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
char cBuf[MAX_STRING];
char *pBuf;
int i;
bool bWarn = FALSE;
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
for ( i = 0; snPartFlagsTable[i].pName[0] != '\0'; i++ )
{
if ( str_compare( snPartFlagsTable[i].pName, cBuf ) == TRUE )
{
SET_FLAG( pNPCIndex->fPartFlags,
snPartFlagsTable[i].iNumber );
break;
}
}
if ( snPartFlagsTable[i].pName[0] == '\0' )
{
sap_warning( "NPC %d: Unknown part flag `%s'.",
pNPCIndex->iNumber, cBuf );
bWarn = TRUE;
}
}
return ( bWarn );
}
bool npc_load_actflags( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
char cBuf[MAX_STRING];
char *pBuf;
int i;
bool bWarn = FALSE;
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
for ( i = 0; snActFlagsTable[i].pName[0] != '\0'; i++ )
{
if ( str_compare( snActFlagsTable[i].pName, cBuf ) == TRUE )
{
SET_FLAG( pNPCIndex->fActFlags,
snActFlagsTable[i].iNumber );
break;
}
}
if ( snActFlagsTable[i].pName[0] == '\0' )
{
sap_warning( "NPC %d: Unknown action flag `%s'.",
pNPCIndex->iNumber, cBuf );
bWarn = TRUE;
}
}
return ( bWarn );
}
bool npc_load_race( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
char *pRace;
int i;
if ( ( pNPCIndex->iRace = get_race_number(
( pRace = fget_word_2( pFile ) ) ) ) == 0 )
{
sap_warning( "NPC %d: Unknown race `%s'.", pNPCIndex->iNumber,
pRace );
pNPCIndex->iRace = rRaceTable[0].iNumber;
return ( TRUE );
}
for ( i = 0; rRaceTable[i].pName[0] != '\0'; i++ )
{
if ( rRaceTable[i].iNumber == pNPCIndex->iRace )
{
pNPCIndex->fActFlags |= rRaceTable[i].fActFlags;
break;
}
}
return ( FALSE );
}
bool npc_load_sex( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
char *pSex;
if ( ( pNPCIndex->iSex = get_sex_number(
( pSex = fget_word_2( pFile ) ) ) ) == 0 )
{
sap_warning( "NPC %d: Unknown sex `%s'.",
pNPCIndex->iNumber, pSex );
pNPCIndex->iSex = snSexTable[0].iNumber;
return ( TRUE );
}
return ( FALSE );
}
bool npc_load_haircolor( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
char *pHairColor;
if ( ( pNPCIndex->iHairColor = get_hair_color_number(
( pHairColor = fget_word_2( pFile ) ) ) ) == 0 )
{
sap_warning( "NPC %d: Unknown hair color `%s'.",
pNPCIndex->iNumber, pHairColor );
pNPCIndex->iHairColor = snHairColorTable[0].iNumber;
return ( TRUE );
}
return ( FALSE );
}
bool npc_load_eyecolor( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
char *pEyeColor;
if ( ( pNPCIndex->iEyeColor = get_hair_color_number(
( pEyeColor = fget_word_2( pFile ) ) ) ) == 0 )
{
sap_warning( "NPC %d: Unknown eye color `%s'.",
pNPCIndex->iNumber, pEyeColor );
pNPCIndex->iEyeColor = snEyeColorTable[0].iNumber;
return ( TRUE );
}
return ( FALSE );
}
bool npc_load_height( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
pNPCIndex->iHeight = fget_number_2( pFile );
return ( FALSE );
}
bool npc_load_weight( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
pNPCIndex->iWeight = fget_number_2( pFile );
return ( FALSE );
}
bool npc_load_maxcarry( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
pNPCIndex->iMaxCarry = fget_number_2( pFile );
if ( pNPCIndex->iMaxCarry < 0 )
{
sap_warning( "NPC %d: Max carry weight less then 0.",
pNPCIndex->iNumber );
pNPCIndex->iMaxCarry = 1;
return ( TRUE );
}
return ( FALSE );
}
bool npc_load_level( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
pNPCIndex->iLevel = fget_number_2( pFile );
if ( pNPCIndex->iLevel > MAX_PLAYER_LEVEL )
{
sap_warning( "NPC %d: Level greater then %d.",
pNPCIndex->iNumber, MAX_PLAYER_LEVEL );
pNPCIndex->iLevel = MAX_PLAYER_LEVEL;
return ( TRUE );
}
if ( pNPCIndex->iLevel < 1 )
{
sap_warning( "NPC %d: Level less then 1.", pNPCIndex->iNumber );
pNPCIndex->iLevel = 1;
return ( TRUE );
}
return ( FALSE );
}
bool npc_load_experience( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
bool bWarn = FALSE;
pNPCIndex->iExp[0] = fget_number_2( pFile );
if ( pNPCIndex->iExp[0] > 100 )
{
sap_warning( "NPC %d: Number of dice greater then 100.",
pNPCIndex->iNumber );
pNPCIndex->iExp[0] = 100;
bWarn = TRUE;
}
if ( pNPCIndex->iExp[0] < 0 )
{
sap_warning( "NPC %d: Number of dice less then 0.",
pNPCIndex->iNumber );
pNPCIndex->iExp[0] = 0;
bWarn = TRUE;
}
if ( fget_letter( pFile ) != 'd' )
{
sap_warning( "NPC %d: Incomplete dice.", pNPCIndex->iNumber );
bWarn = TRUE;
goto end;
}
pNPCIndex->iExp[1] = fget_number_2( pFile );
if ( pNPCIndex->iExp[1] > 100 )
{
sap_warning( "NPC %d: Dice sides greater then 100.",
pNPCIndex->iNumber );
pNPCIndex->iExp[1] = 100;
bWarn = TRUE;
}
if ( pNPCIndex->iExp[1] < 0 )
{
sap_warning( "NPC %d: Dice sides less then 0.",
pNPCIndex->iNumber );
pNPCIndex->iExp[1] = 0;
bWarn = TRUE;
}
if ( fget_letter( pFile ) != '+' )
{
sap_warning( "NPC %d: Incomplete dice.", pNPCIndex->iNumber );
bWarn = TRUE;
goto end;
}
pNPCIndex->iExp[2] = fget_number_2( pFile );
if ( pNPCIndex->iExp[2] > 1000 )
{
sap_warning( "NPC %d: Dice modifier greater then 1000.",
pNPCIndex->iNumber );
pNPCIndex->iExp[2] = 100;
bWarn = TRUE;
}
if ( pNPCIndex->iExp[2] < 0 )
{
sap_warning( "NPC %d: Dice modifier less then 0.",
pNPCIndex->iNumber );
pNPCIndex->iExp[2] = 0;
bWarn = TRUE;
}
end:
return ( bWarn );
}
bool npc_load_alignment( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
pNPCIndex->iAlignment = fget_number_2( pFile );
if ( pNPCIndex->iAlignment > 1000 )
{
sap_warning( "NPC %d: Level greater then 1000.",
pNPCIndex->iNumber );
pNPCIndex->iAlignment = 1000;
return ( TRUE );
}
if ( pNPCIndex->iAlignment < -1000 )
{
sap_warning( "NPC %d: Level less then -1000.",
pNPCIndex->iNumber );
pNPCIndex->iAlignment = -1000;
return ( TRUE );
}
return ( FALSE );
}
bool npc_load_position( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
char *pBuf;
int i;
pBuf = fget_word_2( pFile );
for ( i = 0; snPositionTable[i].pName[0] != '\0'; i++ )
{
if ( str_compare( snPositionTable[i].pName, pBuf ) == TRUE )
{
pNPCIndex->iPosition = snPositionTable[i].iNumber;
return ( FALSE );
}
}
sap_warning( "NPC %d: Unknown position `%s'.", pNPCIndex->iNumber,
pBuf );
pNPCIndex->iPosition = NUMBER_POSITION_STANDING;
return ( TRUE );
}
bool npc_load_gold( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
pNPCIndex->iGold = fget_number_2( pFile );
return ( FALSE );
}
bool npc_load_wander( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
pNPCIndex->iWander = fget_number_2( pFile );
if ( pNPCIndex->iWander > 100 )
{
sap_warning( "NPC %d: Percent chance of wander greater then 100.",
pNPCIndex->iNumber );
pNPCIndex->iWander = 100;
return ( TRUE );
}
if ( pNPCIndex->iWander < 0 )
{
sap_warning( "NPC %d: Percent chance of wander less then 0.",
pNPCIndex->iNumber );
pNPCIndex->iWander = 0;
return ( TRUE );
}
return ( FALSE );
}
bool npc_load_stats( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
char cBuf[MAX_INPUT];
char *pBuf;
char c;
int iNumber;
bool bWarn = FALSE;
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
if ( str_compare( cBuf, "STR" ) == TRUE )
{
pBuf = edit_str( pBuf, cBuf, ' ', "dD\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Number of dice greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Number of dice less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatStr[0] = iNumber;
if ( LOWER( ( c = next_char( pBuf ) ) ) != 'd' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, c, "+\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Dice sides greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice sides less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatStr[1] = iNumber;
if ( next_char( pBuf ) != '+' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, '+', "\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 2000 )
{
sap_warning( "NPC %d: Dice modifier greater then 2000.",
pNPCIndex->iNumber );
iNumber = 2000;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice modifier less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatStr[2] = iNumber;
}
else if ( str_compare( cBuf, "INT" ) == TRUE )
{
pBuf = edit_str( pBuf, cBuf, ' ', "dD\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Number of dice greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Number of dice less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatInt[0] = iNumber;
if ( LOWER( ( c = next_char( pBuf ) ) ) != 'd' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, c, "+\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Dice sides greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice sides less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatInt[1] = iNumber;
if ( next_char( pBuf ) != '+' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, '+', "\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 2000 )
{
sap_warning( "NPC %d: Dice modifier greater then 2000.",
pNPCIndex->iNumber );
iNumber = 2000;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice modifier less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatInt[2] = iNumber;
}
else if ( str_compare( cBuf, "WIS" ) == TRUE )
{
pBuf = edit_str( pBuf, cBuf, ' ', "dD\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Number of dice greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Number of dice less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatWis[0] = iNumber;
if ( LOWER( ( c = next_char( pBuf ) ) ) != 'd' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, c, "+\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Dice sides greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice sides less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatWis[1] = iNumber;
if ( next_char( pBuf ) != '+' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, '+', "\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 2000 )
{
sap_warning( "NPC %d: Dice modifier greater then 2000.",
pNPCIndex->iNumber );
iNumber = 2000;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice modifier less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatWis[2] = iNumber;
}
else if ( str_compare( cBuf, "DEX" ) == TRUE )
{
pBuf = edit_str( pBuf, cBuf, ' ', "dD\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Number of dice greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Number of dice less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatDex[0] = iNumber;
if ( LOWER( ( c = next_char( pBuf ) ) ) != 'd' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, c, "+\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Dice sides greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice sides less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatDex[1] = iNumber;
if ( next_char( pBuf ) != '+' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, '+', "\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 2000 )
{
sap_warning( "NPC %d: Dice modifier greater then 2000.",
pNPCIndex->iNumber );
iNumber = 2000;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice modifier less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatDex[2] = iNumber;
}
else if ( str_compare( cBuf, "CON" ) == TRUE )
{
pBuf = edit_str( pBuf, cBuf, ' ', "dD\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Number of dice greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Number of dice less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatCon[0] = iNumber;
if ( LOWER( ( c = next_char( pBuf ) ) ) != 'd' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, c, "+\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Dice sides greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice sides less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatCon[1] = iNumber;
if ( next_char( pBuf ) != '+' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, '+', "+\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 2000 )
{
sap_warning( "NPC %d: Dice modifier greater then 2000.",
pNPCIndex->iNumber );
iNumber = 2000;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice modifier less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatCon[2] = iNumber;
}
else if ( str_compare( cBuf, "CHA" ) == TRUE )
{
pBuf = edit_str( pBuf, cBuf, ' ', "dD\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Number of dice greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Number of dice less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatCha[0] = iNumber;
if ( LOWER( ( c = next_char( pBuf ) ) ) != 'd' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, c, "+\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Dice sides greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice sides less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatCha[1] = iNumber;
if ( next_char( pBuf ) != '+' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, '+', "\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 2000 )
{
sap_warning( "NPC %d: Dice modifier greater then 2000.",
pNPCIndex->iNumber );
iNumber = 2000;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice modifier less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatCha[2] = iNumber;
}
else if ( str_compare( cBuf, "LUC" ) == TRUE )
{
pBuf = edit_str( pBuf, cBuf, ' ', "dD\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Number of dice greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Number of dice less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatLuc[0] = iNumber;
if ( LOWER( ( c = next_char( pBuf ) ) ) != 'd' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, c, "+\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Dice sides greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice sides less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatLuc[1] = iNumber;
if ( next_char( pBuf ) != '+' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, '+', "\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 2000 )
{
sap_warning( "NPC %d: Dice modifier greater then 2000.",
pNPCIndex->iNumber );
iNumber = 2000;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice modifier less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatLuc[2] = iNumber;
}
else if ( str_compare( cBuf, "HP" ) == TRUE )
{
pBuf = edit_str( pBuf, cBuf, ' ', "dD\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Number of dice greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Number of dice less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatHP[0] = iNumber;
if ( LOWER( ( c = next_char( pBuf ) ) ) != 'd' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, c, "+\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Dice sides greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice sides less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatHP[1] = iNumber;
if ( next_char( pBuf ) != '+' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, '+', "\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 2000 )
{
sap_warning( "NPC %d: Dice modifier greater then 2000.",
pNPCIndex->iNumber );
iNumber = 2000;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice modifier less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatHP[2] = iNumber;
}
else if ( str_compare( cBuf, "MP" ) == TRUE )
{
pBuf = edit_str( pBuf, cBuf, ' ', "dD\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Number of dice greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Number of dice less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatMP[0] = iNumber;
if ( LOWER( ( c = next_char( pBuf ) ) ) != 'd' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, c, "+\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Dice sides greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice sides less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatMP[1] = iNumber;
if ( next_char( pBuf ) != '+' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, '+', "\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 2000 )
{
sap_warning( "NPC %d: Dice modifier greater then 2000.",
pNPCIndex->iNumber );
iNumber = 2000;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice modifier less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatMP[2] = iNumber;
}
else if ( str_compare( cBuf, "MV" ) == TRUE )
{
pBuf = edit_str( pBuf, cBuf, ' ', "dD\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Number of dice greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Number of dice less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatMV[0] = iNumber;
if ( LOWER( ( c = next_char( pBuf ) ) ) != 'd' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, c, "+\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 100 )
{
sap_warning( "NPC %d: Dice sides greater then 100.",
pNPCIndex->iNumber );
iNumber = 100;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice sides less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatMV[1] = iNumber;
if ( next_char( pBuf ) != '+' )
{
sap_warning( "NPC %d: Incomplete dice.",
pNPCIndex->iNumber );
bWarn = TRUE;
continue;
}
pBuf = edit_str( pBuf, cBuf, '+', "\n\r\t " );
iNumber = atoi( cBuf );
if ( iNumber > 2000 )
{
sap_warning( "NPC %d: Dice modifier greater then 2000.",
pNPCIndex->iNumber );
iNumber = 2000;
bWarn = TRUE;
}
if ( iNumber < 0 )
{
sap_warning( "NPC %d: Dice modifier less then 0.",
pNPCIndex->iNumber );
iNumber = 0;
bWarn = TRUE;
}
pNPCIndex->VarStats.iStatMV[2] = iNumber;
}
else
{
pBuf = edit_str( pBuf, cBuf, ' ', "\n\r\t " );
sap_warning( "NPC %d: Unknown stat `%s'.",
pNPCIndex->iNumber, cBuf );
bWarn = TRUE;
}
}
return ( bWarn );
}
bool npc_load_program( NPC_INDEX_DATA *pNPCIndex, FILE *pFile )
{
PROGRAM_DATA *pProgram;
SCRIPT_DATA *pScript;
TRIGGER_DATA *pTrigger;
TRIGGER_ARG_DATA *pTriggerArg;
char *pStr = fget_string_3( pFile, '{', '}' );
char *pBak = pStr;
char cBuf[MAX_STRING];
char cBuf2[MAX_STRING];
char *pBuf;
char c;
int i;
bool bWarn = FALSE;
pProgram = alloc_mem( sizeof( *pProgram ) );
pNPCIndex->pProgram = pProgram;
while ( next_char( pStr ) != '\0' )
{
pStr = edit_str( pStr, cBuf, ' ', "\n\r\t " );
if ( str_compare( cBuf, "TRIGGER" ) == TRUE )
{
pStr = edit_str( pStr, cBuf, ' ', "\n\r\t " );
for ( pScript = pProgram->pScripts; pScript != NULL;
pScript = pScript->pNext )
{
if ( str_compare( pScript->pName, cBuf ) == TRUE )
break;
}
if ( pScript != NULL )
{
sap_error(
"NPC %d: Multiple blocks with the name `%s' in script.",
pNPCIndex->iNumber, cBuf );
bWarn = TRUE;
goto end;
}
pScript = alloc_mem( sizeof( *pScript ) );
pScript->pName = str_dup( cBuf );
pStr = edit_str( pStr, cBuf, ' ', "\n\r\t " );
if ( str_compare( cBuf, "enabled" ) == TRUE )
pScript->bDisabled = FALSE;
else if ( str_compare( cBuf, "disabled" ) == TRUE )
pScript->bDisabled = TRUE;
else
{
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error( "NPC %d: Unknown enabled flag in script.",
pNPCIndex->iNumber );
bWarn = TRUE;
goto end;
}
do
{
pStr = edit_str( pStr, cBuf, ' ', "(\n\r\t " );
if ( next_char( pStr ) != '(' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"NPC %d: Trigger missing `(' symbol in script.",
pNPCIndex->iNumber );
bWarn = TRUE;
goto end;
}
for ( i = 0; snNPCScriptTriggerTable[i].pName[0] != '\0';
i++ )
{
if ( str_compare( cBuf,
snNPCScriptTriggerTable[i].pName ) == TRUE )
break;
}
if ( snNPCScriptTriggerTable[i].pName[0] == '\0' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"NPC %d: Unknown trigger type `%s' in script.",
pNPCIndex->iNumber, cBuf );
bWarn = TRUE;
goto end;
}
pTrigger = alloc_mem( sizeof( *pTrigger ) );
pTrigger->iTrigger = snNPCScriptTriggerTable[i].iNumber;
pStr = edit_str( pStr, cBuf, '(', ")" );
pBuf = remove_spaces( cBuf );
if ( next_char( pStr ) != ')' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
free_mem( (void **) &pTrigger );
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"NPC %d: Trigger missing `)' symbol in script.",
pNPCIndex->iNumber );
bWarn = TRUE;
goto end;
}
switch ( pTrigger->iTrigger )
{
case NUMBER_NPC_TRIGGER_CREATED:
break;
case NUMBER_NPC_TRIGGER_RANDOM :
if ( is_number( pBuf ) != TRUE )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
free_mem( (void **) &pTrigger );
for ( pTrigger = pScript->pTriggers; pTrigger;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs;
pTriggerArg; pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_warning( "NPC %d: Non-number argument for "
"trigger in script.", pNPCIndex->iNumber );
bWarn = TRUE;
goto end;
}
pTriggerArg = alloc_mem( sizeof( *pTriggerArg ) );
pTriggerArg->pArg = alloc_mem( 1 );
*( (intt *) pTriggerArg->pArg ) = (intt) atoi( pBuf );
pTrigger->pArgs = pTriggerArg;
break;
case NUMBER_NPC_TRIGGER_MESSAGE:
case NUMBER_NPC_TRIGGER_EMOTE :
case NUMBER_NPC_TRIGGER_SAY :
case NUMBER_NPC_TRIGGER_TELL :
case NUMBER_NPC_TRIGGER_YELL :
if ( str_compare( pBuf, "all" ) == TRUE )
{
pTriggerArg = alloc_mem( sizeof( *pTriggerArg ) );
pTriggerArg->iType = 1;
pTriggerArg->pArg = EMPTY_STRING;
pTrigger->pArgs = pTriggerArg;
break;
}
while ( *pBuf != '\0' )
{
pTriggerArg = alloc_mem( sizeof( *pTriggerArg ) );
pBuf = edit_str( pBuf, cBuf2, ' ', "\n\r\t " );
if ( next_char( pBuf ) == '"' )
{
if ( str_compare( cBuf2, "exact" ) == TRUE )
pTriggerArg->iType = 2;
else if ( str_compare( cBuf2, "prefix" )
== TRUE )
pTriggerArg->iType = 3;
else if ( str_compare( cBuf2, "infix" )
== TRUE )
pTriggerArg->iType = 4;
else if ( str_compare( cBuf2, "suffix" )
== TRUE )
pTriggerArg->iType = 5;
else
{
sap_warning( "NPC %d: Unknown comparison "
"type for trigger argument in script.",
pNPCIndex->iNumber );
bWarn = TRUE;
pTriggerArg->iType = 2;
continue;
}
pBuf = make_string( pBuf, cBuf2 );
pBuf = remove_char_2( pBuf );
if ( cBuf2[0] == '\0' )
{
sap_warning( "NPC %d: Empty string for "
"trigger argument in script.",
pNPCIndex->iNumber );
bWarn = TRUE;
pTriggerArg->pArg = EMPTY_STRING;
continue;
}
pTriggerArg->pArg = str_dup( cBuf2 );
}
if ( ( c = next_char( pBuf ) ) == ',' )
pBuf = remove_char_2( pBuf );
else if ( c != '\0' )
{
sap_warning( "NPC %d: Missing `,' for "
"trigger argument list in script.",
pNPCIndex->iNumber );
bWarn = TRUE;
}
pTriggerArg->pNext = pTrigger->pArgs;
pTrigger->pArgs = pTriggerArg;
}
break;
default :
pTriggerArg = alloc_mem( sizeof( *pTriggerArg ) );
pTriggerArg->pArg = str_dup( pBuf );
pTrigger->pArgs = pTriggerArg;
break;
}
pStr = remove_char_2( pStr );
pTrigger->pNext = pScript->pTriggers;
pScript->pTriggers = pTrigger;
}
while ( ( c = next_char( pStr ) ) != '{' && c != '\0' );
if ( next_char( pStr ) != '{' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"NPC %d: Trigger missing `{' symbol in script.",
pNPCIndex->iNumber );
bWarn = TRUE;
break;
}
pStr = edit_str_plus( pStr, cBuf, '{', '}' );
if ( next_char( pStr ) != '}' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"NPC %d: Trigger missing `}' symbol in script.",
pNPCIndex->iNumber );
bWarn = TRUE;
break;
}
pStr = remove_char_2( pStr );
pScript->pScript = alloc_mem( ( i = npc_script_translate(
pScript, cBuf ) ) );
memcpy( pScript->pScript, cBuf, i );
pScript->iCodeSize = i;
pScript->pNext = pProgram->pScripts;
pProgram->pScripts = pScript;
}
else if ( str_compare( cBuf, "USES" ) == TRUE )
{
GENERIC_DATA *pGen;
QUEST_DATA *pQuestData;
char *pBuf2;
char c;
pStr = edit_str( pStr, cBuf, ' ', ";" );
if ( *pStr != ';' )
{
sap_error(
"NPC %d: Syntax error in script quest data reference.",
pNPCIndex->iNumber );
bWarn = TRUE;
goto end;
}
pStr++;
pBuf2 = cBuf;
do
{
pBuf2 = edit_str( pBuf2, cBuf2, ' ', ",\n\r\t " );
if ( ( c = next_char( pBuf2 ) ) != ',' && c != '\0' )
{
sap_error( "NPC %d: "
"Syntax error in script quest data reference.",
pNPCIndex->iNumber );
bWarn = TRUE;
goto end;
}
else if ( c == ',' )
pBuf2 = remove_char_2( pBuf2 );
for ( pQuestData = pQuestDataList; pQuestData != NULL;
pQuestData = pQuestData->pNext )
{
if ( strcmp( pQuestData->sName, cBuf2 ) == 0 )
{
for ( pGen = pProgram->pQuestDataList; pGen;
pGen = pGen->pNext )
{
if ( pGen->pData == pQuestData )
break;
}
if ( pGen != NULL )
{
sap_warning(
"NPC %d: Multiply referenced quest data.",
pNPCIndex->iNumber );
bWarn = TRUE;
break;
}
pGen = alloc_mem( sizeof( *pGen ) );
pGen->pData = pQuestData;
pGen->pNext = pProgram->pQuestDataList;
pProgram->pQuestDataList = pGen;
break;
}
}
}
while ( next_char( pBuf2 ) != '\0' );
}
else
{
QUEST_VAR_DATA *pVar;
pVar = alloc_mem( sizeof( *pVar ) );
if ( str_compare( cBuf, "number" ) == TRUE )
pVar->iType = NUMBER_VAR_NUMBER;
else if ( str_compare( cBuf, "string" ) == TRUE )
pVar->iType = NUMBER_VAR_STRING;
else if ( str_compare( cBuf, "character_pointer" ) == TRUE )
pVar->iType = NUMBER_VAR_POINTER_CHAR;
else if ( str_compare( cBuf, "object_pointer" ) == TRUE )
pVar->iType = NUMBER_VAR_POINTER_OBJ;
else if ( str_compare( cBuf, "room_pointer" ) == TRUE )
pVar->iType = NUMBER_VAR_POINTER_ROOM;
else
{
free_mem( (void **) &pVar );
sap_error( "NPC %d: Unknown keyword `%s' in script.",
pNPCIndex->iNumber, cBuf );
bWarn = TRUE;
break;
}
pStr = edit_str( pStr, cBuf, ' ', ";\n\r\t " );
if ( next_char( pStr ) != ';' )
{
free_mem( (void **) &pVar );
sap_error(
"NPC %d: Syntax error in script variable declaration.",
pNPCIndex->iNumber );
bWarn = TRUE;
goto end;
}
pStr = remove_char_2( pStr );
if ( cBuf[0] == '\0' || ( !isalpha( cBuf[0] )
&& cBuf[0] != '_' ) )
{
free_mem( (void **) &pVar );
sap_error( "NPC %d: Illegal name for script variable.",
pNPCIndex->iNumber );
bWarn = TRUE;
goto end;
}
for ( i = 0; cBuf[i] != '\0'; i++ )
{
if ( !isalnum( cBuf[i] ) && cBuf[i] != '_' )
{
free_mem( (void **) &pVar );
sap_error( "NPC %d: Illegal name for script variable.",
pNPCIndex->iNumber );
bWarn = TRUE;
goto end;
}
}
pVar->sName = save_string( cBuf );
if ( pVar->iType == NUMBER_VAR_STRING )
pVar->uData.s = EMPTY_STRING;
pVar->pNext = pProgram->pQuestVars;
pProgram->pQuestVars = pVar;
}
}
end:
if ( pBak != EMPTY_STRING )
free_mem( (void **) &pBak );
return ( bWarn );
}
bool obj_load_inherit( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
pObjIndex->iInherit = fget_number_2( pFile );
if ( pObjIndex->iInherit <= 5
|| pObjIndex->iInherit > MAX_INDEX_NUMBER )
sap_fatal( "Object %d: Illegal object number `%d' for inherit.",
pObjIndex->iNumber, pObjIndex->iInherit );
return ( FALSE );
}
bool obj_load_imagefilename( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
return ( FALSE );
}
bool obj_load_names( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
int i;
for ( i = 0; pObjIndex->pNameList[i] != NULL; i++ )
free_string( &pObjIndex->pNameList[i] );
free_mem( (void **) &pObjIndex->pNameList );
pObjIndex->pNameList = alloc_mem( ( sizeof( string ) * 2 ) );
pObjIndex->pNameList[0] = save_string( fget_string( pFile ) );
pObjIndex->pNameList[1] = NULL;
return ( FALSE );
}
bool obj_load_shortdesc( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
free_string( &pObjIndex->sShortDesc );
pObjIndex->sShortDesc = save_string( fget_string( pFile ) );
return ( FALSE );
}
bool obj_load_desc( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
free_string( &pObjIndex->sDesc );
pObjIndex->sDesc = save_string( fget_string( pFile ) );
return ( FALSE );
}
bool obj_load_longdesc( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
char cBuf[MAX_INPUT];
char *pString;
char *pBuf;
bool bWarn = FALSE;
pString = fget_string( pFile );
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
if ( str_compare( cBuf, "FORMAT" ) == TRUE )
pString = format_string( pString );
else
{
sap_warning( "Object %d: Unknown string flag `%s'.",
pObjIndex->iNumber, cBuf );
bWarn = TRUE;
}
}
free_string( &pObjIndex->sLongDesc );
pObjIndex->sLongDesc = save_string( pString );
return ( bWarn );
}
bool obj_load_itemtype( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
char *pBuf = fget_word_2( pFile );
int i;
for ( i = 0; snItemTypeTable[i].pName[0] != '\0'; i++ )
{
if ( str_compare( snItemTypeTable[i].pName, pBuf ) == TRUE )
{
pObjIndex->iItemType = snItemTypeTable[i].iNumber;
break;
}
}
if ( snItemTypeTable[i].pName[0] == '\0' )
{
sap_error( "Object %d: Unknown item type `%s'.",
pObjIndex->iNumber, pBuf );
return ( TRUE );
}
return ( FALSE );
}
bool obj_load_objectflags( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
char cBuf[MAX_STRING];
char *pBuf;
int i;
bool bWarn = FALSE;
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
for ( i = 0; snObjectFlagsTable[i].pName[0] != '\0'; i++ )
{
if ( str_compare( snObjectFlagsTable[i].pName, cBuf )
== TRUE )
{
SET_FLAG( pObjIndex->fObjFlags,
snObjectFlagsTable[i].iNumber );
break;
}
}
if ( snObjectFlagsTable[i].pName[0] == '\0' )
{
sap_warning( "Object %d: Unknown object flag `%s'.",
pObjIndex->iNumber, cBuf );
bWarn = TRUE;
}
}
if ( !IS_SET( pObjIndex->fObjFlags, FLAG_OBJECT_CLOSABLE )
&& IS_SET( pObjIndex->fObjFlags, FLAG_OBJECT_CLOSED ) )
{
sap_warning(
"Object %d: Closed flag set on non-closable object.",
pObjIndex->iNumber );
REMOVE_FLAG( pObjIndex->fObjFlags, FLAG_OBJECT_CLOSED );
bWarn = TRUE;
}
if ( !IS_SET( pObjIndex->fObjFlags, FLAG_OBJECT_CLOSABLE )
&& IS_SET( pObjIndex->fObjFlags, FLAG_OBJECT_LOCKED ) )
{
sap_warning(
"Object %d: Locked flag set on non-closable object.",
pObjIndex->iNumber );
REMOVE_FLAG( pObjIndex->fObjFlags, FLAG_OBJECT_LOCKED );
bWarn = TRUE;
}
else if ( !IS_SET( pObjIndex->fObjFlags, FLAG_OBJECT_CLOSED )
&& IS_SET( pObjIndex->fObjFlags, FLAG_OBJECT_LOCKED ) )
{
sap_warning( "Object %d: Locked flag set on non-closed object.",
pObjIndex->iNumber );
REMOVE_FLAG( pObjIndex->fObjFlags, FLAG_OBJECT_LOCKED );
bWarn = TRUE;
}
if ( bWarn == TRUE )
return ( TRUE );
else
return ( FALSE );
}
bool obj_load_level( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
pObjIndex->iLevel = fget_number_2( pFile );
if ( pObjIndex->iLevel > MAX_PLAYER_LEVEL )
{
sap_error( "Object %d: Level greater then %d.",
pObjIndex->iNumber, MAX_PLAYER_LEVEL );
pObjIndex->iLevel = MAX_PLAYER_LEVEL;
return ( TRUE );
}
if ( pObjIndex->iLevel < 1 )
{
sap_error( "Object %d: Level less then 1.", pObjIndex->iNumber );
pObjIndex->iLevel = 1;
return ( TRUE );
}
return ( FALSE );
}
bool obj_load_weight( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
pObjIndex->iWeight = fget_number_2( pFile );
if ( pObjIndex->iLevel > 999 )
{
sap_error( "Object %d: Weight greater then 999.",
pObjIndex->iNumber );
pObjIndex->iWeight = 999;
return ( TRUE );
}
if ( pObjIndex->iLevel < 0 )
{
sap_error( "Object %d: Weight less then 0.",
pObjIndex->iNumber );
pObjIndex->iWeight = 1;
return ( TRUE );
}
return ( FALSE );
}
bool obj_load_size( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
char *pBuf;
int i;
pBuf = fget_word_2( pFile );
for ( i = 0; snSizeTable[i].pName[0] != '\0'; i++ )
{
if ( str_compare( snSizeTable[i].pName, pBuf ) == TRUE )
{
pObjIndex->iSize = snSizeTable[i].iNumber;
return ( FALSE );
}
}
sap_warning( "Object %d: Unknown size `%s'.", pObjIndex->iNumber,
pBuf );
pObjIndex->iSize = snSizeTable[0].iNumber;
return ( TRUE );
}
bool obj_load_cost( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
pObjIndex->iCost = fget_number_2( pFile );
return ( FALSE );
}
bool obj_load_condition( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
pObjIndex->iCondition = fget_number_2( pFile );
if ( pObjIndex->iCondition > 100 )
{
sap_warning( "Object %d: Condition greater then 100.",
pObjIndex->iNumber );
pObjIndex->iCondition = 100;
return ( TRUE );
}
if ( pObjIndex->iCondition < 1 )
{
sap_warning( "Object %d: Condition less then 1.",
pObjIndex->iNumber );
pObjIndex->iCondition = 1;
return ( TRUE );
}
return ( FALSE );
}
bool obj_load_material( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
char *pBuf;
int i;
pBuf = fget_word_2( pFile );
for ( i = 0; snMaterialTable[i].pName[0] != '\0'; i++ )
{
if ( str_compare( snMaterialTable[i].pName, pBuf ) == TRUE )
{
pObjIndex->iMaterial = snMaterialTable[i].iNumber;
return ( FALSE );
}
}
sap_warning( "Object %d: Unknown material type `%s'.",
pObjIndex->iNumber, pBuf );
pObjIndex->iMaterial = snMaterialTable[0].iNumber;
return ( TRUE );
}
bool obj_load_values( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
char cBuf[MAX_INPUT];
char *pBuf;
int i = 0;
bool bWarn = FALSE;
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
if ( i == 6 )
{
sap_warning( "Object %d: Too many value settings.",
pObjIndex->iNumber );
bWarn = TRUE;
break;
}
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
if ( is_number( cBuf ) != TRUE )
{
sap_warning( "Object %d: Non-number as value[%d] setting.",
pObjIndex->iNumber, ++i );
bWarn = TRUE;
}
else
pObjIndex->iValues[i++] = atol( cBuf );
}
return ( bWarn );
}
bool obj_load_stringvalue( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
char cBuf[MAX_INPUT];
char *pString;
char *pBuf;
bool bWarn = FALSE;
pString = fget_string( pFile );
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
if ( str_compare( cBuf, "FORMAT" ) == TRUE )
pString = format_string( pString );
else
{
sap_warning( "Object %d: Unknown string flag `%s'.",
pObjIndex->iNumber, cBuf );
bWarn = TRUE;
}
}
free_string( &pObjIndex->sValue );
pObjIndex->sValue = save_string( pString );
return ( bWarn );
}
bool obj_load_program( OBJ_INDEX_DATA *pObjIndex, FILE *pFile )
{
PROGRAM_DATA *pProgram;
SCRIPT_DATA *pScript;
TRIGGER_DATA *pTrigger;
TRIGGER_ARG_DATA *pTriggerArg;
char *pStr = fget_string_3( pFile, '{', '}' );
char *pBak = pStr;
char cBuf[MAX_STRING];
char cBuf2[MAX_STRING];
char *pBuf;
char c;
int i;
bool bWarn = FALSE;
pProgram = alloc_mem( sizeof( *pProgram ) );
pObjIndex->pProgram = pProgram;
while ( next_char( pStr ) != '\0' )
{
pStr = edit_str( pStr, cBuf, ' ', "\n\r\t " );
if ( str_compare( cBuf, "TRIGGER" ) == TRUE )
{
pStr = edit_str( pStr, cBuf, ' ', "\n\r\t " );
for ( pScript = pProgram->pScripts; pScript != NULL;
pScript = pScript->pNext )
{
if ( str_compare( pScript->pName, cBuf ) == TRUE )
break;
}
if ( pScript != NULL )
{
sap_error( "Object %d: Multiple blocks with the name "
"`%s' in script.", pObjIndex->iNumber, cBuf );
bWarn = TRUE;
goto end;
}
pScript = alloc_mem( sizeof( *pScript ) );
pScript->pName = str_dup( cBuf );
pStr = edit_str( pStr, cBuf, ' ', "\n\r\t " );
if ( str_compare( cBuf, "enabled" ) == TRUE )
pScript->bDisabled = FALSE;
else if ( str_compare( cBuf, "disabled" ) == TRUE )
pScript->bDisabled = TRUE;
else
{
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error( "Object %d: Unknown enabled flag in script.",
pObjIndex->iNumber );
bWarn = TRUE;
goto end;
}
do
{
pStr = edit_str( pStr, cBuf, ' ', "(\n\r\t " );
if ( next_char( pStr ) != '(' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"Object %d: Trigger missing `(' symbol in script.",
pObjIndex->iNumber );
bWarn = TRUE;
goto end;
}
for ( i = 0; snNPCScriptTriggerTable[i].pName[0] != '\0';
i++ )
{
if ( str_compare( cBuf,
snNPCScriptTriggerTable[i].pName ) == TRUE )
break;
}
if ( snNPCScriptTriggerTable[i].pName[0] == '\0' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"Object %d: Unknown trigger type `%s' in script.",
pObjIndex->iNumber, cBuf );
bWarn = TRUE;
goto end;
}
pTrigger = alloc_mem( sizeof( *pTrigger ) );
pTrigger->iTrigger = snNPCScriptTriggerTable[i].iNumber;
pStr = edit_str( pStr, cBuf, '(', ")" );
pBuf = remove_spaces( cBuf );
if ( next_char( pStr ) != ')' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
free_mem( (void **) &pTrigger );
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"Object %d: Trigger missing `)' symbol in script.",
pObjIndex->iNumber );
bWarn = TRUE;
goto end;
}
switch ( pTrigger->iTrigger )
{
case NUMBER_OBJ_TRIGGER_RANDOM:
if ( is_number( pBuf ) != TRUE )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
free_mem( (void **) &pTrigger );
for ( pTrigger = pScript->pTriggers; pTrigger;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs;
pTriggerArg; pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_warning( "Object %d: Non-number argument "
"for trigger in script.", pObjIndex->iNumber );
bWarn = TRUE;
goto end;
}
pTriggerArg = alloc_mem( sizeof( *pTriggerArg ) );
pTriggerArg->pArg = alloc_mem( 1 );
*( (intt *) pTriggerArg->pArg ) = (intt) atoi( pBuf );
pTrigger->pArgs = pTriggerArg;
break;
case NUMBER_OBJ_TRIGGER_SAY :
if ( str_compare( pBuf, "all" ) == TRUE )
{
pTriggerArg = alloc_mem( sizeof( *pTriggerArg ) );
pTriggerArg->iType = 1;
pTriggerArg->pArg = EMPTY_STRING;
pTrigger->pArgs = pTriggerArg;
break;
}
while ( *pBuf != '\0' )
{
pTriggerArg = alloc_mem( sizeof( *pTriggerArg ) );
pBuf = edit_str( pBuf, cBuf2, ' ', "\n\r\t " );
if ( next_char( pBuf ) == '"' )
{
if ( str_compare( cBuf2, "exact" ) == TRUE )
pTriggerArg->iType = 2;
else if ( str_compare( cBuf2, "prefix" )
== TRUE )
pTriggerArg->iType = 3;
else if ( str_compare( cBuf2, "infix" )
== TRUE )
pTriggerArg->iType = 4;
else if ( str_compare( cBuf2, "suffix" )
== TRUE )
pTriggerArg->iType = 5;
else
{
sap_warning(
"Object %d: Unknown comparison type "
"for trigger argument in script.",
pObjIndex->iNumber );
bWarn = TRUE;
pTriggerArg->iType = 2;
continue;
}
pBuf = make_string( pBuf, cBuf2 );
pBuf = remove_char_2( pBuf );
if ( cBuf2[0] == '\0' )
{
sap_warning( "Object %d: Empty string "
"for trigger argument in script.",
pObjIndex->iNumber );
bWarn = TRUE;
pTriggerArg->pArg = EMPTY_STRING;
continue;
}
pTriggerArg->pArg = str_dup( cBuf2 );
}
if ( ( c = next_char( pBuf ) ) == ',' )
pBuf = remove_char_2( pBuf );
else if ( c != '\0' )
{
sap_warning( "Object %d: Missing `,' for "
"trigger argument list in script.",
pObjIndex->iNumber );
bWarn = TRUE;
}
pTriggerArg->pNext = pTrigger->pArgs;
pTrigger->pArgs = pTriggerArg;
}
break;
default :
pTriggerArg = alloc_mem( sizeof( *pTriggerArg ) );
pTriggerArg->pArg = str_dup( pBuf );
pTrigger->pArgs = pTriggerArg;
break;
}
pStr = remove_char_2( pStr );
pTrigger->pNext = pScript->pTriggers;
pScript->pTriggers = pTrigger;
}
while ( ( c = next_char( pStr ) ) != '{' && c != '\0' );
if ( next_char( pStr ) != '{' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"Object %d: Trigger missing `{' symbol in script.",
pObjIndex->iNumber );
bWarn = TRUE;
break;
}
pStr = edit_str_plus( pStr, cBuf, '{', '}' );
if ( next_char( pStr ) != '}' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"Object %d: Trigger missing `}' symbol in script.",
pObjIndex->iNumber );
bWarn = TRUE;
break;
}
pStr = remove_char_2( pStr );
pScript->pScript = alloc_mem( ( i = obj_script_translate(
pScript, cBuf ) ) );
memcpy( pScript->pScript, cBuf, i );
pScript->iCodeSize = i;
pScript->pNext = pProgram->pScripts;
pProgram->pScripts = pScript;
}
else
{
QUEST_VAR_DATA *pVar;
pVar = alloc_mem( sizeof( *pVar ) );
if ( str_compare( cBuf, "number" ) == TRUE )
pVar->iType = NUMBER_VAR_NUMBER;
else if ( str_compare( cBuf, "string" ) == TRUE )
pVar->iType = NUMBER_VAR_STRING;
else if ( str_compare( cBuf, "character_pointer" ) == TRUE )
pVar->iType = NUMBER_VAR_POINTER_CHAR;
else if ( str_compare( cBuf, "object_pointer" ) == TRUE )
pVar->iType = NUMBER_VAR_POINTER_OBJ;
else if ( str_compare( cBuf, "room_pointer" ) == TRUE )
pVar->iType = NUMBER_VAR_POINTER_ROOM;
else
{
free_mem( (void **) &pVar );
sap_error( "Object %d: Unknown keyword `%s' in script.",
pObjIndex->iNumber, cBuf );
bWarn = TRUE;
break;
}
pStr = edit_str( pStr, cBuf, ' ', ";\n\r\t " );
if ( next_char( pStr ) != ';' )
{
free_mem( (void **) &pVar );
sap_error( "Object %d: "
"Syntax error in script variable declaration.",
pObjIndex->iNumber );
bWarn = TRUE;
goto end;
}
pStr = remove_char_2( pStr );
if ( cBuf[0] == '\0' || ( !isalpha( cBuf[0] )
&& cBuf[0] != '_' ) )
{
free_mem( (void **) &pVar );
sap_error( "Object %d: Illegal name for script variable.",
pObjIndex->iNumber );
bWarn = TRUE;
goto end;
}
for ( i = 0; cBuf[i] != '\0'; i++ )
{
if ( !isalnum( cBuf[i] ) && cBuf[i] != '_' )
{
free_mem( (void **) &pVar );
sap_error(
"Object %d: Illegal name for script variable.",
pObjIndex->iNumber );
bWarn = TRUE;
goto end;
}
}
pVar->sName = save_string( cBuf );
if ( pVar->iType == NUMBER_VAR_STRING )
pVar->uData.s = EMPTY_STRING;
pVar->pNext = pProgram->pQuestVars;
pProgram->pQuestVars = pVar;
}
}
end:
if ( pBak != EMPTY_STRING )
free_mem( (void **) &pBak );
return ( bWarn );
}
bool room_load_imagefilename( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
char *pBuf = fget_string( pFile );
int i;
if ( ( i = get_file_type( pBuf ) ) != FILE_TYPE_GIF
&& i != FILE_TYPE_JPEG )
{
sap_warning( "Room %d: Unknown image file format.",
pRoomIndex->iNumber );
return ( TRUE );
}
free_string( &pRoomIndex->sImageFilename );
pRoomIndex->sImageFilename = save_string( pBuf );
return ( FALSE );
}
bool room_load_title( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
free_string( &pRoomIndex->sTitle );
pRoomIndex->sTitle = save_string( fget_string( pFile ) );
return ( FALSE );
}
bool room_load_desc( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
char cBuf[MAX_INPUT];
char *pString;
char *pBuf;
bool bWarn = FALSE;
pString = fget_string( pFile );
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
if ( str_compare( cBuf, "FORMAT" ) == TRUE )
pString = format_string( pString );
else
{
sap_warning( "Room %d: Unknown string flag `%s'.",
pRoomIndex->iNumber, cBuf );
bWarn = TRUE;
}
}
free_string( &pRoomIndex->sDesc );
pRoomIndex->sDesc = save_string( pString );
return ( bWarn );
}
bool room_load_roomflags( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
char cBuf[MAX_STRING];
char *pBuf;
int i;
bool bWarn = FALSE;
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
for ( i = 0; snRoomFlagsTable[i].pName[0] != '\0'; i++ )
{
if ( str_compare( snRoomFlagsTable[i].pName, cBuf ) == TRUE )
{
SET_FLAG( pRoomIndex->fRoomFlags,
snRoomFlagsTable[i].iNumber );
break;
}
}
if ( snRoomFlagsTable[i].pName[0] == '\0' )
{
sap_warning( "Room %d: Unknown room flag `%s'.",
pRoomIndex->iNumber, cBuf );
bWarn = TRUE;
}
}
return ( bWarn );
}
bool room_load_sector( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
char *pBuf;
int i;
pBuf = fget_word_2( pFile );
for ( i = 0; snSectorTable[i].pName[0] != '\0'; i++ )
{
if ( str_compare( snSectorTable[i].pName, pBuf ) == TRUE )
{
pRoomIndex->iSectorType = snSectorTable[i].iNumber;
return ( FALSE );
}
}
sap_warning( "Room %d: Unknown sector type `%s'.",
pRoomIndex->iNumber, pBuf );
pRoomIndex->iSectorType = snSectorTable[0].iNumber;
return ( TRUE );
}
bool room_load_temperature( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
pRoomIndex->iTemperature = fget_number_2( pFile );
if ( pRoomIndex->iTemperature > 1000 )
{
sap_warning( "Room %d: Temperature greater then 1000.",
pRoomIndex->iNumber );
pRoomIndex->iTemperature = 1000;
return ( TRUE );
}
if ( pRoomIndex->iTemperature < -1000 )
{
sap_warning( "Room %d: Temperature less then -1000.",
pRoomIndex->iNumber );
pRoomIndex->iTemperature = -1000;
return ( TRUE );
}
return ( FALSE );
}
static bool load_dir_desc( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile,
int iDir )
{
char cBuf[MAX_INPUT];
char *pString;
char *pBuf;
bool bWarn = FALSE;
pString = fget_string( pFile );
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
if ( str_compare( cBuf, "FORMAT" ) == TRUE )
pString = format_string( pString );
else
{
sap_warning( "Room %d: Unknown string flag `%s'.",
pRoomIndex->iNumber, cBuf );
bWarn = TRUE;
}
}
free_string( &pRoomIndex->sDirDescs[iDir] );
pRoomIndex->sDirDescs[iDir] = save_string( pString );
return ( bWarn );
}
bool room_load_northdesc( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_dir_desc( pRoomIndex, pFile, 0 ) );
}
bool room_load_southdesc( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_dir_desc( pRoomIndex, pFile, 1 ) );
}
bool room_load_eastdesc( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_dir_desc( pRoomIndex, pFile, 2 ) );
}
bool room_load_westdesc( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_dir_desc( pRoomIndex, pFile, 3 ) );
}
bool room_load_updesc( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_dir_desc( pRoomIndex, pFile, 4 ) );
}
bool room_load_downdesc( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_dir_desc( pRoomIndex, pFile, 5 ) );
}
bool room_load_northeastdesc( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_dir_desc( pRoomIndex, pFile, 6 ) );
}
bool room_load_southwestdesc( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_dir_desc( pRoomIndex, pFile, 7 ) );
}
bool room_load_northwestdesc( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_dir_desc( pRoomIndex, pFile, 8 ) );
}
bool room_load_southeastdesc( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_dir_desc( pRoomIndex, pFile, 9 ) );
}
static bool load_exit( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile,
int iDoor )
{
char cBuf[MAX_STRING];
char *pBuf;
int i;
bool bWarn = FALSE;
pRoomIndex->eExits[iDoor].uRoom.iNumber = fget_number( pFile );
if ( pRoomIndex->eExits[iDoor].uRoom.iNumber <= 5
|| pRoomIndex->eExits[iDoor].uRoom.iNumber > MAX_INDEX_NUMBER )
sap_fatal( "Room %d: Illegal room number `%d' in exit.",
pRoomIndex->iNumber, pRoomIndex->eExits[iDoor].uRoom.iNumber );
pBuf = fget_word_2( pFile );
if ( str_compare( pBuf, "STANDARD" ) == TRUE )
{
pRoomIndex->eExits[iDoor].iExitType = NUMBER_EXIT_STANDARD;
return ( FALSE );
}
if ( str_compare( pBuf, "SHARED" ) == TRUE )
{
pRoomIndex->eExits[iDoor].bShared = TRUE;
return ( FALSE );
}
else if ( str_compare( pBuf, "DOOR" ) == TRUE )
{
pRoomIndex->eExits[iDoor].iExitType = NUMBER_EXIT_DOOR;
for ( i = 0; pRoomIndex->eExits[iDoor].pDoorNames[i] != NULL; i++ )
free_string( &pRoomIndex->eExits[iDoor].pDoorNames[i] );
free_mem( (void **) &pRoomIndex->eExits[iDoor].pDoorNames );
pRoomIndex->eExits[iDoor].pDoorNames = alloc_mem( sizeof( string )
* 2 );
pRoomIndex->eExits[iDoor].pDoorNames[0] = save_string(
fget_string( pFile ) );
pRoomIndex->eExits[iDoor].pDoorNames[1] = NULL;
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
if ( str_compare( cBuf, "CLOSED" ) == TRUE )
SET_FLAG( pRoomIndex->eExits[iDoor].fOrigFlags,
FLAG_DOOR_CLOSED );
else if ( str_compare( cBuf, "LOCKED" ) == TRUE )
SET_FLAG( pRoomIndex->eExits[iDoor].fOrigFlags,
FLAG_DOOR_LOCKED );
else if ( str_compare( cBuf, "HIDDEN" ) == TRUE )
SET_FLAG( pRoomIndex->eExits[iDoor].fOrigFlags,
FLAG_DOOR_HIDDEN );
else if ( str_compare( cBuf, "LEVEL" ) == TRUE )
{
pBuf = edit_str( pBuf, cBuf, ' ', "\n\r\t " );
pRoomIndex->eExits[iDoor].iLevel = atoi( cBuf );
if ( pRoomIndex->eExits[iDoor].iLevel < 1 )
{
sap_warning( "Room %d: Door level less then 1.",
pRoomIndex->iNumber );
pRoomIndex->eExits[iDoor].iLevel = 1;
bWarn = TRUE;
}
if ( pRoomIndex->eExits[iDoor].iLevel > MAX_PLAYER_LEVEL )
{
sap_warning( "Room %d: Door level higher then %d.",
pRoomIndex->iNumber, MAX_PLAYER_LEVEL );
pRoomIndex->eExits[iDoor].iLevel = MAX_PLAYER_LEVEL;
bWarn = TRUE;
}
}
else if ( str_compare( cBuf, "KEY" ) == TRUE )
{
pBuf = edit_str( pBuf, cBuf, ' ', "\n\r\t " );
pRoomIndex->eExits[iDoor].uKey.iNumber = atoi( cBuf );
if ( pRoomIndex->eExits[iDoor].uKey.iNumber <= 5
|| pRoomIndex->eExits[iDoor].uKey.iNumber
> MAX_INDEX_NUMBER )
sap_fatal(
"Room %d: Illegal object number `%d' for door key.",
pRoomIndex->iNumber,
pRoomIndex->eExits[iDoor].uKey.iNumber );
}
else
{
sap_warning( "Room %d: Unknown door flag `%s'.",
pRoomIndex->iNumber, cBuf );
bWarn = TRUE;
}
}
pRoomIndex->eExits[iDoor].iResetTime = fget_number_2( pFile );
}
else
{
sap_warning( "Room %d: Unknown exit type `%s'.",
pRoomIndex->iNumber, pBuf );
return ( TRUE );
}
pRoomIndex->eExits[iDoor].fCurrFlags
= pRoomIndex->eExits[iDoor].fOrigFlags;
return ( bWarn );
}
bool room_load_exitnorth( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_exit( pRoomIndex, pFile, 0 ) );
}
bool room_load_exitsouth( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_exit( pRoomIndex, pFile, 1 ) );
}
bool room_load_exiteast( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_exit( pRoomIndex, pFile, 2 ) );
}
bool room_load_exitwest( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_exit( pRoomIndex, pFile, 3 ) );
}
bool room_load_exitup( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_exit( pRoomIndex, pFile, 4 ) );
}
bool room_load_exitdown( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_exit( pRoomIndex, pFile, 5 ) );
}
bool room_load_exitnortheast( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_exit( pRoomIndex, pFile, 6 ) );
}
bool room_load_exitsouthwest( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_exit( pRoomIndex, pFile, 7 ) );
}
bool room_load_exitnorthwest( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_exit( pRoomIndex, pFile, 8 ) );
}
bool room_load_exitsoutheast( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
return ( load_exit( pRoomIndex, pFile, 9 ) );
}
static int get_obj_reset_list( char **ppSrc, OBJ_RESET_DATA **ppList )
{
OBJ_RESET_DATA *pReset;
char *pBuf = new_buffer( );
char *pSrc = *ppSrc;
char cBuf[MAX_STRING];
int i;
if ( next_char( pSrc ) != '[' )
return ( -1 );
pSrc = edit_str_plus( pSrc, pBuf, '[', ']' );
if ( next_char( pSrc ) != ']' )
return ( -2 );
*ppSrc = remove_char_2( pSrc );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', "[\n\r\t " );
if ( is_number( cBuf ) != TRUE )
return ( -3 );
i = atoi( cBuf );
if ( i <= 5 || i > MAX_INDEX_NUMBER )
return ( -4 );
pReset = alloc_mem( sizeof( *pReset ) );
pReset->u1.iNumber = i;
if ( ( i = get_obj_reset_list( &pBuf, &pReset->pContentResets ) )
< 0 )
return ( i );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
pReset->pNext = *ppList;
*ppList = pReset;
}
return ( 0 );
}
bool room_load_npcs( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
/* FILE *pFile2; */
NPC_RESET_DATA *pNewReset;
char cBuf[MAX_STRING];
char *pBuf;
int i;
bool bWarn = FALSE;
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', "[\n\r\t " );
pNewReset = alloc_mem( sizeof( *pNewReset ) );
if ( is_number( cBuf ) == FALSE )
{
sap_fatal( "Room %d: Non-number `%s' for NPC number.",
pRoomIndex->iNumber, cBuf );
bWarn = TRUE;
}
else
pNewReset->u1.iNumber = atoi( cBuf );
if ( pNewReset->u1.iNumber <= 5
|| pNewReset->u1.iNumber > MAX_INDEX_NUMBER )
{
sap_fatal( "Room %d: Illegal NPC number `%d' for reset.",
pRoomIndex->iNumber, pNewReset->u1.iNumber );
bWarn = TRUE;
}
if ( ( i = get_obj_reset_list( &pBuf, &pNewReset->pInvenResets ) )
< 0 )
{
sap_error( "Room %d: Error %d.", pRoomIndex->iNumber, i );
bWarn = TRUE;
}
if ( ( i = get_obj_reset_list( &pBuf, &pNewReset->pEqResets ) )
< 0 )
{
sap_error( "Room %d: Error %d.", pRoomIndex->iNumber, i );
bWarn = TRUE;
}
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
if ( is_number( cBuf ) == FALSE )
{
sap_error( "Room %d: Non-number `%s' for NPC reset time.",
pRoomIndex->iNumber, cBuf );
bWarn = TRUE;
}
else
pNewReset->iResetTime = atoi( cBuf );
pNewReset->pNext = pRoomIndex->pNPCResets;
pRoomIndex->pNPCResets = pNewReset;
}
return ( bWarn );
}
bool room_load_objects( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
/* FILE *pFile2; */
OBJ_RESET_DATA *pNewReset;
char cBuf[MAX_STRING];
char *pBuf;
int i;
bool bWarn = FALSE;
pBuf = fget_string_2( pFile, '[', ']' );
while ( next_char( pBuf ) != '\0' )
{
pBuf = edit_str( pBuf, cBuf, ' ', "[\n\r\t " );
pNewReset = alloc_mem( sizeof( *pNewReset ) );
if ( is_number( cBuf ) == FALSE )
{
sap_fatal( "Room %d: Non-number `%s' for object number.",
pRoomIndex->iNumber, cBuf );
bWarn = TRUE;
}
else
pNewReset->u1.iNumber = atoi( cBuf );
if ( pNewReset->u1.iNumber <= 5
|| pNewReset->u1.iNumber > MAX_INDEX_NUMBER )
{
sap_fatal( "Room %d: Illegal object number `%d' for reset.",
pRoomIndex->iNumber, pNewReset->u1.iNumber );
bWarn = TRUE;
}
if ( ( i = get_obj_reset_list( &pBuf,
&pNewReset->pContentResets ) ) < 0 )
{
sap_error( "Room %d: Error %d.", pRoomIndex->iNumber, i );
bWarn = TRUE;
}
pBuf = edit_str( pBuf, cBuf, ' ', ",\n\r\t " );
if ( next_char( pBuf ) == ',' )
pBuf = remove_char_2( pBuf );
if ( is_number( cBuf ) == FALSE )
{
sap_error( "Room %d: Non-number `%s' for object reset time.",
pRoomIndex->iNumber, cBuf );
bWarn = TRUE;
}
else
pNewReset->iResetTime = atoi( cBuf );
pNewReset->pNext = pRoomIndex->pObjResets;
pRoomIndex->pObjResets = pNewReset;
}
return ( bWarn );
}
bool room_load_program( ROOM_INDEX_DATA *pRoomIndex, FILE *pFile )
{
PROGRAM_DATA *pProgram;
SCRIPT_DATA *pScript;
TRIGGER_DATA *pTrigger;
TRIGGER_ARG_DATA *pTriggerArg;
char *pStr = fget_string_3( pFile, '{', '}' );
char *pBak = pStr;
char cBuf[MAX_STRING];
char cBuf2[MAX_STRING];
char *pBuf;
char c;
int i;
bool bWarn = FALSE;
pProgram = alloc_mem( sizeof( *pProgram ) );
pRoomIndex->pProgram = pProgram;
while ( next_char( pStr ) != '\0' )
{
pStr = edit_str( pStr, cBuf, ' ', "\n\r\t " );
if ( str_compare( cBuf, "TRIGGER" ) == TRUE )
{
pStr = edit_str( pStr, cBuf, ' ', "\n\r\t " );
for ( pScript = pProgram->pScripts; pScript != NULL;
pScript = pScript->pNext )
{
if ( str_compare( pScript->pName, cBuf ) == TRUE )
break;
}
if ( pScript != NULL )
{
sap_error(
"Room %d: Multiple blocks with the name `%s' in script.",
pRoomIndex->iNumber, cBuf );
bWarn = TRUE;
goto end;
}
pScript = alloc_mem( sizeof( *pScript ) );
pScript->pName = str_dup( cBuf );
pStr = edit_str( pStr, cBuf, ' ', "\n\r\t " );
if ( str_compare( cBuf, "enabled" ) == TRUE )
pScript->bDisabled = FALSE;
else if ( str_compare( cBuf, "disabled" ) == TRUE )
pScript->bDisabled = TRUE;
else
{
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error( "Room %d: Unknown enabled flag in script.",
pRoomIndex->iNumber );
bWarn = TRUE;
goto end;
}
do
{
pStr = edit_str( pStr, cBuf, ' ', "(\n\r\t " );
if ( next_char( pStr ) != '(' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"Room %d: Trigger missing `(' symbol in script.",
pRoomIndex->iNumber );
bWarn = TRUE;
goto end;
}
for ( i = 0; snRoomScriptTriggerTable[i].pName[0] != '\0';
i++ )
{
if ( str_compare( cBuf,
snRoomScriptTriggerTable[i].pName ) == TRUE )
break;
}
if ( snRoomScriptTriggerTable[i].pName[0] == '\0' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"Room %d: Unknown trigger type `%s' in script.",
pRoomIndex->iNumber, cBuf );
bWarn = TRUE;
goto end;
}
pTrigger = alloc_mem( sizeof( *pTrigger ) );
pTrigger->iTrigger = snRoomScriptTriggerTable[i].iNumber;
pStr = edit_str( pStr, cBuf, '(', ")" );
pBuf = remove_spaces( cBuf );
if ( next_char( pStr ) != ')' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
free_mem( (void **) &pTrigger );
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"Room %d: Trigger missing `)' symbol in script.",
pRoomIndex->iNumber );
bWarn = TRUE;
goto end;
}
switch ( pTrigger->iTrigger )
{
case NUMBER_ROOM_TRIGGER_RANDOM :
if ( is_number( pBuf ) != TRUE )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
free_mem( (void **) &pTrigger );
for ( pTrigger = pScript->pTriggers; pTrigger;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs;
pTriggerArg; pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_warning( "Room %d: Non-number argument for "
"trigger in script.", pRoomIndex->iNumber );
bWarn = TRUE;
goto end;
}
pTriggerArg = alloc_mem( sizeof( *pTriggerArg ) );
pTriggerArg->pArg = alloc_mem( 1 );
*( (intt *) pTriggerArg->pArg ) = (intt) atoi( pBuf );
pTrigger->pArgs = pTriggerArg;
break;
case NUMBER_ROOM_TRIGGER_MESSAGE:
case NUMBER_ROOM_TRIGGER_EMOTE :
case NUMBER_ROOM_TRIGGER_SAY :
case NUMBER_ROOM_TRIGGER_YELL :
if ( str_compare( pBuf, "all" ) == TRUE )
{
pTriggerArg = alloc_mem( sizeof( *pTriggerArg ) );
pTriggerArg->iType = 1;
pTriggerArg->pArg = EMPTY_STRING;
pTrigger->pArgs = pTriggerArg;
break;
}
while ( *pBuf != '\0' )
{
pTriggerArg = alloc_mem( sizeof( *pTriggerArg ) );
pBuf = edit_str( pBuf, cBuf2, ' ', "\n\r\t " );
if ( next_char( pBuf ) == '"' )
{
if ( str_compare( cBuf2, "exact" ) == TRUE )
pTriggerArg->iType = 2;
else if ( str_compare( cBuf2, "prefix" )
== TRUE )
pTriggerArg->iType = 3;
else if ( str_compare( cBuf2, "infix" )
== TRUE )
pTriggerArg->iType = 4;
else if ( str_compare( cBuf2, "suffix" )
== TRUE )
pTriggerArg->iType = 5;
else
{
sap_warning( "Room %d: Unknown "
"comparison type for trigger argument "
"in script.",
pRoomIndex->iNumber );
bWarn = TRUE;
pTriggerArg->iType = 2;
continue;
}
pBuf = make_string( pBuf, cBuf2 );
pBuf = remove_char_2( pBuf );
if ( cBuf2[0] == '\0' )
{
sap_warning( "Room %d: Empty string for "
"trigger argument in script.",
pRoomIndex->iNumber );
bWarn = TRUE;
pTriggerArg->pArg = EMPTY_STRING;
continue;
}
pTriggerArg->pArg = str_dup( cBuf2 );
}
if ( ( c = next_char( pBuf ) ) == ',' )
pBuf = remove_char_2( pBuf );
else if ( c != '\0' )
{
sap_warning( "Room %d: Missing `,' for "
"trigger argument list in script.",
pRoomIndex->iNumber );
bWarn = TRUE;
}
pTriggerArg->pNext = pTrigger->pArgs;
pTrigger->pArgs = pTriggerArg;
}
break;
default :
pTriggerArg = alloc_mem( sizeof( *pTriggerArg ) );
pTriggerArg->pArg = str_dup( pBuf );
pTrigger->pArgs = pTriggerArg;
break;
}
pStr = remove_char_2( pStr );
pTrigger->pNext = pScript->pTriggers;
pScript->pTriggers = pTrigger;
}
while ( ( c = next_char( pStr ) ) != '{' && c != '\0' );
if ( next_char( pStr ) != '{' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"Room %d: Trigger missing `{' symbol in script.",
pRoomIndex->iNumber );
bWarn = TRUE;
break;
}
pStr = edit_str_plus( pStr, cBuf, '{', '}' );
if ( next_char( pStr ) != '}' )
{
TRIGGER_DATA *pTriggerNext;
TRIGGER_ARG_DATA *pTriggerArgNext;
for ( pTrigger = pScript->pTriggers; pTrigger != NULL;
pTrigger = pTriggerNext )
{
pTriggerNext = pTrigger->pNext;
for ( pTriggerArg = pTrigger->pArgs; pTriggerArg;
pTriggerArg = pTriggerArgNext )
{
pTriggerArgNext = pTriggerArg->pNext;
str_free( pTriggerArg->pArg );
free_mem( (void **) &pTriggerArg );
}
free_mem( (void **) &pTrigger );
}
str_free( pScript->pName );
free_mem( (void **) &pScript );
sap_error(
"Room %d: Trigger missing `}' symbol in script.",
pRoomIndex->iNumber );
bWarn = TRUE;
break;
}
pStr = remove_char_2( pStr );
pScript->pScript = alloc_mem( ( i = room_script_translate(
pScript, cBuf ) ) );
memcpy( pScript->pScript, cBuf, i );
pScript->iCodeSize = i;
pScript->pNext = pProgram->pScripts;
pProgram->pScripts = pScript;
}
else if ( str_compare( cBuf, "USES" ) == TRUE )
{
GENERIC_DATA *pGen;
QUEST_DATA *pQuestData;
char *pBuf2;
char c;
pStr = edit_str( pStr, cBuf, ' ', ";" );
if ( *pStr != ';' )
{
sap_error(
"Room %d: Syntax error in script quest data reference.",
pRoomIndex->iNumber );
bWarn = TRUE;
goto end;
}
pStr++;
pBuf2 = cBuf;
do
{
pBuf2 = edit_str( pBuf2, cBuf2, ' ', ",\n\r\t " );
if ( ( c = next_char( pBuf2 ) ) != ',' && c != '\0' )
{
sap_error( "Room %d: "
"Syntax error in script quest data reference.",
pRoomIndex->iNumber );
bWarn = TRUE;
goto end;
}
else if ( c == ',' )
pBuf2 = remove_char_2( pBuf2 );
for ( pQuestData = pQuestDataList; pQuestData != NULL;
pQuestData = pQuestData->pNext )
{
if ( strcmp( pQuestData->sName, cBuf2 ) == 0 )
{
for ( pGen = pProgram->pQuestDataList; pGen;
pGen = pGen->pNext )
{
if ( pGen->pData == pQuestData )
break;
}
if ( pGen != NULL )
{
sap_warning(
"Room %d: Multiply referenced quest data.",
pRoomIndex->iNumber );
bWarn = TRUE;
break;
}
pGen = alloc_mem( sizeof( *pGen ) );
pGen->pData = pQuestData;
pGen->pNext = pProgram->pQuestDataList;
pProgram->pQuestDataList = pGen;
break;
}
}
}
while ( next_char( pBuf2 ) != '\0' );
}
else
{
QUEST_VAR_DATA *pVar;
pVar = alloc_mem( sizeof( *pVar ) );
if ( str_compare( cBuf, "number" ) == TRUE )
pVar->iType = NUMBER_VAR_NUMBER;
else if ( str_compare( cBuf, "string" ) == TRUE )
pVar->iType = NUMBER_VAR_STRING;
else if ( str_compare( cBuf, "character_pointer" ) == TRUE )
pVar->iType = NUMBER_VAR_POINTER_CHAR;
else if ( str_compare( cBuf, "object_pointer" ) == TRUE )
pVar->iType = NUMBER_VAR_POINTER_OBJ;
else if ( str_compare( cBuf, "room_pointer" ) == TRUE )
pVar->iType = NUMBER_VAR_POINTER_ROOM;
else
{
free_mem( (void **) &pVar );
sap_error( "Room %d: Unknown keyword `%s' in script.",
pRoomIndex->iNumber, cBuf );
bWarn = TRUE;
break;
}
pStr = edit_str( pStr, cBuf, ' ', ";\n\r\t " );
if ( next_char( pStr ) != ';' )
{
free_mem( (void **) &pVar );
sap_error(
"Room %d: Syntax error in script variable declaration.",
pRoomIndex->iNumber );
bWarn = TRUE;
goto end;
}
pStr = remove_char_2( pStr );
if ( cBuf[0] == '\0' || ( !isalpha( cBuf[0] )
&& cBuf[0] != '_' ) )
{
free_mem( (void **) &pVar );
sap_error( "Room %d: Illegal name for script variable.",
pRoomIndex->iNumber );
bWarn = TRUE;
goto end;
}
for ( i = 0; cBuf[i] != '\0'; i++ )
{
if ( !isalnum( cBuf[i] ) && cBuf[i] != '_' )
{
free_mem( (void **) &pVar );
sap_error(
"Room %d: Illegal name for script variable.",
pRoomIndex->iNumber );
bWarn = TRUE;
goto end;
}
}
pVar->sName = save_string( cBuf );
if ( pVar->iType == NUMBER_VAR_STRING )
pVar->uData.s = EMPTY_STRING;
pVar->pNext = pProgram->pQuestVars;
pProgram->pQuestVars = pVar;
}
}
end:
if ( pBak != EMPTY_STRING )
free_mem( (void **) &pBak );
return ( bWarn );
}
/*
* End of load.c
*/