]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/mutators/mutator/damagetext/damagetext.qc
my best shot at float comprisons
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mutators / mutator / damagetext / damagetext.qc
index d68feda3a2b221e3f327214b2a365b148108f138..7fd53f8745ebde58edf46c7b2a00b36d787188cd 100644 (file)
@@ -1,5 +1,7 @@
 #include "damagetext.qh"
 
+#include "lib/math.qh"
+
 #define DAMAGETEXT_PRECISION_MULTIPLIER 128
 #define DAMAGETEXT_SHORT_LIMIT 256 // the smallest value that we can't send as short - 2^15 (signed short) / DAMAGETEXT_PRECISION_MULTIPLIER
 
@@ -12,7 +14,8 @@ const int DTFLAG_NO_POTENTIAL = BIT(5);
 
 REGISTER_MUTATOR(damagetext, true);
 
-#if defined(CSQC) || defined(MENUQC)
+// || defined(MENUQC)
+#if defined(CSQC)
 // no translatable cvar description please
 AUTOCVAR_SAVE(cl_damagetext,                        bool,   true,       "Draw damage dealt where you hit the enemy");
 AUTOCVAR_SAVE(cl_damagetext_format,                 string, "-{total}", "How to format the damage text. {health}, {armor}, {total}, {potential}: full damage not capped to target's health, {potential_health}: health damage not capped to target's health");
@@ -101,6 +104,8 @@ CLASS(DamageText, Object)
         int potential = rint(this.m_potential_damage / DAMAGETEXT_PRECISION_MULTIPLIER);
         int potential_health = rint((this.m_potential_damage - this.m_armordamage) / DAMAGETEXT_PRECISION_MULTIPLIER);
 
+        bool redundant = almost_equals_eps(this.m_healthdamage + this.m_armordamage, this.m_potential_damage, 10);
+
         string s = autocvar_cl_damagetext_format;
         s = strreplace("{armor}", (
             (this.m_armordamage == 0 && autocvar_cl_damagetext_format_hide_redundant)
@@ -108,12 +113,12 @@ CLASS(DamageText, Object)
                 : sprintf("%d", armor)
             ), s);
         s = strreplace("{potential}", (
-            (this.m_potential_damage == this.m_healthdamage + this.m_armordamage && autocvar_cl_damagetext_format_hide_redundant)
+            (redundant && autocvar_cl_damagetext_format_hide_redundant)
                 ? ""
                 : sprintf("%d", potential)
             ), s);
         s = strreplace("{potential_health}", (
-            (this.m_potential_damage - this.m_armordamage == this.m_healthdamage && autocvar_cl_damagetext_format_hide_redundant)
+            (redundant && autocvar_cl_damagetext_format_hide_redundant)
                 ? ""
                 : sprintf("%d", potential_health)
             ), s);
@@ -138,7 +143,7 @@ CLASS(DamageText, Object)
             if (closing_pos == -1 || closing_pos <= opening_pos) break;
             s = strcat(
                 substring(s, 0, opening_pos),
-                substring(s, closing_pos + 1, strlen(s))
+                substring_range(s, closing_pos + 1, strlen(s))
             );
         }
 
@@ -171,7 +176,7 @@ ENDCLASS(DamageText)
 REGISTER_NET_TEMP(damagetext)
 
 #ifdef SVQC
-AUTOCVAR(sv_damagetext, int, 2, _("<= 0: disabled, >= 1: spectators, >= 2: players, >= 3: all players"));
+AUTOCVAR(sv_damagetext, int, 2, "<= 0: disabled, >= 1: spectators, >= 2: players, >= 3: all players");
 #define SV_DAMAGETEXT_DISABLED()        (autocvar_sv_damagetext <= 0 /* disabled */)
 #define SV_DAMAGETEXT_SPECTATORS_ONLY() (autocvar_sv_damagetext >= 1 /* spectators only */)
 #define SV_DAMAGETEXT_PLAYERS()         (autocvar_sv_damagetext >= 2 /* players */)
@@ -198,7 +203,7 @@ MUTATOR_HOOKFUNCTION(damagetext, PlayerDamaged) {
             if (armor >= DAMAGETEXT_SHORT_LIMIT) flags |= DTFLAG_BIG_ARMOR;
             if (potential_damage >= DAMAGETEXT_SHORT_LIMIT) flags |= DTFLAG_BIG_POTENTIAL;
             if (!armor) flags |= DTFLAG_NO_ARMOR;
-            if (fabs((armor + health) - potential_damage) < 0.0001) flags |= DTFLAG_NO_POTENTIAL;
+            if (almost_equals_eps(armor + health, potential_damage, 10)) flags |= DTFLAG_NO_POTENTIAL;
 
             msg_entity = it;
             WriteHeader(MSG_ONE, damagetext);