Localplayer: Fix disable_jump effect and getStandingNodePos()
authorSmallJoker <mk939@ymail.com>
Sat, 23 Sep 2017 14:29:48 +0000 (16:29 +0200)
committerSmallJoker <mk939@ymail.com>
Sun, 3 Jun 2018 15:31:59 +0000 (17:31 +0200)
Leave the old move code untouched.

src/localplayer.cpp
src/localplayer.h

index 652cebd7741e551fb776c49bf3135b43d5bc4bda..9000888bf1ceb8321ae34d3b1bf8780dcc84d8b4 100644 (file)
@@ -220,6 +220,11 @@ bool LocalPlayer::updateSneakNode(Map *map, const v3f &position,
 void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
                std::vector<CollisionInfo> *collision_info)
 {
+       if (!collision_info || collision_info->empty()) {
+               // Node below the feet, update each ClientEnvironment::step()
+               m_standing_node = floatToInt(m_position, BS) - v3s16(0, 1, 0);
+       }
+
        // Temporary option for old move code
        if (!physics_override_new_move) {
                old_move(dtime, env, pos_max_d, collision_info);
@@ -241,8 +246,9 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
        bool fly_allowed = m_client->checkLocalPrivilege("fly");
        bool noclip = m_client->checkLocalPrivilege("noclip") &&
                g_settings->getBool("noclip");
-       bool free_move = noclip && fly_allowed && g_settings->getBool("free_move");
-       if (free_move) {
+       bool free_move = g_settings->getBool("free_move") && fly_allowed;
+
+       if (noclip && free_move) {
                position += m_speed * dtime;
                setPosition(position);
                return;
@@ -340,10 +346,35 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
                pos_max_d, m_collisionbox, player_stepheight, dtime,
                &position, &m_speed, accel_f);
 
-       bool could_sneak = control.sneak &&
-               !(fly_allowed && g_settings->getBool("free_move")) &&
-               !in_liquid && !is_climbing &&
-               physics_override_sneak;
+       bool could_sneak = control.sneak && !free_move && !in_liquid &&
+               !is_climbing && physics_override_sneak;
+
+       // Add new collisions to the vector
+       if (collision_info && !free_move) {
+               v3f diff = intToFloat(m_standing_node, BS) - position;
+               f32 distance = diff.getLength();
+               // Force update each ClientEnvironment::step()
+               bool is_first = collision_info->empty();
+
+               for (const auto &colinfo : result.collisions) {
+                       collision_info->push_back(colinfo);
+
+                       if (colinfo.type != COLLISION_NODE ||
+                                       colinfo.new_speed.Y != 0 ||
+                                       (could_sneak && m_sneak_node_exists))
+                               continue;
+
+                       diff = intToFloat(colinfo.node_p, BS) - position;
+
+                       // Find nearest colliding node
+                       f32 len = diff.getLength();
+                       if (is_first || len < distance) {
+                               m_standing_node = colinfo.node_p;
+                               distance = len;
+                       }
+               }
+       }
+
        /*
                If the player's feet touch the topside of any node, this is
                set to true.
@@ -373,6 +404,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
                const v3f old_pos = position;
                const v3f old_speed = m_speed;
                f32 y_diff = bmax.Y - position.Y;
+               m_standing_node = m_sneak_node;
 
                // (BS * 0.6f) is the basic stepheight while standing on ground
                if (y_diff < BS * 0.6f) {
@@ -400,7 +432,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
                if (m_speed.Y == 0 || m_sneak_ladder_detected)
                        sneak_can_jump = true;
 
-               if (collision_info != NULL &&
+               if (collision_info &&
                                m_speed.Y - old_speed.Y > BS) {
                        // Collide with sneak node, report fall damage
                        CollisionInfo sn_info;
@@ -429,14 +461,6 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
                Report collisions
        */
 
-       // Dont report if flying
-       if(collision_info && !(g_settings->getBool("free_move") && fly_allowed)) {
-               for(size_t i=0; i<result.collisions.size(); i++) {
-                       const CollisionInfo &info = result.collisions[i];
-                       collision_info->push_back(info);
-               }
-       }
-
        if(!result.standing_on_object && !touching_ground_was && touching_ground) {
                MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround");
                m_client->event()->put(e);
@@ -459,7 +483,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
        /*
                Check properties of the node on which the player is standing
        */
-       const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(getStandingNodePos()));
+       const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(m_standing_node));
        // Determine if jumping is possible
        m_can_jump = (touching_ground && !in_liquid && !is_climbing)
                        || sneak_can_jump;
@@ -711,7 +735,7 @@ v3s16 LocalPlayer::getStandingNodePos()
 {
        if(m_sneak_node_exists)
                return m_sneak_node;
-       return floatToInt(getPosition() - v3f(0, BS, 0), BS);
+       return m_standing_node;
 }
 
 v3s16 LocalPlayer::getFootstepNodePos()
index 32714ff3226f66f68e75ab95e96662d112a45c0c..c371b345cd4fb1e5c79a8edc4271d835b83266fc 100644 (file)
@@ -146,6 +146,7 @@ private:
        bool updateSneakNode(Map *map, const v3f &position, const v3f &sneak_max);
 
        v3f m_position;
+       v3s16 m_standing_node;
 
        v3s16 m_sneak_node = v3s16(32767, 32767, 32767);
        // Stores the top bounding box of m_sneak_node