init.lua 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. wine = {}
  2. local def = minetest.get_modpath("default")
  3. local snd_d = def and default.node_sound_defaults()
  4. local snd_g = def and default.node_sound_glass_defaults()
  5. local snd_l = def and default.node_sound_leaves_defaults()
  6. local sand = "default:desert_sand"
  7. -- check for MineClone2
  8. local mcl = minetest.get_modpath("mcl_core")
  9. if mcl then
  10. snd_d = mcl_sounds.node_sound_glass_defaults()
  11. snd_g = mcl_sounds.node_sound_defaults()
  12. snd_l = mcl_sounds.node_sound_leaves_defaults()
  13. sand = "mcl_core:sand"
  14. end
  15. -- check for Unified Inventory
  16. local is_uninv = minetest.global_exists("unified_inventory") or false
  17. -- is thirsty mod active
  18. local thirsty_mod = minetest.get_modpath("thirsty")
  19. -- Intllib support
  20. local S
  21. if minetest.get_translator then
  22. S = minetest.get_translator("wine")
  23. elseif minetest.get_modpath("intllib") then
  24. S = intllib.Getter()
  25. else
  26. S = function(s, a, ...)
  27. if a == nil then
  28. return s
  29. end
  30. a = {a, ...}
  31. return s:gsub("(@?)@(%(?)(%d+)(%)?)",
  32. 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. -- Unified Inventory hints
  42. if is_uninv then
  43. unified_inventory.register_craft_type("barrel", {
  44. description = "Barrel",
  45. icon = 'wine_barrel.png',
  46. width = 1,
  47. height = 1
  48. })
  49. end
  50. local ferment = {
  51. {"farming:grapes", "wine:glass_wine"},
  52. {"farming:barley", "wine:glass_beer"},
  53. {"mobs:honey", "wine:glass_mead"},
  54. {"xdecor:honey", "wine:glass_mead"}, -- for when xdcecor is installed
  55. {"default:apple", "wine:glass_cider"},
  56. {"default:papyrus", "wine:glass_rum"},
  57. {"wine:blue_agave", "wine:glass_tequila"},
  58. {"farming:wheat", "wine:glass_wheat_beer"},
  59. {"farming:rice", "wine:glass_sake"},
  60. {"farming:corn", "wine:glass_bourbon"},
  61. {"farming:baked_potato", "wine:glass_vodka"},
  62. {"farming:coffee_beans", "wine:glass_coffee_liquor"},
  63. {"wine:glass_champagne_raw", "wine:glass_champagne"}
  64. }
  65. if mcl then
  66. ferment[4] = {"mcl_core:apple", "wine:glass_cider"}
  67. ferment[5] = {"mcl_core:paper", "wine:glass_rum"}
  68. end
  69. if is_uninv then
  70. for _, f in pairs(ferment) do
  71. unified_inventory.register_craft({
  72. type = "barrel",
  73. items = {f[1]},
  74. output = f[2]
  75. })
  76. end
  77. end
  78. -- add item and resulting beverage to list
  79. function wine:add_item(list)
  80. for n = 1, #list do
  81. table.insert(ferment, list[n])
  82. if is_uninv then
  83. unified_inventory.register_craft({
  84. type = "barrel",
  85. items = {list[n][1]},
  86. output = list[n][2]
  87. })
  88. end
  89. end
  90. end
  91. -- list of beverages (name, desc, has bottle, hunger, thirst)
  92. local beverages = {
  93. {"wine", "Wine", true, 2, 5},
  94. {"beer", "Beer", true, 2, 8},
  95. {"rum", "Rum", true, 2, 5},
  96. {"tequila", "Tequila", true, 2, 3},
  97. {"wheat_beer", "Wheat Beer", true, 2, 8},
  98. {"sake", "Sake", true, 2, 3},
  99. {"bourbon", "Bourbon", true, 2, 3},
  100. {"vodka", "Vodka", true, 2, 3},
  101. {"cider", "Cider", true, 2, 6},
  102. {"mead", "Honey-Mead", true, 4, 5},
  103. {"mint", "Mint Julep", true, 4, 3},
  104. {"brandy", "Brandy", true, 3, 4},
  105. {"coffee_liquor", "Coffee Liquor", true, 3, 4},
  106. {"champagne", "Champagne", true, 4, 5}
  107. }
  108. -- create glasses and bottles
  109. for n = 1, #beverages do
  110. local name = beverages[n][1]
  111. local desc = beverages[n][2]
  112. local has_bottle = beverages[n][3]
  113. local num_hunger = beverages[n][4]
  114. local num_thirst = beverages[n][5]
  115. -- glass
  116. minetest.register_node("wine:glass_" .. name, {
  117. description = S("Glass of " .. desc),
  118. drawtype = "plantlike",
  119. visual_scale = 0.5,
  120. tiles = {"wine_" .. name .. "_glass.png"},
  121. inventory_image = "wine_" .. name .. "_glass.png",
  122. wield_image = "wine_" .. name .. "_glass.png",
  123. paramtype = "light",
  124. is_ground_content = false,
  125. sunlight_propagates = true,
  126. walkable = false,
  127. selection_box = {
  128. type = "fixed",
  129. fixed = {-0.15, -0.5, -0.15, 0.15, 0, 0.15}
  130. },
  131. groups = {
  132. vessel = 1, dig_immediate = 3,
  133. attached_node = 1, alcohol = 1, drink = 1
  134. },
  135. sounds = snd_g,
  136. on_use = function(itemstack, user, pointed_thing)
  137. if user then
  138. if thirsty_mod then
  139. thirsty.drink(user, num_thirst)
  140. end
  141. return minetest.do_item_eat(num_hunger, nil,
  142. itemstack, user, pointed_thing)
  143. end
  144. end
  145. })
  146. -- bottle
  147. if has_bottle then
  148. minetest.register_node("wine:bottle_" .. name, {
  149. description = S("Bottle of " .. desc),
  150. drawtype = "plantlike",
  151. visual_scale = 0.7,
  152. tiles = {"wine_" .. name .. "_bottle.png"},
  153. inventory_image = "wine_" .. name .. "_bottle.png",
  154. paramtype = "light",
  155. sunlight_propagates = true,
  156. walkable = false,
  157. selection_box = {
  158. type = "fixed",
  159. fixed = {-0.15, -0.5, -0.15, 0.15, 0.25, 0.15}
  160. },
  161. groups = {dig_immediate = 3, attached_node = 1, vessel = 1},
  162. sounds = snd_d,
  163. })
  164. local glass = "wine:glass_" .. name
  165. minetest.register_craft({
  166. output = "wine:bottle_" .. name,
  167. recipe = {
  168. {glass, glass, glass},
  169. {glass, glass, glass},
  170. {glass, glass, glass},
  171. },
  172. })
  173. minetest.register_craft({
  174. -- type = "shapeless",
  175. output = glass .. " 9",
  176. recipe = {{"wine:bottle_" .. name}}
  177. })
  178. end
  179. end
  180. -- brandy recipe
  181. minetest.register_craft({
  182. type = "cooking",
  183. cooktime = 15,
  184. output = "wine:glass_brandy",
  185. recipe = "wine:glass_wine"
  186. })
  187. -- Raw champagne
  188. if minetest.get_modpath("farming")
  189. and farming.mod and (farming.mod == "undo" or farming.mod == "redo") then
  190. minetest.register_craftitem("wine:glass_champagne_raw", {
  191. description = "Raw Champagne",
  192. inventory_image = "wine_champagne_raw_glass.png",
  193. groups = {vessel = 1, flammable = 3}
  194. })
  195. minetest.register_craft({
  196. -- type = "shapeless",
  197. output = "wine:glass_champagne_raw",
  198. recipe = {
  199. {"wine:glass_wine", "farming:sugar"}
  200. }
  201. })
  202. end
  203. -- override to add food group to wine and brandy glass
  204. minetest.override_item("wine:glass_wine", {
  205. groups = {
  206. food_wine = 1, vessel = 1, dig_immediate = 3,
  207. attached_node = 1, alcohol = 1, drink = 1
  208. }
  209. })
  210. minetest.override_item("wine:glass_brandy", {
  211. groups = {
  212. food_brandy = 1, vessel = 1, dig_immediate = 3,
  213. attached_node = 1, alcohol = 1, drink = 1
  214. }
  215. })
  216. -- blue agave
  217. minetest.register_node("wine:blue_agave", {
  218. description = S("Blue Agave"),
  219. drawtype = "plantlike",
  220. visual_scale = 0.8,
  221. tiles = {"wine_blue_agave.png"},
  222. inventory_image = "wine_blue_agave.png",
  223. wield_image = "wine_blue_agave.png",
  224. paramtype = "light",
  225. is_ground_content = false,
  226. sunlight_propagates = true,
  227. walkable = false,
  228. selection_box = {
  229. type = "fixed",
  230. fixed = {-0.2, -0.5, -0.2, 0.2, 0.3, 0.2}
  231. },
  232. groups = {snappy = 3, attached_node = 1, plant = 1},
  233. sounds = snd_l,
  234. on_use = minetest.item_eat(2),
  235. on_construct = function(pos)
  236. local timer = minetest.get_node_timer(pos)
  237. timer:start(17)
  238. end,
  239. on_timer = function(pos)
  240. local light = minetest.get_node_light(pos)
  241. if not light or light < 13 or math.random() > 1/76 then
  242. return true -- go to next iteration
  243. end
  244. local n = minetest.find_nodes_in_area_under_air(
  245. {x = pos.x + 2, y = pos.y + 1, z = pos.z + 2},
  246. {x = pos.x - 2, y = pos.y - 1, z = pos.z - 2},
  247. {"wine:blue_agave"})
  248. -- too crowded, we'll wait for another iteration
  249. if #n > 2 then
  250. return true
  251. end
  252. -- find desert sand with air above (grow across and down only)
  253. n = minetest.find_nodes_in_area_under_air(
  254. {x = pos.x + 1, y = pos.y - 1, z = pos.z + 1},
  255. {x = pos.x - 1, y = pos.y - 2, z = pos.z - 1},
  256. {sand})
  257. -- place blue agave
  258. if n and #n > 0 then
  259. local new_pos = n[math.random(#n)]
  260. new_pos.y = new_pos.y + 1
  261. minetest.set_node(new_pos, {name = "wine:blue_agave"})
  262. end
  263. return true
  264. end
  265. })
  266. -- blue agave into cyan dye
  267. minetest.register_craft( {
  268. -- type = "shapeless",
  269. output = "dye:cyan 4",
  270. recipe = {{"wine:blue_agave"}}
  271. })
  272. -- blue agave as fuel
  273. minetest.register_craft({
  274. type = "fuel",
  275. recipe = "wine:blue_agave",
  276. burntime = 10,
  277. })
  278. -- cook blue agave into a sugar syrup
  279. minetest.register_craftitem("wine:agave_syrup", {
  280. description = "Agave Syrup",
  281. inventory_image = "wine_agave_syrup.png",
  282. groups = {food_sugar = 1, vessel = 1, flammable = 3}
  283. })
  284. minetest.register_craft({
  285. type = "cooking",
  286. cooktime = 7,
  287. output = "wine:agave_syrup 2",
  288. recipe = "wine:blue_agave"
  289. })
  290. -- blue agave into paper
  291. minetest.register_craft( {
  292. output = "default:paper 3",
  293. recipe = {
  294. {"wine:blue_agave", "wine:blue_agave", "wine:blue_agave"},
  295. }
  296. })
  297. -- register blue agave on mapgen
  298. minetest.register_decoration({
  299. deco_type = "simple",
  300. place_on = {sand},
  301. sidelen = 16,
  302. fill_ratio = 0.001,
  303. biomes = {"desert"},
  304. decoration = {"wine:blue_agave"},
  305. y_min = 15,
  306. y_max = 50,
  307. spawn_by = sand,
  308. num_spawn_by = 6
  309. })
  310. -- add to bonemeal as decoration if available
  311. if minetest.get_modpath("bonemeal") then
  312. bonemeal:add_deco({
  313. {sand, {}, {"default:dry_shrub", "wine:blue_agave", "", ""} }
  314. })
  315. end
  316. -- Mint Julep recipe
  317. if minetest.get_modpath("farming")
  318. and farming.mod and (farming.mod == "redo" or farming.mod == "undo") then
  319. minetest.register_craft({
  320. -- type = "shapeless",
  321. output = "wine:glass_mint",
  322. recipe = {
  323. {"farming:mint_leaf", "farming:mint_leaf", "farming:mint_leaf"},
  324. {"wine:glass_bourbon", "farming:sugar", ""}
  325. }
  326. })
  327. end
  328. -- Wine barrel formspec
  329. winebarrel_formspec = "size[8,9]"
  330. .. "list[current_name;src;2,1;1,1;]"
  331. .. "list[current_name;dst;5,1;1,1;]"
  332. .. "list[current_player;main;0,5;8,4;]"
  333. .. "listring[current_name;dst]"
  334. .. "listring[current_player;main]"
  335. .. "listring[current_name;src]"
  336. .. "listring[current_player;main]"
  337. .. "image[3.5,1;1,1;gui_furnace_arrow_bg.png^[transformR270]"
  338. -- Wine barrel node
  339. minetest.register_node("wine:wine_barrel", {
  340. description = S("Fermenting Barrel"),
  341. tiles = {"wine_barrel.png" },
  342. drawtype = "mesh",
  343. mesh = "wine_barrel.obj",
  344. paramtype = "light",
  345. paramtype2 = "facedir",
  346. groups = {
  347. choppy = 2, oddly_breakable_by_hand = 1, flammable = 2,
  348. tubedevice = 1, tubedevice_receiver = 1
  349. },
  350. legacy_facedir_simple = true,
  351. on_place = minetest.rotate_node,
  352. on_construct = function(pos)
  353. local meta = minetest.get_meta(pos)
  354. meta:set_string("formspec", winebarrel_formspec)
  355. meta:set_string("infotext", S("Fermenting Barrel"))
  356. meta:set_float("status", 0.0)
  357. local inv = meta:get_inventory()
  358. inv:set_size("src", 1)
  359. inv:set_size("dst", 1)
  360. end,
  361. can_dig = function(pos,player)
  362. local meta = minetest.get_meta(pos)
  363. local inv = meta:get_inventory()
  364. if not inv:is_empty("dst")
  365. or not inv:is_empty("src") then
  366. return false
  367. end
  368. return true
  369. end,
  370. allow_metadata_inventory_take = function(
  371. pos, listname, index, stack, player)
  372. if minetest.is_protected(pos, player:get_player_name()) then
  373. return 0
  374. end
  375. return stack:get_count()
  376. end,
  377. allow_metadata_inventory_put = function(
  378. pos, listname, index, stack, player)
  379. if minetest.is_protected(pos, player:get_player_name()) then
  380. return 0
  381. end
  382. local meta = minetest.get_meta(pos)
  383. local inv = meta:get_inventory()
  384. if listname == "src" then
  385. return stack:get_count()
  386. elseif listname == "dst" then
  387. return 0
  388. end
  389. end,
  390. allow_metadata_inventory_move = function(
  391. pos, from_list, from_index, to_list, to_index, count, player)
  392. if minetest.is_protected(pos, player:get_player_name()) then
  393. return 0
  394. end
  395. local meta = minetest.get_meta(pos)
  396. local inv = meta:get_inventory()
  397. local stack = inv:get_stack(from_list, from_index)
  398. if to_list == "src" then
  399. return count
  400. elseif to_list == "dst" then
  401. return 0
  402. end
  403. end,
  404. on_metadata_inventory_put = function(pos)
  405. local timer = minetest.get_node_timer(pos)
  406. timer:start(5)
  407. end,
  408. tube = (function() if minetest.get_modpath("pipeworks") then return {
  409. -- using a different stack from defaut when inserting
  410. insert_object = function(pos, node, stack, direction)
  411. local meta = minetest.get_meta(pos)
  412. local inv = meta:get_inventory()
  413. local timer = minetest.get_node_timer(pos)
  414. if not timer:is_started() then
  415. timer:start(5)
  416. end
  417. return inv:add_item("src", stack)
  418. end,
  419. can_insert = function(pos,node,stack,direction)
  420. local meta = minetest.get_meta(pos)
  421. local inv = meta:get_inventory()
  422. return inv:room_for_item("src", stack)
  423. end,
  424. -- the default stack, from which objects will be taken
  425. input_inventory = "dst",
  426. connect_sides = {
  427. left = 1, right = 1, back = 1,
  428. front = 1, bottom = 1, top = 1} } end end)(),
  429. on_timer = function(pos)
  430. local meta = minetest.get_meta(pos) ; if not meta then return end
  431. local inv = meta:get_inventory()
  432. -- is barrel empty?
  433. if not inv or inv:is_empty("src") then
  434. meta:set_float("status", 0.0)
  435. meta:set_string("infotext", S("Fermenting Barrel"))
  436. return false
  437. end
  438. -- does it contain any of the source items on the list?
  439. local has_item
  440. for n = 1, #ferment do
  441. if inv:contains_item("src", ItemStack(ferment[n][1])) then
  442. has_item = n
  443. break
  444. end
  445. end
  446. if not has_item then
  447. return false
  448. end
  449. -- is there room for additional fermentation?
  450. if not inv:room_for_item("dst", ferment[has_item][2]) then
  451. meta:set_string("infotext", S("Fermenting Barrel (FULL)"))
  452. return true
  453. end
  454. local status = meta:get_float("status")
  455. -- fermenting (change status)
  456. if status < 100 then
  457. meta:set_string("infotext", S("Fermenting Barrel (@1% Done)", status))
  458. meta:set_float("status", status + 5)
  459. else
  460. inv:remove_item("src", ferment[has_item][1])
  461. inv:add_item("dst", ferment[has_item][2])
  462. meta:set_float("status", 0,0)
  463. end
  464. if inv:is_empty("src") then
  465. meta:set_float("status", 0.0)
  466. meta:set_string("infotext", S("Fermenting Barrel"))
  467. end
  468. return true
  469. end
  470. })
  471. -- wine barrel craft recipe (with mineclone2 check)
  472. local ingot = "default:steel_ingot"
  473. if mcl then
  474. ingot = "mcl_core:iron_ingot"
  475. end
  476. minetest.register_craft({
  477. output = "wine:wine_barrel",
  478. recipe = {
  479. {"group:wood", "group:wood", "group:wood"},
  480. {ingot, "", ingot},
  481. {"group:wood", "group:wood", "group:wood"},
  482. },
  483. })
  484. -- LBMs to start timers on existing, ABM-driven nodes
  485. minetest.register_lbm({
  486. name = "wine:barrel_timer_init",
  487. nodenames = {"wine:wine_barrel"},
  488. run_at_every_load = false,
  489. action = function(pos)
  490. local t = minetest.get_node_timer(pos)
  491. t:start(5)
  492. end,
  493. })
  494. minetest.register_lbm({
  495. name = "wine:agave_timer_init",
  496. nodenames = {"wine:blue_agave"},
  497. run_at_every_load = false,
  498. action = function(pos)
  499. local t = minetest.get_node_timer(pos)
  500. t:start(17)
  501. end,
  502. })
  503. -- add lucky blocks
  504. if minetest.get_modpath("lucky_block") then
  505. lucky_block:add_blocks({
  506. {"fal", {"default:water_source"}, 1, true, 4},
  507. {"dro", {"wine:glass_wine"}, 5},
  508. {"dro", {"wine:glass_beer"}, 5},
  509. {"dro", {"wine:glass_wheat_beer"}, 5},
  510. {"dro", {"wine:glass_mead"}, 5},
  511. {"dro", {"wine:glass_cider"}, 5},
  512. {"dro", {"wine:glass_rum"}, 5},
  513. {"dro", {"wine:glass_sake"}, 5},
  514. {"dro", {"wine:glass_tequila"}, 5},
  515. {"dro", {"wine:glass_bourbon"}, 5},
  516. {"dro", {"wine:glass_vodka"}, 5},
  517. {"dro", {"wine:glass_mint"}, 5},
  518. {"dro", {"wine:glass_coffee_liquor"}, 5},
  519. {"dro", {"wine:glass_brandy"}, 5},
  520. {"dro", {"wine:glass_champagne"}, 5},
  521. {"dro", {"wine:wine_barrel"}, 1},
  522. {"tel", 5, 1},
  523. {"nod", "default:chest", 0, {
  524. {name = "wine:bottle_wine", max = 1},
  525. {name = "wine:bottle_tequila", max = 1},
  526. {name = "wine:bottle_rum", max = 1},
  527. {name = "wine:bottle_cider", max = 1},
  528. {name = "wine:bottle_bourbon", max = 1},
  529. {name = "wine:bottle_vodka", max = 1},
  530. {name = "wine:wine_barrel", max = 1},
  531. {name = "wine:bottle_sake", max = 1},
  532. {name = "wine:bottle_mint", max = 1},
  533. {name = "wine:bottle_mead", max = 1},
  534. {name = "wine:bottle_beer", max = 1},
  535. {name = "wine:bottle_wheat_beer", max = 1},
  536. {name = "wine:bottle_coffee_liquor", max = 1},
  537. {name = "wine:bottle_brandy", max = 1},
  538. {name = "wine:bottle_champagne", max = 1},
  539. {name = "wine:blue_agave", max = 4}}},
  540. })
  541. end
  542. print (S("[MOD] Wine loaded"))