nodes.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  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. paramtype2 = "4dir",
  87. drawtype = "nodebox",
  88. node_box = {
  89. type = "fixed",
  90. fixed = nodebox_hoedsoil,
  91. },
  92. selection_box = {
  93. type = "fixed",
  94. fixed = {
  95. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
  96. },
  97. },
  98. on_rotate = false,
  99. description = "Soil",
  100. movement_speed_multiplier = default.SLOW_SPEED,
  101. tiles = {"default_dirt.png^farming_soil.png", "default_dirt.png"},
  102. drop = "default:dirt",
  103. 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}),
  104. sounds = default.node_sound_dirt_defaults(),
  105. soil = {
  106. base = "default:dirt",
  107. dry = "farming:soil",
  108. wet = "farming:soil_wet"
  109. },
  110. on_notify = function(pos, other)
  111. if other.y == pos.y+1 then
  112. farming.notify_soil_single(pos)
  113. end
  114. end,
  115. on_timer = function(...)
  116. farming.on_soil_notify(...)
  117. end,
  118. on_finish_collapse = function(pos, node)
  119. minetest.swap_node(pos, {name="default:dirt"})
  120. end,
  121. on_player_walk_over = trample_dirt,
  122. _on_bonemeal_use = function(pos, node, user, itemstack)
  123. local meta = minetest.get_meta(pos)
  124. meta:set_int("soil_fatigue", 0)
  125. meta:set_string("last_seed", "")
  126. itemstack:take_item()
  127. return itemstack
  128. end,
  129. })
  130. minetest.register_node("farming:soil_wet", {
  131. paramtype = "light",
  132. paramtype2 = "4dir",
  133. drawtype = "nodebox",
  134. node_box = {
  135. type = "fixed",
  136. fixed = nodebox_hoedsoil,
  137. },
  138. selection_box = {
  139. type = "fixed",
  140. fixed = {
  141. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
  142. },
  143. },
  144. on_rotate = false,
  145. description = "Wet Soil",
  146. movement_speed_multiplier = default.SLOW_SPEED,
  147. tiles = {"default_dirt.png^farming_soil_wet.png", "default_dirt.png^farming_soil_wet_side.png"},
  148. drop = "default:dirt",
  149. 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}),
  150. sounds = default.node_sound_dirt_defaults(),
  151. soil = {
  152. base = "default:dirt",
  153. dry = "farming:soil",
  154. wet = "farming:soil_wet"
  155. },
  156. on_notify = function(pos, other)
  157. if other.y == pos.y+1 then
  158. farming.notify_soil_single(pos)
  159. end
  160. end,
  161. on_timer = function(...)
  162. farming.on_soil_notify(...)
  163. end,
  164. on_finish_collapse = function(pos, node)
  165. minetest.swap_node(pos, {name="default:dirt"})
  166. end,
  167. on_player_walk_over = trample_dirt,
  168. _on_bonemeal_use = function(pos, node, user, itemstack)
  169. local meta = minetest.get_meta(pos)
  170. meta:set_int("soil_fatigue", 0)
  171. meta:set_string("last_seed", "")
  172. itemstack:take_item()
  173. return itemstack
  174. end,
  175. })
  176. -- Can be hoed bypassing protection.
  177. minetest.override_item("default:desert_sand", {
  178. soil = {
  179. base = "default:desert_sand",
  180. dry = "farming:desert_sand_soil",
  181. wet = "farming:desert_sand_soil_wet"
  182. }
  183. })
  184. minetest.register_node("farming:desert_sand_soil", {
  185. paramtype = "light",
  186. paramtype2 = "4dir",
  187. drawtype = "nodebox",
  188. node_box = {
  189. type = "fixed",
  190. fixed = nodebox_hoedsoil,
  191. },
  192. selection_box = {
  193. type = "fixed",
  194. fixed = {
  195. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
  196. },
  197. },
  198. on_rotate = false,
  199. description = "Desert Sand Soil",
  200. movement_speed_multiplier = default.SLOW_SPEED,
  201. drop = "default:desert_sand",
  202. tiles = {"farming_desert_sand_soil.png^[transformR90", "default_desert_sand.png"},
  203. 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}),
  204. sounds = default.node_sound_sand_defaults(),
  205. soil = {
  206. base = "default:desert_sand",
  207. dry = "farming:desert_sand_soil",
  208. wet = "farming:desert_sand_soil_wet"
  209. },
  210. on_notify = function(pos, other)
  211. if other.y == pos.y+1 then
  212. farming.notify_soil_single(pos)
  213. end
  214. end,
  215. on_timer = function(...)
  216. farming.on_soil_notify(...)
  217. end,
  218. on_finish_collapse = function(pos, node)
  219. minetest.swap_node(pos, {name="default:desert_sand"})
  220. end,
  221. on_player_walk_over = trample_dirt,
  222. _on_bonemeal_use = function(pos, node, user, itemstack)
  223. local meta = minetest.get_meta(pos)
  224. meta:set_int("soil_fatigue", 0)
  225. meta:set_string("last_seed", "")
  226. itemstack:take_item()
  227. return itemstack
  228. end,
  229. })
  230. minetest.register_node("farming:desert_sand_soil_wet", {
  231. paramtype = "light",
  232. paramtype2 = "4dir",
  233. drawtype = "nodebox",
  234. node_box = {
  235. type = "fixed",
  236. fixed = nodebox_hoedsoil,
  237. },
  238. selection_box = {
  239. type = "fixed",
  240. fixed = {
  241. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
  242. },
  243. },
  244. on_rotate = false,
  245. description = "Wet Desert Sand Soil",
  246. movement_speed_multiplier = default.SLOW_SPEED,
  247. drop = "default:desert_sand",
  248. tiles = {"farming_desert_sand_soil_wet.png^[transformR90", "farming_desert_sand_soil_wet_side.png"},
  249. 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}),
  250. sounds = default.node_sound_sand_defaults(),
  251. soil = {
  252. base = "default:desert_sand",
  253. dry = "farming:desert_sand_soil",
  254. wet = "farming:desert_sand_soil_wet"
  255. },
  256. on_notify = function(pos, other)
  257. if other.y == pos.y+1 then
  258. farming.notify_soil_single(pos)
  259. end
  260. end,
  261. on_timer = function(...)
  262. farming.on_soil_notify(...)
  263. end,
  264. on_finish_collapse = function(pos, node)
  265. minetest.swap_node(pos, {name="default:desert_sand"})
  266. end,
  267. on_player_walk_over = trample_dirt,
  268. _on_bonemeal_use = function(pos, node, user, itemstack)
  269. local meta = minetest.get_meta(pos)
  270. meta:set_int("soil_fatigue", 0)
  271. meta:set_string("last_seed", "")
  272. itemstack:take_item()
  273. return itemstack
  274. end,
  275. })
  276. minetest.register_node("farming:straw", {
  277. description = "Straw\n\nA soft material to fall on.",
  278. tiles = {"farming_straw.png"},
  279. is_ground_content = false,
  280. groups = utility.dig_groups("straw", {flammable=4, fall_damage_add_percent=-30, falling_node=1}),
  281. sounds = default.node_sound_leaves_defaults(),
  282. movement_speed_multiplier = default.SLOW_SPEED,
  283. })
  284. minetest.register_node("farming:straw_weathered", {
  285. description = "Weathered Straw\n\nA soft material to fall on.",
  286. tiles = {"farming_straw_weathered.png"},
  287. is_ground_content = false,
  288. groups = utility.dig_groups("straw", {flammable=5, fall_damage_add_percent=-30, falling_node=1}),
  289. sounds = default.node_sound_leaves_defaults(),
  290. movement_speed_multiplier = default.SLOW_SPEED,
  291. })
  292. -- Translate timer callback to update callback.
  293. function farming.on_soil_notify(pos, elapsed)
  294. local node = minetest.get_node(pos)
  295. farming.on_update_soil(pos, node)
  296. end
  297. -- Called whenever soil is notified to update via timer.
  298. -- This was originally an ABM function.
  299. function farming.on_update_soil(pos, node)
  300. local n_def = minetest.reg_ns_nodes[node.name] or nil
  301. local wet = n_def.soil.wet or nil
  302. local base = n_def.soil.base or nil
  303. local dry = n_def.soil.dry or nil
  304. if not n_def or not n_def.soil or not wet or not base or not dry then
  305. return
  306. end
  307. pos.y = pos.y + 1
  308. local nn = minetest.get_node_or_nil(pos)
  309. if not nn or not nn.name then
  310. return
  311. end
  312. local nn_def = minetest.reg_ns_nodes[nn.name] or nil
  313. pos.y = pos.y - 1
  314. if not nn_def or (nn_def.walkable and minetest.get_item_group(nn.name, "plant") == 0) then
  315. minetest.add_node(pos, {name = base})
  316. return
  317. end
  318. -- check if there is water nearby
  319. local wet_lvl = minetest.get_item_group(node.name, "wet")
  320. -- Distance needed for water increased from 3 to 4 meters, to compensate for dirt being a falling node.
  321. -- [MustTest]
  322. local radius = 4
  323. if minetest.find_node_near(pos, radius, {"group:water"}) then
  324. -- if it is dry soil and not base node, turn it into wet soil
  325. if wet_lvl == 0 then
  326. minetest.add_node(pos, {name = wet, param2 = node.param2})
  327. farming.notify_soil_single(pos)
  328. end
  329. else
  330. -- only turn back if there are no unloaded blocks (and therefore
  331. -- possible water sources) nearby
  332. if not minetest.find_node_near(pos, radius, {"ignore"}) then
  333. -- turn it back into base if it is already dry
  334. if wet_lvl == 0 then
  335. -- only turn it back if there is no plant/seed on top of it
  336. if minetest.get_item_group(nn.name, "plant") == 0 and minetest.get_item_group(nn.name, "seed") == 0 then
  337. minetest.add_node(pos, {name = base})
  338. -- Base dirt doesn't need soil notifications.
  339. end
  340. -- if its wet turn it back into dry soil
  341. elseif wet_lvl == 1 then
  342. minetest.add_node(pos, {name = dry, param2 = node.param2})
  343. farming.notify_soil_single(pos)
  344. end
  345. end
  346. end
  347. end
  348. for i = 1, 5 do
  349. minetest.override_item("default:grass_"..i, {
  350. drop = {
  351. max_items = 1,
  352. items = {
  353. {items = {'farming:seed_wheat'}, rarity = 5},
  354. },
  355. },
  356. shears_drop = "default:grass_dummy",
  357. })
  358. end
  359. for i = 1, 5 do
  360. minetest.override_item("default:grass_"..i.."_hanging", {
  361. drop = {
  362. max_items = 1,
  363. items = {
  364. {items = {'farming:seed_wheat'}, rarity = 5},
  365. },
  366. },
  367. shears_drop = "default:grass_dummy",
  368. })
  369. end
  370. for i = 1, 5 do
  371. minetest.override_item("default:dry_grass2_"..i, {
  372. drop = {
  373. max_items = 1,
  374. items = {
  375. {items = {'potatoes:seed'}, rarity = 5},
  376. },
  377. },
  378. })
  379. end
  380. for i = 1, 5 do
  381. minetest.override_item("default:dry_grass2_"..i.."_hanging", {
  382. drop = {
  383. max_items = 1,
  384. items = {
  385. {items = {'potatoes:seed'}, rarity = 5},
  386. },
  387. },
  388. })
  389. end
  390. minetest.override_item("default:junglegrass", {
  391. drop = {
  392. max_items = 1,
  393. items = {
  394. {items = {'farming:seed_cotton'}, rarity = 8},
  395. {items = {'default:stick'}},
  396. },
  397. },
  398. shears_drop = "default:junglegrass",
  399. })