Accuracy: share with spectators
authorTimePath <andrew.hardaker1995@gmail.com>
Mon, 26 Oct 2015 09:30:31 +0000 (20:30 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Mon, 26 Oct 2015 09:31:32 +0000 (20:31 +1100)
qcsrc/client/hud.qc
qcsrc/client/main.qc
qcsrc/client/scoreboard.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/weapons/accuracy.qc
qcsrc/server/weapons/accuracy.qh

index a00a9c3..7403d28 100644 (file)
@@ -339,8 +339,9 @@ int weaponorder_cmp(int i, int j, entity pass)
        return aj - ai; // the string is in REVERSE order (higher prio at the right is what we want, but higher prio first is the string)
 }
 
-void HUD_Weapons(void)
-{SELFPARAM();
+void HUD_Weapons()
+{
+       SELFPARAM();
        // declarations
        WepSet weapons_stat = WepSet_GetFromStat();
        int i;
index d43c0bb..0f84b7f 100644 (file)
@@ -636,33 +636,27 @@ void Ent_RandomSeed()
        psrandom(s);
 }
 
-void Ent_ReadAccuracy(void)
+void Ent_ReadAccuracy()
 {
-    int f, w;
     int sf = ReadInt24_t();
-       if(sf == 0)
-       {
-               for(w = 0; w <= WEP_LAST - WEP_FIRST; ++w)
+       if (sf == 0) {
+               for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w)
                        weapon_accuracy[w] = -1;
                return;
        }
 
-       for(w = 0, f = 1; w <= WEP_LAST - WEP_FIRST; ++w)
-       {
-               if(sf & f)
-               {
+       int f = 1;
+       for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w) {
+               if (sf & f) {
             int b = ReadByte();
-                       if(b == 0)
+                       if (b == 0)
                                weapon_accuracy[w] = -1;
-                       else if(b == 255)
+                       else if (b == 255)
                                weapon_accuracy[w] = 1.0; // no better error handling yet, sorry
                        else
                                weapon_accuracy[w] = (b - 1.0) / 100.0;
                }
-               if(f == 0x800000)
-                       f = 1;
-               else
-                       f *= 2;
+               f = (f == 0x800000) ? 1 : f * 2;
        }
 }
 
index 24cfe46..97793c8 100644 (file)
@@ -995,35 +995,28 @@ float HUD_WouldDrawScoreboard() {
 
 float average_accuracy;
 vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
-{SELFPARAM();
+{
+       SELFPARAM();
        WepSet weapons_stat = WepSet_GetFromStat();
        WepSet weapons_inmap = WepSet_GetFromStat_InMap();
        float initial_posx = pos.x;
-       int i;
-       float weapon_stats;
        int disownedcnt = 0;
-       for(i = WEP_FIRST; i <= WEP_LAST; ++i)
-       {
+       for (int i = WEP_FIRST; i <= WEP_LAST; ++i) {
                setself(get_weaponinfo(i));
-               if(!self.weapon)
-                       continue;
+               if (!self.weapon) continue;
 
-               weapon_stats = weapon_accuracy[i-WEP_FIRST];
+               int weapon_stats = weapon_accuracy[i - WEP_FIRST];
 
-               if(weapon_stats < 0 && !(weapons_stat & WepSet_FromWeapon(i) || weapons_inmap & WepSet_FromWeapon(i)))
+               if (weapon_stats < 0 && !(weapons_stat & WepSet_FromWeapon(i) || weapons_inmap & WepSet_FromWeapon(i)))
                        ++disownedcnt;
        }
 
        int weapon_cnt = (Weapons_COUNT - 1) - disownedcnt;
+       if (weapon_cnt <= 0) return pos;
 
-       if(weapon_cnt <= 0)
-               return pos;
-
-       int rows;
-       if(autocvar_scoreboard_accuracy_doublerows && weapon_cnt >= floor((Weapons_COUNT - 1) * 0.5))
+       int rows = 1;
+       if (autocvar_scoreboard_accuracy_doublerows && weapon_cnt >= floor((Weapons_COUNT - 1) * 0.5))
                rows = 2;
-       else
-               rows = 1;
        int columnns = ceil(weapon_cnt / rows);
 
        float height = 40;
@@ -1044,24 +1037,24 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
        drawborderlines(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, DRAWFLAG_NORMAL);
 
        // column highlighting
-       for(i = 0; i < columnns; ++i)
+       for (int i = 0; i < columnns; ++i)
        {
-               if(!(i % 2))
+               if ((i % 2) == 0)
                        drawfill(pos + '1 0 0' * weapon_width * rows * i, '0 1 0' * height * rows + '1 0 0' * weapon_width * rows, '0 0 0', scoreboard_alpha_bg * 0.2, DRAWFLAG_NORMAL);
        }
 
        // row highlighting
-       for(i = 0; i < rows; ++i)
+       for (int i = 0; i < rows; ++i)
        {
                drawfill(pos + '0 1 0' * weapon_height + '0 1 0' * height * i, '1 0 0' * sbwidth + '0 1 0' * fontsize, '1 1 1', scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
        }
 
        average_accuracy = 0;
        int weapons_with_stats = 0;
-       if(rows == 2)
+       if (rows == 2)
                pos.x += weapon_width / 2;
 
-       if(autocvar_scoreboard_accuracy_nocolors)
+       if (autocvar_scoreboard_accuracy_nocolors)
                rgb = '1 1 1';
        else
                Accuracy_LoadColors();
@@ -1069,19 +1062,17 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
        float oldposx = pos.x;
        vector tmpos = pos;
 
-       int column;
-       for(i = WEP_FIRST, column = 0; i <= WEP_LAST; ++i)
-       {
+       int column = 0;
+       for (int i = WEP_FIRST; i <= WEP_LAST; ++i) {
                setself(get_weaponinfo(i));
-               if (!self.weapon)
-                       continue;
-               weapon_stats = weapon_accuracy[i-WEP_FIRST];
+               if (!self.weapon) continue;
+               int weapon_stats = weapon_accuracy[i - WEP_FIRST];
 
-               if(weapon_stats < 0 && !(weapons_stat & WepSet_FromWeapon(i) || weapons_inmap & WepSet_FromWeapon(i)))
+               if (weapon_stats < 0 && !(weapons_stat & WepSet_FromWeapon(i) || weapons_inmap & WepSet_FromWeapon(i)))
                        continue;
 
                float weapon_alpha;
-               if(weapon_stats >= 0)
+               if (weapon_stats >= 0)
                        weapon_alpha = scoreboard_alpha_fg;
                else
                        weapon_alpha = 0.2 * scoreboard_alpha_fg;
@@ -1089,7 +1080,7 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
                // weapon icon
                drawpic_aspect_skin(tmpos, self.model2, '1 0 0' * weapon_width + '0 1 0' * weapon_height, '1 1 1', weapon_alpha, DRAWFLAG_NORMAL);
                // the accuracy
-               if(weapon_stats >= 0) {
+               if (weapon_stats >= 0) {
                        weapons_with_stats += 1;
                        average_accuracy += weapon_stats; // store sum of all accuracies in average_accuracy
 
@@ -1106,7 +1097,7 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
                }
                tmpos.x += weapon_width * rows;
                pos.x += weapon_width * rows;
-               if(rows == 2 && column == columnns - 1) {
+               if (rows == 2 && column == columnns - 1) {
                        tmpos.x = oldposx;
                        tmpos.y += height;
                        pos.y += height;
@@ -1114,7 +1105,7 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
                ++column;
        }
 
-       if(weapons_with_stats)
+       if (weapons_with_stats)
                average_accuracy = floor((average_accuracy * 100 / weapons_with_stats) + 0.5);
 
        pos.y += height;
@@ -1370,7 +1361,7 @@ void HUD_DrawScoreboard()
                }
                pos = HUD_DrawScoreboardRankings(pos, playerslots[player_localnum], rgb, bg_size);
        }
-       else if(autocvar_scoreboard_accuracy && spectatee_status == 0 && !warmup_stage && gametype != MAPINFO_TYPE_NEXBALL) {
+       else if (autocvar_scoreboard_accuracy && !warmup_stage && gametype != MAPINFO_TYPE_NEXBALL) {
                if(teamplay)
                        pos = HUD_DrawScoreboardAccuracyStats(pos, Team_ColorRGB(myteam), bg_size);
                else
index 3a4680e..604e9ee 100644 (file)
@@ -446,11 +446,6 @@ void GetCvars(float f)
        GetCvars_handleFloat(s, f, cvar_cl_noantilag, "cl_noantilag");
        GetCvars_handleFloat(s, f, cvar_cl_voice_directional, "cl_voice_directional");
        GetCvars_handleFloat(s, f, cvar_cl_voice_directional_taunt_attenuation, "cl_voice_directional_taunt_attenuation");
-       GetCvars_handleFloat(s, f, cvar_cl_accuracy_data_share, "cl_accuracy_data_share");
-       GetCvars_handleFloat(s, f, cvar_cl_accuracy_data_receive, "cl_accuracy_data_receive");
-
-       self.cvar_cl_accuracy_data_share = boolean(self.cvar_cl_accuracy_data_share);
-       self.cvar_cl_accuracy_data_receive = boolean(self.cvar_cl_accuracy_data_receive);
 
        GetCvars_handleFloatOnce(s, f, cvar_cl_gunalign, "cl_gunalign");
        GetCvars_handleFloat(s, f, cvar_cl_allow_uid2name, "cl_allow_uid2name");
index 7d1633f..f8bc6a1 100644 (file)
@@ -6,43 +6,32 @@
 #include "../../common/util.qh"
 #include "../../common/weapons/all.qh"
 
-float accuracy_byte(float n, float d)
+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);
 
-       a = self.owner;
-       if(IS_SPEC(a))
-               a = a.enemy;
+       entity a = this.owner;
+       if (IS_SPEC(a)) a = a.enemy;
        a = 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 && !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,11 +39,10 @@ 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 = e.accuracy = new(accuracy);
+       a.owner = e;
+       a.drawonlytoclient = e;
+       Net_LinkEntity(a, false, 0, accuracy_send);
 }
 
 void accuracy_free(entity e)
@@ -72,60 +60,53 @@ void accuracy_resend(entity e)
 .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 = 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;
+       entity e; FOR_EACH_CLIENT(e) if (IS_SPEC(e)) if (e.enemy == this) {
+               e.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 (targ.deadflag != DEAD_NO) return false;
+       if (targ.frozen) 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;
 }
index e8d22d9..33c1fbf 100644 (file)
@@ -1,8 +1,10 @@
 #ifndef ACCURACY_H
 #define ACCURACY_H
 
-.float cvar_cl_accuracy_data_share;
-.float cvar_cl_accuracy_data_receive;
+.bool cvar_cl_accuracy_data_share;
+REPLICATE(cvar_cl_accuracy_data_share, bool, "cl_accuracy_data_share");
+.bool cvar_cl_accuracy_data_receive;
+REPLICATE(cvar_cl_accuracy_data_receive, bool, "cl_accuracy_data_receive");
 
 .entity accuracy;
 .float accuracy_frags[Weapons_MAX];
@@ -24,6 +26,6 @@ void accuracy_resend(entity e);
 void accuracy_add(entity e, float w, float fired, float hit);
 
 // helper
-float accuracy_isgooddamage(entity attacker, entity targ);
-float accuracy_canbegooddamage(entity attacker);
+bool accuracy_isgooddamage(entity attacker, entity targ);
+bool accuracy_canbegooddamage(entity attacker);
 #endif