]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cl_client.qc
Purge self from most of the warpzone lib
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cl_client.qc
index df51f8813f200776b7a55f8e29a4edb79cd20550..5d739ac7b99835c2608e32eeeb31667df1f4faff 100644 (file)
@@ -23,7 +23,9 @@
 #include "bot/navigation.qh"
 
 #include "../common/ent_cs.qh"
-#include "../common/state.qh"
+#include <common/state.qh>
+
+#include <common/effects/qc/globalsound.qh>
 
 #include "../common/triggers/teleporters.qh"
 
 
 #include "../lib/warpzone/server.qh"
 
+STATIC_METHOD(Client, Add, void(Client this, int _team))
+{
+    WITH(entity, self, this, ClientConnect());
+    TRANSMUTE(Player, this);
+    this.frame = 12; // 7
+    this.team = _team;
+    WITH(entity, self, this, PutClientInServer());
+}
+
+void PutObserverInServer();
+void ClientDisconnect();
+
+STATIC_METHOD(Client, Remove, void(Client this))
+{
+    TRANSMUTE(Observer, this);
+    WITH(entity, self, this, PutClientInServer(); ClientDisconnect());
+}
 
 void send_CSQC_teamnagger() {
        WriteHeader(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
@@ -87,14 +106,14 @@ bool ClientData_Send(entity this, entity to, int sf)
 void ClientData_Attach(entity this)
 {
        Net_LinkEntity(this.clientdata = new_pure(clientdata), false, 0, ClientData_Send);
-       self.clientdata.drawonlytoclient = this;
-       self.clientdata.owner = this;
+       this.clientdata.drawonlytoclient = this;
+       this.clientdata.owner = this;
 }
 
 void ClientData_Detach(entity this)
 {
        remove(this.clientdata);
-       self.clientdata = NULL;
+       this.clientdata = NULL;
 }
 
 void ClientData_Touch(entity e)
@@ -158,6 +177,8 @@ void setplayermodel(entity e, string modelname)
        precache_model(modelname);
        _setmodel(e, modelname);
        player_setupanimsformodel();
+       if(!autocvar_g_debug_globalsounds)
+               UpdatePlayerSounds(e);
 }
 
 void FixPlayermodel(entity player);
@@ -190,6 +211,13 @@ void PutObserverInServer()
         }
         // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY
         // so that your view doesn't go into the ceiling with MOVETYPE_FLY_WORLDONLY, previously "PL_VIEW_OFS"
+        if(!autocvar_g_debug_globalsounds)
+        {
+               // needed for player sounds
+               this.model = "";
+               FixPlayermodel(this);
+        } 
+        setmodel(this, MDL_Null);
         setsize(this, STAT(PL_CROUCH_MIN, NULL), STAT(PL_CROUCH_MAX, NULL));
         this.view_ofs = '0 0 0';
     }
@@ -235,7 +263,7 @@ void PutObserverInServer()
        this.spectatortime = time;
        this.bot_attack = false;
     this.hud = HUD_NORMAL;
-       this.classname = STR_OBSERVER;
+       TRANSMUTE(Observer, this);
        this.iscreature = false;
        this.teleportable = TELEPORT_SIMPLE;
        this.damagedbycontents = false;
@@ -274,9 +302,6 @@ void PutObserverInServer()
 
        this.items = 0;
        this.weapons = '0 0 0';
-       this.model = "";
-       FixPlayermodel(this);
-       setmodel(this, MDL_Null);
        this.drawonlytoclient = this;
 
        this.weaponname = "";
@@ -382,6 +407,8 @@ void FixPlayermodel(entity player)
        if(chmdl || oldskin != player.skin) // model or skin has changed
        {
                player.species = player_getspecies(player); // update species
+               if(!autocvar_g_debug_globalsounds)
+                       UpdatePlayerSounds(player); // update skin sounds
        }
 
        if(!teamplay)
@@ -396,14 +423,14 @@ void PutClientInServer()
 {
        SELFPARAM();
        if (IS_BOT_CLIENT(this)) {
-               this.classname = STR_PLAYER;
+               TRANSMUTE(Player, this);
        } else if (IS_REAL_CLIENT(this)) {
                msg_entity = this;
                WriteByte(MSG_ONE, SVC_SETVIEW);
                WriteEntity(MSG_ONE, this);
        }
        if (gameover) {
-               this.classname = STR_OBSERVER;
+               TRANSMUTE(Observer, this);
        }
 
        SetSpectatee(this, NULL);
@@ -428,7 +455,7 @@ void PutClientInServer()
                        return; // spawn failed
                }
 
-               this.classname = STR_PLAYER;
+               TRANSMUTE(Player, this);
                this.wasplayer = true;
                this.iscreature = true;
                this.teleportable = TELEPORT_NORMAL;
@@ -604,7 +631,7 @@ void PutClientInServer()
                if (!warmup_stage && !this.alivetime)
                        this.alivetime = time;
 
-               antilag_clear(this);
+               antilag_clear(this, CS(this));
        }
 }
 
@@ -627,6 +654,7 @@ bool ClientInit_SendEntity(entity this, entity to, int sf)
 }
 void ClientInit_misc()
 {
+    SELFPARAM();
        int channel = MSG_ONE;
        WriteHeader(channel, ENT_CLIENT_INIT);
        WriteByte(channel, g_nexball_meter_period * 32);
@@ -977,16 +1005,14 @@ void ClientConnect()
        SELFPARAM();
        if (Ban_MaybeEnforceBanOnce(this)) return;
        assert(!IS_CLIENT(this), return);
+       this.flags |= FL_CLIENT;
        assert(player_count >= 0, player_count = 0);
-       this.classname = "player_joining";
-       this.flags = FL_CLIENT;
 
 #ifdef WATERMARK
        Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_WATERMARK, WATERMARK);
 #endif
        this.version_nagtime = time + 10 + random() * 10;
-
-       ClientState_attach(this);
+       TRANSMUTE(Client, this);
 
        // identify the right forced team
        if (autocvar_g_campaign)
@@ -1021,24 +1047,24 @@ void ClientConnect()
        }
        if (!teamplay && this.team_forced > 0) this.team_forced = 0;
 
-       JoinBestTeam(this, false, false); // if the team number is valid, keep it
+    {
+        int id = this.playerid;
+        this.playerid = 0; // silent
+           JoinBestTeam(this, false, false); // if the team number is valid, keep it
+           this.playerid = id;
+    }
 
        if (autocvar_sv_spectate || autocvar_g_campaign || this.team_forced < 0) {
-               this.classname = STR_OBSERVER;
+               TRANSMUTE(Observer, this);
        } else {
-               if (!teamplay || autocvar_g_balance_teams)
-               {
-                       this.classname = STR_PLAYER;
-                       campaign_bots_may_start = 1;
-               }
-               else
-               {
-                       this.classname = STR_OBSERVER; // do it anyway
+               if (!teamplay || autocvar_g_balance_teams) {
+                       TRANSMUTE(Player, this);
+                       campaign_bots_may_start = true;
+               } else {
+                       TRANSMUTE(Observer, this); // do it anyway
                }
        }
 
-       this.playerid = ++playerid_last;
-
        PlayerStats_GameReport_AddEvent(sprintf("kills-%d", this.playerid));
 
        // always track bots, don't ask for cl_allow_uidtracking
@@ -1263,12 +1289,13 @@ void respawn()
        PutClientInServer();
 }
 
-void play_countdown(float finished, string samp)
+void play_countdown(float finished, Sound samp)
 {SELFPARAM();
+    TC(Sound, samp);
        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 ()
@@ -1293,7 +1320,7 @@ void player_powerups ()
        {
                if (self.items & ITEM_Strength.m_itemid)
                {
-                       play_countdown(self.strength_finished, SND(POWEROFF));
+                       play_countdown(self.strength_finished, SND_POWEROFF);
                        self.effects = self.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT);
                        if (time > self.strength_finished)
                        {
@@ -1313,7 +1340,7 @@ void player_powerups ()
                }
                if (self.items & ITEM_Shield.m_itemid)
                {
-                       play_countdown(self.invincible_finished, SND(POWEROFF));
+                       play_countdown(self.invincible_finished, SND_POWEROFF);
                        self.effects = self.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT);
                        if (time > self.invincible_finished)
                        {
@@ -1346,7 +1373,7 @@ void player_powerups ()
                        }
                        else
                        {
-                               play_countdown(self.superweapons_finished, SND(POWEROFF));
+                               play_countdown(self.superweapons_finished, SND_POWEROFF);
                                if (time > self.superweapons_finished)
                                {
                                        self.items = self.items - (self.items & IT_SUPERWEAPON);
@@ -1530,66 +1557,66 @@ spectate mode routines
 
 void SpectateCopy(entity this, entity spectatee)
 {
-       MUTATOR_CALLHOOK(SpectateCopy, spectatee, self);
-       self.armortype = spectatee.armortype;
-       self.armorvalue = spectatee.armorvalue;
-       self.ammo_cells = spectatee.ammo_cells;
-       self.ammo_plasma = spectatee.ammo_plasma;
-       self.ammo_shells = spectatee.ammo_shells;
-       self.ammo_nails = spectatee.ammo_nails;
-       self.ammo_rockets = spectatee.ammo_rockets;
-       self.ammo_fuel = spectatee.ammo_fuel;
-       self.clip_load = spectatee.clip_load;
-       self.clip_size = spectatee.clip_size;
-       self.effects = spectatee.effects & EFMASK_CHEAP; // eat performance
-       self.health = spectatee.health;
-       self.impulse = 0;
-       self.items = spectatee.items;
-       self.last_pickup = spectatee.last_pickup;
-       self.hit_time = spectatee.hit_time;
-       self.strength_finished = spectatee.strength_finished;
-       self.invincible_finished = spectatee.invincible_finished;
-       self.pressedkeys = spectatee.pressedkeys;
-       self.weapons = spectatee.weapons;
-       PS(self).m_switchweapon = PS(spectatee).m_switchweapon;
-       PS(self).m_switchingweapon = PS(spectatee).m_switchingweapon;
-       PS(self).m_weapon = PS(spectatee).m_weapon;
-       self.vortex_charge = spectatee.vortex_charge;
-       self.vortex_chargepool_ammo = spectatee.vortex_chargepool_ammo;
-       self.hagar_load = spectatee.hagar_load;
-       self.arc_heat_percent = spectatee.arc_heat_percent;
-       self.minelayer_mines = spectatee.minelayer_mines;
-       self.punchangle = spectatee.punchangle;
-       self.view_ofs = spectatee.view_ofs;
-       self.velocity = spectatee.velocity;
-       self.dmg_take = spectatee.dmg_take;
-       self.dmg_save = spectatee.dmg_save;
-       self.dmg_inflictor = spectatee.dmg_inflictor;
-       self.v_angle = spectatee.v_angle;
-       self.angles = spectatee.v_angle;
-       STAT(FROZEN, self) = STAT(FROZEN, spectatee);
-       self.revive_progress = spectatee.revive_progress;
-       if(!PHYS_INPUT_BUTTON_USE(self))
-               self.fixangle = true;
-       setorigin(self, spectatee.origin);
-       setsize(self, spectatee.mins, spectatee.maxs);
+    TC(Client, this); TC(Client, spectatee);
+
+       MUTATOR_CALLHOOK(SpectateCopy, spectatee, this);
+       PS(this) = PS(spectatee);
+       this.armortype = spectatee.armortype;
+       this.armorvalue = spectatee.armorvalue;
+       this.ammo_cells = spectatee.ammo_cells;
+       this.ammo_plasma = spectatee.ammo_plasma;
+       this.ammo_shells = spectatee.ammo_shells;
+       this.ammo_nails = spectatee.ammo_nails;
+       this.ammo_rockets = spectatee.ammo_rockets;
+       this.ammo_fuel = spectatee.ammo_fuel;
+       this.clip_load = spectatee.clip_load;
+       this.clip_size = spectatee.clip_size;
+       this.effects = spectatee.effects & EFMASK_CHEAP; // eat performance
+       this.health = spectatee.health;
+       this.impulse = 0;
+       this.items = spectatee.items;
+       this.last_pickup = spectatee.last_pickup;
+       this.hit_time = spectatee.hit_time;
+       this.strength_finished = spectatee.strength_finished;
+       this.invincible_finished = spectatee.invincible_finished;
+       this.pressedkeys = spectatee.pressedkeys;
+       this.weapons = spectatee.weapons;
+       this.vortex_charge = spectatee.vortex_charge;
+       this.vortex_chargepool_ammo = spectatee.vortex_chargepool_ammo;
+       this.hagar_load = spectatee.hagar_load;
+       this.arc_heat_percent = spectatee.arc_heat_percent;
+       this.minelayer_mines = spectatee.minelayer_mines;
+       this.punchangle = spectatee.punchangle;
+       this.view_ofs = spectatee.view_ofs;
+       this.velocity = spectatee.velocity;
+       this.dmg_take = spectatee.dmg_take;
+       this.dmg_save = spectatee.dmg_save;
+       this.dmg_inflictor = spectatee.dmg_inflictor;
+       this.v_angle = spectatee.v_angle;
+       this.angles = spectatee.v_angle;
+       STAT(FROZEN, this) = STAT(FROZEN, spectatee);
+       this.revive_progress = spectatee.revive_progress;
+       if(!PHYS_INPUT_BUTTON_USE(this))
+               this.fixangle = true;
+       setorigin(this, spectatee.origin);
+       setsize(this, spectatee.mins, spectatee.maxs);
        SetZoomState(spectatee.zoomstate);
 
-    anticheat_spectatecopy(spectatee);
-       self.hud = spectatee.hud;
+    anticheat_spectatecopy(this, spectatee);
+       this.hud = spectatee.hud;
        if(spectatee.vehicle)
     {
-        self.fixangle = false;
-        //self.velocity = spectatee.vehicle.velocity;
-        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;
+        this.fixangle = false;
+        //this.velocity = spectatee.vehicle.velocity;
+        this.vehicle_health = spectatee.vehicle_health;
+        this.vehicle_shield = spectatee.vehicle_shield;
+        this.vehicle_energy = spectatee.vehicle_energy;
+        this.vehicle_ammo1 = spectatee.vehicle_ammo1;
+        this.vehicle_ammo2 = spectatee.vehicle_ammo2;
+        this.vehicle_reload1 = spectatee.vehicle_reload1;
+        this.vehicle_reload2 = spectatee.vehicle_reload2;
+
+        msg_entity = this;
 
         WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
             WriteAngle(MSG_ONE,  spectatee.v_angle.x);
@@ -1597,9 +1624,9 @@ void SpectateCopy(entity this, entity spectatee)
             WriteAngle(MSG_ONE,  spectatee.v_angle.z);
 
         //WriteByte (MSG_ONE, SVC_SETVIEW);
-        //    WriteEntity(MSG_ONE, self);
+        //    WriteEntity(MSG_ONE, this);
         //makevectors(spectatee.v_angle);
-        //setorigin(self, spectatee.origin - v_forward * 400 + v_up * 300);*/
+        //setorigin(this, spectatee.origin - v_forward * 400 + v_up * 300);*/
     }
 }
 
@@ -1742,13 +1769,13 @@ void LeaveSpectatorMode()
        {
                if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0)
                {
-                       self.classname = STR_PLAYER;
+                       TRANSMUTE(Player, self);
 
                        if(autocvar_g_campaign || autocvar_g_balance_teams)
                                { JoinBestTeam(self, false, true); }
 
                        if(autocvar_g_campaign)
-                               { campaign_bots_may_start = 1; }
+                               { campaign_bots_may_start = true; }
 
                        Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CPID_PREVENT_JOIN);
 
@@ -1886,7 +1913,7 @@ void ObserverThink()
                } else if(PHYS_INPUT_BUTTON_ATCK(self) && !self.version_mismatch) {
                        self.flags &= ~FL_JUMPRELEASED;
                        if(SpectateNext()) {
-                               self.classname = STR_SPECTATOR;
+                               TRANSMUTE(Spectator, self);
                        }
                } else {
                        prefered_movetype = ((!PHYS_INPUT_BUTTON_USE(self) ? self.cvar_cl_clippedspectating : !self.cvar_cl_clippedspectating) ? MOVETYPE_FLY_WORLDONLY : MOVETYPE_NOCLIP);
@@ -1920,24 +1947,24 @@ void SpectatorThink()
                } else if(PHYS_INPUT_BUTTON_ATCK(self) || self.impulse == 10 || self.impulse == 15 || self.impulse == 18 || (self.impulse >= 200 && self.impulse <= 209)) {
                        self.flags &= ~FL_JUMPRELEASED;
                        if(SpectateNext()) {
-                               self.classname = STR_SPECTATOR;
+                               TRANSMUTE(Spectator, self);
                        } else {
-                               self.classname = STR_OBSERVER;
+                               TRANSMUTE(Observer, self);
                                PutClientInServer();
                        }
                        self.impulse = 0;
                } else if(self.impulse == 12 || self.impulse == 16  || self.impulse == 19 || (self.impulse >= 220 && self.impulse <= 229)) {
                        self.flags &= ~FL_JUMPRELEASED;
                        if(SpectatePrev()) {
-                               self.classname = STR_SPECTATOR;
+                               TRANSMUTE(Spectator, self);
                        } else {
-                               self.classname = STR_OBSERVER;
+                               TRANSMUTE(Observer, self);
                                PutClientInServer();
                        }
                        self.impulse = 0;
                } else if (PHYS_INPUT_BUTTON_ATCK2(self)) {
                        self.flags &= ~FL_JUMPRELEASED;
-                       self.classname = STR_OBSERVER;
+                       TRANSMUTE(Observer, self);
                        PutClientInServer();
                } else {
                        if(!SpectateUpdate())
@@ -2023,7 +2050,7 @@ void() nexball_setstatus;
 .int items_added;
 void PlayerPreThink ()
 {SELFPARAM();
-       WarpZone_PlayerPhysics_FixVAngle();
+       WarpZone_PlayerPhysics_FixVAngle(self);
 
        self.stat_game_starttime = game_starttime;
        self.stat_round_starttime = round_starttime;
@@ -2035,7 +2062,7 @@ void PlayerPreThink ()
        if(frametime)
        {
                // physics frames: update anticheat stuff
-               anticheat_prethink();
+               anticheat_prethink(self);
        }
 
        if(blockSpectators && frametime)
@@ -2068,9 +2095,9 @@ void PlayerPreThink ()
                        if(time > self.version_nagtime)
                        {
                                // don't notify git users
-                               if(strstr(self.cvar_g_xonoticversion, "git", 0) < 0 && strstr(self.cvar_g_xonoticversion, "autobuild", 0) < 0)
+                               if(strstrofs(self.cvar_g_xonoticversion, "git", 0) < 0 && strstrofs(self.cvar_g_xonoticversion, "autobuild", 0) < 0)
                                {
-                                       if(strstr(autocvar_g_xonoticversion, "git", 0) >= 0 || strstr(autocvar_g_xonoticversion, "autobuild", 0) >= 0)
+                                       if(strstrofs(autocvar_g_xonoticversion, "git", 0) >= 0 || strstrofs(autocvar_g_xonoticversion, "autobuild", 0) >= 0)
                                        {
                                                // notify release users if connecting to git
                                                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");