potionbrewing.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. -- Base Ingredients
  2. minetest.register_node("lottpotion:glass_bottle_mese", {
  3. description = "Glass Bottle (Mese Water)",
  4. drawtype = "plantlike",
  5. tiles = {"vessels_glass_bottle.png^lottpotion_water_mese.png"},
  6. inventory_image = "vessels_glass_bottle_inv.png^lottpotion_water_mese.png",
  7. wield_image = "vessels_glass_bottle_inv.png^lottpotion_water_mese.png",
  8. paramtype = "light",
  9. walkable = false,
  10. selection_box = {
  11. type = "fixed",
  12. fixed = {-0.25, -0.5, -0.25, 0.25, 0.4, 0.25}
  13. },
  14. groups = {vessel=1,dig_immediate=3,attached_node=1},
  15. sounds = default.node_sound_glass_defaults(),
  16. })
  17. minetest.register_node("lottpotion:glass_bottle_geodes", {
  18. description = "Glass Bottle (Geodes Crystal Water)",
  19. drawtype = "plantlike",
  20. tiles = {"vessels_glass_bottle.png^lottpotion_water_geodes.png"},
  21. inventory_image = "vessels_glass_bottle_inv.png^lottpotion_water_geodes.png",
  22. wield_image = "vessels_glass_bottle_inv.png^lottpotion_water_geodes.png",
  23. paramtype = "light",
  24. walkable = false,
  25. selection_box = {
  26. type = "fixed",
  27. fixed = {-0.25, -0.5, -0.25, 0.25, 0.4, 0.25}
  28. },
  29. groups = {vessel=1,dig_immediate=3,attached_node=1},
  30. sounds = default.node_sound_glass_defaults(),
  31. })
  32. minetest.register_node("lottpotion:glass_bottle_seregon", {
  33. description = "Glass Bottle (Seregon Water)",
  34. drawtype = "plantlike",
  35. tiles = {"vessels_glass_bottle.png^lottpotion_water_seregon.png"},
  36. inventory_image = "vessels_glass_bottle_inv.png^lottpotion_water_seregon.png",
  37. wield_image = "vessels_glass_bottle_inv.png^lottpotion_water_seregon.png",
  38. paramtype = "light",
  39. walkable = false,
  40. selection_box = {
  41. type = "fixed",
  42. fixed = {-0.25, -0.5, -0.25, 0.25, 0.4, 0.25}
  43. },
  44. groups = {vessel=1,dig_immediate=3,attached_node=1},
  45. sounds = default.node_sound_glass_defaults(),
  46. })
  47. minetest.register_craft({
  48. output = 'lottpotion:potion_brewer',
  49. recipe = {
  50. {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
  51. {'', 'default:steel_ingot', ''},
  52. {'group:stone', 'group:stone', 'group:stone'},
  53. }
  54. })
  55. lottpotion.potion_recipes = { cooking = { input_size = 1, output_size = 1 } }
  56. function lottpotion.register_recipe_type(typename, origdata)
  57. local data = {}
  58. for k, v in pairs(origdata) do data[k] = v end
  59. data.input_size = data.input_size or 1
  60. data.output_size = data.output_size or 1
  61. data.recipes = {}
  62. lottpotion.potion_recipes[typename] = data
  63. end
  64. local function get_recipe_index(items)
  65. local l = {}
  66. if items ~= nil then
  67. for i, stack in ipairs(items) do
  68. l[i] = ItemStack(stack):get_name()
  69. end
  70. end
  71. table.sort(l)
  72. return table.concat(l, "/")
  73. end
  74. local function register_recipe(typename, data)
  75. -- Handle aliases
  76. for i, stack in ipairs(data.input) do
  77. data.input[i] = ItemStack(stack):to_string()
  78. end
  79. if type(data.output) == "table" then
  80. for i, v in ipairs(data.output) do
  81. data.output[i] = ItemStack(data.output[i]):to_string()
  82. end
  83. else
  84. data.output = ItemStack(data.output):to_string()
  85. end
  86. local recipe = {time = data.time, input = {}, output = data.output}
  87. local index = get_recipe_index(data.input)
  88. for _, stack in ipairs(data.input) do
  89. recipe.input[ItemStack(stack):get_name()] = ItemStack(stack):get_count()
  90. end
  91. lottpotion.potion_recipes[typename].recipes[index] = recipe
  92. end
  93. function lottpotion.register_recipe(typename, data)
  94. minetest.after(0.01, register_recipe, typename, data) -- Handle aliases
  95. end
  96. function lottpotion.get_potion_recipe(typename, items)
  97. if typename == "cooking" then -- Already builtin in Minetest, so use that
  98. local result, new_input = minetest.get_craft_result({
  99. method = "cooking",
  100. width = 1,
  101. items = items})
  102. -- Compatibility layer
  103. if not result or result.time == 0 then
  104. return nil
  105. else
  106. return {time = result.time,
  107. new_input = new_input.items,
  108. output = result.item}
  109. end
  110. end
  111. local index = get_recipe_index(items)
  112. local recipe = lottpotion.potion_recipes[typename].recipes[index]
  113. if recipe then
  114. local new_input = {}
  115. for i, stack in ipairs(items) do
  116. if stack:get_count() < recipe.input[stack:get_name()] then
  117. return nil
  118. else
  119. new_input[i] = ItemStack(stack)
  120. new_input[i]:take_item(recipe.input[stack:get_name()])
  121. end
  122. end
  123. return {time = recipe.time,
  124. new_input = new_input,
  125. output = recipe.output}
  126. else
  127. return nil
  128. end
  129. end
  130. lottpotion.register_recipe_type("potionbrew", {
  131. description = "Potion Brewing",
  132. input_size = 2,
  133. })
  134. function lottpotion.register_potionbrew_recipe(data)
  135. data.time = data.time or 120
  136. lottpotion.register_recipe("potionbrew", data)
  137. end
  138. local recipes = {
  139. --Base Potion
  140. {"lottplants:seregon", "lottpotion:glass_bottle_water", "lottpotion:glass_bottle_seregon"},
  141. {"default:mese_crystal_fragment 1", "lottpotion:glass_bottle_water", "lottpotion:glass_bottle_mese"},
  142. {"lottores:geodes_crystal_1", "lottpotion:glass_bottle_water", "lottpotion:glass_bottle_geodes"},
  143. --Potions
  144. --Orc Draught
  145. {"lottmobs:meat_raw 5", "lottpotion:glass_bottle_seregon", "lottpotion:orcdraught_power1"},
  146. {"lottmobs:meat_raw 5", "lottpotion:orcdraught_power1", "lottpotion:orcdraught_power2", 180},
  147. {"lottmobs:meat_raw 5", "lottpotion:orcdraught_power2", "lottpotion:orcdraught_power3", 240},
  148. --Spider Poison
  149. {"lottmobs:spiderpoison 2", "lottpotion:glass_bottle_seregon", "lottpotion:spiderpoison_power1"},
  150. {"lottmobs:spiderpoison 2", "lottpotion:spiderpoison_power1", "lottpotion:spiderpoison_power2", 180},
  151. {"lottmobs:spiderpoison 2", "lottpotion:spiderpoison_power2", "lottpotion:spiderpoison_power3", 240},
  152. --Limpe
  153. {"lottplants:yavannamireleaf 10", "lottpotion:glass_bottle_mese", "lottpotion:limpe_power1"},
  154. {"lottplants:yavannamireleaf 10", "lottpotion:limpe_power1", "lottpotion:limpe_power2", 180},
  155. {"lottplants:yavannamireleaf 10", "lottpotion:limpe_power2", "lottpotion:limpe_power3", 240},
  156. --Miruvor
  157. {"lottplants:yavannamirefruit 2", "lottpotion:glass_bottle_mese", "lottpotion:miruvor_power1"},
  158. {"lottplants:yavannamirefruit 2", "lottpotion:miruvor_power1", "lottpotion:miruvor_power2", 180},
  159. {"lottplants:yavannamirefruit 2", "lottpotion:miruvor_power2", "lottpotion:miruvor_power3", 240},
  160. --Athelas Brew
  161. {"lottfarming:athelas 3", "lottpotion:glass_bottle_geodes", "lottpotion:athelasbrew_power1"},
  162. {"lottfarming:athelas 3", "lottpotion:athelasbrew_power1", "lottpotion:athelasbrew_power2", 180},
  163. {"lottfarming:athelas 3", "lottpotion:athelasbrew_power2", "lottpotion:athelasbrew_power3", 240},
  164. --Ent Draught
  165. {"default:leaves 10", "lottpotion:glass_bottle_geodes", "lottpotion:entdraught_power1"},
  166. {"default:leaves 10", "lottpotion:entdraught_power1", "lottpotion:entdraught_power2", 120},
  167. {"default:leaves 10", "lottpotion:entdraught_power2", "lottpotion:entdraught_power3", 240},
  168. }
  169. for _, data in pairs(recipes) do
  170. lottpotion.register_potionbrew_recipe({input = {data[1], data[2]}, output = data[3], time = data[4]})
  171. end
  172. local machine_name = "Potion Brewer"
  173. local formspec =
  174. "size[8,9]"..
  175. "label[0,0;"..machine_name.."]"..
  176. "image[4,2;1,1;lottpotion_bubble_off.png]"..
  177. "image[3,2;1,1;lottpotion_arrow.png]"..
  178. "image[5,2;1,1;lottpotion_arrow.png]"..
  179. "label[3.2,3.2;Fuel:]"..
  180. "list[current_name;fuel;4,3;1,1;]"..
  181. "label[1,1.5;Ingredients:]"..
  182. "list[current_name;src;1,2;2,1;]"..
  183. "label[6,1.5;Result:]"..
  184. "list[current_name;dst;6,2;1,1;]"..
  185. "listring[current_name;src]"..
  186. "listring[current_player;main]"..
  187. "list[current_player;main;0,5;8,4;]"
  188. minetest.register_node("lottpotion:potion_brewer", {
  189. description = machine_name,
  190. drawtype = "plantlike",
  191. visual_scale = 1.0,
  192. tiles = {"lottpotion_potion_brewer.png"},
  193. paramtype = "light",
  194. sounds = default.node_sound_stone_defaults(),
  195. selection_box = {
  196. type = "fixed",
  197. fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
  198. },
  199. groups = {cracky=2},
  200. sounds = default.node_sound_stone_defaults(),
  201. on_construct = function(pos)
  202. local meta = minetest.get_meta(pos)
  203. meta:set_string("formspec", formspec)
  204. meta:set_string("infotext", machine_name)
  205. local inv = meta:get_inventory()
  206. inv:set_size("fuel", 1)
  207. inv:set_size("src", 2)
  208. inv:set_size("dst", 1)
  209. end,
  210. can_dig = lottpotion.can_dig,
  211. })
  212. minetest.register_node("lottpotion:potion_brewer_active", {
  213. description = machine_name,
  214. drawtype = "plantlike",
  215. visual_scale = 1.0,
  216. tiles = {"lottpotion_potion_brewer_active.png"},
  217. paramtype = "light",
  218. light_source = 8,
  219. selection_box = {
  220. type = "fixed",
  221. fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
  222. },
  223. drop = "lottpotion:potion_brewer",
  224. groups = {cracky=2, not_in_creative_inventory=1},
  225. sounds = default.node_sound_stone_defaults(),
  226. can_dig = lottpotion.can_dig,
  227. })
  228. minetest.register_abm({
  229. nodenames = {"lottpotion:potion_brewer", "lottpotion:potion_brewer_active"},
  230. interval = 1,
  231. chance = 1,
  232. action = function(pos, node, active_object_count, active_object_count_wider)
  233. local meta = minetest.get_meta(pos)
  234. local inv = meta:get_inventory()
  235. if meta:get_string("infotext") == "" then
  236. local meta = minetest.get_meta(pos)
  237. meta:set_string("formspec", formspec)
  238. meta:set_string("infotext", machine_name)
  239. local inv = meta:get_inventory()
  240. inv:set_size("fuel", 1)
  241. inv:set_size("src", 2)
  242. inv:set_size("dst", 1)
  243. end
  244. if inv:get_size("src") == 1 then -- Old furnace -> convert it
  245. inv:set_size("src", 2)
  246. inv:set_stack("src", 2, inv:get_stack("src2", 1))
  247. inv:set_size("src2", 0)
  248. end
  249. local recipe = nil
  250. for i, name in pairs({
  251. "fuel_totaltime",
  252. "fuel_time",
  253. "src_totaltime",
  254. "src_time"}) do
  255. if not meta:get_float(name) then
  256. meta:set_float(name, 0.0)
  257. end
  258. end
  259. local result = lottpotion.get_potion_recipe("potionbrew", inv:get_list("src"))
  260. local was_active = false
  261. if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
  262. was_active = true
  263. meta:set_int("fuel_time", meta:get_int("fuel_time") + 1)
  264. if result then
  265. meta:set_int("src_time", meta:get_int("src_time") + 1)
  266. if meta:get_int("src_time") >= result.time then
  267. meta:set_int("src_time", 0)
  268. local result_stack = ItemStack(result.output)
  269. if inv:room_for_item("dst", result_stack) then
  270. inv:set_list("src", result.new_input)
  271. inv:add_item("dst", result_stack)
  272. end
  273. end
  274. else
  275. meta:set_int("src_time", 0)
  276. end
  277. end
  278. if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
  279. local percent = math.floor(meta:get_float("fuel_time") /
  280. meta:get_float("fuel_totaltime") * 100)
  281. meta:set_string("infotext", ("%s Brewing"):format(machine_name).." ("..percent.."%)")
  282. lottpotion.swap_node(pos, "lottpotion:potion_brewer_active")
  283. meta:set_string("formspec",
  284. "size[8,9]"..
  285. "label[0,0;"..machine_name.."]"..
  286. "image[4,2;1,1;lottpotion_bubble_off.png^[lowpart:"..
  287. (percent)..":lottpotion_bubble.png]"..
  288. "image[3,2;1,1;lottpotion_arrow.png]"..
  289. "image[5,2;1,1;lottpotion_arrow.png]"..
  290. "label[3.2,3.2;Fuel:]"..
  291. "list[current_name;fuel;4,3;1,1;]"..
  292. "label[1,1.5;Ingredients:]"..
  293. "list[current_name;src;1,2;2,1;]"..
  294. "label[6,1.5;Result:]"..
  295. "list[current_name;dst;6,2;1,1;]"..
  296. "list[current_player;main;0,5;8,4;]")
  297. return
  298. end
  299. local recipe = lottpotion.get_potion_recipe("potionbrew", inv:get_list("src"))
  300. if not recipe then
  301. if was_active then
  302. meta:set_string("infotext", ("%s is empty"):format(machine_name))
  303. lottpotion.swap_node(pos, "lottpotion:potion_brewer")
  304. meta:set_string("formspec", formspec)
  305. end
  306. return
  307. end
  308. if not inv:room_for_item("dst", ItemStack(result.output)) then
  309. meta:set_string("infotext", ("%s Out Of Heat"):format(machine_name))
  310. lottpotion.swap_node(pos, "lottpotion:potion_brewer")
  311. meta:set_string("formspec", formspec)
  312. return
  313. end
  314. local fuel = nil
  315. local afterfuel
  316. local fuellist = inv:get_list("fuel")
  317. if fuellist then
  318. fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
  319. end
  320. if fuel.time <= 0 then
  321. meta:set_string("infotext", ("%s Out Of Heat"):format(machine_name))
  322. lottpotion.swap_node(pos, "lottpotion:potion_brewer")
  323. meta:set_string("formspec", formspec)
  324. return
  325. end
  326. meta:set_string("fuel_totaltime", fuel.time)
  327. meta:set_string("fuel_time", 0)
  328. inv:set_stack("fuel", 1, afterfuel.items[1])
  329. end,
  330. })