diff options
-rw-r--r-- | src/localplayer.cpp | 57 | ||||
-rw-r--r-- | src/localplayer.h | 1 |
2 files changed, 42 insertions, 16 deletions
diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 81e4009df..eb99d0062 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -169,6 +169,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); @@ -190,8 +195,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; @@ -295,10 +301,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. @@ -328,6 +359,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) { @@ -355,7 +387,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; @@ -384,13 +416,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 (const auto &colinfo : result.collisions) { - collision_info->push_back(colinfo); - } - } - if(!result.standing_on_object && !touching_ground_was && touching_ground) { MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround"); m_client->event()->put(e); @@ -413,7 +438,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; @@ -668,7 +693,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 a407181b1..a3c97db5d 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -151,6 +151,7 @@ private: float getSlipFactor(Environment *env, const v3f &speedH); v3f m_position; + v3s16 m_standing_node; v3s16 m_sneak_node = v3s16(32767, 32767, 32767); // Stores the top bounding box of m_sneak_node |