speed = VectorNormalizeLength(s->velocity);
dot = DotProduct(s->velocity, wishdir);
- k *= cl.movevars_aircontrol*dot*dot*s->cmd.frametime;
if(dot > 0) { // we can't change direction while slowing down
+ k *= cl.movevars_aircontrol*pow(dot, cl.movevars_aircontrol_power)*s->cmd.frametime;
VectorMAM(speed, s->velocity, k, wishdir, s->velocity);
VectorNormalize(s->velocity);
}
// negative: only apply so much sideways friction to stay below the speed you could get by "braking"
{
vec_t f, fmin;
- f = 1 - s->cmd.frametime * wishspeed * sidefric;
+ f = max(0, 1 + s->cmd.frametime * wishspeed * sidefric);
fmin = (vel_xy_backward*vel_xy_backward - vel_straight*vel_straight) / VectorLength2(vel_perpend);
+ // assume: fmin > 1
+ // vel_xy_backward*vel_xy_backward - vel_straight*vel_straight > vel_perpend*vel_perpend
+ // vel_xy_backward*vel_xy_backward > vel_straight*vel_straight + vel_perpend*vel_perpend
+ // vel_xy_backward*vel_xy_backward > vel_xy * vel_xy
+ // obviously, this cannot be
if(fmin <= 0)
VectorScale(vel_perpend, f, vel_perpend);
else
{
fmin = sqrt(fmin);
- VectorScale(vel_perpend, bound(fmin, f, 1.0f), vel_perpend);
+ VectorScale(vel_perpend, max(fmin, f), vel_perpend);
}
}
else
- VectorScale(vel_perpend, 1 - s->cmd.frametime * wishspeed * sidefric, vel_perpend);
+ VectorScale(vel_perpend, max(0, 1 - s->cmd.frametime * wishspeed * sidefric), vel_perpend);
VectorMA(vel_perpend, vel_straight, wishdir, s->velocity);
vec_t addspeed;
vec_t accelspeed;
vec_t f;
+ vec_t gravity;
vec3_t forward;
vec3_t right;
vec3_t up;
accelspeed = min(cl.movevars_accelerate * s->cmd.frametime * wishspeed, addspeed);
VectorMA(s->velocity, accelspeed, wishdir, s->velocity);
}
- s->velocity[2] -= cl.movevars_gravity * cl.movevars_entgravity * s->cmd.frametime;
+ 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;
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;
}
else
{
if(cl.movevars_aircontrol)
CL_ClientMovement_Physics_CPM_PM_Aircontrol(s, wishdir, wishspeed2);
}
- s->velocity[2] -= cl.movevars_gravity * cl.movevars_entgravity * s->cmd.frametime;
+ 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;
CL_ClientMovement_Move(s);
+ if(cl.moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
+ s->velocity[2] -= gravity * 0.5f;
}
}
cl.movevars_airstrafeaccelerate = cl.statsf[STAT_MOVEVARS_AIRSTRAFEACCELERATE];
cl.movevars_maxairstrafespeed = cl.statsf[STAT_MOVEVARS_MAXAIRSTRAFESPEED];
cl.movevars_aircontrol = cl.statsf[STAT_MOVEVARS_AIRCONTROL];
+ cl.movevars_aircontrol_power = cl.statsf[STAT_MOVEVARS_AIRCONTROL_POWER];
cl.movevars_warsowbunny_airforwardaccel = cl.statsf[STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL];
cl.movevars_warsowbunny_accel = cl.statsf[STAT_MOVEVARS_WARSOWBUNNY_ACCEL];
cl.movevars_warsowbunny_topspeed = cl.statsf[STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED];
cl.movevars_airstrafeaccelerate = 0;
cl.movevars_maxairstrafespeed = 0;
cl.movevars_aircontrol = 0;
+ cl.movevars_aircontrol_power = 2;
cl.movevars_warsowbunny_airforwardaccel = 0;
cl.movevars_warsowbunny_accel = 0;
cl.movevars_warsowbunny_topspeed = 0;
if(gamemode == GAME_NEXUIZ)
cl.moveflags = MOVEFLAG_Q2AIRACCELERATE;
}
+
+ if(cl.movevars_aircontrol_power <= 0)
+ cl.movevars_aircontrol = 2; // CPMA default
}
void CL_ClientMovement_Replay(void)