]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/race.qc
Merge branch 'terencehill/ca_arena_mutators' of git://git.xonotic.org/xonotic/xonotic...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / race.qc
index f6ca98682c3d91eb7b4af582118c06dfed317e41..2742888b6179bab1e088d5d4a222b778f01af3e2 100644 (file)
@@ -141,6 +141,7 @@ void race_setTime(string map, float t, string myuid, string mynetname, entity e)
        newpos = race_readPos(map, t);
 
        float i;
+       player_prevpos = 0;
        for(i = 1; i <= RANKINGS_CNT; ++i)
        {
                if(race_readUID(map, i) == myuid)
@@ -272,6 +273,10 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                }
                else
                {
+                       s = PlayerScore_Add(e, SP_RACE_FASTEST, 0);
+                       if(!s || t < s)
+                               PlayerScore_Add(e, SP_RACE_FASTEST, t - s);
+
                        s = PlayerScore_Add(e, SP_RACE_TIME, 0);
                        snew = TIME_ENCODE(time - game_starttime);
                        PlayerScore_Add(e, SP_RACE_TIME, snew - s);
@@ -490,8 +495,8 @@ void checkpoint_passed()
                        self.race_checkpoint = other.race_checkpoint;
                }
 
-               float largest_cp_id;
-               float cp_amount;
+               float largest_cp_id = 0;
+               float cp_amount = 0;
                for(cp = world; (cp = find(cp, classname, "target_checkpoint"));) {
                        cp_amount += 1;
                        if(cp.race_checkpoint > largest_cp_id) // update the finish id if someone hit a new checkpoint
@@ -635,7 +640,7 @@ void trigger_race_checkpoint_verify()
                        // race only (middle of the race)
                        g_race_qualifying = 0;
                        self.race_place = 0;
-                       if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), world, 0, FALSE, FALSE))
+                       if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), 0, FALSE))
                                error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(self.race_place), " (used for respawning in race) - bailing out"));
 
                        if(i == 0)
@@ -643,7 +648,7 @@ void trigger_race_checkpoint_verify()
                                // qualifying only
                                g_race_qualifying = 1;
                                self.race_place = race_lowest_place_spawn;
-                               if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), world, 0, FALSE, FALSE))
+                               if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), 0, FALSE))
                                        error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(self.race_place), " (used for qualifying) - bailing out"));
                                
                                // race only (initial spawn)
@@ -651,7 +656,7 @@ void trigger_race_checkpoint_verify()
                                for(p = 1; p <= race_highest_place_spawn; ++p)
                                {
                                        self.race_place = p;
-                                       if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), world, 0, FALSE, FALSE))
+                                       if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), 0, FALSE))
                                                error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(self.race_place), " (used for initially spawning in race) - bailing out"));
                                }
                        }
@@ -663,8 +668,8 @@ void trigger_race_checkpoint_verify()
                self.race_checkpoint = race_NextCheckpoint(0);
                g_race_qualifying = 1;
                self.race_place = race_lowest_place_spawn;
-               if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), world, 0, FALSE, FALSE))
-                       error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(self.race_place), " (used for qualifying) - bailing out"));
+               if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), 0, FALSE))
+                       error(strcat("Checkpoint 0 misses a spawnpoint with race_place==", ftos(self.race_place), " (used for qualifying) - bailing out"));
        }
        else
        {
@@ -710,7 +715,7 @@ void trigger_race_checkpoint_verify()
                        }
 
                        if(defragcpexists != -1){
-                               float largest_cp_id;
+                               float largest_cp_id = 0;
                                for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
                                        if(cp.race_checkpoint > largest_cp_id)
                                                largest_cp_id = cp.race_checkpoint;
@@ -764,6 +769,38 @@ void trigger_race_checkpoint_verify()
        self = oldself;
 }
 
+vector trigger_race_checkpoint_spawn_evalfunc(entity player, entity spot, vector current)
+{
+       if(g_race_qualifying)
+       {
+               // spawn at first
+               if(self.race_checkpoint != 0)
+                       return '-1 0 0';
+               if(spot.race_place != race_lowest_place_spawn)
+                       return '-1 0 0';
+       }
+       else
+       {
+               if(self.race_checkpoint != player.race_respawn_checkpoint)
+                       return '-1 0 0';
+               // try reusing the previous spawn
+               if(self == player.race_respawn_spotref || spot == player.race_respawn_spotref)
+                       current_x += SPAWN_PRIO_RACE_PREVIOUS_SPAWN;
+               if(self.race_checkpoint == 0)
+               {
+                       float pl;
+                       pl = player.race_place;
+                       if(pl > race_highest_place_spawn)
+                               pl = 0;
+                       if(pl == 0 && !player.race_started)
+                               pl = race_highest_place_spawn; // use last place if he has not even touched finish yet
+                       if(spot.race_place != pl)
+                               return '-1 0 0';
+               }
+       }
+       return current;
+}
+
 void spawnfunc_trigger_race_checkpoint()
 {
        vector o;
@@ -784,11 +821,11 @@ void spawnfunc_trigger_race_checkpoint()
        waypoint_spawnforitem_force(self, trace_endpos);
        self.nearestwaypointtimeout = time + 1000000000;
 
-       if(!self.message)
+       if(self.message == "")
                self.message = "went backwards";
-       if (!self.message2)
+       if (self.message2 == "")
                self.message2 = "was pushed backwards by";
-       if (!self.race_penalty_reason)
+       if (self.race_penalty_reason == "")
                self.race_penalty_reason = "missing a checkpoint";
        
        self.race_checkpoint = self.cnt;
@@ -811,6 +848,7 @@ void spawnfunc_trigger_race_checkpoint()
        }
 
        self.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player;
+       self.spawn_evalfunc = trigger_race_checkpoint_spawn_evalfunc;
 
        InitializeEntity(self, trigger_race_checkpoint_verify, INITPRIO_FINDTARGET);
 }
@@ -836,11 +874,11 @@ void spawnfunc_target_checkpoint() // defrag entity
        waypoint_spawnforitem_force(self, trace_endpos);
        self.nearestwaypointtimeout = time + 1000000000;
 
-       if(!self.message)
+       if(self.message == "")
                self.message = "went backwards";
-       if (!self.message2)
+       if (self.message2 == "")
                self.message2 = "was pushed backwards by";
-       if (!self.race_penalty_reason)
+       if (self.race_penalty_reason == "")
                self.race_penalty_reason = "missing a checkpoint";
 
        if(self.classname == "target_startTimer")
@@ -992,7 +1030,7 @@ void race_ReadyRestart()
        Score_NicePrint(world);
 
        race_ClearRecords();
-       PlayerScore_Sort(race_place);
+       PlayerScore_Sort(race_place, 0, 1, 0);
 
        entity e;
        FOR_EACH_CLIENT(e)
@@ -1068,7 +1106,7 @@ void spawnfunc_trigger_race_penalty()
        if not(self.spawnflags & 1)
                self.touch = penalty_touch;
 
-       if (!self.race_penalty_reason)
+       if (self.race_penalty_reason == "")
                self.race_penalty_reason = "missing a checkpoint";
        if (!self.race_penalty)
                self.race_penalty = 5;