Skip to content

Commit

Permalink
Prevent merging of dropped items with different metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
juhdanad authored and sofar committed Apr 9, 2017
1 parent 31f1d87 commit 67207d2
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 9 deletions.
28 changes: 19 additions & 9 deletions builtin/game/item_entity.lua
Expand Up @@ -102,50 +102,60 @@ core.register_entity(":__builtin:item", {
self:set_item(self.itemstring)
end,

-- moves items from this stack to an other stack
try_merge_with = function(self, own_stack, object, obj)
-- other item's stack
local stack = ItemStack(obj.itemstring)
if own_stack:get_name() == stack:get_name() and stack:get_free_space() > 0 then
-- only merge if items are the same
if own_stack:get_name() == stack:get_name() and
own_stack:get_meta() == stack:get_meta() and
own_stack:get_wear() == stack:get_wear() and
stack:get_free_space() > 0 then
local overflow = false
local count = stack:get_count() + own_stack:get_count()
local max_count = stack:get_stack_max()
if count > max_count then
overflow = true
stack:set_count(max_count)
count = count - max_count
own_stack:set_count(count)
else
self.itemstring = ''
stack:set_count(count)
end
local pos = object:getpos()
pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15
object:moveto(pos, false)
local s, c
local max_count = stack:get_stack_max()
local name = stack:get_name()
if not overflow then
obj.itemstring = name .. " " .. count
obj.itemstring = stack:to_string()
s = 0.2 + 0.1 * (count / max_count)
c = s
object:set_properties({
visual_size = {x = s, y = s},
collisionbox = {-c, -c, -c, c, c, c}
collisionbox = {-c, -c, -c, c, c, c},
wield_item = obj.itemstring
})
self.object:remove()
-- merging succeeded
return true
else
s = 0.4
c = 0.3
obj.itemstring = stack:to_string()
object:set_properties({
visual_size = {x = s, y = s},
collisionbox = {-c, -c, -c, c, c, c}
collisionbox = {-c, -c, -c, c, c, c},
wield_item = obj.itemstring
})
obj.itemstring = name .. " " .. max_count
s = 0.2 + 0.1 * (count / max_count)
c = s
self.itemstring = own_stack:to_string()
self.object:set_properties({
visual_size = {x = s, y = s},
collisionbox = {-c, -c, -c, c, c, c}
collisionbox = {-c, -c, -c, c, c, c},
wield_item = self.itemstring
})
self.itemstring = name .. " " .. count
end
end
-- merging didn't succeed
Expand Down
2 changes: 2 additions & 0 deletions doc/lua_api.txt
Expand Up @@ -2855,6 +2855,8 @@ See `StorageRef`, `NodeMetaRef` and `ItemStackMetaRef`.
* Any non-table value will clear the metadata
* See "Node Metadata" for an example
* returns `true` on success
* `equals(other)`
* returns `true` if this metadata has the same key-value pairs as `other`

### `NodeMetaRef`
Node metadata: reference extra data and functionality stored in a node.
Expand Down
5 changes: 5 additions & 0 deletions src/script/lua_api/l_itemstackmeta.cpp
Expand Up @@ -92,6 +92,10 @@ void ItemStackMetaRef::Register(lua_State *L)
lua_pushcfunction(L, gc_object);
lua_settable(L, metatable);

lua_pushliteral(L, "__eq");
lua_pushcfunction(L, l_equals);
lua_settable(L, metatable);

lua_pop(L, 1); // drop metatable

luaL_openlib(L, 0, methods, 0); // fill methodtable
Expand All @@ -111,5 +115,6 @@ const luaL_Reg ItemStackMetaRef::methods[] = {
luamethod(MetaDataRef, set_float),
luamethod(MetaDataRef, to_table),
luamethod(MetaDataRef, from_table),
luamethod(MetaDataRef, equals),
{0,0}
};
14 changes: 14 additions & 0 deletions src/script/lua_api/l_metadata.cpp
Expand Up @@ -250,3 +250,17 @@ bool MetaDataRef::handleFromTable(lua_State *L, int table, Metadata *meta)

return true;
}

// equals(self, other)
int MetaDataRef::l_equals(lua_State *L){
MetaDataRef *ref1 = checkobject(L, 1);
Metadata *data1 = ref1->getmeta(false);
MetaDataRef *ref2 = checkobject(L, 2);
Metadata *data2 = ref2->getmeta(false);
if (data1 == NULL || data2 == NULL) {
lua_pushboolean(L, data1 == data2);
return 1;
}
lua_pushboolean(L, *data1 == *data2);
return 1;
}
3 changes: 3 additions & 0 deletions src/script/lua_api/l_metadata.h
Expand Up @@ -67,6 +67,9 @@ class MetaDataRef : public ModApiBase

// from_table(self, table)
static int l_from_table(lua_State *L);

// equals(self, other)
static int l_equals(lua_State *L);
};

#endif /* L_NODEMETA_H_ */
5 changes: 5 additions & 0 deletions src/script/lua_api/l_nodemeta.cpp
Expand Up @@ -204,6 +204,10 @@ void NodeMetaRef::RegisterCommon(lua_State *L)
lua_pushcfunction(L, gc_object);
lua_settable(L, metatable);

lua_pushliteral(L, "__eq");
lua_pushcfunction(L, l_equals);
lua_settable(L, metatable);

lua_pop(L, 1); // drop metatable
}

Expand All @@ -225,6 +229,7 @@ const luaL_Reg NodeMetaRef::methodsServer[] = {
luamethod(MetaDataRef, to_table),
luamethod(MetaDataRef, from_table),
luamethod(NodeMetaRef, get_inventory),
luamethod(MetaDataRef, equals),
{0,0}
};

Expand Down
5 changes: 5 additions & 0 deletions src/script/lua_api/l_storage.cpp
Expand Up @@ -98,6 +98,10 @@ void StorageRef::Register(lua_State *L)
lua_pushcfunction(L, gc_object);
lua_settable(L, metatable);

lua_pushliteral(L, "__eq");
lua_pushcfunction(L, l_equals);
lua_settable(L, metatable);

lua_pop(L, 1); // drop metatable

luaL_openlib(L, 0, methods, 0); // fill methodtable
Expand Down Expand Up @@ -138,5 +142,6 @@ const luaL_Reg StorageRef::methods[] = {
luamethod(MetaDataRef, set_float),
luamethod(MetaDataRef, to_table),
luamethod(MetaDataRef, from_table),
luamethod(MetaDataRef, equals),
{0,0}
};

0 comments on commit 67207d2

Please sign in to comment.