init.lua 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. wine = {}
  2. local path = minetest.get_modpath("wine")
  3. local def = minetest.get_modpath("default")
  4. local pipe = minetest.get_modpath("pipeworks")
  5. local snd_d = def and default.node_sound_defaults()
  6. local snd_g = def and default.node_sound_glass_defaults()
  7. local glass_item = def and "default:glass"
  8. local txt
  9. -- check for MineClone2
  10. local mcl = minetest.get_modpath("mcl_core")
  11. if mcl then
  12. snd_d = mcl_sounds.node_sound_glass_defaults()
  13. snd_g = mcl_sounds.node_sound_defaults()
  14. glass_item = "mcl_core:glass"
  15. end
  16. -- check for Unified Inventory
  17. local is_uninv = minetest.global_exists("unified_inventory") or false
  18. -- is thirsty mod active
  19. local thirsty_mod = minetest.get_modpath("thirsty")
  20. -- translation support
  21. local S
  22. if minetest.get_translator then
  23. S = minetest.get_translator("wine")
  24. elseif minetest.get_modpath("intllib") then
  25. S = intllib.Getter()
  26. else
  27. S = function(s, a, ...)
  28. if a == nil then
  29. return s
  30. end
  31. a = {a, ...}
  32. return s:gsub("(@?)@(%(?)(%d+)(%)?)", function(e, o, n, c)
  33. if e == ""then
  34. return a[tonumber(n)] .. (o == "" and c or "")
  35. else
  36. return "@" .. o .. n .. c
  37. end
  38. end)
  39. end
  40. end
  41. wine.S = S
  42. -- Unified Inventory hints
  43. if is_uninv then
  44. unified_inventory.register_craft_type("barrel", {
  45. description = "Barrel",
  46. icon = "wine_barrel.png",
  47. width = 2,
  48. height = 2
  49. })
  50. end
  51. -- fermentation list (drinks added in drinks.lua)
  52. local ferment = {}
  53. -- add item and resulting beverage to list
  54. function wine:add_item(list)
  55. for n = 1, #list do
  56. local item = list[n]
  57. -- change old string recipe item into table
  58. if type(item[1]) == "string" then
  59. item = { {item[1], "vessels:drinking_glass"}, item[2] }
  60. end
  61. table.insert(ferment, item)
  62. -- if ui mod found add recipe
  63. if is_uninv then
  64. unified_inventory.register_craft({
  65. type = "barrel",
  66. items = item[1],
  67. output = item[2]
  68. })
  69. end
  70. end
  71. end
  72. -- add drink with bottle
  73. function wine:add_drink(name, desc, has_bottle, num_hunger, num_thirst, alcoholic)
  74. -- glass
  75. minetest.register_node("wine:glass_" .. name, {
  76. description = S("Glass of " .. desc),
  77. drawtype = "plantlike",
  78. visual_scale = 0.5,
  79. tiles = {"wine_" .. name .. "_glass.png"},
  80. inventory_image = "wine_" .. name .. "_glass.png",
  81. wield_image = "wine_" .. name .. "_glass.png",
  82. paramtype = "light",
  83. is_ground_content = false,
  84. sunlight_propagates = true,
  85. walkable = false,
  86. selection_box = {
  87. type = "fixed",
  88. fixed = {-0.15, -0.5, -0.15, 0.15, 0, 0.15}
  89. },
  90. groups = {
  91. vessel = 1, dig_immediate = 3,
  92. attached_node = 1, drink = 1, alcohol = alcoholic
  93. },
  94. sounds = snd_g,
  95. on_use = function(itemstack, user, pointed_thing)
  96. if user then
  97. if thirsty_mod then
  98. thirsty.drink(user, num_thirst)
  99. end
  100. return minetest.do_item_eat(num_hunger, "vessels:drinking_glass",
  101. itemstack, user, pointed_thing)
  102. end
  103. end
  104. })
  105. -- bottle
  106. if has_bottle then
  107. minetest.register_node("wine:bottle_" .. name, {
  108. description = S("Bottle of " .. desc),
  109. drawtype = "plantlike",
  110. visual_scale = 0.7,
  111. tiles = {"wine_" .. name .. "_bottle.png"},
  112. inventory_image = "wine_" .. name .. "_bottle.png",
  113. paramtype = "light",
  114. sunlight_propagates = true,
  115. walkable = false,
  116. selection_box = {
  117. type = "fixed",
  118. fixed = {-0.15, -0.5, -0.15, 0.15, 0.25, 0.15}
  119. },
  120. groups = {dig_immediate = 3, attached_node = 1, vessel = 1},
  121. sounds = snd_d,
  122. })
  123. local glass = "wine:glass_" .. name
  124. minetest.register_craft({
  125. output = "wine:bottle_" .. name,
  126. recipe = {
  127. {glass, glass, glass},
  128. {glass, glass, glass},
  129. {glass, glass, glass}
  130. }
  131. })
  132. minetest.register_craft({
  133. output = glass .. " 9",
  134. recipe = {{"wine:bottle_" .. name}}
  135. })
  136. end
  137. end
  138. -- Wine barrel formspec
  139. local function winebarrel_formspec(item_percent, brewing, water_percent)
  140. local mcl_bg = mcl and "listcolors[#9d9d9d;#FFF7;#474747]" or ""
  141. return "size[8,9]" .. mcl_bg
  142. -- images
  143. .. "image[0,0;7,5;wine_barrel_fs_bg.png]"
  144. .. "image[5.88,1.8;1,1;wine_barrel_icon_bg.png^[lowpart:"
  145. .. item_percent .. ":wine_barrel_icon.png]"
  146. .. "image[1.04,2.7;4.45,1.65;wine_barrel_water.png"
  147. .. "^[colorize:#261c0e:175^[opacity:125"
  148. .. "^[lowpart:" .. water_percent .. ":wine_barrel_water.png]"
  149. -- inside barrel tinv
  150. .. "list[current_name;src;1.9,0.7;2,2;]"
  151. .. "list[current_name;src_b;2.4,2.95;1,1;0]"
  152. -- outside barrel inv
  153. .. "list[current_name;dst;7,1.8;1,1;]"
  154. .. "list[current_player;main;0,5;8,4;]"
  155. -- tooltips
  156. .. "tooltip[5.88,1.8;1,1;" .. brewing .. "]"
  157. .. "tooltip[1.05,2.7;3.495,1.45;" .. S("Water @1% Full", water_percent) .. "]"
  158. -- shift-click
  159. .. "listring[current_name;dst]"
  160. .. "listring[current_player;main]"
  161. .. "listring[current_name;src]"
  162. .. "listring[current_player;main]"
  163. end
  164. -- list of buckets used to fill barrel
  165. local bucket_list = {
  166. {"bucket:bucket_water", "bucket:bucket_empty", 20},
  167. {"bucket:bucket_river_water", "bucket:bucket_empty", 20},
  168. {"wooden_bucket:bucket_wood_water", "wooden_bucket:bucket_wood_empty", 20},
  169. {"wooden_bucket:bucket_wood_river_water", "wooden_bucket:bucket_wood_empty", 20},
  170. {"bucket_wooden:bucket_water", "bucket_wooden:bucket_empty", 20},
  171. {"bucket_wooden:bucket_river_water", "bucket_wooden:bucket_empty", 20},
  172. {"mcl_buckets:bucket_water", "mcl_buckets:bucket_empty", 20},
  173. {"farming:glass_water", "vessels:drinking_glass", 5}
  174. }
  175. -- water item helper
  176. local function water_check(item)
  177. for n = 1, #bucket_list do
  178. if bucket_list[n][1] == item then
  179. return bucket_list[n]
  180. end
  181. end
  182. end
  183. -- Wine barrel node
  184. minetest.register_node("wine:wine_barrel", {
  185. description = S("Fermenting Barrel"),
  186. tiles = {"wine_barrel.png" },
  187. drawtype = "mesh",
  188. mesh = "wine_barrel.obj",
  189. paramtype = "light",
  190. paramtype2 = "facedir",
  191. groups = {
  192. choppy = 2, oddly_breakable_by_hand = 1, flammable = 2,
  193. tubedevice = 1, tubedevice_receiver = 1, axey = 1
  194. },
  195. legacy_facedir_simple = true,
  196. on_place = minetest.rotate_node,
  197. on_construct = function(pos)
  198. local meta = minetest.get_meta(pos)
  199. meta:set_string("formspec", winebarrel_formspec(0, "", 0))
  200. meta:set_string("infotext", S("Fermenting Barrel"))
  201. meta:set_float("status", 0)
  202. local inv = meta:get_inventory()
  203. inv:set_size("src", 4) -- ingredients
  204. inv:set_size("src_b", 1) -- water bucket
  205. inv:set_size("dst", 1) -- brewed item
  206. end,
  207. -- punch old barrel to change to new 4x slot variant and add a little water
  208. on_punch = function(pos, node, puncher, pointed_thing)
  209. local meta = minetest.get_meta(pos)
  210. local inv = meta and meta:get_inventory()
  211. local size = inv and inv:get_size("src")
  212. if size and size < 4 then
  213. inv:set_size("src", 4)
  214. inv:set_size("src_b", 1)
  215. meta:set_int("water", 50)
  216. meta:set_string("formspec", winebarrel_formspec(0, "", 50))
  217. end
  218. end,
  219. can_dig = function(pos,player)
  220. local meta = minetest.get_meta(pos)
  221. local inv = meta:get_inventory()
  222. if not inv:is_empty("dst")
  223. or not inv:is_empty("src")
  224. or not inv:is_empty("src_b") then
  225. return false
  226. end
  227. return true
  228. end,
  229. allow_metadata_inventory_take = function(pos, listname, index, stack, player)
  230. if minetest.is_protected(pos, player:get_player_name()) then
  231. return 0
  232. end
  233. return stack:get_count()
  234. end,
  235. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  236. if minetest.is_protected(pos, player:get_player_name()) then
  237. return 0
  238. end
  239. local meta = minetest.get_meta(pos)
  240. local inv = meta:get_inventory()
  241. if listname == "src" then
  242. return stack:get_count()
  243. elseif listname == "src_b" then
  244. local water = meta:get_int("water")
  245. -- water full, return item
  246. if water == 100 then
  247. return 0
  248. end
  249. local is_bucket = stack:get_name()
  250. local is_water = water_check(is_bucket)
  251. if is_water then
  252. return stack:get_count()
  253. else
  254. return 0
  255. end
  256. elseif listname == "dst" then
  257. return 0
  258. end
  259. end,
  260. allow_metadata_inventory_move = function(
  261. pos, from_list, from_index, to_list, to_index, count, player)
  262. if minetest.is_protected(pos, player:get_player_name()) then
  263. return 0
  264. end
  265. local meta = minetest.get_meta(pos)
  266. local inv = meta:get_inventory()
  267. local stack = inv:get_stack(from_list, from_index)
  268. if to_list == "src" then
  269. return count
  270. elseif to_list == "dst" then
  271. return 0
  272. elseif to_list == "src_b" then
  273. return 0
  274. end
  275. end,
  276. on_metadata_inventory_put = function(pos, listname, index, stack, player)
  277. if listname == "src_b" then
  278. local meta = minetest.get_meta(pos)
  279. local inv = meta:get_inventory()
  280. local is_bucket = inv:get_stack("src_b", 1):get_name()
  281. local is_water = water_check(is_bucket)
  282. if is_water then
  283. local water = meta:get_int("water")
  284. local amount = tonumber(is_water[3]) or 0
  285. water = water + amount
  286. if water > 100 then water = 100 end
  287. inv:remove_item("src_b", is_water[1])
  288. inv:add_item("src_b", is_water[2])
  289. local status = meta:get_float("status")
  290. meta:set_int("water", water)
  291. meta:set_string("formspec",
  292. winebarrel_formspec(status, S("Water Added"), water))
  293. end
  294. end
  295. local timer = minetest.get_node_timer(pos)
  296. if not timer:is_started() then
  297. minetest.get_node_timer(pos):start(5)
  298. end
  299. end,
  300. on_metadata_inventory_move = function(pos)
  301. local timer = minetest.get_node_timer(pos)
  302. if not timer:is_started() then
  303. minetest.get_node_timer(pos):start(5)
  304. end
  305. end,
  306. on_metadata_inventory_take = function(pos)
  307. local timer = minetest.get_node_timer(pos)
  308. if not timer:is_started() then
  309. minetest.get_node_timer(pos):start(5)
  310. end
  311. end,
  312. pipe_connections = {
  313. left = 1, right = 1, front = 1, back = 1,
  314. left_param2 = 3, right_param2 = 1, front_param2 = 2, back_param2 = 0
  315. },
  316. after_dig_node = function(pos)
  317. if pipe then
  318. pipeworks.scan_for_pipe_objects(pos)
  319. end
  320. end,
  321. tube = (function() if pipe then return {
  322. -- using a different stack from defaut when inserting
  323. insert_object = function(pos, node, stack, direction)
  324. local meta = minetest.get_meta(pos)
  325. local inv = meta:get_inventory()
  326. local timer = minetest.get_node_timer(pos)
  327. if not timer:is_started() then
  328. timer:start(5)
  329. end
  330. return inv:add_item("src", stack)
  331. end,
  332. can_insert = function(pos, node, stack, direction)
  333. local meta = minetest.get_meta(pos)
  334. local inv = meta:get_inventory()
  335. return inv:room_for_item("src", stack)
  336. end,
  337. -- the default stack, from which objects will be taken
  338. input_inventory = "dst",
  339. connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
  340. } end end)(),
  341. on_timer = function(pos)
  342. local meta = minetest.get_meta(pos) ; if not meta then return end
  343. local inv = meta:get_inventory()
  344. local water = meta:get_int("water") or 0
  345. -- check for pipeworks water inlet
  346. if pipe then
  347. if minetest.find_node_near(pos, 1, pipeworks.pipes_full_nodenames) then
  348. water = water + 20
  349. if water > 100 then water = 100 end
  350. meta:set_int("water", water)
  351. end
  352. end
  353. -- is barrel empty?
  354. if not inv or inv:is_empty("src") then
  355. meta:set_float("status", 0)
  356. meta:set_string("infotext", S("Fermenting Barrel"))
  357. meta:set_string("formspec", winebarrel_formspec(0, "", water))
  358. return false
  359. end
  360. -- check water level
  361. if water < 5 then
  362. txt = S("Fermenting Barrel") .. " " .. S("(Water Level Low)")
  363. meta:set_string("infotext", txt)
  364. meta:set_float("status", 0)
  365. meta:set_string("formspec", winebarrel_formspec(0,
  366. S("(Water Level Low)"), water))
  367. return false
  368. end
  369. -- does it contain any of the source items on the list?
  370. local has_items, recipe, item1, item2, item3, item4
  371. for n = 1, #ferment do
  372. recipe = ferment[n]
  373. item1 = recipe[1][1] and ItemStack(recipe[1][1])
  374. item2 = recipe[1][2] and ItemStack(recipe[1][2])
  375. item3 = recipe[1][3] and ItemStack(recipe[1][3])
  376. item4 = recipe[1][4] and ItemStack(recipe[1][4])
  377. -- check for recipe items
  378. if item1 then
  379. has_items = inv:contains_item("src", item1)
  380. if has_items and item2 then
  381. has_items = inv:contains_item("src", item2)
  382. if has_items and item3 then
  383. has_items = inv:contains_item("src", item3)
  384. if has_items and item4 then
  385. has_items = inv:contains_item("src", item4)
  386. end
  387. end
  388. end
  389. end
  390. -- if we have all items in recipe break and continue
  391. if has_items then
  392. break
  393. end
  394. end
  395. -- if we have a wrong recipe change status
  396. if not has_items then
  397. txt = S("Fermenting Barrel") .. " " .. S("(No Valid Recipe)")
  398. meta:set_string("infotext", txt)
  399. meta:set_float("status", 0)
  400. meta:set_string("formspec",
  401. winebarrel_formspec(0, S("(No Valid Recipe)"), water))
  402. return false
  403. end
  404. -- is there room for additional fermentation?
  405. if not inv:room_for_item("dst", recipe[2]) then
  406. txt = S("Fermenting Barrel") .. " " .. S("(Output Full)")
  407. meta:set_string("infotext", txt)
  408. meta:set_string("formspec",
  409. winebarrel_formspec(0, S("(Output Full)"), water))
  410. return false
  411. end
  412. local status = meta:get_float("status")
  413. -- fermenting (change status)
  414. if status < 100 then
  415. txt = S("Fermenting Barrel") .. " " .. S("(@1% Done)", status)
  416. meta:set_string("infotext", txt)
  417. meta:set_float("status", status + 5)
  418. local d1 = recipe[2]:split(" ")[1]
  419. local desc = minetest.registered_items[d1].description or ""
  420. txt = S("Brewing: @1", desc) .. " " .. S("(@1% Done)", status)
  421. meta:set_string("formspec", winebarrel_formspec(status, txt, water))
  422. else -- when we hit 100% remove items needed and add beverage
  423. if item1 then inv:remove_item("src", item1) end
  424. if item2 then inv:remove_item("src", item2) end
  425. if item3 then inv:remove_item("src", item3) end
  426. if item4 then inv:remove_item("src", item4) end
  427. inv:add_item("dst", recipe[2])
  428. water = water - 5
  429. meta:set_float("status", 0)
  430. meta:set_int("water", water)
  431. meta:set_string("formspec", winebarrel_formspec(0, "", water))
  432. end
  433. if inv:is_empty("src") then
  434. meta:set_float("status", 0.0)
  435. meta:set_string("infotext", S("Fermenting Barrel"))
  436. end
  437. return true
  438. end
  439. })
  440. -- wine barrel craft recipe (with mineclone2 check)
  441. local ingot = mcl and "mcl_core:iron_ingot" or "default:steel_ingot"
  442. minetest.register_craft({
  443. output = "wine:wine_barrel",
  444. recipe = {
  445. {"group:wood", "group:wood", "group:wood"},
  446. {ingot, "", ingot},
  447. {"group:wood", "group:wood", "group:wood"}
  448. }
  449. })
  450. -- LBMs to start timers on existing, ABM-driven nodes
  451. minetest.register_lbm({
  452. name = "wine:barrel_timer_upgrade_init",
  453. label = "upgrade old barrels and start timers",
  454. nodenames = {"wine:wine_barrel"},
  455. run_at_every_load = false,
  456. action = function(pos)
  457. -- convert any old 2x slot barrels into new 4x slot ones and add a little water
  458. local meta = minetest.get_meta(pos)
  459. local inv = meta and meta:get_inventory()
  460. local size = inv and inv:get_size("src")
  461. if size and size < 4 then
  462. inv:set_size("src", 4)
  463. inv:set_size("src_b", 1)
  464. meta:set_int("water", 50)
  465. meta:set_string("formspec", winebarrel_formspec(0, "", 50))
  466. end
  467. -- Start barrel timer
  468. minetest.get_node_timer(pos):start(5)
  469. end
  470. })
  471. -- add agave plant and functions
  472. dofile(path .. "/agave.lua")
  473. -- add drink nodes and recipes
  474. dofile(path .. "/drinks.lua")
  475. -- add lucky blocks
  476. if minetest.get_modpath("lucky_block") then
  477. dofile(path .. "/lucky_block.lua")
  478. end
  479. -- mineclone2 doesn't have a drinking glass, so if none found add one
  480. if not minetest.registered_items["vessels:drinking_glass"] then
  481. minetest.register_node(":vessels:drinking_glass", {
  482. description = S("Empty Drinking Glass"),
  483. drawtype = "plantlike",
  484. tiles = {"wine_drinking_glass.png"},
  485. inventory_image = "wine_drinking_glass.png",
  486. wield_image = "wine_drinking_glass.png",
  487. paramtype = "light",
  488. is_ground_content = false,
  489. walkable = false,
  490. selection_box = {
  491. type = "fixed",
  492. fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25}
  493. },
  494. groups = {vessel = 1, dig_immediate = 3, attached_node = 1},
  495. sounds = snd_g,
  496. })
  497. minetest.register_craft( {
  498. output = "vessels:drinking_glass 14",
  499. recipe = {
  500. {glass_item, "" , glass_item},
  501. {glass_item, "" , glass_item},
  502. {glass_item, glass_item, glass_item}
  503. }
  504. })
  505. end
  506. -- sort ferment table to fix recipe overlap (large to small)
  507. minetest.after(0.2, function()
  508. local tmp = {}
  509. for l = 4, 1, -1 do
  510. for n = 1, #ferment do
  511. if #ferment[n][1] == l then
  512. table.insert(tmp, ferment[n])
  513. end
  514. end
  515. end
  516. ferment = tmp
  517. end)
  518. print ("[MOD] Wine loaded")