nodes.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. -- It actually makes sense to build paths in your fields now, otherwise
  2. -- you'll have to constantly hoe where you step!
  3. --
  4. -- Note: not checking protection here. Griefing someone's field this way is
  5. -- "non-destructive", easy to restore.
  6. local function trample_dirt(pos, player)
  7. local meta = minetest.get_meta(pos)
  8. local count = meta:get_int("trampled")
  9. if count >= 3 then
  10. local pos_above = vector.add(pos, {x=0, y=1, z=0})
  11. local node_above = minetest.get_node(pos_above)
  12. -- Only if no plant above.
  13. if node_above.name == "air" then
  14. local node = minetest.get_node(pos)
  15. local ndef = minetest.registered_nodes[node.name]
  16. if ndef and ndef.soil and ndef.soil.base then
  17. node.name = ndef.soil.base
  18. minetest.set_node(pos, node)
  19. end
  20. else
  21. -- Something above? Let's check if it's a plant, BWHAHAHA.
  22. local ndef = minetest.registered_nodes[node_above.name]
  23. if ndef and ndef._farming_prev_plant then
  24. local pdef = minetest.registered_nodes[ndef._farming_prev_plant]
  25. if pdef then
  26. local node = minetest.get_node(pos_above)
  27. node.name = ndef._farming_prev_plant
  28. minetest.set_node(pos_above, node)
  29. -- Restart plant timer.
  30. farming.restart_timer(pos_above)
  31. end
  32. end
  33. end
  34. return
  35. end
  36. meta:set_int("trampled", count + 1)
  37. meta:mark_as_private("trampled")
  38. end
  39. local nodebox_hoedsoil = {
  40. {0, 0, 0, 16, 15, 16},
  41. {0, 15, 2, 16, 15.5, 7},
  42. {0, 15, 9, 16, 15.5, 14},
  43. }
  44. for k, v in ipairs(nodebox_hoedsoil) do
  45. for m, n in ipairs(v) do
  46. local p = nodebox_hoedsoil[k][m]
  47. p = p / 16
  48. p = p - 0.5
  49. nodebox_hoedsoil[k][m] = p
  50. end
  51. end
  52. -- Can be hoed bypassing protection.
  53. minetest.override_item("default:dirt", {
  54. soil = {
  55. base = "default:dirt",
  56. dry = "farming:soil",
  57. wet = "farming:soil_wet"
  58. }
  59. })
  60. -- Cannot be hoed if protected.
  61. minetest.override_item("default:dirt_with_grass", {
  62. soil = {
  63. base = "default:dirt_with_grass",
  64. dry = "farming:soil",
  65. wet = "farming:soil_wet"
  66. }
  67. })
  68. -- Cannot be hoed if protected.
  69. minetest.override_item("moregrass:darkgrass", {
  70. soil = {
  71. base = "moregrass:darkgrass",
  72. dry = "farming:soil",
  73. wet = "farming:soil_wet"
  74. }
  75. })
  76. -- Cannot be hoed if protected.
  77. minetest.override_item("default:dirt_with_dry_grass", {
  78. soil = {
  79. base = "default:dirt_with_dry_grass",
  80. dry = "farming:soil",
  81. wet = "farming:soil_wet"
  82. }
  83. })
  84. minetest.register_node("farming:soil", {
  85. paramtype = "light",
  86. drawtype = "nodebox",
  87. node_box = {
  88. type = "fixed",
  89. fixed = nodebox_hoedsoil,
  90. },
  91. selection_box = {
  92. type = "fixed",
  93. fixed = {
  94. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
  95. },
  96. },
  97. description = "Soil",
  98. movement_speed_multiplier = default.SLOW_SPEED,
  99. tiles = {"default_dirt.png^farming_soil.png", "default_dirt.png"},
  100. drop = "default:dirt",
  101. groups = utility.dig_groups("dirt", {not_in_creative_inventory = 1, dirt_type = 1, non_raw_dirt_type = 1, non_sterile_dirt_type = 1, hoed_dirt_type = 1, soil = 2, grassland = 1, falling_node = 1, field = 1, want_notify = 1}),
  102. sounds = default.node_sound_dirt_defaults(),
  103. soil = {
  104. base = "default:dirt",
  105. dry = "farming:soil",
  106. wet = "farming:soil_wet"
  107. },
  108. on_notify = function(pos, other)
  109. if other.y == pos.y+1 then
  110. farming.notify_soil_single(pos)
  111. end
  112. end,
  113. on_timer = function(...)
  114. farming.on_soil_notify(...)
  115. end,
  116. on_finish_collapse = function(pos, node)
  117. minetest.swap_node(pos, {name="default:dirt"})
  118. end,
  119. on_player_walk_over = trample_dirt,
  120. _on_bonemeal_use = function(pos, node, user, itemstack)
  121. local meta = minetest.get_meta(pos)
  122. meta:set_int("soil_fatigue", 0)
  123. meta:set_string("last_seed", "")
  124. itemstack:take_item()
  125. return itemstack
  126. end,
  127. })
  128. minetest.register_node("farming:soil_wet", {
  129. paramtype = "light",
  130. drawtype = "nodebox",
  131. node_box = {
  132. type = "fixed",
  133. fixed = nodebox_hoedsoil,
  134. },
  135. selection_box = {
  136. type = "fixed",
  137. fixed = {
  138. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
  139. },
  140. },
  141. description = "Wet Soil",
  142. movement_speed_multiplier = default.SLOW_SPEED,
  143. tiles = {"default_dirt.png^farming_soil_wet.png", "default_dirt.png^farming_soil_wet_side.png"},
  144. drop = "default:dirt",
  145. groups = utility.dig_groups("dirt", {not_in_creative_inventory = 1, dirt_type = 1, non_raw_dirt_type = 1, non_sterile_dirt_type = 1, hoed_dirt_type = 1, soil = 3, wet = 1, grassland = 1, falling_node = 1, field = 1, want_notify = 1}),
  146. sounds = default.node_sound_dirt_defaults(),
  147. soil = {
  148. base = "default:dirt",
  149. dry = "farming:soil",
  150. wet = "farming:soil_wet"
  151. },
  152. on_notify = function(pos, other)
  153. if other.y == pos.y+1 then
  154. farming.notify_soil_single(pos)
  155. end
  156. end,
  157. on_timer = function(...)
  158. farming.on_soil_notify(...)
  159. end,
  160. on_finish_collapse = function(pos, node)
  161. minetest.swap_node(pos, {name="default:dirt"})
  162. end,
  163. on_player_walk_over = trample_dirt,
  164. _on_bonemeal_use = function(pos, node, user, itemstack)
  165. local meta = minetest.get_meta(pos)
  166. meta:set_int("soil_fatigue", 0)
  167. meta:set_string("last_seed", "")
  168. itemstack:take_item()
  169. return itemstack
  170. end,
  171. })
  172. -- Can be hoed bypassing protection.
  173. minetest.override_item("default:desert_sand", {
  174. soil = {
  175. base = "default:desert_sand",
  176. dry = "farming:desert_sand_soil",
  177. wet = "farming:desert_sand_soil_wet"
  178. }
  179. })
  180. minetest.register_node("farming:desert_sand_soil", {
  181. paramtype = "light",
  182. drawtype = "nodebox",
  183. node_box = {
  184. type = "fixed",
  185. fixed = nodebox_hoedsoil,
  186. },
  187. selection_box = {
  188. type = "fixed",
  189. fixed = {
  190. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
  191. },
  192. },
  193. description = "Desert Sand Soil",
  194. movement_speed_multiplier = default.SLOW_SPEED,
  195. drop = "default:desert_sand",
  196. tiles = {"farming_desert_sand_soil.png^[transformR90", "default_desert_sand.png"},
  197. groups = utility.dig_groups("sand", {not_in_creative_inventory = 1, falling_node = 1, sand = 1, soil = 2, desert = 1, field = 1, fall_damage_add_percent=-20, want_notify = 1}),
  198. sounds = default.node_sound_sand_defaults(),
  199. soil = {
  200. base = "default:desert_sand",
  201. dry = "farming:desert_sand_soil",
  202. wet = "farming:desert_sand_soil_wet"
  203. },
  204. on_notify = function(pos, other)
  205. if other.y == pos.y+1 then
  206. farming.notify_soil_single(pos)
  207. end
  208. end,
  209. on_timer = function(...)
  210. farming.on_soil_notify(...)
  211. end,
  212. on_finish_collapse = function(pos, node)
  213. minetest.swap_node(pos, {name="default:desert_sand"})
  214. end,
  215. on_player_walk_over = trample_dirt,
  216. _on_bonemeal_use = function(pos, node, user, itemstack)
  217. local meta = minetest.get_meta(pos)
  218. meta:set_int("soil_fatigue", 0)
  219. meta:set_string("last_seed", "")
  220. itemstack:take_item()
  221. return itemstack
  222. end,
  223. })
  224. minetest.register_node("farming:desert_sand_soil_wet", {
  225. paramtype = "light",
  226. drawtype = "nodebox",
  227. node_box = {
  228. type = "fixed",
  229. fixed = nodebox_hoedsoil,
  230. },
  231. selection_box = {
  232. type = "fixed",
  233. fixed = {
  234. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
  235. },
  236. },
  237. description = "Wet Desert Sand Soil",
  238. movement_speed_multiplier = default.SLOW_SPEED,
  239. drop = "default:desert_sand",
  240. tiles = {"farming_desert_sand_soil_wet.png^[transformR90", "farming_desert_sand_soil_wet_side.png"},
  241. groups = utility.dig_groups("sand", {falling_node = 1, sand = 1, not_in_creative_inventory = 1, soil = 3, wet = 1, desert = 1, field = 1, fall_damage_add_percent=-20, want_notify = 1}),
  242. sounds = default.node_sound_sand_defaults(),
  243. soil = {
  244. base = "default:desert_sand",
  245. dry = "farming:desert_sand_soil",
  246. wet = "farming:desert_sand_soil_wet"
  247. },
  248. on_notify = function(pos, other)
  249. if other.y == pos.y+1 then
  250. farming.notify_soil_single(pos)
  251. end
  252. end,
  253. on_timer = function(...)
  254. farming.on_soil_notify(...)
  255. end,
  256. on_finish_collapse = function(pos, node)
  257. minetest.swap_node(pos, {name="default:desert_sand"})
  258. end,
  259. on_player_walk_over = trample_dirt,
  260. _on_bonemeal_use = function(pos, node, user, itemstack)
  261. local meta = minetest.get_meta(pos)
  262. meta:set_int("soil_fatigue", 0)
  263. meta:set_string("last_seed", "")
  264. itemstack:take_item()
  265. return itemstack
  266. end,
  267. })
  268. minetest.register_node("farming:straw", {
  269. description = "Straw\n\nA soft material to fall on.",
  270. tiles = {"farming_straw.png"},
  271. is_ground_content = false,
  272. groups = utility.dig_groups("straw", {flammable=4, fall_damage_add_percent=-30, falling_node=1}),
  273. sounds = default.node_sound_leaves_defaults(),
  274. movement_speed_multiplier = default.SLOW_SPEED,
  275. })
  276. minetest.register_node("farming:straw_weathered", {
  277. description = "Weathered Straw\n\nA soft material to fall on.",
  278. tiles = {"farming_straw_weathered.png"},
  279. is_ground_content = false,
  280. groups = utility.dig_groups("straw", {flammable=5, fall_damage_add_percent=-30, falling_node=1}),
  281. sounds = default.node_sound_leaves_defaults(),
  282. movement_speed_multiplier = default.SLOW_SPEED,
  283. })
  284. -- Translate timer callback to update callback.
  285. function farming.on_soil_notify(pos, elapsed)
  286. local node = minetest.get_node(pos)
  287. farming.on_update_soil(pos, node)
  288. end
  289. -- Called whenever soil is notified to update via timer.
  290. -- This was originally an ABM function.
  291. function farming.on_update_soil(pos, node)
  292. local n_def = minetest.reg_ns_nodes[node.name] or nil
  293. local wet = n_def.soil.wet or nil
  294. local base = n_def.soil.base or nil
  295. local dry = n_def.soil.dry or nil
  296. if not n_def or not n_def.soil or not wet or not base or not dry then
  297. return
  298. end
  299. pos.y = pos.y + 1
  300. local nn = minetest.get_node_or_nil(pos)
  301. if not nn or not nn.name then
  302. return
  303. end
  304. local nn_def = minetest.reg_ns_nodes[nn.name] or nil
  305. pos.y = pos.y - 1
  306. if not nn_def or (nn_def.walkable and minetest.get_item_group(nn.name, "plant") == 0) then
  307. minetest.add_node(pos, {name = base})
  308. return
  309. end
  310. -- check if there is water nearby
  311. local wet_lvl = minetest.get_item_group(node.name, "wet")
  312. -- Distance needed for water increased from 3 to 4 meters, to compensate for dirt being a falling node.
  313. -- [MustTest]
  314. local radius = 4
  315. if minetest.find_node_near(pos, radius, {"group:water"}) then
  316. -- if it is dry soil and not base node, turn it into wet soil
  317. if wet_lvl == 0 then
  318. minetest.add_node(pos, {name = wet})
  319. farming.notify_soil_single(pos)
  320. end
  321. else
  322. -- only turn back if there are no unloaded blocks (and therefore
  323. -- possible water sources) nearby
  324. if not minetest.find_node_near(pos, radius, {"ignore"}) then
  325. -- turn it back into base if it is already dry
  326. if wet_lvl == 0 then
  327. -- only turn it back if there is no plant/seed on top of it
  328. if minetest.get_item_group(nn.name, "plant") == 0 and minetest.get_item_group(nn.name, "seed") == 0 then
  329. minetest.add_node(pos, {name = base})
  330. -- Base dirt doesn't need soil notifications.
  331. end
  332. -- if its wet turn it back into dry soil
  333. elseif wet_lvl == 1 then
  334. minetest.add_node(pos, {name = dry})
  335. farming.notify_soil_single(pos)
  336. end
  337. end
  338. end
  339. end
  340. for i = 1, 5 do
  341. minetest.override_item("default:grass_"..i, {
  342. drop = {
  343. max_items = 1,
  344. items = {
  345. {items = {'farming:seed_wheat'}, rarity = 5},
  346. },
  347. },
  348. shears_drop = "default:grass_dummy",
  349. })
  350. end
  351. for i = 1, 5 do
  352. minetest.override_item("default:grass_"..i.."_hanging", {
  353. drop = {
  354. max_items = 1,
  355. items = {
  356. {items = {'farming:seed_wheat'}, rarity = 5},
  357. },
  358. },
  359. shears_drop = "default:grass_dummy",
  360. })
  361. end
  362. for i = 1, 5 do
  363. minetest.override_item("default:dry_grass2_"..i, {
  364. drop = {
  365. max_items = 1,
  366. items = {
  367. {items = {'potatoes:seed'}, rarity = 5},
  368. },
  369. },
  370. })
  371. end
  372. for i = 1, 5 do
  373. minetest.override_item("default:dry_grass2_"..i.."_hanging", {
  374. drop = {
  375. max_items = 1,
  376. items = {
  377. {items = {'potatoes:seed'}, rarity = 5},
  378. },
  379. },
  380. })
  381. end
  382. minetest.override_item("default:junglegrass", {
  383. drop = {
  384. max_items = 1,
  385. items = {
  386. {items = {'farming:seed_cotton'}, rarity = 8},
  387. {items = {'default:stick'}},
  388. },
  389. },
  390. shears_drop = "default:junglegrass",
  391. })