]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/arena.qc
fix starting the gametype
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / arena.qc
index e68e295022f29ecfe2ef3e579f47caded8ecfdf8..2fad0959774bf2345cd3fb722ad3a902aaf952de 100644 (file)
@@ -8,9 +8,9 @@ float arena_roundbased;
 entity spawnqueue_first;
 entity spawnqueue_last;
 entity champion;
+string champion_name;
 float warmup;
-float allowed_to_spawn;
-float player_cnt;
+float ca_players;
 float required_ca_players;
 .float caplayer;
 
@@ -39,6 +39,10 @@ void reset_map(float dorespawn)
                warmup = time + cvar("g_ca_warmup");
                allowed_to_spawn = 1;
        }
+       else if(g_freezetag)
+       {
+               warmup = time + cvar("g_freezetag_warmup");
+       }
 
        lms_lowest_lives = 999;
        lms_next_place = player_count;
@@ -122,8 +126,8 @@ void reset_map(float dorespawn)
        if(g_keyhunt)
                kh_Controller_SetThink(cvar("g_balance_keyhunt_delay_round")+(game_starttime - time), "", kh_StartRound);
 
-       if(g_arena || g_ca)
-       if(champion && champion.classname == "player" && player_cnt > 1)
+       if(g_arena)
+       if(champion && champion.classname == "player" && player_count > 1)
                UpdateFrags(champion, +1);
 
        self = oldself;
@@ -183,7 +187,7 @@ void Spawnqueue_Mark(entity e)
  * player when player is waiting for the countdown to finish.
  * Blocks the players movement while countdown is active.
  * Unblocks the player once the countdown is over.
- * 
+ *
  * Called in PlayerPostThink()
  */
 float roundStartTime_prev; // prevent networkspam
@@ -195,11 +199,15 @@ void Arena_Warmup()
        if((!g_arena && !g_ca) || (g_arena && !arena_roundbased) || (time < game_starttime))
                return;
 
-       f = floor(warmup - time + 1);
+       f = ceil(warmup - time);
+       if(f > 0)
+               champion = world; // this is done because a if(champion) will not execute if champion = world
 
        allowed_to_spawn = 0;
 
-       if(g_ca && (player_cnt < required_ca_players || inWarmupStage))
+       if(inWarmupStage)
+               allowed_to_spawn = 1;
+       if(ca_players < required_ca_players)
                allowed_to_spawn = 1;
 
        msg = NEWLINES;
@@ -208,7 +216,7 @@ void Arena_Warmup()
                if (g_ca)
                        allowed_to_spawn = 1;
                if(champion && g_arena)
-                       msg = strcat("The Champion is ", champion.netname, "^7\n");
+                       msg = strcat("The Champion is ", champion_name, "^7\n");
                        //centerprint(self, strcat(msg, "The Champion is ", champion.netname, "^7\n"));
 
                if(f != roundStartTime_prev) {
@@ -242,15 +250,13 @@ void Arena_Warmup()
        {
                roundStartTime_prev = f;
                Announce("begin");
-               centerprint(self, "^1Begin!\n");        
+               centerprint(self, "^1Begin!\n");
 
                if(g_ca) {
-                       player_cnt = 0;
+                       ca_players = 0;
 
-                       FOR_EACH_CLIENT(self) {
-                       if (self.classname == "player")
-                               player_cnt += 1;
-                       }               
+                       FOR_EACH_PLAYER(self)
+                               ca_players += 1;
                }
        }
 
@@ -259,62 +265,110 @@ void Arena_Warmup()
 }
 
 float next_round;
+float stopalivecheck;
+float redalive, bluealive, yellowalive, pinkalive;
+.float redalive_stat, bluealive_stat, yellowalive_stat, pinkalive_stat;
 /**
  * This function finds out whether an arena round is over 1 player is left.
  * It determines the last player who's still alive and saves it's entity reference
  * in the global variable 'champion'. Then the new enemy/enemies are put into the server.
- * 
+ *
  * Gets called in StartFrame()
  */
 void Spawnqueue_Check()
 {
+       if(g_ca) // we want to perform this before the return block below...
+       {
+               // this is STUPID to perform again, but has to be done so that we can give instant feedback when a round ends
+               // and so the code won't start searching for a champion using find() before all players are actually REMOVED
+               redalive = 0; bluealive = 0;
+               FOR_EACH_PLAYER(self) {
+                       if (self.team == COLOR_TEAM1 && self.health >= 1) redalive += 1;
+                       else if (self.team == COLOR_TEAM2 && self.health >= 1) bluealive += 1;
+               }
+               // as if the above stuff wasn't stupid enough, let's run it a third time! :D
+               // (so that we can send redalive/bluealive as a stat)
+               FOR_EACH_PLAYER(self) {
+                       self.redalive_stat = redalive;
+                       self.bluealive_stat = bluealive;
+               }
+       }
+       else if(g_freezetag)
+       {
+               redalive = 0; bluealive = 0;
+               FOR_EACH_PLAYER(self) {
+                       if (self.team == COLOR_TEAM1 && self.freezetag_frozen == 0 && self.health >= 1) redalive += 1;
+                       else if (self.team == COLOR_TEAM2 && self.freezetag_frozen == 0 && self.health >= 1) bluealive += 1;
+                       else if (self.team == COLOR_TEAM3 && self.freezetag_frozen == 0 && self.health >= 1) yellowalive += 1;
+                       else if (self.team == COLOR_TEAM4 && self.freezetag_frozen == 0 && self.health >= 1) pinkalive += 1;
+               }
+               FOR_EACH_PLAYER(self) {
+                       self.redalive_stat = redalive;
+                       self.bluealive_stat = bluealive;
+                       self.yellowalive_stat = yellowalive;
+                       self.pinkalive_stat = pinkalive;
+               }
+       }
        if(time < warmup + 1 || inWarmupStage)
                return;
 
        if(g_ca) {
                // check the amount of spawned players in each team
                float redspawned, bluespawned;
-               FOR_EACH_CLIENT(self) {
-                       if (self.classname == "player") {
-                               if (self.team == COLOR_TEAM1) redspawned += 1;
-                               else if (self.team == COLOR_TEAM2) bluespawned += 1;
-                       }
+               FOR_EACH_PLAYER(self) {
+                       if (self.team == COLOR_TEAM1) redspawned += 1;
+                       else if (self.team == COLOR_TEAM2) bluespawned += 1;
                }
 
                required_ca_players = max(2, fabs(cvar("bot_vs_human") + 1));
 
-               if(player_cnt < required_ca_players && (redspawned && bluespawned)) {
+               if(ca_players < required_ca_players && (redspawned && bluespawned)) {
                        reset_map(TRUE);
                }
-               else if(player_cnt < required_ca_players) {
-                       FOR_EACH_CLIENT(self) 
-                       if(self.classname == "player")
+               else if(ca_players < required_ca_players) {
+                       FOR_EACH_PLAYER(self)
                                centerprint(self, strcat("^1Need at least 1 player in each team to play CA", "^7\n"));
-
-                       allowed_to_spawn = 1;
                        return;
                }
-               else if(!next_round)
-                       if((redspawned && bluespawned == 0) || (bluespawned && redspawned == 0)) {
+               else if(!next_round) {
+                       if((redspawned && !bluespawned) || (bluespawned && !redspawned)) {
                                next_round = time + 5;
-
                                champion = find(world, classname, "player");
-                               string champion_team;
-                               if(champion.team == COLOR_TEAM1) {
-                                       champion_team = "^1Red team";
-                                       play2all("ctf/red_capture.wav");
-                               }
-                               else if(champion.team == COLOR_TEAM2) {
-                                       champion_team = "^4Blue team";
-                                       play2all("ctf/blue_capture.wav");
-                               }
-                               FOR_EACH_CLIENT(self) centerprint(self, strcat(champion_team, "^7 wins the round.", "^7\n"));   
-                       else if(!redspawned && !bluespawned) {
+                               if(champion_name)
+                                       strunzone(champion_name);
+                               champion_name = strzone(champion.netname);
+                       }
+                       else if((!redspawned && !bluespawned) || time - warmup > cvar("g_ca_round_timelimit")) {
                                FOR_EACH_CLIENT(self) centerprint(self, strcat("^7Round tied.", "^7\n"));
                                next_round = time + 5;
                        }
+
+               }
+               if(!stopalivecheck)
+               {
+                       if(redalive && !bluealive)
+                       {
+                               play2all("ctf/red_capture.wav");
+                               FOR_EACH_CLIENT(self) centerprint(self, "^1 RED ^7team wins the round.\n");
+                               TeamScore_AddToTeam(COLOR_TEAM1, ST_SCORE, +1);
+                               stopalivecheck = TRUE;
+                       }
+                       else if(bluealive && !redalive)
+                       {
+                               play2all("ctf/blue_capture.wav");
+                               FOR_EACH_CLIENT(self) centerprint(self, "^4 BLUE ^7team wins the round.\n");
+                               TeamScore_AddToTeam(COLOR_TEAM2, ST_SCORE, +1);
+                               stopalivecheck = TRUE;
+                       }
                }
 
+               if((next_round && next_round < time))
+               {
+                       stopalivecheck = FALSE;
+                       next_round = 0;
+                       reset_map(TRUE);
+               }
+       } else if(g_freezetag) {
                if((next_round && next_round < time))
                {
                        next_round = 0;