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.
434 lines
10 KiB
434 lines
10 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $Workfile: $ |
|
// $Date: $ |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "util.h" |
|
#include "basehlcombatweapon.h" |
|
#include "player.h" |
|
#include "gamerules.h" |
|
#include "grenade_tripwire.h" |
|
#include "grenade_satchel.h" |
|
#include "entitylist.h" |
|
#include "weapon_tripwire.h" |
|
#include "npcevent.h" |
|
#include "in_buttons.h" |
|
#include "engine/IEngineSound.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
BEGIN_DATADESC( CWeapon_Tripwire ) |
|
|
|
DEFINE_FIELD( m_bNeedReload, FIELD_BOOLEAN ), |
|
DEFINE_FIELD( m_bClearReload, FIELD_BOOLEAN ), |
|
DEFINE_FIELD( m_bAttachTripwire, FIELD_BOOLEAN ), |
|
|
|
// Function Pointers |
|
DEFINE_FUNCTION( TripwireTouch ), |
|
|
|
END_DATADESC() |
|
|
|
|
|
IMPLEMENT_SERVERCLASS_ST(CWeapon_Tripwire, DT_Weapon_Tripwire) |
|
END_SEND_TABLE() |
|
|
|
LINK_ENTITY_TO_CLASS( weapon_tripwire, CWeapon_Tripwire ); |
|
|
|
// BUGBUG: Enable this when the script & resources are checked in. |
|
//PRECACHE_WEAPON_REGISTER(weapon_tripwire); |
|
|
|
acttable_t CWeapon_Tripwire::m_acttable[] = |
|
{ |
|
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_TRIPWIRE, true }, |
|
}; |
|
|
|
IMPLEMENT_ACTTABLE(CWeapon_Tripwire); |
|
|
|
|
|
void CWeapon_Tripwire::Spawn( ) |
|
{ |
|
UTIL_Remove(this); |
|
return; |
|
|
|
BaseClass::Spawn(); |
|
|
|
Precache( ); |
|
|
|
UTIL_SetSize(this, Vector(-4,-4,-2),Vector(4,4,2)); |
|
|
|
|
|
FallInit();// get ready to fall down |
|
|
|
SetThink( NULL ); |
|
|
|
// Give one piece of default ammo when first picked up |
|
m_iClip2 = 1; |
|
} |
|
|
|
void CWeapon_Tripwire::Precache( void ) |
|
{ |
|
BaseClass::Precache(); |
|
|
|
PrecacheScriptSound( "Weapon_Tripwire.Attach" ); |
|
|
|
UTIL_PrecacheOther( "npc_tripwire" ); |
|
} |
|
|
|
//------------------------------------------------------------------------------ |
|
// Purpose : Override to use tripwire's pickup touch function |
|
// Input : |
|
// Output : |
|
//------------------------------------------------------------------------------ |
|
void CWeapon_Tripwire::SetPickupTouch( void ) |
|
{ |
|
SetTouch(TripwireTouch); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Override so give correct ammo |
|
// Input : pOther - the entity that touched me |
|
// Output : |
|
//----------------------------------------------------------------------------- |
|
void CWeapon_Tripwire::TripwireTouch( CBaseEntity *pOther ) |
|
{ |
|
// --------------------------------------------------- |
|
// First give weapon to touching entity if allowed |
|
// --------------------------------------------------- |
|
BaseClass::DefaultTouch(pOther); |
|
|
|
// ---------------------------------------------------- |
|
// Give ammo if touching client |
|
// ---------------------------------------------------- |
|
if (pOther->GetFlags() & FL_CLIENT) |
|
{ |
|
// ------------------------------------------------ |
|
// If already owned weapon of this type remove me |
|
// ------------------------------------------------ |
|
CBaseCombatCharacter* pBCC = ToBaseCombatCharacter( pOther ); |
|
CWeapon_Tripwire* oldWeapon = (CWeapon_Tripwire*)pBCC->Weapon_OwnsThisType( GetClassname() ); |
|
if (oldWeapon != this) |
|
{ |
|
UTIL_Remove( this ); |
|
} |
|
else |
|
{ |
|
pBCC->GiveAmmo( 1, m_iSecondaryAmmoType ); |
|
SetThink(NULL); |
|
} |
|
} |
|
} |
|
|
|
//------------------------------------------------------------------------------ |
|
// Purpose : |
|
// Input : |
|
// Output : |
|
//------------------------------------------------------------------------------ |
|
bool CWeapon_Tripwire::Holster( CBaseCombatWeapon *pSwitchingTo ) |
|
{ |
|
SetThink(NULL); |
|
return BaseClass::Holster(pSwitchingTo); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Tripwire has no reload, but must call weapon idle to update state |
|
// Input : |
|
// Output : |
|
//----------------------------------------------------------------------------- |
|
bool CWeapon_Tripwire::Reload( void ) |
|
{ |
|
WeaponIdle( ); |
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : |
|
// Output : |
|
//----------------------------------------------------------------------------- |
|
void CWeapon_Tripwire::PrimaryAttack( void ) |
|
{ |
|
CBaseCombatCharacter *pOwner = GetOwner(); |
|
if (!pOwner) |
|
{ |
|
return; |
|
} |
|
|
|
if (pOwner->GetAmmoCount(m_iSecondaryAmmoType) <= 0) |
|
{ |
|
return; |
|
} |
|
|
|
if (CanAttachTripwire()) |
|
{ |
|
StartTripwireAttach(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Secondary attack does nothing |
|
// Input : |
|
// Output : |
|
//----------------------------------------------------------------------------- |
|
void CWeapon_Tripwire::SecondaryAttack( void ) |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : |
|
// Output : |
|
//----------------------------------------------------------------------------- |
|
void CWeapon_Tripwire::TripwireAttach( void ) |
|
{ |
|
CBaseCombatCharacter *pOwner = GetOwner(); |
|
if (!pOwner) |
|
{ |
|
return; |
|
} |
|
|
|
m_bAttachTripwire = false; |
|
|
|
Vector vecSrc = pOwner->Weapon_ShootPosition(); |
|
Vector vecAiming = pOwner->BodyDirection2D( ); |
|
|
|
trace_t tr; |
|
|
|
UTIL_TraceLine( vecSrc, vecSrc + (vecAiming * 128), MASK_SOLID, pOwner, COLLISION_GROUP_NONE, &tr ); |
|
|
|
if (tr.fraction < 1.0) |
|
{ |
|
CBaseEntity *pEntity = tr.m_pEnt; |
|
if (pEntity && !(pEntity->GetFlags() & FL_CONVEYOR)) |
|
{ |
|
QAngle angles; |
|
VectorAngles(tr.plane.normal, angles); |
|
angles.x += 90; |
|
|
|
CBaseEntity *pEnt = CBaseEntity::Create( "npc_tripwire", tr.endpos + tr.plane.normal * 3, angles, NULL ); |
|
|
|
CTripwireGrenade *pMine = (CTripwireGrenade *)pEnt; |
|
pMine->SetThrower( GetOwner() ); |
|
|
|
pOwner->RemoveAmmo( 1, m_iSecondaryAmmoType ); |
|
|
|
EmitSound( "Weapon_Tripwire.Attach" ); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : |
|
// Output : |
|
//----------------------------------------------------------------------------- |
|
void CWeapon_Tripwire::StartTripwireAttach( void ) |
|
{ |
|
// Only the player fires this way so we can cast |
|
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); |
|
if (!pPlayer) |
|
{ |
|
return; |
|
} |
|
|
|
Vector vecSrc = pPlayer->Weapon_ShootPosition(); |
|
Vector vecAiming = pPlayer->BodyDirection3D( ); |
|
|
|
trace_t tr; |
|
|
|
UTIL_TraceLine( vecSrc, vecSrc + (vecAiming * 128), MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr ); |
|
|
|
if (tr.fraction < 1.0) |
|
{ |
|
// ALERT( at_console, "hit %f\n", tr.flFraction ); |
|
|
|
CBaseEntity *pEntity = tr.m_pEnt; |
|
if (pEntity && !(pEntity->GetFlags() & FL_CONVEYOR)) |
|
{ |
|
// player "shoot" animation |
|
pPlayer->SetAnimation( PLAYER_ATTACK1 ); |
|
|
|
// ----------------------------------------- |
|
// Play attach animation |
|
// ----------------------------------------- |
|
SendWeaponAnim(ACT_SLAM_TRIPMINE_ATTACH); |
|
|
|
m_bNeedReload = true; |
|
m_bAttachTripwire = true; |
|
} |
|
else |
|
{ |
|
// ALERT( at_console, "no deploy\n" ); |
|
} |
|
} |
|
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); |
|
m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration(); |
|
// SetWeaponIdleTime( gpGlobals->curtime + SequenceDuration() ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : |
|
// Output : |
|
//----------------------------------------------------------------------------- |
|
bool CWeapon_Tripwire::CanAttachTripwire( void ) |
|
{ |
|
CBaseCombatCharacter *pOwner = GetOwner(); |
|
if (!pOwner) |
|
{ |
|
return false; |
|
} |
|
|
|
Vector vecSrc = pOwner->Weapon_ShootPosition(); |
|
Vector vecAiming = pOwner->BodyDirection2D( ); |
|
|
|
trace_t tr; |
|
|
|
Vector vecEnd = vecSrc + (vecAiming * 42); |
|
UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID, pOwner, COLLISION_GROUP_NONE, &tr ); |
|
|
|
if (tr.fraction < 1.0) |
|
{ |
|
// Don't attach to a living creature |
|
if (tr.m_pEnt) |
|
{ |
|
CBaseEntity *pEntity = tr.m_pEnt; |
|
CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( pEntity ); |
|
if (pBCC) |
|
{ |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
else |
|
{ |
|
return false; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : |
|
// Output : |
|
//----------------------------------------------------------------------------- |
|
void CWeapon_Tripwire::ItemPostFrame( void ) |
|
{ |
|
CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); |
|
if (!pOwner) |
|
{ |
|
return; |
|
} |
|
|
|
if ((pOwner->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime)) |
|
{ |
|
SecondaryAttack(); |
|
} |
|
else if (!m_bNeedReload && (pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime)) |
|
{ |
|
PrimaryAttack(); |
|
} |
|
|
|
// ----------------------- |
|
// No buttons down |
|
// ----------------------- |
|
else |
|
{ |
|
WeaponIdle( ); |
|
return; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : |
|
// Output : |
|
//----------------------------------------------------------------------------- |
|
void CWeapon_Tripwire::WeaponIdle( void ) |
|
{ |
|
// Ready to switch animations? |
|
if ( HasWeaponIdleTimeElapsed() ) |
|
{ |
|
if (m_bClearReload) |
|
{ |
|
m_bNeedReload = false; |
|
m_bClearReload = false; |
|
} |
|
CBaseCombatCharacter *pOwner = GetOwner(); |
|
if (!pOwner) |
|
{ |
|
return; |
|
} |
|
|
|
int iAnim = 0; |
|
|
|
if (m_bAttachTripwire) |
|
{ |
|
TripwireAttach(); |
|
iAnim = ACT_SLAM_TRIPMINE_ATTACH2; |
|
} |
|
else if (m_bNeedReload) |
|
{ |
|
// If owner had ammo draw the correct tripwire type |
|
if (pOwner->GetAmmoCount(m_iSecondaryAmmoType) > 0) |
|
{ |
|
iAnim = ACT_SLAM_TRIPMINE_DRAW; |
|
m_bClearReload = true; |
|
} |
|
else |
|
{ |
|
pOwner->Weapon_Drop( this ); |
|
UTIL_Remove(this); |
|
} |
|
} |
|
else if (pOwner->GetAmmoCount(m_iSecondaryAmmoType) <= 0) |
|
{ |
|
pOwner->Weapon_Drop( this ); |
|
UTIL_Remove(this); |
|
} |
|
|
|
// If I don't need to reload just do the appropriate idle |
|
else |
|
{ |
|
iAnim = ACT_SLAM_TRIPMINE_IDLE; |
|
} |
|
SendWeaponAnim( iAnim ); |
|
} |
|
} |
|
|
|
bool CWeapon_Tripwire::Deploy( void ) |
|
{ |
|
CBaseCombatCharacter *pOwner = GetOwner(); |
|
if (!pOwner) |
|
{ |
|
return false; |
|
} |
|
|
|
SetModel( GetViewModel() ); |
|
|
|
// ------------------------------ |
|
// Pick the right draw animation |
|
// ------------------------------ |
|
int iActivity; |
|
|
|
// If detonator is already armed |
|
m_bNeedReload = false; |
|
iActivity = ACT_SLAM_STICKWALL_ND_DRAW; |
|
return DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), iActivity, (char*)GetAnimPrefix() ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor |
|
// Input : |
|
// Output : |
|
//----------------------------------------------------------------------------- |
|
CWeapon_Tripwire::CWeapon_Tripwire(void) |
|
{ |
|
m_bNeedReload = true; |
|
m_bClearReload = false; |
|
m_bAttachTripwire = false; |
|
}
|
|
|