]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'Mario/ctf_rankings' into 'master'
authorMario <zacjardine@y7mail.com>
Sun, 29 Jan 2017 11:53:34 +0000 (11:53 +0000)
committerMario <zacjardine@y7mail.com>
Sun, 29 Jan 2017 11:53:34 +0000 (11:53 +0000)
Merge branch Mario/ctf_rankings (S merge request)

See merge request !405

1  2 
gamemodes.cfg
qcsrc/common/util.qh
qcsrc/server/mutators/mutator/gamemode_ctf.qc
qcsrc/server/race.qc

diff --combined gamemodes.cfg
index 4549fa801206a2809804eefe72fc87f5c1eb8a1e,5e941f1c115629d125525cb9903857ccfc4e2187..e46c30718ea9ad899959e0c76595b4bf22324822
@@@ -256,6 -256,7 +256,7 @@@ set g_ca_teams 
  set g_ctf 0 "Capture The Flag: take the enemy flag and bring it to yours at your base to score"
  set g_ctf_oneflag 0 "Allow oneflag CTF mode on maps that support it"
  set g_ctf_oneflag_reverse 0 "apply reverse mode to oneflag CTF (take flag to enemy bases to cap), overrides g_ctf_reverse only in oneflag, g_ctf_reverse still affects oneflag"
+ set g_ctf_leaderboard 0 "show top capture times in the scoreboard"
  set g_ctf_flag_return 1 "auto return the flag to base when touched by a teammate"
  set g_ctf_flag_return_carrying 0 "(manual return mode) auto return the flag to base if touched by a flag carrier"
  set g_ctf_flag_return_carried_radius 100 "allow flags to be returned by carrier if base is within this radius"
@@@ -326,6 -327,7 +327,6 @@@ set g_ctf_flag_neutral_skin 
  set g_ctf_flag_glowtrails 1
  set g_ctf_fullbrightflags 0
  set g_ctf_dynamiclights 0
 -set g_ctf_captimerecord_always 0 "always show capture time information when someone captures the flag"
  
  seta g_ctf_ignore_frags 0     "1: regular frags give no points"
  exec ctfscoring-samual.cfg
diff --combined qcsrc/common/util.qh
index 8a471d5949cfb3c164ddfe89634b987e2db75715,5211c7588fb00ebfa8a417aa75dc47d32ef39d86..13c4c0900817d5f8298df91435c3dcfc9c6e2c28
@@@ -49,8 -49,6 +49,8 @@@ void db_put(int db, string key, string 
  int buf_load(string filename);
  void buf_save(int buf, string filename);
  
 +// adding just 0.4 for race times so it rounds down in the .5 case (matching the timer display)
 +// FIXME it doesn't round properly
  #define TIME_TO_NTHS(t,n) floor((t) * (n) + 0.4)
  string format_time(float seconds);
  string mmsss(float t);
@@@ -61,6 -59,7 +61,7 @@@ const float TIME_FACTOR = 100
  #define TIME_ENCODED_TOSTRING(n) mmssss(n)
  #define RACE_RECORD "/race100record/"
  #define CTS_RECORD "/cts100record/"
+ #define CTF_RECORD "/ctf100record/"
  #define TIME_ENCODE(t) TIME_TO_NTHS(t, TIME_FACTOR)
  #define TIME_DECODE(n) ((n) / TIME_FACTOR)
  
index 1e4190be66798b47164b3ee43029b6c2de8ef5a5,fa39b42cad102d31c23b15c21643a158fbc6a8fb..badab51045c88f78b8a7185d25850ac467717d34
@@@ -153,6 -153,9 +153,9 @@@ void ctf_CaptureRecord(entity flag, ent
                db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"), player.netname);
                write_recordmarker(player, (time - cap_time), cap_time);
        }
+       if(autocvar_g_ctf_leaderboard && !ctf_oneflag)
+               race_setTime(GetMapname(), TIME_ENCODE(cap_time), player.crypto_idfp, player.netname, player, false);
  }
  
  bool ctf_Immediate_Return_Allowed(entity flag, entity toucher)
@@@ -1129,7 -1132,7 +1132,7 @@@ METHOD(Flag, giveTo, bool(Flag this, en
                                        else if(is_not_monster && (!toucher.flagcarried))
                                                ctf_Handle_Pickup(flag, toucher, PICKUP_DROPPED);
                                }
 -                              else
 +                              else if(!toucher.flagcarried)
                                        ctf_Handle_Retrieve(flag, toucher);
                        }
                        break;
@@@ -1357,7 -1360,7 +1360,7 @@@ void havocbot_calculate_middlepoint(
        entity f;
        vector s = '0 0 0';
        vector fo = '0 0 0';
 -      float n = 0;
 +      int n = 0;
  
        f = ctf_worldflaglist;
        while (f)
                fo = f.origin;
                s = s + fo;
                f = f.ctf_worldflagnext;
 +              n++;
        }
        if(!n)
                return;
 -      havocbot_ctf_middlepoint = s * (1.0 / n);
 -      havocbot_ctf_middlepoint_radius  = vlen(fo - havocbot_ctf_middlepoint);
 +      havocbot_ctf_middlepoint = s / n;
 +      havocbot_ctf_middlepoint_radius = vlen(fo - havocbot_ctf_middlepoint);
  }
  
  
@@@ -2171,6 -2173,42 +2174,42 @@@ MUTATOR_HOOKFUNCTION(ctf, ClientDisconn
        ctf_RemovePlayer(player);
  }
  
+ MUTATOR_HOOKFUNCTION(ctf, ClientConnect)
+ {
+       if(!autocvar_g_ctf_leaderboard)
+               return;
+       entity player = M_ARGV(0, entity);
+       if(IS_REAL_CLIENT(player))
+       {
+               for(int i = 1; i <= RANKINGS_CNT; ++i)
+               {
+                       race_SendRankings(i, 0, 0, MSG_ONE);
+               }
+       }
+ }
+ MUTATOR_HOOKFUNCTION(ctf, GetPressedKeys)
+ {
+       if(!autocvar_g_ctf_leaderboard)
+               return;
+       entity player = M_ARGV(0, entity);
+       if(player.cvar_cl_allow_uidtracking == 1 && player.cvar_cl_allow_uid2name == 1)
+       {
+               if (!player.stored_netname)
+                       player.stored_netname = strzone(uid2name(player.crypto_idfp));
+               if(player.stored_netname != player.netname)
+               {
+                       db_put(ServerProgsDB, strcat("/uid2name/", player.crypto_idfp), player.netname);
+                       strunzone(player.stored_netname);
+                       player.stored_netname = strzone(player.netname);
+               }
+       }
+ }
  MUTATOR_HOOKFUNCTION(ctf, PortalTeleport)
  {
        entity player = M_ARGV(0, entity);
@@@ -2221,7 -2259,7 +2260,7 @@@ MUTATOR_HOOKFUNCTION(ctf, PlayerUseKey
                                                        player.throw_antispam = time + autocvar_g_ctf_pass_wait;
                                                        return true;
                                                }
 -                                              else if(player.flagcarried)
 +                                              else if(player.flagcarried && !head.flagcarried)
                                                {
                                                        if(closest_target)
                                                        {
diff --combined qcsrc/server/race.qc
index 84afa1144736f1c278cbe47e5b0af3122a58597d,48c8e32ae2b41d993aecaa2867ef1f743a1607c1..1550cd2a3a425070054ecb7e1f5b2d1fbbb6b405
@@@ -26,31 -26,33 +26,33 @@@ void W_Porto_Fail(entity this, float fa
  
  float race_readTime(string map, float pos)
  {
-       string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
+       string rr = ((g_cts) ? CTS_RECORD : ((g_ctf) ? CTF_RECORD : RACE_RECORD));
  
        return stof(db_get(ServerProgsDB, strcat(map, rr, "time", ftos(pos))));
  }
  
  string race_readUID(string map, float pos)
  {
-       string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
+       string rr = ((g_cts) ? CTS_RECORD : ((g_ctf) ? CTF_RECORD : RACE_RECORD));
  
        return db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos)));
  }
  
  float race_readPos(string map, float t)
  {
-       float i;
-       for (i = 1; i <= RANKINGS_CNT; ++i)
-       if (race_readTime(map, i) == 0 || race_readTime(map, i) > t)
-               return i;
+       for(int i = 1; i <= RANKINGS_CNT; ++i)
+       {
+               int mytime = race_readTime(map, i);
+               if(!mytime || mytime > t)
+                       return i;
+       }
  
        return 0; // pos is zero if unranked
  }
  
  void race_writeTime(string map, float t, string myuid)
  {
-       string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
+       string rr = ((g_cts) ? CTS_RECORD : ((g_ctf) ? CTF_RECORD : RACE_RECORD));
  
        float newpos;
        newpos = race_readPos(map, t);
@@@ -87,7 -89,7 +89,7 @@@
  
  string race_readName(string map, float pos)
  {
-       string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
+       string rr = ((g_cts) ? CTS_RECORD : ((g_ctf) ? CTF_RECORD : RACE_RECORD));
  
        return uid2name(db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos))));
  }
@@@ -244,15 -246,13 +246,13 @@@ void race_SendStatus(float id, entity e
        });
  }
  
- void race_setTime(string map, float t, string myuid, string mynetname, entity e)
+ void race_setTime(string map, float t, string myuid, string mynetname, entity e, bool showmessage)
  {
        // netname only used TEMPORARILY for printing
-       float newpos, player_prevpos;
-       newpos = race_readPos(map, t);
+       int newpos = race_readPos(map, t);
  
-       float i;
-       player_prevpos = 0;
-       for(i = 1; i <= RANKINGS_CNT; ++i)
+       int player_prevpos = 0;
+       for(int i = 1; i <= RANKINGS_CNT; ++i)
        {
                if(race_readUID(map, i) == myuid)
                        player_prevpos = i;
        {
                oldrec = race_readTime(GetMapname(), player_prevpos);
                race_SendStatus(0, e); // "fail"
-               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_FAIL_RANKED, mynetname, player_prevpos, t, oldrec);
+               if(showmessage)
+                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_FAIL_RANKED, mynetname, player_prevpos, t, oldrec);
                return;
        }
        else if (!newpos)
                // no ranking, time worse than the worst ranked
                oldrec = race_readTime(GetMapname(), RANKINGS_CNT);
                race_SendStatus(0, e); // "fail"
-               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_FAIL_UNRANKED, mynetname, RANKINGS_CNT, t, oldrec);
+               if(showmessage)
+                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_FAIL_UNRANKED, mynetname, RANKINGS_CNT, t, oldrec);
                return;
        }
  
        // if the player does not have a UID we can unfortunately not store the record, as the rankings system relies on UIDs
        if(myuid == "")
        {
-               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_MISSING_UID, mynetname, t);
+               if(showmessage)
+                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_MISSING_UID, mynetname, t);
                return;
        }
  
 +      if(uid2name(myuid) == "^1Unregistered Player")
 +      {
 +              Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_MISSING_NAME, mynetname, t);
 +              return;
 +      }
 +
        oldrec = race_readTime(GetMapname(), newpos);
        oldrec_holder = race_readName(GetMapname(), newpos);
  
        // store new ranking
        race_writeTime(GetMapname(), t, myuid);
  
-       if (newpos == 1)
+       if (newpos == 1 && showmessage)
        {
                write_recordmarker(e, time - TIME_DECODE(t), TIME_DECODE(t));
                race_send_recordtime(MSG_ALL);
  
        if(newpos == player_prevpos)
        {
-               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_IMPROVED, mynetname, newpos, t, oldrec);
+               if(showmessage)
+                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_IMPROVED, mynetname, newpos, t, oldrec);
                if(newpos == 1) { race_SendStatus(3, e); } // "new server record"
                else { race_SendStatus(1, e); } // "new time"
        }
        else if(oldrec == 0)
        {
-               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_SET, mynetname, newpos, t);
+               if(showmessage)
+                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_SET, mynetname, newpos, t);
                if(newpos == 1) { race_SendStatus(3, e); } // "new server record"
                else { race_SendStatus(2, e); } // "new rank"
        }
        else
        {
-               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_BROKEN, mynetname, oldrec_holder, newpos, t, oldrec);
+               if(showmessage)
+                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_NEW_BROKEN, mynetname, oldrec_holder, newpos, t, oldrec);
                if(newpos == 1) { race_SendStatus(3, e); } // "new server record"
                else { race_SendStatus(2, e); } // "new rank"
        }
  
  void race_deleteTime(string map, float pos)
  {
-       string rr;
-       if(g_cts)
-               rr = CTS_RECORD;
-       else
-               rr = RACE_RECORD;
+       string rr = ((g_cts) ? CTS_RECORD : ((g_ctf) ? CTF_RECORD : RACE_RECORD));
  
-       float i;
-       for (i = pos; i <= RANKINGS_CNT; ++i)
+       for(int i = pos; i <= RANKINGS_CNT; ++i)
        {
+               string therank = ftos(i);
                if (i == RANKINGS_CNT)
                {
-                       db_remove(ServerProgsDB, strcat(map, rr, "time", ftos(i)));
-                       db_remove(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)));
+                       db_remove(ServerProgsDB, strcat(map, rr, "time", therank));
+                       db_remove(ServerProgsDB, strcat(map, rr, "crypto_idfp", therank));
                }
                else
                {
-                       db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(GetMapname(), i+1)));
-                       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(GetMapname(), i+1));
+                       db_put(ServerProgsDB, strcat(map, rr, "time", therank), ftos(race_readTime(GetMapname(), i+1)));
+                       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", therank), race_readUID(GetMapname(), i+1));
                }
        }
  
@@@ -368,6 -364,7 +370,6 @@@ void race_SendTime(entity e, float cp, 
                t += e.race_penalty_accumulator;
  
        t = TIME_ENCODE(t); // make integer
 -      // adding just 0.4 so it rounds down in the .5 case (matching the timer display)
  
        if(tvalid)
        if(cp == race_timed_checkpoint) // finish line
                        {
                                if(cp == race_timed_checkpoint)
                                {
-                                       race_setTime(GetMapname(), t, e.crypto_idfp, e.netname, e);
+                                       race_setTime(GetMapname(), t, e.crypto_idfp, e.netname, e, true);
                                        MUTATOR_CALLHOOK(Race_FinalCheckpoint, e);
                                }
                                if(t < recordtime || recordtime == 0)