Add slippery group for nodes (players/items slide)

This commit is contained in:
Wuzzy 2017-08-11 21:16:09 +02:00 committed by paramat
parent 4381fe0a0a
commit 2ea26e655d
5 changed files with 49 additions and 17 deletions

@ -99,8 +99,8 @@ core.register_entity(":__builtin:item", {
self.itemstring = staticdata self.itemstring = staticdata
end end
self.object:set_armor_groups({immortal = 1}) self.object:set_armor_groups({immortal = 1})
self.object:setvelocity({x = 0, y = 2, z = 0}) self.object:set_velocity({x = 0, y = 2, z = 0})
self.object:setacceleration({x = 0, y = -10, z = 0}) self.object:set_acceleration({x = 0, y = -10, z = 0})
self:set_item(self.itemstring) self:set_item(self.itemstring)
end, end,
@ -177,8 +177,8 @@ core.register_entity(":__builtin:item", {
local in_unloaded = (node == nil) local in_unloaded = (node == nil)
if in_unloaded then if in_unloaded then
-- Don't infinetly fall into unloaded map -- Don't infinetly fall into unloaded map
self.object:setvelocity({x = 0, y = 0, z = 0}) self.object:set_velocity({x = 0, y = 0, z = 0})
self.object:setacceleration({x = 0, y = 0, z = 0}) self.object:set_acceleration({x = 0, y = 0, z = 0})
self.physical_state = false self.physical_state = false
self.object:set_properties({physical = false}) self.object:set_properties({physical = false})
return return
@ -186,7 +186,8 @@ core.register_entity(":__builtin:item", {
local nn = node.name local nn = node.name
-- If node is not registered or node is walkably solid and resting on nodebox -- If node is not registered or node is walkably solid and resting on nodebox
local v = self.object:getvelocity() local v = self.object:getvelocity()
if not core.registered_nodes[nn] or core.registered_nodes[nn].walkable and v.y == 0 then if not core.registered_nodes[nn] or (core.registered_nodes[nn].walkable and
core.get_item_group(nn, "slippery") == 0) and v.y == 0 then
if self.physical_state then if self.physical_state then
local own_stack = ItemStack(self.object:get_luaentity().itemstring) local own_stack = ItemStack(self.object:get_luaentity().itemstring)
-- Merge with close entities of the same item -- Merge with close entities of the same item
@ -199,17 +200,28 @@ core.register_entity(":__builtin:item", {
end end
end end
end end
self.object:setvelocity({x = 0, y = 0, z = 0}) self.object:set_velocity({x = 0, y = 0, z = 0})
self.object:setacceleration({x = 0, y = 0, z = 0}) self.object:set_acceleration({x = 0, y = 0, z = 0})
self.physical_state = false self.physical_state = false
self.object:set_properties({physical = false}) self.object:set_properties({physical = false})
end end
else else
if not self.physical_state then if not self.physical_state then
self.object:setvelocity({x = 0, y = 0, z = 0}) self.object:set_velocity({x = 0, y = 0, z = 0})
self.object:setacceleration({x = 0, y = -10, z = 0}) self.object:set_acceleration({x = 0, y = -10, z = 0})
self.physical_state = true self.physical_state = true
self.object:set_properties({physical = true}) self.object:set_properties({physical = true})
elseif minetest.get_item_group(nn, "slippery") ~= 0 then
if math.abs(v.x) < 0.2 and math.abs(v.z) < 0.2 then
self.object:set_velocity({x = 0, y = 0, z = 0})
self.object:set_acceleration({x = 0, y = 0, z = 0})
self.physical_state = false
self.object:set_properties({
physical = false
})
else
self.object:set_acceleration({x = -v.x, y = -10, z = -v.z})
end
end end
end end
end, end,

@ -1424,6 +1424,9 @@ Another example: Make red wool from white wool and red dye:
* `soil`: saplings will grow on nodes in this group * `soil`: saplings will grow on nodes in this group
* `connect_to_raillike`: makes nodes of raillike drawtype with same group value * `connect_to_raillike`: makes nodes of raillike drawtype with same group value
connect to each other connect to each other
* `slippery`: Players and items will slide on the node.
Only use `slippery = 3` for now to ensure forwards compatibility.
### Known damage and digging time defining groups ### Known damage and digging time defining groups
* `crumbly`: dirt, sand * `crumbly`: dirt, sand

@ -403,7 +403,7 @@ void Client::step(float dtime)
// Control local player (0ms) // Control local player (0ms)
LocalPlayer *player = m_env.getLocalPlayer(); LocalPlayer *player = m_env.getLocalPlayer();
assert(player); assert(player);
player->applyControl(dtime); player->applyControl(dtime, &m_env);
// Step environment // Step environment
m_env.step(dtime); m_env.step(dtime);

@ -444,7 +444,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d)
move(dtime, env, pos_max_d, NULL); move(dtime, env, pos_max_d, NULL);
} }
void LocalPlayer::applyControl(float dtime) void LocalPlayer::applyControl(float dtime, ClientEnvironment *env)
{ {
// Clear stuff // Clear stuff
swimming_vertical = false; swimming_vertical = false;
@ -660,9 +660,16 @@ void LocalPlayer::applyControl(float dtime)
else else
incH = incV = movement_acceleration_default * BS * dtime; incH = incV = movement_acceleration_default * BS * dtime;
INodeDefManager *nodemgr = env->getGameDef()->ndef();
Map *map = &env->getMap();
bool slippery = false;
const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(getStandingNodePos()));
slippery = itemgroup_get(f.groups, "slippery");
// Accelerate to target speed with maximum increment // Accelerate to target speed with maximum increment
accelerateHorizontal(speedH * physics_override_speed, incH * physics_override_speed); accelerateHorizontal(speedH * physics_override_speed,
accelerateVertical(speedV * physics_override_speed, incV * physics_override_speed); incH * physics_override_speed, slippery);
accelerateVertical(speedV * physics_override_speed,
incV * physics_override_speed);
} }
v3s16 LocalPlayer::getStandingNodePos() v3s16 LocalPlayer::getStandingNodePos()
@ -699,12 +706,20 @@ v3f LocalPlayer::getEyeOffset() const
} }
// Horizontal acceleration (X and Z), Y direction is ignored // Horizontal acceleration (X and Z), Y direction is ignored
void LocalPlayer::accelerateHorizontal(const v3f &target_speed, const f32 max_increase) void LocalPlayer::accelerateHorizontal(const v3f &target_speed,
const f32 max_increase, bool slippery)
{ {
if (max_increase == 0) if (max_increase == 0)
return; return;
v3f d_wanted = target_speed - m_speed; v3f d_wanted = target_speed - m_speed;
if (slippery) {
if (target_speed == v3f(0))
d_wanted = -m_speed * 0.05f;
else
d_wanted = target_speed * 0.1f - m_speed * 0.1f;
}
d_wanted.Y = 0; d_wanted.Y = 0;
f32 dl = d_wanted.getLength(); f32 dl = d_wanted.getLength();
if (dl > max_increase) if (dl > max_increase)

@ -29,6 +29,7 @@ class Client;
class Environment; class Environment;
class GenericCAO; class GenericCAO;
class ClientActiveObject; class ClientActiveObject;
class ClientEnvironment;
class IGameDef; class IGameDef;
enum LocalPlayerAnimations enum LocalPlayerAnimations
@ -78,7 +79,7 @@ public:
void old_move(f32 dtime, Environment *env, f32 pos_max_d, void old_move(f32 dtime, Environment *env, f32 pos_max_d,
std::vector<CollisionInfo> *collision_info); std::vector<CollisionInfo> *collision_info);
void applyControl(float dtime); void applyControl(float dtime, ClientEnvironment *env);
v3s16 getStandingNodePos(); v3s16 getStandingNodePos();
v3s16 getFootstepNodePos(); v3s16 getFootstepNodePos();
@ -143,7 +144,8 @@ public:
void setCollisionbox(const aabb3f &box) { m_collisionbox = box; } void setCollisionbox(const aabb3f &box) { m_collisionbox = box; }
private: private:
void accelerateHorizontal(const v3f &target_speed, const f32 max_increase); void accelerateHorizontal(const v3f &target_speed,
const f32 max_increase, bool slippery);
void accelerateVertical(const v3f &target_speed, const f32 max_increase); void accelerateVertical(const v3f &target_speed, const f32 max_increase);
bool updateSneakNode(Map *map, const v3f &position, const v3f &sneak_max); bool updateSneakNode(Map *map, const v3f &position, const v3f &sneak_max);