|
|
|
|
@@ -91,6 +91,7 @@ template <class BASE_NPC>
|
|
|
|
|
class CAI_GrenadeUser : public BASE_NPC, public CAI_GrenadeUserSink
|
|
|
|
|
{
|
|
|
|
|
DECLARE_CLASS_NOFRIEND( CAI_GrenadeUser, BASE_NPC );
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
CAI_GrenadeUser() : CAI_GrenadeUserSink() { }
|
|
|
|
|
|
|
|
|
|
@@ -162,8 +163,8 @@ void CAI_GrenadeUser<BASE_NPC>::HandleAnimEvent( animevent_t *pEvent )
|
|
|
|
|
{
|
|
|
|
|
if ( pEvent->event == COMBINE_AE_BEGIN_ALTFIRE )
|
|
|
|
|
{
|
|
|
|
|
if (GetActiveWeapon())
|
|
|
|
|
GetActiveWeapon()->WeaponSound( SPECIAL1 );
|
|
|
|
|
if (this->GetActiveWeapon())
|
|
|
|
|
this->GetActiveWeapon()->WeaponSound( SPECIAL1 );
|
|
|
|
|
|
|
|
|
|
//SpeakIfAllowed( TLK_CMB_THROWGRENADE, "altfire:1" );
|
|
|
|
|
return;
|
|
|
|
|
@@ -176,8 +177,8 @@ void CAI_GrenadeUser<BASE_NPC>::HandleAnimEvent( animevent_t *pEvent )
|
|
|
|
|
fakeEvent.event = EVENT_WEAPON_AR2_ALTFIRE;
|
|
|
|
|
|
|
|
|
|
// Weapon could've been dropped while playing animation
|
|
|
|
|
if (GetActiveWeapon())
|
|
|
|
|
GetActiveWeapon()->Operator_HandleAnimEvent( &fakeEvent, this );
|
|
|
|
|
if (this->GetActiveWeapon())
|
|
|
|
|
this->GetActiveWeapon()->Operator_HandleAnimEvent( &fakeEvent, this );
|
|
|
|
|
|
|
|
|
|
// Stop other squad members from combine balling for a while.
|
|
|
|
|
DelaySquadAltFireAttack( 10.0f );
|
|
|
|
|
@@ -195,25 +196,25 @@ void CAI_GrenadeUser<BASE_NPC>::HandleAnimEvent( animevent_t *pEvent )
|
|
|
|
|
vecSpin.z = random->RandomFloat( -1000.0, 1000.0 );
|
|
|
|
|
|
|
|
|
|
Vector vecStart;
|
|
|
|
|
GetAttachment( GetGrenadeAttachment(), vecStart );
|
|
|
|
|
this->GetAttachment( GetGrenadeAttachment(), vecStart );
|
|
|
|
|
|
|
|
|
|
if( m_NPCState == NPC_STATE_SCRIPT )
|
|
|
|
|
if( this->GetState() == NPC_STATE_SCRIPT )
|
|
|
|
|
{
|
|
|
|
|
// Use a fixed velocity for grenades thrown in scripted state.
|
|
|
|
|
// Grenades thrown from a script do not count against grenades remaining for the AI to use.
|
|
|
|
|
Vector forward, up, vecThrow;
|
|
|
|
|
|
|
|
|
|
GetVectors( &forward, NULL, &up );
|
|
|
|
|
this->GetVectors( &forward, NULL, &up );
|
|
|
|
|
vecThrow = forward * 750 + up * 175;
|
|
|
|
|
|
|
|
|
|
// This code is used by player allies now, so it's only "combine spawned" if the thrower isn't allied with the player.
|
|
|
|
|
CBaseEntity *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, vecThrow, vecSpin, this, COMBINE_GRENADE_TIMER, !IsPlayerAlly() );
|
|
|
|
|
CBaseEntity *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, vecThrow, vecSpin, this, COMBINE_GRENADE_TIMER, !this->IsPlayerAlly() );
|
|
|
|
|
m_OnThrowGrenade.Set(pGrenade, pGrenade, this);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Use the Velocity that AI gave us.
|
|
|
|
|
CBaseEntity *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, m_vecTossVelocity, vecSpin, this, COMBINE_GRENADE_TIMER, !IsPlayerAlly() );
|
|
|
|
|
CBaseEntity *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, m_vecTossVelocity, vecSpin, this, COMBINE_GRENADE_TIMER, !this->IsPlayerAlly() );
|
|
|
|
|
m_OnThrowGrenade.Set(pGrenade, pGrenade, this);
|
|
|
|
|
AddGrenades(-1, pGrenade);
|
|
|
|
|
}
|
|
|
|
|
@@ -235,20 +236,20 @@ template <class BASE_NPC>
|
|
|
|
|
void CAI_GrenadeUser<BASE_NPC>::InputThrowGrenadeAtTarget( inputdata_t &inputdata )
|
|
|
|
|
{
|
|
|
|
|
// Ignore if we're inside a scripted sequence
|
|
|
|
|
if ( m_NPCState == NPC_STATE_SCRIPT && m_hCine )
|
|
|
|
|
if ( this->GetState() == NPC_STATE_SCRIPT && this->m_hCine )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller );
|
|
|
|
|
if ( !pEntity )
|
|
|
|
|
{
|
|
|
|
|
DevMsg("%s (%s) received ThrowGrenadeAtTarget input, but couldn't find target entity '%s'\n", GetClassname(), GetDebugName(), inputdata.value.String() );
|
|
|
|
|
DevMsg("%s (%s) received ThrowGrenadeAtTarget input, but couldn't find target entity '%s'\n", this->GetClassname(), this->GetDebugName(), inputdata.value.String() );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_hForcedGrenadeTarget = pEntity;
|
|
|
|
|
m_flNextGrenadeCheck = 0;
|
|
|
|
|
|
|
|
|
|
ClearSchedule( "Told to throw grenade via input" );
|
|
|
|
|
this->ClearSchedule( "Told to throw grenade via input" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
@@ -262,33 +263,33 @@ bool CAI_GrenadeUser<BASE_NPC>::CanAltFireEnemy( bool bUseFreeKnowledge )
|
|
|
|
|
if (!IsAltFireCapable())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!GetActiveWeapon())
|
|
|
|
|
if (!this->GetActiveWeapon())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (IsCrouching())
|
|
|
|
|
if (this->IsCrouching())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if ( gpGlobals->curtime < m_flNextAltFireTime || gpGlobals->curtime < m_flNextGrenadeCheck )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if( !GetEnemy() )
|
|
|
|
|
if( !this->GetEnemy() )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!EntIsClass(GetActiveWeapon(), gm_isz_class_AR2) && !EntIsClass(GetActiveWeapon(), gm_isz_class_SMG1))
|
|
|
|
|
if (!EntIsClass(this->GetActiveWeapon(), gm_isz_class_AR2) && !EntIsClass(this->GetActiveWeapon(), gm_isz_class_SMG1))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
CBaseEntity *pEnemy = GetEnemy();
|
|
|
|
|
CBaseEntity *pEnemy = this->GetEnemy();
|
|
|
|
|
|
|
|
|
|
Vector vecTarget;
|
|
|
|
|
|
|
|
|
|
// Determine what point we're shooting at
|
|
|
|
|
if( bUseFreeKnowledge )
|
|
|
|
|
{
|
|
|
|
|
vecTarget = GetEnemies()->LastKnownPosition( pEnemy ) + (pEnemy->GetViewOffset()*0.75);// approximates the chest
|
|
|
|
|
vecTarget = this->GetEnemies()->LastKnownPosition( pEnemy ) + (pEnemy->GetViewOffset()*0.75);// approximates the chest
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
vecTarget = GetEnemies()->LastSeenPosition( pEnemy ) + (pEnemy->GetViewOffset()*0.75);// approximates the chest
|
|
|
|
|
vecTarget = this->GetEnemies()->LastSeenPosition( pEnemy ) + (pEnemy->GetViewOffset()*0.75);// approximates the chest
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Trace a hull about the size of the combine ball (don't shoot through grates!)
|
|
|
|
|
@@ -297,11 +298,11 @@ bool CAI_GrenadeUser<BASE_NPC>::CanAltFireEnemy( bool bUseFreeKnowledge )
|
|
|
|
|
Vector mins( -12, -12, -12 );
|
|
|
|
|
Vector maxs( 12, 12, 12 );
|
|
|
|
|
|
|
|
|
|
Vector vShootPosition = EyePosition();
|
|
|
|
|
Vector vShootPosition = this->EyePosition();
|
|
|
|
|
|
|
|
|
|
if ( GetActiveWeapon() )
|
|
|
|
|
if ( this->GetActiveWeapon() )
|
|
|
|
|
{
|
|
|
|
|
GetActiveWeapon()->GetAttachment( "muzzle", vShootPosition );
|
|
|
|
|
this->GetActiveWeapon()->GetAttachment( "muzzle", vShootPosition );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Trace a hull about the size of the combine ball.
|
|
|
|
|
@@ -350,7 +351,8 @@ void CAI_GrenadeUser<BASE_NPC>::DelaySquadAltFireAttack( float flDelay )
|
|
|
|
|
DelayAltFireAttack( flDelay );
|
|
|
|
|
|
|
|
|
|
AISquadIter_t iter;
|
|
|
|
|
CAI_BaseNPC *pSquadmate = m_pSquad ? m_pSquad->GetFirstMember( &iter ) : NULL;
|
|
|
|
|
CAI_Squad *pSquad = this->GetSquad();
|
|
|
|
|
CAI_BaseNPC *pSquadmate = pSquad ? pSquad->GetFirstMember( &iter ) : NULL;
|
|
|
|
|
while ( pSquadmate )
|
|
|
|
|
{
|
|
|
|
|
CAI_GrenadeUser *pUser = dynamic_cast<CAI_GrenadeUser*>(pSquadmate);
|
|
|
|
|
@@ -359,7 +361,7 @@ void CAI_GrenadeUser<BASE_NPC>::DelaySquadAltFireAttack( float flDelay )
|
|
|
|
|
pUser->DelayAltFireAttack( flDelay );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pSquadmate = m_pSquad->GetNextMember( &iter );
|
|
|
|
|
pSquadmate = pSquad->GetNextMember( &iter );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -368,25 +370,25 @@ void CAI_GrenadeUser<BASE_NPC>::DelaySquadAltFireAttack( float flDelay )
|
|
|
|
|
template <class BASE_NPC>
|
|
|
|
|
bool CAI_GrenadeUser<BASE_NPC>::CanGrenadeEnemy( bool bUseFreeKnowledge )
|
|
|
|
|
{
|
|
|
|
|
CBaseEntity *pEnemy = GetEnemy();
|
|
|
|
|
CBaseEntity *pEnemy = this->GetEnemy();
|
|
|
|
|
|
|
|
|
|
Assert( pEnemy != NULL );
|
|
|
|
|
|
|
|
|
|
if( pEnemy )
|
|
|
|
|
{
|
|
|
|
|
// I'm not allowed to throw grenades during dustoff
|
|
|
|
|
if ( IsCurSchedule(SCHED_DROPSHIP_DUSTOFF) )
|
|
|
|
|
if ( this->IsCurSchedule(SCHED_DROPSHIP_DUSTOFF) )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if( bUseFreeKnowledge )
|
|
|
|
|
{
|
|
|
|
|
// throw to where we think they are.
|
|
|
|
|
return CanThrowGrenade( GetEnemies()->LastKnownPosition( pEnemy ) );
|
|
|
|
|
return CanThrowGrenade( this->GetEnemies()->LastKnownPosition( pEnemy ) );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// hafta throw to where we last saw them.
|
|
|
|
|
return CanThrowGrenade( GetEnemies()->LastSeenPosition( pEnemy ) );
|
|
|
|
|
return CanThrowGrenade( this->GetEnemies()->LastSeenPosition( pEnemy ) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -421,7 +423,7 @@ bool CAI_GrenadeUser<BASE_NPC>::CanThrowGrenade( const Vector &vecTarget )
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float flDist;
|
|
|
|
|
flDist = ( vecTarget - GetAbsOrigin() ).Length();
|
|
|
|
|
flDist = ( vecTarget - this->GetAbsOrigin() ).Length();
|
|
|
|
|
|
|
|
|
|
if( flDist > 1024 || flDist < 128 )
|
|
|
|
|
{
|
|
|
|
|
@@ -433,15 +435,16 @@ bool CAI_GrenadeUser<BASE_NPC>::CanThrowGrenade( const Vector &vecTarget )
|
|
|
|
|
// -----------------------
|
|
|
|
|
// If moving, don't check.
|
|
|
|
|
// -----------------------
|
|
|
|
|
if ( m_flGroundSpeed != 0 )
|
|
|
|
|
if ( this->m_flGroundSpeed != 0 )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
// Are any of my squad members near the intended grenade impact area?
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
if ( m_pSquad )
|
|
|
|
|
CAI_Squad *pSquad = this->GetSquad();
|
|
|
|
|
if ( pSquad )
|
|
|
|
|
{
|
|
|
|
|
if (m_pSquad->SquadMemberInRange( vecTarget, COMBINE_MIN_GRENADE_CLEAR_DIST ))
|
|
|
|
|
if (pSquad->SquadMemberInRange( vecTarget, COMBINE_MIN_GRENADE_CLEAR_DIST ))
|
|
|
|
|
{
|
|
|
|
|
// crap, I might blow my own guy up. Don't throw a grenade and don't check again for a while.
|
|
|
|
|
m_flNextGrenadeCheck = gpGlobals->curtime + 1; // one full second.
|
|
|
|
|
@@ -464,7 +467,7 @@ bool CAI_GrenadeUser<BASE_NPC>::CanThrowGrenade( const Vector &vecTarget )
|
|
|
|
|
template <class BASE_NPC>
|
|
|
|
|
bool CAI_GrenadeUser<BASE_NPC>::CheckCanThrowGrenade( const Vector &vecTarget )
|
|
|
|
|
{
|
|
|
|
|
//NDebugOverlay::Line( EyePosition(), vecTarget, 0, 255, 0, false, 5 );
|
|
|
|
|
//NDebugOverlay::Line( this->EyePosition(), vecTarget, 0, 255, 0, false, 5 );
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
// Check that throw is legal and clear
|
|
|
|
|
@@ -473,21 +476,21 @@ bool CAI_GrenadeUser<BASE_NPC>::CheckCanThrowGrenade( const Vector &vecTarget )
|
|
|
|
|
Vector vecToss;
|
|
|
|
|
Vector vecMins = -Vector(4,4,4);
|
|
|
|
|
Vector vecMaxs = Vector(4,4,4);
|
|
|
|
|
if( FInViewCone( vecTarget ) && CBaseEntity::FVisible( vecTarget ) )
|
|
|
|
|
if( this->FInViewCone( vecTarget ) && CBaseEntity::FVisible( vecTarget ) )
|
|
|
|
|
{
|
|
|
|
|
vecToss = VecCheckThrow( this, EyePosition(), vecTarget, COMBINE_GRENADE_THROW_SPEED, 1.0, &vecMins, &vecMaxs );
|
|
|
|
|
vecToss = VecCheckThrow( this, this->EyePosition(), vecTarget, COMBINE_GRENADE_THROW_SPEED, 1.0, &vecMins, &vecMaxs );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Have to try a high toss. Do I have enough room?
|
|
|
|
|
trace_t tr;
|
|
|
|
|
AI_TraceLine( EyePosition(), EyePosition() + Vector( 0, 0, 64 ), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
|
|
|
|
|
AI_TraceLine( this->EyePosition(), this->EyePosition() + Vector( 0, 0, 64 ), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
|
|
|
|
|
if( tr.fraction != 1.0 )
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vecToss = VecCheckToss( this, EyePosition(), vecTarget, -1, 1.0, true, &vecMins, &vecMaxs );
|
|
|
|
|
vecToss = VecCheckToss( this, this->EyePosition(), vecTarget, -1, 1.0, true, &vecMins, &vecMaxs );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( vecToss != vec3_origin )
|
|
|
|
|
@@ -518,7 +521,7 @@ bool CAI_GrenadeUser<BASE_NPC>::CheckCanThrowGrenade( const Vector &vecTarget )
|
|
|
|
|
template <class BASE_NPC>
|
|
|
|
|
void CAI_GrenadeUser<BASE_NPC>::ClearAttackConditions()
|
|
|
|
|
{
|
|
|
|
|
bool fCanRangeAttack2 = IsGrenadeCapable() && HasCondition( COND_CAN_RANGE_ATTACK2 );
|
|
|
|
|
bool fCanRangeAttack2 = IsGrenadeCapable() && this->HasCondition( COND_CAN_RANGE_ATTACK2 );
|
|
|
|
|
|
|
|
|
|
// Call the base class.
|
|
|
|
|
BaseClass::ClearAttackConditions();
|
|
|
|
|
@@ -527,7 +530,7 @@ void CAI_GrenadeUser<BASE_NPC>::ClearAttackConditions()
|
|
|
|
|
{
|
|
|
|
|
// We don't allow the base class to clear this condition because we
|
|
|
|
|
// don't sense for it every frame.
|
|
|
|
|
SetCondition( COND_CAN_RANGE_ATTACK2 );
|
|
|
|
|
this->SetCondition( COND_CAN_RANGE_ATTACK2 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -537,8 +540,8 @@ void CAI_GrenadeUser<BASE_NPC>::ClearAttackConditions()
|
|
|
|
|
template <class BASE_NPC>
|
|
|
|
|
void CAI_GrenadeUser<BASE_NPC>::StartTask_FaceAltFireTarget( const Task_t *pTask )
|
|
|
|
|
{
|
|
|
|
|
SetIdealActivity( (Activity)(int)pTask->flTaskData );
|
|
|
|
|
GetMotor()->SetIdealYawToTargetAndUpdate( m_vecAltFireTarget, AI_KEEP_YAW_SPEED );
|
|
|
|
|
this->SetIdealActivity( (Activity)(int)pTask->flTaskData );
|
|
|
|
|
this->GetMotor()->SetIdealYawToTargetAndUpdate( m_vecAltFireTarget, AI_KEEP_YAW_SPEED );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class BASE_NPC>
|
|
|
|
|
@@ -546,7 +549,7 @@ void CAI_GrenadeUser<BASE_NPC>::StartTask_GetPathToForced( const Task_t *pTask )
|
|
|
|
|
{
|
|
|
|
|
if ( !m_hForcedGrenadeTarget )
|
|
|
|
|
{
|
|
|
|
|
TaskFail(FAIL_NO_ENEMY);
|
|
|
|
|
this->TaskFail(FAIL_NO_ENEMY);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -559,47 +562,48 @@ void CAI_GrenadeUser<BASE_NPC>::StartTask_GetPathToForced( const Task_t *pTask )
|
|
|
|
|
Vector posLos;
|
|
|
|
|
bool found = false;
|
|
|
|
|
|
|
|
|
|
if ( GetTacticalServices()->FindLateralLos( vecEnemyEye, &posLos ) )
|
|
|
|
|
if ( this->GetTacticalServices()->FindLateralLos( vecEnemyEye, &posLos ) )
|
|
|
|
|
{
|
|
|
|
|
float dist = ( posLos - vecEnemyEye ).Length();
|
|
|
|
|
if ( dist < flMaxRange && dist > flMinRange )
|
|
|
|
|
found = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( !found && GetTacticalServices()->FindLos( vecEnemy, vecEnemyEye, flMinRange, flMaxRange, 1.0, &posLos ) )
|
|
|
|
|
if ( !found && this->GetTacticalServices()->FindLos( vecEnemy, vecEnemyEye, flMinRange, flMaxRange, 1.0, &posLos ) )
|
|
|
|
|
{
|
|
|
|
|
found = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( !found )
|
|
|
|
|
{
|
|
|
|
|
TaskFail( FAIL_NO_SHOOT );
|
|
|
|
|
this->TaskFail( FAIL_NO_SHOOT );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// else drop into run task to offer an interrupt
|
|
|
|
|
m_vInterruptSavePosition = posLos;
|
|
|
|
|
this->m_vInterruptSavePosition = posLos;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class BASE_NPC>
|
|
|
|
|
void CAI_GrenadeUser<BASE_NPC>::StartTask_DeferSquad( const Task_t *pTask )
|
|
|
|
|
{
|
|
|
|
|
if ( m_pSquad )
|
|
|
|
|
CAI_Squad *pSquad = this->GetSquad();
|
|
|
|
|
if ( pSquad )
|
|
|
|
|
{
|
|
|
|
|
// iterate my squad and stop everyone from throwing grenades for a little while.
|
|
|
|
|
AISquadIter_t iter;
|
|
|
|
|
|
|
|
|
|
CAI_BaseNPC *pSquadmate = m_pSquad ? m_pSquad->GetFirstMember( &iter ) : NULL;
|
|
|
|
|
CAI_BaseNPC *pSquadmate = pSquad ? pSquad->GetFirstMember( &iter ) : NULL;
|
|
|
|
|
while ( pSquadmate )
|
|
|
|
|
{
|
|
|
|
|
pSquadmate->DelayGrenadeCheck(5);
|
|
|
|
|
|
|
|
|
|
pSquadmate = m_pSquad->GetNextMember( &iter );
|
|
|
|
|
pSquadmate = pSquad->GetNextMember( &iter );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskComplete();
|
|
|
|
|
this->TaskComplete();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
@@ -607,14 +611,14 @@ void CAI_GrenadeUser<BASE_NPC>::StartTask_DeferSquad( const Task_t *pTask )
|
|
|
|
|
template <class BASE_NPC>
|
|
|
|
|
void CAI_GrenadeUser<BASE_NPC>::RunTask_FaceAltFireTarget( const Task_t *pTask )
|
|
|
|
|
{
|
|
|
|
|
GetMotor()->SetIdealYawToTargetAndUpdate( m_vecAltFireTarget, AI_KEEP_YAW_SPEED );
|
|
|
|
|
this->GetMotor()->SetIdealYawToTargetAndUpdate( m_vecAltFireTarget, AI_KEEP_YAW_SPEED );
|
|
|
|
|
|
|
|
|
|
// New Mapbase thing that fixes forced alt-fires not changing weapon yaw/pitch
|
|
|
|
|
SetAim( m_vecAltFireTarget - Weapon_ShootPosition() );
|
|
|
|
|
this->SetAim( m_vecAltFireTarget - this->Weapon_ShootPosition() );
|
|
|
|
|
|
|
|
|
|
if (IsActivityFinished())
|
|
|
|
|
if (this->IsActivityFinished())
|
|
|
|
|
{
|
|
|
|
|
TaskComplete();
|
|
|
|
|
this->TaskComplete();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -623,23 +627,23 @@ void CAI_GrenadeUser<BASE_NPC>::RunTask_GetPathToForced( const Task_t *pTask )
|
|
|
|
|
{
|
|
|
|
|
if ( !m_hForcedGrenadeTarget )
|
|
|
|
|
{
|
|
|
|
|
TaskFail(FAIL_NO_ENEMY);
|
|
|
|
|
this->TaskFail(FAIL_NO_ENEMY);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( GetTaskInterrupt() > 0 )
|
|
|
|
|
if ( this->GetTaskInterrupt() > 0 )
|
|
|
|
|
{
|
|
|
|
|
ClearTaskInterrupt();
|
|
|
|
|
this->ClearTaskInterrupt();
|
|
|
|
|
|
|
|
|
|
Vector vecEnemy = m_hForcedGrenadeTarget->GetAbsOrigin();
|
|
|
|
|
AI_NavGoal_t goal( m_vInterruptSavePosition, ACT_RUN, AIN_HULL_TOLERANCE );
|
|
|
|
|
AI_NavGoal_t goal( this->m_vInterruptSavePosition, ACT_RUN, AIN_HULL_TOLERANCE );
|
|
|
|
|
|
|
|
|
|
GetNavigator()->SetGoal( goal, AIN_CLEAR_TARGET );
|
|
|
|
|
GetNavigator()->SetArrivalDirection( vecEnemy - goal.dest );
|
|
|
|
|
this->GetNavigator()->SetGoal( goal, AIN_CLEAR_TARGET );
|
|
|
|
|
this->GetNavigator()->SetArrivalDirection( vecEnemy - goal.dest );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TaskInterrupt();
|
|
|
|
|
this->TaskInterrupt();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -647,11 +651,11 @@ template <class BASE_NPC>
|
|
|
|
|
void CAI_GrenadeUser<BASE_NPC>::RunTask_FaceTossDir( const Task_t *pTask )
|
|
|
|
|
{
|
|
|
|
|
// project a point along the toss vector and turn to face that point.
|
|
|
|
|
GetMotor()->SetIdealYawToTargetAndUpdate( GetLocalOrigin() + m_vecTossVelocity * 64, AI_KEEP_YAW_SPEED );
|
|
|
|
|
this->GetMotor()->SetIdealYawToTargetAndUpdate( this->GetLocalOrigin() + m_vecTossVelocity * 64, AI_KEEP_YAW_SPEED );
|
|
|
|
|
|
|
|
|
|
if ( FacingIdeal() )
|
|
|
|
|
if ( this->FacingIdeal() )
|
|
|
|
|
{
|
|
|
|
|
TaskComplete( true );
|
|
|
|
|
this->TaskComplete( true );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|