Skip to content

Commit 991ec0f

Browse files
committed
Improve asw_buzzer AI
- Changed buzzer to sense marines using a sphere instead of using player's camera frustum. This allows to wake up buzzers that for some reason flew above player's camera frustum. Before this change many buzzers could get into infinite sleep while being relatively close to marines. - Increased the range buzzer can detect marines and wake up to 1024 units. Before this buzzers would easily loose marines out of their sight and get into forever sleep state. - Improved the "Spread then hibernate" order (although it still works not perfectly). Now buzzers instead of instantly sleeping move to some random position nearby the spawner and wait for player to see them. - Improved "Move to Nearest Marine" order. Now buzzer similary to other aliens updates nearest marine position periodically and moves to that position. Before this change buzzer would move to a position where marine was when the order would issued, and if marine was not in that position buzzer would enter sleep state. - Improved other orders: "Move to", "Move to Ignoring Marines". "Move to Ignoring Marines" still needs work as buzzers after arival do not retarget to marines (they still ignore them). Moved code of functions MarineCanSee() and MarineNearby() into asw_inhabitable_npc to reduce code duplication.
1 parent 5d374d1 commit 991ec0f

6 files changed

Lines changed: 79 additions & 95 deletions

File tree

src/game/server/swarm/asw_alien.cpp

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,6 @@ CASW_Alien::CASW_Alien( void ) :
142142
m_fLastSleepCheckTime = 0;
143143
m_bVisibleWhenAsleep = false;
144144

145-
m_fLastMarineCanSeeTime = -100;
146-
m_bLastMarineCanSee = false;
147145
m_bTimeToRagdoll = false;
148146
m_iDeadBodyGroup = 1;
149147
m_bNeverRagdoll = false;
@@ -562,34 +560,6 @@ void CASW_Alien::NPCThink( void )
562560
m_flLastThinkTime = gpGlobals->curtime;
563561
}
564562

565-
bool CASW_Alien::MarineNearby(float radius, bool bCheck3D)
566-
{
567-
// find the closest marine
568-
CASW_Game_Resource *pGameResource = ASWGameResource();
569-
if (!pGameResource)
570-
return false;
571-
572-
for (int i=0;i<pGameResource->GetMaxMarineResources();i++)
573-
{
574-
CASW_Marine_Resource* pMarineResource = pGameResource->GetMarineResource(i);
575-
if (!pMarineResource)
576-
continue;
577-
578-
CASW_Marine* pMarine = pMarineResource->GetMarineEntity();
579-
if (!pMarine || pMarine->m_bKnockedOut)
580-
continue;
581-
582-
Vector diff = pMarine->GetAbsOrigin() - GetAbsOrigin();
583-
float dist = bCheck3D ? diff.Length() : diff.Length2D();
584-
585-
if (dist < radius)
586-
{
587-
return true;
588-
}
589-
}
590-
return false;
591-
}
592-
593563
CBaseEntity *CASW_Alien::CheckTraceHullAttack( float flDist, const Vector &mins, const Vector &maxs, float flDamage, int iDmgType, float forceScale, bool bDamageAnyNPC )
594564
{
595565
// If only a length is given assume we want to trace in our facing direction
@@ -2348,19 +2318,6 @@ void CASW_Alien::UpdateEfficiency( bool bInPVS )
23482318
SetEfficiency( ( bFramerateOk ) ? AIE_EFFICIENT : AIE_VERY_EFFICIENT );
23492319
}
23502320

2351-
// checks if a marine can see us
2352-
// caches the results and won't recheck unless the specified interval has passed since the last check
2353-
bool CASW_Alien::MarineCanSee(int padding, float interval)
2354-
{
2355-
if (gpGlobals->curtime >= m_fLastMarineCanSeeTime + interval)
2356-
{
2357-
bool bCorpseCanSee = false;
2358-
m_bLastMarineCanSee = (UTIL_ASW_AnyMarineCanSee(GetAbsOrigin(), padding, bCorpseCanSee) != NULL) || bCorpseCanSee;
2359-
m_fLastMarineCanSeeTime = gpGlobals->curtime;
2360-
}
2361-
return m_bLastMarineCanSee;
2362-
}
2363-
23642321
void CASW_Alien::DropMoney( const CTakeDamageInfo &info )
23652322
{
23662323
if ( !asw_drop_money.GetBool() || !asw_money.GetBool() )

src/game/server/swarm/asw_alien.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ class CASW_Alien : public CASW_Inhabitable_NPC, public IAlienAutoList
7979
CASW_AI_Senses *GetASWSenses();
8080
virtual bool QuerySeeEntity( CBaseEntity *pEntity, bool bOnlyHateOrFearIfNPC );
8181
void SetDistSwarmSense( float flDistSense );
82-
bool MarineNearby( float radius, bool bCheck3D = false );
8382
bool FInViewCone( const Vector &vecSpot );
8483
bool Knockback( Vector vecForce );
8584
virtual void SetDefaultEyeOffset();
@@ -235,11 +234,6 @@ class CASW_Alien : public CASW_Inhabitable_NPC, public IAlienAutoList
235234
string_t m_iMoveCloneName;
236235
matrix3x4_t m_moveCloneOffset;
237236

238-
// can a marine see us?
239-
bool MarineCanSee( int padding, float interval );
240-
float m_fLastMarineCanSeeTime;
241-
bool m_bLastMarineCanSee;
242-
243237
int m_iNumASWOrderRetries;
244238

245239
// notification that an alien we spawned has been killed (used by Harvesters/Queens, which spawn new aliens as part of their attacks)

src/game/server/swarm/asw_buzzer.cpp

Lines changed: 27 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
#define ASW_BUZZER_CHARGE_MIN_DIST 200
8383

8484
#define ASW_BUZZER_SLEEP_CHECK_INTERVAL 1.0f
85-
#define ASW_BUZZER_PVS_CHECK_RANGE 384.0f
85+
#define ASW_BUZZER_PVS_CHECK_RANGE 1024.0f
8686

8787
ConVar sk_asw_buzzer_health( "sk_asw_buzzer_health","30", FCVAR_CHEAT, "Health of the buzzer");
8888
ConVar sk_asw_buzzer_melee_dmg( "sk_asw_buzzer_melee_dmg","15", FCVAR_CHEAT, "Damage caused by buzzer");
@@ -2224,7 +2224,7 @@ void CASW_Buzzer::NPCInit()
22242224

22252225
CASW_GameStats.Event_AlienSpawned( this );
22262226

2227-
SetDistSwarmSense(576.0f);
2227+
//SetDistSwarmSense(576.0f); // is this necessary? commented for now
22282228
}
22292229

22302230
void CASW_Buzzer::NPCThink( void )
@@ -2378,20 +2378,15 @@ void CASW_Buzzer::StartTask( const Task_t *pTask )
23782378
if (pTask->flTaskData <= 0) // check the taskdata to see if we should do a short spread movement when failing to build a path
23792379
{
23802380
// random nearby position
2381-
if ( GetNavigator()->SetWanderGoal( 90, 200 ) )
2381+
Vector dir( RandomFloat( -1, 1 ), RandomFloat( -1, 1 ), 0 );
2382+
Vector vecGoal( GetAbsOrigin() + dir * RandomFloat( 50, 150 ) );
2383+
AI_NavGoal_t goal( vecGoal );
2384+
if ( GetNavigator()->SetGoal( goal ) )
23822385
{
23832386
TaskComplete();
23842387
}
23852388
else
2386-
{
2387-
// if we couldn't go for a full path
2388-
if ( GetNavigator()->SetRandomGoal( 150.0f ) )
2389-
{
2390-
TaskComplete();
2391-
}
2392-
else
2393-
TaskFail(FAIL_NO_ROUTE);
2394-
}
2389+
TaskFail(FAIL_NO_ROUTE);
23952390
}
23962391
else
23972392
{
@@ -3114,19 +3109,6 @@ int CASW_Buzzer::GetBaseHealth()
31143109
return sk_asw_buzzer_health.GetFloat();
31153110
}
31163111

3117-
// checks if a marine can see us
3118-
// caches the results and won't recheck unless the specified interval has passed since the last check
3119-
bool CASW_Buzzer::MarineCanSee(int padding, float interval)
3120-
{
3121-
if (gpGlobals->curtime >= m_fLastMarineCanSeeTime + interval)
3122-
{
3123-
bool bCorpseCanSee = false;
3124-
m_bLastMarineCanSee = (UTIL_ASW_AnyMarineCanSee(GetAbsOrigin(), padding, bCorpseCanSee) != NULL) || bCorpseCanSee;
3125-
m_fLastMarineCanSeeTime = gpGlobals->curtime;
3126-
}
3127-
return m_bLastMarineCanSee;
3128-
}
3129-
31303112
// wake the buzzer up when a marine gets nearby
31313113
void CASW_Buzzer::UpdateSleepState(bool bInPVS)
31323114
{
@@ -3141,12 +3123,6 @@ void CASW_Buzzer::UpdateSleepState(bool bInPVS)
31413123
VPhysicsGetObject()->Wake();
31423124
}
31433125

3144-
bInPVS = MarineCanSee(ASW_BUZZER_PVS_CHECK_RANGE, 0.1f);
3145-
if (bInPVS)
3146-
SetCondition(COND_IN_PVS);
3147-
else
3148-
ClearCondition(COND_IN_PVS);
3149-
31503126
if ( GetSleepState() != AISS_WAITING_FOR_INPUT )
31513127
{
31523128
if (bInPVS)
@@ -3171,8 +3147,8 @@ void CASW_Buzzer::UpdateSleepState(bool bInPVS)
31713147
{
31723148
if (m_fLastSleepCheckTime < gpGlobals->curtime + ASW_BUZZER_SLEEP_CHECK_INTERVAL)
31733149
{
3174-
//if (!GetEnemy() && !MarineNearby(1024.0f) )
3175-
if (!GetEnemy() && !MarineCanSee(ASW_BUZZER_PVS_CHECK_RANGE, 2.0f))
3150+
//if (!GetEnemy() && !MarineCanSee(ASW_BUZZER_PVS_CHECK_RANGE, 2.0f))
3151+
if (!GetEnemy() && !MarineNearby( ASW_BUZZER_PVS_CHECK_RANGE ) )
31763152
{
31773153
SetSleepState(AISS_WAITING_FOR_PVS);
31783154

@@ -3232,8 +3208,8 @@ void CASW_Buzzer::UpdateEfficiency(bool bInPVS)
32323208

32333209
bool bInVisibilityPVS = (UTIL_FindClientInVisibilityPVS(edict()) != NULL);
32343210

3235-
//if ( bInPVS && MarineNearby(1024) )
3236-
if (bInPVS && MarineCanSee(ASW_BUZZER_PVS_CHECK_RANGE, 1.0f))
3211+
if ( bInPVS && MarineNearby( ASW_BUZZER_PVS_CHECK_RANGE ) )
3212+
//if (bInPVS && MarineCanSee(ASW_BUZZER_PVS_CHECK_RANGE, 1.0f))
32373213
{
32383214
SetMoveEfficiency(AIME_NORMAL);
32393215
}
@@ -3275,6 +3251,18 @@ void CASW_Buzzer::UpdateEfficiency(bool bInPVS)
32753251
SetEfficiency((bFramerateOk) ? AIE_EFFICIENT : AIE_VERY_EFFICIENT);
32763252
}
32773253

3254+
bool CASW_Buzzer::CheckPVSCondition()
3255+
{
3256+
bool bInPVS = MarineNearby( ASW_BUZZER_PVS_CHECK_RANGE );
3257+
3258+
if ( bInPVS )
3259+
SetCondition( COND_IN_PVS );
3260+
else
3261+
ClearCondition( COND_IN_PVS );
3262+
3263+
return bInPVS;
3264+
}
3265+
32783266
void CASW_Buzzer::UpdateOnRemove()
32793267
{
32803268
if (m_bRegisteredAsAwake)
@@ -3296,7 +3284,7 @@ AI_BEGIN_CUSTOM_NPC( npc_buzzer, CASW_Buzzer )
32963284
DECLARE_TASK( TASK_ASW_BUZZER_FIND_SQUAD_CENTER );
32973285
DECLARE_TASK( TASK_ASW_BUZZER_FIND_SQUAD_MEMBER );
32983286
DECLARE_TASK( TASK_ASW_BUZZER_MOVEAT_SAVEPOSITION );
3299-
DECLARE_TASK(TASK_ASW_BUZZER_BUILD_PATH_TO_ORDER);
3287+
DECLARE_TASK( TASK_ASW_BUZZER_BUILD_PATH_TO_ORDER );
33003288

33013289
DECLARE_CONDITION( COND_ASW_BUZZER_START_ATTACK );
33023290

@@ -3413,11 +3401,10 @@ DEFINE_SCHEDULE
34133401

34143402
" Tasks"
34153403
" TASK_SET_FAIL_SCHEDULE SCHEDULE:SCHED_ASW_BUZZER_SWARM_FAILURE" // this allows to clear orders and go to Sleep() if we cannot find route
3416-
" TASK_ASW_BUZZER_BUILD_PATH_TO_ORDER 1" // setting 1 here sets flTaskData and prevents buzzer from wandering under the map from one skybox wall to another
3417-
" TASK_WALK_PATH 9999"
3404+
" TASK_ASW_BUZZER_BUILD_PATH_TO_ORDER 0" // setting 1 here sets flTaskData and prevents buzzer from wandering under the map from one skybox wall to another
3405+
" TASK_RUN_PATH 0"
34183406
" TASK_WAIT_FOR_MOVEMENT 0" // 0 is spread if fail to build path
3419-
" TASK_WAIT_PVS 0"
3420-
""
3407+
" "
34213408
" Interrupts"
34223409
" COND_NEW_ENEMY"
34233410
" COND_SEE_ENEMY" // in deference to scripted schedule where the enemy was slammed, thus no COND_NEW_ENEMY
@@ -3430,5 +3417,3 @@ DEFINE_SCHEDULE
34303417
)
34313418

34323419
AI_END_CUSTOM_NPC()
3433-
3434-

src/game/server/swarm/asw_buzzer.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,16 +190,13 @@ DECLARE_SERVERCLASS();
190190
virtual void NPCThink();
191191
void ReachedEndOfSequence();
192192

193-
//stuff related to sleep state
194-
bool MarineCanSee(int padding, float interval);// can a marine see us? //copy from asw_alien
195-
float m_fLastMarineCanSeeTime;
196-
bool m_bLastMarineCanSee;
197193
bool m_bRegisteredAsAwake;
198194
float m_fLastSleepCheckTime;
199195
bool m_bVisibleWhenAsleep;
200196
virtual void UpdateSleepState(bool bInPVS);
201197
void UpdateEfficiency(bool bInPVS);
202198
virtual void UpdateOnRemove();
199+
virtual bool CheckPVSCondition() override;
203200
private:
204201

205202
bool IsInEffectiveTargetZone( CBaseEntity *pTarget );

src/game/server/swarm/asw_inhabitable_npc.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "asw_physics_prop_statue.h"
1414
#include "asw_util_shared.h"
1515
#include "ilagcompensationmanager.h"
16+
#include "asw_marine_resource.h"
1617

1718
// memdbgon must be the last include file in a .cpp file!!!
1819
#include "tier0/memdbgon.h"
@@ -159,6 +160,9 @@ CASW_Inhabitable_NPC::CASW_Inhabitable_NPC()
159160
m_nOldButtons = 0;
160161
m_iControlsOverride = -1;
161162

163+
m_fLastMarineCanSeeTime = -100;
164+
m_bLastMarineCanSee = false;
165+
162166
m_bWasOnFireForStats = false;
163167
m_bFlammable = true;
164168
m_bTeslable = true;
@@ -295,6 +299,47 @@ int CASW_Inhabitable_NPC::DrawDebugTextOverlays()
295299
return text_offset;
296300
}
297301

302+
bool CASW_Inhabitable_NPC::MarineNearby( float radius, bool bCheck3D )
303+
{
304+
// find the closest marine
305+
CASW_Game_Resource* pGameResource = ASWGameResource();
306+
if ( !pGameResource )
307+
return false;
308+
309+
for ( int i = 0; i < pGameResource->GetMaxMarineResources(); i++ )
310+
{
311+
CASW_Marine_Resource* pMarineResource = pGameResource->GetMarineResource( i );
312+
if ( !pMarineResource )
313+
continue;
314+
315+
CASW_Marine* pMarine = pMarineResource->GetMarineEntity();
316+
if ( !pMarine || pMarine->m_bKnockedOut )
317+
continue;
318+
319+
Vector diff = pMarine->GetAbsOrigin() - GetAbsOrigin();
320+
float dist = bCheck3D ? diff.Length() : diff.Length2D();
321+
322+
if ( dist < radius )
323+
{
324+
return true;
325+
}
326+
}
327+
return false;
328+
}
329+
330+
// checks if a marine can see us
331+
// caches the results and won't recheck unless the specified interval has passed since the last check
332+
bool CASW_Inhabitable_NPC::MarineCanSee( int padding, float interval )
333+
{
334+
if ( gpGlobals->curtime >= m_fLastMarineCanSeeTime + interval )
335+
{
336+
bool bCorpseCanSee = false;
337+
m_bLastMarineCanSee = ( UTIL_ASW_AnyMarineCanSee( GetAbsOrigin(), padding, bCorpseCanSee ) != NULL ) || bCorpseCanSee;
338+
m_fLastMarineCanSeeTime = gpGlobals->curtime;
339+
}
340+
return m_bLastMarineCanSee;
341+
}
342+
298343
// sets which player commands this marine
299344
void CASW_Inhabitable_NPC::SetCommander( CASW_Player *player )
300345
{

src/game/server/swarm/asw_inhabitable_npc.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ class CASW_Inhabitable_NPC : public CAI_PlayerAlly, public IASW_Spawnable_NPC
3535
virtual void UpdateOnRemove() override;
3636
virtual int DrawDebugTextOverlays() override;
3737

38+
// util
39+
bool MarineNearby( float radius, bool bCheck3D = false );
40+
bool MarineCanSee( int padding, float interval ); // can a marine see us?
41+
float m_fLastMarineCanSeeTime;
42+
bool m_bLastMarineCanSee;
43+
3844
// player control
3945
void SetCommander( CASW_Player *player );
4046
CASW_Player *GetCommander() const;

0 commit comments

Comments
 (0)