]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cl_client.qc
Merge branch 'TimePath/bot_api' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cl_client.qc
index 40775abee330a29a25ae781017f49e27aaec92dc..adf2542cbd5853f0b8f7e78ca045ac00b7b00ec4 100644 (file)
@@ -20,8 +20,7 @@
 #include "campaign.qh"
 #include "command/common.qh"
 
-#include "bot/bot.qh"
-#include "bot/navigation.qh"
+#include "bot/api.qh"
 
 #include "../common/vehicles/all.qh"
 
@@ -53,7 +52,7 @@ void send_CSQC_teamnagger() {
        WriteByte(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
 }
 
-float ClientData_Send(entity to, int sf)
+bool ClientData_Send(entity this, entity to, int sf)
 {
        if(to != self.owner)
        {
@@ -94,14 +93,14 @@ float ClientData_Send(entity to, int sf)
 }
 
 void ClientData_Attach()
-{
+{SELFPARAM();
        Net_LinkEntity(self.clientdata = spawn(), false, 0, ClientData_Send);
        self.clientdata.drawonlytoclient = self;
        self.clientdata.owner = self;
 }
 
 void ClientData_Detach()
-{
+{SELFPARAM();
        remove(self.clientdata);
        self.clientdata = world;
 }
@@ -172,7 +171,7 @@ string CheckPlayerModel(string plyermodel) {
 void setplayermodel(entity e, string modelname)
 {
        precache_model(modelname);
-       setmodel(e, modelname);
+       _setmodel(e, modelname);
        player_setupanimsformodel();
        UpdatePlayerSounds();
 }
@@ -186,11 +185,11 @@ putting a client as observer in the server
 */
 void FixPlayermodel();
 void PutObserverInServer (void)
-{
+{SELFPARAM();
        entity  spot;
     self.hud = HUD_NORMAL;
 
-       if(IS_PLAYER(self)) { Send_Effect("spawn_event_neutral", self.origin, '0 0 0', 1); }
+       if(IS_PLAYER(self)) { Send_Effect(EFFECT_SPAWN_NEUTRAL, self.origin, '0 0 0', 1); }
 
        spot = SelectSpawnPoint (true);
        if(!spot)
@@ -205,6 +204,7 @@ void PutObserverInServer (void)
        }
 
        self.frags = FRAGS_SPECTATOR;
+       self.bot_attack = false;
 
        MUTATOR_CALLHOOK(MakePlayerObserver);
 
@@ -292,7 +292,7 @@ void PutObserverInServer (void)
        self.weapons = '0 0 0';
        self.model = "";
        FixPlayermodel();
-       setmodel(self, "null");
+       setmodel(self, MDL_Null);
        self.drawonlytoclient = self;
 
        setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX); // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY
@@ -316,7 +316,7 @@ void PutObserverInServer (void)
 
 .float model_randomizer;
 void FixPlayermodel()
-{
+{SELFPARAM();
        string defaultmodel;
        float defaultskin, chmdl, oldskin, n, i;
        vector m1, m2;
@@ -329,9 +329,8 @@ void FixPlayermodel()
        {
                if(teamplay)
                {
-                       string s;
-                       s = Static_Team_ColorName_Lower(self.team);
-                       if(s != "neutral")
+                       string s = Static_Team_ColorName_Lower(self.team);
+                       if (s != "neutral")
                        {
                                defaultmodel = cvar_string(strcat("sv_defaultplayermodel_", s));
                                defaultskin = cvar(strcat("sv_defaultplayerskin_", s));
@@ -362,6 +361,10 @@ void FixPlayermodel()
                }
        }
 
+       MUTATOR_CALLHOOK(FixPlayermodel, defaultmodel, defaultskin);
+       defaultmodel = ret_string;
+       defaultskin = ret_int;
+
        if(defaultmodel != "")
        {
                if (defaultmodel != self.model)
@@ -402,15 +405,11 @@ void FixPlayermodel()
                                setcolor(self, stof(autocvar_sv_defaultplayercolors));
 }
 
-/*
-=============
-PutClientInServer
 
-Called when a client spawns in the server
-=============
-*/
-void PutClientInServer (void)
+/** Called when a client spawns in the server */
+void PutClientInServer()
 {
+       SELFPARAM();
        if(IS_BOT_CLIENT(self))
                self.classname = "player";
        else if(IS_REAL_CLIENT(self))
@@ -432,7 +431,7 @@ void PutClientInServer (void)
 
        if(IS_PLAYER(self))
        {
-               entity spot, oldself;
+               entity spot;
 
                accuracy_resend(self);
 
@@ -463,7 +462,7 @@ void PutClientInServer (void)
                self.frags = FRAGS_PLAYER;
                if(INDEPENDENT_PLAYERS)
                        MAKE_INDEPENDENT_PLAYER(self);
-               self.flags = FL_CLIENT;
+               self.flags = FL_CLIENT | FL_PICKUPITEMS;
                if(autocvar__notarget)
                        self.flags |= FL_NOTARGET;
                self.takedamage = DAMAGE_AIM;
@@ -511,10 +510,10 @@ void PutClientInServer (void)
                if(g_weaponarena_random) // WEAPONTODO: more stuff that should be in a mutator. also: rename those cvars
                {
                        if(g_weaponarena_random_with_blaster)
-                               self.weapons &= ~WEPSET_BLASTER;
+                               self.weapons &= ~WEPSET(BLASTER);
                        W_RandomWeapons(self, g_weaponarena_random);
                        if(g_weaponarena_random_with_blaster)
-                               self.weapons |= WEPSET_BLASTER;
+                               self.weapons |= WEPSET(BLASTER);
                }
 
                self.items = start_items;
@@ -605,7 +604,7 @@ void PutClientInServer (void)
                        self.killcount = 0;
                }
 
-               CL_SpawnWeaponentity();
+               CL_SpawnWeaponentity(self);
                self.alpha = default_player_alpha;
                self.colormod = '1 1 1' * autocvar_g_player_brightness;
                self.exteriorweaponentity.alpha = default_weapon_alpha;
@@ -620,7 +619,8 @@ void PutClientInServer (void)
                // reset fields the weapons may use
                for (int j = WEP_FIRST; j <= WEP_LAST; ++j)
                {
-                       WEP_ACTION(j, WR_RESETPLAYER);
+                       Weapon w = get_weaponinfo(j);
+                       w.wr_resetplayer(w);
 
                        // all weapons must be fully loaded when we spawn
                        entity e = get_weaponinfo(j);
@@ -628,16 +628,12 @@ void PutClientInServer (void)
                                self.(weapon_load[j]) = e.reloading_ammo;
                }
 
-               oldself = self;
-               self = spot;
-                       activator = oldself;
-                               string s;
-                               s = self.target;
-                               self.target = string_null;
-                               SUB_UseTargets();
-                               self.target = s;
-                       activator = world;
-               self = oldself;
+               string s = spot.target;
+               spot.target = string_null;
+               activator = self;
+               WITH(entity, self, spot, SUB_UseTargets());
+               activator = world;
+               spot.target = s;
 
                Unfreeze(self);
 
@@ -670,7 +666,7 @@ void PutClientInServer (void)
 .float ebouncefactor, ebouncestop; // electro's values
 // TODO do we need all these fields, or should we stop autodetecting runtime
 // changes and just have a console command to update this?
-float ClientInit_SendEntity(entity to, int sf)
+bool ClientInit_SendEntity(entity this, entity to, int sf)
 {
        WriteByte(MSG_ENTITY, ENT_CLIENT_INIT);
        WriteByte(MSG_ENTITY, g_nexball_meter_period * 32);
@@ -703,7 +699,7 @@ float ClientInit_SendEntity(entity to, int sf)
 }
 
 void ClientInit_CheckUpdate()
-{
+{SELFPARAM();
        self.nextthink = time;
        if(self.count != autocvar_g_balance_armor_blockpercent)
        {
@@ -733,18 +729,13 @@ void ClientInit_CheckUpdate()
 }
 
 void ClientInit_Spawn()
-{
-       entity o;
-       entity e;
-       e = spawn();
+{SELFPARAM();
+       entity e = spawn();
        e.classname = "clientinit";
        e.think = ClientInit_CheckUpdate;
        Net_LinkEntity(e, false, 0, ClientInit_SendEntity);
 
-       o = self;
-       self = e;
-       ClientInit_CheckUpdate();
-       self = o;
+       WITH(entity, self, e, ClientInit_CheckUpdate());
 }
 
 /*
@@ -764,7 +755,7 @@ SetChangeParms
 =============
 */
 void SetChangeParms (void)
-{
+{SELFPARAM();
        // save parms for level change
        parm1 = self.parm_idlesince - time;
 }
@@ -775,7 +766,7 @@ DecodeLevelParms
 =============
 */
 void DecodeLevelParms (void)
-{
+{SELFPARAM();
        // load parms
        self.parm_idlesince = parm1;
        if(self.parm_idlesince == -(86400 * 366))
@@ -795,7 +786,7 @@ Called when a client types 'kill' in the console
 
 .float clientkill_nexttime;
 void ClientKill_Now_TeamChange()
-{
+{SELFPARAM();
        if(self.killindicator_teamchange == -1)
        {
                JoinBestTeam( self, false, true );
@@ -812,7 +803,7 @@ void ClientKill_Now_TeamChange()
 }
 
 void ClientKill_Now()
-{
+{SELFPARAM();
        if(self.vehicle)
        {
            vehicles_exit(VHEF_RELEASE);
@@ -837,7 +828,7 @@ void ClientKill_Now()
        // now I am sure the player IS dead
 }
 void KillIndicator_Think()
-{
+{SELFPARAM();
        if (gameover)
        {
                self.owner.killindicator = world;
@@ -854,8 +845,7 @@ void KillIndicator_Think()
 
        if(self.cnt <= 0)
        {
-               self = self.owner;
-               ClientKill_Now(); // no oldself needed
+               WITH(entity, self, self.owner, ClientKill_Now());
                return;
        }
     else if(g_cts && self.health == 1) // health == 1 means that it's silent
@@ -866,7 +856,7 @@ void KillIndicator_Think()
        else
        {
                if(self.cnt <= 10)
-                       setmodel(self, strcat("models/sprites/", ftos(self.cnt), ".spr32"));
+                       setmodel(self, MDL_NUM(self.cnt));
                if(IS_REAL_CLIENT(self.owner))
                {
                        if(self.cnt <= 10)
@@ -879,7 +869,7 @@ void KillIndicator_Think()
 
 float clientkilltime;
 void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 = spec
-{
+{SELFPARAM();
        float killtime;
        float starttime;
        entity e;
@@ -983,7 +973,7 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2
 }
 
 void ClientKill (void)
-{
+{SELFPARAM();
        if(gameover) return;
        if(self.player_blocked) return;
        if(self.frozen) return;
@@ -1044,7 +1034,7 @@ Called once (not at each match start) when a client begins a connection to the s
 =============
 */
 void ClientPreConnect (void)
-{
+{SELFPARAM();
        if(autocvar_sv_eventlog)
        {
                GameLogEcho(sprintf(":connect:%d:%d:%s",
@@ -1064,15 +1054,13 @@ Called when a client connects to the server
 =============
 */
 void DecodeLevelParms (void);
-//void dom_player_join_team(entity pl);
-void set_dom_state(entity e);
 void ClientConnect (void)
-{
+{SELFPARAM();
        float t;
 
        if(IS_CLIENT(self))
        {
-               print("Warning: ClientConnect, but already connected!\n");
+               LOG_INFO("Warning: ClientConnect, but already connected!\n");
                return;
        }
 
@@ -1092,7 +1080,7 @@ void ClientConnect (void)
 
        if(player_count<0)
        {
-               dprint("BUG player count is lower than zero, this cannot happen!\n");
+               LOG_TRACE("BUG player count is lower than zero, this cannot happen!\n");
                player_count = 0;
        }
 
@@ -1227,7 +1215,7 @@ void ClientConnect (void)
        else
                stuffcmd(self, "set _teams_available 0\n");
 
-       attach_entcs();
+       attach_entcs(self);
 
        bot_relinkplayerlist();
 
@@ -1248,7 +1236,7 @@ void ClientConnect (void)
                        Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage());
                }
 
-               if(autocvar_g_bugrigs || (g_weaponarena_weapons == WEPSET_TUBA))
+               if(autocvar_g_bugrigs || (g_weaponarena_weapons == WEPSET(TUBA)))
                        stuffcmd(self, "cl_cmd settemp chase_active 1\n");
        }
 
@@ -1262,7 +1250,7 @@ void ClientConnect (void)
 
        CheatInitClient();
 
-       CSQCMODEL_AUTOINIT();
+       CSQCMODEL_AUTOINIT(self);
 
        self.model_randomizer = random();
 
@@ -1270,10 +1258,7 @@ void ClientConnect (void)
                sv_notice_join();
 
        for (entity e = world; (e = findfloat(e, init_for_player_needed, 1)); ) {
-               entity oldself = self;
-               self = e;
-               e.init_for_player(oldself);
-               self = oldself;
+               WITH(entity, self, e, e.init_for_player(this));
        }
 
        MUTATOR_CALLHOOK(ClientConnect, self);
@@ -1288,13 +1273,13 @@ Called when a client disconnects from the server
 .entity chatbubbleentity;
 void ReadyCount();
 void ClientDisconnect (void)
-{
+{SELFPARAM();
        if(self.vehicle)
            vehicles_exit(VHEF_RELEASE);
 
        if (!IS_CLIENT(self))
        {
-               print("Warning: ClientDisconnect without ClientConnect\n");
+               LOG_INFO("Warning: ClientDisconnect without ClientConnect\n");
                return;
        }
 
@@ -1303,7 +1288,7 @@ void ClientDisconnect (void)
        if ( self.active_minigame )
                part_minigame(self);
 
-       if(IS_PLAYER(self)) { Send_Effect("spawn_event_neutral", self.origin, '0 0 0', 1); }
+       if(IS_PLAYER(self)) { Send_Effect(EFFECT_SPAWN_NEUTRAL, self.origin, '0 0 0', 1); }
 
        CheatShutdownClient();
 
@@ -1316,8 +1301,7 @@ void ClientDisconnect (void)
 
        bot_clientdisconnect();
 
-       if(self.entcs)
-               detach_entcs();
+       detach_entcs(self);
 
        if(autocvar_sv_eventlog)
                GameLogEcho(strcat(":part:", ftos(self.playerid)));
@@ -1372,7 +1356,7 @@ void ClientDisconnect (void)
 
 .float BUTTON_CHAT;
 void ChatBubbleThink()
-{
+{SELFPARAM();
        self.nextthink = time;
        if ((self.owner.alpha < 0) || self.owner.chatbubbleentity != self)
        {
@@ -1381,9 +1365,9 @@ void ChatBubbleThink()
                remove(self);
                return;
        }
-       
+
        self.mdl = "";
-       
+
        if ( !self.owner.deadflag && IS_PLAYER(self.owner) )
        {
                if ( self.owner.active_minigame )
@@ -1391,14 +1375,14 @@ void ChatBubbleThink()
                else if ( self.owner.BUTTON_CHAT )
                        self.mdl = "models/misc/chatbubble.spr";
        }
-       
+
        if ( self.model != self.mdl )
-               setmodel(self, self.mdl);
+               _setmodel(self, self.mdl);
 
 }
 
 void UpdateChatBubble()
-{
+{SELFPARAM();
        if (self.alpha < 0)
                return;
        // spawn a chatbubble entity if needed
@@ -1409,7 +1393,7 @@ void UpdateChatBubble()
                self.chatbubbleentity.exteriormodeltoclient = self;
                self.chatbubbleentity.think = ChatBubbleThink;
                self.chatbubbleentity.nextthink = time;
-               setmodel(self.chatbubbleentity, "models/misc/chatbubble.spr"); // precision set below
+               setmodel(self.chatbubbleentity, MDL_CHAT); // precision set below
                //setorigin(self.chatbubbleentity, self.origin + '0 0 15' + self.maxs_z * '0 0 1');
                setorigin(self.chatbubbleentity, '0 0 15' + self.maxs_z * '0 0 1');
                setattachment(self.chatbubbleentity, self, "");  // sticks to moving player better, also conserves bandwidth
@@ -1437,7 +1421,7 @@ void UpdateChatBubble()
 }*/
 
 void respawn(void)
-{
+{SELFPARAM();
        if(self.alpha >= 0 && autocvar_g_respawn_ghosts)
        {
                self.solid = SOLID_NOT;
@@ -1446,7 +1430,7 @@ void respawn(void)
                self.velocity = '0 0 1' * autocvar_g_respawn_ghosts_speed;
                self.avelocity = randomvec() * autocvar_g_respawn_ghosts_speed * 3 - randomvec() * autocvar_g_respawn_ghosts_speed * 3;
                self.effects |= CSQCMODEL_EF_RESPAWNGHOST;
-               Send_Effect("respawn_ghost", self.origin, '0 0 0', 1);
+               Send_Effect(EFFECT_RESPAWN_GHOST, self.origin, '0 0 0', 1);
                if(autocvar_g_respawn_ghosts_maxtime)
                        SUB_SetFade (self, time + autocvar_g_respawn_ghosts_maxtime / 2 + random () * (autocvar_g_respawn_ghosts_maxtime - autocvar_g_respawn_ghosts_maxtime / 2), 1.5);
        }
@@ -1458,15 +1442,15 @@ void respawn(void)
 }
 
 void play_countdown(float finished, string samp)
-{
+{SELFPARAM();
        if(IS_REAL_CLIENT(self))
                if(floor(finished - time - frametime) != floor(finished - time))
                        if(finished - time < 6)
-                               sound (self, CH_INFO, samp, VOL_BASE, ATTEN_NORM);
+                               _sound (self, CH_INFO, samp, VOL_BASE, ATTEN_NORM);
 }
 
 void player_powerups (void)
-{
+{SELFPARAM();
        // add a way to see what the items were BEFORE all of these checks for the mutator hook
        int items_prev = self.items;
 
@@ -1487,7 +1471,7 @@ void player_powerups (void)
        {
                if (self.items & ITEM_Strength.m_itemid)
                {
-                       play_countdown(self.strength_finished, "misc/poweroff.wav");
+                       play_countdown(self.strength_finished, SND(POWEROFF));
                        self.effects = self.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT);
                        if (time > self.strength_finished)
                        {
@@ -1507,7 +1491,7 @@ void player_powerups (void)
                }
                if (self.items & ITEM_Shield.m_itemid)
                {
-                       play_countdown(self.invincible_finished, "misc/poweroff.wav");
+                       play_countdown(self.invincible_finished, SND(POWEROFF));
                        self.effects = self.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT);
                        if (time > self.invincible_finished)
                        {
@@ -1540,7 +1524,7 @@ void player_powerups (void)
                        }
                        else
                        {
-                               play_countdown(self.superweapons_finished, "misc/poweroff.wav");
+                               play_countdown(self.superweapons_finished, SND(POWEROFF));
                                if (time > self.superweapons_finished)
                                {
                                        self.items = self.items - (self.items & IT_SUPERWEAPON);
@@ -1629,16 +1613,25 @@ float CalcRotRegen(float current, float regenstable, float regenfactor, float re
 }
 
 void player_regen (void)
-{
+{SELFPARAM();
        float max_mod, regen_mod, rot_mod, limit_mod;
        max_mod = regen_mod = rot_mod = limit_mod = 1;
-       if(!MUTATOR_CALLHOOK(PlayerRegen, max_mod, regen_mod, rot_mod, limit_mod))
+       regen_mod_max = max_mod;
+       regen_mod_regen = regen_mod;
+       regen_mod_rot = rot_mod;
+       regen_mod_limit = limit_mod;
+
+       regen_health = autocvar_g_balance_health_regen;
+       regen_health_linear = autocvar_g_balance_health_regenlinear;
+       regen_health_rot = autocvar_g_balance_health_rot;
+       regen_health_rotlinear = autocvar_g_balance_health_rotlinear;
+       regen_health_stable = autocvar_g_balance_health_regenstable;
+       regen_health_rotstable = autocvar_g_balance_health_rotstable;
+       if(!MUTATOR_CALLHOOK(PlayerRegen))
        if(!self.frozen)
        {
-               float minh, mina, maxh, maxa, limith, limita;
-               maxh = autocvar_g_balance_health_rotstable;
+               float mina, maxa, limith, limita;
                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;
@@ -1648,13 +1641,13 @@ void player_regen (void)
                rot_mod = regen_mod_rot;
                limit_mod = regen_mod_limit;
 
-               maxh = maxh * max_mod;
-               minh = minh * max_mod;
+               regen_health_rotstable = regen_health_rotstable * max_mod;
+               regen_health_stable = regen_health_stable * max_mod;
                limith = limith * limit_mod;
                limita = limita * limit_mod;
 
                self.armorvalue = CalcRotRegen(self.armorvalue, mina, autocvar_g_balance_armor_regen, autocvar_g_balance_armor_regenlinear, regen_mod * frametime * (time > self.pauseregen_finished), maxa, autocvar_g_balance_armor_rot, autocvar_g_balance_armor_rotlinear, rot_mod * frametime * (time > self.pauserotarmor_finished), limita);
-               self.health = CalcRotRegen(self.health, minh, autocvar_g_balance_health_regen, autocvar_g_balance_health_regenlinear, regen_mod * frametime * (time > self.pauseregen_finished), maxh, autocvar_g_balance_health_rot, autocvar_g_balance_health_rotlinear, rot_mod * frametime * (time > self.pauserothealth_finished), limith);
+               self.health = CalcRotRegen(self.health, regen_health_stable, regen_health, regen_health_linear, regen_mod * frametime * (time > self.pauseregen_finished), regen_health_rotstable, regen_health_rot, regen_health_rotlinear, rot_mod * frametime * (time > self.pauserothealth_finished), limith);
        }
 
        // if player rotted to death...  die!
@@ -1680,7 +1673,7 @@ void player_regen (void)
 
 float zoomstate_set;
 void SetZoomState(float z)
-{
+{SELFPARAM();
        if(z != self.zoomstate)
        {
                self.zoomstate = z;
@@ -1689,7 +1682,8 @@ void SetZoomState(float z)
        zoomstate_set = 1;
 }
 
-void GetPressedKeys(void) {
+void GetPressedKeys()
+{SELFPARAM();
        MUTATOR_CALLHOOK(GetPressedKeys);
        #define X(var,bit,flag) (flag ? var |= bit : var &= ~bit)
        X(self.pressedkeys, KEY_FORWARD,        self.movement_x > 0);
@@ -1710,7 +1704,8 @@ spectate mode routines
 ======================
 */
 
-void SpectateCopy(entity spectatee) {
+void SpectateCopy(entity spectatee)
+{SELFPARAM();
        MUTATOR_CALLHOOK(SpectateCopy, spectatee, self);
        self.armortype = spectatee.armortype;
        self.armorvalue = spectatee.armorvalue;
@@ -1785,49 +1780,36 @@ void SpectateCopy(entity spectatee) {
     }
 }
 
-float SpectateUpdate()
-{
+bool SpectateUpdate()
+{SELFPARAM();
        if(!self.enemy)
-           return 0;
+           return false;
 
        if(!IS_PLAYER(self.enemy) || self == self.enemy)
        {
                SetSpectator(self, world);
-               return 0;
+               return false;
        }
 
        SpectateCopy(self.enemy);
 
-       return 1;
+       return true;
 }
 
-float SpectateSet()
-{
-       if(self.enemy.classname != "player")
+bool SpectateSet()
+{SELFPARAM();
+       if(!IS_PLAYER(self.enemy))
                return false;
-       /*if(self.enemy.vehicle)
-       {
 
-               msg_entity = self;
-               WriteByte(MSG_ONE, SVC_SETVIEW);
-               WriteEntity(MSG_ONE, self.enemy);
-               //stuffcmd(self, "set viewsize $tmpviewsize \n");
+       msg_entity = self;
+       WriteByte(MSG_ONE, SVC_SETVIEW);
+       WriteEntity(MSG_ONE, self.enemy);
+       self.movetype = MOVETYPE_NONE;
+       accuracy_resend(self);
 
-               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();
 
-               if(!SpectateUpdate())
-                       PutObserverInServer();
-       //}
        return true;
 }
 
@@ -1843,47 +1825,47 @@ void SetSpectator(entity player, entity spectatee)
        if(player.enemy && player.enemy.arc_beam) { player.enemy.arc_beam.SendFlags |= ARC_SF_SETTINGS; }
 }
 
-float Spectate(entity pl)
-{
+bool Spectate(entity pl)
+{SELFPARAM();
        if(g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer)
-       if(pl.team != self.team)
-               return 0;
+       if(DIFF_TEAM(pl, self))
+               return false;
 
        SetSpectator(self, pl);
        return SpectateSet();
 }
 
 // Returns next available player to spectate if g_ca_spectate_enemies == 0
-entity CA_SpectateNext(entity start) {
-       if (start.team == self.team) {
+entity CA_SpectateNext(entity start)
+{SELFPARAM();
+       if(SAME_TEAM(start, self))
                return start;
-       }
 
        other = start;
        // continue from current player
-       while(other && other.team != self.team) {
+       while(other && DIFF_TEAM(other, self))
                other = find(other, classname, "player");
-       }
 
-       if (!other) {
+       if (!other)
+       {
                // restart from begining
                other = find(other, classname, "player");
-               while(other && other.team != self.team) {
+               while(other && DIFF_TEAM(other, self))
                        other = find(other, classname, "player");
-               }
        }
 
        return other;
 }
 
-float SpectateNext()
-{
+bool SpectateNext()
+{SELFPARAM();
        other = find(self.enemy, classname, "player");
 
-       if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer) {
+       if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer)
                // CA and ca players when spectating enemies is forbidden
                other = CA_SpectateNext(other);
-       } else {
+       else
+       {
                // other modes and ca spectators or spectating enemies is allowed
                if (!other)
                        other = find(other, classname, "player");
@@ -1894,8 +1876,8 @@ float SpectateNext()
        return SpectateSet();
 }
 
-float SpectatePrev()
-{
+bool SpectatePrev()
+{SELFPARAM();
        // NOTE: chain order is from the highest to the lower entnum (unlike find)
        other = findchain(classname, "player");
        if (!other) // no player
@@ -1910,12 +1892,12 @@ float SpectatePrev()
        if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer)
        {
                do { other = other.chain; }
-               while(other && other.team != self.team);
+               while(other && DIFF_TEAM(other, self));
 
                if (!other)
                {
                        other = first;
-                       while(other.team != self.team)
+                       while(other && DIFF_TEAM(other, self))
                                other = other.chain;
                        if(other == self.enemy)
                                return true;
@@ -1940,7 +1922,7 @@ Update a respawn countdown display.
 =============
 */
 void ShowRespawnCountdown()
-{
+{SELFPARAM();
        float number;
        if(self.deadflag == DEAD_NO) // just respawned?
                return;
@@ -1959,7 +1941,7 @@ void ShowRespawnCountdown()
 }
 
 void LeaveSpectatorMode()
-{
+{SELFPARAM();
        if(self.caplayer)
                return;
        if(nJoinAllowed(self))
@@ -1997,7 +1979,8 @@ void LeaveSpectatorMode()
  * it checks whether the number of currently playing players exceeds g_maxplayers.
  * @return int number of free slots for players, 0 if none
  */
-float nJoinAllowed(entity ignore) {
+float nJoinAllowed(entity ignore)
+{SELFPARAM();
        if(!ignore)
        // this is called that way when checking if anyone may be able to join (to build qcstatus)
        // so report 0 free slots if restricted
@@ -2036,7 +2019,8 @@ float nJoinAllowed(entity ignore) {
  * Checks whether the client is an observer or spectator, if so, he will get kicked after
  * g_maxplayers_spectator_blocktime seconds
  */
-void checkSpectatorBlock() {
+void checkSpectatorBlock()
+{SELFPARAM();
        if(IS_SPEC(self) || IS_OBSERVER(self))
        if(!self.caplayer)
        if(IS_REAL_CLIENT(self))
@@ -2049,7 +2033,7 @@ void checkSpectatorBlock() {
 }
 
 void PrintWelcomeMessage()
-{
+{SELFPARAM();
        if(self.motd_actived_time == 0)
        {
                if (autocvar_g_campaign) {
@@ -2096,7 +2080,7 @@ void PrintWelcomeMessage()
 }
 
 void ObserverThink()
-{
+{SELFPARAM();
        if ( self.impulse )
        {
                MinigameImpulse(self.impulse);
@@ -2131,7 +2115,7 @@ void ObserverThink()
 }
 
 void SpectatorThink()
-{
+{SELFPARAM();
        if ( self.impulse )
        {
                if(MinigameImpulse(self.impulse))
@@ -2186,7 +2170,7 @@ void SpectatorThink()
 
 void vehicles_enter (entity pl, entity veh);
 void PlayerUseKey()
-{
+{SELFPARAM();
        if (!IS_PLAYER(self))
                return;
 
@@ -2272,7 +2256,7 @@ void() nexball_setstatus;
 .float last_vehiclecheck;
 .int items_added;
 void PlayerPreThink (void)
-{
+{SELFPARAM();
        WarpZone_PlayerPhysics_FixVAngle();
 
        self.stat_game_starttime = game_starttime;
@@ -2296,7 +2280,7 @@ void PlayerPreThink (void)
 
        // Savage: Check for nameless players
        if (isInvisibleString(self.netname)) {
-               string new_name = strzone(strcat("Player@", self.netaddress));
+               string new_name = strzone(strcat("Player@", ftos(self.playerid)));
                if(autocvar_sv_eventlog)
                        GameLogEcho(strcat(":name:", ftos(self.playerid), ":", new_name));
                if(self.netname_previous)
@@ -2323,7 +2307,7 @@ void PlayerPreThink (void)
                                        if(strstr(autocvar_g_xonoticversion, "git", 0) >= 0 || strstr(autocvar_g_xonoticversion, "autobuild", 0) >= 0)
                                        {
                                                // 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");
+                                               LOG_TRACE("^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");
                                                Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_BETA, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
                                        }
                                        else
@@ -2333,13 +2317,13 @@ void PlayerPreThink (void)
                                                if(r < 0)
                                                {
                                                        // 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");
+                                                       LOG_TRACE("^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");
                                                        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");
+                                                       LOG_INFO("^1NOTE^7 to ", self.netname, "^7 - the 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);
                                                }
                                        }
@@ -2560,14 +2544,12 @@ void PlayerPreThink (void)
 
                FixPlayermodel();
 
-               GrapplingHookFrame();
-
                // LordHavoc: allow firing on move frames (sub-ticrate), this gives better timing on slow servers
                //if(frametime)
                {
                        self.items &= ~self.items_added;
 
-                       W_WeaponFrame();
+                       W_WeaponFrame(self);
 
                        self.items_added = 0;
                        if(self.items & ITEM_Jetpack.m_itemid)
@@ -2628,15 +2610,14 @@ void PlayerPreThink (void)
        {
                self.teamkill_soundtime = 0;
 
-               entity oldpusher, oldself;
-
-               oldself = self; self = self.teamkill_soundsource;
-               oldpusher = self.pusher; self.pusher = oldself;
+               setself(self.teamkill_soundsource);
+               entity oldpusher = self.pusher;
+               self.pusher = this;
 
                PlayerSound(playersound_teamshoot, CH_VOICE, VOICETYPE_LASTATTACKER_ONLY);
 
                self.pusher = oldpusher;
-               self = oldself;
+               setself(this);
        }
 
        if(self.taunt_soundtime)
@@ -2663,8 +2644,9 @@ Called every frame for each client after the physics are run
 */
 .float idlekick_lasttimeleft;
 void PlayerPostThink (void)
-{
+{SELFPARAM();
        if(sv_maxidle > 0 && frametime) // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero).
+       if(IS_REAL_CLIENT(self))
        if(IS_PLAYER(self) || sv_maxidle_spectatorsareidle)
        {
                if (time - self.parm_idlesince < 1) // instead of (time == self.parm_idlesince) to support sv_maxidle <= 10
@@ -2734,5 +2716,5 @@ void PlayerPostThink (void)
 
        playerdemo_write();
 
-       CSQCMODEL_AUTOUPDATE();
+       CSQCMODEL_AUTOUPDATE(self);
 }