summaryrefslogtreecommitdiff
path: root/game/shared/tf/tf_weapon_laser_pointer.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/shared/tf/tf_weapon_laser_pointer.cpp
downloadarchived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz
archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip
Diffstat (limited to 'game/shared/tf/tf_weapon_laser_pointer.cpp')
-rw-r--r--game/shared/tf/tf_weapon_laser_pointer.cpp462
1 files changed, 462 insertions, 0 deletions
diff --git a/game/shared/tf/tf_weapon_laser_pointer.cpp b/game/shared/tf/tf_weapon_laser_pointer.cpp
new file mode 100644
index 0000000..6e8bb79
--- /dev/null
+++ b/game/shared/tf/tf_weapon_laser_pointer.cpp
@@ -0,0 +1,462 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Engineer's Laser Pointer
+//
+//=============================================================================//
+#include "cbase.h"
+#include "tf_fx_shared.h"
+#include "tf_weapon_laser_pointer.h"
+#include "in_buttons.h"
+
+// Client specific.
+#ifdef CLIENT_DLL
+#include "view.h"
+#include "beamdraw.h"
+#include "vgui/ISurface.h"
+#include <vgui/ILocalize.h>
+#include "vgui_controls/Controls.h"
+#include "hud_crosshair.h"
+#include "functionproxy.h"
+#include "materialsystem/imaterialvar.h"
+#include "toolframework_client.h"
+#include "input.h"
+#include "sourcevr/isourcevirtualreality.h"
+
+// forward declarations
+void ToolFramework_RecordMaterialParams( IMaterial *pMaterial );
+#else
+#include "tf_gamerules.h"
+#include "tf_obj_sentrygun.h"
+#endif
+
+#define TF_WEAPON_SNIPERRIFLE_CHARGE_PER_SEC 50.0
+#define TF_WEAPON_SNIPERRIFLE_UNCHARGE_PER_SEC 75.0
+#define TF_WEAPON_SNIPERRIFLE_DAMAGE_MIN 50
+#define TF_WEAPON_SNIPERRIFLE_DAMAGE_MAX 150
+#define TF_WEAPON_SNIPERRIFLE_RELOAD_TIME 1.5f
+#define TF_WEAPON_SNIPERRIFLE_ZOOM_TIME 0.3f
+
+#define TF_WEAPON_SNIPERRIFLE_NO_CRIT_AFTER_ZOOM_TIME 0.2f
+
+#define LASER_DOT_SPRITE_RED "effects/sniperdot_red.vmt"
+#define LASER_DOT_SPRITE_BLUE "effects/sniperdot_blue.vmt"
+
+//=============================================================================
+//
+// Weapon Laser Pointer tables.
+//
+
+IMPLEMENT_NETWORKCLASS_ALIASED( TFLaserPointer, DT_TFLaserPointer )
+
+BEGIN_NETWORK_TABLE_NOBASE( CTFLaserPointer, DT_LaserPointerLocalData )
+END_NETWORK_TABLE()
+
+BEGIN_NETWORK_TABLE( CTFLaserPointer, DT_TFLaserPointer )
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CTFLaserPointer )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( tf_weapon_laser_pointer, CTFLaserPointer );
+PRECACHE_WEAPON_REGISTER( tf_weapon_laser_pointer );
+
+//=============================================================================
+//
+// Weapon Laser Pointer functions.
+//
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor.
+//-----------------------------------------------------------------------------
+CTFLaserPointer::CTFLaserPointer()
+{
+#ifdef GAME_DLL
+ m_hLaserDot = NULL;
+#endif
+
+ m_flNextAttack = 0.f;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor.
+//-----------------------------------------------------------------------------
+CTFLaserPointer::~CTFLaserPointer()
+{
+// Server specific.
+#ifdef GAME_DLL
+ DestroyLaserDot();
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFLaserPointer::Precache()
+{
+ BaseClass::Precache();
+
+ PrecacheModel( LASER_DOT_SPRITE_RED );
+ PrecacheModel( LASER_DOT_SPRITE_BLUE );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CTFLaserPointer::Deploy( void )
+{
+ if ( BaseClass::Deploy() )
+ {
+ #ifdef GAME_DLL
+ SetContextThink( &CTFLaserPointer::CreateLaserDot, gpGlobals->curtime + 0.5f, "CREATE_LASER_DOT" );
+ #endif
+
+ m_bDeployed = true;
+
+ return true;
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CTFLaserPointer::Holster( CBaseCombatWeapon *pSwitchingTo )
+{
+ if ( BaseClass::Holster( pSwitchingTo ) )
+ {
+ #ifdef GAME_DLL
+ DestroyLaserDot();
+ #endif
+
+ m_bDeployed = false;
+
+ return true;
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFLaserPointer::ItemPostFrame( void )
+{
+ if ( !m_bDeployed )
+ return;
+
+ // Get the owning player.
+ CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
+ if ( !pPlayer )
+ return;
+
+#ifdef GAME_DLL
+ if ( m_hLaserDot )
+ {
+ UpdateLaserDot();
+ }
+#endif
+
+ BaseClass::ItemPostFrame();
+
+ // Return to idle.
+ if ( GetIdealActivity() == ACT_ITEM1_VM_RELOAD && !( pPlayer->m_nButtons & IN_ATTACK ) )
+ {
+ SendWeaponAnim( ACT_ITEM1_RELOAD_FINISH );
+ if ( gpGlobals->curtime - m_flStartedFiring > 5.f )
+ {
+ m_bDoHandIdle = true;
+ m_flTimeWeaponIdle = gpGlobals->curtime + SequenceDuration();
+ }
+ }
+}
+
+void CTFLaserPointer::WeaponIdle( void )
+{
+#ifdef GAME_DLL
+ if ( m_bDoHandIdle && !WeaponShouldBeLowered() && HasWeaponIdleTimeElapsed() )
+ {
+ m_bDoHandIdle = false;
+ SendWeaponAnim( ACT_ITEM1_VM_IDLE_2 );
+ m_flTimeWeaponIdle = gpGlobals->curtime + SequenceDuration();
+ return;
+ }
+#endif
+
+ BaseClass::WeaponIdle();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFLaserPointer::PrimaryAttack( void )
+{
+ CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() );
+ if ( !pPlayer )
+ return;
+
+ if ( !CanAttack() )
+ return;
+#ifdef GAME_DLL
+ CObjectSentrygun *pSentry = dynamic_cast<CObjectSentrygun*>( pPlayer->GetObjectOfType( OBJ_SENTRYGUN ) );
+ if ( !pSentry )
+ return;
+
+ pSentry->FireNextFrame();
+
+ if ( GetIdealActivity() != ACT_ITEM1_VM_RELOAD )
+ {
+ m_flStartedFiring = gpGlobals->curtime;
+ }
+
+ SendWeaponAnim( ACT_ITEM1_VM_RELOAD );
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFLaserPointer::SecondaryAttack( void )
+{
+ CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() );
+ if ( !pPlayer )
+ return;
+
+ if ( !CanAttack() )
+ return;
+#ifdef GAME_DLL
+ CObjectSentrygun *pSentry = dynamic_cast<CObjectSentrygun*>( pPlayer->GetObjectOfType( OBJ_SENTRYGUN ) );
+ if ( !pSentry )
+ return;
+
+ if ( pSentry->GetUpgradeLevel() == 3 )
+ {
+ pSentry->FireRocketNextFrame();
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFLaserPointer::CreateLaserDot( void )
+{
+#ifdef GAME_DLL
+ if ( !m_bDeployed )
+ return;
+
+ if ( m_hLaserDot )
+ return;
+
+ CBaseCombatCharacter *pPlayer = GetOwner();
+ if ( !pPlayer )
+ return;
+
+ m_hLaserDot = CLaserDot::Create( GetAbsOrigin(), pPlayer, true );
+ m_hLaserDot->ChangeTeam( pPlayer->GetTeamNumber() );
+
+ UpdateLaserDot();
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFLaserPointer::DestroyLaserDot( void )
+{
+#ifdef GAME_DLL
+ CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
+ if ( pPlayer )
+ {
+ CObjectSentrygun *pSentry = dynamic_cast<CObjectSentrygun*>( pPlayer->GetObjectOfType( OBJ_SENTRYGUN ) );
+ if ( pSentry )
+ {
+ pSentry->ClearTarget();
+ }
+ }
+
+ if ( m_hLaserDot )
+ {
+ UTIL_Remove( m_hLaserDot );
+ m_hLaserDot = NULL;
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFLaserPointer::UpdateLaserDot( void )
+{
+#ifdef GAME_DLL
+ CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
+ if ( !pPlayer )
+ return;
+
+ Vector vecMuzzlePos = pPlayer->Weapon_ShootPosition();
+ Vector forward;
+ pPlayer->EyeVectors( &forward );
+ Vector vecEndPos = vecMuzzlePos + ( forward * MAX_TRACE_LENGTH );
+
+ trace_t trace;
+ CTraceFilterIgnoreTeammatesAndTeamObjects filter( pPlayer, COLLISION_GROUP_NONE, pPlayer->GetTeamNumber() );
+ UTIL_TraceLine( vecMuzzlePos, vecEndPos, MASK_SOLID, &filter, &trace );
+
+ if ( m_hLaserDot )
+ {
+ CBaseEntity *pEntity = NULL;
+ if ( trace.DidHitNonWorldEntity() )
+ {
+ pEntity = trace.m_pEnt;
+ if ( !pEntity || !pEntity->m_takedamage )
+ {
+ pEntity = NULL;
+ }
+ else if ( pEntity->IsPlayer() )
+ {
+ // We lased a player target. We want to auto-aim on this guy for a short period of time.
+ CObjectSentrygun *pSentry = dynamic_cast<CObjectSentrygun*>( pPlayer->GetObjectOfType( OBJ_SENTRYGUN ) );
+ if ( pSentry )
+ {
+ pSentry->SetAutoAimTarget( ToTFPlayer( pEntity ) );
+ }
+ }
+ }
+
+ m_hLaserDot->Update( pEntity, trace.endpos, trace.plane.normal );
+ }
+#endif
+}
+
+//=============================================================================
+//
+// Laser Dot functions.
+//
+
+IMPLEMENT_NETWORKCLASS_ALIASED( LaserDot, DT_LaserDot )
+
+BEGIN_NETWORK_TABLE( CLaserDot, DT_LaserDot )
+END_NETWORK_TABLE()
+
+LINK_ENTITY_TO_CLASS( env_laserdot, CLaserDot );
+
+BEGIN_DATADESC( CLaserDot )
+END_DATADESC()
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor.
+//-----------------------------------------------------------------------------
+CLaserDot::CLaserDot( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor.
+//-----------------------------------------------------------------------------
+CLaserDot::~CLaserDot( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CLaserDot* CLaserDot::Create( const Vector &origin, CBaseEntity *pOwner, bool bVisibleDot )
+{
+#ifdef CLIENT_DLL
+ return NULL;
+#else
+ CLaserDot *pDot = static_cast<CLaserDot*>( CBaseEntity::Create( "env_laserdot", origin, QAngle( 0.0f, 0.0f, 0.0f ) ) );
+ if ( !pDot )
+ return NULL;
+
+ pDot->SetMoveType( MOVETYPE_NONE );
+ pDot->AddSolidFlags( FSOLID_NOT_SOLID );
+ pDot->AddEffects( EF_NOSHADOW );
+ UTIL_SetSize( pDot, -Vector( 4.0f, 4.0f, 4.0f ), Vector( 4.0f, 4.0f, 4.0f ) );
+
+ pDot->SetOwnerEntity( pOwner );
+
+ pDot->AddEFlags( EFL_FORCE_CHECK_TRANSMIT );
+
+ return pDot;
+#endif
+}
+
+#ifdef CLIENT_DLL
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CLaserDot::DrawModel( int flags )
+{
+ // Get the owning player.
+ C_TFPlayer *pPlayer = ToTFPlayer( GetOwnerEntity() );
+ if ( !pPlayer )
+ return -1;
+
+ // Get the sprite rendering position.
+ Vector vecEndPos;
+
+ float flSize = 6.0;
+
+ if ( !pPlayer->IsDormant() )
+ {
+ Vector vecAttachment, vecDir;
+
+ float flDist = MAX_TRACE_LENGTH;
+
+ // Always draw the dot in front of our faces when in first-person.
+ if ( pPlayer->IsLocalPlayer() )
+ {
+ // Take our view position and orientation
+ vecAttachment = CurrentViewOrigin();
+ vecDir = CurrentViewForward();
+
+ if ( UseVR() )
+ {
+ // It will basically be a copy of CSniperDot::GetRenderingPositions in tf_weapon_sniperrife.cpp
+ Assert ( !"Ask Joe Ludwig to fix CLaserDot::DrawModel() for VR." );
+ }
+
+ // Clamp the forward distance for the sniper's firstperson
+ flDist = 384;
+
+ flSize = 2.0;
+ }
+ else
+ {
+ // Take the owning player eye position and direction.
+ vecAttachment = pPlayer->EyePosition();
+ QAngle angles = pPlayer->EyeAngles();
+ AngleVectors( angles, &vecDir );
+ }
+
+ trace_t trace;
+ CTraceFilterIgnoreTeammatesAndTeamObjects filter( pPlayer, COLLISION_GROUP_NONE, pPlayer->GetTeamNumber() );
+ UTIL_TraceLine( vecAttachment, vecAttachment + ( vecDir * flDist ), MASK_SOLID, &filter, &trace );
+
+ // Backup off the hit plane, towards the source
+ vecEndPos = trace.endpos + vecDir * -4;
+ }
+ else
+ {
+ // Just use our position if we can't predict it otherwise.
+ vecEndPos = GetAbsOrigin();
+ }
+
+ // Draw our laser dot in space.
+ CMatRenderContextPtr pRenderContext( materials );
+ pRenderContext->Bind( m_hSpriteMaterial, this );
+
+ float flLifeTime = gpGlobals->curtime - m_flChargeStartTime;
+ float flStrength = RemapValClamped( flLifeTime, 0.0, TF_WEAPON_SNIPERRIFLE_DAMAGE_MAX / TF_WEAPON_SNIPERRIFLE_CHARGE_PER_SEC, 0.1, 1.0 );
+
+ color32 innercolor = { 255, 255, 255, 255 };
+ color32 outercolor = { 255, 255, 255, 128 };
+
+ DrawSprite( vecEndPos, flSize, flSize, outercolor );
+ DrawSprite( vecEndPos, flSize * flStrength, flSize * flStrength, innercolor );
+
+ // Successful.
+ return 1;
+}
+#endif