]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
add a Spawn_Score mutator hook; simplify spawning
authorRudolf Polzer <divverent@xonotic.org>
Sat, 3 Dec 2011 18:01:15 +0000 (19:01 +0100)
committerRudolf Polzer <divverent@xonotic.org>
Sat, 3 Dec 2011 18:01:15 +0000 (19:01 +0100)
qcsrc/server/cl_client.qc
qcsrc/server/mutators/base.qh
qcsrc/server/race.qc

index 40039ead81f107743a38a78b3a58be2ea38ba6cd..3953b31edaaca3de0596f148bb2ee79690521ef9 100644 (file)
@@ -123,7 +123,7 @@ void spawnpoint_use()
 // Returns:
 //   _x: prio (-1 if unusable)
 //   _y: weight
-vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoint)
+vector Spawn_Score(entity spot, float teamcheck)
 {
        float shortest, thisdist;
        float prio;
@@ -168,35 +168,32 @@ vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoi
                        }
                        else if(ent.classname == "trigger_race_checkpoint")
                        {
-                               if(!anypoint) // spectators may spawn everywhere
+                               if(g_race_qualifying)
                                {
-                                       if(g_race_qualifying)
+                                       // spawn at first
+                                       if(ent.race_checkpoint != 0)
+                                               continue;
+                                       if(spot.race_place != race_lowest_place_spawn)
+                                               continue;
+                               }
+                               else
+                               {
+                                       if(ent.race_checkpoint != self.race_respawn_checkpoint)
+                                               continue;
+                                       // try reusing the previous spawn
+                                       if(ent == self.race_respawn_spotref || spot == self.race_respawn_spotref)
+                                               prio += 1;
+                                       if(ent.race_checkpoint == 0)
                                        {
-                                               // spawn at first
-                                               if(ent.race_checkpoint != 0)
-                                                       continue;
-                                               if(spot.race_place != race_lowest_place_spawn)
+                                               float pl;
+                                               pl = self.race_place;
+                                               if(pl > race_highest_place_spawn)
+                                                       pl = 0;
+                                               if(pl == 0 && !self.race_started)
+                                                       pl = race_highest_place_spawn; // use last place if he has not even touched finish yet
+                                               if(spot.race_place != pl)
                                                        continue;
                                        }
-                                       else
-                                       {
-                                               if(ent.race_checkpoint != self.race_respawn_checkpoint)
-                                                       continue;
-                                               // try reusing the previous spawn
-                                               if(ent == self.race_respawn_spotref || spot == self.race_respawn_spotref)
-                                                       prio += 1;
-                                               if(ent.race_checkpoint == 0)
-                                               {
-                                                       float pl;
-                                                       pl = self.race_place;
-                                                       if(pl > race_highest_place_spawn)
-                                                               pl = 0;
-                                                       if(pl == 0 && !self.race_started)
-                                                               pl = race_highest_place_spawn; // use last place if he has not even touched finish yet
-                                                       if(spot.race_place != pl)
-                                                               continue;
-                                               }
-                                       }
                                }
                        }
                        ++good;
@@ -212,21 +209,22 @@ vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoi
                        return '-1 0 0';
        }
 
-       player = playerlist;
        shortest = vlen(world.maxs - world.mins);
-       for(player = playerlist; player; player = player.chain)
-               if (player != self)
-               {
-                       thisdist = vlen(player.origin - spot.origin);
-                       if (thisdist < shortest)
-                               shortest = thisdist;
-               }
-       return prio * '1 0 0' + shortest * '0 1 0';
+       FOR_EACH_PLAYER(player) if (player != self)
+       {
+               thisdist = vlen(player.origin - spot.origin);
+               if (thisdist < shortest)
+                       shortest = thisdist;
+       }
+
+       spawn_score = prio * '1 0 0' + shortest * '0 1 0';
+       MUTATOR_CALLHOOK(Spawn_Score);
+       return spawn_score;
 }
 
 float spawn_allbad;
 float spawn_allgood;
-entity Spawn_FilterOutBadSpots(entity firstspot, entity playerlist, float mindist, float teamcheck, float anypoint)
+entity Spawn_FilterOutBadSpots(entity firstspot, float mindist, float teamcheck)
 {
        entity spot, spotlist, spotlistend;
        spawn_allgood = TRUE;
@@ -237,7 +235,7 @@ entity Spawn_FilterOutBadSpots(entity firstspot, entity playerlist, float mindis
 
        for(spot = firstspot; spot; spot = spot.chain)
        {
-               spot.spawnpoint_score = Spawn_Score(spot, playerlist, teamcheck, anypoint);
+               spot.spawnpoint_score = Spawn_Score(spot, teamcheck);
 
                if(autocvar_spawn_debugview)
                {
@@ -323,7 +321,7 @@ entity SelectSpawnPoint (float anypoint)
 {
        float teamcheck;
        entity firstspot_new;
-       entity spot, firstspot, playerlist;
+       entity spot, firstspot;
 
        spot = find (world, classname, "testplayerstart");
        if (spot)
@@ -354,8 +352,6 @@ entity SelectSpawnPoint (float anypoint)
                // if we get here, we either require team spawns but have none, or we require non-team spawns and have none; use any spawn then
 
 
-       // get the list of players
-       playerlist = findchain(classname, "player");
        // get the entire list of spots
        firstspot = findchain(classname, "info_player_deathmatch");
        // filter out the bad ones
@@ -366,9 +362,9 @@ entity SelectSpawnPoint (float anypoint)
        }
        else
        {
-               firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, 100, teamcheck, anypoint);
+               firstspot_new = Spawn_FilterOutBadSpots(firstspot, 100, teamcheck);
                if(!firstspot_new)
-                       firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, -1, teamcheck, anypoint);
+                       firstspot_new = Spawn_FilterOutBadSpots(firstspot, -1, teamcheck);
                firstspot = firstspot_new;
 
                // there is 50/50 chance of choosing a random spot or the furthest spot
@@ -376,7 +372,7 @@ entity SelectSpawnPoint (float anypoint)
                // usually won't get fragged at spawn twice in a row)
                if (arena_roundbased && !g_ca)
                {
-                       firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, 800, teamcheck, anypoint);
+                       firstspot_new = Spawn_FilterOutBadSpots(firstspot, 800, teamcheck);
                        if(firstspot_new)
                                firstspot = firstspot_new;
                        spot = Spawn_WeightedPoint(firstspot, 1, 1, 1);
index 73b23bbd3f224201ecffa53725fe544a3b225573..1823eb36813fcaa92922f28260227940c481c6a5 100644 (file)
@@ -188,3 +188,11 @@ MUTATOR_HOOKABLE(SV_ParseClientCommand);
                        return 0;
                }
        */
+
+MUTATOR_HOOKABLE(Spawn_Score);
+       // called when a spawnpoint is being evaluated
+       // return 1 to make the spawnpoint unusable
+       // INPUT
+       entity self; // player wanting to spawn
+       // IN+OUT
+       vector spawn_score; // _x is priority, _y is "distance"
index f6ca98682c3d91eb7b4af582118c06dfed317e41..3d86f28a2494af5d02d166771743fdcbfa5558b0 100644 (file)
@@ -635,7 +635,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 +643,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 +651,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,7 +663,7 @@ 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))
+               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"));
        }
        else