//===========================================================================
//
// 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
Esempio n. 2
0
//===========================================================================
//
// 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
Esempio n. 3
0
//===========================================================================
//
// 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
Esempio n. 4
0
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;
}