//=========================================================================== // // 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 ) { //BOTPRINT( PRT_MESSAGE, "retained %s\n", filename ); return config; } //end if } //end for if( avail == -1 ) { BOTPRINT( PRT_ERROR, "weightFileList was full trying to load %s\n", filename ); return NULL; } //end if } //end if PC_SetBaseFolder(BOTFILESBASEFOLDER); source = LoadSourceFile(filename); if (!source) { BOTPRINT(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\n"); 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\n", 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\n", 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 BOTPRINT(PRT_MESSAGE, "loaded %s\n", filename); #ifdef _DEBUG if (bot_developer) { BOTPRINT(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: - //=========================================================================== bot_character_t *BotLoadCharacterFromFile(char *charfile, int skill) { int indent, index, foundcharacter; bot_character_t *ch; source_t *source; token_t token; foundcharacter = false; //a bot character is parsed in two phases PC_SetBaseFolder(BOTFILESBASEFOLDER); source = LoadSourceFile(charfile); 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 = true; 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", 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]", MAX_CHARACTERISTICS); FreeSource(source); BotFreeCharacterStrings(ch); FreeMemory(ch); return NULL; } //end if if (ch->c[index].type) { SourceError(source, "characteristic %d already initialized", 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 = (char *)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", 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", 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: - //=========================================================================== weaponconfig_t *LoadWeaponConfig(char *filename) { int max_weaponinfo, max_projectileinfo; token_t token; char path[MAX_PATH]; int i, j; source_t *source; weaponconfig_t *wc; weaponinfo_t weaponinfo; max_weaponinfo = (int) LibVarValue("max_weaponinfo", "32"); if (max_weaponinfo < 0) { botimport.Print(PRT_ERROR, "max_weaponinfo = %d\n", max_weaponinfo); max_weaponinfo = 32; LibVarSet("max_weaponinfo", "32"); } //end if max_projectileinfo = (int) LibVarValue("max_projectileinfo", "32"); if (max_projectileinfo < 0) { botimport.Print(PRT_ERROR, "max_projectileinfo = %d\n", max_projectileinfo); max_projectileinfo = 32; LibVarSet("max_projectileinfo", "32"); } //end if strncpy(path, filename, MAX_PATH); PC_SetBaseFolder(BOTFILESBASEFOLDER); source = LoadSourceFile(path); if (!source) { botimport.Print(PRT_ERROR, "counldn't load %s\n", path); return NULL; } //end if //initialize weapon config wc = (weaponconfig_t *) GetClearedHunkMemory(sizeof(weaponconfig_t) + max_weaponinfo * sizeof(weaponinfo_t) + max_projectileinfo * sizeof(projectileinfo_t)); wc->weaponinfo = (weaponinfo_t *) ((char *) wc + sizeof(weaponconfig_t)); wc->projectileinfo = (projectileinfo_t *) ((char *) wc->weaponinfo + max_weaponinfo * sizeof(weaponinfo_t)); wc->numweapons = max_weaponinfo; wc->numprojectiles = 0; //parse the source file while(PC_ReadToken(source, &token)) { if (!strcmp(token.string, "weaponinfo")) { Com_Memset(&weaponinfo, 0, sizeof(weaponinfo_t)); if (!ReadStructure(source, &weaponinfo_struct, (char *) &weaponinfo)) { FreeMemory(wc); FreeSource(source); return NULL; } //end if if (weaponinfo.number < 0 || weaponinfo.number >= max_weaponinfo) { botimport.Print(PRT_ERROR, "weapon info number %d out of range in %s\n", weaponinfo.number, path); FreeMemory(wc); FreeSource(source); return NULL; } //end if Com_Memcpy(&wc->weaponinfo[weaponinfo.number], &weaponinfo, sizeof(weaponinfo_t)); wc->weaponinfo[weaponinfo.number].valid = qtrue; } //end if else if (!strcmp(token.string, "projectileinfo")) { if (wc->numprojectiles >= max_projectileinfo) { botimport.Print(PRT_ERROR, "more than %d projectiles defined in %s\n", max_projectileinfo, path); FreeMemory(wc); FreeSource(source); return NULL; } //end if Com_Memset(&wc->projectileinfo[wc->numprojectiles], 0, sizeof(projectileinfo_t)); if (!ReadStructure(source, &projectileinfo_struct, (char *) &wc->projectileinfo[wc->numprojectiles])) { FreeMemory(wc); FreeSource(source); return NULL; } //end if wc->numprojectiles++; } //end if else { botimport.Print(PRT_ERROR, "unknown definition %s in %s\n", token.string, path); FreeMemory(wc); FreeSource(source); return NULL; } //end else } //end while FreeSource(source); //fix up weapons for (i = 0; i < wc->numweapons; i++) { if (!wc->weaponinfo[i].valid) continue; if (!wc->weaponinfo[i].name[0]) { botimport.Print(PRT_ERROR, "weapon %d has no name in %s\n", i, path); FreeMemory(wc); return NULL; } //end if if (!wc->weaponinfo[i].projectile[0]) { botimport.Print(PRT_ERROR, "weapon %s has no projectile in %s\n", wc->weaponinfo[i].name, path); FreeMemory(wc); return NULL; } //end if //find the projectile info and copy it to the weapon info for (j = 0; j < wc->numprojectiles; j++) { if (!strcmp(wc->projectileinfo[j].name, wc->weaponinfo[i].projectile)) { Com_Memcpy(&wc->weaponinfo[i].proj, &wc->projectileinfo[j], sizeof(projectileinfo_t)); break; } //end if } //end for if (j == wc->numprojectiles) { botimport.Print(PRT_ERROR, "weapon %s uses undefined projectile in %s\n", wc->weaponinfo[i].name, path); FreeMemory(wc); return NULL; } //end if } //end for if (!wc->numweapons) botimport.Print(PRT_WARNING, "no weapon info loaded\n"); botimport.Print(PRT_MESSAGE, "loaded %s\n", path); return wc; } //end of the function LoadWeaponConfig
static itemconfig_t* LoadItemConfig( const char* filename ) { int max_iteminfo = ( int )LibVarValue( "max_iteminfo", "256" ); if ( max_iteminfo < 0 ) { BotImport_Print( PRT_ERROR, "max_iteminfo = %d\n", max_iteminfo ); max_iteminfo = 256; LibVarSet( "max_iteminfo", "256" ); } if ( GGameType & GAME_Quake3 ) { PC_SetBaseFolder( BOTFILESBASEFOLDER ); } char path[ MAX_QPATH ]; String::NCpyZ( path, filename, MAX_QPATH ); source_t* source = LoadSourceFile( path ); if ( !source ) { BotImport_Print( PRT_ERROR, "counldn't load %s\n", path ); return NULL; } //initialize item config itemconfig_t* ic = ( itemconfig_t* )Mem_ClearedAlloc( sizeof ( itemconfig_t ) + max_iteminfo * sizeof ( iteminfo_t ) ); ic->iteminfo = ( iteminfo_t* )( ( char* )ic + sizeof ( itemconfig_t ) ); ic->numiteminfo = 0; //parse the item config file token_t token; while ( PC_ReadToken( source, &token ) ) { if ( !String::Cmp( token.string, "iteminfo" ) ) { if ( ic->numiteminfo >= max_iteminfo ) { SourceError( source, "more than %d item info defined\n", max_iteminfo ); Mem_Free( ic ); FreeSource( source ); return NULL; } iteminfo_t* ii = &ic->iteminfo[ ic->numiteminfo ]; Com_Memset( ii, 0, sizeof ( iteminfo_t ) ); if ( !PC_ExpectTokenType( source, TT_STRING, 0, &token ) ) { Mem_Free( ic ); FreeSource( source ); return NULL; } StripDoubleQuotes( token.string ); String::NCpy( ii->classname, token.string, sizeof ( ii->classname ) - 1 ); if ( !ReadStructure( source, &iteminfo_struct, ( char* )ii ) ) { Mem_Free( ic ); FreeSource( source ); return NULL; } ii->number = ic->numiteminfo; ic->numiteminfo++; } else { SourceError( source, "unknown definition %s\n", token.string ); Mem_Free( ic ); FreeSource( source ); return NULL; } } FreeSource( source ); if ( !ic->numiteminfo ) { BotImport_Print( PRT_WARNING, "no item info loaded\n" ); } BotImport_Print( PRT_MESSAGE, "loaded %s\n", path ); return ic; }