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.
118 lines
3.0 KiB
118 lines
3.0 KiB
4 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
//=============================================================================
|
||
|
#include "cbase.h"
|
||
|
|
||
|
#include "tf_gamerules.h"
|
||
|
#include "tf_player.h"
|
||
|
|
||
|
#include "../merasmus.h"
|
||
|
#include "merasmus_staff_attack.h"
|
||
|
#include "merasmus_stunned.h"
|
||
|
|
||
|
CMerasmusStaffAttack::CMerasmusStaffAttack( CTFPlayer* pTarget )
|
||
|
{
|
||
|
m_hTarget = pTarget;
|
||
|
}
|
||
|
|
||
|
|
||
|
ActionResult< CMerasmus > CMerasmusStaffAttack::OnStart( CMerasmus *me, Action< CMerasmus > *priorAction )
|
||
|
{
|
||
|
// smooth out the bot's path following by moving toward a point farther down the path
|
||
|
m_path.SetMinLookAheadDistance( 100.0f );
|
||
|
|
||
|
int iLayer = me->AddGesture( ACT_MP_ATTACK_STAND_MELEE );
|
||
|
float flDuration = me->GetLayerDuration( iLayer );
|
||
|
m_staffSwingTimer.Start( flDuration );
|
||
|
m_hitTimer.Start( 0.5f * flDuration );
|
||
|
|
||
|
if ( RandomInt( 0, 2 ) == 0 )
|
||
|
{
|
||
|
CPVSFilter filter( me->WorldSpaceCenter() );
|
||
|
if ( RandomInt( 1, 5 ) == 1 )
|
||
|
{
|
||
|
me->PlayLowPrioritySound( filter, "Halloween.MerasmusStaffAttackRare" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
me->PlayLowPrioritySound( filter, "Halloween.MerasmusStaffAttack" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return Continue();
|
||
|
}
|
||
|
|
||
|
|
||
|
ActionResult< CMerasmus > CMerasmusStaffAttack::Update( CMerasmus *me, float interval )
|
||
|
{
|
||
|
// Interupt if stunned
|
||
|
if ( me->HasStunTimer() )
|
||
|
{
|
||
|
return ChangeTo( new CMerasmusStunned, "Stun Interupt!" );
|
||
|
}
|
||
|
|
||
|
if ( m_hitTimer.HasStarted() && m_hitTimer.IsElapsed() )
|
||
|
{
|
||
|
m_hitTimer.Invalidate();
|
||
|
|
||
|
if ( m_hTarget != NULL )
|
||
|
{
|
||
|
Vector forward;
|
||
|
me->GetVectors( &forward, NULL, NULL );
|
||
|
|
||
|
Vector toVictim = m_hTarget->WorldSpaceCenter() - me->WorldSpaceCenter();
|
||
|
toVictim.NormalizeInPlace();
|
||
|
|
||
|
// looser tolerance as victim gets closer
|
||
|
const float closeRange = 100.0f;
|
||
|
float range = me->GetRangeTo( m_hTarget );
|
||
|
float closeness = ( range < closeRange ) ? 0.0f : ( range - closeRange ) / ( tf_merasmus_attack_range.GetFloat() - closeRange );
|
||
|
float hitAngle = 0.0f + closeness * 0.27f;
|
||
|
|
||
|
if ( DotProduct( forward, toVictim ) > hitAngle )
|
||
|
{
|
||
|
if ( me->IsRangeLessThan( m_hTarget, 0.9f * tf_merasmus_attack_range.GetFloat() ) )
|
||
|
{
|
||
|
if ( me->IsLineOfSightClear( m_hTarget ) )
|
||
|
{
|
||
|
// CHOP!
|
||
|
CTakeDamageInfo info( me, me, 70, DMG_CLUB, TF_DMG_CUSTOM_MERASMUS_DECAPITATION );
|
||
|
CalculateMeleeDamageForce( &info, toVictim, me->WorldSpaceCenter(), 5.0f );
|
||
|
m_hTarget->TakeDamage( info );
|
||
|
|
||
|
CPVSFilter filter( me->WorldSpaceCenter() );
|
||
|
me->PlayLowPrioritySound( filter, "Halloween.HeadlessBossAxeHitFlesh" );
|
||
|
|
||
|
me->PushPlayer( m_hTarget, 500.f );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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_staffSwingTimer.IsElapsed() )
|
||
|
{
|
||
|
return Done();
|
||
|
}
|
||
|
|
||
|
return Continue();
|
||
|
}
|