]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/gamemode_freezetag.qc
Merge remote branch 'origin/fruitiex/gamemode_freezetag' into fruitiex/gamemode_freezetag
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / gamemode_freezetag.qc
index 4f1d69eaa7ec9a213d872ebe4f7d2103fe421a22..28c408acecd35cf94cb0be85017e4fe63794f9e6 100644 (file)
@@ -1,11 +1,14 @@
 void freezetag_Initialize()
 {
        precache_model("models/ice/ice.md3");
-       next_round = time + 5;
+       warmup = time + cvar("g_freezetag_warmup");
 }
 
 void freezetag_CheckWinner()
 {
+       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)
@@ -25,15 +28,14 @@ void freezetag_CheckWinner()
 
        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;
+                       TeamScore_AddToTeam(winner.team, ST_SCORE, +1); // just in case a winner isn't found, we do this already here (causes crashes otherwise...)
                        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)
@@ -50,44 +52,56 @@ void freezetag_CheckWinner()
        next_round = time + 5;
 }
 
+void freezetag_Ice_Think()
+{
+       setorigin(self, self.owner.origin - '0 0 16');
+       self.nextthink = time;
+}
+
 void freezetag_Freeze()
 {
        self.freezetag_frozen = 1;
 
-       entity tag;
-       tag = spawn();
-       tag.owner = self;
-       tag.classname = "freezetag_ice";
-       tag.frame = floor(random() * 21); // ice model has 20 different looking frames
-       setmodel(tag, "models/ice/ice.md3");
-
-       setattachment(tag, self, "");
-
-       self.movetype = MOVETYPE_NONE;
+       entity ice;
+       ice = spawn();
+       ice.owner = self;
+       ice.classname = "freezetag_ice";
+       ice.think = freezetag_Ice_Think;
+       ice.nextthink = time;
+       ice.frame = floor(random() * 21); // ice model has 20 different looking frames
+       setmodel(ice, "models/ice/ice.md3");
 
        self.movement = '0 0 0';
-       //self.fixangle = TRUE;
+
+       // add waypoint
+       WaypointSprite_Spawn("freezetag_frozen", 0, 0, self, '0 0 64', world, self.team, self, waypointsprite_attached, TRUE);
+       if(self.waypointsprite_attached)
+       {
+               WaypointSprite_UpdateTeamRadar(self.waypointsprite_attached, RADARICON_WAYPOINT, '0.25 0.90 1');
+       }
 }
 
 void freezetag_Unfreeze()
 {
        self.freezetag_frozen = 0;
 
-       self.movetype = MOVETYPE_WALK;
-       //self.fixangle = FALSE;
-
        // remove the ice block
-       entity tag;
-       for(tag = world; (tag = find(tag, classname, "freezetag_ice")); ) if(tag.owner == self)
+       entity ice;
+       for(ice = world; (ice = find(ice, classname, "freezetag_ice")); ) if(ice.owner == self)
        {
-               remove(tag);
+               remove(ice);
                break;
        }
+
+       // remove waypoint
+       if(self.waypointsprite_attached)
+               WaypointSprite_Kill(self.waypointsprite_attached);
 }
 
 MUTATOR_HOOKFUNCTION(freezetag_RemovePlayer)
 {
        freezetag_CheckWinner();
+       freezetag_Unfreeze();
 
        return 1;
 }
@@ -105,7 +119,7 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
        centerprint(frag_attacker, strcat("^2You froze ^7", frag_target.netname, ".\n"));
        if(frag_attacker == frag_target || frag_attacker == world)
        {
-               centerprint(frag_target, strcat("^1You froze yourself.\n"));
+               centerprint(frag_target, "^1You froze yourself.\n");
                bprint("^7", frag_target.netname, "^1 froze himself.\n");
        }
        else
@@ -123,12 +137,9 @@ 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
        {
-               centerprint(self, strcat("^1You spawned after the round started, you'll spawn as frozen.\n"));
+               centerprint(self, "^1You spawned after the round started, you'll spawn as frozen.\n");
                freezetag_Freeze();
        }
        else // we are still in the delay period before the round starts
@@ -147,16 +158,6 @@ MUTATOR_HOOKFUNCTION(freezetag_GiveFragsForKill)
 
 MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
 {
-       if(self.freezetag_frozen)
-       {
-               // nasty hack, i want them to move around later on as i figure out a better way to block movement TODO TODO TODO !!!
-               self.velocity_x = 0;
-               self.velocity_y = 0;
-               self.velocity_z = min(self.velocity_z, 0);
-               self.movement = '0 0 0'; // don't move anywhere :-P
-               self.avelocity = '0 0 0';
-       }
-
        vector revive_extra_size;
        revive_extra_size = '1 1 1' * cvar("g_freezetag_revive_extra_size");
 
@@ -168,7 +169,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;
                        }
                }
        }
@@ -178,9 +180,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();
@@ -190,17 +196,28 @@ 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
        {
                self.freezetag_beginrevive_time = -9999;
+               self.freezetag_revive_progress = 0;
+               other.freezetag_revive_progress = 0;
        }
 
        return 1;
 }
 
+MUTATOR_HOOKFUNCTION(freezetag_PlayerPhysics)
+{
+       if(self.freezetag_frozen)
+               self.movement = '0 0 0';
+       return 1;
+}
+
 MUTATOR_DEFINITION(gamemode_freezetag)
 {
        MUTATOR_HOOK(MakePlayerObserver, freezetag_RemovePlayer, CBC_ORDER_ANY);
@@ -209,6 +226,7 @@ MUTATOR_DEFINITION(gamemode_freezetag)
        MUTATOR_HOOK(PlayerSpawn, freezetag_PlayerSpawn, CBC_ORDER_ANY);
        MUTATOR_HOOK(GiveFragsForKill, freezetag_GiveFragsForKill, CBC_ORDER_FIRST);
        MUTATOR_HOOK(PlayerPreThink, freezetag_PlayerPreThink, CBC_ORDER_FIRST);
+       MUTATOR_HOOK(PlayerPhysics, freezetag_PlayerPhysics, CBC_ORDER_FIRST);
 
        MUTATOR_ONADD
        {