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

View File

@ -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,

View File

@ -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},