Example #1
0
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 );
			}
		}
	}
}