From f9a384ffd49efafa88f14d364db766f4e5b065f2 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 28 Apr 2012 14:53:15 +0900 Subject: [PATCH] Make simple gravity acceleration framerate independent. Now it doesn't matter if you get 22 fps or 72, you jump the same height, which actually happens to be slightly higher than the previous 72fps jump. Effectively, you jump the height you would if you got infinite fps ;) --- include/qw/pmove.h | 1 + nq/include/server.h | 1 + nq/include/sv_progs.h | 1 + nq/source/sv_cl_phys.c | 4 +++- nq/source/sv_phys.c | 32 ++++++++++++++++++++++++++++---- qw/include/server.h | 1 + qw/include/sv_progs.h | 1 + qw/source/pmove.c | 9 ++++++++- qw/source/sv_phys.c | 32 ++++++++++++++++++++++++++++---- 9 files changed, 72 insertions(+), 10 deletions(-) diff --git a/include/qw/pmove.h b/include/qw/pmove.h index 7b8613853..285513a75 100644 --- a/include/qw/pmove.h +++ b/include/qw/pmove.h @@ -60,6 +60,7 @@ typedef struct { float waterjumptime; qboolean dead; qboolean flying; + qboolean add_grav; int spectator; // world state diff --git a/nq/include/server.h b/nq/include/server.h index 07dca7c94..f33c829cf 100644 --- a/nq/include/server.h +++ b/nq/include/server.h @@ -273,6 +273,7 @@ int SV_FlyMove (edict_t *ent, float time, struct trace_s *steptrace); void SV_CheckVelocity (edict_t *ent); qboolean SV_RunThink (edict_t *ent); void SV_AddGravity (edict_t *ent); +void SV_FinishGravity (edict_t *ent, vec3_t move); void SV_Physics_Toss (edict_t *ent); void SV_Physics_Client (edict_t *ent, int num); void SV_Physics (void); diff --git a/nq/include/sv_progs.h b/nq/include/sv_progs.h index f90b795b6..e1b8d4e4a 100644 --- a/nq/include/sv_progs.h +++ b/nq/include/sv_progs.h @@ -223,6 +223,7 @@ typedef struct sv_data_s { entity_state_t state; byte alpha; qboolean sendinterval; + qboolean add_grav; } sv_data_t; #define SVdata(e) ((sv_data_t *) ((e)->edata)) diff --git a/nq/source/sv_cl_phys.c b/nq/source/sv_cl_phys.c index 9dbae0c61..0801d0693 100644 --- a/nq/source/sv_cl_phys.c +++ b/nq/source/sv_cl_phys.c @@ -220,7 +220,7 @@ SV_TryUnstick (edict_t *ent, vec3_t oldvel) /* SV_WalkMove - Used by only players + Used only by players */ static void SV_WalkMove (edict_t *ent) @@ -319,6 +319,8 @@ SV_Physics_Client (edict_t *ent, int num) *sv_globals.self = EDICT_TO_PROG (&sv_pr_state, ent); PR_ExecuteProgram (&sv_pr_state, sv_funcs.PlayerPreThink); + SVdata (ent)->add_grav = false; + // do a move SV_CheckVelocity (ent); diff --git a/nq/source/sv_phys.c b/nq/source/sv_phys.c index acc24ba00..f6a9e219f 100644 --- a/nq/source/sv_phys.c +++ b/nq/source/sv_phys.c @@ -252,6 +252,10 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) VectorMultAdd (SVvector (ent, origin), time_left, SVvector (ent, velocity), end); + if (SVdata (ent)->add_grav) { + SVdata (ent)->add_grav = false; + SV_FinishGravity (ent, end); + } trace = SV_Move (SVvector (ent, origin), SVvector (ent, mins), SVvector (ent, maxs), end, false, ent); @@ -342,13 +346,27 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) void SV_AddGravity (edict_t *ent) { - float ent_gravity; + float ent_grav; if (sv_fields.gravity != -1 && SVfloat (ent, gravity)) - ent_gravity = SVfloat (ent, gravity); + ent_grav = SVfloat (ent, gravity); else - ent_gravity = 1.0; - SVvector (ent, velocity)[2] -= ent_gravity * sv_gravity->value * sv_frametime; + ent_grav = 1.0; + SVvector (ent, velocity)[2] -= ent_grav * sv_gravity->value * sv_frametime; + SVdata (ent)->add_grav = true; +} + +void +SV_FinishGravity (edict_t *ent, vec3_t move) +{ + float ent_grav; + + if (sv_fields.gravity != -1 && SVfloat (ent, gravity)) + ent_grav = SVfloat (ent, gravity); + else + ent_grav = 1.0; + ent_grav *= sv_gravity->value; + move[2] += ent_grav * sv_frametime * sv_frametime / 2; } /* PUSHMOVE */ @@ -551,6 +569,7 @@ SV_PushMove (edict_t *pusher, float movetime) } VectorScale (SVvector (pusher, velocity), movetime, move); + //FIXME finish gravity VectorScale (SVvector (pusher, avelocity), movetime, amove); if (SV_Push (pusher, move, amove)) @@ -697,6 +716,10 @@ SV_Physics_Toss (edict_t *ent) // move origin VectorScale (SVvector (ent, velocity), sv_frametime, move); + if (SVdata (ent)->add_grav) { + SVdata (ent)->add_grav = false; + SV_FinishGravity (ent, move); + } trace = SV_PushEntity (ent, move); if (trace.fraction == 1) return; @@ -784,6 +807,7 @@ SV_RunEntity (edict_t *ent) return; SVfloat (ent, lastruntime) = (float) sv.time; } + SVdata (ent)->add_grav = false; switch ((int) SVfloat (ent, movetype)) { case MOVETYPE_PUSH: diff --git a/qw/include/server.h b/qw/include/server.h index 50d5212bf..b605d4c81 100644 --- a/qw/include/server.h +++ b/qw/include/server.h @@ -530,6 +530,7 @@ void SV_ProgStartFrame (void); void SV_Physics (void); void SV_CheckVelocity (struct edict_s *ent); void SV_AddGravity (struct edict_s *ent); +void SV_FinishGravity (struct edict_s *ent, vec3_t move); qboolean SV_RunThink (struct edict_s *ent); void SV_Physics_Toss (struct edict_s *ent); void SV_RunNewmis (void); diff --git a/qw/include/sv_progs.h b/qw/include/sv_progs.h index e78da841f..ca96f7de5 100644 --- a/qw/include/sv_progs.h +++ b/qw/include/sv_progs.h @@ -206,6 +206,7 @@ typedef struct sv_data_s { link_t area; ///< linked to a division node or leaf edict_leaf_t *leafs; entity_state_t state; + qboolean add_grav; } sv_data_t; #define SVdata(e) ((sv_data_t *) ((e)->edata)) diff --git a/qw/source/pmove.c b/qw/source/pmove.c index 6c8abfde0..4a0a3c175 100644 --- a/qw/source/pmove.c +++ b/qw/source/pmove.c @@ -131,7 +131,11 @@ PM_FlyMove (void) break; VectorMultAdd (pmove.origin, time_left, pmove.velocity, end); - + if (pmove.add_grav) { + pmove.add_grav = false; + end[2] += movevars.entgravity * movevars.gravity * + frametime * frametime / 2; + } trace = PM_PlayerMove (pmove.origin, end); if (trace.startsolid || trace.allsolid) { // entity is trapped in @@ -508,12 +512,14 @@ PM_AirMove (void) VectorScale (wishvel, movevars.maxspeed / wishspeed, wishvel); wishspeed = movevars.maxspeed; } + pmove.add_grav = false; if (onground != -1) { pmove.velocity[2] = 0; PM_Accelerate (wishdir, wishspeed, movevars.accelerate); pmove.velocity[2] -= movevars.entgravity * movevars.gravity * frametime; + pmove.add_grav = true; PM_GroundMove (); } else if (pmove.flying) { PM_AirAccelerate (wishdir, wishspeed, movevars.accelerate); @@ -525,6 +531,7 @@ PM_AirMove (void) // add gravity pmove.velocity[2] -= movevars.entgravity * movevars.gravity * frametime; + pmove.add_grav = true; if (!PM_FlyMove ()) { // the move didn't get blocked diff --git a/qw/source/sv_phys.c b/qw/source/sv_phys.c index acc24ba00..f6a9e219f 100644 --- a/qw/source/sv_phys.c +++ b/qw/source/sv_phys.c @@ -252,6 +252,10 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) VectorMultAdd (SVvector (ent, origin), time_left, SVvector (ent, velocity), end); + if (SVdata (ent)->add_grav) { + SVdata (ent)->add_grav = false; + SV_FinishGravity (ent, end); + } trace = SV_Move (SVvector (ent, origin), SVvector (ent, mins), SVvector (ent, maxs), end, false, ent); @@ -342,13 +346,27 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) void SV_AddGravity (edict_t *ent) { - float ent_gravity; + float ent_grav; if (sv_fields.gravity != -1 && SVfloat (ent, gravity)) - ent_gravity = SVfloat (ent, gravity); + ent_grav = SVfloat (ent, gravity); else - ent_gravity = 1.0; - SVvector (ent, velocity)[2] -= ent_gravity * sv_gravity->value * sv_frametime; + ent_grav = 1.0; + SVvector (ent, velocity)[2] -= ent_grav * sv_gravity->value * sv_frametime; + SVdata (ent)->add_grav = true; +} + +void +SV_FinishGravity (edict_t *ent, vec3_t move) +{ + float ent_grav; + + if (sv_fields.gravity != -1 && SVfloat (ent, gravity)) + ent_grav = SVfloat (ent, gravity); + else + ent_grav = 1.0; + ent_grav *= sv_gravity->value; + move[2] += ent_grav * sv_frametime * sv_frametime / 2; } /* PUSHMOVE */ @@ -551,6 +569,7 @@ SV_PushMove (edict_t *pusher, float movetime) } VectorScale (SVvector (pusher, velocity), movetime, move); + //FIXME finish gravity VectorScale (SVvector (pusher, avelocity), movetime, amove); if (SV_Push (pusher, move, amove)) @@ -697,6 +716,10 @@ SV_Physics_Toss (edict_t *ent) // move origin VectorScale (SVvector (ent, velocity), sv_frametime, move); + if (SVdata (ent)->add_grav) { + SVdata (ent)->add_grav = false; + SV_FinishGravity (ent, move); + } trace = SV_PushEntity (ent, move); if (trace.fraction == 1) return; @@ -784,6 +807,7 @@ SV_RunEntity (edict_t *ent) return; SVfloat (ent, lastruntime) = (float) sv.time; } + SVdata (ent)->add_grav = false; switch ((int) SVfloat (ent, movetype)) { case MOVETYPE_PUSH: