From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/server/ai_utils.cpp | 1160 +++++++++++++++++++-------------------- 1 file changed, 580 insertions(+), 580 deletions(-) (limited to 'mp/src/game/server/ai_utils.cpp') diff --git a/mp/src/game/server/ai_utils.cpp b/mp/src/game/server/ai_utils.cpp index 3119d2f8..802a1c10 100644 --- a/mp/src/game/server/ai_utils.cpp +++ b/mp/src/game/server/ai_utils.cpp @@ -1,580 +1,580 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#include "cbase.h" -#include "ai_utils.h" -#include "ai_memory.h" -#include "ai_basenpc.h" -#include "ai_senses.h" -#include "ai_moveprobe.h" -#include "vphysics/object_hash.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -//----------------------------------------------------------------------------- - -BEGIN_SIMPLE_DATADESC( CAI_MoveMonitor ) - DEFINE_FIELD( m_vMark, FIELD_POSITION_VECTOR ), - DEFINE_FIELD( m_flMarkTolerance, FIELD_FLOAT ) -END_DATADESC() - -//----------------------------------------------------------------------------- - -BEGIN_SIMPLE_DATADESC( CAI_ShotRegulator ) - DEFINE_FIELD( m_flNextShotTime, FIELD_TIME ), - DEFINE_FIELD( m_bInRestInterval, FIELD_BOOLEAN ), - DEFINE_FIELD( m_nBurstShotsRemaining, FIELD_SHORT ), - DEFINE_FIELD( m_nMinBurstShots, FIELD_SHORT ), - DEFINE_FIELD( m_nMaxBurstShots, FIELD_SHORT ), - DEFINE_FIELD( m_flMinRestInterval, FIELD_FLOAT ), - DEFINE_FIELD( m_flMaxRestInterval, FIELD_FLOAT ), - DEFINE_FIELD( m_flMinBurstInterval, FIELD_FLOAT ), - DEFINE_FIELD( m_flMaxBurstInterval, FIELD_FLOAT ), - DEFINE_FIELD( m_bDisabled, FIELD_BOOLEAN ), -END_DATADESC() - -//----------------------------------------------------------------------------- - - -//----------------------------------------------------------------------------- -// Constructor -//----------------------------------------------------------------------------- -CAI_ShotRegulator::CAI_ShotRegulator() : m_nMinBurstShots(1), m_nMaxBurstShots(1) -{ - m_flMinRestInterval = 0.0f; - m_flMinRestInterval = 0.0f; - m_flMinBurstInterval = 0.0f; - m_flMaxBurstInterval = 0.0f; - m_flNextShotTime = -1; - m_nBurstShotsRemaining = 1; - m_bInRestInterval = false; - m_bDisabled = false; -} - - -//----------------------------------------------------------------------------- -// For backward compatibility -//----------------------------------------------------------------------------- -void CAI_ShotRegulator::SetParameters( int minShotsPerBurst, int maxShotsPerBurst, float minRestTime, float maxRestTime ) -{ - SetBurstShotCountRange( minShotsPerBurst, maxShotsPerBurst ); - SetRestInterval( minRestTime, maxRestTime ); - Reset( false ); -} - - -//----------------------------------------------------------------------------- -// Sets the number of shots to shoot in a single burst -//----------------------------------------------------------------------------- -void CAI_ShotRegulator::SetBurstShotCountRange( int minShotsPerBurst, int maxShotsPerBurst ) -{ - m_nMinBurstShots = minShotsPerBurst; - m_nMaxBurstShots = maxShotsPerBurst; -} - - -//----------------------------------------------------------------------------- -// How much time should I rest between bursts? -//----------------------------------------------------------------------------- -void CAI_ShotRegulator::SetRestInterval( float flMinRestInterval, float flMaxRestInterval ) -{ - m_flMinRestInterval = flMinRestInterval; - m_flMaxRestInterval = flMaxRestInterval; -} - - -//----------------------------------------------------------------------------- -// How much time should I wait in between shots in a single burst? -//----------------------------------------------------------------------------- -void CAI_ShotRegulator::SetBurstInterval( float flMinBurstInterval, float flMaxBurstInterval ) -{ - m_flMinBurstInterval = flMinBurstInterval; - m_flMaxBurstInterval = flMaxBurstInterval; -} - - -//----------------------------------------------------------------------------- -// Poll the current parameters -//----------------------------------------------------------------------------- -void CAI_ShotRegulator::GetBurstShotCountRange( int *pMinShotsPerBurst, int *pMaxShotsPerBurst ) const -{ - *pMinShotsPerBurst = m_nMinBurstShots; - *pMaxShotsPerBurst = m_nMaxBurstShots; -} - -void CAI_ShotRegulator::GetRestInterval( float *pMinRestInterval, float *pMaxRestInterval ) const -{ - *pMinRestInterval = m_flMinRestInterval; - *pMaxRestInterval = m_flMaxRestInterval; -} - -void CAI_ShotRegulator::GetBurstInterval( float *pMinBurstInterval, float *pMaxBurstInterval ) const -{ - *pMinBurstInterval = m_flMinBurstInterval; - *pMaxBurstInterval = m_flMaxBurstInterval; -} - - -//----------------------------------------------------------------------------- -// Resets the shot regulator to start a new burst -//----------------------------------------------------------------------------- -void CAI_ShotRegulator::Reset( bool bStartShooting ) -{ - m_bDisabled = false; - m_nBurstShotsRemaining = random->RandomInt( m_nMinBurstShots, m_nMaxBurstShots ); - if ( bStartShooting ) - { - m_flNextShotTime = gpGlobals->curtime; - m_bInRestInterval = false; - } - else - { - m_flNextShotTime = gpGlobals->curtime + random->RandomFloat( m_flMinRestInterval, m_flMaxRestInterval ); - m_bInRestInterval = true; - } -} - - -//----------------------------------------------------------------------------- -// Should we shoot? -//----------------------------------------------------------------------------- -bool CAI_ShotRegulator::ShouldShoot() const -{ - return ( !m_bDisabled && (m_flNextShotTime <= gpGlobals->curtime) ); -} - - -//----------------------------------------------------------------------------- -// Am I in the middle of a burst? -//----------------------------------------------------------------------------- -bool CAI_ShotRegulator::IsInRestInterval() const -{ - return (m_bInRestInterval && !ShouldShoot()); -} - - -//----------------------------------------------------------------------------- -// When will I shoot next? -//----------------------------------------------------------------------------- -float CAI_ShotRegulator::NextShotTime() const -{ - return m_flNextShotTime; -} - - -//----------------------------------------------------------------------------- -// Causes us to potentially delay our shooting time -//----------------------------------------------------------------------------- -void CAI_ShotRegulator::FireNoEarlierThan( float flTime ) -{ - if ( flTime > m_flNextShotTime ) - { - m_flNextShotTime = flTime; - } -} - - -//----------------------------------------------------------------------------- -// Burst shot count accessors -//----------------------------------------------------------------------------- -int CAI_ShotRegulator::GetBurstShotsRemaining() const -{ - return m_nBurstShotsRemaining; -} - -void CAI_ShotRegulator::SetBurstShotsRemaining( int shots ) -{ - m_nBurstShotsRemaining = shots; -} - - -//----------------------------------------------------------------------------- -// We fired the weapon! Update the next shot time -//----------------------------------------------------------------------------- -void CAI_ShotRegulator::OnFiredWeapon() -{ - --m_nBurstShotsRemaining; - if ( m_nBurstShotsRemaining <= 0 ) - { - Reset( false ); - } - else - { - m_bInRestInterval = false; - m_flNextShotTime += random->RandomFloat( m_flMinBurstInterval, m_flMaxBurstInterval ); - if ( m_flNextShotTime < gpGlobals->curtime ) - { - m_flNextShotTime = gpGlobals->curtime; - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CAI_ShotRegulator::EnableShooting( void ) -{ - m_bDisabled = false; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CAI_ShotRegulator::DisableShooting( void ) -{ - m_bDisabled = true; -} - - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- - -BEGIN_SIMPLE_DATADESC( CAI_AccelDecay ) - DEFINE_FIELD( m_velocity, FIELD_FLOAT ), - DEFINE_FIELD( m_maxVelocity, FIELD_FLOAT ), - DEFINE_FIELD( m_minVelocity, FIELD_FLOAT ), - DEFINE_FIELD( m_invDecay, FIELD_FLOAT ), - DEFINE_FIELD( m_decayTime, FIELD_FLOAT ), - DEFINE_FIELD( m_accel, FIELD_FLOAT ), -END_DATADESC() - - -void CAI_AccelDecay::SetParameters( float minVelocity, float maxVelocity, float accelPercentPerTick, float decelPercentPerTick ) -{ - m_minVelocity = minVelocity; - m_maxVelocity = maxVelocity; - - m_accel = accelPercentPerTick; - m_invDecay = 1.0 - decelPercentPerTick; - - m_decayTime = 0.0; - float d = 1.0; - - int i = 0; - while (d * m_maxVelocity > m_minVelocity && i < 10) - { - d = d * m_invDecay; - m_decayTime = m_decayTime + 0.1 * d; // appox interval call - i++; - } -} - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- - -float CAI_AccelDecay::Update( float flCurrent, float flTarget, float flInterval ) -{ - float delta = flTarget - flCurrent; - float deltaSign = ( delta < 0 ) ? -1 : 1; - delta = fabsf( delta ); - - float curVelocity = m_velocity; - - if ( delta > 0.01 ) - { - if (fabsf( m_velocity ) < m_minVelocity) - m_velocity = m_minVelocity * deltaSign; - - if (delta < m_velocity * deltaSign * m_decayTime ) - { - m_velocity = m_velocity * m_invDecay; - - if (delta < m_velocity * deltaSign * flInterval) - { - m_velocity = delta * deltaSign / flInterval; - } - } - else - { - m_velocity = m_velocity * (1.0f - m_accel) + m_maxVelocity * m_accel * deltaSign; - if (delta < m_velocity * deltaSign * m_decayTime) - { - m_velocity = delta * deltaSign / m_decayTime; - } - } - - float newValue = flCurrent + (curVelocity + m_velocity) * 0.5 * flInterval; - return newValue; - } - - return flTarget; -} - - - -void CAI_AccelDecay::ResetVelocity( float flVelocity ) -{ - m_velocity = flVelocity; -} - - -void CAI_AccelDecay::SetMaxVelocity( float maxVelocity ) -{ - if (maxVelocity != m_maxVelocity) - { - SetParameters( m_minVelocity, maxVelocity, m_accel, 1.0 - m_invDecay ); - } -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -ConVar free_pass_peek_debug( "free_pass_peek_debug", "0" ); - -BEGIN_SIMPLE_DATADESC( AI_FreePassParams_t ) - - DEFINE_KEYFIELD( timeToTrigger, FIELD_FLOAT, "freepass_timetotrigger"), - DEFINE_KEYFIELD( duration, FIELD_FLOAT, "freepass_duration"), - DEFINE_KEYFIELD( moveTolerance, FIELD_FLOAT, "freepass_movetolerance"), - DEFINE_KEYFIELD( refillRate, FIELD_FLOAT, "freepass_refillrate"), - DEFINE_FIELD( coverDist, FIELD_FLOAT), - DEFINE_KEYFIELD( peekTime, FIELD_FLOAT, "freepass_peektime"), - DEFINE_FIELD( peekTimeAfterDamage, FIELD_FLOAT), - DEFINE_FIELD( peekEyeDist, FIELD_FLOAT), - DEFINE_FIELD( peekEyeDistZ, FIELD_FLOAT), - -END_DATADESC() - -BEGIN_SIMPLE_DATADESC( CAI_FreePass ) - - DEFINE_FIELD( m_hTarget, FIELD_EHANDLE ), - DEFINE_FIELD( m_FreePassTimeRemaining, FIELD_FLOAT ), - DEFINE_EMBEDDED( m_FreePassMoveMonitor ), - DEFINE_EMBEDDED( m_Params ), - -END_DATADESC() - -//--------------------------------------------------------- -//--------------------------------------------------------- - -void CAI_FreePass::Reset( float passTime, float moveTolerance ) -{ - CBaseEntity *pTarget = GetPassTarget(); - - if ( !pTarget || m_Params.duration < 0.1 ) - return; - - if ( passTime == -1 ) - { - m_FreePassTimeRemaining = m_Params.duration; - } - else - { - m_FreePassTimeRemaining = passTime; - } - - if ( moveTolerance == -1 ) - { - m_FreePassMoveMonitor.SetMark( pTarget, m_Params.moveTolerance ); - } - else - { - m_FreePassMoveMonitor.SetMark( pTarget, moveTolerance ); - } -} - -//--------------------------------------------------------- -//--------------------------------------------------------- - -void CAI_FreePass::Update( ) -{ - CBaseEntity *pTarget = GetPassTarget(); - if ( !pTarget || m_Params.duration < 0.1 ) - return; - - //--------------------------------- - // - // Free pass logic - // - AI_EnemyInfo_t *pTargetInfo = GetOuter()->GetEnemies()->Find( pTarget ); - - // This works with old data because need to do before base class so as to not choose as enemy - if ( !HasPass() ) - { - float timePlayerLastSeen = (pTargetInfo) ? pTargetInfo->timeLastSeen : AI_INVALID_TIME; - float lastTimeDamagedBy = (pTargetInfo) ? pTargetInfo->timeLastReceivedDamageFrom : AI_INVALID_TIME; - - if ( timePlayerLastSeen == AI_INVALID_TIME || gpGlobals->curtime - timePlayerLastSeen > .15 ) // If didn't see the player last think - { - trace_t tr; - UTIL_TraceLine( pTarget->EyePosition(), GetOuter()->EyePosition(), MASK_BLOCKLOS, GetOuter(), COLLISION_GROUP_NONE, &tr ); - if ( tr.fraction != 1.0 && tr.m_pEnt != pTarget ) - { - float dist = (tr.endpos - tr.startpos).Length() * tr.fraction; - - if ( dist < m_Params.coverDist ) - { - if ( ( timePlayerLastSeen == AI_INVALID_TIME || gpGlobals->curtime - timePlayerLastSeen > m_Params.timeToTrigger ) && - ( lastTimeDamagedBy == AI_INVALID_TIME || gpGlobals->curtime - lastTimeDamagedBy > m_Params.timeToTrigger ) ) - { - m_FreePassTimeRemaining = m_Params.duration; - m_FreePassMoveMonitor.SetMark( pTarget, m_Params.moveTolerance ); - } - } - } - } - } - else - { - float temp = m_FreePassTimeRemaining; - m_FreePassTimeRemaining = 0; - CAI_Senses *pSenses = GetOuter()->GetSenses(); - bool bCanSee = ( pSenses && pSenses->ShouldSeeEntity( pTarget ) && pSenses->CanSeeEntity( pTarget ) ); - m_FreePassTimeRemaining = temp; - - if ( bCanSee ) - { - if ( !m_FreePassMoveMonitor.TargetMoved( pTarget ) ) - m_FreePassTimeRemaining -= 0.1; - else - Revoke( true ); - } - else - { - m_FreePassTimeRemaining += 0.1 * m_Params.refillRate; - if ( m_FreePassTimeRemaining > m_Params.duration ) - m_FreePassTimeRemaining = m_Params.duration; - m_FreePassMoveMonitor.SetMark( pTarget, m_Params.moveTolerance ); - } - } -} - -//--------------------------------------------------------- -//--------------------------------------------------------- -bool CAI_FreePass::HasPass() -{ - return ( m_FreePassTimeRemaining > 0 ); -} - -//--------------------------------------------------------- -//--------------------------------------------------------- -void CAI_FreePass::Revoke( bool bUpdateMemory ) -{ - m_FreePassTimeRemaining = 0; - if ( bUpdateMemory && GetPassTarget() ) - { - GetOuter()->UpdateEnemyMemory( GetPassTarget(), GetPassTarget()->GetAbsOrigin() ); - } -} - -//--------------------------------------------------------- -//--------------------------------------------------------- -bool CAI_FreePass::ShouldAllowFVisible(bool bBaseResult ) -{ - CBaseEntity * pTarget = GetPassTarget(); - AI_EnemyInfo_t *pTargetInfo = GetOuter()->GetEnemies()->Find( pTarget ); - - if ( !bBaseResult || HasPass() ) - return false; - - bool bIsVisible = true; - - // Peek logic - if ( m_Params.peekTime > 0.1 ) - { - float lastTimeSeen = (pTargetInfo) ? pTargetInfo->timeLastSeen : AI_INVALID_TIME; - float lastTimeDamagedBy = (pTargetInfo) ? pTargetInfo->timeLastReceivedDamageFrom : AI_INVALID_TIME; - - if ( ( lastTimeSeen == AI_INVALID_TIME || gpGlobals->curtime - lastTimeSeen > m_Params.peekTime ) && - ( lastTimeDamagedBy == AI_INVALID_TIME || gpGlobals->curtime - lastTimeDamagedBy > m_Params.peekTimeAfterDamage ) ) - { - Vector vToTarget; - - VectorSubtract( pTarget->EyePosition(), GetOuter()->EyePosition(), vToTarget ); - vToTarget.z = 0.0f; - VectorNormalize( vToTarget ); - - Vector vecRight( -vToTarget.y, vToTarget.x, 0.0f ); - trace_t tr; - - UTIL_TraceLine( GetOuter()->EyePosition(), pTarget->EyePosition() + (vecRight * m_Params.peekEyeDist - Vector( 0, 0, m_Params.peekEyeDistZ )), MASK_BLOCKLOS, GetOuter(), COLLISION_GROUP_NONE, &tr ); - if ( tr.fraction != 1.0 && tr.m_pEnt != pTarget ) - { - if ( free_pass_peek_debug.GetBool() ) - NDebugOverlay::Line( tr.startpos, tr.endpos - Vector( 0, 0, 2), 0, 255, 0, false, 0.1 ); - bIsVisible = false; - } - - if ( bIsVisible ) - { - UTIL_TraceLine( GetOuter()->EyePosition(), pTarget->EyePosition() + (-vecRight * m_Params.peekEyeDist - Vector( 0, 0, m_Params.peekEyeDistZ )), MASK_BLOCKLOS, GetOuter(), COLLISION_GROUP_NONE, &tr ); - if ( tr.fraction != 1.0 && tr.m_pEnt != pTarget ) - { - if ( free_pass_peek_debug.GetBool() ) - NDebugOverlay::Line( tr.startpos, tr.endpos - Vector( 0, 0, 2), 0, 255, 0, false, 0.1 ); - bIsVisible = false; - } - } - } - - if ( bIsVisible && free_pass_peek_debug.GetBool() ) - NDebugOverlay::Line( GetOuter()->EyePosition(), pTarget->EyePosition() - Vector( 0, 0, 2), 255, 0, 0, false, 0.1 ); - } - - return bIsVisible; -} - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -string_t g_iszFuncBrushClassname = NULL_STRING; - -//----------------------------------------------------------------------------- -CTraceFilterNav::CTraceFilterNav( CAI_BaseNPC *pProber, bool bIgnoreTransientEntities, const IServerEntity *passedict, int collisionGroup, bool bAllowPlayerAvoid ) : - CTraceFilterSimple( passedict, collisionGroup ), - m_pProber(pProber), - m_bIgnoreTransientEntities(bIgnoreTransientEntities), - m_bAllowPlayerAvoid(bAllowPlayerAvoid) -{ - m_bCheckCollisionTable = g_EntityCollisionHash->IsObjectInHash( pProber ); -} - -//----------------------------------------------------------------------------- -bool CTraceFilterNav::ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask ) -{ - IServerEntity *pServerEntity = (IServerEntity*)pHandleEntity; - CBaseEntity *pEntity = (CBaseEntity *)pServerEntity; - - if ( m_pProber == pEntity ) - return false; - - if ( m_pProber->GetMoveProbe()->ShouldBrushBeIgnored( pEntity ) == true ) - return false; - -#ifdef HL1_DLL - if ( ( contentsMask & CONTENTS_MOVEABLE ) == 0 ) - { - if ( pEntity->ClassMatches( "func_pushable" ) ) - return false; - } -#endif - - if ( m_bIgnoreTransientEntities && (pEntity->IsPlayer() || pEntity->IsNPC() ) ) - return false; - - //Adrian - If I'm flagged as using the new collision method, then ignore the player when trying - //to check if I can get somewhere. - if ( m_bAllowPlayerAvoid && m_pProber->ShouldPlayerAvoid() && pEntity->IsPlayer() ) - return false; - - if ( pEntity->IsNavIgnored() ) - return false; - - if ( m_bCheckCollisionTable ) - { - if ( g_EntityCollisionHash->IsObjectPairInHash( m_pProber, pEntity ) ) - return false; - } - - if ( m_pProber->ShouldProbeCollideAgainstEntity( pEntity ) == false ) - return false; - - return CTraceFilterSimple::ShouldHitEntity( pHandleEntity, contentsMask ); -} +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "ai_utils.h" +#include "ai_memory.h" +#include "ai_basenpc.h" +#include "ai_senses.h" +#include "ai_moveprobe.h" +#include "vphysics/object_hash.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- + +BEGIN_SIMPLE_DATADESC( CAI_MoveMonitor ) + DEFINE_FIELD( m_vMark, FIELD_POSITION_VECTOR ), + DEFINE_FIELD( m_flMarkTolerance, FIELD_FLOAT ) +END_DATADESC() + +//----------------------------------------------------------------------------- + +BEGIN_SIMPLE_DATADESC( CAI_ShotRegulator ) + DEFINE_FIELD( m_flNextShotTime, FIELD_TIME ), + DEFINE_FIELD( m_bInRestInterval, FIELD_BOOLEAN ), + DEFINE_FIELD( m_nBurstShotsRemaining, FIELD_SHORT ), + DEFINE_FIELD( m_nMinBurstShots, FIELD_SHORT ), + DEFINE_FIELD( m_nMaxBurstShots, FIELD_SHORT ), + DEFINE_FIELD( m_flMinRestInterval, FIELD_FLOAT ), + DEFINE_FIELD( m_flMaxRestInterval, FIELD_FLOAT ), + DEFINE_FIELD( m_flMinBurstInterval, FIELD_FLOAT ), + DEFINE_FIELD( m_flMaxBurstInterval, FIELD_FLOAT ), + DEFINE_FIELD( m_bDisabled, FIELD_BOOLEAN ), +END_DATADESC() + +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +CAI_ShotRegulator::CAI_ShotRegulator() : m_nMinBurstShots(1), m_nMaxBurstShots(1) +{ + m_flMinRestInterval = 0.0f; + m_flMinRestInterval = 0.0f; + m_flMinBurstInterval = 0.0f; + m_flMaxBurstInterval = 0.0f; + m_flNextShotTime = -1; + m_nBurstShotsRemaining = 1; + m_bInRestInterval = false; + m_bDisabled = false; +} + + +//----------------------------------------------------------------------------- +// For backward compatibility +//----------------------------------------------------------------------------- +void CAI_ShotRegulator::SetParameters( int minShotsPerBurst, int maxShotsPerBurst, float minRestTime, float maxRestTime ) +{ + SetBurstShotCountRange( minShotsPerBurst, maxShotsPerBurst ); + SetRestInterval( minRestTime, maxRestTime ); + Reset( false ); +} + + +//----------------------------------------------------------------------------- +// Sets the number of shots to shoot in a single burst +//----------------------------------------------------------------------------- +void CAI_ShotRegulator::SetBurstShotCountRange( int minShotsPerBurst, int maxShotsPerBurst ) +{ + m_nMinBurstShots = minShotsPerBurst; + m_nMaxBurstShots = maxShotsPerBurst; +} + + +//----------------------------------------------------------------------------- +// How much time should I rest between bursts? +//----------------------------------------------------------------------------- +void CAI_ShotRegulator::SetRestInterval( float flMinRestInterval, float flMaxRestInterval ) +{ + m_flMinRestInterval = flMinRestInterval; + m_flMaxRestInterval = flMaxRestInterval; +} + + +//----------------------------------------------------------------------------- +// How much time should I wait in between shots in a single burst? +//----------------------------------------------------------------------------- +void CAI_ShotRegulator::SetBurstInterval( float flMinBurstInterval, float flMaxBurstInterval ) +{ + m_flMinBurstInterval = flMinBurstInterval; + m_flMaxBurstInterval = flMaxBurstInterval; +} + + +//----------------------------------------------------------------------------- +// Poll the current parameters +//----------------------------------------------------------------------------- +void CAI_ShotRegulator::GetBurstShotCountRange( int *pMinShotsPerBurst, int *pMaxShotsPerBurst ) const +{ + *pMinShotsPerBurst = m_nMinBurstShots; + *pMaxShotsPerBurst = m_nMaxBurstShots; +} + +void CAI_ShotRegulator::GetRestInterval( float *pMinRestInterval, float *pMaxRestInterval ) const +{ + *pMinRestInterval = m_flMinRestInterval; + *pMaxRestInterval = m_flMaxRestInterval; +} + +void CAI_ShotRegulator::GetBurstInterval( float *pMinBurstInterval, float *pMaxBurstInterval ) const +{ + *pMinBurstInterval = m_flMinBurstInterval; + *pMaxBurstInterval = m_flMaxBurstInterval; +} + + +//----------------------------------------------------------------------------- +// Resets the shot regulator to start a new burst +//----------------------------------------------------------------------------- +void CAI_ShotRegulator::Reset( bool bStartShooting ) +{ + m_bDisabled = false; + m_nBurstShotsRemaining = random->RandomInt( m_nMinBurstShots, m_nMaxBurstShots ); + if ( bStartShooting ) + { + m_flNextShotTime = gpGlobals->curtime; + m_bInRestInterval = false; + } + else + { + m_flNextShotTime = gpGlobals->curtime + random->RandomFloat( m_flMinRestInterval, m_flMaxRestInterval ); + m_bInRestInterval = true; + } +} + + +//----------------------------------------------------------------------------- +// Should we shoot? +//----------------------------------------------------------------------------- +bool CAI_ShotRegulator::ShouldShoot() const +{ + return ( !m_bDisabled && (m_flNextShotTime <= gpGlobals->curtime) ); +} + + +//----------------------------------------------------------------------------- +// Am I in the middle of a burst? +//----------------------------------------------------------------------------- +bool CAI_ShotRegulator::IsInRestInterval() const +{ + return (m_bInRestInterval && !ShouldShoot()); +} + + +//----------------------------------------------------------------------------- +// When will I shoot next? +//----------------------------------------------------------------------------- +float CAI_ShotRegulator::NextShotTime() const +{ + return m_flNextShotTime; +} + + +//----------------------------------------------------------------------------- +// Causes us to potentially delay our shooting time +//----------------------------------------------------------------------------- +void CAI_ShotRegulator::FireNoEarlierThan( float flTime ) +{ + if ( flTime > m_flNextShotTime ) + { + m_flNextShotTime = flTime; + } +} + + +//----------------------------------------------------------------------------- +// Burst shot count accessors +//----------------------------------------------------------------------------- +int CAI_ShotRegulator::GetBurstShotsRemaining() const +{ + return m_nBurstShotsRemaining; +} + +void CAI_ShotRegulator::SetBurstShotsRemaining( int shots ) +{ + m_nBurstShotsRemaining = shots; +} + + +//----------------------------------------------------------------------------- +// We fired the weapon! Update the next shot time +//----------------------------------------------------------------------------- +void CAI_ShotRegulator::OnFiredWeapon() +{ + --m_nBurstShotsRemaining; + if ( m_nBurstShotsRemaining <= 0 ) + { + Reset( false ); + } + else + { + m_bInRestInterval = false; + m_flNextShotTime += random->RandomFloat( m_flMinBurstInterval, m_flMaxBurstInterval ); + if ( m_flNextShotTime < gpGlobals->curtime ) + { + m_flNextShotTime = gpGlobals->curtime; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_ShotRegulator::EnableShooting( void ) +{ + m_bDisabled = false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_ShotRegulator::DisableShooting( void ) +{ + m_bDisabled = true; +} + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +BEGIN_SIMPLE_DATADESC( CAI_AccelDecay ) + DEFINE_FIELD( m_velocity, FIELD_FLOAT ), + DEFINE_FIELD( m_maxVelocity, FIELD_FLOAT ), + DEFINE_FIELD( m_minVelocity, FIELD_FLOAT ), + DEFINE_FIELD( m_invDecay, FIELD_FLOAT ), + DEFINE_FIELD( m_decayTime, FIELD_FLOAT ), + DEFINE_FIELD( m_accel, FIELD_FLOAT ), +END_DATADESC() + + +void CAI_AccelDecay::SetParameters( float minVelocity, float maxVelocity, float accelPercentPerTick, float decelPercentPerTick ) +{ + m_minVelocity = minVelocity; + m_maxVelocity = maxVelocity; + + m_accel = accelPercentPerTick; + m_invDecay = 1.0 - decelPercentPerTick; + + m_decayTime = 0.0; + float d = 1.0; + + int i = 0; + while (d * m_maxVelocity > m_minVelocity && i < 10) + { + d = d * m_invDecay; + m_decayTime = m_decayTime + 0.1 * d; // appox interval call + i++; + } +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +float CAI_AccelDecay::Update( float flCurrent, float flTarget, float flInterval ) +{ + float delta = flTarget - flCurrent; + float deltaSign = ( delta < 0 ) ? -1 : 1; + delta = fabsf( delta ); + + float curVelocity = m_velocity; + + if ( delta > 0.01 ) + { + if (fabsf( m_velocity ) < m_minVelocity) + m_velocity = m_minVelocity * deltaSign; + + if (delta < m_velocity * deltaSign * m_decayTime ) + { + m_velocity = m_velocity * m_invDecay; + + if (delta < m_velocity * deltaSign * flInterval) + { + m_velocity = delta * deltaSign / flInterval; + } + } + else + { + m_velocity = m_velocity * (1.0f - m_accel) + m_maxVelocity * m_accel * deltaSign; + if (delta < m_velocity * deltaSign * m_decayTime) + { + m_velocity = delta * deltaSign / m_decayTime; + } + } + + float newValue = flCurrent + (curVelocity + m_velocity) * 0.5 * flInterval; + return newValue; + } + + return flTarget; +} + + + +void CAI_AccelDecay::ResetVelocity( float flVelocity ) +{ + m_velocity = flVelocity; +} + + +void CAI_AccelDecay::SetMaxVelocity( float maxVelocity ) +{ + if (maxVelocity != m_maxVelocity) + { + SetParameters( m_minVelocity, maxVelocity, m_accel, 1.0 - m_invDecay ); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +ConVar free_pass_peek_debug( "free_pass_peek_debug", "0" ); + +BEGIN_SIMPLE_DATADESC( AI_FreePassParams_t ) + + DEFINE_KEYFIELD( timeToTrigger, FIELD_FLOAT, "freepass_timetotrigger"), + DEFINE_KEYFIELD( duration, FIELD_FLOAT, "freepass_duration"), + DEFINE_KEYFIELD( moveTolerance, FIELD_FLOAT, "freepass_movetolerance"), + DEFINE_KEYFIELD( refillRate, FIELD_FLOAT, "freepass_refillrate"), + DEFINE_FIELD( coverDist, FIELD_FLOAT), + DEFINE_KEYFIELD( peekTime, FIELD_FLOAT, "freepass_peektime"), + DEFINE_FIELD( peekTimeAfterDamage, FIELD_FLOAT), + DEFINE_FIELD( peekEyeDist, FIELD_FLOAT), + DEFINE_FIELD( peekEyeDistZ, FIELD_FLOAT), + +END_DATADESC() + +BEGIN_SIMPLE_DATADESC( CAI_FreePass ) + + DEFINE_FIELD( m_hTarget, FIELD_EHANDLE ), + DEFINE_FIELD( m_FreePassTimeRemaining, FIELD_FLOAT ), + DEFINE_EMBEDDED( m_FreePassMoveMonitor ), + DEFINE_EMBEDDED( m_Params ), + +END_DATADESC() + +//--------------------------------------------------------- +//--------------------------------------------------------- + +void CAI_FreePass::Reset( float passTime, float moveTolerance ) +{ + CBaseEntity *pTarget = GetPassTarget(); + + if ( !pTarget || m_Params.duration < 0.1 ) + return; + + if ( passTime == -1 ) + { + m_FreePassTimeRemaining = m_Params.duration; + } + else + { + m_FreePassTimeRemaining = passTime; + } + + if ( moveTolerance == -1 ) + { + m_FreePassMoveMonitor.SetMark( pTarget, m_Params.moveTolerance ); + } + else + { + m_FreePassMoveMonitor.SetMark( pTarget, moveTolerance ); + } +} + +//--------------------------------------------------------- +//--------------------------------------------------------- + +void CAI_FreePass::Update( ) +{ + CBaseEntity *pTarget = GetPassTarget(); + if ( !pTarget || m_Params.duration < 0.1 ) + return; + + //--------------------------------- + // + // Free pass logic + // + AI_EnemyInfo_t *pTargetInfo = GetOuter()->GetEnemies()->Find( pTarget ); + + // This works with old data because need to do before base class so as to not choose as enemy + if ( !HasPass() ) + { + float timePlayerLastSeen = (pTargetInfo) ? pTargetInfo->timeLastSeen : AI_INVALID_TIME; + float lastTimeDamagedBy = (pTargetInfo) ? pTargetInfo->timeLastReceivedDamageFrom : AI_INVALID_TIME; + + if ( timePlayerLastSeen == AI_INVALID_TIME || gpGlobals->curtime - timePlayerLastSeen > .15 ) // If didn't see the player last think + { + trace_t tr; + UTIL_TraceLine( pTarget->EyePosition(), GetOuter()->EyePosition(), MASK_BLOCKLOS, GetOuter(), COLLISION_GROUP_NONE, &tr ); + if ( tr.fraction != 1.0 && tr.m_pEnt != pTarget ) + { + float dist = (tr.endpos - tr.startpos).Length() * tr.fraction; + + if ( dist < m_Params.coverDist ) + { + if ( ( timePlayerLastSeen == AI_INVALID_TIME || gpGlobals->curtime - timePlayerLastSeen > m_Params.timeToTrigger ) && + ( lastTimeDamagedBy == AI_INVALID_TIME || gpGlobals->curtime - lastTimeDamagedBy > m_Params.timeToTrigger ) ) + { + m_FreePassTimeRemaining = m_Params.duration; + m_FreePassMoveMonitor.SetMark( pTarget, m_Params.moveTolerance ); + } + } + } + } + } + else + { + float temp = m_FreePassTimeRemaining; + m_FreePassTimeRemaining = 0; + CAI_Senses *pSenses = GetOuter()->GetSenses(); + bool bCanSee = ( pSenses && pSenses->ShouldSeeEntity( pTarget ) && pSenses->CanSeeEntity( pTarget ) ); + m_FreePassTimeRemaining = temp; + + if ( bCanSee ) + { + if ( !m_FreePassMoveMonitor.TargetMoved( pTarget ) ) + m_FreePassTimeRemaining -= 0.1; + else + Revoke( true ); + } + else + { + m_FreePassTimeRemaining += 0.1 * m_Params.refillRate; + if ( m_FreePassTimeRemaining > m_Params.duration ) + m_FreePassTimeRemaining = m_Params.duration; + m_FreePassMoveMonitor.SetMark( pTarget, m_Params.moveTolerance ); + } + } +} + +//--------------------------------------------------------- +//--------------------------------------------------------- +bool CAI_FreePass::HasPass() +{ + return ( m_FreePassTimeRemaining > 0 ); +} + +//--------------------------------------------------------- +//--------------------------------------------------------- +void CAI_FreePass::Revoke( bool bUpdateMemory ) +{ + m_FreePassTimeRemaining = 0; + if ( bUpdateMemory && GetPassTarget() ) + { + GetOuter()->UpdateEnemyMemory( GetPassTarget(), GetPassTarget()->GetAbsOrigin() ); + } +} + +//--------------------------------------------------------- +//--------------------------------------------------------- +bool CAI_FreePass::ShouldAllowFVisible(bool bBaseResult ) +{ + CBaseEntity * pTarget = GetPassTarget(); + AI_EnemyInfo_t *pTargetInfo = GetOuter()->GetEnemies()->Find( pTarget ); + + if ( !bBaseResult || HasPass() ) + return false; + + bool bIsVisible = true; + + // Peek logic + if ( m_Params.peekTime > 0.1 ) + { + float lastTimeSeen = (pTargetInfo) ? pTargetInfo->timeLastSeen : AI_INVALID_TIME; + float lastTimeDamagedBy = (pTargetInfo) ? pTargetInfo->timeLastReceivedDamageFrom : AI_INVALID_TIME; + + if ( ( lastTimeSeen == AI_INVALID_TIME || gpGlobals->curtime - lastTimeSeen > m_Params.peekTime ) && + ( lastTimeDamagedBy == AI_INVALID_TIME || gpGlobals->curtime - lastTimeDamagedBy > m_Params.peekTimeAfterDamage ) ) + { + Vector vToTarget; + + VectorSubtract( pTarget->EyePosition(), GetOuter()->EyePosition(), vToTarget ); + vToTarget.z = 0.0f; + VectorNormalize( vToTarget ); + + Vector vecRight( -vToTarget.y, vToTarget.x, 0.0f ); + trace_t tr; + + UTIL_TraceLine( GetOuter()->EyePosition(), pTarget->EyePosition() + (vecRight * m_Params.peekEyeDist - Vector( 0, 0, m_Params.peekEyeDistZ )), MASK_BLOCKLOS, GetOuter(), COLLISION_GROUP_NONE, &tr ); + if ( tr.fraction != 1.0 && tr.m_pEnt != pTarget ) + { + if ( free_pass_peek_debug.GetBool() ) + NDebugOverlay::Line( tr.startpos, tr.endpos - Vector( 0, 0, 2), 0, 255, 0, false, 0.1 ); + bIsVisible = false; + } + + if ( bIsVisible ) + { + UTIL_TraceLine( GetOuter()->EyePosition(), pTarget->EyePosition() + (-vecRight * m_Params.peekEyeDist - Vector( 0, 0, m_Params.peekEyeDistZ )), MASK_BLOCKLOS, GetOuter(), COLLISION_GROUP_NONE, &tr ); + if ( tr.fraction != 1.0 && tr.m_pEnt != pTarget ) + { + if ( free_pass_peek_debug.GetBool() ) + NDebugOverlay::Line( tr.startpos, tr.endpos - Vector( 0, 0, 2), 0, 255, 0, false, 0.1 ); + bIsVisible = false; + } + } + } + + if ( bIsVisible && free_pass_peek_debug.GetBool() ) + NDebugOverlay::Line( GetOuter()->EyePosition(), pTarget->EyePosition() - Vector( 0, 0, 2), 255, 0, 0, false, 0.1 ); + } + + return bIsVisible; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +string_t g_iszFuncBrushClassname = NULL_STRING; + +//----------------------------------------------------------------------------- +CTraceFilterNav::CTraceFilterNav( CAI_BaseNPC *pProber, bool bIgnoreTransientEntities, const IServerEntity *passedict, int collisionGroup, bool bAllowPlayerAvoid ) : + CTraceFilterSimple( passedict, collisionGroup ), + m_pProber(pProber), + m_bIgnoreTransientEntities(bIgnoreTransientEntities), + m_bAllowPlayerAvoid(bAllowPlayerAvoid) +{ + m_bCheckCollisionTable = g_EntityCollisionHash->IsObjectInHash( pProber ); +} + +//----------------------------------------------------------------------------- +bool CTraceFilterNav::ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask ) +{ + IServerEntity *pServerEntity = (IServerEntity*)pHandleEntity; + CBaseEntity *pEntity = (CBaseEntity *)pServerEntity; + + if ( m_pProber == pEntity ) + return false; + + if ( m_pProber->GetMoveProbe()->ShouldBrushBeIgnored( pEntity ) == true ) + return false; + +#ifdef HL1_DLL + if ( ( contentsMask & CONTENTS_MOVEABLE ) == 0 ) + { + if ( pEntity->ClassMatches( "func_pushable" ) ) + return false; + } +#endif + + if ( m_bIgnoreTransientEntities && (pEntity->IsPlayer() || pEntity->IsNPC() ) ) + return false; + + //Adrian - If I'm flagged as using the new collision method, then ignore the player when trying + //to check if I can get somewhere. + if ( m_bAllowPlayerAvoid && m_pProber->ShouldPlayerAvoid() && pEntity->IsPlayer() ) + return false; + + if ( pEntity->IsNavIgnored() ) + return false; + + if ( m_bCheckCollisionTable ) + { + if ( g_EntityCollisionHash->IsObjectPairInHash( m_pProber, pEntity ) ) + return false; + } + + if ( m_pProber->ShouldProbeCollideAgainstEntity( pEntity ) == false ) + return false; + + return CTraceFilterSimple::ShouldHitEntity( pHandleEntity, contentsMask ); +} -- cgit v1.2.3