brewing.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. lottpotion.make_pipe = function( pipes, horizontal )
  2. local result = {};
  3. for i, v in pairs( pipes ) do
  4. local f = v.f;
  5. local h1 = v.h1;
  6. local h2 = v.h2;
  7. if( not( v.b ) or v.b == 0 ) then
  8. table.insert( result, {-0.37*f, h1,-0.37*f, -0.28*f, h2,-0.28*f});
  9. table.insert( result, {-0.37*f, h1, 0.28*f, -0.28*f, h2, 0.37*f});
  10. table.insert( result, { 0.37*f, h1,-0.28*f, 0.28*f, h2,-0.37*f});
  11. table.insert( result, { 0.37*f, h1, 0.37*f, 0.28*f, h2, 0.28*f});
  12. table.insert( result, {-0.30*f, h1,-0.42*f, -0.20*f, h2,-0.34*f});
  13. table.insert( result, {-0.30*f, h1, 0.34*f, -0.20*f, h2, 0.42*f});
  14. table.insert( result, { 0.20*f, h1,-0.42*f, 0.30*f, h2,-0.34*f});
  15. table.insert( result, { 0.20*f, h1, 0.34*f, 0.30*f, h2, 0.42*f});
  16. table.insert( result, {-0.42*f, h1,-0.30*f, -0.34*f, h2,-0.20*f});
  17. table.insert( result, { 0.34*f, h1,-0.30*f, 0.42*f, h2,-0.20*f});
  18. table.insert( result, {-0.42*f, h1, 0.20*f, -0.34*f, h2, 0.30*f});
  19. table.insert( result, { 0.34*f, h1, 0.20*f, 0.42*f, h2, 0.30*f});
  20. table.insert( result, {-0.25*f, h1,-0.45*f, -0.10*f, h2,-0.40*f});
  21. table.insert( result, {-0.25*f, h1, 0.40*f, -0.10*f, h2, 0.45*f});
  22. table.insert( result, { 0.10*f, h1,-0.45*f, 0.25*f, h2,-0.40*f});
  23. table.insert( result, { 0.10*f, h1, 0.40*f, 0.25*f, h2, 0.45*f});
  24. table.insert( result, {-0.45*f, h1,-0.25*f, -0.40*f, h2,-0.10*f});
  25. table.insert( result, { 0.40*f, h1,-0.25*f, 0.45*f, h2,-0.10*f});
  26. table.insert( result, {-0.45*f, h1, 0.10*f, -0.40*f, h2, 0.25*f});
  27. table.insert( result, { 0.40*f, h1, 0.10*f, 0.45*f, h2, 0.25*f});
  28. table.insert( result, {-0.15*f, h1,-0.50*f, 0.15*f, h2,-0.45*f});
  29. table.insert( result, {-0.15*f, h1, 0.45*f, 0.15*f, h2, 0.50*f});
  30. table.insert( result, {-0.50*f, h1,-0.15*f, -0.45*f, h2, 0.15*f});
  31. table.insert( result, { 0.45*f, h1,-0.15*f, 0.50*f, h2, 0.15*f});
  32. else
  33. table.insert( result, {-0.35*f, h1,-0.40*f, 0.35*f, h2,0.40*f});
  34. table.insert( result, {-0.40*f, h1,-0.35*f, 0.40*f, h2,0.35*f});
  35. table.insert( result, {-0.25*f, h1,-0.45*f, 0.25*f, h2,0.45*f});
  36. table.insert( result, {-0.45*f, h1,-0.25*f, 0.45*f, h2,0.25*f});
  37. table.insert( result, {-0.15*f, h1,-0.50*f, 0.15*f, h2,0.50*f});
  38. table.insert( result, {-0.50*f, h1,-0.15*f, 0.50*f, h2,0.15*f});
  39. end
  40. end
  41. if( horizontal == 1 ) then
  42. for i,v in ipairs( result ) do
  43. result[ i ] = { v[2], v[1], v[3], v[5], v[4], v[6] };
  44. end
  45. end
  46. return result;
  47. end
  48. minetest.register_craft({
  49. output = 'lottpotion:brewer',
  50. recipe = {
  51. {'group:wood', 'group:wood', 'group:wood'},
  52. {'group:wood', '', 'group:wood'},
  53. {'group:wood', 'default:steel_ingot', 'group:wood'},
  54. }
  55. })
  56. lottpotion.brew_recipes = { cooking = { input_size = 1, output_size = 1 } }
  57. function lottpotion.register_recipe_type(typename, origdata)
  58. local data = {}
  59. for k, v in pairs(origdata) do data[k] = v end
  60. data.input_size = data.input_size or 1
  61. data.output_size = data.output_size or 1
  62. data.recipes = {}
  63. lottpotion.brew_recipes[typename] = data
  64. end
  65. local function get_recipe_index(items)
  66. local l = {}
  67. if items ~= nil then
  68. for i, stack in ipairs(items) do
  69. l[i] = ItemStack(stack):get_name()
  70. end
  71. end
  72. table.sort(l)
  73. return table.concat(l, "/")
  74. end
  75. local function register_recipe(typename, data)
  76. -- Handle aliases
  77. for i, stack in ipairs(data.input) do
  78. data.input[i] = ItemStack(stack):to_string()
  79. end
  80. if type(data.output) == "table" then
  81. for i, v in ipairs(data.output) do
  82. data.output[i] = ItemStack(data.output[i]):to_string()
  83. end
  84. else
  85. data.output = ItemStack(data.output):to_string()
  86. end
  87. local recipe = {time = data.time, input = {}, output = data.output}
  88. local index = get_recipe_index(data.input)
  89. for _, stack in ipairs(data.input) do
  90. recipe.input[ItemStack(stack):get_name()] = ItemStack(stack):get_count()
  91. end
  92. lottpotion.brew_recipes[typename].recipes[index] = recipe
  93. end
  94. function lottpotion.register_recipe(typename, data)
  95. minetest.after(0.01, register_recipe, typename, data) -- Handle aliases
  96. end
  97. function lottpotion.get_brew_recipe(typename, items)
  98. if typename == "cooking" then -- Already builtin in Minetest, so use that
  99. local result, new_input = minetest.get_craft_result({
  100. method = "cooking",
  101. width = 1,
  102. items = items})
  103. -- Compatibility layer
  104. if not result or result.time == 0 then
  105. return nil
  106. else
  107. return {time = result.time,
  108. new_input = new_input.items,
  109. output = result.item}
  110. end
  111. end
  112. local index = get_recipe_index(items)
  113. local recipe = lottpotion.brew_recipes[typename].recipes[index]
  114. if recipe then
  115. local new_input = {}
  116. for i, stack in ipairs(items) do
  117. if stack:get_count() < recipe.input[stack:get_name()] then
  118. return nil
  119. else
  120. new_input[i] = ItemStack(stack)
  121. new_input[i]:take_item(recipe.input[stack:get_name()])
  122. end
  123. end
  124. return {time = recipe.time,
  125. new_input = new_input,
  126. output = recipe.output}
  127. else
  128. return nil
  129. end
  130. end
  131. lottpotion.register_recipe_type("brew", {
  132. description = "Brewing",
  133. input_size = 2,
  134. })
  135. function lottpotion.register_brew_recipe(data)
  136. data.time = data.time or 60
  137. lottpotion.register_recipe("brew", data)
  138. end
  139. local recipes = {
  140. --Base Potion
  141. {"lottfarming:berries 5", "lottpotion:drinking_glass_water", "lottpotion:wine"},
  142. {"farming:wheat 3", "lottpotion:drinking_glass_water", "lottpotion:beer"},
  143. {"lottplants:honey 6", "lottpotion:drinking_glass_water", "lottpotion:mead"},
  144. {"default:apple 5", "lottpotion:drinking_glass_water", "lottpotion:cider"},
  145. {"lottfarming:barley 6", "lottpotion:drinking_glass_water", "lottpotion:ale"},
  146. }
  147. for _, data in pairs(recipes) do
  148. lottpotion.register_brew_recipe({input = {data[1], data[2]}, output = data[3], time = data[4]})
  149. end
  150. local machine_name = "Brewer"
  151. local formspec =
  152. "size[8,9]"..
  153. "label[0,0;"..machine_name.."]"..
  154. "image[4,2;1,1;default_brewer_inv.png]"..
  155. "image[3,2;1,1;lottpotion_arrow.png]"..
  156. "image[5,2;1,1;lottpotion_arrow.png]"..
  157. "label[3.2,3.2;Fuel:]"..
  158. "list[current_name;fuel;4,3;1,1;]"..
  159. "label[1,1.5;Ingredients:]"..
  160. "list[current_name;src;1,2;2,1;]"..
  161. "label[6,1.5;Result:]"..
  162. "list[current_name;dst;6,2;1,1;]"..
  163. "list[current_player;main;0,5;8,4;]"..
  164. "background[-0.5,-0.65;9,10.35;gui_brewerbg.png]"..
  165. "listring[current_name;src]"..
  166. "listring[current_player;main]"..
  167. "listcolors[#606060AA;#888;#141318;#30434C;#FFF]"
  168. minetest.register_node("lottpotion:brewer", {
  169. description = machine_name,
  170. drawtype = "nodebox",
  171. tiles = {"default_wood.png"},
  172. node_box = {
  173. type = "fixed",
  174. fixed = lottpotion.make_pipe( { {f=0.9,h1=-0.2,h2=0.2,b=0}, {f=0.75,h1=-0.50,h2=-0.35,b=0}, {f=0.75,h1=0.35,h2=0.5,b=0},
  175. {f=0.82,h1=-0.35,h2=-0.2,b=0}, {f=0.82,h1=0.2, h2=0.35,b=0},
  176. {f=0.75,h1= 0.37,h2= 0.42,b=1},
  177. {f=0.75,h1=-0.42,h2=-0.37,b=1}}, 0 ),
  178. },
  179. paramtype = "light",
  180. groups = {choppy=2,oddly_breakable_by_hand=2},
  181. sounds = default.node_sound_stone_defaults(),
  182. selection_box = {
  183. type = "fixed",
  184. fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
  185. },
  186. on_construct = function(pos)
  187. local meta = minetest.get_meta(pos)
  188. meta:set_string("formspec", formspec)
  189. meta:set_string("infotext", machine_name)
  190. local inv = meta:get_inventory()
  191. inv:set_size("fuel", 1)
  192. inv:set_size("src", 2)
  193. inv:set_size("dst", 1)
  194. end,
  195. can_dig = lottpotion.can_dig,
  196. --backwards compatibility: punch to set formspec
  197. on_punch = function(pos,player)
  198. local meta = minetest.get_meta(pos)
  199. meta:set_string("infotext", machine_name)
  200. meta:set_string("formspec", formspec)
  201. end
  202. })
  203. minetest.register_node("lottpotion:brewer_active", {
  204. description = machine_name,
  205. drawtype = "nodebox",
  206. tiles = {"default_wood.png"},
  207. node_box = {
  208. type = "fixed",
  209. fixed = lottpotion.make_pipe( { {f=0.9,h1=-0.2,h2=0.2,b=0}, {f=0.75,h1=-0.50,h2=-0.35,b=0}, {f=0.75,h1=0.35,h2=0.5,b=0},
  210. {f=0.82,h1=-0.35,h2=-0.2,b=0}, {f=0.82,h1=0.2, h2=0.35,b=0},
  211. {f=0.75,h1= 0.37,h2= 0.42,b=1},
  212. {f=0.75,h1=-0.42,h2=-0.37,b=1}}, 0 ),
  213. },
  214. paramtype = "light",
  215. groups = {cracky=2},
  216. sounds = default.node_sound_stone_defaults(),
  217. selection_box = {
  218. type = "fixed",
  219. fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
  220. },
  221. drop = "lottpotion:brewer",
  222. groups = {cracky=2, not_in_creative_inventory=1},
  223. sounds = default.node_sound_stone_defaults(),
  224. can_dig = lottpotion.can_dig,
  225. })
  226. minetest.register_abm({
  227. nodenames = {"lottpotion:brewer", "lottpotion:brewer_active"},
  228. interval = 1,
  229. chance = 1,
  230. action = function(pos, node, active_object_count, active_object_count_wider)
  231. local meta = minetest.get_meta(pos)
  232. local inv = meta:get_inventory()
  233. if meta:get_string("infotext") == "" then
  234. meta:set_string("formspec", formspec)
  235. meta:set_string("infotext", machine_name)
  236. local inv = meta:get_inventory()
  237. inv:set_size("fuel", 1)
  238. inv:set_size("src", 2)
  239. inv:set_size("dst", 1)
  240. end
  241. if inv:get_size("src") == 1 then -- Old furnace -> convert it
  242. inv:set_size("src", 2)
  243. inv:set_stack("src", 2, inv:get_stack("src2", 1))
  244. inv:set_size("src2", 0)
  245. end
  246. local recipe = nil
  247. for i, name in pairs({
  248. "fuel_totaltime",
  249. "fuel_time",
  250. "src_totaltime",
  251. "src_time"}) do
  252. if not meta:get_float(name) then
  253. meta:set_float(name, 0.0)
  254. end
  255. end
  256. local result = lottpotion.get_brew_recipe("brew", inv:get_list("src"))
  257. local was_active = false
  258. if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
  259. was_active = true
  260. meta:set_int("fuel_time", meta:get_int("fuel_time") + 1)
  261. if result then
  262. meta:set_int("src_time", meta:get_int("src_time") + 1)
  263. if meta:get_int("src_time") >= result.time then
  264. meta:set_int("src_time", 0)
  265. local result_stack = ItemStack(result.output)
  266. if inv:room_for_item("dst", result_stack) then
  267. inv:set_list("src", result.new_input)
  268. inv:add_item("dst", result_stack)
  269. end
  270. end
  271. else
  272. meta:set_int("src_time", 0)
  273. end
  274. end
  275. if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
  276. local percent = math.floor(meta:get_float("fuel_time") /
  277. meta:get_float("fuel_totaltime") * 100)
  278. meta:set_string("infotext", ("%s Brewing"):format(machine_name).." ("..percent.."%)")
  279. lottpotion.swap_node(pos, "lottpotion:brewer_active")
  280. meta:set_string("formspec",
  281. "size[8,9]"..
  282. "label[0,0;"..machine_name.."]"..
  283. "image[4,2;1,1;default_brewer_inv.png^[lowpart:"..
  284. (percent)..":lottpotion_bubble.png]"..
  285. "image[3,2;1,1;lottpotion_arrow.png]"..
  286. "image[5,2;1,1;lottpotion_arrow.png]"..
  287. "label[3.2,3.2;Fuel:]"..
  288. "list[current_name;fuel;4,3;1,1;]"..
  289. "label[1,1.5;Ingredients:]"..
  290. "list[current_name;src;1,2;2,1;]"..
  291. "label[6,1.5;Result:]"..
  292. "list[current_name;dst;6,2;1,1;]"..
  293. "list[current_player;main;0,5;8,4;]"..
  294. "background[-0.5,-0.65;9,10.35;gui_brewerbg.png]"..
  295. "listcolors[#606060AA;#888;#141318;#30434C;#FFF]")
  296. return
  297. end
  298. local recipe = lottpotion.get_brew_recipe("brew", inv:get_list("src"))
  299. if not recipe then
  300. if was_active then
  301. meta:set_string("infotext", ("%s is empty"):format(machine_name))
  302. lottpotion.swap_node(pos, "lottpotion:brewer")
  303. meta:set_string("formspec", formspec)
  304. end
  305. return
  306. end
  307. local fuel = nil
  308. local afterfuel
  309. local fuellist = inv:get_list("fuel")
  310. if fuellist then
  311. fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
  312. end
  313. if fuel.time <= 0 then
  314. meta:set_string("infotext", ("%s Out Of Heat"):format(machine_name))
  315. lottpotion.swap_node(pos, "lottpotion:brewer")
  316. meta:set_string("formspec", formspec)
  317. return
  318. end
  319. meta:set_string("fuel_totaltime", fuel.time)
  320. meta:set_string("fuel_time", 0)
  321. inv:set_stack("fuel", 1, afterfuel.items[1])
  322. end,
  323. })