void FoundryHelpers_DrawEntityHighlightEffect( C_BaseEntity *pEnt )
{
	CCollisionProperty *pCollision = pEnt->CollisionProp();

	// Transform the OBB corners into world space.
	const Vector &vMins = pCollision->OBBMins();
	const Vector &vMaxs = pCollision->OBBMaxs();
	Vector vPoints[8] = 
	{
		Vector( vMins.x, vMins.y, vMins.z ),
		Vector( vMaxs.x, vMins.y, vMins.z ),
		Vector( vMaxs.x, vMaxs.y, vMins.z ),
		Vector( vMins.x, vMaxs.y, vMins.z ),
		
		Vector( vMins.x, vMins.y, vMaxs.z ),
		Vector( vMaxs.x, vMins.y, vMaxs.z ),
		Vector( vMaxs.x, vMaxs.y, vMaxs.z ),
		Vector( vMins.x, vMaxs.y, vMaxs.z )
	};

	for ( int i=0; i < 8; i++ )
	{
		Vector vTmp;
		vPoints[i] = pCollision->CollisionToWorldSpace( vPoints[i], &vTmp );
	}

	// Draw lines connecting them up...
	for ( int i=0; i < 4; i++ )
	{
		AddCoolLine( vPoints[i], vPoints[(i+1)%4], 0, false );
		AddCoolLine( vPoints[i+4], vPoints[(i+1)%4 + 4], 4, true );
		AddCoolLine( vPoints[i], vPoints[i+4], i*2+4, (i%1) == 0 );
	}
}
示例#2
0
static bool IsSmall( CBaseEntity *pBlocker )
{
	CCollisionProperty *pCollisionProp = pBlocker->CollisionProp();
	int  nSmaller = 0;
	Vector vecSize = pCollisionProp->OBBMaxs() - pCollisionProp->OBBMins();
	for ( int i = 0; i < 3; i++ )
	{
		if ( vecSize[i] >= 42 )
			return false;

		if ( vecSize[i] <= 30 )
		{
			nSmaller++;
		}
	}

	return ( nSmaller >= 2 );
}
示例#3
0
//-----------------------------------------------------------------------------
// Purpose: Breaks the breakable. m_hBreaker is the entity that caused us to break.
//-----------------------------------------------------------------------------
void CBreakable::Die( void )
{
	Vector vecVelocity;// shard velocity
	char cFlag = 0;
	int pitch;
	float fvol;
	
	pitch = 95 + random->RandomInt(0,29);

	if (pitch > 97 && pitch < 103)
	{
		pitch = 100;
	}

	// The more negative m_iHealth, the louder
	// the sound should be.

	fvol = random->RandomFloat(0.85, 1.0) + (abs(m_iHealth) / 100.0);
	if (fvol > 1.0)
	{
		fvol = 1.0;
	}

	const char *soundname = NULL;

	switch (m_Material)
	{
	default:
		break;

	case matGlass:
		soundname = "Breakable.Glass";
		cFlag = BREAK_GLASS;
		break;

	case matWood:
		soundname = "Breakable.Crate";
		cFlag = BREAK_WOOD;
		break;

	case matComputer:
		soundname = "Breakable.Computer";
		cFlag = BREAK_METAL;
		break;

	case matMetal:
		soundname = "Breakable.Metal";
		cFlag = BREAK_METAL;
		break;

	case matFlesh:
	case matWeb:
		soundname = "Breakable.Flesh";
		cFlag = BREAK_FLESH;
		break;

	case matRocks:
	case matCinderBlock:
		soundname = "Breakable.Concrete";
		cFlag = BREAK_CONCRETE;
		break;

	case matCeilingTile:
		soundname = "Breakable.Ceiling";
		break;
	}

	if ( soundname )
	{
		if ( m_hBreaker && m_hBreaker->IsPlayer() )
		{
			IGameEvent * event = gameeventmanager->CreateEvent( "break_breakable" );
			if ( event )
			{
				event->SetInt( "userid", ToBasePlayer( m_hBreaker )->GetUserID() );
				event->SetInt( "entindex", entindex() );
				event->SetInt( "material", cFlag );
				gameeventmanager->FireEvent( event );
			}
		}

		CSoundParameters params;
		if ( GetParametersForSound( soundname, params, NULL ) )
		{
			CPASAttenuationFilter filter( this );

			EmitSound_t ep;
			ep.m_nChannel = params.channel;
			ep.m_pSoundName = params.soundname;
			ep.m_flVolume = fvol;
			ep.m_SoundLevel = params.soundlevel;
			ep.m_nPitch = pitch;

			EmitSound( filter, entindex(), ep );	
		}
	}
		
	switch( m_Explosion )
	{
	case expDirected:
		vecVelocity = g_vecAttackDir * -200;
		break;

	case expUsePrecise:
		{
			AngleVectors( m_GibDir, &vecVelocity, NULL, NULL );
			vecVelocity *= 200;
		}
		break;

	case expRandom:
		vecVelocity.x = 0;
		vecVelocity.y = 0;
		vecVelocity.z = 0;
		break;

	default:
		DevMsg("**ERROR - Unspecified gib dir method in func_breakable!\n");
		break;
	}

	Vector vecSpot = WorldSpaceCenter();
	CPVSFilter filter2( vecSpot );

	int iModelIndex = 0;
	CCollisionProperty *pCollisionProp = CollisionProp();

	Vector vSize = pCollisionProp->OBBSize();
	int iCount = ( vSize[0] * vSize[1] + vSize[1] * vSize[2] + vSize[2] * vSize[0] ) / ( 3 * 12 * 12 );

	if ( iCount > func_break_max_pieces.GetInt() )
	{
		iCount = func_break_max_pieces.GetInt();
	}

	ConVarRef breakable_disable_gib_limit( "breakable_disable_gib_limit" );
	if ( !breakable_disable_gib_limit.GetBool() && iCount )
	{
		if ( m_PerformanceMode == PM_NO_GIBS )
		{
			iCount = 0;
		}
		else if ( m_PerformanceMode == PM_REDUCED_GIBS )
		{
			int iNewCount = iCount * func_break_reduction_factor.GetFloat();
			iCount = MAX( iNewCount, 1 );
		}
	}

	if ( m_iszModelName != NULL_STRING )
	{
		for ( int i = 0; i < iCount; i++ )
		{

	#ifdef HL1_DLL
			// Use the passed model instead of the propdata type
			const char *modelName = STRING( m_iszModelName );
			
			// if the map specifies a model by name
			if( strstr( modelName, ".mdl" ) != NULL )
			{
				iModelIndex = modelinfo->GetModelIndex( modelName );
			}
			else	// do the hl2 / normal way
	#endif

			iModelIndex = modelinfo->GetModelIndex( g_PropDataSystem.GetRandomChunkModel(  STRING( m_iszModelName ) ) );

			// All objects except the first one in this run are marked as slaves...
			int slaveFlag = 0;
			if ( i != 0 )
			{
				slaveFlag = BREAK_SLAVE;
			}

			te->BreakModel( filter2, 0.0, 
				vecSpot, pCollisionProp->GetCollisionAngles(), vSize, 
				vecVelocity, iModelIndex, 100, 1, 2.5, cFlag | slaveFlag );
		}
	}

	ResetOnGroundFlags();

	// Don't fire something that could fire myself
	SetName( NULL_STRING );

	AddSolidFlags( FSOLID_NOT_SOLID );
	
	// Fire targets on break
	m_OnBreak.FireOutput( m_hBreaker, this );

	VPhysicsDestroyObject();
	SetThink( &CBreakable::SUB_Remove );
	SetNextThink( gpGlobals->curtime + 0.1f );
	if ( m_iszSpawnObject != NULL_STRING )
	{
		CBaseEntity::Create( STRING(m_iszSpawnObject), vecSpot, pCollisionProp->GetCollisionAngles(), this );
	}

	if ( Explodable() )
	{
		ExplosionCreate( vecSpot, pCollisionProp->GetCollisionAngles(), this, GetExplosiveDamage(), GetExplosiveRadius(), true );
	}
}
示例#4
0
static void RecvProxy_OBBMaxs( const CRecvProxyData *pData, void *pStruct, void *pOut )
{
	CCollisionProperty *pProp = ((CCollisionProperty*)pStruct);
	Vector &vecMaxs = *((Vector*)pData->m_Value.m_Vector);
	pProp->SetCollisionBounds( pProp->OBBMins(), vecMaxs );
}
IterationRetval_t CPortalCollideableEnumerator::EnumElement( IHandleEntity *pHandleEntity )
{
	EHANDLE hEnt = pHandleEntity->GetRefEHandle();
	
	CBaseEntity *pEnt = hEnt.Get();
	if( pEnt == NULL ) //I really never thought this would be necessary
		return ITERATION_CONTINUE;
	
	if( hEnt == m_hTestPortal )
		return ITERATION_CONTINUE; //ignore this portal

	/*if( staticpropmgr->IsStaticProp( pHandleEntity ) )
	{
		//we're dealing with a static prop, which unfortunately doesn't have everything I want to use for checking
		
		ICollideable *pCollideable = pEnt->GetCollideable();

		Vector vMins, vMaxs;
		pCollideable->WorldSpaceSurroundingBounds( &vMins, &vMaxs );

		Vector ptTest( (m_vPlaneNormal.x > 0.0f)?(vMaxs.x):(vMins.x),
						(m_vPlaneNormal.y > 0.0f)?(vMaxs.y):(vMins.y),
						(m_vPlaneNormal.z > 0.0f)?(vMaxs.z):(vMins.z) );
	
		float fPtPlaneDist = m_vPlaneNormal.Dot( ptTest ) - m_fPlaneDist;
		if( fPtPlaneDist <= 0.0f )
			return ITERATION_CONTINUE;
	}
	else*/
	{
		//not a static prop, w00t
		CCollisionProperty *pEntityCollision = pEnt->CollisionProp();

		if( !pEntityCollision->IsSolid() )
			return ITERATION_CONTINUE; //not solid

		Vector ptEntCenter = pEntityCollision->WorldSpaceCenter();

		float fBoundRadius = pEntityCollision->BoundingRadius();
		float fPtPlaneDist = m_vPlaneNormal.Dot( ptEntCenter ) - m_fPlaneDist;

		if( fPtPlaneDist < -fBoundRadius )
			return ITERATION_CONTINUE; //object wholly behind the portal

		if( !(fPtPlaneDist > fBoundRadius) && (fPtPlaneDist > -fBoundRadius) ) //object is not wholly in front of the portal, but could be partially in front, do more checks
		{
			Vector ptNearest;
			pEntityCollision->CalcNearestPoint( m_ptForward1000, &ptNearest );
			fPtPlaneDist = m_vPlaneNormal.Dot( ptNearest ) - m_fPlaneDist;
			if( fPtPlaneDist < 0.0f )
				return ITERATION_CONTINUE; //closest point was behind the portal plane, we don't want it
		}


	}

	//if we're down here, this entity needs to be added to our enumeration
	Assert( m_iHandleCount < 1024 );
	if( m_iHandleCount < 1024 ) 
		m_pHandles[m_iHandleCount] = pHandleEntity;
	++m_iHandleCount;

	return ITERATION_CONTINUE;
}