init.lua 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. -- Minetest 0.4 mod: default
  2. -- See README.txt for licensing and other information.
  3. -- Mod is reloadable.
  4. -- Namespace for functions
  5. flowers = flowers or {}
  6. flowers.modpath = minetest.get_modpath("flowers")
  7. -- Localize for performance.
  8. local math_random = math.random
  9. flowers.flora_mintime = 60*3
  10. flowers.flora_maxtime = 60*30
  11. function flowers.flora_density_for_surface(pos)
  12. local cold = 0
  13. if minetest.find_node_near(pos, 2, {
  14. "group:snow",
  15. "group:snowy",
  16. "group:ice",
  17. "group:cold",
  18. }) then
  19. cold = -2
  20. end
  21. -- Heat makes plants grow denser.
  22. local heat = 0
  23. if minetest.find_node_near(pos, 3, "group:melt_around") then
  24. heat = 1
  25. end
  26. -- Minerals improve flower growth.
  27. local minerals = 0
  28. if minetest.find_node_near(pos, 3, "glowstone:minerals") then
  29. minerals = 1
  30. end
  31. -- The presence of water increases the flower density.
  32. local water = 0
  33. if minetest.find_node_near(pos, 3, "group:water") then
  34. water = 1
  35. end
  36. -- Lush grass is better for flora than other grasses.
  37. if minetest.get_node(pos).name == "moregrass:darkgrass" then
  38. return 4 + water + minerals + heat + cold
  39. end
  40. -- Default flower density.
  41. return 3 + water + minerals + heat + cold
  42. end
  43. function flowers.surface_can_spawn_flora(pos)
  44. local name = minetest.get_node(pos).name
  45. if minetest.get_item_group(name, "soil") ~= 0 then
  46. -- Including desert sand, or else flora placed there would never turn to dry shrubs.
  47. return true
  48. end
  49. return false
  50. end
  51. function flowers.on_flora_construct(pos)
  52. if flowers.surface_can_spawn_flora({x=pos.x, y=pos.y-1, z=pos.z}) then
  53. minetest.get_node_timer(pos):start(math_random(flowers.flora_mintime, flowers.flora_maxtime))
  54. end
  55. end
  56. function flowers.on_flora_destruct(pos)
  57. -- Notify nearby flora.
  58. local minp = vector.subtract(pos, 4)
  59. local maxp = vector.add(pos, 4)
  60. local flora = minetest.find_nodes_in_area_under_air(minp, maxp, "group:flora")
  61. if flora and #flora > 0 then
  62. for i=1, #flora do
  63. minetest.get_node_timer(flora[i]):start(math_random(flowers.flora_mintime, flowers.flora_maxtime))
  64. end
  65. end
  66. end
  67. function flowers.on_flora_timer(pos, elapsed)
  68. --minetest.chat_send_player("MustTest", "Flora timer @ " .. minetest.pos_to_string(pos) .. "!")
  69. local node = minetest.get_node(pos)
  70. if flowers.flower_spread(pos, node) then
  71. minetest.get_node_timer(pos):start(math_random(flowers.flora_mintime, flowers.flora_maxtime))
  72. else
  73. -- Else timer should stop, cannot grow anymore.
  74. minetest.get_node_timer(pos):stop()
  75. end
  76. end
  77. function flowers.on_flora_punch(pos, node, puncher, pt)
  78. if flowers.surface_can_spawn_flora({x=pos.x, y=pos.y-1, z=pos.z}) then
  79. minetest.get_node_timer(pos):start(math_random(flowers.flora_mintime, flowers.flora_maxtime))
  80. end
  81. end
  82. --
  83. -- Flowers
  84. --
  85. if not flowers.registered then
  86. -- Aliases for original flowers mod
  87. minetest.register_alias("flowers:flower_rose", "flowers:rose")
  88. minetest.register_alias("flowers:flower_tulip", "flowers:tulip")
  89. minetest.register_alias("flowers:flower_dandelion_yellow", "flowers:dandelion_yellow")
  90. minetest.register_alias("flowers:flower_geranium", "flowers:geranium")
  91. minetest.register_alias("flowers:flower_viola", "flowers:viola")
  92. minetest.register_alias("flowers:flower_dandelion_white", "flowers:dandelion_white")
  93. -- Flower registration
  94. local function add_simple_flower(name, desc, box, f_groups)
  95. -- Common flowers' groups
  96. f_groups.flower = 1
  97. f_groups.flora = 1
  98. f_groups.attached_node = 1
  99. -- Flowers are supposed to be flammable! [MustTest]
  100. f_groups.flammable = 3
  101. minetest.register_node(":flowers:" .. name, {
  102. description = desc,
  103. drawtype = "plantlike",
  104. waving = 1,
  105. tiles = {"flowers_" .. name .. ".png"},
  106. inventory_image = "flowers_" .. name .. ".png",
  107. wield_image = "flowers_" .. name .. ".png",
  108. sunlight_propagates = true,
  109. paramtype = "light",
  110. walkable = false,
  111. buildable_to = true,
  112. --stack_max = 99,
  113. groups = utility.dig_groups("plant", f_groups),
  114. sounds = default.node_sound_leaves_defaults(),
  115. selection_box = {
  116. type = "fixed",
  117. fixed = box
  118. },
  119. movement_speed_multiplier = default.SLOW_SPEED_PLANTS,
  120. on_construct = function(...)
  121. return flowers.on_flora_construct(...)
  122. end,
  123. on_destruct = function(...)
  124. return flowers.on_flora_destruct(...)
  125. end,
  126. on_timer = function(...)
  127. return flowers.on_flora_timer(...)
  128. end,
  129. on_punch = function(...)
  130. return flowers.on_flora_punch(...)
  131. end,
  132. })
  133. end
  134. flowers.datas = {
  135. {
  136. "rose",
  137. "Red Rose",
  138. {-2 / 16, -0.5, -2 / 16, 2 / 16, 5 / 16, 2 / 16},
  139. {color_red = 1, flammable = 1}
  140. },
  141. {
  142. "rose_white",
  143. "White Rose",
  144. {-2 / 16, -0.5, -2 / 16, 2 / 16, 5 / 16, 2 / 16},
  145. {color_white = 1, flammable = 1}
  146. },
  147. {
  148. "tulip",
  149. "Orange Tulip",
  150. {-2 / 16, -0.5, -2 / 16, 2 / 16, 3 / 16, 2 / 16},
  151. {color_orange = 1, flammable = 1}
  152. },
  153. {
  154. "dandelion_yellow",
  155. "Yellow Dandelion",
  156. {-4 / 16, -0.5, -4 / 16, 4 / 16, -2 / 16, 4 / 16},
  157. {color_yellow = 1, flammable = 1}
  158. },
  159. {
  160. "chrysanthemum_green",
  161. "Green Chrysanthemum",
  162. {-4 / 16, -0.5, -4 / 16, 4 / 16, -1 / 16, 4 / 16},
  163. {color_green = 1, flammable = 1}
  164. },
  165. {
  166. "geranium",
  167. "Blue Geranium",
  168. {-2 / 16, -0.5, -2 / 16, 2 / 16, 2 / 16, 2 / 16},
  169. {color_blue = 1, flammable = 1}
  170. },
  171. {
  172. "viola",
  173. "Viola",
  174. {-5 / 16, -0.5, -5 / 16, 5 / 16, -1 / 16, 5 / 16},
  175. {color_violet = 1, flammable = 1}
  176. },
  177. {
  178. "dandelion_white",
  179. "White Dandelion",
  180. {-5 / 16, -0.5, -5 / 16, 5 / 16, -2 / 16, 5 / 16},
  181. {color_white = 1, flammable = 1}
  182. },
  183. {
  184. "tulip_black",
  185. "Black Tulip",
  186. {-2 / 16, -0.5, -2 / 16, 2 / 16, 3 / 16, 2 / 16},
  187. {color_black = 1, flammable = 1}
  188. },
  189. {
  190. "zinnia_red",
  191. "Red Zinnia",
  192. {-5 / 16, -0.5, -5 / 16, 5 / 16, 5 / 16, 5 / 16},
  193. {color_red = 1, flammable = 1}
  194. },
  195. {
  196. "lupine_purple",
  197. "Purple Lupine",
  198. {-2 / 16, -0.5, -2 / 16, 2 / 16, 5 / 16, 2 / 16},
  199. {color_violet = 1, flammable = 1}
  200. },
  201. {
  202. "jack",
  203. "Jack in the Pulpit",
  204. {-0.15, -0.5, -0.15, 0.15, 7 / 16, 0.15},
  205. {color_dark_green = 1, flammable = 1}
  206. },
  207. {
  208. "poppy_orange",
  209. "Orange Poppy",
  210. {-5 / 16, -0.5, -5 / 16, 5 / 16, 5 / 16, 5 / 16},
  211. {color_orange = 1, flammable = 1}
  212. },
  213. {
  214. "daylily",
  215. "Daylily",
  216. {-5 / 16, -0.5, -5 / 16, 5 / 16, 3 / 16, 5 / 16},
  217. {color_yellow = 1, flammable = 1}
  218. },
  219. {
  220. "iris_black",
  221. "Black Iris",
  222. {-2 / 16, -0.5, -2 / 16, 2 / 16, 3 / 16, 2 / 16},
  223. {color_black = 1, flammable = 1}
  224. },
  225. {
  226. "forgetmenot",
  227. "Forget-Me-Not",
  228. {-5 / 16, -0.5, -5 / 16, 5 / 16, -2 / 16, 5 / 16},
  229. {color_cyan = 1, flammable = 1}
  230. },
  231. {
  232. "snapdragon",
  233. "Snapdragon",
  234. {-5 / 16, -0.5, -5 / 16, 5 / 16, 1 / 16, 5 / 16},
  235. {color_magenta = 1, flammable = 1}
  236. },
  237. {
  238. "bluebell",
  239. "Bluebell",
  240. {-2 / 16, -0.5, -2 / 16, 2 / 16, 5 / 16, 2 / 16},
  241. {color_blue = 1, flammable = 1}
  242. },
  243. {
  244. "foxglove_pink",
  245. "Pink Foxglove",
  246. {-0.15, -0.5, -0.15, 0.15, 7 / 16, 0.15},
  247. {color_pink = 1, flammable = 1}
  248. },
  249. -- {
  250. -- "desertrose",
  251. -- "Red Desert Rose",
  252. -- {-0.15, -0.5, -0.15, 0.15, 7 / 16, 0.15},
  253. -- {color_red = 1, flammable = 1}
  254. -- },
  255. -- {
  256. -- "desertrose_pink",
  257. -- "Pink Desert Rose",
  258. -- {-0.15, -0.5, -0.15, 0.15, 7 / 16, 0.15},
  259. -- {color_pink = 1, flammable = 1}
  260. -- },
  261. }
  262. for _,item in pairs(flowers.datas) do
  263. add_simple_flower(unpack(item))
  264. end
  265. flowers.registered = true
  266. end
  267. -- Flower spread
  268. -- Public function to enable override by mods
  269. function flowers.flower_spread(pos, node)
  270. pos.y = pos.y - 1
  271. local under = minetest.get_node(pos)
  272. pos.y = pos.y + 1
  273. -- Replace flora with dry shrub in desert sand and silver sand,
  274. -- as this is the only way to generate them.
  275. -- However, preserve grasses in sand dune biomes.
  276. if minetest.get_item_group(under.name, "sand") == 1 and
  277. under.name ~= "default:sand" then
  278. minetest.add_node(pos, {name = "default:dry_shrub"})
  279. return false
  280. end
  281. if minetest.get_item_group(under.name, "soil") == 0 then
  282. return false
  283. end
  284. local light = minetest.get_node_light(pos) or 0
  285. if light < 13 then
  286. -- Is this just a daytime thing?
  287. if (minetest.get_node_light(pos, 0.5) or 0) < 13 then
  288. return false
  289. else
  290. return true -- Keep trying.
  291. end
  292. end
  293. local density = flowers.flora_density_for_surface({x=pos.x, y=pos.y-1, z=pos.z})
  294. local pos0 = vector.subtract(pos, 4)
  295. local pos1 = vector.add(pos, 4)
  296. if #minetest.find_nodes_in_area(pos0, pos1, "group:flora") > density then
  297. return false -- Max flora reached.
  298. end
  299. local soils = minetest.find_nodes_in_area_under_air(pos0, pos1, "group:soil")
  300. if #soils > 0 then
  301. local seedling = soils[math_random(1, #soils)]
  302. local seedling_above = {x=seedling.x, y=seedling.y+1, z=seedling.z}
  303. local light = minetest.get_node_light(seedling_above) or 0
  304. if light < 13 then
  305. -- Is this just a daytime thing?
  306. if (minetest.get_node_light(seedling_above, 0.5) or 0) < 13 then
  307. return false
  308. else
  309. return true -- Keep trying.
  310. end
  311. end
  312. -- Desert sand is in the soil group.
  313. if minetest.get_node(seedling).name == "default:desert_sand" then
  314. return false
  315. end
  316. minetest.add_node(seedling_above, {name = node.name, param2 = node.param2})
  317. return true
  318. end
  319. return false
  320. end
  321. -- Indexed array.
  322. flowers.mushroom_surfaces = {
  323. "default:dirt",
  324. "rackstone:dauthsand",
  325. "group:soil",
  326. "group:tree",
  327. -- We disable these because they are much too common.
  328. -- Mushroom farms would be too easy to make, especially during a cave survival challenge.
  329. --"group:cavern_soil",
  330. --"darkage:silt",
  331. --"darkage:mud",
  332. }
  333. flowers.mushroom_nodes = {
  334. "flowers:mushroom_red",
  335. "flowers:mushroom_brown",
  336. "cavestuff:mycena",
  337. "cavestuff:fungus",
  338. }
  339. flowers.mushroom_mintime = 60*3
  340. flowers.mushroom_maxtime = 60*30
  341. function flowers.surface_can_spawn_mushroom(pos)
  342. local name = minetest.get_node(pos).name
  343. local nodes = flowers.mushroom_surfaces
  344. for i=1, #nodes do
  345. if string.find(nodes[i], "^group:") then
  346. local group = string.sub(nodes[i], 7)
  347. if minetest.get_item_group(name, group) ~= 0 then
  348. return true
  349. end
  350. elseif nodes[i] == name then
  351. return true
  352. end
  353. end
  354. return false
  355. end
  356. function flowers.on_mushroom_construct(pos)
  357. if flowers.surface_can_spawn_mushroom({x=pos.x, y=pos.y-1, z=pos.z}) then
  358. minetest.get_node_timer(pos):start(math_random(flowers.mushroom_mintime, flowers.mushroom_maxtime))
  359. end
  360. end
  361. function flowers.on_mushroom_destruct(pos)
  362. -- Notify nearby mushrooms.
  363. local minp = {x=pos.x-2, y=pos.y-2, z=pos.z-2}
  364. local maxp = {x=pos.x+2, y=pos.y+1, z=pos.z+2}
  365. local mushrooms = minetest.find_nodes_in_area_under_air(minp, maxp, flowers.mushroom_nodes)
  366. if mushrooms and #mushrooms > 0 then
  367. for i=1, #mushrooms do
  368. minetest.get_node_timer(mushrooms[i]):start(math_random(flowers.mushroom_mintime, flowers.mushroom_maxtime))
  369. end
  370. end
  371. end
  372. function flowers.on_mushroom_timer(pos, elapsed)
  373. --minetest.chat_send_player("MustTest", "Mushroom timer @ " .. minetest.pos_to_string(pos) .. "!")
  374. local node = minetest.get_node(pos)
  375. if flowers.mushroom_spread(pos, node) then
  376. minetest.get_node_timer(pos):start(math_random(flowers.mushroom_mintime, flowers.mushroom_maxtime))
  377. else
  378. -- Else timer should stop, cannot grow anymore.
  379. minetest.get_node_timer(pos):stop()
  380. end
  381. end
  382. function flowers.on_mushroom_punch(pos, node, puncher, pt)
  383. if flowers.surface_can_spawn_mushroom({x=pos.x, y=pos.y-1, z=pos.z}) then
  384. minetest.get_node_timer(pos):start(math_random(flowers.mushroom_mintime, flowers.mushroom_maxtime))
  385. end
  386. end
  387. if not flowers.reg2 then
  388. --
  389. -- Mushrooms
  390. --
  391. local eat_mushroom = minetest.item_eat(1)
  392. local function mushroom_poison(pname, step)
  393. local msg = "# Server: <" .. rename.gpn(pname) .. "> ate a mushroom. Desperate!"
  394. hb4.delayed_harm({name=pname, step=step, min=1, max=1, msg=msg, poison=true})
  395. end
  396. minetest.register_node("flowers:mushroom_red", {
  397. description = "Red Mushroom",
  398. tiles = {"flowers_mushroom_red.png"},
  399. inventory_image = "flowers_mushroom_red.png",
  400. wield_image = "flowers_mushroom_red.png",
  401. drawtype = "plantlike",
  402. paramtype = "light",
  403. sunlight_propagates = true,
  404. walkable = false,
  405. buildable_to = true,
  406. groups = utility.dig_groups("plant", {attached_node = 1, flammable = 1}),
  407. sounds = default.node_sound_leaves_defaults(),
  408. movement_speed_multiplier = default.SLOW_SPEED_PLANTS,
  409. on_use = function(itemstack, user, pointed_thing)
  410. if not user or not user:is_player() then return end
  411. minetest.after(1, mushroom_poison, user:get_player_name(), 5)
  412. return eat_mushroom(itemstack, user, pointed_thing)
  413. end,
  414. selection_box = {
  415. type = "fixed",
  416. fixed = {-0.3, -0.5, -0.3, 0.3, 0, 0.3}
  417. },
  418. on_construct = function(...)
  419. return flowers.on_mushroom_construct(...)
  420. end,
  421. on_destruct = function(...)
  422. return flowers.on_mushroom_destruct(...)
  423. end,
  424. on_timer = function(...)
  425. return flowers.on_mushroom_timer(...)
  426. end,
  427. on_punch = function(...)
  428. return flowers.on_mushroom_punch(...)
  429. end,
  430. })
  431. minetest.register_node("flowers:mushroom_brown", {
  432. description = "Brown Mushroom",
  433. tiles = {"flowers_mushroom_brown.png"},
  434. inventory_image = "flowers_mushroom_brown.png",
  435. wield_image = "flowers_mushroom_brown.png",
  436. drawtype = "plantlike",
  437. paramtype = "light",
  438. sunlight_propagates = true,
  439. walkable = false,
  440. buildable_to = true,
  441. groups = utility.dig_groups("plant", {attached_node = 1, flammable = 1}),
  442. sounds = default.node_sound_leaves_defaults(),
  443. on_use = minetest.item_eat(1),
  444. selection_box = {
  445. type = "fixed",
  446. fixed = {-0.3, -0.5, -0.3, 0.3, 0, 0.3}
  447. },
  448. movement_speed_multiplier = default.SLOW_SPEED_PLANTS,
  449. on_construct = function(...)
  450. return flowers.on_mushroom_construct(...)
  451. end,
  452. on_destruct = function(...)
  453. return flowers.on_mushroom_destruct(...)
  454. end,
  455. on_timer = function(...)
  456. return flowers.on_mushroom_timer(...)
  457. end,
  458. on_punch = function(...)
  459. return flowers.on_mushroom_punch(...)
  460. end,
  461. })
  462. flowers.reg2 = true
  463. end
  464. -- Called by the bonemeal mod.
  465. -- Returns 'true' or 'false' to indicate if a mushroom was spawned.
  466. function flowers.mushroom_spread(pos, node)
  467. if minetest.get_node_light(pos, nil) == 15 then
  468. minetest.remove_node(pos)
  469. return false
  470. end
  471. local minp = {x=pos.x-2, y=pos.y-2, z=pos.z-2}
  472. local maxp = {x=pos.x+2, y=pos.y+1, z=pos.z+2}
  473. local dirt = minetest.find_nodes_in_area_under_air(minp, maxp, flowers.mushroom_surfaces)
  474. if not dirt or #dirt == 0 then
  475. return false
  476. end
  477. local randp = dirt[math_random(1, #dirt)]
  478. local airp = {x=randp.x, y=randp.y+1, z=randp.z}
  479. local airn = minetest.get_node_or_nil(airp)
  480. if not airn or airn.name ~= "air" then
  481. return false
  482. end
  483. -- Mushrooms grow in nether regardless of light level.
  484. if pos.y < -25000 then
  485. minetest.add_node(airp, {name = node.name})
  486. return true
  487. end
  488. -- Otherwise, check light-level before growing.
  489. if minetest.get_node_light(pos, 0.5) <= 7 and
  490. minetest.get_node_light(airp, 0.5) <= 7 then
  491. minetest.add_node(airp, {name = node.name})
  492. return true
  493. end
  494. return false
  495. end
  496. if not flowers.reg3 then
  497. -- These old mushroom related nodes can be simplified now.
  498. minetest.register_alias("flowers:mushroom_spores_brown", "flowers:mushroom_brown")
  499. minetest.register_alias("flowers:mushroom_spores_red", "flowers:mushroom_red")
  500. minetest.register_alias("flowers:mushroom_fertile_brown", "flowers:mushroom_brown")
  501. minetest.register_alias("flowers:mushroom_fertile_red", "flowers:mushroom_red")
  502. minetest.register_alias("mushroom:brown_natural", "flowers:mushroom_brown")
  503. minetest.register_alias("mushroom:red_natural", "flowers:mushroom_red")
  504. --
  505. -- Waterlily
  506. --
  507. minetest.register_node("flowers:waterlily", {
  508. description = "Waterlily",
  509. drawtype = "nodebox",
  510. paramtype = "light",
  511. paramtype2 = "facedir",
  512. -- Horizontal rotation only!
  513. on_rotate = screwdriver.rotate_simple,
  514. tiles = {"flowers_waterlily.png", "flowers_waterlily_bottom.png"},
  515. inventory_image = "flowers_waterlily.png",
  516. wield_image = "flowers_waterlily.png",
  517. liquids_pointable = true,
  518. walkable = false,
  519. buildable_to = true,
  520. sunlight_propagates = true,
  521. floodable = true,
  522. -- Lily does not count as flora, it has special handling.
  523. groups = utility.dig_groups("plant", {flower = 1, flammable = 1}),
  524. sounds = default.node_sound_leaves_defaults(),
  525. node_placement_prediction = "",
  526. node_box = {
  527. type = "fixed",
  528. fixed = {-0.5, -31 / 64, -0.5, 0.5, -15 / 32, 0.5},
  529. },
  530. selection_box = {
  531. type = "fixed",
  532. fixed = {-0.5, -31 / 64, -0.5, 0.5, -15 / 32, 0.5},
  533. },
  534. on_place = function(itemstack, placer, pointed_thing)
  535. local pos = pointed_thing.above
  536. local node = minetest.get_node(pointed_thing.under).name
  537. local def = minetest.reg_ns_nodes[node]
  538. local player_name = placer:get_player_name()
  539. -- Lilies are placeable in any water.
  540. -- They only grow further in regular water sources.
  541. if def and def.liquidtype == "source" and
  542. minetest.get_item_group(node, "water") > 0 then
  543. if not minetest.is_protected(pos, player_name) then
  544. minetest.add_node(pos, {name = "flowers:waterlily",
  545. param2 = math_random(0, 3)})
  546. --if not minetest.setting_getbool("creative_mode") then
  547. itemstack:take_item()
  548. --end
  549. else
  550. minetest.chat_send_player(player_name, "# Server: Position is protected.")
  551. minetest.record_protection_violation(pos, player_name)
  552. end
  553. end
  554. return itemstack
  555. end,
  556. on_construct = function(...)
  557. return flowers.on_lily_construct(...)
  558. end,
  559. on_destruct = function(...)
  560. return flowers.on_lily_destruct(...)
  561. end,
  562. on_timer = function(...)
  563. return flowers.on_lily_timer(...)
  564. end,
  565. on_punch = function(...)
  566. return flowers.on_lily_punch(...)
  567. end,
  568. })
  569. minetest.register_node("flowers:lilyspawner", {
  570. drawtype = "airlike",
  571. description = "Lily Spawner (Please Report to Admin)",
  572. paramtype = "light",
  573. sunlight_propagates = true,
  574. walkable = false,
  575. pointable = false,
  576. groups = {immovable = 1},
  577. climbable = false,
  578. buildable_to = true,
  579. floodable = true,
  580. drop = "",
  581. on_construct = function(...)
  582. flowers.on_lily_construct(...)
  583. end,
  584. on_timer = function(pos, elapsed)
  585. -- Always remove node, even if spawn unsuccessful.
  586. minetest.remove_node(pos)
  587. if minetest.find_node_near(pos, 3, "group:melt_around") then
  588. flowers.lily_spread(pos)
  589. end
  590. end,
  591. on_finish_collapse = function(pos, node)
  592. minetest.remove_node(pos)
  593. end,
  594. on_collapse_to_entity = function(pos, node)
  595. -- Do nothing.
  596. end,
  597. })
  598. flowers.reg3 = true
  599. end
  600. -- Make mod reloadable.
  601. if not flowers.reg4 then
  602. local c = "flowers:core"
  603. local f = flowers.modpath .. "/init.lua"
  604. reload.register_file(c, f, false)
  605. flowers.reg4 = true
  606. end
  607. function flowers.create_lilyspawner_near(pos)
  608. local water = minetest.find_node_near(pos, 3, "default:water_source")
  609. if water then
  610. water.y = water.y + 1
  611. if minetest.get_node(water).name == "air" then
  612. if not minetest.find_node_near(pos, 2, "group:cold") then
  613. minetest.add_node(water, {name="flowers:lilyspawner"})
  614. return true
  615. end
  616. end
  617. end
  618. return false
  619. end
  620. function flowers.lily_density_for_pos(pos)
  621. local cold = 0
  622. if minetest.find_node_near(pos, 2, {
  623. "group:snow",
  624. "group:snowy",
  625. "group:ice",
  626. "group:cold",
  627. }) then
  628. cold = -6
  629. end
  630. -- Heat makes lilies grow denser.
  631. local heat = 0
  632. if minetest.find_node_near(pos, 3, "group:melt_around") then
  633. heat = 1
  634. end
  635. -- Minerals improve lily growth.
  636. local minerals = 0
  637. if minetest.find_node_near(pos, 3, "glowstone:minerals") then
  638. minerals = 1
  639. end
  640. -- Calc lily density.
  641. return 7 + minerals + heat + cold
  642. end
  643. flowers.lily_mintime = 60*2
  644. flowers.lily_maxtime = 60*15
  645. function flowers.surface_can_spawn_lily(pos)
  646. local name = minetest.get_node(pos).name
  647. if name == "default:water_source" then
  648. return true
  649. end
  650. return false
  651. end
  652. -- This is called for both lily and lilyspawner.
  653. function flowers.on_lily_construct(pos)
  654. if flowers.surface_can_spawn_lily({x=pos.x, y=pos.y-1, z=pos.z}) then
  655. minetest.get_node_timer(pos):start(math_random(flowers.lily_mintime, flowers.lily_maxtime))
  656. end
  657. end
  658. function flowers.on_lily_destruct(pos)
  659. -- Notify nearby lilies.
  660. local minp = vector.subtract(pos, 4)
  661. local maxp = vector.add(pos, 4)
  662. local lilies = minetest.find_nodes_in_area(minp, maxp, "flowers:waterlily")
  663. if lilies and #lilies > 0 then
  664. for i=1, #lilies do
  665. minetest.get_node_timer(lilies[i]):start(math_random(flowers.lily_mintime, flowers.lily_maxtime))
  666. end
  667. end
  668. end
  669. function flowers.on_lily_timer(pos, elapsed)
  670. --minetest.chat_send_player("MustTest", "Lily timer @ " .. minetest.pos_to_string(pos) .. "!")
  671. if flowers.lily_spread(pos) then
  672. minetest.get_node_timer(pos):start(math_random(flowers.lily_mintime, flowers.lily_maxtime))
  673. else
  674. -- Else timer should stop, cannot grow anymore.
  675. minetest.get_node_timer(pos):stop()
  676. end
  677. end
  678. function flowers.on_lily_punch(pos, node, puncher, pt)
  679. if flowers.surface_can_spawn_lily({x=pos.x, y=pos.y-1, z=pos.z}) then
  680. minetest.get_node_timer(pos):start(math_random(flowers.lily_mintime, flowers.lily_maxtime))
  681. end
  682. end
  683. -- This is called from lilyspawner and lily.
  684. function flowers.lily_spread(pos)
  685. if not flowers.surface_can_spawn_lily({x=pos.x, y=pos.y-1, z=pos.z}) then
  686. return false
  687. end
  688. local light = minetest.get_node_light(pos) or 0
  689. if light < 13 then
  690. -- Is this just a daytime thing?
  691. if (minetest.get_node_light(pos, 0.5) or 0) < 13 then
  692. return false
  693. else
  694. return true -- Keep trying.
  695. end
  696. end
  697. local density = flowers.lily_density_for_pos(pos)
  698. local pos0 = vector.subtract(pos, 4)
  699. local pos1 = vector.add(pos, 4)
  700. if #minetest.find_nodes_in_area(pos0, pos1, "flowers:waterlily") > density then
  701. return false -- Max lilies reached.
  702. end
  703. local water = minetest.find_nodes_in_area_under_air(pos0, pos1, "default:water_source")
  704. if #water > 0 then
  705. local growpos = water[math_random(1, #water)]
  706. growpos.y = growpos.y + 1
  707. local light = minetest.get_node_light(growpos) or 0
  708. if light < 13 then
  709. -- Is this just a daytime thing?
  710. if (minetest.get_node_light(growpos, 0.5) or 0) < 13 then
  711. return false
  712. else
  713. return true -- Keep trying.
  714. end
  715. end
  716. minetest.add_node(growpos, {name="flowers:waterlily", param2=math_random(0, 3)})
  717. return true
  718. end
  719. return false
  720. end