init.lua 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. stairs = {}
  2. -- Load support for MT game translation.
  3. local S = minetest.get_translator('stairs')
  4. local function rotate_and_place(itemstack, placer, pointed_thing)
  5. local p0 = pointed_thing.under
  6. local p1 = pointed_thing.above
  7. local param2 = 0
  8. if placer then
  9. local placer_pos = placer:get_pos()
  10. if placer_pos then
  11. param2 = minetest.dir_to_facedir(vector.subtract(p1, placer_pos))
  12. end
  13. local finepos = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
  14. local fpos = finepos.y % 1
  15. if p0.y - 1 == p1.y or (fpos > 0 and fpos < 0.5)
  16. or (fpos < -0.5 and fpos > -0.999999999) then
  17. param2 = param2 + 20
  18. if param2 == 21 then
  19. param2 = 23
  20. elseif param2 == 23 then
  21. param2 = 21
  22. end
  23. end
  24. end
  25. return minetest.item_place(itemstack, placer, pointed_thing, param2)
  26. end
  27. -- Register stair
  28. -- Node will be called stairs:stair_<subname>
  29. function stairs.register_stair(subname, groups, images, sounds, worldaligntex, alpha)
  30. -- Set backface culling and world-aligned textures
  31. local stair_images = {}
  32. for i, image in ipairs(images) do
  33. if type(image) == 'string' then
  34. stair_images[i] = {
  35. name = image,
  36. backface_culling = true,
  37. }
  38. if worldaligntex then
  39. stair_images[i].align_style = 'world'
  40. end
  41. else
  42. stair_images[i] = table.copy(image)
  43. if stair_images[i].backface_culling == nil then
  44. stair_images[i].backface_culling = true
  45. end
  46. if worldaligntex and stair_images[i].align_style == nil then
  47. stair_images[i].align_style = 'world'
  48. end
  49. end
  50. end
  51. local new_groups = table.copy(groups)
  52. new_groups.stair = 1
  53. minetest.register_node(':stairs:stair_' .. subname, {
  54. description = subname..' stair',
  55. drawtype = 'nodebox',
  56. tiles = stair_images,
  57. use_texture_alpha = alpha,
  58. paramtype = 'light',
  59. paramtype2 = 'facedir',
  60. is_ground_content = false,
  61. groups = new_groups,
  62. sounds = sounds,
  63. node_box = {
  64. type = 'fixed',
  65. fixed = {
  66. {-0.5, -0.5, -0.5, 0.5, 0.0, 0.5},
  67. {-0.5, 0.0, 0.0, 0.5, 0.5, 0.5},
  68. },
  69. },
  70. on_place = function(itemstack, placer, pointed_thing)
  71. if pointed_thing.type ~= 'node' then
  72. return itemstack
  73. end
  74. return rotate_and_place(itemstack, placer, pointed_thing)
  75. end,
  76. })
  77. end
  78. -- Register slab
  79. -- Node will be called stairs:slab_<subname>
  80. function stairs.register_slab(subname, groups, images, sounds, worldaligntex, alpha)
  81. -- Set world-aligned textures
  82. local slab_images = {}
  83. for i, image in ipairs(images) do
  84. if type(image) == 'string' then
  85. slab_images[i] = {
  86. name = image,
  87. }
  88. if worldaligntex then
  89. slab_images[i].align_style = 'world'
  90. end
  91. else
  92. slab_images[i] = table.copy(image)
  93. if worldaligntex and image.align_style == nil then
  94. slab_images[i].align_style = 'world'
  95. end
  96. end
  97. end
  98. local new_groups = table.copy(groups)
  99. new_groups.slab = 1
  100. minetest.register_node(':stairs:slab_' .. subname, {
  101. description = subname..' slab',
  102. drawtype = 'nodebox',
  103. tiles = slab_images,
  104. use_texture_alpha = alpha,
  105. paramtype = 'light',
  106. paramtype2 = 'facedir',
  107. is_ground_content = false,
  108. groups = new_groups,
  109. sounds = sounds,
  110. node_box = {
  111. type = 'fixed',
  112. fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
  113. },
  114. on_place = function(itemstack, placer, pointed_thing)
  115. local under = minetest.get_node(pointed_thing.under)
  116. local wield_item = itemstack:get_name()
  117. local player_name = placer and placer:get_player_name() or ''
  118. local creative_enabled = (creative and creative.is_enabled_for
  119. and creative.is_enabled_for(player_name))
  120. if under and under.name:find('^stairs:slab_') then
  121. -- place slab using under node orientation
  122. local dir = minetest.dir_to_facedir(vector.subtract(
  123. pointed_thing.above, pointed_thing.under), true)
  124. local p2 = under.param2
  125. -- Placing a slab on an upside down slab should make it right-side up.
  126. if p2 >= 20 and dir == 8 then
  127. p2 = p2 - 20
  128. -- same for the opposite case: slab below normal slab
  129. elseif p2 <= 3 and dir == 4 then
  130. p2 = p2 + 20
  131. end
  132. -- else attempt to place node with proper param2
  133. minetest.item_place_node(ItemStack(wield_item), placer, pointed_thing, p2)
  134. if not creative_enabled then
  135. itemstack:take_item()
  136. end
  137. return itemstack
  138. else
  139. return rotate_and_place(itemstack, placer, pointed_thing)
  140. end
  141. end,
  142. })
  143. end
  144. -- Register inner stair
  145. -- Node will be called stairs:stair_inner_<subname>
  146. function stairs.register_stair_inner(subname, groups, images, sounds, worldaligntex, alpha)
  147. -- Set backface culling and world-aligned textures
  148. local stair_images = {}
  149. for i, image in ipairs(images) do
  150. if type(image) == 'string' then
  151. stair_images[i] = {
  152. name = image,
  153. backface_culling = true,
  154. }
  155. if worldaligntex then
  156. stair_images[i].align_style = 'world'
  157. end
  158. else
  159. stair_images[i] = table.copy(image)
  160. if stair_images[i].backface_culling == nil then
  161. stair_images[i].backface_culling = true
  162. end
  163. if worldaligntex and stair_images[i].align_style == nil then
  164. stair_images[i].align_style = 'world'
  165. end
  166. end
  167. end
  168. local new_groups = table.copy(groups)
  169. new_groups.stair = 1
  170. minetest.register_node(':stairs:stair_inner_' .. subname, {
  171. description = subname..' inner stair',
  172. drawtype = 'nodebox',
  173. tiles = stair_images,
  174. use_texture_alpha = alpha,
  175. paramtype = 'light',
  176. paramtype2 = 'facedir',
  177. is_ground_content = false,
  178. groups = new_groups,
  179. sounds = sounds,
  180. node_box = {
  181. type = 'fixed',
  182. fixed = {
  183. {-0.5, -0.5, -0.5, 0.5, 0.0, 0.5},
  184. {-0.5, 0.0, 0.0, 0.5, 0.5, 0.5},
  185. {-0.5, 0.0, -0.5, 0.0, 0.5, 0.0},
  186. },
  187. },
  188. on_place = function(itemstack, placer, pointed_thing)
  189. if pointed_thing.type ~= 'node' then
  190. return itemstack
  191. end
  192. return rotate_and_place(itemstack, placer, pointed_thing)
  193. end,
  194. })
  195. end
  196. -- Register outer stair
  197. -- Node will be called stairs:stair_outer_<subname>
  198. function stairs.register_stair_outer(subname, groups, images, sounds, worldaligntex, alpha)
  199. -- Set backface culling and world-aligned textures
  200. local stair_images = {}
  201. for i, image in ipairs(images) do
  202. if type(image) == 'string' then
  203. stair_images[i] = {
  204. name = image,
  205. backface_culling = true,
  206. }
  207. if worldaligntex then
  208. stair_images[i].align_style = 'world'
  209. end
  210. else
  211. stair_images[i] = table.copy(image)
  212. if stair_images[i].backface_culling == nil then
  213. stair_images[i].backface_culling = true
  214. end
  215. if worldaligntex and stair_images[i].align_style == nil then
  216. stair_images[i].align_style = 'world'
  217. end
  218. end
  219. end
  220. local new_groups = table.copy(groups)
  221. new_groups.stair = 1
  222. minetest.register_node(':stairs:stair_outer_' .. subname, {
  223. description = subname..' outer stair',
  224. drawtype = 'nodebox',
  225. tiles = stair_images,
  226. use_texture_alpha = alpha,
  227. paramtype = 'light',
  228. paramtype2 = 'facedir',
  229. is_ground_content = false,
  230. groups = new_groups,
  231. sounds = sounds,
  232. node_box = {
  233. type = 'fixed',
  234. fixed = {
  235. {-0.5, -0.5, -0.5, 0.5, 0.0, 0.5},
  236. {-0.5, 0.0, 0.0, 0.0, 0.5, 0.5},
  237. },
  238. },
  239. on_place = function(itemstack, placer, pointed_thing)
  240. if pointed_thing.type ~= 'node' then
  241. return itemstack
  242. end
  243. return rotate_and_place(itemstack, placer, pointed_thing)
  244. end,
  245. })
  246. end
  247. -- Stair/slab registration function.
  248. -- Nodes will be called stairs:{stair,slab}_<subname>
  249. function stairs.register_stair_and_slab(subname, groups, images, sounds, worldaligntex, alpha)
  250. stairs.register_stair(subname, groups, images, sounds, worldaligntex, alpha)
  251. stairs.register_stair_inner(subname, groups, images, sounds, worldaligntex, alpha)
  252. stairs.register_stair_outer(subname, groups, images, sounds, worldaligntex, alpha)
  253. stairs.register_slab(subname, groups, images, sounds, worldaligntex, alpha)
  254. end