api.lua 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. --[[
  2. Ingots - allows the placemant of ingots in the world
  3. Copyright (C) 2018 Skamiz Kazzarch
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  15. ]]--
  16. -- Takes an item name and a texture name and a boolean whether the ingots are
  17. -- big.
  18. function ingots.register_ingots(ingot_item, texture, is_big)
  19. -- Checks, whether the item name is a valid item (thanks 'puzzlecube').
  20. if not minetest.registered_items[ingot_item] then
  21. minetest.log("warning", ingot_item.." is not registered. Skipping ingot registration")
  22. return
  23. end
  24. -- De-hardcoded modname, which allows the api to be properly used from within
  25. -- other mods (thanks 'argyle').
  26. local mod_name = minetest.get_current_modname()
  27. local mod_prefix = mod_name .. ":"
  28. local stack_size = 64
  29. local texture_prefix = "ingot_"
  30. -- Gets item name witout mod part, to be used in the deffinition of the new
  31. -- nodes.
  32. local ingot_name = string.sub(ingot_item, string.find(ingot_item, ":", 1, true) +1, -1)
  33. -- Some ingots do not have unique sub-names.
  34. -- For these ingots, use their whole name, replacing ':' with '_'.
  35. -- Ex: talinite:ingot and brass:ingot have the same sub-name, "ingot".
  36. if ingot_name == "ingot" then
  37. ingot_name = string.gsub(ingot_item, ":", "_")
  38. end
  39. if is_big then
  40. ingot_name = ingot_name .. "_big"
  41. stack_size = 8
  42. texture_prefix = "ingot_big_"
  43. end
  44. -- This is no longer used by the mod, but required for compatibility.
  45. minetest.register_alias(mod_prefix .. ingot_name .."_0", "air")
  46. -- Gives the ingot_item the ability to be placed and increas already placed
  47. -- stacks of ingots.
  48. minetest.override_item(ingot_item, {
  49. on_place = function(itemstack, placer, pointed_thing)
  50. local pos = minetest.get_pointed_thing_position(pointed_thing, true)
  51. if minetest.is_protected(pos, placer:get_player_name()) and not minetest.check_player_privs(placer, "protection_bypass") then
  52. return
  53. end
  54. if pointed_thing["type"] == "node" then
  55. local name = minetest.get_node(pointed_thing.under).name
  56. -- Call on_rightclick function of pointed node if aplicable and not
  57. -- sneak. Might or might not break if item is placed by mod devices.
  58. if minetest.registered_nodes[name].on_rightclick and
  59. not placer:get_player_control().sneak
  60. then
  61. minetest.registered_nodes[name].on_rightclick(pointed_thing.under,
  62. minetest.get_node(pointed_thing.under), placer, itemstack)
  63. elseif string.find(name, mod_prefix .. ingot_name) then
  64. local count = string.gsub(name, "%D*", "")
  65. if stack_size > minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]._ingot_count then
  66. minetest.set_node(pointed_thing.under, {name = mod_prefix .. ingot_name .."_" .. count + 1, param2 = minetest.get_node(pointed_thing.under).param2})
  67. itemstack:take_item()
  68. elseif minetest.get_node(pointed_thing.above).name == "air" then
  69. minetest.set_node(pointed_thing.above, {name = mod_prefix .. ingot_name .."_1"})
  70. itemstack:take_item()
  71. end
  72. elseif minetest.get_node(pointed_thing.above).name == "air" then
  73. minetest.set_node(pointed_thing.above, {
  74. name = mod_prefix .. ingot_name .. "_1",
  75. param2 = math.random(0, 3),
  76. })
  77. itemstack:take_item()
  78. end
  79. return itemstack
  80. end
  81. end
  82. })
  83. -- Talinite ingots glow.
  84. local light_source = nil
  85. if ingot_item == "talinite:ingot" then
  86. light_source = 6
  87. end
  88. local function on_punch(pos, node_stale, puncher, pointed_thing)
  89. if not puncher then
  90. return
  91. end
  92. local wield = puncher:get_wielded_item()
  93. -- Checks that a stack can be taken apart by hand or relevant "ingot_item".
  94. if wield:get_name() == ingot_item or wield:get_count() == 0 then
  95. if minetest.test_protection(pos, puncher:get_player_name()) then
  96. return
  97. end
  98. -- Get actual node at this location. (Function call might be stale!)
  99. -- As a falling node, the falling code might (usually will) run first,
  100. -- which causes this function to misbehave if we don't check ....
  101. local node = minetest.get_node(pos)
  102. if node.name ~= node_stale.name then
  103. return
  104. end
  105. local ndef = minetest.registered_nodes[node.name]
  106. local count = ndef._ingot_count
  107. if count > 1 then
  108. minetest.set_node(pos, {
  109. name = mod_prefix .. ingot_name .."_" .. count - 1,
  110. param2 = node.param2,
  111. })
  112. else
  113. minetest.remove_node(pos)
  114. minetest.check_for_falling(pos)
  115. end
  116. local stack = ItemStack(ingot_item)
  117. puncher:get_inventory():add_item("main", stack)
  118. end
  119. end
  120. -- Registers 'stack_size' number of nodes, each has one more ingot in it than
  121. -- the last.
  122. for i = 1, stack_size do
  123. local box = {
  124. type = "fixed",
  125. fixed = {
  126. -- Rectangular box which encompases all placed ingots
  127. ingots.get_box(is_big, i),
  128. },
  129. }
  130. minetest.register_node(mod_prefix .. ingot_name .. "_" .. i,{
  131. description = "ingots",
  132. drawtype = "mesh",
  133. tiles = {texture},
  134. mesh = texture_prefix .. i .. ".obj",
  135. selection_box = box,
  136. collision_box = box,
  137. paramtype = 'light',
  138. paramtype2 = "facedir",
  139. light_source = light_source,
  140. -- Not quick to walk on top of ingot piles.
  141. movement_speed_multiplier = default.SLOW_SPEED,
  142. -- Horizontal rotation only!
  143. on_rotate = screwdriver.rotate_simple,
  144. groups = {
  145. cracky = 3,
  146. level = 2,
  147. not_in_creative_inventory = 1,
  148. falling_node = 1,
  149. },
  150. drop = ingot_item .. " " .. i,
  151. on_punch = on_punch,
  152. _ingot_name = ingot_name,
  153. _ingot_count = i,
  154. })
  155. end
  156. end
  157. -- Returns an apropriate nodebox for a given number of ingots.
  158. function ingots.get_box(is_big, i)
  159. if is_big then
  160. return {-0.5, -0.5, -0.5, 0.5, (((i + 1 - ((i +1 )%2)) / 8) - 0.5), 0.5}
  161. else
  162. return {-0.5, -0.5, -0.5, 0.5, (((i - 1 - ((i-1)%8)) / 8) - 3) / 8, 0.5}
  163. end
  164. end