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.
This commit is contained in:
paramat 2016-09-22 11:56:15 +01:00
parent 5e4a6e8ac6
commit c0de5646d2
2 changed files with 15 additions and 30 deletions

@ -348,9 +348,7 @@ minetest.register_abm({
label = "Grass spread", label = "Grass spread",
nodenames = {"default:dirt"}, nodenames = {"default:dirt"},
neighbors = { neighbors = {
"default:dirt_with_grass", "air",
"default:dirt_with_dry_grass",
"default:dirt_with_snow",
"group:grass", "group:grass",
"group:dry_grass", "group:dry_grass",
"default:snow", "default:snow",
@ -359,36 +357,27 @@ minetest.register_abm({
chance = 67, chance = 67,
catch_up = false, catch_up = false,
action = function(pos, node) 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} local above = {x = pos.x, y = pos.y + 1, z = pos.z}
if (minetest.get_node_light(above) or 0) < 13 then if (minetest.get_node_light(above) or 0) < 13 then
return return
end end
-- Look for likely neighbors. -- Look for spreading dirt-type neighbours
local p2 = minetest.find_node_near(pos, 1, {"default:dirt_with_grass", local p2 = minetest.find_node_near(pos, 1, "group:spreading_dirt_type")
"default:dirt_with_dry_grass", "default:dirt_with_snow"})
if p2 then if p2 then
-- But the node needs to be under air in this case. local n3 = minetest.get_node(p2)
local n2 = minetest.get_node(above) minetest.set_node(pos, {name = n3.name})
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
return return
end end
local name = n2.name -- Else, any seeding nodes on top?
-- Snow check is cheapest, so comes first. local name = minetest.get_node(above).name
-- Snow check is cheapest, so comes first
if name == "default:snow" then if name == "default:snow" then
minetest.set_node(pos, {name = "default:dirt_with_snow"}) 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 elseif minetest.get_item_group(name, "grass") ~= 0 then
minetest.set_node(pos, {name = "default:dirt_with_grass"}) minetest.set_node(pos, {name = "default:dirt_with_grass"})
elseif minetest.get_item_group(name, "dry_grass") ~= 0 then elseif minetest.get_item_group(name, "dry_grass") ~= 0 then
@ -404,11 +393,7 @@ minetest.register_abm({
minetest.register_abm({ minetest.register_abm({
label = "Grass covered", label = "Grass covered",
nodenames = { nodenames = {"group:spreading_dirt_type"},
"default:dirt_with_grass",
"default:dirt_with_dry_grass",
"default:dirt_with_snow",
},
interval = 8, interval = 8,
chance = 50, chance = 50,
catch_up = false, catch_up = false,

@ -332,7 +332,7 @@ minetest.register_node("default:dirt_with_grass", {
tiles = {"default_grass.png", "default_dirt.png", tiles = {"default_grass.png", "default_dirt.png",
{name = "default_dirt.png^default_grass_side.png", {name = "default_dirt.png^default_grass_side.png",
tileable_vertical = false}}, tileable_vertical = false}},
groups = {crumbly = 3, soil = 1}, groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1},
drop = 'default:dirt', drop = 'default:dirt',
sounds = default.node_sound_dirt_defaults({ sounds = default.node_sound_dirt_defaults({
footstep = {name = "default_grass_footstep", gain = 0.25}, footstep = {name = "default_grass_footstep", gain = 0.25},
@ -357,7 +357,7 @@ minetest.register_node("default:dirt_with_dry_grass", {
"default_dirt.png", "default_dirt.png",
{name = "default_dirt.png^default_dry_grass_side.png", {name = "default_dirt.png^default_dry_grass_side.png",
tileable_vertical = false}}, tileable_vertical = false}},
groups = {crumbly = 3, soil = 1}, groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1},
drop = 'default:dirt', drop = 'default:dirt',
sounds = default.node_sound_dirt_defaults({ sounds = default.node_sound_dirt_defaults({
footstep = {name = "default_grass_footstep", gain = 0.4}, 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", tiles = {"default_snow.png", "default_dirt.png",
{name = "default_dirt.png^default_snow_side.png", {name = "default_dirt.png^default_snow_side.png",
tileable_vertical = false}}, tileable_vertical = false}},
groups = {crumbly = 3, soil = 1}, groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1},
drop = 'default:dirt', drop = 'default:dirt',
sounds = default.node_sound_dirt_defaults({ sounds = default.node_sound_dirt_defaults({
footstep = {name = "default_snow_footstep", gain = 0.15}, footstep = {name = "default_snow_footstep", gain = 0.15},