init.lua 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. --------------------------------------------------------------------------------
  2. -- Mod: Itemframes
  3. -- Author: Zeg9
  4. -- License: WTFPL
  5. --------------------------------------------------------------------------------
  6. local tmp = {}
  7. if not minetest.global_exists("screwdriver") then screwdriver = {} end
  8. local function on_rename_check(pos, nodename)
  9. local meta = minetest.get_meta(pos)
  10. local owner = meta:get_string("owner")
  11. -- Nobody placed this block.
  12. if owner == "" then
  13. return
  14. end
  15. local dname = rename.gpn(owner)
  16. meta:set_string("rename", dname)
  17. meta:set_string("infotext", nodename .. " (Owned by <" .. dname .. ">!)")
  18. end
  19. minetest.register_entity("itemframes:item",{
  20. hp_max = 1,
  21. visual="wielditem",
  22. visual_size={x = 0.33, y = 0.33},
  23. collisionbox = {0, 0, 0, 0, 0, 0},
  24. physical = false,
  25. textures = {"air"},
  26. on_activate = function(self, staticdata)
  27. if tmp.nodename ~= nil and tmp.texture ~= nil then
  28. self.nodename = tmp.nodename
  29. tmp.nodename = nil
  30. self.texture = tmp.texture
  31. tmp.texture = nil
  32. else
  33. if staticdata ~= nil and staticdata ~= "" then
  34. local data = staticdata:split(';')
  35. if data and data[1] and data[2] then
  36. self.nodename = data[1]
  37. self.texture = data[2]
  38. end
  39. end
  40. end
  41. if self.texture ~= nil then
  42. self.object:set_properties({textures = {self.texture}})
  43. end
  44. if self.nodename == "itemframes:pedestal" then
  45. self.object:set_properties({automatic_rotate = 1})
  46. end
  47. end,
  48. get_staticdata = function(self)
  49. if self.nodename ~= nil and self.texture ~= nil then
  50. return self.nodename .. ';' .. self.texture
  51. end
  52. return ""
  53. end,
  54. })
  55. local facedir = {}
  56. facedir[0] = {x = 0, y = 0, z = 1}
  57. facedir[1] = {x = 1, y = 0, z = 0}
  58. facedir[2] = {x = 0, y = 0, z = -1}
  59. facedir[3] = {x = -1, y = 0, z = 0}
  60. local remove_item = function(pos, node)
  61. local objs = nil
  62. if node.name == "itemframes:frame" then
  63. objs = minetest.get_objects_inside_radius(pos, .5)
  64. elseif node.name == "itemframes:pedestal" then
  65. objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y+1,z=pos.z}, .5)
  66. end
  67. if objs then
  68. for _, obj in ipairs(objs) do
  69. if obj and obj:get_luaentity() and obj:get_luaentity().name == "itemframes:item" then
  70. obj:remove()
  71. end
  72. end
  73. end
  74. end
  75. local update_item = function(pos, node)
  76. remove_item(pos, node)
  77. local meta = minetest.get_meta(pos)
  78. if meta:get_string("item") ~= "" then
  79. if node.name == "itemframes:frame" then
  80. local posad = facedir[node.param2]
  81. if not posad then return end
  82. pos.x = pos.x + posad.x * 6.5 / 16
  83. pos.y = pos.y + posad.y * 6.5 / 16
  84. pos.z = pos.z + posad.z * 6.5 / 16
  85. elseif node.name == "itemframes:pedestal" then
  86. pos.y = pos.y + 12 / 16 + 0.33
  87. end
  88. tmp.nodename = node.name
  89. tmp.texture = ItemStack(meta:get_string("item")):get_name()
  90. local e = minetest.add_entity(pos,"itemframes:item")
  91. if e and node.name == "itemframes:frame" then
  92. local yaw = math.pi * 2 - node.param2 * math.pi / 2
  93. e:setyaw(yaw)
  94. end
  95. end
  96. end
  97. local drop_item = function(pos, node)
  98. local meta = minetest.get_meta(pos)
  99. if meta:get_string("item") ~= "" then
  100. if node.name == "itemframes:frame" then
  101. minetest.add_item(pos, meta:get_string("item"))
  102. elseif node.name == "itemframes:pedestal" then
  103. minetest.add_item({x=pos.x,y=pos.y+1,z=pos.z}, meta:get_string("item"))
  104. end
  105. meta:set_string("item","")
  106. end
  107. remove_item(pos, node)
  108. end
  109. minetest.register_node("itemframes:frame",{
  110. description = "Item Frame\n\nSometimes stored items become invisible.\nPunch with a stick to restore them.",
  111. drawtype = "nodebox",
  112. node_box = {
  113. type = "fixed",
  114. fixed = {-0.5, -0.5, 7/16, 0.5, 0.5, 0.5}
  115. },
  116. selection_box = {
  117. type = "fixed",
  118. fixed = {-0.5, -0.5, 7/16, 0.5, 0.5, 0.5}
  119. },
  120. tiles = {"itemframes_frame.png"},
  121. inventory_image = "itemframes_frame.png",
  122. wield_image = "itemframes_frame.png",
  123. paramtype = "light",
  124. paramtype2 = "facedir",
  125. sunlight_propagates = true,
  126. groups = utility.dig_groups("bigitem"),
  127. legacy_wallmounted = true,
  128. sounds = default.node_sound_defaults(),
  129. on_rotate = screwdriver.disallow,
  130. after_place_node = function(pos, placer, itemstack)
  131. local meta = minetest.get_meta(pos)
  132. meta:set_string("owner",placer:get_player_name())
  133. meta:set_string("infotext", string.format("Item Frame (Owned by <%s>!)", rename.gpn(placer:get_player_name())))
  134. end,
  135. -- Called by rename LBM.
  136. _on_update_infotext = function(pos)
  137. on_rename_check(pos, "Item Frame")
  138. end,
  139. _on_update_entity = function(pos)
  140. update_item(pos, minetest.get_node(pos))
  141. end,
  142. on_rightclick = function(pos, node, clicker, itemstack)
  143. if not itemstack then return end
  144. local meta = minetest.get_meta(pos)
  145. local name = clicker and clicker:get_player_name()
  146. if map.is_mapping_kit(itemstack:get_name()) then
  147. --minetest.chat_send_player("MustTest", "Updating inventory: " .. itemstack:get_name() .. ", " .. name)
  148. minetest.after(0, function() map.update_inventory_info(name) end)
  149. end
  150. if name == meta:get_string("owner") or minetest.check_player_privs(name, "protection_bypass") then
  151. drop_item(pos,node)
  152. local s = itemstack:take_item()
  153. meta:set_string("item",s:to_string())
  154. update_item(pos,node)
  155. end
  156. return itemstack
  157. end,
  158. on_punch = function(pos,node,puncher)
  159. local meta = minetest.get_meta(pos)
  160. local name = puncher and puncher:get_player_name()
  161. if name == meta:get_string("owner") or
  162. minetest.check_player_privs(name, "protection_bypass") then
  163. drop_item(pos, node)
  164. end
  165. end,
  166. can_dig = function(pos,player)
  167. if not player then return end
  168. local name = player and player:get_player_name()
  169. local meta = minetest.get_meta(pos)
  170. return name == meta:get_string("owner") or
  171. minetest.check_player_privs(name, "protection_bypass")
  172. end,
  173. on_destruct = function(pos)
  174. local meta = minetest.get_meta(pos)
  175. local node = minetest.get_node(pos)
  176. if meta:get_string("item") ~= "" then
  177. drop_item(pos, node)
  178. end
  179. end,
  180. on_finish_collapse = function(pos, node)
  181. -- Prevent item-duplication.
  182. local meta = minetest.get_meta(pos)
  183. meta:set_string("item", nil)
  184. end,
  185. })
  186. minetest.register_node("itemframes:pedestal",{
  187. description = "Pedestal\n\nSometimes stored items become invisible.\nPunch with a stick to restore them.",
  188. drawtype = "nodebox",
  189. node_box = {
  190. type = "fixed", fixed = {
  191. {-7/16, -8/16, -7/16, 7/16, -7/16, 7/16}, -- bottom plate
  192. {-6/16, -7/16, -6/16, 6/16, -6/16, 6/16}, -- bottom plate (upper)
  193. {-0.25, -6/16, -0.25, 0.25, 11/16, 0.25}, -- pillar
  194. {-7/16, 11/16, -7/16, 7/16, 12/16, 7/16}, -- top plate
  195. }
  196. },
  197. --selection_box = {
  198. -- type = "fixed",
  199. -- fixed = {-7/16, -0.5, -7/16, 7/16, 12/16, 7/16}
  200. --},
  201. tiles = {"itemframes_pedestal.png"},
  202. paramtype = "light",
  203. groups = utility.dig_groups("brick"),
  204. sounds = default.node_sound_defaults(),
  205. on_rotate = screwdriver.disallow,
  206. after_place_node = function(pos, placer, itemstack)
  207. local meta = minetest.get_meta(pos)
  208. meta:set_string("owner",placer:get_player_name())
  209. meta:set_string("infotext", string.format("Pedestal (Owned by <%s>!)", rename.gpn(placer:get_player_name())))
  210. end,
  211. -- Called by rename LBM.
  212. _on_update_infotext = function(pos)
  213. on_rename_check(pos, "Pedestal")
  214. end,
  215. _on_update_entity = function(pos)
  216. update_item(pos, minetest.get_node(pos))
  217. end,
  218. on_rightclick = function(pos, node, clicker, itemstack)
  219. if not itemstack then return end
  220. local meta = minetest.get_meta(pos)
  221. local name = clicker and clicker:get_player_name()
  222. if map.is_mapping_kit(itemstack:get_name()) then
  223. minetest.after(0, function() map.update_inventory_info(name) end)
  224. end
  225. if name == meta:get_string("owner") or minetest.check_player_privs(name, "protection_bypass") then
  226. drop_item(pos,node)
  227. local s = itemstack:take_item()
  228. meta:set_string("item",s:to_string())
  229. update_item(pos,node)
  230. end
  231. return itemstack
  232. end,
  233. on_punch = function(pos,node,puncher)
  234. local meta = minetest.get_meta(pos)
  235. local name = puncher and puncher:get_player_name()
  236. if name == meta:get_string("owner") or
  237. minetest.check_player_privs(name, "protection_bypass") then
  238. drop_item(pos,node)
  239. end
  240. end,
  241. can_dig = function(pos,player)
  242. if not player then return end
  243. local name = player and player:get_player_name()
  244. local meta = minetest.get_meta(pos)
  245. return name == meta:get_string("owner") or
  246. minetest.check_player_privs(name, "protection_bypass")
  247. end,
  248. on_destruct = function(pos)
  249. local meta = minetest.get_meta(pos)
  250. local node = minetest.get_node(pos)
  251. if meta:get_string("item") ~= "" then
  252. drop_item(pos, node)
  253. end
  254. end,
  255. on_finish_collapse = function(pos, node)
  256. -- Prevent item-duplication.
  257. local meta = minetest.get_meta(pos)
  258. meta:set_string("item", nil)
  259. end,
  260. })
  261. -- crafts
  262. minetest.register_craft({
  263. output = 'itemframes:frame',
  264. recipe = {
  265. {'group:stick', 'group:stick', 'group:stick'},
  266. {'group:stick', 'default:paper', 'default:stick'},
  267. {'group:stick', 'group:stick', 'group:stick'},
  268. }
  269. })
  270. minetest.register_craft({
  271. output = 'itemframes:pedestal',
  272. recipe = {
  273. {'default:stone', 'default:stone', 'default:stone'},
  274. {'', 'default:stone', ''},
  275. {'default:stone', 'default:stone', 'default:stone'},
  276. }
  277. })
  278. -- stop mesecon pistons from pushing itemframes and pedestals
  279. if minetest.get_modpath("mesecons_mvps") then
  280. mesecon.register_mvps_stopper("itemframes:frame")
  281. mesecon.register_mvps_stopper("itemframes:pedestal")
  282. end