From: TimePath Date: Sat, 12 Dec 2015 08:04:10 +0000 (+1100) Subject: Weapons: store switchweapon as direct weapon reference X-Git-Tag: xonotic-v0.8.2~1502 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=f3b08f163992b7be4e597cdd2297ed193d96dc1c;p=xonotic%2Fxonotic-data.pk3dir.git Weapons: store switchweapon as direct weapon reference --- diff --git a/qcsrc/Makefile b/qcsrc/Makefile index b49ebbe04..d332a0413 100644 --- a/qcsrc/Makefile +++ b/qcsrc/Makefile @@ -2,6 +2,7 @@ SCM := $(shell if [ -d .svn ]; then echo svn; elif [ -d ../.git ]; then echo git PERL ?= perl QCCFLAGS_WATERMARK ?= -DWATERMARK='"$(shell git describe)"' QCC ?= gmqcc +NDEBUG ?= 1 QCCVERSIONFILE := qccversion.$(shell (cd server && $(QCC) --version) > qccversion.txt && git hash-object qccversion.txt) @@ -22,7 +23,7 @@ QCCFLAGS ?= \ -fftepp -flno -futf8 -fno-bail-on-werror -fftepp-predefs \ -frelaxed-switch -freturn-assignments \ $(QCCFLAGS_WATERMARK) \ - -DNDEBUG=1 \ + -DNDEBUG=$(NDEBUG) \ $(QCCFLAGS_FEATURES) \ $(QCCFLAGS_EXTRA) diff --git a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc index 2206df7c6..0d56d3715 100644 --- a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc +++ b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc @@ -180,12 +180,12 @@ void GiveBall(entity plyr, entity ball) } plyr.(weaponentity).weapons = plyr.weapons; - plyr.(weaponentity).switchweapon = plyr.weapon; + plyr.(weaponentity).m_switchweapon = Weapons_from(plyr.weapon); plyr.weapons = WEPSET(NEXBALL); setself(plyr); Weapon w = WEP_NEXBALL; w.wr_resetplayer(w); - plyr.switchweapon = WEP_NEXBALL.m_id; + PS(plyr).m_switchweapon = WEP_NEXBALL; W_SwitchWeapon(WEP_NEXBALL); setself(this); } @@ -971,8 +971,8 @@ MUTATOR_HOOKFUNCTION(nb, PlayerPreThink) self.weapons = self.(weaponentity).weapons; Weapon w = WEP_NEXBALL; w.wr_resetplayer(w); - self.switchweapon = self.(weaponentity).switchweapon; - W_SwitchWeapon(Weapons_from(self.switchweapon)); + PS(self).m_switchweapon = self.(weaponentity).m_switchweapon; + W_SwitchWeapon(PS(self).m_switchweapon); self.(weaponentity).weapons = '0 0 0'; } diff --git a/qcsrc/common/mutators/mutator/buffs/buffs.qc b/qcsrc/common/mutators/mutator/buffs/buffs.qc index 1c9e3a217..37a0573dc 100644 --- a/qcsrc/common/mutators/mutator/buffs/buffs.qc +++ b/qcsrc/common/mutators/mutator/buffs/buffs.qc @@ -880,7 +880,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) if(self.buffs & BUFF_AMMO.m_itemid) if(self.clip_size) - self.clip_load = self.(weapon_load[self.switchweapon]) = self.clip_size; + self.clip_load = self.(weapon_load[PS(self).m_switchweapon.m_id]) = self.clip_size; if((self.buffs & BUFF_INVISIBLE.m_itemid) && (self.oldbuffs & BUFF_INVISIBLE.m_itemid)) if(self.alpha != autocvar_g_buffs_invisible_alpha) @@ -902,7 +902,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) if(self.clip_load) self.buff_ammo_prev_clipload = self.clip_load; - self.clip_load = self.(weapon_load[self.switchweapon]) = self.clip_size; + self.clip_load = self.(weapon_load[PS(self).m_switchweapon.m_id]) = self.clip_size; } BUFF_ONREM(BUFF_AMMO) diff --git a/qcsrc/common/mutators/mutator/nix/nix.qc b/qcsrc/common/mutators/mutator/nix/nix.qc index 68f4dfaa8..9043a8399 100644 --- a/qcsrc/common/mutators/mutator/nix/nix.qc +++ b/qcsrc/common/mutators/mutator/nix/nix.qc @@ -69,7 +69,7 @@ REGISTER_MUTATOR(nix, cvar("g_nix") && !cvar("g_instagib") && !cvar("g_overkill" e.ammo_fuel = start_ammo_fuel; e.weapons = start_weapons; if(!client_hasweapon(e, Weapons_from(e.weapon), true, false)) - e.switchweapon = w_getbestweapon(self); + PS(e).m_switchweapon = w_getbestweapon(self); } } @@ -210,10 +210,10 @@ void NIX_GiveCurrentWeapon() self.weapons |= WEPSET(BLASTER); self.weapons |= e.m_wepset; - if(self.switchweapon != nix_weapon) - if(!client_hasweapon(self, Weapons_from(self.switchweapon), true, false)) + Weapon w = Weapons_from(nix_weapon); + if(PS(self).m_switchweapon != w) + if(!client_hasweapon(self, PS(self).m_switchweapon, true, false)) { - Weapon w = Weapons_from(nix_weapon); if(client_hasweapon(self, w, true, false)) W_SwitchWeapon(w); } diff --git a/qcsrc/common/mutators/mutator/overkill/hmg.qc b/qcsrc/common/mutators/mutator/overkill/hmg.qc index e78e9110a..28b1715e1 100644 --- a/qcsrc/common/mutators/mutator/overkill/hmg.qc +++ b/qcsrc/common/mutators/mutator/overkill/hmg.qc @@ -65,7 +65,7 @@ void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weapone if(!thiswep.wr_checkammo1(thiswep)) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, Weapons_from(w_getbestweapon(actor))); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); w_ready(thiswep, actor, weaponentity, fire); return; } diff --git a/qcsrc/common/mutators/mutator/overkill/overkill.qc b/qcsrc/common/mutators/mutator/overkill/overkill.qc index 4ad190d25..952537e31 100644 --- a/qcsrc/common/mutators/mutator/overkill/overkill.qc +++ b/qcsrc/common/mutators/mutator/overkill/overkill.qc @@ -146,7 +146,7 @@ MUTATOR_HOOKFUNCTION(ok, PlayerDies) e.velocity = '0 0 200' + normalize(targ.origin - self.origin) * 500; SUB_SetFade(e, time + 5, 1); - this.ok_lastwep = this.switchweapon; + this.ok_lastwep = PS(this).m_switchweapon.m_id; return false; } @@ -186,7 +186,7 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink) if(self.ok_lastwep) { - self.switchweapon = self.ok_lastwep; + PS(self).m_switchweapon = Weapons_from(self.ok_lastwep); self.ok_lastwep = 0; } @@ -224,7 +224,7 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink) if(self.ok_use_ammocharge) if(!ok_CheckWeaponCharge(self, self.weapon)) { - if(autocvar_g_overkill_ammo_charge_notice && time > self.ok_notice_time && self.BUTTON_ATCK && IS_REAL_CLIENT(self) && self.weapon == self.switchweapon) + 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) { //Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_OVERKILL_CHARGE); self.ok_notice_time = time + 2; diff --git a/qcsrc/common/mutators/mutator/pinata/pinata.qc b/qcsrc/common/mutators/mutator/pinata/pinata.qc index 99c1321c1..d5cbb7fda 100644 --- a/qcsrc/common/mutators/mutator/pinata/pinata.qc +++ b/qcsrc/common/mutators/mutator/pinata/pinata.qc @@ -5,7 +5,7 @@ MUTATOR_HOOKFUNCTION(pinata, PlayerDies) {SELFPARAM(); for(int j = WEP_FIRST; j <= WEP_LAST; ++j) if(self.weapons & WepSet_FromWeapon(Weapons_from(j))) - if(self.switchweapon != j) + if(PS(self).m_switchweapon.m_id != j) if(W_IsWeaponThrowable(j)) W_ThrowNewWeapon(self, j, false, self.origin + (self.mins + self.maxs) * 0.5, randomvec() * 175 + '0 0 325'); diff --git a/qcsrc/common/state.qh b/qcsrc/common/state.qh new file mode 100644 index 000000000..84bb94686 --- /dev/null +++ b/qcsrc/common/state.qh @@ -0,0 +1,75 @@ +/** + * Purpose: common client state, usable on client and server + * Client: singleton representing the viewed player + * Server: instance per client + */ +CLASS(ClientState, Object) + ATTRIB(ClientState, m_client, entity, NULL) + CONSTRUCTOR(ClientState, entity client) + { + CONSTRUCT(ClientState); + this.m_client = client; + } +ENDCLASS(ClientState) + +.ClientState _cs; + +#if NDEBUG +#define CS(this) (this._cs) +#else +ClientState CS(entity this) { assert(IS_CLIENT(this)); assert(this._cs); return this._cs; } +#endif + +void ClientState_attach(entity this) +{ + this._cs = NEW(ClientState, this); +} + +void ClientState_detach(entity this) +{ + remove(CS(this)); + this._cs = NULL; +} + + + +/** + * Purpose: common player state, usable on client and server + * Client: singleton representing the viewed player + * Server: instance per client, clients decoupled from players + */ +CLASS(PlayerState, Object) + ATTRIB(PlayerState, m_client, entity, NULL) + CONSTRUCTOR(PlayerState, entity client) + { + CONSTRUCT(PlayerState); + 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(SWITCHWEAPON, this.m_client) = this.m_switchweapon.m_id; + } +ENDCLASS(PlayerState) + +.PlayerState _ps; +#if NDEBUG +#define PS(this) (this._ps) +#else +PlayerState PS(entity this) { assert(IS_CLIENT(this)); return this._ps; } +#endif + +void PlayerState_attach(entity this) +{ + LOG_INFO("Attached\n"); + this._ps = NEW(PlayerState, this); +} + +void PlayerState_detach(entity this) +{ + if (!PS(this)) return; // initial connect + remove(PS(this)); + this._ps = NULL; +} diff --git a/qcsrc/common/vehicles/sv_vehicles.qc b/qcsrc/common/vehicles/sv_vehicles.qc index 2940b9565..97a6b467c 100644 --- a/qcsrc/common/vehicles/sv_vehicles.qc +++ b/qcsrc/common/vehicles/sv_vehicles.qc @@ -877,7 +877,7 @@ void vehicles_exit(bool eject) _player.view_ofs = PL_VIEW_OFS; _player.event_damage = PlayerDamage; _player.hud = HUD_NORMAL; - _player.switchweapon = _vehicle.switchweapon; + PS(_player).m_switchweapon = _vehicle.m_switchweapon; _player.last_vehiclecheck = time + 3; _player.vehicle_enter_delay = time + 2; @@ -1063,7 +1063,7 @@ void vehicles_enter(entity pl, entity veh) veh.colormap = pl.colormap; if(veh.tur_head) veh.tur_head.colormap = pl.colormap; - veh.switchweapon = pl.switchweapon; + veh.m_switchweapon = PS(pl).m_switchweapon; pl.hud = veh.vehicleid; pl.PlayerPhysplug = veh.PlayerPhysplug; diff --git a/qcsrc/common/vehicles/vehicle/bumblebee.qc b/qcsrc/common/vehicles/vehicle/bumblebee.qc index 244b4e2f6..f279e9e2a 100644 --- a/qcsrc/common/vehicles/vehicle/bumblebee.qc +++ b/qcsrc/common/vehicles/vehicle/bumblebee.qc @@ -261,7 +261,7 @@ void bumblebee_gunner_exit(int _exitflag) player.event_damage = PlayerDamage; player.hud = HUD_NORMAL; player.teleportable = TELEPORT_NORMAL; - player.switchweapon = gunner.switchweapon; + PS(player).m_switchweapon = gunner.m_switchweapon; player.vehicle_enter_delay = time + 2; fixedmakevectors(vehic.angles); @@ -330,7 +330,7 @@ bool bumblebee_gunner_enter() RemoveGrapplingHook(player); - gunner.switchweapon = player.switchweapon; + gunner.m_switchweapon = PS(player).m_switchweapon; gunner.vehicle_exit = bumblebee_gunner_exit; gunner.vehicle_hudmodel.viewmodelforclient = player; diff --git a/qcsrc/common/vehicles/vehicle/spiderbot.qc b/qcsrc/common/vehicles/vehicle/spiderbot.qc index 9c2305126..d817c2e1a 100644 --- a/qcsrc/common/vehicles/vehicle/spiderbot.qc +++ b/qcsrc/common/vehicles/vehicle/spiderbot.qc @@ -88,7 +88,7 @@ float spiderbot_frame() player.BUTTON_ZOOM = 0; player.BUTTON_CROUCH = 0; - player.switchweapon = 0; + PS(player).m_switchweapon = WEP_Null; player.vehicle_weapon2mode = spider.vehicle_weapon2mode; diff --git a/qcsrc/common/weapons/all.qh b/qcsrc/common/weapons/all.qh index 9bf60e94a..4c8ede6dc 100644 --- a/qcsrc/common/weapons/all.qh +++ b/qcsrc/common/weapons/all.qh @@ -332,7 +332,6 @@ STATIC_INIT(register_weapons_done) //.int weapon; // current weapon #ifdef SVQC -.int switchweapon = _STAT(SWITCHWEAPON); .int switchingweapon = _STAT(SWITCHINGWEAPON); #endif .string weaponname; // name of .weapon diff --git a/qcsrc/common/weapons/weapon/arc.qc b/qcsrc/common/weapons/weapon/arc.qc index 13037eb7d..11d9115f0 100644 --- a/qcsrc/common/weapons/weapon/arc.qc +++ b/qcsrc/common/weapons/weapon/arc.qc @@ -629,7 +629,7 @@ void Arc_Smoke() } if ( self.arc_smoke_sound && ( self.arc_overheat <= time || - !( self.BUTTON_ATCK || self.BUTTON_ATCK2 ) ) || self.switchweapon != WEP_ARC.m_id ) + !( self.BUTTON_ATCK || self.BUTTON_ATCK2 ) ) || PS(self).m_switchweapon != WEP_ARC ) { self.arc_smoke_sound = 0; sound(self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM); diff --git a/qcsrc/common/weapons/weapon/blaster.qc b/qcsrc/common/weapons/weapon/blaster.qc index 1063a9c66..5ae4dd4b9 100644 --- a/qcsrc/common/weapons/weapon/blaster.qc +++ b/qcsrc/common/weapons/weapon/blaster.qc @@ -191,7 +191,7 @@ void W_Blaster_Attack( { case 0: // switch to last used weapon { - if(actor.switchweapon == WEP_BLASTER.m_id) // don't do this if already switching + if(PS(actor).m_switchweapon == WEP_BLASTER) // don't do this if already switching W_LastWeapon(); break; } diff --git a/qcsrc/common/weapons/weapon/crylink.qc b/qcsrc/common/weapons/weapon/crylink.qc index eb4dbdd87..56f9bba81 100644 --- a/qcsrc/common/weapons/weapon/crylink.qc +++ b/qcsrc/common/weapons/weapon/crylink.qc @@ -626,7 +626,7 @@ void W_Crylink_Attack2(Weapon thiswep) { // ran out of ammo! actor.cnt = WEP_CRYLINK.m_id; - actor.switchweapon = w_getbestweapon(actor); + PS(actor).m_switchweapon = w_getbestweapon(actor); } } } diff --git a/qcsrc/common/weapons/weapon/devastator.qc b/qcsrc/common/weapons/weapon/devastator.qc index 25a823788..31701c319 100644 --- a/qcsrc/common/weapons/weapon/devastator.qc +++ b/qcsrc/common/weapons/weapon/devastator.qc @@ -116,7 +116,7 @@ void W_Devastator_Explode() self.realowner.cnt = WEP_DEVASTATOR.m_id; int slot = 0; // TODO: unhardcode ATTACK_FINISHED(self.realowner, slot) = time; - self.realowner.switchweapon = w_getbestweapon(self.realowner); + PS(self.realowner).m_switchweapon = w_getbestweapon(self.realowner); } } remove(self); @@ -196,7 +196,7 @@ void W_Devastator_DoRemoteExplode(.entity weaponentity) self.realowner.cnt = WEP_DEVASTATOR.m_id; int slot = weaponslot(weaponentity); ATTACK_FINISHED(self.realowner, slot) = time; - self.realowner.switchweapon = w_getbestweapon(self.realowner); + PS(self.realowner).m_switchweapon = w_getbestweapon(self.realowner); } } remove(self); @@ -545,7 +545,7 @@ void W_Devastator_Attack(Weapon thiswep) actor.rl_release = 1; if(fire & 2) - if(actor.switchweapon == WEP_DEVASTATOR.m_id) + if(PS(actor).m_switchweapon == WEP_DEVASTATOR) { entity rock; bool rockfound = false; diff --git a/qcsrc/common/weapons/weapon/hlac.qc b/qcsrc/common/weapons/weapon/hlac.qc index cebe69450..260f4b004 100644 --- a/qcsrc/common/weapons/weapon/hlac.qc +++ b/qcsrc/common/weapons/weapon/hlac.qc @@ -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 != actor.switchweapon) // abort immediately if switching + if(actor.weapon != PS(actor).m_switchweapon.m_id) // abort immediately if switching { w_ready(thiswep, actor, weaponentity, fire); return; @@ -174,7 +174,7 @@ void W_HLAC_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentity, int if(!thiswep.wr_checkammo1(thiswep)) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, Weapons_from(w_getbestweapon(actor))); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); w_ready(thiswep, actor, weaponentity, fire); return; } diff --git a/qcsrc/common/weapons/weapon/hook.qc b/qcsrc/common/weapons/weapon/hook.qc index 1b6fe5e3d..a8a76cfd6 100644 --- a/qcsrc/common/weapons/weapon/hook.qc +++ b/qcsrc/common/weapons/weapon/hook.qc @@ -243,7 +243,7 @@ void W_Hook_Attack2(Weapon thiswep, entity actor) { actor.ammo_fuel = 0; actor.hook_state |= HOOK_REMOVING; - W_SwitchWeapon_Force(actor, Weapons_from(w_getbestweapon(actor))); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); } } } diff --git a/qcsrc/common/weapons/weapon/machinegun.qc b/qcsrc/common/weapons/weapon/machinegun.qc index 7805feda8..8d49f8d7c 100644 --- a/qcsrc/common/weapons/weapon/machinegun.qc +++ b/qcsrc/common/weapons/weapon/machinegun.qc @@ -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 != actor.switchweapon) // abort immediately if switching + if(actor.weapon != PS(actor).m_switchweapon.m_id) // abort immediately if switching { w_ready(thiswep, actor, weaponentity, fire); return; @@ -151,7 +151,7 @@ void W_MachineGun_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentit if(!thiswep.wr_checkammo2(thiswep)) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, Weapons_from(w_getbestweapon(actor))); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); w_ready(thiswep, actor, weaponentity, fire); return; } @@ -177,7 +177,7 @@ void W_MachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity if(!thiswep.wr_checkammo1(thiswep)) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, Weapons_from(w_getbestweapon(actor))); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); w_ready(thiswep, actor, weaponentity, fire); return; } @@ -269,7 +269,7 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, .entity weaponentit if(!thiswep.wr_checkammo2(thiswep)) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, Weapons_from(w_getbestweapon(actor))); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); w_ready(thiswep, actor, weaponentity, fire); return; } diff --git a/qcsrc/common/weapons/weapon/minelayer.qc b/qcsrc/common/weapons/weapon/minelayer.qc index 0b069ca89..a9eee99fa 100644 --- a/qcsrc/common/weapons/weapon/minelayer.qc +++ b/qcsrc/common/weapons/weapon/minelayer.qc @@ -132,7 +132,7 @@ void W_MineLayer_Explode() self.cnt = WEP_MINE_LAYER.m_id; int slot = 0; // TODO: unhardcode ATTACK_FINISHED(self, slot) = time; - self.switchweapon = w_getbestweapon(self); + PS(self).m_switchweapon = w_getbestweapon(self); } setself(this); } @@ -159,7 +159,7 @@ void W_MineLayer_DoRemoteExplode() self.cnt = WEP_MINE_LAYER.m_id; int slot = 0; // TODO: unhardcode ATTACK_FINISHED(self, slot) = time; - self.switchweapon = w_getbestweapon(self); + PS(self).m_switchweapon = w_getbestweapon(self); } setself(this); } diff --git a/qcsrc/common/weapons/weapon/rifle.qc b/qcsrc/common/weapons/weapon/rifle.qc index 59e254990..77f8cb5f2 100644 --- a/qcsrc/common/weapons/weapon/rifle.qc +++ b/qcsrc/common/weapons/weapon/rifle.qc @@ -95,16 +95,16 @@ void W_Rifle_Attack2() .float rifle_bullethail_refire; void W_Rifle_BulletHail_Continue(Weapon thiswep, entity actor, .entity weaponentity, int fire) { - float r, sw, af; + float r, af; - sw = actor.switchweapon; // make it not detect weapon changes as reason to abort firing + 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); - actor.switchweapon = actor.weapon; + PS(actor).m_switchweapon = Weapons_from(actor.weapon); ATTACK_FINISHED(actor, slot) = time; r = weapon_prepareattack(thiswep, actor, weaponentity, actor.rifle_bullethail_frame == WFRAME_FIRE2, actor.rifle_bullethail_refire); - if(actor.switchweapon == actor.weapon) - actor.switchweapon = sw; + if(PS(actor).m_switchweapon.m_id == actor.weapon) + PS(actor).m_switchweapon = sw; if(r) { actor.rifle_bullethail_attackfunc(); diff --git a/qcsrc/common/weapons/weapon/seeker.qc b/qcsrc/common/weapons/weapon/seeker.qc index ae6b736df..039414c7b 100644 --- a/qcsrc/common/weapons/weapon/seeker.qc +++ b/qcsrc/common/weapons/weapon/seeker.qc @@ -420,7 +420,7 @@ void W_Seeker_Vollycontroller_Think() // TODO: Merge this with W_Seeker_Attack entity oldenemy; self.cnt = self.cnt - 1; - if((!(self.realowner.items & IT_UNLIMITED_AMMO) && self.realowner.WEP_AMMO(SEEKER) < WEP_CVAR(seeker, missile_ammo)) || (self.cnt <= -1) || (self.realowner.deadflag != DEAD_NO) || (self.realowner.switchweapon != WEP_SEEKER.m_id)) + if((!(self.realowner.items & IT_UNLIMITED_AMMO) && self.realowner.WEP_AMMO(SEEKER) < WEP_CVAR(seeker, missile_ammo)) || (self.cnt <= -1) || (self.realowner.deadflag != DEAD_NO) || (PS(self.realowner).m_switchweapon != WEP_SEEKER)) { remove(self); return; @@ -458,7 +458,7 @@ void W_Seeker_Vollycontroller_Think() // TODO: Merge this with W_Seeker_Attack void W_Seeker_Tracker_Think() {SELFPARAM(); // commit suicide if: You die OR target dies OR you switch away from the seeker OR commit suicide if lifetime is up - if((self.realowner.deadflag != DEAD_NO) || (self.tag_target.deadflag != DEAD_NO) || (self.realowner.switchweapon != WEP_SEEKER.m_id) + if((self.realowner.deadflag != DEAD_NO) || (self.tag_target.deadflag != DEAD_NO) || (PS(self.realowner).m_switchweapon != WEP_SEEKER) || (time > self.tag_time + WEP_CVAR(seeker, tag_tracker_lifetime))) { if(self) diff --git a/qcsrc/common/weapons/weapon/shotgun.qc b/qcsrc/common/weapons/weapon/shotgun.qc index 7b710b21f..bdc592fed 100644 --- a/qcsrc/common/weapons/weapon/shotgun.qc +++ b/qcsrc/common/weapons/weapon/shotgun.qc @@ -202,7 +202,7 @@ void W_Shotgun_Attack3_Frame2(Weapon thiswep, entity actor, .entity weaponentity if (!thiswep.wr_checkammo2(thiswep)) if (!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, Weapons_from(w_getbestweapon(actor))); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); w_ready(thiswep, actor, weaponentity, fire); return; } @@ -216,7 +216,7 @@ void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, .entity weaponentity if (!thiswep.wr_checkammo2(thiswep)) if (!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) { - W_SwitchWeapon_Force(actor, Weapons_from(w_getbestweapon(actor))); + W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); w_ready(thiswep, actor, weaponentity, fire); return; } diff --git a/qcsrc/lib/macro.qh b/qcsrc/lib/macro.qh index adcbe3553..1301ca4a4 100644 --- a/qcsrc/lib/macro.qh +++ b/qcsrc/lib/macro.qh @@ -10,4 +10,7 @@ #define MACRO_END } while (0) #endif +#define _CAT(a, b) a ## b +#define CAT(a, b) _CAT(a, b) + #endif diff --git a/qcsrc/lib/stats.qh b/qcsrc/lib/stats.qh index 0d445817e..d1823a77d 100644 --- a/qcsrc/lib/stats.qh +++ b/qcsrc/lib/stats.qh @@ -26,6 +26,7 @@ typedef vector vectori; #define _STAT(id) g_stat_##id #define REGISTER_STAT_2(id, T) \ T _STAT(id); \ + T CAT(_STAT(id), _prev); \ REGISTER(Stats, STAT_##id, m_id, new(stat)) \ { \ make_pure(this); \ @@ -36,7 +37,8 @@ typedef vector vectori; } \ [[accumulate]] void stats_get() \ { \ - _STAT(id) = getstat_##T(STAT_##id.m_id); \ + T it = getstat_##T(STAT_##id.m_id); \ + if (it != CAT(_STAT(id), _prev)) _STAT(id) = it; \ } #define REGISTER_STAT_3(x, T, expr) REGISTER_STAT(x, T) #elif defined(SVQC) diff --git a/qcsrc/server/_all.qh b/qcsrc/server/_all.qh index cbda56873..a53ab2435 100644 --- a/qcsrc/server/_all.qh +++ b/qcsrc/server/_all.qh @@ -29,6 +29,16 @@ const string STR_OBSERVER = "observer"; #define FOR_EACH_OBSERVER(v) FOR_EACH_CLIENT(v) if (IS_OBSERVER(v)) #define FOR_EACH_REALPLAYER(v) FOR_EACH_REALCLIENT(v) if (IS_PLAYER(v)) +#define FOREACH_CLIENT(cond, body) \ + MACRO_BEGIN { \ + int i = 0; \ + for (entity it = NULL; (it = nextent(it)) && (num_for_edict(it) <= maxclients); ++i) \ + { \ + if (!IS_CLIENT(it)) continue; \ + if (cond) { LAMBDA(body) } \ + } \ + } MACRO_END + #define FOR_EACH_MONSTER(v) for (v = world; (v = findflags(v, flags, FL_MONSTER)) != world; ) #include "../common/effects/all.qh" diff --git a/qcsrc/server/bot/havocbot/havocbot.qc b/qcsrc/server/bot/havocbot/havocbot.qc index 8cb4a3168..a0a1d78ee 100644 --- a/qcsrc/server/bot/havocbot/havocbot.qc +++ b/qcsrc/server/bot/havocbot/havocbot.qc @@ -175,7 +175,7 @@ void havocbot_ai() { entity e = Weapons_from(i); if ((self.weapons & (e.m_wepset)) && (e.spawnflags & WEP_FLAG_RELOADABLE) && (self.weapon_load[i] < e.reloading_ammo)) - self.switchweapon = i; + PS(self).m_switchweapon = Weapons_from(i); } } } @@ -617,7 +617,7 @@ void havocbot_movetogoal() return; } - self.switchweapon = WEP_DEVASTATOR.m_id; + PS(self).m_switchweapon = WEP_DEVASTATOR; self.v_angle_x = 90; self.BUTTON_ATCK = true; self.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay); @@ -1014,7 +1014,7 @@ void havocbot_chooseweapon() // ;) if(g_weaponarena_weapons == WEPSET(TUBA)) { - self.switchweapon = WEP_TUBA.m_id; + PS(self).m_switchweapon = WEP_TUBA; return; } @@ -1027,7 +1027,7 @@ void havocbot_chooseweapon() { if(client_hasweapon(self, Weapons_from(i), true, false)) { - self.switchweapon = i; + PS(self).m_switchweapon = Weapons_from(i); return; } } @@ -1075,7 +1075,7 @@ void havocbot_chooseweapon() { if ((self.weapon == w && combo) || havocbot_chooseweapon_checkreload(w)) continue; - self.switchweapon = w; + PS(self).m_switchweapon = Weapons_from(w); return; } } @@ -1089,7 +1089,7 @@ void havocbot_chooseweapon() { if ((self.weapon == w && combo) || havocbot_chooseweapon_checkreload(w)) continue; - self.switchweapon = w; + PS(self).m_switchweapon = Weapons_from(w); return; } } @@ -1102,7 +1102,7 @@ void havocbot_chooseweapon() { if ((self.weapon == w && combo) || havocbot_chooseweapon_checkreload(w)) continue; - self.switchweapon = w; + PS(self).m_switchweapon = Weapons_from(w); return; } } diff --git a/qcsrc/server/bot/scripting.qc b/qcsrc/server/bot/scripting.qc index 96f7af3a1..4f14d2f3b 100644 --- a/qcsrc/server/bot/scripting.qc +++ b/qcsrc/server/bot/scripting.qc @@ -576,7 +576,7 @@ float bot_cmd_select_weapon() return CMD_STATUS_ERROR; if(client_hasweapon(self, Weapons_from(id), true, false)) - self.switchweapon = id; + PS(self).m_switchweapon = Weapons_from(id); else return CMD_STATUS_ERROR; diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index ad5b5fc9e..fddaa09cb 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -23,9 +23,12 @@ #include "bot/navigation.qh" #include "../common/ent_cs.qh" -#include "../common/vehicles/all.qh" +#include "../common/state.qh" + #include "../common/triggers/teleporters.qh" +#include "../common/vehicles/all.qh" + #include "weapons/hitplot.qh" #include "weapons/weaponsystem.qh" @@ -186,7 +189,9 @@ putting a client as observer in the server */ void FixPlayermodel(entity player); void PutObserverInServer() -{SELFPARAM(); +{ + SELFPARAM(); + PlayerState_detach(this); entity spot; self.hud = HUD_NORMAL; @@ -438,6 +443,7 @@ void PutClientInServer() if (IS_OBSERVER(this)) { PutObserverInServer(); } else if (IS_PLAYER(this)) { + PlayerState_attach(this); accuracy_resend(this); if (this.team < 0) @@ -617,7 +623,7 @@ void PutClientInServer() remove(spot); // usefull for checking if there are spawnpoints, that let drop through the floor } - this.switchweapon = w_getbestweapon(this); + PS(this).m_switchweapon = w_getbestweapon(this); this.cnt = -1; // W_LastWeapon will not complain this.weapon = 0; this.weaponname = ""; @@ -997,7 +1003,9 @@ Called when a client connects to the server */ void DecodeLevelParms (); void ClientConnect () -{SELFPARAM(); +{ + SELFPARAM(); + ClientState_attach(this); float t; if(IS_CLIENT(self)) @@ -1216,7 +1224,9 @@ Called when a client disconnects from the server .entity chatbubbleentity; void ReadyCount(); void ClientDisconnect () -{SELFPARAM(); +{ + SELFPARAM(); + ClientState_detach(this); if(self.vehicle) vehicles_exit(VHEF_RELEASE); @@ -1670,7 +1680,7 @@ void SpectateCopy(entity this, entity spectatee) self.invincible_finished = spectatee.invincible_finished; self.pressedkeys = spectatee.pressedkeys; self.weapons = spectatee.weapons; - self.switchweapon = spectatee.switchweapon; + PS(self).m_switchweapon = PS(spectatee).m_switchweapon; self.switchingweapon = spectatee.switchingweapon; self.weapon = spectatee.weapon; self.vortex_charge = spectatee.vortex_charge; diff --git a/qcsrc/server/cl_impulse.qc b/qcsrc/server/cl_impulse.qc index 6598039dc..1787d540f 100644 --- a/qcsrc/server/cl_impulse.qc +++ b/qcsrc/server/cl_impulse.qc @@ -202,7 +202,7 @@ IMPULSE(weapon_best) { if (this.vehicle) return; if (this.deadflag != DEAD_NO) return; - W_SwitchWeapon(Weapons_from(w_getbestweapon(this))); + W_SwitchWeapon(w_getbestweapon(this)); } IMPULSE(weapon_drop) diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index d7ce1f66a..f496cf5be 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -573,7 +573,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp // clear waypoints WaypointSprite_PlayerDead(); // throw a weapon - SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon); + SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, PS(self).m_switchweapon.m_id); // become fully visible self.alpha = default_player_alpha; diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index 0e23d0828..dfabd9d3d 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -96,7 +96,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)))) - W_SwitchWeapon_Force(attacker, Weapons_from(w_getbestweapon(attacker))); + W_SwitchWeapon_Force(attacker, w_getbestweapon(attacker)); } // FIXME fix the mess this is (we have REAL points now!) diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 854282f3d..b2570784b 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -1992,6 +1992,7 @@ void EndFrame() setself(e_); antilag_record(e_, altime); } + FOREACH_CLIENT(PS(it), PS(it).ps_push(PS(it))); } diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 07dd423dc..bed49addd 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -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 = WEP_NAME(((!self.weapon) ? (!self.switchweapon ? self.cnt : self.switchweapon) : self.weapon)); break; + case "w": replacement = WEP_NAME(((!self.weapon) ? (!PS(self).m_switchweapon.m_id ? self.cnt : PS(self).m_switchweapon.m_id) : self.weapon)); 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; @@ -374,7 +374,11 @@ string W_FixWeaponOrder_ForceComplete_AndBuildImpulseList(string wo) self.weaponorder_byimpulse = strzone(W_FixWeaponOrder_BuildImpulseList(o)); return o; } -void GetCvars(float f) + +/** + * @param f -1: cleanup, 0: request, 1: receive + */ +void GetCvars(int f) {SELFPARAM(); string s = string_null; @@ -423,7 +427,7 @@ void GetCvars(float f) if (f > 0) { if (s == "cl_weaponpriority") - self.switchweapon = w_getbestweapon(self); + if (PS(self)) PS(self).m_switchweapon = w_getbestweapon(self); if (s == "cl_allow_uidtracking") PlayerStats_GameReport_AddPlayer(self); } diff --git a/qcsrc/server/playerdemo.qc b/qcsrc/server/playerdemo.qc index 5ca2c1ca9..5273a65a7 100644 --- a/qcsrc/server/playerdemo.qc +++ b/qcsrc/server/playerdemo.qc @@ -58,7 +58,7 @@ void playerdemo_open_write(string f) PLAYERDEMO_FIELD(func,string,playerskin) \ PLAYERDEMO_FIELD(func,float,frame) \ PLAYERDEMO_FIELD(func,float,effects) \ - PLAYERDEMO_FIELD(func,float,switchweapon) \ + /* PLAYERDEMO_FIELD(func,float,switchweapon) */ \ PLAYERDEMO_FIELD(func,float,BUTTON_ATCK) \ PLAYERDEMO_FIELD(func,float,BUTTON_ATCK2) \ PLAYERDEMO_FIELD(func,float,BUTTON_CROUCH) \ diff --git a/qcsrc/server/t_items.qc b/qcsrc/server/t_items.qc index d78194eb4..2511c69dc 100644 --- a/qcsrc/server/t_items.qc +++ b/qcsrc/server/t_items.qc @@ -642,10 +642,10 @@ float Item_GiveTo(entity item, entity player) // if the player is using their best weapon before items are given, they // probably want to switch to an even better weapon after items are given if (player.autoswitch) - if (player.switchweapon == w_getbestweapon(player)) + if (PS(player).m_switchweapon == w_getbestweapon(player)) _switchweapon = true; - if (!(player.weapons & WepSet_FromWeapon(Weapons_from(player.switchweapon)))) + if (!(player.weapons & WepSet_FromWeapon(PS(player).m_switchweapon))) _switchweapon = true; pickedup |= Item_GiveAmmoTo(item, player, ammo_fuel, g_pickup_fuel_max, ITEM_MODE_FUEL); @@ -715,8 +715,8 @@ float Item_GiveTo(entity item, entity player) } if (_switchweapon) - if (player.switchweapon != w_getbestweapon(player)) - W_SwitchWeapon_Force(player, Weapons_from(w_getbestweapon(player))); + if (PS(player).m_switchweapon != w_getbestweapon(player)) + W_SwitchWeapon_Force(player, w_getbestweapon(player)); return 1; } @@ -1627,7 +1627,7 @@ float GiveItems(entity e, float beginarg, float endarg) _switchweapon = false; if (e.autoswitch) - if (e.switchweapon == w_getbestweapon(e)) + if (PS(e).m_switchweapon == w_getbestweapon(e)) _switchweapon = true; e.strength_finished = max(0, e.strength_finished - time); @@ -1813,10 +1813,10 @@ float GiveItems(entity e, float beginarg, float endarg) else e.superweapons_finished += time; - if (!(e.weapons & WepSet_FromWeapon(Weapons_from(e.switchweapon)))) + if (!(e.weapons & WepSet_FromWeapon(PS(e).m_switchweapon))) _switchweapon = true; if(_switchweapon) - W_SwitchWeapon_Force(e, Weapons_from(w_getbestweapon(e))); + W_SwitchWeapon_Force(e, w_getbestweapon(e)); return got; } diff --git a/qcsrc/server/weapons/hitplot.qc b/qcsrc/server/weapons/hitplot.qc index ec48c6d3c..984644364 100644 --- a/qcsrc/server/weapons/hitplot.qc +++ b/qcsrc/server/weapons/hitplot.qc @@ -71,7 +71,7 @@ void W_HitPlotAnalysis(entity player, vector screenforward, vector screenright, antilag_takeback(trace_ent, time - lag); hitplot = W_HitPlotNormalizedUntransform(org, trace_ent, screenforward, screenright, screenup, trace_endpos); antilag_restore(trace_ent); - fputs(player.hitplotfh, strcat(ftos(hitplot.x), " ", ftos(hitplot.y), " ", ftos(hitplot.z), " ", ftos(player.switchweapon), "\n")); + fputs(player.hitplotfh, strcat(ftos(hitplot.x), " ", ftos(hitplot.y), " ", ftos(hitplot.z), " ", ftos(PS(player).m_switchweapon.m_id), "\n")); //print(strcat(ftos(hitplot_x), " ", ftos(hitplot_y), " ", ftos(hitplot_z), "\n")); } } diff --git a/qcsrc/server/weapons/selection.qc b/qcsrc/server/weapons/selection.qc index 737ddc8ad..9a2c9fd2b 100644 --- a/qcsrc/server/weapons/selection.qc +++ b/qcsrc/server/weapons/selection.qc @@ -123,7 +123,7 @@ float W_GetCycleWeapon(entity pl, string weaponorder, float dir, float imp, floa entity wep; if(skipmissing || pl.selectweapon == 0) - weaponcur = pl.switchweapon; + weaponcur = PS(pl).m_switchweapon.m_id; else weaponcur = pl.selectweapon; @@ -225,17 +225,16 @@ float W_GetCycleWeapon(entity pl, string weaponorder, float dir, float imp, floa void W_SwitchWeapon_Force(entity e, Weapon wep) { - int w = wep.m_id; - e.cnt = e.switchweapon; - e.switchweapon = w; - e.selectweapon = w; + e.cnt = PS(e).m_switchweapon.m_id; + PS(e).m_switchweapon = wep; + e.selectweapon = wep.m_id; } // perform weapon to attack (weaponstate and attack_finished check is here) 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) - int ww; + Weapon ww; WepSet set = WepSet_FromWeapon(Weapons_from(pl.weapon)); if(pl.weapons & set) { @@ -246,18 +245,17 @@ void W_SwitchToOtherWeapon(entity pl) else ww = w_getbestweapon(pl); if(ww) - W_SwitchWeapon_Force(pl, Weapons_from(ww)); + W_SwitchWeapon_Force(pl, ww); } void W_SwitchWeapon(Weapon w) {SELFPARAM(); - int imp = w.m_id; - if (self.switchweapon != imp) + if (PS(self).m_switchweapon != w) { if (client_hasweapon(self, w, true, true)) W_SwitchWeapon_Force(self, w); else - self.selectweapon = imp; // update selectweapon ANYWAY + self.selectweapon = w.m_id; // update selectweapon ANYWAY } else if(!forbidWeaponUse(self)) { w.wr_reload(w); diff --git a/qcsrc/server/weapons/selection.qh b/qcsrc/server/weapons/selection.qh index 07d8383b1..18e3f5a1c 100644 --- a/qcsrc/server/weapons/selection.qh +++ b/qcsrc/server/weapons/selection.qh @@ -10,7 +10,7 @@ bool client_hasweapon(entity cl, Weapon wpn, float andammo, bool complain); .int weaponcomplainindex; float W_GetCycleWeapon(entity pl, string weaponorder, float dir, float imp, float complain, float skipmissing); -#define w_getbestweapon(ent) W_GetCycleWeapon(ent, ent.cvar_cl_weaponpriority, 0, -1, false, true) +#define w_getbestweapon(ent) Weapons_from(W_GetCycleWeapon(ent, ent.cvar_cl_weaponpriority, 0, -1, false, true)) void W_SwitchWeapon_Force(entity e, Weapon w); diff --git a/qcsrc/server/weapons/throwing.qc b/qcsrc/server/weapons/throwing.qc index 829b6ed62..652ec9200 100644 --- a/qcsrc/server/weapons/throwing.qc +++ b/qcsrc/server/weapons/throwing.qc @@ -182,7 +182,7 @@ void W_ThrowWeapon(vector velo, vector delta, float doreduce) if(!(self.weapons & set)) return; self.weapons &= ~set; - W_SwitchWeapon_Force(self, Weapons_from(w_getbestweapon(self))); + W_SwitchWeapon_Force(self, w_getbestweapon(self)); string a = W_ThrowNewWeapon(self, w, doreduce, self.origin + delta, velo); if(!a) return; diff --git a/qcsrc/server/weapons/weaponsystem.qc b/qcsrc/server/weapons/weaponsystem.qc index f5f279dff..0124fa9f5 100644 --- a/qcsrc/server/weapons/weaponsystem.qc +++ b/qcsrc/server/weapons/weaponsystem.qc @@ -222,7 +222,7 @@ bool weapon_prepareattack_checkammo(Weapon thiswep, entity actor, bool secondary if (thiswep == WEP_SHOTGUN) if (!secondary && WEP_CVAR(shotgun, secondary) == 1) return false; // no clicking, just allow - if (thiswep == Weapons_from(actor.switchweapon) && time - actor.prevdryfire > 1) // only play once BEFORE starting to switch weapons + if (thiswep == PS(actor).m_switchweapon && time - actor.prevdryfire > 1) // only play once BEFORE starting to switch weapons { sound(actor, CH_WEAPON_A, SND_DRYFIRE, VOL_BASE, ATTEN_NORM); actor.prevdryfire = time; @@ -269,7 +269,7 @@ bool weapon_prepareattack_check(Weapon thiswep, entity actor, .entity weaponenti return false; // do not even think about shooting if switching - if (actor.switchweapon != actor.weapon) return false; + if (PS(actor).m_switchweapon.m_id != actor.weapon) return false; if (attacktime >= 0) { @@ -429,7 +429,7 @@ void W_WeaponFrame(entity actor) } } - if (actor.switchweapon == 0) + if (PS(actor).m_switchweapon.m_id == 0) { actor.weapon = 0; actor.switchingweapon = 0; @@ -445,7 +445,7 @@ void W_WeaponFrame(entity actor) vector up = v_up; // Change weapon - if (actor.weapon != actor.switchweapon) + if (actor.weapon != PS(actor).m_switchweapon.m_id) { switch (this.state) { @@ -458,11 +458,11 @@ void W_WeaponFrame(entity actor) case WS_CLEAR: { // end switching! - actor.switchingweapon = actor.switchweapon; - entity newwep = Weapons_from(actor.switchweapon); + Weapon newwep = PS(actor).m_switchweapon; + actor.switchingweapon = newwep.m_id; // the two weapon entities will notice this has changed and update their models - actor.weapon = actor.switchweapon; + actor.weapon = newwep.m_id; actor.weaponname = newwep.mdl; actor.bulletcounter = 0; actor.ammo_field = newwep.ammo_field; @@ -472,7 +472,7 @@ void W_WeaponFrame(entity actor) // set our clip load to the load of the weapon we switched to, if it's reloadable if ((newwep.spawnflags & WEP_FLAG_RELOADABLE) && newwep.reloading_ammo) // prevent accessing undefined cvars { - actor.clip_load = actor.(weapon_load[actor.switchweapon]); + actor.clip_load = actor.(weapon_load[PS(actor).m_switchweapon.m_id]); actor.clip_size = newwep.reloading_ammo; } else @@ -486,13 +486,13 @@ void W_WeaponFrame(entity actor) case WS_DROP: { // in dropping phase we can switch at any time - actor.switchingweapon = actor.switchweapon; + actor.switchingweapon = PS(actor).m_switchweapon.m_id; break; } case WS_READY: { // start switching! - actor.switchingweapon = actor.switchweapon; + actor.switchingweapon = PS(actor).m_switchweapon.m_id; entity oldwep = Weapons_from(actor.weapon); // set up weapon switch think in the future, and start drop anim @@ -520,7 +520,7 @@ void W_WeaponFrame(entity actor) { if (w && !(actor.weapons & WepSet_FromWeapon(Weapons_from(w)))) { - if (actor.weapon == actor.switchweapon) W_SwitchWeapon_Force(actor, Weapons_from(w_getbestweapon(actor))); + if (actor.weapon == PS(actor).m_switchweapon.m_id) W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); w = 0; } @@ -538,7 +538,7 @@ void W_WeaponFrame(entity actor) } else { - if (key_pressed && actor.switchweapon != WEP_HOOK.m_id && !actor.hook_switchweapon) + if (key_pressed && PS(actor).m_switchweapon != WEP_HOOK && !actor.hook_switchweapon) W_SwitchWeapon(WEP_HOOK); actor.hook_switchweapon = key_pressed; Weapon h = WEP_HOOK;