From 466a3c6481161c08396a70d511f2feba4055372a Mon Sep 17 00:00:00 2001 From: terencehill Date: Tue, 23 Apr 2024 17:00:10 +0200 Subject: [PATCH] Optimize damagetext code by spawning only one damagetext entity when player is hit by multiple projectiles at the same time, e.g. shotgun. It reduces CPU usage, networked data and precision errors --- .../mutator/damagetext/sv_damagetext.qc | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/qcsrc/common/mutators/mutator/damagetext/sv_damagetext.qc b/qcsrc/common/mutators/mutator/damagetext/sv_damagetext.qc index c244d170d..d76ecee0e 100644 --- a/qcsrc/common/mutators/mutator/damagetext/sv_damagetext.qc +++ b/qcsrc/common/mutators/mutator/damagetext/sv_damagetext.qc @@ -64,6 +64,22 @@ MUTATOR_HOOKFUNCTION(damagetext, PlayerDamaged) { float potential_damage = M_ARGV(6, float); if(DEATH_WEAPONOF(deathtype) == WEP_VAPORIZER) return; + static entity net_text_prev; + static float net_damagetext_prev_time; + + bool multiple = (net_damagetext_prev_time == time && net_text_prev && !wasfreed(net_text_prev) + && net_text_prev.realowner == attacker && net_text_prev.enemy == hit + && net_text_prev.dent_net_deathtype == deathtype); + + if (multiple) + { + // damage of multiple projectiles hitting player at the same time, e.g. shotgun + // is accumulated on the same damagetext entity + health += net_text_prev.dent_net_health; + armor += net_text_prev.dent_net_armor; + potential_damage += net_text_prev.dent_net_potential; + } + int flags = 0; if (SAME_TEAM(hit, attacker)) flags |= DTFLAG_SAMETEAM; if (health >= DAMAGETEXT_SHORT_LIMIT) flags |= DTFLAG_BIG_HEALTH; @@ -72,6 +88,14 @@ MUTATOR_HOOKFUNCTION(damagetext, PlayerDamaged) { if (!armor) flags |= DTFLAG_NO_ARMOR; if (almost_equals_eps(armor + health, potential_damage, 5)) flags |= DTFLAG_NO_POTENTIAL; + if (multiple) + { + net_text_prev.dent_net_flags = flags; + net_text_prev.dent_net_health = health; + net_text_prev.dent_net_armor = armor; + net_text_prev.dent_net_potential = potential_damage; + return; + } entity net_text = new_pure(net_damagetext); net_text.realowner = attacker; net_text.enemy = hit; @@ -81,6 +105,9 @@ MUTATOR_HOOKFUNCTION(damagetext, PlayerDamaged) { net_text.dent_net_armor = armor; net_text.dent_net_potential = potential_damage; + net_text_prev = net_text; + net_damagetext_prev_time = time; + setthink(net_text, SUB_Remove); net_text.nextthink = (time > 10) ? (time + 0.5) : 10; // allow a buffer from start time for clients to load in -- 2.39.2