From c0de5646d230b209af32c60c3e5d1256855b2767 Mon Sep 17 00:00:00 2001 From: paramat Date: Thu, 22 Sep 2016 11:56:15 +0100 Subject: [PATCH] Default: Generalise, optimise and simplify grass spread function Credit to tenplus1 for the suggestion to generalise for mod use. Mods can add mod nodes to 'group:spreading_dirt_type' enabling the function to work with mod nodes. Add some nodes to this group. Removing 'dirt_with_grass' etc. from 'neighbors' stops the ABM action running everywhere and constantly, on the dirt nodes immediately below the surface nodes. Now the action only runs in the rare case of a dirt node with neighbouring air, grass decorations or snow. Remove check for air above to allow grass to spread under light- transmitting nodes such as fences, walls, plants. This causes spread under slabs, stairs and glass, when near air, but seems worth it. Remove unnecessary check for nil node. --- mods/default/functions.lua | 39 ++++++++++++-------------------------- mods/default/nodes.lua | 6 +++--- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/mods/default/functions.lua b/mods/default/functions.lua index 3c8a871..901dd93 100644 --- a/mods/default/functions.lua +++ b/mods/default/functions.lua @@ -348,9 +348,7 @@ minetest.register_abm({ label = "Grass spread", nodenames = {"default:dirt"}, neighbors = { - "default:dirt_with_grass", - "default:dirt_with_dry_grass", - "default:dirt_with_snow", + "air", "group:grass", "group:dry_grass", "default:snow", @@ -359,36 +357,27 @@ minetest.register_abm({ chance = 67, catch_up = false, action = function(pos, node) - -- Most likely case, half the time it's too dark for this. + -- Check for darkness: night, shadow or under a light-blocking node + -- Returns if ignore above local above = {x = pos.x, y = pos.y + 1, z = pos.z} if (minetest.get_node_light(above) or 0) < 13 then return end - -- Look for likely neighbors. - local p2 = minetest.find_node_near(pos, 1, {"default:dirt_with_grass", - "default:dirt_with_dry_grass", "default:dirt_with_snow"}) + -- Look for spreading dirt-type neighbours + local p2 = minetest.find_node_near(pos, 1, "group:spreading_dirt_type") if p2 then - -- But the node needs to be under air in this case. - local n2 = minetest.get_node(above) - if n2 and n2.name == "air" then - local n3 = minetest.get_node(p2) - minetest.set_node(pos, {name = n3.name}) - return - end - end - - -- Anything on top? - local n2 = minetest.get_node(above) - if not n2 then + local n3 = minetest.get_node(p2) + minetest.set_node(pos, {name = n3.name}) return end - local name = n2.name - -- Snow check is cheapest, so comes first. + -- Else, any seeding nodes on top? + local name = minetest.get_node(above).name + -- Snow check is cheapest, so comes first if name == "default:snow" then minetest.set_node(pos, {name = "default:dirt_with_snow"}) - -- Most likely case first. + -- Most likely case first elseif minetest.get_item_group(name, "grass") ~= 0 then minetest.set_node(pos, {name = "default:dirt_with_grass"}) elseif minetest.get_item_group(name, "dry_grass") ~= 0 then @@ -404,11 +393,7 @@ minetest.register_abm({ minetest.register_abm({ label = "Grass covered", - nodenames = { - "default:dirt_with_grass", - "default:dirt_with_dry_grass", - "default:dirt_with_snow", - }, + nodenames = {"group:spreading_dirt_type"}, interval = 8, chance = 50, catch_up = false, diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index 79aea5b..c5d0523 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -332,7 +332,7 @@ minetest.register_node("default:dirt_with_grass", { tiles = {"default_grass.png", "default_dirt.png", {name = "default_dirt.png^default_grass_side.png", tileable_vertical = false}}, - groups = {crumbly = 3, soil = 1}, + groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1}, drop = 'default:dirt', sounds = default.node_sound_dirt_defaults({ footstep = {name = "default_grass_footstep", gain = 0.25}, @@ -357,7 +357,7 @@ minetest.register_node("default:dirt_with_dry_grass", { "default_dirt.png", {name = "default_dirt.png^default_dry_grass_side.png", tileable_vertical = false}}, - groups = {crumbly = 3, soil = 1}, + groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1}, drop = 'default:dirt', sounds = default.node_sound_dirt_defaults({ footstep = {name = "default_grass_footstep", gain = 0.4}, @@ -369,7 +369,7 @@ minetest.register_node("default:dirt_with_snow", { tiles = {"default_snow.png", "default_dirt.png", {name = "default_dirt.png^default_snow_side.png", tileable_vertical = false}}, - groups = {crumbly = 3, soil = 1}, + groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1}, drop = 'default:dirt', sounds = default.node_sound_dirt_defaults({ footstep = {name = "default_snow_footstep", gain = 0.15},