コード例 #1
0
ファイル: be_interface.cpp プロジェクト: bibendovsky/rtcw
int Export_BotLibLoadMap( const char *mapname ) {
#ifdef DEBUG
	int starttime = Sys_MilliSeconds();
#endif
	int errnum;

	if ( !BotLibSetup( "BotLoadMap" ) ) {
		return BLERR_LIBRARYNOTSETUP;
	}
	//

#if defined RTCW_ET
	// if the mapname is NULL, then this is a restart
	if ( !mapname ) {
		// START	Arnout changes, 29-08-2002.
		// don't init the heap if no aas loaded, causes "SV_Bot_HunkAlloc: Alloc with marks already set"
		if ( ( *aasworld ).loaded ) {
			AAS_InitAASLinkHeap();
			AAS_EnableAllAreas();
		}
		// END	Arnout changes, 29-08-2002.
		( *aasworld ).numframes = 0;
		memset( ( *aasworld ).arealinkedentities, 0, ( *aasworld ).numareas * sizeof( aas_link_t * ) );
		memset( ( *aasworld ).entities, 0, ( *aasworld ).maxentities * sizeof( aas_entity_t ) );
		return BLERR_NOERROR;
	}
	//
#endif // RTCW_XX

	botimport.Print( PRT_MESSAGE, "------------ Map Loading ------------\n" );
	//startup AAS for the current map, model and sound index
	errnum = AAS_LoadMap( mapname );
	if ( errnum != BLERR_NOERROR ) {
		return errnum;
	}
	//initialize the items in the level
	BotInitLevelItems();        //be_ai_goal.h
	BotSetBrushModelTypes();    //be_ai_move.h
	//
	botimport.Print( PRT_MESSAGE, "-------------------------------------\n" );
#ifdef DEBUG
	botimport.Print( PRT_MESSAGE, "map loaded in %d msec\n", Sys_MilliSeconds() - starttime );
#endif
	//
	return BLERR_NOERROR;
} //end of the function Export_BotLibLoadMap
コード例 #2
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int Export_BotLibLoadMap(const char *mapname)
{
#ifdef DEBUG
	int starttime = Sys_MilliSeconds();
#endif
	int errnum;

	if (!BotLibSetup("BotLoadMap")) return BLERR_LIBRARYNOTSETUP;
	//
	botimport.Print(PRT_MESSAGE, "------------ Map Loading ------------\n");
	//startup AAS for the current map, model and sound index
	errnum = AAS_LoadMap(mapname);
	if (errnum != BLERR_NOERROR) return errnum;
	//initialize the items in the level
	BotInitLevelItems();		//be_ai_goal.h
	BotSetBrushModelTypes();	//be_ai_move.h
	//
	botimport.Print(PRT_MESSAGE, "-------------------------------------\n");
#ifdef DEBUG
	botimport.Print(PRT_MESSAGE, "map loaded in %d msec\n", Sys_MilliSeconds() - starttime);
#endif
	//
	return BLERR_NOERROR;
} //end of the function Export_BotLibLoadMap
コード例 #3
0
//===========================================================================
//
// 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
コード例 #4
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int AAS_AlternativeRouteGoals(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
										 aas_altroutegoal_t *altroutegoals, int maxaltroutegoals,
										 int type)
{
#ifndef ENABLE_ALTROUTING
	return 0;
#else
	int i, j, bestareanum;
	int numaltroutegoals, nummidrangeareas;
	int starttime, goaltime, goaltraveltime;
	float dist, bestdist;
	vec3_t mid, dir;
#ifdef ALTROUTE_DEBUG
	int startmillisecs;

	startmillisecs = Sys_MilliSeconds();
#endif

	if (!startareanum || !goalareanum)
		return 0;
	//travel time towards the goal area
	goaltraveltime = AAS_AreaTravelTimeToGoalArea(startareanum, start, goalareanum, travelflags);
	//clear the midrange areas
	Com_Memset(midrangeareas, 0, aasworld.numareas * sizeof(midrangearea_t));
	numaltroutegoals = 0;
	//
	nummidrangeareas = 0;
	//
	for (i = 1; i < aasworld.numareas; i++)
	{
		//
		if (!(type & ALTROUTEGOAL_ALL))
		{
			if (!(type & ALTROUTEGOAL_CLUSTERPORTALS && (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)))
			{
				if (!(type & ALTROUTEGOAL_VIEWPORTALS && (aasworld.areasettings[i].contents & AREACONTENTS_VIEWPORTAL)))
				{
					continue;
				} //end if
			} //end if
		} //end if
		//if the area has no reachabilities
		if (!AAS_AreaReachability(i)) continue;
		//tavel time from the area to the start area
		starttime = AAS_AreaTravelTimeToGoalArea(startareanum, start, i, travelflags);
		if (!starttime) continue;
		//if the travel time from the start to the area is greater than the shortest goal travel time
		if (starttime > (float) 1.1 * goaltraveltime) continue;
		//travel time from the area to the goal area
		goaltime = AAS_AreaTravelTimeToGoalArea(i, NULL, goalareanum, travelflags);
		if (!goaltime) continue;
		//if the travel time from the area to the goal is greater than the shortest goal travel time
		if (goaltime > (float) 0.8 * goaltraveltime) continue;
		//this is a mid range area
		midrangeareas[i].valid = qtrue;
		midrangeareas[i].starttime = starttime;
		midrangeareas[i].goaltime = goaltime;
		Log_Write("%d midrange area %d", nummidrangeareas, i);
		nummidrangeareas++;
	} //end for
	//
	for (i = 1; i < aasworld.numareas; i++)
	{
		if (!midrangeareas[i].valid) continue;
		//get the areas in one cluster
		numclusterareas = 0;
		AAS_AltRoutingFloodCluster_r(i);
		//now we've got a cluster with areas through which an alternative route could go
		//get the 'center' of the cluster
		VectorClear(mid);
		for (j = 0; j < numclusterareas; j++)
		{
			VectorAdd(mid, aasworld.areas[clusterareas[j]].center, mid);
		} //end for
		VectorScale(mid, 1.0 / numclusterareas, mid);
		//get the area closest to the center of the cluster
		bestdist = 999999;
		bestareanum = 0;
		for (j = 0; j < numclusterareas; j++)
		{
			VectorSubtract(mid, aasworld.areas[clusterareas[j]].center, dir);
			dist = VectorLength(dir);
			if (dist < bestdist)
			{
				bestdist = dist;
				bestareanum = clusterareas[j];
			} //end if
		} //end for
		//now we've got an area for an alternative route
		//FIXME: add alternative goal origin
		VectorCopy(aasworld.areas[bestareanum].center, altroutegoals[numaltroutegoals].origin);
		altroutegoals[numaltroutegoals].areanum = bestareanum;
		altroutegoals[numaltroutegoals].starttraveltime = midrangeareas[bestareanum].starttime;
		altroutegoals[numaltroutegoals].goaltraveltime = midrangeareas[bestareanum].goaltime;
		altroutegoals[numaltroutegoals].extratraveltime =
					(midrangeareas[bestareanum].starttime + midrangeareas[bestareanum].goaltime) -
								goaltraveltime;
		numaltroutegoals++;
		//
#ifdef ALTROUTE_DEBUG
		AAS_ShowAreaPolygons(bestareanum, 1, qtrue);
#endif
		//don't return more than the maximum alternative route goals
		if (numaltroutegoals >= maxaltroutegoals) break;
	} //end for
#ifdef ALTROUTE_DEBUG
	botimport.Print(PRT_MESSAGE, "alternative route goals in %d msec\n", Sys_MilliSeconds() - startmillisecs);
#endif
	return numaltroutegoals;
#endif
} //end of the function AAS_AlternativeRouteGoals
コード例 #5
0
qboolean AAS_RT_ReadRouteTable(fileHandle_t fp)
{
	int                  ident, version, i;
	unsigned short int   crc, crc_aas;
	aas_rt_t             *routetable;
	aas_rt_child_t       *child;
	aas_rt_parent_t      *parent;
	aas_rt_parent_link_t *plink;
	unsigned short int   *psi;

	qboolean doswap;

#ifdef DEBUG_READING_TIME
	int pretime;

	pretime = Sys_MilliSeconds();
#endif

	routetable = (*aasworld).routetable;

	doswap = (LittleLong(1) != 1);

	// check ident
	AAS_RT_DBG_Read(&ident, sizeof(ident), fp);
	ident = LittleLong(ident);

	if (ident != RTBID)
	{
		AAS_Error("File is not an RTB file\n");
		botimport.FS_FCloseFile(fp);
		return qfalse;
	}

	// check version
	AAS_RT_DBG_Read(&version, sizeof(version), fp);
	version = LittleLong(version);

	if (version != RTBVERSION)
	{
		AAS_Error("File is version %i not %i\n", version, RTBVERSION);
		botimport.FS_FCloseFile(fp);
		return qfalse;
	}

	// read the CRC check on the AAS data
	AAS_RT_DBG_Read(&crc, sizeof(crc), fp);
	crc = LittleShort(crc);

	// calculate a CRC on the AAS areas
	crc_aas = CRC_ProcessString((unsigned char *)(*aasworld).areas, sizeof(aas_area_t) * (*aasworld).numareas);

	if (crc != crc_aas)
	{
		AAS_Error("Route-table is from different AAS file, ignoring.\n");
		botimport.FS_FCloseFile(fp);
		return qfalse;
	}

	// read the route-table

	// children
	botimport.FS_Read(&routetable->numChildren, sizeof(int), fp);
	routetable->numChildren = LittleLong(routetable->numChildren);
	routetable->children    = (aas_rt_child_t *) AAS_RT_GetClearedMemory(routetable->numChildren * sizeof(aas_rt_child_t));
	botimport.FS_Read(routetable->children, routetable->numChildren * sizeof(aas_rt_child_t), fp);
	child = &routetable->children[0];
	if (doswap)
	{
		for (i = 0; i < routetable->numChildren; i++, child++)
		{
			child->areanum          = LittleShort(child->areanum);
			child->numParentLinks   = LittleLong(child->numParentLinks);
			child->startParentLinks = LittleLong(child->startParentLinks);
		}
	}

	// parents
	botimport.FS_Read(&routetable->numParents, sizeof(int), fp);
	routetable->numParents = LittleLong(routetable->numParents);
	routetable->parents    = (aas_rt_parent_t *) AAS_RT_GetClearedMemory(routetable->numParents * sizeof(aas_rt_parent_t));
	botimport.FS_Read(routetable->parents, routetable->numParents * sizeof(aas_rt_parent_t), fp);
	parent = &routetable->parents[0];
	if (doswap)
	{
		for (i = 0; i < routetable->numParents; i++, parent++)
		{
			parent->areanum             = LittleShort(parent->areanum);
			parent->numParentChildren   = LittleLong(parent->numParentChildren);
			parent->startParentChildren = LittleLong(parent->startParentChildren);
			parent->numVisibleParents   = LittleLong(parent->numVisibleParents);
			parent->startVisibleParents = LittleLong(parent->startVisibleParents);
		}
	}

	// parentChildren
	botimport.FS_Read(&routetable->numParentChildren, sizeof(int), fp);
	routetable->numParentChildren = LittleLong(routetable->numParentChildren);
	routetable->parentChildren    = (unsigned short int *) AAS_RT_GetClearedMemory(routetable->numParentChildren * sizeof(unsigned short int));
	botimport.FS_Read(routetable->parentChildren, routetable->numParentChildren * sizeof(unsigned short int), fp);
	psi = &routetable->parentChildren[0];
	if (doswap)
	{
		for (i = 0; i < routetable->numParentChildren; i++, psi++)
		{
			*psi = LittleShort(*psi);
		}
	}

	// visibleParents
	botimport.FS_Read(&routetable->numVisibleParents, sizeof(int), fp);
	routetable->numVisibleParents = LittleLong(routetable->numVisibleParents);
	routetable->visibleParents    = (unsigned short int *) AAS_RT_GetClearedMemory(routetable->numVisibleParents * sizeof(unsigned short int));
	botimport.FS_Read(routetable->visibleParents, routetable->numVisibleParents * sizeof(unsigned short int), fp);
	psi = &routetable->visibleParents[0];
	if (doswap)
	{
		for (i = 0; i < routetable->numVisibleParents; i++, psi++)
		{
			*psi = LittleShort(*psi);
		}
	}

	// parentLinks
	botimport.FS_Read(&routetable->numParentLinks, sizeof(int), fp);
	routetable->numParentLinks = LittleLong(routetable->numParentLinks);
	routetable->parentLinks    = (aas_rt_parent_link_t *) AAS_RT_GetClearedMemory(routetable->numParentLinks * sizeof(aas_rt_parent_link_t));
	botimport.FS_Read(routetable->parentLinks, routetable->numParentLinks * sizeof(aas_parent_link_t), fp);
	plink = &routetable->parentLinks[0];
	if (doswap)
	{
		for (i = 0; i < routetable->numParentLinks; i++, plink++)
		{
			plink->childIndex = LittleShort(plink->childIndex);
			plink->parent     = LittleShort(plink->parent);
		}
	}

	// build the areaChildIndexes
	routetable->areaChildIndexes = (unsigned short int *) AAS_RT_GetClearedMemory((*aasworld).numareas * sizeof(unsigned short int));
	child                        = routetable->children;
	for (i = 0; i < routetable->numChildren; i++, child++)
	{
		routetable->areaChildIndexes[child->areanum] = i + 1;
	}

	botimport.Print(PRT_MESSAGE, "Total Parents: %d\n", routetable->numParents);
	botimport.Print(PRT_MESSAGE, "Total Children: %d\n", routetable->numChildren);
	botimport.Print(PRT_MESSAGE, "Total Memory Used: %d\n", memorycount);

#ifdef DEBUG_READING_TIME
	botimport.Print(PRT_MESSAGE, "Route-Table read time: %i\n", Sys_MilliSeconds() - pretime);
#endif

	botimport.FS_FCloseFile(fp);
	return qtrue;
}
コード例 #6
0
ファイル: be_ai_char.c プロジェクト: gfx0/Unvanquished
//===========================================================================
//
// Parameter:           -
// Returns:             -
// Changes Globals:     -
//===========================================================================
int BotLoadCachedCharacter( char *charfile, int skill, int reload )
{
    int             handle, cachedhandle;
    bot_character_t *ch = NULL;

#ifdef DEBUG
    int             starttime;

    starttime = Sys_MilliSeconds();
#endif //DEBUG

    //find a free spot for a character
    for ( handle = 1; handle <= MAX_CLIENTS; handle++ )
    {
        if ( !botcharacters[ handle ] )
        {
            break;
        }
    } //end for

    if ( handle > MAX_CLIENTS )
    {
        return 0;
    }

    //try to load a cached character with the given skill
    if ( !reload )
    {
        cachedhandle = BotFindCachedCharacter( charfile, skill );

        if ( cachedhandle )
        {
            //botimport.Print(PRT_MESSAGE, "loaded cached skill %d from %s\n", skill, charfile);
            return cachedhandle;
        } //end if
    } //end else

    //try to load the character with the given skill
    ch = BotLoadCharacterFromFile( charfile, skill );

    if ( ch )
    {
        botcharacters[ handle ] = ch;
        //
        //botimport.Print(PRT_MESSAGE, "loaded skill %d from %s\n", skill, charfile);
#ifdef DEBUG

        if ( bot_developer )
        {
            botimport.Print( PRT_MESSAGE, "skill %d loaded in %d msec from %s\n", skill, Sys_MilliSeconds() - starttime, charfile );
        } //end if

#endif //DEBUG
        return handle;
    } //end if

    //
    botimport.Print( PRT_WARNING, "couldn't find skill %d in %s\n", skill, charfile );

    //
    if ( !reload )
    {
        //try to load a cached default character with the given skill
        cachedhandle = BotFindCachedCharacter( "bots/default_c.c", skill );

        if ( cachedhandle )
        {
            botimport.Print( PRT_MESSAGE, "loaded cached default skill %d from %s\n", skill, charfile );
            return cachedhandle;
        } //end if
    } //end if

    //try to load the default character with the given skill
    ch = BotLoadCharacterFromFile( DEFAULT_CHARACTER, skill );

    if ( ch )
    {
        botcharacters[ handle ] = ch;
        //botimport.Print(PRT_MESSAGE, "loaded default skill %d from %s\n", skill, charfile);
        return handle;
    } //end if

    //
    if ( !reload )
    {
        //try to load a cached character with any skill
        cachedhandle = BotFindCachedCharacter( charfile, -1 );

        if ( cachedhandle )
        {
            //botimport.Print(PRT_MESSAGE, "loaded cached skill %d from %s\n", botcharacters[cachedhandle]->skill, charfile);
            return cachedhandle;
        } //end if
    } //end if

    //try to load a character with any skill
    ch = BotLoadCharacterFromFile( charfile, -1 );

    if ( ch )
    {
        botcharacters[ handle ] = ch;
        //botimport.Print(PRT_MESSAGE, "loaded skill %d from %s\n", ch->skill, charfile);
        return handle;
    } //end if

    //
    if ( !reload )
    {
        //try to load a cached character with any skill
        cachedhandle = BotFindCachedCharacter( DEFAULT_CHARACTER, -1 );

        if ( cachedhandle )
        {
            botimport.Print( PRT_MESSAGE, "loaded cached default skill %d from %s\n", botcharacters[ cachedhandle ]->skill,
                             charfile );
            return cachedhandle;
        } //end if
    } //end if

    //try to load a character with any skill
    ch = BotLoadCharacterFromFile( DEFAULT_CHARACTER, -1 );

    if ( ch )
    {
        botcharacters[ handle ] = ch;
        botimport.Print( PRT_MESSAGE, "loaded default skill %d from %s\n", ch->skill, charfile );
        return handle;
    } //end if

    //
    botimport.Print( PRT_WARNING, "couldn't load any skill from %s\n", charfile );
    //couldn't load any character
    return 0;
} //end of the function BotLoadCachedCharacter
コード例 #7
0
ファイル: be_aas_routetable.c プロジェクト: Justasic/RTCW-MP
qboolean AAS_RT_GetHidePos( vec3_t srcpos, int srcnum, int srcarea, vec3_t destpos, int destnum, int destarea, vec3_t returnPos ) {
	static int tfl = TFL_DEFAULT & ~( TFL_JUMPPAD | TFL_ROCKETJUMP | TFL_BFGJUMP | TFL_GRAPPLEHOOK | TFL_DOUBLEJUMP | TFL_RAMPJUMP | TFL_STRAFEJUMP | TFL_LAVA );   //----(SA)	modified since slime is no longer deadly
//	static int tfl = TFL_DEFAULT & ~(TFL_JUMPPAD|TFL_ROCKETJUMP|TFL_BFGJUMP|TFL_GRAPPLEHOOK|TFL_DOUBLEJUMP|TFL_RAMPJUMP|TFL_STRAFEJUMP|TFL_SLIME|TFL_LAVA);

#if 1
	// use MrE's breadth first method
	int hideareanum;
//	int pretime;

	// disabled this so grenade hiding works
	//if (!srcarea || !destarea)
	//	return qfalse;

//	pretime = -Sys_MilliSeconds();

	hideareanum = AAS_NearestHideArea( srcnum, srcpos, srcarea, destnum, destpos, destarea, tfl );
	if ( !hideareanum ) {
//		botimport.Print(PRT_MESSAGE, "Breadth First HidePos FAILED: %i ms\n", pretime + Sys_MilliSeconds());
		return qfalse;
	}
	// we found a valid hiding area
	VectorCopy( ( *aasworld ).areawaypoints[hideareanum], returnPos );

//	botimport.Print(PRT_MESSAGE, "Breadth First HidePos: %i ms\n", pretime + Sys_MilliSeconds());

	return qtrue;

#else
	// look around at random parent areas, if any of them have a center point
	// that isn't visible from "destpos", then return it's position in returnPos

	int i, j, pathArea, dir;
	unsigned short int destTravelTime;
	aas_rt_parent_t *srcParent, *travParent, *destParent;
	aas_rt_child_t  *srcChild, *destChild, *travChild;
	aas_rt_route_t  *route;
	vec3_t destVec;
	float destTravelDist;
	static float lastTime;
	static int frameCount, maxPerFrame = 2;
	int firstreach;
	aas_reachability_t  *reachability, *reach;
	qboolean startVisible;
	unsigned short int bestTravelTime, thisTravelTime, elapsedTravelTime;
	#define MAX_HIDE_TRAVELTIME     1000    // 10 seconds is a very long way away
	unsigned char destVisLookup[MAX_PARENTS];
	unsigned short int *destVisTrav;

	aas_rt_t    *rt;

	const int MAX_CHECK_VISPARENTS    = 100;
	int visparents_count, total_parents_checked;
	int thisParentIndex;
	int pretime;

	if ( !( rt = aasworld->routetable ) ) { // no route table present
		return qfalse;
	}
/*
	if (lastTime > (AAS_Time() - 0.1)) {
		if (frameCount++ > maxPerFrame) {
			return qfalse;
		}
	} else {
		frameCount = 0;
		lastTime = AAS_Time();
	}
*/
	pretime = -Sys_MilliSeconds();

	// is the src area grounded?
	if ( !( srcChild = AAS_RT_GetChild( srcarea ) ) ) {
		return qfalse;
	}
	// does it have a parent?
// all valid areas have a parent
//	if (!srcChild->numParentLinks) {
//		return qfalse;
//	}
	// get the dest (enemy) area
	if ( !( destChild = AAS_RT_GetChild( destarea ) ) ) {
		return qfalse;
	}
	destParent = &rt->parents[ rt->parentLinks[destChild->startParentLinks].parent ];
	//
	// populate the destVisAreas
	memset( destVisLookup, 0, sizeof( destVisLookup ) );
	destVisTrav = rt->visibleParents + destParent->startVisibleParents;
	for ( i = 0; i < destParent->numVisibleParents; i++, destVisTrav++ ) {
		destVisLookup[*destVisTrav] = 1;
	}
	//
	// use the first parent to source the vis areas from
	srcParent = &rt->parents[ rt->parentLinks[srcChild->startParentLinks].parent ];
	//
	// set the destTravelTime
	if ( route = AAS_RT_GetRoute( srcarea, srcpos, destarea ) ) {
		destTravelTime = route->travel_time;
	} else {
		destTravelTime = 0;
	}
	bestTravelTime = MAX_HIDE_TRAVELTIME;   // ignore any routes longer than 10 seconds away
	// set the destVec
	VectorSubtract( destpos, srcpos, destVec );
	destTravelDist = VectorNormalize( destVec );
	//
	// randomize the direction we traverse the list, so the hiding spot isn't always the same
	if ( rand() % 2 ) {
		dir = 1;    // forward
	} else {
		dir = -1;   // reverse
	}
	// randomize the starting area
	if ( srcParent->numVisibleParents ) {
		i = rand() % srcParent->numVisibleParents;
	} else {    // prevent divide by zero
		i = 0;
	}
	//
	// setup misc stuff
	reachability = ( *aasworld ).reachability;
	startVisible = botimport.AICast_VisibleFromPos( destpos, destnum, srcpos, srcnum, qfalse );
	//
	// set the firstreach to prevent having to do an array and pointer lookup for each destination
	firstreach = ( *aasworld ).areasettings[srcarea].firstreachablearea;
	//
	// just check random parent areas, traversing the route until we find an area that can't be seen from the dest area
	for ( visparents_count = 0, total_parents_checked = 0; visparents_count < MAX_CHECK_VISPARENTS && total_parents_checked < rt->numParents; total_parents_checked++ ) {
		thisParentIndex = rand() % rt->numParents;
		travParent = &rt->parents[ thisParentIndex ];
		//
		// never go to the enemy's areas
		if ( travParent->areanum == destarea ) {
			continue;
		}
		//
		// if it's visible from dest, ignore it
		if ( destVisLookup[thisParentIndex] ) {
			continue;
		}
		//
		visparents_count++;
		// they might be visible, check to see if the path to the area, takes us towards the
		// enemy we are trying to hide from
		{
			qboolean invalidRoute;
			vec3_t curPos, lastVec;
			#define     GETHIDE_MAX_CHECK_PATHS     15
			//
			invalidRoute = qfalse;
			// initialize the pathArea
			pathArea = srcarea;
			VectorCopy( srcpos, curPos );
			// now evaluate the path
			for ( j = 0; j < GETHIDE_MAX_CHECK_PATHS; j++ ) {
				// get the reachability to the travParent
				if ( !( route = AAS_RT_GetRoute( pathArea, curPos, travParent->areanum ) ) ) {
					// we can't get to the travParent, so don't bother checking it
					invalidRoute = qtrue;
					break;
				}
				// set the pathArea
				reach = &reachability[route->reachable_index];
				// how far have we travelled so far?
				elapsedTravelTime = AAS_AreaTravelTimeToGoalArea( pathArea, curPos, reach->areanum, tfl );
				// add the travel to the center of the area
				elapsedTravelTime += AAS_AreaTravelTime( reach->areanum, reach->end, ( *aasworld ).areas[reach->areanum].center );
				// have we gone too far already?
				if ( elapsedTravelTime > bestTravelTime ) {
					invalidRoute = qtrue;
					break;
				} else {
					thisTravelTime = route->travel_time;
				}
				//
				// if this travel would have us do something wierd
				if ( ( reach->traveltype == TRAVEL_WALKOFFLEDGE ) && ( reach->traveltime > 500 ) ) {
					invalidRoute = qtrue;
					break;
				}
				//
				pathArea = reach->areanum;
				VectorCopy( reach->end, curPos );
				//
				// if this moves us into the enemies area, skip it
				if ( pathArea == destarea ) {
					invalidRoute = qtrue;
					break;
				}
				// if we are very close, don't get any closer under any circumstances
				{
					vec3_t vec;
					float dist;
					//
					VectorSubtract( destpos, reachability[firstreach + route->reachable_index].end, vec );
					dist = VectorNormalize( vec );
					//
					if ( destTravelTime < 400 ) {
						if ( dist < destTravelDist ) {
							invalidRoute = qtrue;
							break;
						}
						if ( DotProduct( destVec, vec ) < 0.2 ) {
							invalidRoute = qtrue;
							break;
						}
					} else {
						if ( dist < destTravelDist * 0.7 ) {
							invalidRoute = qtrue;
							break;
						}
					}
					//
					// check the directions to make sure we're not trying to run through them
					if ( j > 0 ) {
						if ( DotProduct( vec, lastVec ) < 0.2 ) {
							invalidRoute = qtrue;
							break;
						}
					} else if ( DotProduct( destVec, vec ) < 0.2 ) {
						invalidRoute = qtrue;
						break;
					}
					//
					VectorCopy( vec, lastVec );
				}
				//
				// if this area isn't in the visible list for the enemy's area, it's a good hiding spot
				if ( !( travChild = AAS_RT_GetChild( pathArea ) ) ) {
					invalidRoute = qtrue;
					break;
				}
				if ( !destVisLookup[rt->parentLinks[travChild->startParentLinks].parent] ) {
					// success ?
					if ( !botimport.AICast_VisibleFromPos( destpos, destnum, ( *aasworld ).areas[pathArea].center, srcnum, qfalse ) ) {
						// SUCESS !!
						travParent = &rt->parents[rt->parentLinks[travChild->startParentLinks].parent];
						break;
					}
				} else {
					// if we weren't visible when starting, make sure we don't move into their view
					if ( !startVisible ) { //botimport.AICast_VisibleFromPos( destpos, destnum, reachability[firstreach + route->reachable_index].end, srcnum, qfalse )) {
						invalidRoute = qtrue;
						break;
					}
				}
				//
				// if this is the travParent, then stop checking
				if ( pathArea == travParent->areanum ) {
					invalidRoute = qtrue;   // we didn't find a hiding spot
					break;
				}
			}   // end for areas in route
			//
			// if the route is invalid, skip this travParent
			if ( invalidRoute ) {
				continue;
			}
		}
		//
		// now last of all, check that this area is a safe hiding spot
//		if (botimport.AICast_VisibleFromPos( destpos, destnum, (*aasworld).areas[travParent->areanum].center, srcnum, qfalse )) {
//			continue;
//		}
		//
		// we've found a good hiding spot, so use it
		VectorCopy( ( *aasworld ).areas[travParent->areanum].center, returnPos );
		bestTravelTime = elapsedTravelTime;
		//
		if ( thisTravelTime < 300 ) {
			botimport.Print( PRT_MESSAGE, "Fuzzy RT HidePos: %i ms\n", pretime + Sys_MilliSeconds() );
			return qtrue;
		}
	}
	//
	// did we find something?
	if ( bestTravelTime < MAX_HIDE_TRAVELTIME ) {
		botimport.Print( PRT_MESSAGE, "Fuzzy RT HidePos: %i ms\n", pretime + Sys_MilliSeconds() );
		return qtrue;
	}
	//
	// couldn't find anything
	botimport.Print( PRT_MESSAGE, "Fuzzy RT HidePos FAILED: %i ms\n", pretime + Sys_MilliSeconds() );
	return qfalse;
#endif
}
コード例 #8
0
ファイル: be_ai_char.c プロジェクト: icanhas/yantar
int
BotLoadCachedCharacter(char *charfile, float skill, int reload)
{
	int handle, cachedhandle, intskill;
	bot_character_t *ch = NULL;
#ifdef DEBUG
	int starttime;

	starttime = Sys_MilliSeconds();
#endif	/* DEBUG */

	/* find a free spot for a character */
	for(handle = 1; handle <= MAX_CLIENTS; handle++)
		if(!botcharacters[handle]) break;
	if(handle > MAX_CLIENTS) return 0;
	/* try to load a cached character with the given skill */
	if(!reload){
		cachedhandle = BotFindCachedCharacter(charfile, skill);
		if(cachedhandle){
			botimport.Print(PRT_MESSAGE,
				"loaded cached skill %f from %s\n", skill,
				charfile);
			return cachedhandle;
		}
	}
	intskill = (int)(skill + 0.5);
	/* try to load the character with the given skill */
	ch = BotLoadCharacterFromFile(charfile, intskill);
	if(ch){
		botcharacters[handle] = ch;
		botimport.Print(PRT_MESSAGE, "loaded skill %d from %s\n",
			intskill,
			charfile);
#ifdef DEBUG
		if(botDeveloper)
			botimport.Print(PRT_MESSAGE,
				"skill %d loaded in %d msec from %s\n", intskill,
				Sys_MilliSeconds() - starttime, charfile);
#endif	/* DEBUG */
		return handle;
	}
	botimport.Print(PRT_WARNING, "couldn't find skill %d in %s\n", intskill,
		charfile);
	if(!reload){
		/* try to load a cached default character with the given skill */
		cachedhandle = BotFindCachedCharacter(DEFAULT_CHARACTER, skill);
		if(cachedhandle){
			botimport.Print(
				PRT_MESSAGE,
				"loaded cached default skill %d from %s\n",
				intskill, charfile);
			return cachedhandle;
		}
	}
	/* try to load the default character with the given skill */
	ch = BotLoadCharacterFromFile(DEFAULT_CHARACTER, intskill);
	if(ch){
		botcharacters[handle] = ch;
		botimport.Print(PRT_MESSAGE, "loaded default skill %d from %s\n",
			intskill,
			charfile);
		return handle;
	}
	if(!reload){
		/* try to load a cached character with any skill */
		cachedhandle = BotFindCachedCharacter(charfile, -1);
		if(cachedhandle){
			botimport.Print(PRT_MESSAGE,
				"loaded cached skill %f from %s\n",
				botcharacters[cachedhandle]->skill,
				charfile);
			return cachedhandle;
		}
	}
	/* try to load a character with any skill */
	ch = BotLoadCharacterFromFile(charfile, -1);
	if(ch){
		botcharacters[handle] = ch;
		botimport.Print(PRT_MESSAGE, "loaded skill %f from %s\n",
			ch->skill,
			charfile);
		return handle;
	}
	if(!reload){
		/* try to load a cached character with any skill */
		cachedhandle = BotFindCachedCharacter(DEFAULT_CHARACTER, -1);
		if(cachedhandle){
			botimport.Print(
				PRT_MESSAGE,
				"loaded cached default skill %f from %s\n",
				botcharacters[cachedhandle]->skill, charfile);
			return cachedhandle;
		}
	}
	/* try to load a character with any skill */
	ch = BotLoadCharacterFromFile(DEFAULT_CHARACTER, -1);
	if(ch){
		botcharacters[handle] = ch;
		botimport.Print(PRT_MESSAGE, "loaded default skill %f from %s\n",
			ch->skill,
			charfile);
		return handle;
	}
	botimport.Print(PRT_WARNING, "couldn't load any skill from %s\n",
		charfile);
	/* couldn't load any character */
	return 0;
}