helpers.lua 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. --[[
  2. Minetest Mod Storage Drawers - A Mod adding storage drawers
  3. Copyright (C) 2017-2019 Linus Jahn <lnj@kaidan.im>
  4. Copyright (C) 2016 Mango Tango <mtango688@gmail.com>
  5. MIT License
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12. The above copyright notice and this permission notice shall be included in all
  13. copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. SOFTWARE.
  21. ]]
  22. -- Load support for intllib.
  23. local MP = core.get_modpath(core.get_current_modname())
  24. local S, NS = dofile(MP.."/intllib.lua")
  25. -- GUI
  26. function drawers.get_upgrade_slots_bg(x,y)
  27. local out = ""
  28. for i = 0, 4, 1 do
  29. out = out .."image["..x+i..","..y..";1,1;drawers_upgrade_slot_bg.png]"
  30. end
  31. return out
  32. end
  33. function drawers.gen_info_text(basename, count, factor, stack_max)
  34. local maxCount = stack_max * factor
  35. local percent = count / maxCount * 100
  36. -- round the number (float -> int)
  37. percent = math.floor(percent + 0.5)
  38. if count == 0 then
  39. return S("@1 (@2% full)", basename, tostring(percent))
  40. else
  41. return S("@1 @2 (@3% full)", tostring(count), basename, tostring(percent))
  42. end
  43. end
  44. function drawers.get_inv_image(name)
  45. local texture = "blank.png"
  46. local def = core.registered_items[name]
  47. if not def then return end
  48. if def.inventory_image and #def.inventory_image > 0 then
  49. texture = def.inventory_image
  50. else
  51. if not def.tiles then return texture end
  52. local tiles = table.copy(def.tiles)
  53. for k,v in pairs(tiles) do
  54. if type(v) == "table" then
  55. tiles[k] = v.name
  56. end
  57. end
  58. -- tiles: up, down, right, left, back, front
  59. -- inventorycube: up, front, right
  60. if #tiles <= 2 then
  61. texture = core.inventorycube(tiles[1], tiles[1], tiles[1])
  62. elseif #tiles <= 5 then
  63. texture = core.inventorycube(tiles[1], tiles[3], tiles[3])
  64. else -- full tileset
  65. texture = core.inventorycube(tiles[1], tiles[6], tiles[3])
  66. end
  67. end
  68. return texture
  69. end
  70. function drawers.spawn_visuals(pos)
  71. local node = core.get_node(pos)
  72. local ndef = core.registered_nodes[node.name]
  73. local drawerType = ndef.groups.drawer
  74. -- data for the new visual
  75. drawers.last_drawer_pos = pos
  76. drawers.last_drawer_type = drawerType
  77. if drawerType == 1 then -- 1x1 drawer
  78. drawers.last_visual_id = ""
  79. drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name"))
  80. local bdir = core.facedir_to_dir(node.param2)
  81. local fdir = vector.new(-bdir.x, 0, -bdir.z)
  82. local pos2 = vector.add(pos, vector.multiply(fdir, 0.45))
  83. local obj = core.add_entity(pos2, "drawers:visual")
  84. if bdir.x < 0 then obj:set_yaw(0.5 * math.pi) end
  85. if bdir.z < 0 then obj:set_yaw(math.pi) end
  86. if bdir.x > 0 then obj:set_yaw(1.5 * math.pi) end
  87. drawers.last_texture = nil
  88. elseif drawerType == 2 then
  89. local bdir = core.facedir_to_dir(node.param2)
  90. local fdir1
  91. local fdir2
  92. if node.param2 == 2 or node.param2 == 0 then
  93. fdir1 = vector.new(-bdir.x, 0.5, -bdir.z)
  94. fdir2 = vector.new(-bdir.x, -0.5, -bdir.z)
  95. else
  96. fdir1 = vector.new(-bdir.x, 0.5, -bdir.z)
  97. fdir2 = vector.new(-bdir.x, -0.5, -bdir.z)
  98. end
  99. local objs = {}
  100. drawers.last_visual_id = 1
  101. drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name1"))
  102. local pos1 = vector.add(pos, vector.multiply(fdir1, 0.45))
  103. objs[1] = core.add_entity(pos1, "drawers:visual")
  104. drawers.last_visual_id = 2
  105. drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name2"))
  106. local pos2 = vector.add(pos, vector.multiply(fdir2, 0.45))
  107. objs[2] = core.add_entity(pos2, "drawers:visual")
  108. for i,obj in pairs(objs) do
  109. if bdir.x < 0 then obj:set_yaw(0.5 * math.pi) end
  110. if bdir.z < 0 then obj:set_yaw(math.pi) end
  111. if bdir.x > 0 then obj:set_yaw(1.5 * math.pi) end
  112. end
  113. else -- 2x2 drawer
  114. local bdir = core.facedir_to_dir(node.param2)
  115. local fdir1
  116. local fdir2
  117. local fdir3
  118. local fdir4
  119. if node.param2 == 2 then
  120. fdir1 = vector.new(-bdir.x + 0.5, 0.5, -bdir.z)
  121. fdir2 = vector.new(-bdir.x - 0.5, 0.5, -bdir.z)
  122. fdir3 = vector.new(-bdir.x + 0.5, -0.5, -bdir.z)
  123. fdir4 = vector.new(-bdir.x - 0.5, -0.5, -bdir.z)
  124. elseif node.param2 == 0 then
  125. fdir1 = vector.new(-bdir.x - 0.5, 0.5, -bdir.z)
  126. fdir2 = vector.new(-bdir.x + 0.5, 0.5, -bdir.z)
  127. fdir3 = vector.new(-bdir.x - 0.5, -0.5, -bdir.z)
  128. fdir4 = vector.new(-bdir.x + 0.5, -0.5, -bdir.z)
  129. elseif node.param2 == 1 then
  130. fdir1 = vector.new(-bdir.x, 0.5, -bdir.z + 0.5)
  131. fdir2 = vector.new(-bdir.x, 0.5, -bdir.z - 0.5)
  132. fdir3 = vector.new(-bdir.x, -0.5, -bdir.z + 0.5)
  133. fdir4 = vector.new(-bdir.x, -0.5, -bdir.z - 0.5)
  134. else
  135. fdir1 = vector.new(-bdir.x, 0.5, -bdir.z - 0.5)
  136. fdir2 = vector.new(-bdir.x, 0.5, -bdir.z + 0.5)
  137. fdir3 = vector.new(-bdir.x, -0.5, -bdir.z - 0.5)
  138. fdir4 = vector.new(-bdir.x, -0.5, -bdir.z + 0.5)
  139. end
  140. local objs = {}
  141. drawers.last_visual_id = 1
  142. drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name1"))
  143. local pos1 = vector.add(pos, vector.multiply(fdir1, 0.45))
  144. objs[1] = core.add_entity(pos1, "drawers:visual")
  145. drawers.last_visual_id = 2
  146. drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name2"))
  147. local pos2 = vector.add(pos, vector.multiply(fdir2, 0.45))
  148. objs[2] = core.add_entity(pos2, "drawers:visual")
  149. drawers.last_visual_id = 3
  150. drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name3"))
  151. local pos3 = vector.add(pos, vector.multiply(fdir3, 0.45))
  152. objs[3] = core.add_entity(pos3, "drawers:visual")
  153. drawers.last_visual_id = 4
  154. drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name4"))
  155. local pos4 = vector.add(pos, vector.multiply(fdir4, 0.45))
  156. objs[4] = core.add_entity(pos4, "drawers:visual")
  157. for i,obj in pairs(objs) do
  158. if bdir.x < 0 then obj:set_yaw(0.5 * math.pi) end
  159. if bdir.z < 0 then obj:set_yaw(math.pi) end
  160. if bdir.x > 0 then obj:set_yaw(1.5 * math.pi) end
  161. end
  162. end
  163. end
  164. function drawers.remove_visuals(pos)
  165. local objs = core.get_objects_inside_radius(pos, 0.58)
  166. if not objs then return end
  167. for _, obj in pairs(objs) do
  168. if obj and obj:get_luaentity() and
  169. obj:get_luaentity().name == "drawers:visual" then
  170. obj:remove()
  171. end
  172. end
  173. end
  174. function drawers.update_drawer_upgrades(pos)
  175. local node = core.get_node(pos)
  176. local ndef = core.registered_nodes[node.name]
  177. local drawerType = ndef.groups.drawer
  178. -- default number of slots/stacks
  179. local stackMaxFactor = ndef.drawer_stack_max_factor
  180. -- storage percent with all upgrades
  181. local storagePercent = 100
  182. -- get info of all upgrades
  183. local inventory = core.get_meta(pos):get_inventory():get_list("upgrades")
  184. for _,itemStack in pairs(inventory) do
  185. local iname = itemStack:get_name()
  186. local idef = core.registered_items[iname]
  187. local addPercent = idef.groups.drawer_upgrade or 0
  188. storagePercent = storagePercent + addPercent
  189. end
  190. -- i.e.: 150% / 100 => 1.50
  191. stackMaxFactor = math.floor(stackMaxFactor * (storagePercent / 100))
  192. -- calculate stack_max factor for a single drawer
  193. stackMaxFactor = stackMaxFactor / drawerType
  194. -- set the new stack max factor in all visuals
  195. local drawer_visuals = drawers.drawer_visuals[core.serialize(pos)]
  196. if not drawer_visuals then return end
  197. for _,visual in pairs(drawer_visuals) do
  198. visual:setStackMaxFactor(stackMaxFactor)
  199. end
  200. end
  201. function drawers.randomize_pos(pos)
  202. local rndpos = table.copy(pos)
  203. local x = math.random(-50, 50) * 0.01
  204. local z = math.random(-50, 50) * 0.01
  205. rndpos.x = rndpos.x + x
  206. rndpos.y = rndpos.y + 0.25
  207. rndpos.z = rndpos.z + z
  208. return rndpos
  209. end
  210. function drawers.node_tiles_front_other(front, other)
  211. return {other, other, other, other, other, front}
  212. end