else
incH = incV = movement_acceleration_default * BS * dtime;
- float slip_factor = getSlipFactor(env, speedH);
+ float slip_factor = 1.0f;
+ if (!free_move)
+ slip_factor = getSlipFactor(env, speedH);
+
// Accelerate to target speed with maximum increment
accelerateHorizontal(speedH * physics_override_speed,
incH * physics_override_speed * slip_factor);
float LocalPlayer::getSlipFactor(Environment *env, const v3f &speedH)
{
-
- if (!touching_ground)
- return 1.0f;
-
- float slip_factor = 1.0f;
// Slip on slippery nodes
const NodeDefManager *nodemgr = env->getGameDef()->ndef();
Map *map = &env->getMap();
const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(
- floatToInt(getPosition() - v3f(0, 0.05f * BS, 0), BS)));
+ getStandingNodePos()));
int slippery = 0;
- if (f.walkable) {
+ if (f.walkable)
slippery = itemgroup_get(f.groups, "slippery");
- } else if (is_slipping) {
- // slipping over an edge? Check surroundings for slippery nodes
- slippery = 2 << 16; // guard value, bigger than all realistic ones
- for (int z = 0; z <= 1; z++) {
- for (int x = 0; x <= 1; x++) {
- // this should cover all nodes surrounding player position
- v3f offset((x - 0.5f) * BS, 0.05f * BS, (z - 0.5f) * BS);
- const ContentFeatures &f2 = nodemgr->get(map->getNodeNoEx(
- floatToInt(getPosition() - offset, BS)));
- if (f2.walkable) {
- // find least slippery node we might be standing on
- int s = itemgroup_get(f2.groups, "slippery");
- if (s < slippery)
- slippery = s;
- }
- }
- }
- // without any hits, ignore slippery
- if (slippery >= (2 << 16))
- slippery = 0;
- }
+
if (slippery >= 1) {
if (speedH == v3f(0.0f)) {
slippery = slippery * 2;
}
- slip_factor = core::clamp(1.0f / (slippery + 1), 0.001f, 1.0f);
- is_slipping = true;
- } else {
- // remember this to avoid checking the edge case above too often
- is_slipping = false;
+ return core::clamp(1.0f / (slippery + 1), 0.001f, 1.0f);
}
- return slip_factor;
+ return 1.0f;
}