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