Esempio n. 1
0
//
// Sticky gib puts blood on the wall and stays put. 
//
void CGib::StickyGibTouch ( CBaseEntity *pOther )
{
	Vector	vecSpot;
	trace_t tr;
	
	SetThink ( &CGib::SUB_Remove );
	SetNextThink( gpGlobals->curtime + 10 );

	if ( !FClassnameIs( pOther, "worldspawn" ) )
	{
		SetNextThink( gpGlobals->curtime );
		return;
	}

	UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + GetAbsVelocity() * 32,  MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);

	UTIL_BloodDecalTrace( &tr, m_bloodColor );

	Vector vecForward = tr.plane.normal * -1;
	QAngle angles;
	VectorAngles( vecForward, angles );
	SetLocalAngles( angles );
	SetAbsVelocity( vec3_origin ); 
	SetLocalAngularVelocity( vec3_angle );
	SetMoveType( MOVETYPE_NONE );
}
Esempio n. 2
0
void CCineBlood :: BloodGush ( void )
{
    Vector	vecSplatDir;
    TraceResult	tr;
    pev->nextthink = gpGlobals->time + 0.1;

    UTIL_MakeVectors(pev->angles);
    if ( pev->health-- < 0 )
        REMOVE_ENTITY(ENT(pev));
// CHANGE_METHOD ( ENT(pev), em_think, SUB_Remove );

    if ( RANDOM_FLOAT ( 0 , 1 ) < 0.7 )// larger chance of globs
    {
        UTIL_BloodDrips( pev->origin, UTIL_RandomBloodVector(), BLOOD_COLOR_RED, 10 );
    }
    else// slim chance of geyser
    {
        UTIL_BloodStream( pev->origin, UTIL_RandomBloodVector(), BLOOD_COLOR_RED, RANDOM_LONG(50, 150) );
    }

    if ( RANDOM_FLOAT ( 0, 1 ) < 0.75 )
    {   // decals the floor with blood.
        vecSplatDir = Vector ( 0 , 0 , -1 );
        vecSplatDir = vecSplatDir + (RANDOM_FLOAT(-1,1) * 0.6 * gpGlobals->v_right) + (RANDOM_FLOAT(-1,1) * 0.6 * gpGlobals->v_forward);// randomize a bit
        UTIL_TraceLine( pev->origin + Vector ( 0, 0 , 64) , pev->origin + vecSplatDir * 256, ignore_monsters, ENT(pev), &tr);
        if ( tr.flFraction != 1.0 )
        {
            // Decal with a bloodsplat
            UTIL_BloodDecalTrace( &tr, BLOOD_COLOR_RED );
        }
    }
}
Esempio n. 3
0
// Sticky gib puts blood on the wall and stays put.
void CGib::StickyGibTouch(CBaseEntity *pOther)
{
	Vector vecSpot;
	TraceResult tr;

	SetThink(&CBaseEntity::SUB_Remove);
	pev->nextthink = gpGlobals->time + 10;

	if (!FClassnameIs(pOther->pev, "worldspawn"))
	{
		pev->nextthink = gpGlobals->time;
		return;
	}

	vecSpot = pev->origin + pev->velocity * 32;

	UTIL_TraceLine(pev->origin, vecSpot, ignore_monsters, ENT(pev), &tr);
	UTIL_BloodDecalTrace(&tr, m_bloodColor);

	pev->velocity = tr.vecPlaneNormal * -1;
	pev->angles = UTIL_VecToAngles(pev->velocity);
	pev->velocity = g_vecZero;
	pev->avelocity = g_vecZero;
	pev->movetype = MOVETYPE_NONE;
}
Esempio n. 4
0
void CGib::BounceGibTouch(CBaseEntity *pOther)
{
	if (pev->flags & FL_ONGROUND)
	{
		pev->velocity = pev->velocity * 0.9;
		pev->angles.x = 0;
		pev->angles.z = 0;
		pev->avelocity.x = 0;
		pev->avelocity.z = 0;
	}
	else
	{
		if (g_Language != LANGUAGE_GERMAN && m_cBloodDecals > 0 && m_bloodColor != DONT_BLEED)
		{
			TraceResult tr;
			Vector vecSpot = pev->origin + Vector(0, 0, 8);
			UTIL_TraceLine(vecSpot, vecSpot + Vector(0, 0, -24), ignore_monsters, ENT(pev), &tr);
			UTIL_BloodDecalTrace(&tr, m_bloodColor);
			m_cBloodDecals--;
		}

		if (m_material != matNone && !RANDOM_LONG(0, 2))
		{
			float zvel = Q_fabs(pev->velocity.z);
			float volume = 0.8 * Q_min(1.0f, zvel / 450);

			CBreakable::MaterialSoundRandom(edict(), (Materials)m_material, volume);
		}
	}
}
Esempio n. 5
0
NOXREF void CBaseMonster::MakeDamageBloodDecal(int cCount, float flNoise, TraceResult *ptr, Vector &vecDir)
{
	// make blood decal on the wall!
	TraceResult Bloodtr;
	Vector vecTraceDir;
	int i;

	if (!IsAlive())
	{
		// dealing with a dead monster.
		if (pev->max_health <= 0)
		{
			// no blood decal for a monster that has already decalled its limit.
			return;
		}
		else
			pev->max_health--;
	}

	for (i = 0; i < cCount; ++i)
	{
		vecTraceDir = vecDir;

		vecTraceDir.x += RANDOM_FLOAT(-flNoise, flNoise);
		vecTraceDir.y += RANDOM_FLOAT(-flNoise, flNoise);
		vecTraceDir.z += RANDOM_FLOAT(-flNoise, flNoise);

		UTIL_TraceLine(ptr->vecEndPos, ptr->vecEndPos + vecTraceDir * 172, ignore_monsters, ENT(pev), &Bloodtr);

		if (Bloodtr.flFraction != 1.0f)
		{
			UTIL_BloodDecalTrace(&Bloodtr, BloodColor());
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pOther - 
//-----------------------------------------------------------------------------
void C_PhysPropClientside::HitSurface( C_BaseEntity *pOther )
{
	if ( HasInteraction( PROPINTER_WORLD_BLOODSPLAT ) )
	{
		trace_t	tr;
		tr = BaseClass::GetTouchTrace();
		if ( tr.m_pEnt )
		{
			UTIL_BloodDecalTrace( &tr, BLOOD_COLOR_RED );
		}
	}
}
Esempio n. 7
0
void CBaseEntity::__MAKE_VHOOK(TraceBleed)(float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType)
{
	if (BloodColor() == DONT_BLEED)
		return;

	if (!flDamage)
		return;

	if (!(bitsDamageType & (DMG_CRUSH | DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB | DMG_MORTAR)))
		return;

	// make blood decal on the wall!
	TraceResult Bloodtr;
	Vector vecTraceDir;
	float flNoise;
	int cCount;
	int i;

	if (flDamage < 10.0f)
	{
		flNoise = 0.1f;
		cCount = 1;
	}
	else if (flDamage < 25.0f)
	{
		flNoise = 0.2f;
		cCount = 2;
	}
	else
	{
		flNoise = 0.3f;
		cCount = 4;
	}

	for (i = 0; i < cCount; ++i)
	{
		// trace in the opposite direction the shot came from (the direction the shot is going)
		vecTraceDir = vecDir * -1.0f;

		vecTraceDir.x += RANDOM_FLOAT(-flNoise, flNoise);
		vecTraceDir.y += RANDOM_FLOAT(-flNoise, flNoise);
		vecTraceDir.z += RANDOM_FLOAT(-flNoise, flNoise);

		UTIL_TraceLine(ptr->vecEndPos, ptr->vecEndPos + vecTraceDir * -172.0f, ignore_monsters, ENT(pev), &Bloodtr);
		if (Bloodtr.flFraction != 1.0f)
		{
			if (!RANDOM_LONG(0, 2))
			{
				UTIL_BloodDecalTrace(&Bloodtr, BloodColor());
			}
		}
	}
}
Esempio n. 8
0
//=========================================================
//=========================================================
void CBaseMonster :: MakeDamageBloodDecal ( int cCount, float flNoise, TraceResult *ptr, const Vector &vecDir )
{
	// make blood decal on the wall! 
	TraceResult Bloodtr;
	Vector vecTraceDir; 
	int i;

	if ( !IsAlive() )
	{
		// dealing with a dead monster. 
		if ( pev->max_health <= 0 )
		{
			// no blood decal for a monster that has already decalled its limit.
			return; 
		}
		else
		{
			pev->max_health--;
		}
	}

	for ( i = 0 ; i < cCount ; i++ )
	{
		vecTraceDir = vecDir;

		vecTraceDir.x += RANDOM_FLOAT( -flNoise, flNoise );
		vecTraceDir.y += RANDOM_FLOAT( -flNoise, flNoise );
		vecTraceDir.z += RANDOM_FLOAT( -flNoise, flNoise );

		UTIL_TraceLine( ptr->vecEndPos, ptr->vecEndPos + vecTraceDir * 172, ignore_monsters, ENT(pev), &Bloodtr);

/*
		MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
			WRITE_BYTE( TE_SHOWLINE);
			WRITE_COORD( ptr->vecEndPos.x );
			WRITE_COORD( ptr->vecEndPos.y );
			WRITE_COORD( ptr->vecEndPos.z );
			
			WRITE_COORD( Bloodtr.vecEndPos.x );
			WRITE_COORD( Bloodtr.vecEndPos.y );
			WRITE_COORD( Bloodtr.vecEndPos.z );
		MESSAGE_END();
*/

		if ( Bloodtr.flFraction != 1.0 )
		{
			UTIL_BloodDecalTrace( &Bloodtr, BloodColor() );
		}
	}
}
//
// Gib bounces on the ground or wall, sponges some blood down, too!
//
void CGib::BounceGibTouch ( CBaseEntity *pOther )
{
	Vector	vecSpot;
	trace_t	tr;
	
	IPhysicsObject *pPhysics = VPhysicsGetObject();

	if ( pPhysics )
		 return;
	
	//if ( random->RandomInt(0,1) )
	//	return;// don't bleed everytime
	if (GetFlags() & FL_ONGROUND)
	{
		SetAbsVelocity( GetAbsVelocity() * 0.9 );
		QAngle angles = GetLocalAngles();
		angles.x = 0;
		angles.z = 0;
		SetLocalAngles( angles );

		QAngle angVel = GetLocalAngularVelocity();
		angVel.x = 0;
		angVel.z = 0;
		SetLocalAngularVelocity( vec3_angle );
	}
	else
	{
		//City17: Germany Violence Fix.
		if ( /*g_Language.GetInt() != LANGUAGE_GERMAN &&*/ m_cBloodDecals > 0 && m_bloodColor != DONT_BLEED )
		{
			vecSpot = GetAbsOrigin() + Vector ( 0 , 0 , 8 );//move up a bit, and trace down.
			UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -24 ),  MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);

			UTIL_BloodDecalTrace( &tr, m_bloodColor );

			m_cBloodDecals--; 
		}

		if ( m_material != matNone && random->RandomInt(0,2) == 0 )
		{
			float volume;
			float zvel = fabs(GetAbsVelocity().z);
		
			volume = 0.8f * min(1.0, ((float)zvel) / 450.0f);

			CBreakable::MaterialSoundRandom( entindex(), (Materials)m_material, volume );
		}
	}
}
Esempio n. 10
0
void CBlood::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
	if ( pev->spawnflags & SF_BLOOD_STREAM )
		UTIL_BloodStream( BloodPosition(pActivator), Direction(), Color(), BloodAmount() );
	else
		UTIL_BloodDrips( BloodPosition(pActivator), Direction(), Color(), BloodAmount() );

	if ( pev->spawnflags & SF_BLOOD_DECAL )
	{
		Vector forward = Direction();
		Vector start = BloodPosition( pActivator );
		TraceResult tr;

		UTIL_TraceLine( start, start + forward * BloodAmount() * 2, ignore_monsters, NULL, &tr );
		if ( tr.flFraction != 1.0 )
			UTIL_BloodDecalTrace( &tr, Color() );
	}
}
Esempio n. 11
0
//
// Gib bounces on the ground or wall, sponges some blood down, too!
//
void CGib :: BounceGibTouch ( CBaseEntity *pOther )
{
	Vector	vecSpot;
	TraceResult	tr;
	
	//if ( RANDOM_LONG(0,1) )
	//	return;// don't bleed everytime

	if (pev->flags & FL_ONGROUND)
	{
		pev->velocity = pev->velocity * 0.9;
		pev->angles.x = 0;
		pev->angles.z = 0;
		pev->avelocity.x = 0;
		pev->avelocity.z = 0;
	}
	else
	{
		if ( g_Language != LANGUAGE_GERMAN && m_cBloodDecals > 0 && m_bloodColor != DONT_BLEED )
		{
			vecSpot = pev->origin + Vector ( 0 , 0 , 8 );//move up a bit, and trace down.
			UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -24 ),  ignore_monsters, ENT(pev), & tr);

			UTIL_BloodDecalTrace( &tr, m_bloodColor );

			m_cBloodDecals--; 
		}

		if ( m_material != matNone && RANDOM_LONG(0,2) == 0 )
		{
			float volume;
			float zvel = fabs(pev->velocity.z);
		
			volume = 0.8 * min(1.0, ((float)zvel) / 450.0);

			CBreakable::MaterialSoundRandom( edict(), (Materials)m_material, volume );
		}
	}
}
Esempio n. 12
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CAntlionGrub::MakeSquashDecals( const Vector &vecOrigin )
{
	trace_t tr;
	Vector	vecStart;
	Vector	vecTraceDir;

	GetVectors( NULL, NULL, &vecTraceDir );
	vecTraceDir.Negate();

	for ( int i = 0 ; i < 8; i++ )
	{
		vecStart.x = vecOrigin.x + random->RandomFloat( -16.0f, 16.0f );
		vecStart.y = vecOrigin.y + random->RandomFloat( -16.0f, 16.0f );
		vecStart.z = vecOrigin.z + 4;

		UTIL_TraceLine( vecStart, vecStart + ( vecTraceDir * (5*12) ), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );

		if ( tr.fraction != 1.0 )
		{
			UTIL_BloodDecalTrace( &tr, BLOOD_COLOR_YELLOW );
		}
	}
}
Esempio n. 13
0
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CRagdollProp::HandleFirstCollisionInteractions( int index, gamevcollisionevent_t *pEvent )
{
	IPhysicsObject *pObj = VPhysicsGetObject();
	if ( !pObj)
		return;

	if( HasPhysgunInteraction( "onfirstimpact", "break" ) )
	{
		// Looks like it's best to break by having the object damage itself. 
		CTakeDamageInfo info;

		info.SetDamage( m_iHealth );
		info.SetAttacker( this );
		info.SetInflictor( this );
		info.SetDamageType( DMG_GENERIC );

		Vector vecPosition;
		Vector vecVelocity;

		VPhysicsGetObject()->GetVelocity( &vecVelocity, NULL );
		VPhysicsGetObject()->GetPosition( &vecPosition, NULL );

		info.SetDamageForce( vecVelocity );
		info.SetDamagePosition( vecPosition );

		TakeDamage( info );
		return;
	}

	if( HasPhysgunInteraction( "onfirstimpact", "paintsplat" ) )
	{
		IPhysicsObject *pObj = VPhysicsGetObject();
 
		Vector vecPos;
		pObj->GetPosition( &vecPos, NULL );
 
		trace_t tr;
		UTIL_TraceLine( vecPos, vecPos + pEvent->preVelocity[0] * 1.5, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );

		switch( random->RandomInt( 1, 3 ) )
		{
		case 1:
			UTIL_DecalTrace( &tr, "PaintSplatBlue" );
			break;

		case 2:
			UTIL_DecalTrace( &tr, "PaintSplatGreen" );
			break;

		case 3:
			UTIL_DecalTrace( &tr, "PaintSplatPink" );
			break;
		}
	}

	bool bAlienBloodSplat = HasPhysgunInteraction( "onfirstimpact", "alienbloodsplat" );
	if( bAlienBloodSplat || HasPhysgunInteraction( "onfirstimpact", "bloodsplat" ) )
	{
		IPhysicsObject *pObj = VPhysicsGetObject();
 
		Vector vecPos;
		pObj->GetPosition( &vecPos, NULL );
 
		trace_t tr;
		UTIL_TraceLine( vecPos, vecPos + pEvent->preVelocity[0] * 1.5, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );

		UTIL_BloodDecalTrace( &tr, bAlienBloodSplat ? BLOOD_COLOR_GREEN : BLOOD_COLOR_RED );
	}
}
Esempio n. 14
0
void CBaseEntity :: TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType )
{
	if (BloodColor() == DONT_BLEED)
		return;
	
	if (flDamage == 0)
		return;

	if (! (bitsDamageType & (DMG_CRUSH | DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB | DMG_MORTAR)))
		return;
	
	// make blood decal on the wall! 
	TraceResult Bloodtr;
	Vector vecTraceDir; 
	float flNoise;
	int cCount;
	int i;

/*
	if ( !IsAlive() )
	{
		// dealing with a dead monster. 
		if ( pev->max_health <= 0 )
		{
			// no blood decal for a monster that has already decalled its limit.
			return; 
		}
		else
		{
			pev->max_health--;
		}
	}
*/

	if (flDamage < 10)
	{
		flNoise = 0.1;
		cCount = 1;
	}
	else if (flDamage < 25)
	{
		flNoise = 0.2;
		cCount = 2;
	}
	else
	{
		flNoise = 0.3;
		cCount = 4;
	}

	for ( i = 0 ; i < cCount ; i++ )
	{
		vecTraceDir = vecDir * -1;// trace in the opposite direction the shot came from (the direction the shot is going)

		vecTraceDir.x += RANDOM_FLOAT( -flNoise, flNoise );
		vecTraceDir.y += RANDOM_FLOAT( -flNoise, flNoise );
		vecTraceDir.z += RANDOM_FLOAT( -flNoise, flNoise );

		UTIL_TraceLine( ptr->vecEndPos, ptr->vecEndPos + vecTraceDir * -172, ignore_monsters, ENT(pev), &Bloodtr);

		if ( Bloodtr.flFraction != 1.0 )
		{
			UTIL_BloodDecalTrace( &Bloodtr, BloodColor() );
		}
	}
}
void C_ClientPartialRagdoll::ImpactTrace( trace_t *pTrace, int iDamageType, const char *pCustomImpactName )
{
	BaseClass::ImpactTrace( pTrace, iDamageType, pCustomImpactName );

	// client entities have the network index -1 so lots of effects don't work easily
	if ( BloodColor() != DONT_BLEED )
	{
		const char *pszDecalName = NULL;

		switch ( BloodColor() )
		{
		case BLOOD_COLOR_RED:
			pszDecalName = "Blood";
			break;
		}

		int index = decalsystem->GetDecalIndexForName( pszDecalName );
		Vector vecDir = pTrace->endpos - pTrace->startpos;
		if ( vecDir.LengthSqr() > FLT_EPSILON )
		{
			vecDir.NormalizeInPlace();
		}

		if ( index >= 0 )
		{
			SetShrinkingEnabled( false );
			InvalidateBoneCache();
			SetupBones( NULL, -1, BONE_USED_BY_ANYTHING, gpGlobals->curtime );

			// add decal to model
			AddDecal( pTrace->startpos, pTrace->endpos, pTrace->endpos, pTrace->hitbox,
						index, false, *pTrace );

			SetShrinkingEnabled( true );
			InvalidateBoneCache();
		}

		// add decal to world
		trace_t tr;
		UTIL_TraceLine( pTrace->endpos, pTrace->endpos + vecDir * 35.0f, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );

		UTIL_BloodDecalTrace( &tr, BloodColor() );
		if ( ShouldCreateBloodParticles() )
		{
			UTIL_BloodImpact( pTrace->endpos, -vecDir, BloodColor(), 5 );
		}
	}

	if ( m_bReleaseRagdoll || m_bFadingOut )
		return;

	const float flGibbingChance = ( ( iDamageType & DMG_BLAST ) != 0 ) ?
		gstring_gibbing_explosion_chance.GetFloat() : gstring_gibbing_chance.GetFloat();
	const bool bSniperImpact = ( iDamageType & DMG_SNIPER ) != 0;

	if ( !bSniperImpact && RandomFloat() > flGibbingChance / 100.0f )
		return;

	CStudioHdr *pHdr = GetModelPtr();

	if ( pHdr == NULL )
		return;

	int iStudioBone = ConvertPhysBoneToStudioBone( this, pTrace->physicsbone );
	const bool bExplosionImpact = ( iDamageType & DMG_BLAST ) != 0;

	// if the hit bone is a valid studio bone and we know that this bone
	// is drawn as a normal bone (not shrunken)
	if ( iStudioBone >= 0
		&& m_normalBones.IsBitSet( iStudioBone )
		|| bExplosionImpact )
	{
		CUtlVector< ragdollparams_partial_t > gibModels;

		// we've been analysed already so use the known hit group
		// and try recusive splitting
		GibbingParamsRecursive_t params;
		params.pHdr = pHdr;
		params.pszHitBone = ( iStudioBone >= 0 && !bExplosionImpact ) ? pHdr->pBone( iStudioBone )->pszName() : NULL;
		params.pszParentName = STRING( m_strRecursiveParent );
		params.pszRootBone = ( m_iBranchRootBone >= 0 && m_iBranchRootBone < pHdr->numbones() )
			? pHdr->pBone( m_iBranchRootBone )->pszName() : NULL;
		params.pJointBones = &m_jointBones;

		const char *pszParentSplitBone;

		// find a suitable joint to cut
		if ( C_GibConfig::GetInstance()->GetGibsForGroup( params, gibModels, &pszParentSplitBone )
			|| bExplosionImpact && C_GibConfig::GetInstance()->GetRandomGibsForGroup( params, gibModels, &pszParentSplitBone ) )
		{
			int iSplitboneIndex = Studio_BoneIndexByName( pHdr, pszParentSplitBone );

			// don't do cutting if we cut this joint in the past
			// or if this joint is our current branch root
			if ( iSplitboneIndex < 0
				|| m_jointBones.IsBitSet( iSplitboneIndex )
				|| m_iBranchRootBone == iSplitboneIndex )
				return;

			matrix3x4_t boneDelta0[MAXSTUDIOBONES];
			matrix3x4_t boneDelta1[MAXSTUDIOBONES];
			matrix3x4_t currentBones[MAXSTUDIOBONES];
			const float boneDt = 0.1f;

			// setup bones without shrinking to position the new gibs
			SetShrinkingEnabled( false );
			GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt );
			SetShrinkingEnabled( true );

			InvalidateBoneCache();

			// create the new gibmodels
			FOR_EACH_VEC( gibModels, i )
			{
				ragdollparams_partial_t &partial = gibModels[ i ];

				// add old trunk joints
				for ( int iBit = m_jointBones.FindNextSetBit( 0 );
					iBit >= 0; iBit = m_jointBones.FindNextSetBit( iBit + 1 ) )
				{
					if ( m_iBranchRootBone == iBit )
						continue;

					const char *pszName = pHdr->pBone( iBit )->pszName();

					partial.trunkBones.AddToTail( pszName );
				}

				// if we create a trunk from an existing branch
				// we have to propagate the branch root bone
				if ( partial.rootBone.IsEmpty()
					&& m_iBranchRootBone >= 0 )
				{
					partial.rootBone = pHdr->pBone( m_iBranchRootBone )->pszName();
				}

				C_BaseAnimating *pGib = CreateRagdollCopy( false );
				C_ClientPartialRagdoll *pRecursiveRagdoll = dynamic_cast< C_ClientPartialRagdoll* >( pGib );
				Assert( pRecursiveRagdoll );

				// apply force and propagate cut information
				if ( pRecursiveRagdoll != NULL )
				{
					pRecursiveRagdoll->SetRecursiveGibData( STRING( m_strRecursiveParent ), STRING( m_strRecursiveGoreName ),
						STRING( m_strRecursiveGoreMaterialName ) );
					pRecursiveRagdoll->SetShrinkingEnabled( true );

					Vector vecDelta = pTrace->endpos - pTrace->startpos;
					if ( vecDelta.LengthSqr() <= FLT_EPSILON )
					{
						vecDelta = RandomVector( -1, 1 );
					}
					vecDelta.NormalizeInPlace();

					pRecursiveRagdoll->m_vecForce = vecDelta * RandomFloat( 15000.0f, 35000.0f );
					pRecursiveRagdoll->m_nForceBone = pTrace->physicsbone;

					pRecursiveRagdoll->SetBloodColor( BloodColor() );
					pRecursiveRagdoll->m_jointBones.Or( m_jointBones, &pRecursiveRagdoll->m_jointBones );

					//FOR_EACH_VEC( m_Gore, i )
					//{
					//	const int iBone = m_Gore[ i ].m_iBone;

					//	if ( iBone >= 0 && iBone == m_iBranchRootBone )
					//	{

					//	}
					//	pRecursiveRagdoll->m_Gore.AddToTail( m_Gore[ i ] );
					//	m_Gore.Remove( i );
					//	i--;
					//}
				}

				pGib->InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt, false, &partial );

				if ( bExplosionImpact
					&& RandomFloat() <= gstring_gibbing_explosion_recursive_chance.GetFloat() / 100.0f )
				{
					pGib->ImpactTrace( pTrace, iDamageType, pCustomImpactName );
				}

				if ( BloodColor() == BLOOD_COLOR_RED
					&& ( !pRecursiveRagdoll || !pRecursiveRagdoll->m_bReleaseRagdoll )
					&& ShouldCreateBloodParticles() )
				{
					Assert( pszParentSplitBone != NULL );

					DispatchGibParticle( pGib, pszParentSplitBone, bExplosionImpact, BloodColor() );
				}
			}
Esempio n. 16
0
void CASW_Alien::DoBloodDecal( float flDamage, const Vector &vecPos, const Vector &vecDir, trace_t *ptr, int bitsDamageType )
{
    if ( ( BloodColor() == DONT_BLEED) || ( BloodColor() == BLOOD_COLOR_MECH ) )
    {
        return;
    }

    if (flDamage == 0)
        return;

    if ( !( bitsDamageType & ( DMG_CRUSH | DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB | DMG_AIRBOAT ) ) )
        return;

    // make blood decal on the wall!
    trace_t Bloodtr;
    Vector vecTraceDir;
    float flNoise;
    int cCount;
    int i;

#ifdef GAME_DLL
    if ( !IsAlive() )
    {
        // dealing with a dead npc.
        if ( GetMaxHealth() <= 0 )
        {
            // no blood decal for a npc that has already decalled its limit.
            return;
        }
        else
        {
            m_iMaxHealth -= 1;
        }
    }
#endif

    if (flDamage < 10)
    {
        flNoise = 0.1;
        cCount = 1;
    }
    else if (flDamage < 25)
    {
        flNoise = 0.2;
        cCount = 2;
    }
    else
    {
        flNoise = 0.3;
        cCount = 4;
    }

    float flTraceDist = (bitsDamageType & DMG_AIRBOAT) ? 384 : 172;
    for ( i = 0 ; i < cCount ; i++ )
    {
        vecTraceDir = vecDir * -1;// trace in the opposite direction the shot came from (the direction the shot is going)

        vecTraceDir.x += random->RandomFloat( -flNoise, flNoise );
        vecTraceDir.y += random->RandomFloat( -flNoise, flNoise );
        vecTraceDir.z += random->RandomFloat( -flNoise, flNoise );

        // Don't bleed on grates.
        UTIL_TraceLine( vecPos, vecPos + vecTraceDir * -flTraceDist, MASK_SOLID_BRUSHONLY & ~CONTENTS_GRATE, this, COLLISION_GROUP_NONE, &Bloodtr);

        if ( Bloodtr.fraction != 1.0 )
        {
            UTIL_BloodDecalTrace( &Bloodtr, BloodColor() );
        }
    }
}
Esempio n. 17
0
static int luasrc_UTIL_BloodDecalTrace (lua_State *L) {
  UTIL_BloodDecalTrace(&luaL_checktrace(L, 1), luaL_checkint(L, 2));
  return 0;
}