Backport "slippery" feature from MT 5.0, replace builtin deprecated function calls, move eat sound in builtin

master
MoNTE48 2019-06-03 15:46:14 +02:00
parent 746490cff8
commit fd83f569a8
12 changed files with 84 additions and 39 deletions

View File

@ -343,7 +343,7 @@ core.register_chatcommand("teleport", {
end
teleportee = core.get_player_by_name(name)
if teleportee then
teleportee:setpos(p)
teleportee:set_pos(p)
return true, "Teleporting to "..core.pos_to_string(p)
end
end
@ -356,12 +356,12 @@ core.register_chatcommand("teleport", {
if target_name then
local target = core.get_player_by_name(target_name)
if target then
p = target:getpos()
p = target:get_pos()
end
end
if teleportee and p then
p = find_free_position_near(p)
teleportee:setpos(p)
teleportee:set_pos(p)
return true, "Teleporting to " .. target_name
.. " at "..core.pos_to_string(p)
end
@ -380,7 +380,7 @@ core.register_chatcommand("teleport", {
teleportee = core.get_player_by_name(teleportee_name)
end
if teleportee and p.x and p.y and p.z then
teleportee:setpos(p)
teleportee:set_pos(p)
return true, "Teleporting " .. teleportee_name
.. " to " .. core.pos_to_string(p)
end
@ -396,12 +396,12 @@ core.register_chatcommand("teleport", {
if target_name then
local target = core.get_player_by_name(target_name)
if target then
p = target:getpos()
p = target:get_pos()
end
end
if teleportee and p then
p = find_free_position_near(p)
teleportee:setpos(p)
teleportee:set_pos(p)
return true, "Teleporting " .. teleportee_name
.. " to " .. target_name
.. " at " .. core.pos_to_string(p)
@ -619,7 +619,7 @@ core.register_chatcommand("spawnentity", {
return false, "Unable to spawn entity, player is nil"
end
if p == "" then
p = player:getpos()
p = player:get_pos()
else
p = core.string_to_pos(p)
if p == nil then
@ -1003,7 +1003,7 @@ minetest.register_chatcommand("spawn", {
return false, "Player not found"
end
if spawn_spawnpos then
player:setpos(spawn_spawnpos)
player:set_pos(spawn_spawnpos)
return true, "Teleporting to spawn..."
else
return false, "The spawn point is not set!"
@ -1020,7 +1020,7 @@ minetest.register_chatcommand("setspawn", {
if not player then
return false, "Player not found"
end
local pos = player:getpos()
local pos = player:get_pos()
local x = pos.x
local y = pos.y
local z = pos.z

View File

@ -52,12 +52,12 @@ core.register_entity(":__builtin:falling_node", {
on_step = function(self, dtime)
-- Set gravity
local acceleration = self.object:getacceleration()
if not vector.equals(acceleration, {x = 0, y = -10, z = 0}) then
self.object:setacceleration({x = 0, y = -10, z = 0})
local acceleration = self.object:get_acceleration()
if not vector.equals(acceleration, {x = 0, y = -9.81, z = 0}) then
self.object:setacceleration({x = 0, y = -9.81, z = 0})
end
-- Turn to actual node when colliding with ground, or continue to move
local pos = self.object:getpos()
local pos = self.object:get_pos()
-- Position of bottom center point
local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z}
-- 'bcn' is nil for unloaded nodes
@ -120,10 +120,10 @@ core.register_entity(":__builtin:falling_node", {
core.check_for_falling(np)
return
end
local vel = self.object:getvelocity()
local vel = self.object:get_velocity()
if vector.equals(vel, {x = 0, y = 0, z = 0}) then
local npos = self.object:getpos()
self.object:setpos(vector.round(npos))
local npos = self.object:get_pos()
self.object:set_pos(vector.round(npos))
end
end
})

View File

@ -33,7 +33,7 @@ function core.get_pointed_thing_position(pointed_thing, above)
-- The position where a node would be dug
return pointed_thing.under
elseif pointed_thing.type == "object" then
return pointed_thing.ref and pointed_thing.ref:getpos()
return pointed_thing.ref and pointed_thing.ref:get_pos()
end
end
@ -331,7 +331,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
-- Calculate the direction for furnaces and chests and stuff
elseif (def.paramtype2 == "facedir" or
def.paramtype2 == "colorfacedir") and not param2 then
local placer_pos = placer and placer:getpos()
local placer_pos = placer and placer:get_pos()
if placer_pos then
local dir = {
x = above.x - placer_pos.x,
@ -488,7 +488,7 @@ function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed
if inv and inv:room_for_item("main", {name=replace_with_item}) then
inv:add_item("main", replace_with_item)
else
local pos = user:getpos()
local pos = user:get_pos()
pos.y = math.floor(pos.y + 0.5)
core.add_item(pos, replace_with_item)
end
@ -501,10 +501,11 @@ end
function core.item_eat(hp_change, replace_with_item)
return function(itemstack, user, pointed_thing) -- closure
if user then
local pos = user:getpos()
local pos = user:get_pos()
pos.y = pos.y + 1.5
local itemname = itemstack:get_name()
local texture = minetest.registered_items[itemname].inventory_image
minetest.sound_play("player_eat", {pos = pos, max_hear_distance = 10, gain = 0.3})
minetest.add_particlespawner({
amount = 20,
time = 0.1,

View File

@ -99,8 +99,8 @@ core.register_entity(":__builtin:item", {
self.itemstring = staticdata
end
self.object:set_armor_groups({immortal = 1})
self.object:setvelocity({x = 0, y = 2, z = 0})
self.object:setacceleration({x = 0, y = -10, z = 0})
self.object:set_velocity({x = 0, y = 2, z = 0})
self.object:set_acceleration({x = 0, y = -9.81, z = 0})
self:set_item(self.itemstring)
end,
@ -125,7 +125,7 @@ core.register_entity(":__builtin:item", {
self.itemstring = ''
stack:set_count(count)
end
local pos = object:getpos()
local pos = object:get_pos()
pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15
object:moveto(pos, false)
local s, c
@ -171,7 +171,7 @@ core.register_entity(":__builtin:item", {
self.object:remove()
return
end
local p = self.object:getpos()
local p = self.object:get_pos()
p.y = p.y - 0.5
local node = core.get_node_or_nil(p)
-- Delete in 'ignore' nodes
@ -183,9 +183,10 @@ core.register_entity(":__builtin:item", {
-- If node is nil (unloaded area), or node is not registered, or node is
-- walkably solid and item is resting on nodebox
local v = self.object:getvelocity()
if not node or not core.registered_nodes[node.name] or
core.registered_nodes[node.name].walkable and v.y == 0 then
local nn = node.name
local v = self.object:get_velocity()
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
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
-- Merge with close entities of the same item
@ -198,17 +199,28 @@ core.register_entity(":__builtin:item", {
end
end
end
self.object:setvelocity({x = 0, y = 0, z = 0})
self.object:setacceleration({x = 0, y = 0, z = 0})
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})
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.object:set_velocity({x = 0, y = 0, z = 0})
self.object:set_acceleration({x = 0, y = -9.81, z = 0})
self.physical_state = 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 = -9.81, z = -v.z})
end
end
end

View File

@ -91,7 +91,7 @@ function core.get_player_radius_area(player_name, radius)
return nil
end
local p1 = player:getpos()
local p1 = player:get_pos()
local p2 = p1
if radius then

View File

@ -17,7 +17,7 @@ local function put_player_in_spawn(player_obj)
end
core.log("action", "Moving " .. player_obj:get_player_name() ..
" to static spawnpoint at " .. core.pos_to_string(static_spawnpoint))
player_obj:setpos(static_spawnpoint)
player_obj:set_pos(static_spawnpoint)
return true
end

View File

@ -1515,6 +1515,8 @@ 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
* `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
* `crumbly`: dirt, sand

View File

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

View File

@ -4485,7 +4485,7 @@ void Game::updateGui(const RunStats &stats, f32 dtime, const CameraOrientation &
s32 status_width = guitext_status->getTextWidth();
s32 status_height = guitext_status->getTextHeight();
#if defined(__ANDROID__) || defined(__IOS__)
s32 status_y = screensize.Y - 320 * g_settings->getFloat("hud_scaling");
s32 status_y = screensize.Y - 250 * g_settings->getFloat("hud_scaling");
#else
s32 status_y = screensize.Y - 150;
#endif

View File

@ -518,7 +518,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d)
move(dtime, env, pos_max_d, NULL);
}
void LocalPlayer::applyControl(float dtime)
void LocalPlayer::applyControl(float dtime, ClientEnvironment *env)
{
// Clear stuff
swimming_vertical = false;
@ -734,8 +734,13 @@ void LocalPlayer::applyControl(float dtime)
else
incH = incV = movement_acceleration_default * BS * dtime;
float slip_factor = 1.0f;
if (!free_move && !in_liquid && !in_liquid_stable)
slip_factor = getSlipFactor(env, speedH);
// Accelerate to target speed with maximum increment
accelerateHorizontal(speedH * physics_override_speed, incH * physics_override_speed);
accelerateHorizontal(speedH * physics_override_speed,
incH * physics_override_speed * slip_factor);
accelerateVertical(speedV * physics_override_speed, incV * physics_override_speed);
}
@ -770,7 +775,8 @@ v3f LocalPlayer::getEyeOffset() const
}
// 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)
{
if (max_increase == 0)
return;
@ -1102,3 +1108,24 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
m_can_jump = false;
}
}
float LocalPlayer::getSlipFactor(Environment *env, const v3f &speedH)
{
// Slip on slippery nodes
const INodeDefManager *nodemgr = env->getGameDef()->ndef();
Map *map = &env->getMap();
const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(
getStandingNodePos()));
int slippery = 0;
if (f.walkable)
slippery = itemgroup_get(f.groups, "slippery");
if (slippery >= 1) {
if (speedH == v3f(0.0f)) {
slippery = slippery * 2;
}
return core::clamp(1.0f / (slippery + 1), 0.001f, 1.0f);
}
return 1.0f;
}

View File

@ -29,6 +29,7 @@ class Client;
class Environment;
class GenericCAO;
class ClientActiveObject;
class ClientEnvironment;
class IGameDef;
enum LocalPlayerAnimations
@ -78,7 +79,7 @@ public:
void old_move(f32 dtime, Environment *env, f32 pos_max_d,
std::vector<CollisionInfo> *collision_info);
void applyControl(float dtime);
void applyControl(float dtime, ClientEnvironment *env);
v3s16 getStandingNodePos();
v3s16 getFootstepNodePos();
@ -144,6 +145,7 @@ private:
void accelerateHorizontal(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);
float getSlipFactor(Environment *env, const v3f &speedH);
v3f m_position;
v3s16 m_standing_node;

View File

@ -222,6 +222,7 @@ void ScriptApiSecurity::initializeSecurityClient()
"core",
"collectgarbage",
"DIR_DELIM",
"PLATFORM",
"error",
"getfenv",
"ipairs",