STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, this) = Physics_ClientOption(this, "airspeedlimit_nonqw", autocvar_sv_airspeedlimit_nonqw) * maxspd_mod;
STAT(MOVEVARS_MAXSPEED, this) = Physics_ClientOption(this, "maxspeed", autocvar_sv_maxspeed) * maxspd_mod; // also slow walking
+ STAT(PL_MIN, this) = autocvar_sv_player_mins;
+ STAT(PL_MAX, this) = autocvar_sv_player_maxs;
+ STAT(PL_VIEW_OFS, this) = autocvar_sv_player_viewoffset;
+ STAT(PL_CROUCH_MIN, this) = autocvar_sv_player_crouch_mins;
+ STAT(PL_CROUCH_MAX, this) = autocvar_sv_player_crouch_maxs;
+ STAT(PL_CROUCH_VIEW_OFS, this) = autocvar_sv_player_crouch_viewoffset;
+
// old stats
// fix some new settings
STAT(MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, this) = Physics_ClientOption(this, "airaccel_qw_stretchfactor", autocvar_sv_airaccel_qw_stretchfactor);
// set crouched
bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
- if(this.hook && !wasfreed(this.hook))
- do_crouch = false;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ entity wep = viewmodels[slot];
+ if(wep.hook && !wasfreed(wep.hook))
+ {
+ do_crouch = false;
+ break; // don't bother checking the others
+ }
+ }
if(this.waterlevel >= WATERLEVEL_SWIMMING)
do_crouch = false;
if(hud != HUD_NORMAL)
this.wasFlying = false;
if (this.waterlevel >= WATERLEVEL_SWIMMING) return;
if (time < this.ladder_time) return;
- if (this.hook) return;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).hook)
+ return;
+ }
this.nextstep = time + 0.3 + random() * 0.1;
trace_dphitq3surfaceflags = 0;
tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
#include "bot/api.qh"
#include "../common/ent_cs.qh"
+#include "../common/wepent.qh"
#include <common/state.qh>
#include <common/effects/qc/globalsound.qh>
if (e.race_completed) sf |= 1; // forced scoreboard
if (to.spectatee_status) sf |= 2; // spectator ent number follows
if (e.zoomstate) sf |= 4; // zoomed
- if (e.porto_v_angle_held) sf |= 8; // angles held
if (autocvar_sv_showspectators) sf |= 16; // show spectators
WriteHeader(MSG_ENTITY, ENT_CLIENT_CLIENTDATA);
{
WriteByte(MSG_ENTITY, to.spectatee_status);
}
- if (sf & 8)
- {
- WriteAngle(MSG_ENTITY, e.v_angle.x);
- WriteAngle(MSG_ENTITY, e.v_angle.y);
- }
if(sf & 16)
{
this.view_ofs = '0 0 0';
}
- RemoveGrapplingHook(this);
+ RemoveGrapplingHooks(this);
Portal_ClearAll(this);
Unfreeze(this);
SetSpectatee(this, NULL);
this.istypefrag = 0;
setthink(this, func_null);
this.nextthink = 0;
- this.hook_time = 0;
this.deadflag = DEAD_NO;
this.crouch = false;
this.revival_time = 0;
this.weapons = '0 0 0';
this.drawonlytoclient = this;
- this.weaponname = "";
this.weaponmodel = "";
for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
+ if(!this.weaponentities[slot])
+ continue; // first load
+ this.weaponentities[slot].hook_time = 0;
+ this.weaponentities[slot].weaponname = "";
this.weaponentities[slot] = NULL;
}
this.exteriorweaponentity = NULL;
this.oldvelocity = this.velocity;
this.fire_endtime = -1;
this.event_damage = func_null;
-
- STAT(ACTIVEWEAPON, this) = WEP_Null.m_id;
- STAT(SWITCHINGWEAPON, this) = WEP_Null.m_id;
- STAT(SWITCHWEAPON, this) = WEP_Null.m_id;
}
int player_getspecies(entity this)
this.drawonlytoclient = NULL;
this.crouch = false;
- this.view_ofs = STAT(PL_VIEW_OFS, NULL);
- setsize(this, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL));
+ this.view_ofs = STAT(PL_VIEW_OFS, this);
+ setsize(this, STAT(PL_MIN, this), STAT(PL_MAX, this));
this.spawnorigin = spot.origin;
setorigin(this, spot.origin + '0 0 1' * (1 - this.mins.z - 24));
// don't reset back to last position, even if new position is stuck in solid
for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- CL_SpawnWeaponentity(this, weaponentities[slot]);
+ .entity weaponentity = weaponentities[slot];
+ CL_SpawnWeaponentity(this, weaponentity);
}
this.alpha = default_player_alpha;
this.colormod = '1 1 1' * autocvar_g_player_brightness;
it.wr_resetplayer(it, this);
// reload all reloadable weapons
if (it.spawnflags & WEP_FLAG_RELOADABLE) {
- this.weapon_load[it.m_id] = it.reloading_ammo;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ this.(weaponentity).weapon_load[it.m_id] = it.reloading_ammo;
+ }
}
));
delete(spot); // usefull for checking if there are spawnpoints, that let drop through the floor
}
- PS(this).m_switchweapon = w_getbestweapon(this);
- this.cnt = -1; // W_LastWeapon will not complain
- PS(this).m_weapon = WEP_Null;
- this.weaponname = "";
- PS(this).m_switchingweapon = WEP_Null;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(slot == 0)
+ this.(weaponentity).m_switchweapon = w_getbestweapon(this, weaponentity);
+ else
+ this.(weaponentity).m_switchweapon = WEP_Null;
+ this.(weaponentity).m_weapon = WEP_Null;
+ this.(weaponentity).weaponname = "";
+ this.(weaponentity).m_switchingweapon = WEP_Null;
+ this.(weaponentity).cnt = -1;
+ }
if (!warmup_stage && !this.alivetime)
this.alivetime = time;
Unfreeze(this);
- RemoveGrapplingHook(this);
+ RemoveGrapplingHooks(this);
// Here, everything has been done that requires this player to be a client.
void GetPressedKeys(entity this)
{
MUTATOR_CALLHOOK(GetPressedKeys, this);
- int keys = this.pressedkeys;
+ int keys = STAT(PRESSED_KEYS, this);
keys = BITSET(keys, KEY_FORWARD, this.movement.x > 0);
keys = BITSET(keys, KEY_BACKWARD, this.movement.x < 0);
keys = BITSET(keys, KEY_RIGHT, this.movement.y > 0);
keys = BITSET(keys, KEY_CROUCH, PHYS_INPUT_BUTTON_CROUCH(this));
keys = BITSET(keys, KEY_ATCK, PHYS_INPUT_BUTTON_ATCK(this));
keys = BITSET(keys, KEY_ATCK2, PHYS_INPUT_BUTTON_ATCK2(this));
- this.pressedkeys = keys;
+ this.pressedkeys = keys; // store for other users
+
+ STAT(PRESSED_KEYS, this) = keys;
}
/*
this.hit_time = spectatee.hit_time;
this.strength_finished = spectatee.strength_finished;
this.invincible_finished = spectatee.invincible_finished;
- this.pressedkeys = spectatee.pressedkeys;
+ STAT(PRESSED_KEYS, this) = STAT(PRESSED_KEYS, spectatee);
this.weapons = spectatee.weapons;
this.vortex_charge = spectatee.vortex_charge;
this.vortex_chargepool_ammo = spectatee.vortex_chargepool_ammo;
{
this.items &= ~this.items_added;
- //for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- //{
- //.entity weaponentity = weaponentities[slot];
- //W_WeaponFrame(this, weaponentity);
- //}
- .entity weaponentity = weaponentities[0]; // TODO
- W_WeaponFrame(this, weaponentity);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_WeaponFrame(this, weaponentity);
+
+ if(slot == 0)
+ {
+ this.clip_load = this.(weaponentity).clip_load;
+ this.clip_size = this.(weaponentity).clip_size;
+ }
+ }
this.items_added = 0;
if (this.items & ITEM_Jetpack.m_itemid && (this.items & ITEM_JetpackRegen.m_itemid || this.ammo_fuel >= 0.01))
// WEAPONTODO: Add a weapon request for this
// rot vortex charge to the charge limit
- if (WEP_CVAR(vortex, charge_rot_rate) && this.vortex_charge > WEP_CVAR(vortex, charge_limit) && this.vortex_charge_rottime < time)
- this.vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if (WEP_CVAR(vortex, charge_rot_rate) && this.(weaponentity).vortex_charge > WEP_CVAR(vortex, charge_limit) && this.(weaponentity).vortex_charge_rottime < time)
+ this.(weaponentity).vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.(weaponentity).vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
+ }
if (frametime) player_anim(this);
// WEAPONTODO: Add weapon request for this
if (!zoomstate_set) {
- SetZoomState(this,
- PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this)
- || (PHYS_INPUT_BUTTON_ATCK2(this) && PS(this).m_weapon == WEP_VORTEX)
- || (PHYS_INPUT_BUTTON_ATCK2(this) && PS(this).m_weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0)
- );
+ bool wep_zoomed = false;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ Weapon thiswep = this.(weaponentity).m_weapon;
+ if(thiswep != WEP_Null && thiswep.wr_zoom)
+ wep_zoomed += thiswep.wr_zoom(thiswep, this);
+ }
+ SetZoomState(this, PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this) || wep_zoomed);
}
if (this.teamkill_soundtime && time > this.teamkill_soundtime)
// 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 (PS(this).m_weapon == WEP_Null)
- this.clip_load = this.clip_size = 0;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).m_weapon == WEP_Null)
+ this.(weaponentity).clip_load = this.(weaponentity).clip_size = 0;
+ }
}
void DrownPlayer(entity this)