void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount ) { if ( !UTIL_ShouldShowBlood( color ) ) return; if ( color == DONT_BLEED || amount == 0 ) return; if ( g_Language.GetInt() == LANGUAGE_GERMAN && color == BLOOD_COLOR_RED ) color = 0; if ( g_pGameRules->IsMultiplayer() ) { // scale up blood effect in multiplayer for better visibility amount *= 5; } if ( amount > 255 ) amount = 255; if (color == BLOOD_COLOR_MECH) { g_pEffects->Sparks(origin); if (random->RandomFloat(0, 2) >= 1) { UTIL_Smoke(origin, random->RandomInt(10, 15), 10); } } else { // Normal blood impact UTIL_BloodImpact( origin, direction, color, amount ); } }
void CHL1NPCTalker::TraceAttack(const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator) { if ( info.GetDamage() >= 1.0 && !(info.GetDamageType() & DMG_SHOCK ) ) { UTIL_BloodImpact( ptr->endpos, vecDir, BloodColor(), 4 ); } BaseClass::TraceAttack( info, vecDir, ptr, pAccumulator ); }
void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount ) { #ifdef HL2SB //Andrew; see https://developer.valvesoftware.com/wiki/Fixing_AI_in_multiplayer#Blood IPredictionSystem::SuppressHostEvents( NULL ); #endif if ( !UTIL_ShouldShowBlood( color ) ) return; if ( color == DONT_BLEED || amount == 0 ) return; if ( g_Language.GetInt() == LANGUAGE_GERMAN && color == BLOOD_COLOR_RED ) color = 0; if ( g_pGameRules->IsMultiplayer() ) { // scale up blood effect in multiplayer for better visibility amount *= 5; } if ( amount > 255 ) amount = 255; if (color == BLOOD_COLOR_MECH) { g_pEffects->Sparks(origin); if (random->RandomFloat(0, 2) >= 1) { UTIL_Smoke(origin, random->RandomInt(10, 15), 10); } } else { // Normal blood impact UTIL_BloodImpact( origin, direction, color, amount ); } }
void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount ) { //Thanks to the prediction, the blood of NPCs is suppressed. This is because in HL2DM the blood of players is done client-side. need to break it for bots IPredictionSystem::SuppressHostEvents( NULL ); if ( !UTIL_ShouldShowBlood( color ) ) return; if ( color == DONT_BLEED || amount == 0 ) return; if ( g_Language.GetInt() == LANGUAGE_GERMAN && color == BLOOD_COLOR_RED ) color = 0; /* if ( g_pGameRules->IsMultiplayer() ) { // scale up blood effect in multiplayer for better visibility amount *= 5; } */ if ( amount > 255 ) amount = 255; if (color == BLOOD_COLOR_MECH) { g_pEffects->Sparks(origin); if (random->RandomFloat(0, 2) >= 1) { UTIL_Smoke(origin, random->RandomInt(10, 15), 10); } } else { // Normal blood impact UTIL_BloodImpact( origin, direction, color, amount ); } }
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() ); } }
static int luasrc_UTIL_BloodImpact (lua_State *L) { UTIL_BloodImpact(luaL_checkvector(L, 1), luaL_checkvector(L, 2), luaL_checkint(L, 3), luaL_checkint(L, 4)); return 0; }