item_s.lua 5.1 KB

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