init.lua 8.5 KB

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