summaryrefslogtreecommitdiff
path: root/src/client/localplayer.cpp
diff options
context:
space:
mode:
authorGaƫl C <gael-de-sailly@netc.eu>2018-12-01 10:01:32 +0100
committerSmallJoker <SmallJoker@users.noreply.github.com>2018-12-01 10:01:32 +0100
commit327bad2eafb8cfc05b7f831992be5700a167a53c (patch)
tree682d70aca114d7d350ed23b22075c96c2fc549be /src/client/localplayer.cpp
parentdcf58a3ad0c1092b3537039ee55892bb7dc83dee (diff)
downloadminetest-327bad2eafb8cfc05b7f831992be5700a167a53c.tar.gz
minetest-327bad2eafb8cfc05b7f831992be5700a167a53c.tar.bz2
minetest-327bad2eafb8cfc05b7f831992be5700a167a53c.zip
Added pitch fly mode (#7817)
In pitch fly mode, you fly to the exact direction you are pointing at, using the forward key. Other move directions are also pitched accordingly. It allows smoother and more complex movements. Can be enabled/disabled by L key by default (set keymap_pitchfly in minetest.conf)
Diffstat (limited to 'src/client/localplayer.cpp')
-rw-r--r--src/client/localplayer.cpp92
1 files changed, 50 insertions, 42 deletions
diff --git a/src/client/localplayer.cpp b/src/client/localplayer.cpp
index 1c65d3b4d..c15c90931 100644
--- a/src/client/localplayer.cpp
+++ b/src/client/localplayer.cpp
@@ -481,9 +481,9 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
PlayerSettings &player_settings = getPlayerSettings();
- v3f move_direction = v3f(0,0,1);
- move_direction.rotateXZBy(getYaw());
-
+ // All vectors are relative to the player's yaw,
+ // (and pitch if pitch fly mode enabled),
+ // and will be rotated at the end
v3f speedH = v3f(0,0,0); // Horizontal (X, Z)
v3f speedV = v3f(0,0,0); // Vertical (Y)
@@ -492,6 +492,7 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
bool free_move = fly_allowed && player_settings.free_move;
bool fast_move = fast_allowed && player_settings.fast_move;
+ bool pitch_fly = free_move && player_settings.pitch_fly;
// When aux1_descends is enabled the fast key is used to go down, so fast isn't possible
bool fast_climb = fast_move && control.aux1 && !player_settings.aux1_descends;
bool continuous_forward = player_settings.continuous_forward;
@@ -582,31 +583,31 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
}
if (continuous_forward)
- speedH += move_direction;
+ speedH += v3f(0,0,1);
if (control.up) {
if (continuous_forward) {
if (fast_move)
superspeed = true;
} else {
- speedH += move_direction;
+ speedH += v3f(0,0,1);
}
}
if (control.down) {
- speedH -= move_direction;
+ speedH -= v3f(0,0,1);
}
if (!control.up && !control.down) {
- speedH -= move_direction *
+ speedH -= v3f(0,0,1) *
(control.forw_move_joystick_axis / 32767.f);
}
if (control.left) {
- speedH += move_direction.crossProduct(v3f(0,1,0));
+ speedH += v3f(-1,0,0);
}
if (control.right) {
- speedH += move_direction.crossProduct(v3f(0,-1,0));
+ speedH += v3f(1,0,0);
}
if (!control.left && !control.right) {
- speedH -= move_direction.crossProduct(v3f(0,1,0)) *
+ speedH += v3f(1,0,0) *
(control.sidew_move_joystick_axis / 32767.f);
}
if(control.jump)
@@ -685,10 +686,9 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
slip_factor = getSlipFactor(env, speedH);
// Accelerate to target speed with maximum increment
- accelerateHorizontal(speedH * physics_override_speed,
- incH * physics_override_speed * slip_factor);
- accelerateVertical(speedV * physics_override_speed,
- incV * physics_override_speed);
+ accelerate((speedH + speedV) * physics_override_speed,
+ incH * physics_override_speed * slip_factor, incV * physics_override_speed,
+ pitch_fly);
}
v3s16 LocalPlayer::getStandingNodePos()
@@ -725,38 +725,46 @@ v3f LocalPlayer::getEyeOffset() const
return v3f(0, BS * eye_height, 0);
}
-// Horizontal acceleration (X and Z), Y direction is ignored
-void LocalPlayer::accelerateHorizontal(const v3f &target_speed,
- const f32 max_increase)
+// 3D acceleration
+void LocalPlayer::accelerate(const v3f &target_speed, const f32 max_increase_H,
+ const f32 max_increase_V, const bool use_pitch)
{
- if (max_increase == 0)
- return;
-
- v3f d_wanted = target_speed - m_speed;
- d_wanted.Y = 0.0f;
- f32 dl = d_wanted.getLength();
- if (dl > max_increase)
- dl = max_increase;
-
- v3f d = d_wanted.normalize() * dl;
-
- m_speed.X += d.X;
- m_speed.Z += d.Z;
-}
+ const f32 yaw = getYaw();
+ const f32 pitch = getPitch();
+ v3f flat_speed = m_speed;
+ // Rotate speed vector by -yaw and -pitch to make it relative to the player's yaw and pitch
+ flat_speed.rotateXZBy(-yaw);
+ if (use_pitch)
+ flat_speed.rotateYZBy(-pitch);
+
+ v3f d_wanted = target_speed - flat_speed;
+ v3f d = v3f(0,0,0);
+
+ // Then compare the horizontal and vertical components with the wanted speed
+ if (max_increase_H > 0) {
+ v3f d_wanted_H = d_wanted * v3f(1,0,1);
+ if (d_wanted_H.getLength() > max_increase_H)
+ d += d_wanted_H.normalize() * max_increase_H;
+ else
+ d += d_wanted_H;
+ }
-// Vertical acceleration (Y), X and Z directions are ignored
-void LocalPlayer::accelerateVertical(const v3f &target_speed, const f32 max_increase)
-{
- if (max_increase == 0)
- return;
+ if (max_increase_V > 0) {
+ f32 d_wanted_V = d_wanted.Y;
+ if (d_wanted_V > max_increase_V)
+ d.Y += max_increase_V;
+ else if (d_wanted_V < -max_increase_V)
+ d.Y -= max_increase_V;
+ else
+ d.Y += d_wanted_V;
+ }
- f32 d_wanted = target_speed.Y - m_speed.Y;
- if (d_wanted > max_increase)
- d_wanted = max_increase;
- else if (d_wanted < -max_increase)
- d_wanted = -max_increase;
+ // Finally rotate it again
+ if (use_pitch)
+ d.rotateYZBy(pitch);
+ d.rotateXZBy(yaw);
- m_speed.Y += d_wanted;
+ m_speed += d;
}
// Temporary option for old move code