forked from VoxeLibre/VoxeLibre
Merge pull request '`mcl_item_entity` fixes' (#2936) from mcl-item-entity-fixes into master
Reviewed-on: MineClone2/MineClone2#2936 Reviewed-by: iliekprogrammar <iliekprogrammar@gmail.com>
This commit is contained in:
commit
5237eca31e
|
@ -14,24 +14,17 @@ local function mcl_log (message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
minetest.register_on_joinplayer(function(player)
|
||||||
local name
|
pool[player:get_player_name()] = 0
|
||||||
name = player:get_player_name()
|
|
||||||
pool[name] = 0
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_on_leaveplayer(function(player)
|
minetest.register_on_leaveplayer(function(player)
|
||||||
local name
|
pool[player:get_player_name()] = nil
|
||||||
name = player:get_player_name()
|
|
||||||
pool[name] = nil
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
local has_awards = minetest.get_modpath("awards")
|
local has_awards = minetest.get_modpath("awards")
|
||||||
|
|
||||||
local mcl_item_entity = {}
|
mcl_item_entity = {}
|
||||||
|
|
||||||
--basic settings
|
--basic settings
|
||||||
local item_drop_settings = {} --settings table
|
local item_drop_settings = {} --settings table
|
||||||
|
@ -52,16 +45,23 @@ local function get_gravity()
|
||||||
return tonumber(minetest.settings:get("movement_gravity")) or 9.81
|
return tonumber(minetest.settings:get("movement_gravity")) or 9.81
|
||||||
end
|
end
|
||||||
|
|
||||||
local registered_pickup_achievement = {}
|
mcl_item_entity.registered_pickup_achievement = {}
|
||||||
|
|
||||||
--TODO: remove limitation of 1 award per itemname
|
---Register an achievement that will be unlocked on pickup.
|
||||||
|
---
|
||||||
|
---TODO: remove limitation of 1 award per itemname
|
||||||
|
---@param itemname string
|
||||||
|
---@param award string
|
||||||
function mcl_item_entity.register_pickup_achievement(itemname, award)
|
function mcl_item_entity.register_pickup_achievement(itemname, award)
|
||||||
if not has_awards then
|
if not has_awards then
|
||||||
minetest.log("warning", "[mcl_item_entity] Trying to register pickup achievement ["..award.."] for ["..itemname.."] while awards missing")
|
minetest.log("warning",
|
||||||
elseif registered_pickup_achievement[itemname] then
|
"[mcl_item_entity] Trying to register pickup achievement [" .. award .. "] for [" ..
|
||||||
minetest.log("error", "[mcl_item_entity] Trying to register already existing pickup achievement ["..award.."] for ["..itemname.."]")
|
itemname .. "] while awards missing")
|
||||||
|
elseif mcl_item_entity.registered_pickup_achievement[itemname] then
|
||||||
|
minetest.log("error",
|
||||||
|
"[mcl_item_entity] Trying to register already existing pickup achievement [" .. award .. "] for [" .. itemname .. "]")
|
||||||
else
|
else
|
||||||
registered_pickup_achievement[itemname] = award
|
mcl_item_entity.registered_pickup_achievement[itemname] = award
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -74,11 +74,13 @@ mcl_item_entity.register_pickup_achievement("mcl_nether:ancient_debris", "mcl:hi
|
||||||
mcl_item_entity.register_pickup_achievement("mcl_end:dragon_egg", "mcl:PickUpDragonEgg")
|
mcl_item_entity.register_pickup_achievement("mcl_end:dragon_egg", "mcl:PickUpDragonEgg")
|
||||||
mcl_item_entity.register_pickup_achievement("mcl_armor:elytra", "mcl:skysTheLimit")
|
mcl_item_entity.register_pickup_achievement("mcl_armor:elytra", "mcl:skysTheLimit")
|
||||||
|
|
||||||
|
---@param object ObjectRef
|
||||||
|
---@param player ObjectRef
|
||||||
local function check_pickup_achievements(object, player)
|
local function check_pickup_achievements(object, player)
|
||||||
if has_awards then
|
if has_awards then
|
||||||
local itemname = ItemStack(object:get_luaentity().itemstring):get_name()
|
local itemname = ItemStack(object:get_luaentity().itemstring):get_name()
|
||||||
local playername = player:get_player_name()
|
local playername = player:get_player_name()
|
||||||
for name,award in pairs(registered_pickup_achievement) do
|
for name, award in pairs(mcl_item_entity.registered_pickup_achievement) do
|
||||||
if itemname == name or minetest.get_item_group(itemname, name) ~= 0 then
|
if itemname == name or minetest.get_item_group(itemname, name) ~= 0 then
|
||||||
awards.unlock(playername, award)
|
awards.unlock(playername, award)
|
||||||
end
|
end
|
||||||
|
@ -86,16 +88,23 @@ local function check_pickup_achievements(object, player)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param object ObjectRef
|
||||||
|
---@param luaentity Luaentity
|
||||||
|
---@param ignore_check? boolean
|
||||||
local function enable_physics(object, luaentity, ignore_check)
|
local function enable_physics(object, luaentity, ignore_check)
|
||||||
if luaentity.physical_state == false or ignore_check == true then
|
if luaentity.physical_state == false or ignore_check == true then
|
||||||
luaentity.physical_state = true
|
luaentity.physical_state = true
|
||||||
object:set_properties({
|
object:set_properties({
|
||||||
physical = true
|
physical = true
|
||||||
})
|
})
|
||||||
object:set_acceleration({x=0,y=-get_gravity(),z=0})
|
object:set_acceleration(vector.new(0, -get_gravity(), 0))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param object ObjectRef
|
||||||
|
---@param luaentity Luaentity
|
||||||
|
---@param ignore_check? boolean
|
||||||
|
---@param reset_movement? boolean
|
||||||
local function disable_physics(object, luaentity, ignore_check, reset_movement)
|
local function disable_physics(object, luaentity, ignore_check, reset_movement)
|
||||||
if luaentity.physical_state == true or ignore_check == true then
|
if luaentity.physical_state == true or ignore_check == true then
|
||||||
luaentity.physical_state = false
|
luaentity.physical_state = false
|
||||||
|
@ -103,14 +112,13 @@ local function disable_physics(object, luaentity, ignore_check, reset_movement)
|
||||||
physical = false
|
physical = false
|
||||||
})
|
})
|
||||||
if reset_movement ~= false then
|
if reset_movement ~= false then
|
||||||
object:set_velocity({x=0,y=0,z=0})
|
object:set_velocity(vector.zero())
|
||||||
object:set_acceleration({x=0,y=0,z=0})
|
object:set_acceleration(vector.zero())
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
minetest.register_globalstep(function(_)
|
||||||
minetest.register_globalstep(function(dtime)
|
|
||||||
tick = not tick
|
tick = not tick
|
||||||
|
|
||||||
for _, player in pairs(minetest.get_connected_players()) do
|
for _, player in pairs(minetest.get_connected_players()) do
|
||||||
|
@ -135,15 +143,18 @@ minetest.register_globalstep(function(dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local inv = player:get_inventory()
|
local inv = player:get_inventory()
|
||||||
local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z}
|
local checkpos = vector.offset(pos, 0, item_drop_settings.player_collect_height, 0)
|
||||||
|
|
||||||
--magnet and collection
|
--magnet and collection
|
||||||
for _, object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do
|
for _, object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do
|
||||||
if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then
|
if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and
|
||||||
|
object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer
|
||||||
|
and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then
|
||||||
|
|
||||||
if object:get_luaentity()._magnet_timer >= 0 and object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then
|
if object:get_luaentity()._magnet_timer >= 0 and
|
||||||
|
object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and
|
||||||
|
inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then
|
||||||
|
|
||||||
-- Collection
|
-- Collection
|
||||||
if not object:get_luaentity()._removed then
|
if not object:get_luaentity()._removed then
|
||||||
|
@ -158,8 +169,8 @@ minetest.register_globalstep(function(dtime)
|
||||||
object:get_luaentity().target = checkpos
|
object:get_luaentity().target = checkpos
|
||||||
object:get_luaentity()._removed = true
|
object:get_luaentity()._removed = true
|
||||||
|
|
||||||
object:set_velocity({x=0,y=0,z=0})
|
object:set_velocity(vector.zero())
|
||||||
object:set_acceleration({x=0,y=0,z=0})
|
object:set_acceleration(vector.zero())
|
||||||
|
|
||||||
object:move_to(checkpos)
|
object:move_to(checkpos)
|
||||||
|
|
||||||
|
@ -179,7 +190,6 @@ minetest.register_globalstep(function(dtime)
|
||||||
local entity = object:get_luaentity()
|
local entity = object:get_luaentity()
|
||||||
entity.collector = player:get_player_name()
|
entity.collector = player:get_player_name()
|
||||||
entity.collected = true
|
entity.collected = true
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -194,6 +204,11 @@ end)
|
||||||
|
|
||||||
local tmp_id = 0
|
local tmp_id = 0
|
||||||
|
|
||||||
|
---@param drop string|drop_definition
|
||||||
|
---@param toolname string
|
||||||
|
---@param param2 integer
|
||||||
|
---@param paramtype2 paramtype2
|
||||||
|
---@return string[]
|
||||||
local function get_drops(drop, toolname, param2, paramtype2)
|
local function get_drops(drop, toolname, param2, paramtype2)
|
||||||
tmp_id = tmp_id + 1
|
tmp_id = tmp_id + 1
|
||||||
local tmp_node_name = "mcl_item_entity:" .. tmp_id
|
local tmp_node_name = "mcl_item_entity:" .. tmp_id
|
||||||
|
@ -265,7 +280,7 @@ function minetest.handle_node_drops(pos, drops, digger)
|
||||||
* table: Drop every itemstring in this table when dug by shears _mcl_silk_touch_drop
|
* table: Drop every itemstring in this table when dug by shears _mcl_silk_touch_drop
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local enchantments = tool and mcl_enchanting.get_enchantments(tool, "silk_touch")
|
local enchantments = tool and mcl_enchanting.get_enchantments(tool)
|
||||||
|
|
||||||
local silk_touch_drop = false
|
local silk_touch_drop = false
|
||||||
local nodedef = minetest.registered_nodes[dug_node.name]
|
local nodedef = minetest.registered_nodes[dug_node.name]
|
||||||
|
@ -294,7 +309,8 @@ function minetest.handle_node_drops(pos, drops, digger)
|
||||||
local max_count = fortune_drop.max_count + fortune_level * (fortune_drop.factor or 1)
|
local max_count = fortune_drop.max_count + fortune_level * (fortune_drop.factor or 1)
|
||||||
local chance = fortune_drop.chance or fortune_drop.get_chance and fortune_drop.get_chance(fortune_level)
|
local chance = fortune_drop.chance or fortune_drop.get_chance and fortune_drop.get_chance(fortune_level)
|
||||||
if not chance or math.random() < chance then
|
if not chance or math.random() < chance then
|
||||||
drops = discrete_uniform_distribution(fortune_drop.multiply and drops or fortune_drop.items, min_count, max_count, fortune_drop.cap)
|
drops = discrete_uniform_distribution(fortune_drop.multiply and drops or fortune_drop.items, min_count, max_count,
|
||||||
|
fortune_drop.cap)
|
||||||
elseif fortune_drop.override then
|
elseif fortune_drop.override then
|
||||||
drops = {}
|
drops = {}
|
||||||
end
|
end
|
||||||
|
@ -348,7 +364,7 @@ end
|
||||||
function minetest.item_drop(itemstack, dropper, pos)
|
function minetest.item_drop(itemstack, dropper, pos)
|
||||||
if dropper and dropper:is_player() then
|
if dropper and dropper:is_player() then
|
||||||
local v = dropper:get_look_dir()
|
local v = dropper:get_look_dir()
|
||||||
local p = {x=pos.x, y=pos.y+1.2, z=pos.z}
|
local p = vector.offset(pos, 0, 1.2, 0)
|
||||||
local cs = itemstack:get_count()
|
local cs = itemstack:get_count()
|
||||||
if dropper:get_player_control().sneak then
|
if dropper:get_player_control().sneak then
|
||||||
cs = 1
|
cs = 1
|
||||||
|
@ -548,7 +564,7 @@ minetest.register_entity(":__builtin:item", {
|
||||||
local z = math.random(5, 10) / 10 * v
|
local z = math.random(5, 10) / 10 * v
|
||||||
if math.random(0, 10) < 5 then z = -z end
|
if math.random(0, 10) < 5 then z = -z end
|
||||||
local y = math.random(2, 4)
|
local y = math.random(2, 4)
|
||||||
self.object:set_velocity({x=x, y=y, z=z})
|
self.object:set_velocity(vector.new(x, y, z))
|
||||||
end
|
end
|
||||||
self.random_velocity = 0
|
self.random_velocity = 0
|
||||||
end,
|
end,
|
||||||
|
@ -696,8 +712,8 @@ minetest.register_entity(":__builtin:item", {
|
||||||
self._forcetimer = 0
|
self._forcetimer = 0
|
||||||
|
|
||||||
self.object:set_armor_groups({ immortal = 1 })
|
self.object:set_armor_groups({ immortal = 1 })
|
||||||
-- self.object:set_velocity({x = 0, y = 2, z = 0})
|
-- self.object:set_velocity(vector.new(0, 2, 0))
|
||||||
self.object:set_acceleration({x = 0, y = -get_gravity(), z = 0})
|
self.object:set_acceleration(vector.new(0, -get_gravity(), 0))
|
||||||
self:set_item(self.itemstring)
|
self:set_item(self.itemstring)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
@ -745,8 +761,8 @@ minetest.register_entity(":__builtin:item", {
|
||||||
self.object:set_properties({
|
self.object:set_properties({
|
||||||
physical = false
|
physical = false
|
||||||
})
|
})
|
||||||
self.object:set_velocity({x=0,y=0,z=0})
|
self.object:set_velocity(vector.zero())
|
||||||
self.object:set_acceleration({x=0,y=0,z=0})
|
self.object:set_acceleration(vector.zero())
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
self.age = self.age + dtime
|
self.age = self.age + dtime
|
||||||
|
@ -761,21 +777,22 @@ minetest.register_entity(":__builtin:item", {
|
||||||
-- Delete corrupted item entities. The itemstring MUST be non-empty on its first step,
|
-- Delete corrupted item entities. The itemstring MUST be non-empty on its first step,
|
||||||
-- otherwise there might have some data corruption.
|
-- otherwise there might have some data corruption.
|
||||||
if self.itemstring == "" then
|
if self.itemstring == "" then
|
||||||
minetest.log("warning", "Item entity with empty itemstring found at "..minetest.pos_to_string(self.object:get_pos()).. "! Deleting it now.")
|
minetest.log("warning",
|
||||||
|
"Item entity with empty itemstring found at " .. minetest.pos_to_string(self.object:get_pos()) ..
|
||||||
|
"! Deleting it now.")
|
||||||
self._removed = true
|
self._removed = true
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local p = self.object:get_pos()
|
local p = self.object:get_pos()
|
||||||
|
|
||||||
-- If hopper has taken item, it has gone, and no operations should be conducted on this item
|
-- If hopper has taken item, it has gone, and no operations should be conducted on this item
|
||||||
if hopper_take_item(self, p) then
|
if hopper_take_item(self, p) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local node = minetest.get_node_or_nil(p)
|
local node = minetest.get_node(p)
|
||||||
local in_unloaded = (node == nil)
|
local in_unloaded = node.name == "ignore"
|
||||||
|
|
||||||
if in_unloaded then
|
if in_unloaded then
|
||||||
-- Don't infinetly fall into unloaded map
|
-- Don't infinetly fall into unloaded map
|
||||||
|
@ -791,7 +808,7 @@ minetest.register_entity(":__builtin:item", {
|
||||||
|
|
||||||
local nn = node.name
|
local nn = node.name
|
||||||
local is_in_water = (minetest.get_item_group(nn, "liquid") ~= 0)
|
local is_in_water = (minetest.get_item_group(nn, "liquid") ~= 0)
|
||||||
local nn_above = minetest.get_node({x=p.x, y=p.y+0.1, z=p.z}).name
|
local nn_above = minetest.get_node(vector.offset(p, 0, 0.1, 0)).name
|
||||||
-- make sure it's more or less stationary and is at water level
|
-- make sure it's more or less stationary and is at water level
|
||||||
local sleep_threshold = 0.3
|
local sleep_threshold = 0.3
|
||||||
local is_floating = false
|
local is_floating = false
|
||||||
|
@ -804,8 +821,8 @@ minetest.register_entity(":__builtin:item", {
|
||||||
end
|
end
|
||||||
|
|
||||||
if is_floating and self.physical_state == true then
|
if is_floating and self.physical_state == true then
|
||||||
self.object:set_velocity({x = 0, y = 0, z = 0})
|
self.object:set_velocity(vector.zero())
|
||||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
self.object:set_acceleration(vector.zero())
|
||||||
disable_physics(self.object, self)
|
disable_physics(self.object, self)
|
||||||
end
|
end
|
||||||
-- If no collector was found for a long enough time, declare the magnet as disabled
|
-- If no collector was found for a long enough time, declare the magnet as disabled
|
||||||
|
@ -875,7 +892,7 @@ minetest.register_entity(":__builtin:item", {
|
||||||
end
|
end
|
||||||
-- If none of the 4 sides is free, shoot upwards
|
-- If none of the 4 sides is free, shoot upwards
|
||||||
if shootdir == nil then
|
if shootdir == nil then
|
||||||
shootdir = { x=0, y=1, z=0 }
|
shootdir = vector.new(0, 1, 0)
|
||||||
local nn = minetest.get_node(vector.add(p, shootdir)).name
|
local nn = minetest.get_node(vector.add(p, shootdir)).name
|
||||||
if nn == "ignore" then
|
if nn == "ignore" then
|
||||||
-- Do not push into ignore
|
-- Do not push into ignore
|
||||||
|
@ -885,7 +902,7 @@ minetest.register_entity(":__builtin:item", {
|
||||||
|
|
||||||
-- Set new item moving speed accordingly
|
-- Set new item moving speed accordingly
|
||||||
local newv = vector.multiply(shootdir, 3)
|
local newv = vector.multiply(shootdir, 3)
|
||||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
self.object:set_acceleration(vector.zero())
|
||||||
self.object:set_velocity(newv)
|
self.object:set_velocity(newv)
|
||||||
disable_physics(self.object, self, false, false)
|
disable_physics(self.object, self, false, false)
|
||||||
|
|
||||||
|
@ -941,7 +958,7 @@ minetest.register_entity(":__builtin:item", {
|
||||||
-- Set new item moving speed into the direciton of the liquid
|
-- Set new item moving speed into the direciton of the liquid
|
||||||
local newv = vector.multiply(vec, f)
|
local newv = vector.multiply(vec, f)
|
||||||
-- Swap to acceleration instead of a static speed to better mimic MC mechanics.
|
-- Swap to acceleration instead of a static speed to better mimic MC mechanics.
|
||||||
self.object:set_acceleration({x = newv.x, y = -0.22, z = newv.z})
|
self.object:set_acceleration(vector.new(newv.x, -0.22, newv.z))
|
||||||
|
|
||||||
self.physical_state = true
|
self.physical_state = true
|
||||||
self._flowing = true
|
self._flowing = true
|
||||||
|
@ -956,7 +973,8 @@ minetest.register_entity(":__builtin:item", {
|
||||||
local vec = {
|
local vec = {
|
||||||
x = 0 - cur_vec.x * 0.9,
|
x = 0 - cur_vec.x * 0.9,
|
||||||
y = 3 - cur_vec.y * 0.9,
|
y = 3 - cur_vec.y * 0.9,
|
||||||
z = 0 -cur_vec.z*0.9}
|
z = 0 - cur_vec.z * 0.9
|
||||||
|
}
|
||||||
self.object:set_acceleration(vec)
|
self.object:set_acceleration(vec)
|
||||||
-- slow down the item in water
|
-- slow down the item in water
|
||||||
local vel = self.object:get_velocity()
|
local vel = self.object:get_velocity()
|
||||||
|
@ -980,7 +998,7 @@ minetest.register_entity(":__builtin:item", {
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 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 nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
|
local nn = minetest.get_node(vector.offset(p, 0, -0.5, 0)).name
|
||||||
local def = minetest.registered_nodes[nn]
|
local def = minetest.registered_nodes[nn]
|
||||||
local v = self.object:get_velocity()
|
local v = self.object:get_velocity()
|
||||||
local is_on_floor = def and (def.walkable
|
local is_on_floor = def and (def.walkable
|
||||||
|
|
Loading…
Reference in New Issue