diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/episodic/c_npc_puppet.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/episodic/c_npc_puppet.cpp')
| -rw-r--r-- | game/client/episodic/c_npc_puppet.cpp | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/game/client/episodic/c_npc_puppet.cpp b/game/client/episodic/c_npc_puppet.cpp new file mode 100644 index 0000000..193b1da --- /dev/null +++ b/game/client/episodic/c_npc_puppet.cpp @@ -0,0 +1,167 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" +#include "c_ai_basenpc.h" +#include "bone_setup.h" + +// Must be the last file included +#include "memdbgon.h" + + +extern ConVar r_sequence_debug; + +class C_NPC_Puppet : public C_AI_BaseNPC +{ + DECLARE_CLASS( C_NPC_Puppet, C_AI_BaseNPC ); +public: + + virtual void ClientThink( void ); + virtual void OnDataChanged( DataUpdateType_t updateType ); + virtual void BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed ); + virtual void AccumulateLayers( IBoneSetup &boneSetup, Vector pos[], Quaternion q[], float currentTime ); + + EHANDLE m_hAnimationTarget; + int m_nTargetAttachment; + + DECLARE_CLIENTCLASS(); +}; + +IMPLEMENT_CLIENTCLASS_DT( C_NPC_Puppet, DT_NPC_Puppet, CNPC_Puppet ) + RecvPropEHandle( RECVINFO(m_hAnimationTarget) ), + RecvPropInt( RECVINFO(m_nTargetAttachment) ), +END_RECV_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_NPC_Puppet::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + if ( updateType == DATA_UPDATE_CREATED ) + { + SetNextClientThink( CLIENT_THINK_ALWAYS ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: We need to slam our position! +//----------------------------------------------------------------------------- +void C_NPC_Puppet::BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed ) +{ + if ( m_hAnimationTarget && m_nTargetAttachment != -1 ) + { + C_BaseAnimating *pTarget = m_hAnimationTarget->GetBaseAnimating(); + if ( pTarget ) + { + matrix3x4_t matTarget; + pTarget->GetAttachment( m_nTargetAttachment, matTarget ); + + MatrixCopy( matTarget, GetBoneForWrite( 0 ) ); + boneComputed.ClearAll(); // FIXME: Why is this calculated already? + boneComputed.MarkBone( 0 ); + } + } + + // Call the baseclass + BaseClass::BuildTransformations( pStudioHdr, pos, q, cameraTransform, boneMask, boneComputed ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_NPC_Puppet::ClientThink( void ) +{ + if ( m_hAnimationTarget == NULL ) + return; + + C_BaseAnimating *pTarget = m_hAnimationTarget->GetBaseAnimating(); + if ( pTarget == NULL ) + return; + + int nTargetSequence = pTarget->GetSequence(); + const char *pSequenceName = pTarget->GetSequenceName( nTargetSequence ); + + int nSequence = LookupSequence( pSequenceName ); + if ( nSequence >= 0 ) + { + if ( nSequence != GetSequence() ) + { + SetSequence( nSequence ); + UpdateVisibility(); + } + + SetCycle( pTarget->GetCycle() ); + SetPlaybackRate( pTarget->GetPlaybackRate() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_NPC_Puppet::AccumulateLayers( IBoneSetup &boneSetup, Vector pos[], Quaternion q[], float currentTime ) +{ + if ( m_hAnimationTarget == NULL ) + return; + + C_BaseAnimatingOverlay *pTarget = dynamic_cast<C_BaseAnimatingOverlay *>( m_hAnimationTarget->GetBaseAnimating() ); + if ( pTarget == NULL ) + return; + + // resort the layers + int layer[MAX_OVERLAYS]; + int i; + for (i = 0; i < MAX_OVERLAYS; i++) + { + layer[i] = MAX_OVERLAYS; + } + for (i = 0; i < pTarget->m_AnimOverlay.Count(); i++) + { + if (pTarget->m_AnimOverlay[i].m_nOrder < MAX_OVERLAYS) + { + layer[pTarget->m_AnimOverlay[i].m_nOrder] = i; + } + } + + int j; + for (j = 0; j < MAX_OVERLAYS; j++) + { + i = layer[ j ]; + if (i < pTarget->m_AnimOverlay.Count()) + { + float fWeight = pTarget->m_AnimOverlay[i].m_flWeight; + + if (fWeight > 0) + { + const char *pSequenceName = pTarget->GetSequenceName( pTarget->m_AnimOverlay[i].m_nSequence ); + + int nSequence = LookupSequence( pSequenceName ); + if ( nSequence >= 0 ) + { + float fCycle = pTarget->m_AnimOverlay[ i ].m_flCycle; + + fCycle = ClampCycle( fCycle, IsSequenceLooping( nSequence ) ); + + if (fWeight > 1) + fWeight = 1; + + boneSetup.AccumulatePose( pos, q, nSequence, fCycle, fWeight, currentTime, NULL ); + +#if _DEBUG + if (Q_stristr( boneSetup.GetStudioHdr()->pszName(), r_sequence_debug.GetString()) != NULL) + { + DevMsgRT( "%6.2f : %30s : %5.3f : %4.2f : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( nSequence ).pszLabel(), fCycle, fWeight, i ); + } +#endif + + } + } + } + } +} + |