From f3e1237a27dc7ce448f3dd5a93124cb65eed0e8b Mon Sep 17 00:00:00 2001 From: cmdskp Date: Thu, 31 Dec 2015 16:14:27 +0000 Subject: [PATCH] Added item sliding, renamed groups setting to 'slip' Renamed groups 'slippery' to 'slip' to avoid name collision with clones and to match override_physics_slip. --- builtin/game/item_entity.lua | 48 +++++++++++++++++++++--------------- doc/lua_api.txt | 4 +++ src/content_cao.cpp | 1 - src/localplayer.cpp | 12 ++++----- src/player.cpp | 21 +++++++--------- src/player.h | 2 +- 6 files changed, 48 insertions(+), 40 deletions(-) diff --git a/builtin/game/item_entity.lua b/builtin/game/item_entity.lua index be158c119..41388b582 100644 --- a/builtin/game/item_entity.lua +++ b/builtin/game/item_entity.lua @@ -163,7 +163,7 @@ core.register_entity(":__builtin:item", { local node = core.get_node_or_nil(p) local in_unloaded = (node == nil) if in_unloaded then - -- Don't infinetly fall into unloaded map + -- Don't infinitely fall into unloaded map self.object:setvelocity({x = 0, y = 0, z = 0}) self.object:setacceleration({x = 0, y = 0, z = 0}) self.physical_state = false @@ -174,30 +174,38 @@ core.register_entity(":__builtin:item", { -- If node is not registered or node is walkably solid and resting on nodebox local v = self.object:getvelocity() if not core.registered_nodes[nn] or core.registered_nodes[nn].walkable and v.y == 0 then + + -- Must check (above) first, if sitting on node to prevent flipping physical_state continuously! if self.physical_state then - local own_stack = ItemStack(self.object:get_luaentity().itemstring) - -- Merge with close entities of the same item - for _, object in ipairs(core.get_objects_inside_radius(p, 0.8)) do - local obj = object:get_luaentity() - if obj and obj.name == "__builtin:item" - and obj.physical_state == false then - if self:try_merge_with(own_stack, object, obj) then - return + local total_velocity = math.abs(v.x) + math.abs(v.z) + local slip = core.get_item_group(nn, "slip") + if slip == 0 or total_velocity < .5 then + local own_stack = ItemStack(self.object:get_luaentity().itemstring) + -- Merge with close entities of the same item + for _, object in ipairs(core.get_objects_inside_radius(p, 0.8)) do + local obj = object:get_luaentity() + if obj and obj.name == "__builtin:item" + and obj.physical_state == false then + if self:try_merge_with(own_stack, object, obj) then + return + end end end + + self.object:setvelocity({x = 0, y = 0, z = 0}) + self.object:setacceleration({x = 0, y = 0, z = 0}) + self.physical_state = false + self.object:set_properties({physical = false}) + elseif slip ~= 0 then + self.object:setacceleration({x = v.x * -120 / slip, y = -10, z = v.z * -120 / slip}) end - self.object:setvelocity({x = 0, y = 0, z = 0}) - self.object:setacceleration({x = 0, y = 0, z = 0}) - self.physical_state = false - self.object:set_properties({physical = false}) - end - else - if not self.physical_state then - self.object:setvelocity({x = 0, y = 0, z = 0}) - self.object:setacceleration({x = 0, y = -10, z = 0}) - self.physical_state = true - self.object:set_properties({physical = true}) end + elseif not self.physical_state then + -- Re-activate & apply gravity if not resting on a walkable nodebox + self.object:setvelocity({x = 0, y = 0, z = 0}) + self.object:setacceleration({x = 0, y = -10, z = 0}) + self.physical_state = true + self.object:set_properties({physical = true}) end end, diff --git a/doc/lua_api.txt b/doc/lua_api.txt index b713b68bf..276def259 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1118,6 +1118,10 @@ Another example: Make red wool from white wool and red dye: * `soil`: saplings will grow on nodes in this group * `connect_to_raillike`: makes nodes of raillike drawtype with same group value connect to each other +* `slip`: players and items will slide on the node. A value of 100 produces + medium slip. Positive values slow to stop, negative values continue speeding up! + Larger positive & negative values produce more gradual change in speed. Small + negative values cause rapid acceleration! ### Known damage and digging time defining groups * `crumbly`: dirt, sand diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 9b75e641d..5536be42b 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -1661,7 +1661,6 @@ void GenericCAO::processMessage(const std::string &data) float override_speed = readF1000(is); float override_jump = readF1000(is); float override_gravity = readF1000(is); -///TODO: detect protocol VERSION! float override_slip = readF1000(is); // these are sent inverted so we get true when the server sends nothing bool sneak = !readU8(is); diff --git a/src/localplayer.cpp b/src/localplayer.cpp index e2be366f5..22a945906 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -610,7 +610,7 @@ void LocalPlayer::applyControl(float dtime, Environment *env) else incH = incV = movement_acceleration_default * BS * dtime; - int slippery; + int slip; if (!free_move && !control.sneak && !is_climbing) { INodeDefManager *nodemgr = m_gamedef->ndef(); @@ -618,17 +618,17 @@ void LocalPlayer::applyControl(float dtime, Environment *env) v3s16 position = floatToInt(getPosition() - v3f(0,BS/2,0), BS); ContentFeatures node = nodemgr->get(map->getNodeNoEx(position)); - slippery = itemgroup_get(node.groups, "slippery"); + slip = itemgroup_get(node.groups, "slip"); // Sliding onto a non-walkable node that you should fall through? - if (slippery==0 && !node.walkable) - slippery = 100; // override to allow sliding off edges into + if (slip==0 && !node.walkable) + slip = 100; // override to allow sliding off edges into } else - slippery = 0; + slip = 0; // Accelerate to target speed with maximum increment - accelerateHorizontal(speedH * physics_override_speed, incH * physics_override_speed, slippery * physics_override_slip); + accelerateHorizontal(speedH * physics_override_speed, incH * physics_override_speed, slip * physics_override_slip); accelerateVertical(speedV * physics_override_speed, incV * physics_override_speed); } diff --git a/src/player.cpp b/src/player.cpp index fdfb9f3a6..e8fe622bd 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -113,29 +113,26 @@ Player::~Player() } // Horizontal acceleration (X and Z), Y direction is ignored -void Player::accelerateHorizontal(v3f target_speed, f32 max_increase, int slippery) +void Player::accelerateHorizontal(v3f target_speed, f32 max_increase, int slip) { if(max_increase == 0) return; v3f d_wanted = target_speed - m_speed; - if (slippery) + if(slip) { - if (target_speed == v3f(0)) - d_wanted = -m_speed * 5 / slippery; + if(target_speed == v3f(0)) + d_wanted = -m_speed * 5 / slip; else d_wanted = target_speed * .1 - m_speed * .1; } d_wanted.Y = 0; - f32 dl = d_wanted.getLength(); - if(dl > max_increase) - dl = max_increase; - - v3f d = d_wanted.normalize() * dl; - - m_speed.X += d.X; - m_speed.Z += d.Z; + f32 wanted_speed = d_wanted.getLength(); + if(wanted_speed > max_increase) + d_wanted = d_wanted * (max_increase / wanted_speed); + m_speed.X += d_wanted.X; + m_speed.Z += d_wanted.Z; } // Vertical acceleration (Y), X and Z directions are ignored diff --git a/src/player.h b/src/player.h index babe7fd80..c072e87ce 100644 --- a/src/player.h +++ b/src/player.h @@ -119,7 +119,7 @@ public: m_speed = speed; } - void accelerateHorizontal(v3f target_speed, f32 max_increase, int slippery); + void accelerateHorizontal(v3f target_speed, f32 max_increase, int slip); void accelerateVertical(v3f target_speed, f32 max_increase); v3f getPosition()