Exemple #1
0
void MakeDecal(enum DECAL_ID decalID, VECTORCH *normalPtr, VECTORCH *positionPtr, int moduleIndex)
{
    if (TooManyDecalsOfThisType(decalID,positionPtr)) return;
    AddDecal(decalID,normalPtr,positionPtr,moduleIndex);

    /* no blood across network? */
    if(AvP.Network!=I_No_Network)
    {
        if(netGameData.sendDecals)
        {
            switch (decalID)
            {
            case DECAL_BULLETHOLE:
            case DECAL_SCORCHED:
            {
                AddNetMsg_MakeDecal(decalID,normalPtr,positionPtr,moduleIndex);
                break;
            }
            default:
                break;
            }
        }
    }
}
Exemple #2
0
int CHudParticules::MsgFunc_ClientDecal( const char *pszName, int iSize, void *pbuf )
{
    BEGIN_READ( pbuf, iSize );

    Vector vecSrc, vecNormal;
    char chTextureType;

    vecSrc.x = READ_COORD();
    vecSrc.y = READ_COORD();
    vecSrc.z = READ_COORD();

    vecNormal.x = READ_COORD();
    vecNormal.y = READ_COORD();
    vecNormal.z = READ_COORD();

    chTextureType = READ_CHAR();
    int decal = READ_BYTE();

    if ( decal == 4 )	// explo electro-roquette
    {
        AddDecal ( vecSrc, Vector ( 90,0,0 ), "sprites/rpg_disk.spr", gHUD.m_flTime + ELECTRO_DISK_MAX / ELECTRO_DISK_SPEED + 0.5, FLAG_DECAL_DISK );
        return 1;
    }
    if ( decal == 5 )	// explo supergun
    {
        Vector angDir;
        VectorAngles ( -vecNormal, angDir );
        angDir.y += 180;

        AddDecal ( vecSrc, angDir, "sprites/rpg_disk.spr", gHUD.m_flTime + 0.5, FLAG_DECAL_SG );
        return 1;
    }

    if ( decal == 6 )	// muzzle outro
    {
        Vector vecDir = vecNormal, velocity (0,0,0), avelocity(0,0,0), src = vecSrc;
        float largeur, brightness;

        //gros

        for ( int j=0; j<4; j++ )
        {
            avelocity	= Vector (0.0f, 0.0f, gEngfuncs.pfnRandomFloat(30,60)* ((j%2)==0?1:-1) );
            velocity	= Vector (vecDir - vecSrc) * 0/*( 0.08 - j*0.02 )*/;
            largeur = 5;
            brightness = 0.3;

            AddParticule ( src, Vector (largeur,brightness,0.0f), velocity, avelocity , "sprites/outro_muzzle.spr", gHUD.m_flTime + 7, FLAG_PARTICULE_OUTRO1 );
        }

        // petits

        for ( int i=0; i<10; i++ )
        {
            brightness = 0.3;
            avelocity	= Vector (0.0f, 0.0f, gEngfuncs.pfnRandomFloat(-300,300) );
            //	velocity	= Vector (vecDir - vecSrc) * ( 0.3 - i*0.03 ) * 2.5;
            velocity	= Vector (vecDir - vecSrc).Normalize() * 0.1;
            largeur		= 1.2 + i*0.3;
            src			= vecSrc + 0.1*(vecDir-vecSrc);

            AddParticule ( src, Vector (largeur,brightness,0.0f), velocity, avelocity, "sprites/outro_muzzle.spr", gHUD.m_flTime + 7, FLAG_PARTICULE_OUTRO2 );
        }

        return 1;
    }

    EV_HLDM_EjectParticules ( vecSrc, vecNormal, chTextureType, decal, 1 );

    return 1;
}
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() );
				}
			}