]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/spawnpoints.qc
Remove .move_* fields and MOVETYPE_PUSH logic (doesn't work)
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / spawnpoints.qc
index ead90d30b56079f0c1fa1e4bad0caa169415e92d..4be19b879d317ac5976bbe87f3c70cd7f1870e93 100644 (file)
@@ -1,23 +1,23 @@
 #include "spawnpoints.qh"
 
-#include "mutators/mutators_include.qh"
+#include "mutators/all.qh"
 #include "g_world.qh"
 #include "race.qh"
 #include "../common/constants.qh"
 #include "../common/teams.qh"
 #include "../common/triggers/subs.qh"
 #include "../common/util.qh"
-#include "../warpzonelib/common.qh"
-#include "../warpzonelib/util_server.qh"
+#include "../lib/warpzone/common.qh"
+#include "../lib/warpzone/util_server.qh"
 
 bool SpawnPoint_Send(entity this, entity to, int sf)
 {
-       WriteByte(MSG_ENTITY, ENT_CLIENT_SPAWNPOINT);
+       WriteHeader(MSG_ENTITY, ENT_CLIENT_SPAWNPOINT);
 
-       WriteByte(MSG_ENTITY, self.team);
-       WriteShort(MSG_ENTITY, self.origin.x);
-       WriteShort(MSG_ENTITY, self.origin.y);
-       WriteShort(MSG_ENTITY, self.origin.z);
+       WriteByte(MSG_ENTITY, this.team);
+       WriteCoord(MSG_ENTITY, this.origin.x);
+       WriteCoord(MSG_ENTITY, this.origin.y);
+       WriteCoord(MSG_ENTITY, this.origin.z);
 
        return true;
 }
@@ -26,17 +26,17 @@ bool SpawnEvent_Send(entity this, entity to, int sf)
 {
        float send;
 
-       WriteByte(MSG_ENTITY, ENT_CLIENT_SPAWNEVENT);
+       WriteHeader(MSG_ENTITY, ENT_CLIENT_SPAWNEVENT);
 
        if(autocvar_g_spawn_alloweffects)
        {
-               WriteByte(MSG_ENTITY, num_for_edict(self.owner));
-               WriteShort(MSG_ENTITY, self.owner.origin.x);
-               WriteShort(MSG_ENTITY, self.owner.origin.y);
-               WriteShort(MSG_ENTITY, self.owner.origin.z);
+               WriteByte(MSG_ENTITY, etof(this.owner));
+               WriteCoord(MSG_ENTITY, this.owner.origin.x);
+               WriteCoord(MSG_ENTITY, this.owner.origin.y);
+               WriteCoord(MSG_ENTITY, this.owner.origin.z);
                send = true;
        }
-       else if((to == self.owner) || (IS_SPEC(to) && (to.enemy == self.owner)) )
+       else if((to == this.owner) || (IS_SPEC(to) && (to.enemy == this.owner)) )
        {
                WriteByte(MSG_ENTITY, 0);
                send = true;
@@ -46,35 +46,46 @@ bool SpawnEvent_Send(entity this, entity to, int sf)
        return send;
 }
 
-void spawnpoint_use()
-{SELFPARAM();
+.vector spawnpoint_prevorigin;
+void spawnpoint_think(entity this)
+{
+       this.nextthink = time + 0.1;
+       if(this.origin != this.spawnpoint_prevorigin)
+       {
+               this.spawnpoint_prevorigin = this.origin;
+               this.SendFlags |= 1;
+       }
+}
+
+void spawnpoint_use(entity this, entity actor, entity trigger)
+{
        if(teamplay)
        if(have_team_spawns > 0)
        {
-               self.team = activator.team;
+               this.team = actor.team;
                some_spawn_has_been_used = 1;
        }
        //LOG_INFO("spawnpoint was used!\n");
 }
 
-void relocate_spawnpoint()
-{SELFPARAM();
+void relocate_spawnpoint(entity this)
+{
     // nudge off the floor
-    setorigin(self, self.origin + '0 0 1');
+    setorigin(this, this.origin + '0 0 1');
 
-    tracebox(self.origin, PL_MIN_CONST, PL_MAX_CONST, self.origin, true, self);
+    tracebox(this.origin, PL_MIN_CONST, PL_MAX_CONST, this.origin, true, this);
     if (trace_startsolid)
     {
         vector o;
-        o = self.origin;
-        self.mins = PL_MIN_CONST;
-        self.maxs = PL_MAX_CONST;
-        if (!move_out_of_solid(self))
-            objerror("could not get out of solid at all!");
+        o = this.origin;
+        this.mins = PL_MIN_CONST;
+        this.maxs = PL_MAX_CONST;
+        if (!move_out_of_solid(this))
+            objerror(this, "could not get out of solid at all!");
         LOG_INFO("^1NOTE: this map needs FIXING. Spawnpoint at ", vtos(o - '0 0 1'));
-        LOG_INFO(" needs to be moved out of solid, e.g. by '", ftos(self.origin.x - o.x));
-        LOG_INFO(" ", ftos(self.origin.y - o.y));
-        LOG_INFO(" ", ftos(self.origin.z - o.z), "'\n");
+        LOG_INFO(" needs to be moved out of solid, e.g. by '", ftos(this.origin.x - o.x));
+        LOG_INFO(" ", ftos(this.origin.y - o.y));
+        LOG_INFO(" ", ftos(this.origin.z - o.z), "'\n");
         if (autocvar_g_spawnpoints_auto_move_out_of_solid)
         {
             if (!spawnpoint_nag)
@@ -83,31 +94,31 @@ void relocate_spawnpoint()
         }
         else
         {
-            setorigin(self, o);
-            self.mins = self.maxs = '0 0 0';
-            objerror("player spawn point in solid, mapper sucks!\n");
+            setorigin(this, o);
+            this.mins = this.maxs = '0 0 0';
+            objerror(this, "player spawn point in solid, mapper sucks!\n");
             return;
         }
     }
 
-    self.use = spawnpoint_use;
-    self.team_saved = self.team;
-    if (!self.cnt)
-        self.cnt = 1;
+    this.use = spawnpoint_use;
+    setthink(this, spawnpoint_think);
+    this.nextthink = time + 0.5 + random() * 2; // shouldn't need it for a little second
+    this.team_saved = this.team;
+    if (!this.cnt)
+        this.cnt = 1;
 
     if (have_team_spawns != 0)
-        if (self.team)
+        if (this.team)
             have_team_spawns = 1;
-    have_team_spawns_forteam[self.team] = 1;
+    have_team_spawns_forteam[this.team] = 1;
 
     if (autocvar_r_showbboxes)
     {
         // show where spawnpoints point at too
-        makevectors(self.angles);
-        entity e;
-        e = spawn();
-        e.classname = "info_player_foo";
-        setorigin(e, self.origin + v_forward * 24);
+        makevectors(this.angles);
+        entity e = new(info_player_foo);
+        setorigin(e, this.origin + v_forward * 24);
         setsize(e, '-8 -8 -8', '8 8 8');
         e.solid = SOLID_TRIGGER;
     }
@@ -119,27 +130,27 @@ void relocate_spawnpoint()
                !(
                        ( // if this passes, there is a DM spawn on a team match
                                teamplay
-                               && (self.team != NUM_TEAM_1)
-                               && (self.team != NUM_TEAM_2)
-                               && (self.team != NUM_TEAM_3)
-                               && (self.team != NUM_TEAM_4)
+                               && (this.team != NUM_TEAM_1)
+                               && (this.team != NUM_TEAM_2)
+                               && (this.team != NUM_TEAM_3)
+                               && (this.team != NUM_TEAM_4)
                        )
                        ||
                        ( // if this passes, there is a team spawn on a DM match
                                !teamplay
                                &&
                                (
-                                       (self.team == NUM_TEAM_1)
-                                       || (self.team == NUM_TEAM_2)
-                                       || (self.team == NUM_TEAM_3)
-                                       || (self.team == NUM_TEAM_4)
+                                       (this.team == NUM_TEAM_1)
+                                       || (this.team == NUM_TEAM_2)
+                                       || (this.team == NUM_TEAM_3)
+                                       || (this.team == NUM_TEAM_4)
                                )
                        )
                )
                ||
                autocvar_g_spawn_useallspawns
        )
-       { Net_LinkEntity(self, false, 0, SpawnPoint_Send); }
+       { Net_LinkEntity(this, false, 0, SpawnPoint_Send); }
 }
 
 spawnfunc(info_player_survivor)
@@ -154,8 +165,8 @@ spawnfunc(info_player_start)
 
 spawnfunc(info_player_deathmatch)
 {
-       self.classname = "info_player_deathmatch";
-       relocate_spawnpoint();
+       this.classname = "info_player_deathmatch";
+       relocate_spawnpoint(this);
 }
 
 /*QUAKED spawnfunc_info_player_team1 (1 0 0) (-16 -16 -24) (16 16 24)
@@ -163,8 +174,6 @@ Starting point for a player in team one (Red).
 Keys: "angle" viewing angle when spawning. */
 spawnfunc(info_player_team1)
 {
-       if(g_assault) { remove(this); return; }
-
        this.team = NUM_TEAM_1; // red
        spawnfunc_info_player_deathmatch(this);
 }
@@ -175,8 +184,6 @@ Starting point for a player in team two (Blue).
 Keys: "angle" viewing angle when spawning. */
 spawnfunc(info_player_team2)
 {
-       if(g_assault) { remove(this); return; }
-
        this.team = NUM_TEAM_2; // blue
        spawnfunc_info_player_deathmatch(this);
 }
@@ -186,8 +193,6 @@ Starting point for a player in team three (Yellow).
 Keys: "angle" viewing angle when spawning. */
 spawnfunc(info_player_team3)
 {
-       if(g_assault) { remove(this); return; }
-
        this.team = NUM_TEAM_3; // yellow
        spawnfunc_info_player_deathmatch(this);
 }
@@ -198,8 +203,6 @@ Starting point for a player in team four (Purple).
 Keys: "angle" viewing angle when spawning. */
 spawnfunc(info_player_team4)
 {
-       if(g_assault) { remove(this); return; }
-
        this.team = NUM_TEAM_4; // purple
        spawnfunc_info_player_deathmatch(this);
 }
@@ -207,11 +210,10 @@ spawnfunc(info_player_team4)
 // Returns:
 //   _x: prio (-1 if unusable)
 //   _y: weight
-vector Spawn_Score(entity spot, float mindist, float teamcheck)
-{SELFPARAM();
+vector Spawn_Score(entity this, entity spot, float mindist, float teamcheck)
+{
        float shortest, thisdist;
        float prio;
-       entity player;
 
        prio = 0;
 
@@ -224,7 +226,7 @@ vector Spawn_Score(entity spot, float mindist, float teamcheck)
                if(spot.target == "")
                        return '-1 0 0';
 
-       if(IS_REAL_CLIENT(self))
+       if(IS_REAL_CLIENT(this))
        {
                if(spot.restriction == 1)
                        return '-1 0 0';
@@ -236,32 +238,26 @@ vector Spawn_Score(entity spot, float mindist, float teamcheck)
        }
 
        shortest = vlen(world.maxs - world.mins);
-       FOR_EACH_PLAYER(player) if (player != self)
-       {
-               thisdist = vlen(player.origin - spot.origin);
+       FOREACH_CLIENT(IS_PLAYER(it) && it != this, LAMBDA(
+               thisdist = vlen(it.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';
-       spawn_spot = spot;
+       vector spawn_score = prio * '1 0 0' + shortest * '0 1 0';
 
        // filter out spots for assault
-       if(spot.target != "") {
-               entity ent;
-               float found;
-
-               found = 0;
-               for(ent = world; (ent = find(ent, targetname, spot.target)); )
+       if(spot.target != "")
+       {
+               int found = 0;
+               for(entity targ = findchain(targetname, spot.target); targ; targ = targ.chain)
                {
                        ++found;
-                       if(ent.spawn_evalfunc)
+                       if(targ.spawn_evalfunc)
                        {
-                               WITH(entity, self, ent, {
-                                       spawn_score = ent.spawn_evalfunc(this, spot, spawn_score);
-                               });
+                               spawn_score = targ.spawn_evalfunc(targ, this, spot, spawn_score);
                                if(spawn_score.x < 0)
                                        return spawn_score;
                        }
@@ -274,25 +270,26 @@ vector Spawn_Score(entity spot, float mindist, float teamcheck)
                }
        }
 
-       MUTATOR_CALLHOOK(Spawn_Score, self, spawn_spot, spawn_score);
+       MUTATOR_CALLHOOK(Spawn_Score, this, spot, spawn_score);
+       spawn_score = M_ARGV(2, vector);
        return spawn_score;
 }
 
-void Spawn_ScoreAll(entity firstspot, float mindist, float teamcheck)
+void Spawn_ScoreAll(entity this, entity firstspot, float mindist, float teamcheck)
 {
        entity spot;
        for(spot = firstspot; spot; spot = spot.chain)
-               spot.spawnpoint_score = Spawn_Score(spot, mindist, teamcheck);
+               spot.spawnpoint_score = Spawn_Score(this, spot, mindist, teamcheck);
 }
 
-entity Spawn_FilterOutBadSpots(entity firstspot, float mindist, float teamcheck)
+entity Spawn_FilterOutBadSpots(entity this, entity firstspot, float mindist, float teamcheck)
 {
        entity spot, spotlist, spotlistend;
 
-       spotlist = world;
-       spotlistend = world;
+       spotlist = NULL;
+       spotlistend = NULL;
 
-       Spawn_ScoreAll(firstspot, mindist, teamcheck);
+       Spawn_ScoreAll(this, firstspot, mindist, teamcheck);
 
        for(spot = firstspot; spot; spot = spot.chain)
        {
@@ -306,7 +303,7 @@ entity Spawn_FilterOutBadSpots(entity firstspot, float mindist, float teamcheck)
                }
        }
        if(spotlistend)
-               spotlistend.chain = world;
+               spotlistend.chain = NULL;
 
        return spotlist;
 }
@@ -331,12 +328,12 @@ SelectSpawnPoint
 Finds a point to respawn
 =============
 */
-entity SelectSpawnPoint (float anypoint)
-{SELFPARAM();
+entity SelectSpawnPoint(entity this, bool anypoint)
+{
        float teamcheck;
        entity spot, firstspot;
 
-       spot = find (world, classname, "testplayerstart");
+       spot = find (NULL, classname, "testplayerstart");
        if (spot)
                return spot;
 
@@ -344,7 +341,7 @@ entity SelectSpawnPoint (float anypoint)
                teamcheck = -1;
        else if(have_team_spawns > 0)
        {
-               if(have_team_spawns_forteam[self.team] == 0)
+               if(have_team_spawns_forteam[this.team] == 0)
                {
                        // we request a spawn for a team, and we have team
                        // spawns, but that team has no spawns?
@@ -356,7 +353,7 @@ entity SelectSpawnPoint (float anypoint)
                                teamcheck = -1;
                }
                else
-                       teamcheck = self.team; // MUST be team
+                       teamcheck = this.team; // MUST be team
        }
        else if(have_team_spawns == 0 && have_team_spawns_forteam[0])
                teamcheck = 0; // MUST be noteam
@@ -375,7 +372,7 @@ entity SelectSpawnPoint (float anypoint)
        }
        else
        {
-               firstspot = Spawn_FilterOutBadSpots(firstspot, 100, teamcheck);
+               firstspot = Spawn_FilterOutBadSpots(this, firstspot, 100, 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
@@ -393,7 +390,7 @@ entity SelectSpawnPoint (float anypoint)
                else
                {
                        if(some_spawn_has_been_used)
-                               return world; // team can't spawn any more, because of actions of other team
+                               return NULL; // team can't spawn any more, because of actions of other team
                        else
                                error("Cannot find a spawn point - please fix the map!");
                }