void CBlobElement::ModifyVelocityForSurface( float flInterval, float flSpeed ) { trace_t tr; Vector vecStart = GetAbsOrigin(); Vector up = Vector( 0, 0, BLOB_TRACE_HEIGHT ); Vector vecWishedGoal = vecStart + (GetAbsVelocity() * flInterval); UTIL_TraceLine( vecStart + up, vecWishedGoal + up, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); //NDebugOverlay::Line( tr.startpos, tr.endpos, 255, 0, 0, false, 0.1f ); m_bOnWall = false; if( tr.fraction == 1.0f ) { UTIL_TraceLine( vecWishedGoal + up, vecWishedGoal - (up * 2.0f), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); //NDebugOverlay::Line( tr.startpos, tr.endpos, 255, 255, 0, false, 0.1f ); tr.endpos.z += MOVE_HEIGHT_EPSILON; } else { //NDebugOverlay::Cross3D( GetAbsOrigin(), 16, 255, 255, 0, false, 0.025f ); m_bOnWall = true; if( tr.m_pEnt != NULL && !tr.m_pEnt->IsWorld() ) { IPhysicsObject *pPhysics = tr.m_pEnt->VPhysicsGetObject(); if( pPhysics != NULL ) { Vector vecMassCenter; Vector vecMassCenterWorld; vecMassCenter = pPhysics->GetMassCenterLocalSpace(); pPhysics->LocalToWorld( &vecMassCenterWorld, vecMassCenter ); if( tr.endpos.z > vecMassCenterWorld.z ) { pPhysics->ApplyForceOffset( (-150.0f * m_flRandomEightyPercent) * tr.plane.normal, tr.endpos ); } } } } Vector vecDir = tr.endpos - vecStart; VectorNormalize( vecDir ); SetElementVelocity( vecDir * flSpeed, false ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFFreezePanel::UpdateCallout( void ) { CTFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !pPlayer ) return; // Abort early if we have no gibs or ragdoll CUtlVector<EHANDLE> *pGibList = pPlayer->GetSpawnedGibs(); IRagdoll *pRagdoll = pPlayer->GetRepresentativeRagdoll(); if ( (!pGibList || pGibList->Count() == 0) && !pRagdoll ) return; if ( m_pFreezePanelBG == NULL ) return; // Precalc the vectors of the freezepanel & statpanel int iX, iY; m_pFreezePanelBG->GetPos( iX, iY ); Vector vecFreezeTL( iX, iY, 0 ); Vector vecFreezeBR( iX + m_pFreezePanelBG->GetWide(), iY + m_pFreezePanelBG->GetTall(), 1 ); CUtlVector<Vector> vecCalloutsTL; CUtlVector<Vector> vecCalloutsBR; Vector vecStatTL(0,0,0); Vector vecStatBR(0,0,1); CTFStatPanel *pStatPanel = GET_HUDELEMENT( CTFStatPanel ); if ( pStatPanel && pStatPanel->IsVisible() ) { pStatPanel->GetPos( iX, iY ); vecStatTL.x = iX; vecStatTL.y = iY; vecStatBR.x = vecStatTL.x + pStatPanel->GetWide(); vecStatBR.y = vecStatTL.y + pStatPanel->GetTall(); } Vector vMins, vMaxs; // Check gibs if ( pGibList && pGibList->Count() ) { int iCount = 0; for ( int i = 0; i < pGibList->Count(); i++ ) { CBaseEntity *pGib = pGibList->Element(i); if ( pGib ) { Vector origin = pGib->GetRenderOrigin(); IPhysicsObject *pPhysicsObject = pGib->VPhysicsGetObject(); if( pPhysicsObject ) { Vector vecMassCenter = pPhysicsObject->GetMassCenterLocalSpace(); pGib->CollisionProp()->CollisionToWorldSpace( vecMassCenter, &origin ); } pGib->GetRenderBounds( vMins, vMaxs ); // Try and add the callout CTFFreezePanelCallout *pCallout = TestAndAddCallout( origin, vMins, vMaxs, &vecCalloutsTL, &vecCalloutsBR, vecFreezeTL, vecFreezeBR, vecStatTL, vecStatBR, &iX, &iY ); if ( pCallout ) { pCallout->UpdateForGib( i, iCount ); iCount++; } } } } else if ( pRagdoll ) { Vector origin = pRagdoll->GetRagdollOrigin(); pRagdoll->GetRagdollBounds( vMins, vMaxs ); // Try and add the callout CTFFreezePanelCallout *pCallout = TestAndAddCallout( origin, vMins, vMaxs, &vecCalloutsTL, &vecCalloutsBR, vecFreezeTL, vecFreezeBR, vecStatTL, vecStatBR, &iX, &iY ); if ( pCallout ) { pCallout->UpdateForRagdoll(); } // even if the callout failed, check that our ragdoll is onscreen and our killer is taunting us (for an achievement) if ( GetVectorInScreenSpace( origin, iX, iY ) ) { C_TFPlayer *pKiller = ToTFPlayer( UTIL_PlayerByIndex( GetSpectatorTarget() ) ); if ( pKiller && pKiller->m_Shared.InCond( TF_COND_TAUNTING ) ) { // tell the server our ragdoll just got taunted during our freezecam char cmd[256]; int iPlayerID = pPlayer->GetUserID(); unsigned short mask = UTIL_GetAchievementEventMask(); Q_snprintf( cmd, sizeof( cmd ), "freezecam_taunt %d %d", GetSpectatorTarget() ^ mask, ( iPlayerID ^ GetSpectatorTarget() ) ^ mask ); engine->ClientCmd_Unrestricted( cmd ); } } } }