]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
my best shot at float comprisons
authorMartin Taibr <taibr.martin@gmail.com>
Fri, 24 Feb 2017 01:16:32 +0000 (02:16 +0100)
committerMartin Taibr <taibr.martin@gmail.com>
Fri, 24 Feb 2017 01:16:32 +0000 (02:16 +0100)
qcsrc/common/mutators/mutator/damagetext/damagetext.qc
qcsrc/lib/float.qh
qcsrc/lib/math.qh

index 04d57e2b5b69ca2adfa87b42ddd3c9d6c838e7e1..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
 
@@ -102,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)
@@ -109,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_healthdamage + this.m_armordamage && autocvar_cl_damagetext_format_hide_redundant)
+            (redundant && autocvar_cl_damagetext_format_hide_redundant)
                 ? ""
                 : sprintf("%d", potential_health)
             ), s);
@@ -199,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);
index 946319e4439ab110f0b46de4b2b9af8c119c6a8a..b4d1f0bd768c785f103ad3886f5453769e10c2ff 100644 (file)
@@ -1,3 +1,4 @@
 #pragma once
 
 const float FLOAT_MAX = 340282346638528859811704183484516925440.0f;
+const float FLOAT_EPSILON = 0.00000011920928955078125f;
index 92d45bf142573663919fcfe5b6f93f09dc2a8f16..f314afad58a9633dd11923c7cb8aa3f7f523c766 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "lib/float.qh"
+
 void mean_accumulate(entity e, .float a, .float c, float mean, float value, float weight)
 {
        if (weight == 0) return;
@@ -176,6 +178,12 @@ float almost_equals(float a, float b)
        return a - b < eps && b - a < eps;
 }
 
+float almost_equals_eps(float a, float b, float times_eps)
+{
+       float eps = (max(a, -a) + max(b, -b)) * FLOAT_EPSILON * times_eps;
+       return a - b < eps && b - a < eps;
+}
+
 float almost_in_bounds(float a, float b, float c)
 {
        float eps = (max(a, -a) + max(c, -c)) * 0.001;