aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/localplayer.cpp57
-rw-r--r--src/localplayer.h1
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