init.lua 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246
  1. -- Mod: BEES
  2. -- Author: Bas080 (Tweaked by TenPlus1)
  3. -- License: MIT
  4. -- Intllib support
  5. local S
  6. if minetest.get_translator then
  7. S = minetest.get_translator("bees")
  8. elseif minetest.global_exists("intllib") then
  9. S = intllib.Getter()
  10. else
  11. S = function(s) return s end
  12. end
  13. -- FUNCTIONS
  14. local floor = math.floor
  15. local random = math.random
  16. local hive_wild = function(pos, grafting)
  17. local spos = pos.x .. "," .. pos.y .. "," ..pos.z
  18. local formspec = "size[8,9]"
  19. .. "list[nodemeta:".. spos .. ";combs;1.5,3;5,1;]"
  20. .. "list[current_player;main;0,5;8,4;]"
  21. if grafting then
  22. formspec = formspec .."list[nodemeta:".. spos .. ";queen;3.5,1;1,1;]"
  23. end
  24. return formspec
  25. end
  26. local hive_artificial = function(pos)
  27. local spos = pos.x..","..pos.y..","..pos.z
  28. local formspec = "size[8,9]"
  29. .. "list[nodemeta:"..spos..";queen;3.5,1;1,1;]"
  30. .. "list[nodemeta:"..spos..";frames;0,3;8,1;]"
  31. .. "list[current_player;main;0,5;8,4;]"
  32. return formspec
  33. end
  34. local polinate_flower = function(pos, flower)
  35. local spawn_pos = {
  36. x = pos.x + random(-3, 3),
  37. y = pos.y + random(-3, 3),
  38. z = pos.z + random(-3, 3)
  39. }
  40. local floor_pos = {x = spawn_pos.x, y = spawn_pos.y - 1, z = spawn_pos.z}
  41. local spawn = minetest.get_node(spawn_pos).name
  42. local floor = minetest.get_node(floor_pos).name
  43. if floor == "group:soil" and spawn == "air" then
  44. minetest.set_node(spawn_pos, {name = flower})
  45. end
  46. end
  47. -- NODES
  48. minetest.register_node("bees:extractor", {
  49. description = S("Honey Extractor"),
  50. tiles = {
  51. "bees_extractor.png", "bees_extractor.png", "bees_extractor.png",
  52. "bees_extractor.png", "bees_extractor.png", "bees_extractor_front.png"
  53. },
  54. paramtype2 = "facedir",
  55. groups = {
  56. choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1,
  57. tubedevice_receiver = 1
  58. },
  59. on_construct = function(pos, node)
  60. local meta = minetest.get_meta(pos)
  61. local inv = meta:get_inventory()
  62. local pos = pos.x .. "," .. pos.y .. "," .. pos.z
  63. inv:set_size("frames_filled", 1)
  64. inv:set_size("frames_emptied", 1)
  65. inv:set_size("bottles_empty", 1)
  66. inv:set_size("bottles_full", 1)
  67. inv:set_size("wax", 1)
  68. meta:set_string("formspec", "size[8,9]"
  69. --input
  70. .. "list[nodemeta:"..pos..";frames_filled;2,1;1,1;]"
  71. .. "list[nodemeta:"..pos..";bottles_empty;2,3;1,1;]"
  72. --output
  73. .. "list[nodemeta:"..pos..";frames_emptied;5,0.5;1,1;]"
  74. .. "list[nodemeta:"..pos..";wax;5,2;1,1;]"
  75. .. "list[nodemeta:"..pos..";bottles_full;5,3.5;1,1;]"
  76. --player inventory
  77. .. "list[current_player;main;0,5;8,4;]"
  78. )
  79. end,
  80. on_timer = function(pos, node)
  81. local meta = minetest.get_meta(pos)
  82. local inv = meta:get_inventory()
  83. if not inv:contains_item("frames_filled", "bees:frame_full")
  84. or not inv:contains_item("bottles_empty", "vessels:glass_bottle") then
  85. return
  86. end
  87. if inv:room_for_item("frames_emptied", "bees:frame_empty")
  88. and inv:room_for_item("wax", "bees:wax")
  89. and inv:room_for_item("bottles_full", "bees:bottle_honey") then
  90. --add to output
  91. inv:add_item("frames_emptied", "bees:frame_empty")
  92. inv:add_item("wax", "bees:wax")
  93. inv:add_item("bottles_full", "bees:bottle_honey")
  94. --remove from input
  95. inv:remove_item("bottles_empty", "vessels:glass_bottle")
  96. inv:remove_item("frames_filled", "bees:frame_full")
  97. local p = {
  98. x = pos.x + random() - 0.5,
  99. y = pos.y + random() - 0.5,
  100. z = pos.z + random() - 0.5
  101. }
  102. --wax flying all over the place
  103. minetest.add_particle({
  104. pos = {x = pos.x, y = pos.y, z = pos.z},
  105. vel = {
  106. x = random(-1, 1),
  107. y = random(4),
  108. z = random(-1, 1)
  109. },
  110. acc = {x = 0, y = -6, z = 0},
  111. expirationtime = 2,
  112. size = random(1, 3),
  113. collisiondetection = false,
  114. texture = "bees_wax_particle.png",
  115. })
  116. local timer = minetest.get_node_timer(pos)
  117. timer:start(5)
  118. else
  119. local timer = minetest.get_node_timer(pos)
  120. timer:start(5) -- Try again in 5 seconds (was 1)
  121. end
  122. end,
  123. tube = {
  124. insert_object = function(pos, node, stack, direction)
  125. local meta = minetest.get_meta(pos)
  126. local inv = meta:get_inventory()
  127. local timer = minetest.get_node_timer(pos)
  128. if stack:get_name() == "bees:frame_full" then
  129. if inv:is_empty("frames_filled") then
  130. timer:start(5)
  131. end
  132. return inv:add_item("frames_filled",stack)
  133. elseif stack:get_name() == "vessels:glass_bottle" then
  134. if inv:is_empty("bottles_empty") then
  135. timer:start(5)
  136. end
  137. return inv:add_item("bottles_empty",stack)
  138. end
  139. return stack
  140. end,
  141. can_insert = function(pos,node,stack,direction)
  142. local meta = minetest.get_meta(pos)
  143. local inv = meta:get_inventory()
  144. if stack:get_name() == "bees:frame_full" then
  145. return inv:room_for_item("frames_filled",stack)
  146. elseif stack:get_name() == "vessels:glass_bottle" then
  147. return inv:room_for_item("bottles_empty",stack)
  148. end
  149. return false
  150. end,
  151. input_inventory = {"frames_emptied", "bottles_full", "wax"},
  152. connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
  153. },
  154. on_metadata_inventory_put = function(pos, listname, index, stack, player)
  155. local timer = minetest.get_node_timer(pos)
  156. local meta = minetest.get_meta(pos)
  157. local inv = meta:get_inventory()
  158. -- if inventory empty start timer for honey bottle, empty frame and wax
  159. if inv:get_stack(listname, 1):get_count() == stack:get_count() then
  160. timer:start(5)
  161. end
  162. end,
  163. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  164. if (listname == "bottles_empty" and stack:get_name() == "vessels:glass_bottle")
  165. or (listname == "frames_filled" and stack:get_name() == "bees:frame_full") then
  166. return stack:get_count()
  167. else
  168. return 0
  169. end
  170. end,
  171. allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
  172. return 0
  173. end,
  174. allow_metadata_inventory_take = function(pos, listname, index, stack, player)
  175. if player and minetest.is_protected(pos, player:get_player_name()) then
  176. return 0
  177. end
  178. return stack:get_count()
  179. end,
  180. })
  181. minetest.register_node("bees:bees", {
  182. description = S("Bees"),
  183. drawtype = "plantlike",
  184. paramtype = "light",
  185. groups = {not_in_creative_inventory = 1},
  186. tiles = {
  187. {
  188. name = "bees_strip.png",
  189. animation = {
  190. type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 2.0
  191. }
  192. }
  193. },
  194. damage_per_second = 1,
  195. walkable = false,
  196. buildable_to = true,
  197. selection_box = {
  198. type = "fixed",
  199. fixed = {
  200. {-0.3, -0.4, -0.3, 0.3, 0.4, 0.3},
  201. }
  202. },
  203. on_punch = function(pos, node, puncher)
  204. puncher:set_hp(puncher:get_hp() - 2)
  205. end,
  206. })
  207. minetest.register_node("bees:hive_wild", {
  208. description = S("Wild Bee Hive"),
  209. tiles = { --Neuromancer"s base texture
  210. "bees_hive_wild.png", "bees_hive_wild.png", "bees_hive_wild.png",
  211. "bees_hive_wild.png", "bees_hive_wild_bottom.png"
  212. },
  213. drawtype = "nodebox",
  214. paramtype = "light",
  215. paramtype2 = "wallmounted",
  216. drop = {
  217. max_items = 6,
  218. items = {
  219. { items = {"bees:honey_comb"}, rarity = 5}
  220. }
  221. },
  222. groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, attached_node = 1},
  223. node_box = { --VanessaE's wild hive nodebox contribution
  224. type = "fixed",
  225. fixed = {
  226. {-0.250000,-0.500000,-0.250000,0.250000,0.375000,0.250000}, --NodeBox 2
  227. {-0.312500,-0.375000,-0.312500,0.312500,0.250000,0.312500}, --NodeBox 4
  228. {-0.375000,-0.250000,-0.375000,0.375000,0.125000,0.375000}, --NodeBox 5
  229. {-0.062500,-0.500000,-0.062500,0.062500,0.500000,0.062500}, --NodeBox 6
  230. }
  231. },
  232. on_timer = function(pos)
  233. local meta = minetest.get_meta(pos)
  234. local inv = meta:get_inventory()
  235. local timer = minetest.get_node_timer(pos)
  236. local rad = 10
  237. local flowers = minetest.find_nodes_in_area(
  238. {x = pos.x - rad, y = pos.y - rad, z = pos.z - rad},
  239. {x = pos.x + rad, y = pos.y + rad, z = pos.z + rad},
  240. "group:flower")
  241. -- Queen dies if no flowers nearby
  242. if #flowers == 0 then
  243. inv:set_stack("queen", 1, "")
  244. meta:set_string("infotext", S("Colony died, not enough flowers in area!"))
  245. return
  246. end
  247. -- Requires 2 or more flowers to make honey
  248. if #flowers < 3 then return end
  249. local flower = flowers[random(#flowers)]
  250. polinate_flower(flower, minetest.get_node(flower).name)
  251. local stacks = inv:get_list("combs")
  252. for k, v in pairs(stacks) do
  253. if inv:get_stack("combs", k):is_empty() then
  254. inv:set_stack("combs", k, "bees:honey_comb")
  255. timer:start(1000 / #flowers)
  256. return
  257. end
  258. end
  259. --what to do if all combs are filled
  260. end,
  261. on_construct = function(pos)
  262. minetest.get_node(pos).param2 = 0
  263. local meta = minetest.get_meta(pos)
  264. local inv = meta:get_inventory()
  265. local timer = minetest.get_node_timer(pos)
  266. meta:set_int("agressive", 1)
  267. timer:start(100 + random(100))
  268. inv:set_size("queen", 1)
  269. inv:set_size("combs", 5)
  270. inv:set_stack("queen", 1, "bees:queen")
  271. for i = 1, random(3) do
  272. inv:set_stack("combs", i, "bees:honey_comb")
  273. end
  274. end,
  275. on_punch = function(pos, node, puncher)
  276. local meta = minetest.get_meta(pos)
  277. local inv = meta:get_inventory()
  278. if inv:contains_item("queen", "bees:queen") then
  279. puncher:set_hp(puncher:get_hp() - 4)
  280. end
  281. end,
  282. on_metadata_inventory_take = function(pos, listname, index, stack, taker)
  283. local meta = minetest.get_meta(pos)
  284. local inv = meta:get_inventory()
  285. local timer= minetest.get_node_timer(pos)
  286. if listname == "combs" and inv:contains_item("queen", "bees:queen") then
  287. timer:start(10)
  288. taker:set_hp(taker:get_hp() - 2)
  289. end
  290. end,
  291. on_metadata_inventory_put = function(pos, listname, index, stack, taker)
  292. local timer = minetest.get_node_timer(pos)
  293. if not timer:is_started() then
  294. timer:start(10)
  295. end
  296. end,
  297. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  298. --restart the colony by adding a queen
  299. if listname == "queen" and stack:get_name() == "bees:queen" then
  300. return 1
  301. else
  302. return 0
  303. end
  304. end,
  305. on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
  306. minetest.show_formspec(clicker:get_player_name(),
  307. "bees:hive_artificial",
  308. hive_wild(pos, (itemstack:get_name() == "bees:grafting_tool"))
  309. )
  310. local meta = minetest.get_meta(pos)
  311. local inv = meta:get_inventory()
  312. if meta:get_int("agressive") == 1
  313. and inv:contains_item("queen", "bees:queen") then
  314. clicker:set_hp(clicker:get_hp() - 4)
  315. else
  316. meta:set_int("agressive", 1)
  317. end
  318. end,
  319. can_dig = function(pos,player)
  320. local meta = minetest.get_meta(pos)
  321. local inv = meta:get_inventory()
  322. if inv:is_empty("queen") and inv:is_empty("combs") then
  323. return true
  324. else
  325. return false
  326. end
  327. end,
  328. after_dig_node = function(pos, oldnode, oldmetadata, user)
  329. local wielded
  330. if user:get_wielded_item() ~= nil then
  331. wielded = user:get_wielded_item()
  332. else
  333. return
  334. end
  335. if "bees:grafting_tool" == wielded:get_name() then
  336. local inv = user:get_inventory()
  337. if inv then
  338. inv:add_item("main", ItemStack("bees:queen"))
  339. end
  340. end
  341. end
  342. })
  343. minetest.register_node("bees:hive_artificial", {
  344. description = S("Artificial Bee Hive"),
  345. tiles = {
  346. "default_wood.png", "default_wood.png", "default_wood.png",
  347. "default_wood.png", "default_wood.png", "bees_hive_artificial.png"
  348. },
  349. drawtype = "nodebox",
  350. paramtype = "light",
  351. paramtype2 = "facedir",
  352. groups = {
  353. snappy = 1, choppy = 2, oddly_breakable_by_hand = 2,
  354. flammable = 3, wood = 1
  355. },
  356. sounds = default.node_sound_wood_defaults(),
  357. node_box = {
  358. type = "fixed",
  359. fixed = {
  360. {-4/8, 2/8, -4/8, 4/8, 3/8, 4/8},
  361. {-3/8, -4/8, -2/8, 3/8, 2/8, 3/8},
  362. {-3/8, 0/8, -3/8, 3/8, 2/8, -2/8},
  363. {-3/8, -4/8, -3/8, 3/8, -1/8, -2/8},
  364. {-3/8, -1/8, -3/8, -1/8, 0/8, -2/8},
  365. {1/8, -1/8, -3/8, 3/8, 0/8, -2/8},
  366. }
  367. },
  368. on_construct = function(pos)
  369. local timer = minetest.get_node_timer(pos)
  370. local meta = minetest.get_meta(pos)
  371. local inv = meta:get_inventory()
  372. meta:set_int("agressive", 1)
  373. inv:set_size("queen", 1)
  374. inv:set_size("frames", 8)
  375. meta:set_string("infotext", S("Requires Queen bee to function"))
  376. end,
  377. on_rightclick = function(pos, node, clicker, itemstack)
  378. if minetest.is_protected(pos, clicker:get_player_name()) then
  379. return
  380. end
  381. minetest.show_formspec(clicker:get_player_name(),
  382. "bees:hive_artificial",
  383. hive_artificial(pos)
  384. )
  385. local meta = minetest.get_meta(pos)
  386. local inv = meta:get_inventory()
  387. if meta:get_int("agressive") == 1
  388. and inv:contains_item("queen", "bees:queen") then
  389. clicker:set_hp(clicker:get_hp() - 4)
  390. else
  391. meta:set_int("agressive", 1)
  392. end
  393. end,
  394. on_timer = function(pos,elapsed)
  395. local meta = minetest.get_meta(pos)
  396. local inv = meta:get_inventory()
  397. local timer = minetest.get_node_timer(pos)
  398. if inv:contains_item("queen", "bees:queen") then
  399. if inv:contains_item("frames", "bees:frame_empty") then
  400. timer:start(30)
  401. local rad = 10
  402. local flowers = minetest.find_nodes_in_area(
  403. {x = pos.x - rad, y = pos.y - rad, z = pos.z - rad},
  404. {x = pos.x + rad, y = pos.y + rad, z = pos.z + rad},
  405. "group:flower")
  406. local progress = meta:get_int("progress")
  407. progress = progress + #flowers
  408. meta:set_int("progress", progress)
  409. if progress > 1000 then
  410. local flower = flowers[random(#flowers)]
  411. polinate_flower(flower, minetest.get_node(flower).name)
  412. local stacks = inv:get_list("frames")
  413. for k, v in pairs(stacks) do
  414. if inv:get_stack("frames", k):get_name() == "bees:frame_empty" then
  415. meta:set_int("progress", 0)
  416. inv:set_stack("frames", k, "bees:frame_full")
  417. return
  418. end
  419. end
  420. else
  421. meta:set_string("infotext", S("progress:")
  422. .. " " .. progress .. " + " .. #flowers .. " / 1000")
  423. end
  424. else
  425. meta:set_string("infotext", S("Does not have empty frame(s)"))
  426. timer:stop()
  427. end
  428. end
  429. end,
  430. on_metadata_inventory_take = function(pos, listname, index, stack, player)
  431. if listname == "queen" then
  432. local timer = minetest.get_node_timer(pos)
  433. local meta = minetest.get_meta(pos)
  434. meta:set_string("infotext", S("Requires Queen bee to function"))
  435. timer:stop()
  436. end
  437. end,
  438. allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
  439. local inv = minetest.get_meta(pos):get_inventory()
  440. if from_list == to_list then
  441. if inv:get_stack(to_list, to_index):is_empty() then
  442. return 1
  443. else
  444. return 0
  445. end
  446. else
  447. return 0
  448. end
  449. end,
  450. on_metadata_inventory_put = function(pos, listname, index, stack, player)
  451. local meta = minetest.get_meta(pos)
  452. local inv = meta:get_inventory()
  453. local timer = minetest.get_node_timer(pos)
  454. if listname == "queen" or listname == "frames" then
  455. meta:set_string("queen", stack:get_name())
  456. meta:set_string("infotext", S("Queen inserted, now for the empty frames"))
  457. if inv:contains_item("frames", "bees:frame_empty") then
  458. timer:start(30)
  459. meta:set_string("infotext", S("Bees are aclimating"))
  460. end
  461. end
  462. end,
  463. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  464. if not minetest.get_meta(pos):get_inventory():get_stack(listname, index):is_empty() then return 0 end
  465. if listname == "queen" then
  466. if stack:get_name():match("bees:queen*") then
  467. return 1
  468. end
  469. elseif listname == "frames" then
  470. if stack:get_name() == ("bees:frame_empty") then
  471. return 1
  472. end
  473. end
  474. return 0
  475. end,
  476. })
  477. -- ABMS
  478. minetest.register_abm({
  479. nodenames = {"bees:hive_artificial", "bees:hive_wild", "bees:hive_industrial"},
  480. interval = 10,
  481. chance = 4,
  482. action = function(pos, node)
  483. -- Bee particle
  484. minetest.add_particle({
  485. pos = {x = pos.x, y = pos.y, z = pos.z},
  486. vel = {
  487. x = (random() - 0.5) * 5,
  488. y = (random() - 0.5) * 5,
  489. z = (random() - 0.5) * 5
  490. },
  491. acc = {
  492. x = random() - 0.5,
  493. y = random() - 0.5,
  494. z = random() - 0.5
  495. },
  496. expirationtime = random(2.5),
  497. size = random(3),
  498. collisiondetection = true,
  499. texture = "bees_particle_bee.png",
  500. })
  501. -- floating hive check and removal
  502. if node.name == "bees:hive_wild" then
  503. local num = #minetest.find_nodes_in_area(
  504. {x = pos.x - 1, y = pos.y - 1, z = pos.z - 1},
  505. {x = pos.x + 1, y = pos.y + 1, z = pos.z + 1},
  506. {"air"})
  507. if num and num > 25 then
  508. minetest.remove_node(pos)
  509. end
  510. end
  511. end,
  512. })
  513. -- spawn abm. This should be changed to a more realistic type of spawning
  514. minetest.register_abm({
  515. nodenames = {"group:leaves"},
  516. neighbors = {"air"},
  517. interval = 800,--1600,
  518. chance = 10,--20,
  519. action = function(pos, node)
  520. if floor(pos.x / 40) ~= pos.x / 40
  521. or floor(pos.z / 40) ~= pos.z / 40
  522. or floor(pos.y / 5) ~= pos.y / 5 then return end
  523. local p = {x = pos.x, y = pos.y - 1, z = pos.z}
  524. local nod = minetest.get_node_or_nil(p)
  525. local def = nod and minetest.registered_nodes[nod.name]
  526. if not def or def.walkable then return end
  527. if minetest.find_node_near(p, 5, "group:flora") then
  528. minetest.add_node(p, {name = "bees:hive_wild"})
  529. end
  530. end,
  531. })
  532. -- spawning bees around bee hive
  533. minetest.register_abm({
  534. nodenames = {"bees:hive_wild", "bees:hive_artificial", "bees:hive_industrial"},
  535. neighbors = {"group:flowers", "group:leaves"},
  536. interval = 30,
  537. chance = 4,
  538. action = function(pos, node, _, _)
  539. local p = {
  540. x = pos.x + random(-5, 5),
  541. y = pos.y - random(0, 3),
  542. z = pos.z + random(-5, 5)
  543. }
  544. if minetest.get_node(p).name == "air" then
  545. minetest.add_node(p, {name="bees:bees"})
  546. end
  547. end,
  548. })
  549. -- remove bees
  550. minetest.register_abm({
  551. nodenames = {"bees:bees"},
  552. interval = 30,
  553. chance = 5,
  554. action = function(pos, node, _, _)
  555. minetest.remove_node(pos)
  556. end,
  557. })
  558. -- ITEMS
  559. minetest.register_craftitem("bees:frame_empty", {
  560. description = S("Empty hive frame"),
  561. inventory_image = "bees_frame_empty.png",
  562. stack_max = 24,
  563. })
  564. minetest.register_craftitem("bees:frame_full", {
  565. description = S("Filled hive frame"),
  566. inventory_image = "bees_frame_full.png",
  567. stack_max = 12,
  568. })
  569. minetest.register_craftitem("bees:bottle_honey", {
  570. description = S("Honey bottle"),
  571. inventory_image = "bees_bottle_honey.png",
  572. stack_max = 12,
  573. on_use = minetest.item_eat(3, "vessels:glass_bottle"),
  574. groups = {vessel = 1},
  575. })
  576. minetest.register_craftitem("bees:wax", {
  577. description = S("Bees wax"),
  578. inventory_image = "bees_wax.png",
  579. stack_max = 48,
  580. })
  581. minetest.register_craftitem("bees:honey_comb", {
  582. description = S("honey comb"),
  583. inventory_image = "bees_comb.png",
  584. on_use = minetest.item_eat(2),
  585. stack_max = 8,
  586. })
  587. minetest.register_craftitem("bees:queen", {
  588. description = S("Queen Bee"),
  589. inventory_image = "bees_particle_bee.png",
  590. stack_max = 1,
  591. })
  592. -- CRAFTS
  593. minetest.register_craft({
  594. output = "bees:extractor",
  595. recipe = {
  596. {"", "default:steel_ingot", ""},
  597. {"default:steel_ingot", "default:stick", "default:steel_ingot"},
  598. {"default:mese_crystal", "default:steel_ingot", "default:mese_crystal"},
  599. }
  600. })
  601. minetest.register_craft({
  602. output = "bees:smoker",
  603. recipe = {
  604. {"default:steel_ingot", "wool:red", ""},
  605. {"", "default:torch", ""},
  606. {"", "default:steel_ingot",""},
  607. }
  608. })
  609. minetest.register_craft({
  610. output = "bees:hive_artificial",
  611. recipe = {
  612. {"group:wood", "group:wood", "group:wood"},
  613. {"group:wood", "default:stick", "group:wood"},
  614. {"group:wood", "default:stick", "group:wood"},
  615. }
  616. })
  617. minetest.register_craft({
  618. output = "bees:grafting_tool",
  619. recipe = {
  620. {"", "", "default:steel_ingot"},
  621. {"", "default:stick", ""},
  622. {"", "", ""},
  623. }
  624. })
  625. minetest.register_craft({
  626. output = "bees:frame_empty",
  627. recipe = {
  628. {"group:wood", "group:wood", "group:wood"},
  629. {"default:stick", "default:stick", "default:stick"},
  630. {"default:stick", "default:stick", "default:stick"},
  631. }
  632. })
  633. if minetest.get_modpath("bushes_classic") then
  634. minetest.register_craft({
  635. type = "cooking",
  636. cooktime = 5,
  637. recipe = "bees:bottle_honey",
  638. output = "bushes:sugar",
  639. })
  640. end
  641. -- TOOLS
  642. minetest.register_tool("bees:smoker", {
  643. description = S("smoker"),
  644. inventory_image = "bees_smoker.png",
  645. tool_capabilities = {
  646. full_punch_interval = 3.0,
  647. max_drop_level = 0,
  648. damage_groups = {fleshy = 2},
  649. },
  650. on_use = function(itemstack, user, pointed_thing)
  651. if pointed_thing.type ~= "node" then
  652. return
  653. end
  654. local pos = pointed_thing.under
  655. for i = 1, 6 do
  656. minetest.add_particle({
  657. pos = {
  658. x = pos.x + random() - 0.5,
  659. y = pos.y,
  660. z = pos.z + random() - 0.5
  661. },
  662. vel = {x = 0, y = 0.5 + random(), z = 0},
  663. acc = {x = 0, y = 0, z = 0},
  664. expirationtime = 2 + random(2.5),
  665. size = random(3),
  666. collisiondetection = false,
  667. texture = "bees_smoke_particle.png",
  668. })
  669. end
  670. itemstack:add_wear(65535 / 200)
  671. local meta = minetest.get_meta(pos)
  672. meta:set_int("agressive", 0)
  673. return itemstack
  674. end,
  675. })
  676. minetest.register_tool("bees:grafting_tool", {
  677. description = S("Grafting tool"),
  678. inventory_image = "bees_grafting_tool.png",
  679. tool_capabilities = {
  680. full_punch_interval = 3.0,
  681. max_drop_level=0,
  682. damage_groups = {fleshy = 2},
  683. },
  684. })
  685. -- COMPATIBILTY --remove after all has been updated
  686. -- ALIASES
  687. minetest.register_alias("bees:honey_extractor", "bees:extractor")
  688. -- BACKWARDS COMPATIBILITY WITH OLDER VERSION
  689. minetest.register_alias("bees:honey_bottle", "bees:bottle_honey")
  690. minetest.register_lbm({
  691. nodenames = {"bees:hive", "bees:hive_artificial_inhabited"},
  692. name = "bees:replace_old_hives",
  693. label = "Replace old hives",
  694. run_at_every_load = true,
  695. action = function(pos, node)
  696. if node.name == "bees:hive" then
  697. minetest.set_node(pos, {name = "bees:hive_wild"})
  698. local meta = minetest.get_meta(pos)
  699. local inv = meta:get_inventory()
  700. inv:set_stack("queen", 1, "bees:queen")
  701. end
  702. if node.name == "bees:hive_artificial_inhabited" then
  703. minetest.set_node(pos, {name = "bees:hive_artificial"})
  704. local meta = minetest.get_meta(pos)
  705. local inv = meta:get_inventory()
  706. inv:set_stack("queen", 1, "bees:queen")
  707. local timer = minetest.get_node_timer(pos)
  708. timer:start(60)
  709. end
  710. end
  711. })
  712. -- PIPEWORKS
  713. if minetest.get_modpath("pipeworks") then
  714. minetest.register_node("bees:hive_industrial", {
  715. description = S("Industrial Bee Hive"),
  716. tiles = {"bees_hive_industrial.png"},
  717. paramtype2 = "facedir",
  718. groups = {
  719. snappy = 1, choppy = 2, oddly_breakable_by_hand = 2,
  720. tubedevice = 1, tubedevice_receiver = 1
  721. },
  722. sounds = default.node_sound_wood_defaults(),
  723. tube = {
  724. insert_object = function(pos, node, stack, direction)
  725. local meta = minetest.get_meta(pos)
  726. local inv = meta:get_inventory()
  727. if stack:get_name() ~= "bees:frame_empty"
  728. or stack:get_count() > 1 then
  729. return stack
  730. end
  731. for i = 1, 8 do
  732. if inv:get_stack("frames", i):is_empty() then
  733. inv:set_stack("frames", i, stack)
  734. local timer = minetest.get_node_timer(pos)
  735. timer:start(30)
  736. meta:set_string("infotext", S("Bees are aclimating"))
  737. return ItemStack("")
  738. end
  739. end
  740. return stack
  741. end,
  742. can_insert = function(pos,node,stack,direction)
  743. local meta = minetest.get_meta(pos)
  744. local inv = meta:get_inventory()
  745. if stack:get_name() ~= "bees:frame_empty"
  746. or stack:get_count() > 1 then
  747. return false
  748. end
  749. for i = 1, 8 do
  750. if inv:get_stack("frames", i):is_empty() then
  751. return true
  752. end
  753. end
  754. return false
  755. end,
  756. can_remove = function(pos,node,stack,direction)
  757. if stack:get_name() == "bees:frame_full" then
  758. return 1
  759. else
  760. return 0
  761. end
  762. end,
  763. input_inventory = "frames",
  764. connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
  765. },
  766. on_construct = function(pos)
  767. local timer = minetest.get_node_timer(pos)
  768. local meta = minetest.get_meta(pos)
  769. local inv = meta:get_inventory()
  770. meta:set_int("agressive", 1)
  771. inv:set_size("queen", 1)
  772. inv:set_size("frames", 8)
  773. meta:set_string("infotext", S("Requires Queen bee to function"))
  774. end,
  775. on_rightclick = function(pos, node, clicker, itemstack)
  776. if minetest.is_protected(pos, clicker:get_player_name()) then
  777. return
  778. end
  779. minetest.show_formspec(clicker:get_player_name(),
  780. "bees:hive_artificial",
  781. hive_artificial(pos)
  782. )
  783. local meta = minetest.get_meta(pos)
  784. local inv = meta:get_inventory()
  785. if meta:get_int("agressive") == 1
  786. and inv:contains_item("queen", "bees:queen") then
  787. clicker:set_hp(clicker:get_hp() - 4)
  788. else
  789. meta:set_int("agressive", 1)
  790. end
  791. end,
  792. on_timer = function(pos,elapsed)
  793. local meta = minetest.get_meta(pos)
  794. local inv = meta:get_inventory()
  795. local timer = minetest.get_node_timer(pos)
  796. if inv:contains_item("queen", "bees:queen") then
  797. if inv:contains_item("frames", "bees:frame_empty") then
  798. timer:start(30)
  799. local rad = 10
  800. local minp = {x = pos.x - rad, y = pos.y - rad, z = pos.z - rad}
  801. local maxp = {x = pos.x + rad, y = pos.y + rad, z = pos.z + rad}
  802. local flowers = minetest.find_nodes_in_area(minp, maxp, "group:flower")
  803. local progress = meta:get_int("progress")
  804. progress = progress + #flowers
  805. meta:set_int("progress", progress)
  806. if progress > 1000 then
  807. local flower = flowers[random(#flowers)]
  808. polinate_flower(flower, minetest.get_node(flower).name)
  809. local stacks = inv:get_list("frames")
  810. for k, v in pairs(stacks) do
  811. if inv:get_stack("frames", k):get_name() == "bees:frame_empty" then
  812. meta:set_int("progress", 0)
  813. inv:set_stack("frames", k, "bees:frame_full")
  814. return
  815. end
  816. end
  817. else
  818. meta:set_string("infotext", S("progress:")
  819. .. " " .. progress .. " + " .. #flowers .. " / 1000")
  820. end
  821. else
  822. meta:set_string("infotext", S("Does not have empty frame(s)"))
  823. timer:stop()
  824. end
  825. end
  826. end,
  827. on_metadata_inventory_take = function(pos, listname, index, stack, player)
  828. if listname == "queen" then
  829. local timer = minetest.get_node_timer(pos)
  830. local meta = minetest.get_meta(pos)
  831. meta:set_string("infotext", S("Requires Queen bee to function"))
  832. timer:stop()
  833. end
  834. end,
  835. allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
  836. local inv = minetest.get_meta(pos):get_inventory()
  837. if from_list == to_list then
  838. if inv:get_stack(to_list, to_index):is_empty() then
  839. return 1
  840. else
  841. return 0
  842. end
  843. else
  844. return 0
  845. end
  846. end,
  847. on_metadata_inventory_put = function(pos, listname, index, stack, player)
  848. local meta = minetest.get_meta(pos)
  849. local inv = meta:get_inventory()
  850. local timer = minetest.get_node_timer(pos)
  851. if listname == "queen" or listname == "frames" then
  852. meta:set_string("queen", stack:get_name())
  853. meta:set_string("infotext", S("Queen inserted, now for the empty frames"))
  854. if inv:contains_item("frames", "bees:frame_empty") then
  855. timer:start(30)
  856. meta:set_string("infotext", S("Bees are aclimating"))
  857. end
  858. end
  859. end,
  860. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  861. if not minetest.get_meta(pos):get_inventory():get_stack(listname, index):is_empty() then
  862. return 0
  863. end
  864. if listname == "queen" then
  865. if stack:get_name():match("bees:queen*") then
  866. return 1
  867. end
  868. elseif listname == "frames" then
  869. if stack:get_name() == ("bees:frame_empty") then
  870. return 1
  871. end
  872. end
  873. return 0
  874. end,
  875. })
  876. minetest.register_craft({
  877. output = "bees:hive_industrial",
  878. recipe = {
  879. {"default:steel_ingot","homedecor:plastic_sheeting","default:steel_ingot"},
  880. {"pipeworks:tube_1","bees:hive_artificial","pipeworks:tube_1"},
  881. {"default:steel_ingot","homedecor:plastic_sheeting","default:steel_ingot"},
  882. }
  883. })
  884. end
  885. -- LUCKY BLOCKS
  886. if minetest.get_modpath("lucky_block") then
  887. local add_bees = function(pos, player)
  888. local objs = minetest.get_objects_inside_radius(pos, 15)
  889. local violet = minetest.get_color_escape_sequence("#ff00ff")
  890. minetest.chat_send_player(player:get_player_name(),
  891. violet .. S("Bees! Bees for all!"))
  892. for n = 1, #objs do
  893. if objs[n]:is_player() then
  894. local player_pos = objs[n]:get_pos()
  895. player_pos.y = player_pos.y + 1
  896. minetest.swap_node(player_pos, {name = "bees:bees"})
  897. end
  898. end
  899. end
  900. lucky_block:add_blocks({
  901. {"cus", add_bees},
  902. {"dro", {"bees:grafting_tool"}, 1},
  903. {"dro", {"bees:frame_empty"}, 2},
  904. {"dro", {"bees:queen"}, 1},
  905. {"nod", "bees:extractor"},
  906. {"dro", {"bees:frame_full"}, 2},
  907. {"dro", {"bees:bottle_honey"}, 3},
  908. {"dro", {"bees:smoker"}, 1},
  909. {"nod", "bees:hive_artificial"},
  910. })
  911. end
  912. print(S("[MOD] Bees Loaded!"))