X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Fphysics.qc;h=731cba8ed45c912bb35b409be792f2ffe15f77bb;hp=410c27131f434abd92cb81b037b3c2c710f18cca;hb=f9e4718d229df569d7878259d3db2bd2df1e7b91;hpb=4ccdf8536721403c05302f83b9ca1b63e756c6f0 diff --git a/qcsrc/common/physics.qc b/qcsrc/common/physics.qc index 410c27131..731cba8ed 100644 --- a/qcsrc/common/physics.qc +++ b/qcsrc/common/physics.qc @@ -1,10 +1,34 @@ #include "physics.qh" -#include "triggers/trigger/swamp.qh" -#include "triggers/trigger/jumppads.qh" +#include "triggers/include.qh" +#include "viewloc.qh" #ifdef SVQC #include "../server/miscfunctions.qh" +#include "triggers/trigger/viewloc.qh" + +// client side physics +bool Physics_Valid(string thecvar) +{ + return autocvar_g_physics_clientselect && strhasword(autocvar_g_physics_clientselect_options, thecvar); +} + +float Physics_ClientOption(entity pl, string option) +{ + if(Physics_Valid(pl.cvar_cl_physics)) + { + string s = sprintf("g_physics_%s_%s", pl.cvar_cl_physics, option); + if(cvar_type(s) & CVAR_TYPEFLAG_EXISTS) + return cvar(s); + } + if(autocvar_g_physics_clientselect && autocvar_g_physics_clientselect_default) + { + string s = sprintf("g_physics_%s_%s", autocvar_g_physics_clientselect_default, option); + if(cvar_type(s) & CVAR_TYPEFLAG_EXISTS) + return cvar(s); + } + return cvar(strcat("sv_", option)); +} void Physics_AddStats() { @@ -52,8 +76,6 @@ void Physics_AddStats() addstat(STAT_DOUBLEJUMP, AS_INT, stat_doublejump); // jump speed caps - addstat(STAT_MOVEVARS_JUMPSPEEDCAP_MIN, AS_FLOAT, stat_jumpspeedcap_min); - addstat(STAT_MOVEVARS_JUMPSPEEDCAP_MIN, AS_FLOAT, stat_jumpspeedcap_min); addstat(STAT_MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS, AS_INT, stat_jumpspeedcap_disable_onramps); // hacks @@ -61,11 +83,32 @@ void Physics_AddStats() addstat(STAT_MOVEVARS_FRICTION_SLICK, AS_FLOAT, stat_sv_friction_slick); addstat(STAT_GAMEPLAYFIX_EASIERWATERJUMP, AS_INT, stat_gameplayfix_easierwaterjump); + // new properties + addstat(STAT_MOVEVARS_JUMPVELOCITY, AS_FLOAT, stat_sv_jumpvelocity); + addstat(STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, AS_FLOAT, stat_sv_airaccel_qw_stretchfactor); + addstat(STAT_MOVEVARS_MAXAIRSTRAFESPEED, AS_FLOAT, stat_sv_maxairstrafespeed); + addstat(STAT_MOVEVARS_MAXAIRSPEED, AS_FLOAT, stat_sv_maxairspeed); + addstat(STAT_MOVEVARS_AIRSTRAFEACCELERATE, AS_FLOAT, stat_sv_airstrafeaccelerate); + addstat(STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL, AS_FLOAT, stat_sv_warsowbunny_turnaccel); + addstat(STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, AS_FLOAT, stat_sv_airaccel_sideways_friction); + addstat(STAT_MOVEVARS_AIRCONTROL, AS_FLOAT, stat_sv_aircontrol); + addstat(STAT_MOVEVARS_AIRCONTROL_POWER, AS_FLOAT, stat_sv_aircontrol_power); + addstat(STAT_MOVEVARS_AIRCONTROL_PENALTY, AS_FLOAT, stat_sv_aircontrol_penalty); + addstat(STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, AS_FLOAT, stat_sv_warsowbunny_airforwardaccel); + addstat(STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED, AS_FLOAT, stat_sv_warsowbunny_topspeed); + addstat(STAT_MOVEVARS_WARSOWBUNNY_ACCEL, AS_FLOAT, stat_sv_warsowbunny_accel); + addstat(STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, AS_FLOAT, stat_sv_warsowbunny_backtosideratio); + addstat(STAT_MOVEVARS_FRICTION, AS_FLOAT, stat_sv_friction); + addstat(STAT_MOVEVARS_ACCELERATE, AS_FLOAT, stat_sv_accelerate); + addstat(STAT_MOVEVARS_STOPSPEED, AS_FLOAT, stat_sv_stopspeed); + addstat(STAT_MOVEVARS_AIRACCELERATE, AS_FLOAT, stat_sv_airaccelerate); + addstat(STAT_MOVEVARS_AIRSTOPACCELERATE, AS_FLOAT, stat_sv_airstopaccelerate); + addstat(STAT_GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, AS_INT, stat_gameplayfix_upvelocityclearsonground); } void Physics_UpdateStats(float maxspd_mod) -{ +{SELFPARAM(); // blah self.stat_pl_view_ofs = PL_VIEW_OFS; self.stat_pl_crouch_view_ofs = PL_CROUCH_VIEW_OFS; @@ -75,13 +118,14 @@ void Physics_UpdateStats(float maxspd_mod) self.stat_pl_crouch_min = PL_CROUCH_MIN; self.stat_pl_crouch_max = PL_CROUCH_MAX; - self.stat_sv_airaccel_qw = AdjustAirAccelQW(autocvar_sv_airaccel_qw, maxspd_mod); - if (autocvar_sv_airstrafeaccel_qw) - self.stat_sv_airstrafeaccel_qw = AdjustAirAccelQW(autocvar_sv_airstrafeaccel_qw, maxspd_mod); + + self.stat_sv_airaccel_qw = AdjustAirAccelQW(Physics_ClientOption(self, "airaccel_qw"), maxspd_mod); + if(Physics_ClientOption(self, "airstrafeaccel_qw")) + self.stat_sv_airstrafeaccel_qw = AdjustAirAccelQW(Physics_ClientOption(self, "airstrafeaccel_qw"), maxspd_mod); else self.stat_sv_airstrafeaccel_qw = 0; - self.stat_sv_airspeedlimit_nonqw = autocvar_sv_airspeedlimit_nonqw * maxspd_mod; - self.stat_sv_maxspeed = autocvar_sv_maxspeed * maxspd_mod; // also slow walking + self.stat_sv_airspeedlimit_nonqw = Physics_ClientOption(self, "airspeedlimit_nonqw") * maxspd_mod; + self.stat_sv_maxspeed = Physics_ClientOption(self, "maxspeed") * maxspd_mod; // also slow walking self.stat_movement_highspeed = PHYS_HIGHSPEED; // TODO: remove this! self.stat_doublejump = PHYS_DOUBLEJUMP; @@ -93,8 +137,6 @@ void Physics_UpdateStats(float maxspd_mod) self.stat_jetpack_maxspeed_up = PHYS_JETPACK_MAXSPEED_UP; self.stat_jetpack_fuel = PHYS_JETPACK_FUEL; - self.stat_jumpspeedcap_min = PHYS_JUMPSPEEDCAP_MIN; - self.stat_jumpspeedcap_max = PHYS_JUMPSPEEDCAP_MAX; self.stat_jumpspeedcap_disable_onramps = PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS; self.stat_sv_friction_on_land = PHYS_FRICTION_ONLAND; @@ -102,6 +144,29 @@ void Physics_UpdateStats(float maxspd_mod) self.stat_gameplayfix_easierwaterjump = GAMEPLAYFIX_EASIERWATERJUMP; + + // old stats + // fix some new settings + self.stat_sv_airaccel_qw_stretchfactor = Physics_ClientOption(self, "airaccel_qw_stretchfactor"); + self.stat_sv_maxairstrafespeed = Physics_ClientOption(self, "maxairstrafespeed"); + self.stat_sv_maxairspeed = Physics_ClientOption(self, "maxairspeed"); + self.stat_sv_airstrafeaccelerate = Physics_ClientOption(self, "airstrafeaccelerate"); + self.stat_sv_warsowbunny_turnaccel = Physics_ClientOption(self, "warsowbunny_turnaccel"); + self.stat_sv_airaccel_sideways_friction = Physics_ClientOption(self, "airaccel_sideways_friction"); + self.stat_sv_aircontrol = Physics_ClientOption(self, "aircontrol"); + self.stat_sv_aircontrol_power = Physics_ClientOption(self, "aircontrol_power"); + self.stat_sv_aircontrol_penalty = Physics_ClientOption(self, "aircontrol_penalty"); + self.stat_sv_warsowbunny_airforwardaccel = Physics_ClientOption(self, "warsowbunny_airforwardaccel"); + self.stat_sv_warsowbunny_topspeed = Physics_ClientOption(self, "warsowbunny_topspeed"); + self.stat_sv_warsowbunny_accel = Physics_ClientOption(self, "warsowbunny_accel"); + self.stat_sv_warsowbunny_backtosideratio = Physics_ClientOption(self, "warsowbunny_backtosideratio"); + self.stat_sv_friction = Physics_ClientOption(self, "friction"); + self.stat_sv_accelerate = Physics_ClientOption(self, "accelerate"); + self.stat_sv_stopspeed = Physics_ClientOption(self, "stopspeed"); + self.stat_sv_airaccelerate = Physics_ClientOption(self, "airaccelerate"); + self.stat_sv_airstopaccelerate = Physics_ClientOption(self, "airstopaccelerate"); + self.stat_sv_jumpvelocity = Physics_ClientOption(self, "jumpvelocity"); + self.stat_gameplayfix_upvelocityclearsonground = UPWARD_VELOCITY_CLEARS_ONGROUND; } #endif @@ -149,7 +214,7 @@ vector unstick_offsets[unstick_count] = }; void PM_ClientMovement_Unstick() -{ +{SELFPARAM(); float i; for (i = 0; i < unstick_count; i++) { @@ -164,7 +229,7 @@ void PM_ClientMovement_Unstick() } void PM_ClientMovement_UpdateStatus(bool ground) -{ +{SELFPARAM(); // make sure player is not stuck PM_ClientMovement_Unstick(); @@ -235,7 +300,7 @@ void PM_ClientMovement_UpdateStatus(bool ground) } void PM_ClientMovement_Move() -{ +{SELFPARAM(); #ifdef CSQC int bump; float t; @@ -254,7 +319,7 @@ void PM_ClientMovement_Move() vector trace1_plane_normal = '0 0 0'; vector trace2_plane_normal = '0 0 0'; vector trace3_plane_normal = '0 0 0'; - + PM_ClientMovement_UpdateStatus(false); primalvelocity = self.velocity; @@ -324,12 +389,12 @@ void PM_ClientMovement_Move() } void CPM_PM_Aircontrol(vector wishdir, float wishspeed) -{ +{SELFPARAM(); float k = 32 * (2 * IsMoveInDirection(self.movement, 0) - 1); if (k <= 0) return; - k *= bound(0, wishspeed / PHYS_MAXAIRSPEED, 1); + k *= bound(0, wishspeed / PHYS_MAXAIRSPEED(self), 1); float zspeed = self.velocity_z; self.velocity_z = 0; @@ -361,7 +426,7 @@ float AdjustAirAccelQW(float accelqw, float factor) // prvm_globalset server speedclamp_mode 1 // (or 2) void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float accel, float accelqw, float stretchfactor, float sidefric, float speedlimit) -{ +{SELFPARAM(); float speedclamp = stretchfactor > 0 ? stretchfactor : accelqw < 0 ? 1 // full clamping, no stretch : -1; // no clamping @@ -425,7 +490,7 @@ void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float acce } void PM_AirAccelerate(vector wishdir, float wishspeed) -{ +{SELFPARAM(); if (wishspeed == 0) return; @@ -468,7 +533,7 @@ returns true if handled ============= */ bool PlayerJump (void) -{ +{SELFPARAM(); if (PHYS_FROZEN(self)) return true; // no jumping in freezetag when frozen @@ -479,15 +544,16 @@ bool PlayerJump (void) bool doublejump = false; float mjumpheight = PHYS_JUMPVELOCITY; - +#ifdef CSQC player_multijump = doublejump; player_jumpheight = mjumpheight; -#ifdef SVQC - if (MUTATOR_CALLHOOK(PlayerJump)) -#elif defined(CSQC) - if(PM_multijump_checkjump()) #endif - return true; + + if (MUTATOR_CALLHOOK(PlayerJump, doublejump, mjumpheight) +#ifdef CSQC + || PM_multijump_checkjump() +#endif + ) { return true; } doublejump = player_multijump; mjumpheight = player_jumpheight; @@ -525,22 +591,22 @@ bool PlayerJump (void) // velocity bounds. Final velocity is bound between (jumpheight * // min + jumpheight) and (jumpheight * max + jumpheight); - if(PHYS_JUMPSPEEDCAP_MIN) + if(PHYS_JUMPSPEEDCAP_MIN != "") { - float minjumpspeed = mjumpheight * PHYS_JUMPSPEEDCAP_MIN; + float minjumpspeed = mjumpheight * stof(PHYS_JUMPSPEEDCAP_MIN); if (self.velocity_z < minjumpspeed) mjumpheight += minjumpspeed - self.velocity_z; } - if(PHYS_JUMPSPEEDCAP_MAX) + if(PHYS_JUMPSPEEDCAP_MAX != "") { // don't do jump speedcaps on ramps to preserve old xonotic ramjump style tracebox(self.origin + '0 0 0.01', self.mins, self.maxs, self.origin - '0 0 0.01', MOVE_NORMAL, self); if (!(trace_fraction < 1 && trace_plane_normal_z < 0.98 && PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS)) { - float maxjumpspeed = mjumpheight * PHYS_JUMPSPEEDCAP_MAX; + float maxjumpspeed = mjumpheight * stof(PHYS_JUMPSPEEDCAP_MAX); if (self.velocity_z > maxjumpspeed) mjumpheight -= self.velocity_z - maxjumpspeed; @@ -551,7 +617,7 @@ bool PlayerJump (void) { #ifdef SVQC if(autocvar_speedmeter) - dprint(strcat("landing velocity: ", vtos(self.velocity), " (abs: ", ftos(vlen(self.velocity)), ")\n")); + LOG_TRACE(strcat("landing velocity: ", vtos(self.velocity), " (abs: ", ftos(vlen(self.velocity)), ")\n")); #endif if(self.lastground < time - 0.3) { @@ -560,7 +626,7 @@ bool PlayerJump (void) } #ifdef SVQC if(self.jumppadcount > 1) - dprint(strcat(ftos(self.jumppadcount), "x jumppad combo\n")); + LOG_TRACE(strcat(ftos(self.jumppadcount), "x jumppad combo\n")); self.jumppadcount = 0; #endif } @@ -583,7 +649,7 @@ bool PlayerJump (void) } void CheckWaterJump() -{ +{SELFPARAM(); // check for a jump-out-of-water makevectors(self.v_angle); vector start = self.origin; @@ -623,7 +689,7 @@ void CheckWaterJump() // Hack: shouldn't need to know about this .float multijump_count; void CheckPlayerJump() -{ +{SELFPARAM(); #ifdef SVQC float was_flying = ITEMS_STAT(self) & IT_USING_JETPACK; #endif @@ -636,7 +702,7 @@ void CheckPlayerJump() float activate = JETPACK_JUMP(self) && air_jump && PHYS_INPUT_BUTTON_JUMP(self) || PHYS_INPUT_BUTTON_JETPACK(self); float has_fuel = !PHYS_JETPACK_FUEL || PHYS_AMMO_FUEL(self) || ITEMS_STAT(self) & IT_UNLIMITED_WEAPON_AMMO; - if (!(ITEMS_STAT(self) & IT_JETPACK)) { } + if (!(ITEMS_STAT(self) & ITEM_Jetpack.m_itemid)) { } else if (self.jetpack_stopped) { } else if (!has_fuel) { @@ -683,7 +749,7 @@ float racecar_angle(float forward, float down) } void RaceCarPhysics() -{ +{SELFPARAM(); #ifdef SVQC // using this move type for "big rigs" // the engine does not push the entity! @@ -897,22 +963,13 @@ void SpecialCommand() TetrisImpulse(); #else if (!CheatImpulse(99)) - print("A hollow voice says \"Plugh\".\n"); -#endif + LOG_INFO("A hollow voice says \"Plugh\".\n"); #endif -} - -float PM_check_keepaway(void) -{ -#ifdef SVQC - return (self.ballcarried && g_keepaway) ? autocvar_g_keepaway_ballcarrier_highspeed : 1; -#else - return 1; #endif } void PM_check_race_movetime(void) -{ +{SELFPARAM(); #ifdef SVQC self.race_movetime_frac += PHYS_INPUT_TIMELENGTH; float f = floor(self.race_movetime_frac); @@ -923,7 +980,7 @@ void PM_check_race_movetime(void) } float PM_check_specialcommand(float buttons) -{ +{SELFPARAM(); #ifdef SVQC string c; if (!buttons) @@ -960,7 +1017,7 @@ float PM_check_specialcommand(float buttons) } void PM_check_nickspam(void) -{ +{SELFPARAM(); #ifdef SVQC if (time >= self.nickspamtime) return; @@ -982,7 +1039,7 @@ void PM_check_nickspam(void) } void PM_check_punch() -{ +{SELFPARAM(); #ifdef SVQC if (self.punchangle != '0 0 0') { @@ -1005,18 +1062,20 @@ void PM_check_punch() } void PM_check_spider(void) -{ +{SELFPARAM(); #ifdef SVQC if (time >= self.spider_slowness) return; PHYS_MAXSPEED(self) *= 0.5; // half speed while slow from spider - self.stat_sv_airspeedlimit_nonqw *= 0.5; + PHYS_MAXAIRSPEED(self) *= 0.5; + PHYS_AIRSPEEDLIMIT_NONQW(self) *= 0.5; + PHYS_AIRSTRAFEACCELERATE(self) *= 0.5; #endif } // predict frozen movement, as frozen players CAN move in some cases void PM_check_frozen(void) -{ +{SELFPARAM(); if (!PHYS_FROZEN(self)) return; if (PHYS_DODGING_FROZEN @@ -1043,7 +1102,7 @@ void PM_check_frozen(void) } void PM_check_hitground() -{ +{SELFPARAM(); #ifdef SVQC if (IS_ONGROUND(self)) if (IS_PLAYER(self)) // no fall sounds for observers thank you very much @@ -1070,7 +1129,7 @@ void PM_check_hitground() } void PM_check_blocked(void) -{ +{SELFPARAM(); #ifdef SVQC if (!self.player_blocked) return; @@ -1084,7 +1143,7 @@ float speedaward_lastsent; float speedaward_lastupdate; #endif void PM_check_race(void) -{ +{SELFPARAM(); #ifdef SVQC if(!(g_cts || g_race)) return; @@ -1114,11 +1173,11 @@ void PM_check_race(void) } void PM_check_vortex(void) -{ +{SELFPARAM(); #ifdef SVQC // WEAPONTODO float xyspeed = vlen(vec2(self.velocity)); - if (self.weapon == WEP_VORTEX && WEP_CVAR(vortex, charge) && WEP_CVAR(vortex, charge_velocity_rate) && xyspeed > WEP_CVAR(vortex, charge_minspeed)) + if (self.weapon == WEP_VORTEX.m_id && 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)); @@ -1130,7 +1189,7 @@ void PM_check_vortex(void) } void PM_fly(float maxspd_mod) -{ +{SELFPARAM(); // noclipping or flying UNSET_ONGROUND(self); @@ -1151,7 +1210,7 @@ void PM_fly(float maxspd_mod) } void PM_swim(float maxspd_mod) -{ +{SELFPARAM(); // swimming UNSET_ONGROUND(self); @@ -1234,7 +1293,7 @@ void PM_swim(float maxspd_mod) } void PM_ladder(float maxspd_mod) -{ +{SELFPARAM(); // on a spawnfunc_func_ladder or swimming in spawnfunc_func_water UNSET_ONGROUND(self); @@ -1287,13 +1346,13 @@ void PM_ladder(float maxspd_mod) } void PM_jetpack(float maxspd_mod) -{ +{SELFPARAM(); //makevectors(self.v_angle.y * '0 1 0'); makevectors(self.v_angle); vector wishvel = v_forward * self.movement_x + v_right * self.movement_y; // add remaining speed as Z component - float maxairspd = PHYS_MAXAIRSPEED * max(1, maxspd_mod); + float maxairspd = PHYS_MAXAIRSPEED(self) * max(1, maxspd_mod); // fix speedhacks :P wishvel = normalize(wishvel) * min(1, vlen(wishvel) / maxairspd); // add the unused velocity as up component @@ -1403,18 +1462,18 @@ void PM_jetpack(float maxspd_mod) } void PM_walk(float buttons_prev, float maxspd_mod) -{ +{SELFPARAM(); if (!WAS_ONGROUND(self)) { #ifdef SVQC if (autocvar_speedmeter) - dprint(strcat("landing velocity: ", vtos(self.velocity), " (abs: ", ftos(vlen(self.velocity)), ")\n")); + LOG_TRACE(strcat("landing velocity: ", vtos(self.velocity), " (abs: ", ftos(vlen(self.velocity)), ")\n")); #endif if (self.lastground < time - 0.3) self.velocity *= (1 - PHYS_FRICTION_ONLAND); #ifdef SVQC if (self.jumppadcount > 1) - dprint(strcat(ftos(self.jumppadcount), "x jumppad combo\n")); + LOG_TRACE(strcat(ftos(self.jumppadcount), "x jumppad combo\n")); self.jumppadcount = 0; #endif } @@ -1488,7 +1547,7 @@ void PM_walk(float buttons_prev, float maxspd_mod) } void PM_air(float buttons_prev, float maxspd_mod) -{ +{SELFPARAM(); makevectors(self.v_angle.y * '0 1 0'); vector wishvel = v_forward * self.movement.x + v_right * self.movement.y; @@ -1502,7 +1561,7 @@ void PM_air(float buttons_prev, float maxspd_mod) if (pmove_waterjumptime <= 0) #endif { - float maxairspd = PHYS_MAXAIRSPEED * min(maxspd_mod, 1); + float maxairspd = PHYS_MAXAIRSPEED(self) * min(maxspd_mod, 1); // apply air speed limit float airaccelqw = PHYS_AIRACCEL_QW(self); @@ -1531,9 +1590,9 @@ void PM_air(float buttons_prev, float maxspd_mod) // log dv/dt = logaccel + logmaxspeed + log(1 - accelqw) (when fast) float strafity = IsMoveInDirection(self.movement, -90) + IsMoveInDirection(self.movement, +90); // if one is nonzero, other is always zero if (PHYS_MAXAIRSTRAFESPEED) - wishspeed = min(wishspeed, GeomLerp(PHYS_MAXAIRSPEED*maxspd_mod, strafity, PHYS_MAXAIRSTRAFESPEED*maxspd_mod)); - if (PHYS_AIRSTRAFEACCELERATE) - airaccel = GeomLerp(airaccel, strafity, PHYS_AIRSTRAFEACCELERATE*maxspd_mod); + wishspeed = min(wishspeed, GeomLerp(PHYS_MAXAIRSPEED(self)*maxspd_mod, strafity, PHYS_MAXAIRSTRAFESPEED*maxspd_mod)); + if (PHYS_AIRSTRAFEACCELERATE(self)) + airaccel = GeomLerp(airaccel, strafity, PHYS_AIRSTRAFEACCELERATE(self)*maxspd_mod); if (PHYS_AIRSTRAFEACCEL_QW(self)) airaccelqw = (((strafity > 0.5 ? PHYS_AIRSTRAFEACCEL_QW(self) : PHYS_AIRACCEL_QW(self)) >= 0) ? +1 : -1) @@ -1574,7 +1633,7 @@ bool IsFlying(entity a) } void PM_Main() -{ +{SELFPARAM(); int buttons = PHYS_INPUT_BUTTON_MASK(self); #ifdef CSQC self.items = getstati(STAT_ITEMS, 0, 24); @@ -1593,13 +1652,12 @@ void PM_Main() PM_ClientMovement_UpdateStatus(true); #endif - + #ifdef SVQC WarpZone_PlayerPhysics_FixVAngle(); #endif float maxspeed_mod = 1; - maxspeed_mod *= PM_check_keepaway(); maxspeed_mod *= PHYS_HIGHSPEED; #ifdef SVQC @@ -1685,6 +1743,8 @@ void PM_Main() self.disableclientprediction = 0; #endif + viewloc_PlayerPhysics(); + PM_check_spider(); PM_check_frozen(); @@ -1741,7 +1801,7 @@ void PM_Main() maxspeed_mod = self.spectatorspeed; } - float spd = max(PHYS_MAXSPEED(self), PHYS_MAXAIRSPEED) * maxspeed_mod; + float spd = max(PHYS_MAXSPEED(self), PHYS_MAXAIRSPEED(self)) * maxspeed_mod; if(self.speed != spd) { self.speed = spd; @@ -1751,6 +1811,17 @@ void PM_Main() stuffcmd(self, strcat("cl_sidespeed ", temps, "\n")); stuffcmd(self, strcat("cl_upspeed ", temps, "\n")); } + + if(self.stat_jumpspeedcap_min != PHYS_JUMPSPEEDCAP_MIN) + { + self.stat_jumpspeedcap_min = PHYS_JUMPSPEEDCAP_MIN; + stuffcmd(self, strcat("cl_jumpspeedcap_min ", PHYS_JUMPSPEEDCAP_MIN, "\n")); + } + if(self.stat_jumpspeedcap_max != PHYS_JUMPSPEEDCAP_MAX) + { + self.stat_jumpspeedcap_min = PHYS_JUMPSPEEDCAP_MAX; + stuffcmd(self, strcat("cl_jumpspeedcap_max ", PHYS_JUMPSPEEDCAP_MAX, "\n")); + } #endif if(PHYS_DEAD(self)) @@ -1797,7 +1868,7 @@ void PM_Main() RaceCarPhysics(); #endif - else if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY || self.movetype == MOVETYPE_FLY_WORLDONLY || (BUFFS(self) & BUFF_FLIGHT)) + else if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY || self.movetype == MOVETYPE_FLY_WORLDONLY || (BUFFS_STAT(self) & BUFF_FLIGHT.m_itemid)) PM_fly(maxspeed_mod); else if (self.waterlevel >= WATERLEVEL_SWIMMING) @@ -1844,11 +1915,11 @@ void SV_PlayerPhysics(void) #elif defined(CSQC) void CSQC_ClientMovement_PlayerMove_Frame(void) #endif -{ +{SELFPARAM(); PM_Main(); #ifdef CSQC - self.pmove_flags = + self.pmove_flags = ((self.flags & FL_DUCKED) ? PMF_DUCKED : 0) | (!(self.flags & FL_JUMPRELEASED) ? 0 : PMF_JUMP_HELD) | ((self.flags & FL_ONGROUND) ? PMF_ONGROUND : 0);