]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/race.qc
Port buttons_old to ClientState
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / race.qc
index 2bd9f9668bc443bd021a7499656be2040c55e606..80023e76ada42a67139ba3aeeaa1644aeda14db5 100644 (file)
@@ -116,6 +116,8 @@ float race_checkpoint_lasttimes[MAX_CHECKPOINTS];
 float race_checkpoint_lastlaps[MAX_CHECKPOINTS];
 entity race_checkpoint_lastplayers[MAX_CHECKPOINTS];
 
+.float race_checkpoint_record[MAX_CHECKPOINTS];
+
 float race_highest_checkpoint;
 float race_timed_checkpoint;
 
@@ -158,23 +160,19 @@ float race_CheckpointNetworkID(float f)
 
 void race_SendNextCheckpoint(entity e, float spec) // qualifying only
 {
-       float recordtime;
-       string recordholder;
-       float cp;
-
        if(!e.race_laptime)
                return;
 
-       cp = e.race_checkpoint;
-       recordtime = race_checkpoint_records[cp];
-       recordholder = race_checkpoint_recordholders[cp];
+       int cp = e.race_checkpoint;
+       float recordtime = race_checkpoint_records[cp];
+       string recordholder = race_checkpoint_recordholders[cp];
        if(recordholder == e.netname)
                recordholder = "";
 
        if(!IS_REAL_CLIENT(e))
                return;
 
-       if(!spec)
+       if(!spec && !e.cvar_cl_race_cptimes_onlyself) // don't show spectators the player's personal time
                msg_entity = e;
        WRITESPECTATABLE_MSG_ONE(msg_entity, {
                WriteHeader(MSG_ONE, TE_CSQC_RACE);
@@ -190,6 +188,18 @@ void race_SendNextCheckpoint(entity e, float spec) // qualifying only
                WriteInt24_t(MSG_ONE, recordtime);
                WriteString(MSG_ONE, recordholder);
        });
+
+       if(!spec && e.cvar_cl_race_cptimes_onlyself) // don't send to spectators!
+       {
+               recordtime = e.race_checkpoint_record[cp];
+
+               // not spectatable
+               msg_entity = e;
+               WriteHeader(MSG_ONE, TE_CSQC_RACE);
+               WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_NEXT_SELF_QUALIFYING);
+               WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player will be at next
+               WriteInt24_t(MSG_ONE, recordtime);
+       }
 }
 
 void race_send_recordtime(float msg)
@@ -411,13 +421,16 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                }
        }
 
-       float recordtime;
-       string recordholder;
        if(g_race_qualifying)
        {
+               float recordtime;
+               float myrecordtime;
+               string recordholder;
+
                if(tvalid)
                {
                        recordtime = race_checkpoint_records[cp];
+                       myrecordtime = e.race_checkpoint_record[cp];
                        recordholder = strcat1(race_checkpoint_recordholders[cp]); // make a tempstring copy, as we'll possibly strunzone it!
                        if(recordholder == e.netname)
                                recordholder = "";
@@ -436,10 +449,11 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                                                strunzone(race_checkpoint_recordholders[cp]);
                                        race_checkpoint_recordholders[cp] = strzone(e.netname);
                                        if(g_race_qualifying)
-                                       {
                                                FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.race_checkpoint == cp, LAMBDA(race_SendNextCheckpoint(it, 0)));
-                                       }
                                }
+
+                               if(t < myrecordtime || myrecordtime == 0)
+                                       e.race_checkpoint_record[cp] = t; // resending done below
                        }
                }
                else
@@ -447,6 +461,7 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                        // dummies
                        t = 0;
                        recordtime = 0;
+                       myrecordtime = 0;
                        recordholder = "";
                }
 
@@ -455,7 +470,9 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                        msg_entity = e;
                        if(g_race_qualifying)
                        {
-                               WRITESPECTATABLE_MSG_ONE(msg_entity, {
+                               WRITESPECTATABLE_MSG_ONE(e, {
+                                       if(it == e && e.cvar_cl_race_cptimes_onlyself)
+                                               continue;
                                        WriteHeader(MSG_ONE, TE_CSQC_RACE);
                                        WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_QUALIFYING);
                                        WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
@@ -463,14 +480,23 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                                        WriteInt24_t(MSG_ONE, recordtime); // previously best time
                                        WriteString(MSG_ONE, recordholder); // record holder
                                });
+
+                               if(e.cvar_cl_race_cptimes_onlyself)
+                               {
+                                       msg_entity = e;
+                                       WriteHeader(MSG_ONE, TE_CSQC_RACE);
+                                       WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_SELF_QUALIFYING);
+                                       WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
+                                       WriteInt24_t(MSG_ONE, t); // time to that intermediate
+                                       WriteInt24_t(MSG_ONE, myrecordtime); // previously best time
+                               }
                        }
                }
        }
        else // RACE! Not Qualifying
        {
                float mylaps, lother, othtime;
-               entity oth;
-               oth = race_checkpoint_lastplayers[cp];
+               entity oth = race_checkpoint_lastplayers[cp];
                if(oth)
                {
                        mylaps = PlayerScore_Add(e, SP_RACE_LAPS, 0);
@@ -491,13 +517,13 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                                {
                                        WriteInt24_t(MSG_ONE, 0);
                                        WriteByte(MSG_ONE, 0);
-                                       WriteString(MSG_ONE, "");
+                                       WriteByte(MSG_ONE, 0);
                                }
                                else
                                {
                                        WriteInt24_t(MSG_ONE, TIME_ENCODE(time - race_checkpoint_lasttimes[cp]));
                                        WriteByte(MSG_ONE, mylaps - lother);
-                                       WriteString(MSG_ONE, oth.netname); // record holder
+                                       WriteByte(MSG_ONE, etof(oth)); // record holder
                                }
                        });
                }
@@ -517,13 +543,13 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                                {
                                        WriteInt24_t(MSG_ONE, 0);
                                        WriteByte(MSG_ONE, 0);
-                                       WriteString(MSG_ONE, "");
+                                       WriteByte(MSG_ONE, 0);
                                }
                                else
                                {
                                        WriteInt24_t(MSG_ONE, TIME_ENCODE(time - othtime));
                                        WriteByte(MSG_ONE, lother - mylaps);
-                                       WriteString(MSG_ONE, e.netname); // record holder
+                                       WriteByte(MSG_ONE, etof(e) - 1); // record holder
                                }
                        });
                }
@@ -548,38 +574,11 @@ void race_ClearTime(entity e)
        });
 }
 
-void dumpsurface(entity e)
-{
-       float n, si, ni;
-       vector norm, vec;
-       LOG_INFO("Surfaces of ", etos(e), ":\n");
-
-       LOG_INFO("TEST = ", ftos(getsurfacenearpoint(e, '0 0 0')), "\n");
-
-       for(si = 0; ; ++si)
-       {
-               n = getsurfacenumpoints(e, si);
-               if(n <= 0)
-                       break;
-               LOG_INFO("  Surface ", ftos(si), ":\n");
-               norm = getsurfacenormal(e, si);
-               LOG_INFO("    Normal = ", vtos(norm), "\n");
-               for(ni = 0; ni < n; ++ni)
-               {
-                       vec = getsurfacepoint(e, si, ni);
-                       LOG_INFO("    Point ", ftos(ni), " = ", vtos(vec), " (", ftos(norm * vec), ")\n");
-               }
-       }
-}
-
 void checkpoint_passed(entity this, entity player)
 {
        if(player.personal && autocvar_g_allow_checkpoints)
                return; // practice mode!
 
-       string oldmsg;
-       entity cp;
-
        if(player.classname == "porto")
        {
                // do not allow portalling through checkpoints
@@ -588,6 +587,8 @@ void checkpoint_passed(entity this, entity player)
                return;
        }
 
+       string oldmsg; // used twice
+
        /*
         * Trigger targets
         */
@@ -616,30 +617,37 @@ void checkpoint_passed(entity this, entity player)
                        this.race_checkpoint = player.race_checkpoint;
                }
 
-               float largest_cp_id = 0;
-               float cp_amount = 0;
-               for(cp = NULL; (cp = find(cp, classname, "target_checkpoint"));)
+               int cp_amount = 0, largest_cp_id = 0;
+               IL_EACH(g_race_targets, it.classname == "target_checkpoint",
                {
                        cp_amount += 1;
-                       if(cp.race_checkpoint > largest_cp_id) // update the finish id if someone hit a new checkpoint
+                       if(it.race_checkpoint > largest_cp_id) // update the finish id if someone hit a new checkpoint
                        {
-                               largest_cp_id = cp.race_checkpoint;
-                               for(cp = NULL; (cp = find(cp, classname, "target_stopTimer"));)
-                                       cp.race_checkpoint = largest_cp_id + 1; // finish line
-                               race_highest_checkpoint = largest_cp_id + 1;
-                               race_timed_checkpoint = largest_cp_id + 1;
-
-                               for(cp = NULL; (cp = find(cp, classname, "target_checkpoint"));)
+                               if(!largest_cp_id)
                                {
-                                       if(cp.race_checkpoint == -2) // set defragcpexists to -1 so that the cp id file will be rewritten when someone finishes
-                                               defragcpexists = -1;
+                                       IL_EACH(g_race_targets, it.classname == "target_checkpoint",
+                                       {
+                                               if(it.race_checkpoint == -2) // set defragcpexists to -1 so that the cp id file will be rewritten when someone finishes
+                                                       defragcpexists = -1;
+                                       });
                                }
+
+                               largest_cp_id = it.race_checkpoint;
+                               IL_EACH(g_race_targets, it.classname == "target_stopTimer",
+                               {
+                                       it.race_checkpoint = largest_cp_id + 1; // finish line
+                               });
+                               race_highest_checkpoint = largest_cp_id + 1;
+                               race_timed_checkpoint = largest_cp_id + 1;
                        }
-               }
-               if(cp_amount == 0)
+               });
+
+               if(!cp_amount)
                {
-                       for(cp = NULL; (cp = find(cp, classname, "target_stopTimer"));)
-                               cp.race_checkpoint = 1;
+                       IL_EACH(g_race_targets, it.classname == "target_stopTimer",
+                       {
+                               it.race_checkpoint = 1;
+                       });
                        race_highest_checkpoint = 1;
                        race_timed_checkpoint = 1;
                }
@@ -695,8 +703,10 @@ void checkpoint_passed(entity this, entity player)
                        defragcpexists = fh = fopen(strcat("maps/", GetMapname(), ".defragcp"), FILE_WRITE);
                        if(fh >= 0)
                        {
-                               for(cp = NULL; (cp = find(cp, classname, "target_checkpoint"));)
-                               fputs(fh, strcat(cp.targetname, " ", ftos(cp.race_checkpoint), "\n"));
+                               IL_EACH(g_race_targets, it.classname == "target_checkpoint",
+                               {
+                                       fputs(fh, strcat(it.targetname, " ", ftos(it.race_checkpoint), "\n"));
+                               });
                        }
                        fclose(fh);
                }