summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--builtin/settingtypes.txt7
-rw-r--r--minetest.conf.example9
-rw-r--r--src/client/game.cpp16
-rw-r--r--src/client/inputhandler.cpp1
-rw-r--r--src/client/keys.h1
-rw-r--r--src/client/localplayer.cpp92
-rw-r--r--src/client/localplayer.h4
-rw-r--r--src/defaultsettings.cpp2
-rw-r--r--src/player.cpp1
-rw-r--r--src/player.h5
11 files changed, 93 insertions, 46 deletions
diff --git a/README.md b/README.md
index 3cc0be09e..5846a9783 100644
--- a/README.md
+++ b/README.md
@@ -52,6 +52,7 @@ Some can be changed in the key config dialog in the settings tab.
| + | Increase view range |
| - | Decrease view range |
| K | Enable/disable fly mode (needs fly privilege) |
+| L | Enable/disable pitch fly mode |
| J | Enable/disable fast mode (needs fast privilege) |
| H | Enable/disable noclip mode (needs noclip privilege) |
| E | Move fast in fast mode |
diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt
index 950de5d1c..3effd694a 100644
--- a/builtin/settingtypes.txt
+++ b/builtin/settingtypes.txt
@@ -72,6 +72,9 @@ enable_build_where_you_stand (Build inside player) bool false
# This requires the "fly" privilege on the server.
free_move (Flying) bool false
+# If enabled together with fly mode, makes move directions relative to the player's pitch.
+pitch_fly (Pitch fly mode) bool false
+
# Fast movement (via the "special" key).
# This requires the "fast" privilege on the server.
fast_move (Fast movement) bool false
@@ -208,6 +211,10 @@ keymap_rangeselect (Range select key) key KEY_KEY_R
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_freemove (Fly key) key KEY_KEY_K
+# Key for toggling pitch fly mode.
+# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
+keymap_pitchfly (Pitch fly key) key KEY_KEY_L
+
# Key for toggling fast mode.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_fastmove (Fast key) key KEY_KEY_J
diff --git a/minetest.conf.example b/minetest.conf.example
index ccb57520c..173b85c70 100644
--- a/minetest.conf.example
+++ b/minetest.conf.example
@@ -26,6 +26,10 @@
# type: bool
# free_move = false
+# If enabled together with fly mode, makes move directions relative to the player's pitch.
+# type: bool
+# pitch_fly = false
+
# Fast movement (via the "special" key).
# This requires the "fast" privilege on the server.
# type: bool
@@ -194,6 +198,11 @@
# type: key
# keymap_freemove = KEY_KEY_K
+# Key for toggling pitch fly mode.
+# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
+# type: key
+# keymap_pitchfly = KEY_KEY_L
+
# Key for toggling fast mode.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
# type: key
diff --git a/src/client/game.cpp b/src/client/game.cpp
index 6cf6723e9..418b412fa 100644
--- a/src/client/game.cpp
+++ b/src/client/game.cpp
@@ -701,6 +701,7 @@ protected:
void openConsole(float scale, const wchar_t *line=NULL);
void toggleFreeMove();
void toggleFreeMoveAlt();
+ void togglePitchFly();
void toggleFast();
void toggleNoClip();
void toggleCinematic();
@@ -1896,6 +1897,8 @@ void Game::processKeyInput()
toggleFreeMove();
} else if (wasKeyDown(KeyType::JUMP)) {
toggleFreeMoveAlt();
+ } else if (wasKeyDown(KeyType::PITCHFLY)) {
+ togglePitchFly();
} else if (wasKeyDown(KeyType::FASTMOVE)) {
toggleFast();
} else if (wasKeyDown(KeyType::NOCLIP)) {
@@ -2107,6 +2110,19 @@ void Game::toggleFreeMoveAlt()
}
+void Game::togglePitchFly()
+{
+ bool pitch_fly = !g_settings->getBool("pitch_fly");
+ g_settings->set("pitch_fly", bool_to_cstr(pitch_fly));
+
+ if (pitch_fly) {
+ m_game_ui->showTranslatedStatusText("Pitch fly mode enabled");
+ } else {
+ m_game_ui->showTranslatedStatusText("Pitch fly mode disabled");
+ }
+}
+
+
void Game::toggleFast()
{
bool fast_move = !g_settings->getBool("fast_move");
diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp
index e465c018a..29c68cf01 100644
--- a/src/client/inputhandler.cpp
+++ b/src/client/inputhandler.cpp
@@ -47,6 +47,7 @@ void KeyCache::populate()
key[KeyType::CONSOLE] = getKeySetting("keymap_console");
key[KeyType::MINIMAP] = getKeySetting("keymap_minimap");
key[KeyType::FREEMOVE] = getKeySetting("keymap_freemove");
+ key[KeyType::PITCHFLY] = getKeySetting("keymap_pitchfly");
key[KeyType::FASTMOVE] = getKeySetting("keymap_fastmove");
key[KeyType::NOCLIP] = getKeySetting("keymap_noclip");
key[KeyType::HOTBAR_PREV] = getKeySetting("keymap_hotbar_previous");
diff --git a/src/client/keys.h b/src/client/keys.h
index e7ef5f456..15e46293c 100644
--- a/src/client/keys.h
+++ b/src/client/keys.h
@@ -47,6 +47,7 @@ public:
CONSOLE,
MINIMAP,
FREEMOVE,
+ PITCHFLY,
FASTMOVE,
NOCLIP,
HOTBAR_PREV,
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
diff --git a/src/client/localplayer.h b/src/client/localplayer.h
index 7148bc4de..28404aa01 100644
--- a/src/client/localplayer.h
+++ b/src/client/localplayer.h
@@ -149,8 +149,8 @@ public:
bool getAutojump() const { return m_autojump; }
private:
- void accelerateHorizontal(const v3f &target_speed, const f32 max_increase);
- void accelerateVertical(const v3f &target_speed, const f32 max_increase);
+ void accelerate(const v3f &target_speed, const f32 max_increase_H,
+ const f32 max_increase_V, const bool use_pitch);
bool updateSneakNode(Map *map, const v3f &position, const v3f &sneak_max);
float getSlipFactor(Environment *env, const v3f &speedH);
void handleAutojump(f32 dtime, Environment *env,
diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
index e12ad0b3b..095ebc841 100644
--- a/src/defaultsettings.cpp
+++ b/src/defaultsettings.cpp
@@ -43,6 +43,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("meshgen_block_cache_size", "20");
settings->setDefault("enable_vbo", "true");
settings->setDefault("free_move", "false");
+ settings->setDefault("pitch_fly", "false");
settings->setDefault("fast_move", "false");
settings->setDefault("noclip", "false");
settings->setDefault("screenshot_path", ".");
@@ -80,6 +81,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("keymap_console", "KEY_F10");
settings->setDefault("keymap_rangeselect", "KEY_KEY_R");
settings->setDefault("keymap_freemove", "KEY_KEY_K");
+ settings->setDefault("keymap_pitchfly", "KEY_KEY_L");
settings->setDefault("keymap_fastmove", "KEY_KEY_J");
settings->setDefault("keymap_noclip", "KEY_KEY_H");
settings->setDefault("keymap_hotbar_next", "KEY_KEY_N");
diff --git a/src/player.cpp b/src/player.cpp
index 4b104a71b..f00eb0829 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -139,6 +139,7 @@ void Player::clearHud()
void PlayerSettings::readGlobalSettings()
{
free_move = g_settings->getBool("free_move");
+ pitch_fly = g_settings->getBool("pitch_fly");
fast_move = g_settings->getBool("fast_move");
continuous_forward = g_settings->getBool("continuous_forward");
always_fly_fast = g_settings->getBool("always_fly_fast");
diff --git a/src/player.h b/src/player.h
index 674491546..9af6e5cac 100644
--- a/src/player.h
+++ b/src/player.h
@@ -87,6 +87,7 @@ struct PlayerControl
struct PlayerSettings
{
bool free_move = false;
+ bool pitch_fly = false;
bool fast_move = false;
bool continuous_forward = false;
bool always_fly_fast = false;
@@ -94,8 +95,8 @@ struct PlayerSettings
bool noclip = false;
bool autojump = false;
- const std::string setting_names[7] = {
- "free_move", "fast_move", "continuous_forward", "always_fly_fast",
+ const std::string setting_names[8] = {
+ "free_move", "pitch_fly", "fast_move", "continuous_forward", "always_fly_fast",
"aux1_descends", "noclip", "autojump"
};
void readGlobalSettings();