diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 652cebd77..9000888bf 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -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 *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; ipush_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() diff --git a/src/localplayer.h b/src/localplayer.h index 32714ff32..c371b345c 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -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