Slippery: Simplify, make more efficient (#7086)

Use already existing collision results for the nearest colliding node
Fix slippery effect in free_move mode
This commit is contained in:
SmallJoker 2018-03-03 10:59:14 +01:00 committed by GitHub
parent f5fd4a0af1
commit a1cf8a127c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 9 additions and 36 deletions

@ -681,7 +681,10 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
else else
incH = incV = movement_acceleration_default * BS * dtime; 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 // Accelerate to target speed with maximum increment
accelerateHorizontal(speedH * physics_override_speed, accelerateHorizontal(speedH * physics_override_speed,
incH * physics_override_speed * slip_factor); incH * physics_override_speed * slip_factor);
@ -1057,49 +1060,20 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
float LocalPlayer::getSlipFactor(Environment *env, const v3f &speedH) float LocalPlayer::getSlipFactor(Environment *env, const v3f &speedH)
{ {
if (!touching_ground)
return 1.0f;
float slip_factor = 1.0f;
// Slip on slippery nodes // Slip on slippery nodes
const NodeDefManager *nodemgr = env->getGameDef()->ndef(); const NodeDefManager *nodemgr = env->getGameDef()->ndef();
Map *map = &env->getMap(); Map *map = &env->getMap();
const ContentFeatures &f = nodemgr->get(map->getNodeNoEx( const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(
floatToInt(getPosition() - v3f(0, 0.05f * BS, 0), BS))); getStandingNodePos()));
int slippery = 0; int slippery = 0;
if (f.walkable) { if (f.walkable)
slippery = itemgroup_get(f.groups, "slippery"); 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 (slippery >= 1) {
if (speedH == v3f(0.0f)) { if (speedH == v3f(0.0f)) {
slippery = slippery * 2; slippery = slippery * 2;
} }
slip_factor = core::clamp(1.0f / (slippery + 1), 0.001f, 1.0f); return 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 slip_factor; return 1.0f;
} }

@ -61,7 +61,6 @@ public:
u8 liquid_viscosity = 0; u8 liquid_viscosity = 0;
bool is_climbing = false; bool is_climbing = false;
bool swimming_vertical = false; bool swimming_vertical = false;
bool is_slipping = false;
float physics_override_speed = 1.0f; float physics_override_speed = 1.0f;
float physics_override_jump = 1.0f; float physics_override_jump = 1.0f;