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.
299 lines
7.8 KiB
299 lines
7.8 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose: Simple, small, free-standing tools for building AIs
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
|
||
|
#ifndef AI_UTILS_H
|
||
|
#define AI_UTILS_H
|
||
|
|
||
|
#include "simtimer.h"
|
||
|
#include "ai_component.h"
|
||
|
|
||
|
#if defined( _WIN32 )
|
||
|
#pragma once
|
||
|
#endif
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function to get the local player. AI does not want asserts or warnings,
|
||
|
// just NULL result
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
inline CBasePlayer *AI_GetSinglePlayer()
|
||
|
{
|
||
|
if ( gpGlobals->maxClients > 1 )
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return UTIL_GetLocalPlayer();
|
||
|
}
|
||
|
|
||
|
inline bool AI_IsSinglePlayer()
|
||
|
{
|
||
|
return ( gpGlobals->maxClients == 1 );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// CAI_MoveMonitor
|
||
|
//
|
||
|
// Purpose: Watch an entity, trigger if moved more than a tolerance
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
class CAI_MoveMonitor
|
||
|
{
|
||
|
public:
|
||
|
CAI_MoveMonitor()
|
||
|
: m_vMark( 0, 0, 0 ),
|
||
|
m_flMarkTolerance( NO_MARK )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void SetMark( CBaseEntity *pEntity, float tolerance )
|
||
|
{
|
||
|
if ( pEntity )
|
||
|
{
|
||
|
m_vMark = pEntity->GetAbsOrigin();
|
||
|
m_flMarkTolerance = tolerance;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ClearMark()
|
||
|
{
|
||
|
m_flMarkTolerance = NO_MARK;
|
||
|
}
|
||
|
|
||
|
bool IsMarkSet()
|
||
|
{
|
||
|
return ( m_flMarkTolerance != NO_MARK );
|
||
|
}
|
||
|
|
||
|
bool TargetMoved( CBaseEntity *pEntity )
|
||
|
{
|
||
|
if ( IsMarkSet() && pEntity != NULL )
|
||
|
{
|
||
|
float distance = ( m_vMark - pEntity->GetAbsOrigin() ).Length();
|
||
|
if ( distance > m_flMarkTolerance )
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool TargetMoved2D( CBaseEntity *pEntity )
|
||
|
{
|
||
|
if ( IsMarkSet() && pEntity != NULL )
|
||
|
{
|
||
|
float distance = ( m_vMark.AsVector2D() - pEntity->GetAbsOrigin().AsVector2D() ).Length();
|
||
|
if ( distance > m_flMarkTolerance )
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
Vector GetMarkPos() { return m_vMark; }
|
||
|
|
||
|
private:
|
||
|
enum
|
||
|
{
|
||
|
NO_MARK = -1
|
||
|
};
|
||
|
|
||
|
Vector m_vMark;
|
||
|
float m_flMarkTolerance;
|
||
|
|
||
|
DECLARE_SIMPLE_DATADESC();
|
||
|
};
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// CAI_ShotRegulator
|
||
|
//
|
||
|
// Purpose: Assists in creating non-constant bursty shooting style
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
class CAI_ShotRegulator
|
||
|
{
|
||
|
public:
|
||
|
CAI_ShotRegulator();
|
||
|
|
||
|
// Sets the various parameters for burst (this one's for backwards compatibility)
|
||
|
// NOTE: This will modify the next shot time
|
||
|
void SetParameters( int minShotsPerBurst, int maxShotsPerBurst, float minRestTime, float maxRestTime = 0.0 );
|
||
|
|
||
|
// NOTE: The next 3 methods will *not* modify the next shot time
|
||
|
// Sets the number of shots to shoot in a single burst
|
||
|
void SetBurstShotCountRange( int minShotsPerBurst, int maxShotsPerBurst );
|
||
|
|
||
|
// How much time should I rest between bursts?
|
||
|
void SetRestInterval( float flMinRestInterval, float flMaxRestInterval );
|
||
|
|
||
|
// How much time should I wait in between shots in a single burst?
|
||
|
void SetBurstInterval( float flMinBurstInterval, float flMaxBurstInterval );
|
||
|
|
||
|
// Poll the current parameters
|
||
|
void GetBurstShotCountRange( int *pMinShotsPerBurst, int *pMaxShotsPerBurst ) const;
|
||
|
void GetRestInterval( float *pMinRestInterval, float *pMaxRestInterval ) const;
|
||
|
void GetBurstInterval( float *pMinBurstInterval, float *pMaxBurstInterval ) const;
|
||
|
|
||
|
// Reset the state. If true, the next burst time is set to now,
|
||
|
// otherwise it'll wait one rest interval before shooting
|
||
|
void Reset( bool bStartShooting = true );
|
||
|
|
||
|
// Should we shoot?
|
||
|
bool ShouldShoot() const;
|
||
|
|
||
|
// When will I shoot next?
|
||
|
float NextShotTime() const;
|
||
|
|
||
|
// Am I in the middle of a rest period?
|
||
|
bool IsInRestInterval() const;
|
||
|
|
||
|
// NOTE: These will not modify the next shot time
|
||
|
int GetBurstShotsRemaining() const;
|
||
|
void SetBurstShotsRemaining( int shots );
|
||
|
|
||
|
// Call this when the NPC fired the weapon;
|
||
|
void OnFiredWeapon();
|
||
|
|
||
|
// Causes us to potentially delay our shooting time
|
||
|
void FireNoEarlierThan( float flTime );
|
||
|
|
||
|
// Prevent/Allow shooting
|
||
|
void EnableShooting( void );
|
||
|
void DisableShooting( void );
|
||
|
|
||
|
private:
|
||
|
float m_flNextShotTime;
|
||
|
bool m_bInRestInterval;
|
||
|
unsigned short m_nBurstShotsRemaining;
|
||
|
unsigned short m_nMinBurstShots, m_nMaxBurstShots;
|
||
|
float m_flMinRestInterval, m_flMaxRestInterval;
|
||
|
float m_flMinBurstInterval, m_flMaxBurstInterval;
|
||
|
bool m_bDisabled;
|
||
|
|
||
|
DECLARE_SIMPLE_DATADESC();
|
||
|
};
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// CAI_AccelDecay
|
||
|
//
|
||
|
// Purpose: Maintain a smooth acceleration, deceleration curve
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
class CAI_AccelDecay
|
||
|
{
|
||
|
public:
|
||
|
CAI_AccelDecay();
|
||
|
|
||
|
void SetParameters( float minVelocity, float maxVelocity, float accelPercent, float decelPercent );
|
||
|
float Update( float flCurrent, float flTarget, float flInterval );
|
||
|
void ResetVelocity( float flVelocity = 0.0f );
|
||
|
void SetMaxVelocity( float maxVelocity );
|
||
|
|
||
|
private:
|
||
|
float m_velocity;
|
||
|
|
||
|
float m_maxVelocity; // = 300;
|
||
|
float m_minVelocity; // = 10;
|
||
|
|
||
|
float m_invDecay; // 0.8 // maintain X percent of velocity when slowing down
|
||
|
float m_decayTime;// 0.4161 // Sum( 1..cycle, HEIGHTINVDECAY^cycle )
|
||
|
float m_accel; // 0.5 // accel toward maxVelocity by X percent each cycle
|
||
|
|
||
|
DECLARE_SIMPLE_DATADESC();
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Purpose: Utility to allow place grace in cover
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
struct AI_FreePassParams_t
|
||
|
{
|
||
|
float timeToTrigger; // How long after not detected to issue pass
|
||
|
float duration; // How long in the open pass before revoked
|
||
|
float moveTolerance; // How far in open needed to move to revoke pass
|
||
|
float refillRate; // After hiding again during pass, how quickly to reinstitute pass(seconds per second)
|
||
|
float coverDist; // When hiding, how far from an obstructing object needed to be considered in cover
|
||
|
|
||
|
float peekTime; // How long allowed to peek
|
||
|
float peekTimeAfterDamage; // How long allowed to peek after damaged by
|
||
|
float peekEyeDist; // how far spaced out the eyes are
|
||
|
float peekEyeDistZ; // how far below eye position to test eyes (handles peek up)
|
||
|
|
||
|
DECLARE_SIMPLE_DATADESC();
|
||
|
};
|
||
|
|
||
|
//-------------------------------------
|
||
|
|
||
|
class CAI_FreePass : public CAI_Component
|
||
|
{
|
||
|
public:
|
||
|
CAI_FreePass()
|
||
|
: m_FreePassTimeRemaining(0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void Reset( float passTime = -1, float moveTolerance = -1 );
|
||
|
|
||
|
void SetPassTarget( CBaseEntity *pTarget ) { m_hTarget = pTarget; m_FreePassTimeRemaining = 0; }
|
||
|
CBaseEntity * GetPassTarget() { return m_hTarget; }
|
||
|
|
||
|
void SetParams( const AI_FreePassParams_t ¶ms ) { m_Params = params; }
|
||
|
const AI_FreePassParams_t &GetParams() const { return m_Params; }
|
||
|
|
||
|
//---------------------------------
|
||
|
// Free pass
|
||
|
//---------------------------------
|
||
|
void Update();
|
||
|
|
||
|
bool HasPass();
|
||
|
void Revoke( bool bUpdateMemory = false );
|
||
|
|
||
|
float GetTimeRemaining() { return m_FreePassTimeRemaining; }
|
||
|
void SetTimeRemaining( float passTime ) { m_FreePassTimeRemaining = passTime; }
|
||
|
|
||
|
bool ShouldAllowFVisible( bool bBaseResult );
|
||
|
|
||
|
private:
|
||
|
EHANDLE m_hTarget;
|
||
|
|
||
|
float m_FreePassTimeRemaining;
|
||
|
CAI_MoveMonitor m_FreePassMoveMonitor;
|
||
|
|
||
|
AI_FreePassParams_t m_Params;
|
||
|
|
||
|
DECLARE_SIMPLE_DATADESC();
|
||
|
};
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
class CTraceFilterNav : public CTraceFilterSimple
|
||
|
{
|
||
|
public:
|
||
|
CTraceFilterNav( CAI_BaseNPC *pProber, bool bIgnoreTransientEntities, const IServerEntity *passedict, int collisionGroup, bool m_bAllowPlayerAvoid = true );
|
||
|
bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask );
|
||
|
|
||
|
private:
|
||
|
CAI_BaseNPC *m_pProber;
|
||
|
bool m_bIgnoreTransientEntities;
|
||
|
bool m_bCheckCollisionTable;
|
||
|
bool m_bAllowPlayerAvoid;
|
||
|
};
|
||
|
|
||
|
extern string_t g_iszFuncBrushClassname;
|
||
|
|
||
|
#endif // AI_UTILS_H
|