X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_physics.qc;h=79087eb8a366e9a5ed91c67de9024d058ef3140f;hb=44954e3827788e2d9adba9c16c72792a5fbfe10b;hp=83c438b47600f7b07bd8fbf3fe54e99f2c992d15;hpb=b067640a0a39aa413ec687818cc402b9562d3a28;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/cl_physics.qc b/qcsrc/server/cl_physics.qc index 83c438b47..79087eb8a 100644 --- a/qcsrc/server/cl_physics.qc +++ b/qcsrc/server/cl_physics.qc @@ -34,7 +34,15 @@ void PlayerJump (void) { 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; + + // we MUST clip velocity here! + float f; + f = self.velocity * trace_plane_normal; + if(f < 0) + self.velocity -= f * trace_plane_normal; + } } mjumpheight = autocvar_sv_jumpvelocity; @@ -104,7 +112,7 @@ void PlayerJump (void) if (!(self.flags & FL_ONGROUND)) return; - if(!sv_pogostick) + if(self.cvar_cl_movement_track_canjump) if (!(self.flags & FL_JUMPRELEASED)) return; @@ -163,7 +171,7 @@ void PlayerJump (void) if (self.crouch) setanim(self, self.anim_duckjump, FALSE, TRUE, TRUE); - else + else if (self.animstate_startframe != self.anim_melee_x || (self.animstate_startframe == self.anim_melee_x && time - self.animstate_starttime >= 21/20)) // jump animation shouldn't override melee until we have animation blending (or until the anim finished, 21/20 = numframes/fps) setanim(self, self.anim_jump, FALSE, TRUE, TRUE); if(g_jump_grunt) @@ -172,10 +180,9 @@ void PlayerJump (void) self.restart_jump = -1; // restart jump anim next time // value -1 is used to not use the teleport bit (workaround for tiny hitch when re-jumping) } - void CheckWaterJump() { - local vector start, end; + vector start, end; // check for a jump-out-of-water makevectors (self.angles); @@ -200,7 +207,26 @@ void CheckWaterJump() return; } } -}; +} +void CheckPlayerJump() +{ + if(self.flags & FL_ONGROUND) + { + if (autocvar_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 + self.flags |= FL_JUMPRELEASED; + + if (self.waterlevel == WATERLEVEL_SWIMMING) + CheckWaterJump (); + self.prevjumpbutton = self.BUTTON_JUMP; +} float racecar_angle(float forward, float down) { @@ -671,8 +697,8 @@ float speedaward_lastupdate; float speedaward_lastsent; void SV_PlayerPhysics() { - local vector wishvel, wishdir, v; - local float wishspeed, f, maxspd_mod, spd, maxairspd, airaccel, swampspd_mod, buttons; + vector wishvel, wishdir, v; + float wishspeed, f, maxspd_mod, spd, maxairspd, airaccel, swampspd_mod, buttons; string temps; float buttons_prev; float not_allowed_to_move; @@ -706,6 +732,7 @@ void SV_PlayerPhysics() maxspd_mod *= autocvar_g_movement_highspeed; // fix physics stats for g_movement_highspeed + // TODO maybe rather use maxairspeed? needs testing 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); @@ -855,6 +882,10 @@ void SV_PlayerPhysics() swampspd_mod = self.swamp_slowdown; //cvar("g_balance_swamp_moverate"); } + // conveyors: first fix velocity + if(self.conveyor.state) + self.velocity -= self.conveyor.movedir; + if(self.classname != "player") { maxspd_mod = autocvar_sv_spectator_speed_multiplier; @@ -904,6 +935,7 @@ void SV_PlayerPhysics() } if(self.flags & FL_ONGROUND) + if(self.classname == "player") // no fall sounds for observers thank you very much if(self.wasFlying) { self.wasFlying = 0; @@ -929,24 +961,7 @@ void SV_PlayerPhysics() self.wasFlying = 1; if(self.classname == "player") - { - if(self.flags & FL_ONGROUND) - { - if (autocvar_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 - self.flags |= FL_JUMPRELEASED; - - if (self.waterlevel == WATERLEVEL_SWIMMING) - CheckWaterJump (); - self.prevjumpbutton = self.BUTTON_JUMP; - } + CheckPlayerJump(); if (self.flags & FL_WATERJUMP ) { @@ -962,7 +977,7 @@ void SV_PlayerPhysics() { RaceCarPhysics(); } - else if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY) + else if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY || self.movetype == MOVETYPE_FLY_WORLDONLY) { // noclipping or flying self.flags &~= FL_ONGROUND; @@ -1200,6 +1215,28 @@ void SV_PlayerPhysics() self.velocity = self.velocity * f; else self.velocity = '0 0 0'; + /* + Mathematical analysis time! + + Our goal is to invert this mess. + + For the two cases we get: + v = v0 * (1 - frametime * (autocvar_sv_stopspeed / v0) * autocvar_sv_friction) + = v0 - frametime * autocvar_sv_stopspeed * autocvar_sv_friction + v0 = v + frametime * autocvar_sv_stopspeed * autocvar_sv_friction + and + v = v0 * (1 - frametime * autocvar_sv_friction) + v0 = v / (1 - frametime * autocvar_sv_friction) + + These cases would be chosen ONLY if: + v0 < autocvar_sv_stopspeed + v + frametime * autocvar_sv_stopspeed * autocvar_sv_friction < autocvar_sv_stopspeed + v < autocvar_sv_stopspeed * (1 - frametime * autocvar_sv_friction) + and, respectively: + v0 >= autocvar_sv_stopspeed + v / (1 - frametime * autocvar_sv_friction) >= autocvar_sv_stopspeed + v >= autocvar_sv_stopspeed * (1 - frametime * autocvar_sv_friction) + */ } // acceleration @@ -1328,6 +1365,10 @@ void SV_PlayerPhysics() if(self.flags & FL_ONGROUND) self.lastground = time; + // conveyors: then break velocity again + if(self.conveyor.state) + self.velocity += self.conveyor.movedir; + self.lastflags = self.flags; self.lastclassname = self.classname; -}; +}