init.lua 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. --Bees
  2. ------
  3. --Author Bas080
  4. --Version 2.0
  5. --License WTFPL
  6. --[[TODO
  7. smoker maybe
  8. Spreading bee colonies
  9. x Grafting Tool - to remove queen bees from wild hives
  10. x Make flowers reproduce when near a hive
  11. x Add formspec to twild hive when using grafting tool
  12. ]]
  13. --VARIABLES
  14. local sound = {}
  15. local particles = {}
  16. local bees = {}
  17. local formspecs = {}
  18. --FUNCTIONS
  19. function formspecs.hive_wild(pos, grafting)
  20. local spos = pos.x .. ',' .. pos.y .. ',' ..pos.z
  21. local formspec =
  22. 'size[8,9]'..
  23. 'list[nodemeta:'.. spos .. ';combs;1.5,3;5,1;]'..
  24. 'list[current_player;main;0,5;8,4;]'
  25. if grafting then
  26. formspec = formspec..'list[nodemeta:'.. spos .. ';queen;3.5,1;1,1;]'
  27. end
  28. return formspec
  29. end
  30. function formspecs.hive_artificial(pos)
  31. local spos = pos.x..','..pos.y..','..pos.z
  32. local formspec =
  33. 'size[8,9]'..
  34. 'list[nodemeta:'..spos..';queen;3.5,1;1,1;]'..
  35. 'list[nodemeta:'..spos..';frames;0,3;8,1;]'..
  36. 'list[current_player;main;0,5;8,4;]'
  37. return formspec
  38. end
  39. function bees.polinate_flower(pos, flower)
  40. local spawn_pos = { x=pos.x+math.random(-3,3) , y=pos.y+math.random(-3,3) , z=pos.z+math.random(-3,3) }
  41. local floor_pos = { x=spawn_pos.x , y=spawn_pos.y-1 , z=spawn_pos.z }
  42. local spawn = minetest.get_node(spawn_pos).name
  43. local floor = minetest.get_node(floor_pos).name
  44. if floor == 'default:dirt_with_grass' and spawn == 'air' then
  45. minetest.set_node(spawn_pos, {name=flower})
  46. end
  47. end
  48. --NODES
  49. minetest.register_node('bees:bees', {
  50. description = 'Flying Bees',
  51. drawtype = 'plantlike',
  52. paramtype = 'light',
  53. tiles = {
  54. {
  55. name='bees_strip.png',
  56. animation={type='vertical_frames', aspect_w=16,aspect_h=16, length=2.0}
  57. }
  58. },
  59. damage_per_second = 1,
  60. walkable = false,
  61. buildable_to = true,
  62. pointable = false,
  63. on_punch = function(pos, node, puncher)
  64. local health = puncher:get_hp()
  65. puncher:set_hp(health-2)
  66. end,
  67. })
  68. minetest.register_node('bees:hive_wild', {
  69. description = 'wild bee hive',
  70. tile_images = {'bees_hive_wild.png','bees_hive_wild.png','bees_hive_wild.png', 'bees_hive_wild.png', 'bees_hive_wild_bottom.png'}, --Neuromancer's base texture
  71. drawtype = 'nodebox',
  72. paramtype = 'light',
  73. paramtype2 = 'wallmounted',
  74. drop = {
  75. max_items = 6,
  76. items = {
  77. { items = {'bees:honey_comb'}, rarity = 5}
  78. }
  79. },
  80. groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,attached_node=1},
  81. node_box = { --VanessaE's wild hive nodebox contribution
  82. type = 'fixed',
  83. fixed = {
  84. {-0.250000,-0.500000,-0.250000,0.250000,0.375000,0.250000}, --NodeBox 2
  85. {-0.312500,-0.375000,-0.312500,0.312500,0.250000,0.312500}, --NodeBox 4
  86. {-0.375000,-0.250000,-0.375000,0.375000,0.125000,0.375000}, --NodeBox 5
  87. {-0.062500,-0.500000,-0.062500,0.062500,0.500000,0.062500}, --NodeBox 6
  88. }
  89. },
  90. on_timer = function(pos)
  91. local meta = minetest.get_meta(pos)
  92. local inv = meta:get_inventory()
  93. local timer= minetest.get_node_timer(pos)
  94. local rad = 10
  95. local minp = {x=pos.x-rad, y=pos.y-rad, z=pos.z-rad}
  96. local maxp = {x=pos.x+rad, y=pos.y+rad, z=pos.z+rad}
  97. local flowers = minetest.find_nodes_in_area(minp, maxp, 'group:flower')
  98. if #flowers == 0 then
  99. inv:set_stack('queen', 1, '')
  100. meta:set_string('infotext', 'this colony died, not enough flowers in area')
  101. return
  102. end --not any flowers nearby The queen dies!
  103. if #flowers < 3 then return end --requires 2 or more flowers before can make honey
  104. local flower = flowers[math.random(#flowers)]
  105. bees.polinate_flower(flower, minetest.get_node(flower).name)
  106. local stacks = inv:get_list('combs')
  107. for k, v in pairs(stacks) do
  108. if inv:get_stack('combs', k):is_empty() then --then replace that with a full one and reset pro..
  109. inv:set_stack('combs',k,'bees:honey_comb')
  110. timer:start(1000/#flowers)
  111. return
  112. end
  113. end
  114. --what to do if all combs are filled
  115. end,
  116. on_construct = function(pos)
  117. minetest.get_node(pos).param2 = 0
  118. local meta = minetest.get_meta(pos)
  119. local inv = meta:get_inventory()
  120. local timer = minetest.get_node_timer(pos)
  121. timer:start(100+math.random(100))
  122. inv:set_size('queen', 1)
  123. inv:set_size('combs', 5)
  124. inv:set_stack('queen', 1, 'bees:queen')
  125. for i=1,math.random(3) do
  126. inv:set_stack('combs', i, 'bees:honey_comb')
  127. end
  128. end,
  129. on_punch = function(pos, node, puncher)
  130. local meta = minetest.get_meta(pos)
  131. local inv = meta:get_inventory()
  132. if inv:contains_item('queen','bees:queen') then
  133. local health = puncher:get_hp()
  134. puncher:set_hp(health-4)
  135. end
  136. end,
  137. on_metadata_inventory_take = function(pos, listname, index, stack, taker)
  138. local meta = minetest.get_meta(pos)
  139. local inv = meta:get_inventory()
  140. local timer= minetest.get_node_timer(pos)
  141. if listname == 'combs' and inv:contains_item('queen', 'bees:queen') then
  142. local health = taker:get_hp()
  143. timer:start(10)
  144. taker:set_hp(health-2)
  145. end
  146. end,
  147. on_metadata_inventory_put = function(pos, listname, index, stack, taker) --restart the colony by adding a queen
  148. local timer = minetest.get_node_timer(pos)
  149. if not timer:is_started() then
  150. timer:start(10)
  151. end
  152. end,
  153. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  154. if listname == 'queen' and stack:get_name() == 'bees:queen' then
  155. return 1
  156. else
  157. return 0
  158. end
  159. end,
  160. on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
  161. minetest.show_formspec(
  162. clicker:get_player_name(),
  163. 'bees:hive_artificial',
  164. formspecs.hive_wild(pos, (itemstack:get_name() == 'bees:grafting_tool'))
  165. )
  166. end,
  167. can_dig = function(pos,player)
  168. local meta = minetest.get_meta(pos)
  169. local inv = meta:get_inventory()
  170. if inv:is_empty('queen') and inv:is_empty('combs') then
  171. return true
  172. else
  173. return false
  174. end
  175. end,
  176. after_dig_node = function(pos, oldnode, oldmetadata, user)
  177. local wielded if user:get_wielded_item() ~= nil then wielded = user:get_wielded_item() else return end
  178. if 'bees:grafting_tool' == wielded:get_name() then
  179. local inv = user:get_inventory()
  180. if inv then
  181. inv:add_item('main', ItemStack('bees:queen'))
  182. end
  183. end
  184. end
  185. })
  186. minetest.register_node('bees:hive_artificial', {
  187. description = 'Bee Hive',
  188. tiles = {'default_wood.png','default_wood.png','default_wood.png', 'default_wood.png','default_wood.png','bees_hive_artificial.png'},
  189. drawtype = 'nodebox',
  190. paramtype = 'light',
  191. paramtype2 = 'facedir',
  192. groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
  193. sounds = default.node_sound_wood_defaults(),
  194. node_box = {
  195. type = 'fixed',
  196. fixed = {
  197. {-4/8, 2/8, -4/8, 4/8, 3/8, 4/8},
  198. {-3/8, -4/8, -2/8, 3/8, 2/8, 3/8},
  199. {-3/8, 0/8, -3/8, 3/8, 2/8, -2/8},
  200. {-3/8, -4/8, -3/8, 3/8, -1/8, -2/8},
  201. {-3/8, -1/8, -3/8, -1/8, 0/8, -2/8},
  202. {1/8, -1/8, -3/8, 3/8, 0/8, -2/8},
  203. }
  204. },
  205. on_construct = function(pos)
  206. local timer = minetest.get_node_timer(pos)
  207. local meta = minetest.get_meta(pos)
  208. local inv = meta:get_inventory()
  209. inv:set_size('queen', 1)
  210. inv:set_size('frames', 8)
  211. meta:set_string('infotext','requires queen bee to function')
  212. end,
  213. on_rightclick = function(pos, node, clicker, itemstack)
  214. minetest.show_formspec(
  215. clicker:get_player_name(),
  216. 'bees:hive_artificial',
  217. formspecs.hive_artificial(pos)
  218. )
  219. end,
  220. on_timer = function(pos,elapsed)
  221. local meta = minetest.get_meta(pos)
  222. local inv = meta:get_inventory()
  223. local timer = minetest.get_node_timer(pos)
  224. if inv:contains_item('queen', 'bees:queen') then
  225. if inv:contains_item('frames', 'bees:frame_empty') then
  226. timer:start(30)
  227. local rad = 10
  228. local minp = {x=pos.x-rad, y=pos.y-rad, z=pos.z-rad}
  229. local maxp = {x=pos.x+rad, y=pos.y+rad, z=pos.z+rad}
  230. local flowers = minetest.find_nodes_in_area(minp, maxp, 'group:flower')
  231. local progress = meta:get_int('progress')
  232. progress = progress + #flowers
  233. meta:set_int('progress', progress)
  234. if progress > 1000 then
  235. local flower = flowers[math.random(#flowers)]
  236. bees.polinate_flower(flower, minetest.get_node(flower).name)
  237. local stacks = inv:get_list('frames')
  238. for k, v in pairs(stacks) do
  239. if inv:get_stack('frames', k):get_name() == 'bees:frame_empty' then --then replace that with a full one and reset pro..
  240. meta:set_int('progress', 0)
  241. inv:set_stack('frames',k,'bees:frame_full')
  242. return
  243. end
  244. end
  245. else
  246. meta:set_string('infotext', 'progress: '..progress..'+'..#flowers..'/1000')
  247. end
  248. else
  249. meta:set_string('infotext', 'does not have empty frame(s)')
  250. timer:stop()
  251. end
  252. end
  253. end,
  254. on_metadata_inventory_take = function(pos, listname, index, stack, player)
  255. if listname == 'queen' then
  256. local timer = minetest.get_node_timer(pos)
  257. local meta = minetest.get_meta(pos)
  258. meta:set_string('infotext','requires queen bee to function')
  259. timer:stop()
  260. end
  261. end,
  262. allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
  263. if from_list ~= to_list then
  264. return 1
  265. else
  266. return 0
  267. end
  268. end,
  269. on_metadata_inventory_put = function(pos, listname, index, stack, player)
  270. local meta = minetest.get_meta(pos)
  271. local inv = meta:get_inventory()
  272. local timer = minetest.get_node_timer(pos)
  273. if listname == 'queen' or listname == 'frames' then
  274. meta:set_string('queen', stack:get_name())
  275. meta:set_string('infotext','queen is inserted, now for the empty frames');
  276. if inv:contains_item('frames', 'bees:frame_empty') then
  277. timer:start(30)
  278. meta:set_string('infotext','bees are aclimating');
  279. end
  280. end
  281. end,
  282. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  283. if listname == 'queen' then
  284. if stack:get_name():match('bees:queen*') then
  285. return 1
  286. end
  287. elseif listname == 'frames' then
  288. if stack:get_name() == ('bees:frame_empty') then
  289. return 1
  290. end
  291. end
  292. return 0
  293. end,
  294. })
  295. --ABMS
  296. minetest.register_abm({ --spawn abm. This should be changed to a more realistic type of spawning
  297. nodenames = {'group:leaves'},
  298. neighbors = {''},
  299. interval = 1600,
  300. chance = 20,
  301. action = function(pos, node, _, _)
  302. local p = {x=pos.x, y=pos.y-1, z=pos.z}
  303. if minetest.get_node(p).walkable == false then return end
  304. if (minetest.find_node_near(p, 5, 'group:flora') ~= nil and minetest.find_node_near(p, 40, 'bees:hive_wild') == nil) then
  305. minetest.add_node(p, {name='bees:hive_wild'})
  306. end
  307. end,
  308. })
  309. minetest.register_abm({ --spawning bees around bee hive
  310. nodenames = {'bees:hive_wild', 'bees:hive_artificial'},
  311. neighbors = {'group:flowers', 'group:leaves'},
  312. interval = 30,
  313. chance = 4,
  314. action = function(pos, node, _, _)
  315. local p = {x=pos.x+math.random(-5,5), y=pos.y-math.random(0,3), z=pos.z+math.random(-5,5)}
  316. if minetest.get_node(p).name == 'air' then
  317. minetest.add_node(p, {name='bees:bees'})
  318. end
  319. end,
  320. })
  321. minetest.register_abm({ --remove bees
  322. nodenames = {'bees:bees'},
  323. interval = 30,
  324. chance = 5,
  325. action = function(pos, node, _, _)
  326. minetest.remove_node(pos)
  327. end,
  328. })
  329. --ITEMS
  330. minetest.register_craftitem('bees:frame_empty', {
  331. description = 'empty hive frame',
  332. inventory_image = 'bees_frame_empty.png',
  333. stack_max = 20,
  334. })
  335. minetest.register_craftitem('bees:frame_full', {
  336. description = 'filled hive frame',
  337. inventory_image = 'bees_frame_full.png',
  338. stack_max = 4,
  339. })
  340. minetest.register_craftitem('bees:honey_comb', {
  341. description = 'Honey Comb',
  342. inventory_image = 'bees_comb.png',
  343. on_use = minetest.item_eat(2),
  344. stack_max = 8,
  345. })
  346. minetest.register_craftitem('bees:queen', {
  347. description = 'Queen Bee',
  348. inventory_image = 'bees_particle_bee.png',
  349. stack_max = 1,
  350. })
  351. --CRAFTS
  352. minetest.register_craft({
  353. output = 'bees:hive_artificial',
  354. recipe = {
  355. {'group:wood','group:wood','group:wood'},
  356. {'group:wood','default:stick','group:wood'},
  357. {'group:wood','default:stick','group:wood'},
  358. }
  359. })
  360. minetest.register_craft({
  361. output = 'bees:grafting_tool',
  362. recipe = {
  363. {'', '', 'default:steel_ingot'},
  364. {'', 'default:stick', ''},
  365. {'', '', ''},
  366. }
  367. })
  368. minetest.register_craft({
  369. output = 'bees:frame_empty',
  370. recipe = {
  371. {'default:wood', 'default:wood', 'default:wood'},
  372. {'default:stick', 'default:stick', 'default:stick'},
  373. {'default:stick', 'default:stick', 'default:stick'},
  374. }
  375. })
  376. --TOOLS
  377. minetest.register_tool('bees:grafting_tool', {
  378. description = 'Grafting Tool',
  379. inventory_image = 'bees_grafting_tool.png',
  380. tool_capabilities = {
  381. full_punch_interval = 3.0,
  382. max_drop_level=0,
  383. groupcaps={
  384. choppy = {times={[2]=3.00, [3]=2.00}, uses=10, maxlevel=1},
  385. },
  386. damage_groups = {fleshy=2},
  387. },
  388. })
  389. --ALIASES
  390. minetest.register_alias('bees:hive', 'bees:hive_wild')
  391. minetest.register_alias('bees:hive_artificial_inhabited', 'bees:hive_artificial')
  392. print('[Mod]Bees Loaded!')