init.lua 28 KB

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