]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cl_client.qc
Merge branch 'master' into terencehill/ca_fixes
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cl_client.qc
index bb88fe431918be9f0e8913134ab4ced910a59d29..6490073d5f78d8785e1f1d523979db7acaac0e20 100644 (file)
@@ -156,6 +156,8 @@ void PutObserverInServer (void)
 
        Portal_ClearAll(self);
 
+       Unfreeze(self);
+
        if(self.alivetime)
        {
                if(!warmup_stage)
@@ -227,6 +229,7 @@ void PutObserverInServer (void)
        self.angles_z = 0;
        self.fixangle = TRUE;
        self.crouch = FALSE;
+       self.revival_time = 0;
 
        setorigin (self, (spot.origin + PL_VIEW_OFS)); // offset it so that the spectator spawns higher off the ground, looks better this way
        self.prevorigin = self.origin;
@@ -253,6 +256,7 @@ void PutObserverInServer (void)
        self.punchvector = '0 0 0';
        self.oldvelocity = self.velocity;
        self.fire_endtime = -1;
+       self.event_damage = func_null;
 }
 
 .float model_randomizer;
@@ -505,11 +509,15 @@ void PutClientInServer (void)
                self.punchvector = '0 0 0';
                self.oldvelocity = self.velocity;
                self.fire_endtime = -1;
+               self.revival_time = 0;
 
                entity spawnevent = spawn();
                spawnevent.owner = self;
                Net_LinkEntity(spawnevent, FALSE, 0.5, SpawnEvent_Send);
 
+               // Cut off any still running player sounds.
+               stopsound(self, CH_PLAYER_SINGLE);
+
                self.model = "";
                FixPlayermodel();
                self.drawonlytoclient = world;
@@ -576,6 +584,8 @@ void PutClientInServer (void)
                        activator = world;
                self = oldself;
 
+               Unfreeze(self);
+
                spawn_spot = spot;
                MUTATOR_CALLHOOK(PlayerSpawn);
 
@@ -770,8 +780,8 @@ void ClientKill_Now()
        if(self.killindicator_teamchange)
                ClientKill_Now_TeamChange();
 
-       // in any case:
-       Damage(self, self, self, 100000, DEATH_KILL, self.origin, '0 0 0');
+       if(IS_PLAYER(self))
+               Damage(self, self, self, 100000, DEATH_KILL, self.origin, '0 0 0');
 
        // now I am sure the player IS dead
 }
@@ -925,7 +935,7 @@ void ClientKill (void)
 {
        if(gameover) return;
        if(self.player_blocked) return;
-       if(self.freezetag_frozen) return;
+       if(self.frozen) return;
 
        ClientKill_TeamChange(0);
 }
@@ -1254,6 +1264,8 @@ void ClientDisconnect (void)
 
        Portal_ClearAll(self);
 
+       Unfreeze(self);
+
        RemoveGrapplingHook(self);
 
        // Here, everything has been done that requires this player to be a client.
@@ -1547,17 +1559,27 @@ float CalcRotRegen(float current, float regenstable, float regenfactor, float re
 
 void player_regen (void)
 {
+       float max_mod, regen_mod, rot_mod, limit_mod;
+       max_mod = regen_mod = rot_mod = limit_mod = 1;
+       regen_mod_max = max_mod;
+       regen_mod_regen = regen_mod;
+       regen_mod_rot = rot_mod;
+       regen_mod_limit = limit_mod;
        if(!MUTATOR_CALLHOOK(PlayerRegen))
+       if(!self.frozen)
        {
-               float minh, mina, maxh, maxa, limith, limita, max_mod, regen_mod, rot_mod, limit_mod;
+               float minh, mina, maxh, maxa, limith, limita;
                maxh = autocvar_g_balance_health_rotstable;
                maxa = autocvar_g_balance_armor_rotstable;
                minh = autocvar_g_balance_health_regenstable;
                mina = autocvar_g_balance_armor_regenstable;
                limith = autocvar_g_balance_health_limit;
                limita = autocvar_g_balance_armor_limit;
-
-               max_mod = regen_mod = rot_mod = limit_mod = 1;
+               
+               max_mod = regen_mod_max;
+               regen_mod = regen_mod_regen;
+               rot_mod = regen_mod_rot;
+               limit_mod = regen_mod_limit;
 
                maxh = maxh * max_mod;
                minh = minh * max_mod;
@@ -1693,6 +1715,8 @@ void SpectateCopy(entity spectatee) {
        self.dmg_inflictor = spectatee.dmg_inflictor;
        self.v_angle = spectatee.v_angle;
        self.angles = spectatee.v_angle;
+       self.frozen = spectatee.frozen;
+       self.revive_progress = spectatee.revive_progress;
        if(!self.BUTTON_USE)
                self.fixangle = TRUE;
        setorigin(self, spectatee.origin);
@@ -1898,6 +1922,7 @@ void LeaveSpectatorMode()
                if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0)
                {
                        self.classname = "player";
+                       nades_RemoveBonus(self);
 
                        if(autocvar_g_campaign || autocvar_g_balance_teams)
                                { JoinBestTeam(self, FALSE, TRUE); }
@@ -1953,7 +1978,7 @@ float nJoinAllowed(entity ignore) {
 
        float currentlyPlaying = 0;
        FOR_EACH_REALCLIENT(e)
-               if(IS_PLAYER(e) || e.caplayer == 1)
+               if(IS_PLAYER(e) || e.caplayer)
                        currentlyPlaying += 1;
 
        if(currentlyPlaying < autocvar_g_maxplayers)
@@ -1967,7 +1992,10 @@ float nJoinAllowed(entity ignore) {
  * g_maxplayers_spectator_blocktime seconds
  */
 void checkSpectatorBlock() {
-       if(IS_SPEC(self) || IS_OBSERVER(self)) {
+       if(IS_SPEC(self) || IS_OBSERVER(self))
+       if(!self.caplayer)
+       if(IS_REAL_CLIENT(self))
+       {
                if( time > (self.spectatortime + autocvar_g_maxplayers_spectator_blocktime) ) {
                        Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_QUIT_KICK_SPECTATING);
                        dropclient(self);
@@ -2203,6 +2231,30 @@ void PlayerPreThink (void)
                return;
 #endif
 
+       if(self.frozen == 2)
+       {
+               self.revive_progress = bound(0, self.revive_progress + frametime * self.revive_speed, 1);
+               self.health = max(1, self.revive_progress * start_health);
+               self.iceblock.alpha = bound(0.2, 1 - self.revive_progress, 1);
+
+               if(self.revive_progress >= 1)
+                       Unfreeze(self);
+       }
+       else if(self.frozen == 3)
+       {
+               self.revive_progress = bound(0, self.revive_progress - frametime * self.revive_speed, 1);
+               self.health = max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * self.revive_progress );
+               
+               if(self.health < 1)
+               {
+                       if(self.vehicle)
+                               vehicles_exit(VHEF_RELESE);
+                       self.event_damage(self, self.frozen_by, 1, DEATH_NADE_ICE_FREEZE, self.origin, '0 0 0');
+               }
+               else if ( self.revive_progress <= 0 )
+                       Unfreeze(self);
+       }
+
        MUTATOR_CALLHOOK(PlayerPreThink);
 
        if(!self.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button
@@ -2327,7 +2379,7 @@ void PlayerPreThink (void)
                        do_crouch = 0;
                if(self.vehicle)
                        do_crouch = 0;
-               if(self.freezetag_frozen)
+               if(self.frozen)
                        do_crouch = 0;
                if(self.weapon == WEP_SHOTGUN && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink)
                        do_crouch = 0;