cl.cmd.cursor_fraction = CL_SelectTraceLine(cl.cmd.cursor_start, cl.cmd.cursor_end, cl.cmd.cursor_impact, cl.cmd.cursor_normal, &cl.cmd.cursor_entitynumber, (chase_active.integer || cl.intermission) ? &cl.entities[cl.playerentity].render : NULL);
}
-typedef enum waterlevel_e
-{
- WATERLEVEL_NONE,
- WATERLEVEL_WETFEET,
- WATERLEVEL_SWIMMING,
- WATERLEVEL_SUBMERGED
-}
-waterlevel_t;
-
-typedef struct cl_clientmovement_state_s
-{
- // position
- vec3_t origin;
- vec3_t velocity;
- // current bounding box (different if crouched vs standing)
- vec3_t mins;
- vec3_t maxs;
- // currently on the ground
- qboolean onground;
- // currently crouching
- qboolean crouched;
- // what kind of water (SUPERCONTENTS_LAVA for instance)
- int watertype;
- // how deep
- waterlevel_t waterlevel;
- // weird hacks when jumping out of water
- // (this is in seconds and counts down to 0)
- float waterjumptime;
-
- // user command
- usercmd_t cmd;
-}
-cl_clientmovement_state_t;
-
#define NUMOFFSETS 27
static vec3_t offsets[NUMOFFSETS] =
{
if (trace.fraction == 1)
break;
- //if (trace.plane.normal[2] > 0.7)
- // s->onground = true;
+ // this is only really needed for nogravityonground combined with gravityunaffectedbyticrate
+ // <LordHavoc> I'm pretty sure I commented it out solely because it seemed redundant
+ // this got commented out in a change that supposedly makes the code match QW better
+ // so if this is broken, maybe put it in an if(cls.protocol != PROTOCOL_QUAKEWORLD) block
+ if (trace.plane.normal[2] > 0.7)
+ s->onground = true;
t -= t * trace.fraction;
accelspeed = min(cl.movevars_accelerate * s->cmd.frametime * wishspeed, addspeed);
VectorMA(s->velocity, accelspeed, wishdir, s->velocity);
}
- if(cl.moveflags & MOVEFLAG_NOGRAVITYONGROUND)
- gravity = 0;
- else
- gravity = cl.movevars_gravity * cl.movevars_entgravity * s->cmd.frametime;
- if(cl.moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
- s->velocity[2] -= gravity * 0.5f;
- else
- s->velocity[2] -= gravity;
+ gravity = cl.movevars_gravity * cl.movevars_entgravity * s->cmd.frametime;
+ if(!(cl.moveflags & MOVEFLAG_NOGRAVITYONGROUND))
+ {
+ if(cl.moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
+ s->velocity[2] -= gravity * 0.5f;
+ else
+ s->velocity[2] -= gravity;
+ }
if (cls.protocol == PROTOCOL_QUAKEWORLD)
s->velocity[2] = 0;
if (VectorLength2(s->velocity))
CL_ClientMovement_Move(s);
- if(cl.moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
- s->velocity[2] -= gravity * 0.5f;
+ if(!(cl.moveflags & MOVEFLAG_NOGRAVITYONGROUND) || !s->onground)
+ {
+ if(cl.moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
+ s->velocity[2] -= gravity * 0.5f;
+ }
}
else
{
else
s->velocity[2] -= gravity;
CL_ClientMovement_Move(s);
- if(cl.moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
- s->velocity[2] -= gravity * 0.5f;
+ if(!(cl.moveflags & MOVEFLAG_NOGRAVITYONGROUND) || !s->onground)
+ {
+ if(cl.moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
+ s->velocity[2] -= gravity * 0.5f;
+ }
}
}
cl.movevars_aircontrol_power = 2; // CPMA default
}
+void CL_ClientMovement_PlayerMove_Frame(cl_clientmovement_state_t *s)
+{
+ // if a move is more than 50ms, do it as two moves (matching qwsv)
+ //Con_Printf("%i ", s.cmd.msec);
+ if(s->cmd.frametime > 0.0005)
+ {
+ if (s->cmd.frametime > 0.05)
+ {
+ s->cmd.frametime /= 2;
+ CL_ClientMovement_PlayerMove(s);
+ }
+ CL_ClientMovement_PlayerMove(s);
+ }
+ else
+ {
+ // we REALLY need this handling to happen, even if the move is not executed
+ if (!s->cmd.jump)
+ s->cmd.canjump = true;
+ }
+}
+
void CL_ClientMovement_Replay(void)
{
int i;
double totalmovemsec;
cl_clientmovement_state_t s;
+ VectorCopy(cl.mvelocity[0], cl.movement_velocity);
+
if (cl.movement_predicted && !cl.movement_replay)
return;
if (i < CL_MAX_USERCMDS - 1)
s.cmd.canjump = cl.movecmd[i+1].canjump;
- // if a move is more than 50ms, do it as two moves (matching qwsv)
- //Con_Printf("%i ", s.cmd.msec);
- if(s.cmd.frametime > 0.0005)
- {
- if (s.cmd.frametime > 0.05)
- {
- s.cmd.frametime /= 2;
- CL_ClientMovement_PlayerMove(&s);
- }
- CL_ClientMovement_PlayerMove(&s);
- }
- else
- {
- // we REALLY need this handling to happen, even if the move is not executed
- if (!s.cmd.jump)
- s.cmd.canjump = true;
- }
+ CL_ClientMovement_PlayerMove_Frame(&s);
+
cl.movecmd[i].canjump = s.cmd.canjump;
}
//Con_Printf("\n");
s.cmd = cl.movecmd[0];
}
- if (cls.demoplayback) // for bob, speedometer
- VectorCopy(cl.mvelocity[0], cl.movement_velocity);
- else
+ if (!cls.demoplayback) // for bob, speedometer
{
cl.movement_replay = false;
// update the interpolation target position and velocity
if (s.onground)
cl.onground = true;
}
-
- // react to onground state changes (for gun bob)
- if (cl.onground)
- {
- if (!cl.oldonground)
- cl.hitgroundtime = cl.movecmd[0].time;
- cl.lastongroundtime = cl.movecmd[0].time;
- }
- cl.oldonground = cl.onground;
}
static void QW_MSG_WriteDeltaUsercmd(sizebuf_t *buf, usercmd_t *from, usercmd_t *to)