void C_SDKPlayer::AvoidPlayers( CUserCmd *pCmd ) { // Player Avoidance is only active with teams // Don't test if the player doesn't exist or is dead. if ( IsAlive() == false ) return; // Up vector. static Vector vecUp( 0.0f, 0.0f, 1.0f ); Vector vecSDKPlayerCenter = GetAbsOrigin(); Vector vecSDKPlayerMin = GetPlayerMins(); Vector vecSDKPlayerMax = GetPlayerMaxs(); float flZHeight = vecSDKPlayerMax.z - vecSDKPlayerMin.z; vecSDKPlayerCenter.z += 0.5f * flZHeight; VectorAdd( vecSDKPlayerMin, vecSDKPlayerCenter, vecSDKPlayerMin ); VectorAdd( vecSDKPlayerMax, vecSDKPlayerCenter, vecSDKPlayerMax ); // Find an intersecting player or object. int nAvoidPlayerCount = 0; C_SDKPlayer *pAvoidPlayerList[MAX_PLAYERS]; C_SDKPlayer *pIntersectPlayer = NULL; float flAvoidRadius = 0.0f; Vector vecAvoidCenter, vecAvoidMin, vecAvoidMax; for ( int i = 1; i <= gpGlobals->maxClients; ++i ) { //C_SDKPlayer *pAvoidPlayer = static_cast< C_SDKPlayer * >( pTeam->GetPlayer( i ) ); C_SDKPlayer *pAvoidPlayer = static_cast< C_SDKPlayer * >( UTIL_PlayerByIndex(i) ); if ( pAvoidPlayer == NULL ) continue; // Is the avoid player me? if ( pAvoidPlayer == this ) continue; // Save as list to check against for objects. pAvoidPlayerList[nAvoidPlayerCount] = pAvoidPlayer; ++nAvoidPlayerCount; // Check to see if the avoid player is dormant. if ( pAvoidPlayer->IsDormant() ) continue; // Is the avoid player solid? if ( pAvoidPlayer->IsSolidFlagSet( FSOLID_NOT_SOLID ) ) continue; Vector t1, t2; vecAvoidCenter = pAvoidPlayer->GetAbsOrigin(); vecAvoidMin = pAvoidPlayer->GetPlayerMins(); vecAvoidMax = pAvoidPlayer->GetPlayerMaxs(); flZHeight = vecAvoidMax.z - vecAvoidMin.z; vecAvoidCenter.z += 0.5f * flZHeight; VectorAdd( vecAvoidMin, vecAvoidCenter, vecAvoidMin ); VectorAdd( vecAvoidMax, vecAvoidCenter, vecAvoidMax ); if ( IsBoxIntersectingBox( vecSDKPlayerMin, vecSDKPlayerMax, vecAvoidMin, vecAvoidMax ) ) { // Need to avoid this player. if ( !pIntersectPlayer ) { pIntersectPlayer = pAvoidPlayer; break; } } } // Anything to avoid? if ( !pIntersectPlayer ) return; // Calculate the push strength and direction. Vector vecDelta; // Avoid a player - they have precedence. if ( pIntersectPlayer ) { VectorSubtract( pIntersectPlayer->WorldSpaceCenter(), vecSDKPlayerCenter, vecDelta ); Vector vRad = pIntersectPlayer->WorldAlignMaxs() - pIntersectPlayer->WorldAlignMins(); vRad.z = 0; flAvoidRadius = vRad.Length(); } float flPushStrength = RemapValClamped( vecDelta.Length(), flAvoidRadius, 0, 0, sdk_max_separation_force.GetInt() ); //flPushScale; //Msg( "PushScale = %f\n", flPushStrength ); // Check to see if we have enough push strength to make a difference. if ( flPushStrength < 0.01f ) return; Vector vecPush; if ( GetAbsVelocity().Length2DSqr() > 0.1f ) { Vector vecVelocity = GetAbsVelocity(); vecVelocity.z = 0.0f; CrossProduct( vecUp, vecVelocity, vecPush ); VectorNormalize( vecPush ); } else { // We are not moving, but we're still intersecting. QAngle angView = pCmd->viewangles; angView.x = 0.0f; AngleVectors( angView, NULL, &vecPush, NULL ); } // Move away from the other player/object. Vector vecSeparationVelocity; if ( vecDelta.Dot( vecPush ) < 0 ) { vecSeparationVelocity = vecPush * flPushStrength; } else { vecSeparationVelocity = vecPush * -flPushStrength; } // Don't allow the max push speed to be greater than the max player speed. float flMaxPlayerSpeed = MaxSpeed(); float flCropFraction = 1.33333333f; //if ( ( GetFlags() & FL_DUCKING ) && ( GetGroundEntity() != NULL ) ) //{ // flMaxPlayerSpeed *= flCropFraction; //} float flMaxPlayerSpeedSqr = flMaxPlayerSpeed * flMaxPlayerSpeed; if ( vecSeparationVelocity.LengthSqr() > flMaxPlayerSpeedSqr ) { vecSeparationVelocity.NormalizeInPlace(); VectorScale( vecSeparationVelocity, flMaxPlayerSpeed, vecSeparationVelocity ); } QAngle vAngles = pCmd->viewangles; vAngles.x = 0; Vector currentdir; Vector rightdir; AngleVectors( vAngles, ¤tdir, &rightdir, NULL ); Vector vDirection = vecSeparationVelocity; VectorNormalize( vDirection ); float fwd = currentdir.Dot( vDirection ); float rt = rightdir.Dot( vDirection ); float forward = fwd * flPushStrength; float side = rt * flPushStrength; //Msg( "fwd: %f - rt: %f - forward: %f - side: %f\n", fwd, rt, forward, side ); pCmd->forwardmove += forward; pCmd->sidemove += side; // Clamp the move to within legal limits, preserving direction. This is a little // complicated because we have different limits for forward, back, and side //Msg( "PRECLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove ); float flForwardScale = 1.0f; if ( pCmd->forwardmove > fabs( cl_forwardspeed.GetFloat() ) ) { flForwardScale = fabs( cl_forwardspeed.GetFloat() ) / pCmd->forwardmove; } else if ( pCmd->forwardmove < -fabs( cl_backspeed.GetFloat() ) ) { flForwardScale = fabs( cl_backspeed.GetFloat() ) / fabs( pCmd->forwardmove ); } float flSideScale = 1.0f; if ( fabs( pCmd->sidemove ) > fabs( cl_sidespeed.GetFloat() ) ) { flSideScale = fabs( cl_sidespeed.GetFloat() ) / fabs( pCmd->sidemove ); } float flScale = min( flForwardScale, flSideScale ); pCmd->forwardmove *= flScale; pCmd->sidemove *= flScale; //Msg( "Pforwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove ); }
void C_SDKRagdoll::ClientThink( void ) { SetNextClientThink( CLIENT_THINK_ALWAYS ); if ( m_bFadingOut == true ) { int iAlpha = GetRenderColor().a; int iFadeSpeed = 600.0f; iAlpha = max( iAlpha - ( iFadeSpeed * gpGlobals->frametime ), 0 ); SetRenderMode( kRenderTransAlpha ); SetRenderColorA( iAlpha ); if ( iAlpha == 0 ) { Release(); } return; } for( int iClient = 1; iClient <= gpGlobals->maxClients; ++iClient ) { C_SDKPlayer *pEnt = static_cast< C_SDKPlayer *> ( UTIL_PlayerByIndex( iClient ) ); if(!pEnt || !pEnt->IsPlayer()) continue; if ( m_hPlayer == NULL ) continue; if ( pEnt->entindex() == m_hPlayer->entindex() ) continue; if ( pEnt->GetHealth() <= 0 ) continue; #if defined ( SDK_USE_PRONE ) if ( pEnt->m_Shared.IsProne() == false ) continue; #endif Vector vTargetOrigin = pEnt->GetAbsOrigin(); Vector vMyOrigin = GetAbsOrigin(); Vector vDir = vTargetOrigin - vMyOrigin; if ( vDir.Length() > cl_ragdoll_pronecheck_distance.GetInt() ) continue; SetNextClientThink( CLIENT_THINK_ALWAYS ); m_bFadingOut = true; return; } //Tony; this is kind of silly, because.. whats the point of fading out? // if the player is looking at us, delay the fade if ( IsRagdollVisible() ) { StartFadeOut( 5.0 ); return; } if ( m_fDeathTime > gpGlobals->curtime ) return; Release(); // Die }
int CBaseGrenadeProjectile::DrawModel( int flags ) { // During the first half-second of our life, don't draw ourselves if he's // still playing his throw animation. // (better yet, we could draw ourselves in his hand). if ( GetThrower() != C_BasePlayer::GetLocalPlayer() ) { if ( gpGlobals->curtime - m_flSpawnTime < 0.5 ) { //Tony; FIXME! // C_SDKPlayer *pPlayer = dynamic_cast<C_SDKPlayer*>( GetThrower() ); // if ( pPlayer && pPlayer->m_PlayerAnimState->IsThrowingGrenade() ) // { // return 0; // } } } if (!g_hGrenadeArrow.IsValid()) g_hGrenadeArrow.Init( "particle/grenadearrow.vmt", TEXTURE_GROUP_OTHER ); int iReturn = BaseClass::DrawModel(flags); C_SDKPlayer* pLocalPlayer = C_SDKPlayer::GetLocalSDKPlayer(); if (!pLocalPlayer) return iReturn; if (pLocalPlayer == GetThrower()) return iReturn; float flAppearDistance = 500; float flAppearDistanceSqr = flAppearDistance*flAppearDistance; if ((pLocalPlayer->GetAbsOrigin() - GetAbsOrigin()).LengthSqr() < flAppearDistanceSqr) m_flArrowGoalSize = 20; else m_flArrowGoalSize = 0; float flTime = C_SDKPlayer::GetLocalSDKPlayer()->GetCurrentTime() + m_flArrowSpinOffset; float flFrameTime = gpGlobals->frametime * C_SDKPlayer::GetLocalSDKPlayer()->GetSlowMoMultiplier(); m_flArrowCurSize = Approach(m_flArrowGoalSize, m_flArrowCurSize, flFrameTime*100); if (m_flArrowCurSize == 0) return iReturn; Vector vecViewForward, vecViewRight, vecViewUp; pLocalPlayer->EyeVectors(&vecViewForward, &vecViewRight, &vecViewUp); float flSin = sin(flTime*4); float flCos = cos(flTime*4); Vector vecOrigin = GetAbsOrigin(); Vector vecRight = vecViewRight * flSin + vecViewUp * flCos; Vector vecUp = vecViewRight * -flCos + vecViewUp * flSin; float flSize = m_flArrowCurSize; CMeshBuilder meshBuilder; CMatRenderContextPtr pRenderContext( materials ); IMesh* pMesh = pRenderContext->GetDynamicMesh(); pRenderContext->Bind( g_hGrenadeArrow ); meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); meshBuilder.Color4f( 1, 1, 1, 1 ); meshBuilder.TexCoord2f( 0,0, 0 ); meshBuilder.Position3fv( (vecOrigin + (vecRight * -flSize) + (vecUp * flSize)).Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Color4f( 1, 1, 1, 1 ); meshBuilder.TexCoord2f( 0,1, 0 ); meshBuilder.Position3fv( (vecOrigin + (vecRight * flSize) + (vecUp * flSize)).Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Color4f( 1, 1, 1, 1 ); meshBuilder.TexCoord2f( 0,1, 1 ); meshBuilder.Position3fv( (vecOrigin + (vecRight * flSize) + (vecUp * -flSize)).Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Color4f( 1, 1, 1, 1 ); meshBuilder.TexCoord2f( 0,0, 1 ); meshBuilder.Position3fv( (vecOrigin + (vecRight * -flSize) + (vecUp * -flSize)).Base() ); meshBuilder.AdvanceVertex(); meshBuilder.End(false, true); return iReturn; }