- Make Exhumed's new view tilting features accessible for all games.

This commit is contained in:
Mitchell Richters 2023-04-22 19:34:44 +10:00
parent 49863c79ce
commit 71d833f9ea
11 changed files with 122 additions and 43 deletions

View file

@ -36,6 +36,12 @@ CVAR(Float, m_pitch, 1.f, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
CVAR(Float, m_yaw, 1.f, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) CVAR(Float, m_yaw, 1.f, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
CVAR(Float, m_forward, 1.f, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) CVAR(Float, m_forward, 1.f, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
CVAR(Float, m_side, 1.f, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) CVAR(Float, m_side, 1.f, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
CVAR(Float, cl_viewtiltscale, 1.f, CVAR_GLOBALCONFIG | CVAR_ARCHIVE);
CUSTOM_CVAR(Int, cl_viewtilting, 0, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
{
if (self < 0) self = 0;
else if (self > 3) self = 3;
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -500,6 +506,52 @@ void PlayerAngles::doViewYaw(InputPacket* const input)
} }
//---------------------------------------------------------------------------
//
// View tilting effects, mostly for Exhumed to enhance its gameplay feel.
//
//---------------------------------------------------------------------------
void PlayerAngles::doViewTilting(InputPacket* const pInput, const DVector2& nVelVect, const double nMaxVel, const bool bUnderwater)
{
// Scale/attenuate tilting based on player actions.
const auto runScale = 1. / (!(pInput->actions & SB_RUN) + 1);
const auto waterScale = 1. / (bUnderwater + 1);
const auto strafeScale = !!pInput->svel + 1;
if (cl_viewtilting == 1)
{
// Console-like yaw rolling. Adjustment == (90/32) for keyboard turning. Clamp is 1.5x this value.
const auto rollAdj = pActor->spr.Angles.Roll.Degrees() + pInput->avel * (48779.f / 150000.f) * cl_viewtiltscale;
const auto rollAmp = waterScale;
const auto rollMax = (11553170. / 1347146.) * cl_viewtiltscale;
pActor->spr.Angles.Roll = DAngle::fromDeg(clamp(rollAdj * rollAmp, -rollMax, rollMax));
scaletozero(pActor->spr.Angles.Roll, ROLL_TILTRETURN);
}
else if (cl_viewtilting == 2)
{
// Quake-like strafe rolling. Adjustment == (90/48) for running keyboard strafe.
const auto rollAdj = StrafeVel * cl_viewtiltscale;
const auto rollAmp = strafeScale * waterScale;
const auto rollMax = nMaxVel * runScale * cl_viewtiltscale;
pActor->spr.Angles.Roll = DAngle::fromDeg(clamp(rollAdj * rollAmp, -rollMax, rollMax) * (1.875 / nMaxVel));
}
else if (cl_viewtilting == 3)
{
// Movement rolling from player's velocity. Adjustment == (90/48) for running keyboard strafe.
const auto rollAdj = nVelVect.Rotated(-pActor->spr.Angles.Yaw).Y * cl_viewtiltscale;
const auto rollAmp = strafeScale * waterScale;
const auto rollMax = nMaxVel * runScale * cl_viewtiltscale;
pActor->spr.Angles.Roll = DAngle::fromDeg(clamp(rollAdj * rollAmp, -rollMax, rollMax) * (1.875 / nMaxVel));
}
else
{
// Always reset roll if we're not tilting at all.
pActor->spr.Angles.Roll = nullAngle;
}
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// //

View file

@ -78,6 +78,9 @@ struct PlayerAngles
// Player viewing angles, separate from the camera. // Player viewing angles, separate from the camera.
DRotator PrevViewAngles, ViewAngles; DRotator PrevViewAngles, ViewAngles;
// Strafe roll counter, to be incremented/managed by the game's velocity handler.
double PrevStrafeVel, StrafeVel;
// Holder of current yaw spin state for the 180 degree turn. // Holder of current yaw spin state for the 180 degree turn.
DAngle YawSpin; DAngle YawSpin;
@ -90,6 +93,7 @@ struct PlayerAngles
void doYawInput(InputPacket* const input); void doYawInput(InputPacket* const input);
void doViewPitch(const bool canslopetilt, const bool climbing = false); void doViewPitch(const bool canslopetilt, const bool climbing = false);
void doViewYaw(InputPacket* const input); void doViewYaw(InputPacket* const input);
void doViewTilting(InputPacket* const pInput, const DVector2& nVelVect, const double nMaxVel, const bool bUnderwater);
// General methods. // General methods.
void initialize(DCoreActor* const actor, const DAngle viewyaw = nullAngle) void initialize(DCoreActor* const actor, const DAngle viewyaw = nullAngle)
@ -149,6 +153,7 @@ private:
DCoreActor* pActor; DCoreActor* pActor;
// Constants used throughout input functions. // Constants used throughout input functions.
static constexpr double ROLL_TILTRETURN = 15.;
static constexpr double YAW_LOOKINGSPEED = 801.5625; static constexpr double YAW_LOOKINGSPEED = 801.5625;
static constexpr double YAW_ROTATESPEED = 63.28125; static constexpr double YAW_ROTATESPEED = 63.28125;
static constexpr double YAW_LOOKRETURN = 7.5; static constexpr double YAW_LOOKRETURN = 7.5;

View file

@ -5153,8 +5153,16 @@ void MoveDude(DBloodActor* actor)
actor->vel.X += FixedToFloat(-mulscale16r(FloatToFixed(actor->vel.X), nDrag)); actor->vel.X += FixedToFloat(-mulscale16r(FloatToFixed(actor->vel.X), nDrag));
actor->vel.Y += FixedToFloat(-mulscale16r(FloatToFixed(actor->vel.Y), nDrag)); actor->vel.Y += FixedToFloat(-mulscale16r(FloatToFixed(actor->vel.Y), nDrag));
if (pPlayer)
{
pPlayer->Angles.StrafeVel += FixedToFloat(-mulscale16r(FloatToFixed(pPlayer->Angles.StrafeVel), nDrag));
}
if (actor->vel.XY().Length() < 0.0625) if (actor->vel.XY().Length() < 0.0625)
{
actor->vel.XY().Zero(); actor->vel.XY().Zero();
if (pPlayer) pPlayer->Angles.StrafeVel = 0;
}
} }
} }

View file

@ -1571,11 +1571,15 @@ void ProcessInput(PLAYER* pPlayer)
const double& fvAccel = pInput->fvel > 0 ? pPosture->frontAccel : pPosture->backAccel; const double& fvAccel = pInput->fvel > 0 ? pPosture->frontAccel : pPosture->backAccel;
const double& svAccel = pPosture->sideAccel; const double& svAccel = pPosture->sideAccel;
actor->vel.XY() += DVector2(pInput->fvel * fvAccel, pInput->svel * svAccel).Rotated(actor->spr.Angles.Yaw) * speed; actor->vel.XY() += DVector2(pInput->fvel * fvAccel, pInput->svel * svAccel).Rotated(actor->spr.Angles.Yaw) * speed;
pPlayer->Angles.StrafeVel += pInput->svel * svAccel * speed;
} }
pPlayer->Angles.doViewYaw(pInput); pPlayer->Angles.doViewYaw(pInput);
pPlayer->Angles.doYawInput(pInput); pPlayer->Angles.doYawInput(pInput);
constexpr auto maxVel = (36211. / 3000.);
pPlayer->Angles.doViewTilting(pInput, actor->vel.XY(), maxVel, pPlayer->posture == kPostureSwim);
if (!(pInput->actions & SB_JUMP)) if (!(pInput->actions & SB_JUMP))
pPlayer->cantJump = 0; pPlayer->cantJump = 0;

View file

@ -1630,6 +1630,10 @@ void processinput_d(int snum)
ESyncBits& actions = p->sync.actions; ESyncBits& actions = p->sync.actions;
// Get strafe value before it's rotated by the angle.
const auto strafeVel = PlayerInputSideVel(snum);
constexpr auto maxVel = (117351124. / 10884538.);
processinputvel(snum); processinputvel(snum);
auto sb_fvel = PlayerInputForwardVel(snum); auto sb_fvel = PlayerInputForwardVel(snum);
auto sb_svel = PlayerInputSideVel(snum); auto sb_svel = PlayerInputSideVel(snum);
@ -1872,6 +1876,7 @@ void processinput_d(int snum)
p->vel.X += sb_fvel * doubvel * (5. / 16.); p->vel.X += sb_fvel * doubvel * (5. / 16.);
p->vel.Y += sb_svel * doubvel * (5. / 16.); p->vel.Y += sb_svel * doubvel * (5. / 16.);
p->Angles.StrafeVel += strafeVel * doubvel * (5. / 16.);
bool check; bool check;
@ -1880,28 +1885,37 @@ void processinput_d(int snum)
if (check) if (check)
{ {
p->vel.XY() *= gs.playerfriction - 0.125; p->vel.XY() *= gs.playerfriction - 0.125;
p->Angles.StrafeVel *= gs.playerfriction - 0.125;
} }
else else
{ {
if (psectlotag == 2) if (psectlotag == 2)
{ {
p->vel.XY() *= gs.playerfriction - FixedToFloat(0x1400); p->vel.XY() *= gs.playerfriction - FixedToFloat(0x1400);
p->Angles.StrafeVel *= gs.playerfriction - FixedToFloat(0x1400);
} }
else else
{ {
p->vel.XY() *= gs.playerfriction; p->vel.XY() *= gs.playerfriction;
p->Angles.StrafeVel *= gs.playerfriction;
} }
} }
if (abs(p->vel.X) < 1/128. && abs(p->vel.Y) < 1 / 128.) if (abs(p->vel.X) < 1/128. && abs(p->vel.Y) < 1 / 128.)
{
p->vel.X = p->vel.Y = 0; p->vel.X = p->vel.Y = 0;
p->Angles.StrafeVel = 0;
}
if (shrunk) if (shrunk)
{ {
p->vel.XY() *= gs.playerfriction * 0.75; p->vel.XY() *= gs.playerfriction * 0.75;
p->Angles.StrafeVel *= gs.playerfriction * 0.75;
} }
} }
p->Angles.doViewTilting(&p->sync, p->vel.XY(), maxVel, (psectlotag == 1) || (psectlotag == 2));
HORIZONLY: HORIZONLY:
double iif = (psectlotag == 1 || p->spritebridge == 1) ? 4 : 20; double iif = (psectlotag == 1 || p->spritebridge == 1) ? 4 : 20;

View file

@ -2335,6 +2335,10 @@ void processinput_r(int snum)
ESyncBits& actions = p->sync.actions; ESyncBits& actions = p->sync.actions;
// Get strafe value before it's rotated by the angle.
const auto strafeVel = PlayerInputSideVel(snum);
constexpr auto maxVel = (117351124. / 10884538.);
auto psectp = p->cursector; auto psectp = p->cursector;
if (p->OnMotorcycle && pact->spr.extra > 0) if (p->OnMotorcycle && pact->spr.extra > 0)
{ {
@ -2689,20 +2693,24 @@ void processinput_r(int snum)
p->vel.X += sb_fvel * doubvel * (5. / 16.); p->vel.X += sb_fvel * doubvel * (5. / 16.);
p->vel.Y += sb_svel * doubvel * (5. / 16.); p->vel.Y += sb_svel * doubvel * (5. / 16.);
p->Angles.StrafeVel += strafeVel * doubvel * (5. / 16.);
if (!isRRRA() && ((p->curr_weapon == KNEE_WEAPON && p->kickback_pic > 10 && p->on_ground) || (p->on_ground && (actions & SB_CROUCH)))) if (!isRRRA() && ((p->curr_weapon == KNEE_WEAPON && p->kickback_pic > 10 && p->on_ground) || (p->on_ground && (actions & SB_CROUCH))))
{ {
p->vel.XY() *= gs.playerfriction - 0.125; p->vel.XY() *= gs.playerfriction - 0.125;
p->Angles.StrafeVel *= gs.playerfriction - 0.125;
} }
else else
{ {
if (psectlotag == 2) if (psectlotag == 2)
{ {
p->vel.XY() *= gs.playerfriction - FixedToFloat(0x1400); p->vel.XY() *= gs.playerfriction - FixedToFloat(0x1400);
p->Angles.StrafeVel *= gs.playerfriction - FixedToFloat(0x1400);
} }
else else
{ {
p->vel.XY() *= gs.playerfriction; p->vel.XY() *= gs.playerfriction;
p->Angles.StrafeVel *= gs.playerfriction;
} }
} }
@ -2724,6 +2732,7 @@ void processinput_r(int snum)
else else
{ {
p->vel.XY() *= gs.playerfriction; p->vel.XY() *= gs.playerfriction;
p->Angles.StrafeVel *= gs.playerfriction;
} }
} }
else if (tilesurface(psectp->floortexture) == TSURF_MUDDY) else if (tilesurface(psectp->floortexture) == TSURF_MUDDY)
@ -2733,6 +2742,7 @@ void processinput_r(int snum)
if (p->on_ground) if (p->on_ground)
{ {
p->vel.XY() *= gs.playerfriction - FixedToFloat(0x1800); p->vel.XY() *= gs.playerfriction - FixedToFloat(0x1800);
p->Angles.StrafeVel *= gs.playerfriction - FixedToFloat(0x1800);
} }
} }
else else
@ -2741,18 +2751,25 @@ void processinput_r(int snum)
else else
{ {
p->vel.XY() *= gs.playerfriction - FixedToFloat(0x1800); p->vel.XY() *= gs.playerfriction - FixedToFloat(0x1800);
p->Angles.StrafeVel *= gs.playerfriction - FixedToFloat(0x1800);
} }
} }
if (abs(p->vel.X) < 1 / 128. && abs(p->vel.Y) < 1 / 128.) if (abs(p->vel.X) < 1 / 128. && abs(p->vel.Y) < 1 / 128.)
{
p->vel.X = p->vel.Y = 0; p->vel.X = p->vel.Y = 0;
p->Angles.StrafeVel = 0;
}
if (shrunk) if (shrunk)
{ {
p->vel.XY() *= gs.playerfriction * 0.75; p->vel.XY() *= gs.playerfriction * 0.75;
p->Angles.StrafeVel *= gs.playerfriction * 0.75;
} }
} }
p->Angles.doViewTilting(&p->sync, p->vel.XY(), maxVel, (psectlotag == 1) || (psectlotag == 2));
HORIZONLY: HORIZONLY:
double iif = (psectlotag == 1 || p->spritebridge == 1) ? 4 : 20; double iif = (psectlotag == 1 || p->spritebridge == 1) ? 4 : 20;

View file

@ -36,12 +36,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
CUSTOM_CVAR(Int, cl_exviewtilting, 0, CVAR_ARCHIVE)
{
if (self < 0) self = 0;
else if (self > 3) self = 3;
}
CVAR(Float, cl_extiltscale, 1.f, CVAR_ARCHIVE);
CVAR(Bool, cl_exjumprebound, false, CVAR_ARCHIVE); CVAR(Bool, cl_exjumprebound, false, CVAR_ARCHIVE);
CVAR(Float, cl_exviewbobspeed, 4.f, CVAR_ARCHIVE); CVAR(Float, cl_exviewbobspeed, 4.f, CVAR_ARCHIVE);
CVAR(Float, cl_exviewbobheight, 5.f, CVAR_ARCHIVE); CVAR(Float, cl_exviewbobheight, 5.f, CVAR_ARCHIVE);
@ -1124,8 +1118,8 @@ static void updatePlayerVelocity(Player* const pPlayer)
{ {
pPlayer->vel += inputvect; pPlayer->vel += inputvect;
pPlayer->vel *= 0.953125; pPlayer->vel *= 0.953125;
pPlayer->nStrafeRoll += pInput->svel * 0.375; pPlayer->Angles.StrafeVel += pInput->svel * 0.375;
pPlayer->nStrafeRoll *= 0.953125; pPlayer->Angles.StrafeVel *= 0.953125;
} }
} }
@ -1133,7 +1127,7 @@ static void updatePlayerVelocity(Player* const pPlayer)
{ {
pPlayer->vel.Zero(); pPlayer->vel.Zero();
pPlayer->nIdxBobZ = 0; pPlayer->nIdxBobZ = 0;
pPlayer->nStrafeRoll = 0; pPlayer->Angles.StrafeVel = 0;
} }
pPlayerActor->vel.XY() = pPlayer->vel; pPlayerActor->vel.XY() = pPlayer->vel;
@ -1567,50 +1561,21 @@ static void doPlayerCameraEffects(Player* const pPlayer, const double nDestVertP
{ {
const auto pPlayerActor = pPlayer->pActor; const auto pPlayerActor = pPlayer->pActor;
const auto pInput = &pPlayer->input; const auto pInput = &pPlayer->input;
const auto pAngles = &pPlayerActor->spr.Angles;
const auto nUnderwater = !!(pPlayerActor->sector()->Flag & kSectUnderwater); const auto nUnderwater = !!(pPlayerActor->sector()->Flag & kSectUnderwater);
const auto waterScale = 1. / (nUnderwater + 1);
constexpr auto maxVel = 15.25; constexpr auto maxVel = 15.25;
// Pitch tilting when player's Z changes (stairs, jumping, etc). // Pitch tilting when player's Z changes (stairs, jumping, etc).
doPlayerVertPanning(pPlayer, nDestVertPan * cl_slopetilting); doPlayerVertPanning(pPlayer, nDestVertPan * cl_slopetilting);
// Roll tilting effect, either console or Quake-style. // Roll tilting effect, either console or Quake-style.
if (cl_exviewtilting == 1) pPlayer->Angles.doViewTilting(pInput, pPlayerActor->vel.XY(), maxVel, nUnderwater);
{
// Console-like yaw rolling. Adjustment == (90/32) for keyboard turning. Clamp is 1.5x this value.
const auto rollAdj = pAngles->Roll.Degrees() + pInput->avel * (48779.f / 150000.f) * cl_extiltscale;
const auto rollMax = (11553170. / 1347146.) * cl_extiltscale;
pAngles->Roll = DAngle::fromDeg(clamp(rollAdj * waterScale, -rollMax, rollMax));
scaletozero(pAngles->Roll, GameTicRate * 0.5);
}
else if (cl_exviewtilting == 2)
{
// Quake-like strafe rolling. Adjustment == (90/48) for running keyboard strafe.
const auto rollAdj = pPlayer->nStrafeRoll * cl_extiltscale;
const auto rollAmp = (!!pInput->svel + 1.) * waterScale;
const auto rollMax = maxVel / (!(pInput->actions & SB_RUN) + 1) * cl_extiltscale;
pAngles->Roll = DAngle::fromDeg(clamp(rollAdj * rollAmp, -rollMax, rollMax) * (15. / 122.));
}
else if (cl_exviewtilting == 3)
{
// Movement rolling. Adjustment == (90/48) for running keyboard strafe.
const auto rollAdj = pPlayerActor->vel.XY().Rotated(-pAngles->Yaw).Y * cl_extiltscale;
const auto rollAmp = (!!pInput->svel + 1.) * waterScale;
const auto rollMax = maxVel / (!(pInput->actions & SB_RUN) + 1) * cl_extiltscale;
pAngles->Roll = DAngle::fromDeg(clamp(rollAdj * rollAmp, -rollMax, rollMax) * (15. / 122.));
}
else
{
pAngles->Roll = nullAngle;
}
// Update Z bobbing. // Update Z bobbing.
if (cl_viewbob) if (cl_viewbob)
{ {
// Increment index, attenuating by bob speed, type and whether we're underwater. // Increment index, attenuating by bob speed, type and whether we're underwater.
pPlayer->nPrevBobZ = pPlayer->nBobZ; pPlayer->nPrevBobZ = pPlayer->nBobZ;
pPlayer->nIdxBobZ += (2048. / 90.) * cl_exviewbobspeed / cl_viewbob * waterScale; pPlayer->nIdxBobZ += (2048. / 90.) * cl_exviewbobspeed / cl_viewbob / (nUnderwater + 1);
pPlayer->nIdxBobZ *= !pPlayerActor->vel.Z; pPlayer->nIdxBobZ *= !pPlayerActor->vel.Z;
// Increment bob value with index's sine, amplifed by player velocity, bob type and bob height CVAR. // Increment bob value with index's sine, amplifed by player velocity, bob type and bob height CVAR.

View file

@ -104,7 +104,6 @@ struct Player
double nIdxBobZ; double nIdxBobZ;
double nPrevWeapBob; double nPrevWeapBob;
double nWeapBob; double nWeapBob;
double nStrafeRoll;
bool crouch_toggle; bool crouch_toggle;
bool bTouchFloor; bool bTouchFloor;
bool bJumping; bool bJumping;

View file

@ -1837,6 +1837,7 @@ struct PLAYER
char cookieQuote[256]; // Should be an FString but must be POD for now so that PLAYER remains POD. char cookieQuote[256]; // Should be an FString but must be POD for now so that PLAYER remains POD.
int cookieTime; int cookieTime;
double height; double height;
double svel;
uint8_t WpnReloadState; uint8_t WpnReloadState;

View file

@ -2038,9 +2038,11 @@ void DoPlayerMove(PLAYER* pp)
DoPlayerSlide(pp); DoPlayerSlide(pp);
pp->ovect = pp->vect; pp->ovect = pp->vect;
pp->Angles.PrevStrafeVel = pp->Angles.StrafeVel;
pp->vect.X += pp->input.fvel * INPUT_SCALE; pp->vect.X += pp->input.fvel * INPUT_SCALE;
pp->vect.Y += pp->input.svel * INPUT_SCALE; pp->vect.Y += pp->input.svel * INPUT_SCALE;
pp->Angles.StrafeVel += pp->svel * INPUT_SCALE;
friction = pp->friction; friction = pp->friction;
if (!(pp->Flags & PF_SWIMMING) && pp->WadeDepth) if (!(pp->Flags & PF_SWIMMING) && pp->WadeDepth)
@ -2049,23 +2051,32 @@ void DoPlayerMove(PLAYER* pp)
} }
pp->vect *= FixedToFloat(friction); pp->vect *= FixedToFloat(friction);
pp->Angles.StrafeVel *= FixedToFloat(friction);
if (pp->Flags & (PF_FLYING)) if (pp->Flags & (PF_FLYING))
{ {
// do a bit of weighted averaging // do a bit of weighted averaging
pp->vect = (pp->vect + (pp->ovect*1))/2; pp->vect = (pp->vect + (pp->ovect*1))/2;
pp->Angles.StrafeVel = (pp->Angles.StrafeVel + (pp->Angles.PrevStrafeVel*1))/2;
} }
else if (pp->Flags & (PF_DIVING)) else if (pp->Flags & (PF_DIVING))
{ {
// do a bit of weighted averaging // do a bit of weighted averaging
pp->vect = (pp->vect + (pp->ovect*2))/3; pp->vect = (pp->vect + (pp->ovect*2))/3;
pp->Angles.StrafeVel = (pp->Angles.StrafeVel + (pp->Angles.PrevStrafeVel*2))/3;
} }
if (abs(pp->vect.X) < 0.05 && abs(pp->vect.Y) < 0.05) if (abs(pp->vect.X) < 0.05 && abs(pp->vect.Y) < 0.05)
{
pp->vect.Zero(); pp->vect.Zero();
pp->Angles.StrafeVel = 0;
}
actor->vel.X = pp->vect.Length(); actor->vel.X = pp->vect.Length();
constexpr auto maxVel = (380401538. / 36022361.);
pp->Angles.doViewTilting(&pp->input, pp->vect, maxVel, pp->Flags & (PF_SWIMMING|PF_DIVING));
if (pp->Flags & (PF_CLIP_CHEAT)) if (pp->Flags & (PF_CLIP_CHEAT))
{ {
auto sect = pp->cursector; auto sect = pp->cursector;
@ -6971,6 +6982,9 @@ void domovethings(void)
DoPlayerSectorUpdatePreMove(pp); DoPlayerSectorUpdatePreMove(pp);
ChopsCheck(pp); ChopsCheck(pp);
// Get strafe value before it's rotated by the angle.
pp->svel = pp->input.svel;
// convert fvel/svel into a vector before performing actions. // convert fvel/svel into a vector before performing actions.
const auto velvect = DVector2(pp->input.fvel, pp->input.svel).Rotated(pp->actor->spr.Angles.Yaw); const auto velvect = DVector2(pp->input.fvel, pp->input.svel).Rotated(pp->actor->spr.Angles.Yaw);
pp->input.fvel = (float)velvect.X; pp->input.fvel = (float)velvect.X;

View file

@ -1132,14 +1132,14 @@ OptionMenu "VideoOptions" protected
Option "$DSPLYMNU_VIEWBOB", "cl_viewbob", "ViewBobbing" Option "$DSPLYMNU_VIEWBOB", "cl_viewbob", "ViewBobbing"
Slider "$DSPLYMNU_VIEWBOBSPEED", "cl_exviewbobspeed", 0.0, 10.0, 0.1 Slider "$DSPLYMNU_VIEWBOBSPEED", "cl_exviewbobspeed", 0.0, 10.0, 0.1
Slider "$DSPLYMNU_VIEWBOBHEIGHT", "cl_exviewbobheight", 0.0, 20.0, 0.1 Slider "$DSPLYMNU_VIEWBOBHEIGHT", "cl_exviewbobheight", 0.0, 20.0, 0.1
Option "$DSPLYMNU_VIEWTILTING", "cl_exviewtilting", "ViewTilting"
Slider "$DSPLYMNU_VIEWTILTSCALE", "cl_extiltscale", 0.0, 2.0, 0.05
} }
ifgame(Blood) ifgame(Blood)
{ {
Option "$DSPLYMNU_VIEWBOB", "cl_viewvbob", "OnOff" Option "$DSPLYMNU_VIEWBOB", "cl_viewvbob", "OnOff"
Option "$DSPLYMNU_VIEWSWAY", "cl_viewhbob", "OnOff" Option "$DSPLYMNU_VIEWSWAY", "cl_viewhbob", "OnOff"
} }
Option "$DSPLYMNU_VIEWTILTING", "cl_viewtilting", "ViewTilting"
Slider "$DSPLYMNU_VIEWTILTSCALE", "cl_viewtiltscale", 0.0, 2.0, 0.05
Slider "$DSPLYMNU_FOV", "r_fov", 60, 130, 10, 1 Slider "$DSPLYMNU_FOV", "r_fov", 60, 130, 10, 1
StaticText "" StaticText ""