Our very own player class! (CFF_SH_Player, CFF_CL_Player, CFF_SV_Player)

- Note: FFPlayer still derives from CBaseHLPlayer, which has HL-style sprinting code and whatnot, will probably want to end up removing that inheritance
 - All references to the old HL2MP player have been switched to our FF player (temporarily if we end up replacing those files)
This commit is contained in:
squeek 2013-10-29 02:56:08 +00:00
parent 1d6736cb3c
commit 9818913608
34 changed files with 3774 additions and 91 deletions

View file

@ -30,6 +30,16 @@ $Project "Client (FF)"
// for FF Shared, see game\shared\ff\ff_shared.vpc
$Folder "FF"
{
$Folder "Game"
{
}
$Folder "Player"
{
$File "ff\ff_cl_player.cpp"
$File "ff\ff_cl_player.h"
}
$Folder "Libraries"
{
$Lib lua
@ -39,11 +49,20 @@ $Project "Client (FF)"
// IMPORTANT: remove conflicting hl2dm SDK stuff as we implement our own!!
// done for us in HL2DM sdk vpc: -$File "$SRCDIR\game\shared\weapon_parse_default.cpp"
$Folder "HL2 DLL"
{
-$File "$SRCDIR\game\shared\hl2\hl_gamemovement.cpp"
-$File "$SRCDIR\game\shared\hl2\hl_gamemovement.h"
}
$Folder "HL2MP"
{
// Player
-$File "hl2mp\c_hl2mp_player.cpp"
-$File "hl2mp\c_hl2mp_player.h"
-$File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.cpp"
-$File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.h"
}
}
}

View file

@ -0,0 +1,985 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Player for FF.
//
//=============================================================================//
#include "cbase.h"
#include "vcollide_parse.h"
#include "ff_cl_player.h"
#include "view.h"
#include "takedamageinfo.h"
#include "ff_sh_gamerules.h"
#include "in_buttons.h"
#include "iviewrender_beams.h" // flashlight beam
#include "r_efx.h"
#include "dlight.h"
// Don't alias here
#if defined( CFF_SH_Player )
#undef CFF_SH_Player
#endif
LINK_ENTITY_TO_CLASS( player, CFF_CL_Player );
IMPLEMENT_CLIENTCLASS_DT(CFF_CL_Player, DT_FF_Player, CFF_SV_Player)
RecvPropFloat( RECVINFO( m_angEyeAngles[0] ) ),
RecvPropFloat( RECVINFO( m_angEyeAngles[1] ) ),
RecvPropEHandle( RECVINFO( m_hRagdoll ) ),
RecvPropInt( RECVINFO( m_iSpawnInterpCounter ) ),
RecvPropInt( RECVINFO( m_iPlayerSoundType) ),
RecvPropBool( RECVINFO( m_fIsWalking ) ),
END_RECV_TABLE()
BEGIN_PREDICTION_DATA( CFF_CL_Player )
DEFINE_PRED_FIELD( m_fIsWalking, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
END_PREDICTION_DATA()
#define HL2_WALK_SPEED 150
#define HL2_NORM_SPEED 190
#define HL2_SPRINT_SPEED 320
static ConVar cl_playermodel( "cl_playermodel", "none", FCVAR_USERINFO | FCVAR_ARCHIVE | FCVAR_SERVER_CAN_EXECUTE, "Default Player Model");
static ConVar cl_defaultweapon( "cl_defaultweapon", "weapon_physcannon", FCVAR_USERINFO | FCVAR_ARCHIVE, "Default Spawn Weapon");
void SpawnBlood (Vector vecSpot, const Vector &vecDir, int bloodColor, float flDamage);
CFF_CL_Player::CFF_CL_Player() : m_PlayerAnimState( this ), m_iv_angEyeAngles( "CFF_CL_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_blinkTimer.Invalidate();
m_pFlashlightBeam = NULL;
}
CFF_CL_Player::~CFF_CL_Player( void )
{
ReleaseFlashlight();
}
int CFF_CL_Player::GetIDTarget() const
{
return m_iIDEntIndex;
}
//-----------------------------------------------------------------------------
// Purpose: Update this client's target entity
//-----------------------------------------------------------------------------
void CFF_CL_Player::UpdateIDTarget()
{
if ( !IsLocalPlayer() )
return;
// Clear old target and find a new one
m_iIDEntIndex = 0;
// don't show IDs in chase spec mode
if ( GetObserverMode() == OBS_MODE_CHASE ||
GetObserverMode() == OBS_MODE_DEATHCAM )
return;
trace_t tr;
Vector vecStart, vecEnd;
VectorMA( MainViewOrigin(), 1500, MainViewForward(), vecEnd );
VectorMA( MainViewOrigin(), 10, MainViewForward(), vecStart );
UTIL_TraceLine( vecStart, vecEnd, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
if ( !tr.startsolid && tr.DidHitNonWorldEntity() )
{
C_BaseEntity *pEntity = tr.m_pEnt;
if ( pEntity && (pEntity != this) )
{
m_iIDEntIndex = pEntity->entindex();
}
}
}
void CFF_CL_Player::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator )
{
Vector vecOrigin = ptr->endpos - vecDir * 4;
float flDistance = 0.0f;
if ( info.GetAttacker() )
{
flDistance = (ptr->endpos - info.GetAttacker()->GetAbsOrigin()).Length();
}
if ( m_takedamage )
{
AddMultiDamage( info, this );
int blood = BloodColor();
CBaseEntity *pAttacker = info.GetAttacker();
if ( pAttacker )
{
if ( FFRules()->IsTeamplay() && pAttacker->InSameTeam( this ) == true )
return;
}
if ( blood != DONT_BLEED )
{
SpawnBlood( vecOrigin, vecDir, blood, flDistance );// a little surface blood.
TraceBleed( flDistance, vecDir, ptr, info.GetDamageType() );
}
}
}
CFF_CL_Player* CFF_CL_Player::GetLocalFFPlayer()
{
return (CFF_CL_Player*)C_BasePlayer::GetLocalPlayer();
}
void CFF_CL_Player::Initialize( void )
{
m_headYawPoseParam = LookupPoseParameter( "head_yaw" );
GetPoseParameterRange( m_headYawPoseParam, m_headYawMin, m_headYawMax );
m_headPitchPoseParam = LookupPoseParameter( "head_pitch" );
GetPoseParameterRange( m_headPitchPoseParam, m_headPitchMin, m_headPitchMax );
CStudioHdr *hdr = GetModelPtr();
for ( int i = 0; i < hdr->GetNumPoseParameters() ; i++ )
{
SetPoseParameter( hdr, i, 0.0 );
}
}
CStudioHdr *CFF_CL_Player::OnNewModel( void )
{
CStudioHdr *hdr = BaseClass::OnNewModel();
Initialize( );
return hdr;
}
//-----------------------------------------------------------------------------
/**
* Orient head and eyes towards m_lookAt.
*/
void CFF_CL_Player::UpdateLookAt( void )
{
// head yaw
if (m_headYawPoseParam < 0 || m_headPitchPoseParam < 0)
return;
// orient eyes
m_viewtarget = m_vLookAtTarget;
// blinking
if (m_blinkTimer.IsElapsed())
{
m_blinktoggle = !m_blinktoggle;
m_blinkTimer.Start( RandomFloat( 1.5f, 4.0f ) );
}
// Figure out where we want to look in world space.
QAngle desiredAngles;
Vector to = m_vLookAtTarget - EyePosition();
VectorAngles( to, desiredAngles );
// Figure out where our body is facing in world space.
QAngle bodyAngles( 0, 0, 0 );
bodyAngles[YAW] = GetLocalAngles()[YAW];
float flBodyYawDiff = bodyAngles[YAW] - m_flLastBodyYaw;
m_flLastBodyYaw = bodyAngles[YAW];
// Set the head's yaw.
float desired = AngleNormalize( desiredAngles[YAW] - bodyAngles[YAW] );
desired = clamp( desired, m_headYawMin, m_headYawMax );
m_flCurrentHeadYaw = ApproachAngle( desired, m_flCurrentHeadYaw, 130 * gpGlobals->frametime );
// Counterrotate the head from the body rotation so it doesn't rotate past its target.
m_flCurrentHeadYaw = AngleNormalize( m_flCurrentHeadYaw - flBodyYawDiff );
desired = clamp( desired, m_headYawMin, m_headYawMax );
SetPoseParameter( m_headYawPoseParam, m_flCurrentHeadYaw );
// Set the head's yaw.
desired = AngleNormalize( desiredAngles[PITCH] );
desired = clamp( desired, m_headPitchMin, m_headPitchMax );
m_flCurrentHeadPitch = ApproachAngle( desired, m_flCurrentHeadPitch, 130 * gpGlobals->frametime );
m_flCurrentHeadPitch = AngleNormalize( m_flCurrentHeadPitch );
SetPoseParameter( m_headPitchPoseParam, m_flCurrentHeadPitch );
}
void CFF_CL_Player::ClientThink( void )
{
bool bFoundViewTarget = false;
Vector vForward;
AngleVectors( GetLocalAngles(), &vForward );
for( int iClient = 1; iClient <= gpGlobals->maxClients; ++iClient )
{
CBaseEntity *pEnt = UTIL_PlayerByIndex( iClient );
if(!pEnt || !pEnt->IsPlayer())
continue;
if ( pEnt->entindex() == entindex() )
continue;
Vector vTargetOrigin = pEnt->GetAbsOrigin();
Vector vMyOrigin = GetAbsOrigin();
Vector vDir = vTargetOrigin - vMyOrigin;
if ( vDir.Length() > 128 )
continue;
VectorNormalize( vDir );
if ( DotProduct( vForward, vDir ) < 0.0f )
continue;
m_vLookAtTarget = pEnt->EyePosition();
bFoundViewTarget = true;
break;
}
if ( bFoundViewTarget == false )
{
m_vLookAtTarget = GetAbsOrigin() + vForward * 512;
}
UpdateIDTarget();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CFF_CL_Player::DrawModel( int flags )
{
if ( !m_bReadyToDraw )
return 0;
return BaseClass::DrawModel(flags);
}
//-----------------------------------------------------------------------------
// Should this object receive shadows?
//-----------------------------------------------------------------------------
bool CFF_CL_Player::ShouldReceiveProjectedTextures( int flags )
{
Assert( flags & SHADOW_FLAGS_PROJECTED_TEXTURE_TYPE_MASK );
if ( IsEffectActive( EF_NODRAW ) )
return false;
if( flags & SHADOW_FLAGS_FLASHLIGHT )
{
return true;
}
return BaseClass::ShouldReceiveProjectedTextures( flags );
}
void CFF_CL_Player::DoImpactEffect( trace_t &tr, int nDamageType )
{
if ( GetActiveWeapon() )
{
GetActiveWeapon()->DoImpactEffect( tr, nDamageType );
return;
}
BaseClass::DoImpactEffect( tr, nDamageType );
}
void CFF_CL_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();
if ( m_HL2Local.m_flSuitPower <= 0.0f )
{
if( IsSprinting() )
{
StopSprinting();
}
}
}
const QAngle &CFF_CL_Player::EyeAngles()
{
if( IsLocalPlayer() )
{
return BaseClass::EyeAngles();
}
else
{
return m_angEyeAngles;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CFF_CL_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 );
if( this != C_BasePlayer::GetLocalPlayer() )
{
if ( IsEffectActive( EF_DIMLIGHT ) )
{
int iAttachment = LookupAttachment( "anim_attachment_RH" );
if ( iAttachment < 0 )
return;
Vector vecOrigin;
QAngle eyeAngles = m_angEyeAngles;
GetAttachment( iAttachment, vecOrigin, eyeAngles );
Vector vForward;
AngleVectors( eyeAngles, &vForward );
trace_t tr;
UTIL_TraceLine( vecOrigin, vecOrigin + (vForward * 200), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
if( !m_pFlashlightBeam )
{
BeamInfo_t beamInfo;
beamInfo.m_nType = TE_BEAMPOINTS;
beamInfo.m_vecStart = tr.startpos;
beamInfo.m_vecEnd = tr.endpos;
beamInfo.m_pszModelName = "sprites/glow01.vmt";
beamInfo.m_pszHaloName = "sprites/glow01.vmt";
beamInfo.m_flHaloScale = 3.0;
beamInfo.m_flWidth = 8.0f;
beamInfo.m_flEndWidth = 35.0f;
beamInfo.m_flFadeLength = 300.0f;
beamInfo.m_flAmplitude = 0;
beamInfo.m_flBrightness = 60.0;
beamInfo.m_flSpeed = 0.0f;
beamInfo.m_nStartFrame = 0.0;
beamInfo.m_flFrameRate = 0.0;
beamInfo.m_flRed = 255.0;
beamInfo.m_flGreen = 255.0;
beamInfo.m_flBlue = 255.0;
beamInfo.m_nSegments = 8;
beamInfo.m_bRenderable = true;
beamInfo.m_flLife = 0.5;
beamInfo.m_nFlags = FBEAM_FOREVER | FBEAM_ONLYNOISEONCE | FBEAM_NOTILE | FBEAM_HALOBEAM;
m_pFlashlightBeam = beams->CreateBeamPoints( beamInfo );
}
if( m_pFlashlightBeam )
{
BeamInfo_t beamInfo;
beamInfo.m_vecStart = tr.startpos;
beamInfo.m_vecEnd = tr.endpos;
beamInfo.m_flRed = 255.0;
beamInfo.m_flGreen = 255.0;
beamInfo.m_flBlue = 255.0;
beams->UpdateBeamInfo( m_pFlashlightBeam, beamInfo );
dlight_t *el = effects->CL_AllocDlight( 0 );
el->origin = tr.endpos;
el->radius = 50;
el->color.r = 200;
el->color.g = 200;
el->color.b = 200;
el->die = gpGlobals->curtime + 0.1;
}
}
else if ( m_pFlashlightBeam )
{
ReleaseFlashlight();
}
}
}
ShadowType_t CFF_CL_Player::ShadowCastType( void )
{
if ( !IsVisible() )
return SHADOWS_NONE;
return SHADOWS_RENDER_TO_TEXTURE_DYNAMIC;
}
const QAngle& CFF_CL_Player::GetRenderAngles()
{
if ( IsRagdoll() )
{
return vec3_angle;
}
else
{
return m_PlayerAnimState.GetRenderAngles();
}
}
bool CFF_CL_Player::ShouldDraw( void )
{
// If we're dead, our ragdoll will be drawn for us instead.
if ( !IsAlive() )
return false;
// if( GetTeamNumber() == TEAM_SPECTATOR )
// return false;
if( IsLocalPlayer() && IsRagdoll() )
return true;
if ( IsRagdoll() )
return false;
return BaseClass::ShouldDraw();
}
void CFF_CL_Player::NotifyShouldTransmit( ShouldTransmitState_t state )
{
if ( state == SHOULDTRANSMIT_END )
{
if( m_pFlashlightBeam != NULL )
{
ReleaseFlashlight();
}
}
BaseClass::NotifyShouldTransmit( state );
}
void CFF_CL_Player::OnDataChanged( DataUpdateType_t type )
{
BaseClass::OnDataChanged( type );
if ( type == DATA_UPDATE_CREATED )
{
SetNextClientThink( CLIENT_THINK_ALWAYS );
}
UpdateVisibility();
}
void CFF_CL_Player::PostDataUpdate( DataUpdateType_t updateType )
{
if ( m_iSpawnInterpCounter != m_iSpawnInterpCounterCache )
{
MoveToLastReceivedPosition( true );
ResetLatched();
m_iSpawnInterpCounterCache = m_iSpawnInterpCounter;
}
BaseClass::PostDataUpdate( updateType );
}
void CFF_CL_Player::ReleaseFlashlight( void )
{
if( m_pFlashlightBeam )
{
m_pFlashlightBeam->flags = 0;
m_pFlashlightBeam->die = gpGlobals->curtime - 1;
m_pFlashlightBeam = NULL;
}
}
float CFF_CL_Player::GetFOV( void )
{
//Find our FOV with offset zoom value
float flFOVOffset = C_BasePlayer::GetFOV() + GetZoom();
// Clamp FOV in MP
int min_fov = GetMinFOV();
// Don't let it go too low
flFOVOffset = MAX( min_fov, flFOVOffset );
return flFOVOffset;
}
//=========================================================
// Autoaim
// set crosshair position to point to enemey
//=========================================================
Vector CFF_CL_Player::GetAutoaimVector( float flDelta )
{
// Never autoaim a predicted weapon (for now)
Vector forward;
AngleVectors( EyeAngles() + m_Local.m_vecPunchAngle, &forward );
return forward;
}
//-----------------------------------------------------------------------------
// Purpose: Returns whether or not we are allowed to sprint now.
//-----------------------------------------------------------------------------
bool CFF_CL_Player::CanSprint( void )
{
return ( (!m_Local.m_bDucked && !m_Local.m_bDucking) && (GetWaterLevel() != 3) );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CFF_CL_Player::StartSprinting( void )
{
if( m_HL2Local.m_flSuitPower < 10 )
{
// Don't sprint unless there's a reasonable
// amount of suit power.
CPASAttenuationFilter filter( this );
filter.UsePredictionRules();
EmitSound( filter, entindex(), "HL2Player.SprintNoPower" );
return;
}
CPASAttenuationFilter filter( this );
filter.UsePredictionRules();
EmitSound( filter, entindex(), "HL2Player.SprintStart" );
SetMaxSpeed( HL2_SPRINT_SPEED );
m_fIsSprinting = true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CFF_CL_Player::StopSprinting( void )
{
SetMaxSpeed( HL2_NORM_SPEED );
m_fIsSprinting = false;
}
void CFF_CL_Player::HandleSpeedChanges( void )
{
int buttonsChanged = m_afButtonPressed | m_afButtonReleased;
if( buttonsChanged & IN_SPEED )
{
// The state of the sprint/run button has changed.
if ( IsSuitEquipped() )
{
if ( !(m_afButtonPressed & IN_SPEED) && IsSprinting() )
{
StopSprinting();
}
else if ( (m_afButtonPressed & IN_SPEED) && !IsSprinting() )
{
if ( CanSprint() )
{
StartSprinting();
}
else
{
// Reset key, so it will be activated post whatever is suppressing it.
m_nButtons &= ~IN_SPEED;
}
}
}
}
else if( buttonsChanged & IN_WALK )
{
if ( IsSuitEquipped() )
{
// The state of the WALK button has changed.
if( IsWalking() && !(m_afButtonPressed & IN_WALK) )
{
StopWalking();
}
else if( !IsWalking() && !IsSprinting() && (m_afButtonPressed & IN_WALK) && !(m_nButtons & IN_DUCK) )
{
StartWalking();
}
}
}
if ( IsSuitEquipped() && m_fIsWalking && !(m_nButtons & IN_WALK) )
StopWalking();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CFF_CL_Player::StartWalking( void )
{
SetMaxSpeed( HL2_WALK_SPEED );
m_fIsWalking = true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CFF_CL_Player::StopWalking( void )
{
SetMaxSpeed( HL2_NORM_SPEED );
m_fIsWalking = false;
}
void CFF_CL_Player::ItemPreFrame( void )
{
if ( GetFlags() & FL_FROZEN )
return;
// Disallow shooting while zooming
if ( m_nButtons & IN_ZOOM )
{
//FIXME: Held weapons like the grenade get sad when this happens
m_nButtons &= ~(IN_ATTACK|IN_ATTACK2);
}
BaseClass::ItemPreFrame();
}
void CFF_CL_Player::ItemPostFrame( void )
{
if ( GetFlags() & FL_FROZEN )
return;
BaseClass::ItemPostFrame();
}
C_BaseAnimating *CFF_CL_Player::BecomeRagdollOnClient()
{
// Let the C_CSRagdoll entity do this.
// m_builtRagdoll = true;
return NULL;
}
void CFF_CL_Player::CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov )
{
if ( m_lifeState != LIFE_ALIVE && !IsObserver() )
{
Vector origin = EyePosition();
IRagdoll *pRagdoll = GetRepresentativeRagdoll();
if ( pRagdoll )
{
origin = pRagdoll->GetRagdollOrigin();
origin.z += VEC_DEAD_VIEWHEIGHT_SCALED( this ).z; // look over ragdoll, not through
}
BaseClass::CalcView( eyeOrigin, eyeAngles, zNear, zFar, fov );
eyeOrigin = origin;
Vector vForward;
AngleVectors( eyeAngles, &vForward );
VectorNormalize( vForward );
VectorMA( origin, -CHASE_CAM_DISTANCE_MAX, vForward, eyeOrigin );
Vector WALL_MIN( -WALL_OFFSET, -WALL_OFFSET, -WALL_OFFSET );
Vector WALL_MAX( WALL_OFFSET, WALL_OFFSET, WALL_OFFSET );
trace_t trace; // clip against world
C_BaseEntity::PushEnableAbsRecomputations( false ); // HACK don't recompute positions while doing RayTrace
UTIL_TraceHull( origin, eyeOrigin, WALL_MIN, WALL_MAX, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trace );
C_BaseEntity::PopEnableAbsRecomputations();
if (trace.fraction < 1.0)
{
eyeOrigin = trace.endpos;
}
return;
}
BaseClass::CalcView( eyeOrigin, eyeAngles, zNear, zFar, fov );
}
IRagdoll* CFF_CL_Player::GetRepresentativeRagdoll() const
{
if ( m_hRagdoll.Get() )
{
CFF_CL_Ragdoll *pRagdoll = (CFF_CL_Ragdoll*)m_hRagdoll.Get();
return pRagdoll->GetIRagdoll();
}
else
{
return NULL;
}
}
//FFRAGDOLL
IMPLEMENT_CLIENTCLASS_DT_NOBASE( CFF_CL_Ragdoll, DT_FFRagdoll, CFF_SV_Ragdoll )
RecvPropVector( RECVINFO(m_vecRagdollOrigin) ),
RecvPropEHandle( RECVINFO( m_hPlayer ) ),
RecvPropInt( RECVINFO( m_nModelIndex ) ),
RecvPropInt( RECVINFO(m_nForceBone) ),
RecvPropVector( RECVINFO(m_vecForce) ),
RecvPropVector( RECVINFO( m_vecRagdollVelocity ) )
END_RECV_TABLE()
CFF_CL_Ragdoll::CFF_CL_Ragdoll()
{
}
CFF_CL_Ragdoll::~CFF_CL_Ragdoll()
{
PhysCleanupFrictionSounds( this );
if ( m_hPlayer )
{
m_hPlayer->CreateModelInstance();
}
}
void CFF_CL_Ragdoll::Interp_Copy( C_BaseAnimatingOverlay *pSourceEntity )
{
if ( !pSourceEntity )
return;
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++ )
{
VarMapEntry_t *pDestEntry = &pDest->m_Entries[i];
const char *pszName = pDestEntry->watcher->GetDebugName();
for ( int j=0; j < pSrc->m_Entries.Count(); j++ )
{
VarMapEntry_t *pSrcEntry = &pSrc->m_Entries[j];
if ( !Q_strcmp( pSrcEntry->watcher->GetDebugName(), pszName ) )
{
pDestEntry->watcher->Copy( pSrcEntry->watcher );
break;
}
}
}
}
void CFF_CL_Ragdoll::ImpactTrace( trace_t *pTrace, int iDamageType, const char *pCustomImpactName )
{
IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
if( !pPhysicsObject )
return;
Vector dir = pTrace->endpos - pTrace->startpos;
if ( iDamageType == DMG_BLAST )
{
dir *= 4000; // adjust impact strenght
// apply force at object mass center
pPhysicsObject->ApplyForceCenter( dir );
}
else
{
Vector hitpos;
VectorMA( pTrace->startpos, pTrace->fraction, dir, hitpos );
VectorNormalize( dir );
dir *= 4000; // adjust impact strenght
// apply force where we hit it
pPhysicsObject->ApplyForceOffset( dir, hitpos );
// Blood spray!
// FX_CS_BloodSpray( hitpos, dir, 10 );
}
m_pRagdoll->ResetRagdollSleepAfterTime();
}
void CFF_CL_Ragdoll::CreateFFRagdoll( void )
{
// First, initialize all our data. If we have the player's entity on our client,
// then we can make ourselves start out exactly where the player is.
CFF_CL_Player *pPlayer = dynamic_cast< CFF_CL_Player* >( m_hPlayer.Get() );
if ( pPlayer && !pPlayer->IsDormant() )
{
// move my current model instance to the ragdoll's so decals are preserved.
pPlayer->SnatchModelInstance( this );
VarMapping_t *varMap = GetVarMapping();
// Copy all the interpolated vars from the player entity.
// The entity uses the interpolated history to get bone velocity.
bool bRemotePlayer = (pPlayer != C_BasePlayer::GetLocalPlayer());
if ( bRemotePlayer )
{
Interp_Copy( pPlayer );
SetAbsAngles( pPlayer->GetRenderAngles() );
GetRotationInterpolator().Reset();
m_flAnimTime = pPlayer->m_flAnimTime;
SetSequence( pPlayer->GetSequence() );
m_flPlaybackRate = pPlayer->GetPlaybackRate();
}
else
{
// This is the local player, so set them in a default
// pose and slam their velocity, angles and origin
SetAbsOrigin( m_vecRagdollOrigin );
SetAbsAngles( pPlayer->GetRenderAngles() );
SetAbsVelocity( m_vecRagdollVelocity );
int iSeq = pPlayer->GetSequence();
if ( iSeq == -1 )
{
Assert( false ); // missing walk_lower?
iSeq = 0;
}
SetSequence( iSeq ); // walk_lower, basic pose
SetCycle( 0.0 );
Interp_Reset( varMap );
}
}
else
{
// overwrite network origin so later interpolation will
// use this position
SetNetworkOrigin( m_vecRagdollOrigin );
SetAbsOrigin( m_vecRagdollOrigin );
SetAbsVelocity( m_vecRagdollVelocity );
Interp_Reset( GetVarMapping() );
}
SetModelIndex( m_nModelIndex );
// Make us a ragdoll..
m_nRenderFX = kRenderFxRagdoll;
matrix3x4_t boneDelta0[MAXSTUDIOBONES];
matrix3x4_t boneDelta1[MAXSTUDIOBONES];
matrix3x4_t currentBones[MAXSTUDIOBONES];
const float boneDt = 0.05f;
if ( pPlayer && !pPlayer->IsDormant() )
{
pPlayer->GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt );
}
else
{
GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt );
}
InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt );
}
void CFF_CL_Ragdoll::OnDataChanged( DataUpdateType_t type )
{
BaseClass::OnDataChanged( type );
if ( type == DATA_UPDATE_CREATED )
{
CreateFFRagdoll();
}
}
IRagdoll* CFF_CL_Ragdoll::GetIRagdoll() const
{
return m_pRagdoll;
}
void CFF_CL_Ragdoll::UpdateOnRemove( void )
{
VPhysicsSetObject( NULL );
BaseClass::UpdateOnRemove();
}
//-----------------------------------------------------------------------------
// Purpose: clear out any face/eye values stored in the material system
//-----------------------------------------------------------------------------
void CFF_CL_Ragdoll::SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights )
{
BaseClass::SetupWeights( pBoneToWorld, nFlexWeightCount, pFlexWeights, pFlexDelayedWeights );
static float destweight[128];
static bool bIsInited = false;
CStudioHdr *hdr = GetModelPtr();
if ( !hdr )
return;
int nFlexDescCount = hdr->numflexdesc();
if ( nFlexDescCount )
{
Assert( !pFlexDelayedWeights );
memset( pFlexWeights, 0, nFlexWeightCount * sizeof(float) );
}
if ( m_iEyeAttachment > 0 )
{
matrix3x4_t attToWorld;
if (GetAttachment( m_iEyeAttachment, attToWorld ))
{
Vector local, tmp;
local.Init( 1000.0f, 0.0f, 0.0f );
VectorTransform( local, attToWorld, tmp );
modelrender->SetViewTarget( GetModelPtr(), GetBody(), tmp );
}
}
}
void CFF_CL_Player::PostThink( void )
{
BaseClass::PostThink();
// Store the eye angles pitch so the client can compute its animation state correctly.
m_angEyeAngles = EyeAngles();
}

View file

@ -0,0 +1,173 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef FF_CL_PLAYER_H
#define FF_CL_PLAYER_H
#pragma once
class CFF_CL_Player;
#include "c_basehlplayer.h"
#include "ff_sh_player.h"
#include "beamdraw.h"
//=============================================================================
// >> FF_Player
//=============================================================================
class CFF_CL_Player : public C_BaseHLPlayer
{
public:
DECLARE_CLASS( CFF_CL_Player, C_BaseHLPlayer );
DECLARE_CLIENTCLASS();
DECLARE_PREDICTABLE();
DECLARE_INTERPOLATION();
CFF_CL_Player();
~CFF_CL_Player( void );
void ClientThink( void );
static CFF_CL_Player* GetLocalFFPlayer();
virtual int DrawModel( int flags );
virtual void AddEntity( void );
QAngle GetAnimEyeAngles( void ) { return m_angEyeAngles; }
Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL );
// Should this object cast shadows?
virtual ShadowType_t ShadowCastType( void );
virtual C_BaseAnimating *BecomeRagdollOnClient();
virtual const QAngle& GetRenderAngles();
virtual bool ShouldDraw( void );
virtual void OnDataChanged( DataUpdateType_t type );
virtual float GetFOV( void );
virtual CStudioHdr *OnNewModel( void );
virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
virtual void ItemPreFrame( void );
virtual void ItemPostFrame( void );
virtual float GetMinFOV() const { return 5.0f; }
virtual Vector GetAutoaimVector( float flDelta );
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
virtual void CreateLightEffects( void ) {}
virtual bool ShouldReceiveProjectedTextures( int flags );
virtual void PostDataUpdate( DataUpdateType_t updateType );
virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
virtual void PreThink( void );
virtual void DoImpactEffect( trace_t &tr, int nDamageType );
IRagdoll* GetRepresentativeRagdoll() const;
virtual void CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov );
virtual const QAngle& EyeAngles( void );
bool CanSprint( void );
void StartSprinting( void );
void StopSprinting( void );
void HandleSpeedChanges( void );
void UpdateLookAt( void );
void Initialize( void );
int GetIDTarget() const;
void UpdateIDTarget( void );
void PrecacheFootStepSounds( void );
const char *GetPlayerModelSoundPrefix( void );
FFPlayerState State_Get() const;
// Walking
void StartWalking( void );
void StopWalking( void );
bool IsWalking( void ) { return m_fIsWalking; }
virtual void PostThink( void );
private:
CFF_CL_Player( const CFF_CL_Player & );
CPlayerAnimState m_PlayerAnimState;
QAngle m_angEyeAngles;
CInterpolatedVar< QAngle > m_iv_angEyeAngles;
EHANDLE m_hRagdoll;
int m_headYawPoseParam;
int m_headPitchPoseParam;
float m_headYawMin;
float m_headYawMax;
float m_headPitchMin;
float m_headPitchMax;
bool m_isInit;
Vector m_vLookAtTarget;
float m_flLastBodyYaw;
float m_flCurrentHeadYaw;
float m_flCurrentHeadPitch;
int m_iIDEntIndex;
CountdownTimer m_blinkTimer;
int m_iSpawnInterpCounter;
int m_iSpawnInterpCounterCache;
int m_iPlayerSoundType;
void ReleaseFlashlight( void );
Beam_t *m_pFlashlightBeam;
CNetworkVar( FFPlayerState, m_iPlayerState );
bool m_fIsWalking;
};
inline CFF_CL_Player *ToFFPlayer( CBaseEntity *pEntity )
{
if ( !pEntity || !pEntity->IsPlayer() )
return NULL;
return dynamic_cast<CFF_CL_Player*>( pEntity );
}
class CFF_CL_Ragdoll : public C_BaseAnimatingOverlay
{
public:
DECLARE_CLASS( CFF_CL_Ragdoll, C_BaseAnimatingOverlay );
DECLARE_CLIENTCLASS();
CFF_CL_Ragdoll();
~CFF_CL_Ragdoll();
virtual void OnDataChanged( DataUpdateType_t type );
int GetPlayerEntIndex() const;
IRagdoll* GetIRagdoll() const;
void ImpactTrace( trace_t *pTrace, int iDamageType, const char *pCustomImpactName );
void UpdateOnRemove( void );
virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights );
private:
CFF_CL_Ragdoll( const CFF_CL_Ragdoll & ) {}
void Interp_Copy( C_BaseAnimatingOverlay *pDestinationEntity );
void CreateFFRagdoll( void );
private:
EHANDLE m_hPlayer;
CNetworkVector( m_vecRagdollVelocity );
CNetworkVector( m_vecRagdollOrigin );
};
#endif //FF_CL_PLAYER_H

View file

@ -12,7 +12,7 @@
#include "vgui/ILocalize.h"
#include "c_team.h"
#include "c_playerresource.h"
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#include "ff_sh_gamerules.h"
#include "ihudlcd.h"

View file

@ -7,7 +7,7 @@
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#include "c_playerresource.h"
#include "vgui_entitypanel.h"
#include "iclientmode.h"
@ -106,7 +106,7 @@ void CTargetID::Paint()
wchar_t sIDString[ MAX_ID_STRING ];
sIDString[0] = 0;
C_HL2MP_Player *pPlayer = C_HL2MP_Player::GetLocalHL2MPPlayer();
CFF_CL_Player *pPlayer = CFF_CL_Player::GetLocalFFPlayer();
if ( !pPlayer )
return;

View file

@ -7,7 +7,7 @@
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#include "c_playerresource.h"
#include "vgui_entitypanel.h"
#include "iclientmode.h"

View file

@ -10,7 +10,7 @@
#include "hl2mpclientscoreboard.h"
#include "c_team.h"
#include "c_playerresource.h"
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#include "ff_sh_gamerules.h"
#include <KeyValues.h>

View file

@ -14,7 +14,7 @@
*/
#include "cbase.h"
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#include "ff_sh_gamerules.h"
#include "gamerules.h"
#include "teamplay_gamerules.h"
@ -38,7 +38,7 @@ ConVar sv_motd_unload_on_dismissal( "sv_motd_unload_on_dismissal", "0", 0, "If e
extern CBaseEntity* FindPickerEntityClass( CBasePlayer *pPlayer, char *classname );
extern bool g_fGameOver;
void FinishClientPutInServer( CHL2MP_Player *pPlayer )
void FinishClientPutInServer( CFF_SV_Player *pPlayer )
{
pPlayer->InitialSpawn();
pPlayer->Spawn();
@ -87,7 +87,7 @@ called each time a player is spawned into the game
void ClientPutInServer( edict_t *pEdict, const char *playername )
{
// Allocate a CBaseTFPlayer for pev, and call spawn
CHL2MP_Player *pPlayer = CHL2MP_Player::CreatePlayer( "player", pEdict );
CFF_SV_Player *pPlayer = CFF_SV_Player::CreatePlayer( "player", pEdict );
pPlayer->SetPlayerName( playername );
}
@ -97,7 +97,7 @@ void ClientActive( edict_t *pEdict, bool bLoadGame )
// Can't load games in CS!
Assert( !bLoadGame );
CHL2MP_Player *pPlayer = ToHL2MPPlayer( CBaseEntity::Instance( pEdict ) );
CFF_SV_Player *pPlayer = ToFFPlayer( CBaseEntity::Instance( pEdict ) );
FinishClientPutInServer( pPlayer );
}
@ -160,7 +160,7 @@ void ClientGamePrecache( void )
// called by ClientKill and DeadThink
void respawn( CBaseEntity *pEdict, bool fCopyCorpse )
{
CHL2MP_Player *pPlayer = ToHL2MPPlayer( pEdict );
CFF_SV_Player *pPlayer = ToFFPlayer( pEdict );
if ( pPlayer )
{

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,176 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef FF_SV_PLAYER_H
#define FF_SV_PLAYER_H
#pragma once
class CFF_SV_Player;
#include "basemultiplayerplayer.h"
#include "hl2_playerlocaldata.h"
#include "hl2_player.h"
#include "simtimer.h"
#include "soundenvelope.h"
#include "ff_sh_player.h"
#include "ff_sh_gamerules.h"
#include "utldict.h"
//=============================================================================
// >> FF_Player
//=============================================================================
class CFFPlayerStateInfo
{
public:
FFPlayerState m_iPlayerState;
const char *m_pStateName;
void (CFF_SV_Player::*pfnEnterState)(); // Init and deinit the state.
void (CFF_SV_Player::*pfnLeaveState)();
void (CFF_SV_Player::*pfnPreThink)(); // Do a PreThink() in this state.
};
class CFF_SV_Player : public CHL2_Player
{
public:
DECLARE_CLASS( CFF_SV_Player, CHL2_Player );
CFF_SV_Player();
~CFF_SV_Player( void );
static CFF_SV_Player *CreatePlayer( const char *className, edict_t *ed )
{
CFF_SV_Player::s_PlayerEdict = ed;
return (CFF_SV_Player*)CreateEntityByName( className );
}
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
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 );
virtual bool BecomeRagdollOnClient( const Vector &force );
virtual void Event_Killed( const CTakeDamageInfo &info );
virtual int OnTakeDamage( const CTakeDamageInfo &inputInfo );
virtual bool WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const;
virtual void FireBullets ( const FireBulletsInfo_t &info );
virtual bool Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex = 0);
virtual bool BumpWeapon( CBaseCombatWeapon *pWeapon );
virtual void ChangeTeam( int iTeam );
virtual void PickupObject ( CBaseEntity *pObject, bool bLimitMassAndSize );
virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
virtual void Weapon_Drop( CBaseCombatWeapon *pWeapon, const Vector *pvecTarget = NULL, const Vector *pVelocity = NULL );
virtual void UpdateOnRemove( void );
virtual void DeathSound( const CTakeDamageInfo &info );
virtual CBaseEntity* EntSelectSpawnPoint( void );
int FlashlightIsOn( void );
void FlashlightTurnOn( void );
void FlashlightTurnOff( void );
void PrecacheFootStepSounds( void );
bool ValidatePlayerModel( const char *pModel );
QAngle GetAnimEyeAngles( void ) { return m_angEyeAngles.Get(); }
Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL );
void CheatImpulseCommands( int iImpulse );
void CreateRagdollEntity( void );
void GiveAllItems( void );
void GiveDefaultItems( void );
void NoteWeaponFired( void );
void ResetAnimation( void );
void SetPlayerModel( void );
void SetPlayerTeamModel( void );
Activity TranslateTeamActivity( Activity ActToTranslate );
float GetNextModelChangeTime( void ) { return m_flNextModelChangeTime; }
float GetNextTeamChangeTime( void ) { return m_flNextTeamChangeTime; }
void PickDefaultSpawnTeam( void );
void SetupPlayerSoundsByModel( const char *pModelName );
const char *GetPlayerModelSoundPrefix( void );
int GetPlayerModelType( void ) { return m_iPlayerSoundType; }
void DetonateTripmines( void );
void Reset();
bool IsReady();
void SetReady( bool bReady );
void CheckChatText( char *p, int bufsize );
void State_Transition( FFPlayerState newState );
void State_Enter( FFPlayerState newState );
void State_Leave();
void State_PreThink();
CFFPlayerStateInfo *State_LookupInfo( FFPlayerState state );
void State_Enter_ACTIVE();
void State_PreThink_ACTIVE();
void State_Enter_OBSERVER_MODE();
void State_PreThink_OBSERVER_MODE();
virtual bool StartObserverMode( int mode );
virtual void StopObserverMode( void );
Vector m_vecTotalBulletForce; //Accumulator for bullet force in a single frame
// Tracks our ragdoll entity.
CNetworkHandle( CBaseEntity, m_hRagdoll ); // networked entity handle
virtual bool CanHearAndReadChatFrom( CBasePlayer *pPlayer );
private:
CNetworkQAngle( m_angEyeAngles );
CPlayerAnimState m_PlayerAnimState;
int m_iLastWeaponFireUsercmd;
int m_iModelType;
CNetworkVar( int, m_iSpawnInterpCounter );
CNetworkVar( int, m_iPlayerSoundType );
float m_flNextModelChangeTime;
float m_flNextTeamChangeTime;
float m_flSlamProtectTime;
FFPlayerState m_iPlayerState;
CFFPlayerStateInfo *m_pCurStateInfo;
bool ShouldRunRateLimitedCommand( const CCommand &args );
// 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_bReady;
};
inline CFF_SV_Player *ToFFPlayer( CBaseEntity *pEntity )
{
if ( !pEntity || !pEntity->IsPlayer() )
return NULL;
return dynamic_cast<CFF_SV_Player*>( pEntity );
}
#endif //FF_SV_PLAYER_H

View file

@ -14,12 +14,12 @@
#include "cbase.h"
#include "player.h"
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#include "in_buttons.h"
#include "movehelper_server.h"
void ClientPutInServer( edict_t *pEdict, const char *playername );
void Bot_Think( CHL2MP_Player *pBot );
void Bot_Think( CFF_SV_Player *pBot );
#ifdef DEBUG
@ -91,7 +91,7 @@ CBasePlayer *BotPutInServer( bool bFrozen, int iTeam )
// Allocate a CBasePlayer for the bot, and call spawn
//ClientPutInServer( pEdict, botname );
CHL2MP_Player *pPlayer = ((CHL2MP_Player *)CBaseEntity::Instance( pEdict ));
CFF_SV_Player *pPlayer = ((CFF_SV_Player *)CBaseEntity::Instance( pEdict ));
pPlayer->ClearFlags();
pPlayer->AddFlag( FL_CLIENT | FL_FAKECLIENT );
@ -113,7 +113,7 @@ void Bot_RunAll( void )
{
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CHL2MP_Player *pPlayer = ToHL2MPPlayer( UTIL_PlayerByIndex( i ) );
CFF_SV_Player *pPlayer = ToFFPlayer( UTIL_PlayerByIndex( i ) );
if ( pPlayer && (pPlayer->GetFlags() & FL_FAKECLIENT) )
{
@ -156,7 +156,7 @@ bool RunMimicCommand( CUserCmd& cmd )
// msec -
// Output : virtual void
//-----------------------------------------------------------------------------
static void RunPlayerMove( CHL2MP_Player *fakeclient, const QAngle& viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, float frametime )
static void RunPlayerMove( CFF_SV_Player *fakeclient, const QAngle& viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, float frametime )
{
if ( !fakeclient )
return;
@ -206,7 +206,7 @@ static void RunPlayerMove( CHL2MP_Player *fakeclient, const QAngle& viewangles,
//-----------------------------------------------------------------------------
// Purpose: Run this Bot's AI for one frame.
//-----------------------------------------------------------------------------
void Bot_Think( CHL2MP_Player *pBot )
void Bot_Think( CFF_SV_Player *pBot )
{
// Make sure we stay being a bot
pBot->AddFlag( FL_FAKECLIENT );

View file

@ -34,9 +34,17 @@ $Project "Server (FF)"
// for FF Shared, see game\shared\ff\ff_shared.vpc
$Folder "FF"
{
$File "FF\ff_sv_client.cpp"
$File "FF\ff_sv_gameinterface.cpp"
$File "FF\ff_sv_gameinterface.h"
$Folder "Game"
{
$File "FF\ff_sv_client.cpp"
$File "FF\ff_sv_gameinterface.cpp"
$File "FF\ff_sv_gameinterface.h"
}
$Folder "Player"
{
$File "ff\ff_sv_player.cpp"
$File "ff\ff_sv_player.h"
}
$Folder "Libraries"
{
@ -59,6 +67,11 @@ $Project "Server (FF)"
-$File "hl2mp\hl2mp_client.cpp"
-$File "hl2mp\hl2mp_gameinterface.cpp"
-$File "hl2mp\hl2mp_gameinterface.h"
// Player
-$File "hl2mp\hl2mp_player.cpp"
-$File "hl2mp\hl2mp_player.h"
-$File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.cpp"
-$File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.h"
}
}
}

View file

@ -12,7 +12,7 @@
#include "ammodef.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#else
#include "eventqueue.h"
@ -26,7 +26,7 @@
#include <ctype.h>
#include "voice_gamemgr.h"
#include "iscorer.h"
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#include "team.h"
#include "voice_gamemgr.h"
@ -764,9 +764,9 @@ void CFF_SH_Rules::ClientSettingsChanged( CBasePlayer *pPlayer )
{
#ifndef CLIENT_DLL
CHL2MP_Player *pHL2Player = ToHL2MPPlayer( pPlayer );
CFF_SH_Player *pFFPlayer = ToFFPlayer( pPlayer );
if ( pHL2Player == NULL )
if ( pFFPlayer == NULL )
return;
const char *pCurrentModel = modelinfo->GetModelName( pPlayer->GetModel() );
@ -778,44 +778,44 @@ void CFF_SH_Rules::ClientSettingsChanged( CBasePlayer *pPlayer )
//Too soon, set the cvar back to what it was.
//Note: this will make this function be called again
//but since our models will match it'll just skip this whole dealio.
if ( pHL2Player->GetNextModelChangeTime() >= gpGlobals->curtime )
if ( pFFPlayer->GetNextModelChangeTime() >= gpGlobals->curtime )
{
char szReturnString[512];
Q_snprintf( szReturnString, sizeof (szReturnString ), "cl_playermodel %s\n", pCurrentModel );
engine->ClientCommand ( pHL2Player->edict(), szReturnString );
engine->ClientCommand ( pFFPlayer->edict(), szReturnString );
Q_snprintf( szReturnString, sizeof( szReturnString ), "Please wait %d more seconds before trying to switch.\n", (int)(pHL2Player->GetNextModelChangeTime() - gpGlobals->curtime) );
ClientPrint( pHL2Player, HUD_PRINTTALK, szReturnString );
Q_snprintf( szReturnString, sizeof( szReturnString ), "Please wait %d more seconds before trying to switch.\n", (int)(pFFPlayer->GetNextModelChangeTime() - gpGlobals->curtime) );
ClientPrint( pFFPlayer, HUD_PRINTTALK, szReturnString );
return;
}
if (FFRules()->IsTeamplay() == false )
{
pHL2Player->SetPlayerModel();
pFFPlayer->SetPlayerModel();
const char *pszCurrentModelName = modelinfo->GetModelName( pHL2Player->GetModel() );
const char *pszCurrentModelName = modelinfo->GetModelName( pFFPlayer->GetModel() );
char szReturnString[128];
Q_snprintf( szReturnString, sizeof( szReturnString ), "Your player model is: %s\n", pszCurrentModelName );
ClientPrint( pHL2Player, HUD_PRINTTALK, szReturnString );
ClientPrint( pFFPlayer, HUD_PRINTTALK, szReturnString );
}
else
{
if ( Q_stristr( szModelName, "models/human") )
{
pHL2Player->ChangeTeam( TEAM_REBELS );
pFFPlayer->ChangeTeam( TEAM_REBELS );
}
else
{
pHL2Player->ChangeTeam( TEAM_COMBINE );
pFFPlayer->ChangeTeam( TEAM_COMBINE );
}
}
}
if ( sv_report_client_settings.GetInt() == 1 )
{
UTIL_LogPrintf( "\"%s\" cl_cmdrate = \"%s\"\n", pHL2Player->GetPlayerName(), engine->GetClientConVarValue( pHL2Player->entindex(), "cl_cmdrate" ));
UTIL_LogPrintf( "\"%s\" cl_cmdrate = \"%s\"\n", pFFPlayer->GetPlayerName(), engine->GetClientConVarValue( pFFPlayer->entindex(), "cl_cmdrate" ));
}
BaseClass::ClientSettingsChanged( pPlayer );
@ -899,7 +899,7 @@ bool CFF_SH_Rules::ClientCommand( CBaseEntity *pEdict, const CCommand &args )
return true;
CHL2MP_Player *pPlayer = (CHL2MP_Player *) pEdict;
CFF_SH_Player *pPlayer = (CFF_SH_Player *) pEdict;
if ( pPlayer->ClientCommand( args ) )
return true;
@ -1018,7 +1018,7 @@ void CFF_SH_Rules::RestartGame()
// now respawn all players
for (int i = 1; i <= gpGlobals->maxClients; i++ )
{
CHL2MP_Player *pPlayer = (CHL2MP_Player*) UTIL_PlayerByIndex( i );
CFF_SH_Player *pPlayer = (CFF_SH_Player*) UTIL_PlayerByIndex( i );
if ( !pPlayer )
continue;
@ -1160,7 +1160,7 @@ void CFF_SH_Rules::CleanUpMap()
MapEntity_ParseAllEntities( engine->GetMapEntitiesString(), &filter, true );
}
void CFF_SH_Rules::CheckChatForReadySignal( CHL2MP_Player *pPlayer, const char *chatmsg )
void CFF_SH_Rules::CheckChatForReadySignal( CFF_SH_Player *pPlayer, const char *chatmsg )
{
if( m_bAwaitingReadyRestart && FStrEq( chatmsg, mp_ready_signal.GetString() ) )
{
@ -1223,7 +1223,7 @@ void CFF_SH_Rules::CheckAllPlayersReady( void )
{
for (int i = 1; i <= gpGlobals->maxClients; i++ )
{
CHL2MP_Player *pPlayer = (CHL2MP_Player*) UTIL_PlayerByIndex( i );
CFF_SH_Player *pPlayer = (CFF_SH_Player*) UTIL_PlayerByIndex( i );
if ( !pPlayer )
continue;

View file

@ -20,7 +20,7 @@
#include "gamevars_shared.h"
#ifndef CLIENT_DLL
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#endif
#define VEC_CROUCH_TRACE_MIN FFRules()->GetFFViewVectors()->m_vCrouchTraceMin
@ -134,7 +134,7 @@ public:
void AddLevelDesignerPlacedObject( CBaseEntity *pEntity );
void RemoveLevelDesignerPlacedObject( CBaseEntity *pEntity );
void ManageObjectRelocation( void );
void CheckChatForReadySignal( CHL2MP_Player *pPlayer, const char *chatmsg );
void CheckChatForReadySignal( CFF_SH_Player *pPlayer, const char *chatmsg );
const char *GetChatFormat( bool bTeamOnly, CBasePlayer *pPlayer );
#endif

View file

@ -0,0 +1,577 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#ifdef CLIENT_DLL
#include "ff_cl_player.h"
#include "prediction.h"
#define CRecipientFilter C_RecipientFilter
#else
#include "ff_sv_player.h"
#endif
#include "engine/IEngineSound.h"
#include "SoundEmitterSystem/isoundemittersystembase.h"
extern ConVar sv_footsteps;
const char *g_ppszPlayerSoundPrefixNames[PLAYER_SOUNDS_MAX] =
{
"NPC_Citizen",
"NPC_CombineS",
"NPC_MetroPolice",
};
const char *CFF_SH_Player::GetPlayerModelSoundPrefix( void )
{
return g_ppszPlayerSoundPrefixNames[m_iPlayerSoundType];
}
void CFF_SH_Player::PrecacheFootStepSounds( void )
{
int iFootstepSounds = ARRAYSIZE( g_ppszPlayerSoundPrefixNames );
int i;
for ( i = 0; i < iFootstepSounds; ++i )
{
char szFootStepName[128];
Q_snprintf( szFootStepName, sizeof( szFootStepName ), "%s.RunFootstepLeft", g_ppszPlayerSoundPrefixNames[i] );
PrecacheScriptSound( szFootStepName );
Q_snprintf( szFootStepName, sizeof( szFootStepName ), "%s.RunFootstepRight", g_ppszPlayerSoundPrefixNames[i] );
PrecacheScriptSound( szFootStepName );
}
}
//-----------------------------------------------------------------------------
// Consider the weapon's built-in accuracy, this character's proficiency with
// the weapon, and the status of the target. Use this information to determine
// how accurately to shoot at the target.
//-----------------------------------------------------------------------------
Vector CFF_SH_Player::GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget )
{
if ( pWeapon )
return pWeapon->GetBulletSpread( WEAPON_PROFICIENCY_PERFECT );
return VECTOR_CONE_15DEGREES;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : step -
// fvol -
// force - force sound to play
//-----------------------------------------------------------------------------
void CFF_SH_Player::PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force )
{
if ( gpGlobals->maxClients > 1 && !sv_footsteps.GetFloat() )
return;
#if defined( CLIENT_DLL )
// during prediction play footstep sounds only once
if ( !prediction->IsFirstTimePredicted() )
return;
#endif
if ( GetFlags() & FL_DUCKING )
return;
m_Local.m_nStepside = !m_Local.m_nStepside;
char szStepSound[128];
if ( m_Local.m_nStepside )
{
Q_snprintf( szStepSound, sizeof( szStepSound ), "%s.RunFootstepLeft", g_ppszPlayerSoundPrefixNames[m_iPlayerSoundType] );
}
else
{
Q_snprintf( szStepSound, sizeof( szStepSound ), "%s.RunFootstepRight", g_ppszPlayerSoundPrefixNames[m_iPlayerSoundType] );
}
CSoundParameters params;
if ( GetParametersForSound( szStepSound, params, NULL ) == false )
return;
CRecipientFilter filter;
filter.AddRecipientsByPAS( vecOrigin );
#ifndef CLIENT_DLL
// im MP, server removed all players in origins PVS, these players
// generate the footsteps clientside
if ( gpGlobals->maxClients > 1 )
filter.RemoveRecipientsByPVS( vecOrigin );
#endif
EmitSound_t ep;
ep.m_nChannel = CHAN_BODY;
ep.m_pSoundName = params.soundname;
ep.m_flVolume = fvol;
ep.m_SoundLevel = params.soundlevel;
ep.m_nFlags = 0;
ep.m_nPitch = params.pitch;
ep.m_pOrigin = &vecOrigin;
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( CFF_SH_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
//-----------------------------------------------------------------------------
CFF_SH_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

@ -0,0 +1,99 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef FF_SH_PLAYER_H
#define FF_SH_PLAYER_H
#pragma once
#define FF_PUSHAWAY_THINK_INTERVAL (1.0f / 20.0f)
#include "studio.h"
enum
{
PLAYER_SOUNDS_CITIZEN = 0,
PLAYER_SOUNDS_COMBINESOLDIER,
PLAYER_SOUNDS_METROPOLICE,
PLAYER_SOUNDS_MAX,
};
enum FFPlayerState
{
// Happily running around in the game.
STATE_ACTIVE=0,
STATE_OBSERVER_MODE, // Noclipping around, watching players, etc.
NUM_PLAYER_STATES
};
#if defined( CLIENT_DLL )
#define CFF_SH_Player CFF_CL_Player
#else
#define CFF_SH_Player CFF_SV_Player
#endif
class CPlayerAnimState
{
public:
enum
{
TURN_NONE = 0,
TURN_LEFT,
TURN_RIGHT
};
CPlayerAnimState( CFF_SH_Player *outer );
Activity BodyYawTranslateActivity( Activity activity );
void Update();
const QAngle& GetRenderAngles();
void GetPoseParameters( CStudioHdr *pStudioHdr, float poseParameter[MAXSTUDIOPOSEPARAM] );
CFF_SH_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();
CFF_SH_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 //FF_SH_PLAYER_H

View file

@ -17,9 +17,16 @@ $Project
$File "$SRCDIR\game\shared\ff\ff_sh_gamemovement.cpp"
$File "$SRCDIR\game\shared\ff\ff_sh_gamemovement.h"
}
$File "$SRCDIR\game\shared\ff\ff_sh_gamerules.cpp"
$File "$SRCDIR\game\shared\ff\ff_sh_gamerules.h"
$Folder "Player"
{
$File "$SRCDIR\game\shared\ff\ff_sh_player.cpp"
$File "$SRCDIR\game\shared\ff\ff_sh_player.h"
}
$Folder "Game"
{
$File "$SRCDIR\game\shared\ff\ff_sh_gamerules.cpp"
$File "$SRCDIR\game\shared\ff\ff_sh_gamerules.h"
}
}

View file

@ -10,9 +10,9 @@
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#endif
#include "weapon_hl2mpbasehlmpcombatweapon.h"

View file

@ -9,10 +9,10 @@
#include "npcevent.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#include "c_te_effect_dispatch.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#include "te_effect_dispatch.h"
#include "prop_combine_ball.h"
#endif

View file

@ -9,10 +9,10 @@
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#include "c_te_effect_dispatch.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#include "te_effect_dispatch.h"
#include "IEffects.h"
#include "Sprite.h"

View file

@ -16,9 +16,9 @@
#include "npcevent.h"
#if defined( CLIENT_DLL )
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#include "ai_basenpc.h"
#endif

View file

@ -9,10 +9,10 @@
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#include "c_te_effect_dispatch.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#include "te_effect_dispatch.h"
#include "grenade_frag.h"
#endif
@ -405,7 +405,7 @@ void CWeaponFrag::CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye
}
}
void DropPrimedFragGrenade( CHL2MP_Player *pPlayer, CBaseCombatWeapon *pGrenade )
void DropPrimedFragGrenade( CFF_SH_Player *pPlayer, CBaseCombatWeapon *pGrenade )
{
CWeaponFrag *pWeaponFrag = dynamic_cast<CWeaponFrag*>( pGrenade );

View file

@ -23,12 +23,12 @@ extern IVModelInfo* modelinfo;
#include "vgui/ISurface.h"
#include "vgui_controls/Controls.h"
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#include "hud_crosshair.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#include "vphysics/constraints.h"
#endif
@ -131,9 +131,9 @@ CBasePlayer* CWeaponHL2MPBase::GetPlayerOwner() const
return dynamic_cast< CBasePlayer* >( GetOwner() );
}
CHL2MP_Player* CWeaponHL2MPBase::GetHL2MPPlayerOwner() const
CFF_SH_Player* CWeaponHL2MPBase::GetFFPlayerOwner() const
{
return dynamic_cast< CHL2MP_Player* >( GetOwner() );
return dynamic_cast< CFF_SH_Player* >( GetOwner() );
}
#ifdef CLIENT_DLL

View file

@ -10,7 +10,7 @@
#pragma once
#endif
#include "hl2mp_player_shared.h"
#include "ff_sh_player.h"
#include "basecombatweapon_shared.h"
#include "hl2mp_weapon_parse.h"
@ -19,7 +19,7 @@
void UTIL_ClipPunchAngleOffset( QAngle &in, const QAngle &punch, const QAngle &clip );
#endif
class CHL2MP_Player;
class CFF_SH_Player;
// These are the names of the ammo types that go in the CAmmoDefs and that the
// weapon script files reference.
@ -51,7 +51,7 @@ public:
virtual bool IsPredicted() const;
CBasePlayer* GetPlayerOwner() const;
CHL2MP_Player* GetHL2MPPlayerOwner() const;
CFF_SH_Player* GetFFPlayerOwner() const;
void WeaponSound( WeaponSound_t sound_type, float soundtime = 0.0f );

View file

@ -7,9 +7,9 @@
#include "cbase.h"
#if defined( CLIENT_DLL )
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#endif
#include "weapon_hl2mpbase_machinegun.h"
@ -91,14 +91,14 @@ void CHL2MPMachineGun::PrimaryAttack( void )
m_iClip1 -= iBulletsToFire;
}
CHL2MP_Player *pHL2MPPlayer = ToHL2MPPlayer( pPlayer );
CFF_SH_Player *pFFPlayer = ToFFPlayer( pPlayer );
// Fire the bullets
FireBulletsInfo_t info;
info.m_iShots = iBulletsToFire;
info.m_vecSrc = pHL2MPPlayer->Weapon_ShootPosition( );
info.m_vecSrc = pFFPlayer->Weapon_ShootPosition( );
info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
info.m_vecSpread = pHL2MPPlayer->GetAttackSpread( this );
info.m_vecSpread = pFFPlayer->GetAttackSpread( this );
info.m_flDistance = MAX_TRACE_LENGTH;
info.m_iAmmoType = m_iPrimaryAmmoType;
info.m_iTracerFreq = 2;

View file

@ -15,9 +15,9 @@
#include "animation.h"
#if defined( CLIENT_DLL )
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#include "ndebugoverlay.h"
#include "te_effect_dispatch.h"
#include "ilagcompensationmanager.h"
@ -103,7 +103,7 @@ void CBaseHL2MPBludgeonWeapon::PrimaryAttack()
{
#ifndef CLIENT_DLL
CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetPlayerOwner() );
CFF_SH_Player *pPlayer = ToFFPlayer( GetPlayerOwner() );
// Move other players back to history positions based on local player's lag
lagcompensation->StartLagCompensation( pPlayer, pPlayer->GetCurrentCommand() );
#endif

View file

@ -7,7 +7,7 @@
#include "cbase.h"
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#include "hl2mp_player_shared.h"
#include "ff_sh_player.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@ -115,7 +115,7 @@ bool CBaseHL2MPCombatWeapon::Deploy( void )
// We have to ask the player if the last time it checked, the weapon was lowered
if ( GetOwner() && GetOwner()->IsPlayer() )
{
CHL2MP_Player *pPlayer = assert_cast<CHL2MP_Player*>( GetOwner() );
CFF_SH_Player *pPlayer = assert_cast<CFF_SH_Player*>( GetOwner() );
if ( pPlayer->IsWeaponLowered() )
{
if ( SelectWeightedSequence( ACT_VM_IDLE_LOWERED ) != ACTIVITY_NOT_AVAILABLE )

View file

@ -6,9 +6,9 @@
#endif
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#endif
#include "weapon_hl2mpbase.h"

View file

@ -7,7 +7,7 @@
#include "cbase.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#include "vcollide_parse.h"
#include "engine/ivdebugoverlay.h"
#include "iviewrender_beams.h"
@ -17,7 +17,7 @@
#include "clienteffectprecachesystem.h"
#include "fx_interpvalue.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#include "soundent.h"
#include "ndebugoverlay.h"
#include "ai_basenpc.h"
@ -760,7 +760,7 @@ void CPlayerPickupController::Init( CBasePlayer *pPlayer, CBaseEntity *pObject )
}
CHL2MP_Player *pOwner = (CHL2MP_Player *)ToBasePlayer( pPlayer );
CFF_SH_Player *pOwner = (CFF_SH_Player *)ToBasePlayer( pPlayer );
if ( pOwner )
{
pOwner->EnableSprint( false );
@ -813,7 +813,7 @@ void CPlayerPickupController::Shutdown( bool bThrown )
if ( m_pPlayer )
{
CHL2MP_Player *pOwner = (CHL2MP_Player *)ToBasePlayer( m_pPlayer );
CFF_SH_Player *pOwner = (CFF_SH_Player *)ToBasePlayer( m_pPlayer );
if ( pOwner )
{
pOwner->EnableSprint( true );
@ -2015,7 +2015,7 @@ bool CWeaponPhysCannon::AttachObject( CBaseEntity *pObject, const Vector &vPosit
if ( !pPhysics )
return false;
CHL2MP_Player *pOwner = (CHL2MP_Player *)ToBasePlayer( GetOwner() );
CFF_SH_Player *pOwner = (CFF_SH_Player *)ToBasePlayer( GetOwner() );
m_bActive = true;
if( pOwner )
@ -2375,7 +2375,7 @@ void CWeaponPhysCannon::DetachObject( bool playSound, bool wasLaunched )
if ( m_bActive == false )
return;
CHL2MP_Player *pOwner = (CHL2MP_Player *)ToBasePlayer( GetOwner() );
CFF_SH_Player *pOwner = (CFF_SH_Player *)ToBasePlayer( GetOwner() );
if( pOwner != NULL )
{
pOwner->EnableSprint( true );

View file

@ -9,9 +9,9 @@
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#endif
#include "weapon_hl2mpbasehlmpcombatweapon.h"

View file

@ -10,7 +10,7 @@
#include "weapon_rpg.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#include "model_types.h"
#include "beamdraw.h"
#include "fx_line.h"
@ -2226,7 +2226,7 @@ int CLaserDot::DrawModel( int flags )
float scale;
Vector endPos;
C_HL2MP_Player *pOwner = ToHL2MPPlayer( GetOwnerEntity() );
CFF_CL_Player *pOwner = ToFFPlayer( GetOwnerEntity() );
if ( pOwner != NULL && pOwner->IsDormant() == false )
{

View file

@ -9,9 +9,9 @@
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#endif
#include "weapon_hl2mpbasehlmpcombatweapon.h"

View file

@ -11,9 +11,9 @@
#include "engine/IEngineSound.h"
#if defined( CLIENT_DLL )
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#else
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#include "grenade_tripmine.h"
#include "grenade_satchel.h"
#include "entitylist.h"
@ -339,7 +339,7 @@ void CWeapon_SLAM::StartSatchelDetonate()
//-----------------------------------------------------------------------------
void CWeapon_SLAM::TripmineAttach( void )
{
CHL2MP_Player *pOwner = ToHL2MPPlayer( GetOwner() );
CFF_SH_Player *pOwner = ToFFPlayer( GetOwner() );
if (!pOwner)
{
return;
@ -698,7 +698,7 @@ void CWeapon_SLAM::SLAMThink( void )
//-----------------------------------------------------------------------------
bool CWeapon_SLAM::CanAttachSLAM( void )
{
CHL2MP_Player *pOwner = ToHL2MPPlayer( GetOwner() );
CFF_SH_Player *pOwner = ToFFPlayer( GetOwner() );
if (!pOwner)
{

View file

@ -9,10 +9,10 @@
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "ff_cl_player.h"
#else
#include "grenade_ar2.h"
#include "hl2mp_player.h"
#include "ff_sv_player.h"
#include "basegrenade_shared.h"
#endif