Backport "slippery" feature from MT 5.0, replace builtin deprecated function calls, move eat sound in builtin
This commit is contained in:
parent
746490cff8
commit
fd83f569a8
|
@ -343,7 +343,7 @@ core.register_chatcommand("teleport", {
|
||||||
end
|
end
|
||||||
teleportee = core.get_player_by_name(name)
|
teleportee = core.get_player_by_name(name)
|
||||||
if teleportee then
|
if teleportee then
|
||||||
teleportee:setpos(p)
|
teleportee:set_pos(p)
|
||||||
return true, "Teleporting to "..core.pos_to_string(p)
|
return true, "Teleporting to "..core.pos_to_string(p)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -356,12 +356,12 @@ core.register_chatcommand("teleport", {
|
||||||
if target_name then
|
if target_name then
|
||||||
local target = core.get_player_by_name(target_name)
|
local target = core.get_player_by_name(target_name)
|
||||||
if target then
|
if target then
|
||||||
p = target:getpos()
|
p = target:get_pos()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if teleportee and p then
|
if teleportee and p then
|
||||||
p = find_free_position_near(p)
|
p = find_free_position_near(p)
|
||||||
teleportee:setpos(p)
|
teleportee:set_pos(p)
|
||||||
return true, "Teleporting to " .. target_name
|
return true, "Teleporting to " .. target_name
|
||||||
.. " at "..core.pos_to_string(p)
|
.. " at "..core.pos_to_string(p)
|
||||||
end
|
end
|
||||||
|
@ -380,7 +380,7 @@ core.register_chatcommand("teleport", {
|
||||||
teleportee = core.get_player_by_name(teleportee_name)
|
teleportee = core.get_player_by_name(teleportee_name)
|
||||||
end
|
end
|
||||||
if teleportee and p.x and p.y and p.z then
|
if teleportee and p.x and p.y and p.z then
|
||||||
teleportee:setpos(p)
|
teleportee:set_pos(p)
|
||||||
return true, "Teleporting " .. teleportee_name
|
return true, "Teleporting " .. teleportee_name
|
||||||
.. " to " .. core.pos_to_string(p)
|
.. " to " .. core.pos_to_string(p)
|
||||||
end
|
end
|
||||||
|
@ -396,12 +396,12 @@ core.register_chatcommand("teleport", {
|
||||||
if target_name then
|
if target_name then
|
||||||
local target = core.get_player_by_name(target_name)
|
local target = core.get_player_by_name(target_name)
|
||||||
if target then
|
if target then
|
||||||
p = target:getpos()
|
p = target:get_pos()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if teleportee and p then
|
if teleportee and p then
|
||||||
p = find_free_position_near(p)
|
p = find_free_position_near(p)
|
||||||
teleportee:setpos(p)
|
teleportee:set_pos(p)
|
||||||
return true, "Teleporting " .. teleportee_name
|
return true, "Teleporting " .. teleportee_name
|
||||||
.. " to " .. target_name
|
.. " to " .. target_name
|
||||||
.. " at " .. core.pos_to_string(p)
|
.. " at " .. core.pos_to_string(p)
|
||||||
|
@ -619,7 +619,7 @@ core.register_chatcommand("spawnentity", {
|
||||||
return false, "Unable to spawn entity, player is nil"
|
return false, "Unable to spawn entity, player is nil"
|
||||||
end
|
end
|
||||||
if p == "" then
|
if p == "" then
|
||||||
p = player:getpos()
|
p = player:get_pos()
|
||||||
else
|
else
|
||||||
p = core.string_to_pos(p)
|
p = core.string_to_pos(p)
|
||||||
if p == nil then
|
if p == nil then
|
||||||
|
@ -1003,7 +1003,7 @@ minetest.register_chatcommand("spawn", {
|
||||||
return false, "Player not found"
|
return false, "Player not found"
|
||||||
end
|
end
|
||||||
if spawn_spawnpos then
|
if spawn_spawnpos then
|
||||||
player:setpos(spawn_spawnpos)
|
player:set_pos(spawn_spawnpos)
|
||||||
return true, "Teleporting to spawn..."
|
return true, "Teleporting to spawn..."
|
||||||
else
|
else
|
||||||
return false, "The spawn point is not set!"
|
return false, "The spawn point is not set!"
|
||||||
|
@ -1020,7 +1020,7 @@ minetest.register_chatcommand("setspawn", {
|
||||||
if not player then
|
if not player then
|
||||||
return false, "Player not found"
|
return false, "Player not found"
|
||||||
end
|
end
|
||||||
local pos = player:getpos()
|
local pos = player:get_pos()
|
||||||
local x = pos.x
|
local x = pos.x
|
||||||
local y = pos.y
|
local y = pos.y
|
||||||
local z = pos.z
|
local z = pos.z
|
||||||
|
|
|
@ -52,12 +52,12 @@ core.register_entity(":__builtin:falling_node", {
|
||||||
|
|
||||||
on_step = function(self, dtime)
|
on_step = function(self, dtime)
|
||||||
-- Set gravity
|
-- Set gravity
|
||||||
local acceleration = self.object:getacceleration()
|
local acceleration = self.object:get_acceleration()
|
||||||
if not vector.equals(acceleration, {x = 0, y = -10, z = 0}) then
|
if not vector.equals(acceleration, {x = 0, y = -9.81, z = 0}) then
|
||||||
self.object:setacceleration({x = 0, y = -10, z = 0})
|
self.object:setacceleration({x = 0, y = -9.81, z = 0})
|
||||||
end
|
end
|
||||||
-- Turn to actual node when colliding with ground, or continue to move
|
-- 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
|
-- Position of bottom center point
|
||||||
local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z}
|
local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z}
|
||||||
-- 'bcn' is nil for unloaded nodes
|
-- 'bcn' is nil for unloaded nodes
|
||||||
|
@ -120,10 +120,10 @@ core.register_entity(":__builtin:falling_node", {
|
||||||
core.check_for_falling(np)
|
core.check_for_falling(np)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local vel = self.object:getvelocity()
|
local vel = self.object:get_velocity()
|
||||||
if vector.equals(vel, {x = 0, y = 0, z = 0}) then
|
if vector.equals(vel, {x = 0, y = 0, z = 0}) then
|
||||||
local npos = self.object:getpos()
|
local npos = self.object:get_pos()
|
||||||
self.object:setpos(vector.round(npos))
|
self.object:set_pos(vector.round(npos))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
|
@ -33,7 +33,7 @@ function core.get_pointed_thing_position(pointed_thing, above)
|
||||||
-- The position where a node would be dug
|
-- The position where a node would be dug
|
||||||
return pointed_thing.under
|
return pointed_thing.under
|
||||||
elseif pointed_thing.type == "object" then
|
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
|
||||||
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
|
-- Calculate the direction for furnaces and chests and stuff
|
||||||
elseif (def.paramtype2 == "facedir" or
|
elseif (def.paramtype2 == "facedir" or
|
||||||
def.paramtype2 == "colorfacedir") and not param2 then
|
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
|
if placer_pos then
|
||||||
local dir = {
|
local dir = {
|
||||||
x = above.x - placer_pos.x,
|
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
|
if inv and inv:room_for_item("main", {name=replace_with_item}) then
|
||||||
inv:add_item("main", replace_with_item)
|
inv:add_item("main", replace_with_item)
|
||||||
else
|
else
|
||||||
local pos = user:getpos()
|
local pos = user:get_pos()
|
||||||
pos.y = math.floor(pos.y + 0.5)
|
pos.y = math.floor(pos.y + 0.5)
|
||||||
core.add_item(pos, replace_with_item)
|
core.add_item(pos, replace_with_item)
|
||||||
end
|
end
|
||||||
|
@ -501,10 +501,11 @@ end
|
||||||
function core.item_eat(hp_change, replace_with_item)
|
function core.item_eat(hp_change, replace_with_item)
|
||||||
return function(itemstack, user, pointed_thing) -- closure
|
return function(itemstack, user, pointed_thing) -- closure
|
||||||
if user then
|
if user then
|
||||||
local pos = user:getpos()
|
local pos = user:get_pos()
|
||||||
pos.y = pos.y + 1.5
|
pos.y = pos.y + 1.5
|
||||||
local itemname = itemstack:get_name()
|
local itemname = itemstack:get_name()
|
||||||
local texture = minetest.registered_items[itemname].inventory_image
|
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({
|
minetest.add_particlespawner({
|
||||||
amount = 20,
|
amount = 20,
|
||||||
time = 0.1,
|
time = 0.1,
|
||||||
|
|
|
@ -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 = -9.81, z = 0})
|
||||||
self:set_item(self.itemstring)
|
self:set_item(self.itemstring)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ core.register_entity(":__builtin:item", {
|
||||||
self.itemstring = ''
|
self.itemstring = ''
|
||||||
stack:set_count(count)
|
stack:set_count(count)
|
||||||
end
|
end
|
||||||
local pos = object:getpos()
|
local pos = object:get_pos()
|
||||||
pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15
|
pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15
|
||||||
object:moveto(pos, false)
|
object:moveto(pos, false)
|
||||||
local s, c
|
local s, c
|
||||||
|
@ -171,7 +171,7 @@ core.register_entity(":__builtin:item", {
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local p = self.object:getpos()
|
local p = self.object:get_pos()
|
||||||
p.y = p.y - 0.5
|
p.y = p.y - 0.5
|
||||||
local node = core.get_node_or_nil(p)
|
local node = core.get_node_or_nil(p)
|
||||||
-- Delete in 'ignore' nodes
|
-- 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
|
-- If node is nil (unloaded area), or node is not registered, or node is
|
||||||
-- walkably solid and item is resting on nodebox
|
-- walkably solid and item is resting on nodebox
|
||||||
local v = self.object:getvelocity()
|
local nn = node.name
|
||||||
if not node or not core.registered_nodes[node.name] or
|
local v = self.object:get_velocity()
|
||||||
core.registered_nodes[node.name].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
|
||||||
|
@ -198,17 +199,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 = -9.81, 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 = -9.81, z = -v.z})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ function core.get_player_radius_area(player_name, radius)
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local p1 = player:getpos()
|
local p1 = player:get_pos()
|
||||||
local p2 = p1
|
local p2 = p1
|
||||||
|
|
||||||
if radius then
|
if radius then
|
||||||
|
|
|
@ -17,7 +17,7 @@ local function put_player_in_spawn(player_obj)
|
||||||
end
|
end
|
||||||
core.log("action", "Moving " .. player_obj:get_player_name() ..
|
core.log("action", "Moving " .. player_obj:get_player_name() ..
|
||||||
" to static spawnpoint at " .. core.pos_to_string(static_spawnpoint))
|
" to static spawnpoint at " .. core.pos_to_string(static_spawnpoint))
|
||||||
player_obj:setpos(static_spawnpoint)
|
player_obj:set_pos(static_spawnpoint)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1515,6 +1515,8 @@ 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
|
||||||
|
|
|
@ -424,7 +424,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 != NULL);
|
assert(player != NULL);
|
||||||
player->applyControl(dtime);
|
player->applyControl(dtime, &m_env);
|
||||||
|
|
||||||
// Step environment
|
// Step environment
|
||||||
m_env.step(dtime);
|
m_env.step(dtime);
|
||||||
|
|
|
@ -4485,7 +4485,7 @@ void Game::updateGui(const RunStats &stats, f32 dtime, const CameraOrientation &
|
||||||
s32 status_width = guitext_status->getTextWidth();
|
s32 status_width = guitext_status->getTextWidth();
|
||||||
s32 status_height = guitext_status->getTextHeight();
|
s32 status_height = guitext_status->getTextHeight();
|
||||||
#if defined(__ANDROID__) || defined(__IOS__)
|
#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
|
#else
|
||||||
s32 status_y = screensize.Y - 150;
|
s32 status_y = screensize.Y - 150;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -518,7 +518,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;
|
||||||
|
@ -734,8 +734,13 @@ void LocalPlayer::applyControl(float dtime)
|
||||||
else
|
else
|
||||||
incH = incV = movement_acceleration_default * BS * dtime;
|
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
|
// 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);
|
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
|
// 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)
|
if (max_increase == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -1102,3 +1108,24 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
|
||||||
m_can_jump = false;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
@ -144,6 +145,7 @@ private:
|
||||||
void accelerateHorizontal(const v3f &target_speed, const f32 max_increase);
|
void accelerateHorizontal(const v3f &target_speed, const f32 max_increase);
|
||||||
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);
|
||||||
|
float getSlipFactor(Environment *env, const v3f &speedH);
|
||||||
|
|
||||||
v3f m_position;
|
v3f m_position;
|
||||||
v3s16 m_standing_node;
|
v3s16 m_standing_node;
|
||||||
|
|
|
@ -222,6 +222,7 @@ void ScriptApiSecurity::initializeSecurityClient()
|
||||||
"core",
|
"core",
|
||||||
"collectgarbage",
|
"collectgarbage",
|
||||||
"DIR_DELIM",
|
"DIR_DELIM",
|
||||||
|
"PLATFORM",
|
||||||
"error",
|
"error",
|
||||||
"getfenv",
|
"getfenv",
|
||||||
"ipairs",
|
"ipairs",
|
||||||
|
|
Loading…
Reference in New Issue