Compare against canonical item name on pickup
This commit is contained in:
parent
13be3b747a
commit
e686c40c55
@ -17,7 +17,7 @@ Features:
|
||||
the item entity will be instantly deleted
|
||||
* If `_rp_canonical_item` is set in the item definition, this item (itemname) will
|
||||
be used for the entity instead when it spawns. Useful when an item has multiple
|
||||
variants ike a compass
|
||||
variants like a compass
|
||||
|
||||
## Licensing
|
||||
Credits: Originally by Minetest developers (from the `builtin` part of Minetest)
|
||||
|
@ -257,8 +257,9 @@ minetest.register_entity(":__builtin:item", {
|
||||
end
|
||||
if closest_player ~= nil and lua.item_magnet_timer <= 0 and len < ITEM_MAGNET_ACTIVE_DISTANCE then
|
||||
local inv = closest_player:get_inventory()
|
||||
local luastack = ItemStack(lua.itemstring)
|
||||
-- Activate item magnet
|
||||
if inv and inv:room_for_item("main", ItemStack(lua.itemstring)) then
|
||||
if inv and inv:room_for_item("main", luastack) then
|
||||
if len >= ITEM_MAGNET_COLLECT_DISTANCE then
|
||||
-- Attract item to player
|
||||
vec = vector.divide(vec, len) -- It's a normalize but we have len yet (vector.normalize(vec))
|
||||
@ -273,13 +274,13 @@ minetest.register_entity(":__builtin:item", {
|
||||
return
|
||||
else
|
||||
-- Player collects item if close enough
|
||||
if inv:room_for_item("main", ItemStack(lua.itemstring)) then
|
||||
if inv:room_for_item("main", luastack) then
|
||||
if minetest.is_creative_enabled(closest_player:get_player_name()) then
|
||||
if not inv:contains_item("main", ItemStack(lua.itemstring), true) then
|
||||
inv:add_item("main", ItemStack(lua.itemstring))
|
||||
if not inv:contains_item("main", luastack, true) and not util.contains_item_canonical(inv, "main", luastack) then
|
||||
inv:add_item("main", luastack)
|
||||
end
|
||||
else
|
||||
inv:add_item("main", ItemStack(lua.itemstring))
|
||||
inv:add_item("main", luastack)
|
||||
end
|
||||
|
||||
if lua.itemstring ~= "" then
|
||||
|
@ -1 +1,2 @@
|
||||
name = rp_builtin_item
|
||||
depends = rp_util
|
||||
|
@ -100,7 +100,8 @@ function minetest.handle_node_drops(pos, drops, digger)
|
||||
local inv = digger:get_inventory()
|
||||
if inv then
|
||||
for _,item in ipairs(drops) do
|
||||
if not inv:contains_item("main", item, true) then
|
||||
item = ItemStack(item)
|
||||
if not inv:contains_item("main", item, true) and not util.contains_item_canonical(inv, "main", item) then
|
||||
inv:add_item("main", item)
|
||||
end
|
||||
end
|
||||
|
@ -1 +1,2 @@
|
||||
name = rp_item_drop
|
||||
depends = rp_util
|
||||
|
@ -172,3 +172,22 @@ Always returns `false` for non-nodes.
|
||||
|
||||
Returns `true` if node at given pos is water AND either a source or a "waterfall"
|
||||
(water flowing downwards)
|
||||
|
||||
|
||||
|
||||
## ` util.contains_item_canonical(inv, list, stack)`
|
||||
|
||||
Checks if the inventory contains `stack` with the same metadata.
|
||||
Unlike `inv:contains_item`, it will treat two item names as equal
|
||||
if the *canonical name* of each item is equal.
|
||||
The canonical name of an item is specified by the item definition field
|
||||
`_rp_canonical_item`. If this is nil, the canonical item name is
|
||||
same the item name.
|
||||
|
||||
Parameters:
|
||||
|
||||
* `inv`: InvRef of inventory to check
|
||||
* `list`: Inventory list name
|
||||
* `stack`: ItemStack to compare to
|
||||
|
||||
Returns `true` if a matching item was found, `false` otherwise.
|
||||
|
@ -285,3 +285,42 @@ function util.is_water_source_or_waterfall(pos)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function util.contains_item_canonical(inv, list, stack)
|
||||
stack = ItemStack(stack)
|
||||
if stack:is_empty() then
|
||||
return false
|
||||
end
|
||||
-- Set count and wear of stack and comparison stack
|
||||
-- to identical value because we don't care about
|
||||
-- those
|
||||
stack:set_count(1)
|
||||
stack:set_wear(0)
|
||||
local def = stack:get_definition()
|
||||
if not def then
|
||||
return false
|
||||
end
|
||||
if def._rp_canonical_item then
|
||||
stack:set_name(def._rp_canonical_item)
|
||||
else
|
||||
-- If no canonical item, just use the regular contains_item check instead
|
||||
return inv:contains_item(list, stack, true)
|
||||
end
|
||||
-- Iterate through all items in the list and check if the item
|
||||
-- is equal
|
||||
for i=1, inv:get_size(list) do
|
||||
local cstack = inv:get_stack(list, i)
|
||||
if not cstack:is_empty() then
|
||||
cstack:set_count(1)
|
||||
cstack:set_wear(0)
|
||||
local cdef = cstack:get_definition()
|
||||
if cdef and cdef._rp_canonical_item then
|
||||
cstack:set_name(cdef._rp_canonical_item)
|
||||
end
|
||||
if stack:equals(cstack) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user