interesting metrics (idea by KrimZon) to maybe sort players in the
authordiv0 <div0@f962a42d-fe04-0410-a3ab-8c8b0445ebaa>
Sat, 23 Jan 2010 15:06:45 +0000 (15:06 +0000)
committerdiv0 <div0@f962a42d-fe04-0410-a3ab-8c8b0445ebaa>
Sat, 23 Jan 2010 15:06:45 +0000 (15:06 +0000)
scoreboard, immediately updates when overtaking (but, the code is
currently unused)

git-svn-id: svn://svn.icculus.org/nexuiz/trunk@8533 f962a42d-fe04-0410-a3ab-8c8b0445ebaa

data/qcsrc/server/cl_client.qc
data/qcsrc/server/race.qc
data/qcsrc/server/race.qh
data/qcsrc/server/scores_rules.qc

index a9b580c..72e9c4c 100644 (file)
@@ -3077,4 +3077,9 @@ void PlayerPostThink (void)
                WaypointSprite_UpdateHealth(self.waypointsprite_attachedforcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, cvar("g_balance_armor_blockpercent")));
        
        playerdemo_write();
+
+       /*
+       if(g_race)
+               dprint(sprintf("%f %.6f\n", time, race_GetFractionalLapCount(self)));
+       */
 }
index 77a4ef5..1760a6d 100644 (file)
@@ -1241,3 +1241,64 @@ void spawnfunc_trigger_race_penalty()
        if (!self.race_penalty)
                self.race_penalty = 5;
 }
+
+float race_GetFractionalLapCount(entity e)
+{
+       // interesting metrics (idea by KrimZon) to maybe sort players in the
+       // scoreboard, immediately updates when overtaking
+       //
+       // requires the track to be built so you never get farther away from the
+       // next checkpoint, though, and current Nexuiz race maps are not built that
+       // way
+       //
+       // also, this code is slow and would need optimization (i.e. "next CP"
+       // links on CP entities)
+
+       float l;
+       l = PlayerScore_Add(e, SP_RACE_LAPS, 0);
+       if(e.race_completed)
+               return l; // not fractional
+       
+       vector o0, o1;
+       float bestfraction, fraction;
+       entity lastcp, cp0, cp1;
+       float nextcpindex, lastcpindex;
+
+       nextcpindex = max(e.race_checkpoint, 0);
+       lastcpindex = e.race_respawn_checkpoint;
+       lastcp = e.race_respawn_spotref;
+
+       if(nextcpindex == lastcpindex)
+               return l; // finish
+       
+       bestfraction = 1;
+       for(cp0 = world; (cp0 = find(cp0, classname, "trigger_race_checkpoint")); )
+       {
+               if(cp0.race_checkpoint != lastcpindex)
+                       continue;
+               if(lastcp)
+                       if(cp0 != lastcp)
+                               continue;
+               o0 = (cp0.absmin + cp0.absmax) * 0.5;
+               for(cp1 = world; (cp1 = find(cp1, classname, "trigger_race_checkpoint")); )
+               {
+                       if(cp1.race_checkpoint != nextcpindex)
+                               continue;
+                       o1 = (cp1.absmin + cp1.absmax) * 0.5;
+                       if(o0 == o1)
+                               continue;
+                       fraction = bound(0.0001, vlen(e.origin - o1) / vlen(o0 - o1), 1);
+                       if(fraction < bestfraction)
+                               bestfraction = fraction;
+               }
+       }
+
+       // we are at CP "nextcpindex - bestfraction"
+       // race_timed_checkpoint == 4: then nextcp==4 means 0.9999x, nextcp==0 means 0.0000x
+       // race_timed_checkpoint == 0: then nextcp==0 means 0.9999x
+       float c, nc;
+       nc = race_highest_checkpoint + 1;
+       c = (mod(nextcpindex - race_timed_checkpoint + nc + nc - 1, nc) + 1) - bestfraction;
+
+       return l + c / nc;
+}
index 71684a5..f6cc54a 100644 (file)
@@ -27,3 +27,5 @@ void race_StartCompleting();
 
 .float race_respawn_checkpoint;
 .entity race_respawn_spotref; // try THIS spawn in case you respawn
+
+float race_GetFractionalLapCount(entity e);
index 7854427..4db1b44 100644 (file)
@@ -140,6 +140,7 @@ void ScoreRules_kh(float teams)
 #define SP_RACE_LAPS 4
 #define SP_RACE_FASTEST 5
 #define SP_RACE_TIME 5
+//#define SP_RACE_RANK 6
 void ScoreRules_race()
 {
        ScoreRules_basics(race_teams, 0, 0, FALSE);
@@ -148,6 +149,7 @@ void ScoreRules_race()
                ScoreInfo_SetLabel_TeamScore(  ST_RACE_LAPS,    "laps",      SFL_SORT_PRIO_PRIMARY);
                ScoreInfo_SetLabel_PlayerScore(SP_RACE_LAPS,    "laps",      SFL_SORT_PRIO_PRIMARY);
                ScoreInfo_SetLabel_PlayerScore(SP_RACE_TIME,    "time",      SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER | SFL_TIME);
+               //ScoreInfo_SetLabel_PlayerScore(SP_RACE_RANK,    "rank",      SFL_LOWER_IS_BETTER | SFL_RANK | SFL_ALLOW_HIDE);
        }
        else if(g_race_qualifying)
        {