Cristiano Magro
2020-10-19 c189a33eec2e9a22c0101c07e4177619c6b6240c
wrench/init.lua
@@ -6,7 +6,12 @@
The wrench has the same tool capability as the normal hand.
To pickup a node simply right click on it. If the node contains a formspec,
you will need to shift+right click instead.
Because it enables arbitrary nesting of chests, and so allows the player
to carry an unlimited amount of material at once, this wrench is not
available to survival-mode players.
--]]
local LATEST_SERIALIZATION_VERSION = 1
wrench = {}
@@ -14,12 +19,12 @@
dofile(modpath.."/support.lua")
dofile(modpath.."/technic.lua")
-- Boilerplate to support localized strings if intllib mod is installed.
local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end
local function get_meta_type(name, metaname)
   local def = wrench.registered_nodes[name]
   if not def or not def.metas or not def.metas[metaname] then
      return nil
   end
   return def.metas[metaname]
   return def and def.metas and def.metas[metaname] or nil
end
local function get_pickup_name(name)
@@ -28,14 +33,21 @@
local function restore(pos, placer, itemstack)
   local name = itemstack:get_name()
   local node = minetest.get_node(pos)
   local meta = minetest.get_meta(pos)
   local inv = meta:get_inventory()
   local data = minetest.deserialize(itemstack:get_metadata())
   minetest.set_node(pos, {name = data.name})
   local lists = data.lists
   for listname, list in pairs(lists) do
      inv:set_list(listname, list)
   local data = itemstack:get_meta():get_string("data")
   data = (data ~= "" and data) or   itemstack:get_metadata()
   data = minetest.deserialize(data)
   if not data then
      minetest.remove_node(pos)
      minetest.log("error", placer:get_player_name().." wanted to place "..
            name.." at "..minetest.pos_to_string(pos)..
            ", but it had no data.")
      minetest.log("verbose", "itemstack: "..itemstack:to_string())
      return true
   end
   minetest.set_node(pos, {name = data.name, param2 = node.param2})
   for name, value in pairs(data.metas) do
      local meta_type = get_meta_type(data.name, name)
      if meta_type == wrench.META_TYPE_INT then
@@ -45,6 +57,10 @@
      elseif meta_type == wrench.META_TYPE_STRING then
         meta:set_string(name, value)
      end
   end
   local lists = data.lists
   for listname, list in pairs(lists) do
      inv:set_list(listname, list)
   end
   itemstack:take_item()
   return itemstack
@@ -58,7 +74,7 @@
         newdef[key] = value
      end
      newdef.stack_max = 1
      newdef.description = newdef.description.." with items"
      newdef.description = S("%s with items"):format(newdef.description)
      newdef.groups = {}
      newdef.groups.not_in_creative_inventory = 1
      newdef.on_construct = nil
@@ -69,7 +85,7 @@
end
minetest.register_tool("wrench:wrench", {
   description = "Wrench",
   description = S("Wrench"),
   inventory_image = "technic_wrench.png",
   tool_capabilities = {
      full_punch_interval = 0.9,
@@ -87,8 +103,9 @@
      if not placer or not pos then
         return
      end
      if minetest.is_protected(pos, placer:get_player_name()) then
         minetest.record_protection_violation(pos, placer:get_player_name())
      local player_name = placer:get_player_name()
      if minetest.is_protected(pos, player_name) then
         minetest.record_protection_violation(pos, player_name)
         return
      end
      local name = minetest.get_node(pos).name
@@ -103,11 +120,11 @@
         return
      end
      local meta = minetest.get_meta(pos)
      if def.owned then
      if def.owned and not minetest.check_player_privs(placer, "protection_bypass") then
         local owner = meta:get_string("owner")
         if owner and owner ~= placer:get_player_name() then
            minetest.log("action", placer:get_player_name()..
               " tried to pick up a owned node belonging to "..
         if owner and owner ~= player_name then
            minetest.log("action", player_name..
               " tried to pick up an owned node belonging to "..
               owner.." at "..
               minetest.pos_to_string(pos))
            return
@@ -116,13 +133,11 @@
      local metadata = {}
      metadata.name = name
      metadata.version = LATEST_SERIALIZATION_VERSION
      local inv = meta:get_inventory()
      local lists = {}
      for _, listname in pairs(def.lists or {}) do
         if not inv:is_empty(listname) then
            empty = false
         end
         local list = inv:get_list(listname)
         for i, stack in pairs(list) do
            list[i] = stack:to_string()
@@ -130,32 +145,23 @@
         lists[listname] = list
      end
      metadata.lists = lists
      local metas = {}
      local item_meta = stack:get_meta()
      metadata.metas = {}
      for name, meta_type in pairs(def.metas or {}) do
         if meta_type == wrench.META_TYPE_INT then
            metas[name] = meta:get_int(name)
            metadata.metas[name] = meta:get_int(name)
         elseif meta_type == wrench.META_TYPE_FLOAT then
            metas[name] = meta:get_float(name)
            metadata.metas[name] = meta:get_float(name)
         elseif meta_type == wrench.META_TYPE_STRING then
            metas[name] = meta:get_string(name)
            metadata.metas[name] = meta:get_string(name)
         end
      end
      metadata.metas = metas
      stack:set_metadata(minetest.serialize(metadata))
      item_meta:set_string("data", minetest.serialize(metadata))
      minetest.remove_node(pos)
      itemstack:add_wear(65535 / 20)
      player_inv:add_item("main", stack)
      return itemstack
   end,
})
minetest.register_craft({
   output = "wrench:wrench",
   recipe = {
      {"default:steel_ingot", "",                    "default:steel_ingot"},
      {"",                    "default:steel_ingot", ""},
      {"",                    "default:steel_ingot", ""},
   },
})