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.
159 lines
3.9 KiB
159 lines
3.9 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// |
|
// |
|
//============================================================================= |
|
#include "cbase.h" |
|
|
|
#include "tf_player.h" |
|
#include "tf_gamerules.h" |
|
#include "particle_parse.h" |
|
|
|
#include "../merasmus.h" |
|
#include "merasmus_throwing_grenade.h" |
|
#include "merasmus_stunned.h" |
|
|
|
CMerasmusThrowingGrenade::CMerasmusThrowingGrenade( CTFPlayer* pTarget ) |
|
{ |
|
m_hTarget = pTarget; |
|
} |
|
|
|
|
|
ActionResult< CMerasmus > CMerasmusThrowingGrenade::OnStart( CMerasmus *me, Action< CMerasmus > *priorAction ) |
|
{ |
|
if ( m_hTarget == NULL ) |
|
{ |
|
return Done( "No Target" ); |
|
} |
|
|
|
if ( !me->IsLineOfSightClear( m_hTarget ) ) |
|
{ |
|
CUtlVector< CTFPlayer * > playerVector; |
|
|
|
// collect everyone |
|
CollectPlayers( &playerVector, TF_TEAM_RED, COLLECT_ONLY_LIVING_PLAYERS ); |
|
CollectPlayers( &playerVector, TF_TEAM_BLUE, COLLECT_ONLY_LIVING_PLAYERS, APPEND_PLAYERS ); |
|
|
|
CUtlVector< CTFPlayer * > newTargetVector; |
|
for ( int i=0; i<playerVector.Count(); ++i ) |
|
{ |
|
if ( playerVector[i] == m_hTarget ) |
|
{ |
|
continue; |
|
} |
|
|
|
if ( !me->IsLineOfSightClear( playerVector[i] ) ) |
|
{ |
|
continue; |
|
} |
|
|
|
newTargetVector.AddToTail( playerVector[i] ); |
|
} |
|
|
|
if ( newTargetVector.Count() == 0 ) |
|
{ |
|
m_hTarget = NULL; |
|
} |
|
else |
|
{ |
|
int which = RandomInt( 0, newTargetVector.Count() - 1 ); |
|
m_hTarget = newTargetVector[ which ]; |
|
} |
|
} |
|
|
|
if ( m_hTarget == NULL ) |
|
{ |
|
return Done( "No Target" ); |
|
} |
|
|
|
me->GetLocomotionInterface()->FaceTowards( m_hTarget->WorldSpaceCenter() ); |
|
int iLayer = me->AddGesture( ACT_MP_ATTACK_STAND_ITEM1 ); |
|
float flDuration = me->GetLayerDuration( iLayer ); |
|
m_throwTimer.Start( flDuration ); |
|
|
|
// we want to release the grenade mid-animation |
|
m_releaseGrenadeTimer.Start( 0.25f ); |
|
|
|
// hide his staff |
|
int staffBodyGroup = me->FindBodygroupByName( "staff" ); |
|
me->SetBodygroup( staffBodyGroup, 2 ); |
|
|
|
// smooth out the bot's path following by moving toward a point farther down the path |
|
m_path.SetMinLookAheadDistance( 100.0f ); |
|
|
|
return Continue(); |
|
} |
|
|
|
|
|
ActionResult< CMerasmus > CMerasmusThrowingGrenade::Update( CMerasmus *me, float interval ) |
|
{ |
|
// Interupt if stunned |
|
if ( me->HasStunTimer() ) |
|
{ |
|
return ChangeTo( new CMerasmusStunned, "Stun Interupt!" ); |
|
} |
|
|
|
if ( m_releaseGrenadeTimer.HasStarted() && m_releaseGrenadeTimer.IsElapsed() ) |
|
{ |
|
m_releaseGrenadeTimer.Invalidate(); |
|
|
|
DispatchParticleEffect( "merasmus_shoot", PATTACH_ABSORIGIN_FOLLOW, me, "effect_hand_R" ); |
|
|
|
Vector vPos; |
|
QAngle qAngles; |
|
me->GetAttachment( "effect_hand_R", vPos, qAngles ); |
|
|
|
Vector vForward, vRight, vUp; |
|
AngleVectors( me->EyeAngles(), &vForward, &vRight, &vUp ); |
|
float flLaunchSpeed = RandomFloat( 1500.f, 2000.f ); |
|
Vector vecVelocity = ( vForward * flLaunchSpeed ) + ( vUp * 200.0f ) + ( RandomFloat( -10.0f, 10.0f ) * vRight ) + ( RandomFloat( -10.0f, 10.0f ) * vUp ); |
|
CTFWeaponBaseGrenadeProj* pGrenade = CMerasmus::CreateMerasmusGrenade( vPos, vecVelocity, me ); |
|
if ( pGrenade ) |
|
{ |
|
if ( RandomInt( 0, 6 ) == 0 ) |
|
{ |
|
CPVSFilter filter( me->WorldSpaceCenter() ); |
|
if ( RandomInt(1,10) == 1 ) |
|
{ |
|
me->PlayLowPrioritySound( filter, "Halloween.MerasmusGrenadeThrowRare" ); |
|
} |
|
else |
|
{ |
|
me->PlayLowPrioritySound( filter, "Halloween.MerasmusGrenadeThrow" ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
if ( m_hTarget ) |
|
{ |
|
if ( me->IsRangeGreaterThan( m_hTarget, 100.f ) || !me->IsLineOfSightClear( m_hTarget ) ) |
|
{ |
|
if ( m_path.GetAge() > 1.0f ) |
|
{ |
|
CMerasmusPathCost cost( me ); |
|
m_path.Compute( me, m_hTarget, cost ); |
|
} |
|
|
|
m_path.Update( me ); |
|
} |
|
|
|
me->GetLocomotionInterface()->FaceTowards( m_hTarget->WorldSpaceCenter() ); |
|
} |
|
|
|
|
|
if ( m_throwTimer.IsElapsed() ) |
|
{ |
|
return Done( "Fire in the hole!" ); |
|
} |
|
|
|
return Continue(); |
|
} |
|
|
|
|
|
void CMerasmusThrowingGrenade::OnEnd( CMerasmus *me, Action< CMerasmus > *nextAction ) |
|
{ |
|
// turn his staff back on |
|
int staffBodyGroup = me->FindBodygroupByName( "staff" ); |
|
me->SetBodygroup( staffBodyGroup, 0 ); |
|
}
|
|
|