X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_physics.qc;h=c9531bbc630d45f2cca4bfc2aeb97e5b248e2072;hp=0051d8759a4d9a3a9384152d53e848d0a8427dc4;hb=580c768d0f2e32d2b545fa80c08c515aeb0ca67a;hpb=46c4e79a158eab8a239dd10e41d0fe24bbc24f38 diff --git a/qcsrc/server/cl_physics.qc b/qcsrc/server/cl_physics.qc index 0051d8759a..c9531bbc63 100644 --- a/qcsrc/server/cl_physics.qc +++ b/qcsrc/server/cl_physics.qc @@ -16,11 +16,13 @@ float sv_maxairstrafespeed; float sv_airstrafeaccel_qw; float sv_aircontrol; float sv_aircontrol_power; +float sv_aircontrol_penalty; float sv_warsowbunny_airforwardaccel; float sv_warsowbunny_accel; float sv_warsowbunny_topspeed; float sv_warsowbunny_turnaccel; float sv_warsowbunny_backtosideratio; +float sv_airspeedlimit_nonqw; .float ladder_time; .entity ladder_entity; @@ -31,6 +33,12 @@ float sv_warsowbunny_backtosideratio; .float wasFlying; .float spectatorspeed; +.float multijump_count; +.float multijump_ready; +.float prevjumpbutton; + +.float nexspeed; + /* ============= PlayerJump @@ -64,9 +72,58 @@ void PlayerJump (void) return; } + if (cvar("g_multijump")) + { + if (self.prevjumpbutton == FALSE && !(self.flags & FL_ONGROUND)) // jump button pressed this frame and we are in midair + self.multijump_ready = TRUE; // this is necessary to check that we released the jump button and pressed it again + else + self.multijump_ready = FALSE; + } + + if(!doublejump && self.multijump_ready && self.multijump_count < cvar("g_multijump") && self.velocity_z > cvar("g_multijump_speed")) + { + // doublejump = FALSE; // checked above in the if + if (cvar("g_multijump") > 0) + { + if (cvar("g_multijump_add") == 0) // in this case we make the z velocity == jumpvelocity + { + if (self.velocity_z < mjumpheight) + { + doublejump = TRUE; + self.velocity_z = 0; + } + } + else + doublejump = TRUE; + + if(doublejump) + { + if(self.movement_x != 0 || self.movement_y != 0) // don't remove all speed if player isnt pressing any movement keys + { + float curspeed; + vector wishvel, wishdir; + + curspeed = max( + vlen(vec2(self.velocity)), // current xy speed + vlen(vec2(antilag_takebackavgvelocity(self, max(self.lastteleporttime + sys_frametime, time - 0.25), time))) // average xy topspeed over the last 0.25 secs + ); + makevectors(self.v_angle_y * '0 1 0'); + wishvel = v_forward * self.movement_x + v_right * self.movement_y; + wishdir = normalize(wishvel); + + self.velocity_x = wishdir_x * curspeed; // allow "dodging" at a multijump + self.velocity_y = wishdir_y * curspeed; + // keep velocity_z unchanged! + } + self.multijump_count += 1; + } + } + self.multijump_ready = FALSE; // require releasing and pressing the jump button again for the next jump + } + if (!doublejump) - if (!(self.flags & FL_ONGROUND)) - return; + if (!(self.flags & FL_ONGROUND)) + return; if(!sv_pogostick) if (!(self.flags & FL_JUMPRELEASED)) @@ -317,8 +374,7 @@ void RaceCarPhysics() float mt; rigvel_z -= frametime * sv_gravity; // 4x gravity plays better - rigvel_xy = rigvel; - rigvel_xy_z = 0; + rigvel_xy = vec2(rigvel); if(g_bugrigs_planar_movement_car_jumping && !g_touchexplode) // touchexplode is a better way to handle collisions mt = MOVE_NORMAL; @@ -469,7 +525,9 @@ void CPM_PM_Aircontrol(vector wishdir, float wishspeed) if(dot > 0) // we can't change direction while slowing down { - k *= fabs(sv_aircontrol)*pow(dot, sv_aircontrol_power)*frametime; + k *= pow(dot, sv_aircontrol_power)*frametime; + xyspeed = max(0, xyspeed - sv_aircontrol_penalty * sqrt(max(0, 1 - dot*dot)) * k/32); + k *= sv_aircontrol; self.velocity = normalize(self.velocity * xyspeed + wishdir * k); } @@ -477,12 +535,17 @@ void CPM_PM_Aircontrol(vector wishdir, float wishspeed) 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; @@ -503,12 +566,14 @@ void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float acce vel_straight = self.velocity * wishdir; vel_z = self.velocity_z; - vel_xy = self.velocity - vel_z * '0 0 1'; + vel_xy = vec2(self.velocity); vel_perpend = vel_xy - vel_straight * wishdir; 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) @@ -633,7 +698,6 @@ void race_send_speedaward_alltimebest(float msg) string GetMapname(void); float speedaward_lastupdate; float speedaward_lastsent; -var float autocvar_g_movement_highspeed = 1; void SV_PlayerPhysics() { local vector wishvel, wishdir, v; @@ -642,13 +706,14 @@ void SV_PlayerPhysics() float buttons_prev; float not_allowed_to_move; 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()) @@ -886,6 +951,14 @@ void SV_PlayerPhysics() if(self.classname == "player") { + if(self.flags & FL_ONGROUND) + { + if (cvar("g_multijump") > 0) + self.multijump_count = 0; + else + self.multijump_count = -2; // the cvar value for infinite jumps is -1, so this needs to be smaller + } + if (self.BUTTON_JUMP) PlayerJump (); else @@ -893,6 +966,7 @@ void SV_PlayerPhysics() if (self.waterlevel == WATERLEVEL_SWIMMING) CheckWaterJump (); + self.prevjumpbutton = self.BUTTON_JUMP; } if (self.flags & FL_WATERJUMP ) @@ -924,7 +998,7 @@ void SV_PlayerPhysics() 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) { @@ -947,7 +1021,7 @@ void SV_PlayerPhysics() 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) { @@ -990,7 +1064,7 @@ void SV_PlayerPhysics() 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)) @@ -1150,7 +1224,7 @@ void SV_PlayerPhysics() 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 { @@ -1194,8 +1268,13 @@ void SV_PlayerPhysics() // CPM if(sv_airstopaccelerate) - if(self.velocity * wishdir < 0) - airaccel = sv_airstopaccelerate*maxspd_mod; + { + vector curdir; + curdir = self.velocity; + curdir_z = 0; + curdir = normalize(curdir); + airaccel = airaccel + (sv_airstopaccelerate*maxspd_mod - airaccel) * max(0, -(curdir * wishdir)); + } // note that for straight forward jumping: // step = accel * frametime * wishspeed0; // accel = bound(0, wishspeed - vel_xy_current, step) * accelqw + step * (1 - accelqw); @@ -1216,7 +1295,7 @@ void SV_PlayerPhysics() 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); @@ -1246,6 +1325,15 @@ void SV_PlayerPhysics() } } } + + float f; + float xyspeed; + f = cvar("g_balance_nex_velocitydependent_falloff_factor"); + xyspeed = vlen('1 0 0' * self.velocity_x + '0 1 0' * self.velocity_y); + if(xyspeed > self.nexspeed) + self.nexspeed = min(xyspeed, cvar("g_balance_nex_velocitydependent_maxspeed")); + else + self.nexspeed = (1 - f) * self.nexspeed; :end if(self.flags & FL_ONGROUND) self.lastground = time;