From 2bdd0a6bdb372b6fe71170ab8c78995ab758f820 Mon Sep 17 00:00:00 2001 From: grorp Date: Tue, 30 Apr 2024 13:50:01 +0200 Subject: [PATCH] Add physics overrides for walk speed and Fast Mode (#14475) Co-authored-by: Wuzzy --- doc/client_lua_api.md | 19 +++++++++++-- doc/lua_api.md | 13 +++++++-- src/client/content_cao.cpp | 15 +++++++++- src/client/localplayer.cpp | 41 +++++++++++++++------------- src/player.h | 5 +++- src/script/lua_api/l_localplayer.cpp | 9 ++++++ src/script/lua_api/l_object.cpp | 9 ++++++ src/server/player_sao.cpp | 16 +++++++---- 8 files changed, 94 insertions(+), 33 deletions(-) diff --git a/doc/client_lua_api.md b/doc/client_lua_api.md index 99f341de9..260603971 100644 --- a/doc/client_lua_api.md +++ b/doc/client_lua_api.md @@ -702,8 +702,18 @@ Methods: ```lua { speed = float, + speed_climb = float, + speed_crouch = float, + speed_fast = float, + speed_walk = float, + acceleration_default = float, + acceleration_air = float, + acceleration_fast = float, jump = float, gravity = float, + liquid_fluidity = float, + liquid_fluidity_smooth = float, + liquid_sink = float, sneak = boolean, sneak_glitch = boolean, new_move = boolean, @@ -719,7 +729,8 @@ Methods: * `get_breath()` * returns the player's breath * `get_movement_acceleration()` - * returns acceleration of the player in different environments: + * returns acceleration of the player in different environments + (note: does not take physics overrides into account): ```lua { @@ -730,7 +741,8 @@ Methods: ``` * `get_movement_speed()` - * returns player's speed in different environments: + * returns player's speed in different environments + (note: does not take physics overrides into account): ```lua { @@ -743,7 +755,8 @@ Methods: ``` * `get_movement()` - * returns player's movement in different environments: + * returns player's movement in different environments + (note: does not take physics overrides into account): ```lua { diff --git a/doc/lua_api.md b/doc/lua_api.md index b4c1613c2..ca09f436b 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -8089,13 +8089,18 @@ child will follow movement and rotation of that bone. * `set_physics_override(override_table)` * Overrides the physics attributes of the player * `override_table` is a table with the following fields: - * `speed`: multiplier to default movement speed and acceleration values (default: `1`) - * `jump`: multiplier to default jump value (default: `1`) - * `gravity`: multiplier to default gravity value (default: `1`) + * `speed`: multiplier to *all* movement speed (`speed_*`) and + acceleration (`acceleration_*`) values (default: `1`) + * `speed_walk`: multiplier to default walk speed value (default: `1`) + * Note: The actual walk speed is the product of `speed` and `speed_walk` * `speed_climb`: multiplier to default climb speed value (default: `1`) * Note: The actual climb speed is the product of `speed` and `speed_climb` * `speed_crouch`: multiplier to default sneak speed value (default: `1`) * Note: The actual sneak speed is the product of `speed` and `speed_crouch` + * `speed_fast`: multiplier to default speed value in Fast Mode (default: `1`) + * Note: The actual fast speed is the product of `speed` and `speed_fast` + * `jump`: multiplier to default jump value (default: `1`) + * `gravity`: multiplier to default gravity value (default: `1`) * `liquid_fluidity`: multiplier to liquid movement resistance value (for nodes with `liquid_move_physics`); the higher this value, the lower the resistance to movement. At `math.huge`, the resistance is zero and you can @@ -8113,6 +8118,8 @@ child will follow movement and rotation of that bone. * `acceleration_air`: multiplier to acceleration when jumping or falling (default: `1`) * Note: The actual acceleration is the product of `speed` and `acceleration_air` + * `acceleration_fast`: multiplier to acceleration in Fast Mode (default: `1`) + * Note: The actual acceleration is the product of `speed` and `acceleration_fast` * `sneak`: whether player can sneak (default: `true`) * `sneak_glitch`: whether player can use the new move code replications of the old sneak side-effects: sneak ladders and 2 node sneak jump diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 945f41e89..0044cc16e 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -1804,6 +1804,7 @@ void GenericCAO::processMessage(const std::string &data) bool sneak_glitch = !readU8(is); bool new_move = !readU8(is); + // new overrides since 5.8.0 float override_speed_climb = readF32(is); float override_speed_crouch = readF32(is); float override_liquid_fluidity = readF32(is); @@ -1811,7 +1812,6 @@ void GenericCAO::processMessage(const std::string &data) float override_liquid_sink = readF32(is); float override_acceleration_default = readF32(is); float override_acceleration_air = readF32(is); - // fallback for new overrides (since 5.8.0) if (is.eof()) { override_speed_climb = 1.0f; override_speed_crouch = 1.0f; @@ -1822,6 +1822,16 @@ void GenericCAO::processMessage(const std::string &data) override_acceleration_air = 1.0f; } + // new overrides since 5.9.0 + float override_speed_fast = readF32(is); + float override_acceleration_fast = readF32(is); + float override_speed_walk = readF32(is); + if (is.eof()) { + override_speed_fast = 1.0f; + override_acceleration_fast = 1.0f; + override_speed_walk = 1.0f; + } + if (m_is_local_player) { auto &phys = m_env->getLocalPlayer()->physics_override; phys.speed = override_speed; @@ -1837,6 +1847,9 @@ void GenericCAO::processMessage(const std::string &data) phys.liquid_sink = override_liquid_sink; phys.acceleration_default = override_acceleration_default; phys.acceleration_air = override_acceleration_air; + phys.speed_fast = override_speed_fast; + phys.acceleration_fast = override_acceleration_fast; + phys.speed_walk = override_speed_walk; } } else if (cmd == AO_CMD_SET_ANIMATION) { // TODO: change frames send as v2s32 value diff --git a/src/client/localplayer.cpp b/src/client/localplayer.cpp index e606e1edc..796c89306 100644 --- a/src/client/localplayer.cpp +++ b/src/client/localplayer.cpp @@ -586,6 +586,9 @@ void LocalPlayer::applyControl(float dtime, Environment *env) // Whether superspeed mode is used or not bool superspeed = false; + const f32 speed_walk = movement_speed_walk * physics_override.speed_walk; + const f32 speed_fast = movement_speed_fast * physics_override.speed_fast; + if (always_fly_fast && free_move && fast_move) superspeed = true; @@ -600,11 +603,11 @@ void LocalPlayer::applyControl(float dtime, Environment *env) if (free_move) { // In free movement mode, aux1 descends if (fast_move) - speedV.Y = -movement_speed_fast; + speedV.Y = -speed_fast; else - speedV.Y = -movement_speed_walk; + speedV.Y = -speed_walk; } else if ((in_liquid || in_liquid_stable) && !m_disable_descend) { - speedV.Y = -movement_speed_walk; + speedV.Y = -speed_walk; swimming_vertical = true; } else if (is_climbing && !m_disable_descend) { speedV.Y = -movement_speed_climb * physics_override.speed_climb; @@ -632,18 +635,18 @@ void LocalPlayer::applyControl(float dtime, Environment *env) if (free_move) { // In free movement mode, sneak descends if (fast_move && (control.aux1 || always_fly_fast)) - speedV.Y = -movement_speed_fast; + speedV.Y = -speed_fast; else - speedV.Y = -movement_speed_walk; + speedV.Y = -speed_walk; } else if ((in_liquid || in_liquid_stable) && !m_disable_descend) { if (fast_climb) - speedV.Y = -movement_speed_fast; + speedV.Y = -speed_fast; else - speedV.Y = -movement_speed_walk; + speedV.Y = -speed_walk; swimming_vertical = true; } else if (is_climbing && !m_disable_descend) { if (fast_climb) - speedV.Y = -movement_speed_fast; + speedV.Y = -speed_fast; else speedV.Y = -movement_speed_climb * physics_override.speed_climb; } @@ -666,14 +669,14 @@ void LocalPlayer::applyControl(float dtime, Environment *env) // Don't fly up if sneak key is pressed if (player_settings.aux1_descends || always_fly_fast) { if (fast_move) - speedV.Y = movement_speed_fast; + speedV.Y = speed_fast; else - speedV.Y = movement_speed_walk; + speedV.Y = speed_walk; } else { if (fast_move && control.aux1) - speedV.Y = movement_speed_fast; + speedV.Y = speed_fast; else - speedV.Y = movement_speed_walk; + speedV.Y = speed_walk; } } } else if (m_can_jump) { @@ -690,13 +693,13 @@ void LocalPlayer::applyControl(float dtime, Environment *env) } } else if (in_liquid && !m_disable_jump && !control.sneak) { if (fast_climb) - speedV.Y = movement_speed_fast; + speedV.Y = speed_fast; else - speedV.Y = movement_speed_walk; + speedV.Y = speed_walk; swimming_vertical = true; } else if (is_climbing && !m_disable_jump && !control.sneak) { if (fast_climb) - speedV.Y = movement_speed_fast; + speedV.Y = speed_fast; else speedV.Y = movement_speed_climb * physics_override.speed_climb; } @@ -705,11 +708,11 @@ void LocalPlayer::applyControl(float dtime, Environment *env) // The speed of the player (Y is ignored) if (superspeed || (is_climbing && fast_climb) || ((in_liquid || in_liquid_stable) && fast_climb)) - speedH = speedH.normalize() * movement_speed_fast; + speedH = speedH.normalize() * speed_fast; else if (control.sneak && !free_move && !in_liquid && !in_liquid_stable) speedH = speedH.normalize() * movement_speed_crouch * physics_override.speed_crouch; else - speedH = speedH.normalize() * movement_speed_walk; + speedH = speedH.normalize() * speed_walk; speedH *= control.movement_speed; /* Apply analog input */ @@ -720,13 +723,13 @@ void LocalPlayer::applyControl(float dtime, Environment *env) (!free_move && m_can_jump && control.jump)) { // Jumping and falling if (superspeed || (fast_move && control.aux1)) - incH = movement_acceleration_fast * BS * dtime; + incH = movement_acceleration_fast * physics_override.acceleration_fast * BS * dtime; else incH = movement_acceleration_air * physics_override.acceleration_air * BS * dtime; incV = 0.0f; // No vertical acceleration in air } else if (superspeed || (is_climbing && fast_climb) || ((in_liquid || in_liquid_stable) && fast_climb)) { - incH = incV = movement_acceleration_fast * BS * dtime; + incH = incV = movement_acceleration_fast * physics_override.acceleration_fast * BS * dtime; } else { incH = incV = movement_acceleration_default * physics_override.acceleration_default * BS * dtime; } diff --git a/src/player.h b/src/player.h index a79a13228..373c81780 100644 --- a/src/player.h +++ b/src/player.h @@ -126,6 +126,9 @@ struct PlayerPhysicsOverride float liquid_sink = 1.f; float acceleration_default = 1.f; float acceleration_air = 1.f; + float speed_fast = 1.f; + float acceleration_fast = 1.f; + float speed_walk = 1.f; private: auto tie() const { @@ -133,7 +136,7 @@ private: return std::tie( speed, jump, gravity, sneak, sneak_glitch, new_move, speed_climb, speed_crouch, liquid_fluidity, liquid_fluidity_smooth, liquid_sink, acceleration_default, - acceleration_air + acceleration_air, speed_fast, acceleration_fast, speed_walk ); } diff --git a/src/script/lua_api/l_localplayer.cpp b/src/script/lua_api/l_localplayer.cpp index dc88466f7..72913161d 100644 --- a/src/script/lua_api/l_localplayer.cpp +++ b/src/script/lua_api/l_localplayer.cpp @@ -198,6 +198,15 @@ int LuaLocalPlayer::l_get_physics_override(lua_State *L) lua_pushnumber(L, phys.acceleration_air); lua_setfield(L, -2, "acceleration_air"); + lua_pushnumber(L, phys.speed_fast); + lua_setfield(L, -2, "speed_fast"); + + lua_pushnumber(L, phys.acceleration_fast); + lua_setfield(L, -2, "acceleration_fast"); + + lua_pushnumber(L, phys.speed_walk); + lua_setfield(L, -2, "speed_walk"); + return 1; } diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index c78a87317..5e2e6607c 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1610,6 +1610,9 @@ int ObjectRef::l_set_physics_override(lua_State *L) getfloatfield(L, 2, "liquid_sink", phys.liquid_sink); getfloatfield(L, 2, "acceleration_default", phys.acceleration_default); getfloatfield(L, 2, "acceleration_air", phys.acceleration_air); + getfloatfield(L, 2, "speed_fast", phys.speed_fast); + getfloatfield(L, 2, "acceleration_fast", phys.acceleration_fast); + getfloatfield(L, 2, "speed_walk", phys.speed_walk); if (phys != old) playersao->m_physics_override_sent = false; @@ -1653,6 +1656,12 @@ int ObjectRef::l_get_physics_override(lua_State *L) lua_setfield(L, -2, "acceleration_default"); lua_pushnumber(L, phys.acceleration_air); lua_setfield(L, -2, "acceleration_air"); + lua_pushnumber(L, phys.speed_fast); + lua_setfield(L, -2, "speed_fast"); + lua_pushnumber(L, phys.acceleration_fast); + lua_setfield(L, -2, "acceleration_fast"); + lua_pushnumber(L, phys.speed_walk); + lua_setfield(L, -2, "speed_walk"); return 1; } diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index 29bd8045f..b2e2351c9 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -336,6 +336,9 @@ std::string PlayerSAO::generateUpdatePhysicsOverrideCommand() const writeF32(os, phys.liquid_sink); writeF32(os, phys.acceleration_default); writeF32(os, phys.acceleration_air); + writeF32(os, phys.speed_fast); + writeF32(os, phys.acceleration_fast); + writeF32(os, phys.speed_walk); return os.str(); } @@ -652,14 +655,15 @@ bool PlayerSAO::checkMovementCheat() float player_max_walk = 0; // horizontal movement float player_max_jump = 0; // vertical upwards movement - float speed_walk = m_player->movement_speed_walk; - float speed_fast = m_player->movement_speed_fast; + float speed_walk = m_player->movement_speed_walk * m_player->physics_override.speed_walk; + float speed_fast = m_player->movement_speed_fast * m_player->physics_override.speed_fast; float speed_crouch = m_player->movement_speed_crouch * m_player->physics_override.speed_crouch; - float speed_climb = m_player->movement_speed_climb * m_player->physics_override.speed_climb; - speed_walk *= m_player->physics_override.speed; - speed_fast *= m_player->physics_override.speed; + float speed_climb = m_player->movement_speed_climb * m_player->physics_override.speed_climb; + + speed_walk *= m_player->physics_override.speed; + speed_fast *= m_player->physics_override.speed; speed_crouch *= m_player->physics_override.speed; - speed_climb *= m_player->physics_override.speed; + speed_climb *= m_player->physics_override.speed; // Get permissible max. speed if (m_privs.count("fast") != 0) {