//======================================================================== // // Parameter: - // Returns: - // Changes Globals: - //======================================================================== void BotFreeCharacter2( int handle ) { if ( handle <= 0 || handle > MAX_CLIENTS ) { botimport.Print( PRT_FATAL, "character handle %d out of range\n", handle ); return; } //end if if ( !botcharacters[handle] ) { botimport.Print( PRT_FATAL, "invalid character %d\n", handle ); return; } //end if BotFreeCharacterStrings( botcharacters[handle] ); FreeMemory( botcharacters[handle] ); botcharacters[handle] = NULL; } //end of the function BotFreeCharacter2
//======================================================================== // // Parameter: - // Returns: - // Changes Globals: - //======================================================================== void BotFreeCharacter2(int handle) { if (handle <= 0 || handle >= MAX_BOT_CHARACTERS) { BotAI_Print(PRT_FATAL, "character handle %d out of range\n", handle); return; } //end if if (!botcharacters[handle].skill) { BotAI_Print(PRT_FATAL, "invalid character %d\n", handle); return; } //end if BotFreeCharacterStrings(&botcharacters[handle]); Com_Memset(&botcharacters[handle], 0, sizeof (bot_character_t)); } //end of the function BotFreeCharacter2
//=========================================================================== // // 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