From: Martin Taibr Date: Fri, 24 Feb 2017 01:16:32 +0000 (+0100) Subject: my best shot at float comprisons X-Git-Tag: xonotic-v0.8.2~169^2~2 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=5aec2ffb9528c6b6db21d0c09bdcac9038337fbd;p=xonotic%2Fxonotic-data.pk3dir.git my best shot at float comprisons --- diff --git a/qcsrc/common/mutators/mutator/damagetext/damagetext.qc b/qcsrc/common/mutators/mutator/damagetext/damagetext.qc index 04d57e2b5..7fd53f874 100644 --- a/qcsrc/common/mutators/mutator/damagetext/damagetext.qc +++ b/qcsrc/common/mutators/mutator/damagetext/damagetext.qc @@ -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); diff --git a/qcsrc/lib/float.qh b/qcsrc/lib/float.qh index 946319e44..b4d1f0bd7 100644 --- a/qcsrc/lib/float.qh +++ b/qcsrc/lib/float.qh @@ -1,3 +1,4 @@ #pragma once const float FLOAT_MAX = 340282346638528859811704183484516925440.0f; +const float FLOAT_EPSILON = 0.00000011920928955078125f; diff --git a/qcsrc/lib/math.qh b/qcsrc/lib/math.qh index 92d45bf14..f314afad5 100644 --- a/qcsrc/lib/math.qh +++ b/qcsrc/lib/math.qh @@ -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;