fermenter.lua 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. local S = minetest.get_translator("default")
  2. -- List of sound handles for active furnace
  3. local fermenter_fire_sounds = {}
  4. --
  5. -- Formspecs
  6. --
  7. function technic_farming.get_fermenter_active_formspec(item_percent)
  8. return "size[8,8.5]"..
  9. "list[context;src;2.75,0.5;1,1;]"..
  10. "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:"..
  11. (item_percent)..":gui_furnace_arrow_fg.png^[transformR270]"..
  12. "list[context;dst;4.75,0.96;2,2;]"..
  13. "list[current_player;main;0,4.25;8,1;]"..
  14. "list[current_player;main;0,5.5;8,3;8]"..
  15. "listring[context;dst]"..
  16. "listring[current_player;main]"..
  17. "listring[context;src]"..
  18. "listring[current_player;main]"..
  19. default.get_hotbar_bg(0, 4.25)
  20. end
  21. function technic_farming.get_fermenter_inactive_formspec()
  22. return "size[8,8.5]"..
  23. "list[context;src;2.75,0.5;1,1;]"..
  24. "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
  25. "list[context;dst;4.75,0.96;2,2;]"..
  26. "list[current_player;main;0,4.25;8,1;]"..
  27. "list[current_player;main;0,5.5;8,3;8]"..
  28. "listring[context;dst]"..
  29. "listring[current_player;main]"..
  30. "listring[context;src]"..
  31. "listring[current_player;main]"..
  32. default.get_hotbar_bg(0, 4.25)
  33. end
  34. local function stop_fermenter_sound(pos, fadeout_step)
  35. local hash = minetest.hash_node_position(pos)
  36. local sound_ids = fermenter_fire_sounds[hash]
  37. if sound_ids then
  38. for _, sound_id in ipairs(sound_ids) do
  39. minetest.sound_fade(sound_id, -1, 0)
  40. end
  41. fermenter_fire_sounds[hash] = nil
  42. end
  43. end
  44. local function fermenter_node_timer(pos, elapsed)
  45. --
  46. -- Initialize metadata
  47. --
  48. local meta = minetest.get_meta(pos)
  49. local src_time = meta:get_float("src_time") or 0
  50. local inv = meta:get_inventory()
  51. local srclist = inv:get_list("src")
  52. local dst_full = false
  53. local full_flow = 120
  54. local timer_elapsed = meta:get_int("timer_elapsed") or 0
  55. meta:set_int("timer_elapsed", timer_elapsed + 1)
  56. -- ensure that grinding with mp machines are slower than with electric machines
  57. local rel_time = 1
  58. local update = true
  59. local fermentable
  60. local fermenttime = 0
  61. while elapsed > 0 and update do
  62. update = false
  63. srclist = inv:get_list("src")
  64. -- Check if we have grindable content
  65. local fermented = technic.get_recipe("ferment",srclist)
  66. fermenttime = 0
  67. local fermentoutput
  68. if fermented then
  69. fermenttime = fermented.time or 0
  70. fermentoutput = string.split(fermented.output,' ')[1]
  71. if(srclist[1]:get_count() > 0 and minetest.registered_items[fermentoutput] and fermenttime == 0) then
  72. fermenttime = 1
  73. end
  74. end
  75. fermentable = fermenttime ~= 0
  76. if fermentable then
  77. src_time = src_time + rel_time
  78. if src_time >= fermenttime then
  79. -- Place result in dst list if possible
  80. if inv:room_for_item("dst", fermentoutput) then
  81. inv:add_item("dst", fermented.output)
  82. inv:set_stack("src",1,fermented.new_input[1])
  83. src_time = src_time - fermenttime
  84. update = true
  85. else
  86. dst_full = true
  87. end
  88. -- Play cooling sound
  89. minetest.sound_play("default_cool_lava",
  90. {pos = pos, max_hear_distance = 16, gain = 0.07}, true)
  91. else
  92. -- Item could not be cooked: probably missing fuel
  93. update = true
  94. end
  95. end
  96. elapsed = elapsed - 1
  97. end
  98. --
  99. -- Update formspec, infotext and node
  100. --
  101. local formspec
  102. local item_state
  103. local item_percent = 0
  104. if fermentable then
  105. item_percent = math.floor(src_time / fermenttime * 100)
  106. if dst_full then
  107. item_state = S("100% (output full)")
  108. else
  109. item_state = S("@1%", item_percent)
  110. end
  111. else
  112. if srclist and not srclist[1]:is_empty() then
  113. item_state = S("Not fermentable")
  114. else
  115. item_state = S("Empty")
  116. end
  117. end
  118. local active = true
  119. if srclist and srclist[1]:is_empty() then
  120. print("empty")
  121. active = false
  122. end
  123. -- local fuel_state = S("Empty")
  124. -- local active = false
  125. local result = false
  126. if active then
  127. -- if false then
  128. active = true
  129. formspec = technic_farming.get_fermenter_active_formspec(item_percent)
  130. technic_farming.swap_node(pos, "technic_farming:fermenter_active")
  131. -- make sure timer restarts automatically
  132. result = true
  133. -- Play sound every 5 seconds while the furnace is active
  134. if timer_elapsed == 0 or (timer_elapsed + 1) % 5 == 0 then
  135. local sound_id = minetest.sound_play("technic_farming:fermenter_active",
  136. {pos = pos, max_hear_distance = 16, gain = 0.25})
  137. local hash = minetest.hash_node_position(pos)
  138. fermenter_fire_sounds[hash] = fermenter_fire_sounds[hash] or {}
  139. table.insert(fermenter_fire_sounds[hash], sound_id)
  140. -- Only remember the 3 last sound handles
  141. if #fermenter_fire_sounds[hash] > 3 then
  142. table.remove(fermenter_fire_sounds[hash], 1)
  143. end
  144. -- Remove the sound ID automatically from table after 11 seconds
  145. minetest.after(11, function()
  146. if not fermenter_fire_sounds[hash] then
  147. return
  148. end
  149. for f=#fermenter_fire_sounds[hash], 1, -1 do
  150. if fermenter_fire_sounds[hash][f] == sound_id then
  151. table.remove(fermenter_fire_sounds[hash], f)
  152. end
  153. end
  154. if #fermenter_fire_sounds[hash] == 0 then
  155. fermenter_fire_sounds[hash] = nil
  156. end
  157. end)
  158. end
  159. else
  160. formspec = technic_farming.get_fermenter_inactive_formspec()
  161. technic_farming.swap_node(pos, "technic_farming:fermenter")
  162. -- stop timer on the inactive furnace
  163. minetest.get_node_timer(pos):stop()
  164. meta:set_int("timer_elapsed", 0)
  165. stop_fermenter_sound(pos)
  166. end
  167. local infotext
  168. if active then
  169. infotext = S("Fermenter active")
  170. else
  171. infotext = S("Fermenter inactive")
  172. end
  173. infotext = infotext .. "\n" .. S("(Item: @1)", item_state)
  174. --
  175. -- Set meta values
  176. --
  177. meta:set_float("src_time", src_time)
  178. meta:set_string("formspec", formspec)
  179. meta:set_string("infotext", infotext)
  180. return result
  181. end
  182. --
  183. -- Node definitions
  184. --
  185. minetest.register_node("technic_farming:fermenter", {
  186. description = S("Fermenter"),
  187. tiles = {
  188. "technic_farming_fermenter_bottom.png",
  189. "technic_farming_fermenter_bottom.png",
  190. "technic_farming_fermenter_side.png",
  191. "technic_farming_fermenter_side.png",
  192. "technic_farming_fermenter_side.png",
  193. "technic_farming_fermenter_front.png"
  194. },
  195. paramtype2 = "facedir",
  196. groups = {cracky=2},
  197. legacy_facedir_simple = true,
  198. is_ground_content = false,
  199. sounds = default.node_sound_stone_defaults(),
  200. can_dig = technic_farming.can_dig,
  201. on_timer = fermenter_node_timer,
  202. on_construct = function(pos)
  203. local meta = minetest.get_meta(pos)
  204. local inv = meta:get_inventory()
  205. inv:set_size('src', 1)
  206. inv:set_size('dst', 4)
  207. fermenter_node_timer(pos, 0)
  208. end,
  209. on_metadata_inventory_move = function(pos)
  210. minetest.get_node_timer(pos):start(1.0)
  211. end,
  212. on_metadata_inventory_put = function(pos)
  213. minetest.get_node_timer(pos):start(1.0)
  214. end,
  215. on_metadata_inventory_take = function(pos)
  216. minetest.get_node_timer(pos):start(1.0)
  217. end,
  218. on_blast = function(pos)
  219. local drops = {}
  220. default.get_inventory_drops(pos, "src", drops)
  221. default.get_inventory_drops(pos, "dst", drops)
  222. drops[#drops+1] = "technic_farming:fermenter"
  223. minetest.remove_node(pos)
  224. return drops
  225. end,
  226. allow_metadata_inventory_put = technic_farming.allow_metadata_inventory_put,
  227. allow_metadata_inventory_move = technic_farming.allow_metadata_inventory_move,
  228. allow_metadata_inventory_take = technic_farming.allow_metadata_inventory_take,
  229. })
  230. minetest.register_node("technic_farming:fermenter_active", {
  231. description = S("Fermenter"),
  232. tiles = {
  233. "technic_farming_fermenter_bottom.png",
  234. "technic_farming_fermenter_bottom.png",
  235. "technic_farming_fermenter_side.png",
  236. "technic_farming_fermenter_side.png",
  237. "technic_farming_fermenter_side.png",
  238. "technic_farming_fermenter_front.png"
  239. },
  240. paramtype2 = "facedir",
  241. light_source = 8,
  242. drop = "technic_farming:fermenter",
  243. groups = {cracky=2, not_in_creative_inventory=1},
  244. legacy_facedir_simple = true,
  245. is_ground_content = false,
  246. sounds = default.node_sound_stone_defaults(),
  247. on_timer = fermenter_node_timer,
  248. on_destruct = function(pos)
  249. stop_fermenter_sound(pos)
  250. end,
  251. can_dig = technic_farming.can_dig,
  252. allow_metadata_inventory_put = technic_farming.allow_metadata_inventory_put,
  253. allow_metadata_inventory_move = technic_farming.allow_metadata_inventory_move,
  254. allow_metadata_inventory_take = technic_farming.allow_metadata_inventory_take,
  255. })
  256. minetest.register_craft({
  257. output = 'technic_farming:fermenter',
  258. recipe = {
  259. {'group:wood', 'technic_farming:wooden_plate', 'group:wood'},
  260. {'group:wood', '', 'group:wood'},
  261. {'group:wood', 'technic_farming:wooden_plate', 'group:wood'},
  262. }
  263. })