Cleaned up the damage routines to prepare for a bunch of new changes

related to obituaries etc.

Also added support for headshots. Right now they'll explode scientists'
heads so that's hilarious.
This commit is contained in:
Marco Cawthorne 2019-09-04 10:38:39 +02:00
parent 9f68bc97e1
commit 53a12821e1
9 changed files with 128 additions and 146 deletions

View file

@ -357,7 +357,7 @@ void Game_Parse_Event(float fHeader) {
Radio_PlayMessage(readbyte()); Radio_PlayMessage(readbyte());
} else if (fHeader == EV_RADIOMSG2) { } else if (fHeader == EV_RADIOMSG2) {
Radio_PlayPlayerMessage(readbyte(), readbyte()); Radio_PlayPlayerMessage(readbyte(), readbyte());
} else if (fHeader == EV_ORBITUARY) { } else if (fHeader == EV_OLDREMOVEME) {
HUD_AddOrbituaries(readbyte(), readbyte(), readbyte(), readbyte(), readbyte(), readbyte()); HUD_AddOrbituaries(readbyte(), readbyte(), readbyte(), readbyte(), readbyte(), readbyte());
} else if (fHeader == EV_SMOKE) { } else if (fHeader == EV_SMOKE) {
vector vSmokePos; vector vSmokePos;

View file

@ -66,6 +66,18 @@ const vector VEC_PLAYER_CVIEWPOS = [0,0,12];
#define FL_FROZEN (1<<21) #define FL_FROZEN (1<<21)
#define FL_ONLADDER (1<<13) #define FL_ONLADDER (1<<13)
/* global hitmesh definitions */
enum {
BODY_DEFAULT,
BODY_HEAD,
BODY_CHEST,
BODY_STOMACH,
BODY_ARMLEFT,
BODY_ARMRIGHT,
BODY_LEGLEFT,
BODY_LEGRIGHT
};
#define clamp(d,min,max) bound(min,d,max) #define clamp(d,min,max) bound(min,d,max)
.float jumptime; .float jumptime;

View file

@ -32,7 +32,8 @@ enum {
EV_SPRITE, EV_SPRITE,
EV_MODELGIB, EV_MODELGIB,
EV_CAMERATRIGGER, EV_CAMERATRIGGER,
EV_ORBITUARY, EV_OLDREMOVEME,
EV_OBITUARY, // new one
EV_SPEAK, EV_SPEAK,
EV_SENTENCE, EV_SENTENCE,
EV_CHAT, EV_CHAT,

View file

@ -24,7 +24,7 @@ Sends a message to the clients to display a death message
void Damage_CastOrbituary(entity eAttacker, entity eTarget, float fWeapon, float fHeadShot) void Damage_CastOrbituary(entity eAttacker, entity eTarget, float fWeapon, float fHeadShot)
{ {
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_ORBITUARY); WriteByte(MSG_MULTICAST, EV_OLDREMOVEME);
WriteByte(MSG_MULTICAST, num_for_edict(eAttacker) - 1); WriteByte(MSG_MULTICAST, num_for_edict(eAttacker) - 1);
WriteByte(MSG_MULTICAST, eAttacker.team); WriteByte(MSG_MULTICAST, eAttacker.team);
WriteByte(MSG_MULTICAST, num_for_edict(eTarget) - 1); WriteByte(MSG_MULTICAST, num_for_edict(eTarget) - 1);
@ -103,26 +103,6 @@ void Damage_Apply(entity eTarget, entity eAttacker, float iDamage, vector vHitPo
return; return;
} }
/* Modify the damage based on the location */
switch (trace_surface_id) {
case BODY_HEAD:
if (eTarget.iEquipment & EQUIPMENT_HELMET) {
sound(self, CHAN_ITEM, "weapons/ric_metal-2.wav", 1, ATTN_IDLE);
iDamage = 0;
eTarget.iEquipment -= EQUIPMENT_HELMET;
} else {
iDamage *= 4;
}
break;
case BODY_STOMACH:
iDamage *= 0.9;
break;
case BODY_LEGLEFT:
case BODY_LEGRIGHT:
iDamage *= 0.4;
break;
}
dprint(sprintf("[DEBUG] Hit Bodypart: %s\n", Damage_GetHitLocation(trace_surface_id))); dprint(sprintf("[DEBUG] Hit Bodypart: %s\n", Damage_GetHitLocation(trace_surface_id)));
if (eTarget != eAttacker) { if (eTarget != eAttacker) {

View file

@ -47,18 +47,6 @@ var string autocvar_mapcyclefile = "mapcycle.txt";
var int iMapCycleCount; var int iMapCycleCount;
string *sMapCycle; string *sMapCycle;
// Hit Group standards
enum {
BODY_DEFAULT,
BODY_HEAD,
BODY_CHEST,
BODY_STOMACH,
BODY_ARMLEFT,
BODY_ARMRIGHT,
BODY_LEGLEFT,
BODY_LEGRIGHT
};
// Grenade states // Grenade states
enum { enum {
GRENADE_UNREADY, GRENADE_UNREADY,

View file

@ -179,21 +179,22 @@ void hostage_entity::touch(void)
void hostage_entity::PlayerUse(void) void hostage_entity::PlayerUse(void)
{ {
if (eActivator.team == TEAM_CT) { if (eActivator.team == TEAM_CT) {
if ((m_eUser == world)) { if (m_eUser != world) {
/* Only give cash to the CT for using it for the first time */
if (m_iUsed == FALSE) {
int rand = floor(random(0,5));
sound(this, CHAN_VOICE, g_hostsnd[rand], 1.0, ATTN_IDLE);
Money_AddMoney(eActivator, 150);
m_iUsed = TRUE;
}
m_eUser = eActivator;
m_eRescuer = m_eUser;
m_vecLastUserPos = m_eUser.origin;
} else {
m_eUser = world; m_eUser = world;
return;
} }
/* only give cash to the CT for using it for the first time */
if (m_iUsed == FALSE) {
int r = floor(random(0,5));
sound(this, CHAN_VOICE, g_hostsnd[r], 1.0, ATTN_IDLE);
Money_AddMoney(eActivator, 150);
m_iUsed = TRUE;
}
m_eUser = eActivator;
m_eRescuer = m_eUser;
m_vecLastUserPos = m_eUser.origin;
} }
} }

View file

@ -15,79 +15,109 @@
*/ */
#ifdef CSTRIKE #ifdef CSTRIKE
#define PENETRATION #define PENETRATION
#endif #endif
#ifdef PENETRATION #ifdef PENETRATION
var int iTotalPenetrations; var int iTotalPenetrations;
#endif #endif
void TraceAttack_FireSingle(vector vPos, vector vAngle, int iDamage) /* cast a single bullet shot */
void
TraceAttack_FireSingle(vector vPos, vector vAngle, int iDamage)
{ {
string tex;
vector range;
float surf;
#ifdef CSTRIKE #ifdef CSTRIKE
traceline(vPos, vPos + (vAngle * wptTable[self.weapon].fRange), MOVE_LAGGED | MOVE_HITMODEL, self); range = (vAngle * wptTable[self.weapon].fRange);
#else #else
traceline(vPos, vPos + (vAngle * 8196), MOVE_LAGGED | MOVE_HITMODEL, self); range = (vAngle * 8196);
#endif #endif
if (trace_fraction != 1.0) { traceline(vPos, vPos + range, MOVE_LAGGED | MOVE_HITMODEL, self);
if (trace_ent.takedamage == DAMAGE_YES) { if (trace_fraction >= 1.0f) {
return;
}
Damage_Apply(trace_ent, self, iDamage, trace_endpos, FALSE); if (trace_ent.takedamage == DAMAGE_YES) {
#ifdef CSTRIKE
/*if (trace_ent.health <= 0 && trace_ent.iBleeds == TRUE) { /* modify the damage based on the location */
makevectors(self.v_angle); switch (trace_surface_id) {
trace_ent.movetype = MOVETYPE_BOUNCE; case BODY_HEAD:
trace_ent.velocity = (v_forward * (150 * iDamage)) + [0,0,100 * iDamage]; /* the helmet is one power house */
}*/ if (trace_ent.iEquipment & EQUIPMENT_HELMET) {
iDamage = 0;
sound(self, CHAN_ITEM, "weapons/ric_metal-2.wav", 1, ATTN_IDLE);
trace_ent.iEquipment -= EQUIPMENT_HELMET;
return;
} else {
iDamage *= 4;
}
break;
case BODY_STOMACH:
iDamage *= 0.9;
break;
case BODY_LEGLEFT:
case BODY_LEGRIGHT:
iDamage *= 0.4;
break;
} }
#else
/* only headshots count in HL */
if (trace_surface_id == BODY_HEAD) {
iDamage *= 3;
}
#endif
Damage_Apply(trace_ent, self, iDamage, trace_endpos, FALSE);
}
if (trace_ent.iBleeds != TRUE) { if (trace_ent.iBleeds == TRUE) {
string sTexture = getsurfacetexture(trace_ent, getsurfacenearpoint(trace_ent, trace_endpos)); Effect_CreateBlood(trace_endpos, [0,0,0]);
return;
}
switch ((float)hash_get(hashMaterials, sTexture)) { surf = getsurfacenearpoint(trace_ent, trace_endpos);
case 'G': tex = getsurfacetexture(trace_ent, surf);
case 'V':
Effect_Impact(IMPACT_METAL, trace_endpos, trace_plane_normal); /* our hashtable is the key to all this */
break; switch ((float)hash_get(hashMaterials, tex)) {
case 'M': case 'G':
case 'P': case 'V':
Effect_Impact(IMPACT_METAL, trace_endpos, trace_plane_normal); Effect_Impact(IMPACT_METAL, trace_endpos, trace_plane_normal);
break; break;
case 'D': case 'M':
case 'W': case 'P':
Effect_Impact(IMPACT_WOOD, trace_endpos, trace_plane_normal); Effect_Impact(IMPACT_METAL, trace_endpos, trace_plane_normal);
break; break;
case 'Y': case 'D':
Effect_Impact(IMPACT_GLASS, trace_endpos, trace_plane_normal); case 'W':
break; Effect_Impact(IMPACT_WOOD, trace_endpos, trace_plane_normal);
case 'N': break;
Effect_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal); case 'Y':
break; Effect_Impact(IMPACT_GLASS, trace_endpos, trace_plane_normal);
case 'T': break;
default: case 'N':
Effect_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal); Effect_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
break; break;
} case 'T':
default:
Effect_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
break;
}
#ifdef PENETRATION #ifdef PENETRATION
if (iTotalPenetrations > 0) { if (iTotalPenetrations > 0) {
iTotalPenetrations -= 1; iTotalPenetrations -= 1;
TraceAttack_FireSingle(trace_endpos + (v_forward * 2), vAngle, iDamage); TraceAttack_FireSingle(trace_endpos + (v_forward * 2), vAngle, iDamage);
}
#endif
}
} }
#endif
} }
/* /* fire a given amount of shots */
================= void
TraceAttack_FireBullets TraceAttack_FireBullets(int iShots, vector vPos, int iDamage, vector vecSpread)
Fire a given amount of shots
=================
*/
void TraceAttack_FireBullets(int iShots, vector vPos, int iDamage, vector vecAccuracy)
{ {
vector vDir; vector vDir;
makevectors(self.v_angle); makevectors(self.v_angle);
@ -96,7 +126,9 @@ void TraceAttack_FireBullets(int iShots, vector vPos, int iDamage, vector vecAcc
#ifdef PENETRATION #ifdef PENETRATION
iTotalPenetrations = 4; iTotalPenetrations = 4;
#endif #endif
vDir = aim(self, 100000) + Math_CRandom()*vecAccuracy[0]*v_right + Math_CRandom()*vecAccuracy[1]*v_up; vDir = aim(self, 100000);
vDir += Math_CRandom() * vecSpread[0] * v_right;
vDir += Math_CRandom() * vecSpread[1] * v_up;
TraceAttack_FireSingle(vPos, vDir, iDamage); TraceAttack_FireSingle(vPos, vDir, iDamage);
iShots--; iShots--;
} }

View file

@ -14,34 +14,21 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* /* someone dieded */
=================
Damage_CastOrbituary
Sends a message to the clients to display a death message
=================
*/
void void
Damage_CastOrbituary(entity eCulprit, entity eTarget, float fWeapon) Damage_CastObituary(entity eCulprit, entity eTarget, float weapon, float flags)
{ {
WriteByte(MSG_BROADCAST, SVC_CGAMEPACKET); /*WriteByte(MSG_BROADCAST, SVC_CGAMEPACKET);
WriteByte(MSG_BROADCAST, EV_ORBITUARY); WriteByte(MSG_BROADCAST, EV_OBITUARY);
WriteByte(MSG_BROADCAST, num_for_edict(eCulprit) - 1); WriteByte(MSG_BROADCAST, num_for_edict(eCulprit) - 1);
WriteByte(MSG_BROADCAST, eCulprit.team);
WriteByte(MSG_BROADCAST, num_for_edict(eTarget) - 1); WriteByte(MSG_BROADCAST, num_for_edict(eTarget) - 1);
WriteByte(MSG_BROADCAST, eTarget.team); WriteByte(MSG_BROADCAST, weapon);
WriteByte(MSG_BROADCAST, fWeapon); WriteByte(MSG_BROADCAST, flags);
msg_entity = self; msg_entity = self;
multicast([0,0,0], MULTICAST_ALL); multicast([0,0,0], MULTICAST_ALL);*/
} }
/* /* generic function that applies damage, pain and suffering */
=================
Damage_Apply
Generic function that applies damage, pain and suffering
=================
*/
void void
Damage_Apply(entity eTarget, entity eCulprit, float fDmg, vector pos, int a) Damage_Apply(entity eTarget, entity eCulprit, float fDmg, vector pos, int a)
{ {
@ -86,13 +73,12 @@ Damage_Apply(entity eTarget, entity eCulprit, float fDmg, vector pos, int a)
forceinfokey(eTarget, "*deaths", ftos(eTarget.deaths)); forceinfokey(eTarget, "*deaths", ftos(eTarget.deaths));
} }
if ((eTarget.flags & FL_CLIENT) && (eCulprit.flags & FL_CLIENT)) { if (eCulprit.flags & FL_CLIENT) {
if (eTarget == eCulprit) { if (eTarget == eCulprit) {
eCulprit.frags--; eCulprit.frags--;
} else { } else {
eCulprit.frags++; eCulprit.frags++;
} }
//Damage_CastOrbituary(eCulprit, eTarget, eCulprit.weapon);
} }
} }
@ -105,21 +91,10 @@ Damage_Apply(entity eTarget, entity eCulprit, float fDmg, vector pos, int a)
self.vPain(trace_surface_id); self.vPain(trace_surface_id);
} }
if (self.iBleeds == TRUE && fDmg > 0) {
Effect_CreateBlood(pos, [0,0,0]);
}
self = eOld; self = eOld;
} }
/* /* physical check of whether or not we can trace important parts of an ent */
=================
Damage_CheckTrace
This verifies that the entity is actually able to receive some damage,
from a plain geographical standpoint
=================
*/
float float
Damage_CheckTrace(entity eTarget, vector vecHitPos) Damage_CheckTrace(entity eTarget, vector vecHitPos)
{ {
@ -152,13 +127,7 @@ Damage_CheckTrace(entity eTarget, vector vecHitPos)
return FALSE; return FALSE;
} }
/* /* even more pain and suffering, mostly used for explosives */
=================
Damage_Radius
Even more pain and suffering, mostly used for explosives
=================
*/
void void
Damage_Radius(vector org, entity attacker, float dmg, float radius, int check) Damage_Radius(vector org, entity attacker, float dmg, float radius, int check)
{ {

View file

@ -168,4 +168,3 @@ weapon_t w_chainsaw =
w_chainsaw_aimanim, w_chainsaw_aimanim,
w_chainsaw_hudpic w_chainsaw_hudpic
}; };