bottom[1] = top[1];
bottom[2] = top[2] - 160;
- tr = SV_Move (top, vec3_origin, vec3_origin, bottom, MOVE_NOMONSTERS, host_client->edict, SUPERCONTENTS_SOLID);
+ tr = SV_TraceLine(top, bottom, MOVE_NOMONSTERS, host_client->edict, SUPERCONTENTS_SOLID);
// if looking at a wall, leave ideal the way is was
if (tr.startsolid)
return;
start[2] = host_client->edict->fields.server->origin[2] + host_client->edict->fields.server->mins[2];
stop[2] = start[2] - 34;
- trace = SV_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, host_client->edict, SV_GenericHitSuperContentsMask(host_client->edict));
+ trace = SV_TraceLine(start, stop, MOVE_NOMONSTERS, host_client->edict, SV_GenericHitSuperContentsMask(host_client->edict));
if (trace.fraction == 1.0)
friction = sv_friction.value*sv_edgefriction.value;
host_client->edict->fields.server->velocity[i] += accelspeed*wishdir[i];
}
+extern cvar_t sv_gameplayfix_q2airaccelerate;
void SV_AirAccelerate (vec3_t wishveloc)
{
int i;
addspeed = wishspd - currentspeed;
if (addspeed <= 0)
return;
- accelspeed = (sv_airaccelerate.value < 0 ? sv_accelerate.value : sv_airaccelerate.value)*wishspeed * sv.frametime;
+ accelspeed = (sv_airaccelerate.value < 0 ? sv_accelerate.value : sv_airaccelerate.value)*(sv_gameplayfix_q2airaccelerate.integer ? wishspd : wishspeed) * sv.frametime;
if (accelspeed > addspeed)
accelspeed = addspeed;
if (host_client->edict->fields.server->movetype == MOVETYPE_NONE)
return;
- onground = (int)host_client->edict->fields.server->flags & FL_ONGROUND;
+ onground = ((int)host_client->edict->fields.server->flags & FL_ONGROUND) != 0;
DropPunchAngle ();
// (we have to buffer the moves because of old ones being repeated)
if (sv_numreadmoves < CL_MAX_USERCMDS)
sv_readmoves[sv_numreadmoves++] = *move;
+
+ // movement packet loss tracking
+ if(move->sequence)
+ {
+ if(move->sequence > host_client->movement_highestsequence_seen)
+ {
+ if(host_client->movement_highestsequence_seen)
+ {
+ // mark moves in between as lost
+ if(move->sequence - host_client->movement_highestsequence_seen - 1 < NETGRAPH_PACKETS)
+ for(i = host_client->movement_highestsequence_seen + 1; i < move->sequence; ++i)
+ host_client->movement_count[i % NETGRAPH_PACKETS] = -1;
+ else
+ memset(host_client->movement_count, -1, sizeof(host_client->movement_count));
+ }
+ // mark THIS move as seen for the first time
+ host_client->movement_count[move->sequence % NETGRAPH_PACKETS] = 1;
+ // update highest sequence seen
+ host_client->movement_highestsequence_seen = move->sequence;
+ }
+ else
+ if(host_client->movement_count[move->sequence % NETGRAPH_PACKETS] >= 0)
+ ++host_client->movement_count[move->sequence % NETGRAPH_PACKETS];
+ }
+ else
+ {
+ host_client->movement_highestsequence_seen = 0;
+ memset(host_client->movement_count, 0, sizeof(host_client->movement_count));
+ }
}
void SV_ExecuteClientMoves(void)
// discard (treat like lost) moves with too low distance from
// the previous one to prevent hacks using float inaccuracy
// clients will see this as packet loss in the netgraph
- if(sv_clmovement_maxnetfps.value > 0)
- if(moveframetime + 0.0001 < 1 / sv_clmovement_maxnetfps.value)
+ if(moveframetime < 0.0005)
continue;
//Con_Printf("movesequence = %i (%i lost), moveframetime = %f\n", move->sequence, move->sequence ? move->sequence - host_client->movesequence - 1 : 0, moveframetime);