]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cl_player.qc
Merge branch 'samual/keepaway' into fruitiex/freezetag_vs_keepaway
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cl_player.qc
index 494a80b369ec7954cde34aa8e2b82521cfc0acd3..f8acd05036ae9d7acb3982fed0502a7017598061 100644 (file)
@@ -386,6 +386,8 @@ void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float
 }
 
 void ClientKill_Now_TeamChange();
+void freezetag_CheckWinner();
+void freezetag_Unfreeze();
 
 void PlayerDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 {
@@ -449,6 +451,16 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                take = damage;
        }
 
+       frag_inflictor = inflictor;
+       frag_attacker = attacker;
+       frag_target = self;
+       damage_take = take;
+       damage_save = save;
+       damage_force = force;
+       MUTATOR_CALLHOOK(PlayerDamage_SplitHealthArmor);
+       take = bound(0, damage_take, self.health);
+       save = bound(0, damage_save, self.armorvalue);
+
        if(sound_allowed(MSG_BROADCAST, attacker))
        {
                if (save > 10)
@@ -488,15 +500,18 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
 
                                        if(sound_allowed(MSG_BROADCAST, attacker))
                                        if(!DEATH_ISWEAPON(deathtype, WEP_LASER) || attacker != self || self.health < 2 * cvar("g_balance_laser_primary_damage") * cvar("g_balance_selfdamagepercent") + 1)
+                                       if(self.health > 1)
                                        // exclude pain sounds for laserjumps as long as you aren't REALLY low on health and would die of the next two
                                        {
-                                               if(self.health > 75) // TODO make a "gentle" version?
+                                               if(deathtype == DEATH_FALL)
+                                                       PlayerSound(playersound_fall, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
+                                               else if(self.health > 75) // TODO make a "gentle" version?
                                                        PlayerSound(playersound_pain100, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
                                                else if(self.health > 50)
                                                        PlayerSound(playersound_pain75, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
                                                else if(self.health > 25)
                                                        PlayerSound(playersound_pain50, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
-                                               else if(self.health > 1)
+                                               else
                                                        PlayerSound(playersound_pain25, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
                                        }
                                }
@@ -554,6 +569,12 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                float defer_ClientKill_Now_TeamChange;
                defer_ClientKill_Now_TeamChange = FALSE;
 
+               if(self.alivetime)
+               {
+                       PlayerStats_Event(self, PLAYERSTATS_ALIVETIME, time - self.alivetime);
+                       self.alivetime = 0;
+               }
+
                if(valid_damage_for_weaponstats)
                        WeaponStats_LogKill(DEATH_WEAPONOF(deathtype), self.weapon);
 
@@ -582,22 +603,37 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                        }
                }
 
-               // become fully visible
-               self.alpha = 1;
-               // clear selected player display
-               ClearSelectedPlayer();
-               // throw a weapon
-               SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon);
+               if(!g_freezetag)
+               {
+                       // become fully visible
+                       self.alpha = 1;
+                       // clear selected player display
+                       ClearSelectedPlayer();
+                       // throw a weapon
+                       SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon);
+               }
+
                // print an obituary message
                Obituary (attacker, inflictor, self, deathtype);
                race_PreDie();
                DropAllRunes(self);
 
+               if(deathtype == DEATH_HURTTRIGGER && g_freezetag)
+               {
+                       PutClientInServer();
+                       count_alive_players(); // re-count players
+                       freezetag_CheckWinner();
+                       return;
+               }
+
                frag_attacker = attacker;
                frag_inflictor = inflictor;
                frag_target = self;
                MUTATOR_CALLHOOK(PlayerDies);
 
+               if(g_freezetag)
+            return;
+
                if(self.flagcarried)
                {
                        if(attacker.classname != "player" && attacker.classname != "gib")
@@ -607,7 +643,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                        else
                                DropFlag(self.flagcarried, world, attacker);
                }
-               if(self.ballcarried)
+               if(self.ballcarried && g_nexball)
                        DropBall(self.ballcarried, self.origin, self.velocity);
                Portal_ClearAllLater(self);
                // clear waypoints
@@ -660,12 +696,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                // call the corpse damage function just in case it wants to gib
                self.event_damage(inflictor, attacker, 0, deathtype, hitloc, force);
                // set up to fade out later
-               SUB_SetFade (self, time + 12 + random () * 4, 1);
-
-               // remove laserdot
-               if(self.weaponentity)
-                       if(self.weaponentity.lasertarget)
-                               remove(self.weaponentity.lasertarget);
+               SUB_SetFade (self, time + 6 + random (), 1);
 
                if(clienttype(self) == CLIENTTYPE_REAL)
                {
@@ -855,6 +886,7 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f
 {
        string msgstr, colorstr, cmsgstr, namestr, fullmsgstr, sourcemsgstr, fullcmsgstr, sourcecmsgstr, privatemsgprefix;
        float flood, privatemsgprefixlen;
+       var .float flood_field;
        entity head;
        float ret;
 
@@ -936,7 +968,6 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f
                float flood_spl;
                float flood_burst;
                float flood_lmax;
-               var .float flood_field;
                float lines;
                if(privatesay)
                {
@@ -998,10 +1029,10 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f
                        else
                                flood = 1;
                }
-       }
 
-       if (timeoutStatus == 2) //when game is paused, no flood protection
-               source.flood_field = flood = 0;
+               if (timeoutStatus == 2) //when game is paused, no flood protection
+                       source.flood_field = flood = 0;
+       }
 
        if(flood == 2) // cannot happen for empty msgstr
        {