init.lua 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. bluegrass = bluegrass or {}
  2. bluegrass.modpath = minetest.get_modpath("bluegrass")
  3. -- Localize for performance.
  4. local math_random = math.random
  5. -- How often node timers for plants will tick, +/- some random value.
  6. local function tick(pos, data)
  7. if data then
  8. minetest.get_node_timer(pos):start(math_random(data.min_time, data.max_time))
  9. else
  10. minetest.get_node_timer(pos):start(math_random(166, 286))
  11. --minetest.get_node_timer(pos):start(1.0) -- Debug
  12. end
  13. end
  14. -- How often a growth failure tick is retried.
  15. local function tick_again(pos)
  16. minetest.get_node_timer(pos):start(math_random(40, 80))
  17. --minetest.get_node_timer(pos):start(1.0) -- Debug
  18. end
  19. -- Seed placement.
  20. bluegrass.place_seed = function(itemstack, placer, pointed_thing, plantname)
  21. local pt = pointed_thing
  22. -- check if pointing at a node
  23. if not pt then
  24. return itemstack
  25. end
  26. if pt.type ~= "node" then
  27. return itemstack
  28. end
  29. local under = minetest.get_node(pt.under)
  30. -- Pass through interactions to nodes that define them (like chests).
  31. do
  32. local pdef = minetest.reg_ns_nodes[under.name]
  33. if pdef and pdef.on_rightclick and not placer:get_player_control().sneak then
  34. return pdef.on_rightclick(pt.under, under, placer, itemstack, pt)
  35. end
  36. end
  37. local above = minetest.get_node(pt.above)
  38. if minetest.is_protected(pt.under, placer:get_player_name()) then
  39. minetest.record_protection_violation(pt.under, placer:get_player_name())
  40. return
  41. end
  42. if minetest.is_protected(pt.above, placer:get_player_name()) then
  43. minetest.record_protection_violation(pt.above, placer:get_player_name())
  44. return
  45. end
  46. -- return if any of the nodes is not registered
  47. if not minetest.reg_ns_nodes[under.name] then
  48. return itemstack
  49. end
  50. if not minetest.reg_ns_nodes[above.name] then
  51. return itemstack
  52. end
  53. -- check if pointing at the bottom of the node
  54. if pt.above.y ~= pt.under.y-1 then
  55. return itemstack
  56. end
  57. -- check if you can replace the node above the pointed node
  58. local ndef_above = minetest.reg_ns_nodes[above.name]
  59. if not ndef_above or not ndef_above.buildable_to then
  60. return itemstack
  61. end
  62. -- check if pointing at soil
  63. if under.name ~= "rackstone:dauthsand_stable" then
  64. return itemstack
  65. end
  66. -- add the node and remove 1 item from the itemstack
  67. -- note: use of `add_node` causes additional callbacks to run (droplift, dirtspread).
  68. minetest.add_node(pt.above, {name=plantname})
  69. tick(pt.above)
  70. itemstack:take_item()
  71. return itemstack
  72. end
  73. bluegrass.grow_plant = function(pos, elapsed)
  74. local node = minetest.get_node(pos)
  75. local name = node.name
  76. local def = minetest.reg_ns_nodes[name]
  77. if not def.next_plant then
  78. -- disable timer for fully grown plant
  79. return
  80. end
  81. -- grow seed
  82. if minetest.get_item_group(node.name, "seed") and def.fertility then
  83. local soil_node = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
  84. if not soil_node then
  85. tick_again(pos)
  86. return
  87. end
  88. -- omitted is a check for light, we assume seeds can germinate in the dark.
  89. for _, v in pairs(def.fertility) do
  90. if minetest.get_item_group(soil_node.name, v) ~= 0 then
  91. local placenode = {name = def.next_plant}
  92. if def.place_param2 then
  93. placenode.param2 = def.place_param2
  94. end
  95. minetest.swap_node(pos, placenode)
  96. if minetest.reg_ns_nodes[def.next_plant].next_plant then
  97. tick(pos)
  98. return
  99. end
  100. end
  101. end
  102. return
  103. end
  104. -- check if below soil
  105. local above = minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z})
  106. if above.name ~= "rackstone:dauthsand_stable" then
  107. -- We really shouldn't be able to get here, but we should still handle it just in case.
  108. tick_again(pos)
  109. return
  110. end
  111. local tick_data = {
  112. min_time = 300,
  113. max_time = 400,
  114. }
  115. local can_grow = false
  116. do
  117. if minetest.find_node_near(pos, 4, "group:lava") then
  118. can_grow = true
  119. end
  120. if minetest.find_node_near(pos, 2, "group:flame") then
  121. can_grow = true
  122. end
  123. end
  124. if not can_grow then
  125. tick_again(pos)
  126. return
  127. end
  128. -- Minerals nearby make bluegrass grow faster.
  129. local lava_near = minetest.find_node_near(pos, 2, "glowstone:minerals")
  130. if lava_near then
  131. tick_data.min_time = 200
  132. tick_data.max_time = 300
  133. end
  134. -- grow
  135. local placenode = {name = def.next_plant}
  136. if def.place_param2 then
  137. placenode.param2 = def.place_param2
  138. end
  139. minetest.swap_node(pos, placenode)
  140. -- new timer needed?
  141. if minetest.reg_ns_nodes[def.next_plant].next_plant then
  142. tick(pos, tick_data)
  143. end
  144. return
  145. end
  146. minetest.register_craftitem("bluegrass:bluegrass", {
  147. description = "Bluegrass Stalk (Completely Inedible)",
  148. inventory_image = "bluegrass_bluegrass.png",
  149. -- Does not rot.
  150. })
  151. minetest.register_craftitem("bluegrass:cooked", {
  152. description = "Cooked Bluegrass (Unappetizing)",
  153. inventory_image = "bluegrass_cooked.png",
  154. on_use = minetest.item_eat(1),
  155. groups = {foodrot=1},
  156. })
  157. minetest.register_craft({
  158. type = "cooking",
  159. output = "bluegrass:cooked 3",
  160. recipe = "bluegrass:bluegrass",
  161. cooktime = 2,
  162. })
  163. minetest.register_node("bluegrass:seed", {
  164. description = "Bluegrass Seed",
  165. tiles = {"bluegrass_seed.png"},
  166. wield_image = "bluegrass_seed.png",
  167. inventory_image = "bluegrass_seed.png",
  168. drawtype = "signlike",
  169. paramtype = "light",
  170. paramtype2 = "wallmounted",
  171. walkable = false,
  172. sunlight_propagates = true,
  173. selection_box = {
  174. type = "fixed",
  175. fixed = {-0.5, 5/16, -0.5, 0.5, 0.5, 0.5},
  176. },
  177. groups = utility.dig_groups("seeds", {seed = 1, hanging_node = 1, flammable = 2}),
  178. on_place = function(itemstack, placer, pointed_thing)
  179. return bluegrass.place_seed(itemstack, placer, pointed_thing, "bluegrass:seed")
  180. end,
  181. on_timer = bluegrass.grow_plant,
  182. next_plant = "bluegrass:plant_1",
  183. sounds = default.node_sound_dirt_defaults({
  184. dug = {name = "default_grass_footstep", gain = 0.2},
  185. place = {name = "default_place_node", gain = 0.25},
  186. }),
  187. })
  188. local crop_def = {
  189. drawtype = "plantlike",
  190. tiles = {"bluegrass_plant_1.png"},
  191. paramtype = "light",
  192. paramtype2 = "meshoptions",
  193. place_param2 = 2,
  194. sunlight_propagates = true,
  195. --waving = 1,
  196. walkable = false,
  197. buildable_to = true,
  198. drop = "",
  199. selection_box = {
  200. type = "fixed",
  201. fixed = {-0.5, 5/16, -0.5, 0.5, 0.5, 0.5},
  202. },
  203. groups = utility.dig_groups("crop", {
  204. flammable = 2, plant = 1, hanging_node = 1,
  205. not_in_creative_inventory = 1,
  206. }),
  207. sounds = default.node_sound_leaves_defaults(),
  208. movement_speed_multiplier = default.SLOW_SPEED_PLANTS,
  209. on_timer = bluegrass.grow_plant,
  210. }
  211. -- Stage 1.
  212. crop_def.next_plant = "bluegrass:plant_2"
  213. minetest.register_node("bluegrass:plant_1", table.copy(crop_def))
  214. -- Stage 2.
  215. crop_def.next_plant = "bluegrass:plant_3"
  216. crop_def.tiles = {"bluegrass_plant_2.png"}
  217. minetest.register_node("bluegrass:plant_2", table.copy(crop_def))
  218. -- Stage 3.
  219. crop_def.next_plant = "bluegrass:plant_4"
  220. crop_def.tiles = {"bluegrass_plant_3.png"}
  221. minetest.register_node("bluegrass:plant_3", table.copy(crop_def))
  222. -- Stage 4.
  223. crop_def.next_plant = "bluegrass:plant_5"
  224. crop_def.tiles = {"bluegrass_plant_4.png"}
  225. minetest.register_node("bluegrass:plant_4", table.copy(crop_def))
  226. -- Stage 5.
  227. crop_def.next_plant = "bluegrass:plant_6"
  228. crop_def.tiles = {"bluegrass_plant_5.png"}
  229. minetest.register_node("bluegrass:plant_5", table.copy(crop_def))
  230. -- Stage 6.
  231. crop_def.next_plant = "bluegrass:plant_7"
  232. crop_def.tiles = {"bluegrass_plant_6.png"}
  233. minetest.register_node("bluegrass:plant_6", table.copy(crop_def))
  234. -- Stage 7.
  235. crop_def.next_plant = nil
  236. crop_def.tiles = {"bluegrass_plant_7.png"}
  237. crop_def.drop = {
  238. items = {
  239. {items = {"bluegrass:bluegrass"}, rarity = 1},
  240. {items = {"bluegrass:bluegrass 2"}, rarity = 2},
  241. {items = {"bluegrass:seed"}, rarity = 2},
  242. {items = {"bluegrass:seed"}, rarity = 2},
  243. {items = {"bluegrass:seed"}, rarity = 3},
  244. }
  245. }
  246. minetest.register_node("bluegrass:plant_7", table.copy(crop_def))