Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
Gael-de-Sailly authored and SmallJoker committed Dec 1, 2018
1 parent dcf58a3 commit 327bad2
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 46 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -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 |
Expand Down
7 changes: 7 additions & 0 deletions builtin/settingtypes.txt
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions minetest.conf.example
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions src/client/game.cpp
Expand Up @@ -701,6 +701,7 @@ class Game {
void openConsole(float scale, const wchar_t *line=NULL);
void toggleFreeMove();
void toggleFreeMoveAlt();
void togglePitchFly();
void toggleFast();
void toggleNoClip();
void toggleCinematic();
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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");
Expand Down
1 change: 1 addition & 0 deletions src/client/inputhandler.cpp
Expand Up @@ -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");
Expand Down
1 change: 1 addition & 0 deletions src/client/keys.h
Expand Up @@ -47,6 +47,7 @@ class KeyType
CONSOLE,
MINIMAP,
FREEMOVE,
PITCHFLY,
FASTMOVE,
NOCLIP,
HOTBAR_PREV,
Expand Down
92 changes: 50 additions & 42 deletions src/client/localplayer.cpp
Expand Up @@ -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)

Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/client/localplayer.h
Expand Up @@ -149,8 +149,8 @@ class LocalPlayer : public Player
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,
Expand Down
2 changes: 2 additions & 0 deletions src/defaultsettings.cpp
Expand Up @@ -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", ".");
Expand Down Expand Up @@ -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");
Expand Down
1 change: 1 addition & 0 deletions src/player.cpp
Expand Up @@ -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");
Expand Down
5 changes: 3 additions & 2 deletions src/player.h
Expand Up @@ -87,15 +87,16 @@ 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;
bool aux1_descends = false;
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();
Expand Down

0 comments on commit 327bad2

Please sign in to comment.