Delete un-initialized item entities on first step
Due to data corruption, item entities in a world may be loaded with empty staticdata. These items are now deleted on their first on_step. This commit also should fix all dropped hand bugs.
This commit is contained in:
parent
a5b213968c
commit
312652552e
|
@ -68,7 +68,7 @@ minetest.register_globalstep(function(dtime)
|
||||||
|
|
||||||
-- Collection
|
-- Collection
|
||||||
if vector.distance(checkpos, object:getpos()) <= item_drop_settings.radius_collect and not object:get_luaentity()._removed then
|
if vector.distance(checkpos, object:getpos()) <= item_drop_settings.radius_collect and not object:get_luaentity()._removed then
|
||||||
|
-- Ignore if itemstring is not set yet
|
||||||
if object:get_luaentity().itemstring ~= "" then
|
if object:get_luaentity().itemstring ~= "" then
|
||||||
inv:add_item("main", ItemStack(object:get_luaentity().itemstring))
|
inv:add_item("main", ItemStack(object:get_luaentity().itemstring))
|
||||||
minetest.sound_play("item_drop_pickup", {
|
minetest.sound_play("item_drop_pickup", {
|
||||||
|
@ -78,20 +78,14 @@ minetest.register_globalstep(function(dtime)
|
||||||
})
|
})
|
||||||
check_pickup_achievements(object, player)
|
check_pickup_achievements(object, player)
|
||||||
|
|
||||||
-- If this happens, itemstring was "" (=hand). This is always a bug, the hand must never drop as item.
|
|
||||||
else
|
|
||||||
-- Scream this to the error log because this is bad.
|
|
||||||
minetest.log("error", "Player "..player:get_player_name().." collected a hand at "..minetest.pos_to_string(object:getpos()).." (age="..object:get_luaentity().age..")!")
|
|
||||||
|
|
||||||
|
-- Destroy entity
|
||||||
|
-- This just prevents this section to be run again because object:remove() doesn't remove the item immediately.
|
||||||
|
object:get_luaentity()._removed = true
|
||||||
|
object:remove()
|
||||||
|
collected = true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Destroy entity
|
|
||||||
|
|
||||||
-- This just prevents this sectino to be run again because object:remove() doesn't remove the item immediately.
|
|
||||||
object:get_luaentity()._removed = true
|
|
||||||
object:remove()
|
|
||||||
collected = true
|
|
||||||
|
|
||||||
-- Magnet
|
-- Magnet
|
||||||
else
|
else
|
||||||
|
|
||||||
|
@ -313,17 +307,27 @@ core.register_entity(":__builtin:item", {
|
||||||
infotext = "",
|
infotext = "",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
-- Itemstring of dropped item. The empty string is used when the item is not yet initialized yet.
|
||||||
|
-- The itemstring MUST be set immediately to a non-empty string after creating the entity.
|
||||||
|
-- The hand is NOT permitted as dropped item. ;-)
|
||||||
|
-- Item entities will be deleted if they still have an empty itemstring on their first on_step tick.
|
||||||
itemstring = '',
|
itemstring = '',
|
||||||
|
|
||||||
|
-- If true, item will fall
|
||||||
physical_state = true,
|
physical_state = true,
|
||||||
_flowing = false, -- item entity is currently flowing
|
|
||||||
-- States:
|
-- If item entity is currently flowing in water
|
||||||
-- * "magnet": Attracted to a nearby player or item
|
_flowing = false,
|
||||||
-- * "flowing": Moving in a flowing liquid
|
|
||||||
-- * "normal": Affected by gravitiy
|
-- Number of seconds this item entity has existed so far
|
||||||
age = 0,
|
age = 0,
|
||||||
|
|
||||||
set_item = function(self, itemstring)
|
set_item = function(self, itemstring)
|
||||||
self.itemstring = itemstring
|
self.itemstring = itemstring
|
||||||
|
if self.itemstring == "" then
|
||||||
|
-- item not yet known
|
||||||
|
return
|
||||||
|
end
|
||||||
local stack = ItemStack(itemstring)
|
local stack = ItemStack(itemstring)
|
||||||
local count = stack:get_count()
|
local count = stack:get_count()
|
||||||
local max_count = stack:get_stack_max()
|
local max_count = stack:get_stack_max()
|
||||||
|
@ -488,11 +492,12 @@ core.register_entity(":__builtin:item", {
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- If, for some reason, an item entity with itemstring == "" (hand) appears, this is very bad.
|
-- Delete corrupted item entities. The itemstring MUST be non-empty on its first step,
|
||||||
if not self._hand_bug_detected and self.age > 1 and self.itemstring == "" then
|
-- otherwise there might have some data corruption.
|
||||||
-- We must this scream this into the error console. The bug is rare an
|
if self.itemstring == "" then
|
||||||
minetest.log("error", "A hand item entity appeared at "..minetest.pos_to_string(self.object:getpos()).. "!")
|
minetest.log("warning", "Item entity with empty itemstring found at "..minetest.pos_to_string(self.object:getpos()).. "! Deleting it now.")
|
||||||
self._hand_bug_detected = true
|
self._removed = true
|
||||||
|
self.object:remove()
|
||||||
end
|
end
|
||||||
|
|
||||||
local p = self.object:getpos()
|
local p = self.object:getpos()
|
||||||
|
|
Loading…
Reference in New Issue