Added bot code.

This commit is contained in:
Justin Marshall
2026-05-19 18:34:55 -07:00
parent b97127f038
commit af56d4bfeb
166 changed files with 22251 additions and 297 deletions
+13
View File
@@ -273,3 +273,16 @@ void idAASLocal::GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const {
start = file->GetVertex( v[INTSIGNBITSET(edgeNum)] );
end = file->GetVertex( v[INTSIGNBITNOTSET(edgeNum)] );
}
/*
============
idAASLocal::AdjustPositionAndGetArea
============
*/
int idAASLocal::AdjustPositionAndGetArea(idVec3& origin)
{
int area = PointReachableAreaNum(origin, DefaultSearchBounds(), AREA_REACHABLE_WALK);
PushPointIntoAreaNum(area, origin);
return area;
}
+6 -1
View File
@@ -67,7 +67,7 @@ typedef struct aasObstacle_s {
class idAASCallback {
public:
virtual ~idAASCallback() {};
virtual bool TestArea( const class idAAS *aas, int areaNum ) = 0;
virtual bool AreaIsGoal( const class idAAS *aas, int areaNum ) = 0;
};
typedef int aasHandle_t;
@@ -136,6 +136,11 @@ public:
virtual void ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const = 0;
// Find the nearest goal which satisfies the callback.
virtual bool FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback ) const = 0;
virtual int AdjustPositionAndGetArea(idVec3& origin) = 0;
virtual void ShowArea(const idVec3& origin) const = 0;
virtual idAASFile* GetAASFile(void) = 0;
virtual const idBounds& DefaultSearchBounds(void) const = 0;
};
#endif /* !__AAS_H__ */
@@ -0,0 +1,126 @@
// Copyright (C) 2007 Id Software, Inc.
//
#pragma hdrstop
#include "precompiled.h"
#include "AAS_local.h"
#include "../Game_local.h" // for print and error
#include "AASCallback_AvoidLocation.h"
/*
============
idAASCallback_AvoidLocation::idAASCallback_AvoidLocation
============
*/
idAASCallback_AvoidLocation::idAASCallback_AvoidLocation()
{
avoidLocation.Zero();
avoidDist = 0.0f;
obstacles = NULL;
numObstacles = 0;
}
/*
============
idAASCallback_AvoidLocation::~idAASCallback_AvoidLocation
============
*/
idAASCallback_AvoidLocation::~idAASCallback_AvoidLocation()
{
}
/*
============
idAASCallback_AvoidLocation::SetAvoidLocation
============
*/
void idAASCallback_AvoidLocation::SetAvoidLocation( const idVec3& start, const idVec3& avoidLocation )
{
this->avoidLocation = avoidLocation;
this->avoidDist = ( avoidLocation - start ).Length();
}
/*
============
idAASCallback_AvoidLocation::SetObstacles
============
*/
void idAASCallback_AvoidLocation::SetObstacles( const idAAS* aas, const idAASObstacle* obstacles, int numObstacles )
{
this->obstacles = obstacles;
this->numObstacles = numObstacles;
for( int i = 0; i < numObstacles; i++ )
{
obstacles[i].expAbsBounds[0] = obstacles[i].absBounds[0] - aas->GetSettings()->boundingBoxes[0][1];
obstacles[i].expAbsBounds[1] = obstacles[i].absBounds[1] - aas->GetSettings()->boundingBoxes[0][0];
}
}
/*
============
idAASCallback_AvoidLocation::PathValid
============
*/
bool idAASCallback_AvoidLocation::PathValid( const idAAS* aas, const idVec3& start, const idVec3& end )
{
// path may not go through any obstacles
for( int i = 0; i < numObstacles; i++ )
{
// if the movement vector intersects the expanded obstacle bounds
if( obstacles[i].expAbsBounds.LineIntersection( start, end ) )
{
return false;
}
}
return true;
}
/*
============
idAASCallback_AvoidLocation::AdditionalTravelTimeForPath
============
*/
int idAASCallback_AvoidLocation::AdditionalTravelTimeForPath( const idAAS* aas, const idVec3& start, const idVec3& end )
{
if( avoidDist <= 0.0f )
{
return 0;
}
// project avoidLocation origin onto movement vector
idVec3 v1 = end - start;
v1.Normalize();
idVec3 v2 = avoidLocation - start;
idVec3 p = start + ( v2 * v1 ) * v1;
// get the point on the path closest to the avoidLocation
int i;
for( i = 0; i < 3; i++ )
{
if( ( p[i] > start[i] + 0.1f && p[i] > end[i] + 0.1f ) ||
( p[i] < start[i] - 0.1f && p[i] < end[i] - 0.1f ) )
{
break;
}
}
float dist;
if( i >= 3 )
{
dist = ( avoidLocation - p ).Length();
}
else
{
dist = ( avoidLocation - end ).Length();
}
// avoid moving closer to the avoidLocation
if( dist < avoidDist )
{
return idMath::Ftoi( ( avoidDist - dist ) * 10.0f );
}
return 0;
}
@@ -0,0 +1,41 @@
// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __AASCALLBACK_AVOIDLOCATION_H__
#define __AASCALLBACK_AVOIDLOCATION_H__
/*
===============================================================================
idAASCallback_AvoidLocation
===============================================================================
*/
struct idAASObstacle
{
idBounds absBounds; // absolute bounds of obstacle
mutable idBounds expAbsBounds; // expanded absolute bounds of obstacle
};
class idAASCallback_AvoidLocation : public idAASCallback
{
public:
idAASCallback_AvoidLocation();
~idAASCallback_AvoidLocation();
void SetAvoidLocation( const idVec3& start, const idVec3& avoidLocation );
void SetObstacles( const idAAS* aas, const idAASObstacle* obstacles, int numObstacles );
virtual bool PathValid( const idAAS* aas, const idVec3& start, const idVec3& end );
virtual int AdditionalTravelTimeForPath( const idAAS* aas, const idVec3& start, const idVec3& end );
virtual bool AreaIsGoal( const idAAS* aas, int areaNum ) = 0;
private:
idVec3 avoidLocation;
float avoidDist;
const idAASObstacle* obstacles;
int numObstacles;
};
#endif /* !__AASCALLBACK_AVOIDLOCATION_H__ */
@@ -0,0 +1,49 @@
// Copyright (C) 2007 Id Software, Inc.
//
#pragma hdrstop
#include "precompiled.h"
#include "AAS_local.h"
#include "../Game_local.h" // for print and error
#include "AASCallback_FindAreaOutOfRange.h"
/*
============
idAASCallback_FindAreaOutOfRange::idAASCallback_FindAreaOutOfRange
============
*/
idAASCallback_FindAreaOutOfRange::idAASCallback_FindAreaOutOfRange( const idVec3& targetPos, float maxDist )
{
this->targetPos = targetPos;
this->maxDistSqr = maxDist * maxDist;
}
/*
============
idAASCallback_FindAreaOutOfRange::AreaIsGoal
============
*/
bool idAASCallback_FindAreaOutOfRange::AreaIsGoal( const idAAS* aas, int areaNum )
{
const idVec3& areaCenter = aas->AreaCenter( areaNum );
if( maxDistSqr > 0.0f )
{
float dist = ( targetPos.ToVec2() - areaCenter.ToVec2() ).LengthSqr();
if( dist < maxDistSqr )
{
return false;
}
}
trace_t trace;
gameLocal.clip.TracePoint( trace, targetPos, areaCenter + idVec3( 0.0f, 0.0f, 1.0f ), MASK_OPAQUE, NULL );
if( trace.fraction < 1.0f )
{
return false;
}
return true;
}
@@ -0,0 +1,29 @@
// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __AASCALLBACK_FINDAREAOUTOFRANGE_H__
#define __AASCALLBACK_FINDAREAOUTOFRANGE_H__
#include "AASCallback_AvoidLocation.h"
/*
===============================================================================
idAASCallback_FindAreaOutOfRange
===============================================================================
*/
class idAASCallback_FindAreaOutOfRange : public idAASCallback_AvoidLocation
{
public:
idAASCallback_FindAreaOutOfRange( const idVec3& targetPos, float maxDist );
virtual bool AreaIsGoal( const idAAS* aas, int areaNum );
private:
idVec3 targetPos;
float maxDistSqr;
};
#endif /* !__AASCALLBACK_FINDAREAOUTOFRANGE_H__ */
@@ -0,0 +1,76 @@
#pragma hdrstop
#include "precompiled.h"
#include "AAS_local.h"
#include "../Game_local.h"
#include "AASCallback_FindAttackPosition.h"
/*
============
idAASFindAttackPosition::idAASFindAttackPosition
============
*/
idAASFindAttackPosition::idAASFindAttackPosition(const idAI* self, const idMat3& gravityAxis, idEntity* target, const idVec3& targetPos, const idVec3& fireOffset) {
int numPVSAreas;
this->target = target;
this->targetPos = targetPos;
this->fireOffset = fireOffset;
this->self = self;
this->gravityAxis = gravityAxis;
excludeBounds = idBounds(idVec3(-64.0, -64.0f, -8.0f), idVec3(64.0, 64.0f, 64.0f));
excludeBounds.TranslateSelf(self->GetPhysics()->GetOrigin());
// setup PVS
idBounds bounds(targetPos - idVec3(16, 16, 0), targetPos + idVec3(16, 16, 64));
numPVSAreas = gameLocal.pvs.GetPVSAreas(bounds, PVSAreas, idEntity::MAX_PVS_AREAS);
targetPVS = gameLocal.pvs.SetupCurrentPVS(PVSAreas, numPVSAreas);
}
/*
============
idAASFindAttackPosition::~idAASFindAttackPosition
============
*/
idAASFindAttackPosition::~idAASFindAttackPosition() {
gameLocal.pvs.FreeCurrentPVS(targetPVS);
}
/*
============
idAASFindAttackPosition::TestArea
============
*/
bool idAASFindAttackPosition::AreaIsGoal(const idAAS* aas, int areaNum) {
idVec3 dir;
idVec3 local_dir;
idVec3 fromPos;
idMat3 axis;
idVec3 areaCenter;
int numPVSAreas;
int PVSAreas[idEntity::MAX_PVS_AREAS];
areaCenter = aas->AreaCenter(areaNum);
areaCenter[2] += 1.0f;
if (excludeBounds.ContainsPoint(areaCenter)) {
// too close to where we already are
return false;
}
numPVSAreas = gameLocal.pvs.GetPVSAreas(idBounds(areaCenter).Expand(16.0f), PVSAreas, idEntity::MAX_PVS_AREAS);
if (!gameLocal.pvs.InCurrentPVS(targetPVS, PVSAreas, numPVSAreas)) {
return false;
}
// calculate the world transform of the launch position
dir = targetPos - areaCenter;
gravityAxis.ProjectVector(dir, local_dir);
local_dir.z = 0.0f;
local_dir.ToVec2().Normalize();
axis = local_dir.ToMat3();
fromPos = areaCenter + fireOffset * axis;
return self->GetAimDir(fromPos, target, self, dir);
}
@@ -0,0 +1,19 @@
#pragma once
class idAASFindAttackPosition : public idAASCallback {
public:
idAASFindAttackPosition(const idAI* self, const idMat3& gravityAxis, idEntity* target, const idVec3& targetPos, const idVec3& fireOffset);
~idAASFindAttackPosition();
virtual bool AreaIsGoal(const idAAS* aas, int areaNum);
private:
const idAI* self;
idEntity* target;
idBounds excludeBounds;
idVec3 targetPos;
idVec3 fireOffset;
idMat3 gravityAxis;
pvsHandle_t targetPVS;
int PVSAreas[idEntity::MAX_PVS_AREAS];
};
@@ -0,0 +1,58 @@
// Copyright (C) 2007 Id Software, Inc.
//
#pragma hdrstop
#include "precompiled.h"
#include "AAS_local.h"
#include "../Game_local.h" // for print and error
#include "AASCallback_FindCoverArea.h"
/*
============
idAASCallback_FindCoverArea::idAASCallback_FindCoverArea
============
*/
idAASCallback_FindCoverArea::idAASCallback_FindCoverArea( const idVec3& hideFromPos )
{
int numPVSAreas;
idBounds bounds( hideFromPos - idVec3( 16, 16, 0 ), hideFromPos + idVec3( 16, 16, 64 ) );
// setup PVS
numPVSAreas = gameLocal.pvs.GetPVSAreas( bounds, PVSAreas, MAX_PVS_AREAS );
hidePVS = gameLocal.pvs.SetupCurrentPVS( PVSAreas, numPVSAreas );
}
/*
============
idAASCallback_FindCoverArea::~idAASCallback_FindCoverArea
============
*/
idAASCallback_FindCoverArea::~idAASCallback_FindCoverArea()
{
gameLocal.pvs.FreeCurrentPVS( hidePVS );
}
/*
============
idAASCallback_FindCoverArea::AreaIsGoal
============
*/
bool idAASCallback_FindCoverArea::AreaIsGoal( const idAAS* aas, int areaNum )
{
idVec3 areaCenter;
int numPVSAreas;
int PVSAreas[ MAX_PVS_AREAS ];
areaCenter = aas->AreaCenter( areaNum );
areaCenter[ 2 ] += 1.0f;
numPVSAreas = gameLocal.pvs.GetPVSAreas( idBounds( areaCenter ).Expand( 16.0f ), PVSAreas, MAX_PVS_AREAS );
if( !gameLocal.pvs.InCurrentPVS( hidePVS, PVSAreas, numPVSAreas ) )
{
return true;
}
return false;
}
@@ -0,0 +1,32 @@
// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __AASCALLBACK_FINDCOVERAREA_H__
#define __AASCALLBACK_FINDCOVERAREA_H__
#include "AASCallback_AvoidLocation.h"
/*
===============================================================================
idAASCallback_FindCoverArea
===============================================================================
*/
class idAASCallback_FindCoverArea : public idAASCallback_AvoidLocation
{
public:
idAASCallback_FindCoverArea( const idVec3& hideFromPos );
~idAASCallback_FindCoverArea();
virtual bool AreaIsGoal( const idAAS* aas, int areaNum );
private:
static const int MAX_PVS_AREAS = 4;
pvsHandle_t hidePVS;
int PVSAreas[ MAX_PVS_AREAS ];
};
#endif /* !__AASCALLBACK_FINDCOVERAREA_H__ */
+2 -2
View File
@@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#include "AAS_local.h"
#include "../Game_local.h" // for cvars and debug drawing
#include "AASCallback_FindCoverArea.h"
/*
============
@@ -372,7 +372,7 @@ void idAASLocal::ShowHideArea( const idVec3 &origin, int targetAreaNum ) const {
DrawCone( target, idVec3(0,0,1), 16.0f, colorYellow );
idAASFindCover findCover( target );
idAASCallback_FindCoverArea findCover( target );
if ( FindNearestGoal( goal, areaNum, origin, target, TFL_WALK|TFL_AIR, obstacles, numObstacles, findCover ) ) {
DrawArea( goal.areaNum );
ShowWalkPath( origin, goal.areaNum, goal.origin );
+4 -3
View File
@@ -118,7 +118,10 @@ public:
virtual void ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const;
virtual void ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const;
virtual bool FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback ) const;
virtual int AdjustPositionAndGetArea(idVec3& origin);
virtual void ShowArea(const idVec3& origin) const;
virtual idAASFile* GetAASFile(void) { return file; }
virtual const idBounds& DefaultSearchBounds(void) const;
private:
idAASFile * file;
idStr name;
@@ -172,13 +175,11 @@ private: // pathing
idVec3 SubSampleFlyPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const;
private: // debug
const idBounds & DefaultSearchBounds( void ) const;
void DrawCone( const idVec3 &origin, const idVec3 &dir, float radius, const idVec4 &color ) const;
void DrawArea( int areaNum ) const;
void DrawFace( int faceNum, bool side ) const;
void DrawEdge( int edgeNum, bool arrow ) const;
void DrawReachability( const idReachability *reach ) const;
void ShowArea( const idVec3 &origin ) const;
void ShowWallEdges( const idVec3 &origin ) const;
void ShowHideArea( const idVec3 &origin, int targerAreaNum ) const;
bool PullPlayer( const idVec3 &origin, int toAreaNum ) const;
+2 -2
View File
@@ -1182,7 +1182,7 @@ bool idAASLocal::FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 ori
}
// if the first area is valid goal, just return the origin
if ( callback.TestArea( this, areaNum ) ) {
if ( callback.AreaIsGoal( this, areaNum ) ) {
goal.areaNum = areaNum;
goal.origin = origin;
return true;
@@ -1330,7 +1330,7 @@ bool idAASLocal::FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 ori
if ( !bestTravelTime || t < bestTravelTime ) {
// if the area is not visible to the target
if ( callback.TestArea( this, reach->toAreaNum ) ) {
if ( callback.AreaIsGoal( this, reach->toAreaNum ) ) {
bestTravelTime = t;
bestAreaNum = reach->toAreaNum;
}
+6 -150
View File
@@ -30,6 +30,10 @@ If you have questions concerning this license or the applicable additional terms
#pragma hdrstop
#include "../Game_local.h"
#include "AASCallback_AvoidLocation.h"
#include "AASCallback_FindAreaOutOfRange.h"
#include "AASCallback_FindAttackPosition.h"
#include "AASCallback_FindCoverArea.h"
static const char* moveCommandString[NUM_MOVE_COMMANDS] = {
"MOVE_NONE",
@@ -128,154 +132,6 @@ void idMoveState::Restore(idRestoreGame* savefile) {
savefile->ReadInt(anim);
}
/*
============
idAASFindCover::idAASFindCover
============
*/
idAASFindCover::idAASFindCover(const idVec3& hideFromPos) {
int numPVSAreas;
idBounds bounds(hideFromPos - idVec3(16, 16, 0), hideFromPos + idVec3(16, 16, 64));
// setup PVS
numPVSAreas = gameLocal.pvs.GetPVSAreas(bounds, PVSAreas, idEntity::MAX_PVS_AREAS);
hidePVS = gameLocal.pvs.SetupCurrentPVS(PVSAreas, numPVSAreas);
}
/*
============
idAASFindCover::~idAASFindCover
============
*/
idAASFindCover::~idAASFindCover() {
gameLocal.pvs.FreeCurrentPVS(hidePVS);
}
/*
============
idAASFindCover::TestArea
============
*/
bool idAASFindCover::TestArea(const idAAS* aas, int areaNum) {
idVec3 areaCenter;
int numPVSAreas;
int PVSAreas[idEntity::MAX_PVS_AREAS];
areaCenter = aas->AreaCenter(areaNum);
areaCenter[2] += 1.0f;
numPVSAreas = gameLocal.pvs.GetPVSAreas(idBounds(areaCenter).Expand(16.0f), PVSAreas, idEntity::MAX_PVS_AREAS);
if (!gameLocal.pvs.InCurrentPVS(hidePVS, PVSAreas, numPVSAreas)) {
return true;
}
return false;
}
/*
============
idAASFindAreaOutOfRange::idAASFindAreaOutOfRange
============
*/
idAASFindAreaOutOfRange::idAASFindAreaOutOfRange(const idVec3& targetPos, float maxDist) {
this->targetPos = targetPos;
this->maxDistSqr = maxDist * maxDist;
}
/*
============
idAASFindAreaOutOfRange::TestArea
============
*/
bool idAASFindAreaOutOfRange::TestArea(const idAAS* aas, int areaNum) {
const idVec3& areaCenter = aas->AreaCenter(areaNum);
trace_t trace;
float dist;
dist = (targetPos.ToVec2() - areaCenter.ToVec2()).LengthSqr();
if ((maxDistSqr > 0.0f) && (dist < maxDistSqr)) {
return false;
}
gameLocal.clip.TracePoint(trace, targetPos, areaCenter + idVec3(0.0f, 0.0f, 1.0f), MASK_OPAQUE, NULL);
if (trace.fraction < 1.0f) {
return false;
}
return true;
}
/*
============
idAASFindAttackPosition::idAASFindAttackPosition
============
*/
idAASFindAttackPosition::idAASFindAttackPosition(const idAI* self, const idMat3& gravityAxis, idEntity* target, const idVec3& targetPos, const idVec3& fireOffset) {
int numPVSAreas;
this->target = target;
this->targetPos = targetPos;
this->fireOffset = fireOffset;
this->self = self;
this->gravityAxis = gravityAxis;
excludeBounds = idBounds(idVec3(-64.0, -64.0f, -8.0f), idVec3(64.0, 64.0f, 64.0f));
excludeBounds.TranslateSelf(self->GetPhysics()->GetOrigin());
// setup PVS
idBounds bounds(targetPos - idVec3(16, 16, 0), targetPos + idVec3(16, 16, 64));
numPVSAreas = gameLocal.pvs.GetPVSAreas(bounds, PVSAreas, idEntity::MAX_PVS_AREAS);
targetPVS = gameLocal.pvs.SetupCurrentPVS(PVSAreas, numPVSAreas);
}
/*
============
idAASFindAttackPosition::~idAASFindAttackPosition
============
*/
idAASFindAttackPosition::~idAASFindAttackPosition() {
gameLocal.pvs.FreeCurrentPVS(targetPVS);
}
/*
============
idAASFindAttackPosition::TestArea
============
*/
bool idAASFindAttackPosition::TestArea(const idAAS* aas, int areaNum) {
idVec3 dir;
idVec3 local_dir;
idVec3 fromPos;
idMat3 axis;
idVec3 areaCenter;
int numPVSAreas;
int PVSAreas[idEntity::MAX_PVS_AREAS];
areaCenter = aas->AreaCenter(areaNum);
areaCenter[2] += 1.0f;
if (excludeBounds.ContainsPoint(areaCenter)) {
// too close to where we already are
return false;
}
numPVSAreas = gameLocal.pvs.GetPVSAreas(idBounds(areaCenter).Expand(16.0f), PVSAreas, idEntity::MAX_PVS_AREAS);
if (!gameLocal.pvs.InCurrentPVS(targetPVS, PVSAreas, numPVSAreas)) {
return false;
}
// calculate the world transform of the launch position
dir = targetPos - areaCenter;
gravityAxis.ProjectVector(dir, local_dir);
local_dir.z = 0.0f;
local_dir.ToVec2().Normalize();
axis = local_dir.ToMat3();
fromPos = areaCenter + fireOffset * axis;
return self->GetAimDir(fromPos, target, self, dir);
}
/*
=====================
idAI::idAI
@@ -1839,7 +1695,7 @@ bool idAI::MoveOutOfRange(idEntity* ent, float range) {
pos = ent->GetPhysics()->GetOrigin();
}
idAASFindAreaOutOfRange findGoal(pos, range);
idAASCallback_FindAreaOutOfRange findGoal(pos, range);
if (!aas->FindNearestGoal(goal, areaNum, org, pos, travelFlags, &obstacle, 1, findGoal)) {
StopMove(MOVE_STATUS_DEST_UNREACHABLE);
AI_DEST_UNREACHABLE = true;
@@ -1990,7 +1846,7 @@ bool idAI::MoveToCover(idEntity* entity, const idVec3& hideFromPos) {
// consider the entity the monster tries to hide from as an obstacle
obstacle.absBounds = entity->GetPhysics()->GetAbsBounds();
idAASFindCover findCover(hideFromPos);
idAASCallback_FindCoverArea findCover(hideFromPos);
if (!aas->FindNearestGoal(hideGoal, areaNum, org, hideFromPos, travelFlags, &obstacle, 1, findCover)) {
StopMove(MOVE_STATUS_DEST_UNREACHABLE);
AI_DEST_UNREACHABLE = true;
-39
View File
@@ -195,46 +195,7 @@ public:
int anim;
};
class idAASFindCover : public idAASCallback {
public:
idAASFindCover(const idVec3& hideFromPos);
~idAASFindCover();
virtual bool TestArea(const idAAS* aas, int areaNum);
private:
pvsHandle_t hidePVS;
int PVSAreas[idEntity::MAX_PVS_AREAS];
};
class idAASFindAreaOutOfRange : public idAASCallback {
public:
idAASFindAreaOutOfRange(const idVec3& targetPos, float maxDist);
virtual bool TestArea(const idAAS* aas, int areaNum);
private:
idVec3 targetPos;
float maxDistSqr;
};
class idAASFindAttackPosition : public idAASCallback {
public:
idAASFindAttackPosition(const idAI* self, const idMat3& gravityAxis, idEntity* target, const idVec3& targetPos, const idVec3& fireOffset);
~idAASFindAttackPosition();
virtual bool TestArea(const idAAS* aas, int areaNum);
private:
const idAI* self;
idEntity* target;
idBounds excludeBounds;
idVec3 targetPos;
idVec3 fireOffset;
idMat3 gravityAxis;
pvsHandle_t targetPVS;
int PVSAreas[idEntity::MAX_PVS_AREAS];
};
class idAI : public idActor {
public: