X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=cl_input.c;h=4400e3a60ea8dcd8f4cb3ac4eada29f0b09bc29b;hp=9f75a36fbc4571c39d75aaa09572ad9e1de0f374;hb=728e717bdc878f4ef2fb4311619b232949fb16aa;hpb=e00dfcca1f85679216378931ea4774eb294f290a diff --git a/cl_input.c b/cl_input.c index 9f75a36f..4400e3a6 100644 --- a/cl_input.c +++ b/cl_input.c @@ -625,7 +625,7 @@ void CL_Input (void) if (!key_consoleactive && key_dest == key_game && !cl.csqc_wantsmousemove) { float modulatedsensitivity = sensitivity.value * cl.sensitivityscale; - if (cl_prydoncursor.integer) + if (cl_prydoncursor.integer > 0) { // mouse interacting with the scene, mostly stationary view V_StopPitchDrift(); @@ -743,7 +743,7 @@ void CL_UpdatePrydonCursor(void) { vec3_t temp; - if (!cl_prydoncursor.integer) + if (cl_prydoncursor.integer <= 0) VectorClear(cl.cmd.cursor_screen); /* @@ -778,7 +778,15 @@ void CL_UpdatePrydonCursor(void) VectorSet(temp, cl.cmd.cursor_screen[2] * 1000000, (v_flipped.integer ? -1 : 1) * cl.cmd.cursor_screen[0] * -r_refdef.view.frustum_x * 1000000, cl.cmd.cursor_screen[1] * -r_refdef.view.frustum_y * 1000000); Matrix4x4_Transform(&r_refdef.view.matrix, temp, cl.cmd.cursor_end); // trace from view origin to the cursor - 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); + if (cl_prydoncursor_notrace.integer) + { + cl.cmd.cursor_fraction = 1.0f; + VectorCopy(cl.cmd.cursor_end, cl.cmd.cursor_impact); + VectorClear(cl.cmd.cursor_normal); + cl.cmd.cursor_entitynumber = 0; + } + else + 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 @@ -1091,6 +1099,25 @@ static vec_t CL_IsMoveInDirection(vec_t forward, vec_t side, vec_t angle) return 1 - fabs(angle); } +static vec_t CL_GeomLerp(vec_t a, vec_t lerp, vec_t b) +{ + if(a == 0) + { + if(lerp < 1) + return 0; + else + return b; + } + if(b == 0) + { + if(lerp > 0) + return 0; + else + return a; + } + return a * pow(fabs(b / a), lerp); +} + void CL_ClientMovement_Physics_CPM_PM_Aircontrol(cl_clientmovement_state_t *s, vec3_t wishdir, vec_t wishspeed) { vec_t zspeed, speed, dot, k; @@ -1113,9 +1140,9 @@ void CL_ClientMovement_Physics_CPM_PM_Aircontrol(cl_clientmovement_state_t *s, v 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); } @@ -1161,18 +1188,23 @@ void CL_ClientMovement_Physics_PM_Accelerate(cl_clientmovement_state_t *s, vec3_ // 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); @@ -1247,6 +1279,7 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) vec_t addspeed; vec_t accelspeed; vec_t f; + vec_t gravity; vec3_t forward; vec3_t right; vec3_t up; @@ -1319,18 +1352,27 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) 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 (s->waterjumptime <= 0) { // apply air speed limit - vec_t accel, wishspeed0, wishspeed2, accelqw; + vec_t accel, wishspeed0, wishspeed2, accelqw, strafity; qboolean accelerating; accelqw = cl.movevars_airaccel_qw; @@ -1347,9 +1389,17 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) if(cl.movevars_airstopaccelerate != 0) if(DotProduct(s->velocity, wishdir) < 0) accel = cl.movevars_airstopaccelerate; - // this doesn't play well with analog input, but can't really be - // fixed like the AirControl can. So, don't set the maxairstrafe* - // cvars when you want to support analog input. + strafity = CL_IsMoveInDirection(s->cmd.forwardmove, s->cmd.sidemove, -90) + CL_IsMoveInDirection(s->cmd.forwardmove, s->cmd.sidemove, +90); // if one is nonzero, other is always zero + if(cl.movevars_maxairstrafespeed) + wishspeed = min(wishspeed, CL_GeomLerp(cl.movevars_maxairspeed, strafity, cl.movevars_maxairstrafespeed)); + if(cl.movevars_airstrafeaccelerate) + accel = CL_GeomLerp(cl.movevars_airaccelerate, strafity, cl.movevars_airstrafeaccelerate); + if(cl.movevars_airstrafeaccel_qw) + accelqw = + (((strafity > 0.5 ? cl.movevars_airstrafeaccel_qw : cl.movevars_airaccel_qw) >= 0) ? +1 : -1) + * + (1 - CL_GeomLerp(1 - fabs(cl.movevars_airaccel_qw), strafity, 1 - fabs(cl.movevars_airstrafeaccel_qw))); + if(s->cmd.forwardmove == 0 && s->cmd.sidemove != 0) { if(cl.movevars_maxairstrafespeed) @@ -1382,8 +1432,14 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) 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; } } @@ -1432,7 +1488,9 @@ void CL_UpdateMoveVars(void) cl.movevars_airstopaccelerate = cl.statsf[STAT_MOVEVARS_AIRSTOPACCELERATE]; cl.movevars_airstrafeaccelerate = cl.statsf[STAT_MOVEVARS_AIRSTRAFEACCELERATE]; cl.movevars_maxairstrafespeed = cl.statsf[STAT_MOVEVARS_MAXAIRSTRAFESPEED]; + cl.movevars_airstrafeaccel_qw = cl.statsf[STAT_MOVEVARS_AIRSTRAFEACCEL_QW]; 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]; @@ -1464,7 +1522,9 @@ void CL_UpdateMoveVars(void) cl.movevars_airstopaccelerate = 0; cl.movevars_airstrafeaccelerate = 0; cl.movevars_maxairstrafespeed = 0; + cl.movevars_airstrafeaccel_qw = 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; @@ -1477,6 +1537,9 @@ void CL_UpdateMoveVars(void) 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) @@ -1678,7 +1741,7 @@ void CL_SendMove(void) if (in_button8.state & 3) bits |= 128; if (in_use.state & 3) bits |= 256; if (key_dest != key_game || key_consoleactive) bits |= 512; - if (cl_prydoncursor.integer) bits |= 1024; + if (cl_prydoncursor.integer > 0) bits |= 1024; if (in_button9.state & 3) bits |= 2048; if (in_button10.state & 3) bits |= 4096; if (in_button11.state & 3) bits |= 8192;