dirt.lua 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. local S = ethereal.intllib
  2. -- override default dirt (to stop caves cutting away dirt)
  3. minetest.override_item("default:dirt", {is_ground_content = ethereal.cavedirt})
  4. minetest.register_alias("ethereal:green_dirt", "default:dirt_with_grass")
  5. -- dry dirt
  6. minetest.register_node("ethereal:dry_dirt", {
  7. description = S("Dried Dirt"),
  8. tiles = {"ethereal_dry_dirt.png"},
  9. is_ground_content = ethereal.cavedirt,
  10. groups = {crumbly = 3},
  11. sounds = default.node_sound_dirt_defaults()
  12. })
  13. minetest.register_craft({
  14. type = "cooking",
  15. output = "ethereal:dry_dirt",
  16. recipe = "default:dirt",
  17. cooktime = 3,
  18. })
  19. local dirts = {
  20. "Bamboo", "Jungle", "Grove", "Prairie", "Cold",
  21. "Crystal", "Mushroom", "Fiery", "Gray"
  22. }
  23. for n = 1, #dirts do
  24. local desc = dirts[n]
  25. local name = desc:lower()
  26. minetest.register_node("ethereal:"..name.."_dirt", {
  27. description = S(desc.." Dirt"),
  28. tiles = {
  29. "ethereal_grass_"..name.."_top.png",
  30. "default_dirt.png",
  31. {name = "default_dirt.png^ethereal_grass_"..name.."_side.png",
  32. tileable_vertical = false}
  33. },
  34. is_ground_content = ethereal.cavedirt,
  35. groups = {crumbly = 3, soil = 1, ethereal_grass = 1},
  36. soil = {
  37. base = "ethereal:"..name.."_dirt",
  38. dry = "farming:soil",
  39. wet = "farming:soil_wet"
  40. },
  41. drop = "default:dirt",
  42. sounds = default.node_sound_dirt_defaults({
  43. footstep = {name = "default_grass_footstep", gain = 0.25},
  44. }),
  45. })
  46. end
  47. -- re-register dirt types for abm
  48. dirts = {
  49. "ethereal:bamboo_dirt", "ethereal:jungle_dirt", "ethereal:grove_dirt",
  50. "ethereal:prairie_dirt", "ethereal:cold_dirt", "ethereal:crystal_dirt",
  51. "ethereal:mushroom_dirt", "ethereal:fiery_dirt", "ethereal:gray_dirt",
  52. "default:dirt_with_grass", "default:dirt_with_dry_grass",
  53. "default:dirt_with_snow", "default:dirt_with_rainforest_litter"
  54. }
  55. -- check surrounding grass and change dirt to same colour
  56. local grass_spread = function(pos, node)
  57. local above = {x = pos.x, y = pos.y + 1, z = pos.z}
  58. -- not enough light
  59. if (minetest.get_node_light(above) or 0) < 13 then
  60. return
  61. end
  62. local name = minetest.get_node(above).name
  63. local def = minetest.registered_nodes[name]
  64. -- water above grass
  65. if name == "ignore" or not def or def.liquidtype ~= "none" then
  66. return
  67. end
  68. local curr_max, curr_type, num = 0, ""
  69. -- find all default and ethereal grasses in area around dirt
  70. local positions, grasses = minetest.find_nodes_in_area(
  71. {x = pos.x - 1, y = pos.y - 2, z = pos.z - 1},
  72. {x = pos.x + 1, y = pos.y + 2, z = pos.z + 1}, dirts)
  73. -- count new grass nodes
  74. for n = 1, #dirts do
  75. num = grasses[ dirts[n] ] or 0
  76. if num > curr_max then
  77. curr_max = num
  78. curr_type = dirts[n]
  79. end
  80. end
  81. -- no grass nearby, keep as dirt
  82. if curr_type == "" then
  83. return
  84. end
  85. minetest.swap_node(pos, {name = curr_type})
  86. end
  87. -- any grass with a block above will turn into dirt
  88. local grass_devoid = function(pos, node)
  89. local above = {x = pos.x, y = pos.y + 1, z = pos.z}
  90. local name = minetest.get_node(above).name
  91. local nodedef = minetest.registered_nodes[name]
  92. if name ~= "ignore" and nodedef and not ((nodedef.sunlight_propagates or
  93. nodedef.paramtype == "light") and
  94. nodedef.liquidtype == "none") then
  95. minetest.swap_node(pos, {name = "default:dirt"})
  96. end
  97. end
  98. -- flower spread, also crystal and fire flower regeneration
  99. local flower_spread = function(pos, node)
  100. if (minetest.get_node_light(pos) or 0) < 13 then
  101. return
  102. end
  103. local pos0 = {x = pos.x - 4, y = pos.y - 2, z = pos.z - 4}
  104. local pos1 = {x = pos.x + 4, y = pos.y + 2, z = pos.z + 4}
  105. local num = #minetest.find_nodes_in_area(pos0, pos1, "group:flora")
  106. -- stop flowers spreading too much just below top of map block
  107. if minetest.find_node_near(pos, 2, "ignore") then
  108. return
  109. end
  110. if num > 3
  111. and node.name == "ethereal:crystalgrass" then
  112. local grass = minetest.find_nodes_in_area_under_air(
  113. pos0, pos1, {"ethereal:crystalgrass"})
  114. if #grass > 4
  115. and not minetest.find_node_near(pos, 4, {"ethereal:crystal_spike"}) then
  116. pos = grass[math.random(#grass)]
  117. pos.y = pos.y - 1
  118. if minetest.get_node(pos).name == "ethereal:crystal_dirt" then
  119. pos.y = pos.y + 1
  120. minetest.swap_node(pos, {name = "ethereal:crystal_spike"})
  121. end
  122. end
  123. return
  124. elseif num > 3
  125. and node.name == "ethereal:dry_shrub" then
  126. local grass = minetest.find_nodes_in_area_under_air(
  127. pos0, pos1, {"ethereal:dry_shrub"})
  128. if #grass > 8
  129. and not minetest.find_node_near(pos, 4, {"ethereal:fire_flower"}) then
  130. pos = grass[math.random(#grass)]
  131. pos.y = pos.y - 1
  132. if minetest.get_node(pos).name == "ethereal:fiery_dirt" then
  133. pos.y = pos.y + 1
  134. minetest.swap_node(pos, {name = "ethereal:fire_flower"})
  135. end
  136. end
  137. return
  138. elseif num > 3 then
  139. return
  140. end
  141. local seedling = minetest.find_nodes_in_area_under_air(
  142. pos0, pos1, {"group:soil"})
  143. if #seedling > 0 then
  144. pos = seedling[math.random(#seedling)]
  145. -- default farming has desert sand as soil, so dont spread on this
  146. if minetest.get_node(pos).name == "default:desert_sand" then
  147. return
  148. end
  149. pos.y = pos.y + 1
  150. if (minetest.get_node_light(pos) or 0) < 13 then
  151. return
  152. end
  153. minetest.swap_node(pos, {name = node.name})
  154. end
  155. end
  156. -- grow papyrus up to 4 high and bamboo up to 8 high
  157. local grow_papyrus = function(pos, node)
  158. local oripos = pos.y
  159. local high = 4
  160. pos.y = pos.y - 1
  161. local nod = minetest.get_node_or_nil(pos)
  162. if not nod
  163. or minetest.get_item_group(nod.name, "soil") < 1
  164. or minetest.find_node_near(pos, 3, {"group:water"}) == nil then
  165. return
  166. end
  167. if node.name == "ethereal:bamboo" then
  168. high = 8
  169. end
  170. pos.y = pos.y + 1
  171. local height = 0
  172. while height < high
  173. and minetest.get_node(pos).name == node.name do
  174. height = height + 1
  175. pos.y = pos.y + 1
  176. end
  177. nod = minetest.get_node_or_nil(pos)
  178. if nod
  179. and nod.name == "air"
  180. and height < high then
  181. if node.name == "ethereal:bamboo"
  182. and height == (high - 1) then
  183. ethereal.grow_bamboo_tree({x = pos.x, y = oripos, z = pos.z})
  184. else
  185. minetest.swap_node(pos, {name = node.name})
  186. end
  187. end
  188. end
  189. -- loop through active abm's
  190. for _, ab in pairs(minetest.registered_abms) do
  191. local label = ab.label or ""
  192. local node1 = ab.nodenames and ab.nodenames[1] or ""
  193. local node2 = ab.nodenames and ab.nodenames[2] or ""
  194. local neigh = ab.neighbors and ab.neighbors[1] or ""
  195. -- find 'dirt to grass abm' and replace with spread function
  196. if label == "Grass spread"
  197. or (node1 == "default:dirt"
  198. and neigh == "default:dirt_with_grass") then
  199. --ab.interval = 2
  200. --ab.chance = 1
  201. ab.nodenames = {"default:dirt"}
  202. ab.neighbors = {"air"}
  203. ab.action = grass_spread
  204. -- find 'grass devoid of light to dirt' abm and change to devoid function
  205. elseif label == "Grass covered"
  206. or (node1 == "default:dirt_with_grass"
  207. and node2 == "default:dirt_with_dry_grass") then
  208. --ab.interval = 2
  209. --ab.chance = 1
  210. ab.nodenames = {
  211. "default:dirt_with_grass", "default:dirt_with_dry_grass",
  212. "default:dirt_with_snow", "group:ethereal_grass"
  213. }
  214. ab.action = grass_devoid
  215. -- find flower spread abm and change to spread function
  216. elseif label == "Flower spread"
  217. or node1 == "group:flora" then
  218. --ab.interval = 1
  219. --ab.chance = 1
  220. ab.nodenames = {"group:flora"}
  221. ab.neighbors = {"group:soil"}
  222. ab.action = flower_spread
  223. -- find grow papyrus abm and change to grow_papyrus function
  224. elseif label == "Grow papyrus"
  225. or node1 == "default:papyrus" then
  226. --ab.interval = 2
  227. --ab.chance = 1
  228. ab.nodenames = {"default:papyrus", "ethereal:bamboo"}
  229. ab.neighbors = {"group:soil"}
  230. ab.action = grow_papyrus
  231. end
  232. end
  233. -- If Baked Clay mod not active, make Red, Orange and Grey nodes
  234. if not minetest.get_modpath("bakedclay") then
  235. minetest.register_node(":bakedclay:red", {
  236. description = S("Red Baked Clay"),
  237. tiles = {"baked_clay_red.png"},
  238. groups = {cracky = 3},
  239. is_ground_content = ethereal.cavedirt,
  240. sounds = default.node_sound_stone_defaults(),
  241. })
  242. minetest.register_node(":bakedclay:orange", {
  243. description = S("Orange Baked Clay"),
  244. tiles = {"baked_clay_orange.png"},
  245. groups = {cracky = 3},
  246. is_ground_content = ethereal.cavedirt,
  247. sounds = default.node_sound_stone_defaults(),
  248. })
  249. minetest.register_node(":bakedclay:grey", {
  250. description = S("Grey Baked Clay"),
  251. tiles = {"baked_clay_grey.png"},
  252. groups = {cracky = 3},
  253. is_ground_content = ethereal.cavedirt,
  254. sounds = default.node_sound_stone_defaults(),
  255. })
  256. end
  257. -- Quicksand (old style, sinking inside shows black instead of yellow effect,
  258. -- works ok with noclip enabled though)
  259. minetest.register_node("ethereal:quicksand", {
  260. description = S("Quicksand"),
  261. tiles = {"default_sand.png"},
  262. drop = "default:sand",
  263. liquid_viscosity = 15,
  264. liquidtype = "source",
  265. liquid_alternative_flowing = "ethereal:quicksand",
  266. liquid_alternative_source = "ethereal:quicksand",
  267. liquid_renewable = false,
  268. liquid_range = 0,
  269. drowning = 1,
  270. walkable = false,
  271. climbable = false,
  272. post_effect_color = {r = 230, g = 210, b = 160, a = 245},
  273. groups = {crumbly = 3, sand = 1, liquid = 3, disable_jump = 1},
  274. sounds = default.node_sound_sand_defaults(),
  275. })
  276. -- Quicksand (new style, sinking inside shows yellow effect with or without noclip,
  277. -- but old quicksand is shown as black until block placed nearby to update light)
  278. minetest.register_node("ethereal:quicksand2", {
  279. description = S("Quicksand"),
  280. tiles = {"default_sand.png"},
  281. drawtype = "glasslike",
  282. paramtype = "light",
  283. drop = "default:sand",
  284. liquid_viscosity = 15,
  285. liquidtype = "source",
  286. liquid_alternative_flowing = "ethereal:quicksand2",
  287. liquid_alternative_source = "ethereal:quicksand2",
  288. liquid_renewable = false,
  289. liquid_range = 0,
  290. drowning = 1,
  291. walkable = false,
  292. climbable = false,
  293. post_effect_color = {r = 230, g = 210, b = 160, a = 245},
  294. groups = {crumbly = 3, sand = 1, liquid = 3, disable_jump = 1},
  295. sounds = default.node_sound_sand_defaults(),
  296. })
  297. -- craft quicksand
  298. minetest.register_craft({
  299. output = "ethereal:quicksand2",
  300. recipe = {
  301. {"group:sand", "group:sand", "group:sand"},
  302. {"group:sand", "bucket:bucket_water", "group:sand"},
  303. {"group:sand", "group:sand", "group:sand"},
  304. },
  305. replacements = {
  306. {"bucket:bucket_water", "bucket:bucket_empty"}
  307. }
  308. })