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.
203 lines
6.1 KiB
203 lines
6.1 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Crowbar - an old favorite |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "basehlcombatweapon.h" |
|
#include "player.h" |
|
#include "gamerules.h" |
|
#include "ammodef.h" |
|
#include "mathlib/mathlib.h" |
|
#include "in_buttons.h" |
|
#include "soundent.h" |
|
#include "basebludgeonweapon.h" |
|
#include "vstdlib/random.h" |
|
#include "npcevent.h" |
|
#include "ai_basenpc.h" |
|
#include "weapon_crowbar.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
ConVar sk_plr_dmg_crowbar ( "sk_plr_dmg_crowbar","0"); |
|
ConVar sk_npc_dmg_crowbar ( "sk_npc_dmg_crowbar","0"); |
|
|
|
//----------------------------------------------------------------------------- |
|
// CWeaponCrowbar |
|
//----------------------------------------------------------------------------- |
|
|
|
IMPLEMENT_SERVERCLASS_ST(CWeaponCrowbar, DT_WeaponCrowbar) |
|
END_SEND_TABLE() |
|
|
|
#ifndef HL2MP |
|
LINK_ENTITY_TO_CLASS( weapon_crowbar, CWeaponCrowbar ); |
|
PRECACHE_WEAPON_REGISTER( weapon_crowbar ); |
|
#endif |
|
|
|
acttable_t CWeaponCrowbar::m_acttable[] = |
|
{ |
|
{ ACT_MELEE_ATTACK1, ACT_MELEE_ATTACK_SWING, true }, |
|
{ ACT_IDLE, ACT_IDLE_ANGRY_MELEE, false }, |
|
{ ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_MELEE, false }, |
|
}; |
|
|
|
IMPLEMENT_ACTTABLE(CWeaponCrowbar); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Constructor |
|
//----------------------------------------------------------------------------- |
|
CWeaponCrowbar::CWeaponCrowbar( void ) |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the damage amount for the animation we're doing |
|
// Input : hitActivity - currently played activity |
|
// Output : Damage amount |
|
//----------------------------------------------------------------------------- |
|
float CWeaponCrowbar::GetDamageForActivity( Activity hitActivity ) |
|
{ |
|
if ( ( GetOwner() != NULL ) && ( GetOwner()->IsPlayer() ) ) |
|
return sk_plr_dmg_crowbar.GetFloat(); |
|
|
|
return sk_npc_dmg_crowbar.GetFloat(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Add in a view kick for this weapon |
|
//----------------------------------------------------------------------------- |
|
void CWeaponCrowbar::AddViewKick( void ) |
|
{ |
|
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); |
|
|
|
if ( pPlayer == NULL ) |
|
return; |
|
|
|
QAngle punchAng; |
|
|
|
punchAng.x = random->RandomFloat( 1.0f, 2.0f ); |
|
punchAng.y = random->RandomFloat( -2.0f, -1.0f ); |
|
punchAng.z = 0.0f; |
|
|
|
pPlayer->ViewPunch( punchAng ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!) |
|
//----------------------------------------------------------------------------- |
|
ConVar sk_crowbar_lead_time( "sk_crowbar_lead_time", "0.9" ); |
|
|
|
int CWeaponCrowbar::WeaponMeleeAttack1Condition( float flDot, float flDist ) |
|
{ |
|
// Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!) |
|
CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer(); |
|
CBaseEntity *pEnemy = pNPC->GetEnemy(); |
|
if (!pEnemy) |
|
return COND_NONE; |
|
|
|
Vector vecVelocity; |
|
vecVelocity = pEnemy->GetSmoothedVelocity( ); |
|
|
|
// Project where the enemy will be in a little while |
|
float dt = sk_crowbar_lead_time.GetFloat(); |
|
dt += random->RandomFloat( -0.3f, 0.2f ); |
|
if ( dt < 0.0f ) |
|
dt = 0.0f; |
|
|
|
Vector vecExtrapolatedPos; |
|
VectorMA( pEnemy->WorldSpaceCenter(), dt, vecVelocity, vecExtrapolatedPos ); |
|
|
|
Vector vecDelta; |
|
VectorSubtract( vecExtrapolatedPos, pNPC->WorldSpaceCenter(), vecDelta ); |
|
|
|
if ( fabs( vecDelta.z ) > 70 ) |
|
{ |
|
return COND_TOO_FAR_TO_ATTACK; |
|
} |
|
|
|
Vector vecForward = pNPC->BodyDirection2D( ); |
|
vecDelta.z = 0.0f; |
|
float flExtrapolatedDist = Vector2DNormalize( vecDelta.AsVector2D() ); |
|
if ((flDist > 64) && (flExtrapolatedDist > 64)) |
|
{ |
|
return COND_TOO_FAR_TO_ATTACK; |
|
} |
|
|
|
float flExtrapolatedDot = DotProduct2D( vecDelta.AsVector2D(), vecForward.AsVector2D() ); |
|
if ((flDot < 0.7) && (flExtrapolatedDot < 0.7)) |
|
{ |
|
return COND_NOT_FACING_ATTACK; |
|
} |
|
|
|
return COND_CAN_MELEE_ATTACK1; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Animation event handlers |
|
//----------------------------------------------------------------------------- |
|
void CWeaponCrowbar::HandleAnimEventMeleeHit( animevent_t *pEvent, CBaseCombatCharacter *pOperator ) |
|
{ |
|
// Trace up or down based on where the enemy is... |
|
// But only if we're basically facing that direction |
|
Vector vecDirection; |
|
AngleVectors( GetAbsAngles(), &vecDirection ); |
|
|
|
CBaseEntity *pEnemy = pOperator->MyNPCPointer() ? pOperator->MyNPCPointer()->GetEnemy() : NULL; |
|
if ( pEnemy ) |
|
{ |
|
Vector vecDelta; |
|
VectorSubtract( pEnemy->WorldSpaceCenter(), pOperator->Weapon_ShootPosition(), vecDelta ); |
|
VectorNormalize( vecDelta ); |
|
|
|
Vector2D vecDelta2D = vecDelta.AsVector2D(); |
|
Vector2DNormalize( vecDelta2D ); |
|
if ( DotProduct2D( vecDelta2D, vecDirection.AsVector2D() ) > 0.8f ) |
|
{ |
|
vecDirection = vecDelta; |
|
} |
|
} |
|
|
|
Vector vecEnd; |
|
VectorMA( pOperator->Weapon_ShootPosition(), 50, vecDirection, vecEnd ); |
|
CBaseEntity *pHurt = pOperator->CheckTraceHullAttack( pOperator->Weapon_ShootPosition(), vecEnd, |
|
Vector(-16,-16,-16), Vector(36,36,36), sk_npc_dmg_crowbar.GetFloat(), DMG_CLUB, 0.75 ); |
|
|
|
// did I hit someone? |
|
if ( pHurt ) |
|
{ |
|
// play sound |
|
WeaponSound( MELEE_HIT ); |
|
|
|
// Fake a trace impact, so the effects work out like a player's crowbaw |
|
trace_t traceHit; |
|
UTIL_TraceLine( pOperator->Weapon_ShootPosition(), pHurt->GetAbsOrigin(), MASK_SHOT_HULL, pOperator, COLLISION_GROUP_NONE, &traceHit ); |
|
ImpactEffect( traceHit ); |
|
} |
|
else |
|
{ |
|
WeaponSound( MELEE_MISS ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Animation event |
|
//----------------------------------------------------------------------------- |
|
void CWeaponCrowbar::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ) |
|
{ |
|
switch( pEvent->event ) |
|
{ |
|
case EVENT_WEAPON_MELEE_HIT: |
|
HandleAnimEventMeleeHit( pEvent, pOperator ); |
|
break; |
|
|
|
default: |
|
BaseClass::Operator_HandleAnimEvent( pEvent, pOperator ); |
|
break; |
|
} |
|
}
|
|
|