]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/gamemode_freezetag.qc
fix, again, several important things
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / gamemode_freezetag.qc
index ca8e78f7be25e777160282c2f827c143ebe7fbb4..14fe430f1209b8cc6496eddb165d497864b3d15f 100644 (file)
@@ -1,51 +1,53 @@
 void freezetag_Initialize()
 {
        precache_model("models/ice/ice.md3");
-       next_round = time + 5;
+       warmup = time + cvar("g_start_delay") + cvar("g_freezetag_warmup");
 }
 
 void freezetag_CheckWinner()
 {
+       if(time <= game_starttime) // game didn't even start yet! nobody can win in that case.
+               return;
+
+       if(next_round || (time > warmup - cvar("g_freezetag_warmup") && time < warmup))
+               return; // already waiting for next round to start
+
        if((redalive >= 1 && bluealive >= 1) // counted in arena.qc
                || (redalive >= 1 && yellowalive >= 1)
                || (redalive >= 1 && pinkalive >= 1)
                || (bluealive >= 1 && yellowalive >= 1)
                || (bluealive >= 1 && pinkalive >= 1)
                || (yellowalive >= 1 && pinkalive >= 1))
-               return; // we still have active players on two or more teams
-
-       if(redalive + bluealive + yellowalive + pinkalive <= 0)
-       {
-               next_round = time + 5;
-               return;
-       }
+               return; // we still have active players on two or more teams, nobody won yet
 
        entity e, winner;
        string teamname;
 
        FOR_EACH_PLAYER(e)
        {
-               if(e.freezetag_frozen == 0) // here's one player from the winning team... good
+               if(e.freezetag_frozen == 0 && e.classname == "player" && e.health >= 1) // here's one player from the winning team... good
                {
                        winner = e;
                        break; // break, we found the winner
                }
        }
 
-       TeamScore_AddToTeam(winner.team, ST_SCORE, +1);
-
-       if(winner.team == COLOR_TEAM1)
-               teamname = "^1Red Team";
-       else if(winner.team == COLOR_TEAM2)
-               teamname = "^4Blue Team";
-       else if(winner.team == COLOR_TEAM3)
-               teamname = "^3Yellow Team";
-       else
-               teamname = "^6Pink Team";
-       FOR_EACH_PLAYER(e) {
-               centerprint(e, strcat(teamname, "^5 wins the round, all other teams were frozen.\n"));
+       if(winner != world) // just in case a winner wasn't found
+       {
+               TeamScore_AddToTeam(winner.team, ST_SCORE, +1);
+               if(winner.team == COLOR_TEAM1)
+                       teamname = "^1Red Team";
+               else if(winner.team == COLOR_TEAM2)
+                       teamname = "^4Blue Team";
+               else if(winner.team == COLOR_TEAM3)
+                       teamname = "^3Yellow Team";
+               else
+                       teamname = "^6Pink Team";
+               FOR_EACH_PLAYER(e) {
+                       centerprint(e, strcat(teamname, "^5 wins the round, all other teams were frozen.\n"));
+               }
+               bprint(teamname, "^5 wins the round since all the other teams were frozen.\n");
        }
-       bprint(teamname, "^5 wins the round since all the other teams were frozen.\n");
 
        next_round = time + 5;
 }
@@ -76,8 +78,6 @@ void freezetag_Freeze()
        if(self.waypointsprite_attached)
        {
                WaypointSprite_UpdateTeamRadar(self.waypointsprite_attached, RADARICON_WAYPOINT, '0.25 0.90 1');
-               //WaypointSprite_UpdateMaxHealth(self.waypointsprite_attached, ITEM_RESPAWN_TICKS + 1);
-               //WaypointSprite_UpdateBuildFinished(self.waypointsprite_attached, time + ITEM_RESPAWN_TICKS);
        }
 }
 
@@ -85,8 +85,6 @@ void freezetag_Unfreeze()
 {
        self.freezetag_frozen = 0;
 
-       self.movetype = MOVETYPE_WALK;
-
        // remove the ice block
        entity ice;
        for(ice = world; (ice = find(ice, classname, "freezetag_ice")); ) if(ice.owner == self)
@@ -102,19 +100,42 @@ void freezetag_Unfreeze()
 
 MUTATOR_HOOKFUNCTION(freezetag_RemovePlayer)
 {
-       freezetag_CheckWinner();
+       if(self.freezetag_frozen == 0)
+       {
+               if(self.team == COLOR_TEAM1)
+                       --redalive;
+               else if(self.team == COLOR_TEAM2)
+                       --bluealive;
+               else if(self.team == COLOR_TEAM3)
+                       --yellowalive;
+               else if(self.team == COLOR_TEAM4)
+                       --pinkalive;
+               --totalalive;
+       }
+
+       if(totalspawned > 2) // only check for winners if we had more than two players (one of them left, don't let the other player win just because of that)
+               freezetag_CheckWinner();
+
+       freezetag_Unfreeze();
 
        return 1;
 }
 
 MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
 {
-       // if the player was previously not frozen (should be the case anyway), decrement alive playercount before running CheckWinner
-       if (self.team == COLOR_TEAM1 && self.freezetag_frozen == 0) redalive -= 1;
-       else if (self.team == COLOR_TEAM2 && self.freezetag_frozen == 0) bluealive -= 1;
-       else if (self.team == COLOR_TEAM3 && self.freezetag_frozen == 0) yellowalive -= 1;
-       else if (self.team == COLOR_TEAM4 && self.freezetag_frozen == 0) pinkalive -= 1;
-       
+       if(self.freezetag_frozen == 0)
+       {
+               if(self.team == COLOR_TEAM1)
+                       --redalive;
+               else if(self.team == COLOR_TEAM2)
+                       --bluealive;
+               else if(self.team == COLOR_TEAM3)
+                       --yellowalive;
+               else if(self.team == COLOR_TEAM4)
+                       --pinkalive;
+               --totalalive;
+       }
+
        freezetag_Freeze();
 
        centerprint(frag_attacker, strcat("^2You froze ^7", frag_target.netname, ".\n"));
@@ -138,10 +159,13 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
 
 MUTATOR_HOOKFUNCTION(freezetag_PlayerSpawn)
 {
-       if(redalive + bluealive + yellowalive + pinkalive == 1 && time > warmup)
-               next_round = time; // start a new round immediately
-
-       if(time > warmup) // spawn too late, freeze player
+       if(totalspawned == 1 && time > game_starttime) // only one player active on server, start a new match immediately
+       if(!next_round && warmup && (time < warmup - cvar("g_freezetag_warmup") || time > warmup)) // not awaiting next round
+       {
+               next_round = time;
+               return 1;
+       }
+       if(warmup && time > warmup) // spawn too late, freeze player
        {
                centerprint(self, "^1You spawned after the round started, you'll spawn as frozen.\n");
                freezetag_Freeze();
@@ -173,7 +197,8 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
                        if(other.team == self.team)
                        {
                                teammate_nearby = boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax);
-                               break;
+                               if(teammate_nearby)
+                                       break;
                        }
                }
        }
@@ -183,9 +208,13 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
                if(self.freezetag_beginrevive_time == -9999)
                {
                        self.freezetag_beginrevive_time = time;
+                       self.freezetag_revive_progress = 0;
+                       other.freezetag_revive_progress = 0;
                }
                else
                {
+                       self.freezetag_revive_progress = (time - self.freezetag_beginrevive_time) / cvar("g_freezetag_revive_time");
+                       other.freezetag_revive_progress = (time - self.freezetag_beginrevive_time) / cvar("g_freezetag_revive_time");
                        if(time - self.freezetag_beginrevive_time >= cvar("g_freezetag_revive_time"))
                        {
                                freezetag_Unfreeze();
@@ -195,12 +224,15 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
                                bprint("^7", other.netname, "^5 revived ^7", self.netname, ".\n");
 
                                self.freezetag_beginrevive_time = -9999;
+                               self.freezetag_revive_progress = 0;
+                               other.freezetag_revive_progress = 0;
                        }
                }
        }
-       else
+       else if(!teammate_nearby) // only if no teammate is nearby will we reset
        {
                self.freezetag_beginrevive_time = -9999;
+               self.freezetag_revive_progress = 0;
        }
 
        return 1;