Counter Strike : Global Offensive Source Code
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.

661 lines
19 KiB

  1. //========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Client side implementation of CBaseCombatWeapon.
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "history_resource.h"
  9. #include "iclientmode.h"
  10. #include "iinput.h"
  11. #include "weapon_selection.h"
  12. #include "hud_crosshair.h"
  13. #include "engine/ivmodelinfo.h"
  14. #include "tier0/vprof.h"
  15. #include "hltvcamera.h"
  16. #include "tier1/keyvalues.h"
  17. #include "toolframework/itoolframework.h"
  18. #include "toolframework_client.h"
  19. #if defined( CSTRIKE15 )
  20. #include "c_cs_player.h"
  21. #endif
  22. // memdbgon must be the last include file in a .cpp file!!!
  23. #include "tier0/memdbgon.h"
  24. //-----------------------------------------------------------------------------
  25. // Purpose:
  26. //-----------------------------------------------------------------------------
  27. void C_BaseCombatWeapon::SetDormant( bool bDormant )
  28. {
  29. // If I'm going from active to dormant and I'm carried by another player, holster me.
  30. if ( !IsDormant() && bDormant && GetOwner() && !IsCarriedByLocalPlayer() )
  31. {
  32. Holster( NULL );
  33. }
  34. BaseClass::SetDormant( bDormant );
  35. }
  36. //-----------------------------------------------------------------------------
  37. // Purpose:
  38. //-----------------------------------------------------------------------------
  39. void C_BaseCombatWeapon::NotifyShouldTransmit( ShouldTransmitState_t state )
  40. {
  41. BaseClass::NotifyShouldTransmit(state);
  42. if (state == SHOULDTRANSMIT_END)
  43. {
  44. if (m_iState == WEAPON_IS_ACTIVE)
  45. {
  46. m_iState = WEAPON_IS_CARRIED_BY_PLAYER;
  47. }
  48. }
  49. else if( state == SHOULDTRANSMIT_START )
  50. {
  51. // We don't check the value of m_iState because if the weapon is active, we need the state to match reguardless
  52. // of what it was.
  53. if( GetOwner() && GetOwner()->GetActiveWeapon() == this )
  54. {
  55. // Restore the Activeness of the weapon if we client-twiddled it off in the first case above.
  56. m_iState = WEAPON_IS_ACTIVE;
  57. }
  58. }
  59. }
  60. //-----------------------------------------------------------------------------
  61. // Purpose: To wrap PORTAL mod specific functionality into one place
  62. //-----------------------------------------------------------------------------
  63. static inline bool ShouldDrawLocalPlayer( C_BasePlayer *pl )
  64. {
  65. #if defined( PORTAL )
  66. return true;
  67. #else
  68. Assert( pl );
  69. return pl->ShouldDrawLocalPlayer();
  70. #endif
  71. }
  72. //-----------------------------------------------------------------------------
  73. // Purpose:
  74. //-----------------------------------------------------------------------------
  75. void C_BaseCombatWeapon::OnRestore()
  76. {
  77. BaseClass::OnRestore();
  78. // if the player is holding this weapon,
  79. // mark it as just restored so it won't show as a new pickup
  80. if ( C_BasePlayer::IsLocalPlayer( GetOwner() ) )
  81. {
  82. m_bJustRestored = true;
  83. }
  84. }
  85. void C_BaseCombatWeapon::UpdateOnRemove( void )
  86. {
  87. BaseClass::UpdateOnRemove();
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Purpose:
  91. // Input : bnewentity -
  92. //-----------------------------------------------------------------------------
  93. void C_BaseCombatWeapon::OnDataChanged( DataUpdateType_t updateType )
  94. {
  95. // Must update visibility prior to calling OnDataChanged so that
  96. // shadows are dealt with correctly.
  97. UpdateVisibility();
  98. BaseClass::OnDataChanged( updateType );
  99. // let the world model know we're updating, in case it wants to as well
  100. CBaseWeaponWorldModel *pWeaponWorldModel = GetWeaponWorldModel();
  101. if ( pWeaponWorldModel )
  102. {
  103. pWeaponWorldModel->OnDataChanged( updateType );
  104. }
  105. // If it's being carried by the *local* player, on the first update,
  106. // find the registered weapon for this ID
  107. C_BaseCombatCharacter *pOwner = GetOwner();
  108. C_BasePlayer *pPlayer = ToBasePlayer( pOwner );
  109. #if defined( CSTRIKE15 )
  110. C_CSPlayer *pObservedPlayer = GetHudPlayer();
  111. // check if weapon was dropped by local player or the player we are observing
  112. if ( pObservedPlayer == pPlayer && pObservedPlayer->State_Get() == STATE_ACTIVE )
  113. #else
  114. // check if weapon is carried by local player
  115. bool bIsLocalPlayer = C_BasePlayer::IsLocalPlayer( pPlayer );
  116. if ( bIsLocalPlayer )
  117. #endif
  118. {
  119. ACTIVE_SPLITSCREEN_PLAYER_GUARD( C_BasePlayer::GetSplitScreenSlotForPlayer( pPlayer ) );
  120. // If I was just picked up, or created & immediately carried, add myself to this client's list of weapons
  121. if ( m_iState != WEAPON_NOT_CARRIED && m_iOldState == WEAPON_NOT_CARRIED )
  122. {
  123. // Tell the HUD this weapon's been picked up
  124. if ( ShouldDrawPickup() )
  125. {
  126. CBaseHudWeaponSelection *pHudSelection = GetHudWeaponSelection();
  127. if ( pHudSelection )
  128. {
  129. pHudSelection->OnWeaponPickup( this );
  130. }
  131. }
  132. }
  133. }
  134. UpdateVisibility();
  135. m_iOldState = m_iState;
  136. m_bJustRestored = false;
  137. }
  138. //-----------------------------------------------------------------------------
  139. // Is anyone carrying it?
  140. //-----------------------------------------------------------------------------
  141. bool C_BaseCombatWeapon::IsBeingCarried() const
  142. {
  143. return ( m_hOwner.Get() != NULL );
  144. }
  145. //-----------------------------------------------------------------------------
  146. // Is the carrier alive?
  147. //-----------------------------------------------------------------------------
  148. bool C_BaseCombatWeapon::IsCarrierAlive() const
  149. {
  150. if ( !m_hOwner.Get() )
  151. return false;
  152. return m_hOwner.Get()->GetHealth() > 0;
  153. }
  154. //-----------------------------------------------------------------------------
  155. // Should this object cast shadows?
  156. //-----------------------------------------------------------------------------
  157. ShadowType_t C_BaseCombatWeapon::ShadowCastType()
  158. {
  159. if ( IsEffectActive( /*EF_NODRAW |*/ EF_NOSHADOW ) )
  160. return SHADOWS_NONE;
  161. if (!IsBeingCarried())
  162. return SHADOWS_RENDER_TO_TEXTURE;
  163. if (IsCarriedByLocalPlayer())
  164. return SHADOWS_NONE;
  165. return (m_iState != WEAPON_IS_CARRIED_BY_PLAYER) ? SHADOWS_RENDER_TO_TEXTURE : SHADOWS_NONE;
  166. }
  167. //-----------------------------------------------------------------------------
  168. // Purpose: This weapon is the active weapon, and it should now draw anything
  169. // it wants to. This gets called every frame.
  170. //-----------------------------------------------------------------------------
  171. void C_BaseCombatWeapon::Redraw()
  172. {
  173. if ( GetClientMode()->ShouldDrawCrosshair() )
  174. {
  175. DrawCrosshair();
  176. }
  177. // ammo drawing has been moved into hud_ammo.cpp
  178. }
  179. //-----------------------------------------------------------------------------
  180. // Purpose: Draw the weapon's crosshair
  181. //-----------------------------------------------------------------------------
  182. void C_BaseCombatWeapon::DrawCrosshair()
  183. {
  184. #ifndef INFESTED_DLL
  185. C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
  186. if ( !player )
  187. return;
  188. Color clr = GetHud().m_clrNormal;
  189. /*
  190. // TEST: if the thing under your crosshair is on a different team, light the crosshair with a different color.
  191. Vector vShootPos, vShootAngles;
  192. GetShootPosition( vShootPos, vShootAngles );
  193. Vector vForward;
  194. AngleVectors( vShootAngles, &vForward );
  195. // Change the color depending on if we're looking at a friend or an enemy.
  196. CPartitionFilterListMask filter( PARTITION_ALL_CLIENT_EDICTS );
  197. trace_t tr;
  198. traceline->TraceLine( vShootPos, vShootPos + vForward * 10000, COLLISION_GROUP_NONE, MASK_SHOT, &tr, true, ~0, &filter );
  199. if ( tr.index != 0 && tr.index != INVALID_CLIENTENTITY_HANDLE )
  200. {
  201. C_BaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( tr.index );
  202. if ( pEnt )
  203. {
  204. if ( pEnt->GetTeamNumber() != player->GetTeamNumber() )
  205. {
  206. g = b = 0;
  207. }
  208. }
  209. }
  210. */
  211. CHudCrosshair *crosshair = GET_HUDELEMENT( CHudCrosshair );
  212. if ( !crosshair )
  213. return;
  214. // Find out if this weapon's auto-aimed onto a target
  215. bool bOnTarget = ( m_iState == WEAPON_IS_ACTIVE ) && player->m_fOnTarget;
  216. if ( player->GetFOV() >= 90 )
  217. {
  218. // normal crosshairs
  219. if ( bOnTarget && GetWpnData().iconAutoaim )
  220. {
  221. clr[3] = 255;
  222. crosshair->SetCrosshair( GetWpnData().iconAutoaim, clr );
  223. }
  224. else if ( GetWpnData().iconCrosshair )
  225. {
  226. clr[3] = 255;
  227. crosshair->SetCrosshair( GetWpnData().iconCrosshair, clr );
  228. }
  229. else
  230. {
  231. crosshair->ResetCrosshair();
  232. }
  233. }
  234. else
  235. {
  236. Color white( 255, 255, 255, 255 );
  237. // zoomed crosshairs
  238. if (bOnTarget && GetWpnData().iconZoomedAutoaim)
  239. crosshair->SetCrosshair(GetWpnData().iconZoomedAutoaim, white);
  240. else if ( GetWpnData().iconZoomedCrosshair )
  241. crosshair->SetCrosshair( GetWpnData().iconZoomedCrosshair, white );
  242. else
  243. crosshair->ResetCrosshair();
  244. }
  245. #endif
  246. }
  247. //-----------------------------------------------------------------------------
  248. // Purpose: This weapon is the active weapon, and the viewmodel for it was just drawn.
  249. //-----------------------------------------------------------------------------
  250. void C_BaseCombatWeapon::ViewModelDrawn( int nFlags, C_BaseViewModel *pViewModel )
  251. {
  252. }
  253. //-----------------------------------------------------------------------------
  254. // Purpose: Returns true if this client's carrying this weapon
  255. //-----------------------------------------------------------------------------
  256. bool C_BaseCombatWeapon::IsCarriedByLocalPlayer( void )
  257. {
  258. if ( !GetOwner() )
  259. return false;
  260. return ( C_BasePlayer::IsLocalPlayer( GetOwner() ) );
  261. }
  262. //-----------------------------------------------------------------------------
  263. // Purpose: Returns true if this weapon is the local client's currently wielded weapon
  264. //-----------------------------------------------------------------------------
  265. bool C_BaseCombatWeapon::IsActiveByLocalPlayer( void )
  266. {
  267. if ( IsCarriedByLocalPlayer() )
  268. {
  269. return (m_iState == WEAPON_IS_ACTIVE);
  270. }
  271. return false;
  272. }
  273. bool C_BaseCombatWeapon::GetShootPosition( Vector &vOrigin, QAngle &vAngles )
  274. {
  275. // Get the entity because the weapon doesn't have the right angles.
  276. C_BaseCombatCharacter *pEnt = ToBaseCombatCharacter( GetOwner() );
  277. if ( pEnt )
  278. {
  279. if ( pEnt == C_BasePlayer::GetLocalPlayer() )
  280. {
  281. vAngles = pEnt->EyeAngles();
  282. }
  283. else
  284. {
  285. vAngles = pEnt->GetRenderAngles();
  286. }
  287. }
  288. else
  289. {
  290. vAngles.Init();
  291. }
  292. C_BasePlayer *player = ToBasePlayer( pEnt );
  293. bool bUseViewModel = false;
  294. if ( C_BasePlayer::IsLocalPlayer( pEnt ) )
  295. {
  296. ACTIVE_SPLITSCREEN_PLAYER_GUARD_ENT( pEnt );
  297. bUseViewModel = !player->ShouldDrawLocalPlayer();
  298. }
  299. QAngle vDummy;
  300. if ( IsActiveByLocalPlayer() && bUseViewModel )
  301. {
  302. C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL;
  303. if ( vm )
  304. {
  305. int iAttachment = vm->LookupAttachment( "muzzle" );
  306. if ( vm->GetAttachment( iAttachment, vOrigin, vDummy ) )
  307. {
  308. return true;
  309. }
  310. }
  311. }
  312. else
  313. {
  314. // Thirdperson
  315. int iAttachment = LookupAttachment( "muzzle" );
  316. if ( GetAttachment( iAttachment, vOrigin, vDummy ) )
  317. {
  318. return true;
  319. }
  320. }
  321. vOrigin = GetRenderOrigin();
  322. return false;
  323. }
  324. bool C_BaseCombatWeapon::ShouldSuppressForSplitScreenPlayer( int nSlot )
  325. {
  326. if ( BaseClass::ShouldSuppressForSplitScreenPlayer( nSlot ) )
  327. {
  328. return true;
  329. }
  330. C_BaseCombatCharacter *pOwner = GetOwner();
  331. // If the owner of this weapon is not allowed to draw in this split screen slot, then don't draw the weapon either.
  332. if ( pOwner && pOwner->ShouldSuppressForSplitScreenPlayer( nSlot ) )
  333. {
  334. return true;
  335. }
  336. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer( nSlot );
  337. // Carried by local player?
  338. // Only draw the weapon if we're in some kind of 3rd person mode because the viewmodel will do that otherwise.
  339. if ( pOwner == pLocalPlayer && !pLocalPlayer->ShouldDrawLocalPlayer() )
  340. {
  341. return true;
  342. }
  343. return false;
  344. }
  345. //-----------------------------------------------------------------------------
  346. // Purpose:
  347. // Output : Returns true on success, false on failure.
  348. //-----------------------------------------------------------------------------
  349. bool C_BaseCombatWeapon::ShouldDraw( void )
  350. {
  351. if ( IsEffectActive( EF_NODRAW ) )
  352. return false;
  353. // weapon has no owner, always draw it
  354. if ( !GetOwner() && !IsViewModel() )
  355. {
  356. return true;
  357. }
  358. else
  359. {
  360. CBaseWeaponWorldModel *pWeaponWorldModel = GetWeaponWorldModel();
  361. if ( pWeaponWorldModel )
  362. {
  363. return false; // the weapon world model will render in our place if it exists
  364. }
  365. else
  366. {
  367. // render only if equipped. The holstered model will render for weapons that aren't equipped
  368. return ( GetOwner() && GetOwner()->GetActiveWeapon() == this );
  369. }
  370. }
  371. }
  372. //-----------------------------------------------------------------------------
  373. // Purpose: Return true if a weapon-pickup icon should be displayed when this weapon is received
  374. //-----------------------------------------------------------------------------
  375. bool C_BaseCombatWeapon::ShouldDrawPickup( void )
  376. {
  377. if ( GetWeaponFlags() & ITEM_FLAG_NOITEMPICKUP )
  378. return false;
  379. if ( m_bJustRestored )
  380. return false;
  381. return true;
  382. }
  383. bool C_BaseCombatWeapon::IsFirstPersonSpectated( void )
  384. {
  385. // check if local player chases owner of this weapon in first person
  386. C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
  387. if ( localplayer && localplayer->IsObserver() && GetOwner() )
  388. {
  389. // don't draw weapon if chasing this guy as spectator
  390. // we don't check that in ShouldDraw() since this may change
  391. // without notification
  392. if ( localplayer->GetObserverMode() == OBS_MODE_IN_EYE &&
  393. localplayer->GetObserverTarget() == GetOwner() &&
  394. localplayer->GetObserverInterpState() != C_BasePlayer::OBSERVER_INTERP_TRAVELING )
  395. return true;
  396. }
  397. return false;
  398. }
  399. //----------------------------------------------------------------------------
  400. // Hooks into the fast path render system
  401. //----------------------------------------------------------------------------
  402. IClientModelRenderable* C_BaseCombatWeapon::GetClientModelRenderable()
  403. {
  404. if ( !m_bReadyToDraw )
  405. return 0;
  406. if( IsFirstPersonSpectated() )
  407. return NULL;
  408. VerifyAndSetContextSensitiveWeaponModel();
  409. return BaseClass::GetClientModelRenderable();
  410. }
  411. //-----------------------------------------------------------------------------
  412. // Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried
  413. // by this player, otherwise draw the worldmodel.
  414. //-----------------------------------------------------------------------------
  415. int C_BaseCombatWeapon::DrawModel( int flags, const RenderableInstance_t &instance )
  416. {
  417. VPROF_BUDGET( "C_BaseCombatWeapon::DrawModel", VPROF_BUDGETGROUP_MODEL_RENDERING );
  418. if ( !m_bReadyToDraw )
  419. return 0;
  420. if ( !IsVisible() )
  421. return 0;
  422. if( IsFirstPersonSpectated() )
  423. return 0;
  424. return BaseClass::DrawModel( flags, instance );
  425. }
  426. #ifdef _DEBUG
  427. ConVar stickers_enabled_thirdperson( "stickers_enabled_thirdperson", "1", FCVAR_DEVELOPMENTONLY, "Enable work-in-progress stickers on worldmodels." );
  428. ConVar stickers_debug_thirdperson_constant( "stickers_debug_thirdperson_constant", "0", FCVAR_DEVELOPMENTONLY, "Continually apply stickers on worldmodels. SLOW" );
  429. ConVar stickers_debug_thirdperson_ray( "stickers_debug_thirdperson_ray", "0", FCVAR_DEVELOPMENTONLY, "Show worldmodel sticker projection position and direction." );
  430. ConVar stickers_debug_thirdperson_ray_duration( "stickers_debug_thirdperson_ray_duration", "0.1", FCVAR_DEVELOPMENTONLY, "Duration to show sticker projection lines." );
  431. ConVar stickers_debug_thirdperson_size( "stickers_debug_thirdperson_size", "0", FCVAR_DEVELOPMENTONLY, "Override worldmodel sticker size." );
  432. extern ConVar stickers_debug_randomize;
  433. #endif
  434. void C_BaseCombatWeapon::ApplyThirdPersonStickers( C_BaseAnimating *pWeaponModelTargetOverride )
  435. {
  436. #ifdef _DEBUG
  437. if (stickers_enabled_thirdperson.GetBool() == 0)
  438. return;
  439. #endif
  440. if ( !IsAbsQueriesValid() )
  441. return;
  442. CEconItemView *pItem = GetEconItemView();
  443. if (!pItem)
  444. return;
  445. if ( pItem->GetNumSupportedStickerSlots() == 0 )
  446. return;
  447. C_BaseAnimating *pTargetModel = pWeaponModelTargetOverride ? pWeaponModelTargetOverride : this;
  448. if ( !pTargetModel->ShouldDraw() )
  449. return;
  450. MDLCACHE_CRITICAL_SECTION();
  451. pTargetModel->CreateModelInstance();
  452. if ( pTargetModel->GetModelInstance() != MODEL_INSTANCE_INVALID )
  453. {
  454. if ( modelrender->ModelHasDecals( pTargetModel->GetModelInstance() ) &&
  455. #ifdef _DEBUG
  456. !stickers_debug_thirdperson_constant.GetBool() &&
  457. #endif
  458. pItem->ItemHasAnyStickersApplied() )
  459. {
  460. return; //decals are already applied
  461. }
  462. modelrender->RemoveAllDecals( pTargetModel->GetModelInstance() );
  463. }
  464. else
  465. {
  466. return; //no model instance
  467. }
  468. matrix3x4_t weaponBoneTransform;
  469. const char* const szStickerBoneLookupTable[] = {
  470. "sticker_a",
  471. "sticker_b",
  472. "sticker_c",
  473. "sticker_d",
  474. "sticker_e"
  475. };
  476. for (int i=0; i<pItem->GetNumSupportedStickerSlots(); i++ )
  477. {
  478. IMaterial *pStickerMaterialThirdPerson = pItem->GetStickerIMaterialBySlotIndex(i, true);
  479. if ( !pStickerMaterialThirdPerson )
  480. {
  481. #ifdef _DEBUG
  482. if ( stickers_debug_randomize.GetBool() )
  483. {
  484. pItem->GenerateStickerMaterials();
  485. pStickerMaterialThirdPerson = pItem->GetStickerIMaterialBySlotIndex(i, true);
  486. }
  487. else
  488. {
  489. continue;
  490. }
  491. #else
  492. continue; //sticker material is not valid
  493. #endif
  494. }
  495. //if the weapon model has world model sticker projection points, use those
  496. //otherwise use schema values
  497. Vector vecWorldRayOrigin, vecWorldRayDirection;
  498. bool bWeaponProvidedStickerAttachments = false;
  499. int nStickerAttachmentBoneIndex = pTargetModel->LookupBone( szStickerBoneLookupTable[i] );
  500. if ( nStickerAttachmentBoneIndex != -1 )
  501. {
  502. pTargetModel->GetBoneTransform( nStickerAttachmentBoneIndex, weaponBoneTransform );
  503. MatrixPosition( weaponBoneTransform, vecWorldRayOrigin );
  504. Vector a,b;
  505. MatrixVectors( weaponBoneTransform, &vecWorldRayDirection, &a, &b );
  506. bWeaponProvidedStickerAttachments = true;
  507. }
  508. else
  509. {
  510. int nBIndex = pTargetModel->LookupBone( pItem->GetStickerWorldModelBoneParentNameBySlotIndex(i) );
  511. if ( nBIndex == -1 )
  512. continue; //couldn't find the parent bone this sticker slot wanted
  513. pTargetModel->GetBoneTransform( nBIndex, weaponBoneTransform );
  514. Ray_t stickerRayLocal;
  515. stickerRayLocal.Init( pItem->GetStickerSlotWorldProjectionStartBySlotIndex( i ),
  516. pItem->GetStickerSlotWorldProjectionEndBySlotIndex( i ) );
  517. VectorTransform( stickerRayLocal.m_Start, weaponBoneTransform, vecWorldRayOrigin );
  518. VectorRotate( stickerRayLocal.m_Delta, weaponBoneTransform, vecWorldRayDirection );
  519. }
  520. #ifdef _DEBUG
  521. if ( stickers_debug_thirdperson_ray.GetBool() )
  522. {
  523. debugoverlay->AddBoxOverlay( vecWorldRayOrigin, Vector(-0.25,-0.25,-0.25), Vector(0.5,0.5,0.5), QAngle(0,0,0), 255, 0, 0, 180, stickers_debug_thirdperson_ray_duration.GetFloat() );
  524. debugoverlay->AddLineOverlay( vecWorldRayOrigin, vecWorldRayOrigin + vecWorldRayDirection, 0,255,0, true, stickers_debug_thirdperson_ray_duration.GetFloat() );
  525. }
  526. #endif
  527. Ray_t stickerRayWorld;
  528. stickerRayWorld.Init( vecWorldRayOrigin, vecWorldRayOrigin + (3*vecWorldRayDirection) );
  529. VMatrix vmatrix_weaponBoneTransform( weaponBoneTransform );
  530. Vector vecStickerUp = vmatrix_weaponBoneTransform.GetLeft();
  531. if ( bWeaponProvidedStickerAttachments )
  532. {
  533. //content defined sticker attachments are z-up
  534. vecStickerUp = -vmatrix_weaponBoneTransform.GetUp();
  535. }
  536. #ifdef _DEBUG
  537. float flStickerSize = (stickers_debug_thirdperson_size.GetFloat() == 0) ? stickers_debug_thirdperson_size.GetFloat() : 1.2f;
  538. pTargetModel->GetBaseEntity()->AddStudioMaterialDecal( stickerRayWorld, pStickerMaterialThirdPerson, flStickerSize, vecStickerUp );
  539. #else
  540. pTargetModel->GetBaseEntity()->AddStudioMaterialDecal( stickerRayWorld, pStickerMaterialThirdPerson, 1.2f, vecStickerUp );
  541. #endif
  542. }
  543. //Msg( "Applied stickers to: %s\n", this->GetName() );
  544. }
  545. //-----------------------------------------------------------------------------
  546. // tool recording
  547. //-----------------------------------------------------------------------------
  548. void C_BaseCombatWeapon::GetToolRecordingState( KeyValues *msg )
  549. {
  550. if ( !ToolsEnabled() )
  551. return;
  552. Assert(false);
  553. }