]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cl_client.qc
Merge branch 'master' into Mario/classname_checks
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cl_client.qc
index a403af3292c6bf3957cdf2a213717403e1094436..4f741fa4435abe5481cecf737e67e0a1ced851fb 100644 (file)
@@ -6,22 +6,6 @@ void send_CSQC_teamnagger() {
        WriteByte(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
 }
 
-void Announce(string snd) {
-       WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
-       WriteByte(MSG_BROADCAST, TE_CSQC_ANNOUNCE);
-       WriteString(MSG_BROADCAST, snd);
-}
-
-void AnnounceTo(entity e, string snd) {
-       if (clienttype(e) == CLIENTTYPE_REAL)
-       {
-               msg_entity = e;
-               WriteByte(MSG_ONE, SVC_TEMPENTITY);
-               WriteByte(MSG_ONE, TE_CSQC_ANNOUNCE);
-               WriteString(MSG_ONE, snd);
-       }
-}
-
 float ClientData_Send(entity to, float sf)
 {
        if(to != self.owner)
@@ -33,7 +17,7 @@ float ClientData_Send(entity to, float sf)
        entity e;
 
        e = to;
-       if(to.classname == "spectator")
+       if(IS_SPEC(to))
                e = to.enemy;
 
        sf = 0;
@@ -84,7 +68,7 @@ void ClientData_Touch(entity e)
        FOR_EACH_REALCLIENT(e2)
        {
                if(e2 != e)
-                       if(e2.classname == "spectator")
+                       if(IS_SPEC(e2))
                                if(e2.enemy == e)
                                        e2.clientdata.SendFlags = 1;
        }
@@ -140,7 +124,7 @@ vector Spawn_Score(entity spot, float mindist, float teamcheck)
                if(spot.target == "")
                        return '-1 0 0';
 
-       if(clienttype(self) == CLIENTTYPE_REAL)
+       if(IS_REAL_CLIENT(self))
        {
                if(spot.restriction == 1)
                        return '-1 0 0';
@@ -293,7 +277,7 @@ entity SelectSpawnPoint (float anypoint)
        else
        {
                float mindist;
-               if (arena_roundbased && !g_ca)
+               if (g_arena && arena_roundbased)
                        mindist = 800;
                else
                        mindist = 100;
@@ -394,13 +378,31 @@ void PutObserverInServer (void)
                error("No spawnpoints for observers?!?\n");
        RemoveGrapplingHook(self); // Wazat's Grappling Hook
 
-       if(clienttype(self) == CLIENTTYPE_REAL)
+       if(IS_REAL_CLIENT(self))
        {
                msg_entity = self;
                WriteByte(MSG_ONE, SVC_SETVIEW);
                WriteEntity(MSG_ONE, self);
        }
 
+       if(g_lms)
+       {
+               // Only if the player cannot play at all
+               if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666)
+                       self.frags = FRAGS_SPECTATOR;
+               else
+                       self.frags = FRAGS_LMS_LOSER;
+       }
+       else if((g_race && g_race_qualifying) || g_cts)
+       {
+               if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
+                       self.frags = FRAGS_LMS_LOSER;
+               else
+                       self.frags = FRAGS_SPECTATOR;
+       }
+       else
+               self.frags = FRAGS_SPECTATOR;
+
        MUTATOR_CALLHOOK(MakePlayerObserver);
 
        minstagib_stop_countdown(self);
@@ -424,12 +426,11 @@ void PutObserverInServer (void)
 
        if(self.killcount != -666) {
                if(g_lms) {
-                       if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0)
-                               bprint ("^4", self.netname, "^4 has no more lives left\n");
+                       if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0 && self.lms_spectate_warning != 2)
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_NOLIVES, self.netname);
                        else
-                               bprint ("^4", self.netname, "^4 is spectating now\n"); // TODO turn this into a proper forfeit?
-               } else
-                       bprint ("^4", self.netname, "^4 is spectating now\n");
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_FORFEIT, self.netname);
+               } else { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_SPECTATE, self.netname); }
 
                if(self.just_joined == FALSE) {
                        LogTeamchange(self.playerid, -1, 4);
@@ -460,7 +461,9 @@ void PutObserverInServer (void)
        self.pauseregen_finished = 0;
        self.damageforcescale = 0;
        self.death_time = 0;
+       self.respawn_flags = 0;
        self.respawn_time = 0;
+       self.stat_respawn_time = 0;
        self.alpha = 0;
        self.scale = 0;
        self.fade_time = 0;
@@ -505,45 +508,6 @@ void PutObserverInServer (void)
        self.punchvector = '0 0 0';
        self.oldvelocity = self.velocity;
        self.fire_endtime = -1;
-
-       if(g_arena)
-       {
-               if(self.version_mismatch)
-               {
-                       self.frags = FRAGS_SPECTATOR;
-                       Spawnqueue_Unmark(self);
-                       Spawnqueue_Remove(self);
-               }
-               else
-               {
-                       self.frags = FRAGS_LMS_LOSER;
-                       Spawnqueue_Insert(self);
-               }
-       }
-       else if(g_lms)
-       {
-               // Only if the player cannot play at all
-               if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666)
-                       self.frags = FRAGS_SPECTATOR;
-               else
-                       self.frags = FRAGS_LMS_LOSER;
-       }
-       else if(g_ca)
-       {
-               if(self.caplayer)
-                       self.frags = FRAGS_LMS_LOSER;
-               else
-                       self.frags = FRAGS_SPECTATOR;
-       }
-       else if((g_race && g_race_qualifying) || g_cts)
-       {
-               if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
-                       self.frags = FRAGS_LMS_LOSER;
-               else
-                       self.frags = FRAGS_SPECTATOR;
-       }
-       else
-               self.frags = FRAGS_SPECTATOR;
 }
 
 .float model_randomizer;
@@ -562,7 +526,7 @@ void FixPlayermodel()
                if(teamplay)
                {
                        string s;
-                       s = Team_ColorNameLowerCase(self.team);
+                       s = Team_ColorName_Lower(self.team);
                        if(s != "neutral")
                        {
                                defaultmodel = cvar_string(strcat("sv_defaultplayermodel_", s));
@@ -616,8 +580,11 @@ void FixPlayermodel()
                self.skin = stof(self.playerskin);
        }
 
-       if(chmdl || oldskin != self.skin)
-               self.species = player_getspecies(); // model or skin has changed
+       if(chmdl || oldskin != self.skin) // model or skin has changed
+       {
+               self.species = player_getspecies(); // update species
+               UpdatePlayerSounds(); // update skin sounds
+       }
 
        if(!teamplay)
                if(strlen(autocvar_sv_defaultplayercolors))
@@ -625,21 +592,6 @@ void FixPlayermodel()
                                setcolor(self, stof(autocvar_sv_defaultplayercolors));
 }
 
-void PlayerTouchExplode(entity p1, entity p2)
-{
-       vector org;
-       org = (p1.origin + p2.origin) * 0.5;
-       org_z += (p1.mins_z + p2.mins_z) * 0.5;
-
-       te_explosion(org);
-
-       entity e;
-       e = spawn();
-       setorigin(e, org);
-       RadiusDamage(e, world, g_touchexplode_damage, g_touchexplode_edgedamage, g_touchexplode_radius, world, g_touchexplode_force, DEATH_TOUCHEXPLODE, world);
-       remove(e);
-}
-
 /*
 =============
 PutClientInServer
@@ -651,11 +603,7 @@ Called when a client spawns in the server
 void PutClientInServer (void)
 {
        if(clienttype(self) == CLIENTTYPE_BOT)
-       {
                self.classname = "player";
-               if(g_ca)
-                       self.caplayer = 1;
-       }
        else if(clienttype(self) == CLIENTTYPE_REAL)
        {
                msg_entity = self;
@@ -674,13 +622,13 @@ void PutClientInServer (void)
                        self.classname = "observer";
        }
 
-       if((g_arena && !self.spawned) || (g_ca && !allowed_to_spawn))
-               self.classname = "observer";
+       MUTATOR_CALLHOOK(PutClientInServer);
 
        if(gameover)
                self.classname = "observer";
 
-       if(self.classname == "player" && (!g_ca || (g_ca && allowed_to_spawn))) {
+       if(IS_PLAYER(self))
+       {
                entity spot, oldself;
                float j;
 
@@ -694,7 +642,7 @@ void PutClientInServer (void)
                spot = SelectSpawnPoint (FALSE);
                if(!spot)
                {
-                       centerprint(self, "Sorry, no spawnpoints available!\nHope your team can fix it...");
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_JOIN_NOSPAWNS);
                        return; // spawn failed
                }
 
@@ -710,7 +658,7 @@ void PutClientInServer (void)
                self.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID;
                if(autocvar_g_playerclip_collisions)
                        self.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP;
-               if(clienttype(self) == CLIENTTYPE_BOT && autocvar_g_botclip_collisions)
+               if(IS_BOT_CLIENT(self) && autocvar_g_botclip_collisions)
                        self.dphitcontentsmask |= DPCONTENTS_BOTCLIP;
                self.frags = FRAGS_PLAYER;
                if(INDEPENDENT_PLAYERS)
@@ -786,7 +734,9 @@ void PutClientInServer (void)
                }
                self.damageforcescale = 2;
                self.death_time = 0;
+               self.respawn_flags = 0;
                self.respawn_time = 0;
+               self.stat_respawn_time = 0;
                self.scale = 0;
                self.fade_time = 0;
                self.pain_frame = 0;
@@ -838,14 +788,6 @@ void PutClientInServer (void)
                self.lastteleporttime = time; // prevent insane speeds due to changing origin
         self.hud = HUD_NORMAL;
 
-               if(g_arena)
-               {
-                       Spawnqueue_Remove(self);
-                       Spawnqueue_Mark(self);
-               }
-               else if(g_ca)
-                       self.caplayer = 1;
-
                self.event_damage = PlayerDamage;
 
                self.bot_attack = TRUE;
@@ -874,9 +816,9 @@ void PutClientInServer (void)
 
                if(g_assault) {
                        if(self.team == assault_attacker_team)
-                               centerprint(self, "You are attacking!");
+                               Send_Notification(NOTIF_TEAM, self, MSG_CENTER, CENTER_ASSAULT_ATTACKING);
                        else
-                               centerprint(self, "You are defending!");
+                               Send_Notification(NOTIF_TEAM, self, MSG_CENTER, CENTER_ASSAULT_DEFENDING);
                }
 
                target_voicescript_clear(self);
@@ -927,7 +869,7 @@ void PutClientInServer (void)
 
                if (autocvar_g_spawnsound)
                        soundat(world, self.origin, CH_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTN_NORM);
-       } else if(self.classname == "observer") {
+       } else if(IS_OBSERVER(self)) {
                PutObserverInServer ();
        }
 }
@@ -1076,14 +1018,13 @@ void ClientKill_Now_TeamChange()
        }
        else if(self.killindicator_teamchange == -2)
        {
-               if(g_ca)
-                       self.caplayer = 0;
                if(blockSpectators)
-                       sprint(self, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
                PutObserverInServer();
        }
        else
                SV_ChangeTeam(self.killindicator_teamchange - 1);
+       self.killindicator_teamchange = 0;
 }
 
 void ClientKill_Now()
@@ -1142,10 +1083,10 @@ void KillIndicator_Think()
        {
                if(self.cnt <= 10)
                        setmodel(self, strcat("models/sprites/", ftos(self.cnt), ".spr32"));
-               if(clienttype(self.owner) == CLIENTTYPE_REAL)
+               if(IS_REAL_CLIENT(self.owner))
                {
                        if(self.cnt <= 10)
-                               AnnounceTo(self.owner, strcat(ftos(self.cnt), ""));
+                               { Send_Notification(NOTIF_ONE, self.owner, MSG_ANNCE, Announcer_PickNumber(self.cnt)); }
                }
                self.nextthink = time + 1;
                self.cnt -= 1;
@@ -1186,7 +1127,7 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2
                        self.clientkill_nexttime = time + killtime + autocvar_g_balance_kill_antispam;
                }
 
-               if(killtime <= 0 || self.classname != "player" || self.deadflag != DEAD_NO)
+               if(killtime <= 0 || !IS_PLAYER(self) || self.deadflag != DEAD_NO)
                {
                        ClientKill_Now();
                }
@@ -1228,30 +1169,30 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2
                if(targetteam == 0) // just die
                {
                        self.killindicator.colormod = '0 0 0';
-                       if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(IS_REAL_CLIENT(self))
                        if(self.killindicator.cnt > 0)
-                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "^1Suicide in %d seconds", 1, self.killindicator.cnt);
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_SUICIDE, self.killindicator.cnt);
                }
                else if(targetteam == -1) // auto
                {
                        self.killindicator.colormod = '0 1 0';
-                       if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(IS_REAL_CLIENT(self))
                        if(self.killindicator.cnt > 0)
-                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "Changing team in %d seconds", 1, self.killindicator.cnt);
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_AUTO, self.killindicator.cnt);
                }
                else if(targetteam == -2) // spectate
                {
                        self.killindicator.colormod = '0.5 0.5 0.5';
-                       if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(IS_REAL_CLIENT(self))
                        if(self.killindicator.cnt > 0)
-                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "Spectating in %d seconds", 1, self.killindicator.cnt);
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_SPECTATE, self.killindicator.cnt);
                }
                else
                {
-                       self.killindicator.colormod = TeamColor(targetteam);
-                       if(clienttype(self) == CLIENTTYPE_REAL)
+                       self.killindicator.colormod = Team_ColorRGB(targetteam);
+                       if(IS_REAL_CLIENT(self))
                        if(self.killindicator.cnt > 0)
-                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, strcat("Changing to ", ColoredTeamName(targetteam), " in %d seconds"), 1, self.killindicator.cnt);
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, APP_TEAM_NUM_4(targetteam, CENTER_TEAMCHANGE_), self.killindicator.cnt);
                }
        }
 
@@ -1259,19 +1200,11 @@ 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
-       }
-    else if(self.freezetag_frozen)
-    {
-        // do nothing
-    }
-       else
-               ClientKill_TeamChange(0);
+       if(gameover) return;
+       if(self.player_blocked) return;
+       if(self.freezetag_frozen) return;
+       
+       ClientKill_TeamChange(0);
 }
 
 void CTS_ClientKill (entity e) // silent version of ClientKill, used when player finishes a CTS run. Useful to prevent cheating by running back to the start line and starting out with more speed
@@ -1293,7 +1226,7 @@ void FixClientCvars(entity e)
                stuffcmd(e, "cl_cmd settemp cl_movecliptokeyboard 2\n");
        if(autocvar_g_antilag == 3) // client side hitscan
                stuffcmd(e, "cl_cmd settemp cl_prydoncursor_notrace 0\n");
-       if(sv_gentle)
+       if(autocvar_sv_gentle)
                stuffcmd(e, "cl_cmd settemp cl_gentle 1\n");
        /*
         * we no longer need to stuff this. Remove this comment block if you feel
@@ -1342,7 +1275,6 @@ ClientConnect
 Called when a client connects to the server
 =============
 */
-string ColoredTeamName(float t);
 void DecodeLevelParms (void);
 //void dom_player_join_team(entity pl);
 void set_dom_state(entity e);
@@ -1350,7 +1282,7 @@ void ClientConnect (void)
 {
        float t;
 
-       if(self.flags & FL_CLIENT)
+       if(IS_CLIENT(self))
        {
                print("Warning: ClientConnect, but already connected!\n");
                return;
@@ -1362,7 +1294,7 @@ void ClientConnect (void)
        DecodeLevelParms();
 
 #ifdef WATERMARK
-       sprint(self, strcat("^4SVQC Build information: ^1", WATERMARK, "\n"));
+       Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_WATERMARK, WATERMARK);
 #endif
 
        self.classname = "player_joining";
@@ -1391,34 +1323,34 @@ void ClientConnect (void)
        // identify the right forced team
        if(autocvar_g_campaign)
        {
-               if(clienttype(self) == CLIENTTYPE_REAL) // only players, not bots
+               if(IS_REAL_CLIENT(self)) // only players, not bots
                {
                        switch(autocvar_g_campaign_forceteam)
                        {
-                               case 1: self.team_forced = COLOR_TEAM1; break;
-                               case 2: self.team_forced = COLOR_TEAM2; break;
-                               case 3: self.team_forced = COLOR_TEAM3; break;
-                               case 4: self.team_forced = COLOR_TEAM4; break;
+                               case 1: self.team_forced = NUM_TEAM_1; break;
+                               case 2: self.team_forced = NUM_TEAM_2; break;
+                               case 3: self.team_forced = NUM_TEAM_3; break;
+                               case 4: self.team_forced = NUM_TEAM_4; break;
                                default: self.team_forced = 0;
                        }
                }
        }
        else if(PlayerInIDList(self, autocvar_g_forced_team_red))
-               self.team_forced = COLOR_TEAM1;
+               self.team_forced = NUM_TEAM_1;
        else if(PlayerInIDList(self, autocvar_g_forced_team_blue))
-               self.team_forced = COLOR_TEAM2;
+               self.team_forced = NUM_TEAM_2;
        else if(PlayerInIDList(self, autocvar_g_forced_team_yellow))
-               self.team_forced = COLOR_TEAM3;
+               self.team_forced = NUM_TEAM_3;
        else if(PlayerInIDList(self, autocvar_g_forced_team_pink))
-               self.team_forced = COLOR_TEAM4;
+               self.team_forced = NUM_TEAM_4;
        else if(autocvar_g_forced_team_otherwise == "red")
-               self.team_forced = COLOR_TEAM1;
+               self.team_forced = NUM_TEAM_1;
        else if(autocvar_g_forced_team_otherwise == "blue")
-               self.team_forced = COLOR_TEAM2;
+               self.team_forced = NUM_TEAM_2;
        else if(autocvar_g_forced_team_otherwise == "yellow")
-               self.team_forced = COLOR_TEAM3;
+               self.team_forced = NUM_TEAM_3;
        else if(autocvar_g_forced_team_otherwise == "pink")
-               self.team_forced = COLOR_TEAM4;
+               self.team_forced = NUM_TEAM_4;
        else if(autocvar_g_forced_team_otherwise == "spectate")
                self.team_forced = -1;
        else if(autocvar_g_forced_team_otherwise == "spectator")
@@ -1458,11 +1390,11 @@ void ClientConnect (void)
 
        PlayerStats_AddEvent(sprintf("kills-%d", self.playerid));
 
-    if(clienttype(self) == CLIENTTYPE_BOT)
+    if(IS_BOT_CLIENT(self))
         PlayerStats_AddPlayer(self);
 
        if(autocvar_sv_eventlog)
-               GameLogEcho(strcat(":join:", ftos(self.playerid), ":", ftos(num_for_edict(self)), ":", ((clienttype(self) == CLIENTTYPE_REAL) ? self.netaddress : "bot"), ":", self.netname));
+               GameLogEcho(strcat(":join:", ftos(self.playerid), ":", ftos(num_for_edict(self)), ":", ((IS_REAL_CLIENT(self)) ? self.netaddress : "bot"), ":", self.netname));
 
        LogTeamchange(self.playerid, self.team, 1);
 
@@ -1470,12 +1402,10 @@ void ClientConnect (void)
 
        self.netname_previous = strzone(self.netname);
 
-       bprint("^4", self.netname, "^4 connected");
-
-       if(self.classname != "observer" && (g_domination || g_ctf))
-               bprint(" and joined the ", ColoredTeamName(self.team));
-
-       bprint("\n");
+       if(IS_PLAYER(self) && teamplay)
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(self, INFO_JOIN_CONNECT_TEAM_), self.netname);
+       else
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_CONNECT, self.netname);
 
        stuffcmd(self, strcat(clientstuff, "\n"));
        stuffcmd(self, "cl_particles_reloadeffects\n"); // TODO do we still need this?
@@ -1504,13 +1434,6 @@ void ClientConnect (void)
        else
                stuffcmd(self, "set _teams_available 0\n");
 
-       if(g_arena || g_ca)
-       {
-               self.classname = "observer";
-               if(g_arena)
-                       Spawnqueue_Insert(self);
-       }
-
        attach_entcs();
 
        bot_relinkplayerlist();
@@ -1518,14 +1441,20 @@ void ClientConnect (void)
        self.spectatortime = time;
        if(blockSpectators)
        {
-               sprint(self, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));
+               Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
        }
 
        self.jointime = time;
        self.allowed_timeouts = autocvar_sv_timeout_number;
 
-       if(clienttype(self) == CLIENTTYPE_REAL)
+       if(IS_REAL_CLIENT(self))
        {
+               if(!autocvar_g_campaign)
+               {
+                       self.motd_actived_time = -1;
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage());
+               }
+
                if(autocvar_g_bugrigs || WEPSET_EQ_AW(g_weaponarena_weapons, WEP_TUBA))
                        stuffcmd(self, "cl_cmd settemp chase_active 1\n");
        }
@@ -1575,19 +1504,14 @@ void ClientConnect (void)
 
        CheatInitClient();
 
-       if(!autocvar_g_campaign)
-               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), autocvar_welcome_message_time, 0);
-
        CSQCMODEL_AUTOINIT();
 
        self.model_randomizer = random();
-    
-    if(clienttype(self) != CLIENTTYPE_REAL)
-        return;
-        
-    sv_notice_join();
-    
-    MUTATOR_CALLHOOK(ClientConnect);
+
+       if(IS_REAL_CLIENT(self))
+               sv_notice_join();
+
+       MUTATOR_CALLHOOK(ClientConnect);
 }
 /*
 =============
@@ -1603,7 +1527,7 @@ void ClientDisconnect (void)
        if(self.vehicle)
            vehicles_exit(VHEF_RELESE);
 
-       if not(self.flags & FL_CLIENT)
+       if not(IS_CLIENT(self))
        {
                print("Warning: ClientDisconnect without ClientConnect\n");
                return;
@@ -1631,8 +1555,8 @@ void ClientDisconnect (void)
 
        if(autocvar_sv_eventlog)
                GameLogEcho(strcat(":part:", ftos(self.playerid)));
-       bprint ("^4",self.netname);
-       bprint ("^4 disconnected\n");
+               
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_DISCONNECT, self.netname);
 
        MUTATOR_CALLHOOK(ClientDisconnect);
 
@@ -1654,12 +1578,6 @@ void ClientDisconnect (void)
 
        bot_relinkplayerlist();
 
-       if(g_arena)
-       {
-               Spawnqueue_Unmark(self);
-               Spawnqueue_Remove(self);
-       }
-
        accuracy_free(self);
        ClientData_Detach();
        PlayerScore_Detach(self);
@@ -1766,7 +1684,7 @@ void respawn(void)
 
 void play_countdown(float finished, string samp)
 {
-       if(clienttype(self) == CLIENTTYPE_REAL)
+       if(IS_REAL_CLIENT(self))
                if(floor(finished - time - frametime) != floor(finished - time))
                        if(finished - time < 6)
                                sound (self, CH_INFO, samp, VOL_BASE, ATTN_NORM);
@@ -1802,7 +1720,8 @@ void player_powerups (void)
                                self.alpha = default_player_alpha;
                                self.exteriorweaponentity.alpha = default_weapon_alpha;
                                self.items &~= IT_STRENGTH;
-                               sprint(self, "^3Invisibility has worn off\n");
+                               //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_INVISIBILITY, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_INVISIBILITY);
                        }
                }
                else
@@ -1812,7 +1731,8 @@ void player_powerups (void)
                                self.alpha = g_minstagib_invis_alpha;
                                self.exteriorweaponentity.alpha = g_minstagib_invis_alpha;
                                self.items |= IT_STRENGTH;
-                               sprint(self, "^3You are invisible\n");
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_INVISIBILITY, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_INVISIBILITY);
                        }
                }
 
@@ -1822,7 +1742,8 @@ void player_powerups (void)
                        if (time > self.invincible_finished)
                        {
                                self.items = self.items - (self.items & IT_INVINCIBLE);
-                               sprint(self, "^3Speed has worn off\n");
+                               //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_SPEED, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SPEED);
                        }
                }
                else
@@ -1830,7 +1751,8 @@ void player_powerups (void)
                        if (time < self.invincible_finished)
                        {
                                self.items = self.items | IT_INVINCIBLE;
-                               sprint(self, "^3You are on speed\n");
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SPEED, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SPEED);
                        }
                }
        }
@@ -1843,7 +1765,8 @@ void player_powerups (void)
                        if (time > self.strength_finished)
                        {
                                self.items = self.items - (self.items & IT_STRENGTH);
-                               sprint(self, "^3Strength has worn off\n");
+                               //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_STRENGTH, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_STRENGTH);
                        }
                }
                else
@@ -1851,7 +1774,8 @@ void player_powerups (void)
                        if (time < self.strength_finished)
                        {
                                self.items = self.items | IT_STRENGTH;
-                               sprint(self, "^3Strength infuses your weapons with devastating power\n");
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_STRENGTH, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_STRENGTH);
                        }
                }
                if (self.items & IT_INVINCIBLE)
@@ -1861,7 +1785,8 @@ void player_powerups (void)
                        if (time > self.invincible_finished)
                        {
                                self.items = self.items - (self.items & IT_INVINCIBLE);
-                               sprint(self, "^3Shield has worn off\n");
+                               //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_SHIELD, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SHIELD);
                        }
                }
                else
@@ -1869,7 +1794,8 @@ void player_powerups (void)
                        if (time < self.invincible_finished)
                        {
                                self.items = self.items | IT_INVINCIBLE;
-                               sprint(self, "^3Shield surrounds you\n");
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SHIELD, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SHIELD);
                        }
                }
                if (self.items & IT_SUPERWEAPON)
@@ -1878,7 +1804,8 @@ void player_powerups (void)
                        {
                                self.superweapons_finished = 0;
                                self.items = self.items - (self.items & IT_SUPERWEAPON);
-                               sprint(self, "^3Superweapons have been lost\n");
+                               //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_LOST, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_LOST);
                        }
                        else if (self.items & IT_UNLIMITED_SUPERWEAPONS)
                        {
@@ -1891,7 +1818,8 @@ void player_powerups (void)
                                {
                                        self.items = self.items - (self.items & IT_SUPERWEAPON);
                                        WEPSET_ANDNOT_EA(self, WEPBIT_SUPERWEAPONS);
-                                       sprint(self, "^3Superweapons have broken down\n");
+                                       //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_BROKEN, self.netname);
+                                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_BROKEN);
                                }
                        }
                }
@@ -1900,7 +1828,8 @@ void player_powerups (void)
                        if (time < self.superweapons_finished || (self.items & IT_UNLIMITED_SUPERWEAPONS))
                        {
                                self.items = self.items | IT_SUPERWEAPON;
-                               sprint(self, "^3You now have a superweapon\n");
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_PICKUP, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_PICKUP);
                        }
                        else
                        {
@@ -2006,7 +1935,7 @@ void player_regen (void)
        limita = limita * limit_mod;
        //limitf = limitf * limit_mod;
 
-       if(g_lms && g_ca)
+       if(g_ca)
                rot_mod = 0;
 
        if (!g_minstagib && !g_ca && (!g_lms || autocvar_g_lms_regenerate))
@@ -2131,7 +2060,6 @@ void SpectateCopy(entity spectatee) {
        self.dmg_inflictor = spectatee.dmg_inflictor;
        self.v_angle = spectatee.v_angle;
        self.angles = spectatee.v_angle;
-       self.stat_respawn_time = spectatee.stat_respawn_time;
        if(!self.BUTTON_USE)
                self.fixangle = TRUE;
        setorigin(self, spectatee.origin);
@@ -2173,7 +2101,7 @@ float SpectateUpdate() {
        if (self == self.enemy)
                return 0;
 
-       if(self.enemy.classname != "player")
+       if not(IS_PLAYER(self.enemy))
                return 0;
 
        SpectateCopy(self.enemy);
@@ -2224,7 +2152,7 @@ float SpectateNext(entity _prefer) {
        if (other)
                self.enemy = other;
 
-       if(self.enemy.classname == "player") {
+       if(IS_PLAYER(self.enemy)) {
            /*if(self.enemy.vehicle)
            {      
             
@@ -2275,55 +2203,40 @@ void ShowRespawnCountdown()
                {
                        self.respawn_countdown = number - 1;
                        if(ceil(self.respawn_time - (time + 0.5)) == number) // only say it if it is the same number even in 0.5s; to prevent overlapping sounds
-                               AnnounceTo(self, strcat(ftos(number), ""));
+                               Send_Notification(NOTIF_ONE, self, MSG_ANNCE, Announcer_PickNumber(number)); 
                }
        }
 }
 
-.float prevent_join_msgtime;
 void LeaveSpectatorMode()
 {
-       if(nJoinAllowed(self)) {
-               if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) {
+       if(self.caplayer)
+               return;
+       if(nJoinAllowed(self))
+       {
+               if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0)
+               {
                        self.classname = "player";
 
                        if(autocvar_g_campaign || autocvar_g_balance_teams)
-                               JoinBestTeam(self, FALSE, TRUE);
+                               { JoinBestTeam(self, FALSE, TRUE); }
 
                        if(autocvar_g_campaign)
-                               campaign_bots_may_start = 1;
-
-                       PutClientInServer();
+                               { campaign_bots_may_start = 1; }
 
-                       if(self.classname == "player")
-                               bprint ("^4", self.netname, "^4 is playing now\n");
+                       Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN);
 
-                       if(!autocvar_g_campaign)
-                       if (time < self.jointime + autocvar_welcome_message_time)
-                               Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD); // clear MOTD
-
-                       if (self.prevent_join_msgtime)
-                       {
-                               Send_CSQC_Centerprint_Generic_Expire(self, CPID_PREVENT_JOIN);
-                               self.prevent_join_msgtime = 0;
-                       }
+                       PutClientInServer();
 
-                       return;
-               } else {
-                       if (g_ca && self.caplayer) {
-                       }       // do nothing
-                       else
-                               stuffcmd(self,"menu_showteamselect\n");
-                       return;
+                       if(IS_PLAYER(self)) { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_PLAY, self.netname); }
                }
+               else
+                       stuffcmd(self, "menu_showteamselect\n");
        }
-       else {
-               //player may not join because of g_maxplayers is set
-               if (time - self.prevent_join_msgtime > 2)
-               {
-                       Send_CSQC_Centerprint_Generic(self, CPID_PREVENT_JOIN, PREVENT_JOIN_TEXT, 0, 0);
-                       self.prevent_join_msgtime = time;
-               }
+       else
+       {
+               // Player may not join because g_maxplayers is set
+               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_JOIN_PREVENT);
        }
 }
 
@@ -2358,8 +2271,9 @@ float nJoinAllowed(entity ignore) {
                return maxclients - totalClients;
 
        float currentlyPlaying = 0;
-       FOR_EACH_REALPLAYER(e)
-               currentlyPlaying += 1;
+       FOR_EACH_REALCLIENT(e)
+               if(IS_PLAYER(e) || e.caplayer == 1)
+                       currentlyPlaying += 1;
 
        if(currentlyPlaying < autocvar_g_maxplayers)
                return min(maxclients - totalClients, autocvar_g_maxplayers - currentlyPlaying);
@@ -2372,48 +2286,59 @@ float nJoinAllowed(entity ignore) {
  * g_maxplayers_spectator_blocktime seconds
  */
 void checkSpectatorBlock() {
-       if(self.classname == "spectator" || self.classname == "observer") {
+       if(IS_SPEC(self) || IS_OBSERVER(self)) {
                if( time > (self.spectatortime + autocvar_g_maxplayers_spectator_blocktime) ) {
-                       sprint(self, "^7You were kicked from the server because you are spectator and spectators aren't allowed at the moment.\n");
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_QUIT_KICK_SPECTATING);
                        dropclient(self);
                }
        }
 }
 
-.float motd_actived_time; // used for both motd and campaign_message
 void PrintWelcomeMessage()
 {
-       if (self.motd_actived_time == 0) { // is there already a message showing?
+       if(self.motd_actived_time == 0)
+       {
                if (autocvar_g_campaign) {
-                       if ((self.classname == "player" && self.BUTTON_INFO) || (self.classname != "player")) {
+                       if ((IS_PLAYER(self) && self.BUTTON_INFO) || (!IS_PLAYER(self))) {
                                self.motd_actived_time = time;
-                               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, campaign_message, -1, 0);
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, campaign_message);
                        }
                } else {
-                       if ((time - self.jointime > autocvar_welcome_message_time) && self.BUTTON_INFO) {
+                       if (self.BUTTON_INFO) {
                                self.motd_actived_time = time;
-                               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), -1, 0);
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage());
                        }
                }
-       } else { // showing MOTD or campaign message
+       }
+       else if(self.motd_actived_time > 0) // showing MOTD or campaign message
+       {
                if (autocvar_g_campaign) {
                        if (self.BUTTON_INFO)
                                self.motd_actived_time = time;
-                       else if ((time - self.motd_actived_time > 2) && self.classname == "player") { // hide it some seconds after BUTTON_INFO has been released
+                       else if ((time - self.motd_actived_time > 2) && IS_PLAYER(self)) { // hide it some seconds after BUTTON_INFO has been released
                                self.motd_actived_time = 0;
-                               Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD);
+                               Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
                        }
                } else {
-                       if ((time - self.jointime) > autocvar_welcome_message_time) {
-                               if (self.BUTTON_INFO)
-                                       self.motd_actived_time = time;
-                               else if (time - self.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
-                                       self.motd_actived_time = 0;
-                                       Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD);
-                               }
+                       if (self.BUTTON_INFO)
+                               self.motd_actived_time = time;
+                       else if (time - self.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
+                               self.motd_actived_time = 0;
+                               Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
                        }
                }
        }
+       else //if(self.motd_actived_time < 0) // just connected, motd is active
+       {
+               if(self.BUTTON_INFO) // BUTTON_INFO hides initial MOTD
+                       self.motd_actived_time = -2; // wait until BUTTON_INFO gets released
+               else if(self.motd_actived_time == -2 || IS_PLAYER(self) || time - self.jointime > autocvar_welcome_message_time)
+               {
+                       // instanctly hide MOTD
+                       self.motd_actived_time = 0;
+                       Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
+               }
+       }
 }
 
 void ObserverThink()
@@ -2444,8 +2369,6 @@ void ObserverThink()
                        }
                }
        }
-
-       PrintWelcomeMessage();
 }
 
 void SpectatorThink()
@@ -2484,13 +2407,12 @@ void SpectatorThink()
                        PutObserverInServer();
        }
 
-       PrintWelcomeMessage();
        self.flags |= FL_CLIENT | FL_NOTARGET;
 }
 
 void PlayerUseKey()
 {
-       if(self.classname != "player")
+       if not(IS_PLAYER(self))
                return;
 
        if(self.vehicle)
@@ -2503,8 +2425,6 @@ void PlayerUseKey()
        MUTATOR_CALLHOOK(PlayerUseKey);
 }
 
-.float touchexplode_time;
-
 /*
 =============
 PlayerPreThink
@@ -2520,14 +2440,10 @@ void PlayerPreThink (void)
        WarpZone_PlayerPhysics_FixVAngle();
 
        self.stat_game_starttime = game_starttime;
+       self.stat_round_starttime = round_starttime;
        self.stat_allow_oldnexbeam = autocvar_g_allow_oldnexbeam;
        self.stat_leadlimit = autocvar_leadlimit;
 
-       if(g_arena || (g_ca && !allowed_to_spawn))
-               self.stat_respawn_time = 0;
-       else
-               self.stat_respawn_time = self.respawn_time;
-
        if(frametime)
        {
                // physics frames: update anticheat stuff
@@ -2561,7 +2477,7 @@ void PlayerPreThink (void)
                                        {
                                                // notify release users if connecting to git
                                                dprint("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n");
-                                               sprint(self, strcat("\{1}^1NOTE: ^7the server is running ^3Xonotic ", autocvar_g_xonoticversion, " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"));
+                                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_BETA, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
                                        }
                                        else
                                        {
@@ -2571,13 +2487,13 @@ void PlayerPreThink (void)
                                                {
                                                        // give users new version
                                                        dprint("^1NOTE^7 to ", self.netname, "^7 - ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.org/^1!\n");
-                                                       sprint(self, strcat("\{1}^1NOTE: ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.org/^1!\n"));
+                                                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_OUTDATED, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
                                                }
                                                else if(r > 0)
                                                {
                                                        // notify users about old server version
                                                        print("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n");
-                                                       sprint(self, strcat("\{1}^1NOTE: ^7the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"));
+                                                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_OLD, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
                                                }
                                        }
                                }
@@ -2587,7 +2503,7 @@ void PlayerPreThink (void)
        // GOD MODE info
        if(!(self.flags & FL_GODMODE)) if(self.max_armorvalue)
        {
-               sprint(self, strcat("godmode saved you ", ftos(self.max_armorvalue), " units of damage, cheater!\n"));
+               Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_GODMODE_OFF, self.max_armorvalue);
                self.max_armorvalue = 0;
        }
 
@@ -2605,11 +2521,11 @@ void PlayerPreThink (void)
                self.usekeypressed = self.BUTTON_USE;
        }
 
-       PrintWelcomeMessage();
+       if(IS_REAL_CLIENT(self))
+               PrintWelcomeMessage();
 
-       if(self.classname == "player") {
-//             if(self.netname == "Wazat")
-//                     bprint(self.classname, "\n");
+       if(IS_PLAYER(self))
+       {
 
                CheckRules_Player();
 
@@ -2653,25 +2569,26 @@ void PlayerPreThink (void)
 
                if (self.deadflag != DEAD_NO)
                {
-                       float button_pressed, force_respawn;
                        if(self.personal && g_race_qualifying)
                        {
                                if(time > self.respawn_time)
                                {
                                        self.respawn_time = time + 1; // only retry once a second
+                                       self.stat_respawn_time = self.respawn_time;
                                        respawn();
                                        self.impulse = 141;
                                }
                        }
                        else
                        {
+                               float button_pressed;
                                if(frametime)
                                        player_anim();
                                button_pressed = (self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE);
-                               force_respawn = (g_lms || g_ca || g_cts || autocvar_g_forced_respawn);
+
                                if (self.deadflag == DEAD_DYING)
                                {
-                                       if(force_respawn)
+                                       if(self.respawn_flags & RESPAWN_FORCE)
                                                self.deadflag = DEAD_RESPAWNING;
                                        else if(!button_pressed)
                                                self.deadflag = DEAD_DEAD;
@@ -2694,7 +2611,13 @@ void PlayerPreThink (void)
                                                respawn();
                                        }
                                }
+
                                ShowRespawnCountdown();
+
+                               if(self.respawn_flags & RESPAWN_SILENT)
+                                       self.stat_respawn_time = 0;
+                               else
+                                       self.stat_respawn_time = self.respawn_time;
                        }
 
                        // if respawning, invert stat_respawn_time to indicate this, the client translates it
@@ -2703,25 +2626,6 @@ void PlayerPreThink (void)
 
                        return;
                }
-               // FIXME from now on self.deadflag is always 0 (and self.health is never < 1)
-               // so (self.deadflag == DEAD_NO) is always true in the code below
-
-               if(g_touchexplode)
-               if(time > self.touchexplode_time)
-               if(self.classname == "player")
-               if(self.deadflag == DEAD_NO)
-               if not(IS_INDEPENDENT_PLAYER(self))
-               FOR_EACH_PLAYER(other) if(self != other)
-               {
-                       if(time > other.touchexplode_time)
-                       if(other.deadflag == DEAD_NO)
-                       if not(IS_INDEPENDENT_PLAYER(other))
-                       if(boxesoverlap(self.absmin, self.absmax, other.absmin, other.absmax))
-                       {
-                               PlayerTouchExplode(self, other);
-                               self.touchexplode_time = other.touchexplode_time = time + 0.2;
-                       }
-               }
 
                if(g_lms && !self.deadflag && autocvar_g_lms_campcheck_interval)
                {
@@ -2743,10 +2647,13 @@ void PlayerPreThink (void)
                                //sprint(self, "distance: ", ftos(self.lms_traveled_distance), "\n");
                                if(self.lms_traveled_distance < autocvar_g_lms_campcheck_distance)
                                {
-                                       centerprint(self, autocvar_g_lms_campcheck_message);
+                                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_LMS_CAMPCHECK);
                                        // FIXME KadaverJack: gibbing player here causes playermodel to bounce around, instead of eye.md3
                                        // I wasn't able to find out WHY that happens, so I put a workaround in place that shall prevent players from being gibbed :(
-                                       Damage(self, self, self, bound(0, autocvar_g_lms_campcheck_damage, self.health + self.armorvalue * autocvar_g_balance_armor_blockpercent + 5), DEATH_CAMP, self.origin, '0 0 0');
+                                       if(self.vehicle)
+                                               Damage(self.vehicle, self, self, autocvar_g_lms_campcheck_damage * 2, DEATH_CAMP, self.vehicle.origin, '0 0 0');
+                                       else
+                                               Damage(self, self, self, bound(0, autocvar_g_lms_campcheck_damage, self.health + self.armorvalue * autocvar_g_balance_armor_blockpercent + 5), DEATH_CAMP, self.origin, '0 0 0');
                                }
                                self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval;
                                self.lms_traveled_distance = 0;
@@ -2841,9 +2748,9 @@ void PlayerPreThink (void)
                if (intermission_running)
                        IntermissionThink ();   // otherwise a button could be missed between
                return;
-       } else if(self.classname == "observer") {
+       } else if(IS_OBSERVER(self)) {
                ObserverThink();
-       } else if(self.classname == "spectator") {
+       } else if(IS_SPEC(self)) {
                SpectatorThink();
        }
 
@@ -2852,9 +2759,9 @@ void PlayerPreThink (void)
 
        float oldspectatee_status;
        oldspectatee_status = self.spectatee_status;
-       if(self.classname == "spectator")
+       if(IS_SPEC(self))
                self.spectatee_status = num_for_edict(self.enemy);
-       else if(self.classname == "observer")
+       else if(IS_OBSERVER(self))
                self.spectatee_status = num_for_edict(self);
        else
                self.spectatee_status = 0;
@@ -2942,11 +2849,7 @@ void PlayerPostThink (void)
        {
                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;
-                       }
+                       if(self.idlekick_lasttimeleft) { self.idlekick_lasttimeleft = 0; }
                }
                else
                {
@@ -2955,19 +2858,18 @@ void PlayerPostThink (void)
                        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);
+                                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_DISCONNECT_IDLING, timeleft);
                        }
                        if(timeleft <= 0)
                        {
-                               bprint("^3", self.netname, "^3 was kicked for idling.\n");
-                               AnnounceTo(self, "terminated");
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_KICK_IDLING, self.netname);
                                dropclient(self);
                                return;
                        }
                        else if(timeleft <= 10)
                        {
                                if(timeleft != self.idlekick_lasttimeleft)
-                                       AnnounceTo(self, ftos(timeleft));
+                                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, Announcer_PickNumber(timeleft));
                                self.idlekick_lasttimeleft = timeleft;
                        }
                }
@@ -2984,7 +2886,7 @@ void PlayerPostThink (void)
 
        //CheckPlayerJump();
 
-       if(self.classname == "player") {
+       if(IS_PLAYER(self)) {
                CheckRules_Player();
                UpdateChatBubble();
                if (self.impulse)