Added pitch fly mode (#7817)
authorGaël C <gael-de-sailly@netc.eu>
Sat, 1 Dec 2018 09:01:32 +0000 (10:01 +0100)
committerSmallJoker <SmallJoker@users.noreply.github.com>
Sat, 1 Dec 2018 09:01:32 +0000 (10:01 +0100)
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)

README.md
builtin/settingtypes.txt
minetest.conf.example
src/client/game.cpp
src/client/inputhandler.cpp
src/client/keys.h
src/client/localplayer.cpp
src/client/localplayer.h
src/defaultsettings.cpp
src/player.cpp
src/player.h

index 3cc0be09ea135e10ca442f942b7d845244d66418..5846a9783a716e4073490d277f98145757207fd1 100644 (file)
--- 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                                         |
index 950de5d1cd34fdb7b4a4254c2ff1ef04155e4f03..3effd694a4a3feeba55ccb18a5dfec536e736825 100644 (file)
@@ -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
index ccb57520ce7412f016ac3f8e1f62c2bae9637fe9..173b85c700a26dd5126c9535e406af82c2b98ca9 100644 (file)
 #    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
 #    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
index 6cf6723e9368a02a925e6853e2b14b9c681d7648..418b412fa5f3406dda77385af54e4f8e7b67800f 100644 (file)
@@ -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");
index e465c018a13a8f0807f44b150d552be8238e184a..29c68cf0132aac2e7ac0478b25a921acd24203eb 100644 (file)
@@ -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");
index e7ef5f4569d1accc1c24db1910500cd13dcb2d5b..15e46293c47356147db7ceecb23e014f019ecb15 100644 (file)
@@ -47,6 +47,7 @@ public:
                CONSOLE,
                MINIMAP,
                FREEMOVE,
+               PITCHFLY,
                FASTMOVE,
                NOCLIP,
                HOTBAR_PREV,
index 1c65d3b4d210d3aeeefa74215cbd6a3425fb1efc..c15c909318afb3862d2134ef84ca61a72c94a9ed 100644 (file)
@@ -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
index 7148bc4ded9c8837a8372d2c42583dc1aa9dbf15..28404aa012f92018b10bc6ba5ad2ac563dda879e 100644 (file)
@@ -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,
index e12ad0b3bc3c8cd569204ef8b82f7762883bca72..095ebc8412566b440c10214a13292d6c3c160f3e 100644 (file)
@@ -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");
index 4b104a71b924c65082de297a827807b7d47df4f9..f00eb082917da17f3fd0c35cbe3ec0c8010101a0 100644 (file)
@@ -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");
index 67449154616b1a6f12b13200ef0eaa01f765a0b8..9af6e5cac595f9da957e9c41767a87e84877f30f 100644 (file)
@@ -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();