// Render the Scene
view_origin = getpropertyvec(VF_ORIGIN);
view_angles = getpropertyvec(VF_ANGLES);
+
+ /*{
+ vector grav_angles = vectoangles(PHYS_GRAVITY_DIR(this));
+
+ // model is already facing the floor, no need to tilt 90 degrees
+ PITCH(grav_angles) += 90;
+
+ // adjust roll and pitch depending on grav direction
+ float pitch_ratio = cos((YAW(grav_angles) - YAW(view_angles)) * DEG2RAD);
+ float roll_ratio = sin((YAW(grav_angles) - YAW(view_angles)) * DEG2RAD);
+ ROLL(view_angles) = PITCH(grav_angles) * roll_ratio + ROLL(grav_angles) * pitch_ratio;
+ }*/
+
+ {
+ vector grav_dir = PHYS_GRAVITY_DIR(this);
+ bool upside_down = grav_dir.z > 0;
+
+ if (upside_down) grav_dir.z = -grav_dir.z;
+
+ vector grav_angles = vectoangles(grav_dir);
+
+ // model is already facing the floor, no need to tilt 90 degrees
+ PITCH(grav_angles) += 90;
+ PITCH(grav_angles) = PITCH(grav_angles) % 360;
+
+ if (upside_down) YAW(grav_angles) += 180;
+
+ // adjust roll and pitch depending on grav direction
+ float pitch_ratio = cos((YAW(grav_angles) - YAW(view_angles)) * DEG2RAD);
+ float roll_ratio = sin((YAW(grav_angles) - YAW(view_angles)) * DEG2RAD);
+ ROLL(view_angles) = PITCH(grav_angles) * roll_ratio + ROLL(grav_angles) * pitch_ratio;
+
+ if (upside_down) ROLL(view_angles) += 180;
+ }
+
MAKE_VECTORS(view_angles, view_forward, view_right, view_up);
#ifdef BLURTEST
if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this))
{
if(GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
- this.velocity_z -= grav * 0.5;
+ this.velocity += grav * 0.5 * normalize(PHYS_GRAVITY_DIR(this));
else
- this.velocity_z -= grav;
+ this.velocity += grav * normalize(PHYS_GRAVITY_DIR(this));
}
}
if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this))
{
if(GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
- this.velocity_z -= grav * 0.5f;
+ this.velocity += grav * 0.5f * normalize(PHYS_GRAVITY_DIR(this));
}
}
#define PHYS_GRAVITY(s) STAT(MOVEVARS_GRAVITY, s)
// FIXME: 0 doesn't mean zero gravity
+ #define PHYS_GRAVITY_DIR(s) STAT(MOVEVARS_GRAVITY_DIR, s)
#define PHYS_ENTGRAVITY(s) STAT(MOVEVARS_ENTGRAVITY, s)
#define TICRATE ticrate
#define GAMEPLAYFIX_Q2AIRACCELERATE autocvar_sv_gameplayfix_q2airaccelerate
#define PHYS_GRAVITY(s) autocvar_sv_gravity
+ #define PHYS_GRAVITY_DIR(s) autocvar_sv_gravity_dir
#define PHYS_ENTGRAVITY(s) ((s).gravity)
#define TICRATE sys_frametime
bool doublejump = false;
float mjumpheight = ((PHYS_JUMPVELOCITY_CROUCH(this) && IS_DUCKED(this)) ? PHYS_JUMPVELOCITY_CROUCH(this) : PHYS_JUMPVELOCITY(this));
+ vector grav_dir = normalize(PHYS_GRAVITY_DIR(this));
+ float velocity_up = this.velocity * -grav_dir;
bool track_jump = PHYS_CL_TRACK_CANJUMP(this);
if (MUTATOR_CALLHOOK(PlayerJump, this, mjumpheight, doublejump))
}
else
{
- this.velocity_z = PHYS_MAXSPEED(this) * 0.7;
+ this.velocity = PHYS_MAXSPEED(this) * 0.7 * -grav_dir;
return true;
}
}
{
float minjumpspeed = mjumpheight * stof(PHYS_JUMPSPEEDCAP_MIN);
- if (this.velocity_z < minjumpspeed)
- mjumpheight += minjumpspeed - this.velocity_z;
+ if (velocity_up < minjumpspeed)
+ mjumpheight += minjumpspeed - velocity_up;
}
if(PHYS_JUMPSPEEDCAP_MAX != "")
{
float maxjumpspeed = mjumpheight * stof(PHYS_JUMPSPEEDCAP_MAX);
- if (this.velocity_z > maxjumpspeed)
- mjumpheight -= this.velocity_z - maxjumpspeed;
+ if (velocity_up > maxjumpspeed)
+ mjumpheight -= velocity_up - maxjumpspeed;
}
}
#endif
}
- this.velocity_z += mjumpheight;
+ this.velocity += mjumpheight * -grav_dir;
UNSET_ONGROUND(this);
UNSET_ONSLICK(this);
#ifdef SVQC
float autocvar_sv_wallfriction;
#define autocvar_sv_gravity cvar("sv_gravity")
+vector autocvar_sv_gravity_dir = '0 0 -1';
float autocvar_sv_stepheight;
#endif
REGISTER_STAT(MOVEVARS_WALLFRICTION, int, autocvar_sv_wallfriction)
REGISTER_STAT(MOVEVARS_TICRATE, float, autocvar_sys_ticrate)
REGISTER_STAT(MOVEVARS_TIMESCALE, float, autocvar_slowmo)
REGISTER_STAT(MOVEVARS_GRAVITY, float, autocvar_sv_gravity)
+REGISTER_STAT(MOVEVARS_GRAVITY_DIR, vector, autocvar_sv_gravity_dir)
REGISTER_STAT(MOVEVARS_STOPSPEED, float)
REGISTER_STAT(MOVEVARS_MAXSPEED, float)
REGISTER_STAT(MOVEVARS_ACCELERATE, float)
CheckPlayerJump(this);
}
+ // make the player model face the ground relative to the current gravity direction
+ {
+ float saved_yaw = YAW(this.angles);
+ vector grav_dir = PHYS_GRAVITY_DIR(this);
+ bool upside_down = grav_dir.z > 0;
+
+ if (upside_down) {
+ grav_dir.z = -grav_dir.z;
+ }
+
+ this.angles = vectoangles(grav_dir);
+
+ // model is already facing the floor, no need to tilt 90 degrees
+ PITCH(this.angles) += 90;
+ PITCH(this.angles) = PITCH(this.angles) % 360;
+
+ if (upside_down) YAW(this.angles) += 180;
+
+ // adjust roll and pitch depending on grav direction
+ float saved_pitch = PITCH(this.angles);
+ float saved_roll = ROLL(this.angles);
+ float pitch_ratio = cos((YAW(this.angles) - saved_yaw) * DEG2RAD);
+ float roll_ratio = sin((YAW(this.angles) - saved_yaw) * DEG2RAD);
+ PITCH(this.angles) = saved_pitch * pitch_ratio + saved_roll * roll_ratio;
+ ROLL(this.angles) = saved_pitch * roll_ratio + saved_roll * pitch_ratio;
+ YAW(this.angles) = saved_yaw;
+
+ if (upside_down) ROLL(this.angles) += 180;
+
+ // pitch can't be >= 90, transform to something usable
+ if (fabs(PITCH(this.angles)) >= 91) {
+ PITCH(this.angles) = copysign(180, PITCH(this.angles)) - PITCH(this.angles);
+ YAW(this.angles) += 180;
+ ROLL(this.angles) += 180;
+ }
+ else if (fabs(PITCH(this.angles)) > 89) {
+ PITCH(this.angles) = copysign(89, PITCH(this.angles));
+ }
+ }
+
if (this.flags & FL_WATERJUMP) {
this.velocity_x = this.movedir.x;
this.velocity_y = this.movedir.y;