Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
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.
 
 
 
 
 
 

117 lines
3.0 KiB

//========= 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();
}