]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cl_client.qc
Merge remote branch 'origin/master' into fruitiex/animations
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cl_client.qc
index bcc5b6617aaa8b97efd66ec796c05aca1851e334..0513156a03f582f37bd4c4cc673f3815a90fa103 100644 (file)
@@ -596,7 +596,7 @@ void FixPlayermodel();
 void PutObserverInServer (void)
 {
        entity  spot;
-
+    self.hud = HUD_NORMAL;
        race_PreSpawnObserver();
 
        spot = SelectSpawnPoint (TRUE);
@@ -625,6 +625,9 @@ void PutObserverInServer (void)
                self.alivetime = 0;
        }
 
+       if(self.vehicle)
+           vehicles_exit(VHEF_RELESE);
+
        if(self.flagcarried)
                DropFlag(self.flagcarried, world, world);
 
@@ -1015,6 +1018,7 @@ void PutClientInServer (void)
                self.oldorigin = self.origin;
                self.prevorigin = self.origin;
                self.lastrocket = world; // stop rocket guiding, no revenge from the grave!
+               self.lastteleporttime = time; // prevent insane speeds due to changing origin
 
                if(g_arena)
                {
@@ -1060,7 +1064,7 @@ void PutClientInServer (void)
                //stuffcmd(self, "set viewsize $tmpviewsize \n");
 
                if (autocvar_g_spawnsound)
-                       sound (self, CHAN_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTN_NORM);
+                       sound (self, CH_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTN_NORM);
 
                if(g_assault) {
                        if(self.team == assault_attacker_team)
@@ -1267,7 +1271,19 @@ void ClientKill_Now_TeamChange()
 
 void ClientKill_Now()
 {
-       remove(self.killindicator);
+       if(self.vehicle)
+       {
+           vehicles_exit(VHEF_RELESE);
+           if(!self.killindicator_teamchange)
+           {
+            self.vehicle_health = -1;
+            Damage(self, self, self, 1 , DEATH_KILL, self.origin, '0 0 0');            
+           }
+       }
+
+       if(self.killindicator && !wasfreed(self.killindicator))
+               remove(self.killindicator);
+
        self.killindicator = world;
 
        if(self.killindicator_teamchange)
@@ -1280,6 +1296,13 @@ void ClientKill_Now()
 }
 void KillIndicator_Think()
 {
+       if (gameover)
+       {
+               self.owner.killindicator = world;
+               remove(self);
+               return;
+       }
+
        if (!self.owner.modelindex)
        {
                self.owner.killindicator = world;
@@ -1316,6 +1339,10 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2
 {
        float killtime;
        entity e;
+
+       if (gameover)
+               return;
+
        killtime = autocvar_g_balance_kill_delay;
 
        if(g_race_qualifying || g_cts)
@@ -1379,24 +1406,28 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2
                {
                        self.killindicator.colormod = '0 0 0';
                        if(clienttype(self) == CLIENTTYPE_REAL)
-                               Send_CSQC_Centerprint_Generic(self, CPID_KILL, "^1Suicide in %d seconds", 1, self.killindicator.cnt);
+                       if(self.killindicator.cnt > 0)
+                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "^1Suicide in %d seconds", 1, self.killindicator.cnt);
                }
                else if(targetteam == -1) // auto
                {
                        self.killindicator.colormod = '0 1 0';
                        if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(self.killindicator.cnt > 0)
                                Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "Changing team in %d seconds", 1, self.killindicator.cnt);
                }
                else if(targetteam == -2) // spectate
                {
                        self.killindicator.colormod = '0.5 0.5 0.5';
                        if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(self.killindicator.cnt > 0)
                                Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "Spectating in %d seconds", 1, self.killindicator.cnt);
                }
                else
                {
                        self.killindicator.colormod = TeamColor(targetteam);
                        if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(self.killindicator.cnt > 0)
                                Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, strcat("Changing to ", ColoredTeamName(targetteam), " in %d seconds"), 1, self.killindicator.cnt);
                }
        }
@@ -1405,6 +1436,9 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2
 
 void ClientKill (void)
 {
+       if (gameover)
+               return;
+
        if((g_arena || g_ca) && ((champion && champion.classname == "player" && player_count > 1) || player_count == 1)) // don't allow a kill in this case either
        {
                // do nothing
@@ -1428,55 +1462,6 @@ void CTS_ClientKill (entity e) // silent version of ClientKill, used when player
     e.lip = 0;
 }
 
-void DoTeamChange(float destteam)
-{
-       float t, c0;
-       if(!teamplay)
-       {
-               if(destteam >= 0)
-                       SetPlayerColors(self, destteam);
-               return;
-       }
-       if(self.classname == "player")
-       if(destteam == -1)
-       {
-               CheckAllowedTeams(self);
-               t = FindSmallestTeam(self, TRUE);
-               switch(self.team)
-               {
-                       case COLOR_TEAM1: c0 = c1; break;
-                       case COLOR_TEAM2: c0 = c2; break;
-                       case COLOR_TEAM3: c0 = c3; break;
-                       case COLOR_TEAM4: c0 = c4; break;
-                       default:          c0 = 999;
-               }
-               switch(t)
-               {
-                       case 1:
-                               if(c0 > c1)
-                                       destteam = COLOR_TEAM1;
-                               break;
-                       case 2:
-                               if(c0 > c2)
-                                       destteam = COLOR_TEAM2;
-                               break;
-                       case 3:
-                               if(c0 > c3)
-                                       destteam = COLOR_TEAM3;
-                               break;
-                       case 4:
-                               if(c0 > c4)
-                                       destteam = COLOR_TEAM4;
-                               break;
-               }
-               if(destteam == -1)
-                       return;
-       }
-       if(destteam == self.team && destteam >= 0 && !self.killindicator)
-               return;
-       ClientKill_TeamChange(destteam);
-}
-
 void FixClientCvars(entity e)
 {
        // send prediction settings to the client
@@ -1578,7 +1563,7 @@ void ClientConnect (void)
        playerdemo_init();
 
        anticheat_init();
-       
+
        race_PreSpawnObserver();
 
        //if(g_domination)
@@ -1652,6 +1637,8 @@ void ClientConnect (void)
 
        self.playerid = (playerid_last = playerid_last + 1);
 
+       PlayerStats_AddEvent(sprintf("kills-%d", self.playerid));
+
     if(clienttype(self) == CLIENTTYPE_BOT)
         PlayerStats_AddPlayer(self);
 
@@ -1800,6 +1787,9 @@ Called when a client disconnects from the server
 void ReadyCount();
 void ClientDisconnect (void)
 {
+       if(self.vehicle)
+           vehicles_exit(VHEF_RELESE);
+
        if not(self.flags & FL_CLIENT)
        {
                print("Warning: ClientDisconnect without ClientConnect\n");
@@ -1979,22 +1969,22 @@ void play_countdown(float finished, string samp)
        if(clienttype(self) == CLIENTTYPE_REAL)
                if(floor(finished - time - frametime) != floor(finished - time))
                        if(finished - time < 6)
-                               sound (self, CHAN_AUTO, samp, VOL_BASE, ATTN_NORM);
+                               sound (self, CH_INFO, samp, VOL_BASE, ATTN_NORM);
 }
 
 void player_powerups (void)
 {
        // add a way to see what the items were BEFORE all of these checks for the mutator hook
        olditems = self.items;
-       
+
        if((self.items & IT_USING_JETPACK) && !self.deadflag)
        {
-               SoundEntity_StartSound(self, CHAN_PLAYER, "misc/jetpack_fly.wav", VOL_BASE, autocvar_g_jetpack_attenuation);
+               SoundEntity_StartSound(self, CH_TRIGGER_SINGLE, "misc/jetpack_fly.wav", VOL_BASE, autocvar_g_jetpack_attenuation);
                self.modelflags |= MF_ROCKET;
        }
        else
        {
-               SoundEntity_StopSound(self, CHAN_PLAYER);
+               SoundEntity_StopSound(self, CH_TRIGGER_SINGLE);
                self.modelflags &~= MF_ROCKET;
        }
 
@@ -2002,7 +1992,7 @@ void player_powerups (void)
 
        if(!self.modelindex || self.deadflag) // don't apply the flags if the player is gibbed
                return;
-       
+
        Fire_ApplyDamage(self);
        Fire_ApplyEffect(self);
 
@@ -2108,7 +2098,7 @@ void player_powerups (void)
                if (time < self.spawnshieldtime)
                        self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT);
        }
-       
+
        MUTATOR_CALLHOOK(PlayerPowerups);
 }
 
@@ -2329,11 +2319,34 @@ void SpectateCopy(entity spectatee) {
        SetZoomState(spectatee.zoomstate);
 
        anticheat_spectatecopy(spectatee);
+
+       //self.vehicle = spectatee.vehicle;
+
+       self.hud = spectatee.hud;
+       if(spectatee.vehicle)
+    {
+        setorigin(self, spectatee.origin);
+        self.velocity = spectatee.vehicle.velocity;
+        self.v_angle += spectatee.vehicle.angles;
+        //self.v_angle_x *= -1;
+        self.vehicle_health = spectatee.vehicle_health;
+        self.vehicle_shield = spectatee.vehicle_shield;
+        self.vehicle_energy = spectatee.vehicle_energy;
+        self.vehicle_ammo1 = spectatee.vehicle_ammo1;
+        self.vehicle_ammo2 = spectatee.vehicle_ammo2;
+        self.vehicle_reload1 = spectatee.vehicle_reload1;
+        self.vehicle_reload2 = spectatee.vehicle_reload2;
+        
+        msg_entity = self;
+        WriteByte (MSG_ONE, SVC_SETVIEWPORT);
+        WriteEntity(MSG_ONE, spectatee);
+        //self.tur_head = spectatee.vehicle.vehicle_viewport;
+    }
 }
 
 float SpectateUpdate() {
        if(!self.enemy)
-               return 0;
+           return 0;           
 
        if (self == self.enemy)
                return 0;
@@ -2356,17 +2369,28 @@ float SpectateNext() {
                self.enemy = other;
 
        if(self.enemy.classname == "player") {
-               msg_entity = self;
-               WriteByte(MSG_ONE, SVC_SETVIEW);
-               WriteEntity(MSG_ONE, self.enemy);
-               //stuffcmd(self, "set viewsize $tmpviewsize \n");
-               self.movetype = MOVETYPE_NONE;
-               accuracy_resend(self);
-
-               if(!SpectateUpdate())
-                       PutObserverInServer();
-
-               return 1;
+           if(self.enemy.vehicle)
+           {      
+            msg_entity = self;
+            WriteByte(MSG_ONE, SVC_SETVIEWPORT);
+            WriteEntity(MSG_ONE, self.enemy);
+            //stuffcmd(self, "set viewsize $tmpviewsize \n");
+            self.movetype = MOVETYPE_NONE;
+            accuracy_resend(self);
+           }
+           else 
+           {           
+            msg_entity = self;
+            WriteByte(MSG_ONE, SVC_SETVIEW);
+            WriteEntity(MSG_ONE, self.enemy);
+            //stuffcmd(self, "set viewsize $tmpviewsize \n");
+            self.movetype = MOVETYPE_NONE;
+            accuracy_resend(self);
+
+            if(!SpectateUpdate())
+                PutObserverInServer();
+        }
+        return 1;
        } else {
                return 0;
        }
@@ -2416,6 +2440,7 @@ void LeaveSpectatorMode()
                                bprint ("^4", self.netname, "^4 is playing now\n");
 
                        if(!autocvar_g_campaign)
+                       if (time < self.jointime + autocvar_welcome_message_time)
                                Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD); // clear MOTD
 
                        return;
@@ -2480,11 +2505,9 @@ void ObserverThink()
 {
        if (self.flags & FL_JUMPRELEASED) {
                if (self.BUTTON_JUMP && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.flags |= FL_SPAWNING;
                } else if(self.BUTTON_ATCK && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        if(SpectateNext() == 1) {
                                self.classname = "spectator";
@@ -2507,11 +2530,9 @@ void SpectatorThink()
 {
        if (self.flags & FL_JUMPRELEASED) {
                if (self.BUTTON_JUMP && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.flags |= FL_SPAWNING;
                } else if(self.BUTTON_ATCK) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        if(SpectateNext() == 1) {
                                self.classname = "spectator";
@@ -2520,7 +2541,6 @@ void SpectatorThink()
                                PutClientInServer();
                        }
                } else if (self.BUTTON_ATCK2) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.classname = "observer";
                        PutClientInServer();
@@ -2538,6 +2558,8 @@ void SpectatorThink()
                                return;
                        }
                }
+               if(!SpectateUpdate())
+                       PutObserverInServer();
        }
 
        self.flags |= FL_CLIENT | FL_NOTARGET;
@@ -2549,6 +2571,12 @@ void PlayerUseKey()
        if(self.classname != "player")
                return;
 
+       if(self.vehicle)
+       {
+        vehicles_exit(VHEF_NORMAL);
+        return;
+       }
+       
        // a use key was pressed; call handlers
        if(ctf_usekey())
                return;
@@ -2652,12 +2680,12 @@ void PlayerPreThink (void)
                if (autocvar_g_campaign) {
                        if (self.classname == "player" && self.BUTTON_INFO) {
                                self.motd_actived_time = time;
-                               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, campaign_message, 999, 0);
+                               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, campaign_message, -1, 0);
                        }
                } else {
                        if ((self.classname == "player" || time - self.jointime > autocvar_welcome_message_time) && self.BUTTON_INFO) {
                                self.motd_actived_time = time;
-                               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), 999, 0);
+                               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), -1, 0);
                        }
                }
        } else { // showing MOTD or campaign message
@@ -2845,7 +2873,7 @@ void PlayerPreThink (void)
 
                self.prevorigin = self.origin;
 
-               if ((self.BUTTON_CROUCH && !self.hook.state) || self.health <= g_bloodloss)
+               if (((self.BUTTON_CROUCH && !self.hook.state) || self.health <= g_bloodloss) && self.animstate_startframe != 23) // prevent crouching if using melee attack
                {
                        if (!self.crouch)
                        {
@@ -2953,7 +2981,7 @@ void PlayerPreThink (void)
                oldself = self; self = self.teamkill_soundsource;
                oldpusher = self.pusher; self.pusher = oldself;
 
-               PlayerSound(playersound_teamshoot, CHAN_VOICE, VOICETYPE_LASTATTACKER_ONLY);
+               PlayerSound(playersound_teamshoot, CH_VOICE, VOICETYPE_LASTATTACKER_ONLY);
 
                self.pusher = oldpusher;
                self = oldself;
@@ -2963,7 +2991,7 @@ void PlayerPreThink (void)
        if(time > self.taunt_soundtime)
        {
                self.taunt_soundtime = 0;
-               PlayerSound(playersound_taunt, CHAN_VOICE, VOICETYPE_AUTOTAUNT);
+               PlayerSound(playersound_taunt, CH_VOICE, VOICETYPE_AUTOTAUNT);
        }
 
        target_voicescript_next(self);
@@ -3032,7 +3060,21 @@ void PlayerPostThink (void)
        {
                // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero).
                float timeleft;
+               if (time - self.parm_idlesince < 1) // instead of (time == self.parm_idlesince) to support sv_maxidle <= 10
+               {
+                       if(self.idlekick_lasttimeleft)
+                       {
+                               Send_CSQC_Centerprint_Generic_Expire(self, CPID_DISCONNECT_IDLING);
+                               self.idlekick_lasttimeleft = 0;
+                       }
+                       return;
+               }
                timeleft = ceil(sv_maxidle - (time - self.parm_idlesince));
+               if(timeleft == min(10, sv_maxidle - 1)) // - 1 to support sv_maxidle <= 10
+               {
+                       if(!self.idlekick_lasttimeleft)
+                               Send_CSQC_Centerprint_Generic(self, CPID_DISCONNECT_IDLING, "^3Stop idling!\n^3Disconnecting in %d seconds...", 1, timeleft);
+               }
                if(timeleft <= 0)
                {
                        bprint("^3", self.netname, "^3 was kicked for idling.\n");
@@ -3043,17 +3085,9 @@ void PlayerPostThink (void)
                else if(timeleft <= 10)
                {
                        if(timeleft != self.idlekick_lasttimeleft)
-                       {
-                               // TODO: send this msg only once
-                               Send_CSQC_Centerprint_Generic(self, CPID_DISCONNECT_IDLING, "^3Stop idling!\n^3Disconnecting in %d seconds...", 1, timeleft);
-                               AnnounceTo(self, strcat(ftos(timeleft), ""));
-                       }
-               }
-               else
-               {
-                       Send_CSQC_Centerprint_Generic(self, CPID_DISCONNECT_IDLING, "", 1, timeleft);
+                               AnnounceTo(self, ftos(timeleft));
+                       self.idlekick_lasttimeleft = timeleft;
                }
-               self.idlekick_lasttimeleft = timeleft;
        }
 
 #ifdef TETRIS
@@ -3078,7 +3112,7 @@ void PlayerPostThink (void)
        } else if (self.classname == "spectator") {
                //do nothing
        }
-
+       
        /*
        float i;
        for(i = 0; i < 1000; ++i)
@@ -3101,7 +3135,7 @@ void PlayerPostThink (void)
 
        if(self.waypointsprite_attachedforcarrier)
                WaypointSprite_UpdateHealth(self.waypointsprite_attachedforcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, autocvar_g_balance_armor_blockpercent));
-       
+
        if(self.classname == "player" && self.deadflag == DEAD_NO && autocvar_r_showbboxes)
        {
                if(!self.showheadshotbbox)
@@ -3119,7 +3153,8 @@ void PlayerPostThink (void)
        else
        {
                if(self.showheadshotbbox)
-                       remove(self.showheadshotbbox);
+                       if(self.showheadshotbbox && !wasfreed(self.showheadshotbbox))
+                remove(self.showheadshotbbox);
        }
 
        playerdemo_write();