forked from Mirrorlandia_minetest/minetest
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)
This commit is contained in:
parent
dcf58a3ad0
commit
327bad2eaf
@ -52,6 +52,7 @@ Some can be changed in the key config dialog in the settings tab.
|
|||||||
| + | Increase view range |
|
| + | Increase view range |
|
||||||
| - | Decrease view range |
|
| - | Decrease view range |
|
||||||
| K | Enable/disable fly mode (needs fly privilege) |
|
| K | Enable/disable fly mode (needs fly privilege) |
|
||||||
|
| L | Enable/disable pitch fly mode |
|
||||||
| J | Enable/disable fast mode (needs fast privilege) |
|
| J | Enable/disable fast mode (needs fast privilege) |
|
||||||
| H | Enable/disable noclip mode (needs noclip privilege) |
|
| H | Enable/disable noclip mode (needs noclip privilege) |
|
||||||
| E | Move fast in fast mode |
|
| E | Move fast in fast mode |
|
||||||
|
@ -72,6 +72,9 @@ enable_build_where_you_stand (Build inside player) bool false
|
|||||||
# This requires the "fly" privilege on the server.
|
# This requires the "fly" privilege on the server.
|
||||||
free_move (Flying) bool false
|
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).
|
# Fast movement (via the "special" key).
|
||||||
# This requires the "fast" privilege on the server.
|
# This requires the "fast" privilege on the server.
|
||||||
fast_move (Fast movement) bool false
|
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
|
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||||
keymap_freemove (Fly key) key KEY_KEY_K
|
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.
|
# Key for toggling fast mode.
|
||||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||||
keymap_fastmove (Fast key) key KEY_KEY_J
|
keymap_fastmove (Fast key) key KEY_KEY_J
|
||||||
|
@ -26,6 +26,10 @@
|
|||||||
# type: bool
|
# type: bool
|
||||||
# free_move = false
|
# 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).
|
# Fast movement (via the "special" key).
|
||||||
# This requires the "fast" privilege on the server.
|
# This requires the "fast" privilege on the server.
|
||||||
# type: bool
|
# type: bool
|
||||||
@ -194,6 +198,11 @@
|
|||||||
# type: key
|
# type: key
|
||||||
# keymap_freemove = KEY_KEY_K
|
# 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.
|
# Key for toggling fast mode.
|
||||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||||
# type: key
|
# type: key
|
||||||
|
@ -701,6 +701,7 @@ protected:
|
|||||||
void openConsole(float scale, const wchar_t *line=NULL);
|
void openConsole(float scale, const wchar_t *line=NULL);
|
||||||
void toggleFreeMove();
|
void toggleFreeMove();
|
||||||
void toggleFreeMoveAlt();
|
void toggleFreeMoveAlt();
|
||||||
|
void togglePitchFly();
|
||||||
void toggleFast();
|
void toggleFast();
|
||||||
void toggleNoClip();
|
void toggleNoClip();
|
||||||
void toggleCinematic();
|
void toggleCinematic();
|
||||||
@ -1896,6 +1897,8 @@ void Game::processKeyInput()
|
|||||||
toggleFreeMove();
|
toggleFreeMove();
|
||||||
} else if (wasKeyDown(KeyType::JUMP)) {
|
} else if (wasKeyDown(KeyType::JUMP)) {
|
||||||
toggleFreeMoveAlt();
|
toggleFreeMoveAlt();
|
||||||
|
} else if (wasKeyDown(KeyType::PITCHFLY)) {
|
||||||
|
togglePitchFly();
|
||||||
} else if (wasKeyDown(KeyType::FASTMOVE)) {
|
} else if (wasKeyDown(KeyType::FASTMOVE)) {
|
||||||
toggleFast();
|
toggleFast();
|
||||||
} else if (wasKeyDown(KeyType::NOCLIP)) {
|
} 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()
|
void Game::toggleFast()
|
||||||
{
|
{
|
||||||
bool fast_move = !g_settings->getBool("fast_move");
|
bool fast_move = !g_settings->getBool("fast_move");
|
||||||
|
@ -47,6 +47,7 @@ void KeyCache::populate()
|
|||||||
key[KeyType::CONSOLE] = getKeySetting("keymap_console");
|
key[KeyType::CONSOLE] = getKeySetting("keymap_console");
|
||||||
key[KeyType::MINIMAP] = getKeySetting("keymap_minimap");
|
key[KeyType::MINIMAP] = getKeySetting("keymap_minimap");
|
||||||
key[KeyType::FREEMOVE] = getKeySetting("keymap_freemove");
|
key[KeyType::FREEMOVE] = getKeySetting("keymap_freemove");
|
||||||
|
key[KeyType::PITCHFLY] = getKeySetting("keymap_pitchfly");
|
||||||
key[KeyType::FASTMOVE] = getKeySetting("keymap_fastmove");
|
key[KeyType::FASTMOVE] = getKeySetting("keymap_fastmove");
|
||||||
key[KeyType::NOCLIP] = getKeySetting("keymap_noclip");
|
key[KeyType::NOCLIP] = getKeySetting("keymap_noclip");
|
||||||
key[KeyType::HOTBAR_PREV] = getKeySetting("keymap_hotbar_previous");
|
key[KeyType::HOTBAR_PREV] = getKeySetting("keymap_hotbar_previous");
|
||||||
|
@ -47,6 +47,7 @@ public:
|
|||||||
CONSOLE,
|
CONSOLE,
|
||||||
MINIMAP,
|
MINIMAP,
|
||||||
FREEMOVE,
|
FREEMOVE,
|
||||||
|
PITCHFLY,
|
||||||
FASTMOVE,
|
FASTMOVE,
|
||||||
NOCLIP,
|
NOCLIP,
|
||||||
HOTBAR_PREV,
|
HOTBAR_PREV,
|
||||||
|
@ -481,9 +481,9 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
|
|||||||
|
|
||||||
PlayerSettings &player_settings = getPlayerSettings();
|
PlayerSettings &player_settings = getPlayerSettings();
|
||||||
|
|
||||||
v3f move_direction = v3f(0,0,1);
|
// All vectors are relative to the player's yaw,
|
||||||
move_direction.rotateXZBy(getYaw());
|
// (and pitch if pitch fly mode enabled),
|
||||||
|
// and will be rotated at the end
|
||||||
v3f speedH = v3f(0,0,0); // Horizontal (X, Z)
|
v3f speedH = v3f(0,0,0); // Horizontal (X, Z)
|
||||||
v3f speedV = v3f(0,0,0); // Vertical (Y)
|
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 free_move = fly_allowed && player_settings.free_move;
|
||||||
bool fast_move = fast_allowed && player_settings.fast_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
|
// 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 fast_climb = fast_move && control.aux1 && !player_settings.aux1_descends;
|
||||||
bool continuous_forward = player_settings.continuous_forward;
|
bool continuous_forward = player_settings.continuous_forward;
|
||||||
@ -582,31 +583,31 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (continuous_forward)
|
if (continuous_forward)
|
||||||
speedH += move_direction;
|
speedH += v3f(0,0,1);
|
||||||
|
|
||||||
if (control.up) {
|
if (control.up) {
|
||||||
if (continuous_forward) {
|
if (continuous_forward) {
|
||||||
if (fast_move)
|
if (fast_move)
|
||||||
superspeed = true;
|
superspeed = true;
|
||||||
} else {
|
} else {
|
||||||
speedH += move_direction;
|
speedH += v3f(0,0,1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (control.down) {
|
if (control.down) {
|
||||||
speedH -= move_direction;
|
speedH -= v3f(0,0,1);
|
||||||
}
|
}
|
||||||
if (!control.up && !control.down) {
|
if (!control.up && !control.down) {
|
||||||
speedH -= move_direction *
|
speedH -= v3f(0,0,1) *
|
||||||
(control.forw_move_joystick_axis / 32767.f);
|
(control.forw_move_joystick_axis / 32767.f);
|
||||||
}
|
}
|
||||||
if (control.left) {
|
if (control.left) {
|
||||||
speedH += move_direction.crossProduct(v3f(0,1,0));
|
speedH += v3f(-1,0,0);
|
||||||
}
|
}
|
||||||
if (control.right) {
|
if (control.right) {
|
||||||
speedH += move_direction.crossProduct(v3f(0,-1,0));
|
speedH += v3f(1,0,0);
|
||||||
}
|
}
|
||||||
if (!control.left && !control.right) {
|
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);
|
(control.sidew_move_joystick_axis / 32767.f);
|
||||||
}
|
}
|
||||||
if(control.jump)
|
if(control.jump)
|
||||||
@ -685,10 +686,9 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
|
|||||||
slip_factor = getSlipFactor(env, speedH);
|
slip_factor = getSlipFactor(env, speedH);
|
||||||
|
|
||||||
// Accelerate to target speed with maximum increment
|
// Accelerate to target speed with maximum increment
|
||||||
accelerateHorizontal(speedH * physics_override_speed,
|
accelerate((speedH + speedV) * physics_override_speed,
|
||||||
incH * physics_override_speed * slip_factor);
|
incH * physics_override_speed * slip_factor, incV * physics_override_speed,
|
||||||
accelerateVertical(speedV * physics_override_speed,
|
pitch_fly);
|
||||||
incV * physics_override_speed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v3s16 LocalPlayer::getStandingNodePos()
|
v3s16 LocalPlayer::getStandingNodePos()
|
||||||
@ -725,38 +725,46 @@ v3f LocalPlayer::getEyeOffset() const
|
|||||||
return v3f(0, BS * eye_height, 0);
|
return v3f(0, BS * eye_height, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Horizontal acceleration (X and Z), Y direction is ignored
|
// 3D acceleration
|
||||||
void LocalPlayer::accelerateHorizontal(const v3f &target_speed,
|
void LocalPlayer::accelerate(const v3f &target_speed, const f32 max_increase_H,
|
||||||
const f32 max_increase)
|
const f32 max_increase_V, const bool use_pitch)
|
||||||
{
|
{
|
||||||
if (max_increase == 0)
|
const f32 yaw = getYaw();
|
||||||
return;
|
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 - m_speed;
|
v3f d_wanted = target_speed - flat_speed;
|
||||||
d_wanted.Y = 0.0f;
|
v3f d = v3f(0,0,0);
|
||||||
f32 dl = d_wanted.getLength();
|
|
||||||
if (dl > max_increase)
|
|
||||||
dl = max_increase;
|
|
||||||
|
|
||||||
v3f d = d_wanted.normalize() * dl;
|
// Then compare the horizontal and vertical components with the wanted speed
|
||||||
|
if (max_increase_H > 0) {
|
||||||
m_speed.X += d.X;
|
v3f d_wanted_H = d_wanted * v3f(1,0,1);
|
||||||
m_speed.Z += d.Z;
|
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
|
if (max_increase_V > 0) {
|
||||||
void LocalPlayer::accelerateVertical(const v3f &target_speed, const f32 max_increase)
|
f32 d_wanted_V = d_wanted.Y;
|
||||||
{
|
if (d_wanted_V > max_increase_V)
|
||||||
if (max_increase == 0)
|
d.Y += max_increase_V;
|
||||||
return;
|
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;
|
// Finally rotate it again
|
||||||
if (d_wanted > max_increase)
|
if (use_pitch)
|
||||||
d_wanted = max_increase;
|
d.rotateYZBy(pitch);
|
||||||
else if (d_wanted < -max_increase)
|
d.rotateXZBy(yaw);
|
||||||
d_wanted = -max_increase;
|
|
||||||
|
|
||||||
m_speed.Y += d_wanted;
|
m_speed += d;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporary option for old move code
|
// Temporary option for old move code
|
||||||
|
@ -149,8 +149,8 @@ public:
|
|||||||
bool getAutojump() const { return m_autojump; }
|
bool getAutojump() const { return m_autojump; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void accelerateHorizontal(const v3f &target_speed, const f32 max_increase);
|
void accelerate(const v3f &target_speed, const f32 max_increase_H,
|
||||||
void accelerateVertical(const v3f &target_speed, const f32 max_increase);
|
const f32 max_increase_V, const bool use_pitch);
|
||||||
bool updateSneakNode(Map *map, const v3f &position, const v3f &sneak_max);
|
bool updateSneakNode(Map *map, const v3f &position, const v3f &sneak_max);
|
||||||
float getSlipFactor(Environment *env, const v3f &speedH);
|
float getSlipFactor(Environment *env, const v3f &speedH);
|
||||||
void handleAutojump(f32 dtime, Environment *env,
|
void handleAutojump(f32 dtime, Environment *env,
|
||||||
|
@ -43,6 +43,7 @@ void set_default_settings(Settings *settings)
|
|||||||
settings->setDefault("meshgen_block_cache_size", "20");
|
settings->setDefault("meshgen_block_cache_size", "20");
|
||||||
settings->setDefault("enable_vbo", "true");
|
settings->setDefault("enable_vbo", "true");
|
||||||
settings->setDefault("free_move", "false");
|
settings->setDefault("free_move", "false");
|
||||||
|
settings->setDefault("pitch_fly", "false");
|
||||||
settings->setDefault("fast_move", "false");
|
settings->setDefault("fast_move", "false");
|
||||||
settings->setDefault("noclip", "false");
|
settings->setDefault("noclip", "false");
|
||||||
settings->setDefault("screenshot_path", ".");
|
settings->setDefault("screenshot_path", ".");
|
||||||
@ -80,6 +81,7 @@ void set_default_settings(Settings *settings)
|
|||||||
settings->setDefault("keymap_console", "KEY_F10");
|
settings->setDefault("keymap_console", "KEY_F10");
|
||||||
settings->setDefault("keymap_rangeselect", "KEY_KEY_R");
|
settings->setDefault("keymap_rangeselect", "KEY_KEY_R");
|
||||||
settings->setDefault("keymap_freemove", "KEY_KEY_K");
|
settings->setDefault("keymap_freemove", "KEY_KEY_K");
|
||||||
|
settings->setDefault("keymap_pitchfly", "KEY_KEY_L");
|
||||||
settings->setDefault("keymap_fastmove", "KEY_KEY_J");
|
settings->setDefault("keymap_fastmove", "KEY_KEY_J");
|
||||||
settings->setDefault("keymap_noclip", "KEY_KEY_H");
|
settings->setDefault("keymap_noclip", "KEY_KEY_H");
|
||||||
settings->setDefault("keymap_hotbar_next", "KEY_KEY_N");
|
settings->setDefault("keymap_hotbar_next", "KEY_KEY_N");
|
||||||
|
@ -139,6 +139,7 @@ void Player::clearHud()
|
|||||||
void PlayerSettings::readGlobalSettings()
|
void PlayerSettings::readGlobalSettings()
|
||||||
{
|
{
|
||||||
free_move = g_settings->getBool("free_move");
|
free_move = g_settings->getBool("free_move");
|
||||||
|
pitch_fly = g_settings->getBool("pitch_fly");
|
||||||
fast_move = g_settings->getBool("fast_move");
|
fast_move = g_settings->getBool("fast_move");
|
||||||
continuous_forward = g_settings->getBool("continuous_forward");
|
continuous_forward = g_settings->getBool("continuous_forward");
|
||||||
always_fly_fast = g_settings->getBool("always_fly_fast");
|
always_fly_fast = g_settings->getBool("always_fly_fast");
|
||||||
|
@ -87,6 +87,7 @@ struct PlayerControl
|
|||||||
struct PlayerSettings
|
struct PlayerSettings
|
||||||
{
|
{
|
||||||
bool free_move = false;
|
bool free_move = false;
|
||||||
|
bool pitch_fly = false;
|
||||||
bool fast_move = false;
|
bool fast_move = false;
|
||||||
bool continuous_forward = false;
|
bool continuous_forward = false;
|
||||||
bool always_fly_fast = false;
|
bool always_fly_fast = false;
|
||||||
@ -94,8 +95,8 @@ struct PlayerSettings
|
|||||||
bool noclip = false;
|
bool noclip = false;
|
||||||
bool autojump = false;
|
bool autojump = false;
|
||||||
|
|
||||||
const std::string setting_names[7] = {
|
const std::string setting_names[8] = {
|
||||||
"free_move", "fast_move", "continuous_forward", "always_fly_fast",
|
"free_move", "pitch_fly", "fast_move", "continuous_forward", "always_fly_fast",
|
||||||
"aux1_descends", "noclip", "autojump"
|
"aux1_descends", "noclip", "autojump"
|
||||||
};
|
};
|
||||||
void readGlobalSettings();
|
void readGlobalSettings();
|
||||||
|
Loading…
Reference in New Issue
Block a user