brasier.lua 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. -- internationalization boilerplate
  2. local MP = minetest.get_modpath(minetest.get_current_modname())
  3. local S, NS = dofile(MP.."/intllib.lua")
  4. local brasier_longdesc = S("A brasier for producing copious amounts of light and heat.")
  5. local brasier_usagehelp = S("To ignite the brasier place a flammable fuel in its inventory slot. A lump of coal will burn for about half an hour.")
  6. local brasier_nodebox = {
  7. type = "fixed",
  8. fixed = {
  9. {-0.25, 0, -0.25, 0.25, 0.125, 0.25}, -- base
  10. {-0.375, 0.125, -0.375, 0.375, 0.25, 0.375}, -- mid
  11. {-0.5, 0.25, -0.5, 0.5, 0.375, 0.5}, -- plat
  12. {-0.5, 0.375, 0.375, 0.5, 0.5, 0.5}, -- edge
  13. {-0.5, 0.375, -0.5, 0.5, 0.5, -0.375}, -- edge
  14. {0.375, 0.375, -0.375, 0.5, 0.5, 0.375}, -- edge
  15. {-0.5, 0.375, -0.375, -0.375, 0.5, 0.375}, -- edge
  16. {0.25, -0.5, -0.375, 0.375, 0.125, -0.25}, -- leg
  17. {-0.375, -0.5, 0.25, -0.25, 0.125, 0.375}, -- leg
  18. {0.25, -0.5, 0.25, 0.375, 0.125, 0.375}, -- leg
  19. {-0.375, -0.5, -0.375, -0.25, 0.125, -0.25}, -- leg
  20. {-0.125, -0.0625, -0.125, 0.125, 0, 0.125}, -- bottom_knob
  21. }
  22. }
  23. local brasier_selection_box = {
  24. type = "fixed",
  25. fixed = {
  26. {-0.375, -0.5, -0.375, 0.375, 0.25, 0.375}, -- mid
  27. {-0.5, 0.25, -0.5, 0.5, 0.5, 0.5}, -- plat
  28. }
  29. }
  30. local brasier_burn = function(pos)
  31. local pos_above = {x=pos.x, y=pos.y+1, z=pos.z}
  32. local node_above = minetest.get_node(pos_above)
  33. local timer = minetest.get_node_timer(pos)
  34. if timer:is_started() and node_above.name == "fire:permanent_flame" then return end -- already burning, don't burn a new thing.
  35. local inv = minetest.get_inventory({type="node", pos=pos})
  36. local item = inv:get_stack("fuel", 1)
  37. local fuel_burned = minetest.get_craft_result({method="fuel", width=1, items={item:peek_item(1)}}).time
  38. if fuel_burned > 0 and (node_above.name == "air" or node_above.name == "fire:permanent_flame") then
  39. item:set_count(item:get_count() - 1)
  40. inv:set_stack("fuel", 1, item)
  41. timer:start(fuel_burned * 60) -- one minute of flame per second of burn time, for balance.
  42. if node_above.name == "air" then
  43. minetest.add_node(pos_above, {name = "fire:permanent_flame"})
  44. end
  45. else
  46. if node_above.name == "fire:permanent_flame" then
  47. minetest.add_node(pos_above, {name = "air"})
  48. end
  49. end
  50. end
  51. local brasier_on_construct = function(pos)
  52. local inv = minetest.get_meta(pos):get_inventory()
  53. inv:set_size("fuel", 1)
  54. local meta = minetest.get_meta(pos)
  55. meta:set_string("formspec",
  56. "size[8,5.3]" ..
  57. default.gui_bg ..
  58. default.gui_bg_img ..
  59. default.gui_slots ..
  60. "list[current_name;fuel;3.5,0;1,1;]" ..
  61. "list[current_player;main;0,1.15;8,1;]" ..
  62. "list[current_player;main;0,2.38;8,3;8]" ..
  63. "listring[current_name;main]" ..
  64. "listring[current_player;main]" ..
  65. default.get_hotbar_bg(0,1.15)
  66. )
  67. end
  68. local brasier_on_destruct = function(pos, oldnode)
  69. local pos_above = {x=pos.x, y=pos.y+1, z=pos.z}
  70. local node_above = minetest.get_node(pos_above)
  71. if node_above.name == "fire:permanent_flame" then
  72. minetest.add_node(pos_above, {name = "air"})
  73. end
  74. end
  75. local brasier_can_dig = function(pos, player)
  76. local inv = minetest.get_meta(pos):get_inventory()
  77. return inv:is_empty("fuel")
  78. end
  79. -- Only allow fuel items to be placed in fuel
  80. local brasier_allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  81. if listname == "fuel" then
  82. if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then
  83. return stack:get_count()
  84. else
  85. return 0
  86. end
  87. end
  88. return 0
  89. end
  90. minetest.register_node("castle_lighting:brasier_floor", {
  91. description = S("Floor Brasier"),
  92. _doc_items_longdesc = brasier_longdesc,
  93. _doc_items_usagehelp = brasier_usagehelp,
  94. tiles = {
  95. "castle_steel.png^(castle_coal_bed.png^[mask:castle_brasier_bed_mask.png)",
  96. "castle_steel.png",
  97. "castle_steel.png",
  98. "castle_steel.png",
  99. "castle_steel.png",
  100. "castle_steel.png",
  101. },
  102. drawtype = "nodebox",
  103. paramtype2 = "facedir",
  104. on_rotate = screwdriver.rotate_simple,
  105. groups = utility.dig_groups("brick"),
  106. paramtype = "light",
  107. node_box = brasier_nodebox,
  108. selection_box = brasier_selection_box,
  109. -- Unlit brasier should still emit a small amount of light, since it has coals.
  110. light_source = 4,
  111. on_construct = brasier_on_construct,
  112. on_destruct = brasier_on_destruct,
  113. can_dig = brasier_can_dig,
  114. allow_metadata_inventory_put = brasier_allow_metadata_inventory_put,
  115. on_metadata_inventory_put = brasier_burn,
  116. on_timer = brasier_burn,
  117. on_player_walk_over = function(pos, player)
  118. local pname = player:get_player_name()
  119. if player:get_hp() > 0 and not heatdamage.is_immune(pname) then
  120. player:set_hp(player:get_hp() - 1)
  121. if player:get_hp() <= 0 then
  122. minetest.chat_send_all("# Server: <" .. rename.gpn(pname) .. "> tripped on hot coals!")
  123. end
  124. end
  125. end,
  126. })
  127. minetest.register_craft({
  128. output = "castle_lighting:brasier_floor",
  129. recipe = {
  130. {"default:steel_ingot", "default:torch", "default:steel_ingot"},
  131. {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
  132. }
  133. })
  134. if minetest.get_modpath("hopper") and hopper ~= nil and hopper.add_container ~= nil then
  135. hopper:add_container({
  136. {"top", "castle_lighting:brasier_floor", "fuel"},
  137. {"bottom", "castle_lighting:brasier_floor", "fuel"},
  138. {"side", "castle_lighting:brasier_floor", "fuel"},
  139. })
  140. end
  141. ------------------------------------------------------------------------------------------------------
  142. -- Masonry brasiers
  143. local materials = {
  144. {name="stonebrick", desc=S("Stone Brick"), tile="default_stone_brick.png", craft_material="default:stonebrick"},
  145. {name="desert_stonebrick", desc=S("Redstone Brick"), tile="default_desert_stone_brick.png", craft_material="default:desert_stonebrick"},
  146. {name="rackstone_brick", desc=S("Rackstone Brick"), tile="rackstone_rackstone_brick.png", craft_material="rackstone:rackstone_brick2"},
  147. {name="obsidian_brick", desc=S("Obsidian Brick"), tile="default_obsidian_brick.png", craft_material="default:obsidianbrick"},
  148. }
  149. local get_material_properties = function(material)
  150. local composition_def
  151. local burn_time
  152. if material.composition_material ~= nil then
  153. composition_def = minetest.registered_nodes[material.composition_material]
  154. burn_time = minetest.get_craft_result({method="fuel", width=1, items={ItemStack(material.composition_material)}}).time
  155. else
  156. composition_def = minetest.registered_nodes[material.craft_material]
  157. burn_time = minetest.get_craft_result({method="fuel", width=1, items={ItemStack(material.craft_material)}}).time
  158. end
  159. local tiles = material.tile
  160. if tiles == nil then
  161. tiles = composition_def.tile
  162. elseif type(tiles) == "string" then
  163. tiles = {tiles}
  164. end
  165. -- Apply bed of coals to the texture.
  166. if table.getn(tiles) == 1 then
  167. tiles = {tiles[1].."^(castle_coal_bed.png^[mask:castle_brasier_bed_mask.png)", tiles[1], tiles[1], tiles[1], tiles[1], tiles[1]}
  168. else
  169. tiles[1] = tiles[1].."^(castle_coal_bed.png^[mask:castle_brasier_bed_mask.png)"
  170. end
  171. local desc = material.desc
  172. if desc == nil then
  173. desc = composition_def.description
  174. end
  175. return composition_def, burn_time, tiles, desc
  176. end
  177. local pillar_brasier_nodebox = {
  178. type = "fixed",
  179. fixed = {
  180. {-0.375, 0.125, -0.375, 0.375, 0.25, 0.375}, -- mid
  181. {-0.5, 0.25, -0.5, 0.5, 0.375, 0.5}, -- plat
  182. {-0.5, 0.375, 0.375, 0.5, 0.5, 0.5}, -- edge
  183. {-0.5, 0.375, -0.5, 0.5, 0.5, -0.375}, -- edge
  184. {0.375, 0.375, -0.375, 0.5, 0.5, 0.375}, -- edge
  185. {-0.5, 0.375, -0.375, -0.375, 0.5, 0.375}, -- edge
  186. {-0.25,-0.5,-0.25,0.25,0.125,0.25}, -- support
  187. }
  188. }
  189. local pillar_brasier_selection_box = {
  190. type = "fixed",
  191. fixed = {
  192. {-0.375, 0.125, -0.375, 0.375, 0.25, 0.375}, -- mid
  193. {-0.5, 0.25, -0.5, 0.5, 0.5, 0.5}, -- plat
  194. {-0.25,-0.5,-0.25,0.25,0.125,0.25}, -- support
  195. }
  196. }
  197. castle_lighting.register_pillar_brasier = function(material)
  198. local composition_def, burn_time, tile, desc = get_material_properties(material)
  199. if burn_time > 0 or composition_def.groups.puts_out_fire then return end -- No wooden brasiers, snow brasiers, or ice brasiers, alas.
  200. local groups = utility.copy_builtin_groups(composition_def.groups)
  201. local mod_name = minetest.get_current_modname()
  202. minetest.register_node(mod_name..":"..material.name.."_pillar_brasier", {
  203. drawtype = "nodebox",
  204. description = S("@1 Brasier", desc),
  205. _doc_items_longdesc = brasier_longdesc,
  206. _doc_items_usagehelp = brasier_usagehelp,
  207. tiles = tile,
  208. paramtype = "light",
  209. paramtype2 = "facedir",
  210. on_rotate = screwdriver.rotate_simple,
  211. groups = groups,
  212. sounds = composition_def.sounds,
  213. -- Unlit brasier should still emit a small amount of light, since it has coals.
  214. light_source = 4,
  215. node_box = pillar_brasier_nodebox,
  216. selection_box = pillar_brasier_selection_box,
  217. on_construct = brasier_on_construct,
  218. on_destruct = brasier_on_destruct,
  219. can_dig = brasier_can_dig,
  220. allow_metadata_inventory_put = brasier_allow_metadata_inventory_put,
  221. on_metadata_inventory_put = brasier_burn,
  222. on_timer = brasier_burn,
  223. on_player_walk_over = function(pos, player)
  224. local pname = player:get_player_name()
  225. if player:get_hp() > 0 and not heatdamage.is_immune(pname) then
  226. player:set_hp(player:get_hp() - 1)
  227. if player:get_hp() <= 0 then
  228. minetest.chat_send_all("# Server: <" .. rename.gpn(pname) .. "> tripped on hot coals!")
  229. end
  230. end
  231. end,
  232. })
  233. minetest.register_craft({
  234. output = mod_name..":"..material.name.."_pillar_brasier",
  235. recipe = {
  236. {material.craft_material,"default:torch",material.craft_material},
  237. {material.craft_material,material.craft_material,material.craft_material},
  238. },
  239. })
  240. end
  241. for _, material in pairs(materials) do
  242. castle_lighting.register_pillar_brasier(material)
  243. end