Sneak: Improve and fix various things
authorSmallJoker <mk939@ymail.com>
Sat, 1 Apr 2017 18:38:14 +0000 (20:38 +0200)
committerparamat <mat.gregory@virginmedia.com>
Wed, 3 May 2017 02:16:20 +0000 (03:16 +0100)
Remove useless `got_teleported`.
Fix jitter when walking against the sneak limits.
Fix damage evading on sneak ladders.

doc/client_lua_api.md
src/localplayer.cpp
src/localplayer.h
src/network/clientpackethandler.cpp
src/script/lua_api/l_localplayer.cpp
src/script/lua_api/l_localplayer.h

index d435c4aae3aad25ebb335be858ca8036f9a5fae0..3e81818ae189b84472bc9cb495697024d6f42bfe 100644 (file)
@@ -810,8 +810,6 @@ Methods:
     * returns player HP
 * `get_name()`
     * returns player name
-* `got_teleported()`
-    * returns true if player was teleported
 * `is_attached()`
     * returns true if player is attached
 * `is_touching_ground()`
index ab44f155f13a1fb51ed2726d6f09cbf78e618c8e..9e30aeac8eee5a97fb12f2cf4c8c53a48e081c4d 100644 (file)
@@ -35,7 +35,6 @@ LocalPlayer::LocalPlayer(Client *client, const char *name):
        Player(name, client->idef()),
        parent(0),
        hp(PLAYER_MAX_HP),
-       got_teleported(false),
        isAttached(false),
        touching_ground(false),
        in_liquid(false),
@@ -305,29 +304,43 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
        if (control.sneak && m_sneak_node_exists &&
                        !(fly_allowed && g_settings->getBool("free_move")) &&
                        !in_liquid && !is_climbing &&
-                       physics_override_sneak && !got_teleported) {
-               v3f sn_f = intToFloat(m_sneak_node, BS);
-               const v3f bmin = m_sneak_node_bb_top.MinEdge;
-               const v3f bmax = m_sneak_node_bb_top.MaxEdge;
+                       physics_override_sneak) {
+               const v3f sn_f = intToFloat(m_sneak_node, BS);
+               const v3f bmin = sn_f + m_sneak_node_bb_top.MinEdge;
+               const v3f bmax = sn_f + m_sneak_node_bb_top.MaxEdge;
+               const v3f old_pos = position;
+               const v3f old_speed = m_speed;
 
                position.X = rangelim(position.X,
-                               sn_f.X+bmin.X - sneak_max.X, sn_f.X+bmax.X + sneak_max.X);
+                               bmin.X - sneak_max.X, bmax.X + sneak_max.X);
                position.Z = rangelim(position.Z,
-                               sn_f.Z+bmin.Z - sneak_max.Z, sn_f.Z+bmax.Z + sneak_max.Z);
+                               bmin.Z - sneak_max.Z, bmax.Z + sneak_max.Z);
+
+               if (position.X != old_pos.X)
+                       m_speed.X = 0;
+               if (position.Z != old_pos.Z)
+                       m_speed.Z = 0;
 
                // Because we keep the player collision box on the node, limiting
                // position.Y is not necessary but useful to prevent players from
                // being inside a node if sneaking on e.g. the lower part of a stair
                if (!m_sneak_ladder_detected) {
-                       position.Y = MYMAX(position.Y, sn_f.Y+bmax.Y);
+                       position.Y = MYMAX(position.Y, bmax.Y);
                } else {
                        // legacy behaviour that sometimes causes some weird slow sinking
                        m_speed.Y = MYMAX(m_speed.Y, 0);
                }
-       }
 
-       if (got_teleported)
-               got_teleported = false;
+               if (collision_info != NULL &&
+                               m_speed.Y - old_speed.Y > BS) {
+                       // Collide with sneak node, report fall damage
+                       CollisionInfo sn_info;
+                       sn_info.node_p = m_sneak_node;
+                       sn_info.old_speed = old_speed;
+                       sn_info.new_speed = m_speed;
+                       collision_info->push_back(sn_info);
+               }
+       }
 
        // TODO: this shouldn't be hardcoded but transmitted from server
        float player_stepheight = touching_ground ? (BS*0.6) : (BS*0.2);
@@ -449,9 +462,11 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
                m_ledge_detected = detectLedge(map, nodemgr, floatToInt(position, BS));
 
        /*
-               Set new position
+               Set new position but keep sneak node set
        */
+       bool sneak_node_exists = m_sneak_node_exists;
        setPosition(position);
+       m_sneak_node_exists = sneak_node_exists;
 
        /*
                Report collisions
@@ -917,7 +932,7 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
        */
        if (control.sneak && m_sneak_node_exists &&
                        !(fly_allowed && g_settings->getBool("free_move")) && !in_liquid &&
-                       physics_override_sneak && !got_teleported) {
+                       physics_override_sneak) {
                f32 maxd = 0.5 * BS + sneak_max;
                v3f lwn_f = intToFloat(m_sneak_node, BS);
                position.X = rangelim(position.X, lwn_f.X - maxd, lwn_f.X + maxd);
@@ -938,9 +953,6 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
                }
        }
 
-       if (got_teleported)
-               got_teleported = false;
-
        // this shouldn't be hardcoded but transmitted from server
        float player_stepheight = touching_ground ? (BS * 0.6) : (BS * 0.2);
 
@@ -1055,9 +1067,11 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
        }
 
        /*
-               Set new position
+               Set new position but keep sneak node set
        */
+       bool sneak_node_exists = m_sneak_node_exists;
        setPosition(position);
+       m_sneak_node_exists = sneak_node_exists;
 
        /*
                Report collisions
index d8d2f310b9c9bc38e41cc648cb82000bc7a9cda4..dcfefcb1ae2c629f6b7dd70e66c1b6b2e0b16bd7 100644 (file)
@@ -47,7 +47,6 @@ public:
        ClientActiveObject *parent;
 
        u16 hp;
-       bool got_teleported;
        bool isAttached;
        bool touching_ground;
        // This oscillates so that the player jumps a bit above the surface
@@ -126,7 +125,11 @@ public:
 
        f32 getPitch() const { return m_pitch; }
 
-       void setPosition(const v3f &position) { m_position = position; }
+       inline void setPosition(const v3f &position)
+       {
+               m_position = position;
+               m_sneak_node_exists = false;
+       }
 
        v3f getPosition() const { return m_position; }
        v3f getEyePosition() const { return m_position + getEyeOffset(); }
index a895acc8419822eab8eea13f48ea52b7bc1b8807..4316a77d4ca1c8ccf2b26d2327216ddd4a60b7dc 100644 (file)
@@ -561,7 +561,6 @@ void Client::handleCommand_MovePlayer(NetworkPacket* pkt)
 
        *pkt >> pos >> pitch >> yaw;
 
-       player->got_teleported = true;
        player->setPosition(pos);
 
        infostream << "Client got TOCLIENT_MOVE_PLAYER"
index 4b44bb70926ee24d6e39d6427ff6acd732225b01..177df55f30f5751eb5da4caab070a9ae9931c67c 100644 (file)
@@ -68,14 +68,6 @@ int LuaLocalPlayer::l_get_name(lua_State *L)
        return 1;
 }
 
-int LuaLocalPlayer::l_is_teleported(lua_State *L)
-{
-       LocalPlayer *player = getobject(L, 1);
-
-       lua_pushboolean(L, player->got_teleported);
-       return 1;
-}
-
 int LuaLocalPlayer::l_is_attached(lua_State *L)
 {
        LocalPlayer *player = getobject(L, 1);
@@ -386,7 +378,6 @@ const luaL_Reg LuaLocalPlayer::methods[] = {
                luamethod(LuaLocalPlayer, get_velocity),
                luamethod(LuaLocalPlayer, get_hp),
                luamethod(LuaLocalPlayer, get_name),
-               luamethod(LuaLocalPlayer, is_teleported),
                luamethod(LuaLocalPlayer, is_attached),
                luamethod(LuaLocalPlayer, is_touching_ground),
                luamethod(LuaLocalPlayer, is_in_liquid),
index 1070857c551a21193b105fc467b258974cf57bb5..6ec3f4c09009f2a1b2723a62d8b5d9629f0cb44b 100644 (file)
@@ -39,7 +39,6 @@ private:
 
        static int l_get_name(lua_State *L);
 
-       static int l_is_teleported(lua_State *L);
        static int l_is_attached(lua_State *L);
        static int l_is_touching_ground(lua_State *L);
        static int l_is_in_liquid(lua_State *L);