item_s.lua 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. -- Minetest: builtin/item_s.lua
  2. -- The distinction of what goes here is a bit tricky, basically it's everything
  3. -- that does not (directly or indirectly) need access to ServerEnvironment,
  4. -- Server or writable access to IGameDef on the engine side.
  5. -- (The '_s' stands for standalone.)
  6. local builtin_shared = ...
  7. --
  8. -- Item definition helpers
  9. --
  10. function core.inventorycube(img1, img2, img3)
  11. img2 = img2 or img1
  12. img3 = img3 or img1
  13. return "[inventorycube"
  14. .. "{" .. img1:gsub("%^", "&")
  15. .. "{" .. img2:gsub("%^", "&")
  16. .. "{" .. img3:gsub("%^", "&")
  17. end
  18. function core.dir_to_facedir(dir, is6d)
  19. --account for y if requested
  20. if is6d and math.abs(dir.y) > math.abs(dir.x) and math.abs(dir.y) > math.abs(dir.z) then
  21. --from above
  22. if dir.y < 0 then
  23. if math.abs(dir.x) > math.abs(dir.z) then
  24. if dir.x < 0 then
  25. return 19
  26. else
  27. return 13
  28. end
  29. else
  30. if dir.z < 0 then
  31. return 10
  32. else
  33. return 4
  34. end
  35. end
  36. --from below
  37. else
  38. if math.abs(dir.x) > math.abs(dir.z) then
  39. if dir.x < 0 then
  40. return 15
  41. else
  42. return 17
  43. end
  44. else
  45. if dir.z < 0 then
  46. return 6
  47. else
  48. return 8
  49. end
  50. end
  51. end
  52. --otherwise, place horizontally
  53. elseif math.abs(dir.x) > math.abs(dir.z) then
  54. if dir.x < 0 then
  55. return 3
  56. else
  57. return 1
  58. end
  59. else
  60. if dir.z < 0 then
  61. return 2
  62. else
  63. return 0
  64. end
  65. end
  66. end
  67. -- Table of possible dirs
  68. local facedir_to_dir = {
  69. vector.new( 0, 0, 1),
  70. vector.new( 1, 0, 0),
  71. vector.new( 0, 0, -1),
  72. vector.new(-1, 0, 0),
  73. vector.new( 0, -1, 0),
  74. vector.new( 0, 1, 0),
  75. }
  76. -- Mapping from facedir value to index in facedir_to_dir.
  77. local facedir_to_dir_map = {
  78. [0]=1, 2, 3, 4,
  79. 5, 2, 6, 4,
  80. 6, 2, 5, 4,
  81. 1, 5, 3, 6,
  82. 1, 6, 3, 5,
  83. 1, 4, 3, 2,
  84. }
  85. function core.facedir_to_dir(facedir)
  86. return facedir_to_dir[facedir_to_dir_map[facedir % 32]]
  87. end
  88. function core.dir_to_fourdir(dir)
  89. if math.abs(dir.x) > math.abs(dir.z) then
  90. if dir.x < 0 then
  91. return 3
  92. else
  93. return 1
  94. end
  95. else
  96. if dir.z < 0 then
  97. return 2
  98. else
  99. return 0
  100. end
  101. end
  102. end
  103. function core.fourdir_to_dir(fourdir)
  104. return facedir_to_dir[facedir_to_dir_map[fourdir % 4]]
  105. end
  106. function core.dir_to_wallmounted(dir)
  107. if math.abs(dir.y) > math.max(math.abs(dir.x), math.abs(dir.z)) then
  108. if dir.y < 0 then
  109. return 1
  110. else
  111. return 0
  112. end
  113. elseif math.abs(dir.x) > math.abs(dir.z) then
  114. if dir.x < 0 then
  115. return 3
  116. else
  117. return 2
  118. end
  119. else
  120. if dir.z < 0 then
  121. return 5
  122. else
  123. return 4
  124. end
  125. end
  126. end
  127. -- table of dirs in wallmounted order
  128. local wallmounted_to_dir = {
  129. [0] = vector.new( 0, 1, 0),
  130. vector.new( 0, -1, 0),
  131. vector.new( 1, 0, 0),
  132. vector.new(-1, 0, 0),
  133. vector.new( 0, 0, 1),
  134. vector.new( 0, 0, -1),
  135. vector.new( 0, 1, 0),
  136. vector.new( 0, -1, 0),
  137. }
  138. function core.wallmounted_to_dir(wallmounted)
  139. return wallmounted_to_dir[wallmounted % 8]
  140. end
  141. function core.dir_to_yaw(dir)
  142. return -math.atan2(dir.x, dir.z)
  143. end
  144. function core.yaw_to_dir(yaw)
  145. return vector.new(-math.sin(yaw), 0, math.cos(yaw))
  146. end
  147. function core.is_colored_paramtype(ptype)
  148. return (ptype == "color") or (ptype == "colorfacedir") or
  149. (ptype == "color4dir") or (ptype == "colorwallmounted") or
  150. (ptype == "colordegrotate")
  151. end
  152. function core.strip_param2_color(param2, paramtype2)
  153. if not core.is_colored_paramtype(paramtype2) then
  154. return nil
  155. end
  156. if paramtype2 == "colorfacedir" then
  157. param2 = math.floor(param2 / 32) * 32
  158. elseif paramtype2 == "color4dir" then
  159. param2 = math.floor(param2 / 4) * 4
  160. elseif paramtype2 == "colorwallmounted" then
  161. param2 = math.floor(param2 / 8) * 8
  162. elseif paramtype2 == "colordegrotate" then
  163. param2 = math.floor(param2 / 32) * 32
  164. end
  165. -- paramtype2 == "color" requires no modification.
  166. return param2
  167. end
  168. -- Content ID caching
  169. local old_get_content_id = core.get_content_id
  170. local old_get_name_from_content_id = core.get_name_from_content_id
  171. local name2content = setmetatable({}, {
  172. __index = function(self, name)
  173. return old_get_content_id(name)
  174. end,
  175. })
  176. local content2name = setmetatable({}, {
  177. __index = function(self, id)
  178. return old_get_name_from_content_id(id)
  179. end,
  180. })
  181. function core.get_content_id(name)
  182. return name2content[name]
  183. end
  184. function core.get_name_from_content_id(id)
  185. return content2name[id]
  186. end
  187. -- Cache content IDs after they have stopped changing.
  188. function builtin_shared.cache_content_ids()
  189. for name in pairs(core.registered_nodes) do
  190. local id = old_get_content_id(name)
  191. name2content[name] = id
  192. content2name[id] = name
  193. end
  194. -- unknown is not in the registered node list.
  195. local unknown_name = old_get_name_from_content_id(core.CONTENT_UNKNOWN)
  196. name2content[unknown_name] = core.CONTENT_UNKNOWN
  197. content2name[core.CONTENT_UNKNOWN] = unknown_name
  198. for name in pairs(core.registered_aliases) do
  199. if core.registered_nodes[name] then
  200. name2content[name] = old_get_content_id(name)
  201. end
  202. end
  203. end
  204. if core.set_read_node and core.set_push_node then
  205. local function read_node(node)
  206. return name2content[node.name], node.param1, node.param2
  207. end
  208. core.set_read_node(read_node)
  209. core.set_read_node = nil
  210. local function push_node(content, param1, param2)
  211. return {name = content2name[content], param1 = param1, param2 = param2}
  212. end
  213. core.set_push_node(push_node)
  214. core.set_push_node = nil
  215. end