//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int ReadValue(int source, float *value) { pc_token_t token; if (!PC_ExpectAnyToken(source, &token)) return qfalse; if (!strcmp(token.string, "-")) { PC_SourceWarning(source, "negative value set to zero"); if(!PC_ExpectAnyToken(source, &token)) { PC_SourceError(source, "Missing return value"); return qfalse; } } if (token.type != TT_NUMBER) { PC_SourceError(source, "invalid return value %s", token.string); return qfalse; } *value = token.floatvalue; return qtrue; } //end of the function ReadValue
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== qboolean ReadChar( source_t *source, fielddef_t *fd, void *p ) { token_t token; if ( !PC_ExpectAnyToken( source, &token ) ) { return 0; } //take literals into account if ( token.type == TT_LITERAL ) { StripSingleQuotes( token.string ); * ( char * ) p = token.string[ 0 ]; } //end if else { PC_UnreadLastToken( source ); if ( !ReadNumber( source, fd, p ) ) { return 0; } } //end if return 1; } //end of the function ReadChar
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int ReadValue(source_t *source, float *value) { token_t token; if(!PC_ExpectAnyToken(source, &token)) { return qfalse; } if(!strcmp(token.string, "-")) { SourceWarning(source, "negative value set to zero\n"); if(!PC_ExpectTokenType(source, TT_NUMBER, 0, &token)) { return qfalse; } } //end if if(token.type != TT_NUMBER) { SourceError(source, "invalid return value %s\n", token.string); return qfalse; } //end if *value = token.floatvalue; return qtrue; } //end of the function ReadValue
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== qboolean ReadChar(source_t *source, fielddef_t *fd, void *p) { token_t token; if (!PC_ExpectAnyToken(source, &token)) return (qboolean)0; // ***GREGS_VC9_PORT_MOD*** -- added typecast(s) //take literals into account if (token.type == TT_LITERAL) { StripSingleQuotes(token.string); *(char *) p = token.string[0]; } //end if else { PC_UnreadLastToken(source); if (!ReadNumber(source, fd, p)) return (qboolean)0; // ***GREGS_VC9_PORT_MOD*** -- added typecast(s) } //end if return (qboolean)1; // ***GREGS_VC9_PORT_MOD*** -- added typecast(s) } //end of the function ReadChar
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== weightconfig_t *ReadWeightConfig( char *filename ) { int newindent, avail = 0, n; token_t token; source_t *source; fuzzyseperator_t *fs; weightconfig_t *config = NULL; #ifdef DEBUG int starttime; starttime = Sys_MilliSeconds(); #endif //DEBUG if ( !LibVarGetValue( "bot_reloadcharacters" ) ) { avail = -1; for ( n = 0; n < MAX_WEIGHT_FILES; n++ ) { config = weightFileList[n]; if ( !config ) { if ( avail == -1 ) { avail = n; } //end if continue; } //end if if ( strcmp( filename, config->filename ) == 0 ) { //botimport.Print( PRT_MESSAGE, "retained %s\n", filename ); return config; } //end if } //end for if ( avail == -1 ) { botimport.Print( PRT_ERROR, "weightFileList was full trying to load %s\n", filename ); return NULL; } //end if } //end if source = LoadSourceFile( filename ); if ( !source ) { botimport.Print( PRT_ERROR, "counldn't load %s\n", filename ); return NULL; } //end if // config = (weightconfig_t *) GetClearedMemory( sizeof( weightconfig_t ) ); config->numweights = 0; Q_strncpyz( config->filename, filename, sizeof( config->filename ) ); //parse the item config file while ( PC_ReadToken( source, &token ) ) { if ( !strcmp( token.string, "weight" ) ) { if ( config->numweights >= MAX_WEIGHTS ) { SourceWarning( source, "too many fuzzy weights" ); break; } //end if if ( !PC_ExpectTokenType( source, TT_STRING, 0, &token ) ) { FreeWeightConfig( config ); FreeSource( source ); return NULL; } //end if StripDoubleQuotes( token.string ); config->weights[config->numweights].name = (char *) GetClearedMemory( strlen( token.string ) + 1 ); strcpy( config->weights[config->numweights].name, token.string ); if ( !PC_ExpectAnyToken( source, &token ) ) { FreeWeightConfig( config ); FreeSource( source ); return NULL; } //end if newindent = qfalse; if ( !strcmp( token.string, "{" ) ) { newindent = qtrue; if ( !PC_ExpectAnyToken( source, &token ) ) { FreeWeightConfig( config ); FreeSource( source ); return NULL; } //end if } //end if if ( !strcmp( token.string, "switch" ) ) { fs = ReadFuzzySeperators_r( source ); if ( !fs ) { FreeWeightConfig( config ); FreeSource( source ); return NULL; } //end if config->weights[config->numweights].firstseperator = fs; } //end if else if ( !strcmp( token.string, "return" ) ) { fs = (fuzzyseperator_t *) GetClearedMemory( sizeof( fuzzyseperator_t ) ); fs->index = 0; fs->value = MAX_INVENTORYVALUE; fs->next = NULL; fs->child = NULL; if ( !ReadFuzzyWeight( source, fs ) ) { FreeMemory( fs ); FreeWeightConfig( config ); FreeSource( source ); return NULL; } //end if config->weights[config->numweights].firstseperator = fs; } //end else if else { SourceError( source, "invalid name %s", token.string ); FreeWeightConfig( config ); FreeSource( source ); return NULL; } //end else if ( newindent ) { if ( !PC_ExpectTokenString( source, "}" ) ) { FreeWeightConfig( config ); FreeSource( source ); return NULL; } //end if } //end if config->numweights++; } //end if else { SourceError( source, "invalid name %s", token.string ); FreeWeightConfig( config ); FreeSource( source ); return NULL; } //end else } //end while //free the source at the end of a pass FreeSource( source ); //if the file was located in a pak file botimport.Print( PRT_MESSAGE, "loaded %s\n", filename ); #ifdef DEBUG if ( botDeveloper ) { botimport.Print( PRT_MESSAGE, "weights loaded in %d msec\n", Sys_MilliSeconds() - starttime ); } //end if #endif //DEBUG // if ( !LibVarGetValue( "bot_reloadcharacters" ) ) { weightFileList[avail] = config; } //end if // return config; } //end of the function ReadWeightConfig
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== fuzzyseperator_t *ReadFuzzySeperators_r( source_t *source ) { int newindent, index, def, founddefault; token_t token; fuzzyseperator_t *fs, *lastfs, *firstfs; founddefault = qfalse; firstfs = NULL; lastfs = NULL; if ( !PC_ExpectTokenString( source, "(" ) ) { return NULL; } if ( !PC_ExpectTokenType( source, TT_NUMBER, TT_INTEGER, &token ) ) { return NULL; } index = token.intvalue; if ( !PC_ExpectTokenString( source, ")" ) ) { return NULL; } if ( !PC_ExpectTokenString( source, "{" ) ) { return NULL; } if ( !PC_ExpectAnyToken( source, &token ) ) { return NULL; } do { def = !strcmp( token.string, "default" ); if ( def || !strcmp( token.string, "case" ) ) { fs = (fuzzyseperator_t *) GetClearedMemory( sizeof( fuzzyseperator_t ) ); fs->index = index; if ( lastfs ) { lastfs->next = fs; } else { firstfs = fs;} lastfs = fs; if ( def ) { if ( founddefault ) { SourceError( source, "switch already has a default" ); FreeFuzzySeperators_r( firstfs ); return NULL; } //end if fs->value = MAX_INVENTORYVALUE; founddefault = qtrue; } //end if else { if ( !PC_ExpectTokenType( source, TT_NUMBER, TT_INTEGER, &token ) ) { FreeFuzzySeperators_r( firstfs ); return NULL; } //end if fs->value = token.intvalue; } //end else if ( !PC_ExpectTokenString( source, ":" ) || !PC_ExpectAnyToken( source, &token ) ) { FreeFuzzySeperators_r( firstfs ); return NULL; } //end if newindent = qfalse; if ( !strcmp( token.string, "{" ) ) { newindent = qtrue; if ( !PC_ExpectAnyToken( source, &token ) ) { FreeFuzzySeperators_r( firstfs ); return NULL; } //end if } //end if if ( !strcmp( token.string, "return" ) ) { if ( !ReadFuzzyWeight( source, fs ) ) { FreeFuzzySeperators_r( firstfs ); return NULL; } //end if } //end if else if ( !strcmp( token.string, "switch" ) ) { fs->child = ReadFuzzySeperators_r( source ); if ( !fs->child ) { FreeFuzzySeperators_r( firstfs ); return NULL; } //end if } //end else if else { SourceError( source, "invalid name %s", token.string ); return NULL; } //end else if ( newindent ) { if ( !PC_ExpectTokenString( source, "}" ) ) { FreeFuzzySeperators_r( firstfs ); return NULL; } //end if } //end if } //end if else { FreeFuzzySeperators_r( firstfs ); SourceError( source, "invalid name %s", token.string ); return NULL; } //end else if ( !PC_ExpectAnyToken( source, &token ) ) { FreeFuzzySeperators_r( firstfs ); return NULL; } //end if } while ( strcmp( token.string, "}" ) ); // if ( !founddefault ) { SourceWarning( source, "switch without default" ); fs = (fuzzyseperator_t *) GetClearedMemory( sizeof( fuzzyseperator_t ) ); fs->index = index; fs->value = MAX_INVENTORYVALUE; fs->weight = 0; fs->next = NULL; fs->child = NULL; if ( lastfs ) { lastfs->next = fs; } else { firstfs = fs;} } //end if // return firstfs; } //end of the function ReadFuzzySeperators_r
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== weightconfig_t *ReadWeightConfig(char *filename) { int newindent, avail = 0, n; pc_token_t token; int source; fuzzyseperator_t *fs; weightconfig_t *config = NULL; int starttime; starttime = trap_Milliseconds(); if (!bot_reloadcharacters.integer) { avail = -1; for( n = 0; n < MAX_WEIGHT_FILES; n++ ) { config = weightFileList[n]; if( !config ) { if( avail == -1 ) { avail = n; } //end if continue; } //end if if( strcmp( filename, config->filename ) == 0 ) { //BotAI_Print( PRT_MESSAGE, "retained %s\n", filename ); return config; } //end if } //end for if( avail == -1 ) { BotAI_Print( PRT_ERROR, "weightFileList was full trying to load %s\n", filename ); return NULL; } //end if } //end if source = trap_PC_LoadSource(filename, BOTFILESBASEFOLDER); if (!source) { BotAI_Print(PRT_ERROR, "counldn't load %s\n", filename); return NULL; } //end if // config = (weightconfig_t *) trap_HeapMalloc(sizeof(weightconfig_t)); config->numweights = 0; Q_strncpyz( config->filename, filename, sizeof(config->filename) ); //parse the item config file while(trap_PC_ReadToken(source, &token)) { if (!strcmp(token.string, "weight")) { if (config->numweights >= MAX_WEIGHTS) { PC_SourceWarning(source, "too many fuzzy weights"); break; } //end if if (!PC_ExpectTokenType(source, TT_STRING, 0, &token)) { FreeWeightConfig(config); trap_PC_FreeSource(source); return NULL; } //end if config->weights[config->numweights].name = (char *) trap_HeapMalloc(strlen(token.string) + 1); strcpy(config->weights[config->numweights].name, token.string); if (!PC_ExpectAnyToken(source, &token)) { FreeWeightConfig(config); trap_PC_FreeSource(source); return NULL; } //end if newindent = qfalse; if (!strcmp(token.string, "{")) { newindent = qtrue; if (!PC_ExpectAnyToken(source, &token)) { FreeWeightConfig(config); trap_PC_FreeSource(source); return NULL; } //end if } //end if if (!strcmp(token.string, "switch")) { fs = ReadFuzzySeperators_r(source); if (!fs) { FreeWeightConfig(config); trap_PC_FreeSource(source); return NULL; } //end if config->weights[config->numweights].firstseperator = fs; } //end if else if (!strcmp(token.string, "return")) { fs = (fuzzyseperator_t *) trap_HeapMalloc(sizeof(fuzzyseperator_t)); fs->index = 0; fs->value = MAX_INVENTORYVALUE; fs->next = NULL; fs->child = NULL; if (!ReadFuzzyWeight(source, fs)) { trap_HeapFree(fs); FreeWeightConfig(config); trap_PC_FreeSource(source); return NULL; } //end if config->weights[config->numweights].firstseperator = fs; } //end else if else { PC_SourceError(source, "invalid name %s", token.string); FreeWeightConfig(config); trap_PC_FreeSource(source); return NULL; } //end else if (newindent) { if (!PC_ExpectTokenString(source, "}")) { FreeWeightConfig(config); trap_PC_FreeSource(source); return NULL; } //end if } //end if config->numweights++; } //end if else { PC_SourceError(source, "invalid name %s", token.string); FreeWeightConfig(config); trap_PC_FreeSource(source); return NULL; } //end else } //end while //free the source at the end of a pass trap_PC_FreeSource(source); //if the file was located in a pak file BotAI_Print(PRT_DEVELOPER, "loaded %s\n", filename); BotAI_Print(PRT_DEVELOPER, "weights loaded in %d msec\n", trap_Milliseconds() - starttime); // if (!bot_reloadcharacters.integer) { weightFileList[avail] = config; } //end if // return config; } //end of the function ReadWeightConfig
/* ======================================================================================================================================= ReadNumber ======================================================================================================================================= */ qboolean ReadNumber(source_t *source, fielddef_t *fd, void *p) { token_t token; int negative = qfalse; long int intval, intmin = 0, intmax = 0; double floatval; if (!PC_ExpectAnyToken(source, &token)) { return 0; } // check for minus sign if (token.type == TT_PUNCTUATION) { if (fd->type & FT_UNSIGNED) { SourceError(source, "expected unsigned value, found %s", token.string); return 0; } // if not a minus sign if (strcmp(token.string, "-")) { SourceError(source, "unexpected punctuation %s", token.string); return 0; } negative = qtrue; // read the number if (!PC_ExpectAnyToken(source, &token)) { return 0; } } // check if it is a number if (token.type != TT_NUMBER) { SourceError(source, "expected number, found %s", token.string); return 0; } // check for a float value if (token.subtype & TT_FLOAT) { if ((fd->type & FT_TYPE) != FT_FLOAT) { SourceError(source, "unexpected float"); return 0; } floatval = token.floatvalue; if (negative) { floatval = -floatval; } if (fd->type & FT_BOUNDED) { if (floatval < fd->floatmin || floatval > fd->floatmax) { SourceError(source, "float out of range [%f, %f]", fd->floatmin, fd->floatmax); return 0; } } *(float *)p = (float)floatval; return 1; } intval = token.intvalue; if (negative) { intval = -intval; } // check bounds if ((fd->type & FT_TYPE) == FT_CHAR) { if (fd->type & FT_UNSIGNED) { intmin = 0; intmax = 255; } else { intmin = -128; intmax = 127; } } if ((fd->type & FT_TYPE) == FT_INT) { if (fd->type & FT_UNSIGNED) { intmin = 0; intmax = 65535; } else { intmin = -32768; intmax = 32767; } } if ((fd->type & FT_TYPE) == FT_CHAR || (fd->type & FT_TYPE) == FT_INT) { if (fd->type & FT_BOUNDED) { intmin = Maximum(intmin, fd->floatmin); intmax = Minimum(intmax, fd->floatmax); } if (intval < intmin || intval > intmax) { SourceError(source, "value %ld out of range [%ld, %ld]", intval, intmin, intmax); return 0; } } else if ((fd->type & FT_TYPE) == FT_FLOAT) { if (fd->type & FT_BOUNDED) { if (intval < fd->floatmin || intval > fd->floatmax) { SourceError(source, "value %ld out of range [%f, %f]", intval, fd->floatmin, fd->floatmax); return 0; } } } // store the value if ((fd->type & FT_TYPE) == FT_CHAR) { if (fd->type & FT_UNSIGNED) { *(unsigned char *)p = (unsigned char)intval; } else { *(char *)p = (char)intval; } } else if ((fd->type & FT_TYPE) == FT_INT) { if (fd->type & FT_UNSIGNED) { *(unsigned int *)p = (unsigned int)intval; } else { *(int *)p = (int)intval; } } else if ((fd->type & FT_TYPE) == FT_FLOAT) { *(float *)p = (float)intval; } return 1; }
/* ======================================================================================================================================= ReadStructure ======================================================================================================================================= */ int ReadStructure(source_t *source, structdef_t *def, char *structure) { token_t token; fielddef_t *fd; void *p; int num; if (!PC_ExpectTokenString(source, "{")) { return 0; } while (1) { if (!PC_ExpectAnyToken(source, &token)) { return qfalse; } // if end of structure if (!strcmp(token.string, "}")) { break; } // find the field with the name fd = FindField(def->fields, token.string); if (!fd) { SourceError(source, "unknown structure field %s", token.string); return qfalse; } if (fd->type & FT_ARRAY) { num = fd->maxarray; if (!PC_ExpectTokenString(source, "{")) { return qfalse; } } else { num = 1; } p = (void *)(structure + fd->offset); while (num-- > 0) { if (fd->type & FT_ARRAY) { if (PC_CheckTokenString(source, "}")) { break; } } switch (fd->type & FT_TYPE) { case FT_CHAR: { if (!ReadChar(source, fd, p)) { return qfalse; } p = (char *)p + sizeof(char); break; } case FT_INT: { if (!ReadNumber(source, fd, p)) { return qfalse; } p = (char *)p + sizeof(int); break; } case FT_FLOAT: { if (!ReadNumber(source, fd, p)) { return qfalse; } p = (char *)p + sizeof(float); break; } case FT_STRING: { if (!ReadString(source, fd, p)) { return qfalse; } p = (char *)p + MAX_STRINGFIELD; break; } case FT_STRUCT: { if (!fd->substruct) { SourceError(source, "BUG: no sub structure defined"); return qfalse; } ReadStructure(source, fd->substruct, (char *)p); p = (char *)p + fd->substruct->size; break; } } if (fd->type & FT_ARRAY) { if (!PC_ExpectAnyToken(source, &token)) { return qfalse; } if (!strcmp(token.string, "}")) { break; } if (strcmp(token.string, ",")) { SourceError(source, "expected a comma, found %s", token.string); return qfalse; } } } } return qtrue; }
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== bot_character_t *BotLoadCharacterFromFile( char *charfile, int skill ) { int indent, index, foundcharacter; bot_character_t *ch; source_t *source; token_t token; foundcharacter = qfalse; //a bot character is parsed in two phases PS_SetBaseFolder( "botfiles" ); source = LoadSourceFile( charfile ); PS_SetBaseFolder( "" ); if ( !source ) { botimport.Print( PRT_ERROR, "counldn't load %s\n", charfile ); return NULL; } //end if ch = ( bot_character_t * ) GetClearedMemory( sizeof( bot_character_t ) + MAX_CHARACTERISTICS * sizeof( bot_characteristic_t ) ); strcpy( ch->filename, charfile ); while ( PC_ReadToken( source, &token ) ) { if ( !strcmp( token.string, "skill" ) ) { if ( !PC_ExpectTokenType( source, TT_NUMBER, 0, &token ) ) { FreeSource( source ); BotFreeCharacterStrings( ch ); FreeMemory( ch ); return NULL; } //end if if ( !PC_ExpectTokenString( source, "{" ) ) { FreeSource( source ); BotFreeCharacterStrings( ch ); FreeMemory( ch ); return NULL; } //end if //if it's the correct skill if ( skill < 0 || token.intvalue == skill ) { foundcharacter = qtrue; ch->skill = token.intvalue; while ( PC_ExpectAnyToken( source, &token ) ) { if ( !strcmp( token.string, "}" ) ) { break; } if ( token.type != TT_NUMBER || !( token.subtype & TT_INTEGER ) ) { SourceError( source, "expected integer index, found %s\n", token.string ); FreeSource( source ); BotFreeCharacterStrings( ch ); FreeMemory( ch ); return NULL; } //end if index = token.intvalue; if ( index < 0 || index > MAX_CHARACTERISTICS ) { SourceError( source, "characteristic index out of range [0, %d]\n", MAX_CHARACTERISTICS ); FreeSource( source ); BotFreeCharacterStrings( ch ); FreeMemory( ch ); return NULL; } //end if if ( ch->c[ index ].type ) { SourceError( source, "characteristic %d already initialized\n", index ); FreeSource( source ); BotFreeCharacterStrings( ch ); FreeMemory( ch ); return NULL; } //end if if ( !PC_ExpectAnyToken( source, &token ) ) { FreeSource( source ); BotFreeCharacterStrings( ch ); FreeMemory( ch ); return NULL; } //end if if ( token.type == TT_NUMBER ) { if ( token.subtype & TT_FLOAT ) { ch->c[ index ].value._float = token.floatvalue; ch->c[ index ].type = CT_FLOAT; } //end if else { ch->c[ index ].value.integer = token.intvalue; ch->c[ index ].type = CT_INTEGER; } //end else } //end if else if ( token.type == TT_STRING ) { StripDoubleQuotes( token.string ); ch->c[ index ].value.string = GetMemory( strlen( token.string ) + 1 ); strcpy( ch->c[ index ].value.string, token.string ); ch->c[ index ].type = CT_STRING; } //end else if else { SourceError( source, "expected integer, float or string, found %s\n", token.string ); FreeSource( source ); BotFreeCharacterStrings( ch ); FreeMemory( ch ); return NULL; } //end else } //end if break; } //end if else { indent = 1; while ( indent ) { if ( !PC_ExpectAnyToken( source, &token ) ) { FreeSource( source ); BotFreeCharacterStrings( ch ); FreeMemory( ch ); return NULL; } //end if if ( !strcmp( token.string, "{" ) ) { indent++; } else if ( !strcmp( token.string, "}" ) ) { indent--; } } //end while } //end else } //end if else { SourceError( source, "unknown definition %s\n", token.string ); FreeSource( source ); BotFreeCharacterStrings( ch ); FreeMemory( ch ); return NULL; } //end else } //end while FreeSource( source ); // if ( !foundcharacter ) { BotFreeCharacterStrings( ch ); FreeMemory( ch ); return NULL; } //end if return ch; } //end of the function BotLoadCharacterFromFile
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== qboolean BotLoadCharacterFromFile(char *charfile, int skill, bot_character_t *ch) { int indent, index, foundcharacter; int source; pc_token_t token; foundcharacter = qfalse; //a bot character is parsed in two phases source = trap_PC_LoadSource(charfile, BOTFILESBASEFOLDER); if (!source) { BotAI_Print(PRT_ERROR, "counldn't load %s\n", charfile); return qfalse; } //end if strcpy(ch->filename, charfile); while(trap_PC_ReadToken(source, &token)) { if (!strcmp(token.string, "skill")) { if (!PC_ExpectTokenType(source, TT_NUMBER, 0, &token)) { trap_PC_FreeSource(source); BotFreeCharacterStrings(ch); return qfalse; } //end if if (!PC_ExpectTokenString(source, "{")) { trap_PC_FreeSource(source); BotFreeCharacterStrings(ch); return qfalse; } //end if //if it's the correct skill if (skill < 0 || token.intvalue == skill) { foundcharacter = qtrue; ch->skill = token.intvalue; while(PC_ExpectAnyToken(source, &token)) { if (!strcmp(token.string, "}")) break; if (token.type != TT_NUMBER || !(token.subtype & TT_INTEGER)) { PC_SourceError(source, "expected integer index, found %s", token.string); trap_PC_FreeSource(source); BotFreeCharacterStrings(ch); return qfalse; } //end if index = token.intvalue; if (index < 0 || index > MAX_CHARACTERISTICS) { PC_SourceError(source, "characteristic index out of range [0, %d]", MAX_CHARACTERISTICS); trap_PC_FreeSource(source); BotFreeCharacterStrings(ch); return qfalse; } //end if if (ch->c[index].type) { PC_SourceError(source, "characteristic %d already initialized", index); trap_PC_FreeSource(source); BotFreeCharacterStrings(ch); return qfalse; } //end if if (!PC_ExpectAnyToken(source, &token)) { trap_PC_FreeSource(source); BotFreeCharacterStrings(ch); return qfalse; } //end if if (token.type == TT_NUMBER) { if (token.subtype & TT_FLOAT) { ch->c[index].value._float = token.floatvalue; ch->c[index].type = CT_FLOAT; } //end if else { ch->c[index].value.integer = token.intvalue; ch->c[index].type = CT_INTEGER; } //end else } //end if else if (token.type == TT_STRING) { // ZTM: FIXME: ### I think I made this be done in the engine //StripDoubleQuotes(token.string); ch->c[index].value.string = trap_Alloc(strlen(token.string)+1, NULL); strcpy(ch->c[index].value.string, token.string); ch->c[index].type = CT_STRING; } //end else if else { PC_SourceError(source, "expected integer, float or string, found %s", token.string); trap_PC_FreeSource(source); BotFreeCharacterStrings(ch); return qfalse; } //end else } //end if break; } //end if else { indent = 1; while(indent) { if (!PC_ExpectAnyToken(source, &token)) { trap_PC_FreeSource(source); BotFreeCharacterStrings(ch); return qfalse; } //end if if (!strcmp(token.string, "{")) indent++; else if (!strcmp(token.string, "}")) indent--; } //end while } //end else } //end if else { PC_SourceError(source, "unknown definition %s", token.string); trap_PC_FreeSource(source); BotFreeCharacterStrings(ch); return qfalse; } //end else } //end while trap_PC_FreeSource(source); // if (!foundcharacter) { BotFreeCharacterStrings(ch); return qfalse; } //end if return qtrue; } //end of the function BotLoadCharacterFromFile