Merge pull request #1 from tonysergi/master

Tony Sergi fixes
This commit is contained in:
Andrew 2015-08-16 21:49:51 -04:00
commit f2ebd09cca
45 changed files with 1752 additions and 1131 deletions

View file

@ -228,9 +228,9 @@ END_RECV_TABLE()
RecvPropEHandle ( RECVINFO( m_hLastWeapon ) ),
RecvPropEHandle ( RECVINFO( m_hGroundEntity ) ),
RecvPropFloat ( RECVINFO(m_vecVelocity[0]), 0, RecvProxy_LocalVelocityX ),
RecvPropFloat ( RECVINFO(m_vecVelocity[1]), 0, RecvProxy_LocalVelocityY ),
RecvPropFloat ( RECVINFO(m_vecVelocity[2]), 0, RecvProxy_LocalVelocityZ ),
RecvPropFloat ( RECVINFO(m_vecVelocity[0]), 0, RecvProxy_LocalVelocityX ),
RecvPropFloat ( RECVINFO(m_vecVelocity[1]), 0, RecvProxy_LocalVelocityY ),
RecvPropFloat ( RECVINFO(m_vecVelocity[2]), 0, RecvProxy_LocalVelocityZ ),
RecvPropVector ( RECVINFO( m_vecBaseVelocity ) ),
@ -469,7 +469,7 @@ void C_BasePlayer::Spawn( void )
m_iFOV = 0; // init field of view.
SetModel( "models/player.mdl" );
SetModel( "models/player.mdl" );
Precache();
@ -1854,6 +1854,13 @@ void C_BasePlayer::ThirdPersonSwitch( bool bThirdperson )
}
}
}
//Notify weapon.
CBaseCombatWeapon *pWeapon = GetActiveWeapon();
if ( pWeapon )
{
pWeapon->ThirdPersonSwitch( bThirdperson );
}
}
}

View file

@ -103,8 +103,8 @@ static void RecordEffect( const char *pEffectName, const CEffectData &data )
char pName[1024];
Q_snprintf( pName, sizeof(pName), "TE_DispatchEffect %s %s", pEffectName, pSurfacePropName );
msg->SetInt( "te", TE_DISPATCH_EFFECT );
msg->SetString( "name", pName );
msg->SetInt( "te", TE_DISPATCH_EFFECT );
msg->SetString( "name", pName );
msg->SetFloat( "time", gpGlobals->curtime );
msg->SetFloat( "originx", data.m_vOrigin.x );
msg->SetFloat( "originy", data.m_vOrigin.y );
@ -126,10 +126,10 @@ static void RecordEffect( const char *pEffectName, const CEffectData &data )
msg->SetInt( "color", data.m_nColor );
msg->SetInt( "damagetype", data.m_nDamageType );
msg->SetInt( "hitbox", data.m_nHitBox );
msg->SetString( "effectname", pEffectName );
msg->SetString( "effectname", pEffectName );
// FIXME: Need to write the attachment name here
msg->SetInt( "attachmentindex", data.m_nAttachmentIndex );
msg->SetInt( "attachmentindex", data.m_nAttachmentIndex );
// NOTE: Ptrs are our way of indicating it's an entindex
msg->SetPtr( "entindex", (void*)data.entindex() );
@ -178,7 +178,10 @@ void DispatchEffect( const char *pName, const CEffectData &data )
CPASFilter filter( data.m_vOrigin );
te->DispatchEffect( filter, 0.0, data.m_vOrigin, pName, data );
}
void DispatchEffect( const char *pName, const CEffectData &data, IRecipientFilter &filter )
{
te->DispatchEffect( filter, 0.0, data.m_vOrigin, pName, data );
}
//-----------------------------------------------------------------------------
// Playback

View file

@ -42,5 +42,6 @@ public:
void DispatchEffectToCallback( const char *pEffectName, const CEffectData &m_EffectData );
void DispatchEffect( const char *pName, const CEffectData &data );
void DispatchEffect( const char *pName, const CEffectData &data, IRecipientFilter &filter );
#endif // C_TE_EFFECT_DISPATCH_H

View file

@ -14,7 +14,7 @@ $Configuration
{
$Compiler
{
$AdditionalIncludeDirectories "$BASE;hl2mp\ui,.\hl2mp,$SRCDIR\game\shared\hl2mp,.\hl2,.\hl2\elements,$SRCDIR\game\shared\hl2"
$AdditionalIncludeDirectories "$BASE;hl2mp\ui,.\hl2mp,$SRCDIR\game\shared\hl2mp,.\hl2,.\hl2\elements,$SRCDIR\game\shared\hl2,$SRCDIR\game\shared\Multiplayer"
$PreprocessorDefinitions "$BASE;HL2MP;HL2_CLIENT_DLL"
}
}
@ -127,6 +127,10 @@ $Project "Client (HL2MP)"
$File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.h"
$File "$SRCDIR\game\shared\hl2mp\hl2mp_weapon_parse.cpp"
$File "$SRCDIR\game\shared\hl2mp\hl2mp_weapon_parse.h"
$File "$SRCDIR\game\shared\hl2mp\hl2mp_playeranimstate.h"
$File "$SRCDIR\game\shared\hl2mp\hl2mp_playeranimstate.cpp"
$File "$SRCDIR\game\shared\Multiplayer\multiplayer_animstate.h"
$File "$SRCDIR\game\shared\Multiplayer\multiplayer_animstate.cpp"
$Folder "Weapons"
{

View file

@ -53,6 +53,11 @@ void CC_DropPrimary( void )
static ConCommand dropprimary("dropprimary", CC_DropPrimary, "dropprimary: Drops the primary weapon of the player.");
// link to the correct class.
#if !defined ( HL2MP )
LINK_ENTITY_TO_CLASS( player, C_BaseHLPlayer );
#endif
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------

View file

@ -14,6 +14,9 @@
#include "iviewrender_beams.h" // flashlight beam
#include "r_efx.h"
#include "dlight.h"
#include "c_basetempentity.h"
#include "prediction.h"
#include "bone_setup.h"
// Don't alias here
#if defined( CHL2MP_Player )
@ -22,9 +25,23 @@
LINK_ENTITY_TO_CLASS( player, C_HL2MP_Player );
IMPLEMENT_CLIENTCLASS_DT(C_HL2MP_Player, DT_HL2MP_Player, CHL2MP_Player)
BEGIN_RECV_TABLE_NOBASE( C_HL2MP_Player, DT_HL2MPLocalPlayerExclusive )
RecvPropVector( RECVINFO_NAME( m_vecNetworkOrigin, m_vecOrigin ) ),
RecvPropFloat( RECVINFO( m_angEyeAngles[0] ) ),
// RecvPropFloat( RECVINFO( m_angEyeAngles[1] ) ),
END_RECV_TABLE()
BEGIN_RECV_TABLE_NOBASE( C_HL2MP_Player, DT_HL2MPNonLocalPlayerExclusive )
RecvPropVector( RECVINFO_NAME( m_vecNetworkOrigin, m_vecOrigin ) ),
RecvPropFloat( RECVINFO( m_angEyeAngles[0] ) ),
RecvPropFloat( RECVINFO( m_angEyeAngles[1] ) ),
END_RECV_TABLE()
IMPLEMENT_CLIENTCLASS_DT(C_HL2MP_Player, DT_HL2MP_Player, CHL2MP_Player)
RecvPropDataTable( "hl2mplocaldata", 0, 0, &REFERENCE_RECV_TABLE(DT_HL2MPLocalPlayerExclusive) ),
RecvPropDataTable( "hl2mpnonlocaldata", 0, 0, &REFERENCE_RECV_TABLE(DT_HL2MPNonLocalPlayerExclusive) ),
RecvPropEHandle( RECVINFO( m_hRagdoll ) ),
RecvPropInt( RECVINFO( m_iSpawnInterpCounter ) ),
RecvPropInt( RECVINFO( m_iPlayerSoundType) ),
@ -33,7 +50,12 @@ IMPLEMENT_CLIENTCLASS_DT(C_HL2MP_Player, DT_HL2MP_Player, CHL2MP_Player)
END_RECV_TABLE()
BEGIN_PREDICTION_DATA( C_HL2MP_Player )
DEFINE_PRED_FIELD( m_flCycle, FIELD_FLOAT, FTYPEDESC_OVERRIDE | FTYPEDESC_PRIVATE | FTYPEDESC_NOERRORCHECK ),
DEFINE_PRED_FIELD( m_fIsWalking, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_nSequence, FIELD_INTEGER, FTYPEDESC_OVERRIDE | FTYPEDESC_PRIVATE | FTYPEDESC_NOERRORCHECK ),
DEFINE_PRED_FIELD( m_flPlaybackRate, FIELD_FLOAT, FTYPEDESC_OVERRIDE | FTYPEDESC_PRIVATE | FTYPEDESC_NOERRORCHECK ),
DEFINE_PRED_ARRAY_TOL( m_flEncodedController, FIELD_FLOAT, MAXSTUDIOBONECTRLS, FTYPEDESC_OVERRIDE | FTYPEDESC_PRIVATE, 0.02f ),
DEFINE_PRED_FIELD( m_nNewSequenceParity, FIELD_INTEGER, FTYPEDESC_OVERRIDE | FTYPEDESC_PRIVATE | FTYPEDESC_NOERRORCHECK ),
END_PREDICTION_DATA()
#define HL2_WALK_SPEED 150
@ -45,16 +67,16 @@ static ConVar cl_defaultweapon( "cl_defaultweapon", "weapon_physcannon", FCVAR_U
void SpawnBlood (Vector vecSpot, const Vector &vecDir, int bloodColor, float flDamage);
C_HL2MP_Player::C_HL2MP_Player() : m_PlayerAnimState( this ), m_iv_angEyeAngles( "C_HL2MP_Player::m_iv_angEyeAngles" )
C_HL2MP_Player::C_HL2MP_Player() : m_iv_angEyeAngles( "C_HL2MP_Player::m_iv_angEyeAngles" )
{
m_iIDEntIndex = 0;
m_iSpawnInterpCounterCache = 0;
m_angEyeAngles.Init();
AddVar( &m_angEyeAngles, &m_iv_angEyeAngles, LATCH_SIMULATION_VAR );
m_EntClientFlags |= ENTCLIENTFLAG_DONTUSEIK;
// m_EntClientFlags |= ENTCLIENTFLAG_DONTUSEIK;
m_PlayerAnimState = CreateHL2MPPlayerAnimState( this );
m_blinkTimer.Invalidate();
m_pFlashlightBeam = NULL;
@ -63,6 +85,7 @@ C_HL2MP_Player::C_HL2MP_Player() : m_PlayerAnimState( this ), m_iv_angEyeAngles(
C_HL2MP_Player::~C_HL2MP_Player( void )
{
ReleaseFlashlight();
m_PlayerAnimState->Release();
}
int C_HL2MP_Player::GetIDTarget() const
@ -163,6 +186,12 @@ CStudioHdr *C_HL2MP_Player::OnNewModel( void )
Initialize( );
// Reset the players animation states, gestures
if ( m_PlayerAnimState )
{
m_PlayerAnimState->OnNewModel();
}
return hdr;
}
@ -271,7 +300,7 @@ int C_HL2MP_Player::DrawModel( int flags )
if ( !m_bReadyToDraw )
return 0;
return BaseClass::DrawModel(flags);
return BaseClass::DrawModel(flags);
}
//-----------------------------------------------------------------------------
@ -305,24 +334,6 @@ void C_HL2MP_Player::DoImpactEffect( trace_t &tr, int nDamageType )
void C_HL2MP_Player::PreThink( void )
{
QAngle vTempAngles = GetLocalAngles();
if ( GetLocalPlayer() == this )
{
vTempAngles[PITCH] = EyeAngles()[PITCH];
}
else
{
vTempAngles[PITCH] = m_angEyeAngles[PITCH];
}
if ( vTempAngles[YAW] < 0.0f )
{
vTempAngles[YAW] += 360.0f;
}
SetLocalAngles( vTempAngles );
BaseClass::PreThink();
HandleSpeedChanges();
@ -355,13 +366,6 @@ void C_HL2MP_Player::AddEntity( void )
{
BaseClass::AddEntity();
QAngle vTempAngles = GetLocalAngles();
vTempAngles[PITCH] = m_angEyeAngles[PITCH];
SetLocalAngles( vTempAngles );
m_PlayerAnimState.Update();
// Zero out model pitch, blending takes care of all of it.
SetLocalAnglesDim( X_INDEX, 0 );
@ -457,7 +461,7 @@ const QAngle& C_HL2MP_Player::GetRenderAngles()
}
else
{
return m_PlayerAnimState.GetRenderAngles();
return m_PlayerAnimState->GetRenderAngles();
}
}
@ -780,7 +784,7 @@ void C_HL2MPRagdoll::Interp_Copy( C_BaseAnimatingOverlay *pSourceEntity )
VarMapping_t *pSrc = pSourceEntity->GetVarMapping();
VarMapping_t *pDest = GetVarMapping();
// Find all the VarMapEntry_t's that represent the same variable.
for ( int i = 0; i < pDest->m_Entries.Count(); i++ )
{
@ -976,10 +980,140 @@ void C_HL2MPRagdoll::SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWei
}
}
void C_HL2MP_Player::PostThink( void )
void C_HL2MP_Player::UpdateClientSideAnimation()
{
BaseClass::PostThink();
m_PlayerAnimState->Update( EyeAngles()[YAW], EyeAngles()[PITCH] );
// Store the eye angles pitch so the client can compute its animation state correctly.
m_angEyeAngles = EyeAngles();
BaseClass::UpdateClientSideAnimation();
}
// -------------------------------------------------------------------------------- //
// Player animation event. Sent to the client when a player fires, jumps, reloads, etc..
// -------------------------------------------------------------------------------- //
class C_TEPlayerAnimEvent : public C_BaseTempEntity
{
public:
DECLARE_CLASS( C_TEPlayerAnimEvent, C_BaseTempEntity );
DECLARE_CLIENTCLASS();
virtual void PostDataUpdate( DataUpdateType_t updateType )
{
// Create the effect.
C_HL2MP_Player *pPlayer = dynamic_cast< C_HL2MP_Player* >( m_hPlayer.Get() );
if ( pPlayer && !pPlayer->IsDormant() )
{
pPlayer->DoAnimationEvent( (PlayerAnimEvent_t)m_iEvent.Get(), m_nData );
}
}
public:
CNetworkHandle( CBasePlayer, m_hPlayer );
CNetworkVar( int, m_iEvent );
CNetworkVar( int, m_nData );
};
IMPLEMENT_CLIENTCLASS_EVENT( C_TEPlayerAnimEvent, DT_TEPlayerAnimEvent, CTEPlayerAnimEvent );
BEGIN_RECV_TABLE_NOBASE( C_TEPlayerAnimEvent, DT_TEPlayerAnimEvent )
RecvPropEHandle( RECVINFO( m_hPlayer ) ),
RecvPropInt( RECVINFO( m_iEvent ) ),
RecvPropInt( RECVINFO( m_nData ) )
END_RECV_TABLE()
void C_HL2MP_Player::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
{
if ( IsLocalPlayer() )
{
if ( ( prediction->InPrediction() && !prediction->IsFirstTimePredicted() ) )
return;
}
MDLCACHE_CRITICAL_SECTION();
m_PlayerAnimState->DoAnimationEvent( event, nData );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_HL2MP_Player::CalculateIKLocks( float currentTime )
{
if (!m_pIk)
return;
int targetCount = m_pIk->m_target.Count();
if ( targetCount == 0 )
return;
// In TF, we might be attaching a player's view to a walking model that's using IK. If we are, it can
// get in here during the view setup code, and it's not normally supposed to be able to access the spatial
// partition that early in the rendering loop. So we allow access right here for that special case.
SpatialPartitionListMask_t curSuppressed = partition->GetSuppressedLists();
partition->SuppressLists( PARTITION_ALL_CLIENT_EDICTS, false );
CBaseEntity::PushEnableAbsRecomputations( false );
for (int i = 0; i < targetCount; i++)
{
trace_t trace;
CIKTarget *pTarget = &m_pIk->m_target[i];
if (!pTarget->IsActive())
continue;
switch( pTarget->type)
{
case IK_GROUND:
{
pTarget->SetPos( Vector( pTarget->est.pos.x, pTarget->est.pos.y, GetRenderOrigin().z ));
pTarget->SetAngles( GetRenderAngles() );
}
break;
case IK_ATTACHMENT:
{
C_BaseEntity *pEntity = NULL;
float flDist = pTarget->est.radius;
// FIXME: make entity finding sticky!
// FIXME: what should the radius check be?
for ( CEntitySphereQuery sphere( pTarget->est.pos, 64 ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() )
{
C_BaseAnimating *pAnim = pEntity->GetBaseAnimating( );
if (!pAnim)
continue;
int iAttachment = pAnim->LookupAttachment( pTarget->offset.pAttachmentName );
if (iAttachment <= 0)
continue;
Vector origin;
QAngle angles;
pAnim->GetAttachment( iAttachment, origin, angles );
// debugoverlay->AddBoxOverlay( origin, Vector( -1, -1, -1 ), Vector( 1, 1, 1 ), QAngle( 0, 0, 0 ), 255, 0, 0, 0, 0 );
float d = (pTarget->est.pos - origin).Length();
if ( d >= flDist)
continue;
flDist = d;
pTarget->SetPos( origin );
pTarget->SetAngles( angles );
// debugoverlay->AddBoxOverlay( pTarget->est.pos, Vector( -pTarget->est.radius, -pTarget->est.radius, -pTarget->est.radius ), Vector( pTarget->est.radius, pTarget->est.radius, pTarget->est.radius), QAngle( 0, 0, 0 ), 0, 255, 0, 0, 0 );
}
if (flDist >= pTarget->est.radius)
{
// debugoverlay->AddBoxOverlay( pTarget->est.pos, Vector( -pTarget->est.radius, -pTarget->est.radius, -pTarget->est.radius ), Vector( pTarget->est.radius, pTarget->est.radius, pTarget->est.radius), QAngle( 0, 0, 0 ), 0, 0, 255, 0, 0 );
// no solution, disable ik rule
pTarget->IKFailed( );
}
}
break;
}
}
CBaseEntity::PopEnableAbsRecomputations();
partition->SuppressLists( curSuppressed, true );
}

View file

@ -9,7 +9,7 @@
#define HL2MP_PLAYER_H
#pragma once
class C_HL2MP_Player;
#include "hl2mp_playeranimstate.h"
#include "c_basehlplayer.h"
#include "hl2mp_player_shared.h"
#include "beamdraw.h"
@ -37,7 +37,6 @@ public:
virtual int DrawModel( int flags );
virtual void AddEntity( void );
QAngle GetAnimEyeAngles( void ) { return m_angEyeAngles; }
Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL );
@ -84,13 +83,14 @@ public:
void StopWalking( void );
bool IsWalking( void ) { return m_fIsWalking; }
virtual void PostThink( void );
virtual void UpdateClientSideAnimation();
void DoAnimationEvent( PlayerAnimEvent_t event, int nData = 0 );
virtual void CalculateIKLocks( float currentTime );
private:
C_HL2MP_Player( const C_HL2MP_Player & );
CPlayerAnimState m_PlayerAnimState;
CHL2MPPlayerAnimState *m_PlayerAnimState;
QAngle m_angEyeAngles;

View file

@ -1575,7 +1575,28 @@ int CBaseEntity::VPhysicsTakeDamage( const CTakeDamageInfo &info )
if ( gameFlags & FVPHYSICS_PLAYER_HELD )
{
// if the player is holding the object, use it's real mass (player holding reduced the mass)
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
CBasePlayer *pPlayer = NULL;
if ( gpGlobals->maxClients == 1 )
{
pPlayer = UTIL_GetLocalPlayer();
}
else
{
// See which MP player is holding the physics object and then use that player to get the real mass of the object.
// This is ugly but better than having linkage between an object and its "holding" player.
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i );
if ( tempPlayer && (tempPlayer->GetHeldObject() == this ) )
{
pPlayer = tempPlayer;
break;
}
}
}
if ( pPlayer )
{
float mass = pPlayer->GetHeldObjectMass( VPhysicsGetObject() );

View file

@ -372,7 +372,8 @@ protected:
bool PassesDamageFilterImpl(const CTakeDamageInfo &info)
{
return info.GetDamageType() == m_iDamageType;
//Tony; these are bitflags. check them as so.
return ((info.GetDamageType() & m_iDamageType) == m_iDamageType);
}
int m_iDamageType;

View file

@ -2083,7 +2083,7 @@ bool CHL2_Player::IsIlluminatedByFlashlight( CBaseEntity *pEntity, float *flRetu
}
// Within 50 feet?
float flDistSqr = GetAbsOrigin().DistToSqr(pEntity->GetAbsOrigin());
float flDistSqr = GetAbsOrigin().DistToSqr(pEntity->GetAbsOrigin());
if( flDistSqr > FLASHLIGHT_RANGE )
return false;
@ -2159,7 +2159,7 @@ void CHL2_Player::SetPlayerUnderwater( bool state )
}
else
{
SuitPower_RemoveDevice( SuitDeviceBreather );
SuitPower_RemoveDevice( SuitDeviceBreather );
}
BaseClass::SetPlayerUnderwater( state );
@ -3154,6 +3154,10 @@ float CHL2_Player::GetHeldObjectMass( IPhysicsObject *pHeldObject )
return mass;
}
CBaseEntity *CHL2_Player::GetHeldObject( void )
{
return PhysCannonGetHeldEntity( GetActiveWeapon() );
}
//-----------------------------------------------------------------------------
// Purpose: Force the player to drop any physics objects he's carrying
//-----------------------------------------------------------------------------

View file

@ -15,6 +15,14 @@
#include "simtimer.h"
#include "soundenvelope.h"
// In HL2MP we need to inherit from BaseMultiplayerPlayer!
#if defined ( HL2MP )
#include "basemultiplayerplayer.h"
#define BASEPLAYERCLASS CBaseMultiplayerPlayer
#else
#define BASEPLAYERCLASS CBasePlayer
#endif
class CAI_Squad;
class CPropCombineBall;
@ -75,10 +83,10 @@ public:
//=============================================================================
// >> HL2_PLAYER
//=============================================================================
class CHL2_Player : public CBasePlayer
class CHL2_Player : public BASEPLAYERCLASS
{
public:
DECLARE_CLASS( CHL2_Player, CBasePlayer );
DECLARE_CLASS( CHL2_Player, BASEPLAYERCLASS );
CHL2_Player();
~CHL2_Player( void );
@ -241,6 +249,7 @@ public:
virtual bool IsHoldingEntity( CBaseEntity *pEnt );
virtual void ForceDropOfCarriedPhysObjects( CBaseEntity *pOnlyIfHoldindThis );
virtual float GetHeldObjectMass( IPhysicsObject *pHeldObject );
virtual CBaseEntity *GetHeldObject( void );
virtual bool IsFollowingPhysics( void ) { return (m_afPhysicsFlags & PFLAG_ONBARNACLE) > 0; }
void InputForceDropPhysObjects( inputdata_t &data );

View file

@ -8,7 +8,7 @@
#include "cbase.h"
#include "beam_shared.h"
#include "shake.h"
#include "grenade_tripmine.h"
#include "hl2mp/grenade_tripmine.h" // Load the hl2mp header!!
#include "vstdlib/random.h"
#include "engine/IEngineSound.h"
#include "explode.h"
@ -49,8 +49,23 @@ CTripmineGrenade::CTripmineGrenade()
m_vecEnd.Init();
m_posOwner.Init();
m_angleOwner.Init();
m_pConstraint = NULL;
m_bAttached = false;
m_hAttachEntity = NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTripmineGrenade::~CTripmineGrenade( void )
{
if (m_pConstraint)
{
physenv->DestroyConstraint(m_pConstraint);
m_pConstraint = NULL;
}
}
void CTripmineGrenade::Spawn( void )
{
Precache( );
@ -59,7 +74,7 @@ void CTripmineGrenade::Spawn( void )
SetSolid( SOLID_BBOX );
SetModel( "models/Weapons/w_slam.mdl" );
IPhysicsObject *pObject = VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, true );
IPhysicsObject *pObject = VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, true );
pObject->EnableMotion( false );
SetCollisionGroup( COLLISION_GROUP_WEAPON );
@ -117,10 +132,16 @@ void CTripmineGrenade::PowerupThink( void )
{
if (gpGlobals->curtime > m_flPowerUp)
{
m_flPowerUp = 0;
MakeBeam( );
RemoveSolidFlags( FSOLID_NOT_SOLID );
m_bIsLive = true;
// The moment it's live, then do this - incase the attach entity moves between placing it, and activation
// use the absorigin of what we're attaching to for the check, if it moves - we blow up.
if ( m_bAttached && m_hAttachEntity.Get() != NULL )
m_vAttachedPosition = m_hAttachEntity.Get()->GetAbsOrigin();
// play enabled sound
EmitSound( "TripmineGrenade.Activate" );
}
@ -146,8 +167,6 @@ void CTripmineGrenade::MakeBeam( void )
m_flBeamLength = tr.fraction;
// If I hit a living thing, send the beam through me so it turns on briefly
// and then blows the living thing up
CBaseEntity *pEntity = tr.m_pEnt;
@ -219,31 +238,42 @@ void CTripmineGrenade::BeamBreakThink( void )
CBaseEntity *pEntity = tr.m_pEnt;
CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( pEntity );
if (pBCC || fabs( m_flBeamLength - tr.fraction ) > 0.001)
bool bAttachMoved = false;
if ( m_bAttached && m_hAttachEntity.Get() != NULL )
{
if ( m_hAttachEntity.Get()->GetAbsOrigin() != m_vAttachedPosition )
bAttachMoved = true;
}
// Also blow up if the attached entity goes away, ie: a crate
if (pBCC || fabs( m_flBeamLength - tr.fraction ) > 0.001 || ( m_bAttached && m_hAttachEntity.Get() == NULL) || bAttachMoved )
{
m_iHealth = 0;
if (m_pConstraint)
m_pConstraint->Deactivate();
Event_Killed( CTakeDamageInfo( (CBaseEntity*)m_hOwner, this, 100, GIB_NORMAL ) );
return;
}
SetNextThink( gpGlobals->curtime + 0.05f );
}
#if 0 // FIXME: OnTakeDamage_Alive() is no longer called now that base grenade derives from CBaseAnimating
int CTripmineGrenade::OnTakeDamage_Alive( const CTakeDamageInfo &info )
int CTripmineGrenade::OnTakeDamage( const CTakeDamageInfo &info )
{
if (gpGlobals->curtime < m_flPowerUp && info.GetDamage() < m_iHealth)
if ( m_iHealth < 0 )
return 0; //already dead.
if ( gpGlobals->curtime > m_flPowerUp )
{
// disable
// Create( "weapon_tripmine", GetLocalOrigin() + m_vecDir * 24, GetAngles() );
SetThink( &CTripmineGrenade::SUB_Remove );
SetNextThink( gpGlobals->curtime + 0.1f );
KillBeam();
return FALSE;
m_iHealth -= info.GetDamage();
if ( m_iHealth <= 0 )
Event_Killed( info );
return info.GetDamage();
}
return BaseClass::OnTakeDamage_Alive( info );
return 0;
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
@ -254,6 +284,9 @@ void CTripmineGrenade::Event_Killed( const CTakeDamageInfo &info )
{
m_takedamage = DAMAGE_NO;
if (m_pConstraint)
m_pConstraint->Deactivate();
SetThink( &CTripmineGrenade::DelayDeathThink );
SetNextThink( gpGlobals->curtime + 0.25 );
@ -274,3 +307,60 @@ void CTripmineGrenade::DelayDeathThink( void )
UTIL_Remove( this );
}
bool CTripmineGrenade::MakeConstraint( CBaseEntity *pObject )
{
IPhysicsObject *cMinePhysics = VPhysicsGetObject();
Assert( cMinePhysics );
IPhysicsObject *pAttached = pObject->VPhysicsGetObject();
if ( !cMinePhysics || !pAttached )
return false;
// constraining to the world means object 1 is fixed
if ( pAttached == g_PhysWorldObject )
PhysSetGameFlags( cMinePhysics, FVPHYSICS_CONSTRAINT_STATIC );
IPhysicsConstraintGroup *pGroup = NULL;
constraint_fixedparams_t fixed;
fixed.Defaults();
fixed.InitWithCurrentObjectState( cMinePhysics, pAttached );
fixed.constraint.Defaults();
m_pConstraint = physenv->CreateFixedConstraint( cMinePhysics, pAttached, pGroup, fixed );
if (!m_pConstraint)
return false;
m_pConstraint->SetGameData( (void *)this );
return true;
}
void CTripmineGrenade::AttachToEntity(CBaseEntity *pOther)
{
if (!pOther)
return;
if ( !VPhysicsGetObject() )
return;
m_bAttached = true;
m_hAttachEntity = pOther;
SetMoveType ( MOVETYPE_NONE );
if (pOther->GetSolid() == SOLID_VPHYSICS && pOther->VPhysicsGetObject() != NULL )
{
SetSolid(SOLID_BBOX); //Tony; switch to bbox solid instead of vphysics, because we've made the physics object non-solid
MakeConstraint(pOther);
SetMoveType ( MOVETYPE_VPHYSICS ); // use vphysics while constrained!!
}
//if it isnt vphysics or bsp, use SetParent to follow it.
else if (pOther->GetSolid() != SOLID_BSP)
{
SetSolid(SOLID_BBOX); //Tony; switch to bbox solid instead of vphysics, because we've made the physics object non-solid
SetParent( m_hAttachEntity.Get() );
}
}

View file

@ -15,6 +15,8 @@
class CBeam;
// for constraints
#include "vphysics/constraints.h"
class CTripmineGrenade : public CBaseGrenade
{
@ -22,12 +24,12 @@ public:
DECLARE_CLASS( CTripmineGrenade, CBaseGrenade );
CTripmineGrenade();
~CTripmineGrenade();
void Spawn( void );
void Precache( void );
#if 0 // FIXME: OnTakeDamage_Alive() is no longer called now that base grenade derives from CBaseAnimating
int OnTakeDamage_Alive( const CTakeDamageInfo &info );
#endif
virtual int OnTakeDamage( const CTakeDamageInfo &info );
void WarningThink( void );
void PowerupThink( void );
void BeamBreakThink( void );
@ -37,8 +39,14 @@ public:
void MakeBeam( void );
void KillBeam( void );
// Added to create a constraint
void AttachToEntity( CBaseEntity *pOther );
bool MakeConstraint( CBaseEntity *pOther );
public:
EHANDLE m_hOwner;
// Added for following
EHANDLE m_hAttachEntity;
private:
float m_flPowerUp;
@ -50,6 +58,11 @@ private:
Vector m_posOwner;
Vector m_angleOwner;
// signifies if we're attached to something, and need to update slightly differently.
bool m_bAttached;
IPhysicsConstraint *m_pConstraint;
Vector m_vAttachedPosition; // if the attached position changes, we need to detonate
DECLARE_DATADESC();
};

View file

@ -20,12 +20,17 @@
#include "grenade_satchel.h"
#include "eventqueue.h"
#include "gamestats.h"
#include "tier0/vprof.h"
#include "bone_setup.h"
#include "engine/IEngineSound.h"
#include "SoundEmitterSystem/isoundemittersystembase.h"
#include "ilagcompensationmanager.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
int g_iLastCitizenModel = 0;
int g_iLastCombineModel = 0;
@ -42,19 +47,58 @@ LINK_ENTITY_TO_CLASS( player, CHL2MP_Player );
LINK_ENTITY_TO_CLASS( info_player_combine, CPointEntity );
LINK_ENTITY_TO_CLASS( info_player_rebel, CPointEntity );
extern void SendProxy_Origin( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
//Tony; this should ideally be added to dt_send.cpp
void* SendProxy_SendNonLocalDataTable( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID )
{
pRecipients->SetAllRecipients();
pRecipients->ClearRecipient( objectID - 1 );
return ( void * )pVarData;
}
REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_SendNonLocalDataTable );
BEGIN_SEND_TABLE_NOBASE( CHL2MP_Player, DT_HL2MPLocalPlayerExclusive )
// send a hi-res origin to the local player for use in prediction
SendPropVector (SENDINFO(m_vecOrigin), -1, SPROP_NOSCALE|SPROP_CHANGES_OFTEN, 0.0f, HIGH_DEFAULT, SendProxy_Origin ),
SendPropFloat( SENDINFO_VECTORELEM(m_angEyeAngles, 0), 8, SPROP_CHANGES_OFTEN, -90.0f, 90.0f ),
// SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 1), 10, SPROP_CHANGES_OFTEN ),
END_SEND_TABLE()
BEGIN_SEND_TABLE_NOBASE( CHL2MP_Player, DT_HL2MPNonLocalPlayerExclusive )
// send a lo-res origin to other players
SendPropVector (SENDINFO(m_vecOrigin), -1, SPROP_COORD_MP_LOWPRECISION|SPROP_CHANGES_OFTEN, 0.0f, HIGH_DEFAULT, SendProxy_Origin ),
SendPropFloat( SENDINFO_VECTORELEM(m_angEyeAngles, 0), 8, SPROP_CHANGES_OFTEN, -90.0f, 90.0f ),
SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 1), 10, SPROP_CHANGES_OFTEN ),
END_SEND_TABLE()
IMPLEMENT_SERVERCLASS_ST(CHL2MP_Player, DT_HL2MP_Player)
SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 0), 11, SPROP_CHANGES_OFTEN ),
SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 1), 11, SPROP_CHANGES_OFTEN ),
SendPropExclude( "DT_BaseAnimating", "m_flPoseParameter" ),
SendPropExclude( "DT_BaseAnimating", "m_flPlaybackRate" ),
SendPropExclude( "DT_BaseAnimating", "m_nSequence" ),
SendPropExclude( "DT_BaseEntity", "m_angRotation" ),
SendPropExclude( "DT_BaseAnimatingOverlay", "overlay_vars" ),
SendPropExclude( "DT_BaseEntity", "m_vecOrigin" ),
// playeranimstate and clientside animation takes care of these on the client
SendPropExclude( "DT_ServerAnimationData" , "m_flCycle" ),
SendPropExclude( "DT_AnimTimeMustBeFirst" , "m_flAnimTime" ),
SendPropExclude( "DT_BaseFlex", "m_flexWeight" ),
SendPropExclude( "DT_BaseFlex", "m_blinktoggle" ),
SendPropExclude( "DT_BaseFlex", "m_viewtarget" ),
// Data that only gets sent to the local player.
SendPropDataTable( "hl2mplocaldata", 0, &REFERENCE_SEND_TABLE(DT_HL2MPLocalPlayerExclusive), SendProxy_SendLocalDataTable ),
// Data that gets sent to all other players
SendPropDataTable( "hl2mpnonlocaldata", 0, &REFERENCE_SEND_TABLE(DT_HL2MPNonLocalPlayerExclusive), SendProxy_SendNonLocalDataTable ),
SendPropEHandle( SENDINFO( m_hRagdoll ) ),
SendPropInt( SENDINFO( m_iSpawnInterpCounter), 4 ),
SendPropInt( SENDINFO( m_iPlayerSoundType), 3 ),
SendPropExclude( "DT_BaseAnimating", "m_flPoseParameter" ),
SendPropExclude( "DT_BaseFlex", "m_viewtarget" ),
// SendPropExclude( "DT_ServerAnimationData" , "m_flCycle" ),
// SendPropExclude( "DT_AnimTimeMustBeFirst" , "m_flAnimTime" ),
END_SEND_TABLE()
BEGIN_DATADESC( CHL2MP_Player )
@ -96,8 +140,12 @@ const char *g_ppszRandomCombineModels[] =
#pragma warning( disable : 4355 )
CHL2MP_Player::CHL2MP_Player() : m_PlayerAnimState( this )
CHL2MP_Player::CHL2MP_Player()
{
//Tony; create our player animation state.
m_PlayerAnimState = CreateHL2MPPlayerAnimState( this );
UseClientSideAnimation();
m_angEyeAngles.Init();
m_iLastWeaponFireUsercmd = 0;
@ -107,16 +155,16 @@ CHL2MP_Player::CHL2MP_Player() : m_PlayerAnimState( this )
m_iSpawnInterpCounter = 0;
m_bEnterObserver = false;
m_bEnterObserver = false;
m_bReady = false;
BaseClass::ChangeTeam( 0 );
// UseClientSideAnimation();
}
CHL2MP_Player::~CHL2MP_Player( void )
{
m_PlayerAnimState->Release();
}
@ -142,13 +190,13 @@ void CHL2MP_Player::Precache( void )
int i;
for ( i = 0; i < nHeads; ++i )
PrecacheModel( g_ppszRandomCitizenModels[i] );
PrecacheModel( g_ppszRandomCitizenModels[i] );
//Precache Combine Models
nHeads = ARRAYSIZE( g_ppszRandomCombineModels );
for ( i = 0; i < nHeads; ++i )
PrecacheModel( g_ppszRandomCombineModels[i] );
PrecacheModel( g_ppszRandomCombineModels[i] );
PrecacheFootStepSounds();
@ -304,8 +352,6 @@ void CHL2MP_Player::Spawn(void)
GiveDefaultItems();
}
SetNumAnimOverlays( 3 );
ResetAnimation();
m_nRenderFX = kRenderNormal;
@ -331,6 +377,10 @@ void CHL2MP_Player::Spawn(void)
SetPlayerUnderwater(false);
m_bReady = false;
//Tony; do the spawn animevent
DoAnimationEvent( PLAYERANIMEVENT_SPAWN );
}
void CHL2MP_Player::PickupObject( CBaseEntity *pObject, bool bLimitMassAndSize )
@ -355,7 +405,7 @@ bool CHL2MP_Player::ValidatePlayerModel( const char *pModel )
for ( i = 0; i < iModels; ++i )
{
if ( !Q_stricmp( g_ppszRandomCombineModels[i], pModel ) )
if ( !Q_stricmp( g_ppszRandomCombineModels[i], pModel ) )
{
return true;
}
@ -505,55 +555,20 @@ void CHL2MP_Player::SetupPlayerSoundsByModel( const char *pModelName )
}
}
void CHL2MP_Player::ResetAnimation( void )
{
if ( IsAlive() )
{
SetSequence ( -1 );
SetActivity( ACT_INVALID );
if (!GetAbsVelocity().x && !GetAbsVelocity().y)
SetAnimation( PLAYER_IDLE );
else if ((GetAbsVelocity().x || GetAbsVelocity().y) && ( GetFlags() & FL_ONGROUND ))
SetAnimation( PLAYER_WALK );
else if (GetWaterLevel() > 1)
SetAnimation( PLAYER_WALK );
}
}
bool CHL2MP_Player::Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex )
{
bool bRet = BaseClass::Weapon_Switch( pWeapon, viewmodelindex );
if ( bRet == true )
{
ResetAnimation();
}
return bRet;
}
void CHL2MP_Player::PreThink( void )
{
QAngle vOldAngles = GetLocalAngles();
QAngle vTempAngles = GetLocalAngles();
vTempAngles = EyeAngles();
if ( vTempAngles[PITCH] > 180.0f )
{
vTempAngles[PITCH] -= 360.0f;
}
SetLocalAngles( vTempAngles );
BaseClass::PreThink();
State_PreThink();
//Reset bullet force accumulator, only lasts one frame
m_vecTotalBulletForce = vec3_origin;
SetLocalAngles( vOldAngles );
}
void CHL2MP_Player::PostThink( void )
@ -565,14 +580,13 @@ void CHL2MP_Player::PostThink( void )
SetCollisionBounds( VEC_CROUCH_TRACE_MIN, VEC_CROUCH_TRACE_MAX );
}
m_PlayerAnimState.Update();
// Store the eye angles pitch so the client can compute its animation state correctly.
m_angEyeAngles = EyeAngles();
QAngle angles = GetLocalAngles();
angles[PITCH] = 0;
SetLocalAngles( angles );
// Store the eye angles pitch so the client can compute its animation state correctly.
m_angEyeAngles = EyeAngles();
m_PlayerAnimState->Update( m_angEyeAngles[YAW], m_angEyeAngles[PITCH] );
}
void CHL2MP_Player::PlayerDeathThink()
@ -671,170 +685,6 @@ Activity CHL2MP_Player::TranslateTeamActivity( Activity ActToTranslate )
extern ConVar hl2_normspeed;
// Set the activity based on an event or current state
void CHL2MP_Player::SetAnimation( PLAYER_ANIM playerAnim )
{
int animDesired;
float speed;
speed = GetAbsVelocity().Length2D();
// bool bRunning = true;
//Revisit!
/* if ( ( m_nButtons & ( IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT ) ) )
{
if ( speed > 1.0f && speed < hl2_normspeed.GetFloat() - 20.0f )
{
bRunning = false;
}
}*/
if ( GetFlags() & ( FL_FROZEN | FL_ATCONTROLS ) )
{
speed = 0;
playerAnim = PLAYER_IDLE;
}
Activity idealActivity = ACT_HL2MP_RUN;
// This could stand to be redone. Why is playerAnim abstracted from activity? (sjb)
if ( playerAnim == PLAYER_JUMP )
{
idealActivity = ACT_HL2MP_JUMP;
}
else if ( playerAnim == PLAYER_DIE )
{
if ( m_lifeState == LIFE_ALIVE )
{
return;
}
}
else if ( playerAnim == PLAYER_ATTACK1 )
{
if ( GetActivity( ) == ACT_HOVER ||
GetActivity( ) == ACT_SWIM ||
GetActivity( ) == ACT_HOP ||
GetActivity( ) == ACT_LEAP ||
GetActivity( ) == ACT_DIESIMPLE )
{
idealActivity = GetActivity( );
}
else
{
idealActivity = ACT_HL2MP_GESTURE_RANGE_ATTACK;
}
}
else if ( playerAnim == PLAYER_RELOAD )
{
idealActivity = ACT_HL2MP_GESTURE_RELOAD;
}
else if ( playerAnim == PLAYER_IDLE || playerAnim == PLAYER_WALK )
{
if ( !( GetFlags() & FL_ONGROUND ) && GetActivity( ) == ACT_HL2MP_JUMP ) // Still jumping
{
idealActivity = GetActivity( );
}
/*
else if ( GetWaterLevel() > 1 )
{
if ( speed == 0 )
idealActivity = ACT_HOVER;
else
idealActivity = ACT_SWIM;
}
*/
else
{
if ( GetFlags() & FL_DUCKING )
{
if ( speed > 0 )
{
idealActivity = ACT_HL2MP_WALK_CROUCH;
}
else
{
idealActivity = ACT_HL2MP_IDLE_CROUCH;
}
}
else
{
if ( speed > 0 )
{
/*
if ( bRunning == false )
{
idealActivity = ACT_WALK;
}
else
*/
{
idealActivity = ACT_HL2MP_RUN;
}
}
else
{
idealActivity = ACT_HL2MP_IDLE;
}
}
}
idealActivity = TranslateTeamActivity( idealActivity );
}
if ( idealActivity == ACT_HL2MP_GESTURE_RANGE_ATTACK )
{
RestartGesture( Weapon_TranslateActivity( idealActivity ) );
// FIXME: this seems a bit wacked
Weapon_SetActivity( Weapon_TranslateActivity( ACT_RANGE_ATTACK1 ), 0 );
return;
}
else if ( idealActivity == ACT_HL2MP_GESTURE_RELOAD )
{
RestartGesture( Weapon_TranslateActivity( idealActivity ) );
return;
}
else
{
SetActivity( idealActivity );
animDesired = SelectWeightedSequence( Weapon_TranslateActivity ( idealActivity ) );
if (animDesired == -1)
{
animDesired = SelectWeightedSequence( idealActivity );
if ( animDesired == -1 )
{
animDesired = 0;
}
}
// Already using the desired animation?
if ( GetSequence() == animDesired )
return;
m_flPlaybackRate = 1.0;
ResetSequence( animDesired );
SetCycle( 0 );
return;
}
// Already using the desired animation?
if ( GetSequence() == animDesired )
return;
//Msg( "Set animation to %d\n", animDesired );
// Reset to first frame of desired animation
ResetSequence( animDesired );
SetCycle( 0 );
}
extern int gEvilImpulse101;
//-----------------------------------------------------------------------------
// Purpose: Player reacts to bumping a weapon.
@ -1225,8 +1075,6 @@ void CHL2MP_Player::Event_Killed( const CTakeDamageInfo &info )
CTakeDamageInfo subinfo = info;
subinfo.SetDamageForce( m_vecTotalBulletForce );
SetNumAnimOverlays( 0 );
// Note: since we're dead, it won't draw us on the client, but we don't set EF_NODRAW
// because we still want to transmit to the clients in our PVS.
CreateRagdollEntity();
@ -1415,7 +1263,7 @@ CON_COMMAND( timeleft, "prints the time remaining in the match" )
CHL2MP_Player *pPlayer = ToHL2MPPlayer( UTIL_GetCommandClient() );
int iTimeRemaining = (int)HL2MPRules()->GetMapRemainingTime();
if ( iTimeRemaining == 0 )
{
if ( pPlayer )
@ -1627,3 +1475,140 @@ bool CHL2MP_Player::CanHearAndReadChatFrom( CBasePlayer *pPlayer )
return true;
}
//-----------------------------------------------------------------------------
// Purpose: multiplayer does not do autoaiming.
//-----------------------------------------------------------------------------
Vector CHL2MP_Player::GetAutoaimVector( float flScale )
{
//No Autoaim
Vector forward;
AngleVectors( EyeAngles() + m_Local.m_vecPunchAngle, &forward );
return forward;
}
//-----------------------------------------------------------------------------
// Purpose: Do nothing multiplayer_animstate takes care of animation.
// Input : playerAnim -
//-----------------------------------------------------------------------------
void CHL2MP_Player::SetAnimation( PLAYER_ANIM playerAnim )
{
return;
}
// -------------------------------------------------------------------------------- //
// Player animation event. Sent to the client when a player fires, jumps, reloads, etc..
// -------------------------------------------------------------------------------- //
class CTEPlayerAnimEvent : public CBaseTempEntity
{
public:
DECLARE_CLASS( CTEPlayerAnimEvent, CBaseTempEntity );
DECLARE_SERVERCLASS();
CTEPlayerAnimEvent( const char *name ) : CBaseTempEntity( name )
{
}
CNetworkHandle( CBasePlayer, m_hPlayer );
CNetworkVar( int, m_iEvent );
CNetworkVar( int, m_nData );
};
IMPLEMENT_SERVERCLASS_ST_NOBASE( CTEPlayerAnimEvent, DT_TEPlayerAnimEvent )
SendPropEHandle( SENDINFO( m_hPlayer ) ),
SendPropInt( SENDINFO( m_iEvent ), Q_log2( PLAYERANIMEVENT_COUNT ) + 1, SPROP_UNSIGNED ),
SendPropInt( SENDINFO( m_nData ), 32 )
END_SEND_TABLE()
static CTEPlayerAnimEvent g_TEPlayerAnimEvent( "PlayerAnimEvent" );
void TE_PlayerAnimEvent( CBasePlayer *pPlayer, PlayerAnimEvent_t event, int nData )
{
CPVSFilter filter( (const Vector&)pPlayer->EyePosition() );
//Tony; use prediction rules.
filter.UsePredictionRules();
g_TEPlayerAnimEvent.m_hPlayer = pPlayer;
g_TEPlayerAnimEvent.m_iEvent = event;
g_TEPlayerAnimEvent.m_nData = nData;
g_TEPlayerAnimEvent.Create( filter, 0 );
}
void CHL2MP_Player::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
{
m_PlayerAnimState->DoAnimationEvent( event, nData );
TE_PlayerAnimEvent( this, event, nData ); // Send to any clients who can see this guy.
}
//-----------------------------------------------------------------------------
// Purpose: Override setup bones so that is uses the render angles from
// the HL2MP animation state to setup the hitboxes.
//-----------------------------------------------------------------------------
void CHL2MP_Player::SetupBones( matrix3x4_t *pBoneToWorld, int boneMask )
{
VPROF_BUDGET( "CHL2MP_Player::SetupBones", VPROF_BUDGETGROUP_SERVER_ANIM );
// Get the studio header.
Assert( GetModelPtr() );
CStudioHdr *pStudioHdr = GetModelPtr( );
if ( !pStudioHdr )
return;
Vector pos[MAXSTUDIOBONES];
Quaternion q[MAXSTUDIOBONES];
// Adjust hit boxes based on IK driven offset.
Vector adjOrigin = GetAbsOrigin() + Vector( 0, 0, m_flEstIkOffset );
// FIXME: pass this into Studio_BuildMatrices to skip transforms
CBoneBitList boneComputed;
if ( m_pIk )
{
m_iIKCounter++;
m_pIk->Init( pStudioHdr, GetAbsAngles(), adjOrigin, gpGlobals->curtime, m_iIKCounter, boneMask );
GetSkeleton( pStudioHdr, pos, q, boneMask );
m_pIk->UpdateTargets( pos, q, pBoneToWorld, boneComputed );
CalculateIKLocks( gpGlobals->curtime );
m_pIk->SolveDependencies( pos, q, pBoneToWorld, boneComputed );
}
else
{
GetSkeleton( pStudioHdr, pos, q, boneMask );
}
CBaseAnimating *pParent = dynamic_cast< CBaseAnimating* >( GetMoveParent() );
if ( pParent )
{
// We're doing bone merging, so do special stuff here.
CBoneCache *pParentCache = pParent->GetBoneCache();
if ( pParentCache )
{
BuildMatricesWithBoneMerge(
pStudioHdr,
m_PlayerAnimState->GetRenderAngles(),
adjOrigin,
pos,
q,
pBoneToWorld,
pParent,
pParentCache );
return;
}
}
Studio_BuildMatrices(
pStudioHdr,
m_PlayerAnimState->GetRenderAngles(),
adjOrigin,
pos,
q,
-1,
GetModelScale(), // Scaling
pBoneToWorld,
boneMask );
}

View file

@ -16,6 +16,7 @@ class CHL2MP_Player;
#include "hl2_player.h"
#include "simtimer.h"
#include "soundenvelope.h"
#include "hl2mp_playeranimstate.h"
#include "hl2mp_player_shared.h"
#include "hl2mp_gamerules.h"
#include "utldict.h"
@ -51,13 +52,17 @@ public:
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
DECLARE_PREDICTABLE();
// This passes the event to the client's and server's CHL2MPPlayerAnimState.
void DoAnimationEvent( PlayerAnimEvent_t event, int nData = 0 );
void SetupBones( matrix3x4_t *pBoneToWorld, int boneMask );
virtual void Precache( void );
virtual void Spawn( void );
virtual void PostThink( void );
virtual void PreThink( void );
virtual void PlayerDeathThink( void );
virtual void SetAnimation( PLAYER_ANIM playerAnim );
virtual bool HandleCommand_JoinTeam( int team );
virtual bool ClientCommand( const CCommand &args );
virtual void CreateViewModel( int viewmodelindex = 0 );
@ -82,9 +87,8 @@ public:
void PrecacheFootStepSounds( void );
bool ValidatePlayerModel( const char *pModel );
QAngle GetAnimEyeAngles( void ) { return m_angEyeAngles.Get(); }
Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL );
virtual Vector GetAutoaimVector( float flDelta );
void CheatImpulseCommands( int iImpulse );
void CreateRagdollEntity( void );
@ -93,7 +97,8 @@ public:
void NoteWeaponFired( void );
void ResetAnimation( void );
void SetAnimation( PLAYER_ANIM playerAnim );
void SetPlayerModel( void );
void SetPlayerTeamModel( void );
Activity TranslateTeamActivity( Activity ActToTranslate );
@ -140,8 +145,9 @@ public:
private:
CHL2MPPlayerAnimState *m_PlayerAnimState;
CNetworkQAngle( m_angEyeAngles );
CPlayerAnimState m_PlayerAnimState;
int m_iLastWeaponFireUsercmd;
int m_iModelType;
@ -161,7 +167,7 @@ private:
// This lets us rate limit the commands the players can execute so they don't overflow things like reliable buffers.
CUtlDict<float,int> m_RateLimitLastCommandTimes;
bool m_bEnterObserver;
bool m_bEnterObserver;
bool m_bReady;
};

View file

@ -335,15 +335,33 @@ float CalculatePhysicsImpactDamage( int index, gamevcollisionevent_t *pEvent, co
if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
{
// if the player is holding the object, use its real mass (player holding reduced the mass)
CBasePlayer *pPlayer = NULL;
if ( gpGlobals->maxClients == 1 )
{
// if the player is holding the object, use it's real mass (player holding reduced the mass)
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
if ( pPlayer )
pPlayer = UTIL_GetLocalPlayer();
}
else
{
// See which MP player is holding the physics object and then use that player to get the real mass of the object.
// This is ugly but better than having linkage between an object and its "holding" player.
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
otherMass = pPlayer->GetHeldObjectMass( pEvent->pObjects[otherIndex] );
CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i );
if ( tempPlayer && pEvent->pEntities[index] == tempPlayer->GetHeldObject() )
{
pPlayer = tempPlayer;
break;
}
}
}
if ( pPlayer )
{
otherMass = pPlayer->GetHeldObjectMass( pEvent->pObjects[otherIndex] );
}
}
// NOTE: sum the mass of each object in this system for the purpose of damage
@ -438,19 +456,36 @@ float CalculatePhysicsImpactDamage( int index, gamevcollisionevent_t *pEvent, co
}
else if ( pEvent->pObjects[index]->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
{
// if the player is holding the object, use it's real mass (player holding reduced the mass)
CBasePlayer *pPlayer = NULL;
if ( gpGlobals->maxClients == 1 )
{
// if the player is holding the object, use it's real mass (player holding reduced the mass)
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
if ( pPlayer )
pPlayer = UTIL_GetLocalPlayer();
}
else
{
// See which MP player is holding the physics object and then use that player to get the real mass of the object.
// This is ugly but better than having linkage between an object and its "holding" player.
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
float mass = pPlayer->GetHeldObjectMass( pEvent->pObjects[index] );
if ( mass > 0 )
CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i );
if ( tempPlayer && pEvent->pEntities[index] == tempPlayer->GetHeldObject() )
{
invMass = 1.0f / mass;
pPlayer = tempPlayer;
break;
}
}
}
if ( pPlayer )
{
float mass = pPlayer->GetHeldObjectMass( pEvent->pObjects[index] );
if ( mass > 0 )
{
invMass = 1.0f / mass;
}
}
}
eliminatedEnergy *= invMass * energyScale;

View file

@ -1079,7 +1079,7 @@ int CBasePlayer::OnTakeDamage( const CTakeDamageInfo &inputInfo )
return 0;
}
if ( IsInCommentaryMode() )
if ( IsInCommentaryMode() )
{
if( !ShouldTakeDamageInCommentaryMode( info ) )
return 0;
@ -1466,7 +1466,7 @@ void CBasePlayer::PackDeadPlayerItems( void )
// get the game rules
iWeaponRules = g_pGameRules->DeadPlayerWeapons( this );
iAmmoRules = g_pGameRules->DeadPlayerAmmo( this );
iAmmoRules = g_pGameRules->DeadPlayerAmmo( this );
if ( iWeaponRules == GR_PLR_DROP_GUN_NO && iAmmoRules == GR_PLR_DROP_AMMO_NO )
{
@ -1552,7 +1552,7 @@ void CBasePlayer::RemoveAllItems( bool removeSuit )
Weapon_SetLast( NULL );
RemoveAllWeapons();
RemoveAllAmmo();
RemoveAllAmmo();
if ( removeSuit )
{
@ -1636,7 +1636,7 @@ int CBasePlayer::OnTakeDamage_Alive( const CTakeDamageInfo &info )
event->SetInt("attacker", 0 ); // hurt by "world"
}
gameeventmanager->FireEvent( event );
gameeventmanager->FireEvent( event );
}
// Insert a combat sound so that nearby NPCs hear battle
@ -2255,17 +2255,17 @@ bool CBasePlayer::StartObserverMode(int mode)
m_afPhysicsFlags |= PFLAG_OBSERVER;
// Holster weapon immediately, to allow it to cleanup
if ( GetActiveWeapon() )
if ( GetActiveWeapon() )
GetActiveWeapon()->Holster();
// clear out the suit message cache so we don't keep chattering
SetSuitUpdate(NULL, FALSE, 0);
SetSuitUpdate(NULL, FALSE, 0);
SetGroundEntity( (CBaseEntity *)NULL );
RemoveFlag( FL_DUCKING );
AddSolidFlags( FSOLID_NOT_SOLID );
AddSolidFlags( FSOLID_NOT_SOLID );
SetObserverMode( mode );
@ -2275,7 +2275,7 @@ bool CBasePlayer::StartObserverMode(int mode)
}
// Setup flags
m_Local.m_iHideHUD = HIDEHUD_HEALTH;
m_Local.m_iHideHUD = HIDEHUD_HEALTH;
m_takedamage = DAMAGE_NO;
// Become invisible
@ -2662,7 +2662,7 @@ bool CBasePlayer::IsValidObserverTarget(CBaseEntity * target)
CBasePlayer * player = ToBasePlayer( target );
/* Don't spec observers or players who haven't picked a class yet
if ( player->IsObserver() )
if ( player->IsObserver() )
return false; */
if( player == this )
@ -2754,10 +2754,10 @@ CBaseEntity * CBasePlayer::FindNextObserverTarget(bool bReverse)
currentIndex += iDir;
// Loop through the clients
if (currentIndex > gpGlobals->maxClients)
currentIndex = 1;
if (currentIndex > gpGlobals->maxClients)
currentIndex = 1;
else if (currentIndex < 1)
currentIndex = gpGlobals->maxClients;
currentIndex = gpGlobals->maxClients;
} while ( currentIndex != startIndex );
@ -2867,6 +2867,10 @@ float CBasePlayer::GetHeldObjectMass( IPhysicsObject *pHeldObject )
return 0;
}
CBaseEntity *CBasePlayer::GetHeldObject( void )
{
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Server side of jumping rules. Most jumping logic is already
@ -4955,7 +4959,7 @@ void CBasePlayer::Spawn( void )
m_Local.m_bDucked = false;// This will persist over round restart if you hold duck otherwise.
m_Local.m_bDucking = false;
SetViewOffset( VEC_VIEW_SCALED( this ) );
SetViewOffset( VEC_VIEW_SCALED( this ) );
Precache();
m_bitsDamageType = 0;
@ -5599,7 +5603,7 @@ void CSprayCan::Think( void )
CBasePlayer *pPlayer = ToBasePlayer( GetOwnerEntity() );
if ( pPlayer )
{
int playernum = pPlayer->entindex();
int playernum = pPlayer->entindex();
Vector forward;
trace_t tr;
@ -5877,12 +5881,12 @@ void CBasePlayer::ImpulseCommands( )
switch (iImpulse)
{
case 100:
// temporary flashlight for level designers
if ( FlashlightIsOn() )
// temporary flashlight for level designers
if ( FlashlightIsOn() )
{
FlashlightTurnOff();
}
else
else
{
FlashlightTurnOn();
}
@ -6413,7 +6417,7 @@ bool CBasePlayer::ClientCommand( const CCommand &args )
else
{
// switch to next spec mode if no parameter given
mode = GetObserverMode() + 1;
mode = GetObserverMode() + 1;
if ( mode > LAST_PLAYER_OBSERVERMODE )
{
@ -8369,7 +8373,7 @@ void CBasePlayer::SetVCollisionState( const Vector &vecAbsOrigin, const Vector &
switch( collisionState )
{
case VPHYS_WALK:
m_pShadowStand->SetPosition( vecAbsOrigin, vec3_angle, true );
m_pShadowStand->SetPosition( vecAbsOrigin, vec3_angle, true );
m_pShadowStand->SetVelocity( &vecAbsVelocity, NULL );
m_pShadowCrouch->EnableCollisions( false );
m_pPhysicsController->SetObject( m_pShadowStand );

View file

@ -550,6 +550,7 @@ public:
virtual void PickupObject( CBaseEntity *pObject, bool bLimitMassAndSize = true ) {}
virtual void ForceDropOfCarriedPhysObjects( CBaseEntity *pOnlyIfHoldindThis = NULL ) {}
virtual float GetHeldObjectMass( IPhysicsObject *pHeldObject );
virtual CBaseEntity *GetHeldObject( void );
void CheckSuitUpdate();
void SetSuitUpdate(const char *name, int fgroup, int iNoRepeat);
@ -922,7 +923,7 @@ protected:
int m_iTrain; // Train control position
float m_iRespawnFrames; // used in PlayerDeathThink() to make sure players can always respawn
unsigned int m_afPhysicsFlags; // physics flags - set when 'normal' physics should be revisited or overriden
unsigned int m_afPhysicsFlags; // physics flags - set when 'normal' physics should be revisited or overriden
// Vehicles
CNetworkHandle( CBaseEntity, m_hVehicle );

View file

@ -15,7 +15,7 @@ $Configuration
{
$Compiler
{
$AdditionalIncludeDirectories "$BASE;$SRCDIR\game\shared\hl2,.\hl2,.\hl2mp,$SRCDIR\game\shared\hl2mp"
$AdditionalIncludeDirectories "$BASE;$SRCDIR\game\shared\hl2,.\hl2,.\hl2mp,$SRCDIR\game\shared\hl2mp,$SRCDIR\game\shared\Multiplayer"
$PreprocessorDefinitions "$BASE;HL2MP;HL2_DLL"
}
}
@ -258,6 +258,10 @@ $Project "Server (HL2MP)"
$File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.h"
$File "$SRCDIR\game\shared\hl2mp\hl2mp_weapon_parse.cpp"
$File "$SRCDIR\game\shared\hl2mp\hl2mp_weapon_parse.h"
$File "$SRCDIR\game\shared\hl2mp\hl2mp_playeranimstate.h"
$File "$SRCDIR\game\shared\hl2mp\hl2mp_playeranimstate.cpp"
$File "$SRCDIR\game\shared\Multiplayer\multiplayer_animstate.h"
$File "$SRCDIR\game\shared\Multiplayer\multiplayer_animstate.cpp"
$Folder "Weapons"
{

View file

@ -513,6 +513,9 @@ public:
bool WantsToOverrideViewmodelAttachments( void ) { return false; }
#endif
//Tony; notifications of any third person switches.
virtual void ThirdPersonSwitch( bool bThirdPerson ) {};
#endif // End client-only methods
virtual bool CanLower( void ) { return false; }

View file

@ -18,6 +18,9 @@
#include "engine/IEngineSound.h"
#include "SoundEmitterSystem/isoundemittersystembase.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
extern ConVar sv_footsteps;
const char *g_ppszPlayerSoundPrefixNames[PLAYER_SOUNDS_MAX] =
@ -120,458 +123,3 @@ void CHL2MP_Player::PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, f
EmitSound( filter, entindex(), ep );
}
//==========================
// ANIMATION CODE
//==========================
// Below this many degrees, slow down turning rate linearly
#define FADE_TURN_DEGREES 45.0f
// After this, need to start turning feet
#define MAX_TORSO_ANGLE 90.0f
// Below this amount, don't play a turning animation/perform IK
#define MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION 15.0f
static ConVar tf2_feetyawrunscale( "tf2_feetyawrunscale", "2", FCVAR_REPLICATED, "Multiplier on tf2_feetyawrate to allow turning faster when running." );
extern ConVar sv_backspeed;
extern ConVar mp_feetyawrate;
extern ConVar mp_facefronttime;
extern ConVar mp_ik;
CPlayerAnimState::CPlayerAnimState( CHL2MP_Player *outer )
: m_pOuter( outer )
{
m_flGaitYaw = 0.0f;
m_flGoalFeetYaw = 0.0f;
m_flCurrentFeetYaw = 0.0f;
m_flCurrentTorsoYaw = 0.0f;
m_flLastYaw = 0.0f;
m_flLastTurnTime = 0.0f;
m_flTurnCorrectionTime = 0.0f;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPlayerAnimState::Update()
{
m_angRender = GetOuter()->GetLocalAngles();
m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f;
ComputePoseParam_BodyYaw();
ComputePoseParam_BodyPitch(GetOuter()->GetModelPtr());
ComputePoseParam_BodyLookYaw();
ComputePlaybackRate();
#ifdef CLIENT_DLL
GetOuter()->UpdateLookAt();
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPlayerAnimState::ComputePlaybackRate()
{
// Determine ideal playback rate
Vector vel;
GetOuterAbsVelocity( vel );
float speed = vel.Length2D();
bool isMoving = ( speed > 0.5f ) ? true : false;
float maxspeed = GetOuter()->GetSequenceGroundSpeed( GetOuter()->GetSequence() );
if ( isMoving && ( maxspeed > 0.0f ) )
{
float flFactor = 1.0f;
// Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below
GetOuter()->SetPlaybackRate( ( speed * flFactor ) / maxspeed );
// BUG BUG:
// This stuff really should be m_flPlaybackRate = speed / m_flGroundSpeed
}
else
{
GetOuter()->SetPlaybackRate( 1.0f );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : CBasePlayer
//-----------------------------------------------------------------------------
CHL2MP_Player *CPlayerAnimState::GetOuter()
{
return m_pOuter;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : dt -
//-----------------------------------------------------------------------------
void CPlayerAnimState::EstimateYaw( void )
{
float dt = gpGlobals->frametime;
if ( !dt )
{
return;
}
Vector est_velocity;
QAngle angles;
GetOuterAbsVelocity( est_velocity );
angles = GetOuter()->GetLocalAngles();
if ( est_velocity[1] == 0 && est_velocity[0] == 0 )
{
float flYawDiff = angles[YAW] - m_flGaitYaw;
flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360;
if (flYawDiff > 180)
flYawDiff -= 360;
if (flYawDiff < -180)
flYawDiff += 360;
if (dt < 0.25)
flYawDiff *= dt * 4;
else
flYawDiff *= dt;
m_flGaitYaw += flYawDiff;
m_flGaitYaw = m_flGaitYaw - (int)(m_flGaitYaw / 360) * 360;
}
else
{
m_flGaitYaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI);
if (m_flGaitYaw > 180)
m_flGaitYaw = 180;
else if (m_flGaitYaw < -180)
m_flGaitYaw = -180;
}
}
//-----------------------------------------------------------------------------
// Purpose: Override for backpeddling
// Input : dt -
//-----------------------------------------------------------------------------
void CPlayerAnimState::ComputePoseParam_BodyYaw( void )
{
int iYaw = GetOuter()->LookupPoseParameter( "move_yaw" );
if ( iYaw < 0 )
return;
// view direction relative to movement
float flYaw;
EstimateYaw();
QAngle angles = GetOuter()->GetLocalAngles();
float ang = angles[ YAW ];
if ( ang > 180.0f )
{
ang -= 360.0f;
}
else if ( ang < -180.0f )
{
ang += 360.0f;
}
// calc side to side turning
flYaw = ang - m_flGaitYaw;
// Invert for mapping into 8way blend
flYaw = -flYaw;
flYaw = flYaw - (int)(flYaw / 360) * 360;
if (flYaw < -180)
{
flYaw = flYaw + 360;
}
else if (flYaw > 180)
{
flYaw = flYaw - 360;
}
GetOuter()->SetPoseParameter( iYaw, flYaw );
#ifndef CLIENT_DLL
//Adrian: Make the model's angle match the legs so the hitboxes match on both sides.
GetOuter()->SetLocalAngles( QAngle( GetOuter()->GetAnimEyeAngles().x, m_flCurrentFeetYaw, 0 ) );
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr )
{
// Get pitch from v_angle
float flPitch = GetOuter()->GetLocalAngles()[ PITCH ];
if ( flPitch > 180.0f )
{
flPitch -= 360.0f;
}
flPitch = clamp( flPitch, -90, 90 );
QAngle absangles = GetOuter()->GetAbsAngles();
absangles.x = 0.0f;
m_angRender = absangles;
m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f;
// See if we have a blender for pitch
GetOuter()->SetPoseParameter( pStudioHdr, "aim_pitch", flPitch );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : goal -
// maxrate -
// dt -
// current -
// Output : int
//-----------------------------------------------------------------------------
int CPlayerAnimState::ConvergeAngles( float goal,float maxrate, float dt, float& current )
{
int direction = TURN_NONE;
float anglediff = goal - current;
float anglediffabs = fabs( anglediff );
anglediff = AngleNormalize( anglediff );
float scale = 1.0f;
if ( anglediffabs <= FADE_TURN_DEGREES )
{
scale = anglediffabs / FADE_TURN_DEGREES;
// Always do at least a bit of the turn ( 1% )
scale = clamp( scale, 0.01f, 1.0f );
}
float maxmove = maxrate * dt * scale;
if ( fabs( anglediff ) < maxmove )
{
current = goal;
}
else
{
if ( anglediff > 0 )
{
current += maxmove;
direction = TURN_LEFT;
}
else
{
current -= maxmove;
direction = TURN_RIGHT;
}
}
current = AngleNormalize( current );
return direction;
}
void CPlayerAnimState::ComputePoseParam_BodyLookYaw( void )
{
QAngle absangles = GetOuter()->GetAbsAngles();
absangles.y = AngleNormalize( absangles.y );
m_angRender = absangles;
m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f;
// See if we even have a blender for pitch
int upper_body_yaw = GetOuter()->LookupPoseParameter( "aim_yaw" );
if ( upper_body_yaw < 0 )
{
return;
}
// Assume upper and lower bodies are aligned and that we're not turning
float flGoalTorsoYaw = 0.0f;
int turning = TURN_NONE;
float turnrate = 360.0f;
Vector vel;
GetOuterAbsVelocity( vel );
bool isMoving = ( vel.Length() > 1.0f ) ? true : false;
if ( !isMoving )
{
// Just stopped moving, try and clamp feet
if ( m_flLastTurnTime <= 0.0f )
{
m_flLastTurnTime = gpGlobals->curtime;
m_flLastYaw = GetOuter()->GetAnimEyeAngles().y;
// Snap feet to be perfectly aligned with torso/eyes
m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y;
m_flCurrentFeetYaw = m_flGoalFeetYaw;
m_nTurningInPlace = TURN_NONE;
}
// If rotating in place, update stasis timer
if ( m_flLastYaw != GetOuter()->GetAnimEyeAngles().y )
{
m_flLastTurnTime = gpGlobals->curtime;
m_flLastYaw = GetOuter()->GetAnimEyeAngles().y;
}
if ( m_flGoalFeetYaw != m_flCurrentFeetYaw )
{
m_flLastTurnTime = gpGlobals->curtime;
}
turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw );
QAngle eyeAngles = GetOuter()->GetAnimEyeAngles();
QAngle vAngle = GetOuter()->GetLocalAngles();
// See how far off current feetyaw is from true yaw
float yawdelta = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw;
yawdelta = AngleNormalize( yawdelta );
bool rotated_too_far = false;
float yawmagnitude = fabs( yawdelta );
// If too far, then need to turn in place
if ( yawmagnitude > 45 )
{
rotated_too_far = true;
}
// Standing still for a while, rotate feet around to face forward
// Or rotated too far
// FIXME: Play an in place turning animation
if ( rotated_too_far ||
( gpGlobals->curtime > m_flLastTurnTime + mp_facefronttime.GetFloat() ) )
{
m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y;
m_flLastTurnTime = gpGlobals->curtime;
/* float yd = m_flCurrentFeetYaw - m_flGoalFeetYaw;
if ( yd > 0 )
{
m_nTurningInPlace = TURN_RIGHT;
}
else if ( yd < 0 )
{
m_nTurningInPlace = TURN_LEFT;
}
else
{
m_nTurningInPlace = TURN_NONE;
}
turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw );
yawdelta = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw;*/
}
// Snap upper body into position since the delta is already smoothed for the feet
flGoalTorsoYaw = yawdelta;
m_flCurrentTorsoYaw = flGoalTorsoYaw;
}
else
{
m_flLastTurnTime = 0.0f;
m_nTurningInPlace = TURN_NONE;
m_flCurrentFeetYaw = m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y;
flGoalTorsoYaw = 0.0f;
m_flCurrentTorsoYaw = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw;
}
if ( turning == TURN_NONE )
{
m_nTurningInPlace = turning;
}
if ( m_nTurningInPlace != TURN_NONE )
{
// If we're close to finishing the turn, then turn off the turning animation
if ( fabs( m_flCurrentFeetYaw - m_flGoalFeetYaw ) < MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION )
{
m_nTurningInPlace = TURN_NONE;
}
}
// Rotate entire body into position
absangles = GetOuter()->GetAbsAngles();
absangles.y = m_flCurrentFeetYaw;
m_angRender = absangles;
m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f;
GetOuter()->SetPoseParameter( upper_body_yaw, clamp( m_flCurrentTorsoYaw, -60.0f, 60.0f ) );
/*
// FIXME: Adrian, what is this?
int body_yaw = GetOuter()->LookupPoseParameter( "body_yaw" );
if ( body_yaw >= 0 )
{
GetOuter()->SetPoseParameter( body_yaw, 30 );
}
*/
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : activity -
// Output : Activity
//-----------------------------------------------------------------------------
Activity CPlayerAnimState::BodyYawTranslateActivity( Activity activity )
{
// Not even standing still, sigh
if ( activity != ACT_IDLE )
return activity;
// Not turning
switch ( m_nTurningInPlace )
{
default:
case TURN_NONE:
return activity;
/*
case TURN_RIGHT:
return ACT_TURNRIGHT45;
case TURN_LEFT:
return ACT_TURNLEFT45;
*/
case TURN_RIGHT:
case TURN_LEFT:
return mp_ik.GetBool() ? ACT_TURN : activity;
}
Assert( 0 );
return activity;
}
const QAngle& CPlayerAnimState::GetRenderAngles()
{
return m_angRender;
}
void CPlayerAnimState::GetOuterAbsVelocity( Vector& vel )
{
#if defined( CLIENT_DLL )
GetOuter()->EstimateAbsVelocity( vel );
#else
vel = GetOuter()->GetAbsVelocity();
#endif
}

View file

@ -34,64 +34,5 @@ enum HL2MPPlayerState
#define CHL2MP_Player C_HL2MP_Player
#endif
class CPlayerAnimState
{
public:
enum
{
TURN_NONE = 0,
TURN_LEFT,
TURN_RIGHT
};
CPlayerAnimState( CHL2MP_Player *outer );
Activity BodyYawTranslateActivity( Activity activity );
void Update();
const QAngle& GetRenderAngles();
void GetPoseParameters( CStudioHdr *pStudioHdr, float poseParameter[MAXSTUDIOPOSEPARAM] );
CHL2MP_Player *GetOuter();
private:
void GetOuterAbsVelocity( Vector& vel );
int ConvergeAngles( float goal,float maxrate, float dt, float& current );
void EstimateYaw( void );
void ComputePoseParam_BodyYaw( void );
void ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr );
void ComputePoseParam_BodyLookYaw( void );
void ComputePlaybackRate();
CHL2MP_Player *m_pOuter;
float m_flGaitYaw;
float m_flStoredCycle;
// The following variables are used for tweaking the yaw of the upper body when standing still and
// making sure that it smoothly blends in and out once the player starts moving
// Direction feet were facing when we stopped moving
float m_flGoalFeetYaw;
float m_flCurrentFeetYaw;
float m_flCurrentTorsoYaw;
// To check if they are rotating in place
float m_flLastYaw;
// Time when we stopped moving
float m_flLastTurnTime;
// One of the above enums
int m_nTurningInPlace;
QAngle m_angRender;
float m_flTurnCorrectionTime;
};
#endif //HL2MP_PLAYER_SHARED_h

View file

@ -0,0 +1,703 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
#include "cbase.h"
#include "base_playeranimstate.h"
#include "tier0/vprof.h"
#include "animation.h"
#include "studio.h"
#include "apparent_velocity_helper.h"
#include "utldict.h"
#include "hl2mp_playeranimstate.h"
#include "base_playeranimstate.h"
#include "datacache/imdlcache.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#else
#include "hl2mp_player.h"
#endif
#define HL2MP_RUN_SPEED 320.0f
#define HL2MP_WALK_SPEED 75.0f
#define HL2MP_CROUCHWALK_SPEED 110.0f
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pPlayer -
// Output : CMultiPlayerAnimState*
//-----------------------------------------------------------------------------
CHL2MPPlayerAnimState* CreateHL2MPPlayerAnimState( CHL2MP_Player *pPlayer )
{
MDLCACHE_CRITICAL_SECTION();
// Setup the movement data.
MultiPlayerMovementData_t movementData;
movementData.m_flBodyYawRate = 720.0f;
movementData.m_flRunSpeed = HL2MP_RUN_SPEED;
movementData.m_flWalkSpeed = HL2MP_WALK_SPEED;
movementData.m_flSprintSpeed = -1.0f;
// Create animation state for this player.
CHL2MPPlayerAnimState *pRet = new CHL2MPPlayerAnimState( pPlayer, movementData );
// Specific HL2MP player initialization.
pRet->InitHL2MPAnimState( pPlayer );
return pRet;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
//-----------------------------------------------------------------------------
CHL2MPPlayerAnimState::CHL2MPPlayerAnimState()
{
m_pHL2MPPlayer = NULL;
// Don't initialize HL2MP specific variables here. Init them in InitHL2MPAnimState()
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pPlayer -
// &movementData -
//-----------------------------------------------------------------------------
CHL2MPPlayerAnimState::CHL2MPPlayerAnimState( CBasePlayer *pPlayer, MultiPlayerMovementData_t &movementData )
: CMultiPlayerAnimState( pPlayer, movementData )
{
m_pHL2MPPlayer = NULL;
// Don't initialize HL2MP specific variables here. Init them in InitHL2MPAnimState()
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
//-----------------------------------------------------------------------------
CHL2MPPlayerAnimState::~CHL2MPPlayerAnimState()
{
}
//-----------------------------------------------------------------------------
// Purpose: Initialize HL2MP specific animation state.
// Input : *pPlayer -
//-----------------------------------------------------------------------------
void CHL2MPPlayerAnimState::InitHL2MPAnimState( CHL2MP_Player *pPlayer )
{
m_pHL2MPPlayer = pPlayer;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPPlayerAnimState::ClearAnimationState( void )
{
BaseClass::ClearAnimationState();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : actDesired -
// Output : Activity
//-----------------------------------------------------------------------------
Activity CHL2MPPlayerAnimState::TranslateActivity( Activity actDesired )
{
// Hook into baseclass when / if hl2mp player models get swim animations.
Activity translateActivity = actDesired; //BaseClass::TranslateActivity( actDesired );
if ( GetHL2MPPlayer()->GetActiveWeapon() )
{
translateActivity = GetHL2MPPlayer()->GetActiveWeapon()->ActivityOverride( translateActivity, false );
}
return translateActivity;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPPlayerAnimState::Update( float eyeYaw, float eyePitch )
{
// Profile the animation update.
VPROF( "CHL2MPPlayerAnimState::Update" );
// Get the HL2MP player.
CHL2MP_Player *pHL2MPPlayer = GetHL2MPPlayer();
if ( !pHL2MPPlayer )
return;
// Get the studio header for the player.
CStudioHdr *pStudioHdr = pHL2MPPlayer->GetModelPtr();
if ( !pStudioHdr )
return;
// Check to see if we should be updating the animation state - dead, ragdolled?
if ( !ShouldUpdateAnimState() )
{
ClearAnimationState();
return;
}
// Store the eye angles.
m_flEyeYaw = AngleNormalize( eyeYaw );
m_flEyePitch = AngleNormalize( eyePitch );
// Compute the player sequences.
ComputeSequences( pStudioHdr );
if ( SetupPoseParameters( pStudioHdr ) )
{
// Pose parameter - what direction are the player's legs running in.
ComputePoseParam_MoveYaw( pStudioHdr );
// Pose parameter - Torso aiming (up/down).
ComputePoseParam_AimPitch( pStudioHdr );
// Pose parameter - Torso aiming (rotation).
ComputePoseParam_AimYaw( pStudioHdr );
}
#ifdef CLIENT_DLL
if ( C_BasePlayer::ShouldDrawLocalPlayer() )
{
m_pHL2MPPlayer->SetPlaybackRate( 1.0f );
}
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : event -
//-----------------------------------------------------------------------------
void CHL2MPPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
{
Activity iGestureActivity = ACT_INVALID;
switch( event )
{
case PLAYERANIMEVENT_ATTACK_PRIMARY:
{
// Weapon primary fire.
if ( m_pHL2MPPlayer->GetFlags() & FL_DUCKING )
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_PRIMARYFIRE );
else
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_PRIMARYFIRE );
iGestureActivity = ACT_VM_PRIMARYATTACK;
break;
}
case PLAYERANIMEVENT_VOICE_COMMAND_GESTURE:
{
if ( !IsGestureSlotActive( GESTURE_SLOT_ATTACK_AND_RELOAD ) )
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, (Activity)nData );
break;
}
case PLAYERANIMEVENT_ATTACK_SECONDARY:
{
// Weapon secondary fire.
if ( m_pHL2MPPlayer->GetFlags() & FL_DUCKING )
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_SECONDARYFIRE );
else
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_SECONDARYFIRE );
iGestureActivity = ACT_VM_PRIMARYATTACK;
break;
}
case PLAYERANIMEVENT_ATTACK_PRE:
{
if ( m_pHL2MPPlayer->GetFlags() & FL_DUCKING )
{
// Weapon pre-fire. Used for minigun windup, sniper aiming start, etc in crouch.
iGestureActivity = ACT_MP_ATTACK_CROUCH_PREFIRE;
}
else
{
// Weapon pre-fire. Used for minigun windup, sniper aiming start, etc.
iGestureActivity = ACT_MP_ATTACK_STAND_PREFIRE;
}
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, iGestureActivity, false );
break;
}
case PLAYERANIMEVENT_ATTACK_POST:
{
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_POSTFIRE );
break;
}
case PLAYERANIMEVENT_RELOAD:
{
// Weapon reload.
if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_CROUCH );
else
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_STAND );
break;
}
case PLAYERANIMEVENT_RELOAD_LOOP:
{
// Weapon reload.
if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_CROUCH_LOOP );
else
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_STAND_LOOP );
break;
}
case PLAYERANIMEVENT_RELOAD_END:
{
// Weapon reload.
if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_CROUCH_END );
else
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_STAND_END );
break;
}
default:
{
BaseClass::DoAnimationEvent( event, nData );
break;
}
}
#ifdef CLIENT_DLL
// Make the weapon play the animation as well
if ( iGestureActivity != ACT_INVALID )
{
CBaseCombatWeapon *pWeapon = GetHL2MPPlayer()->GetActiveWeapon();
if ( pWeapon )
{
// pWeapon->EnsureCorrectRenderingModel();
pWeapon->SendWeaponAnim( iGestureActivity );
// // Force animation events!
// pWeapon->ResetEventsParity(); // reset event parity so the animation events will occur on the weapon.
pWeapon->DoAnimationEvents( pWeapon->GetModelPtr() );
}
}
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *idealActivity -
//-----------------------------------------------------------------------------
bool CHL2MPPlayerAnimState::HandleSwimming( Activity &idealActivity )
{
bool bInWater = BaseClass::HandleSwimming( idealActivity );
return bInWater;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *idealActivity -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CHL2MPPlayerAnimState::HandleMoving( Activity &idealActivity )
{
return BaseClass::HandleMoving( idealActivity );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *idealActivity -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CHL2MPPlayerAnimState::HandleDucking( Activity &idealActivity )
{
if ( m_pHL2MPPlayer->GetFlags() & FL_DUCKING )
{
if ( GetOuterXYSpeed() < MOVING_MINIMUM_SPEED )
{
idealActivity = ACT_MP_CROUCH_IDLE;
}
else
{
idealActivity = ACT_MP_CROUCHWALK;
}
return true;
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose:
bool CHL2MPPlayerAnimState::HandleJumping( Activity &idealActivity )
{
Vector vecVelocity;
GetOuterAbsVelocity( vecVelocity );
if ( m_bJumping )
{
static bool bNewJump = false; //Tony; hl2mp players only have a 'hop'
if ( m_bFirstJumpFrame )
{
m_bFirstJumpFrame = false;
RestartMainSequence(); // Reset the animation.
}
// Reset if we hit water and start swimming.
if ( m_pHL2MPPlayer->GetWaterLevel() >= WL_Waist )
{
m_bJumping = false;
RestartMainSequence();
}
// Don't check if he's on the ground for a sec.. sometimes the client still has the
// on-ground flag set right when the message comes in.
else if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f )
{
if ( m_pHL2MPPlayer->GetFlags() & FL_ONGROUND )
{
m_bJumping = false;
RestartMainSequence();
if ( bNewJump )
{
RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_JUMP_LAND );
}
}
}
// if we're still jumping
if ( m_bJumping )
{
if ( bNewJump )
{
if ( gpGlobals->curtime - m_flJumpStartTime > 0.5 )
{
idealActivity = ACT_MP_JUMP_FLOAT;
}
else
{
idealActivity = ACT_MP_JUMP_START;
}
}
else
{
idealActivity = ACT_MP_JUMP;
}
}
}
if ( m_bJumping )
return true;
return false;
}
bool CHL2MPPlayerAnimState::SetupPoseParameters( CStudioHdr *pStudioHdr )
{
// Check to see if this has already been done.
if ( m_bPoseParameterInit )
return true;
// Save off the pose parameter indices.
if ( !pStudioHdr )
return false;
// Tony; just set them both to the same for now.
m_PoseParameterData.m_iMoveX = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "move_yaw" );
m_PoseParameterData.m_iMoveY = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "move_yaw" );
if ( ( m_PoseParameterData.m_iMoveX < 0 ) || ( m_PoseParameterData.m_iMoveY < 0 ) )
return false;
// Look for the aim pitch blender.
m_PoseParameterData.m_iAimPitch = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "aim_pitch" );
if ( m_PoseParameterData.m_iAimPitch < 0 )
return false;
// Look for aim yaw blender.
m_PoseParameterData.m_iAimYaw = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "aim_yaw" );
if ( m_PoseParameterData.m_iAimYaw < 0 )
return false;
m_bPoseParameterInit = true;
return true;
}
float SnapYawTo( float flValue );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPPlayerAnimState::EstimateYaw( void )
{
// Get the frame time.
float flDeltaTime = gpGlobals->frametime;
if ( flDeltaTime == 0.0f )
return;
#if 0 // 9way
// Get the player's velocity and angles.
Vector vecEstVelocity;
GetOuterAbsVelocity( vecEstVelocity );
QAngle angles = GetBasePlayer()->GetLocalAngles();
// If we are not moving, sync up the feet and eyes slowly.
if ( vecEstVelocity.x == 0.0f && vecEstVelocity.y == 0.0f )
{
float flYawDelta = angles[YAW] - m_PoseParameterData.m_flEstimateYaw;
flYawDelta = AngleNormalize( flYawDelta );
if ( flDeltaTime < 0.25f )
{
flYawDelta *= ( flDeltaTime * 4.0f );
}
else
{
flYawDelta *= flDeltaTime;
}
m_PoseParameterData.m_flEstimateYaw += flYawDelta;
AngleNormalize( m_PoseParameterData.m_flEstimateYaw );
}
else
{
m_PoseParameterData.m_flEstimateYaw = ( atan2( vecEstVelocity.y, vecEstVelocity.x ) * 180.0f / M_PI );
m_PoseParameterData.m_flEstimateYaw = clamp( m_PoseParameterData.m_flEstimateYaw, -180.0f, 180.0f );
}
#else
float dt = gpGlobals->frametime;
// Get the player's velocity and angles.
Vector vecEstVelocity;
GetOuterAbsVelocity( vecEstVelocity );
QAngle angles = GetBasePlayer()->GetLocalAngles();
if ( vecEstVelocity.y == 0 && vecEstVelocity.x == 0 )
{
float flYawDiff = angles[YAW] - m_PoseParameterData.m_flEstimateYaw;
flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360;
if (flYawDiff > 180)
flYawDiff -= 360;
if (flYawDiff < -180)
flYawDiff += 360;
if (dt < 0.25)
flYawDiff *= dt * 4;
else
flYawDiff *= dt;
m_PoseParameterData.m_flEstimateYaw += flYawDiff;
m_PoseParameterData.m_flEstimateYaw = m_PoseParameterData.m_flEstimateYaw - (int)(m_PoseParameterData.m_flEstimateYaw / 360) * 360;
}
else
{
m_PoseParameterData.m_flEstimateYaw = (atan2(vecEstVelocity.y, vecEstVelocity.x) * 180 / M_PI);
if (m_PoseParameterData.m_flEstimateYaw > 180)
m_PoseParameterData.m_flEstimateYaw = 180;
else if (m_PoseParameterData.m_flEstimateYaw < -180)
m_PoseParameterData.m_flEstimateYaw = -180;
}
#endif
}
//-----------------------------------------------------------------------------
// Purpose: Override for backpeddling
// Input : dt -
//-----------------------------------------------------------------------------
float SnapYawTo( float flValue );
void CHL2MPPlayerAnimState::ComputePoseParam_MoveYaw( CStudioHdr *pStudioHdr )
{
// Get the estimated movement yaw.
EstimateYaw();
#if 0 // 9way
ConVarRef mp_slammoveyaw("mp_slammoveyaw");
// Get the view yaw.
float flAngle = AngleNormalize( m_flEyeYaw );
// Calc side to side turning - the view vs. movement yaw.
float flYaw = flAngle - m_PoseParameterData.m_flEstimateYaw;
flYaw = AngleNormalize( -flYaw );
// Get the current speed the character is running.
bool bIsMoving;
float flPlaybackRate = CalcMovementPlaybackRate( &bIsMoving );
// Setup the 9-way blend parameters based on our speed and direction.
Vector2D vecCurrentMoveYaw( 0.0f, 0.0f );
if ( bIsMoving )
{
if ( mp_slammoveyaw.GetBool() )
flYaw = SnapYawTo( flYaw );
vecCurrentMoveYaw.x = cos( DEG2RAD( flYaw ) ) * flPlaybackRate;
vecCurrentMoveYaw.y = -sin( DEG2RAD( flYaw ) ) * flPlaybackRate;
}
GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveX, vecCurrentMoveYaw.x );
GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveY, vecCurrentMoveYaw.y );
m_DebugAnimData.m_vecMoveYaw = vecCurrentMoveYaw;
#else
// view direction relative to movement
float flYaw;
QAngle angles = GetBasePlayer()->GetLocalAngles();
float ang = angles[ YAW ];
if ( ang > 180.0f )
{
ang -= 360.0f;
}
else if ( ang < -180.0f )
{
ang += 360.0f;
}
// calc side to side turning
flYaw = ang - m_PoseParameterData.m_flEstimateYaw;
// Invert for mapping into 8way blend
flYaw = -flYaw;
flYaw = flYaw - (int)(flYaw / 360) * 360;
if (flYaw < -180)
{
flYaw = flYaw + 360;
}
else if (flYaw > 180)
{
flYaw = flYaw - 360;
}
//Tony; oops, i inverted this previously above.
GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveY, flYaw );
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPPlayerAnimState::ComputePoseParam_AimPitch( CStudioHdr *pStudioHdr )
{
// Get the view pitch.
float flAimPitch = m_flEyePitch;
// Set the aim pitch pose parameter and save.
GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iAimPitch, flAimPitch );
m_DebugAnimData.m_flAimPitch = flAimPitch;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPPlayerAnimState::ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr )
{
// Get the movement velocity.
Vector vecVelocity;
GetOuterAbsVelocity( vecVelocity );
// Check to see if we are moving.
bool bMoving = ( vecVelocity.Length() > 1.0f ) ? true : false;
// If we are moving or are prone and undeployed.
if ( bMoving || m_bForceAimYaw )
{
// The feet match the eye direction when moving - the move yaw takes care of the rest.
m_flGoalFeetYaw = m_flEyeYaw;
}
// Else if we are not moving.
else
{
// Initialize the feet.
if ( m_PoseParameterData.m_flLastAimTurnTime <= 0.0f )
{
m_flGoalFeetYaw = m_flEyeYaw;
m_flCurrentFeetYaw = m_flEyeYaw;
m_PoseParameterData.m_flLastAimTurnTime = gpGlobals->curtime;
}
// Make sure the feet yaw isn't too far out of sync with the eye yaw.
// TODO: Do something better here!
else
{
float flYawDelta = AngleNormalize( m_flGoalFeetYaw - m_flEyeYaw );
if ( fabs( flYawDelta ) > 45.0f )
{
float flSide = ( flYawDelta > 0.0f ) ? -1.0f : 1.0f;
m_flGoalFeetYaw += ( 45.0f * flSide );
}
}
}
// Fix up the feet yaw.
m_flGoalFeetYaw = AngleNormalize( m_flGoalFeetYaw );
if ( m_flGoalFeetYaw != m_flCurrentFeetYaw )
{
if ( m_bForceAimYaw )
{
m_flCurrentFeetYaw = m_flGoalFeetYaw;
}
else
{
ConvergeYawAngles( m_flGoalFeetYaw, 720.0f, gpGlobals->frametime, m_flCurrentFeetYaw );
m_flLastAimTurnTime = gpGlobals->curtime;
}
}
// Rotate the body into position.
m_angRender[YAW] = m_flCurrentFeetYaw;
// Find the aim(torso) yaw base on the eye and feet yaws.
float flAimYaw = m_flEyeYaw - m_flCurrentFeetYaw;
flAimYaw = AngleNormalize( flAimYaw );
// Set the aim yaw and save.
GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iAimYaw, flAimYaw );
m_DebugAnimData.m_flAimYaw = flAimYaw;
// Turn off a force aim yaw - either we have already updated or we don't need to.
m_bForceAimYaw = false;
#ifndef CLIENT_DLL
QAngle angle = GetBasePlayer()->GetAbsAngles();
angle[YAW] = m_flCurrentFeetYaw;
GetBasePlayer()->SetAbsAngles( angle );
#endif
}
//-----------------------------------------------------------------------------
// Purpose: Override the default, because hl2mp models don't use moveX
// Input : -
// Output : float
//-----------------------------------------------------------------------------
float CHL2MPPlayerAnimState::GetCurrentMaxGroundSpeed()
{
CStudioHdr *pStudioHdr = GetBasePlayer()->GetModelPtr();
if ( pStudioHdr == NULL )
return 1.0f;
// float prevX = GetBasePlayer()->GetPoseParameter( m_PoseParameterData.m_iMoveX );
float prevY = GetBasePlayer()->GetPoseParameter( m_PoseParameterData.m_iMoveY );
float d = sqrt( /*prevX * prevX + */prevY * prevY );
float newY;//, newX;
if ( d == 0.0 )
{
// newX = 1.0;
newY = 0.0;
}
else
{
// newX = prevX / d;
newY = prevY / d;
}
// GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveX, newX );
GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveY, newY );
float speed = GetBasePlayer()->GetSequenceGroundSpeed( GetBasePlayer()->GetSequence() );
// GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveX, prevX );
GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveY, prevY );
return speed;
}

View file

@ -0,0 +1,65 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
#ifndef HL2MP_PLAYERANIMSTATE_H
#define HL2MP_PLAYERANIMSTATE_H
#ifdef _WIN32
#pragma once
#endif
#include "convar.h"
#include "multiplayer_animstate.h"
#if defined( CLIENT_DLL )
class C_HL2MP_Player;
#define CHL2MP_Player C_HL2MP_Player
#else
class CHL2MP_Player;
#endif
// ------------------------------------------------------------------------------------------------ //
// CPlayerAnimState declaration.
// ------------------------------------------------------------------------------------------------ //
class CHL2MPPlayerAnimState : public CMultiPlayerAnimState
{
public:
DECLARE_CLASS( CHL2MPPlayerAnimState, CMultiPlayerAnimState );
CHL2MPPlayerAnimState();
CHL2MPPlayerAnimState( CBasePlayer *pPlayer, MultiPlayerMovementData_t &movementData );
~CHL2MPPlayerAnimState();
void InitHL2MPAnimState( CHL2MP_Player *pPlayer );
CHL2MP_Player *GetHL2MPPlayer( void ) { return m_pHL2MPPlayer; }
virtual void ClearAnimationState();
virtual Activity TranslateActivity( Activity actDesired );
virtual void Update( float eyeYaw, float eyePitch );
void DoAnimationEvent( PlayerAnimEvent_t event, int nData = 0 );
bool HandleMoving( Activity &idealActivity );
bool HandleJumping( Activity &idealActivity );
bool HandleDucking( Activity &idealActivity );
bool HandleSwimming( Activity &idealActivity );
virtual float GetCurrentMaxGroundSpeed();
private:
bool SetupPoseParameters( CStudioHdr *pStudioHdr );
virtual void EstimateYaw( void );
virtual void ComputePoseParam_MoveYaw( CStudioHdr *pStudioHdr );
virtual void ComputePoseParam_AimPitch( CStudioHdr *pStudioHdr );
virtual void ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr );
CHL2MP_Player *m_pHL2MPPlayer;
bool m_bInAirWalk;
float m_flHoldDeployedPoseUntilTime;
};
CHL2MPPlayerAnimState *CreateHL2MPPlayerAnimState( CHL2MP_Player *pPlayer );
#endif // HL2MP_PLAYERANIMSTATE_H

View file

@ -35,10 +35,7 @@ public:
void PrimaryAttack( void );
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
private:
@ -57,25 +54,25 @@ LINK_ENTITY_TO_CLASS( weapon_357, CWeapon357 );
PRECACHE_WEAPON_REGISTER( weapon_357 );
#ifndef CLIENT_DLL
acttable_t CWeapon357::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_PISTOL, false },
{ ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_PISTOL, false },
{ ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_PISTOL, false },
{ ACT_MP_RUN, ACT_HL2MP_RUN_PISTOL, false },
{ ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_PISTOL, false },
{ ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false },
{ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false },
{ ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false },
{ ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false },
{ ACT_MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false },
};
IMPLEMENT_ACTTABLE( CWeapon357 );
#endif
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
@ -91,7 +88,7 @@ CWeapon357::CWeapon357( void )
void CWeapon357::PrimaryAttack( void )
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() );
if ( !pPlayer )
{
@ -117,7 +114,7 @@ void CWeapon357::PrimaryAttack( void )
pPlayer->DoMuzzleFlash();
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
pPlayer->SetAnimation( PLAYER_ATTACK1 );
pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
m_flNextPrimaryAttack = gpGlobals->curtime + 0.75;
m_flNextSecondaryAttack = gpGlobals->curtime + 0.75;
@ -125,7 +122,7 @@ void CWeapon357::PrimaryAttack( void )
m_iClip1--;
Vector vecSrc = pPlayer->Weapon_ShootPosition();
Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
FireBulletsInfo_t info( 1, vecSrc, vecAiming, vec3_origin, MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
info.m_pAttacker = pPlayer;

View file

@ -46,24 +46,25 @@ LINK_ENTITY_TO_CLASS( weapon_ar2, CWeaponAR2 );
PRECACHE_WEAPON_REGISTER(weapon_ar2);
#ifndef CLIENT_DLL
acttable_t CWeaponAR2::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_AR2, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_AR2, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_AR2, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_AR2, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_AR2, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_AR2, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_AR2, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_AR2, false },
{ ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_AR2, false },
{ ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_AR2, false },
{ ACT_MP_RUN, ACT_HL2MP_RUN_AR2, false },
{ ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_AR2, false },
{ ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_AR2, false },
{ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_AR2, false },
{ ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_AR2, false },
{ ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_AR2, false },
{ ACT_MP_JUMP, ACT_HL2MP_JUMP_AR2, false },
};
IMPLEMENT_ACTTABLE(CWeaponAR2);
#endif
CWeaponAR2::CWeaponAR2( )
{
m_fMinRange1 = 65;

View file

@ -75,9 +75,7 @@ protected:
bool m_bShotDelayed;
int m_nVentPose;
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
};

View file

@ -433,9 +433,7 @@ private:
void SetChargerState( ChargerState_t state );
void DoLoadEffect( void );
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
private:
@ -475,23 +473,25 @@ LINK_ENTITY_TO_CLASS( weapon_crossbow, CWeaponCrossbow );
PRECACHE_WEAPON_REGISTER( weapon_crossbow );
#ifndef CLIENT_DLL
acttable_t CWeaponCrossbow::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_CROSSBOW, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_CROSSBOW, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_CROSSBOW, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_CROSSBOW, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_CROSSBOW, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_CROSSBOW, false },
{ ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_CROSSBOW, false },
{ ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_CROSSBOW, false },
{ ACT_MP_RUN, ACT_HL2MP_RUN_CROSSBOW, false },
{ ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_CROSSBOW, false },
{ ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false },
{ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false },
{ ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false },
{ ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false },
{ ACT_MP_JUMP, ACT_HL2MP_JUMP_CROSSBOW, false },
};
IMPLEMENT_ACTTABLE(CWeaponCrossbow);
#endif
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
@ -792,29 +792,34 @@ void CWeaponCrossbow::DoLoadEffect( void )
if ( pOwner == NULL )
return;
CBaseViewModel *pViewModel = pOwner->GetViewModel();
if ( pViewModel == NULL )
return;
//Tony; change this up a bit; on the server, dispatch an effect but don't send it to the client who fires
//on the client, create an effect either in the view model, or on the world model if first person.
CEffectData data;
#ifdef CLIENT_DLL
data.m_hEntity = pViewModel->GetRefEHandle();
#else
data.m_nEntIndex = pViewModel->entindex();
#endif
data.m_nAttachmentIndex = 1;
data.m_vOrigin = pOwner->GetAbsOrigin();
DispatchEffect( "CrossbowLoad", data );
CPASFilter filter( data.m_vOrigin );
#ifdef GAME_DLL
filter.RemoveRecipient( pOwner );
data.m_nEntIndex = entindex();
#else
CBaseViewModel *pViewModel = pOwner->GetViewModel();
if ( ShouldDrawUsingViewModel() && pViewModel != NULL )
data.m_hEntity = pViewModel->GetRefEHandle();
else
data.m_hEntity = GetRefEHandle();
#endif
DispatchEffect( "CrossbowLoad", data, filter );
#ifndef CLIENT_DLL
CSprite *pBlast = CSprite::SpriteCreate( CROSSBOW_GLOW_SPRITE2, GetAbsOrigin(), false );
if ( pBlast )
{
pBlast->SetAttachment( pOwner->GetViewModel(), 1 );
pBlast->SetAttachment( this, 1 );
pBlast->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNone );
pBlast->SetBrightness( 128 );
pBlast->SetScale( 0.2f );

View file

@ -45,24 +45,25 @@ END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( weapon_crowbar, CWeaponCrowbar );
PRECACHE_WEAPON_REGISTER( weapon_crowbar );
#ifndef CLIENT_DLL
acttable_t CWeaponCrowbar::m_acttable[] =
{
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true },
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_MELEE, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_MELEE, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false },
{ ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_MELEE, false },
{ ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_MELEE, false },
{ ACT_MP_RUN, ACT_HL2MP_RUN_MELEE, false },
{ ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_MELEE, false },
{ ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false },
{ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false },
{ ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_MELEE, false },
{ ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_MELEE, false },
{ ACT_MP_JUMP, ACT_HL2MP_JUMP_MELEE, false },
};
IMPLEMENT_ACTTABLE(CWeaponCrowbar);
#endif
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------

View file

@ -35,10 +35,7 @@ public:
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
CWeaponCrowbar();

View file

@ -82,29 +82,27 @@ private:
CNetworkVar( bool, m_fDrawbackFinished );
CWeaponFrag( const CWeaponFrag & );
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
};
#ifndef CLIENT_DLL
acttable_t CWeaponFrag::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_GRENADE, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_GRENADE, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_GRENADE, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_GRENADE, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_GRENADE, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_GRENADE, false },
{ ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_GRENADE, false },
{ ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_GRENADE, false },
{ ACT_MP_RUN, ACT_HL2MP_RUN_GRENADE, false },
{ ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_GRENADE, false },
{ ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false },
{ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false },
{ ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_GRENADE, false },
{ ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_GRENADE, false },
{ ACT_MP_JUMP, ACT_HL2MP_JUMP_GRENADE, false },
};
IMPLEMENT_ACTTABLE(CWeaponFrag);
#endif
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponFrag, DT_WeaponFrag )
BEGIN_NETWORK_TABLE( CWeaponFrag, DT_WeaponFrag )
@ -341,7 +339,7 @@ void CWeaponFrag::ItemPostFrame( void )
{
if( m_fDrawbackFinished )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
CHL2MP_Player *pOwner = ToHL2MPPlayer( GetOwner() );
if (pOwner)
{
@ -351,6 +349,7 @@ void CWeaponFrag::ItemPostFrame( void )
if( !(pOwner->m_nButtons & IN_ATTACK) )
{
SendWeaponAnim( ACT_VM_THROW );
pOwner->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
m_fDrawbackFinished = false;
}
break;
@ -369,6 +368,8 @@ void CWeaponFrag::ItemPostFrame( void )
//Send the weapon animation
SendWeaponAnim( ACT_VM_HAULBACK );
}
//Tony; the grenade really should have a secondary anim. but it doesn't on the player.
pOwner->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
m_fDrawbackFinished = false;
}

View file

@ -105,7 +105,17 @@ bool CWeaponHL2MPBase::IsPredicted() const
{
return true;
}
//Tony; override for animation purposes.
bool CWeaponHL2MPBase::Reload( void )
{
bool fRet = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD );
if ( fRet )
{
// WeaponSound( RELOAD );
ToHL2MPPlayer(GetOwner())->DoAnimationEvent( PLAYERANIMEVENT_RELOAD );
}
return fRet;
}
void CWeaponHL2MPBase::WeaponSound( WeaponSound_t sound_type, float soundtime /* = 0.0f */ )
{
#ifdef CLIENT_DLL

View file

@ -40,9 +40,6 @@ public:
#ifdef GAME_DLL
DECLARE_DATADESC();
void SendReloadSoundEvent( void );
void Materialize( void );
virtual int ObjectCaps( void );
#endif
@ -60,6 +57,7 @@ public:
virtual void FireBullets( const FireBulletsInfo_t &info );
virtual void FallInit( void );
virtual bool Reload();
public:
#if defined( CLIENT_DLL )

View file

@ -114,7 +114,8 @@ void CHL2MPMachineGun::PrimaryAttack( void )
}
SendWeaponAnim( GetPrimaryAttackActivity() );
pPlayer->SetAnimation( PLAYER_ATTACK1 );
ToHL2MPPlayer(pPlayer)->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
}
//-----------------------------------------------------------------------------

View file

@ -355,7 +355,7 @@ void CBaseHL2MPBludgeonWeapon::Swing( int bIsSecondary )
// Send the anim
SendWeaponAnim( nHitActivity );
pOwner->SetAnimation( PLAYER_ATTACK1 );
ToHL2MPPlayer(pOwner)->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
//Setup our next attack times
m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();

View file

@ -1224,7 +1224,9 @@ protected:
bool m_bOldOpen; // Used for parity checks
void NotifyShouldTransmit( ShouldTransmitState_t state );
private:
virtual void ThirdPersonSwitch( bool bThirdPerson );
protected:
#endif // CLIENT_DLL
int m_nChangeState; // For delayed state change of elements
@ -1249,10 +1251,7 @@ protected:
private:
CWeaponPhysCannon( const CWeaponPhysCannon & );
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
};
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponPhysCannon, DT_WeaponPhysCannon )
@ -1289,24 +1288,25 @@ END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( weapon_physcannon, CWeaponPhysCannon );
PRECACHE_WEAPON_REGISTER( weapon_physcannon );
#ifndef CLIENT_DLL
acttable_t CWeaponPhysCannon::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PHYSGUN, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_PHYSGUN, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PHYSGUN, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PHYSGUN, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PHYSGUN, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PHYSGUN, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PHYSGUN, false },
{ ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_PHYSGUN, false },
{ ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_PHYSGUN, false },
{ ACT_MP_RUN, ACT_HL2MP_RUN_PHYSGUN, false },
{ ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_PHYSGUN, false },
{ ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PHYSGUN, false },
{ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PHYSGUN, false },
{ ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_PHYSGUN, false },
{ ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_PHYSGUN, false },
{ ACT_MP_JUMP, ACT_HL2MP_JUMP_PHYSGUN, false },
};
IMPLEMENT_ACTTABLE(CWeaponPhysCannon);
#endif
enum
{
ELEMENT_STATE_NONE = -1,
@ -2601,56 +2601,26 @@ void CWeaponPhysCannon::DoEffectIdle( void )
StartEffects();
//if ( ShouldDrawUsingViewModel() )
// Turn on the glow sprites
for ( int i = PHYSCANNON_GLOW1; i < (PHYSCANNON_GLOW1+NUM_GLOW_SPRITES); i++ )
{
// Turn on the glow sprites
for ( int i = PHYSCANNON_GLOW1; i < (PHYSCANNON_GLOW1+NUM_GLOW_SPRITES); i++ )
{
m_Parameters[i].GetScale().SetAbsolute( random->RandomFloat( 0.075f, 0.05f ) * SPRITE_SCALE );
m_Parameters[i].GetAlpha().SetAbsolute( random->RandomInt( 24, 32 ) );
}
// Turn on the glow sprites
for ( int i = PHYSCANNON_ENDCAP1; i < (PHYSCANNON_ENDCAP1+NUM_ENDCAP_SPRITES); i++ )
{
m_Parameters[i].GetScale().SetAbsolute( random->RandomFloat( 3, 5 ) );
m_Parameters[i].GetAlpha().SetAbsolute( random->RandomInt( 200, 255 ) );
}
if ( m_EffectState != EFFECT_HOLDING )
{
// Turn beams off
m_Beams[0].SetVisible( false );
m_Beams[1].SetVisible( false );
m_Beams[2].SetVisible( false );
}
m_Parameters[i].GetScale().SetAbsolute( random->RandomFloat( 0.075f, 0.05f ) * SPRITE_SCALE );
m_Parameters[i].GetAlpha().SetAbsolute( random->RandomInt( 24, 32 ) );
}
/*
else
// Turn on the glow sprites
for ( int i = PHYSCANNON_ENDCAP1; i < (PHYSCANNON_ENDCAP1+NUM_ENDCAP_SPRITES); i++ )
{
// Turn on the glow sprites
for ( int i = PHYSCANNON_GLOW1; i < (PHYSCANNON_GLOW1+NUM_GLOW_SPRITES); i++ )
{
m_Parameters[i].GetScale().SetAbsolute( random->RandomFloat( 0.075f, 0.05f ) * SPRITE_SCALE );
m_Parameters[i].GetAlpha().SetAbsolute( random->RandomInt( 24, 32 ) );
}
// Turn on the glow sprites
for ( i = PHYSCANNON_ENDCAP1; i < (PHYSCANNON_ENDCAP1+NUM_ENDCAP_SPRITES); i++ )
{
m_Parameters[i].GetScale().SetAbsolute( random->RandomFloat( 3, 5 ) );
m_Parameters[i].GetAlpha().SetAbsolute( random->RandomInt( 200, 255 ) );
}
if ( m_EffectState != EFFECT_HOLDING )
{
// Turn beams off
m_Beams[0].SetVisible( false );
m_Beams[1].SetVisible( false );
m_Beams[2].SetVisible( false );
}
m_Parameters[i].GetScale().SetAbsolute( random->RandomFloat( 3, 5 ) );
m_Parameters[i].GetAlpha().SetAbsolute( random->RandomInt( 200, 255 ) );
}
if ( m_EffectState != EFFECT_HOLDING )
{
// Turn beams off
m_Beams[0].SetVisible( false );
m_Beams[1].SetVisible( false );
m_Beams[2].SetVisible( false );
}
*/
#endif
}
@ -2957,6 +2927,15 @@ void CWeaponPhysCannon::StopEffects( bool stopSound )
#endif // !CLIENT_DLL
}
#ifdef CLIENT_DLL
void CWeaponPhysCannon::ThirdPersonSwitch( bool bThirdPerson )
{
//Tony; if we switch to first or third person or whatever, destroy and recreate the effects.
//Note: the sound only ever gets shut off on the server, so it's okay - as this is entirely client side.
DestroyEffects();
StartEffects();
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------

View file

@ -15,6 +15,7 @@
#endif
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#include "weapon_hl2mpbase_machinegun.h"
#define PISTOL_FASTEST_REFIRE_TIME 0.1f
#define PISTOL_FASTEST_DRY_REFIRE_TIME 0.2f
@ -30,10 +31,10 @@
// CWeaponPistol
//-----------------------------------------------------------------------------
class CWeaponPistol : public CBaseHL2MPCombatWeapon
class CWeaponPistol : public CHL2MPMachineGun
{
public:
DECLARE_CLASS( CWeaponPistol, CBaseHL2MPCombatWeapon );
DECLARE_CLASS( CWeaponPistol, CHL2MPMachineGun );
CWeaponPistol(void);
@ -84,10 +85,7 @@ public:
{
return 0.5f;
}
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
private:
CNetworkVar( float, m_flSoonestPrimaryAttack );
@ -127,24 +125,25 @@ END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( weapon_pistol, CWeaponPistol );
PRECACHE_WEAPON_REGISTER( weapon_pistol );
#ifndef CLIENT_DLL
acttable_t CWeaponPistol::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_PISTOL, false },
{ ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_PISTOL, false },
{ ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_PISTOL, false },
{ ACT_MP_RUN, ACT_HL2MP_RUN_PISTOL, false },
{ ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_PISTOL, false },
{ ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false },
{ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false },
{ ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false },
{ ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false },
{ ACT_MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false },
};
IMPLEMENT_ACTTABLE( CWeaponPistol );
#endif
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
@ -313,6 +312,7 @@ bool CWeaponPistol::Reload( void )
if ( fRet )
{
WeaponSound( RELOAD );
ToHL2MPPlayer(GetOwner())->DoAnimationEvent( PLAYERANIMEVENT_RELOAD );
m_flAccuracyPenalty = 0.0f;
}
return fRet;

View file

@ -453,7 +453,7 @@ void CMissile::IgniteThink( void )
SetMoveType( MOVETYPE_FLY );
SetModel("models/weapons/w_missile.mdl");
UTIL_SetSize( this, vec3_origin, vec3_origin );
RemoveSolidFlags( FSOLID_NOT_SOLID );
RemoveSolidFlags( FSOLID_NOT_SOLID );
//TODO: Play opening sound
@ -983,7 +983,7 @@ void CAPCMissile::ExplodeDelay( float flDelay )
void CAPCMissile::BeginSeekThink( void )
{
RemoveSolidFlags( FSOLID_NOT_SOLID );
RemoveSolidFlags( FSOLID_NOT_SOLID );
SetThink( &CAPCMissile::SeekThink );
SetNextThink( gpGlobals->curtime );
}
@ -1248,7 +1248,7 @@ void CAPCMissile::ComputeActualDotPosition( CLaserDot *pLaserDot, Vector *pActua
#define RPG_BEAM_SPRITE "effects/laser1.vmt"
#define RPG_BEAM_SPRITE_NOZ "effects/laser1_noz.vmt"
#define RPG_LASER_SPRITE "sprites/redglow1"
#define RPG_LASER_SPRITE "sprites/redglow1.vmt"
//=============================================================================
// RPG
@ -1305,23 +1305,25 @@ END_PREDICTION_DATA()
#endif
#ifndef CLIENT_DLL
acttable_t CWeaponRPG::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_RPG, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_RPG, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_RPG, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_RPG, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_RPG, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_RPG, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_RPG, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_RPG, false },
{ ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_RPG, false },
{ ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_RPG, false },
{ ACT_MP_RUN, ACT_HL2MP_RUN_RPG, false },
{ ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_RPG, false },
{ ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_RPG, false },
{ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_RPG, false },
{ ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_RPG, false },
{ ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_RPG, false },
{ ACT_MP_JUMP, ACT_HL2MP_JUMP_RPG, false },
};
IMPLEMENT_ACTTABLE(CWeaponRPG);
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
@ -1361,7 +1363,6 @@ void CWeaponRPG::Precache( void )
PrecacheScriptSound( "Missile.Accelerate" );
// Laser dot...
PrecacheModel( "sprites/redglow1.vmt" );
PrecacheModel( RPG_LASER_SPRITE );
PrecacheModel( RPG_BEAM_SPRITE );
PrecacheModel( RPG_BEAM_SPRITE_NOZ );
@ -1425,7 +1426,7 @@ bool CWeaponRPG::WeaponShouldBeLowered( void )
void CWeaponRPG::PrimaryAttack( void )
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() );
if (!pPlayer)
return;
@ -1480,7 +1481,8 @@ void CWeaponRPG::PrimaryAttack( void )
WeaponSound( SINGLE );
// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );
pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
}
//-----------------------------------------------------------------------------
@ -1883,6 +1885,19 @@ void CWeaponRPG::GetWeaponAttachment( int attachmentId, Vector &outVector, Vecto
}
}
//Tony; added so when the rpg switches to third person, the beam etc is re-created.
void CWeaponRPG::ThirdPersonSwitch( bool bThirdPerson )
{
if ( m_pBeam != NULL )
{
//Tell it to die right away and let the beam code free it.
m_pBeam->brightness = 0.0f;
m_pBeam->flags &= ~FBEAM_FOREVER;
m_pBeam->die = gpGlobals->curtime - 0.1;
m_pBeam = NULL;
}
}
//-----------------------------------------------------------------------------
// Purpose: Setup our laser beam
//-----------------------------------------------------------------------------
@ -2231,7 +2246,7 @@ int CLaserDot::DrawModel( int flags )
if ( pOwner != NULL && pOwner->IsDormant() == false )
{
// Always draw the dot in front of our faces when in first-person
if ( pOwner->IsLocalPlayer() )
if ( pOwner->IsLocalPlayer() && C_BasePlayer::LocalPlayerInFirstPersonView() ) //Tony; !!!
{
// Take our view position and orientation
vecAttachment = CurrentViewOrigin();
@ -2241,8 +2256,7 @@ int CLaserDot::DrawModel( int flags )
{
// Take the eye position and direction
vecAttachment = pOwner->EyePosition();
QAngle angles = pOwner->GetAnimEyeAngles();
QAngle angles = pOwner->EyeAngles();
AngleVectors( angles, &vecDir );
}

View file

@ -238,13 +238,14 @@ public:
CMaterialReference m_hBeamMaterial; // Used for the laser beam
Beam_t *m_pBeam; // Laser beam temp entity
//Tony; third person check thing, to destroy/reinitialize the beam ( swapping first -> third or back, etc )
virtual void ThirdPersonSwitch( bool bThirdPerson );
#endif //CLIENT_DLL
CBaseEntity *GetMissile( void ) { return m_hMissile; }
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
protected:

View file

@ -61,9 +61,7 @@ public:
void DryFire( void );
virtual float GetFireRate( void ) { return 0.7; };
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
CWeaponShotgun(void);
@ -99,23 +97,25 @@ END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( weapon_shotgun, CWeaponShotgun );
PRECACHE_WEAPON_REGISTER(weapon_shotgun);
#ifndef CLIENT_DLL
acttable_t CWeaponShotgun::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SHOTGUN, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_SHOTGUN, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SHOTGUN, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SHOTGUN, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SHOTGUN, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SHOTGUN, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SHOTGUN, false },
{ ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_SHOTGUN, false },
{ ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_SHOTGUN, false },
{ ACT_MP_RUN, ACT_HL2MP_RUN_SHOTGUN, false },
{ ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_SHOTGUN, false },
{ ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN, false },
{ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN, false },
{ ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_SHOTGUN, false },
{ ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_SHOTGUN, false },
{ ACT_MP_JUMP, ACT_HL2MP_JUMP_SHOTGUN, false },
};
IMPLEMENT_ACTTABLE(CWeaponShotgun);
#endif
//-----------------------------------------------------------------------------
// Purpose: Override so only reload one shell at a time
@ -127,7 +127,7 @@ bool CWeaponShotgun::StartReload( void )
if ( m_bNeedPump )
return false;
CBaseCombatCharacter *pOwner = GetOwner();
CHL2MP_Player *pOwner = ToHL2MPPlayer( GetOwner() );
if ( pOwner == NULL )
return false;
@ -146,6 +146,9 @@ bool CWeaponShotgun::StartReload( void )
SendWeaponAnim( ACT_SHOTGUN_RELOAD_START );
//Tony; BUG BUG BUG!!! shotgun does one shell at a time!!! -- player model only has a single reload!!! so I'm just going to dispatch the singular for now.
pOwner->DoAnimationEvent( PLAYERANIMEVENT_RELOAD );
// Make shotgun shell visible
SetBodygroup(1,0);
@ -293,7 +296,7 @@ void CWeaponShotgun::DryFire( void )
void CWeaponShotgun::PrimaryAttack( void )
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() );
if (!pPlayer)
{
@ -312,7 +315,8 @@ void CWeaponShotgun::PrimaryAttack( void )
m_iClip1 -= 1;
// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );
pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
Vector vecSrc = pPlayer->Weapon_ShootPosition( );
Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
@ -344,7 +348,7 @@ void CWeaponShotgun::PrimaryAttack( void )
void CWeaponShotgun::SecondaryAttack( void )
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() );
if (!pPlayer)
{
@ -364,10 +368,11 @@ void CWeaponShotgun::SecondaryAttack( void )
m_iClip1 -= 2; // Shotgun uses same clip for primary and secondary attacks
// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );
pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); //Tony; shotgun doesn't have a secondary anim, use primary.
Vector vecSrc = pPlayer->Weapon_ShootPosition();
Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
Vector vecSrc = pPlayer->Weapon_ShootPosition();
Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
FireBulletsInfo_t info( 12, vecSrc, vecAiming, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
info.m_pAttacker = pPlayer;

View file

@ -14,7 +14,7 @@
#include "c_hl2mp_player.h"
#else
#include "hl2mp_player.h"
#include "grenade_tripmine.h"
#include "hl2mp/grenade_tripmine.h" // Load the hl2mp version!
#include "grenade_satchel.h"
#include "entitylist.h"
#include "eventqueue.h"
@ -26,6 +26,7 @@
#include "tier0/memdbgon.h"
#define SLAM_PRIMARY_VOLUME 450
#define SLAM_REFIRE_DELAY 0.05f
IMPLEMENT_NETWORKCLASS_ALIASED( Weapon_SLAM, DT_Weapon_SLAM )
@ -91,21 +92,26 @@ BEGIN_DATADESC( CWeapon_SLAM )
DEFINE_FUNCTION( SlamTouch ),
END_DATADESC()
#endif
acttable_t CWeapon_SLAM::m_acttable[] =
{
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true },
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SLAM, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_SLAM, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SLAM, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SLAM, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SLAM, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SLAM, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SLAM, false },
{ ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_SLAM, false },
{ ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_SLAM, false },
{ ACT_MP_RUN, ACT_HL2MP_RUN_SLAM, false },
{ ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_SLAM, false },
{ ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_SLAM, false },
{ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_SLAM, false },
{ ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_SLAM, false },
{ ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_SLAM, false },
{ ACT_MP_JUMP, ACT_HL2MP_JUMP_SLAM, false },
};
IMPLEMENT_ACTTABLE(CWeapon_SLAM);
#endif
void CWeapon_SLAM::Spawn( )
@ -327,8 +333,8 @@ void CWeapon_SLAM::StartSatchelDetonate()
}
SatchelDetonate();
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration();
// needs a higher delay on all of these, a minimum time really - to elimiate refires.
m_flNextPrimaryAttack = m_flNextSecondaryAttack = SLAM_REFIRE_DELAY + gpGlobals->curtime + SequenceDuration();
}
@ -376,6 +382,8 @@ void CWeapon_SLAM::TripmineAttach( void )
CTripmineGrenade *pMine = (CTripmineGrenade *)pEnt;
pMine->m_hOwner = GetOwner();
// Attempt to attach to entity, or just sit still in place.
pMine->AttachToEntity( pEntity );
#endif
@ -392,7 +400,7 @@ void CWeapon_SLAM::TripmineAttach( void )
void CWeapon_SLAM::StartTripmineAttach( void )
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() );
if (!pPlayer)
{
return;
@ -419,7 +427,7 @@ void CWeapon_SLAM::StartTripmineAttach( void )
if (pEntity && !(pEntity->GetFlags() & FL_CONVEYOR))
{
// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );
pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
// -----------------------------------------
// Play attach animation
@ -444,8 +452,8 @@ void CWeapon_SLAM::StartTripmineAttach( void )
}
}
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration();
// needs a higher delay on all of these, a minimum time really - to elimiate refires.
m_flNextPrimaryAttack = m_flNextSecondaryAttack = SLAM_REFIRE_DELAY + gpGlobals->curtime + SequenceDuration();
// SetWeaponIdleTime( gpGlobals->curtime + SequenceDuration() );
}
@ -456,11 +464,12 @@ void CWeapon_SLAM::StartTripmineAttach( void )
//-----------------------------------------------------------------------------
void CWeapon_SLAM::SatchelThrow( void )
{
// Only the player fires this way so we can cast
CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() );
#ifndef CLIENT_DLL
m_bThrowSatchel = false;
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
Vector vecSrc = pPlayer->WorldSpaceCenter();
Vector vecFacing = pPlayer->BodyDirection3D( );
@ -492,10 +501,11 @@ void CWeapon_SLAM::SatchelThrow( void )
}
pPlayer->RemoveAmmo( 1, m_iSecondaryAmmoType );
pPlayer->SetAnimation( PLAYER_ATTACK1 );
#endif
//Tony; is there a different anim in the player? must check..
pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
// Play throw sound
EmitSound( "Weapon_SLAM.SatchelThrow" );
}
@ -527,8 +537,7 @@ void CWeapon_SLAM::StartSatchelThrow( void )
m_bNeedReload = true;
m_bThrowSatchel = true;
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration();
m_flNextPrimaryAttack = m_flNextSecondaryAttack = SLAM_REFIRE_DELAY + gpGlobals->curtime + SequenceDuration();
}
//-----------------------------------------------------------------------------
@ -587,7 +596,7 @@ void CWeapon_SLAM::SatchelAttach( void )
void CWeapon_SLAM::StartSatchelAttach( void )
{
#ifndef CLIENT_DLL
CBaseCombatCharacter *pOwner = GetOwner();
CHL2MP_Player *pOwner = ToHL2MPPlayer( GetOwner() );
if (!pOwner)
{
return;
@ -605,11 +614,8 @@ void CWeapon_SLAM::StartSatchelAttach( void )
CBaseEntity *pEntity = tr.m_pEnt;
if (pEntity && !(pEntity->GetFlags() & FL_CONVEYOR))
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( pOwner );
// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );
pOwner->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
// -----------------------------------------
// Play attach animation
@ -631,7 +637,8 @@ void CWeapon_SLAM::StartSatchelAttach( void )
m_bNeedReload = true;
m_bAttachSatchel = true;
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
m_flNextPrimaryAttack = m_flNextSecondaryAttack = SLAM_REFIRE_DELAY + gpGlobals->curtime + SequenceDuration();
}
}
#endif
@ -813,7 +820,7 @@ void CWeapon_SLAM::Weapon_Switch( void )
void CWeapon_SLAM::WeaponIdle( void )
{
// Ready to switch animations?
if ( HasWeaponIdleTimeElapsed() )
if ( HasWeaponIdleTimeElapsed() )
{
// Don't allow throw to attach switch unless in idle
if (m_bClearReload)

View file

@ -78,8 +78,8 @@ public:
CWeapon_SLAM();
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#ifndef CLIENT_DLL
DECLARE_DATADESC();
#endif

View file

@ -61,9 +61,7 @@ public:
const WeaponProficiencyInfo_t *GetProficiencyValues();
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
protected:
@ -85,21 +83,24 @@ END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( weapon_smg1, CWeaponSMG1 );
PRECACHE_WEAPON_REGISTER(weapon_smg1);
#ifndef CLIENT_DLL
acttable_t CWeaponSMG1::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SMG1, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_SMG1, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SMG1, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SMG1, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG1, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SMG1, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SMG1, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, false },
{ ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_SMG1, false },
{ ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_SMG1, false },
{ ACT_MP_RUN, ACT_HL2MP_RUN_SMG1, false },
{ ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_SMG1, false },
{ ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG1, false },
{ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG1, false },
{ ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_SMG1, false },
{ ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_SMG1, false },
{ ACT_MP_JUMP, ACT_HL2MP_JUMP_SMG1, false },
};
IMPLEMENT_ACTTABLE(CWeaponSMG1);
#endif
//=========================================================
CWeaponSMG1::CWeaponSMG1( )
@ -164,6 +165,7 @@ bool CWeaponSMG1::Reload( void )
m_flNextSecondaryAttack = GetOwner()->m_flNextAttack = fCacheTime;
WeaponSound( RELOAD );
ToHL2MPPlayer(GetOwner())->DoAnimationEvent( PLAYERANIMEVENT_RELOAD );
}
return fRet;
@ -193,7 +195,7 @@ void CWeaponSMG1::AddViewKick( void )
void CWeaponSMG1::SecondaryAttack( void )
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() );
if ( pPlayer == NULL )
return;
@ -234,7 +236,7 @@ void CWeaponSMG1::SecondaryAttack( void )
SendWeaponAnim( ACT_VM_SECONDARYATTACK );
// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );
pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );
// Decrease ammo
pPlayer->RemoveAmmo( 1, m_iSecondaryAmmoType );

View file

@ -57,10 +57,7 @@ public:
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
#ifdef CLIENT_DLL
virtual int DrawModel( int flags );
@ -68,7 +65,7 @@ public:
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual RenderGroup_t GetRenderGroup( void );
virtual void ViewModelDrawn( C_BaseViewModel *pBaseViewModel );
virtual bool IsTransparent( void );
#endif
virtual void Precache();
@ -123,6 +120,9 @@ private:
float m_flFadeTime;
//Tony; third person check thing, this has to be done for the local player if third person switches, so we can re-calc attachment points.
virtual void ThirdPersonSwitch( bool bThirdPerson );
#endif
CNetworkVar( bool, m_bActive );
@ -149,24 +149,25 @@ LINK_ENTITY_TO_CLASS( weapon_stunstick, CWeaponStunStick );
PRECACHE_WEAPON_REGISTER( weapon_stunstick );
#ifndef CLIENT_DLL
acttable_t CWeaponStunStick::m_acttable[] =
{
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true },
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_MELEE, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_MELEE, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false },
{ ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_MELEE, false },
{ ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_MELEE, false },
{ ACT_MP_RUN, ACT_HL2MP_RUN_MELEE, false },
{ ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_MELEE, false },
{ ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false },
{ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false },
{ ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_MELEE, false },
{ ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_MELEE, false },
{ ACT_MP_JUMP, ACT_HL2MP_JUMP_MELEE, false },
};
IMPLEMENT_ACTTABLE(CWeaponStunStick);
#endif
//-----------------------------------------------------------------------------
// Constructor
@ -447,6 +448,10 @@ void CWeaponStunStick::SetStunState( bool state )
bool CWeaponStunStick::Deploy( void )
{
SetStunState( true );
#ifdef CLIENT_DLL
//Tony; we need to just do this
SetupAttachmentPoints();
#endif
return BaseClass::Deploy();
}
@ -842,6 +847,10 @@ void C_WeaponStunStick::DrawFirstPersonEffects( void )
}
}
void C_WeaponStunStick::ThirdPersonSwitch( bool bThirdPerson )
{
SetupAttachmentPoints();
}
//-----------------------------------------------------------------------------
// Purpose: Draw our special effects
//-----------------------------------------------------------------------------
@ -872,6 +881,13 @@ void C_WeaponStunStick::ViewModelDrawn( C_BaseViewModel *pBaseViewModel )
BaseClass::ViewModelDrawn( pBaseViewModel );
}
//-----------------------------------------------------------------------------
// Purpose: We are always considered transparent
//-----------------------------------------------------------------------------
bool C_WeaponStunStick::IsTransparent( void )
{
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Draw a cheap glow quad at our impact point (with sparks)
//-----------------------------------------------------------------------------

View file

@ -372,7 +372,8 @@ protected:
bool PassesDamageFilterImpl(const CTakeDamageInfo &info)
{
return info.GetDamageType() == m_iDamageType;
//Tony; these are bitflags. check them as so.
return ((info.GetDamageType() & m_iDamageType) == m_iDamageType);
}
int m_iDamageType;