]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Weapons: store activeweapon as direct weapon reference
authorTimePath <andrew.hardaker1995@gmail.com>
Sat, 12 Dec 2015 11:03:33 +0000 (22:03 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Sat, 12 Dec 2015 11:03:33 +0000 (22:03 +1100)
24 files changed:
qcsrc/common/gamemodes/gamemode/nexball/nexball.qc
qcsrc/common/mutators/mutator/nix/nix.qc
qcsrc/common/mutators/mutator/overkill/overkill.qc
qcsrc/common/state.qh
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/hlac.qc
qcsrc/common/weapons/weapon/machinegun.qc
qcsrc/common/weapons/weapon/minelayer.qc
qcsrc/common/weapons/weapon/rifle.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/common/weapons/weapon/vortex.qc
qcsrc/server/bot/aim.qc
qcsrc/server/bot/havocbot/havocbot.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_impulse.qc
qcsrc/server/cl_player.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/weapons/selection.qc
qcsrc/server/weapons/throwing.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponsystem.qc

index 0d56d37155b0359113d2e096e83619c6568a722d..97bfe91538f6e2e820f4eb10003e9a771b9054b9 100644 (file)
@@ -180,7 +180,7 @@ void GiveBall(entity plyr, entity ball)
        }
 
        plyr.(weaponentity).weapons = plyr.weapons;
-       plyr.(weaponentity).m_switchweapon = Weapons_from(plyr.weapon);
+       plyr.(weaponentity).m_switchweapon = PS(plyr).m_weapon;
        plyr.weapons = WEPSET(NEXBALL);
        setself(plyr);
        Weapon w = WEP_NEXBALL;
@@ -1021,12 +1021,12 @@ MUTATOR_HOOKFUNCTION(nb, PlayerPhysics)
 
 MUTATOR_HOOKFUNCTION(nb, ForbidThrowCurrentWeapon)
 {SELFPARAM();
-       return self.weapon == WEP_NEXBALL.m_id;
+       return PS(self).m_weapon == WEP_NEXBALL;
 }
 
 MUTATOR_HOOKFUNCTION(nb, ForbidDropCurrentWeapon)
 {SELFPARAM();
-       return self.weapon == WEP_MORTAR.m_id; // TODO: what is this for?
+       return PS(self).m_weapon == WEP_MORTAR; // TODO: what is this for?
 }
 
 MUTATOR_HOOKFUNCTION(nb, FilterItem)
index 5995dcd8b670c8f617c6d226aee72686a145b4e6..a6d42d58e8fc650911d0b80926e515143dfeb5e5 100644 (file)
@@ -68,7 +68,7 @@ REGISTER_MUTATOR(nix, cvar("g_nix") && !cvar("g_instagib") && !cvar("g_overkill"
                        e.ammo_rockets = start_ammo_rockets;
                        e.ammo_fuel = start_ammo_fuel;
                        e.weapons = start_weapons;
-                       if(!client_hasweapon(e, Weapons_from(e.weapon), true, false))
+                       if(!client_hasweapon(e, PS(e).m_weapon, true, false))
                                PS(e).m_switchweapon = w_getbestweapon(self);
                }
        }
index 789b2085d99b4701ec04283fc5a45f2b950ab378..bd1a9efe308496c9a4cecb38b58d6c40b36514c7 100644 (file)
@@ -44,7 +44,7 @@ MUTATOR_HOOKFUNCTION(ok, W_DecreaseAmmo)
        entity actor = MUTATOR_ARGV(0, entity);
        if (actor.ok_use_ammocharge)
        {
-               ok_DecreaseCharge(actor, actor.weapon);
+               ok_DecreaseCharge(actor, PS(actor).m_weapon.m_id);
                return true;
        }
 }
@@ -187,7 +187,7 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink)
                self.ok_lastwep = 0;
        }
 
-       ok_IncreaseCharge(self, self.weapon);
+       ok_IncreaseCharge(self, PS(self).m_weapon.m_id);
 
        if(self.BUTTON_ATCK2)
        if(!forbidWeaponUse(self) || self.weapon_blocked) // allow if weapon is blocked
@@ -196,8 +196,8 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink)
                self.jump_interval = time + WEP_CVAR_PRI(blaster, refire) * W_WeaponRateFactor();
                makevectors(self.v_angle);
 
-               int oldwep = self.weapon;
-               self.weapon = WEP_BLASTER.m_id;
+               Weapon oldwep = PS(self).m_weapon;
+               PS(self).m_weapon = WEP_BLASTER;
                W_Blaster_Attack(
                        self,
                        WEP_BLASTER.m_id | HITTYPE_SECONDARY,
@@ -211,23 +211,23 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink)
                        WEP_CVAR_SEC(vaporizer, delay),
                        WEP_CVAR_SEC(vaporizer, lifetime)
                );
-               self.weapon = oldwep;
+               PS(self).m_weapon = oldwep;
        }
 
        self.weapon_blocked = false;
 
-       self.ok_ammo_charge = self.ammo_charge[self.weapon];
+       self.ok_ammo_charge = self.ammo_charge[PS(self).m_weapon.m_id];
 
        if(self.ok_use_ammocharge)
-       if(!ok_CheckWeaponCharge(self, self.weapon))
+       if(!ok_CheckWeaponCharge(self, PS(self).m_weapon.m_id))
        {
-               if(autocvar_g_overkill_ammo_charge_notice && time > self.ok_notice_time && self.BUTTON_ATCK && IS_REAL_CLIENT(self) && self.weapon == PS(self).m_switchweapon.m_id)
+               if(autocvar_g_overkill_ammo_charge_notice && time > self.ok_notice_time && self.BUTTON_ATCK && IS_REAL_CLIENT(self) && PS(self).m_weapon == PS(self).m_switchweapon)
                {
                        //Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_OVERKILL_CHARGE);
                        self.ok_notice_time = time + 2;
                        play2(self, SND(DRYFIRE));
                }
-               Weapon wpn = Weapons_from(self.weapon);
+               Weapon wpn = PS(self).m_weapon;
                .entity weaponentity = weaponentities[0]; // TODO: unhardcode
                if(self.(weaponentity).state != WS_CLEAR)
                        w_ready(wpn, self, weaponentity, (self.BUTTON_ATCK ? 1 : 0) | (self.BUTTON_ATCK2 ? 2 : 0));
@@ -320,7 +320,7 @@ MUTATOR_HOOKFUNCTION(ok, FilterItem)
 
 MUTATOR_HOOKFUNCTION(ok, SpectateCopy)
 {SELFPARAM();
-       self.ammo_charge[self.weapon] = other.ammo_charge[other.weapon];
+       self.ammo_charge[PS(self).m_weapon.m_id] = other.ammo_charge[PS(other).m_weapon.m_id];
        self.ok_use_ammocharge = other.ok_use_ammocharge;
 
        return false;
index 6c0b327afb843c636d5f99d21d8d93793e16d66e..177935445db8621fd8f573a17a67cd38969654c5 100644 (file)
@@ -1,75 +1,78 @@
 /**
- * Purpose: common client state, usable on client and server
+ * Purpose: common player state, usable on client and server
  * Client: singleton representing the viewed player
- * Server: instance per client
+ * Server: instance per client, clients decoupled from players
  */
-CLASS(ClientState, Object)
-       ATTRIB(ClientState, m_client, entity, NULL)
-       CONSTRUCTOR(ClientState, entity client)
+CLASS(PlayerState, Object)
+       ATTRIB(PlayerState, m_client, entity, NULL)
+       CONSTRUCTOR(PlayerState, entity client)
        {
-               CONSTRUCT(ClientState);
+               CONSTRUCT(PlayerState);
                this.m_client = client;
        }
-ENDCLASS(ClientState)
-
-.ClientState _cs;
+       ATTRIB(PlayerState, m_switchingweapon, Weapon, Weapons_from(-1))
+       ATTRIB(PlayerState, m_switchweapon, Weapon, Weapons_from(-1))
+       ATTRIB(PlayerState, m_weapon, Weapon, Weapons_from(-1))
+       METHOD(PlayerState, ps_push, void(PlayerState this, entity cl))
+       {
+               STAT(ACTIVEWEAPON, cl) = this.m_weapon.m_id;
+               STAT(SWITCHINGWEAPON, cl) = this.m_switchingweapon.m_id;
+               STAT(SWITCHWEAPON, cl) = this.m_switchweapon.m_id;
+       }
+ENDCLASS(PlayerState)
 
+.PlayerState _ps;
 #if NDEBUG
-#define CS(this) (this._cs)
+       #define PS(this) (this._ps)
 #else
-ClientState CS(entity this) { assert(IS_CLIENT(this)); assert(this._cs); return this._cs; }
+       PlayerState PS(entity this) { assert(IS_CLIENT(this)); return this._ps; }
 #endif
 
-void ClientState_attach(entity this)
+void PlayerState_attach(entity this)
 {
-       this._cs = NEW(ClientState, this);
+       // TODO: dynamic
+       // this._ps = NEW(PlayerState, this);
 }
 
-void ClientState_detach(entity this)
+void PlayerState_detach(entity this)
 {
-       remove(CS(this));
-       this._cs = NULL;
+       // TODO: dynamic
+       // if (!PS(this)) return;  // initial connect
+       // remove(PS(this));
+       // this._ps = NULL;
 }
 
-
-
 /**
- * Purpose: common player state, usable on client and server
+ * Purpose: common client state, usable on client and server
  * Client: singleton representing the viewed player
- * Server: instance per client, clients decoupled from players
+ * Server: instance per client
  */
-CLASS(PlayerState, Object)
-       ATTRIB(PlayerState, m_client, entity, NULL)
-       CONSTRUCTOR(PlayerState, entity client)
+CLASS(ClientState, Object)
+       ATTRIB(ClientState, m_client, entity, NULL)
+       CONSTRUCTOR(ClientState, entity client)
        {
-               CONSTRUCT(PlayerState);
+               CONSTRUCT(ClientState);
                this.m_client = client;
        }
-       ATTRIB(PlayerState, m_switchingweapon, Weapon, Weapons_from(-1))
-       ATTRIB(PlayerState, m_switchweapon, Weapon, Weapons_from(-1))
-       ATTRIB(PlayerState, m_weapon, Weapon, Weapons_from(-1))
-       METHOD(PlayerState, ps_push, void(PlayerState this))
-       {
-               STAT(SWITCHINGWEAPON, this.m_client) = this.m_switchingweapon.m_id;
-               STAT(SWITCHWEAPON, this.m_client) = this.m_switchweapon.m_id;
-       }
-ENDCLASS(PlayerState)
+ENDCLASS(ClientState)
+
+.ClientState _cs;
 
-.PlayerState _ps;
 #if NDEBUG
-#define PS(this) (this._ps)
+       #define CS(this) (this._cs)
 #else
-PlayerState PS(entity this) { assert(IS_CLIENT(this)); return this._ps; }
+       ClientState CS(entity this) { assert(IS_CLIENT(this)); assert(this._cs); return this._cs; }
 #endif
 
-void PlayerState_attach(entity this)
+void ClientState_attach(entity this)
 {
-       this._ps = NEW(PlayerState, this);
+       this._cs = NEW(ClientState, this);
+       this._ps = NEW(PlayerState, this);  // TODO: dynamic
 }
 
-void PlayerState_detach(entity this)
+void ClientState_detach(entity this)
 {
-       if (!PS(this)) return;  // initial connect
-       remove(PS(this));
-       this._ps = NULL;
+       remove(CS(this));
+       this._cs = NULL;
+       this._ps = NULL;  // TODO: dynamic
 }
index a26d91c0c17d8dd915c53cbb1d51280bd977b49b..6aff9a2f3ea0842cd8d1229dd83afa5cb2273054 100644 (file)
@@ -109,7 +109,7 @@ void W_Devastator_Explode()
        );
 
        Weapon thiswep = WEP_DEVASTATOR;
-       if(self.realowner.weapon == thiswep.m_id)
+       if(PS(self.realowner).m_weapon == thiswep)
        {
                if(self.realowner.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo))
                if(!(self.realowner.items & IT_UNLIMITED_WEAPON_AMMO))
@@ -190,7 +190,7 @@ void W_Devastator_DoRemoteExplode(.entity weaponentity)
        );
 
        Weapon thiswep = WEP_DEVASTATOR;
-       if(self.realowner.weapon == thiswep.m_id)
+       if(PS(self.realowner).m_weapon == thiswep)
        {
                if(self.realowner.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo))
                if(!(self.realowner.items & IT_UNLIMITED_WEAPON_AMMO))
@@ -272,7 +272,7 @@ void W_Devastator_Think()
                self.velocity = self.velocity + v_forward * min(WEP_CVAR(devastator, speedaccel) * W_WeaponSpeedFactor() * frametime, velspeed);
 
        // laser guided, or remote detonation
-       if(self.realowner.weapon == WEP_DEVASTATOR.m_id)
+       if(PS(self.realowner).m_weapon == WEP_DEVASTATOR)
        {
                if(self == self.realowner.lastrocket)
                if(!self.realowner.rl_release)
@@ -572,7 +572,7 @@ void W_Devastator_Attack(Weapon thiswep)
                {
                        #if 0
                        // don't switch while guiding a missile
-                       if(ATTACK_FINISHED(self, slot) <= time || self.weapon != WEP_DEVASTATOR.m_id)
+                       if(ATTACK_FINISHED(self, slot) <= time || PS(self).m_weapon != WEP_DEVASTATOR)
                        {
                                ammo_amount = false;
                                if(WEP_CVAR(devastator, reload_ammo))
index 94c5d3e5ddedc059217947e1c48f6e92c88297e0..4398386704a0675002482479b9b08ae3bef888e5 100644 (file)
@@ -163,7 +163,7 @@ void W_HLAC_Attack2()
 // weapon frames
 void W_HLAC_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentity, int fire)
 {
-       if(actor.weapon != PS(actor).m_switchweapon.m_id) // abort immediately if switching
+       if(PS(actor).m_weapon != PS(actor).m_switchweapon) // abort immediately if switching
        {
                w_ready(thiswep, actor, weaponentity, fire);
                return;
index 83c943fc0969245e93fbbc14e22a4fd29fc33a21..beebed977beb03df83bf8934850f2a4b3df3a7e1 100644 (file)
@@ -141,7 +141,7 @@ void W_MachineGun_Attack(Weapon thiswep, int deathtype, .entity weaponentity)
 // weapon frames
 void W_MachineGun_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentity, int fire)
 {
-       if(actor.weapon != PS(actor).m_switchweapon.m_id) // abort immediately if switching
+       if(PS(actor).m_weapon != PS(actor).m_switchweapon) // abort immediately if switching
        {
                w_ready(thiswep, actor, weaponentity, fire);
                return;
index 1205b3d10820747189a4b5cb1601d8371fe817ca..ee5660b326e99d402914a2eb58274fb69311c87f 100644 (file)
@@ -123,7 +123,7 @@ void W_MineLayer_Explode()
 
        RadiusDamage(self, self.realowner, WEP_CVAR(minelayer, damage), WEP_CVAR(minelayer, edgedamage), WEP_CVAR(minelayer, radius), world, world, WEP_CVAR(minelayer, force), self.projectiledeathtype, other);
 
-       if(self.realowner.weapon == WEP_MINE_LAYER.m_id)
+       if(PS(self.realowner).m_weapon == WEP_MINE_LAYER)
        {
                setself(self.realowner);
                Weapon w = WEP_MINE_LAYER;
@@ -150,7 +150,7 @@ void W_MineLayer_DoRemoteExplode()
 
        RadiusDamage(self, self.realowner, WEP_CVAR(minelayer, remote_damage), WEP_CVAR(minelayer, remote_edgedamage), WEP_CVAR(minelayer, remote_radius), world, world, WEP_CVAR(minelayer, remote_force), self.projectiledeathtype | HITTYPE_BOUNCE, world);
 
-       if(self.realowner.weapon == WEP_MINE_LAYER.m_id)
+       if(PS(self.realowner).m_weapon == WEP_MINE_LAYER)
        {
                setself(self.realowner);
                Weapon w = WEP_MINE_LAYER;
@@ -265,7 +265,7 @@ void W_MineLayer_Think()
        }
 
        // remote detonation
-       if(self.realowner.weapon == WEP_MINE_LAYER.m_id)
+       if(PS(self.realowner).m_weapon == WEP_MINE_LAYER)
        if(self.realowner.deadflag == DEAD_NO)
        if(self.minelayer_detonate)
                W_MineLayer_RemoteExplode();
@@ -530,7 +530,7 @@ float W_MineLayer_PlacedMines(float detonate)
                {
                        int slot = 0; // TODO: unhardcode
                        // don't switch while placing a mine
-                       if(ATTACK_FINISHED(self, slot) <= time || self.weapon != WEP_MINE_LAYER.m_id)
+                       if(ATTACK_FINISHED(self, slot) <= time || PS(self).m_weapon != WEP_MINE_LAYER)
                        {
                                float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(minelayer, ammo);
                                ammo_amount += self.(weapon_load[WEP_MINE_LAYER.m_id]) >= WEP_CVAR(minelayer, ammo);
index e0ead086d06ab33aa03549c3b6885e7e205b78d3..97bcac8bb5d7de7833b4ec32409188354bf1cfd9 100644 (file)
@@ -100,10 +100,10 @@ void W_Rifle_BulletHail_Continue(Weapon thiswep, entity actor, .entity weaponent
        Weapon sw = PS(actor).m_switchweapon; // make it not detect weapon changes as reason to abort firing
        int slot = weaponslot(weaponentity);
        af = ATTACK_FINISHED(actor, slot);
-       PS(actor).m_switchweapon = Weapons_from(actor.weapon);
+       PS(actor).m_switchweapon = PS(actor).m_weapon;
        ATTACK_FINISHED(actor, slot) = time;
        r = weapon_prepareattack(thiswep, actor, weaponentity, actor.rifle_bullethail_frame == WFRAME_FIRE2, actor.rifle_bullethail_refire);
-       if(PS(actor).m_switchweapon.m_id == actor.weapon)
+       if(PS(actor).m_switchweapon == PS(actor).m_weapon)
                PS(actor).m_switchweapon = sw;
        if(r)
        {
index eb461380616ced1de1f5d070842977d03d23101c..529435d3562086831bd84746772a3caae59e2c46 100644 (file)
@@ -245,10 +245,10 @@ void W_RocketMinsta_Attack2()
        float spread = autocvar_g_rm_laser_spread;
        float rndspread = autocvar_g_rm_laser_spread_random;
 
-       float w = self.weapon;
-       self.weapon = WEP_ELECTRO.m_id;
+       Weapon w = PS(self).m_weapon;
+       PS(self).m_weapon = WEP_ELECTRO;
        W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', false, 2, SND(CRYLINK_FIRE), CH_WEAPON_A, autocvar_g_rm_laser_damage);
-       self.weapon = w;
+       PS(self).m_weapon = w;
 
        Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
@@ -297,10 +297,10 @@ void W_RocketMinsta_Attack3 ()
        float counter = 0;
        float total = 1;
 
-       int w = self.weapon;
-       self.weapon = WEP_ELECTRO.m_id;
+       Weapon w = PS(self).m_weapon;
+       PS(self).m_weapon = WEP_ELECTRO;
        W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', false, 2, SND(ELECTRO_FIRE2), CH_WEAPON_A, autocvar_g_rm_laser_damage);
-       self.weapon = w;
+       PS(self).m_weapon = w;
 
        Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
@@ -396,8 +396,8 @@ void W_RocketMinsta_Attack3 ()
 
                                        // ugly instagib hack to reuse the fire mode of the laser
                                        makevectors(actor.v_angle);
-                                       int oldwep = actor.weapon; // we can't avoid this hack
-                                       actor.weapon = WEP_BLASTER.m_id;
+                                       Weapon oldwep = PS(actor).m_weapon; // we can't avoid this hack
+                                       PS(actor).m_weapon = WEP_BLASTER;
                                        W_Blaster_Attack(
                                                actor,
                                                WEP_BLASTER.m_id | HITTYPE_SECONDARY,
@@ -411,7 +411,7 @@ void W_RocketMinsta_Attack3 ()
                                                WEP_CVAR_SEC(vaporizer, delay),
                                                WEP_CVAR_SEC(vaporizer, lifetime)
                                        );
-                                       actor.weapon = oldwep;
+                                       PS(actor).m_weapon = oldwep;
 
                                        // now do normal refire
                                        weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(vaporizer, animtime), w_ready);
index d6204219048419ae569438a39f4983bd93eaffa5..21e4dc92e517c572730d3bdc9d622baf51180626 100644 (file)
@@ -145,7 +145,7 @@ MUTATOR_HOOKFUNCTION(vortex_charge, GetPressedKeys)
 {SELFPARAM();
        // WEAPONTODO
        float xyspeed = vlen(vec2(self.velocity));
-       if (self.weapon == WEP_VORTEX.m_id && WEP_CVAR(vortex, charge) && WEP_CVAR(vortex, charge_velocity_rate) && xyspeed > WEP_CVAR(vortex, charge_minspeed))
+       if (PS(self).m_weapon == WEP_VORTEX && WEP_CVAR(vortex, charge) && WEP_CVAR(vortex, charge_velocity_rate) && xyspeed > WEP_CVAR(vortex, charge_minspeed))
        {
                // add a maximum of charge_velocity_rate when going fast (f = 1), gradually increasing from minspeed (f = 0) to maxspeed
                xyspeed = min(xyspeed, WEP_CVAR(vortex, charge_maxspeed));
index d4614b84672902e555b57b9976fd1e07fedddfd8..d8d7d1b92b346f5864f0f43ade890387551dcc25 100644 (file)
@@ -338,12 +338,12 @@ float bot_aim(float shotspeed, float shotspeedupward, float maxshottime, float a
        shotspeedupward *= W_WeaponSpeedFactor();
        if (!shotspeed)
        {
-               LOG_TRACE("bot_aim: WARNING: weapon ", Weapons_from(self.weapon).m_name, " shotspeed is zero!\n");
+               LOG_TRACE("bot_aim: WARNING: weapon ", PS(self).m_weapon.m_name, " shotspeed is zero!\n");
                shotspeed = 1000000;
        }
        if (!maxshottime)
        {
-               LOG_TRACE("bot_aim: WARNING: weapon ", Weapons_from(self.weapon).m_name, " maxshottime is zero!\n");
+               LOG_TRACE("bot_aim: WARNING: weapon ", PS(self).m_weapon.m_name, " maxshottime is zero!\n");
                maxshottime = 1;
        }
        makevectors(self.v_angle);
index a0a1d78ee6fc1d0ea181ebe37fb6fffc580b4757..9f91db1f86329e780d460b65e8802a420e424a97 100644 (file)
@@ -104,7 +104,7 @@ void havocbot_ai()
 
                if(self.weapons)
                {
-                       Weapon w = Weapons_from(self.weapon);
+                       Weapon w = PS(self).m_weapon;
                        w.wr_aim(w);
                        if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self))
                        {
@@ -114,7 +114,7 @@ void havocbot_ai()
                        else
                        {
                                if(self.BUTTON_ATCK||self.BUTTON_ATCK2)
-                                       self.lastfiredweapon = self.weapon;
+                                       self.lastfiredweapon = PS(self).m_weapon.m_id;
                        }
                }
                else
@@ -1022,7 +1022,7 @@ void havocbot_chooseweapon()
        if(self.enemy==world)
        {
                // If no weapon was chosen get the first available weapon
-               if(self.weapon==0)
+               if(PS(self).m_weapon==WEP_Null)
                for(i = WEP_FIRST; i <= WEP_LAST; ++i) if(i != WEP_BLASTER.m_id)
                {
                        if(client_hasweapon(self, Weapons_from(i), true, false))
@@ -1055,7 +1055,7 @@ void havocbot_chooseweapon()
        combo = false;
 
        if(autocvar_bot_ai_weapon_combo)
-       if(self.weapon == self.lastfiredweapon)
+       if(PS(self).m_weapon.m_id == self.lastfiredweapon)
        if(af > combo_time)
        {
                combo = true;
@@ -1073,7 +1073,7 @@ void havocbot_chooseweapon()
                                w = bot_weapons_far[i];
                                if ( client_hasweapon(self, Weapons_from(w), true, false) )
                                {
-                                       if ((self.weapon == w && combo) || havocbot_chooseweapon_checkreload(w))
+                                       if ((PS(self).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(w))
                                                continue;
                                        PS(self).m_switchweapon = Weapons_from(w);
                                        return;
@@ -1087,7 +1087,7 @@ void havocbot_chooseweapon()
                                w = bot_weapons_mid[i];
                                if ( client_hasweapon(self, Weapons_from(w), true, false) )
                                {
-                                       if ((self.weapon == w && combo) || havocbot_chooseweapon_checkreload(w))
+                                       if ((PS(self).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(w))
                                                continue;
                                        PS(self).m_switchweapon = Weapons_from(w);
                                        return;
@@ -1100,7 +1100,7 @@ void havocbot_chooseweapon()
                        w = bot_weapons_close[i];
                        if ( client_hasweapon(self, Weapons_from(w), true, false) )
                        {
-                               if ((self.weapon == w && combo) || havocbot_chooseweapon_checkreload(w))
+                               if ((PS(self).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(w))
                                        continue;
                                PS(self).m_switchweapon = Weapons_from(w);
                                return;
index 6fc79fef2e0fc1c27eee554bf9c35221922a4f01..7a113d24a7c6b2badd55c742e677d6a5c94305d5 100644 (file)
@@ -304,7 +304,7 @@ void PutObserverInServer()
        setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX); // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY
        self.view_ofs = '0 0 0'; // so that your view doesn't go into the ceiling with MOVETYPE_FLY_WORLDONLY, previously "PL_VIEW_OFS"
 
-       self.weapon = 0;
+       PS(self).m_weapon = WEP_Null;
        self.weaponname = "";
        PS(self).m_switchingweapon = WEP_Null;
        self.weaponmodel = "";
@@ -625,7 +625,7 @@ void PutClientInServer()
 
                PS(this).m_switchweapon = w_getbestweapon(this);
                this.cnt = -1; // W_LastWeapon will not complain
-               this.weapon = 0;
+               PS(this).m_weapon = WEP_Null;
                this.weaponname = "";
                PS(this).m_switchingweapon = WEP_Null;
 
@@ -1682,7 +1682,7 @@ void SpectateCopy(entity this, entity spectatee)
        self.weapons = spectatee.weapons;
        PS(self).m_switchweapon = PS(spectatee).m_switchweapon;
        PS(self).m_switchingweapon = PS(spectatee).m_switchingweapon;
-       self.weapon = spectatee.weapon;
+       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;
@@ -2396,7 +2396,7 @@ void PlayerPreThink ()
                // WEAPONTODO: THIS SHIT NEEDS TO GO EVENTUALLY
                // It cannot be predicted by the engine!
                .entity weaponentity = weaponentities[0]; // TODO: unhardcode
-               if((self.weapon == WEP_SHOCKWAVE.m_id || self.weapon == WEP_SHOTGUN.m_id) && self.(weaponentity).wframe == WFRAME_FIRE2 && time < self.(weaponentity).weapon_nextthink)
+               if((PS(self).m_weapon == WEP_SHOCKWAVE || PS(self).m_weapon == WEP_SHOTGUN) && self.(weaponentity).wframe == WFRAME_FIRE2 && time < self.(weaponentity).weapon_nextthink)
                        do_crouch = 0;
 
                if (do_crouch)
@@ -2471,7 +2471,12 @@ void PlayerPreThink ()
 
        // WEAPONTODO: Add weapon request for this
        if(!zoomstate_set)
-               SetZoomState(self.BUTTON_ZOOM || self.BUTTON_ZOOMSCRIPT || (self.BUTTON_ATCK2 && self.weapon == WEP_VORTEX.m_id) || (self.BUTTON_ATCK2 && self.weapon == WEP_RIFLE.m_id && WEP_CVAR(rifle, secondary) == 0)); // WEAPONTODO
+               SetZoomState(
+                       self.BUTTON_ZOOM
+                       || self.BUTTON_ZOOMSCRIPT
+                       || (self.BUTTON_ATCK2 && PS(self).m_weapon == WEP_VORTEX)
+                       || (self.BUTTON_ATCK2 && PS(self).m_weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0)
+               ); // WEAPONTODO
 
        float oldspectatee_status;
        oldspectatee_status = self.spectatee_status;
@@ -2511,7 +2516,7 @@ void PlayerPreThink ()
 
        // WEAPONTODO: Move into weaponsystem somehow
        // if a player goes unarmed after holding a loaded weapon, empty his clip size and remove the crosshair ammo ring
-       if(!self.weapon)
+       if (PS(self).m_weapon == WEP_Null)
                self.clip_load = self.clip_size = 0;
 }
 
index 1787d540fa1c10612d7de96b8665319ddccd8a54..59fc183aa495b492e48f3ccbcb4e0f6a47bc0ae4 100644 (file)
@@ -217,7 +217,7 @@ IMPULSE(weapon_reload)
        if (this.vehicle) return;
        if (this.deadflag != DEAD_NO) return;
        if (forbidWeaponUse(this)) return;
-       Weapon w = Weapons_from(this.weapon);
+       Weapon w = PS(this).m_weapon;
        w.wr_reload(w);
 }
 
index f496cf5be8fbec37399dcc9382ec79f51c330032..cbe38ac5a5cb16dd232eb2eea27d5757f10fe462 100644 (file)
@@ -482,7 +482,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp
        if(DIFF_TEAM(self, attacker))
        {
                if(DEATH_ISSPECIAL(deathtype))
-                       awep = Weapons_from(attacker.weapon);
+                       awep = PS(attacker).m_weapon;
                else
                        awep = DEATH_WEAPONOF(deathtype);
                valid_damage_for_weaponstats = 1;
@@ -492,7 +492,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp
        {
                dh = dh - max(self.health, 0);
                da = da - max(self.armorvalue, 0);
-               WeaponStats_LogDamage(awep.m_id, abot, self.weapon, vbot, dh + da);
+               WeaponStats_LogDamage(awep.m_id, abot, PS(self).m_weapon.m_id, vbot, dh + da);
                MUTATOR_CALLHOOK(PlayerDamaged, attacker, self, dh, da, hitloc, deathtype);
        }
 
@@ -508,7 +508,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp
                }
 
                if(valid_damage_for_weaponstats)
-                       WeaponStats_LogKill(awep.m_id, abot, self.weapon, vbot);
+                       WeaponStats_LogKill(awep.m_id, abot, PS(self).m_weapon.m_id, vbot);
 
                if(autocvar_sv_gentle < 1) // TODO make a "gentle" version?
                if(sound_allowed(MSG_BROADCAST, attacker))
@@ -548,7 +548,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp
                MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, self, deathtype);
                excess = frag_damage;
 
-               Weapon wep = Weapons_from(self.weapon);
+               Weapon wep = PS(self).m_weapon;
                wep.wr_playerdeath(wep);
 
                RemoveGrapplingHook(self);
index 4bebdbfc14b5989ff92c96b41e247edd2da033d9..1aa3059c8ad6a3a1e34043860c00ec30aa3166d9 100644 (file)
@@ -242,7 +242,7 @@ float bot_waypoints_for_items;
 #else
 #define ATTACK_FINISHED_FOR(ent, w, slot) ((ent).attack_finished_single[slot])
 #endif
-#define ATTACK_FINISHED(ent, slot) ATTACK_FINISHED_FOR(ent, (ent).weapon, slot)
+#define ATTACK_FINISHED(ent, slot) ATTACK_FINISHED_FOR(ent, PS(ent).m_weapon.m_id, slot)
 
 // assault game mode: Which team is attacking in this round?
 float assault_attacker_team;
index dfabd9d3dc9758b24fbbe9b0a843c581685bfe4c..e5ee28cc856e266d6670573ac1f7af7e622c60cf 100644 (file)
@@ -61,8 +61,8 @@ void GiveFrags (entity attacker, entity targ, float f, int deathtype)
        {
                // after a frag, exchange the current weapon (or the culprit, if detectable) by a new random weapon
                Weapon culprit = DEATH_WEAPONOF(deathtype);
-               if(!culprit) culprit = Weapons_from(attacker.weapon);
-               else if(!(attacker.weapons & (culprit.m_wepset))) culprit = Weapons_from(attacker.weapon);
+               if(!culprit) culprit = PS(attacker).m_weapon;
+               else if(!(attacker.weapons & (culprit.m_wepset))) culprit = PS(attacker).m_weapon;
 
                if(g_weaponarena_random_with_blaster && culprit == WEP_BLASTER) // WEAPONTODO: Shouldn't this be in a mutator?
                {
@@ -95,7 +95,7 @@ void GiveFrags (entity attacker, entity targ, float f, int deathtype)
                }
 
                // after a frag, choose another random weapon set
-               if (!(attacker.weapons & WepSet_FromWeapon(Weapons_from(attacker.weapon))))
+               if (!(attacker.weapons & WepSet_FromWeapon(PS(attacker).m_weapon)))
                        W_SwitchWeapon_Force(attacker, w_getbestweapon(attacker));
        }
 
@@ -113,8 +113,7 @@ void GiveFrags (entity attacker, entity targ, float f, int deathtype)
 
 string AppendItemcodes(string s, entity player)
 {
-       float w;
-       w = player.weapon;
+       int w = PS(player).m_weapon.m_id;
        //if(w == 0)
        //      w = player.switchweapon;
        if(w == 0)
index b2570784b5a2cc6b96e3f361dfd2cd8628c7697d..0fa0462d87eb4d3e7b93ecd4ea2d0102fe96bfca 100644 (file)
@@ -1992,7 +1992,10 @@ void EndFrame()
                setself(e_);
                antilag_record(e_, altime);
        }
-       FOREACH_CLIENT(PS(it), PS(it).ps_push(PS(it)));
+       FOREACH_CLIENT(PS(it), {
+               PlayerState s = PS(it);
+               s.ps_push(s, it);
+       });
 }
 
 
index 012ac3997ac5eacf596a8d3ae1deb5bedda154e4..d5e41b9477edd9a15888aac9faad631c8c527667 100644 (file)
@@ -262,7 +262,7 @@ string formatmessage(string msg)
                        case "l": replacement = NearestLocation(self.origin); break;
                        case "y": replacement = NearestLocation(cursor); break;
                        case "d": replacement = NearestLocation(self.death_origin); break;
-                       case "w": replacement = ((!self.weapon) ? ((PS(self).m_switchweapon == WEP_Null) ? Weapons_from(self.cnt) : PS(self).m_switchweapon) : Weapons_from(self.weapon)).m_name; break;
+                       case "w": replacement = ((PS(self).m_weapon == WEP_Null) ? ((PS(self).m_switchweapon == WEP_Null) ? Weapons_from(self.cnt) : PS(self).m_switchweapon) : PS(self).m_weapon).m_name; break;
                        case "W": replacement = ammoitems; break;
                        case "x": replacement = ((cursor_ent.netname == "" || !cursor_ent) ? "nothing" : cursor_ent.netname); break;
                        case "s": replacement = ftos(vlen(self.velocity - self.velocity_z * '0 0 1')); break;
index b54cdf4b76a5c33c33d8e4dd610522a16d8b4ffd..1c286829f6d506c7fd007b56fcf982a931361c87 100644 (file)
@@ -233,7 +233,7 @@ void W_SwitchToOtherWeapon(entity pl)
 {
        // hack to ensure it switches to an OTHER weapon (in case the other fire mode still has ammo, we want that anyway)
        Weapon ww;
-       WepSet set = WepSet_FromWeapon(Weapons_from(pl.weapon));
+       WepSet set = WepSet_FromWeapon(PS(pl).m_weapon);
        if(pl.weapons & set)
        {
                pl.weapons &= ~set;
index 652ec92005aba884ea26c3955b42644fb33a6726..1bd88e16f66417ab4dbe7c83ef178b9e9da30b70 100644 (file)
@@ -97,10 +97,11 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto
                if(doreduce && g_weapon_stay == 2)
                {
                        // if our weapon is loaded, give its load back to the player
-                       if(self.(weapon_load[self.weapon]) > 0)
+                       int i = PS(self).m_weapon.m_id;
+                       if(self.(weapon_load[i]) > 0)
                        {
-                               own.(ammotype) += self.(weapon_load[self.weapon]);
-                               self.(weapon_load[self.weapon]) = -1; // schedule the weapon for reloading
+                               own.(ammotype) += self.(weapon_load[i]);
+                               self.(weapon_load[i]) = -1; // schedule the weapon for reloading
                        }
 
                        wep.(ammotype) = 0;
@@ -108,10 +109,11 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto
                else if(doreduce)
                {
                        // if our weapon is loaded, give its load back to the player
-                       if(self.(weapon_load[self.weapon]) > 0)
+                       int i = PS(self).m_weapon.m_id;
+                       if(self.(weapon_load[i]) > 0)
                        {
-                               own.(ammotype) += self.(weapon_load[self.weapon]);
-                               self.(weapon_load[self.weapon]) = -1; // schedule the weapon for reloading
+                               own.(ammotype) += self.(weapon_load[i]);
+                               self.(weapon_load[i]) = -1; // schedule the weapon for reloading
                        }
 
                        thisammo = min(own.(ammotype), wep.(ammotype));
@@ -165,8 +167,8 @@ bool W_IsWeaponThrowable(bool w)
 // toss current weapon
 void W_ThrowWeapon(vector velo, vector delta, float doreduce)
 {SELFPARAM();
-       int w = self.weapon;
-       if (w == WEP_Null.m_id)
+       Weapon w = PS(self).m_weapon;
+       if (w == WEP_Null)
                return; // just in case
        if(MUTATOR_CALLHOOK(ForbidThrowCurrentWeapon))
                return;
@@ -175,23 +177,23 @@ void W_ThrowWeapon(vector velo, vector delta, float doreduce)
        .entity weaponentity = weaponentities[0]; // TODO: unhardcode
        if(self.(weaponentity).state != WS_READY)
                return;
-       if(!W_IsWeaponThrowable(w))
+       if(!W_IsWeaponThrowable(w.m_id))
                return;
 
-       WepSet set = WepSet_FromWeapon(Weapons_from(w));
+       WepSet set = WepSet_FromWeapon(w);
        if(!(self.weapons & set)) return;
        self.weapons &= ~set;
 
        W_SwitchWeapon_Force(self, w_getbestweapon(self));
-       string a = W_ThrowNewWeapon(self, w, doreduce, self.origin + delta, velo);
+       string a = W_ThrowNewWeapon(self, w.m_id, doreduce, self.origin + delta, velo);
 
        if(!a) return;
-       Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_WEAPON_DROP, a, w);
+       Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_WEAPON_DROP, a, w.m_id);
 }
 
 void SpawnThrownWeapon(vector org, float w)
 {SELFPARAM();
-       if(self.weapons & WepSet_FromWeapon(Weapons_from(self.weapon)))
-               if(W_IsWeaponThrowable(self.weapon))
-                       W_ThrowNewWeapon(self, self.weapon, false, org, randomvec() * 125 + '0 0 200');
+       if(self.weapons & WepSet_FromWeapon(PS(self).m_weapon))
+               if(W_IsWeaponThrowable(PS(self).m_weapon.m_id))
+                       W_ThrowNewWeapon(self, PS(self).m_weapon.m_id, false, org, randomvec() * 125 + '0 0 200');
 }
index ea0faa845b3ad6974ae040e656286ec3a12a004f..2d9dd23886b99e8f472fb46509252b29d54bf7e6 100644 (file)
@@ -25,7 +25,7 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector m
        float oldsolid;
        vector vecs, dv;
        oldsolid = ent.dphitcontentsmask;
-       if(ent.weapon == WEP_RIFLE.m_id)
+       if(PS(ent).m_weapon == WEP_RIFLE)
                ent.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE;
        else
                ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
@@ -51,7 +51,7 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector m
 
        // track max damage
        if(accuracy_canbegooddamage(ent))
-               accuracy_add(ent, ent.weapon, maxdamage, 0);
+               accuracy_add(ent, PS(ent).m_weapon.m_id, maxdamage, 0);
 
        W_HitPlotAnalysis(ent, v_forward, v_right, v_up);
 
@@ -331,7 +331,7 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
        }
 
        // calculate hits and fired shots for hitscan
-       accuracy_add(self, self.weapon, 0, min(bdamage, totaldmg));
+       accuracy_add(self, PS(self).m_weapon.m_id, 0, min(bdamage, totaldmg));
 
        trace_endpos = endpoint;
        trace_ent = endent;
@@ -434,7 +434,7 @@ void fireBullet(vector start, vector dir, float spread, float max_solid_penetrat
                                // do not exceed 100%
                                float added_damage = min(damage - total_damage, damage * solid_penetration_left);
                                total_damage += damage * solid_penetration_left;
-                               accuracy_add(self, self.weapon, 0, added_damage);
+                               accuracy_add(self, PS(self).m_weapon.m_id, 0, added_damage);
                        }
                }
 
index 3b0aed87b3627ca289d4b213c7fb776202845d6c..919c88809c3dd80709f5d7abffde4a4d566190a4 100644 (file)
@@ -185,11 +185,8 @@ void CL_SpawnWeaponentity(entity actor, .entity weaponentity)
 // Weapon subs
 void w_clear(Weapon thiswep, entity actor, .entity weaponentity, int fire)
 {
-       if (actor.weapon != -1)
-       {
-               actor.weapon = 0;
-               PS(actor).m_switchingweapon = WEP_Null;
-       }
+       PS(actor).m_weapon = WEP_Null;
+       PS(actor).m_switchingweapon = WEP_Null;
        entity this = actor.(weaponentity);
        if (this)
        {
@@ -269,7 +266,7 @@ bool weapon_prepareattack_check(Weapon thiswep, entity actor, .entity weaponenti
                return false;
 
        // do not even think about shooting if switching
-       if (PS(actor).m_switchweapon.m_id != actor.weapon) return false;
+       if (PS(actor).m_switchweapon != PS(actor).m_weapon) return false;
 
        if (attacktime >= 0)
        {
@@ -386,7 +383,7 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void(
 
        if ((fr == WFRAME_FIRE1 || fr == WFRAME_FIRE2) && t)
        {
-               int act = (fr == WFRAME_FIRE2 && (actor.weapon == WEP_SHOCKWAVE.m_id || actor.weapon == WEP_SHOTGUN.m_id))
+               int act = (fr == WFRAME_FIRE2 && (PS(actor).m_weapon == WEP_SHOCKWAVE || PS(actor).m_weapon == WEP_SHOTGUN))
                        ? ANIMACTION_MELEE
                        : ANIMACTION_SHOOT
                        ;
@@ -423,15 +420,15 @@ void W_WeaponFrame(entity actor)
        {
                if (actor.(weaponentity).state != WS_CLEAR)
                {
-                       Weapon wpn = Weapons_from(actor.weapon);
+                       Weapon wpn = PS(actor).m_weapon;
                        w_ready(wpn, actor, weaponentity, (actor.BUTTON_ATCK ? 1 : 0) | (actor.BUTTON_ATCK2 ? 2 : 0));
                        return;
                }
        }
 
-       if (PS(actor).m_switchweapon.m_id == 0)
+       if (PS(actor).m_switchweapon == WEP_Null)
        {
-               actor.weapon = 0;
+               PS(actor).m_weapon = WEP_Null;
                PS(actor).m_switchingweapon = WEP_Null;
                this.state = WS_CLEAR;
                actor.weaponname = "";
@@ -445,7 +442,7 @@ void W_WeaponFrame(entity actor)
        vector up = v_up;
 
        // Change weapon
-       if (actor.weapon != PS(actor).m_switchweapon.m_id)
+       if (PS(actor).m_weapon != PS(actor).m_switchweapon)
        {
                switch (this.state)
                {
@@ -462,7 +459,7 @@ void W_WeaponFrame(entity actor)
                                PS(actor).m_switchingweapon = newwep;
 
                                // the two weapon entities will notice this has changed and update their models
-                               actor.weapon = newwep.m_id;
+                               PS(actor).m_weapon = newwep;
                                actor.weaponname = newwep.mdl;
                                actor.bulletcounter = 0;
                                actor.ammo_field = newwep.ammo_field;
@@ -493,7 +490,7 @@ void W_WeaponFrame(entity actor)
                        {
                                // start switching!
                                PS(actor).m_switchingweapon = PS(actor).m_switchweapon;
-                               entity oldwep = Weapons_from(actor.weapon);
+                               entity oldwep = PS(actor).m_weapon;
 
                                // set up weapon switch think in the future, and start drop anim
                                if (INDEPENDENT_ATTACK_FINISHED || ATTACK_FINISHED(actor, weaponslot(weaponentity)) <= time + actor.weapon_frametime * 0.5)
@@ -511,7 +508,7 @@ void W_WeaponFrame(entity actor)
        // if (actor.button0)
        //      print(ftos(frametime), " ", ftos(time), " >= ", ftos(ATTACK_FINISHED(actor, slot)), " >= ", ftos(this.weapon_nextthink), "\n");
 
-       int w = actor.weapon;
+       int w = PS(actor).m_weapon.m_id;
 
        // call the think code which may fire the weapon
        // and do so multiple times to resolve framerate dependency issues if the
@@ -520,7 +517,7 @@ void W_WeaponFrame(entity actor)
        {
                if (w && !(actor.weapons & WepSet_FromWeapon(Weapons_from(w))))
                {
-                       if (actor.weapon == PS(actor).m_switchweapon.m_id) W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
+                       if (PS(actor).m_weapon == PS(actor).m_switchweapon) W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
                        w = 0;
                }
 
@@ -542,7 +539,7 @@ void W_WeaponFrame(entity actor)
                                        W_SwitchWeapon(WEP_HOOK);
                                actor.hook_switchweapon = key_pressed;
                                Weapon h = WEP_HOOK;
-                               block_weapon = (actor.weapon == h.m_id && (actor.BUTTON_ATCK || key_pressed));
+                               block_weapon = (PS(actor).m_weapon == h && (actor.BUTTON_ATCK || key_pressed));
                                h.wr_think(h, actor, weaponentity, block_weapon ? 1 : 0);
                        }
                }
@@ -555,12 +552,12 @@ void W_WeaponFrame(entity actor)
                {
                        if (w)
                        {
-                               Weapon e = Weapons_from(actor.weapon);
+                               Weapon e = PS(actor).m_weapon;
                                e.wr_think(e, actor, weaponentity, (actor.BUTTON_ATCK ? 1 : 0) | (actor.BUTTON_ATCK2 ? 2 : 0));
                        }
                        else
                        {
-                               Weapon w = Weapons_from(actor.weapon);
+                               Weapon w = PS(actor).m_weapon;
                                w.wr_gonethink(w);
                        }
                }
@@ -572,7 +569,7 @@ void W_WeaponFrame(entity actor)
                                v_forward = fo;
                                v_right = ri;
                                v_up = up;
-                               Weapon wpn = Weapons_from(actor.weapon);
+                               Weapon wpn = PS(actor).m_weapon;
                                this.weapon_think(wpn, actor, weaponentity,
                                        (actor.BUTTON_ATCK ? 1 : 0) | (actor.BUTTON_ATCK2 ? 2 : 0));
                        }
@@ -625,7 +622,7 @@ void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use)
        if (wep.reloading_ammo)
        {
                actor.clip_load -= ammo_use;
-               actor.(weapon_load[actor.weapon]) = actor.clip_load;
+               actor.(weapon_load[PS(actor).m_weapon.m_id]) = actor.clip_load;
        }
        else if (wep.ammo_field != ammo_none)
        {
@@ -669,7 +666,7 @@ void W_ReloadedAndReady(Weapon thiswep, entity actor, .entity weaponentity, int
                actor.clip_load += load;
                actor.(actor.ammo_field) -= load;
        }
-       actor.(weapon_load[actor.weapon]) = actor.clip_load;
+       actor.(weapon_load[PS(actor).m_weapon.m_id]) = actor.clip_load;
 
        // do not set ATTACK_FINISHED in reload code any more. This causes annoying delays if eg: You start reloading a weapon,
        // then quickly switch to another weapon and back. Reloading is canceled, but the reload delay is still there,
@@ -677,7 +674,7 @@ void W_ReloadedAndReady(Weapon thiswep, entity actor, .entity weaponentity, int
 
        // ATTACK_FINISHED(actor, slot) -= actor.reload_time - 1;
 
-       Weapon wpn = Weapons_from(actor.weapon);
+       Weapon wpn = Weapons_from(PS(actor).m_weapon.m_id);
        w_ready(wpn, actor, weaponentity, (actor.BUTTON_ATCK ? 1 : 0) | (actor.BUTTON_ATCK2 ? 2 : 0));
 }
 
@@ -685,7 +682,7 @@ void W_Reload(entity actor, float sent_ammo_min, string sent_sound)
 {
        .entity weaponentity = weaponentities[0];
        // set global values to work with
-       entity e = Weapons_from(actor.weapon);
+       Weapon e = PS(actor).m_weapon;
 
        if (MUTATOR_CALLHOOK(W_Reload, actor)) return;
 
@@ -718,11 +715,11 @@ void W_Reload(entity actor, float sent_ammo_min, string sent_sound)
                                if (IS_REAL_CLIENT(actor) && actor.reload_complain < time)
                                {
                                        play2(actor, SND(UNAVAILABLE));
-                                       sprint(actor, strcat("You don't have enough ammo to reload the ^2", Weapons_from(actor.weapon).m_name, "\n"));
+                                       sprint(actor, strcat("You don't have enough ammo to reload the ^2", PS(actor).m_weapon.m_name, "\n"));
                                        actor.reload_complain = time + 1;
                                }
                                // switch away if the amount of ammo is not enough to keep using this weapon
-                               Weapon w = Weapons_from(actor.weapon);
+                               Weapon w = PS(actor).m_weapon;
                                if (!(w.wr_checkammo1(w) + w.wr_checkammo2(w)))
                                {
                                        actor.clip_load = -1;  // reload later
@@ -756,7 +753,7 @@ void W_Reload(entity actor, float sent_ammo_min, string sent_sound)
 
        if (actor.clip_load < 0) actor.clip_load = 0;
        actor.old_clip_load = actor.clip_load;
-       actor.clip_load = actor.(weapon_load[actor.weapon]) = -1;
+       actor.clip_load = actor.(weapon_load[PS(actor).m_weapon.m_id]) = -1;
 }
 
 void W_DropEvent(.void(Weapon) event, entity player, float weapon_type, entity weapon_item)