initial
This commit is contained in:
661
game/client/c_basecombatweapon.cpp
Normal file
661
game/client/c_basecombatweapon.cpp
Normal file
@@ -0,0 +1,661 @@
|
||||
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client side implementation of CBaseCombatWeapon.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "history_resource.h"
|
||||
#include "iclientmode.h"
|
||||
#include "iinput.h"
|
||||
#include "weapon_selection.h"
|
||||
#include "hud_crosshair.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include "hltvcamera.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "toolframework/itoolframework.h"
|
||||
#include "toolframework_client.h"
|
||||
#if defined( CSTRIKE15 )
|
||||
#include "c_cs_player.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::SetDormant( bool bDormant )
|
||||
{
|
||||
// If I'm going from active to dormant and I'm carried by another player, holster me.
|
||||
if ( !IsDormant() && bDormant && GetOwner() && !IsCarriedByLocalPlayer() )
|
||||
{
|
||||
Holster( NULL );
|
||||
}
|
||||
|
||||
BaseClass::SetDormant( bDormant );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::NotifyShouldTransmit( ShouldTransmitState_t state )
|
||||
{
|
||||
BaseClass::NotifyShouldTransmit(state);
|
||||
|
||||
if (state == SHOULDTRANSMIT_END)
|
||||
{
|
||||
if (m_iState == WEAPON_IS_ACTIVE)
|
||||
{
|
||||
m_iState = WEAPON_IS_CARRIED_BY_PLAYER;
|
||||
}
|
||||
}
|
||||
else if( state == SHOULDTRANSMIT_START )
|
||||
{
|
||||
// We don't check the value of m_iState because if the weapon is active, we need the state to match reguardless
|
||||
// of what it was.
|
||||
if( GetOwner() && GetOwner()->GetActiveWeapon() == this )
|
||||
{
|
||||
// Restore the Activeness of the weapon if we client-twiddled it off in the first case above.
|
||||
m_iState = WEAPON_IS_ACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: To wrap PORTAL mod specific functionality into one place
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline bool ShouldDrawLocalPlayer( C_BasePlayer *pl )
|
||||
{
|
||||
#if defined( PORTAL )
|
||||
return true;
|
||||
#else
|
||||
Assert( pl );
|
||||
return pl->ShouldDrawLocalPlayer();
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::OnRestore()
|
||||
{
|
||||
BaseClass::OnRestore();
|
||||
|
||||
// if the player is holding this weapon,
|
||||
// mark it as just restored so it won't show as a new pickup
|
||||
if ( C_BasePlayer::IsLocalPlayer( GetOwner() ) )
|
||||
{
|
||||
m_bJustRestored = true;
|
||||
}
|
||||
}
|
||||
|
||||
void C_BaseCombatWeapon::UpdateOnRemove( void )
|
||||
{
|
||||
BaseClass::UpdateOnRemove();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bnewentity -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
// Must update visibility prior to calling OnDataChanged so that
|
||||
// shadows are dealt with correctly.
|
||||
UpdateVisibility();
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
// let the world model know we're updating, in case it wants to as well
|
||||
CBaseWeaponWorldModel *pWeaponWorldModel = GetWeaponWorldModel();
|
||||
if ( pWeaponWorldModel )
|
||||
{
|
||||
pWeaponWorldModel->OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
// If it's being carried by the *local* player, on the first update,
|
||||
// find the registered weapon for this ID
|
||||
|
||||
C_BaseCombatCharacter *pOwner = GetOwner();
|
||||
C_BasePlayer *pPlayer = ToBasePlayer( pOwner );
|
||||
|
||||
#if defined( CSTRIKE15 )
|
||||
C_CSPlayer *pObservedPlayer = GetHudPlayer();
|
||||
// check if weapon was dropped by local player or the player we are observing
|
||||
if ( pObservedPlayer == pPlayer && pObservedPlayer->State_Get() == STATE_ACTIVE )
|
||||
#else
|
||||
// check if weapon is carried by local player
|
||||
bool bIsLocalPlayer = C_BasePlayer::IsLocalPlayer( pPlayer );
|
||||
if ( bIsLocalPlayer )
|
||||
#endif
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD( C_BasePlayer::GetSplitScreenSlotForPlayer( pPlayer ) );
|
||||
|
||||
// If I was just picked up, or created & immediately carried, add myself to this client's list of weapons
|
||||
if ( m_iState != WEAPON_NOT_CARRIED && m_iOldState == WEAPON_NOT_CARRIED )
|
||||
{
|
||||
// Tell the HUD this weapon's been picked up
|
||||
if ( ShouldDrawPickup() )
|
||||
{
|
||||
CBaseHudWeaponSelection *pHudSelection = GetHudWeaponSelection();
|
||||
if ( pHudSelection )
|
||||
{
|
||||
pHudSelection->OnWeaponPickup( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateVisibility();
|
||||
|
||||
m_iOldState = m_iState;
|
||||
|
||||
m_bJustRestored = false;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is anyone carrying it?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::IsBeingCarried() const
|
||||
{
|
||||
return ( m_hOwner.Get() != NULL );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is the carrier alive?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::IsCarrierAlive() const
|
||||
{
|
||||
if ( !m_hOwner.Get() )
|
||||
return false;
|
||||
|
||||
return m_hOwner.Get()->GetHealth() > 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Should this object cast shadows?
|
||||
//-----------------------------------------------------------------------------
|
||||
ShadowType_t C_BaseCombatWeapon::ShadowCastType()
|
||||
{
|
||||
if ( IsEffectActive( /*EF_NODRAW |*/ EF_NOSHADOW ) )
|
||||
return SHADOWS_NONE;
|
||||
|
||||
if (!IsBeingCarried())
|
||||
return SHADOWS_RENDER_TO_TEXTURE;
|
||||
|
||||
if (IsCarriedByLocalPlayer())
|
||||
return SHADOWS_NONE;
|
||||
|
||||
return (m_iState != WEAPON_IS_CARRIED_BY_PLAYER) ? SHADOWS_RENDER_TO_TEXTURE : SHADOWS_NONE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This weapon is the active weapon, and it should now draw anything
|
||||
// it wants to. This gets called every frame.
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::Redraw()
|
||||
{
|
||||
if ( GetClientMode()->ShouldDrawCrosshair() )
|
||||
{
|
||||
DrawCrosshair();
|
||||
}
|
||||
|
||||
// ammo drawing has been moved into hud_ammo.cpp
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draw the weapon's crosshair
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::DrawCrosshair()
|
||||
{
|
||||
#ifndef INFESTED_DLL
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
Color clr = GetHud().m_clrNormal;
|
||||
/*
|
||||
|
||||
// TEST: if the thing under your crosshair is on a different team, light the crosshair with a different color.
|
||||
Vector vShootPos, vShootAngles;
|
||||
GetShootPosition( vShootPos, vShootAngles );
|
||||
|
||||
Vector vForward;
|
||||
AngleVectors( vShootAngles, &vForward );
|
||||
|
||||
|
||||
// Change the color depending on if we're looking at a friend or an enemy.
|
||||
CPartitionFilterListMask filter( PARTITION_ALL_CLIENT_EDICTS );
|
||||
trace_t tr;
|
||||
traceline->TraceLine( vShootPos, vShootPos + vForward * 10000, COLLISION_GROUP_NONE, MASK_SHOT, &tr, true, ~0, &filter );
|
||||
|
||||
if ( tr.index != 0 && tr.index != INVALID_CLIENTENTITY_HANDLE )
|
||||
{
|
||||
C_BaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( tr.index );
|
||||
if ( pEnt )
|
||||
{
|
||||
if ( pEnt->GetTeamNumber() != player->GetTeamNumber() )
|
||||
{
|
||||
g = b = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
CHudCrosshair *crosshair = GET_HUDELEMENT( CHudCrosshair );
|
||||
if ( !crosshair )
|
||||
return;
|
||||
|
||||
// Find out if this weapon's auto-aimed onto a target
|
||||
bool bOnTarget = ( m_iState == WEAPON_IS_ACTIVE ) && player->m_fOnTarget;
|
||||
|
||||
if ( player->GetFOV() >= 90 )
|
||||
{
|
||||
// normal crosshairs
|
||||
if ( bOnTarget && GetWpnData().iconAutoaim )
|
||||
{
|
||||
clr[3] = 255;
|
||||
|
||||
crosshair->SetCrosshair( GetWpnData().iconAutoaim, clr );
|
||||
}
|
||||
else if ( GetWpnData().iconCrosshair )
|
||||
{
|
||||
clr[3] = 255;
|
||||
crosshair->SetCrosshair( GetWpnData().iconCrosshair, clr );
|
||||
}
|
||||
else
|
||||
{
|
||||
crosshair->ResetCrosshair();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Color white( 255, 255, 255, 255 );
|
||||
|
||||
// zoomed crosshairs
|
||||
if (bOnTarget && GetWpnData().iconZoomedAutoaim)
|
||||
crosshair->SetCrosshair(GetWpnData().iconZoomedAutoaim, white);
|
||||
else if ( GetWpnData().iconZoomedCrosshair )
|
||||
crosshair->SetCrosshair( GetWpnData().iconZoomedCrosshair, white );
|
||||
else
|
||||
crosshair->ResetCrosshair();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This weapon is the active weapon, and the viewmodel for it was just drawn.
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::ViewModelDrawn( int nFlags, C_BaseViewModel *pViewModel )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns true if this client's carrying this weapon
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::IsCarriedByLocalPlayer( void )
|
||||
{
|
||||
if ( !GetOwner() )
|
||||
return false;
|
||||
|
||||
return ( C_BasePlayer::IsLocalPlayer( GetOwner() ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns true if this weapon is the local client's currently wielded weapon
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::IsActiveByLocalPlayer( void )
|
||||
{
|
||||
if ( IsCarriedByLocalPlayer() )
|
||||
{
|
||||
return (m_iState == WEAPON_IS_ACTIVE);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool C_BaseCombatWeapon::GetShootPosition( Vector &vOrigin, QAngle &vAngles )
|
||||
{
|
||||
// Get the entity because the weapon doesn't have the right angles.
|
||||
C_BaseCombatCharacter *pEnt = ToBaseCombatCharacter( GetOwner() );
|
||||
if ( pEnt )
|
||||
{
|
||||
if ( pEnt == C_BasePlayer::GetLocalPlayer() )
|
||||
{
|
||||
vAngles = pEnt->EyeAngles();
|
||||
}
|
||||
else
|
||||
{
|
||||
vAngles = pEnt->GetRenderAngles();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vAngles.Init();
|
||||
}
|
||||
|
||||
C_BasePlayer *player = ToBasePlayer( pEnt );
|
||||
bool bUseViewModel = false;
|
||||
if ( C_BasePlayer::IsLocalPlayer( pEnt ) )
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD_ENT( pEnt );
|
||||
bUseViewModel = !player->ShouldDrawLocalPlayer();
|
||||
}
|
||||
|
||||
QAngle vDummy;
|
||||
if ( IsActiveByLocalPlayer() && bUseViewModel )
|
||||
{
|
||||
C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL;
|
||||
if ( vm )
|
||||
{
|
||||
int iAttachment = vm->LookupAttachment( "muzzle" );
|
||||
if ( vm->GetAttachment( iAttachment, vOrigin, vDummy ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Thirdperson
|
||||
int iAttachment = LookupAttachment( "muzzle" );
|
||||
if ( GetAttachment( iAttachment, vOrigin, vDummy ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
vOrigin = GetRenderOrigin();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool C_BaseCombatWeapon::ShouldSuppressForSplitScreenPlayer( int nSlot )
|
||||
{
|
||||
if ( BaseClass::ShouldSuppressForSplitScreenPlayer( nSlot ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
C_BaseCombatCharacter *pOwner = GetOwner();
|
||||
|
||||
// If the owner of this weapon is not allowed to draw in this split screen slot, then don't draw the weapon either.
|
||||
if ( pOwner && pOwner->ShouldSuppressForSplitScreenPlayer( nSlot ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer( nSlot );
|
||||
|
||||
// Carried by local player?
|
||||
// Only draw the weapon if we're in some kind of 3rd person mode because the viewmodel will do that otherwise.
|
||||
if ( pOwner == pLocalPlayer && !pLocalPlayer->ShouldDrawLocalPlayer() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::ShouldDraw( void )
|
||||
{
|
||||
|
||||
if ( IsEffectActive( EF_NODRAW ) )
|
||||
return false;
|
||||
|
||||
// weapon has no owner, always draw it
|
||||
if ( !GetOwner() && !IsViewModel() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CBaseWeaponWorldModel *pWeaponWorldModel = GetWeaponWorldModel();
|
||||
if ( pWeaponWorldModel )
|
||||
{
|
||||
return false; // the weapon world model will render in our place if it exists
|
||||
}
|
||||
else
|
||||
{
|
||||
// render only if equipped. The holstered model will render for weapons that aren't equipped
|
||||
return ( GetOwner() && GetOwner()->GetActiveWeapon() == this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return true if a weapon-pickup icon should be displayed when this weapon is received
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::ShouldDrawPickup( void )
|
||||
{
|
||||
if ( GetWeaponFlags() & ITEM_FLAG_NOITEMPICKUP )
|
||||
return false;
|
||||
|
||||
if ( m_bJustRestored )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool C_BaseCombatWeapon::IsFirstPersonSpectated( void )
|
||||
{
|
||||
// check if local player chases owner of this weapon in first person
|
||||
C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( localplayer && localplayer->IsObserver() && GetOwner() )
|
||||
{
|
||||
// don't draw weapon if chasing this guy as spectator
|
||||
// we don't check that in ShouldDraw() since this may change
|
||||
// without notification
|
||||
if ( localplayer->GetObserverMode() == OBS_MODE_IN_EYE &&
|
||||
localplayer->GetObserverTarget() == GetOwner() &&
|
||||
localplayer->GetObserverInterpState() != C_BasePlayer::OBSERVER_INTERP_TRAVELING )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Hooks into the fast path render system
|
||||
//----------------------------------------------------------------------------
|
||||
IClientModelRenderable* C_BaseCombatWeapon::GetClientModelRenderable()
|
||||
{
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
if( IsFirstPersonSpectated() )
|
||||
return NULL;
|
||||
|
||||
VerifyAndSetContextSensitiveWeaponModel();
|
||||
|
||||
return BaseClass::GetClientModelRenderable();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried
|
||||
// by this player, otherwise draw the worldmodel.
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_BaseCombatWeapon::DrawModel( int flags, const RenderableInstance_t &instance )
|
||||
{
|
||||
VPROF_BUDGET( "C_BaseCombatWeapon::DrawModel", VPROF_BUDGETGROUP_MODEL_RENDERING );
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
if ( !IsVisible() )
|
||||
return 0;
|
||||
|
||||
if( IsFirstPersonSpectated() )
|
||||
return 0;
|
||||
|
||||
return BaseClass::DrawModel( flags, instance );
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
ConVar stickers_enabled_thirdperson( "stickers_enabled_thirdperson", "1", FCVAR_DEVELOPMENTONLY, "Enable work-in-progress stickers on worldmodels." );
|
||||
|
||||
ConVar stickers_debug_thirdperson_constant( "stickers_debug_thirdperson_constant", "0", FCVAR_DEVELOPMENTONLY, "Continually apply stickers on worldmodels. SLOW" );
|
||||
ConVar stickers_debug_thirdperson_ray( "stickers_debug_thirdperson_ray", "0", FCVAR_DEVELOPMENTONLY, "Show worldmodel sticker projection position and direction." );
|
||||
ConVar stickers_debug_thirdperson_ray_duration( "stickers_debug_thirdperson_ray_duration", "0.1", FCVAR_DEVELOPMENTONLY, "Duration to show sticker projection lines." );
|
||||
ConVar stickers_debug_thirdperson_size( "stickers_debug_thirdperson_size", "0", FCVAR_DEVELOPMENTONLY, "Override worldmodel sticker size." );
|
||||
|
||||
extern ConVar stickers_debug_randomize;
|
||||
#endif
|
||||
|
||||
void C_BaseCombatWeapon::ApplyThirdPersonStickers( C_BaseAnimating *pWeaponModelTargetOverride )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (stickers_enabled_thirdperson.GetBool() == 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if ( !IsAbsQueriesValid() )
|
||||
return;
|
||||
|
||||
CEconItemView *pItem = GetEconItemView();
|
||||
if (!pItem)
|
||||
return;
|
||||
|
||||
if ( pItem->GetNumSupportedStickerSlots() == 0 )
|
||||
return;
|
||||
|
||||
C_BaseAnimating *pTargetModel = pWeaponModelTargetOverride ? pWeaponModelTargetOverride : this;
|
||||
|
||||
if ( !pTargetModel->ShouldDraw() )
|
||||
return;
|
||||
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
|
||||
pTargetModel->CreateModelInstance();
|
||||
if ( pTargetModel->GetModelInstance() != MODEL_INSTANCE_INVALID )
|
||||
{
|
||||
if ( modelrender->ModelHasDecals( pTargetModel->GetModelInstance() ) &&
|
||||
#ifdef _DEBUG
|
||||
!stickers_debug_thirdperson_constant.GetBool() &&
|
||||
#endif
|
||||
pItem->ItemHasAnyStickersApplied() )
|
||||
{
|
||||
return; //decals are already applied
|
||||
}
|
||||
modelrender->RemoveAllDecals( pTargetModel->GetModelInstance() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return; //no model instance
|
||||
}
|
||||
|
||||
matrix3x4_t weaponBoneTransform;
|
||||
|
||||
const char* const szStickerBoneLookupTable[] = {
|
||||
"sticker_a",
|
||||
"sticker_b",
|
||||
"sticker_c",
|
||||
"sticker_d",
|
||||
"sticker_e"
|
||||
};
|
||||
|
||||
for (int i=0; i<pItem->GetNumSupportedStickerSlots(); i++ )
|
||||
{
|
||||
IMaterial *pStickerMaterialThirdPerson = pItem->GetStickerIMaterialBySlotIndex(i, true);
|
||||
|
||||
if ( !pStickerMaterialThirdPerson )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if ( stickers_debug_randomize.GetBool() )
|
||||
{
|
||||
pItem->GenerateStickerMaterials();
|
||||
pStickerMaterialThirdPerson = pItem->GetStickerIMaterialBySlotIndex(i, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
continue; //sticker material is not valid
|
||||
#endif
|
||||
}
|
||||
|
||||
//if the weapon model has world model sticker projection points, use those
|
||||
//otherwise use schema values
|
||||
|
||||
Vector vecWorldRayOrigin, vecWorldRayDirection;
|
||||
|
||||
bool bWeaponProvidedStickerAttachments = false;
|
||||
|
||||
int nStickerAttachmentBoneIndex = pTargetModel->LookupBone( szStickerBoneLookupTable[i] );
|
||||
if ( nStickerAttachmentBoneIndex != -1 )
|
||||
{
|
||||
pTargetModel->GetBoneTransform( nStickerAttachmentBoneIndex, weaponBoneTransform );
|
||||
MatrixPosition( weaponBoneTransform, vecWorldRayOrigin );
|
||||
Vector a,b;
|
||||
MatrixVectors( weaponBoneTransform, &vecWorldRayDirection, &a, &b );
|
||||
bWeaponProvidedStickerAttachments = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
int nBIndex = pTargetModel->LookupBone( pItem->GetStickerWorldModelBoneParentNameBySlotIndex(i) );
|
||||
if ( nBIndex == -1 )
|
||||
continue; //couldn't find the parent bone this sticker slot wanted
|
||||
|
||||
pTargetModel->GetBoneTransform( nBIndex, weaponBoneTransform );
|
||||
|
||||
Ray_t stickerRayLocal;
|
||||
stickerRayLocal.Init( pItem->GetStickerSlotWorldProjectionStartBySlotIndex( i ),
|
||||
pItem->GetStickerSlotWorldProjectionEndBySlotIndex( i ) );
|
||||
|
||||
VectorTransform( stickerRayLocal.m_Start, weaponBoneTransform, vecWorldRayOrigin );
|
||||
VectorRotate( stickerRayLocal.m_Delta, weaponBoneTransform, vecWorldRayDirection );
|
||||
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ( stickers_debug_thirdperson_ray.GetBool() )
|
||||
{
|
||||
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() );
|
||||
debugoverlay->AddLineOverlay( vecWorldRayOrigin, vecWorldRayOrigin + vecWorldRayDirection, 0,255,0, true, stickers_debug_thirdperson_ray_duration.GetFloat() );
|
||||
}
|
||||
#endif
|
||||
|
||||
Ray_t stickerRayWorld;
|
||||
stickerRayWorld.Init( vecWorldRayOrigin, vecWorldRayOrigin + (3*vecWorldRayDirection) );
|
||||
|
||||
VMatrix vmatrix_weaponBoneTransform( weaponBoneTransform );
|
||||
|
||||
Vector vecStickerUp = vmatrix_weaponBoneTransform.GetLeft();
|
||||
if ( bWeaponProvidedStickerAttachments )
|
||||
{
|
||||
//content defined sticker attachments are z-up
|
||||
vecStickerUp = -vmatrix_weaponBoneTransform.GetUp();
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
float flStickerSize = (stickers_debug_thirdperson_size.GetFloat() == 0) ? stickers_debug_thirdperson_size.GetFloat() : 1.2f;
|
||||
pTargetModel->GetBaseEntity()->AddStudioMaterialDecal( stickerRayWorld, pStickerMaterialThirdPerson, flStickerSize, vecStickerUp );
|
||||
#else
|
||||
pTargetModel->GetBaseEntity()->AddStudioMaterialDecal( stickerRayWorld, pStickerMaterialThirdPerson, 1.2f, vecStickerUp );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//Msg( "Applied stickers to: %s\n", this->GetName() );
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// tool recording
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::GetToolRecordingState( KeyValues *msg )
|
||||
{
|
||||
if ( !ToolsEnabled() )
|
||||
return;
|
||||
|
||||
Assert(false);
|
||||
}
|
||||
Reference in New Issue
Block a user