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());
} else if (fHeader == EV_RADIOMSG2) {
Radio_PlayPlayerMessage(readbyte(), readbyte());
} else if (fHeader == EV_ORBITUARY) {
} else if (fHeader == EV_OLDREMOVEME) {
HUD_AddOrbituaries(readbyte(), readbyte(), readbyte(), readbyte(), readbyte(), readbyte());
} else if (fHeader == EV_SMOKE) {
vector vSmokePos;

View File

@ -66,6 +66,18 @@ const vector VEC_PLAYER_CVIEWPOS = [0,0,12];
#define FL_FROZEN (1<<21)
#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)
.float jumptime;

View File

@ -32,7 +32,8 @@ enum {
EV_SPRITE,
EV_MODELGIB,
EV_CAMERATRIGGER,
EV_ORBITUARY,
EV_OLDREMOVEME,
EV_OBITUARY, // new one
EV_SPEAK,
EV_SENTENCE,
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)
{
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, eAttacker.team);
WriteByte(MSG_MULTICAST, num_for_edict(eTarget) - 1);
@ -103,26 +103,6 @@ void Damage_Apply(entity eTarget, entity eAttacker, float iDamage, vector vHitPo
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)));
if (eTarget != eAttacker) {

View File

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

View File

@ -179,21 +179,22 @@ void hostage_entity::touch(void)
void hostage_entity::PlayerUse(void)
{
if (eActivator.team == TEAM_CT) {
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 {
if (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
#define PENETRATION
#define PENETRATION
#endif
#ifdef PENETRATION
var int iTotalPenetrations;
var int iTotalPenetrations;
#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
traceline(vPos, vPos + (vAngle * wptTable[self.weapon].fRange), MOVE_LAGGED | MOVE_HITMODEL, self);
range = (vAngle * wptTable[self.weapon].fRange);
#else
traceline(vPos, vPos + (vAngle * 8196), MOVE_LAGGED | MOVE_HITMODEL, self);
range = (vAngle * 8196);
#endif
if (trace_fraction != 1.0) {
if (trace_ent.takedamage == DAMAGE_YES) {
traceline(vPos, vPos + range, MOVE_LAGGED | MOVE_HITMODEL, self);
if (trace_fraction >= 1.0f) {
return;
}
Damage_Apply(trace_ent, self, iDamage, trace_endpos, FALSE);
/*if (trace_ent.health <= 0 && trace_ent.iBleeds == TRUE) {
makevectors(self.v_angle);
trace_ent.movetype = MOVETYPE_BOUNCE;
trace_ent.velocity = (v_forward * (150 * iDamage)) + [0,0,100 * iDamage];
}*/
if (trace_ent.takedamage == DAMAGE_YES) {
#ifdef CSTRIKE
/* modify the damage based on the location */
switch (trace_surface_id) {
case BODY_HEAD:
/* 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) {
string sTexture = getsurfacetexture(trace_ent, getsurfacenearpoint(trace_ent, trace_endpos));
if (trace_ent.iBleeds == TRUE) {
Effect_CreateBlood(trace_endpos, [0,0,0]);
return;
}
switch ((float)hash_get(hashMaterials, sTexture)) {
case 'G':
case 'V':
Effect_Impact(IMPACT_METAL, trace_endpos, trace_plane_normal);
break;
case 'M':
case 'P':
Effect_Impact(IMPACT_METAL, trace_endpos, trace_plane_normal);
break;
case 'D':
case 'W':
Effect_Impact(IMPACT_WOOD, trace_endpos, trace_plane_normal);
break;
case 'Y':
Effect_Impact(IMPACT_GLASS, trace_endpos, trace_plane_normal);
break;
case 'N':
Effect_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
break;
case 'T':
default:
Effect_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
break;
}
surf = getsurfacenearpoint(trace_ent, trace_endpos);
tex = getsurfacetexture(trace_ent, surf);
/* our hashtable is the key to all this */
switch ((float)hash_get(hashMaterials, tex)) {
case 'G':
case 'V':
Effect_Impact(IMPACT_METAL, trace_endpos, trace_plane_normal);
break;
case 'M':
case 'P':
Effect_Impact(IMPACT_METAL, trace_endpos, trace_plane_normal);
break;
case 'D':
case 'W':
Effect_Impact(IMPACT_WOOD, trace_endpos, trace_plane_normal);
break;
case 'Y':
Effect_Impact(IMPACT_GLASS, trace_endpos, trace_plane_normal);
break;
case 'N':
Effect_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
break;
case 'T':
default:
Effect_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
break;
}
#ifdef PENETRATION
if (iTotalPenetrations > 0) {
iTotalPenetrations -= 1;
TraceAttack_FireSingle(trace_endpos + (v_forward * 2), vAngle, iDamage);
}
#endif
}
if (iTotalPenetrations > 0) {
iTotalPenetrations -= 1;
TraceAttack_FireSingle(trace_endpos + (v_forward * 2), vAngle, iDamage);
}
#endif
}
/*
=================
TraceAttack_FireBullets
Fire a given amount of shots
=================
*/
void TraceAttack_FireBullets(int iShots, vector vPos, int iDamage, vector vecAccuracy)
/* fire a given amount of shots */
void
TraceAttack_FireBullets(int iShots, vector vPos, int iDamage, vector vecSpread)
{
vector vDir;
makevectors(self.v_angle);
@ -96,7 +126,9 @@ void TraceAttack_FireBullets(int iShots, vector vPos, int iDamage, vector vecAcc
#ifdef PENETRATION
iTotalPenetrations = 4;
#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);
iShots--;
}

View File

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