node_def.lua 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. gourds.register_gourd = function(def)
  2. local base_speed = def.base_speed
  3. local root_name = "gourds:"..def.name.."_vine_root"
  4. local vine_name = "gourds:"..def.name.."_vine"
  5. local dead_vine_name = "gourds:dead_"..def.name.."_vine"
  6. local vine_name_flowers = "gourds:"..def.name.."_vine_with_flowers"
  7. local vine_group = "group:"..def.name.."_vine"
  8. local rotting_fruit_name = "gourds:rotting_"..def.name
  9. local ripe_fruit_name = "gourds:"..def.name.."_8"
  10. local growing_fruit_group = "group:growing_"..def.name
  11. for i = 1,7 do
  12. local n = 0.1 + (.1 * i)
  13. minetest.register_node("gourds:"..def.name.."_"..i, {
  14. description = "Unripe "..def.desc,
  15. paramtype = "light",
  16. drawtype = "nodebox",
  17. drop = "",
  18. tiles = {def.textures.unripe_fruit},
  19. node_box = {
  20. type = "fixed",
  21. fixed = {
  22. {-n/2, -0.5, -n/2, n/2, -0.5 + n, n/2}
  23. },
  24. },
  25. groups = {choppy=3, ["growing_"..def.name] = i, [def.name.."_gourd"] = 1, flammable=3, not_in_creative_inventory=1, plant=1 },
  26. sounds = default.node_sound_leaves_defaults(),
  27. })
  28. end
  29. minetest.register_node(ripe_fruit_name, {
  30. description = "Ripe "..def.desc,
  31. paramtype = "light",
  32. drawtype = "nodebox",
  33. tiles = {def.textures.ripe_fruit},
  34. node_box = {
  35. type = "fixed",
  36. fixed = {
  37. {-0.4, -0.5, -0.4, 0.4, 0.3, 0.4}
  38. },
  39. },
  40. groups = {choppy=3, flammable=3, [def.name.."_gourd"]=2, plant=1 },
  41. sounds = default.node_sound_leaves_defaults(),
  42. })
  43. minetest.register_node(rotting_fruit_name, {
  44. description = "Rotting "..def.desc,
  45. paramtype = "light",
  46. drawtype = "nodebox",
  47. drop = "",
  48. tiles = {def.textures.rotting_fruit},
  49. node_box = {
  50. type = "fixed",
  51. fixed = {
  52. {-0.25, -0.5, -0.25, 0.25, 0.0, 0.25}
  53. },
  54. },
  55. groups = {choppy=3, [def.name.."_gourd"] = 3, flammable=3, plant=1 },
  56. sounds = default.node_sound_leaves_defaults(),
  57. })
  58. minetest.register_node(root_name, {
  59. description = def.desc.." Vine Root",
  60. drawtype = "plantlike",
  61. --waving = 1,
  62. stack_max = 20,
  63. tiles = {def.textures.vine_root},
  64. -- inventory_image = "default_acacia_leaves.png",
  65. -- wield_image = "default_acacia_leaves.png",
  66. paramtype = "light",
  67. paramtype2 = "meshoptions",
  68. place_param2 = 4,
  69. sunlight_propagates = true,
  70. walkable = false,
  71. buildable_to = true,
  72. groups = {snappy = 3, flammable = 3, attached_node = 1},
  73. sounds = default.node_sound_leaves_defaults(),
  74. selection_box = {
  75. type = "fixed",
  76. fixed = {-8 / 16, -0.5, -8 / 16, 8 / 16, 4 / 16, 8 / 16},
  77. },
  78. })
  79. minetest.register_node(vine_name, {
  80. description = def.desc.." Vines",
  81. drawtype = "nodebox",
  82. paramtype = "light",
  83. paramtype2 = "leveled",
  84. tiles = {def.textures.vine},
  85. leveled = 2,
  86. walkable = false, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled
  87. climbable = true, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled
  88. buildable_to = true,
  89. groups = {snappy = 3, [def.name.."_vine"] = 1 },
  90. sounds = default.node_sound_water_defaults(),
  91. node_box = {
  92. type = "leveled",
  93. fixed = {
  94. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, -- NodeBox1
  95. }
  96. }
  97. })
  98. minetest.register_node(vine_name_flowers, {
  99. description = def.desc.." Vines",
  100. drawtype = "nodebox",
  101. paramtype = "light",
  102. paramtype2 = "leveled",
  103. leveled = 2,
  104. tiles = {def.textures.vine_flowers},
  105. walkable = false, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled
  106. climbable = true, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled
  107. buildable_to = true,
  108. groups = {snappy = 3, [def.name.."_vine"] = 1 },
  109. sounds = default.node_sound_water_defaults(),
  110. node_box = {
  111. type = "leveled",
  112. fixed = {
  113. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, -- NodeBox1
  114. }
  115. }
  116. })
  117. minetest.register_node(dead_vine_name, {
  118. description = "Dead "..def.desc.." Vines",
  119. drawtype = "nodebox",
  120. paramtype = "light",
  121. paramtype2 = "leveled",
  122. tiles = {def.textures.dead_vine},
  123. leveled = 2,
  124. walkable = false, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled
  125. climbable = true, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled
  126. buildable_to = true,
  127. groups = {snappy = 3, },
  128. sounds = default.node_sound_water_defaults(),
  129. node_box = {
  130. type = "leveled",
  131. fixed = {
  132. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, -- NodeBox1
  133. }
  134. }
  135. })
  136. local function swap_leveled(pos, name)
  137. local lvl = minetest.get_node_level(pos)
  138. minetest.set_node(pos, {name=name})
  139. minetest.set_node_level(pos, lvl)
  140. end
  141. -- vines spawn near the root
  142. minetest.register_abm({
  143. nodenames = {root_name},
  144. interval = 5,
  145. chance = base_speed * 0.25,
  146. action = function(pos)
  147. local air_nodes = minetest.find_nodes_in_area(
  148. {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1},
  149. {x=pos.x + 1, y=pos.y + 1, z=pos.z + 1},
  150. "air"
  151. )
  152. local off = math.random(1, #air_nodes)
  153. for i = 1,#air_nodes do
  154. --local theirlevel = minetest.get_node_level(fp)
  155. local fp = air_nodes[((i + off) % #air_nodes) + 1]
  156. local bp = {x=fp.x, y=fp.y - 1, z=fp.z}
  157. local bn = minetest.get_node(bp)
  158. if minetest.get_item_group(bn.name, "soil") > 0 then
  159. minetest.set_node(fp, {name = vine_name})
  160. minetest.set_node_level(fp, 10)
  161. return
  162. end
  163. end
  164. end
  165. })
  166. -- vines near the root will grow
  167. minetest.register_abm({
  168. nodenames = {vine_name},
  169. neighbors = {root_name},
  170. interval = 10,
  171. chance = base_speed * 5,
  172. action = function(pos)
  173. local mylevel = minetest.get_node_level(pos)
  174. if minetest.get_node_light(pos) > 10 then
  175. minetest.add_node_level(pos, 16)
  176. end
  177. end
  178. })
  179. -- vines near taller vines will grow
  180. minetest.register_abm({
  181. nodenames = {vine_group},
  182. neighbors = {vine_group},
  183. interval = 5,
  184. chance = base_speed * 5,
  185. action = function(pos)
  186. local mylevel = minetest.get_node_level(pos)
  187. local vine_nodes = minetest.find_nodes_in_area(
  188. {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1},
  189. {x=pos.x + 1, y=pos.y + 1, z=pos.z + 1},
  190. vine_group
  191. )
  192. local highest_lvl = 0
  193. for i = 1,#vine_nodes do
  194. local l = minetest.get_node_level(vine_nodes[i])
  195. if l > highest_lvl then
  196. highest_lvl = l
  197. end
  198. end
  199. if highest_lvl > mylevel + 3 then
  200. minetest.set_node_level(pos, math.min(highest_lvl - 1, math.min(mylevel + 5, 64)))
  201. end
  202. end
  203. })
  204. -- new vines grow near tall vines
  205. minetest.register_abm({
  206. nodenames = {vine_group},
  207. neighbors = {"air"},
  208. interval = 10,
  209. chance = base_speed * 10,
  210. action = function(pos)
  211. local mylevel = minetest.get_node_level(pos)
  212. if mylevel < 16 then
  213. return
  214. end
  215. local vine_nodes = minetest.find_nodes_in_area(
  216. {x=pos.x - 2, y=pos.y - 2, z=pos.z - 2},
  217. {x=pos.x + 2, y=pos.y + 2, z=pos.z + 2},
  218. vine_group
  219. )
  220. local avg = {x=0, y=0, z=0}
  221. for _,n in ipairs(vine_nodes) do
  222. avg.x = avg.x + n.x
  223. avg.y = avg.y + n.y
  224. avg.z = avg.z + n.z
  225. end
  226. avg.x = avg.x / #vine_nodes
  227. avg.y = avg.y / #vine_nodes
  228. avg.z = avg.z / #vine_nodes
  229. --local dir = vector.subtract(pos, avg)
  230. local air_nodes = minetest.find_nodes_in_area(
  231. {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1},
  232. {x=pos.x + 1, y=pos.y + 1, z=pos.z + 1},
  233. "air"
  234. )
  235. local potentials = {}
  236. local off = math.random(1, #air_nodes)
  237. for i = 1,#air_nodes do
  238. --local theirlevel = minetest.get_node_level(fp)
  239. local fp = air_nodes[((i + off) % #air_nodes) + 1]
  240. local bp = {x=fp.x, y=fp.y - 1, z=fp.z}
  241. --print(minetest.pos_to_string(fp))
  242. local bn = minetest.get_node(bp)
  243. if minetest.get_item_group(bn.name, "soil") > 0 then
  244. local dd = vector.distance(fp, avg)
  245. if dd >2 then
  246. table.insert(potentials, {d=dd, pos=fp})
  247. end
  248. end
  249. end
  250. --print(dump2(potentials))
  251. if #potentials == 0 then
  252. return
  253. end
  254. --table.sort(potentials, function(a,b) return b.d < a.d end)
  255. minetest.set_node(potentials[1].pos, {name = vine_name})
  256. minetest.set_node_level(potentials[1].pos, 1)
  257. end
  258. })
  259. -- vines die unless near a taller vine or a root
  260. minetest.register_abm({
  261. nodenames = {vine_group},
  262. interval = 5,
  263. chance = base_speed * 20,
  264. action = function(pos)
  265. local mylevel = minetest.get_node_level(pos)
  266. local root_nodes = minetest.find_nodes_in_area(
  267. {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1},
  268. {x=pos.x + 1, y=pos.y + 1, z=pos.z + 1},
  269. root_name
  270. )
  271. if #root_nodes > 0 then
  272. return
  273. end
  274. local vine_nodes = minetest.find_nodes_in_area(
  275. {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1},
  276. {x=pos.x + 1, y=pos.y + 1, z=pos.z + 1},
  277. vine_group
  278. )
  279. for i = 1,#vine_nodes do
  280. local l = minetest.get_node_level(vine_nodes[i])
  281. if l > mylevel then
  282. return
  283. end
  284. end
  285. minetest.set_node(pos, {name = dead_vine_name})
  286. minetest.set_node_level(pos, mylevel * .75)
  287. end
  288. })
  289. -- dead vines shrink
  290. minetest.register_abm({
  291. nodenames = {dead_vine_name},
  292. interval = 10,
  293. chance = base_speed * 1,
  294. action = function(pos)
  295. local mylevel = minetest.get_node_level(pos)
  296. mylevel = mylevel - 7
  297. if mylevel <= 0 then
  298. minetest.set_node(pos, {name="air"})
  299. else
  300. minetest.set_node_level(pos, mylevel)
  301. end
  302. end
  303. })
  304. -- some vines grow flowers
  305. minetest.register_abm({
  306. nodenames = {vine_group},
  307. interval = 16,
  308. chance = base_speed * 30,
  309. action = function(pos)
  310. local mylevel = minetest.get_node_level(pos)
  311. if minetest.get_node_light(pos) > 10 and mylevel > 5 then
  312. swap_leveled(pos, vine_name_flowers)
  313. end
  314. end
  315. })
  316. -- vines with flowers grow gourds nearby
  317. minetest.register_abm({
  318. nodenames = {vine_name_flowers},
  319. interval = 10,
  320. chance = base_speed * 20,
  321. action = function(pos)
  322. local air_nodes = minetest.find_nodes_in_area(
  323. {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1},
  324. {x=pos.x + 1, y=pos.y + 1, z=pos.z + 1},
  325. "air"
  326. )
  327. local off = math.random(1, #air_nodes)
  328. for i = 1,#air_nodes do
  329. --local theirlevel = minetest.get_node_level(fp)
  330. local fp = air_nodes[((i + off) % #air_nodes) + 1]
  331. local bp = {x=fp.x, y=fp.y - 1, z=fp.z}
  332. local bn = minetest.get_node(bp)
  333. if minetest.get_item_group(bn.name, def.grows_on) > 0 then
  334. swap_leveled(pos, vine_name)
  335. minetest.set_node(fp, {name="gourds:"..def.name.."_1"})
  336. return
  337. end
  338. end
  339. swap_leveled(pos, vine_name)
  340. end
  341. })
  342. -- gourds grow
  343. minetest.register_abm({
  344. nodenames = {"group:growing_"..def.name},
  345. interval = base_speed * 10,
  346. chance = 5,
  347. action = function(pos)
  348. local node = minetest.get_node(pos)
  349. local lvl = minetest.get_item_group(node.name, "growing_"..def.name)
  350. minetest.set_node(pos, {name="gourds:"..def.name.."_"..(lvl+1)})
  351. end
  352. })
  353. -- isolated gourds rot
  354. minetest.register_abm({
  355. nodenames = {"group:"..def.name.."_gourd"},
  356. interval = 20,
  357. chance = base_speed * 30,
  358. action = function(pos)
  359. local vine_nodes = minetest.find_nodes_in_area(
  360. {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1},
  361. {x=pos.x + 1, y=pos.y + 1, z=pos.z + 1},
  362. vine_name
  363. )
  364. if #vine_nodes > 0 then
  365. return
  366. end
  367. minetest.set_node(pos, {name=rotting_fruit_name})
  368. end
  369. })
  370. -- ripe gourds eventually rot
  371. minetest.register_abm({
  372. nodenames = {"gourds:"..def.name.."_8"},
  373. interval = 10,
  374. chance = base_speed * 20,
  375. action = function(pos)
  376. minetest.set_node(pos, {name=rotting_fruit_name})
  377. end
  378. })
  379. -- rotten gourds disappear
  380. minetest.register_abm({
  381. nodenames = {rotting_fruit_name},
  382. interval = 10,
  383. chance = base_speed * 20,
  384. action = function(pos)
  385. if math.random(50) == 1 then
  386. minetest.set_node(pos, {name=root_name, param2 = 4})
  387. else
  388. minetest.set_node(pos, {name="air"})
  389. end
  390. end
  391. })
  392. -- vine roots die eventually
  393. minetest.register_abm({
  394. nodenames = {root_name},
  395. interval = 120,
  396. chance = base_speed * 70,
  397. action = function(pos)
  398. minetest.set_node(pos, {name="air"})
  399. end
  400. })
  401. if minetest.global_exists("seasons") then
  402. -- vines die off completely in the winter
  403. -- seasons.reg_custom("spring", vine_name, vine_name)
  404. -- seasons.reg_custom("summer", vine_name, vine_name)
  405. seasons.reg_custom("fall", vine_name, dead_vine_name)
  406. seasons.reg_custom("winter", vine_name, "air")
  407. -- seasons.reg_custom("spring", vine_name_flowers, vine_name_flowers)
  408. -- seasons.reg_custom("summer", vine_name_flowers, vine_name_flowers)
  409. seasons.reg_custom("fall", vine_name_flowers, dead_vine_name)
  410. seasons.reg_custom("winter", vine_name_flowers, "air")
  411. seasons.reg_custom("winter", dead_vine_name, "air")
  412. seasons.reg_custom("winter", ripe_fruit_name, rotting_fruit_name)
  413. for i = 1,7 do
  414. seasons.reg_custom("winter", "gourds:"..def.name.."_"..i, "air")
  415. end
  416. end
  417. end