float sv_warsowbunny_topspeed;
float sv_warsowbunny_turnaccel;
float sv_warsowbunny_backtosideratio;
+float sv_airspeedlimit_nonqw;
.float ladder_time;
.entity ladder_entity;
void PlayerJump (void)
{
float mjumpheight;
+ float doublejump;
+
+ doublejump = FALSE;
+ if (sv_doublejump)
+ {
+ 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.7)
+ doublejump = TRUE;
+ }
mjumpheight = cvar("sv_jumpvelocity");
if (self.waterlevel >= WATERLEVEL_SWIMMING)
return;
}
+ if (!doublejump)
if (!(self.flags & FL_ONGROUND))
return;
mjumpheight = mjumpheight * cvar("g_minstagib_speed_jumpheight");
}
+ // sv_jumpspeedcap_min/sv_jumpspeedcap_max act as baseline
+ // velocity bounds. Final velocity is bound between (jumpheight *
+ // min + jumpheight) and (jumpheight * max + jumpheight);
+
if(cvar_string("sv_jumpspeedcap_min") != "")
- self.velocity_z = max(cvar("sv_jumpvelocity") * cvar("sv_jumpspeedcap_min"), self.velocity_z);
- if(cvar_string("sv_jumpspeedcap_max") != "") {
+ {
+ float minjumpspeed;
+
+ minjumpspeed = mjumpheight * cvar("sv_jumpspeedcap_min");
+
+ if (self.velocity_z < minjumpspeed)
+ mjumpheight += minjumpspeed - self.velocity_z;
+ }
+
+ if(cvar_string("sv_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 && cvar("sv_jumpspeedcap_max_disable_on_ramps")) {
- // don't do jump speedcaps on ramps to preserve old xonotic ramjump style
- //print("Trace plane normal z: ", ftos(trace_plane_normal_z), ", disabling speed cap!\n");
+
+ if(!(trace_fraction < 1 && trace_plane_normal_z < 0.98 && cvar("sv_jumpspeedcap_max_disable_on_ramps")))
+ {
+ float maxjumpspeed;
+
+ maxjumpspeed = mjumpheight * cvar("sv_jumpspeedcap_max");
+
+ if (self.velocity_z > maxjumpspeed)
+ mjumpheight -= self.velocity_z - maxjumpspeed;
}
- else
- self.velocity_z = min(cvar("sv_jumpvelocity") * cvar("sv_jumpspeedcap_max"), self.velocity_z) + trace_ent.velocity_z;
}
if(!(self.lastflags & FL_ONGROUND))
self.velocity_z = zspeed;
}
+float AdjustAirAccelQW(float accelqw, float factor)
+{
+ return copysign(bound(0.000001, 1 - (1 - fabs(accelqw)) * factor, 1), accelqw);
+}
+
// example config for alternate speed clamping:
// sv_airaccel_qw 0.8
// sv_airaccel_sideways_friction 0
// prvm_globalset server speedclamp_mode 1
// (or 2)
-void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float accel, float accelqw, float sidefric)
+void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float accel, float accelqw, float sidefric, float speedlimit)
{
float vel_straight;
float vel_z;
step = accel * frametime * wishspeed0;
vel_xy_current = vlen(vel_xy);
+ if(speedlimit)
+ accelqw = AdjustAirAccelQW(accelqw, (speedlimit - bound(wishspeed, vel_xy_current, speedlimit)) / max(1, speedlimit - wishspeed));
vel_xy_forward = vel_xy_current + bound(0, wishspeed - vel_xy_current, step) * accelqw + step * (1 - accelqw);
vel_xy_backward = vel_xy_current - bound(0, wishspeed + vel_xy_current, step) * accelqw - step * (1 - accelqw);
if(vel_xy_backward < 0)
string GetMapname(void);
float speedaward_lastupdate;
float speedaward_lastsent;
-.float jumppadusetime;
-var float autocvar_g_movement_highspeed = 1;
void SV_PlayerPhysics()
{
local vector wishvel, wishdir, v;
string c;
// fix physics stats for g_movement_highspeed
- self.stat_sv_airaccel_qw = copysign(bound(0, 1-(1-fabs(sv_airaccel_qw))*autocvar_g_movement_highspeed, 1), sv_airaccel_qw);
+ self.stat_sv_airaccel_qw = AdjustAirAccelQW(sv_airaccel_qw, autocvar_g_movement_highspeed);
if(sv_airstrafeaccel_qw)
- self.stat_sv_airstrafeaccel_qw = copysign(bound(0.001, 1-(1-fabs(sv_airstrafeaccel_qw))*autocvar_g_movement_highspeed, 1), sv_airstrafeaccel_qw);
+ self.stat_sv_airstrafeaccel_qw = AdjustAirAccelQW(sv_airstrafeaccel_qw, autocvar_g_movement_highspeed);
else
self.stat_sv_airstrafeaccel_qw = 0;
+ self.stat_sv_airspeedlimit_nonqw = sv_airspeedlimit_nonqw * autocvar_g_movement_highspeed;
if(self.PlayerPhysplug)
if(self.PlayerPhysplug())
if(self.classname == "player")
{
- if(sv_doublejump && time - self.jumppadusetime > 2 * sys_frametime)
- {
- tracebox(self.origin + '0 0 0.01', self.mins, self.maxs, self.origin - '0 0 0.01', MOVE_NORMAL, self);
- self.flags &~= FL_ONGROUND;
- if(trace_fraction < 1 && trace_plane_normal_z > 0.7)
- self.flags |= FL_ONGROUND;
- }
-
if (self.BUTTON_JUMP)
PlayerJump ();
else
if (wishspeed > sv_maxspeed*maxspd_mod)
wishspeed = sv_maxspeed*maxspd_mod;
if (time >= self.teleport_time)
- PM_Accelerate(wishdir, wishspeed, wishspeed, sv_accelerate*maxspd_mod, 1, 0);
+ PM_Accelerate(wishdir, wishspeed, wishspeed, sv_accelerate*maxspd_mod, 1, 0, 0);
}
else if (self.waterlevel >= WATERLEVEL_SWIMMING)
{
self.velocity = self.velocity * (1 - frametime * sv_friction);
// water acceleration
- PM_Accelerate(wishdir, wishspeed, wishspeed, sv_accelerate*maxspd_mod, 1, 0);
+ PM_Accelerate(wishdir, wishspeed, wishspeed, sv_accelerate*maxspd_mod, 1, 0, 0);
}
else if (time < self.ladder_time)
{
if (time >= self.teleport_time)
{
// water acceleration
- PM_Accelerate(wishdir, wishspeed, wishspeed, sv_accelerate*maxspd_mod, 1, 0);
+ PM_Accelerate(wishdir, wishspeed, wishspeed, sv_accelerate*maxspd_mod, 1, 0, 0);
}
}
else if ((self.items & IT_JETPACK) && self.BUTTON_HOOK && (!cvar("g_jetpack_fuel") || self.ammo_fuel >= 0.01 || self.items & IT_UNLIMITED_WEAPON_AMMO))
if (self.crouch)
wishspeed = wishspeed * 0.5;
if (time >= self.teleport_time)
- PM_Accelerate(wishdir, wishspeed, wishspeed, sv_accelerate*maxspd_mod, 1, 0);
+ PM_Accelerate(wishdir, wishspeed, wishspeed, sv_accelerate*maxspd_mod, 1, 0, 0);
}
else
{
if(sv_warsowbunny_turnaccel && accelerating && self.movement_y == 0 && self.movement_x != 0)
PM_AirAccelerate(wishdir, wishspeed);
else
- PM_Accelerate(wishdir, wishspeed, wishspeed0, airaccel, airaccelqw, sv_airaccel_sideways_friction / maxairspd);
+ PM_Accelerate(wishdir, wishspeed, wishspeed0, airaccel, airaccelqw, sv_airaccel_sideways_friction / maxairspd, self.stat_sv_airspeedlimit_nonqw);
if(sv_aircontrol)
CPM_PM_Aircontrol(wishdir, wishspeed2);