init.lua 23 KB

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