Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

243 lines
6.8 KiB

// NextBotUtil.h
// Utilities for the NextBot system
// Author: Michael Booth, May 2006
// Copyright (c) 2006 Turtle Rock Studios, Inc. - All Rights Reserved
#ifndef _NEXT_BOT_UTIL_H_
#define _NEXT_BOT_UTIL_H_
#include "NextBotLocomotionInterface.h"
//--------------------------------------------------------------------------------------------
/**
* A simple filter interface for various NextBot queries
*/
class INextBotEntityFilter
{
public:
// return true if the given entity passes this filter
virtual bool IsAllowed( CBaseEntity *entity ) const = 0;
};
// trace filter callback functions. needed for use with the querycache/optimization functionality
bool VisionTraceFilterFunction( IHandleEntity *pServerEntity, int contentsMask );
bool IgnoreActorsTraceFilterFunction( IHandleEntity *pServerEntity, int contentsMask );
//--------------------------------------------------------------------------------------------
/**
* Trace filter that skips all players and NextBots
*/
class NextBotTraceFilterIgnoreActors : public CTraceFilterSimple
{
public:
NextBotTraceFilterIgnoreActors( const IHandleEntity *passentity, int collisionGroup ) : CTraceFilterSimple( passentity, collisionGroup, IgnoreActorsTraceFilterFunction )
{
}
};
//--------------------------------------------------------------------------------------------
/**
* Trace filter that skips all players, NextBots, and non-LOS blockers
*/
class NextBotVisionTraceFilter : public CTraceFilterSimple
{
public:
NextBotVisionTraceFilter( const IHandleEntity *passentity, int collisionGroup ) : CTraceFilterSimple( passentity, collisionGroup, VisionTraceFilterFunction )
{
}
};
//--------------------------------------------------------------------------------------------
/**
* Trace filter that skips all NextBots, but includes Players
*/
class NextBotTraceFilterIgnoreNextBots : public CTraceFilterSimple
{
public:
NextBotTraceFilterIgnoreNextBots( const IHandleEntity *passentity, int collisionGroup )
: CTraceFilterSimple( passentity, collisionGroup )
{
}
virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
{
if ( CTraceFilterSimple::ShouldHitEntity( pServerEntity, contentsMask ) )
{
CBaseEntity *entity = EntityFromEntityHandle( pServerEntity );
#ifdef TERROR
CBasePlayer *player = ToBasePlayer( entity );
if ( player && player->IsGhost() )
return false;
#endif // TERROR
return ( entity->MyNextBotPointer() == NULL );
}
return false;
}
};
//--------------------------------------------------------------------------------------------
/**
* Trace filter that obeys INextBot::IsAbleToBlockMovementOf()
*/
class NextBotTraceFilter : public CTraceFilterSimple
{
public:
NextBotTraceFilter( const IHandleEntity *passentity, int collisionGroup )
: CTraceFilterSimple( passentity, collisionGroup )
{
CBaseEntity *entity = const_cast<CBaseEntity *>(EntityFromEntityHandle( passentity ));
m_passBot = entity->MyNextBotPointer();
}
virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
{
if ( CTraceFilterSimple::ShouldHitEntity( pServerEntity, contentsMask ) )
{
CBaseEntity *entity = EntityFromEntityHandle( pServerEntity );
#ifdef TERROR
CBasePlayer *player = ToBasePlayer( entity );
if ( player && player->IsGhost() )
return false;
#endif // TERROR
// Skip players on the same team - they're not solid to us, and we'll avoid them
if ( entity->IsPlayer() && m_passBot && m_passBot->GetEntity() &&
m_passBot->GetEntity()->GetTeamNumber() == entity->GetTeamNumber() )
return false;
INextBot *bot = entity->MyNextBotPointer();
return ( !bot || bot->IsAbleToBlockMovementOf( m_passBot ) );
}
return false;
}
const INextBot *m_passBot;
};
//--------------------------------------------------------------------------------------------
/**
* Trace filter that only hits players and NextBots
*/
class NextBotTraceFilterOnlyActors : public CTraceFilterSimple
{
public:
NextBotTraceFilterOnlyActors( const IHandleEntity *passentity, int collisionGroup )
: CTraceFilterSimple( passentity, collisionGroup )
{
}
virtual TraceType_t GetTraceType() const
{
return TRACE_ENTITIES_ONLY;
}
virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
{
if ( CTraceFilterSimple::ShouldHitEntity( pServerEntity, contentsMask ) )
{
CBaseEntity *entity = EntityFromEntityHandle( pServerEntity );
#ifdef TERROR
CBasePlayer *player = ToBasePlayer( entity );
if ( player && player->IsGhost() )
return false;
#endif // TERROR
return ( entity->MyNextBotPointer() || entity->IsPlayer() );
}
return false;
}
};
//--------------------------------------------------------------------------------------------
/**
* Trace filter that skips "traversable" entities. The "when" argument creates
* a temporal context for asking if an entity is IMMEDIATELY traversable (like thin
* glass that just breaks as we walk through it) or EVENTUALLY traversable (like a
* breakable object that will take some time to break through)
*/
class NextBotTraversableTraceFilter : public CTraceFilterSimple
{
public:
NextBotTraversableTraceFilter( INextBot *bot, ILocomotion::TraverseWhenType when = ILocomotion::EVENTUALLY ) : CTraceFilterSimple( bot->GetEntity(), COLLISION_GROUP_NONE )
{
m_bot = bot;
m_when = when;
}
virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
{
CBaseEntity *entity = EntityFromEntityHandle( pServerEntity );
if ( m_bot->IsSelf( entity ) )
{
return false;
}
if ( CTraceFilterSimple::ShouldHitEntity( pServerEntity, contentsMask ) )
{
return !m_bot->GetLocomotionInterface()->IsEntityTraversable( entity, m_when );
}
return false;
}
private:
INextBot *m_bot;
ILocomotion::TraverseWhenType m_when;
};
#ifdef OBSOLETE
//--------------------------------------------------------------------------------------------
/**
* Trace filter that skips "traversable" entities, but hits other Actors.
* Used for obstacle avoidance.
*/
class NextBotMovementAvoidanceTraceFilter : public CTraceFilterSimple
{
public:
NextBotMovementAvoidanceTraceFilter( INextBot *bot ) : CTraceFilterSimple( bot->GetEntity(), COLLISION_GROUP_NONE )
{
m_bot = bot;
}
virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
{
CBaseEntity *entity = EntityFromEntityHandle( pServerEntity );
#ifdef TERROR
CBasePlayer *player = ToBasePlayer( entity );
if ( player && player->IsGhost() )
return false;
#endif // TERROR
if ( m_bot->IsSelf( entity ) )
{
return false;
}
if ( CTraceFilterSimple::ShouldHitEntity( pServerEntity, contentsMask ) )
{
return !m_bot->GetLocomotionInterface()->IsEntityTraversable( entity, ILocomotion::IMMEDIATELY );
}
return false;
}
private:
INextBot *m_bot;
};
#endif
#endif // _NEXT_BOT_UTIL_H_