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.
688 lines
20 KiB
688 lines
20 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "basetfplayer_shared.h" |
|
#include "in_buttons.h" |
|
#include "tf_shareddefs.h" |
|
#include "basegrenade_shared.h" |
|
#include "basetfcombatweapon_shared.h" |
|
#include "weapon_limpetmine.h" |
|
#include "IEffects.h" |
|
#include "engine/IEngineSound.h" |
|
#include "weapon_grenade_rocket.h" |
|
#include "beam_shared.h" |
|
#include "tf_gamerules.h" |
|
|
|
#if defined( CLIENT_DLL ) |
|
#else |
|
#include "grenade_limpetmine.h" |
|
#include "tf_obj_sentrygun.h" |
|
#include "ai_network.h" |
|
#include "tf_team.h" |
|
#endif |
|
|
|
// Damage CVars |
|
ConVar weapon_laserdesignator_range( "weapon_laserdesignator_range","2048", FCVAR_REPLICATED, "Laser Designator maximum range" ); |
|
ConVar weapon_limpetmine_max_deployed( "weapon_limpetmine_max_deployed","0", FCVAR_REPLICATED, "Maximum number of Limpet Mines that can be deployed at a single time" ); |
|
ConVar weapon_limpetmine_max_distance_off_trace( "weapon_limpetmine_max_distance_off_trace","25", FCVAR_REPLICATED, "Maximum distance off of the trace that a limpet can be." ); |
|
|
|
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponLimpetmine, DT_WeaponLimpetmine ) |
|
|
|
BEGIN_NETWORK_TABLE( CWeaponLimpetmine, DT_WeaponLimpetmine ) |
|
#if !defined( CLIENT_DLL ) |
|
SendPropInt( SENDINFO( m_iDeployedLimpets ), 5, SPROP_UNSIGNED ), |
|
SendPropEHandle( SENDINFO( m_hDesignatedEntity ) ), |
|
#else |
|
RecvPropInt( RECVINFO( m_iDeployedLimpets ) ), |
|
RecvPropEHandle( RECVINFO(m_hDesignatedEntity) ), |
|
#endif |
|
END_NETWORK_TABLE() |
|
|
|
BEGIN_PREDICTION_DATA( CWeaponLimpetmine ) |
|
|
|
DEFINE_PRED_FIELD( m_iDeployedLimpets, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), |
|
DEFINE_PRED_FIELD( m_hDesignatedEntity, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ), |
|
|
|
END_PREDICTION_DATA() |
|
|
|
LINK_ENTITY_TO_CLASS( weapon_limpetmine, CWeaponLimpetmine ); |
|
PRECACHE_WEAPON_REGISTER(weapon_limpetmine); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CWeaponLimpetmine::CWeaponLimpetmine( void ) |
|
{ |
|
SetPredictionEligible( true ); |
|
|
|
m_hDesignatedEntity = NULL; |
|
m_flNextBuzzTime = 0; |
|
m_iDeployedLimpets = 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::Precache( void ) |
|
{ |
|
BaseClass::Precache(); |
|
|
|
#ifndef CLIENT_DLL |
|
UTIL_PrecacheOther( "grenade_limpetmine" ); |
|
#endif |
|
|
|
PrecacheScriptSound( "WeaponLimpetmine.Deny" ); |
|
|
|
PrecacheModel( "sprites/laserbeam.vmt" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::UpdateOnRemove( void ) |
|
{ |
|
#ifndef CLIENT_DLL |
|
RemoveDeployedLimpets(); |
|
|
|
if ( m_hLaserDesignation ) |
|
{ |
|
UTIL_Remove( m_hLaserDesignation ); |
|
} |
|
#endif |
|
|
|
// Chain at end to mimic destructor unwind order |
|
BaseClass::UpdateOnRemove(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::CleanupOnActStart( void ) |
|
{ |
|
#ifndef CLIENT_DLL |
|
RemoveDeployedLimpets(); |
|
#endif |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
float CWeaponLimpetmine::GetFireRate( void ) |
|
{ |
|
return 0.5; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Limpetmine considers itself as having ammo at all times, because it contains the designator |
|
//----------------------------------------------------------------------------- |
|
bool CWeaponLimpetmine::HasAnyAmmo( void ) |
|
{ |
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Stop thinking and holster |
|
//----------------------------------------------------------------------------- |
|
bool CWeaponLimpetmine::Holster( CBaseCombatWeapon *pSwitchingTo ) |
|
{ |
|
StopDesignating(); |
|
return BaseClass::Holster(pSwitchingTo); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::ItemPostFrame( void ) |
|
{ |
|
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); |
|
if ( !pPlayer ) |
|
return; |
|
|
|
#ifndef CLIENT_DLL |
|
// If we don't have a laser designator yet, create one |
|
if ( !m_hLaserDesignation ) |
|
{ |
|
m_hLaserDesignation = CEnvLaserDesignation::Create( pPlayer ); |
|
} |
|
#endif |
|
|
|
// Is the player trying to designate? |
|
if ( pPlayer->m_nButtons & IN_ATTACK ) |
|
{ |
|
if ( m_bDesignating ) |
|
{ |
|
#ifndef CLIENT_DLL |
|
ActivateBeam(); |
|
#endif |
|
} |
|
else if ( m_flNextPrimaryAttack <= gpGlobals->curtime ) |
|
{ |
|
StartDesignating(); |
|
#ifndef CLIENT_DLL |
|
ActivateBeam(); |
|
#endif |
|
} |
|
} |
|
else if ( m_bDesignating ) |
|
{ |
|
StopDesignating(); |
|
} |
|
else if ( (pPlayer->m_nButtons & IN_ATTACK2) && !m_flStartedLaunchingAt && (m_flNextPrimaryAttack <= gpGlobals->curtime) ) |
|
{ |
|
m_flStartedLaunchingAt = gpGlobals->curtime; |
|
|
|
SendWeaponAnim( ACT_VM_PRIMARYATTACK ); |
|
} |
|
else if ( (pPlayer->m_afButtonReleased & IN_ATTACK2) && (m_flNextPrimaryAttack <= gpGlobals->curtime) && m_flStartedLaunchingAt ) |
|
{ |
|
m_flNextPrimaryAttack = gpGlobals->curtime; |
|
PrimaryAttack(); |
|
m_flStartedLaunchingAt = 0; |
|
} |
|
|
|
UpdateBeamTarget(); |
|
|
|
// Always idle |
|
WeaponIdle(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::PrimaryAttack( void ) |
|
{ |
|
CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() ); |
|
if ( !pPlayer ) |
|
return; |
|
|
|
// Don't allow anymore limpets to be placed if we've reached the max |
|
if ( m_iDeployedLimpets >= weapon_limpetmine_max_deployed.GetInt() ) |
|
{ |
|
#ifdef CLIENT_DLL |
|
// We should flash the limpet mine count on the weapon at this point |
|
CLocalPlayerFilter filter; |
|
EmitSound( filter, entindex(), "WeaponLimpetmine.Deny" ); |
|
m_flNextBuzzTime = gpGlobals->curtime + 0.5f; // only buzz every so often. |
|
#endif |
|
return; |
|
} |
|
|
|
if ( IsOwnerEMPed() ) |
|
return; |
|
|
|
trace_t tr; |
|
// Get an aim vector. Don't use GetAimVector() because we don't want autoaiming. |
|
Vector vecSrc = pPlayer->Weapon_ShootPosition( ); |
|
Vector vecAiming; |
|
pPlayer->EyeVectors( &vecAiming ); |
|
|
|
// Calculate launch velocity (3 seconds for max distance) |
|
float flThrowTime = MIN( (gpGlobals->curtime - m_flStartedLaunchingAt), 3.0 ); |
|
float flSpeed = 600 + (300 * flThrowTime); |
|
vecAiming *= flSpeed; |
|
|
|
WeaponSound( WPN_DOUBLE ); |
|
#ifndef CLIENT_DLL |
|
ThrowLimpet( pPlayer, vecSrc, vecAiming ); |
|
#endif |
|
SendWeaponAnim( ACT_VM_SECONDARYATTACK ); |
|
|
|
m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); |
|
m_flNextSecondaryAttack = gpGlobals->curtime + GetFireRate(); |
|
|
|
pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType ); |
|
} |
|
|
|
#if !defined( CLIENT_DLL ) |
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::ThrowLimpet( CBasePlayer *pPlayer, Vector vecSrc, Vector vecAiming ) |
|
{ |
|
CLimpetMine *pLimpet = CLimpetMine::Create(vecSrc, vecAiming, pPlayer); |
|
pLimpet->SetLauncher( this ); |
|
|
|
// Increase the limpet count |
|
m_iDeployedLimpets += 1; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Detonates all deployed limpets for this weapon |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::DetonateDeployedLimpets( void ) |
|
{ |
|
CBaseEntity *pEntity = NULL; |
|
while ((pEntity = gEntList.FindEntityByClassname( pEntity, "grenade_limpetmine" )) != NULL) |
|
{ |
|
CLimpetMine* pLimpet = (CLimpetMine*)pEntity; |
|
if ( pLimpet->IsLive() && pLimpet->GetThrower() == GetOwner() ) |
|
{ |
|
pLimpet->Use( GetOwner(), this, USE_ON, 0 ); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Quietly removes all deployed limpets for this weapon |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::RemoveDeployedLimpets( void ) |
|
{ |
|
CBaseEntity *pEntity = NULL; |
|
while ((pEntity = gEntList.FindEntityByClassname( pEntity, "grenade_limpetmine" )) != NULL) |
|
{ |
|
CLimpetMine* pLimpet = (CLimpetMine*)pEntity; |
|
if ( pLimpet->GetThrower() == GetOwner() ) |
|
{ |
|
pLimpet->Use( GetOwner(), this, USE_SET, 0 ); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::ActivateBeam( void ) |
|
{ |
|
CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() ); |
|
if ( !pPlayer ) |
|
return; |
|
|
|
Assert( m_pBeam ); |
|
if( m_hDesignatedEntity != NULL ) |
|
{ |
|
CBaseEntity* pEntity = m_hDesignatedEntity.Get(); |
|
|
|
// If we hit a player, and it's an enemy, tell my sentryguns to attack it |
|
if ( pEntity->IsPlayer() && !pPlayer->InSameTeam(pEntity) ) |
|
{ |
|
DesignateSentriesToAttack( pEntity ); |
|
} |
|
else if ( pEntity->GetFlags() & FL_NPC ) |
|
{ |
|
// If it's an enemy NPC, tell my sentryguns to attack it |
|
if ( !pPlayer->InSameTeam( pEntity ) ) |
|
{ |
|
DesignateSentriesToAttack( pEntity ); |
|
} |
|
} |
|
else |
|
{ |
|
// Is it a sentrygun? If so, tell it to toggle it's sunken state. |
|
if ( pEntity->Classify() == CLASS_MILITARY ) |
|
{ |
|
CObjectSentrygun *pSentry = dynamic_cast<CObjectSentrygun *>(pEntity); |
|
if ( pSentry && pSentry->GetBuilder() == pPlayer ) |
|
{ |
|
pSentry->ToggleTurtle(); |
|
return; |
|
} |
|
else |
|
{ |
|
// If it's an enemy object, tell my sentryguns to attack it |
|
if ( !pPlayer->InSameTeam( pEntity ) ) |
|
{ |
|
DesignateSentriesToAttack( pEntity ); |
|
return; |
|
} |
|
} |
|
} |
|
|
|
// Is it a limpet mine? If so, detonate it |
|
CLimpetMine *pLimpet = dynamic_cast<CLimpetMine *>(pEntity); |
|
if ( pLimpet && pLimpet->IsLive() && pLimpet->GetThrower() == pPlayer ) |
|
{ |
|
pLimpet->Use( pPlayer, this, USE_ON, 0 ); |
|
} |
|
|
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Return true if the specified entity is a valid one for designation |
|
//----------------------------------------------------------------------------- |
|
bool CWeaponLimpetmine::ValidDesignationTarget( CBaseEntity *pEntity ) |
|
{ |
|
if( !pEntity ) |
|
return false; |
|
|
|
// Ignore the world |
|
if ((!pEntity) || ( pEntity->entindex() == 0 )) |
|
return false; |
|
|
|
CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() ); |
|
Assert(pPlayer); |
|
if(!pPlayer) |
|
return false; |
|
|
|
// Ignore players on my team |
|
if ( pEntity->IsPlayer() ) |
|
{ |
|
if( pEntity->InSameTeam(GetOwner()) ) |
|
return false; |
|
else |
|
return true; |
|
} |
|
|
|
// can either target my own sentry guns to turtle, or enemy buildings to target for sentries: |
|
if ( pEntity->Classify() == CLASS_MILITARY ) |
|
{ |
|
// Is it a sentry gun I built? |
|
if ( dynamic_cast<CObjectSentrygun *>(pEntity) && ((CObjectSentrygun*)pEntity)->GetBuilder() == pPlayer ) |
|
{ |
|
return true; |
|
} |
|
// Is it an enemy object? |
|
else if ( !pPlayer->InSameTeam( pEntity ) ) |
|
{ |
|
return true; |
|
} |
|
} |
|
|
|
// My limpet mines are valid |
|
CLimpetMine *pLimpet = dynamic_cast<CLimpetMine *>(pEntity); |
|
if ( pLimpet && pLimpet->IsLive() && pLimpet->GetThrower() == GetOwner() ) |
|
return true; |
|
|
|
// NPCs are valid |
|
if ( pEntity->GetFlags() & FL_NPC ) |
|
return true; |
|
|
|
return false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the player's sentryguns to all attack the specified target |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::DesignateSentriesToAttack( CBaseEntity *pEntity ) |
|
{ |
|
CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() ); |
|
if ( !pPlayer ) |
|
return; |
|
|
|
// Tell all this player's sentryguns |
|
for ( int i = 0; i < pPlayer->GetObjectCount(); i++ ) |
|
{ |
|
CBaseObject *pObj = pPlayer->GetObject(i); |
|
if ( !pObj ) |
|
continue; |
|
|
|
if ( pObj->IsSentrygun() ) |
|
{ |
|
CObjectSentrygun *pSentry = static_cast<CObjectSentrygun *>(pObj); |
|
pSentry->DesignateTarget( pEntity ); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CBaseEntity* CWeaponLimpetmine::GetDesignatedEntity( CBaseTFPlayer *pPlayer ) |
|
{ |
|
// Construct the start and end vectors. |
|
Vector vecSrc = pPlayer->Weapon_ShootPosition( ); |
|
Vector vecAiming; |
|
pPlayer->EyeVectors( &vecAiming ); |
|
Vector vecEnd = vecSrc + vecAiming * weapon_laserdesignator_range.GetFloat(); |
|
|
|
float fBestDistanceSq = FLT_MAX; |
|
CBaseEntity* pBestEntity = NULL; |
|
float fMaxDist = weapon_limpetmine_max_distance_off_trace.GetFloat(); |
|
float fMaxDistSq = fMaxDist * fMaxDist; |
|
|
|
// Check all limpets against a cylinder: |
|
if( CLimpetMine::allLimpets ) |
|
{ |
|
for ( CLimpetMine *pLimpet = CLimpetMine::allLimpets ;pLimpet; pLimpet = pLimpet->nextLimpet) |
|
{ |
|
// Find the closest limpet to the center of the cylinder: |
|
if( pLimpet->IsLive() && pLimpet->GetThrower() != NULL && pLimpet->GetThrower() == pPlayer ) |
|
{ |
|
Vector vecNearestPoint = PointOnLineNearestPoint( vecSrc, vecEnd, pLimpet->GetAbsOrigin() ); |
|
|
|
float fDistSq = ( pLimpet->GetAbsOrigin() - vecNearestPoint ).LengthSqr(); |
|
|
|
if (( fDistSq > fMaxDistSq ) || ( fDistSq >= fBestDistanceSq )) |
|
continue; |
|
|
|
if (TFGameRules()->IsBlockedByEnemyShields( vecSrc, pLimpet->GetAbsOrigin(), GetOwner()->GetTeamNumber() )) |
|
continue; |
|
|
|
pBestEntity = pLimpet; |
|
fBestDistanceSq = fDistSq; |
|
} |
|
} |
|
|
|
if( pBestEntity ) |
|
return pBestEntity; |
|
} |
|
|
|
// Check to see if we are designating a combat object: |
|
for ( int i = 0; i < pPlayer->GetObjectCount(); i++ ) |
|
{ |
|
CBaseObject *pObj = pPlayer->GetObject(i); |
|
if ( !pObj || !pObj->IsSentrygun() ) |
|
continue; |
|
|
|
Vector vecObjCenter = pObj->WorldSpaceCenter(); |
|
Vector vecNearestPoint = PointOnLineNearestPoint( vecSrc, vecEnd, vecObjCenter ); |
|
|
|
float fDistSq = ( vecObjCenter - vecNearestPoint ).LengthSqr(); |
|
|
|
if (( fDistSq > fMaxDistSq ) || ( fDistSq >= fBestDistanceSq )) |
|
continue; |
|
|
|
if (TFGameRules()->IsBlockedByEnemyShields( vecSrc, vecObjCenter, GetOwner()->GetTeamNumber() )) |
|
continue; |
|
|
|
pBestEntity = pObj; |
|
fBestDistanceSq = fDistSq; |
|
} |
|
|
|
// Valid or NULL |
|
return pBestEntity; |
|
} |
|
|
|
#endif |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::WeaponIdle( void ) |
|
{ |
|
if ( HasWeaponIdleTimeElapsed() ) |
|
{ |
|
if ( m_bDesignating || m_flStartedLaunchingAt ) |
|
{ |
|
SendWeaponAnim( ACT_VM_PRIMARYATTACK ); |
|
} |
|
else |
|
{ |
|
SendWeaponAnim( ACT_VM_IDLE ); |
|
} |
|
SetWeaponIdleTime( gpGlobals->curtime + 0.2 ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Start designating with the laser |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::StartDesignating( void ) |
|
{ |
|
m_bDesignating = true; |
|
|
|
// Add myself to the designated target list |
|
Vector vecOrigin(0,0,0); |
|
|
|
SendWeaponAnim( ACT_VM_PRIMARYATTACK ); |
|
|
|
#ifndef CLIENT_DLL |
|
CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() ); |
|
if ( !pPlayer ) |
|
return; |
|
|
|
if ( !m_pBeam ) |
|
{ |
|
m_pBeam = CBeam::BeamCreate( "sprites/laserbeam.vmt", 5 ); |
|
|
|
m_pBeam->PointEntInit( vec3_origin, this ); |
|
m_pBeam->SetEndAttachment( 1 ); |
|
m_pBeam->SetColor( 255, 32, 32 ); |
|
m_pBeam->SetBrightness( 255 ); |
|
m_pBeam->SetNoise( 0 ); |
|
m_pBeam->SetWidth( 0.5 ); |
|
m_pBeam->SetEndWidth( 0.5 ); |
|
} |
|
#endif |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Stop designating with the laser |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::StopDesignating( void ) |
|
{ |
|
SendWeaponAnim( ACT_VM_IDLE ); |
|
|
|
m_bDesignating = false; |
|
|
|
#ifndef CLIENT_DLL |
|
if ( m_pBeam ) |
|
{ |
|
UTIL_Remove( m_pBeam ); |
|
m_pBeam = NULL; |
|
} |
|
|
|
if ( m_hLaserDesignation ) |
|
{ |
|
m_hLaserDesignation->SetActive( false ); |
|
} |
|
|
|
// Remove any designated target: |
|
m_hDesignatedEntity.Set( NULL ); |
|
#endif |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Update the beam position and do designator functions |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::UpdateBeamTarget() |
|
{ |
|
CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() ); |
|
if ( !pPlayer ) |
|
return; |
|
|
|
// "Fire" the designator beam |
|
Vector vecSrc = pPlayer->Weapon_ShootPosition( ); |
|
Vector vecAiming; |
|
pPlayer->EyeVectors( &vecAiming ); |
|
Vector vecEnd = vecSrc + vecAiming * weapon_laserdesignator_range.GetFloat(); |
|
|
|
trace_t tr; |
|
TFGameRules()->WeaponTraceLine(vecSrc, vecEnd, MASK_SHOT, pPlayer, DMG_PROBE, &tr); |
|
|
|
// Only update our designated target point if we hit something |
|
#ifndef CLIENT_DLL |
|
if ( tr.fraction != 1.0 && m_bDesignating ) |
|
{ |
|
m_hLaserDesignation->SetActive( true ); |
|
m_hLaserDesignation->SetAbsOrigin( tr.endpos ); |
|
} |
|
else |
|
{ |
|
m_hLaserDesignation->SetActive( false ); |
|
} |
|
|
|
// Update beam visual |
|
if( m_pBeam ) |
|
{ |
|
m_pBeam->SetStartPos( tr.endpos ); |
|
m_pBeam->RelinkBeam(); |
|
} |
|
|
|
CBaseEntity* pEntity= NULL; |
|
|
|
// Perform designator functions |
|
// Did we hit something? |
|
//pEntity = CBaseEntity::Instance( tr.u.ent ); |
|
|
|
// If we hit a target we don't care about, try and grab the nearest valid target to our crosshair |
|
//if ( !ValidDesignationTarget( pEntity ) ) |
|
{ |
|
// Get the designated entity, ignoring trace information: |
|
pEntity = GetDesignatedEntity( pPlayer ); |
|
|
|
if( !ValidDesignationTarget( pEntity ) ) |
|
{ |
|
m_hDesignatedEntity.Set( NULL ); |
|
return; |
|
} |
|
} |
|
|
|
// We have a valid entity, light it up. |
|
m_hDesignatedEntity.Set( pEntity ); |
|
#endif |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CWeaponLimpetmine::DecrementLimpets( void ) |
|
{ |
|
#ifndef CLIENT_DLL |
|
if ( m_iDeployedLimpets ) |
|
{ |
|
m_iDeployedLimpets -= 1; |
|
} |
|
#endif |
|
} |
|
|
|
#ifdef CLIENT_DLL |
|
//----------------------------------------------------------------------------- |
|
// Purpose: Limpet mine's always selectable, because the laser designator can always fire |
|
//----------------------------------------------------------------------------- |
|
bool C_WeaponLimpetmine::CanBeSelected( void ) |
|
{ |
|
return true; |
|
} |
|
|
|
void C_WeaponLimpetmine::PreDataUpdate( DataUpdateType_t updateType ) |
|
{ |
|
BaseClass::PreDataUpdate( updateType ); |
|
|
|
m_hOldDesignatedEntity = m_hDesignatedEntity; |
|
} |
|
|
|
void C_WeaponLimpetmine::PostDataUpdate( DataUpdateType_t updateType ) |
|
{ |
|
BaseClass::PostDataUpdate( updateType ); |
|
|
|
if ( GetOwner() == C_BaseTFPlayer::GetLocalPlayer() ) |
|
{ |
|
// Old target isn't valid anymore, so reset it's render properties |
|
if ( m_hOldDesignatedEntity.Get() && m_hOldDesignatedEntity != m_hDesignatedEntity ) |
|
{ |
|
m_hOldDesignatedEntity->m_nRenderFX = m_eDesignatedEntityOriginalRenderFx; |
|
m_hOldDesignatedEntity->SetRenderMode( (RenderMode_t)m_eDesignatedEntityOriginalRenderMode ); |
|
} |
|
|
|
// New target? Set it's render properties |
|
if ( m_hDesignatedEntity != NULL && m_hOldDesignatedEntity != m_hDesignatedEntity ) |
|
{ |
|
// Store off original info for designated entity |
|
m_eDesignatedEntityOriginalRenderFx = m_hDesignatedEntity->m_nRenderFX; |
|
m_eDesignatedEntityOriginalRenderMode = m_hDesignatedEntity->GetRenderMode(); |
|
|
|
// Set up alpha blended pulsefast renderer |
|
m_hDesignatedEntity->m_nRenderFX = kRenderFxPulseFastWider; |
|
m_hDesignatedEntity->SetRenderMode( kRenderTransAlpha ); |
|
} |
|
} |
|
} |
|
|
|
#endif |