// muzzleflash
$attachment 0 "bip01 R hand" 15 3.5 5 X 1
$hbox 3 "Bip01 Pelvis" -9.89 -5.66 -8.60 2.94 6.52 6.79
$hbox 6 "Bip01 L Leg" 0.00 -5.92 -4.00 19.37 3.78 3.73
$hbox 6 "Bip01 L Leg1" 0.00 -5.69 -3.62 18.83 3.07 2.94
$hbox 6 "Bip01 L Foot" 0.00 -2.99 -4.04 6.42 8.68 1.61
$hbox 7 "Bip01 R Leg" 0.00 -5.93 -3.87 19.27 3.75 3.79
$hbox 7 "Bip01 R Leg1" -0.33 -5.73 -2.98 18.95 2.96 3.19
$hbox 7 "Bip01 R Foot" 0.00 -3.24 -2.32 6.21 8.44 3.28
$hbox 3 "Bip01 Spine" 0.00 -4.89 -6.97 8.37 8.00 6.73
$hbox 2 "Bip01 Spine2" 0.00 -3.46 -8.32 6.11 8.00 7.53
$hbox 2 "Bip01 Spine3" -1.00 -5.99 -8.22 5.96 8.00 8.48
$hbox 4 "Bip01 L Arm" -0.40 -4.18 0.00 7.20 4.75 4.20
$hbox 4 "Bip01 L Arm1" -2.52 -4.57 -3.92 9.86 2.28 3.43
$hbox 4 "Bip01 L Arm2" 0.00 -2.85 -2.08 11.90 2.85 2.75
$hbox 4 "Bip01 L Hand" 0.00 -1.32 -2.29 4.66 2.60 1.65
$hbox 5 "Bip01 R Arm" 0.00 -4.15 -4.19 7.53 4.12 4.24
$hbox 5 "Bip01 R Arm1" -2.69 -4.65 -3.42 9.47 2.28 3.76
$hbox 5 "Bip01 R Arm2" 0.00 -2.73 -2.56 11.00 3.14 2.19
$hbox 5 "Bip01 R Hand" 0.00 -1.32 -2.91 10.38 3.23 4.00
//$hbox 1 "Bip01 Head" -0.66 -4.25 -5.24 11.19 7.97 4.63
$hbox 1 "Bip01 Head" -0.66 2.25 -4.24 6.00 7.97 3.63
$hbox 10 "Bip01 Head" -0.66 -4.25 -5.24 6.00 2.25 4.63
$hbox 10 "Bip01 Head" 6.00 -4.25 -5.24 11.19 7.97 4.63
//$hbox 0 "Bone05" 0.00 -2.47 -2.29 3.73 0.00 2.12
//$hbox 0 "Bone03" -2.69 -14.48 -6.05 1.60 4.30 2.29
Those are all the hitboxes, don't worry about the last bunch of numbers, as they are not relevant to this article.
$hbox 1 "Bip01 Head"
$hbox 10 "Bip01 Head"
$hbox 10 "Bip01 Head"
Here are the three hitboxes for barney's head, you'll notice two different numbers here, 1 and 10. These two numbers are important when refering to the code.
void CBarney::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType)
{
switch( ptr->iHitgroup)
{
case HITGROUP_CHEST:
case HITGROUP_STOMACH:
if (bitsDamageType & (DMG_BULLET | DMG_SLASH | DMG_BLAST))
{
flDamage = flDamage / 2;
}
break;
case 10:
if (bitsDamageType & (DMG_BULLET | DMG_SLASH | DMG_CLUB))
{
flDamage -= 20;
if (flDamage <= 0)
{
UTIL_Ricochet( ptr->vecEndPos, 1.0 );
flDamage = 0.01;
}
}
// always a head shot
ptr->iHitgroup = HITGROUP_HEAD;
break;
}
CTalkMonster::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType );
}
You may notice the case 10, this is one way of refering to hitboxes in the code, the HITGROUP_CHEST and HITGROUP_HEAD are other ways of refering to hitboxes, and here's why (this is located in monsters.h):
// Hit Group standards
#define HITGROUP_GENERIC 0
#define HITGROUP_HEAD 1
#define HITGROUP_CHEST 2
#define HITGROUP_STOMACH 3
#define HITGROUP_LEFTARM 4
#define HITGROUP_RIGHTARM 5
#define HITGROUP_LEFTLEG 6
#define HITGROUP_RIGHTLEG 7
As you can see, HITGROUP_HEAD is equal to 1, HITGROUP_CHEST is 2, and so on... If you look throughout the SDK (particulary combat.cpp), you'll see these popup again and again.case HITGROUP_CHEST:
case HITGROUP_STOMACH:
if (bitsDamageType & (DMG_BULLET | DMG_SLASH | DMG_BLAST))
{
flDamage = flDamage / 2;
}
break;
The two cases are stating that if hitbox 2 or 3 are hit by any damage, then the if statement will be executed; which is dividing the damage by 2.
case 10:
if (bitsDamageType & (DMG_BULLET | DMG_SLASH | DMG_CLUB))
{
flDamage -= 20;
if (flDamage <= 0)
{
UTIL_Ricochet( ptr->vecEndPos, 1.0 );
flDamage = 0.01;
}
}
// always a head shot
ptr->iHitgroup = HITGROUP_HEAD;
break;
This case is executed if hitbox 10 is hit. If it is hit by any of the damage types defined, it will take away 20 damage. If the damage turns out to be zero (after taking away damage), then it will make a ricochet and give out a very little bit of damage. That last bit basically forces it to count as a headshot.// check for helmet shot
if (ptr->iHitgroup == 11)
{
// make sure we're wearing one
if (GetBodygroup( 1 ) == HEAD_GRUNT && (bitsDamageType & (DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB)))
{
// absorb damage
flDamage -= 20;
if (flDamage <= 0)
{
UTIL_Ricochet( ptr->vecEndPos, 1.0 );
flDamage = 0.01;
}
}
// it's head shot anyways
ptr->iHitgroup = HITGROUP_HEAD;
}
This is in the TraceAttack function in hgrunt.cpp. Here you can see that it is set up differently, instead of a switch statement, it uses an if statement.// Teh_Freak: TraceAttack checks to see if it was shot in the head
void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
Now you'll need to make the actual function, add this at the end of the file:
//=========================================================
// TraceAttack - checks to see if the zombie was shot in the head
//=========================================================
void CZombie :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType)
{
// Teh_Freak: check to see if shot in the head
if (ptr->iHitgroup == HITGROUP_HEAD)
{
m_bloodColor = BLOOD_COLOR_YELLOW; // Teh_Freak: is shot in the head, emit yellow blood
}
else
{
m_bloodColor = BLOOD_COLOR_RED; // Teh_Freak: if not, emit red blood
}
CBaseMonster::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType );
}
OK, what the if statement does is check to see if hitbox 1 was hit (remeber that little list I showed you?), if it was, then the monsters blood color will change to yellow; if it wasn't, however, then the blood color will change to red.
$hbox 6 "Bip01 L Leg" -3.96 -6.55 -3.51 18.51 5.56 4.46
$hbox 6 "Bip01 L Leg1" -0.64 -2.27 -2.09 13.41 3.03 1.95
$hbox 6 "Bip01 L Foot" -0.55 -2.82 -6.41 8.7 8.88 4.51
$hbox 7 "Bip01 R Leg" -4.07 -6.65 -4.52 18.51 5.49 3.46
$hbox 7 "Bip01 R Leg1" -0.54 -2.34 -2.00 13.41 1.72 2.03
$hbox 7 "Bip01 R Foot" -0.54 -3.17 -4.46 8.66 9.01 6.46
$hbox 3 "Bip01 Pelvis" -6.31 -8.74 -7.26 6.33 5.23 7.64
$hbox 3 "Bip01 Spine" 0.00 -6.02 -4.51 6.15 5.10 5.35
$hbox 2 "Bip01 Spine1" 0.00 -1.49 -5.48 6.18 0.00 6.13
$hbox 2 "Bip01 Spine2" 0.00 -10.04 -13.03 8.82 8.40 13.29
$hbox 2 "Bip01 Spine3" 0.00 -13.07 -13.18 10.64 11.36 13.76 // <------
$hbox 4 "Bip01 L Arm" 0.00 0.00 -6.89 8.36 1.88 0.00
$hbox 4 "Bip01 L Arm1" 0.00 -5.12 -4.23 22.309999 2.61 2.65
$hbox 4 "Bip01 L Arm2" 0.00 -4.05 -4.42 14.97 2.97 4.59 // <------
$hbox 4 "Bip01 L Hand" 0.00 -1.87 -2.40 7.80 2.52 2.61
$hbox 5 "Bip01 R Arm" 0.00 0.00 0.00 8.42 1.87 7.10
$hbox 5 "Bip01 R Arm1" 0.00 -4.98 -2.42 22.309999 2.82 4.49
$hbox 5 "Bip01 R Arm2" -0.04 -3.65 -4.19 15.23 3.34 4.69 // <------
$hbox 5 "Bip01 R Hand" 0.00 -1.84 -2.38 7.54 2.58 2.63
$hbox 1 "Bip01 Head" 0.00 -5.54 -7.74 11.38 9.60 8.16
The three that I highlighted are the three we are going to edit (I found them by looking through Milkshape3D at the bone view, and a little bit of guesswork)// Teh_Freak: if damaged in the collar/arm brace
if ( ptr->iHitgroup == 11 )
{
if (bitsDamageType & (DMG_BULLET | DMG_SLASH | DMG_CLUB))
{
// Teh_Freak: make a ricochet effect and take little damage
UTIL_Ricochet( ptr->vecEndPos, 1.0 );
flDamage = 0.01;
}
}
Well, now all that explaining at the top may make sense now. Hitgroup 11 gets hit, so a ricochet effect will be made.You must log in to post a comment. You can login or register a new account.