]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/client.qc
Merge branch 'master' into Mario/wepent_experimental
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / client.qc
index a9b9e6e7e265b7480d0432dc0908bcbaebb61659..6ce1cd62f9234f5fcc91aed550c75863215b66b3 100644 (file)
@@ -37,6 +37,7 @@
 #include "weapons/weaponsystem.qh"
 
 #include "../common/net_notice.qh"
+#include "../common/net_linked.qh"
 #include "../common/physics/player.qh"
 
 #include "../common/items/_mod.qh"
@@ -112,7 +113,6 @@ bool ClientData_Send(entity this, entity to, int sf)
        if (e.race_completed)       sf |= 1; // forced scoreboard
        if (to.spectatee_status)    sf |= 2; // spectator ent number follows
        if (e.zoomstate)            sf |= 4; // zoomed
-       if (e.porto_v_angle_held)   sf |= 8; // angles held
        if (autocvar_sv_showspectators) sf |= 16; // show spectators
 
        WriteHeader(MSG_ENTITY, ENT_CLIENT_CLIENTDATA);
@@ -122,11 +122,6 @@ bool ClientData_Send(entity this, entity to, int sf)
        {
                WriteByte(MSG_ENTITY, to.spectatee_status);
        }
-       if (sf & 8)
-       {
-               WriteAngle(MSG_ENTITY, e.v_angle.x);
-               WriteAngle(MSG_ENTITY, e.v_angle.y);
-       }
 
        if(sf & 16)
        {
@@ -304,6 +299,8 @@ void PutObserverInServer(entity this)
        TRANSMUTE(Observer, this);
        this.iscreature = false;
        this.teleportable = TELEPORT_SIMPLE;
+       if(this.damagedbycontents)
+               IL_REMOVE(g_damagedbycontents, this);
        this.damagedbycontents = false;
        this.health = FRAGS_SPECTATOR;
        SetSpectatee_status(this, etof(this));
@@ -345,6 +342,8 @@ void PutObserverInServer(entity this)
        this.weaponmodel = "";
        for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
        {
+               if(!this.weaponentities[slot])
+                       continue; // first load
                this.weaponentities[slot].hook_time = 0;
                this.weaponentities[slot].weaponname = "";
                this.weaponentities[slot] = NULL;
@@ -358,10 +357,6 @@ void PutObserverInServer(entity this)
        this.oldvelocity = this.velocity;
        this.fire_endtime = -1;
        this.event_damage = func_null;
-
-       STAT(ACTIVEWEAPON, this) = WEP_Null.m_id;
-       STAT(SWITCHINGWEAPON, this) = WEP_Null.m_id;
-       STAT(SWITCHWEAPON, this) = WEP_Null.m_id;
 }
 
 int player_getspecies(entity this)
@@ -525,6 +520,8 @@ void PutClientInServer(entity this)
                this.wasplayer = true;
                this.iscreature = true;
                this.teleportable = TELEPORT_NORMAL;
+               if(!this.damagedbycontents)
+                       IL_PUSH(g_damagedbycontents, this);
                this.damagedbycontents = true;
                set_movetype(this, MOVETYPE_WALK);
                this.solid = SOLID_SLIDEBOX;
@@ -626,9 +623,11 @@ void PutClientInServer(entity this)
                FixPlayermodel(this);
                this.drawonlytoclient = NULL;
 
+               this.viewloc = NULL;
+
                this.crouch = false;
-               this.view_ofs = STAT(PL_VIEW_OFS, NULL);
-               setsize(this, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL));
+               this.view_ofs = STAT(PL_VIEW_OFS, this);
+               setsize(this, STAT(PL_MIN, this), STAT(PL_MAX, this));
                this.spawnorigin = spot.origin;
                setorigin(this, spot.origin + '0 0 1' * (1 - this.mins.z - 24));
                // don't reset back to last position, even if new position is stuck in solid
@@ -656,7 +655,8 @@ void PutClientInServer(entity this)
 
                for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
                {
-                       CL_SpawnWeaponentity(this, weaponentities[slot]);
+                       .entity weaponentity = weaponentities[slot];
+                       CL_SpawnWeaponentity(this, weaponentity);
                }
                this.alpha = default_player_alpha;
                this.colormod = '1 1 1' * autocvar_g_player_brightness;
@@ -671,7 +671,11 @@ void PutClientInServer(entity this)
                        it.wr_resetplayer(it, this);
                        // reload all reloadable weapons
                        if (it.spawnflags & WEP_FLAG_RELOADABLE) {
-                               this.weapon_load[it.m_id] = it.reloading_ammo;
+                               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+                               {
+                                       .entity weaponentity = weaponentities[slot];
+                                       this.(weaponentity).weapon_load[it.m_id] = it.reloading_ammo;
+                               }
                        }
                ));
 
@@ -699,6 +703,7 @@ void PutClientInServer(entity this)
                                this.(weaponentity).m_switchweapon = w_getbestweapon(this, weaponentity);
                        else
                                this.(weaponentity).m_switchweapon = WEP_Null;
+                       this.(weaponentity).m_weapon = WEP_Null;
                        this.(weaponentity).weaponname = "";
                        this.(weaponentity).m_switchingweapon = WEP_Null;
                        this.(weaponentity).cnt = -1;
@@ -713,7 +718,6 @@ void PutClientInServer(entity this)
 
 void ClientInit_misc(entity this);
 
-.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?
 bool ClientInit_SendEntity(entity this, entity to, int sf)
@@ -1215,6 +1219,9 @@ void ClientConnect(entity this)
        if (IS_REAL_CLIENT(this))
                sv_notice_join(this);
 
+       // update physics stats (players can spawn before physics runs)
+       Physics_UpdateStats(this, PHYS_HIGHSPEED(this));
+
        IL_EACH(g_initforplayer, it.init_for_player, {
                it.init_for_player(it, this);
        });
@@ -1275,6 +1282,8 @@ void ClientDisconnect(entity this)
        this.playerid = 0;
        ReadyCount();
        if (vote_called && IS_REAL_CLIENT(this)) VoteCount(false);
+
+       ONREMOVE(this);
 }
 
 void ChatBubbleThink(entity this)
@@ -1614,7 +1623,7 @@ void SetZoomState(entity this, float z)
 void GetPressedKeys(entity this)
 {
        MUTATOR_CALLHOOK(GetPressedKeys, this);
-       int keys = this.pressedkeys;
+       int keys = STAT(PRESSED_KEYS, this);
        keys = BITSET(keys, KEY_FORWARD,        this.movement.x > 0);
        keys = BITSET(keys, KEY_BACKWARD,       this.movement.x < 0);
        keys = BITSET(keys, KEY_RIGHT,          this.movement.y > 0);
@@ -1624,7 +1633,9 @@ void GetPressedKeys(entity this)
        keys = BITSET(keys, KEY_CROUCH,         PHYS_INPUT_BUTTON_CROUCH(this));
        keys = BITSET(keys, KEY_ATCK,           PHYS_INPUT_BUTTON_ATCK(this));
        keys = BITSET(keys, KEY_ATCK2,          PHYS_INPUT_BUTTON_ATCK2(this));
-       this.pressedkeys = keys;
+       this.pressedkeys = keys; // store for other users
+
+       STAT(PRESSED_KEYS, this) = keys;
 }
 
 /*
@@ -1657,7 +1668,7 @@ void SpectateCopy(entity this, entity spectatee)
        this.hit_time = spectatee.hit_time;
        this.strength_finished = spectatee.strength_finished;
        this.invincible_finished = spectatee.invincible_finished;
-       this.pressedkeys = spectatee.pressedkeys;
+       STAT(PRESSED_KEYS, this) = STAT(PRESSED_KEYS, spectatee);
        this.weapons = spectatee.weapons;
        this.vortex_charge = spectatee.vortex_charge;
        this.vortex_chargepool_ammo = spectatee.vortex_chargepool_ammo;
@@ -1674,12 +1685,19 @@ void SpectateCopy(entity this, entity spectatee)
        this.angles = spectatee.v_angle;
        STAT(FROZEN, this) = STAT(FROZEN, spectatee);
        this.revive_progress = spectatee.revive_progress;
+       this.viewloc = spectatee.viewloc;
        if(!PHYS_INPUT_BUTTON_USE(this) && STAT(CAMERA_SPECTATOR, this) != 2)
                this.fixangle = true;
        setorigin(this, spectatee.origin);
        setsize(this, spectatee.mins, spectatee.maxs);
        SetZoomState(this, spectatee.zoomstate);
 
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+       {
+               .entity weaponentity = weaponentities[slot];
+               this.(weaponentity) = spectatee.(weaponentity);
+       }
+
     anticheat_spectatecopy(this, spectatee);
        this.hud = spectatee.hud;
        if(spectatee.vehicle)