Пример #1
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void AAS_ShowReachableAreas(int areanum)
{
    aas_areasettings_t *settings;
    static aas_reachability_t reach;
    static int index, lastareanum;
    static float lasttime;

    if (areanum != lastareanum)
    {
        index = 0;
        lastareanum = areanum;
    } //end if
    settings = &aasworld.areasettings[areanum];
    //
    if (!settings->numreachableareas) return;
    //
    if (index >= settings->numreachableareas) index = 0;
    //
    if (AAS_Time() - lasttime > 1.5)
    {
        Com_Memcpy(&reach, &aasworld.reachability[settings->firstreachablearea + index], sizeof(aas_reachability_t));
        index++;
        lasttime = AAS_Time();
        AAS_PrintTravelType(reach.traveltype & TRAVELTYPE_MASK);
        botimport.Print(PRT_MESSAGE, "\n");
    } //end if
    AAS_ShowReachability(&reach);
} //end of the function ShowReachableAreas
Пример #2
0
float BotAvoidGoalTime( int goalstate, int number ) {
	bot_goalstate_t* gs = BotGoalStateFromHandle( goalstate );
	if ( !gs ) {
		return 0;
	}
	for ( int i = 0; i < MAX_AVOIDGOALS; i++ ) {
		if ( gs->avoidgoals[ i ] == number && gs->avoidgoaltimes[ i ] >= AAS_Time() ) {
			return gs->avoidgoaltimes[ i ] - AAS_Time();
		}
	}
	return 0;
}
Пример #3
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void BotAddToAvoidGoals( bot_goalstate_t *gs, int number, float avoidtime ) {
	int i;

	for ( i = 0; i < MAX_AVOIDGOALS; i++ )
	{
		//if this avoid goal has expired
		if ( gs->avoidgoaltimes[i] < AAS_Time() ) {
			gs->avoidgoals[i] = number;
			gs->avoidgoaltimes[i] = AAS_Time() + avoidtime;
			return;
		} //end if
	} //end for
} //end of the function BotAddToAvoidGoals
Пример #4
0
void BotDumpAvoidGoals( int goalstate ) {
	bot_goalstate_t* gs = BotGoalStateFromHandle( goalstate );
	if ( !gs ) {
		return;
	}
	for ( int i = 0; i < MAX_AVOIDGOALS; i++ ) {
		if ( gs->avoidgoaltimes[ i ] >= AAS_Time() ) {
			char name[ 32 ];
			BotGoalName( gs->avoidgoals[ i ], name, 32 );
			Log_Write( "avoid goal %s, number %d for %f seconds", name,
				gs->avoidgoals[ i ], gs->avoidgoaltimes[ i ] - AAS_Time() );
		}
	}
}
Пример #5
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int BotItemGoalInVisButNotVisible( int viewer, vec3_t eye, vec3_t viewangles, bot_goal_t *goal ) {
	aas_entityinfo_t entinfo;
	bsp_trace_t trace;
	vec3_t middle;

	if ( !( goal->flags & GFL_ITEM ) ) {
		return qfalse;
	}
	//
	VectorAdd( goal->mins, goal->mins, middle );
	VectorScale( middle, 0.5, middle );
	VectorAdd( goal->origin, middle, middle );
	//
	trace = AAS_Trace( eye, NULL, NULL, middle, viewer, CONTENTS_SOLID );
	//if the goal middle point is visible
	if ( trace.fraction >= 1 ) {
		//the goal entity number doesn't have to be valid
		//just assume it's valid
		if ( goal->entitynum <= 0 ) {
			return qfalse;
		}
		//
		//if the entity data isn't valid
		AAS_EntityInfo( goal->entitynum, &entinfo );
		//NOTE: for some wacko reason entities are sometimes
		// not updated
		//if (!entinfo.valid) return qtrue;
		if ( entinfo.ltime < AAS_Time() - 0.5 ) {
			return qtrue;
		}
	} //end if
	return qfalse;
} //end of the function BotItemGoalInVisButNotVisible
Пример #6
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
float BotAvoidGoalTime( int goalstate, int number ) {
	int i;
	bot_goalstate_t *gs;

	gs = BotGoalStateFromHandle( goalstate );
	if ( !gs ) {
		return 0;
	}
	//don't use the goals the bot wants to avoid
	for ( i = 0; i < MAX_AVOIDGOALS; i++ )
	{
		if ( gs->avoidgoals[i] == number && gs->avoidgoaltimes[i] >= AAS_Time() ) {
			return gs->avoidgoaltimes[i] - AAS_Time();
		} //end if
	} //end for
	return 0;
} //end of the function BotAvoidGoalTime
Пример #7
0
static void BotAddToAvoidGoals( bot_goalstate_t* gs, int number, float avoidtime ) {
	for ( int i = 0; i < MAX_AVOIDGOALS; i++ ) {
		//if the avoid goal is already stored
		if ( gs->avoidgoals[ i ] == number ) {
			gs->avoidgoals[ i ] = number;
			gs->avoidgoaltimes[ i ] = AAS_Time() + avoidtime;
			return;
		}
	}

	for ( int i = 0; i < MAX_AVOIDGOALS; i++ ) {
		//if this avoid goal has expired
		if ( gs->avoidgoaltimes[ i ] < AAS_Time() ) {
			gs->avoidgoals[ i ] = number;
			gs->avoidgoaltimes[ i ] = AAS_Time() + avoidtime;
			return;
		}
	}
}
Пример #8
0
void BotRemoveFromAvoidGoals( int goalstate, int number ) {
	bot_goalstate_t* gs = BotGoalStateFromHandle( goalstate );
	if ( !gs ) {
		return;
	}
	for ( int i = 0; i < MAX_AVOIDGOALS; i++ ) {
		if ( gs->avoidgoals[ i ] == number && gs->avoidgoaltimes[ i ] >= AAS_Time() ) {
			gs->avoidgoaltimes[ i ] = 0;
			return;
		}
	}
}
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int AAS_UpdateEntity(int entnum, bot_entitystate_t *state)
{
	int relink;
	aas_entity_t *ent;
	vec3_t absmins, absmaxs;

	if (!aasworld.loaded)
	{
		botimport.Print(PRT_MESSAGE, "AAS_UpdateEntity: not loaded\n");
		return BLERR_NOAASFILE;
	} //end if

	ent = &aasworld.entities[entnum];

	if (!state) {
		//unlink the entity
		AAS_UnlinkFromAreas(ent->areas);
		//unlink the entity from the BSP leaves
		AAS_UnlinkFromBSPLeaves(ent->leaves);
		//
		ent->areas = NULL;
		//
		ent->leaves = NULL;
		return BLERR_NOERROR;
	}

	ent->i.update_time = AAS_Time() - ent->i.ltime;
	ent->i.type = state->type;
	ent->i.flags = state->flags;
	ent->i.ltime = AAS_Time();
	VectorCopy(ent->i.origin, ent->i.lastvisorigin);
	VectorCopy(state->old_origin, ent->i.old_origin);
	ent->i.solid = state->solid;
	ent->i.groundent = state->groundent;
	ent->i.modelindex = state->modelindex;
	ent->i.modelindex2 = state->modelindex2;
	ent->i.frame = state->frame;
	ent->i.event = state->event;
	ent->i.eventParm = state->eventParm;
	ent->i.powerups = state->powerups;
	ent->i.weapon = state->weapon;
	ent->i.legsAnim = state->legsAnim;
	ent->i.torsoAnim = state->torsoAnim;
	//number of the entity
	ent->i.number = entnum;
	//updated so set valid flag
	ent->i.valid = qtrue;
	//link everything the first frame
	if (aasworld.numframes == 1) relink = qtrue;
	else relink = qfalse;
	//
	if (ent->i.solid == SOLID_BSP)
	{
		//if the angles of the model changed
		if (!VectorCompare(state->angles, ent->i.angles))
		{
			VectorCopy(state->angles, ent->i.angles);
			relink = qtrue;
		} //end if
		//get the mins and maxs of the model
		//FIXME: rotate mins and maxs
		AAS_BSPModelMinsMaxsOrigin(ent->i.modelindex, ent->i.angles, ent->i.mins, ent->i.maxs, NULL);
	} //end if
	else if (ent->i.solid == SOLID_BBOX)
	{
		//if the bounding box size changed
		if (!VectorCompare(state->mins, ent->i.mins) ||
				!VectorCompare(state->maxs, ent->i.maxs))
		{
			VectorCopy(state->mins, ent->i.mins);
			VectorCopy(state->maxs, ent->i.maxs);
			relink = qtrue;
		} //end if
		VectorCopy(state->angles, ent->i.angles);
	} //end if
	//if the origin changed
	if (!VectorCompare(state->origin, ent->i.origin))
	{
		VectorCopy(state->origin, ent->i.origin);
		relink = qtrue;
	} //end if
	//if the entity should be relinked
	if (relink)
	{
		//don't link the world model
		if (entnum != ENTITYNUM_WORLD)
		{
			//absolute mins and maxs
			VectorAdd(ent->i.mins, ent->i.origin, absmins);
			VectorAdd(ent->i.maxs, ent->i.origin, absmaxs);
			//unlink the entity
			AAS_UnlinkFromAreas(ent->areas);
			//relink the entity to the AAS areas (use the larges bbox)
			ent->areas = AAS_LinkEntityClientBBox(absmins, absmaxs, entnum, PRESENCE_NORMAL);
			//unlink the entity from the BSP leaves
			AAS_UnlinkFromBSPLeaves(ent->leaves);
			//link the entity to the world BSP tree
			ent->leaves = AAS_BSPLinkEntity(absmins, absmaxs, entnum, 0);
		} //end if
	} //end if
	return BLERR_NOERROR;
} //end of the function AAS_UpdateEntity
Пример #10
0
void BotUpdateEntityItems( void ) {
	int ent, i, modelindex;
	vec3_t dir;
	levelitem_t *li, *nextli;
	aas_entityinfo_t entinfo;
	itemconfig_t *ic;

	//timeout current entity items if necessary
	for ( li = levelitems; li; li = nextli )
	{
		nextli = li->next;
		//if it is a item that will time out
		if ( li->timeout ) {
			//timeout the item
			if ( li->timeout < AAS_Time() ) {
				RemoveLevelItemFromList( li );
				FreeLevelItem( li );
			} //end if
		} //end if
	} //end for
	  //find new entity items
	ic = itemconfig;
	if ( !itemconfig ) {
		return;
	}
	//
	for ( ent = AAS_NextEntity( 0 ); ent; ent = AAS_NextEntity( ent ) )
	{
		if ( AAS_EntityType( ent ) != ET_ITEM ) {
			continue;
		}
		//get the model index of the entity
		modelindex = AAS_EntityModelindex( ent );
		//
		if ( !modelindex ) {
			continue;
		}
		//get info about the entity
		AAS_EntityInfo( ent, &entinfo );
		//FIXME: don't do this
		//skip all floating items for now
		if ( entinfo.groundent != ENTITYNUM_WORLD ) {
			continue;
		}
		//if the entity is still moving
		if ( entinfo.origin[0] != entinfo.lastvisorigin[0] ||
			 entinfo.origin[1] != entinfo.lastvisorigin[1] ||
			 entinfo.origin[2] != entinfo.lastvisorigin[2] ) {
			continue;
		}
		//check if the level item isn't already stored
		for ( li = levelitems; li; li = li->next )
		{
			//if the model of the level item and the entity are different
			if ( ic->iteminfo[li->iteminfo].modelindex != modelindex ) {
				continue;
			}
			//if the level item is linked to an entity
			if ( li->entitynum ) {
				if ( li->entitynum == ent ) {
					VectorCopy( entinfo.origin, li->origin );
					break;
				} //end if
			} //end if
			else
			{
				//check if the entity is very close
				VectorSubtract( li->origin, entinfo.origin, dir );
				if ( VectorLength( dir ) < 30 ) {
					//found an entity for this level item
					li->entitynum = ent;
					//keep updating the entity origin
					VectorCopy( entinfo.origin, li->origin );
					//also update the goal area number
					li->goalareanum = AAS_BestReachableArea( li->origin,
															 ic->iteminfo[li->iteminfo].mins, ic->iteminfo[li->iteminfo].maxs,
															 li->goalorigin );
					//Log_Write("found item %s entity", ic->iteminfo[li->iteminfo].classname);
					break;
				} //end if
				  //else botimport.Print(PRT_MESSAGE, "item %s has no attached entity\n",
				  //						ic->iteminfo[li->iteminfo].name);
			} //end else
		} //end for
		if ( li ) {
			continue;
		}
		//check if the model is from a known item
		for ( i = 0; i < ic->numiteminfo; i++ )
		{
			if ( ic->iteminfo[i].modelindex == modelindex ) {
				break;
			} //end if
		} //end for
		  //if the model is not from a known item
		if ( i >= ic->numiteminfo ) {
			continue;
		}
		//allocate a new level item
		li = AllocLevelItem();
		//
		if ( !li ) {
			continue;
		}
		//entity number of the level item
		li->entitynum = ent;
		//number for the level item
		li->number = numlevelitems + ent;
		//set the item info index for the level item
		li->iteminfo = i;
		//origin of the item
		VectorCopy( entinfo.origin, li->origin );
		//get the item goal area and goal origin
		li->goalareanum = AAS_BestReachableArea( li->origin,
												 ic->iteminfo[i].mins, ic->iteminfo[i].maxs,
												 li->goalorigin );
		//
		if ( AAS_AreaJumpPad( li->goalareanum ) ) {
			FreeLevelItem( li );
			continue;
		} //end if
		  //time this item out after 30 seconds
		  //dropped items disappear after 30 seconds
		li->timeout = AAS_Time() + 30;
		//add the level item to the list
		AddLevelItemToList( li );
		//botimport.Print(PRT_MESSAGE, "found new level item %s\n", ic->iteminfo[i].classname);
	} //end for
} //end of the function BotUpdateEntityItems
Пример #11
0
void BotUpdateEntityItems() {
	int ent, i, modelindex;
	vec3_t dir;
	levelitem_t* li, * nextli;
	aas_entityinfo_t entinfo;
	itemconfig_t* ic;

	//timeout current entity items if necessary
	for ( li = levelitems; li; li = nextli ) {
		nextli = li->next;
		//if it is a item that will time out
		if ( li->timeout ) {
			//timeout the item
			if ( li->timeout < AAS_Time() ) {
				RemoveLevelItemFromList( li );
				FreeLevelItem( li );
			}	//end if
		}	//end if
	}	//end for
		//find new entity items
	ic = itemconfig;
	if ( !itemconfig ) {
		return;
	}
	//
	for ( ent = AAS_NextEntity( 0 ); ent; ent = AAS_NextEntity( ent ) ) {
		if ( AAS_EntityType( ent ) != Q3ET_ITEM ) {
			continue;
		}
		//get the model index of the entity
		modelindex = AAS_EntityModelindex( ent );
		//
		if ( !modelindex ) {
			continue;
		}
		//get info about the entity
		AAS_EntityInfo( ent, &entinfo );
		//FIXME: don't do this
		//skip all floating items for now
		if ( !( GGameType & GAME_Quake3 ) && entinfo.groundent != Q3ENTITYNUM_WORLD ) {
			continue;
		}
		//if the entity is still moving
		if ( entinfo.origin[ 0 ] != entinfo.lastvisorigin[ 0 ] ||
			 entinfo.origin[ 1 ] != entinfo.lastvisorigin[ 1 ] ||
			 entinfo.origin[ 2 ] != entinfo.lastvisorigin[ 2 ] ) {
			continue;
		}
		//check if the entity is already stored as a level item
		for ( li = levelitems; li; li = li->next ) {
			if ( GGameType & GAME_Quake3 ) {
				//if the level item is linked to an entity
				if ( li->entitynum && li->entitynum == ent ) {
					//the entity is re-used if the models are different
					if ( ic->iteminfo[ li->iteminfo ].modelindex != modelindex ) {
						//remove this level item
						RemoveLevelItemFromList( li );
						FreeLevelItem( li );
						li = NULL;
						break;
					} else {
						if ( entinfo.origin[ 0 ] != li->origin[ 0 ] ||
							 entinfo.origin[ 1 ] != li->origin[ 1 ] ||
							 entinfo.origin[ 2 ] != li->origin[ 2 ] ) {
							VectorCopy( entinfo.origin, li->origin );
							//also update the goal area number
							li->goalareanum = AAS_BestReachableArea( li->origin,
								ic->iteminfo[ li->iteminfo ].mins, ic->iteminfo[ li->iteminfo ].maxs,
								li->goalorigin );
						}
						break;
					}
				}
			} else {
				//if the model of the level item and the entity are different
				if ( ic->iteminfo[ li->iteminfo ].modelindex != modelindex ) {
					continue;
				}
				//if the level item is linked to an entity
				if ( li->entitynum ) {
					if ( li->entitynum == ent ) {
						VectorCopy( entinfo.origin, li->origin );
						break;
					}	//end if
				}	//end if
				else {
					//check if the entity is very close
					VectorSubtract( li->origin, entinfo.origin, dir );
					if ( VectorLength( dir ) < 30 ) {
						//found an entity for this level item
						li->entitynum = ent;
						//keep updating the entity origin
						VectorCopy( entinfo.origin, li->origin );
						//also update the goal area number
						li->goalareanum = AAS_BestReachableArea( li->origin,
							ic->iteminfo[ li->iteminfo ].mins, ic->iteminfo[ li->iteminfo ].maxs,
							li->goalorigin );
						//Log_Write("found item %s entity", ic->iteminfo[li->iteminfo].classname);
						break;
					}	//end if
						//else BotImport_Print(PRT_MESSAGE, "item %s has no attached entity\n",
						//						ic->iteminfo[li->iteminfo].name);
				}	//end else
			}
		}	//end for
		if ( li ) {
			continue;
		}
		if ( GGameType & GAME_Quake3 ) {
			//try to link the entity to a level item
			for ( li = levelitems; li; li = li->next ) {
				//if this level item is already linked
				if ( li->entitynum ) {
					continue;
				}

				if ( g_gametype == Q3GT_SINGLE_PLAYER ) {
					if ( li->flags & IFL_NOTSINGLE ) {
						continue;
					}
				} else if ( g_gametype >= Q3GT_TEAM ) {
					if ( li->flags & IFL_NOTTEAM ) {
						continue;
					}
				} else {
					if ( li->flags & IFL_NOTFREE ) {
						continue;
					}
				}
				//if the model of the level item and the entity are the same
				if ( ic->iteminfo[ li->iteminfo ].modelindex == modelindex ) {
					//check if the entity is very close
					VectorSubtract( li->origin, entinfo.origin, dir );
					if ( VectorLength( dir ) < 30 ) {
						//found an entity for this level item
						li->entitynum = ent;
						//if the origin is different
						if ( entinfo.origin[ 0 ] != li->origin[ 0 ] ||
							 entinfo.origin[ 1 ] != li->origin[ 1 ] ||
							 entinfo.origin[ 2 ] != li->origin[ 2 ] ) {
							//update the level item origin
							VectorCopy( entinfo.origin, li->origin );
							//also update the goal area number
							li->goalareanum = AAS_BestReachableArea( li->origin,
								ic->iteminfo[ li->iteminfo ].mins, ic->iteminfo[ li->iteminfo ].maxs,
								li->goalorigin );
						}
#ifdef DEBUG
						Log_Write( "linked item %s to an entity", ic->iteminfo[ li->iteminfo ].classname );
#endif
						break;
					}
				}
			}
			if ( li ) {
				continue;
			}
		}
		//check if the model is from a known item
		for ( i = 0; i < ic->numiteminfo; i++ ) {
			if ( ic->iteminfo[ i ].modelindex == modelindex ) {
				break;
			}	//end if
		}	//end for
			//if the model is not from a known item
		if ( i >= ic->numiteminfo ) {
			continue;
		}
		//allocate a new level item
		li = AllocLevelItem();
		//
		if ( !li ) {
			continue;
		}
		//entity number of the level item
		li->entitynum = ent;
		//number for the level item
		li->number = numlevelitems + ent;
		//set the item info index for the level item
		li->iteminfo = i;
		//origin of the item
		VectorCopy( entinfo.origin, li->origin );
		//get the item goal area and goal origin
		li->goalareanum = AAS_BestReachableArea( li->origin,
			ic->iteminfo[ i ].mins, ic->iteminfo[ i ].maxs,
			li->goalorigin );
		//never go for items dropped into jumppads
		if ( AAS_AreaJumpPad( li->goalareanum ) ) {
			FreeLevelItem( li );
			continue;
		}	//end if
			//time this item out after 30 seconds
			//dropped items disappear after 30 seconds
		li->timeout = AAS_Time() + 30;
		//add the level item to the list
		AddLevelItemToList( li );
	}
}