SERVER: Improve accuracy and readability of damage and score components

This commit is contained in:
cypress 2024-06-16 14:04:15 -07:00
parent 2ae79b8d2d
commit 6d55ebbcec
11 changed files with 98 additions and 58 deletions

View file

@ -400,7 +400,7 @@ void() Zombie_Think = //called every frame for zombies
Effect_Fire(self.origin); Effect_Fire(self.origin);
if (self.ltime < time && self.onfire){ if (self.ltime < time && self.onfire){
DamageHandler(self, self.firer, 300, S_FLAME); DamageHandler(self, self.firer, 300, DMG_TYPE_FLAMETHROWER);
self.ltime = time + 2; self.ltime = time + 2;
if (self.fire_timeout < time) if (self.fire_timeout < time)
@ -418,7 +418,7 @@ void() Zombie_Think = //called every frame for zombies
if (self.bleedingtime < time && !self.head.deadflag) if (self.bleedingtime < time && !self.head.deadflag)
{ {
self.bleedingtime = time + 1; self.bleedingtime = time + 1;
DamageHandler (self, self.usedent, z_health * 0.2, S_HEADSHOT); DamageHandler (self, self.usedent, z_health * 0.2, DMG_TYPE_HEADSHOT);
} }
// If we're mid attack and our enemy has moved out of range // If we're mid attack and our enemy has moved out of range
@ -634,9 +634,9 @@ void() zombie_attack2 =
if(vlen(self.enemy.origin - self.origin) < 64) if(vlen(self.enemy.origin - self.origin) < 64)
{ {
if (self.classname == "ai_dog") if (self.classname == "ai_dog")
DamageHandler (self.enemy, self, 40, S_ZOMBIE); DamageHandler (self.enemy, self, 40, DMG_TYPE_ZOMBIESWIPE);
else else
DamageHandler (self.enemy, self, 50, S_ZOMBIE); DamageHandler (self.enemy, self, 50, DMG_TYPE_ZOMBIESWIPE);
} }
} }
else return; else return;
@ -747,7 +747,7 @@ void() zombie_attack_through_window =
{ {
if(who.classname == "player") if(who.classname == "player")
{ {
DamageHandler (who, self, ZOMBIE_DAMAGE_THROUGH_WINDOW, S_ZOMBIE); DamageHandler (who, self, ZOMBIE_DAMAGE_THROUGH_WINDOW, DMG_TYPE_ZOMBIESWIPE);
} }
who = who.chain; who = who.chain;
} }

View file

@ -27,6 +27,15 @@
*/ */
void (float achievement_id, optional entity who) GiveAchievement; void (float achievement_id, optional entity who) GiveAchievement;
#define DMG_SCORE_HEADSHOT 100 // Death by Headshot
#define DMG_SCORE_MELEE 130 // Death by Melee
#define DMG_SCORE_UPPERTORSO 60 // Death by gunshot, upper torso.
#define DMG_SCORE_LOWERTORSO 50 // Death by gunshot, lower torso.
#define DMG_SCORE_GRENADE 50 // Death by Grenade.
#define DMG_SCORE_EXPLOSIVE 60 // Death by Explosive Weapon.
#define DMG_SCORE_TESLA 50 // Death by Tesla.
#define DMG_SCORE_STDDAMAGE 10 // Standard Damage reward.
void() Barrel_Hit; void() Barrel_Hit;
void() teddy_react; void() teddy_react;
@ -430,46 +439,58 @@ void(entity attacker, float d_style) DieHandler =
float points_earned = 0; float points_earned = 0;
switch(d_style) { switch(d_style) {
case S_HEADSHOT: case DMG_TYPE_HEADSHOT:
points_earned = 100; points_earned = DMG_SCORE_HEADSHOT;
attacker.headshots++; attacker.headshots++;
break; break;
case S_KNIFE: case DMG_TYPE_MELEE:
points_earned = 130; points_earned = DMG_SCORE_MELEE;
break; break;
case S_TESLA: case DMG_TYPE_TESLA:
points_earned = 50; points_earned = DMG_SCORE_GRENADE;
break; break;
case S_FLAME: case DMG_TYPE_FLAMETHROWER:
points_earned = 50; points_earned = DMG_SCORE_GRENADE;
// override their death sound (FIXME: make a new sound..) // override their death sound (FIXME: make a new sound..)
sound(self, CHAN_BODY, "sounds/pu/drop.wav", 1, ATTN_NORM); sound(self, CHAN_BODY, "sounds/pu/drop.wav", 1, ATTN_NORM);
break; break;
case DMG_TYPE_GRENADE:
points_earned = DMG_SCORE_GRENADE;
break;
case DMG_TYPE_EXPLOSIVE:
points_earned = DMG_SCORE_EXPLOSIVE;
break;
case DMG_TYPE_LOWERTORSO:
points_earned = DMG_SCORE_LOWERTORSO;
break;
case DMG_TYPE_UPPERTORSO:
points_earned = DMG_SCORE_UPPERTORSO;
break;
default: default:
points_earned = 60; if (cvar("developer"))
bprint(PRINT_HIGH, "DieHandler: Received invalid style\n");
break; break;
} }
Player_AddScore(attacker, points_earned, true); Player_AddScore(attacker, points_earned, true);
} }
} }
void(entity victim, entity attacker, float damage, float d_style) DamageHandler = { void(entity victim, entity attacker, float damage, float d_style) DamageHandler = {
// don't do any attacking during nuke delay // don't do any attacking during nuke delay
if (d_style == S_ZOMBIE && nuke_powerup_active > time) if (d_style == DMG_TYPE_ZOMBIESWIPE && nuke_powerup_active > time)
return; return;
entity old_self; entity old_self;
if (victim.classname == "ai_zombie" || victim.classname == "ai_dog") { if (victim.classname == "ai_zombie" || victim.classname == "ai_dog") {
if (attacker.classname == "player" && (victim.health - damage) > 0) { if (attacker.classname == "player" && (victim.health - damage) > 0 && d_style != DMG_TYPE_OTHER) {
Player_AddScore(attacker, 10, true); Player_AddScore(attacker, DMG_SCORE_STDDAMAGE, true);
} }
victim.health = victim.health - damage; victim.health = victim.health - damage;
if (d_style == S_EXPLOSIVE && damage != 0) { if (d_style == DMG_TYPE_EXPLOSIVE && damage != 0) {
if (victim.health > 0 && victim.crawling == 2) { if (victim.health > 0 && victim.crawling == 2) {
makeCrawler(victim); makeCrawler(victim);
GiveAchievement(3, attacker); GiveAchievement(3, attacker);
@ -528,7 +549,7 @@ void(entity victim, entity attacker, float damage, float d_style) DamageHandler
victim.punchangle_y = distance_y; victim.punchangle_y = distance_y;
// Play pain noise if this isn't done by an electric barrier. // Play pain noise if this isn't done by an electric barrier.
if (d_style != S_ZAPPER) if (d_style != DMG_TYPE_ELECTRICTRAP)
sound (victim, CHAN_AUTO, "sounds/player/pain4.wav", 1, ATTN_NORM); sound (victim, CHAN_AUTO, "sounds/player/pain4.wav", 1, ATTN_NORM);
else else
sound (victim, CHAN_AUTO, "sounds/machines/elec_shock.wav", 1, ATTN_NORM); sound (victim, CHAN_AUTO, "sounds/machines/elec_shock.wav", 1, ATTN_NORM);
@ -613,6 +634,7 @@ float(float min, float max, vector org1, vector org2, float radius) calculate_pr
void(entity inflictor, entity attacker, float damage2, float mindamage, float radius) DamgageExplode = void(entity inflictor, entity attacker, float damage2, float mindamage, float radius) DamgageExplode =
{ {
float final_damage = 0; float final_damage = 0;
float damage_style = 0;
entity ent; entity ent;
float multi, r; float multi, r;
@ -643,11 +665,11 @@ void(entity inflictor, entity attacker, float damage2, float mindamage, float ra
if (final_damage < other.health) if (final_damage < other.health)
{ {
Player_AddScore(self, 10, false); Player_AddScore(self, DMG_SCORE_STDDAMAGE, false);
} }
else if (final_damage > other.health) else if (final_damage > other.health)
{ {
Player_AddScore(self, 10, false); Player_AddScore(self, DMG_SCORE_STDDAMAGE, false);
} }
else else
{ {
@ -704,10 +726,6 @@ void(entity inflictor, entity attacker, float damage2, float mindamage, float ra
} }
else if (ent.takedamage && ent.classname != "ai_zombie_head" && ent.classname != "ai_zombie_larm" && ent.classname != "ai_zombie_rarm") else if (ent.takedamage && ent.classname != "ai_zombie_head" && ent.classname != "ai_zombie_larm" && ent.classname != "ai_zombie_rarm")
{ {
// verify we aren't doin anything with a bmodel
if (ent.solid == SOLID_BSP || ent.movetype == MOVETYPE_PUSH)
return;
if (mapname == "ndu" && ent.classname == "ai_zombie" && inflictor.classname == "explosive_barrel") { if (mapname == "ndu" && ent.classname == "ai_zombie" && inflictor.classname == "explosive_barrel") {
ach_tracker_barr++; ach_tracker_barr++;
@ -724,23 +742,28 @@ void(entity inflictor, entity attacker, float damage2, float mindamage, float ra
// grenades follow the logic of (rounds + (rand 150-500)) // grenades follow the logic of (rounds + (rand 150-500))
// rounds is basically meaningless though.. wtf? // rounds is basically meaningless though.. wtf?
final_damage = rounds + rint(random() * 350) + 150; final_damage = rounds + rint(random() * 350) + 150;
damage_style = DMG_TYPE_GRENADE;
} else if (inflictor.classname == "projectile_grenade") { } else if (inflictor.classname == "projectile_grenade") {
// projectile-based grenades (mustang & sally) seem to do // projectile-based grenades (mustang & sally) seem to do
// more damage than standard grenades. // more damage than standard grenades.
// (rounds + (rand 1200-5000)) // (rounds + (rand 1200-5000))
final_damage = rounds + rint(random() * 3800) + 1200; final_damage = rounds + rint(random() * 3800) + 1200;
damage_style = DMG_TYPE_EXPLOSIVE;
} else if (inflictor.classname == "rocket") { } else if (inflictor.classname == "rocket") {
// rockets were kinda tricky to figure out, this is as close // rockets were kinda tricky to figure out, this is as close
// as i can get and i'm not super confident.. // as i can get and i'm not super confident..
// (rounds * (rand 0-100) * weapon_damage/500). // (rounds * (rand 0-100) * weapon_damage/500).
final_damage = (rounds * rint(random() * 100)) * damage2/500; final_damage = (rounds * rint(random() * 100)) * damage2/500;
damage_style = DMG_TYPE_EXPLOSIVE;
} else if (inflictor.classname == "projectile_raybeam") { } else if (inflictor.classname == "projectile_raybeam") {
//final_damage = calculate_proximity_value(mindamage, damage2, inflictor.origin, ent.origin, radius); //final_damage = calculate_proximity_value(mindamage, damage2, inflictor.origin, ent.origin, radius);
//bprint(PRINT_HIGH, strcat("damage: ", ftos(final_damage), "\n")); //bprint(PRINT_HIGH, strcat("damage: ", ftos(final_damage), "\n"));
final_damage = damage2; final_damage = damage2;
damage_style = DMG_TYPE_GRENADE;
} else if (inflictor.classname == "player") { } else if (inflictor.classname == "player") {
// phd flopper. // phd flopper.
final_damage = calculate_proximity_value(mindamage, damage2, inflictor.origin, ent.origin, radius); final_damage = calculate_proximity_value(mindamage, damage2, inflictor.origin, ent.origin, radius);
damage_style = DMG_TYPE_GRENADE;
} else { } else {
r = rounds; r = rounds;
multi = 1.07; multi = 1.07;
@ -768,7 +791,7 @@ void(entity inflictor, entity attacker, float damage2, float mindamage, float ra
if (final_damage > 0) { if (final_damage > 0) {
if (CanDamage (ent, inflictor)) if (CanDamage (ent, inflictor))
DamageHandler (ent, attacker, final_damage, S_EXPLOSIVE); DamageHandler (ent, attacker, final_damage, damage_style);
} }
ent = ent.chain; ent = ent.chain;
} }

View file

@ -394,7 +394,13 @@ float sounds_playing;
//.float OrgStuckCount; //.float OrgStuckCount;
.float crawling; .float crawling;
#define HIT_REGION_HEAD 1
#define HIT_REGION_ARM 2
#define HIT_REGION_TORSO_LOWER 3
#define HIT_REGION_TORSO_UPPER 4
.float washit; .float washit;
.float hit_region;
.float hitamount; .float hitamount;
.float laststep; .float laststep;

View file

@ -82,7 +82,7 @@ void() door_go_up;
void() door_blocked = void() door_blocked =
{ {
DamageHandler (other, self, self.dmg, S_NORMAL); DamageHandler (other, self, self.dmg, DMG_TYPE_OTHER);
// if a door has a negative wait, it would never come back if blocked, // if a door has a negative wait, it would never come back if blocked,
// so let it just squash the object to death real fast // so let it just squash the object to death real fast

View file

@ -111,7 +111,7 @@ void () func_rotating_use =
void() rot_crush = void() rot_crush =
{ {
DamageHandler(self, other, 1, S_ZOMBIE); DamageHandler(self, other, 1, DMG_TYPE_OTHER);
} }
void () func_rotating = void () func_rotating =
@ -159,7 +159,7 @@ void() train_blocked =
self.death_timer = time + 0.5; self.death_timer = time + 0.5;
DamageHandler(self, other, self.dmg, S_ZOMBIE); DamageHandler(self, other, self.dmg, DMG_TYPE_OTHER);
}; };
void() train_use = void() train_use =

View file

@ -69,9 +69,9 @@ void() zapper_do_damage
// Inflict Damage // Inflict Damage
if (other.damage_timer < time) { if (other.damage_timer < time) {
if (other.perks & P_JUG) if (other.perks & P_JUG)
DamageHandler(other, self, 50, S_ZAPPER); DamageHandler(other, self, 50, DMG_TYPE_ELECTRICTRAP);
else else
DamageHandler(other, self, other.health, S_ZAPPER); DamageHandler(other, self, other.health, DMG_TYPE_ELECTRICTRAP);
other.damage_timer = time + 1.25; other.damage_timer = time + 1.25;
} }
// Inflict Speed Penalty // Inflict Speed Penalty

View file

@ -417,7 +417,7 @@ void() hurt_touch =
(other.aistatus == "1" && !(self.spawnflags & HURT_SPAWNFLAG_NOAI))) (other.aistatus == "1" && !(self.spawnflags & HURT_SPAWNFLAG_NOAI)))
{ {
self.solid = SOLID_NOT; self.solid = SOLID_NOT;
DamageHandler(other, self, self.dmg, S_NORMAL); DamageHandler(other, self, self.dmg, DMG_TYPE_OTHER);
self.think = hurt_on; self.think = hurt_on;
self.nextthink = time + 1; self.nextthink = time + 1;

View file

@ -89,7 +89,7 @@ void() Flame_Touch =
Effect_Fire(target.origin); Effect_Fire(target.origin);
// Only do 1 damage to trigger insta-kill damage. // Only do 1 damage to trigger insta-kill damage.
DamageHandler(target, target.firer, 1, S_FLAME); DamageHandler(target, target.firer, 1, DMG_TYPE_FLAMETHROWER);
} }
// Set the monster alight // Set the monster alight

View file

@ -85,7 +85,7 @@ void(entity hit_ent, entity arc_parent, entity arc_owner, float arc_num, float d
// 50 points for waffe kills // 50 points for waffe kills
if(arc_owner.classname == "player") { if(arc_owner.classname == "player") {
arc_owner.kills += 1; arc_owner.kills += 1;
Player_AddScore(arc_owner, 50, true); Player_AddScore(arc_owner, DMG_SCORE_TESLA, true);
} }
} }
@ -332,10 +332,7 @@ void() W_FireTesla =
float damage = lerp(0, 75, lerp_frac); float damage = lerp(0, 75, lerp_frac);
// print("Giving player ",ftos(damage), " damage.\n"); // print("Giving player ",ftos(damage), " damage.\n");
if (other.perks & P_JUG) DamageHandler(ent, self, damage, DMG_TYPE_ELECTRICTRAP);
DamageHandler(ent, self, damage, S_ZAPPER);
else
DamageHandler(ent, self, damage, S_ZAPPER);
// ---------------------------------------- // ----------------------------------------
} }

View file

@ -752,13 +752,18 @@ void Parse_Damage () = // DO NOT TOUCH
} }
if (head_hit) if (head_hit)
DamageHandler(body_ent,self, total_dmg, S_HEADSHOT); DamageHandler(body_ent,self, total_dmg, DMG_TYPE_HEADSHOT);
else {
if (body_ent.hit_region == HIT_REGION_TORSO_LOWER)
DamageHandler(body_ent,self, total_dmg, DMG_TYPE_LOWERTORSO);
else else
DamageHandler(body_ent,self, total_dmg, S_NORMAL); DamageHandler(body_ent,self, total_dmg, DMG_TYPE_UPPERTORSO);
}
if (body_ent != world) { if (body_ent != world) {
body_ent.washit = 0; body_ent.washit = 0;
body_ent.hitamount = 0; body_ent.hitamount = 0;
body_ent.hit_region = 0;
} }
} }
ent = findfloat (ent, washit, 1); ent = findfloat (ent, washit, 1);
@ -813,16 +818,22 @@ void(float damage, vector dir, vector org, vector plane, entity hit_ent, float s
switch(hit_ent.classname) { switch(hit_ent.classname) {
case "ai_zombie_head": case "ai_zombie_head":
f_damage = damage*getWeaponMultiplier(self.weapon, HEAD_X); f_damage = damage*getWeaponMultiplier(self.weapon, HEAD_X);
hit_ent.hit_region = HIT_REGION_HEAD;
break; break;
case "ai_zombie_larm": case "ai_zombie_larm":
case "ai_zombie_rarm": case "ai_zombie_rarm":
f_damage = damage*getWeaponMultiplier(self.weapon, LIMBS_X); f_damage = damage*getWeaponMultiplier(self.weapon, LIMBS_X);
hit_ent.hit_region = HIT_REGION_ARM;
break; break;
case "ai_zombie": case "ai_zombie":
if (trace_endpos_z < hit_ent.origin_z) if (trace_endpos_z < hit_ent.origin_z) {
f_damage = damage*getWeaponMultiplier(self.weapon, LOWER_TORSO_X); f_damage = damage*getWeaponMultiplier(self.weapon, LOWER_TORSO_X);
else hit_ent.hit_region = HIT_REGION_TORSO_LOWER;
}
else {
f_damage = damage*getWeaponMultiplier(self.weapon, UPPER_TORSO_X); f_damage = damage*getWeaponMultiplier(self.weapon, UPPER_TORSO_X);
hit_ent.hit_region = HIT_REGION_TORSO_UPPER;
}
break; break;
default: default:
f_damage = damage; f_damage = damage;
@ -1248,7 +1259,7 @@ void() WeaponCore_Melee =
// Apply damage to the entity. // Apply damage to the entity.
if (trace_ent.takedamage) { if (trace_ent.takedamage) {
float melee_damage = WepDef_CalculateMeleeDamage(self.weapon, self.bowie); float melee_damage = WepDef_CalculateMeleeDamage(self.weapon, self.bowie);
DamageHandler (trace_ent, self, melee_damage, S_KNIFE); DamageHandler (trace_ent, self, melee_damage, DMG_TYPE_MELEE);
} }
} }
} }
@ -1344,7 +1355,7 @@ void() Velocity_reduce =
{ {
// Do one (1) damage on monster contact, to kill when Insta-Kill is active. // Do one (1) damage on monster contact, to kill when Insta-Kill is active.
if (other.flags & FL_MONSTER) if (other.flags & FL_MONSTER)
DamageHandler(other, self.owner, 1, S_NORMAL); DamageHandler(other, self.owner, 1, DMG_TYPE_OTHER);
if (!other.solid || other.solid == SOLID_TRIGGER) if (!other.solid || other.solid == SOLID_TRIGGER)
if (other != world) if (other != world)
@ -1716,8 +1727,8 @@ void() CheckPlayer =
traceline(self.origin, self.origin + (v_up * -40), 0, self); traceline(self.origin, self.origin + (v_up * -40), 0, self);
if (trace_ent.classname == "player") { if (trace_ent.classname == "player") {
DamageHandler(self, trace_ent, 100000, S_NORMAL); DamageHandler(self, trace_ent, 100000, DMG_TYPE_OTHER);
DamageHandler(trace_ent, self, 100000, S_NORMAL); DamageHandler(trace_ent, self, 100000, DMG_TYPE_OTHER);
} }
} }
@ -1749,7 +1760,7 @@ void() CheckPlayer =
if (damage > 98) damage = 98; if (damage > 98) damage = 98;
DamageHandler (self, other, damage, S_ZOMBIE); DamageHandler (self, other, damage, DMG_TYPE_OTHER);
if (self.health <= 5) if (self.health <= 5)
GiveAchievement(7, self); GiveAchievement(7, self);

View file

@ -261,14 +261,17 @@ float map_compatibility_mode;
#define MELEE_NORMAL 15 #define MELEE_NORMAL 15
#define MELEE_LUNGED 16 #define MELEE_LUNGED 16
#define S_HEADSHOT 1 #define DMG_TYPE_HEADSHOT 1 // Player-inflicted: Headshot
#define S_KNIFE 2 #define DMG_TYPE_MELEE 2 // Player-inflicted: Melee
#define S_NORMAL 3 #define DMG_TYPE_UPPERTORSO 3 // Player-inflicted: Upper torso shot
#define S_ZOMBIE 4 #define DMG_TYPE_LOWERTORSO 4 // Player-inflicted: Lower torso shot
#define S_EXPLOSIVE 5 #define DMG_TYPE_EXPLOSIVE 5 // Player-inflicted: Non-grenade explosive weapon
#define S_ZAPPER 6 #define DMG_TYPE_FLAMETHROWER 6 // Player-inflicted: Flamethrower
#define S_TESLA 7 #define DMG_TYPE_GRENADE 7 // Player-inflicted: Grenade-based weapons (includes Ray Gun)
#define S_FLAME 8 #define DMG_TYPE_TESLA 8 // Player-inflicted: Wunderwaffe
#define DMG_TYPE_ZOMBIESWIPE 9 // Zombie-inflicted: Any attack on Player
#define DMG_TYPE_ELECTRICTRAP 10 // Trap-inflicted: Electric trap damage
#define DMG_TYPE_OTHER 11 // For use with misc. damage infliction
//Perk types //Perk types
#define P_JUG 1 #define P_JUG 1