Merge pull request #316 from Blixibon/mapbase/feature/improved-animstate

Playermodel legs and other player anim improvements
This commit is contained in:
Blixibon 2025-02-28 20:34:44 -06:00 committed by GitHub
commit fccb3f8e38
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 828 additions and 81 deletions

View File

@ -90,11 +90,10 @@ static inline bool ShouldDrawLocalPlayerViewModel( void )
C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
if (localplayer)
{
if (localplayer->m_bDrawPlayerModelExternally)
if (localplayer->DrawingPlayerModelExternally() && localplayer->InFirstPersonView())
{
// If this isn't the main view, draw the weapon.
view_id_t viewID = CurrentViewID();
if (viewID != VIEW_MAIN && viewID != VIEW_INTRO_CAMERA)
if (!localplayer->InPerspectiveView())
return false;
}
@ -224,8 +223,16 @@ ShadowType_t C_BaseCombatWeapon::ShadowCastType()
if (!IsBeingCarried())
return SHADOWS_RENDER_TO_TEXTURE;
if (IsCarriedByLocalPlayer() && !C_BasePlayer::ShouldDrawLocalPlayer())
return SHADOWS_NONE;
if (IsCarriedByLocalPlayer())
{
if (!C_BasePlayer::ShouldDrawLocalPlayer())
return SHADOWS_NONE;
#ifdef MAPBASE
if (C_BasePlayer::GetLocalPlayer() && C_BasePlayer::GetLocalPlayer()->ShadowCastType() == SHADOWS_NONE)
return SHADOWS_NONE;
#endif
}
return SHADOWS_RENDER_TO_TEXTURE;
}
@ -458,7 +465,7 @@ bool C_BaseCombatWeapon::ShouldDraw( void )
#ifdef MAPBASE
// We're drawing this in non-main views, handle it in DrawModel()
if ( pLocalPlayer->m_bDrawPlayerModelExternally )
if ( pLocalPlayer->DrawingPlayerModelExternally() )
return true;
#endif
@ -511,11 +518,10 @@ int C_BaseCombatWeapon::DrawModel( int flags )
if ( localplayer )
{
#ifdef MAPBASE
if (localplayer->m_bDrawPlayerModelExternally)
if (GetOwner() == localplayer && localplayer->DrawingPlayerModelExternally())
{
// If this isn't the main view, draw the weapon.
view_id_t viewID = CurrentViewID();
if ( (!localplayer->InFirstPersonView() || (viewID != VIEW_MAIN && viewID != VIEW_INTRO_CAMERA)) && (viewID != VIEW_SHADOW_DEPTH_TEXTURE || !localplayer->IsEffectActive(EF_DIMLIGHT)) )
if ( (!localplayer->InPerspectiveView() || !localplayer->InFirstPersonView()) && (CurrentViewID() != VIEW_SHADOW_DEPTH_TEXTURE || !localplayer->IsEffectActive(EF_DIMLIGHT)))
{
// TODO: Is this inefficient?
int nModelIndex = GetModelIndex();
@ -534,6 +540,10 @@ int C_BaseCombatWeapon::DrawModel( int flags )
return iDraw;
}
else
{
return 0;
}
}
#endif
if ( localplayer->IsObserver() && GetOwner() )
@ -551,6 +561,24 @@ int C_BaseCombatWeapon::DrawModel( int flags )
return BaseClass::DrawModel( flags );
}
#ifdef MAPBASE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool C_BaseCombatWeapon::DispatchMuzzleEffect( const char *options, bool isFirstPerson )
{
// Don't show muzzle flashes in first-person
C_BasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if (pPlayer)
{
if (pPlayer->DrawingPlayerModelExternally() && pPlayer->InFirstPersonView())
return false;
}
return BaseClass::DispatchMuzzleEffect( options, isFirstPerson );
}
#endif
//-----------------------------------------------------------------------------
// Allows the client-side entity to override what the network tells it to use for

View File

@ -125,6 +125,16 @@ ConVar demo_fov_override( "demo_fov_override", "0", FCVAR_CLIENTDLL | FCVAR_DONT
// This value is found by hand, and a good value depends more on the in-game models than on actual human shapes.
ConVar cl_meathook_neck_pivot_ingame_up( "cl_meathook_neck_pivot_ingame_up", "7.0" );
ConVar cl_meathook_neck_pivot_ingame_fwd( "cl_meathook_neck_pivot_ingame_fwd", "3.0" );
#ifdef MAPBASE
ConVar cl_meathook_neck_pivot_override( "cl_meathook_neck_pivot_override", "0", FCVAR_NONE, "Overrides playermodel values for meathook and uses cvars only" );
//-------------------------------------------------------------------------------------
ConVar cl_playermodel_draw_externally_override( "cl_playermodel_draw_externally_override", "-1", FCVAR_ARCHIVE, "Overrides developer-placed options to draw the player's model externally." );
ConVar cl_playermodel_legs_override( "cl_playermodel_legs_override", "-1", FCVAR_ARCHIVE, "Overrides developer-placed options to draw the player's model below the camera." );
ConVar cl_playermodel_legs_scale_bones( "cl_playermodel_legs_scale_bones", "1" );
#endif
void RecvProxy_LocalVelocityX( const CRecvProxyData *pData, void *pStruct, void *pOut );
void RecvProxy_LocalVelocityY( const CRecvProxyData *pData, void *pStruct, void *pOut );
@ -280,6 +290,7 @@ END_RECV_TABLE()
// See baseplayer_shared.h for more details.
RecvPropInt ( RECVINFO( m_spawnflags ), 0, RecvProxy_ShiftPlayerSpawnflags ),
RecvPropBool ( RECVINFO( m_bDrawPlayerLegs ) ),
RecvPropBool ( RECVINFO( m_bDrawPlayerModelExternally ) ),
RecvPropBool ( RECVINFO( m_bInTriggerFall ) ),
#endif
@ -1486,13 +1497,186 @@ bool C_BasePlayer::ShouldInterpolate()
}
#ifdef MAPBASE
bool C_BasePlayer::InPerspectiveView() const
{
// VIEW_NONE is used by the water intersection view, see CAboveWaterView::CIntersectionView::Draw()
// (TODO: Consider changing the view ID at the source to VIEW_REFRACTION? VIEW_NONE could be an oversight)
view_id_t viewID = CurrentViewID();
return (viewID == VIEW_MAIN || viewID == VIEW_INTRO_CAMERA || viewID == VIEW_REFRACTION || viewID == VIEW_NONE);
}
bool C_BasePlayer::DrawingPlayerModelExternally() const
{
if (cl_playermodel_draw_externally_override.GetInt() > -1)
return cl_playermodel_draw_externally_override.GetBool();
return m_bDrawPlayerModelExternally;
}
bool C_BasePlayer::DrawingLegs() const
{
if (cl_playermodel_legs_override.GetInt() > -1)
return cl_playermodel_legs_override.GetBool();
// For now, don't draw legs if looking up in any way
// (fixes issues with some animations causing clipping with chest)
if (GetAbsAngles().x < 0.0f)
return false;
return m_bDrawPlayerLegs;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStudioHdr *C_BasePlayer::OnNewModel( void )
{
CStudioHdr *hdr = BaseClass::OnNewModel();
if (!hdr)
return NULL;
KeyValues *modelKeyValues = new KeyValues( "" );
CUtlBuffer buf( 1024, 0, CUtlBuffer::TEXT_BUFFER );
// Init values
m_FirstPersonModelData.Reset();
if (!modelinfo->GetModelKeyValue( GetModel(), buf ))
{
modelKeyValues->deleteThis();
return hdr;
}
if (modelKeyValues->LoadFromBuffer( modelinfo->GetModelName( GetModel() ), buf ))
{
CUtlVector<string_t> iszUsedNames;
for (KeyValues *pkvModelBlock = modelKeyValues; pkvModelBlock != nullptr; pkvModelBlock = pkvModelBlock->GetNextKey())
{
KeyValues *pkvPlayerModelData = pkvModelBlock->FindKey( "playermodel_data" );
if (pkvPlayerModelData)
{
m_FirstPersonModelData.ParseModelData( this, pkvPlayerModelData );
break;
}
}
}
modelKeyValues->deleteThis();
return hdr;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BasePlayer::FirstPersonModelData_t::ParseModelData( C_BasePlayer *pPlayer, KeyValues *pkvPlayerModelData )
{
m_flFirstPersonNeckPivotUp = pkvPlayerModelData->GetFloat( "neck_pivot_up", FLT_MAX );
m_flFirstPersonNeckPivotFwd = pkvPlayerModelData->GetFloat( "neck_pivot_fwd", FLT_MAX );
m_flFirstPersonNeckPivotDuckUp = pkvPlayerModelData->GetFloat( "neck_pivot_duck_up", FLT_MAX );
m_flFirstPersonNeckPivotDuckFwd = pkvPlayerModelData->GetFloat( "neck_pivot_duck_fwd", FLT_MAX );
KeyValues *pkvBoneScales = pkvPlayerModelData->FindKey( "bone_transforms" );
if (pkvBoneScales)
{
KeyValues *pkvSpineTransforms = pkvBoneScales->FindKey( "spine" );
if (pkvSpineTransforms)
{
for (KeyValues *pkvBone = pkvSpineTransforms->GetFirstSubKey(); pkvBone != nullptr; pkvBone = pkvBone->GetNextKey())
{
int nBone = pPlayer->LookupBone( pkvBone->GetName() );
if (nBone == -1)
continue;
m_FirstPersonBoneScales[BoneScales_Spine].Insert(nBone, pkvBone->GetFloat());
}
}
KeyValues *pkvArmsTransforms = pkvBoneScales->FindKey( "arms" );
if (pkvArmsTransforms)
{
for (KeyValues *pkvBone = pkvArmsTransforms->GetFirstSubKey(); pkvBone != nullptr; pkvBone = pkvBone->GetNextKey())
{
int nBone = pPlayer->LookupBone( pkvBone->GetName() );
if (nBone == -1)
continue;
m_FirstPersonBoneScales[BoneScales_Arms].Insert( nBone, pkvBone->GetFloat() );
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: move position and rotation transforms into global matrices
//-----------------------------------------------------------------------------
void C_BasePlayer::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion *q, const matrix3x4_t &cameraTransform, int boneMask, CBoneBitList &boneComputed )
{
BaseClass::BuildTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed );
if (DrawingLegs() && InPerspectiveView() && InFirstPersonView())
{
//BuildFirstPersonMeathookTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed, "ValveBiped.Bip01_Head1" );
if (cl_playermodel_legs_scale_bones.GetBool())
{
// For now, only do transforms when we have an active weapon
// (since we typically just cull stuff influenced by viewmodels and upper-body weapon posture, like arms)
if ((GetActiveWeapon() && !GetActiveWeapon()->IsEffectActive( EF_NODRAW )) || GetUseEntity())
{
matrix3x4_t *pFirstZero = NULL;
for (int nMap = 0; nMap < FirstPersonModelData_t::BoneScales_Max; nMap++)
{
const CUtlMap<int, float> &scaleMap = m_FirstPersonModelData.m_FirstPersonBoneScales[nMap];
FOR_EACH_MAP( scaleMap, i )
{
int nBone = scaleMap.Key(i);
if (nBone == -1)
continue;
if (!(hdr->boneFlags( nBone ) & boneMask))
continue;
float flScale = scaleMap.Element(i);
matrix3x4_t &mTransform = GetBoneForWrite( nBone );
if (flScale == 0.0f)
{
if (!pFirstZero)
{
MatrixScaleByZero( mTransform );
pFirstZero = &mTransform;
}
else
{
// Keep zeroes in one place
MatrixCopy( *pFirstZero, mTransform );
}
}
else
{
MatrixScaleBy( flScale, mTransform );
}
}
}
}
}
}
}
#endif
bool C_BasePlayer::ShouldDraw()
{
#ifdef MAPBASE
// We have to "always draw" a player with m_bDrawPlayerModelExternally in order to show up in whatever rendering list all of the views use,
// but we can't put this in ShouldDrawThisPlayer() because we would have no way of knowing if it stomps the other checks that draw the player model anyway.
// As a result, we have to put it here in the central ShouldDraw() function. DrawModel() makes sure we only draw in non-main views and nothing's drawing the model anyway.
return (ShouldDrawThisPlayer() || m_bDrawPlayerModelExternally) && BaseClass::ShouldDraw();
return (ShouldDrawThisPlayer() || DrawingPlayerModelExternally() || DrawingLegs()) && BaseClass::ShouldDraw();
#else
return ShouldDrawThisPlayer() && BaseClass::ShouldDraw();
#endif
@ -1501,12 +1685,16 @@ bool C_BasePlayer::ShouldDraw()
int C_BasePlayer::DrawModel( int flags )
{
#ifdef MAPBASE
if (m_bDrawPlayerModelExternally)
if (DrawingLegs() && InFirstPersonView() && InPerspectiveView())
{
return BaseClass::DrawModel( flags );
}
if (DrawingPlayerModelExternally())
{
// Draw the player in any view except the main or "intro" view, both of which are default first-person views.
// HACKHACK: Also don't draw in shadow depth textures if the player's flashlight is on, as that causes the playermodel to block it.
view_id_t viewID = CurrentViewID();
if (viewID == VIEW_MAIN || viewID == VIEW_INTRO_CAMERA || (viewID == VIEW_SHADOW_DEPTH_TEXTURE && IsEffectActive(EF_DIMLIGHT)))
if (InPerspectiveView() || (CurrentViewID() == VIEW_SHADOW_DEPTH_TEXTURE && IsEffectActive(EF_DIMLIGHT)))
{
// Make sure the player model wouldn't draw anyway...
if (!ShouldDrawThisPlayer())
@ -3057,13 +3245,21 @@ void C_BasePlayer::BuildFirstPersonMeathookTransformations( CStudioHdr *hdr, Vec
return;
}
#ifdef MAPBASE
if ( !InPerspectiveView() )
#else
if ( !DrawingMainView() )
#endif
{
return;
}
// If we aren't drawing the player anyway, don't mess with the bones. This can happen in Portal.
#ifdef MAPBASE
if ( !ShouldDrawThisPlayer() && !DrawingPlayerModelExternally() && !DrawingLegs() )
#else
if( !ShouldDrawThisPlayer() )
#endif
{
return;
}
@ -3084,6 +3280,63 @@ void C_BasePlayer::BuildFirstPersonMeathookTransformations( CStudioHdr *hdr, Vec
Vector vHeadTransformTranslation ( mHeadTransform[0][3], mHeadTransform[1][3], mHeadTransform[2][3] );
float flNeckPivotUp = cl_meathook_neck_pivot_ingame_up.GetFloat();
float flNeckPivotFwd = cl_meathook_neck_pivot_ingame_fwd.GetFloat();
#ifdef MAPBASE
if (DrawingLegs() && !cl_meathook_neck_pivot_override.GetBool())
{
if (m_FirstPersonModelData.m_flFirstPersonNeckPivotUp != FLT_MAX || m_FirstPersonModelData.m_flFirstPersonNeckPivotFwd != FLT_MAX)
{
if (m_FirstPersonModelData.m_flFirstPersonNeckPivotUp != FLT_MAX)
flNeckPivotUp = m_FirstPersonModelData.m_flFirstPersonNeckPivotUp;
if (m_FirstPersonModelData.m_flFirstPersonNeckPivotFwd != FLT_MAX)
flNeckPivotFwd = m_FirstPersonModelData.m_flFirstPersonNeckPivotFwd;
if (GetFlags() & FL_DUCKING || m_Local.m_flDucktime > 0.0f)
{
if (!IsLocalPlayer() || m_Local.m_flDucktime <= 0.0f)
{
if (m_FirstPersonModelData.m_flFirstPersonNeckPivotDuckUp != FLT_MAX)
flNeckPivotUp = m_FirstPersonModelData.m_flFirstPersonNeckPivotDuckUp;
if (m_FirstPersonModelData.m_flFirstPersonNeckPivotDuckFwd != FLT_MAX)
flNeckPivotFwd = m_FirstPersonModelData.m_flFirstPersonNeckPivotDuckFwd;
}
else
{
bool bDucking;
if (IsLocalPlayer())
bDucking = input->GetButtonBits(0) & IN_DUCK;
else
bDucking = GetCurrentUserCommand()->buttons & IN_DUCK;
// HACKHACK using constants from game movement
float flPerc = SimpleSpline( RemapValClamped( m_Local.m_flDucktime, bDucking ? 600.0f : 800.0f, 1000.0f, 0.0f, 1.0f ) );
if (bDucking)
{
// Ducking
//Msg( "Ducking with perc %f (%f)\n", flPerc, m_Local.m_flDucktime );
if (m_FirstPersonModelData.m_flFirstPersonNeckPivotDuckUp != FLT_MAX)
flNeckPivotUp = FLerp( m_FirstPersonModelData.m_flFirstPersonNeckPivotDuckUp, flNeckPivotUp, flPerc );
if (m_FirstPersonModelData.m_flFirstPersonNeckPivotDuckFwd != FLT_MAX)
flNeckPivotFwd = FLerp( m_FirstPersonModelData.m_flFirstPersonNeckPivotDuckFwd, flNeckPivotFwd, flPerc );
}
else
{
// Unducking
//Msg( "Unducking with perc %f (%f)\n", flPerc, m_Local.m_flDucktime );
if (m_FirstPersonModelData.m_flFirstPersonNeckPivotDuckUp != FLT_MAX)
flNeckPivotUp = FLerp( flNeckPivotUp, m_FirstPersonModelData.m_flFirstPersonNeckPivotDuckUp, flPerc );
if (m_FirstPersonModelData.m_flFirstPersonNeckPivotDuckFwd != FLT_MAX)
flNeckPivotFwd = FLerp( flNeckPivotFwd, m_FirstPersonModelData.m_flFirstPersonNeckPivotDuckFwd, flPerc );
}
}
}
}
}
#endif
// Find out where the player's head (driven by the HMD) is in the world.
// We can't move this with animations or effects without causing nausea, so we need to move
// the whole body so that the animated head is in the right place to match the player-controlled head.
@ -3100,7 +3353,7 @@ void C_BasePlayer::BuildFirstPersonMeathookTransformations( CStudioHdr *hdr, Vec
// The head bone is the neck pivot point of the in-game character.
Vector vRealMidEyePos = mWorldFromMideye.GetTranslation();
vRealPivotPoint = vRealMidEyePos - ( mWorldFromMideye.GetUp() * cl_meathook_neck_pivot_ingame_up.GetFloat() ) - ( mWorldFromMideye.GetForward() * cl_meathook_neck_pivot_ingame_fwd.GetFloat() );
vRealPivotPoint = vRealMidEyePos - ( mWorldFromMideye.GetUp() * flNeckPivotUp ) - ( mWorldFromMideye.GetForward() * flNeckPivotFwd );
}
else
{
@ -3108,7 +3361,7 @@ void C_BasePlayer::BuildFirstPersonMeathookTransformations( CStudioHdr *hdr, Vec
Vector vForward, vRight, vUp;
AngleVectors( MainViewAngles(), &vForward, &vRight, &vUp );
vRealPivotPoint = MainViewOrigin() - ( vUp * cl_meathook_neck_pivot_ingame_up.GetFloat() ) - ( vForward * cl_meathook_neck_pivot_ingame_fwd.GetFloat() );
vRealPivotPoint = MainViewOrigin() - ( vUp * flNeckPivotUp ) - ( vForward * flNeckPivotFwd );
}
Vector vDeltaToAdd = vRealPivotPoint - vHeadTransformTranslation;

View File

@ -293,6 +293,15 @@ public:
virtual bool ShouldInterpolate();
#ifdef MAPBASE
bool InPerspectiveView() const; // In a view that renders directly from the player's perspective (and may, for example, render the playermodel)
bool DrawingPlayerModelExternally() const;
bool DrawingLegs() const;
virtual CStudioHdr *OnNewModel( void );
virtual void BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t &cameraTransform, int boneMask, CBoneBitList &boneComputed );
#endif
virtual bool ShouldDraw();
virtual int DrawModel( int flags );
@ -468,6 +477,9 @@ public:
inline void RemoveSpawnFlags( int flags ) { m_spawnflags &= ~flags; }
inline void AddSpawnFlags( int flags ) { m_spawnflags |= flags; }
// Draws the player's model below the camera, visible when the player looks down.
bool m_bDrawPlayerLegs;
// Allows the player's model to draw on non-main views, like monitors or mirrors.
bool m_bDrawPlayerModelExternally;
@ -502,6 +514,10 @@ protected:
virtual void FireGameEvent( IGameEvent *event );
#ifdef MAPBASE
inline CUtlMap<int, float> &GetFirstPersonArmScales() { return m_FirstPersonModelData.m_FirstPersonBoneScales[FirstPersonModelData_t::BoneScales_Arms]; }
#endif
protected:
// Did we just enter a vehicle this frame?
bool JustEnteredVehicle();
@ -556,6 +572,41 @@ private:
bool m_bFiredWeapon;
#ifdef MAPBASE
struct FirstPersonModelData_t
{
void Reset()
{
m_flFirstPersonNeckPivotUp = m_flFirstPersonNeckPivotFwd = FLT_MAX;
m_flFirstPersonNeckPivotDuckUp = m_flFirstPersonNeckPivotDuckFwd = FLT_MAX;
for (int i = 0; i < BoneScales_Max; i++)
{
m_FirstPersonBoneScales[i].RemoveAll();
m_FirstPersonBoneScales[i].SetLessFunc( DefLessFunc( int ) );
}
}
void ParseModelData( C_BasePlayer *pPlayer, KeyValues *pkvPlayerModelData );
enum
{
BoneScales_Spine,
BoneScales_Arms,
BoneScales_Max
};
// Values to scale bones by when drawing playermodel in first person
CUtlMap<int, float> m_FirstPersonBoneScales[BoneScales_Max];
float m_flFirstPersonNeckPivotUp, m_flFirstPersonNeckPivotFwd = FLT_MAX;
float m_flFirstPersonNeckPivotDuckUp, m_flFirstPersonNeckPivotDuckFwd = FLT_MAX;
};
FirstPersonModelData_t m_FirstPersonModelData;
#endif
// Player flashlight dynamic light pointers
CFlashlightEffect *m_pFlashlight;

View File

@ -47,8 +47,8 @@ $Project
$File "$SRCDIR\game\shared\mapbase\MapEdit.h"
$File "$SRCDIR\game\shared\mapbase\matchers.cpp"
$File "$SRCDIR\game\shared\mapbase\matchers.h"
$File "$SRCDIR\game\shared\mapbase\singleplayer_animstate.cpp"
$File "$SRCDIR\game\shared\mapbase\singleplayer_animstate.h"
$File "$SRCDIR\game\shared\mapbase\mapbase_playeranimstate.cpp"
$File "$SRCDIR\game\shared\mapbase\mapbase_playeranimstate.h"
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT]
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT]
$File "$SRCDIR\game\shared\mapbase\vscript_singletons.cpp" [$MAPBASE_VSCRIPT]

View File

@ -33,6 +33,7 @@ IMPLEMENT_CLIENTCLASS_DT(C_BaseHLPlayer, DT_HL2_Player, CHL2_Player)
RecvPropBool( RECVINFO( m_fIsSprinting ) ),
#ifdef SP_ANIM_STATE
RecvPropFloat( RECVINFO( m_flAnimRenderYaw ) ),
RecvPropFloat( RECVINFO( m_flAnimRenderZ ) ),
#endif
END_RECV_TABLE()
@ -103,6 +104,22 @@ void C_BaseHLPlayer::OnDataChanged( DataUpdateType_t updateType )
BaseClass::OnDataChanged( updateType );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseHLPlayer::AddEntity( void )
{
BaseClass::AddEntity();
#ifdef MAPBASE_MP
if (m_pPlayerAnimState)
{
QAngle angEyeAngles = EyeAngles();
m_pPlayerAnimState->Update( angEyeAngles.y, angEyeAngles.x );
}
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
@ -664,24 +681,76 @@ bool C_BaseHLPlayer::CreateMove( float flInputSampleTime, CUserCmd *pCmd )
void C_BaseHLPlayer::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed )
{
BaseClass::BuildTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed );
/*#ifdef MAPBASE
// BuildFirstPersonMeathookTransformations is used prior to this when drawing legs
if (!DrawingLegs() || !InPerspectiveView() || !InFirstPersonView())
#endif*/
BuildFirstPersonMeathookTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed, "ValveBiped.Bip01_Head1" );
}
#ifdef SP_ANIM_STATE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const Vector &C_BaseHLPlayer::GetRenderOrigin()
{
if (m_flAnimRenderZ != 0.0f)
{
static Vector vecRender;
vecRender = BaseClass::GetRenderOrigin();
vecRender.z += m_flAnimRenderZ;
return vecRender;
}
return BaseClass::GetRenderOrigin();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const QAngle& C_BaseHLPlayer::GetRenderAngles( void )
{
#ifdef MAPBASE_MP
if ( m_pPlayerAnimState )
{
return m_pPlayerAnimState->GetRenderAngles();
}
#else
if ( m_flAnimRenderYaw != FLT_MAX )
{
return m_angAnimRender;
}
#endif
else
{
return BaseClass::GetRenderAngles();
}
}
//-----------------------------------------------------------------------------
// Purpose: model-change notification. Fires on dynamic load completion as well
//-----------------------------------------------------------------------------
CStudioHdr *C_BaseHLPlayer::OnNewModel()
{
CStudioHdr *hdr = BaseClass::OnNewModel();
#ifdef MAPBASE_MP
// Clears the animation state if we already have one.
if ( m_pPlayerAnimState != NULL )
{
m_pPlayerAnimState->Release();
m_pPlayerAnimState = NULL;
}
if ( hdr && hdr->HaveSequenceForActivity(ACT_HL2MP_IDLE) /*&& hl2_use_sp_animstate.GetBool()*/ )
{
// Here we create and init the player animation state.
m_pPlayerAnimState = CreatePlayerAnimationState(this);
}
#endif
return hdr;
}
#endif

View File

@ -16,7 +16,7 @@
#include "c_hl2_playerlocaldata.h"
#if !defined( HL2MP ) && defined ( MAPBASE )
#include "mapbase/singleplayer_animstate.h"
#include "mapbase/mapbase_playeranimstate.h"
#endif
class C_BaseHLPlayer : public C_BasePlayer
@ -29,6 +29,7 @@ public:
C_BaseHLPlayer();
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual void AddEntity( void );
void Weapon_DropPrimary( void );
@ -63,7 +64,9 @@ public:
bool IsWeaponLowered( void ) { return m_HL2Local.m_bWeaponLowered; }
#ifdef SP_ANIM_STATE
virtual const Vector& GetRenderOrigin();
virtual const QAngle& GetRenderAngles( void );
virtual CStudioHdr *OnNewModel();
#endif
public:
@ -87,10 +90,13 @@ private:
float m_flSpeedMod;
float m_flExitSpeedMod;
#ifdef SP_ANIM_STATE
#ifdef MAPBASE_MP
CSinglePlayerAnimState *m_pPlayerAnimState;
#elif MAPBASE
// At the moment, we network the render angles since almost none of the player anim stuff is done on the client in SP.
// If any of this is ever adapted for MP, this method should be replaced with replicating/moving the anim state to the client.
float m_flAnimRenderYaw;
float m_flAnimRenderZ;
QAngle m_angAnimRender;
#endif

View File

@ -2595,6 +2595,18 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_MELEE );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SLAM );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_PISTOL );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_SHOTGUN );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_SMG1 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_AR2 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_PHYSGUN );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_GRENADE );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_RPG );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_CROSSBOW );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_MELEE );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_SLAM );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_REVOLVER );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_RUN_REVOLVER );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_WALK_REVOLVER );
@ -2603,6 +2615,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_REVOLVER );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_REVOLVER );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_REVOLVER );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_REVOLVER );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_REVOLVER );
#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES
@ -2614,6 +2627,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_AR1 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR1 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_AR1 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_AR1 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_AR1 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_AR3 );
@ -2624,6 +2638,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_AR3 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR3 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_AR3 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_AR3 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_AR3 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_SMG2 );
@ -2634,6 +2649,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG2 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG2 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_SMG2 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_SMG2 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_SMG2 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_SMG3 );
@ -2644,6 +2660,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG3 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG3 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_SMG3 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_SMG3 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_SMG3 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_HMG1 );
@ -2654,6 +2671,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_HMG1 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_HMG1 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_HMG1 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_HMG1 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_HMG1 );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_SNIPER_RIFLE );
@ -2664,6 +2682,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_SNIPER_RIFLE );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_SNIPER_RIFLE );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_SNIPER_RIFLE );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_IDLE_DUAL_PISTOLS );
@ -2674,6 +2693,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RANGE_ATTACK2_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELOAD_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_GESTURE_RELAX_DUAL_PISTOLS );
ADD_ACTIVITY_TO_SR( ACT_HL2MP_JUMP_DUAL_PISTOLS );
#endif

View File

@ -1654,6 +1654,12 @@ bool CBaseFlex::ProcessSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, C
case CChoreoEvent::SPEAK:
return true;
#ifdef MAPBASE
// Prevents "unknown type" console spam on players
case CChoreoEvent::GENERIC:
return true;
#endif
default:
{
Msg( "unknown type %d in ProcessSceneEvent()\n", event->GetType() );

View File

@ -121,6 +121,7 @@ ConVar player_autoswitch_enabled( "player_autoswitch_enabled", "1", FCVAR_NONE,
#ifdef SP_ANIM_STATE
ConVar hl2_use_sp_animstate( "hl2_use_sp_animstate", "1", FCVAR_NONE, "Allows SP HL2 players to use HL2:DM animations for custom player models. (changes may not apply until model is reloaded)" );
ConVar player_process_scene_events( "player_process_scene_events", "1", FCVAR_NONE, "Allows players to process scene events." );
#endif
#endif
@ -267,6 +268,7 @@ public:
void InputSetHandModelBodyGroup( inputdata_t &inputdata );
void InputSetPlayerModel( inputdata_t &inputdata );
void InputSetPlayerDrawLegs( inputdata_t &inputdata );
void InputSetPlayerDrawExternally( inputdata_t &inputdata );
#endif
@ -674,6 +676,7 @@ IMPLEMENT_SERVERCLASS_ST(CHL2_Player, DT_HL2_Player)
SendPropBool( SENDINFO(m_fIsSprinting) ),
#ifdef SP_ANIM_STATE
SendPropFloat( SENDINFO(m_flAnimRenderYaw), 0, SPROP_NOSCALE ),
SendPropFloat( SENDINFO(m_flAnimRenderZ), 0, SPROP_NOSCALE ),
#endif
END_SEND_TABLE()
@ -1166,6 +1169,18 @@ void CHL2_Player::PostThink( void )
m_pPlayerAnimState->Update( angEyeAngles.y, angEyeAngles.x );
m_flAnimRenderYaw.Set( m_pPlayerAnimState->GetRenderAngles().y );
if (m_pPlayerAnimState->IsJumping() && !m_pPlayerAnimState->IsDuckJumping())
{
m_flAnimRenderZ.Set( -(GetViewOffset().z) );
}
else
m_flAnimRenderZ.Set( 0.0f );
if (player_process_scene_events.GetBool())
{
ProcessSceneEvents();
}
}
#endif
}
@ -1483,6 +1498,7 @@ CStudioHdr *CHL2_Player::OnNewModel()
}
extern char g_szDefaultPlayerModel[MAX_PATH];
extern bool g_bDefaultPlayerLegs;
extern bool g_bDefaultPlayerDrawExternally;
#endif
@ -1515,6 +1531,7 @@ void CHL2_Player::Spawn(void)
RemoveEffects( EF_NODRAW );
}
SetDrawPlayerLegs( g_bDefaultPlayerLegs );
SetDrawPlayerModelExternally( g_bDefaultPlayerDrawExternally );
#endif
@ -3349,6 +3366,11 @@ void CHL2_Player::Weapon_Equip( CBaseCombatWeapon *pWeapon )
if( GetActiveWeapon() == NULL )
{
m_HL2Local.m_bWeaponLowered = false;
#ifdef SP_ANIM_STATE
if (m_pPlayerAnimState)
m_pPlayerAnimState->StopWeaponRelax();
#endif
}
BaseClass::Weapon_Equip( pWeapon );
@ -3754,6 +3776,11 @@ bool CHL2_Player::Weapon_Lower( void )
m_HL2Local.m_bWeaponLowered = true;
#ifdef SP_ANIM_STATE
if (m_pPlayerAnimState)
m_pPlayerAnimState->StartWeaponRelax();
#endif
CBaseCombatWeapon *pWeapon = dynamic_cast<CBaseCombatWeapon *>(GetActiveWeapon());
if ( pWeapon == NULL )
@ -3776,6 +3803,11 @@ bool CHL2_Player::Weapon_Ready( void )
m_HL2Local.m_bWeaponLowered = false;
#ifdef SP_ANIM_STATE
if (m_pPlayerAnimState)
m_pPlayerAnimState->StopWeaponRelax();
#endif
CBaseCombatWeapon *pWeapon = dynamic_cast<CBaseCombatWeapon *>(GetActiveWeapon());
if ( pWeapon == NULL )
@ -3989,6 +4021,21 @@ void CHL2_Player::OnRestore()
{
BaseClass::OnRestore();
m_pPlayerAISquad = g_AI_SquadManager.FindCreateSquad(AllocPooledString(PLAYER_SQUADNAME));
#ifdef SP_ANIM_STATE
if ( m_pPlayerAnimState == NULL )
{
if ( GetModelPtr() && GetModelPtr()->HaveSequenceForActivity(ACT_HL2MP_IDLE) && hl2_use_sp_animstate.GetBool() )
{
// Here we create and init the player animation state.
m_pPlayerAnimState = CreatePlayerAnimationState(this);
}
else
{
m_flAnimRenderYaw = FLT_MAX;
}
}
#endif
}
//---------------------------------------------------------
@ -4594,6 +4641,7 @@ BEGIN_DATADESC( CLogicPlayerProxy )
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHandModelSkin", InputSetHandModelSkin ),
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHandModelBodyGroup", InputSetHandModelBodyGroup ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetPlayerModel", InputSetPlayerModel ),
DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetPlayerDrawLegs", InputSetPlayerDrawLegs ),
DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetPlayerDrawExternally", InputSetPlayerDrawExternally ),
DEFINE_INPUT( m_MaxArmor, FIELD_INTEGER, "SetMaxInputArmor" ),
DEFINE_INPUT( m_SuitZoomFOV, FIELD_INTEGER, "SetSuitZoomFOV" ),
@ -5072,6 +5120,15 @@ void CLogicPlayerProxy::InputSetPlayerModel( inputdata_t &inputdata )
m_hPlayer->SetModel( STRING(iszModel) );
}
void CLogicPlayerProxy::InputSetPlayerDrawLegs( inputdata_t &inputdata )
{
if (!m_hPlayer)
return;
CBasePlayer *pPlayer = static_cast<CBasePlayer*>(m_hPlayer.Get());
pPlayer->SetDrawPlayerLegs( inputdata.value.Bool() );
}
void CLogicPlayerProxy::InputSetPlayerDrawExternally( inputdata_t &inputdata )
{
if (!m_hPlayer)

View File

@ -19,7 +19,7 @@
#if defined ( HL2MP )
#include "basemultiplayerplayer.h"
#elif defined ( MAPBASE )
#include "mapbase/singleplayer_animstate.h"
#include "mapbase/mapbase_playeranimstate.h"
#endif
class CAI_Squad;
@ -443,11 +443,12 @@ private:
friend class CHL2GameMovement;
#ifdef SP_ANIM_STATE
CSinglePlayerAnimState* m_pPlayerAnimState;
CMapbasePlayerAnimState* m_pPlayerAnimState;
// At the moment, we network the render angles since almost none of the player anim stuff is done on the client in SP.
// If any of this is ever adapted for MP, this method should be replaced with replicating/moving the anim state to the client.
CNetworkVar( float, m_flAnimRenderYaw );
CNetworkVar( float, m_flAnimRenderZ );
#endif
};

View File

@ -7959,7 +7959,7 @@ Activity CBasePlayer::Weapon_TranslateActivity( Activity baseAct, bool *pRequire
{
Activity weaponTranslation = BaseClass::Weapon_TranslateActivity( baseAct, pRequired );
if ( GetActiveWeapon() && GetActiveWeapon()->IsEffectActive(EF_NODRAW) && baseAct != ACT_ARM )
if ( GetActiveWeapon() && !GetActiveWeapon()->IsWeaponVisible() && baseAct != ACT_ARM )
{
// Our weapon is holstered. Use the base activity.
return baseAct;
@ -8866,6 +8866,7 @@ void SendProxy_ShiftPlayerSpawnflags( const SendProp *pProp, const void *pStruct
// See baseplayer_shared.h for more details.
SendPropInt ( SENDINFO( m_spawnflags ), 3, SPROP_UNSIGNED, SendProxy_ShiftPlayerSpawnflags ),
SendPropBool ( SENDINFO( m_bDrawPlayerLegs ) ),
SendPropBool ( SENDINFO( m_bDrawPlayerModelExternally ) ),
SendPropBool ( SENDINFO( m_bInTriggerFall ) ),
#endif

View File

@ -1179,6 +1179,9 @@ public:
int m_nNumCrateHudHints;
#ifdef MAPBASE
bool GetDrawPlayerLegs( void ) { return m_bDrawPlayerLegs; }
void SetDrawPlayerLegs( bool bToggle ) { m_bDrawPlayerLegs.Set( bToggle ); }
bool GetDrawPlayerModelExternally( void ) { return m_bDrawPlayerModelExternally; }
void SetDrawPlayerModelExternally( bool bToggle ) { m_bDrawPlayerModelExternally.Set( bToggle ); }
#endif
@ -1222,6 +1225,7 @@ private:
char m_szNetname[MAX_PLAYER_NAME_LENGTH];
#ifdef MAPBASE
CNetworkVar( bool, m_bDrawPlayerLegs );
CNetworkVar( bool, m_bDrawPlayerModelExternally );
#endif

View File

@ -46,8 +46,8 @@ $Project
$File "$SRCDIR\game\shared\mapbase\MapEdit.h"
$File "$SRCDIR\game\shared\mapbase\matchers.cpp"
$File "$SRCDIR\game\shared\mapbase\matchers.h"
$File "$SRCDIR\game\shared\mapbase\singleplayer_animstate.cpp"
$File "$SRCDIR\game\shared\mapbase\singleplayer_animstate.h"
$File "$SRCDIR\game\shared\mapbase\mapbase_playeranimstate.cpp"
$File "$SRCDIR\game\shared\mapbase\mapbase_playeranimstate.h"
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT]
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT]
$File "$SRCDIR\game\shared\mapbase\vscript_singletons.cpp" [$MAPBASE_VSCRIPT]

View File

@ -2694,6 +2694,18 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_MELEE );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SLAM );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_PISTOL );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_SHOTGUN );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_SMG1 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_AR2 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_PHYSGUN );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_GRENADE );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_RPG );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_CROSSBOW );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_MELEE );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_SLAM );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_REVOLVER );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_RUN_REVOLVER );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_WALK_REVOLVER );
@ -2702,6 +2714,7 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_REVOLVER );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_REVOLVER );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_REVOLVER );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_REVOLVER );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_REVOLVER );
#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES
@ -2713,6 +2726,7 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_AR1 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR1 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_AR1 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_AR1 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_AR1 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_AR3 );
@ -2723,6 +2737,7 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_AR3 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR3 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_AR3 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_AR3 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_AR3 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_SMG2 );
@ -2733,6 +2748,7 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG2 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG2 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_SMG2 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_SMG2 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_SMG2 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_SMG3 );
@ -2743,6 +2759,7 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG3 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG3 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_SMG3 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_SMG3 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_SMG3 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_HMG1 );
@ -2753,6 +2770,7 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_HMG1 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_HMG1 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_HMG1 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_HMG1 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_HMG1 );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_SNIPER_RIFLE );
@ -2763,6 +2781,7 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_SNIPER_RIFLE );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_SNIPER_RIFLE );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_SNIPER_RIFLE );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_IDLE_DUAL_PISTOLS );
@ -2773,6 +2792,7 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RANGE_ATTACK2_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELOAD_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_GESTURE_RELAX_DUAL_PISTOLS );
REGISTER_SHARED_ACTIVITY( ACT_HL2MP_JUMP_DUAL_PISTOLS );
#endif

View File

@ -2598,6 +2598,18 @@ typedef enum
ACT_HL2MP_GESTURE_RANGE_ATTACK2_MELEE,
ACT_HL2MP_GESTURE_RANGE_ATTACK2_SLAM,
ACT_HL2MP_GESTURE_RELAX,
ACT_HL2MP_GESTURE_RELAX_PISTOL,
ACT_HL2MP_GESTURE_RELAX_SHOTGUN,
ACT_HL2MP_GESTURE_RELAX_SMG1,
ACT_HL2MP_GESTURE_RELAX_AR2,
ACT_HL2MP_GESTURE_RELAX_PHYSGUN,
ACT_HL2MP_GESTURE_RELAX_GRENADE,
ACT_HL2MP_GESTURE_RELAX_RPG,
ACT_HL2MP_GESTURE_RELAX_CROSSBOW,
ACT_HL2MP_GESTURE_RELAX_MELEE,
ACT_HL2MP_GESTURE_RELAX_SLAM,
ACT_HL2MP_IDLE_REVOLVER,
ACT_HL2MP_RUN_REVOLVER,
ACT_HL2MP_WALK_REVOLVER,
@ -2606,6 +2618,7 @@ typedef enum
ACT_HL2MP_GESTURE_RANGE_ATTACK_REVOLVER,
ACT_HL2MP_GESTURE_RANGE_ATTACK2_REVOLVER,
ACT_HL2MP_GESTURE_RELOAD_REVOLVER,
ACT_HL2MP_GESTURE_RELAX_REVOLVER,
ACT_HL2MP_JUMP_REVOLVER,
#if EXPANDED_HL2_UNUSED_WEAPON_ACTIVITIES
@ -2618,6 +2631,7 @@ typedef enum
ACT_HL2MP_GESTURE_RANGE_ATTACK_AR1,
ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR1,
ACT_HL2MP_GESTURE_RELOAD_AR1,
ACT_HL2MP_GESTURE_RELAX_AR1,
ACT_HL2MP_JUMP_AR1,
ACT_HL2MP_IDLE_AR3,
@ -2628,6 +2642,7 @@ typedef enum
ACT_HL2MP_GESTURE_RANGE_ATTACK_AR3,
ACT_HL2MP_GESTURE_RANGE_ATTACK2_AR3,
ACT_HL2MP_GESTURE_RELOAD_AR3,
ACT_HL2MP_GESTURE_RELAX_AR3,
ACT_HL2MP_JUMP_AR3,
ACT_HL2MP_IDLE_SMG2,
@ -2638,6 +2653,7 @@ typedef enum
ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG2,
ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG2,
ACT_HL2MP_GESTURE_RELOAD_SMG2,
ACT_HL2MP_GESTURE_RELAX_SMG2,
ACT_HL2MP_JUMP_SMG2,
ACT_HL2MP_IDLE_SMG3,
@ -2648,6 +2664,7 @@ typedef enum
ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG3,
ACT_HL2MP_GESTURE_RANGE_ATTACK2_SMG3,
ACT_HL2MP_GESTURE_RELOAD_SMG3,
ACT_HL2MP_GESTURE_RELAX_SMG3,
ACT_HL2MP_JUMP_SMG3,
ACT_HL2MP_IDLE_HMG1,
@ -2658,6 +2675,7 @@ typedef enum
ACT_HL2MP_GESTURE_RANGE_ATTACK_HMG1,
ACT_HL2MP_GESTURE_RANGE_ATTACK2_HMG1,
ACT_HL2MP_GESTURE_RELOAD_HMG1,
ACT_HL2MP_GESTURE_RELAX_HMG1,
ACT_HL2MP_JUMP_HMG1,
ACT_HL2MP_IDLE_SNIPER_RIFLE,
@ -2668,6 +2686,7 @@ typedef enum
ACT_HL2MP_GESTURE_RANGE_ATTACK_SNIPER_RIFLE,
ACT_HL2MP_GESTURE_RANGE_ATTACK2_SNIPER_RIFLE,
ACT_HL2MP_GESTURE_RELOAD_SNIPER_RIFLE,
ACT_HL2MP_GESTURE_RELAX_SNIPER_RIFLE,
ACT_HL2MP_JUMP_SNIPER_RIFLE,
ACT_HL2MP_IDLE_DUAL_PISTOLS,
@ -2678,6 +2697,7 @@ typedef enum
ACT_HL2MP_GESTURE_RANGE_ATTACK_DUAL_PISTOLS,
ACT_HL2MP_GESTURE_RANGE_ATTACK2_DUAL_PISTOLS,
ACT_HL2MP_GESTURE_RELOAD_DUAL_PISTOLS,
ACT_HL2MP_GESTURE_RELAX_DUAL_PISTOLS,
ACT_HL2MP_JUMP_DUAL_PISTOLS,
#endif

View File

@ -18,12 +18,12 @@
#include "c_baseplayer.h"
#include "engine/ivdebugoverlay.h"
ConVar cl_showanimstate( "cl_showanimstate", "-1", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, "Show the (client) animation state for the specified entity (-1 for none)." );
ConVar showanimstate_log( "cl_showanimstate_log", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, "1 to output cl_showanimstate to Msg(). 2 to store in AnimStateClient.log. 3 for both." );
ConVar cl_showanimstate( "cl_showanimstate", "-1", FCVAR_CHEAT /*| FCVAR_DEVELOPMENTONLY*/, "Show the (client) animation state for the specified entity (-1 for none)." );
ConVar showanimstate_log( "cl_showanimstate_log", "0", FCVAR_CHEAT /*| FCVAR_DEVELOPMENTONLY*/, "1 to output cl_showanimstate to Msg(). 2 to store in AnimStateClient.log. 3 for both." );
#else
#include "player.h"
ConVar sv_showanimstate( "sv_showanimstate", "-1", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, "Show the (server) animation state for the specified entity (-1 for none)." );
ConVar showanimstate_log( "sv_showanimstate_log", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, "1 to output sv_showanimstate to Msg(). 2 to store in AnimStateServer.log. 3 for both." );
ConVar sv_showanimstate( "sv_showanimstate", "-1", FCVAR_CHEAT /*| FCVAR_DEVELOPMENTONLY*/, "Show the (server) animation state for the specified entity (-1 for none)." );
ConVar showanimstate_log( "sv_showanimstate_log", "0", FCVAR_CHEAT /*| FCVAR_DEVELOPMENTONLY*/, "1 to output sv_showanimstate to Msg(). 2 to store in AnimStateServer.log. 3 for both." );
#endif
@ -654,9 +654,11 @@ void CBasePlayerAnimState::ComputePoseParam_MoveYaw( CStudioHdr *pStudioHdr )
if ( m_AnimConfig.m_LegAnimType == LEGANIM_9WAY )
{
#ifndef MAPBASE // This causes problems with entities that rely on the player having a pitch (TODO: gate behind virtual function?)
#ifndef CLIENT_DLL
//Adrian: Make the model's angle match the legs so the hitboxes match on both sides.
GetOuter()->SetLocalAngles( QAngle( 0, m_flCurrentFeetYaw, 0 ) );
#endif
#endif
int iMoveX = GetOuter()->LookupPoseParameter( pStudioHdr, "move_x" );
@ -942,6 +944,15 @@ void CBasePlayerAnimState::GetOuterAbsVelocity( Vector& vel ) const
#else
vel = GetOuter()->GetAbsVelocity();
#endif
#ifdef MAPBASE
if (GetOuter()->IsPlayer())
{
CBasePlayer *pPlayer = ToBasePlayer( GetOuter() );
if (pPlayer->GetLaggedMovementValue() != 1.0f)
vel *= pPlayer->GetLaggedMovementValue();
}
#endif
}
@ -1024,9 +1035,15 @@ void CBasePlayerAnimState::DebugShowAnimState( int iStartLine )
(float)pLayer->m_flWeight );
}
#ifdef MAPBASE
for ( int i=0; i < m_pOuter->GetNumAnimOverlays(); i++ )
{
CAnimationLayer *pLayer = m_pOuter->GetAnimOverlay( i );
#else
for ( int i=0; i < m_pOuter->GetNumAnimOverlays()-1; i++ )
{
CAnimationLayer *pLayer = m_pOuter->GetAnimOverlay( AIMSEQUENCE_LAYER + i );
#endif
#ifdef CLIENT_DLL
AnimStatePrintf( iLine++, "%s(%d), weight: %.2f, cycle: %.2f, order (%d), aim (%d)",
!pLayer->IsActive() ? "-- ": (pLayer->m_nSequence == 0 ? "-- " : GetSequenceName( m_pOuter->GetModelPtr(), pLayer->m_nSequence ) ),

View File

@ -307,6 +307,10 @@ public:
virtual bool ShouldBlockPrimaryFire() { return false; }
#ifdef CLIENT_DLL
#ifdef MAPBASE
virtual bool DispatchMuzzleEffect( const char *options, bool isFirstPerson );
#endif
virtual void CreateMove( float flInputSampleTime, CUserCmd *pCmd, const QAngle &vecOldViewAngles ) {}
virtual int CalcOverrideModelIndex() OVERRIDE;
#endif

View File

@ -15,7 +15,7 @@
//=============================================================================//
#include "cbase.h"
#include "singleplayer_animstate.h"
#include "mapbase_playeranimstate.h"
#include "tier0/vprof.h"
#include "animation.h"
#include "studio.h"
@ -23,25 +23,33 @@
#include "utldict.h"
#include "filesystem.h"
#include "in_buttons.h"
#include "gamemovement.h"
#include "datacache/imdlcache.h"
#ifdef CLIENT_DLL
#include "input.h"
#endif
extern ConVar mp_facefronttime, mp_feetyawrate, mp_ik;
extern ConVar mp_facefronttime, mp_feetyawrate;
ConVar sv_playeranimstate_animtype( "sv_playeranimstate_animtype", "0", FCVAR_NONE, "The leg animation type used by the singleplayer animation state. 9way = 0, 8way = 1, GoldSrc = 2" );
ConVar sv_playeranimstate_bodyyaw( "sv_playeranimstate_bodyyaw", "45.0", FCVAR_NONE, "The maximum body yaw used by the singleplayer animation state." );
ConVar sv_playeranimstate_use_aim_sequences( "sv_playeranimstate_use_aim_sequences", "1", FCVAR_NONE, "Allows the singleplayer animation state to use aim sequences." );
ConVar sv_playeranimstate_animtype( "sv_playeranimstate_animtype", "0", FCVAR_NONE, "The leg animation type used by the Mapbase animation state. 9way = 0, 8way = 1, GoldSrc = 2" );
ConVar sv_playeranimstate_bodyyaw( "sv_playeranimstate_bodyyaw", "45.0", FCVAR_NONE, "The maximum body yaw used by the Mapbase animation state." );
ConVar sv_playeranimstate_use_aim_sequences( "sv_playeranimstate_use_aim_sequences", "0", FCVAR_NONE, "Allows the Mapbase animation state to use aim sequences." );
ConVar sv_playeranimstate_use_walk_anims( "sv_playeranimstate_use_walk_anims", "0", FCVAR_NONE, "Allows the Mapbase animation state to use walk animations when the player is walking." );
#define MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION 15.0f
#define WEAPON_RELAX_TIME 0.5f
#define FIRESEQUENCE_LAYER (AIMSEQUENCE_LAYER+NUM_AIMSEQUENCE_LAYERS)
#define RELOADSEQUENCE_LAYER (FIRESEQUENCE_LAYER + 1)
#define NUM_LAYERS_WANTED (RELOADSEQUENCE_LAYER + 1)
#define MISCSEQUENCE_LAYER (RELOADSEQUENCE_LAYER + 1)
#define NUM_LAYERS_WANTED (MISCSEQUENCE_LAYER + 1)
CSinglePlayerAnimState *CreatePlayerAnimationState( CBasePlayer *pPlayer )
CMapbasePlayerAnimState *CreatePlayerAnimationState( CBasePlayer *pPlayer )
{
MDLCACHE_CRITICAL_SECTION();
CSinglePlayerAnimState *pState = new CSinglePlayerAnimState( pPlayer );
CMapbasePlayerAnimState *pState = new CMapbasePlayerAnimState( pPlayer );
// Setup the movement data.
CModAnimConfig movementData;
@ -65,22 +73,25 @@ CSinglePlayerAnimState *CreatePlayerAnimationState( CBasePlayer *pPlayer )
extern ConVar sv_backspeed;
extern ConVar mp_feetyawrate;
extern ConVar mp_facefronttime;
extern ConVar mp_ik;
CSinglePlayerAnimState::CSinglePlayerAnimState( CBasePlayer *pPlayer ): m_pPlayer( pPlayer )
CMapbasePlayerAnimState::CMapbasePlayerAnimState( CBasePlayer *pPlayer ): m_pPlayer( pPlayer )
{
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
Activity CSinglePlayerAnimState::CalcMainActivity()
Activity CMapbasePlayerAnimState::CalcMainActivity()
{
#ifdef CLIENT_DLL
return ACT_IDLE;
#else
float speed = GetOuter()->GetAbsVelocity().Length2D();
if (m_pPlayer->GetLaggedMovementValue() != 1.0f)
speed *= m_pPlayer->GetLaggedMovementValue();
// May not always be precise
if (speed < 0.01f)
speed = 0.0f;
if ( HandleJumping() )
{
return ACT_HL2MP_JUMP;
@ -95,7 +106,24 @@ Activity CSinglePlayerAnimState::CalcMainActivity()
}
else
{
if ( GetOuter()->GetFlags() & FL_DUCKING )
bool bDucking = (GetOuter()->GetFlags() & FL_DUCKING) ? true : false;
// (currently singleplayer-exclusive since clients can't read whether other players are holding down IN_DUCK)
if (m_pPlayer->m_Local.m_flDucktime > 0 && gpGlobals->maxClients == 1)
{
// Consider ducking if half-way through duck time
bDucking = (m_pPlayer->m_Local.m_flDucktime < (GAMEMOVEMENT_DUCK_TIME * 0.9f));
// Unducking
#ifdef CLIENT_DLL
if (!((m_pPlayer->IsLocalPlayer() ? input->GetButtonBits( 0 ) : m_pPlayer->GetCurrentUserCommand()->buttons) & IN_DUCK))
#else
if (!(m_pPlayer->m_nButtons & IN_DUCK))
#endif
bDucking = !bDucking;
}
if ( bDucking )
{
if ( speed > 0 )
{
@ -111,7 +139,7 @@ Activity CSinglePlayerAnimState::CalcMainActivity()
if ( speed > 0 )
{
#if EXPANDED_HL2DM_ACTIVITIES
if ( m_pPlayer->GetButtons() & IN_WALK )
if ( m_pPlayer->m_nButtons & IN_WALK && sv_playeranimstate_use_walk_anims.GetBool() )
{
idealActivity = ACT_HL2MP_WALK;
}
@ -132,19 +160,22 @@ Activity CSinglePlayerAnimState::CalcMainActivity()
}
//return m_pPlayer->GetActivity();
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSinglePlayerAnimState::SetPlayerAnimation( PLAYER_ANIM playerAnim )
void CMapbasePlayerAnimState::SetPlayerAnimation( PLAYER_ANIM playerAnim )
{
if ( playerAnim == PLAYER_ATTACK1 )
{
m_iFireSequence = SelectWeightedSequence( TranslateActivity( ACT_HL2MP_GESTURE_RANGE_ATTACK ) );
m_bFiring = m_iFireSequence != -1;
m_flFireCycle = 0;
// Be sure to stop reloading
m_bReloading = false;
m_flReloadCycle = 0;
}
else if ( playerAnim == PLAYER_ATTACK2 )
{
@ -155,6 +186,10 @@ void CSinglePlayerAnimState::SetPlayerAnimation( PLAYER_ANIM playerAnim )
#endif
m_bFiring = m_iFireSequence != -1;
m_flFireCycle = 0;
// Be sure to stop reloading
m_bReloading = false;
m_flReloadCycle = 0;
}
else if ( playerAnim == PLAYER_JUMP )
{
@ -162,6 +197,7 @@ void CSinglePlayerAnimState::SetPlayerAnimation( PLAYER_ANIM playerAnim )
if (!m_bJumping)
{
m_bJumping = true;
m_bDuckJumping = (GetOuter()->GetFlags() & FL_DUCKING) ? true : false; //m_pPlayer->m_nButtons & IN_DUCK;
m_bFirstJumpFrame = true;
m_flJumpStartTime = gpGlobals->curtime;
}
@ -184,13 +220,13 @@ void CSinglePlayerAnimState::SetPlayerAnimation( PLAYER_ANIM playerAnim )
if (m_iWeaponSwitchSequence != -1)
{
// clear other events that might be playing in our layer
m_bPlayingMisc = false;
//m_bPlayingMisc = false;
m_bReloading = false;
m_bWeaponSwitching = true;
m_flWeaponSwitchCycle = 0;
m_flMiscBlendOut = 0.1f;
m_flMiscBlendIn = 0.1f;
//m_flMiscBlendOut = 0.1f;
//m_flMiscBlendIn = 0.1f;
m_bMiscNoOverride = false;
}
}
@ -199,10 +235,10 @@ void CSinglePlayerAnimState::SetPlayerAnimation( PLAYER_ANIM playerAnim )
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
Activity CSinglePlayerAnimState::TranslateActivity( Activity actDesired )
Activity CMapbasePlayerAnimState::TranslateActivity( Activity actDesired )
{
#ifdef CLIENT_DLL
return actDesired;
#if defined(CLIENT_DLL) && !defined(MAPBASE_MP)
return actDesired;
#else
return m_pPlayer->Weapon_TranslateActivity( actDesired );
#endif
@ -211,7 +247,7 @@ Activity CSinglePlayerAnimState::TranslateActivity( Activity actDesired )
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CSinglePlayerAnimState::HandleJumping()
bool CMapbasePlayerAnimState::HandleJumping()
{
if ( m_bJumping )
{
@ -230,6 +266,7 @@ bool CSinglePlayerAnimState::HandleJumping()
if ( m_pOuter->GetFlags() & FL_ONGROUND || GetOuter()->GetGroundEntity() != NULL)
{
m_bJumping = false;
m_bDuckJumping = false;
RestartMainSequence(); // Reset the animation.
}
}
@ -242,7 +279,7 @@ bool CSinglePlayerAnimState::HandleJumping()
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSinglePlayerAnimState::ComputeSequences( CStudioHdr *pStudioHdr )
void CMapbasePlayerAnimState::ComputeSequences( CStudioHdr *pStudioHdr )
{
CBasePlayerAnimState::ComputeSequences(pStudioHdr);
@ -250,12 +287,13 @@ void CSinglePlayerAnimState::ComputeSequences( CStudioHdr *pStudioHdr )
ComputeMiscSequence();
ComputeReloadSequence();
ComputeWeaponSwitchSequence();
ComputeRelaxSequence();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSinglePlayerAnimState::AddMiscSequence( int iSequence, float flBlendIn, float flBlendOut, float flPlaybackRate, bool bHoldAtEnd, bool bOnlyWhenStill )
void CMapbasePlayerAnimState::AddMiscSequence( int iSequence, float flBlendIn, float flBlendOut, float flPlaybackRate, bool bHoldAtEnd, bool bOnlyWhenStill )
{
Assert( iSequence != -1 );
@ -265,7 +303,7 @@ void CSinglePlayerAnimState::AddMiscSequence( int iSequence, float flBlendIn, fl
m_bPlayingMisc = true;
m_bMiscHoldAtEnd = bHoldAtEnd;
m_bReloading = false;
//m_bReloading = false;
m_flMiscCycle = 0;
m_bMiscOnlyWhenStill = bOnlyWhenStill;
m_bMiscNoOverride = true;
@ -275,12 +313,36 @@ void CSinglePlayerAnimState::AddMiscSequence( int iSequence, float flBlendIn, fl
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSinglePlayerAnimState::ClearAnimationState()
void CMapbasePlayerAnimState::StartWeaponRelax()
{
if (m_bWeaponRelaxing)
return;
m_bWeaponRelaxing = true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMapbasePlayerAnimState::StopWeaponRelax()
{
if (!m_bWeaponRelaxing)
return;
m_bWeaponRelaxing = false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMapbasePlayerAnimState::ClearAnimationState()
{
m_bJumping = false;
m_bDuckJumping = false;
m_bFiring = false;
m_bReloading = false;
m_bWeaponSwitching = false;
m_bWeaponRelaxing = false;
m_bPlayingMisc = false;
m_flReloadBlendIn = 0.0f;
m_flReloadBlendOut = 0.0f;
@ -289,32 +351,42 @@ void CSinglePlayerAnimState::ClearAnimationState()
CBasePlayerAnimState::ClearAnimationState();
}
void CSinglePlayerAnimState::ClearAnimationLayers()
void CMapbasePlayerAnimState::ClearAnimationLayers()
{
VPROF( "CBasePlayerAnimState::ClearAnimationLayers" );
// In c_baseanimatingoverlay.cpp, this sometimes desyncs from the interpolated overlays and causes a crash in ResizeAnimationLayerCallback when the player dies. (pVec->Count() != pVecIV->Count())
// Is there a better way of getting around this issue?
#ifndef CLIENT_DLL
if ( !m_pOuter )
return;
m_pOuter->SetNumAnimOverlays( NUM_LAYERS_WANTED );
for ( int i=0; i < m_pOuter->GetNumAnimOverlays(); i++ )
{
// If we're not using aim sequences, leave the aim layers alone
// (allows them to be used outside of anim state)
if ( !m_AnimConfig.m_bUseAimSequences && i <= NUM_AIMSEQUENCE_LAYERS )
continue;
m_pOuter->GetAnimOverlay( i )->SetOrder( CBaseAnimatingOverlay::MAX_OVERLAYS );
#ifndef CLIENT_DLL
m_pOuter->GetAnimOverlay( i )->m_fFlags = 0;
#endif
}
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CSinglePlayerAnimState::CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle )
int CMapbasePlayerAnimState::CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle )
{
// TODO?
return m_pOuter->LookupSequence( "soldier_Aim_9_directions" );
}
void CSinglePlayerAnimState::UpdateLayerSequenceGeneric( int iLayer, bool &bEnabled,
void CMapbasePlayerAnimState::UpdateLayerSequenceGeneric( int iLayer, bool &bEnabled,
float &flCurCycle, int &iSequence, bool bWaitAtEnd,
float fBlendIn, float fBlendOut, bool bMoveBlend, float fPlaybackRate, bool bUpdateCycle /* = true */ )
{
@ -383,7 +455,7 @@ void CSinglePlayerAnimState::UpdateLayerSequenceGeneric( int iLayer, bool &bEnab
pLayer->m_flPlaybackRate = fPlaybackRate;
pLayer->m_flWeight = 1.0f;
if (iLayer == RELOADSEQUENCE_LAYER)
if (fBlendIn > 0.0f || fBlendOut > 0.0f)
{
// blend this layer in and out for smooth reloading
if (flCurCycle < fBlendIn && fBlendIn>0)
@ -418,25 +490,91 @@ void CSinglePlayerAnimState::UpdateLayerSequenceGeneric( int iLayer, bool &bEnab
pLayer->SetOrder( iLayer );
}
void CSinglePlayerAnimState::ComputeFireSequence()
void CMapbasePlayerAnimState::ComputeFireSequence()
{
UpdateLayerSequenceGeneric( FIRESEQUENCE_LAYER, m_bFiring, m_flFireCycle, m_iFireSequence, false );
}
void CSinglePlayerAnimState::ComputeReloadSequence()
void CMapbasePlayerAnimState::ComputeReloadSequence()
{
UpdateLayerSequenceGeneric( RELOADSEQUENCE_LAYER, m_bReloading, m_flReloadCycle, m_iReloadSequence, false, m_flReloadBlendIn, m_flReloadBlendOut, false, m_fReloadPlaybackRate );
}
void CSinglePlayerAnimState::ComputeWeaponSwitchSequence()
void CMapbasePlayerAnimState::ComputeWeaponSwitchSequence()
{
UpdateLayerSequenceGeneric( RELOADSEQUENCE_LAYER, m_bWeaponSwitching, m_flWeaponSwitchCycle, m_iWeaponSwitchSequence, false, 0, 0.5f );
}
// does misc gestures if we're not firing
void CSinglePlayerAnimState::ComputeMiscSequence()
void CMapbasePlayerAnimState::ComputeRelaxSequence()
{
UpdateLayerSequenceGeneric( RELOADSEQUENCE_LAYER, m_bPlayingMisc, m_flMiscCycle, m_iMiscSequence, m_bMiscHoldAtEnd, m_flMiscBlendIn, m_flMiscBlendOut, m_bMiscOnlyWhenStill, m_fMiscPlaybackRate );
bool bRelaxing = m_bWeaponRelaxing;
float flRelaxSpeed = 0.05f;
if ((m_bFiring && m_flFireCycle < 1.0f) || m_bReloading)
{
// Keep weapon raised
bRelaxing = false;
flRelaxSpeed = 0.5f;
//GetOuter()->SetPoseParameter( GetOuter()->LookupPoseParameter( "weapon_lower" ), 0.0f );
}
if (bRelaxing ? m_flWeaponRelaxAmount != 1.0f : m_flWeaponRelaxAmount != 0.0f)
{
if (bRelaxing)
m_flWeaponRelaxAmount += flRelaxSpeed;
else
m_flWeaponRelaxAmount -= flRelaxSpeed;
m_flWeaponRelaxAmount = clamp( m_flWeaponRelaxAmount, 0.0f, 1.0f );
GetOuter()->SetPoseParameter( GetOuter()->LookupPoseParameter( "weapon_lower" ), m_flWeaponRelaxAmount );
/*int nPose = GetOuter()->LookupPoseParameter( "weapon_lower" );
if (nPose != -1)
{
float flValue = RemapValClamped( (m_flWeaponRelaxTime - gpGlobals->curtime), 0.0f, 0.5f, 0.0f, 1.0f );
if (flValue <= 0.0f)
{
// All done
m_flWeaponRelaxTime = FLT_MAX;
}
if (m_bWeaponRelaxing)
flValue = 1.0f - flValue;
GetOuter()->SetPoseParameter( nPose, SimpleSpline( flValue ) );
}*/
}
else if (bRelaxing)
{
GetOuter()->SetPoseParameter( GetOuter()->LookupPoseParameter( "weapon_lower" ), 1.0f );
}
/*bool bEnabled = m_bWeaponRelaxing;
bool bUpdateCycle = true;
if (bEnabled)
{
if (m_flWeaponRelaxCycle >= 0.5f)
{
// Pause at 0.5
m_flWeaponRelaxCycle = 0.5f;
bUpdateCycle = false;
}
}
else if (m_flWeaponRelaxCycle < 1.0f)
{
// Make sure we exit the relax
bEnabled = true;
}
UpdateLayerSequenceGeneric( AIMSEQUENCE_LAYER, bEnabled, m_flWeaponRelaxCycle, m_iWeaponRelaxSequence, false, 0.5f, 0.5f, false, 1.0f, bUpdateCycle );*/
}
// does misc gestures if we're not firing
void CMapbasePlayerAnimState::ComputeMiscSequence()
{
UpdateLayerSequenceGeneric( MISCSEQUENCE_LAYER, m_bPlayingMisc, m_flMiscCycle, m_iMiscSequence, m_bMiscHoldAtEnd, m_flMiscBlendIn, m_flMiscBlendOut, m_bMiscOnlyWhenStill, m_fMiscPlaybackRate );
}
//-----------------------------------------------------------------------------
@ -444,7 +582,7 @@ void CSinglePlayerAnimState::ComputeMiscSequence()
// Input : -
// Output : float
//-----------------------------------------------------------------------------
float CSinglePlayerAnimState::GetCurrentMaxGroundSpeed()
float CMapbasePlayerAnimState::GetCurrentMaxGroundSpeed()
{
CStudioHdr *pStudioHdr = GetOuter()->GetModelPtr();
@ -481,11 +619,42 @@ float CSinglePlayerAnimState::GetCurrentMaxGroundSpeed()
return speed;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
inline bool CMapbasePlayerAnimState::ShouldUseAimPoses( void ) const
{
return GetAimPoseBlend() > 0.0f;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
float CMapbasePlayerAnimState::GetAimPoseBlend( void ) const
{
if (!GetOuter()->MyCombatCharacterPointer() || !GetOuter()->MyCombatCharacterPointer()->GetActiveWeapon()
|| GetOuter()->MyCombatCharacterPointer()->GetActiveWeapon()->IsEffectActive( EF_NODRAW ))
return 0.0f;
return 1.0f - m_flWeaponRelaxAmount;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
float CMapbasePlayerAnimState::SetOuterBodyYaw( float flValue )
{
float flAimPoseBlend = GetAimPoseBlend();
GetOuter()->SetPoseParameter( GetOuter()->LookupPoseParameter( "aim_yaw" ), flValue * flAimPoseBlend );
return CBasePlayerAnimState::SetOuterBodyYaw( flValue * (1.0f - flAimPoseBlend) );
}
//-----------------------------------------------------------------------------
// Purpose: Override for backpeddling
// Input : dt -
//-----------------------------------------------------------------------------
void CSinglePlayerAnimState::ComputePoseParam_BodyYaw( void )
void CMapbasePlayerAnimState::ComputePoseParam_BodyYaw( void )
{
CBasePlayerAnimState::ComputePoseParam_BodyYaw();
@ -495,7 +664,7 @@ void CSinglePlayerAnimState::ComputePoseParam_BodyYaw( void )
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSinglePlayerAnimState::ComputePoseParam_BodyLookYaw( void )
void CMapbasePlayerAnimState::ComputePoseParam_BodyLookYaw( void )
{
// See if we even have a blender for pitch
int upper_body_yaw = GetOuter()->LookupPoseParameter( "aim_yaw" );
@ -632,7 +801,7 @@ void CSinglePlayerAnimState::ComputePoseParam_BodyLookYaw( void )
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSinglePlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr )
void CMapbasePlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr )
{
// Get pitch from v_angle
float flPitch = m_flEyePitch;
@ -643,16 +812,19 @@ void CSinglePlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr
}
flPitch = clamp( flPitch, -90, 90 );
//float flAimPoseBlend = GetAimPoseBlend();
// See if we have a blender for pitch
GetOuter()->SetPoseParameter( pStudioHdr, "aim_pitch", flPitch );
GetOuter()->SetPoseParameter( pStudioHdr, "head_pitch", flPitch );
ComputePoseParam_HeadPitch( pStudioHdr );
//ComputePoseParam_HeadPitch( pStudioHdr );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSinglePlayerAnimState::ComputePoseParam_HeadPitch( CStudioHdr *pStudioHdr )
void CMapbasePlayerAnimState::ComputePoseParam_HeadPitch( CStudioHdr *pStudioHdr )
{
// Get pitch from v_angle
int iHeadPitch = GetOuter()->LookupPoseParameter("head_pitch");

View File

@ -14,8 +14,8 @@
//
//=============================================================================//
#ifndef SINGLEPLAYER_ANIMSTATE_H
#define SINGLEPLAYER_ANIMSTATE_H
#ifndef MAPBASE_PLAYERANIMSTATE_H
#define MAPBASE_PLAYERANIMSTATE_H
#ifdef _WIN32
#pragma once
#endif
@ -34,10 +34,10 @@
#define SP_ANIM_STATE 1
#endif
class CSinglePlayerAnimState : public CBasePlayerAnimState
class CMapbasePlayerAnimState : public CBasePlayerAnimState
{
public:
CSinglePlayerAnimState( CBasePlayer *pPlayer );
CMapbasePlayerAnimState( CBasePlayer *pPlayer );
Activity CalcMainActivity();
int CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle );
@ -50,9 +50,15 @@ public:
void AddMiscSequence( int iSequence, float flBlendIn = 0.0f, float flBlendOut = 0.0f, float flPlaybackRate = 1.0f, bool bHoldAtEnd = false, bool bOnlyWhenStill = false );
void StartWeaponRelax();
void StopWeaponRelax();
void ClearAnimationState();
void ClearAnimationLayers();
inline bool IsJumping() const { return m_bJumping; }
inline bool IsDuckJumping() const { return m_bDuckJumping; }
private:
bool HandleJumping();
@ -60,13 +66,19 @@ private:
void ComputeFireSequence();
void ComputeReloadSequence();
void ComputeWeaponSwitchSequence();
void ComputeRelaxSequence();
void ComputeMiscSequence();
void UpdateLayerSequenceGeneric( int iLayer, bool &bEnabled, float &flCurCycle,
int &iSequence, bool bWaitAtEnd,
float fBlendIn=0.15f, float fBlendOut=0.15f, bool bMoveBlend = false,
float fBlendIn=0.0f, float fBlendOut=0.0f, bool bMoveBlend = false,
float fPlaybackRate=1.0f, bool bUpdateCycle = true );
bool ShouldUseAimPoses() const;
float GetAimPoseBlend() const;
float SetOuterBodyYaw( float flValue );
void ComputePoseParam_BodyYaw( void );
void ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr );
void ComputePoseParam_BodyLookYaw( void );
@ -76,6 +88,7 @@ private:
// Current state variables.
bool m_bJumping; // Set on a jump event.
bool m_bDuckJumping; // Jump started while ducking
float m_flJumpStartTime;
bool m_bFirstJumpFrame;
@ -90,6 +103,9 @@ private:
float m_flWeaponSwitchCycle;
int m_iWeaponSwitchSequence;
bool m_bWeaponRelaxing;
float m_flWeaponRelaxAmount;
bool m_bPlayingMisc;
float m_flMiscCycle, m_flMiscBlendOut, m_flMiscBlendIn;
int m_iMiscSequence;
@ -105,6 +121,6 @@ private:
float m_flFireCycle;
};
CSinglePlayerAnimState *CreatePlayerAnimationState( CBasePlayer *pPlayer );
CMapbasePlayerAnimState *CreatePlayerAnimationState( CBasePlayer *pPlayer );
#endif // SINGLEPLAYER_ANIMSTATE_H
#endif // MAPBASE_PLAYERANIMSTATE_H

View File

@ -86,6 +86,7 @@ char g_iszGameName[128];
#ifdef GAME_DLL
// Default player configuration
char g_szDefaultPlayerModel[MAX_PATH];
bool g_bDefaultPlayerLegs;
bool g_bDefaultPlayerDrawExternally;
char g_szDefaultHandsModel[MAX_PATH];
@ -236,6 +237,7 @@ public:
#ifdef GAME_DLL
Q_strncpy( g_szDefaultPlayerModel, gameinfo->GetString( "player_default_model", "models/player.mdl" ), sizeof( g_szDefaultPlayerModel ) );
g_bDefaultPlayerLegs = gameinfo->GetBool( "player_default_legs", false );
g_bDefaultPlayerDrawExternally = gameinfo->GetBool( "player_default_draw_externally", false );
Q_strncpy( g_szDefaultHandsModel, gameinfo->GetString( "player_default_hands", "models/weapons/v_hands.mdl" ), sizeof( g_szDefaultHandsModel ) );