From 6d55ebbcec0d3bf7f46652da93da926085c652b3 Mon Sep 17 00:00:00 2001 From: cypress Date: Sun, 16 Jun 2024 14:04:15 -0700 Subject: [PATCH] SERVER: Improve accuracy and readability of damage and score components --- source/server/ai/zombie_core.qc | 10 ++-- source/server/damage.qc | 69 ++++++++++++++++++--------- source/server/defs/custom.qc | 6 +++ source/server/entities/doors.qc | 2 +- source/server/entities/func.qc | 4 +- source/server/entities/traps.qc | 4 +- source/server/entities/triggers.qc | 2 +- source/server/weapons/flamethrower.qc | 2 +- source/server/weapons/tesla.qc | 7 +-- source/server/weapons/weapon_core.qc | 31 ++++++++---- source/shared/shared_defs.qc | 19 ++++---- 11 files changed, 98 insertions(+), 58 deletions(-) diff --git a/source/server/ai/zombie_core.qc b/source/server/ai/zombie_core.qc index 7d4b3f8..d77c129 100644 --- a/source/server/ai/zombie_core.qc +++ b/source/server/ai/zombie_core.qc @@ -400,7 +400,7 @@ void() Zombie_Think = //called every frame for zombies Effect_Fire(self.origin); 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; if (self.fire_timeout < time) @@ -418,7 +418,7 @@ void() Zombie_Think = //called every frame for zombies if (self.bleedingtime < time && !self.head.deadflag) { 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 @@ -634,9 +634,9 @@ void() zombie_attack2 = if(vlen(self.enemy.origin - self.origin) < 64) { if (self.classname == "ai_dog") - DamageHandler (self.enemy, self, 40, S_ZOMBIE); + DamageHandler (self.enemy, self, 40, DMG_TYPE_ZOMBIESWIPE); else - DamageHandler (self.enemy, self, 50, S_ZOMBIE); + DamageHandler (self.enemy, self, 50, DMG_TYPE_ZOMBIESWIPE); } } else return; @@ -747,7 +747,7 @@ void() zombie_attack_through_window = { 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; } diff --git a/source/server/damage.qc b/source/server/damage.qc index 9b99f63..5daf0a1 100644 --- a/source/server/damage.qc +++ b/source/server/damage.qc @@ -27,6 +27,15 @@ */ 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() teddy_react; @@ -430,46 +439,58 @@ void(entity attacker, float d_style) DieHandler = float points_earned = 0; switch(d_style) { - case S_HEADSHOT: - points_earned = 100; + case DMG_TYPE_HEADSHOT: + points_earned = DMG_SCORE_HEADSHOT; attacker.headshots++; break; - case S_KNIFE: - points_earned = 130; + case DMG_TYPE_MELEE: + points_earned = DMG_SCORE_MELEE; break; - case S_TESLA: - points_earned = 50; + case DMG_TYPE_TESLA: + points_earned = DMG_SCORE_GRENADE; break; - case S_FLAME: - points_earned = 50; + case DMG_TYPE_FLAMETHROWER: + points_earned = DMG_SCORE_GRENADE; // override their death sound (FIXME: make a new sound..) sound(self, CHAN_BODY, "sounds/pu/drop.wav", 1, ATTN_NORM); 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: - points_earned = 60; + if (cvar("developer")) + bprint(PRINT_HIGH, "DieHandler: Received invalid style\n"); break; } - Player_AddScore(attacker, points_earned, true); } } void(entity victim, entity attacker, float damage, float d_style) DamageHandler = { // 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; entity old_self; if (victim.classname == "ai_zombie" || victim.classname == "ai_dog") { - if (attacker.classname == "player" && (victim.health - damage) > 0) { - Player_AddScore(attacker, 10, true); + if (attacker.classname == "player" && (victim.health - damage) > 0 && d_style != DMG_TYPE_OTHER) { + Player_AddScore(attacker, DMG_SCORE_STDDAMAGE, true); } 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) { makeCrawler(victim); GiveAchievement(3, attacker); @@ -528,7 +549,7 @@ void(entity victim, entity attacker, float damage, float d_style) DamageHandler victim.punchangle_y = distance_y; // 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); else 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 = { float final_damage = 0; + float damage_style = 0; entity ent; float multi, r; @@ -643,11 +665,11 @@ void(entity inflictor, entity attacker, float damage2, float mindamage, float ra if (final_damage < other.health) { - Player_AddScore(self, 10, false); + Player_AddScore(self, DMG_SCORE_STDDAMAGE, false); } else if (final_damage > other.health) { - Player_AddScore(self, 10, false); + Player_AddScore(self, DMG_SCORE_STDDAMAGE, false); } else { @@ -703,11 +725,7 @@ void(entity inflictor, entity attacker, float damage2, float mindamage, float ra self = oldself2; } 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") { 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)) // rounds is basically meaningless though.. wtf? final_damage = rounds + rint(random() * 350) + 150; + damage_style = DMG_TYPE_GRENADE; } else if (inflictor.classname == "projectile_grenade") { // projectile-based grenades (mustang & sally) seem to do // more damage than standard grenades. // (rounds + (rand 1200-5000)) final_damage = rounds + rint(random() * 3800) + 1200; + damage_style = DMG_TYPE_EXPLOSIVE; } else if (inflictor.classname == "rocket") { // rockets were kinda tricky to figure out, this is as close // as i can get and i'm not super confident.. // (rounds * (rand 0-100) * weapon_damage/500). final_damage = (rounds * rint(random() * 100)) * damage2/500; + damage_style = DMG_TYPE_EXPLOSIVE; } else if (inflictor.classname == "projectile_raybeam") { //final_damage = calculate_proximity_value(mindamage, damage2, inflictor.origin, ent.origin, radius); //bprint(PRINT_HIGH, strcat("damage: ", ftos(final_damage), "\n")); final_damage = damage2; + damage_style = DMG_TYPE_GRENADE; } else if (inflictor.classname == "player") { // phd flopper. final_damage = calculate_proximity_value(mindamage, damage2, inflictor.origin, ent.origin, radius); + damage_style = DMG_TYPE_GRENADE; } else { r = rounds; multi = 1.07; @@ -768,7 +791,7 @@ void(entity inflictor, entity attacker, float damage2, float mindamage, float ra if (final_damage > 0) { if (CanDamage (ent, inflictor)) - DamageHandler (ent, attacker, final_damage, S_EXPLOSIVE); + DamageHandler (ent, attacker, final_damage, damage_style); } ent = ent.chain; } diff --git a/source/server/defs/custom.qc b/source/server/defs/custom.qc index 278df76..99e0f0a 100644 --- a/source/server/defs/custom.qc +++ b/source/server/defs/custom.qc @@ -394,7 +394,13 @@ float sounds_playing; //.float OrgStuckCount; .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 hit_region; .float hitamount; .float laststep; diff --git a/source/server/entities/doors.qc b/source/server/entities/doors.qc index 71efa81..5422706 100644 --- a/source/server/entities/doors.qc +++ b/source/server/entities/doors.qc @@ -82,7 +82,7 @@ void() door_go_up; 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, // so let it just squash the object to death real fast diff --git a/source/server/entities/func.qc b/source/server/entities/func.qc index 121c7a5..7351c48 100644 --- a/source/server/entities/func.qc +++ b/source/server/entities/func.qc @@ -111,7 +111,7 @@ void () func_rotating_use = void() rot_crush = { - DamageHandler(self, other, 1, S_ZOMBIE); + DamageHandler(self, other, 1, DMG_TYPE_OTHER); } void () func_rotating = @@ -159,7 +159,7 @@ void() train_blocked = self.death_timer = time + 0.5; - DamageHandler(self, other, self.dmg, S_ZOMBIE); + DamageHandler(self, other, self.dmg, DMG_TYPE_OTHER); }; void() train_use = diff --git a/source/server/entities/traps.qc b/source/server/entities/traps.qc index 1e86fea..35e9b62 100644 --- a/source/server/entities/traps.qc +++ b/source/server/entities/traps.qc @@ -69,9 +69,9 @@ void() zapper_do_damage // Inflict Damage if (other.damage_timer < time) { if (other.perks & P_JUG) - DamageHandler(other, self, 50, S_ZAPPER); + DamageHandler(other, self, 50, DMG_TYPE_ELECTRICTRAP); else - DamageHandler(other, self, other.health, S_ZAPPER); + DamageHandler(other, self, other.health, DMG_TYPE_ELECTRICTRAP); other.damage_timer = time + 1.25; } // Inflict Speed Penalty diff --git a/source/server/entities/triggers.qc b/source/server/entities/triggers.qc index f29f16b..9f1e5f8 100644 --- a/source/server/entities/triggers.qc +++ b/source/server/entities/triggers.qc @@ -417,7 +417,7 @@ void() hurt_touch = (other.aistatus == "1" && !(self.spawnflags & HURT_SPAWNFLAG_NOAI))) { self.solid = SOLID_NOT; - DamageHandler(other, self, self.dmg, S_NORMAL); + DamageHandler(other, self, self.dmg, DMG_TYPE_OTHER); self.think = hurt_on; self.nextthink = time + 1; diff --git a/source/server/weapons/flamethrower.qc b/source/server/weapons/flamethrower.qc index 61e3cad..b05215a 100644 --- a/source/server/weapons/flamethrower.qc +++ b/source/server/weapons/flamethrower.qc @@ -89,7 +89,7 @@ void() Flame_Touch = Effect_Fire(target.origin); // 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 diff --git a/source/server/weapons/tesla.qc b/source/server/weapons/tesla.qc index 6e9eab9..b6508e2 100644 --- a/source/server/weapons/tesla.qc +++ b/source/server/weapons/tesla.qc @@ -85,7 +85,7 @@ void(entity hit_ent, entity arc_parent, entity arc_owner, float arc_num, float d // 50 points for waffe kills if(arc_owner.classname == "player") { 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); // print("Giving player ",ftos(damage), " damage.\n"); - if (other.perks & P_JUG) - DamageHandler(ent, self, damage, S_ZAPPER); - else - DamageHandler(ent, self, damage, S_ZAPPER); + DamageHandler(ent, self, damage, DMG_TYPE_ELECTRICTRAP); // ---------------------------------------- } diff --git a/source/server/weapons/weapon_core.qc b/source/server/weapons/weapon_core.qc index 9c96e06..4e62eb3 100644 --- a/source/server/weapons/weapon_core.qc +++ b/source/server/weapons/weapon_core.qc @@ -752,13 +752,18 @@ void Parse_Damage () = // DO NOT TOUCH } if (head_hit) - DamageHandler(body_ent,self, total_dmg, S_HEADSHOT); - else - DamageHandler(body_ent,self, total_dmg, S_NORMAL); + 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 + DamageHandler(body_ent,self, total_dmg, DMG_TYPE_UPPERTORSO); + } if (body_ent != world) { body_ent.washit = 0; body_ent.hitamount = 0; + body_ent.hit_region = 0; } } 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) { case "ai_zombie_head": f_damage = damage*getWeaponMultiplier(self.weapon, HEAD_X); + hit_ent.hit_region = HIT_REGION_HEAD; break; case "ai_zombie_larm": case "ai_zombie_rarm": f_damage = damage*getWeaponMultiplier(self.weapon, LIMBS_X); + hit_ent.hit_region = HIT_REGION_ARM; break; 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); - else + hit_ent.hit_region = HIT_REGION_TORSO_LOWER; + } + else { f_damage = damage*getWeaponMultiplier(self.weapon, UPPER_TORSO_X); + hit_ent.hit_region = HIT_REGION_TORSO_UPPER; + } break; default: f_damage = damage; @@ -1248,7 +1259,7 @@ void() WeaponCore_Melee = // Apply damage to the entity. if (trace_ent.takedamage) { 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. 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 != world) @@ -1716,8 +1727,8 @@ void() CheckPlayer = traceline(self.origin, self.origin + (v_up * -40), 0, self); if (trace_ent.classname == "player") { - DamageHandler(self, trace_ent, 100000, S_NORMAL); - DamageHandler(trace_ent, self, 100000, S_NORMAL); + DamageHandler(self, trace_ent, 100000, DMG_TYPE_OTHER); + DamageHandler(trace_ent, self, 100000, DMG_TYPE_OTHER); } } @@ -1749,7 +1760,7 @@ void() CheckPlayer = if (damage > 98) damage = 98; - DamageHandler (self, other, damage, S_ZOMBIE); + DamageHandler (self, other, damage, DMG_TYPE_OTHER); if (self.health <= 5) GiveAchievement(7, self); diff --git a/source/shared/shared_defs.qc b/source/shared/shared_defs.qc index 2de4cec..f9309a6 100644 --- a/source/shared/shared_defs.qc +++ b/source/shared/shared_defs.qc @@ -261,14 +261,17 @@ float map_compatibility_mode; #define MELEE_NORMAL 15 #define MELEE_LUNGED 16 -#define S_HEADSHOT 1 -#define S_KNIFE 2 -#define S_NORMAL 3 -#define S_ZOMBIE 4 -#define S_EXPLOSIVE 5 -#define S_ZAPPER 6 -#define S_TESLA 7 -#define S_FLAME 8 +#define DMG_TYPE_HEADSHOT 1 // Player-inflicted: Headshot +#define DMG_TYPE_MELEE 2 // Player-inflicted: Melee +#define DMG_TYPE_UPPERTORSO 3 // Player-inflicted: Upper torso shot +#define DMG_TYPE_LOWERTORSO 4 // Player-inflicted: Lower torso shot +#define DMG_TYPE_EXPLOSIVE 5 // Player-inflicted: Non-grenade explosive weapon +#define DMG_TYPE_FLAMETHROWER 6 // Player-inflicted: Flamethrower +#define DMG_TYPE_GRENADE 7 // Player-inflicted: Grenade-based weapons (includes Ray Gun) +#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 #define P_JUG 1