]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
spawnpoint selection: restructure to be WAY more mutator friendly and simpler; move...
authorRudolf Polzer <divverent@xonotic.org>
Sat, 3 Dec 2011 18:24:15 +0000 (19:24 +0100)
committerRudolf Polzer <divverent@xonotic.org>
Sat, 3 Dec 2011 18:25:59 +0000 (19:25 +0100)
qcsrc/common/constants.qh
qcsrc/server/assault.qc
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/defs.qh
qcsrc/server/race.qc
qcsrc/server/sv_main.qc

index d838f09e2bc52ca2d936353ab40fcd9e63283a3b..e42afed4ef047f09406a0785744ff0d98890df16 100644 (file)
@@ -574,3 +574,7 @@ float HUD_MENU_ENABLE               = 0;
 #define SERVERFLAG_ALLOW_FULLBRIGHT 1
 #define SERVERFLAG_TEAMPLAY 2
 #define SERVERFLAG_PLAYERSTATS 4
+
+// spawnpoint prios
+#define SPAWN_PRIO_GOOD_DISTANCE        100
+#define SPAWN_PRIO_RACE_PREVIOUS_SPAWN   50
index 45fa5c77d43aabc688d325e9f8f6edd191cc2c7f..1e91619f7aff418a4ecaf4db0d55d22738156e9d 100644 (file)
@@ -47,6 +47,13 @@ void assault_objective_use() {
        self = oldself;
 }
 
+vector target_objective_spawn_evalfunc(entity player, entity spot, float teamcheck, vector current)
+{
+       if(self.health < 0 || self.health >= ASSAULT_VALUE_INACTIVE)
+               return '-1 0 0';
+       return current;
+}
+
 void spawnfunc_target_objective() {
        if(!g_assault)
        {
@@ -57,6 +64,7 @@ void spawnfunc_target_objective() {
        self.use = assault_objective_use;
        assault_objective_reset();
        self.reset = assault_objective_reset;
+       self.spawn_evalfunc = target_objective_spawn_evalfunc;
 }
 
 
index 609516634c3282858329786bc0c7aeabdabcb6e1..f1bd5b024d75b924f2068bebc1f16b7ba5bced58 100644 (file)
@@ -1065,7 +1065,6 @@ float autocvar_skill_auto;
 #define autocvar_slowmo cvar("slowmo")
 float autocvar_snd_soundradius;
 float autocvar_spawn_debug;
-float autocvar_spawn_debugview;
 float autocvar_speedmeter;
 float autocvar_sv_accelerate;
 var float autocvar_sv_accuracy_data_share = 1;
index 3953b31edaaca3de0596f148bb2ee79690521ef9..97e44c3ca2dc6d776819cf950aa734d1603778de 100644 (file)
@@ -123,7 +123,7 @@ void spawnpoint_use()
 // Returns:
 //   _x: prio (-1 if unusable)
 //   _y: weight
-vector Spawn_Score(entity spot, float teamcheck)
+vector Spawn_Score(entity spot, float mindist, float teamcheck)
 {
        float shortest, thisdist;
        float prio;
@@ -151,52 +151,36 @@ vector Spawn_Score(entity spot, float teamcheck)
                        return '-1 0 0';
        }
 
+       shortest = vlen(world.maxs - world.mins);
+       FOR_EACH_PLAYER(player) if (player != self)
+       {
+               thisdist = vlen(player.origin - spot.origin);
+               if (thisdist < shortest)
+                       shortest = thisdist;
+       }
+       if(shortest < mindist)
+               prio += SPAWN_PRIO_GOOD_DISTANCE;
+
+       spawn_score = prio * '1 0 0' + shortest * '0 1 0';
+
        // filter out spots for assault
        if(spot.target != "") {
                entity ent;
-               float good, found;
+               float found;
 
                found = 0;
-               good = 0;
                for(ent = world; (ent = find(ent, targetname, spot.target)); )
                {
                        ++found;
-                       if(ent.classname == "target_objective")
+                       if(ent.spawn_evalfunc)
                        {
-                               if(ent.health < 0 || ent.health >= ASSAULT_VALUE_INACTIVE)
-                                       continue;
+                               entity oldself = self;
+                               self = ent;
+                               spawn_score = ent.spawn_evalfunc(oldself, spot, teamcheck, spawn_score);
+                               self = oldself;
+                               if(spawn_score_x < 0)
+                                       return spawn_score;
                        }
-                       else if(ent.classname == "trigger_race_checkpoint")
-                       {
-                               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)
-                                       {
-                                               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;
                }
 
                if(!found)
@@ -204,96 +188,42 @@ vector Spawn_Score(entity spot, float teamcheck)
                        dprint("WARNING: spawnpoint at ", vtos(spot.origin), " could not find its target ", spot.target, "\n");
                        return '-1 0 0';
                }
-
-               if(good < found) // at least one was bad
-                       return '-1 0 0';
-       }
-
-       shortest = vlen(world.maxs - world.mins);
-       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;
+void Spawn_ScoreAll(entity firstspot, float mindist, float teamcheck)
+{
+       entity spot;
+       for(spot = firstspot; spot; spot = spot.chain)
+               spot.spawnpoint_score = Spawn_Score(spot, mindist, teamcheck);
+}
+
 entity Spawn_FilterOutBadSpots(entity firstspot, float mindist, float teamcheck)
 {
        entity spot, spotlist, spotlistend;
-       spawn_allgood = TRUE;
-       spawn_allbad = TRUE;
 
        spotlist = world;
        spotlistend = world;
 
+       Spawn_ScoreAll(firstspot, mindist, teamcheck);
+
        for(spot = firstspot; spot; spot = spot.chain)
        {
-               spot.spawnpoint_score = Spawn_Score(spot, teamcheck);
-
-               if(autocvar_spawn_debugview)
-               {
-                       setmodel(spot, "models/runematch/rune.mdl");
-                       if(spot.spawnpoint_score_y < mindist)
-                       {
-                               spot.colormod = '1 0 0';
-                               spot.scale = 1;
-                       }
-                       else
-                       {
-                               spot.colormod = '0 1 0';
-                               spot.scale = spot.spawnpoint_score_y / mindist;
-                       }
-               }
-
                if(spot.spawnpoint_score_x >= 0) // spawning allowed here
                {
-                       if(spot.spawnpoint_score_y < mindist)
-                       {
-                               // too short distance
-                               spawn_allgood = FALSE;
-                       }
-                       else
-                       {
-                               // perfect
-                               spawn_allbad = FALSE;
-
-                               if(spotlistend)
-                                       spotlistend.chain = spot;
-                               spotlistend = spot;
-                               if(!spotlist)
-                                       spotlist = spot;
-
-                               /*
-                               if(teamcheck >= 0)
-                               if(spot.team != teamcheck)
-                                       error("invalid spawn added");
-
-                               print("added ", etos(spot), "\n");
-                               */
-                       }
+                       if(spotlistend)
+                               spotlistend.chain = spot;
+                       spotlistend = spot;
+                       if(!spotlist)
+                               spotlist = spot;
                }
        }
        if(spotlistend)
                spotlistend.chain = world;
 
-       /*
-               entity e;
-               if(teamcheck >= 0)
-                       for(e = spotlist; e; e = e.chain)
-                       {
-                               print("seen ", etos(e), "\n");
-                               if(e.team != teamcheck)
-                                       error("invalid spawn found");
-                       }
-       */
-
        return spotlist;
 }
 
@@ -320,7 +250,6 @@ Finds a point to respawn
 entity SelectSpawnPoint (float anypoint)
 {
        float teamcheck;
-       entity firstspot_new;
        entity spot, firstspot;
 
        spot = find (world, classname, "testplayerstart");
@@ -362,38 +291,22 @@ entity SelectSpawnPoint (float anypoint)
        }
        else
        {
-               firstspot_new = Spawn_FilterOutBadSpots(firstspot, 100, teamcheck);
-               if(!firstspot_new)
-                       firstspot_new = Spawn_FilterOutBadSpots(firstspot, -1, teamcheck);
-               firstspot = firstspot_new;
+               float mindist;
+               if (arena_roundbased && !g_ca)
+                       mindist = 800;
+               else
+                       mindist = 100;
+               firstspot = Spawn_FilterOutBadSpots(firstspot, mindist, teamcheck);
 
                // 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
                // usually won't get fragged at spawn twice in a row)
-               if (arena_roundbased && !g_ca)
-               {
-                       firstspot_new = Spawn_FilterOutBadSpots(firstspot, 800, teamcheck);
-                       if(firstspot_new)
-                               firstspot = firstspot_new;
-                       spot = Spawn_WeightedPoint(firstspot, 1, 1, 1);
-               }
-               else if (random() > autocvar_g_spawn_furthest)
+               if (random() > autocvar_g_spawn_furthest)
                        spot = Spawn_WeightedPoint(firstspot, 1, 1, 1);
                else
                        spot = Spawn_WeightedPoint(firstspot, 1, 5000, 5); // chooses a far far away spawnpoint
        }
 
-       if(autocvar_spawn_debugview)
-       {
-               print("spot mindistance: ", vtos(spot.spawnpoint_score), "\n");
-
-               entity e;
-               if(teamcheck >= 0)
-                       for(e = firstspot; e; e = e.chain)
-                               if(e.team != teamcheck)
-                                       error("invalid spawn found");
-       }
-
        if (!spot)
        {
                if(autocvar_spawn_debug)
index 21d6db4401ed5f4730390de6002fde6080a1dfd3..065814018b6883319b50dbf78c357a0181b9aca2 100644 (file)
@@ -669,3 +669,6 @@ float serverflags;
 .float misc_bulletcounter;     // replaces uzi & hlac bullet counter.
 
 void PlayerUseKey();
+
+typedef vector(entity player, entity spot, float teamcheck, vector current) spawn_evalfunc_t;
+.spawn_evalfunc_t spawn_evalfunc;
index 3d86f28a2494af5d02d166771743fdcbfa5558b0..f145306d44ec2e38d30c9da7d0240505f2509555 100644 (file)
@@ -764,6 +764,38 @@ void trigger_race_checkpoint_verify()
        self = oldself;
 }
 
+vector trigger_race_checkpoint_spawn_evalfunc(entity player, entity spot, float teamcheck, 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;
@@ -811,6 +843,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);
 }
index 6e4b0ccb7a47e6a9e9ba20c9801af2996bff260d..c4cc090c3b289adcfd77a8fd71ba6733f13c6a93 100644 (file)
@@ -231,15 +231,6 @@ void StartFrame (void)
        RuneMatchGivePoints();
        bot_serverframe();
 
-       if(autocvar_spawn_debugview)
-       {
-               RandomSelection_Init();
-               for(self = world; (self = find(self, classname, "player")); )
-                       RandomSelection_Add(self, 0, string_null, 1, 0);
-               self = RandomSelection_chosen_ent;
-               SelectSpawnPoint(0);
-       }
-
        FOR_EACH_PLAYER(self)
                self.porto_forbidden = max(0, self.porto_forbidden - 1);
 }