From: Rudolf Polzer Date: Sat, 3 Dec 2011 18:01:15 +0000 (+0100) Subject: add a Spawn_Score mutator hook; simplify spawning X-Git-Tag: xonotic-v0.6.0~35^2~26 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=441447ab367e6ae01c55d0b066bc2888fa4ef6a0;p=xonotic%2Fxonotic-data.pk3dir.git add a Spawn_Score mutator hook; simplify spawning --- diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 40039ead8..3953b31ed 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -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); diff --git a/qcsrc/server/mutators/base.qh b/qcsrc/server/mutators/base.qh index 73b23bbd3..1823eb368 100644 --- a/qcsrc/server/mutators/base.qh +++ b/qcsrc/server/mutators/base.qh @@ -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" diff --git a/qcsrc/server/race.qc b/qcsrc/server/race.qc index f6ca98682..3d86f28a2 100644 --- a/qcsrc/server/race.qc +++ b/qcsrc/server/race.qc @@ -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