]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/weapons/accuracy.qc
Merge branch 'master' into terencehill/accuracy_shotgun
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / weapons / accuracy.qc
index 7d1633f7f34124e6de945eb2fd17657c3b47daec..879dd88327bdf17824d08dfd85c7a819ceb4010b 100644 (file)
@@ -1,48 +1,38 @@
 #include "accuracy.qh"
 
-#include "../mutators/all.qh"
-#include "../../common/constants.qh"
-#include "../../common/teams.qh"
-#include "../../common/util.qh"
-#include "../../common/weapons/all.qh"
-
-float accuracy_byte(float n, float d)
+#include "../mutators/_mod.qh"
+#include <common/constants.qh>
+#include <common/net_linked.qh>
+#include <common/teams.qh>
+#include <common/util.qh>
+#include <common/weapons/_all.qh>
+
+int accuracy_byte(float n, float d)
 {
-       //printf("accuracy: %d / %d\n", n, d);
-       if(n <= 0)
-               return 0;
-       if(n > d)
-               return 255;
+       if (n <= 0) return 0;
+       if (n > d) return 255;
        return 1 + rint(n * 100.0 / d);
 }
 
 bool accuracy_send(entity this, entity to, int sf)
 {
-       int w, f;
-       entity a;
-       WriteByte(MSG_ENTITY, ENT_CLIENT_ACCURACY);
+       WriteHeader(MSG_ENTITY, ENT_CLIENT_ACCURACY);
 
-       a = self.owner;
-       if(IS_SPEC(a))
-               a = a.enemy;
-       a = a.accuracy;
+       entity a = this.owner;
+       if (IS_SPEC(a)) a = a.enemy;
+       a = CS(a).accuracy;
 
-       if(to != a.owner)
-               if (!(self.owner.cvar_cl_accuracy_data_share && autocvar_sv_accuracy_data_share))
+       if (to != a.owner)
+               if (!autocvar_sv_accuracy_data_share && !CS(a.owner).cvar_cl_accuracy_data_share)
                        sf = 0;
        // note: zero sendflags can never be sent... so we can use that to say that we send no accuracy!
        WriteInt24_t(MSG_ENTITY, sf);
-       if(sf == 0)
-               return true;
+       if (sf == 0) return true;
        // note: we know that client and server agree about SendFlags...
-       for(w = 0, f = 1; w <= WEP_LAST - WEP_FIRST; ++w)
-       {
-               if(sf & f)
-                       WriteByte(MSG_ENTITY, accuracy_byte(self.(accuracy_hit[w]), self.(accuracy_fired[w])));
-               if(f == 0x800000)
-                       f = 1;
-               else
-                       f *= 2;
+       int f = 1;
+       for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w) {
+               if (sf & f) WriteByte(MSG_ENTITY, accuracy_byte(a.accuracy_hit[w], a.accuracy_fired[w]));
+               f = (f == 0x800000) ? 1 : f * 2;
        }
        return true;
 }
@@ -50,82 +40,72 @@ bool accuracy_send(entity this, entity to, int sf)
 // init/free
 void accuracy_init(entity e)
 {
-       e.accuracy = spawn();
-       e.accuracy.owner = e;
-       e.accuracy.classname = "accuracy";
-       e.accuracy.drawonlytoclient = e;
-       Net_LinkEntity(e.accuracy, false, 0, accuracy_send);
+       entity a = CS(e).accuracy = new_pure(accuracy);
+       a.owner = e;
+       a.drawonlytoclient = e;
+       Net_LinkEntity(a, false, 0, accuracy_send);
 }
 
 void accuracy_free(entity e)
 {
-       remove(e.accuracy);
+       delete(CS(e).accuracy);
 }
 
 // force a resend of a player's accuracy stats
 void accuracy_resend(entity e)
 {
-       e.accuracy.SendFlags = 0xFFFFFF;
+       CS(e).accuracy.SendFlags = 0xFFFFFF;
 }
 
 // update accuracy stats
-.float hit_time;
+//.float hit_time;
 .float fired_time;
 
-void accuracy_add(entity e, int w, float fired, float hit)
+void accuracy_add(entity this, int w, int fired, int hit)
 {
-       entity a;
-       float b;
-       if(IS_INDEPENDENT_PLAYER(e))
-               return;
-       a = e.accuracy;
-       if(!a || !(hit || fired))
-               return;
+       if (IS_INDEPENDENT_PLAYER(this)) return;
+       entity a = CS(this).accuracy;
+       if (!a) return;
+       if (!hit && !fired) return;
        w -= WEP_FIRST;
-       b = accuracy_byte(a.(accuracy_hit[w]), a.(accuracy_fired[w]));
-       if(hit)
-               a.(accuracy_hit[w]) += hit;
-       if(fired)
-               a.(accuracy_fired[w]) += fired;
-
-    if(hit && a.hit_time != time) // only run this once per frame
-    {
-        a.(accuracy_cnt_hit[w]) += 1;
+       int b = accuracy_byte(a.accuracy_hit[w], a.accuracy_fired[w]);
+       if (hit)    a.accuracy_hit  [w] += hit;
+       if (fired)  a.accuracy_fired[w] += fired;
+
+    if (hit && a.hit_time != time) { // only run this once per frame
+        a.accuracy_cnt_hit[w] += 1;
         a.hit_time = time;
     }
 
-    if(fired && a.fired_time != time) // only run this once per frame
-    {
-        a.(accuracy_cnt_fired[w]) += 1;
+    if (fired && a.fired_time != time) { // only run this once per frame
+        a.accuracy_cnt_fired[w] += 1;
         a.fired_time = time;
     }
 
-       if(b == accuracy_byte(a.(accuracy_hit[w]), a.(accuracy_fired[w])))
-               return;
-       w = pow(2, w % 24);
-       a.SendFlags |= w;
-       FOR_EACH_CLIENT(a)
-               if(IS_SPEC(a))
-                       if(a.enemy == e)
-                               a.SendFlags |= w;
+       if (b == accuracy_byte(a.accuracy_hit[w], a.accuracy_fired[w])) return; // no change
+       int sf = 1 << (w % 24);
+       a.SendFlags |= sf;
+       FOREACH_CLIENT(IS_SPEC(it) && it.enemy == this, { CS(it).accuracy.SendFlags |= sf; });
 }
 
-float accuracy_isgooddamage(entity attacker, entity targ)
+bool accuracy_isgooddamage(entity attacker, entity targ)
 {
-       float mutator_check = MUTATOR_CALLHOOK(AccuracyTargetValid, attacker, targ);
-
-       if(!warmup_stage)
-       if(targ.deadflag == DEAD_NO)
-       if(!targ.frozen)
-       if(mutator_check == MUT_ACCADD_INVALID || (mutator_check == MUT_ACCADD_VALID && IS_CLIENT(targ)))
-       if(DIFF_TEAM(attacker, targ))
-               return true;
-       return false;
+       int mutator_check = MUTATOR_CALLHOOK(AccuracyTargetValid, attacker, targ);
+
+       if (warmup_stage) return false;
+       if (IS_DEAD(targ) && time > targ.death_time) return false;
+       if (STAT(FROZEN, targ) && time > targ.freeze_time) return false;
+       if (SAME_TEAM(attacker, targ)) return false;
+
+       if (mutator_check == MUT_ACCADD_INVALID) return true;
+
+       if (mutator_check != MUT_ACCADD_VALID) return false;
+       if (!IS_CLIENT(targ)) return false;
+
+       return true;
 }
 
-float accuracy_canbegooddamage(entity attacker)
+bool accuracy_canbegooddamage(entity attacker)
 {
-       if(!warmup_stage)
-               return true;
-       return false;
+       return !warmup_stage;
 }