]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/spawnpoints.qc
If no valid spawnpoints exist in the map, perform another check without targets,...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / spawnpoints.qc
index e2c5ab307aa7743dedc878cc89f0b2254f4ae8bc..616824bbcbb78b4c0ebe2f2a67cd1ca65d54fc90 100644 (file)
@@ -222,7 +222,7 @@ spawnfunc(info_player_team4)
 // Returns:
 //   _x: prio (-1 if unusable)
 //   _y: weight
-vector Spawn_Score(entity this, entity spot, float mindist, float teamcheck)
+vector Spawn_Score(entity this, entity spot, float mindist, float teamcheck, bool targetcheck)
 {
        // filter out spots for the wrong team
        if(teamcheck >= 0)
@@ -230,7 +230,7 @@ vector Spawn_Score(entity this, entity spot, float mindist, float teamcheck)
                        return '-1 0 0';
 
        if(race_spawns)
-               if(spot.target == "")
+               if(!spot.target || spot.target == "")
                        return '-1 0 0';
 
        if(IS_REAL_CLIENT(this))
@@ -257,7 +257,7 @@ vector Spawn_Score(entity this, entity spot, float mindist, float teamcheck)
        vector spawn_score = prio * '1 0 0' + shortest * '0 1 0';
 
        // filter out spots for assault
-       if(spot.target && spot.target != "")
+       if(spot.target && spot.target != "" && targetcheck)
        {
                int found = 0;
                for(entity targ = findchain(targetname, spot.target); targ; targ = targ.chain)
@@ -283,21 +283,21 @@ vector Spawn_Score(entity this, entity spot, float mindist, float teamcheck)
        return spawn_score;
 }
 
-void Spawn_ScoreAll(entity this, entity firstspot, float mindist, float teamcheck)
+void Spawn_ScoreAll(entity this, entity firstspot, float mindist, float teamcheck, bool targetcheck)
 {
        entity spot;
        for(spot = firstspot; spot; spot = spot.chain)
-               spot.spawnpoint_score = Spawn_Score(this, spot, mindist, teamcheck);
+               spot.spawnpoint_score = Spawn_Score(this, spot, mindist, teamcheck, targetcheck);
 }
 
-entity Spawn_FilterOutBadSpots(entity this, entity firstspot, float mindist, float teamcheck)
+entity Spawn_FilterOutBadSpots(entity this, entity firstspot, float mindist, float teamcheck, bool targetcheck)
 {
        entity spot, spotlist, spotlistend;
 
        spotlist = NULL;
        spotlistend = NULL;
 
-       Spawn_ScoreAll(this, firstspot, mindist, teamcheck);
+       Spawn_ScoreAll(this, firstspot, mindist, teamcheck, targetcheck);
 
        for(spot = firstspot; spot; spot = spot.chain)
        {
@@ -399,7 +399,23 @@ entity SelectSpawnPoint(entity this, bool anypoint)
        }
        else
        {
-               firstspot = Spawn_FilterOutBadSpots(this, firstspot, 100, teamcheck);
+               firstspot = Spawn_FilterOutBadSpots(this, firstspot, 100, teamcheck, true);
+
+               // emergency fallback! double check without targets
+               // fixes some crashes with improperly repacked maps
+               if(!firstspot)
+               {
+                       firstspot = IL_FIRST(g_spawnpoints);
+                       prev = NULL;
+                       IL_EACH(g_spawnpoints, true,
+                       {
+                               if(prev)
+                                       prev.chain = it;
+                               it.chain = NULL;
+                               prev = it;
+                       });
+                       firstspot = Spawn_FilterOutBadSpots(this, firstspot, 100, teamcheck, false);
+               }
 
                // there is 50/50 chance of choosing a random spot or the furthest spot
                // (this means that roughly every other spawn will be furthest, so you