//----------------------------------------------------------------------------- bool C_LowViolenceHostageDeathModel::SetupLowViolenceModel( C_CHostage *pHostage ) { const model_t *model = pHostage->GetModel(); const char *pModelName = modelinfo->GetModelName( model ); if ( InitializeAsClientEntity( pModelName, RENDER_GROUP_OPAQUE_ENTITY ) == false ) { Release(); return false; } // Play the low-violence death anim if ( LookupSequence( "death1" ) == -1 ) { Release(); return false; } m_flFadeOutStart = gpGlobals->curtime + 5.0f; SetNextClientThink( CLIENT_THINK_ALWAYS ); SetSequence( LookupSequence( "death1" ) ); ForceClientSideAnimationOn(); if ( pHostage && !pHostage->IsDormant() ) { SetNetworkOrigin( pHostage->GetAbsOrigin() ); SetAbsOrigin( pHostage->GetAbsOrigin() ); SetAbsVelocity( pHostage->GetAbsVelocity() ); // move my current model instance to the ragdoll's so decals are preserved. pHostage->SnatchModelInstance( this ); SetAbsAngles( pHostage->GetRenderAngles() ); SetNetworkAngles( pHostage->GetRenderAngles() ); CStudioHdr *pStudioHdr = GetModelPtr(); // update pose parameters float poseParameter[MAXSTUDIOPOSEPARAM]; GetPoseParameters( pStudioHdr, poseParameter ); for ( int i=0; i<NumInterestingPoseParameters; ++i ) { int poseParameterIndex = LookupPoseParameter( pStudioHdr, InterestingPoseParameters[i] ); SetPoseParameter( pStudioHdr, poseParameterIndex, poseParameter[poseParameterIndex] ); } } Interp_Reset( GetVarMapping() ); return true; }
//Handle all necessary movement stuffs void CDHLProjectile::MoveProjectileToPosition( Vector& vecPos ) { #ifdef CLIENT_DLL SetLocalOrigin( vecPos ); //This is VERY important - C_BaseEntity::PostDataUpdate calls MoveToLastReceivedPosition which forces the origin and angles to their "network" values //Result is that if we don't set them here there will be painful hitching in real world situations (with lag). SetNetworkOrigin( vecPos ); if ( m_pTrail ) m_pTrail->SetAbsOrigin( vecPos ); //m_pTrail->m_vecPosition = vecPos; #else m_vecCurPosition = vecPos; #endif }
void C_HL2MPRagdoll::CreateHL2MPRagdoll( 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. C_HL2MP_Player *pPlayer = dynamic_cast< C_HL2MP_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 C_SDKRagdoll::CreateRagdoll() { // 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. C_SDKPlayer *pPlayer = dynamic_cast< C_SDKPlayer* >( 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. if ( !pPlayer->IsLocalPlayer() && pPlayer->IsInterpolationEnabled() ) { 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 = LookupSequence( "RagdollSpawn" ); // hax, find a neutral standing pose if ( iSeq == -1 ) { Assert( false ); // missing look_idle? iSeq = 0; } SetSequence( iSeq ); // look_idle, basic pose SetCycle( 0.0 ); Interp_Reset( varMap ); } m_nBody = pPlayer->GetBody(); } 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 ); // Turn it into a ragdoll. if ( cl_ragdoll_physics_enable.GetInt() ) { // 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 == C_BasePlayer::GetLocalPlayer() ) { pPlayer->GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt ); } else { GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt ); } InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt ); } else { ClientLeafSystem()->SetRenderGroup( GetRenderHandle(), RENDER_GROUP_TRANSLUCENT_ENTITY ); } // Fade out the ragdoll in a while StartFadeOut( cl_ragdoll_fade_time.GetFloat() ); SetNextClientThink( gpGlobals->curtime + 5.0f ); }
void C_GENPCRagdoll::CreateRagdoll( 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. C_AI_BaseNPC *pNPC = dynamic_cast< C_AI_BaseNPC* >( m_hNPC.Get() ); // Cache away our skin before we start meddling (setting it later down) int skin = 0; if ( pNPC ) skin = pNPC->GetSkin(); if ( pNPC && !pNPC->IsDormant() ) { // move my current model instance to the ragdoll's so decals are preserved. pNPC->SnatchModelInstance( this ); // Copy all the interpolated vars from the player entity. // The entity uses the interpolated history to get bone velocity. Interp_Copy( pNPC ); SetAbsAngles( pNPC->GetRenderAngles() ); GetRotationInterpolator().Reset(); m_flAnimTime = pNPC->m_flAnimTime; SetSequence( pNPC->GetSequence() ); m_flPlaybackRate = pNPC->GetPlaybackRate(); } 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 ( pNPC && !pNPC->IsDormant() ) { pNPC->GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt ); } else { GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt ); } // Finally reset our skin m_nSkin = skin; InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt ); }
void C_StriderRagdoll::CreateStriderRagdoll( 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. C_QUA_Strider *pStrider = dynamic_cast< C_QUA_Strider* >( m_hStrider.Get()); if ( pStrider) { // move my current model instance to the ragdoll's so decals are preserved. pStrider->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( varMap, this, pStrider, pStrider->C_BaseAnimating::GetVarMapping() ); SetAbsAngles( pStrider->GetRenderAngles() ); GetRotationInterpolator().Reset(); m_flAnimTime = pStrider->m_flAnimTime; SetSequence( pStrider->GetSequence() ); m_flPlaybackRate = pStrider->GetPlaybackRate(); SetPoseParameter(LookupPoseParameter("body_height"),200.0f); /*} 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 ); SetSequence(LookupSequence("idle01")); SetPoseParameter(LookupPoseParameter("body_height"),m_fAltura); Interp_Reset( GetVarMapping() ); } SetModelIndex( m_nModelIndex ); //engine->Con_NPrintf(27,"Le volvemos a poner de altura: %f",m_fAltura); SetPoseParameter(LookupPoseParameter("body_height"),200.0f); // Make us a ragdoll.. m_nRenderFX = kRenderFxRagdoll; BecomeRagdollOnClient( /*false*/ ); //FixMe No? xd }
//----------------------------------------------------------------------------- void C_Fish::ClientThink() { if (FishDebug.GetBool()) { debugoverlay->AddLineOverlay( m_pos, m_actualPos, 255, 0, 0, true, 0.1f ); switch( m_localLifeState ) { case LIFE_DYING: debugoverlay->AddTextOverlay( m_pos, 0.1f, "DYING" ); break; case LIFE_DEAD: debugoverlay->AddTextOverlay( m_pos, 0.1f, "DEAD" ); break; } } float deltaT = gpGlobals->frametime; // check if we just died if (m_localLifeState == LIFE_ALIVE && m_lifeState != LIFE_ALIVE) { // we have died m_localLifeState = LIFE_DYING; m_deathDepth = m_pos.z; // determine surface float angle m_deathAngle = RandomFloat( 87.0f, 93.0f ) * ((RandomInt( 0, 100 ) < 50) ? 1.0f : -1.0f); } switch( m_localLifeState ) { case LIFE_DYING: { // depth parameter float t = (m_pos.z - m_deathDepth) / (m_waterLevel - m_deathDepth); t *= t; // roll onto side m_angles.z = m_deathAngle * t; // float to surface const float fudge = 2.0f; if (m_pos.z < m_waterLevel - fudge) { m_vel.z += (1.0f - t) * m_buoyancy * deltaT; } else { m_localLifeState = LIFE_DEAD; } break; } case LIFE_DEAD: { // depth parameter float t = (m_pos.z - m_deathDepth) / (m_waterLevel - m_deathDepth); t *= t; // roll onto side m_angles.z = m_deathAngle * t; // keep near water surface const float sub = 0.5f; m_vel.z += 10.0f * (m_waterLevel - m_pos.z - sub) * deltaT; // bob on surface const float rollAmp = 5.0f; const float rollFreq = 2.33f; m_angles.z += rollAmp * sin( rollFreq * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT; const float rollAmp2 = 7.0f; const float rollFreq2 = 4.0f; m_angles.x += rollAmp2 * sin( rollFreq2 * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT; const float bobAmp = 0.75f; const float bobFreq = 4.0f; m_vel.z += bobAmp * sin( bobFreq * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT; const float bobAmp2 = 0.75f; const float bobFreq2 = 3.333f; m_vel.z += bobAmp2 * sin( bobFreq2 * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT; // decay movement speed to zero const float drag = 1.0f; m_vel.z -= drag * m_vel.z * deltaT; break; } case LIFE_ALIVE: { // use server-side Z coordinate directly m_pos.z = m_actualPos.z; // use server-side angles m_angles = m_actualAngles; // fishy wiggle based on movement if (!m_wiggleTimer.IsElapsed()) { float swimPower = 1.0f - (m_wiggleTimer.GetElapsedTime() / m_wiggleTimer.GetCountdownDuration()); const float amp = 6.0f * swimPower; float wiggle = amp * sin( m_wigglePhase ); m_wigglePhase += m_wiggleRate * deltaT; // wiggle decay const float wiggleDecay = 5.0f; m_wiggleRate -= wiggleDecay * deltaT; m_angles.y += wiggle; } break; } } // compute error between our local position and actual server position Vector error = m_actualPos - m_pos; error.z = 0.0f; float errorLen = error.Length(); if (m_localLifeState == LIFE_ALIVE) { // if error is far above average, start swimming const float wiggleThreshold = 2.0f; if (errorLen - m_averageError > wiggleThreshold) { // if error is large, we must have started swimming const float swimTime = 5.0f; m_wiggleTimer.Start( swimTime ); m_wiggleRate = 2.0f * errorLen; const float maxWiggleRate = 30.0f; if (m_wiggleRate > maxWiggleRate) { m_wiggleRate = maxWiggleRate; } } // update average error m_errorHistory[ m_errorHistoryIndex++ ] = errorLen; if (m_errorHistoryIndex >= MAX_ERROR_HISTORY) { m_errorHistoryIndex = 0; m_errorHistoryCount = MAX_ERROR_HISTORY; } else if (m_errorHistoryCount < MAX_ERROR_HISTORY) { ++m_errorHistoryCount; } m_averageError = 0.0f; if (m_errorHistoryCount) { for( int r=0; r<m_errorHistoryCount; ++r ) { m_averageError += m_errorHistory[r]; } m_averageError /= (float)m_errorHistoryCount; } } // keep fish motion smooth by correcting towards actual server position // NOTE: This only tracks XY motion const float maxError = 20.0f; float errorT = errorLen / maxError; if (errorT > 1.0f) { errorT = 1.0f; } // we want a nonlinear spring force for tracking errorT *= errorT; // as fish move faster, their error increases - use a stiffer spring when fast, and a weak one when slow const float trackRate = 0.0f + errorT * 115.0f; m_vel.x += trackRate * error.x * deltaT; m_vel.y += trackRate * error.y * deltaT; const float trackDrag = 2.0f + errorT * 6.0f; m_vel.x -= trackDrag * m_vel.x * deltaT; m_vel.y -= trackDrag * m_vel.y * deltaT; // euler integration m_pos += m_vel * deltaT; SetNetworkOrigin( m_pos ); SetAbsOrigin( m_pos ); SetNetworkAngles( m_angles ); SetAbsAngles( m_angles ); }
void C_CFRagdoll::CreateRagdoll() { // 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. C_CFPlayer *pPlayer = dynamic_cast< C_CFPlayer* >( 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 = LookupSequence( "idle" ); 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() ); } if (pPlayer) { SetModelIndex( m_nModelIndex ); m_nSkin = pPlayer->m_nSkin; SetBodygroup(1, pPlayer->m_bIsDecapitated); } // Turn it into a ragdoll. if ( cl_ragdoll_physics_enable.GetBool() ) { // Make us a ragdoll.. m_nRenderFX = kRenderFxRagdoll; matrix3x4_t boneDelta0[MAXSTUDIOBONES]; matrix3x4_t boneDelta1[MAXSTUDIOBONES]; matrix3x4_t currentBones[MAXSTUDIOBONES]; const float boneDt = 0.05f; // We have to make sure that we're initting this client ragdoll off of the same model. // GetRagdollInitBoneArrays uses the *player* Hdr, which may be a different model than // the ragdoll Hdr, if we try to create a ragdoll in the same frame that the player // changes their player model. CStudioHdr *pRagdollHdr = GetModelPtr(); CStudioHdr *pPlayerHdr = NULL; if ( pPlayer ) pPlayerHdr = pPlayer->GetModelPtr(); bool bChangedModel = false; if ( pRagdollHdr && pPlayerHdr ) { bChangedModel = pRagdollHdr->GetVirtualModel() != pPlayerHdr->GetVirtualModel(); Assert( !bChangedModel && "C_CFRagdoll::CreateRagdoll: Trying to create ragdoll with a different model than the player it's based on" ); } if ( pPlayer && !pPlayer->IsDormant() && !bChangedModel && pPlayerHdr ) { pPlayer->GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt ); } else { GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt ); } InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt ); } SetNextClientThink( CLIENT_THINK_ALWAYS ); }