]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/spawnpoints.qc
Merge branch 'master' into Mario/hagar_notfixed
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / spawnpoints.qc
index bc191f74f46be02808a00148036e1e6ef5e92641..344f05846f742cdb4d59b2c98ac053be715d1b8d 100644 (file)
@@ -1,41 +1,42 @@
 #include "spawnpoints.qh"
-#include "_all.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/util_server.qh"
+#include "../lib/warpzone/common.qh"
+#include "../lib/warpzone/util_server.qh"
 
-float SpawnPoint_Send(entity to, int sf)
+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);
+       WriteCoord(MSG_ENTITY, self.origin.x);
+       WriteCoord(MSG_ENTITY, self.origin.y);
+       WriteCoord(MSG_ENTITY, self.origin.z);
 
        return true;
 }
 
-float SpawnEvent_Send(entity to, int sf)
+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;
@@ -45,19 +46,31 @@ float SpawnEvent_Send(entity to, int sf)
        return send;
 }
 
-void spawnpoint_use()
+.vector spawnpoint_prevorigin;
+void spawnpoint_think()
 {
+    SELFPARAM();
+       self.nextthink = time + 0.1;
+       if(self.origin != self.spawnpoint_prevorigin)
+       {
+               self.spawnpoint_prevorigin = self.origin;
+               self.SendFlags |= 1;
+       }
+}
+
+void spawnpoint_use()
+{SELFPARAM();
        if(teamplay)
        if(have_team_spawns > 0)
        {
                self.team = activator.team;
                some_spawn_has_been_used = 1;
        }
-       print("spawnpoint was used!\n");
+       //LOG_INFO("spawnpoint was used!\n");
 }
 
 void relocate_spawnpoint()
-{
+{SELFPARAM();
     // nudge off the floor
     setorigin(self, self.origin + '0 0 1');
 
@@ -70,14 +83,14 @@ void relocate_spawnpoint()
         self.maxs = PL_MAX_CONST;
         if (!move_out_of_solid(self))
             objerror("could not get out of solid at all!");
-        print("^1NOTE: this map needs FIXING. Spawnpoint at ", vtos(o - '0 0 1'));
-        print(" needs to be moved out of solid, e.g. by '", ftos(self.origin.x - o.x));
-        print(" ", ftos(self.origin.y - o.y));
-        print(" ", ftos(self.origin.z - o.z), "'\n");
+        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");
         if (autocvar_g_spawnpoints_auto_move_out_of_solid)
         {
             if (!spawnpoint_nag)
-                print("\{1}^1NOTE: this map needs FIXING (it contains spawnpoints in solid, see server log)\n");
+                LOG_INFO("\{1}^1NOTE: this map needs FIXING (it contains spawnpoints in solid, see server log)\n");
             spawnpoint_nag = 1;
         }
         else
@@ -90,6 +103,8 @@ void relocate_spawnpoint()
     }
 
     self.use = spawnpoint_use;
+    self.think = spawnpoint_think;
+    self.nextthink = time + 0.5 + random() * 2; // shouldn't need it for a little second
     self.team_saved = self.team;
     if (!self.cnt)
         self.cnt = 1;
@@ -103,9 +118,7 @@ void relocate_spawnpoint()
     {
         // show where spawnpoints point at too
         makevectors(self.angles);
-        entity e;
-        e = spawn();
-        e.classname = "info_player_foo";
+        entity e = new(info_player_foo);
         setorigin(e, self.origin + v_forward * 24);
         setsize(e, '-8 -8 -8', '8 8 8');
         e.solid = SOLID_TRIGGER;
@@ -141,30 +154,67 @@ void relocate_spawnpoint()
        { Net_LinkEntity(self, false, 0, SpawnPoint_Send); }
 }
 
-void spawnfunc_info_player_survivor (void)
+spawnfunc(info_player_survivor)
 {
-       spawnfunc_info_player_deathmatch();
+       spawnfunc_info_player_deathmatch(this);
 }
 
-void spawnfunc_info_player_start (void)
+spawnfunc(info_player_start)
 {
-       spawnfunc_info_player_deathmatch();
+       spawnfunc_info_player_deathmatch(this);
 }
 
-void spawnfunc_info_player_deathmatch (void)
+spawnfunc(info_player_deathmatch)
 {
        self.classname = "info_player_deathmatch";
        relocate_spawnpoint();
 }
 
+/*QUAKED spawnfunc_info_player_team1 (1 0 0) (-16 -16 -24) (16 16 24)
+Starting point for a player in team one (Red).
+Keys: "angle" viewing angle when spawning. */
+spawnfunc(info_player_team1)
+{
+       this.team = NUM_TEAM_1; // red
+       spawnfunc_info_player_deathmatch(this);
+}
+
+
+/*QUAKED spawnfunc_info_player_team2 (1 0 0) (-16 -16 -24) (16 16 24)
+Starting point for a player in team two (Blue).
+Keys: "angle" viewing angle when spawning. */
+spawnfunc(info_player_team2)
+{
+       this.team = NUM_TEAM_2; // blue
+       spawnfunc_info_player_deathmatch(this);
+}
+
+/*QUAKED spawnfunc_info_player_team3 (1 0 0) (-16 -16 -24) (16 16 24)
+Starting point for a player in team three (Yellow).
+Keys: "angle" viewing angle when spawning. */
+spawnfunc(info_player_team3)
+{
+       this.team = NUM_TEAM_3; // yellow
+       spawnfunc_info_player_deathmatch(this);
+}
+
+
+/*QUAKED spawnfunc_info_player_team4 (1 0 0) (-16 -16 -24) (16 16 24)
+Starting point for a player in team four (Purple).
+Keys: "angle" viewing angle when spawning. */
+spawnfunc(info_player_team4)
+{
+       this.team = NUM_TEAM_4; // purple
+       spawnfunc_info_player_deathmatch(this);
+}
+
 // Returns:
 //   _x: prio (-1 if unusable)
 //   _y: weight
 vector Spawn_Score(entity spot, float mindist, float teamcheck)
-{
+{SELFPARAM();
        float shortest, thisdist;
        float prio;
-       entity player;
 
        prio = 0;
 
@@ -189,12 +239,11 @@ 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 != self, LAMBDA(
+               thisdist = vlen(it.origin - spot.origin);
                if (thisdist < shortest)
                        shortest = thisdist;
-       }
+       ));
        if(shortest > mindist)
                prio += SPAWN_PRIO_GOOD_DISTANCE;
 
@@ -212,10 +261,9 @@ vector Spawn_Score(entity spot, float mindist, float teamcheck)
                        ++found;
                        if(ent.spawn_evalfunc)
                        {
-                               entity oldself = self;
-                               self = ent;
-                               spawn_score = ent.spawn_evalfunc(oldself, spot, spawn_score);
-                               self = oldself;
+                               WITH(entity, self, ent, {
+                                       spawn_score = ent.spawn_evalfunc(this, spot, spawn_score);
+                               });
                                if(spawn_score.x < 0)
                                        return spawn_score;
                        }
@@ -223,7 +271,7 @@ vector Spawn_Score(entity spot, float mindist, float teamcheck)
 
                if(!found)
                {
-                       dprint("WARNING: spawnpoint at ", vtos(spot.origin), " could not find its target ", spot.target, "\n");
+                       LOG_TRACE("WARNING: spawnpoint at ", vtos(spot.origin), " could not find its target ", spot.target, "\n");
                        return '-1 0 0';
                }
        }
@@ -286,7 +334,7 @@ Finds a point to respawn
 =============
 */
 entity SelectSpawnPoint (float anypoint)
-{
+{SELFPARAM();
        float teamcheck;
        entity spot, firstspot;