misc_register.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. -- Minetest: builtin/misc_register.lua
  2. --
  3. -- Make raw registration functions inaccessible to anyone except this file
  4. --
  5. local register_item_raw = minetest.register_item_raw
  6. minetest.register_item_raw = nil
  7. local register_alias_raw = minetest.register_alias_raw
  8. minetest.register_item_raw = nil
  9. --
  10. -- Item / entity / ABM registration functions
  11. --
  12. minetest.registered_abms = {}
  13. minetest.registered_entities = {}
  14. minetest.registered_items = {}
  15. minetest.registered_nodes = {}
  16. minetest.registered_craftitems = {}
  17. minetest.registered_tools = {}
  18. minetest.registered_aliases = {}
  19. -- For tables that are indexed by item name:
  20. -- If table[X] does not exist, default to table[minetest.registered_aliases[X]]
  21. local function set_alias_metatable(table)
  22. setmetatable(table, {
  23. __index = function(name)
  24. return rawget(table, minetest.registered_aliases[name])
  25. end
  26. })
  27. end
  28. set_alias_metatable(minetest.registered_items)
  29. set_alias_metatable(minetest.registered_nodes)
  30. set_alias_metatable(minetest.registered_craftitems)
  31. set_alias_metatable(minetest.registered_tools)
  32. -- These item names may not be used because they would interfere
  33. -- with legacy itemstrings
  34. local forbidden_item_names = {
  35. MaterialItem = true,
  36. MaterialItem2 = true,
  37. MaterialItem3 = true,
  38. NodeItem = true,
  39. node = true,
  40. CraftItem = true,
  41. craft = true,
  42. MBOItem = true,
  43. ToolItem = true,
  44. tool = true,
  45. }
  46. local function check_modname_prefix(name)
  47. if name:sub(1,1) == ":" then
  48. -- Escape the modname prefix enforcement mechanism
  49. return name:sub(2)
  50. else
  51. -- Modname prefix enforcement
  52. local expected_prefix = minetest.get_current_modname() .. ":"
  53. if name:sub(1, #expected_prefix) ~= expected_prefix then
  54. error("Name " .. name .. " does not follow naming conventions: " ..
  55. "\"modname:\" or \":\" prefix required")
  56. end
  57. local subname = name:sub(#expected_prefix+1)
  58. if subname:find("[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]") then
  59. error("Name " .. name .. " does not follow naming conventions: " ..
  60. "contains unallowed characters")
  61. end
  62. return name
  63. end
  64. end
  65. function minetest.register_abm(spec)
  66. -- Add to minetest.registered_abms
  67. minetest.registered_abms[#minetest.registered_abms+1] = spec
  68. end
  69. function minetest.register_entity(name, prototype)
  70. -- Check name
  71. if name == nil then
  72. error("Unable to register entity: Name is nil")
  73. end
  74. name = check_modname_prefix(tostring(name))
  75. prototype.name = name
  76. prototype.__index = prototype -- so that it can be used as a metatable
  77. -- Add to minetest.registered_entities
  78. minetest.registered_entities[name] = prototype
  79. end
  80. function minetest.register_item(name, itemdef)
  81. -- Check name
  82. if name == nil then
  83. error("Unable to register item: Name is nil")
  84. end
  85. name = check_modname_prefix(tostring(name))
  86. if forbidden_item_names[name] then
  87. error("Unable to register item: Name is forbidden: " .. name)
  88. end
  89. itemdef.name = name
  90. -- Apply defaults and add to registered_* table
  91. if itemdef.type == "node" then
  92. -- Use the nodebox as selection box if it's not set manually
  93. if itemdef.drawtype == "nodebox" and not itemdef.selection_box then
  94. itemdef.selection_box = itemdef.node_box
  95. end
  96. setmetatable(itemdef, {__index = minetest.nodedef_default})
  97. minetest.registered_nodes[itemdef.name] = itemdef
  98. elseif itemdef.type == "craft" then
  99. setmetatable(itemdef, {__index = minetest.craftitemdef_default})
  100. minetest.registered_craftitems[itemdef.name] = itemdef
  101. elseif itemdef.type == "tool" then
  102. setmetatable(itemdef, {__index = minetest.tooldef_default})
  103. minetest.registered_tools[itemdef.name] = itemdef
  104. elseif itemdef.type == "none" then
  105. setmetatable(itemdef, {__index = minetest.noneitemdef_default})
  106. else
  107. error("Unable to register item: Type is invalid: " .. dump(itemdef))
  108. end
  109. -- Flowing liquid uses param2
  110. if itemdef.type == "node" and itemdef.liquidtype == "flowing" then
  111. itemdef.paramtype2 = "flowingliquid"
  112. end
  113. -- BEGIN Legacy stuff
  114. if itemdef.cookresult_itemstring ~= nil and itemdef.cookresult_itemstring ~= "" then
  115. minetest.register_craft({
  116. type="cooking",
  117. output=itemdef.cookresult_itemstring,
  118. recipe=itemdef.name,
  119. cooktime=itemdef.furnace_cooktime
  120. })
  121. end
  122. if itemdef.furnace_burntime ~= nil and itemdef.furnace_burntime >= 0 then
  123. minetest.register_craft({
  124. type="fuel",
  125. recipe=itemdef.name,
  126. burntime=itemdef.furnace_burntime
  127. })
  128. end
  129. -- END Legacy stuff
  130. -- Disable all further modifications
  131. getmetatable(itemdef).__newindex = {}
  132. --minetest.log("Registering item: " .. itemdef.name)
  133. minetest.registered_items[itemdef.name] = itemdef
  134. minetest.registered_aliases[itemdef.name] = nil
  135. register_item_raw(itemdef)
  136. end
  137. function minetest.register_node(name, nodedef)
  138. nodedef.type = "node"
  139. minetest.register_item(name, nodedef)
  140. end
  141. function minetest.register_craftitem(name, craftitemdef)
  142. craftitemdef.type = "craft"
  143. -- BEGIN Legacy stuff
  144. if craftitemdef.inventory_image == nil and craftitemdef.image ~= nil then
  145. craftitemdef.inventory_image = craftitemdef.image
  146. end
  147. -- END Legacy stuff
  148. minetest.register_item(name, craftitemdef)
  149. end
  150. function minetest.register_tool(name, tooldef)
  151. tooldef.type = "tool"
  152. tooldef.stack_max = 1
  153. -- BEGIN Legacy stuff
  154. if tooldef.inventory_image == nil and tooldef.image ~= nil then
  155. tooldef.inventory_image = tooldef.image
  156. end
  157. if tooldef.tool_capabilities == nil and
  158. (tooldef.full_punch_interval ~= nil or
  159. tooldef.basetime ~= nil or
  160. tooldef.dt_weight ~= nil or
  161. tooldef.dt_crackiness ~= nil or
  162. tooldef.dt_crumbliness ~= nil or
  163. tooldef.dt_cuttability ~= nil or
  164. tooldef.basedurability ~= nil or
  165. tooldef.dd_weight ~= nil or
  166. tooldef.dd_crackiness ~= nil or
  167. tooldef.dd_crumbliness ~= nil or
  168. tooldef.dd_cuttability ~= nil) then
  169. tooldef.tool_capabilities = {
  170. full_punch_interval = tooldef.full_punch_interval,
  171. basetime = tooldef.basetime,
  172. dt_weight = tooldef.dt_weight,
  173. dt_crackiness = tooldef.dt_crackiness,
  174. dt_crumbliness = tooldef.dt_crumbliness,
  175. dt_cuttability = tooldef.dt_cuttability,
  176. basedurability = tooldef.basedurability,
  177. dd_weight = tooldef.dd_weight,
  178. dd_crackiness = tooldef.dd_crackiness,
  179. dd_crumbliness = tooldef.dd_crumbliness,
  180. dd_cuttability = tooldef.dd_cuttability,
  181. }
  182. end
  183. -- END Legacy stuff
  184. minetest.register_item(name, tooldef)
  185. end
  186. function minetest.register_alias(name, convert_to)
  187. if forbidden_item_names[name] then
  188. error("Unable to register alias: Name is forbidden: " .. name)
  189. end
  190. if minetest.registered_items[name] ~= nil then
  191. minetest.log("WARNING: Not registering alias, item with same name" ..
  192. " is already defined: " .. name .. " -> " .. convert_to)
  193. else
  194. --minetest.log("Registering alias: " .. name .. " -> " .. convert_to)
  195. minetest.registered_aliases[name] = convert_to
  196. register_alias_raw(name, convert_to)
  197. end
  198. end
  199. local register_biome_raw = minetest.register_biome
  200. minetest.registered_biomes = {}
  201. function minetest.register_biome(biome)
  202. minetest.registered_biomes[biome.name] = biome
  203. register_biome_raw(biome)
  204. end
  205. -- Alias the forbidden item names to "" so they can't be
  206. -- created via itemstrings (e.g. /give)
  207. local name
  208. for name in pairs(forbidden_item_names) do
  209. minetest.registered_aliases[name] = ""
  210. register_alias_raw(name, "")
  211. end
  212. -- Deprecated:
  213. -- Aliases for minetest.register_alias (how ironic...)
  214. --minetest.alias_node = minetest.register_alias
  215. --minetest.alias_tool = minetest.register_alias
  216. --minetest.alias_craftitem = minetest.register_alias
  217. --
  218. -- Built-in node definitions. Also defined in C.
  219. --
  220. minetest.register_item(":unknown", {
  221. type = "none",
  222. description = "Unknown Item",
  223. inventory_image = "unknown_item.png",
  224. on_place = minetest.item_place,
  225. on_drop = minetest.item_drop,
  226. groups = {not_in_creative_inventory=1},
  227. })
  228. minetest.register_node(":air", {
  229. description = "Air (you hacker you!)",
  230. inventory_image = "unknown_node.png",
  231. wield_image = "unknown_node.png",
  232. drawtype = "airlike",
  233. paramtype = "light",
  234. sunlight_propagates = true,
  235. walkable = false,
  236. pointable = false,
  237. diggable = false,
  238. buildable_to = true,
  239. air_equivalent = true,
  240. drop = "",
  241. groups = {not_in_creative_inventory=1},
  242. })
  243. minetest.register_node(":ignore", {
  244. description = "Ignore (you hacker you!)",
  245. inventory_image = "unknown_node.png",
  246. wield_image = "unknown_node.png",
  247. drawtype = "airlike",
  248. paramtype = "none",
  249. sunlight_propagates = false,
  250. walkable = false,
  251. pointable = false,
  252. diggable = false,
  253. buildable_to = true, -- A way to remove accidentally placed ignores
  254. air_equivalent = true,
  255. drop = "",
  256. groups = {not_in_creative_inventory=1},
  257. })
  258. -- The hand (bare definition)
  259. minetest.register_item(":", {
  260. type = "none",
  261. groups = {not_in_creative_inventory=1},
  262. })
  263. --
  264. -- Callback registration
  265. --
  266. local function make_registration()
  267. local t = {}
  268. local registerfunc = function(func) table.insert(t, func) end
  269. return t, registerfunc
  270. end
  271. local function make_registration_reverse()
  272. local t = {}
  273. local registerfunc = function(func) table.insert(t, 1, func) end
  274. return t, registerfunc
  275. end
  276. minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
  277. minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
  278. minetest.registered_on_mapgen_inits, minetest.register_on_mapgen_init = make_registration()
  279. minetest.registered_on_shutdown, minetest.register_on_shutdown = make_registration()
  280. minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
  281. minetest.registered_on_placenodes, minetest.register_on_placenode = make_registration()
  282. minetest.registered_on_dignodes, minetest.register_on_dignode = make_registration()
  283. minetest.registered_on_generateds, minetest.register_on_generated = make_registration()
  284. minetest.registered_on_newplayers, minetest.register_on_newplayer = make_registration()
  285. minetest.registered_on_dieplayers, minetest.register_on_dieplayer = make_registration()
  286. minetest.registered_on_respawnplayers, minetest.register_on_respawnplayer = make_registration()
  287. minetest.registered_on_joinplayers, minetest.register_on_joinplayer = make_registration()
  288. minetest.registered_on_leaveplayers, minetest.register_on_leaveplayer = make_registration()
  289. minetest.registered_on_player_receive_fields, minetest.register_on_player_receive_fields = make_registration_reverse()
  290. minetest.registered_on_cheats, minetest.register_on_cheat = make_registration()