}
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;
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)
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);
}
}
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;
}
}
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
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,
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));
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;
/**
- * 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
}
);
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))
);
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))
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)
{
#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))
// 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;
// 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;
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;
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;
}
// 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();
{
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);
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)
{
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);
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);
// 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,
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);
{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));
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);
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))
{
else
{
if(self.BUTTON_ATCK||self.BUTTON_ATCK2)
- self.lastfiredweapon = self.weapon;
+ self.lastfiredweapon = PS(self).m_weapon.m_id;
}
}
else
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))
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;
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;
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;
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;
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 = "";
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;
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;
// 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)
// 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;
// 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;
}
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);
}
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;
{
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);
}
}
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))
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);
#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;
{
// 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?
{
}
// 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));
}
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)
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);
+ });
}
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;
{
// 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;
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;
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));
// 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;
.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');
}
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;
// 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);
}
// 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;
// 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);
}
}
// 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)
{
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)
{
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
;
{
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 = "";
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)
{
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;
{
// 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)
// 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
{
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;
}
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);
}
}
{
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);
}
}
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));
}
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)
{
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,
// 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));
}
{
.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;
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
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)