⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 be_ai_weight.c

📁 quakeIII源码这个不用我多说吧
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.

This file is part of Quake III Arena source code.

Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.

Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
===========================================================================
*/

/*****************************************************************************
 * name:		be_ai_weight.c
 *
 * desc:		fuzzy logic
 *
 * $Archive: /MissionPack/code/botlib/be_ai_weight.c $
 *
 *****************************************************************************/

#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_log.h"
#include "l_utils.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_libvar.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_ai_weight.h"

#define MAX_INVENTORYVALUE			999999
#define EVALUATERECURSIVELY

#define MAX_WEIGHT_FILES			128
weightconfig_t	*weightFileList[MAX_WEIGHT_FILES];

//===========================================================================
//
// 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:		-
//===========================================================================
int ReadFuzzyWeight(source_t *source, fuzzyseperator_t *fs)
{
	if (PC_CheckTokenString(source, "balance"))
	{
		fs->type = WT_BALANCE;
		if (!PC_ExpectTokenString(source, "(")) return qfalse;
		if (!ReadValue(source, &fs->weight)) return qfalse;
		if (!PC_ExpectTokenString(source, ",")) return qfalse;
		if (!ReadValue(source, &fs->minweight)) return qfalse;
		if (!PC_ExpectTokenString(source, ",")) return qfalse;
		if (!ReadValue(source, &fs->maxweight)) return qfalse;
		if (!PC_ExpectTokenString(source, ")")) return qfalse;
	} //end if
	else
	{
		fs->type = 0;
		if (!ReadValue(source, &fs->weight)) return qfalse;
		fs->minweight = fs->weight;
		fs->maxweight = fs->weight;
	} //end if
	if (!PC_ExpectTokenString(source, ";")) return qfalse;
	return qtrue;
} //end of the function ReadFuzzyWeight
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void FreeFuzzySeperators_r(fuzzyseperator_t *fs)
{
	if (!fs) return;
	if (fs->child) FreeFuzzySeperators_r(fs->child);
	if (fs->next) FreeFuzzySeperators_r(fs->next);
	FreeMemory(fs);
} //end of the function FreeFuzzySeperators
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
void FreeWeightConfig2(weightconfig_t *config)
{
	int i;

	for (i = 0; i < config->numweights; i++)
	{
		FreeFuzzySeperators_r(config->weights[i].firstseperator);
		if (config->weights[i].name) FreeMemory(config->weights[i].name);
	} //end for
	FreeMemory(config);
} //end of the function FreeWeightConfig2
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
void FreeWeightConfig(weightconfig_t *config)
{
	if (!LibVarGetValue("bot_reloadcharacters")) return;
	FreeWeightConfig2(config);
} //end of the function FreeWeightConfig
//===========================================================================
//
// 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\n");
					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\n", 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\n", 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\n");
		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;
		lastfs = 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;
	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

	PC_SetBaseFolder(BOTFILESBASEFOLDER);
	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\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
	botimport.Print(PRT_MESSAGE, "loaded %s\n", filename);
#ifdef DEBUG
	if (bot_developer)
	{
		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
#if 0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
qboolean WriteFuzzyWeight(FILE *fp, fuzzyseperator_t *fs)
{
	if (fs->type == WT_BALANCE)
	{
		if (fprintf(fp, " return balance(") < 0) return qfalse;
		if (!WriteFloat(fp, fs->weight)) return qfalse;
		if (fprintf(fp, ",") < 0) return qfalse;
		if (!WriteFloat(fp, fs->minweight)) return qfalse;
		if (fprintf(fp, ",") < 0) return qfalse;
		if (!WriteFloat(fp, fs->maxweight)) return qfalse;
		if (fprintf(fp, ");\n") < 0) return qfalse;
	} //end if
	else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -