Mod: Growing

randomproof
Member
 
Posts: 214
Joined: Thu Nov 17, 2011 06:31

Mod: Growing

by randomproof » Thu Dec 01, 2011 23:52

I remade the patch for growing papyrus into a mod. The interval and chance need some tweaking though as I'm not exactly sure how they are used. In enviroment.cpp at line 643 the call if(myrand() % i->chance != 0) doesn't really make sense. It should be more like this: if(myrand_range(1, 1000) > i->chance != 0). I don't think doing 'myrand() % value' really works for this kind of use and it seems to be all over the code.

Just put this into a file named init.lua add put that in to a directory under data/mods/growing
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
math.randomseed(os.time())

minetest.register_abm(
{nodenames = {"papyrus"},
interval = 360,
chance = 2,
action = function(pos, node, active_object_count, active_object_count_wider)
    if math.random(1,1000) > 950 then
        p_bottom1 = {x=pos.x, y=pos.y-1, z=pos.z}
        n_bottom1 = minetest.env:get_node(p_bottom1)
        p_bottom2 = {x=pos.x, y=pos.y-2, z=pos.z}
        n_bottom2 = minetest.env:get_node(p_bottom2)
        p_top = {x=pos.x, y=pos.y+1, z=pos.z}
        n_top = minetest.env:get_node(p_top)
   
        if (string.sub(n_bottom1.name,1,string.len("dirt"))=="dirt") or (string.sub(n_bottom2.name,1,string.len("dirt"))=="dirt" and n_bottom1.name == "papyrus") then
            if n_top.name == "air" then
                minetest.env:add_node(p_top, {name="papyrus"})
            end
        end
    end
end
})
Last edited by randomproof on Fri Dec 02, 2011 00:06, edited 1 time in total.
 

User avatar
Melkor
Member
 
Posts: 285
Joined: Sat Sep 24, 2011 01:03

by Melkor » Fri Dec 02, 2011 03:58

testing... :)

works fine! (but is too goddamn slow)

now im changing a bit the code to make grow cactus too

(replacing all the "papyrus" with "cactus" and all "dirt" with "sand")

let's see what happen

EDIT: is WORKING!! XD

Now i can make a cactus farm too

Here: just copy and paste this in the same file below of the original code

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all

math.randomseed(os.time())

minetest.register_abm(
{nodenames = {"cactus"},
interval = 360,
chance = 2,
action = function(pos, node, active_object_count, active_object_count_wider)
    if math.random(1,1000) > 950 then
        p_bottom1 = {x=pos.x, y=pos.y-1, z=pos.z}
        n_bottom1 = minetest.env:get_node(p_bottom1)
        p_bottom2 = {x=pos.x, y=pos.y-2, z=pos.z}
        n_bottom2 = minetest.env:get_node(p_bottom2)
        p_top = {x=pos.x, y=pos.y+1, z=pos.z}
        n_top = minetest.env:get_node(p_top)
   
        if (string.sub(n_bottom1.name,1,string.len("sand"))=="sand") or (string.sub(n_bottom2.name,1,string.len("sand"))=="sand" and n_bottom1.name == "cactus") then
            if n_top.name == "air" then
                minetest.env:add_node(p_top, {name="cactus"})
            end
        end
    end
end
})



Thanks randomproof :)
Last edited by Melkor on Fri Dec 02, 2011 06:00, edited 1 time in total.
 

User avatar
Calinou
Member
 
Posts: 3124
Joined: Mon Aug 01, 2011 14:26
GitHub: Calinou
IRC: Calinou
In-game: Calinou

by Calinou » Fri Dec 02, 2011 09:41

Great. Papyrus/Cactus growth should be added in official game...
 

ironzorg
Member
 
Posts: 46
Joined: Tue Aug 23, 2011 06:34

by ironzorg » Fri Dec 02, 2011 13:35

Here's my humble improvement of your script !

I wanted to get cacti AND papyrus to grow, so I modified the original script so you can basically grow anything you want with specific random values.

You can get a properly highlighted version of my script here, or just copy paste it from below.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
math.randomseed(os.time())

--[[
-- The growable table is to be used as following:
--   name describes the node that is to grow
--   surfaces is a table of:
--     the name of the node the said node is allowed to grow
--     the odds it has over 1000 to grow at each callback cycle
--]]
growable = {
    {
        name = "papyrus",
        surfaces = {
            -- Papyrus will grow normally on dirt,
            -- it has 50/1000 chances of growing on a cycle
            {name = "dirt", odds = 50},
            -- Papyrus won't grow very well on sand
            {name = "sand", odds = 10}
        }
    },
    {
        name = "cactus",
        surfaces = {
            {name = "sand", odds = 50}
        }
    },
    {
        -- Grass has chances of growing
        name = "junglegrass",
        surfaces = {
            {name = "sand", odds = 2},
            {name = "dirt", odds = 1}
        }
    },
    {
        -- In case you want a nice frontyard with high hurdles
        name = "leaves",
        surfaces = {
            {name = "dirt", odds = 10}
        }
    }
}

for _, e in ipairs(growable) do
    minetest.register_abm({
        nodenames = { e.name },
        interval = 360,
        chance = 2,
        action = function(pos, node, active_object_count, active_object_count_wider)
            for _, s in ipairs(e.surfaces) do
                if (math.random(1, 1000) > 1001 - s.odds) then
                    p_bottom1 = {x = pos.x, y = pos.y - 1, z = pos.z}
                    n_bottom1 = minetest.env:get_node(p_bottom1)
                    p_bottom2 = {x = pos.x, y = pos.y - 2, z = pos.z}
                    n_bottom2 = minetest.env:get_node(p_bottom2)
                    p_top = {x = pos.x, y = pos.y + 1, z = pos.z}
                    n_top = minetest.env:get_node(p_top)
                    n_namelen = string.len(s.name)

                    if (string.sub(n_bottom1.name, 1, n_namelen) == s.name) or (string.sub(n_bottom2.name, 1, n_namelen) == s.name and n_bottom1.name == e.name) then
                        if n_top.name == "air" then
                            minetest.env:add_node(p_top, {name = e.name})
                        end
                    end
                end
            end
        end
    })
end


Please report any bug you find so I can fix them.
Last edited by ironzorg on Fri Dec 02, 2011 15:32, edited 1 time in total.
 

User avatar
Melkor
Member
 
Posts: 285
Joined: Sat Sep 24, 2011 01:03

by Melkor » Fri Dec 02, 2011 14:40

testing...
 

randomproof
Member
 
Posts: 214
Joined: Thu Nov 17, 2011 06:31

by randomproof » Fri Dec 02, 2011 16:44

Thak you ironzorg. I like what you did with this. I wrote this very quickly as a proof of concept and I intended to make it more generic today anyway so you saved me some time. I'm going to give you credit on the wiki page. Here is a version that includes a max_height variable and I moved some of the checks around to be more efficient. My plan is to make wheat so it can be farmed and made in to bread which will heal like other foods. The only thing I need to figure out is how to get it to appear when the map is generated like junglegrass is without changing server code. Probably need to wait until some of that code is exposed to the scripting api.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
math.randomseed(os.time())

--[[
-- The growable table is to be used as following:
--   name describes the node that is to grow
--   surfaces is a table of:
--     the name of the node the said node is allowed to grow
--     the odds it has over 1000 to grow at each callback cycle
--]]
growable = {
    {
        name = "papyrus",
        surfaces = {
            -- Papyrus will grow normally on dirt,
            -- it has 50/1000 chances of growing on a cycle
            {name = "dirt", odds = 50, max_height = 3},
            -- Papyrus won't grow very well on sand
            {name = "sand", odds = 10, max_height = 3}
        }
    },
    {
        name = "cactus",
        surfaces = {
            {name = "dirt", odds = 50, max_height = 3},
        {name = "sand", odds = 25, max_height = 4}
        }
    }
}

for _, e in ipairs(growable) do
    minetest.register_abm({
        nodenames = { e.name },
        interval = 120,
        chance = 2,
        action = function(pos, node, active_object_count, active_object_count_wider)
        -- First check if there is space above to grow
        p_top = {x = pos.x, y = pos.y + 1, z = pos.z}
        n_top = minetest.env:get_node(p_top)

        if n_top.name == "air" then
        -- Calc current height
        cur_height = 1
        p_next = {x = pos.x, y = pos.y - 1, z = pos.z}
        n_next  = minetest.env:get_node(p_next);
        while true do
            if n_next.name ~= node.name then
            break
            end
            cur_height = cur_height + 1
            p_next = {x = p_next.x, y = p_next.y - 1, z = p_next.z}
            n_next = minetest.env:get_node(p_next)
        end

        for _, s in ipairs(e.surfaces) do
            if string.sub(n_next.name, 1, string.len(s.name)) == s.name and (math.random(1, 1000) > (1000 - s.odds)) then
            if cur_height < s.max_height then
                minetest.env:add_node(p_top, {name = node.name})
            end
            end
        end
        end
    end
    })
end


I took out the junglegrass because that is only 1 node and stacking them doesn't work. Here is some code that will work. I've not tried it yet. It might slow stuff down since there is usually a lot of "dirt_with_grass" You'll need to tweak the odds to fit you needs of course. I tried to make it very rare.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
minetest.register_abm({
    nodenames = { "dirt_with_grass" },
    interval = 1200,
    chance = 256,
    action = function(pos, node, active_object_count, active_object_count_wider)
    -- First check if there is space above to grow ( there should be if it is dirt_with_grass )
    p_top = {x = pos.x, y = pos.y + 1, z = pos.z}
    n_top = minetest.env:get_node(p_top)
    if n_top.name == "air" then
        if math.random(1, 10000) > 9995 then
        minetest.env:add_node(p_top, {name = "junglegrass"})
        end
    end
    end
})
Last edited by randomproof on Fri Dec 02, 2011 16:54, edited 1 time in total.
 

ironzorg
Member
 
Posts: 46
Joined: Tue Aug 23, 2011 06:34

by ironzorg » Fri Dec 02, 2011 18:22

randomproof wrote:Here is a version that includes a max_height variable and I moved some of the checks around to be more efficient. My plan is to make wheat so it can be farmed and made in to bread which will heal like other foods. The only thing I need to figure out is how to get it to appear when the map is generated like junglegrass is without changing server code. Probably need to wait until some of that code is exposed to the scripting api.


I thought of the max_height var too, but didn't want to make this callback a bottleneck for the whole game.
I also thought of how I would add resource that would naturally grow on the map, but same problem here: if you do it with the API, I think it will add a lot of CPU charge (you can prove me wrong with a poc, but I doubt it's worth the try ;)).

randomproof wrote:I took out the junglegrass because that is only 1 node and stacking them doesn't work.


Hm that's weird, it worked when I tried (got myself a nice weed greenhouse ;)).

randomproof wrote:Here is some code that will work. I've not tried it yet. It might slow stuff down since there is usually a lot of "dirt_with_grass" You'll need to tweak the odds to fit you needs of course. I tried to make it very rare.


Doesn't planting grass on a "dirt with glass" node make it a "dirt only" node ?

Anyway, I hope you didn't feel like I took over your work, I needed a warm up before I can make my own mods (I've never used LUA before, that was a good exercise) ;)
Also sorry for my poor english, I feel like the comments state the obvious but with bad grammar.
 

User avatar
Casimir
Member
 
Posts: 1101
Joined: Fri Aug 03, 2012 16:59

by Casimir » Fri Aug 03, 2012 17:07

I updated it so it works with 0.4.2
Cacti now grow on desertsand two, no more on dirt.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
math.randomseed(os.time())

--[[
-- The growable table is to be used as following:
--   name describes the node that is to grow
--   surfaces is a table of:
--     the name of the node the said node is allowed to grow
--     the odds it has over 1000 to grow at each callback cycle
--]]
growable = {
    {
        name = "default:papyrus",
        surfaces = {
            -- Papyrus will grow normally on dirt,
            -- it has 50/1000 chances of growing on a cycle
            {name = "default:dirt", odds = 50, max_height = 4},
            -- Papyrus won't grow very well on sand
            {name = "default:sand", odds = 10, max_height = 3}
        }
    },
    {
        name = "default:cactus",
        surfaces = {
            -- deleted dirt and added desert_sand
            {name = "default:desert_sand", odds = 50, max_height = 4},
            {name = "default:sand", odds = 40, max_height = 3}
        }
    }
}

for _, e in ipairs(growable) do
    minetest.register_abm({
        nodenames = { e.name },
        interval = 137,
        chance = 2,
        action = function(pos, node, active_object_count, active_object_count_wider)
        -- First check if there is space above to grow
        p_top = {x = pos.x, y = pos.y + 1, z = pos.z}
        n_top = minetest.env:get_node(p_top)

        if n_top.name == "air" then
        -- Calc current height
        cur_height = 1
        p_next = {x = pos.x, y = pos.y - 1, z = pos.z}
        n_next  = minetest.env:get_node(p_next);
        while true do
            if n_next.name ~= node.name then
            break
            end
            cur_height = cur_height + 1
            p_next = {x = p_next.x, y = p_next.y - 1, z = p_next.z}
            n_next = minetest.env:get_node(p_next)
        end

        for _, s in ipairs(e.surfaces) do
            if string.sub(n_next.name, 1, string.len(s.name)) == s.name and (math.random(1, 1000) > (1000 - s.odds)) then
            if cur_height < s.max_height then
                minetest.env:add_node(p_top, {name = node.name})
            end
            end
        end
        end
    end
    })
end


Bye the way, what is the first line for?
Last edited by Casimir on Fri Aug 03, 2012 17:12, edited 1 time in total.
 

Temperest
Member
 
Posts: 651
Joined: Tue Nov 15, 2011 23:13
GitHub: Uberi

by Temperest » Fri Aug 03, 2012 17:20

The first line seeds the PRNG with the system time, which is the source of entropy for the math.random() function.

IIRC MineTest already does this now, so it is no longer necessary.
WorldEdit 1.0 released

The Mesecons Laboratory - the art of Mesecons circuitry
Latest article: Mesecons Basics.
 

User avatar
Casimir
Member
 
Posts: 1101
Joined: Fri Aug 03, 2012 16:59

by Casimir » Fri Aug 03, 2012 17:46

Thanks. I didn't realised it is already growing.

[edit]Growing isn't default yet, but the first line is. Now I understood you.[/edit]
Last edited by Casimir on Sun Aug 05, 2012 00:12, edited 1 time in total.
 

Belgac
Member
 
Posts: 57
Joined: Wed Aug 08, 2012 15:27

by Belgac » Thu Aug 09, 2012 12:23

Hello, I was using this code to learn more about LUA and minetest coding.

I made some improvements:
- Removed the "math.randomseed(os.time())" as it is already included in minetest (see Temperest's post)
- Added a per plant abm interval and chance
- Added a per planting surface light level support so plants don't grow in the dark and needed light level varies with surface.
-Corrected the odds to keep grow speed in the same range after the minimal_light implementation

I have also some other improvements planned:
- growing:isplant and growing:addsurface function to make this a default growing library for any other mod (kind of unified_growing)
-plant aging (so node "evolve")
-multi-node plants (ie: plants with trunk and leaves)
- forking other mods (ie: hydro) so they depend on [growing] to show possibilities
-adding aging plants (not growing:wheat,... and growing:hop,...) -- as part of a separated package to show off possibilities

I have some questions:
- What's the license of this mod?
-Why isn't it in a modding related section?
-Are people interested in maintainig this?

Here is the content of init.lua
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
--[[
-- The growable table is to be used as following:
--   name describes the node that is to grow
-- interval is the interval of the grow abm
-- chance is the chance of the grow abm
--   surfaces is a table of:
--     the name of the node the said node is allowed to grow
--     the odds it has over 1000 to grow at each callback cycle
--       the minimal_light needed to grow on this surface
--     the maximal height of the plant on this surface
--]]
growable = {
    {
        name = "default:papyrus",
        interval = 270,
        chance = 2,
        surfaces =
        {
            -- Papyrus will grow normally on dirt,
            -- it has 100/1000 chances of growing on a cycle
            {name = "default:dirt", odds = 100, minimal_light = 12, max_height = 4},
            -- Papyrus won't grow very well on sand
            {name = "default:sand", odds = 20,    minimal_light = 14, max_height = 3}
        }
    },
    {
        name = "default:cactus",
        interval = 270,
        chance = 2,
        surfaces =
        {
            {name = "default:desert_sand", odds = 100, minimal_light = 12, max_height = 4},
            {name = "default:sand", odds = 80, minimal_light = 14, max_height = 3}
        }
    }
}

for _, e in ipairs(growable) do
    minetest.register_abm(
    {
        nodenames = { e.name },
        interval = e.interval,
        chance = e.chance,
        action = function(pos, node, active_object_count, active_object_count_wider)
            -- First check if there is space above to grow
            p_top = {x = pos.x, y = pos.y + 1, z = pos.z}
            n_top = minetest.env:get_node(p_top)
            if n_top.name == "air" then
                --Get light level
                local light = minetest.env:get_node_light(p_top, nil)
                if light == nil then light = 0 end
                -- Calc current height
                cur_height = 1
                p_next = {x = pos.x, y = pos.y - 1, z = pos.z}
                n_next  = minetest.env:get_node(p_next);
            while true do
                if n_next.name ~= node.name then
                    break
                end
                cur_height = cur_height + 1
                p_next = {x = p_next.x, y = p_next.y - 1, z = p_next.z}
                n_next = minetest.env:get_node(p_next)
            end
            --analyze surface properties
            for _, s in ipairs(e.surfaces) do
                if string.sub(n_next.name, 1, string.len(s.name)) == s.name and (math.random(1, 1000) > (1000 - s.odds)) then
                    if (cur_height < s.max_height) and (light >= s.minimal_light) then
                        minetest.env:add_node(p_top, {name = node.name})
                    end
                end
            end
        end
    end
 })
end


[edit] sorry for my english [/edit]
Last edited by Belgac on Thu Aug 09, 2012 13:50, edited 1 time in total.
Contributor: Plant aging library
Creator: (soon)
 

User avatar
Casimir
Member
 
Posts: 1101
Joined: Fri Aug 03, 2012 16:59

by Casimir » Thu Aug 09, 2012 13:21

Belgac wrote:-Are people interested in maintainig this?

Yes. Thanks for your changes.
You seem to have mixed up the brackets at the end. "})" has to be before the last "end"

For my part the licence is WTFPL.
 

Belgac
Member
 
Posts: 57
Joined: Wed Aug 08, 2012 15:27

by Belgac » Thu Aug 09, 2012 13:46

Thank you for the correction it's done.

I'm happy to see that someone is maintainig the code as i'm really not good at this and would hate to work on things to see them disapear.

The license is exactly what I was hoping for.

The question about the fact that this subject is in the c code part of the forum remains obscure to me probably because i don't really understand what randomproof is saying in the first post.
Contributor: Plant aging library
Creator: (soon)
 

Belgac
Member
 
Posts: 57
Joined: Wed Aug 08, 2012 15:27

by Belgac » Fri Aug 10, 2012 11:16

So here is a new update:
-coderewrite to integrate as a function (plantaging)
-code rewrite to check for plant on surfaces instead of free air on top (will help for non-growing maturing plants)
-check if plant is growable via max_height (maturing code not there yet)
-separated the mod in two parts the age-ing library ([plant_aging]) and the default plants growing depending on the aging library ([default_growing])

so here is the code
[plant_aging]
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
function plantaging (plantname, plantinterval, plantchance, plantsurfaces)
    minetest.register_abm(
    {
        nodenames = { plantname },
        interval = plantinterval,
        chance = plantchance,
        action = function(pos, node, active_object_count, active_object_count_wider)
            -- First check if there is a fertile surface under it and if the growing odds are good
            p_down = {x = pos.x, y = pos.y - 1, z = pos.z}
            n_down = minetest.env:get_node(p_down)
            if n_down.name ~= node.name then
                for _, s in ipairs(plantsurfaces) do
                    if string.sub(n_down.name, 1, string.len(s.name)) == s.name and (math.random(1, 1000) > (1000 - s.odds)) then
                        --check if the plant grows
                        if s.max_height > 1 then
                            --calculate de actual height
                            cur_height = 1
                            p_next = {x = pos.x, y = pos.y + 1, z = pos.z}
                            n_next  = minetest.env:get_node(p_next);
                            while true do
                                if n_next.name ~= node.name then
                                    break
                                end
                                cur_height = cur_height + 1
                                p_next = {x = p_next.x, y = p_next.y + 1, z = p_next.z}
                                n_next = minetest.env:get_node(p_next)
                            end
                            --get light level for the potential growth block
                            local light = minetest.env:get_node_light(p_next, nil)
                            -- replace nil by 0 if needed
                            if light == nil then
                                light = 0
                            end
                            -- check the light level, the height and the growth possibility
                            if (cur_height < s.max_height) and (light >= s.minimal_light) and n_next.name == "air" then
                                --place a new block on top
                                minetest.env:add_node(p_next, {name = node.name})
                            end
                        end   
                    end
                end
            end
        end
    })
    end

[default_growing]
depends.txt = plantaging
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
--[[
-- The growable table is to be used as following:
--   name describes the node that is to grow
-- interval is the interval of the grow abm
-- chance is the chance of the grow abm
--   surfaces is a table of:
--     the name of the node the said node is allowed to grow
--     the odds it has over 1000 to grow at each callback cycle
--       the minimal_light needed to grow on this surface
--     the maximal height of the plant on this surface
--]]
growable = {
    {
        name = "default:papyrus",
        interval = 270,
        chance = 1,
        surfaces =
        {
            -- Papyrus will grow normally on dirt,
            -- it has 100/1000 chances of growing on a cycle
            {name = "default:dirt", odds = 100, minimal_light = 12, max_height = 4},
            -- Papyrus won't grow very well on sand
            {name = "default:sand", odds = 40,    minimal_light = 12, max_height = 3}
        }
    },
    {
        name = "default:cactus",
        interval = 270,
        chance = 1,
        surfaces =
        {
            {name = "default:desert_sand", odds = 100, minimal_light = 12, max_height = 4},
            {name = "default:sand", odds = 80, minimal_light = 12, max_height = 3}
        }
    }
}

for _, e in ipairs(growable) do
plantaging (e.name, e.interval, e.chance, e.surfaces)
end


I'm not quite sure aging is the right word??
Moderators: Can this topic be moved to modding general?
I know there is some c talk at the beginning but it's more a mod right now.
Contributor: Plant aging library
Creator: (soon)
 

Belgac
Member
 
Posts: 57
Joined: Wed Aug 08, 2012 15:27

by Belgac » Fri Aug 10, 2012 20:52

And a new update again:
-Separated height calculation
-added plant aging (you need to add maturing (boolean), maturing_height (minimal height for maturing) and matured_node (node it evolves too) to the surface table)

Next step:
on this mod:
-adding a fertilizer friendly system
-dynamicaly adding surfaces
-multi-node type plants
on other mods:
-reloading the farm mod (http://minetest.net/forum/viewtopic.php?id=607) to show off possibilities of plant_aging
-forking some mods for compatibilities ([hydro] being the first objective)

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
function plant_height (plantx, planty, plantz, plantnodename)
    temp_height = 1
    p_next = {x = plantx, y = planty + 1, z = plantz}
    n_next  = minetest.env:get_node(p_next);
    while true do
        if n_next.name ~= plantnodename then
            break
        end
        temp_height = temp_height + 1
        p_next = {x = p_next.x, y = p_next.y + 1, z = p_next.z}
        n_next = minetest.env:get_node(p_next)
    end
    return temp_height
end

function plantaging (plantname, plantinterval, plantchance, plantsurfaces)
    minetest.register_abm(
    {
        nodenames = { plantname },
        interval = plantinterval,
        chance = plantchance,
        action = function(pos, node, active_object_count, active_object_count_wider)
            -- First check if there is a fertile surface under it and if the growing odds are good
            p_down = {x = pos.x, y = pos.y - 1, z = pos.z}
            n_down = minetest.env:get_node(p_down)
            if n_down.name ~= node.name then
                for _, s in ipairs(plantsurfaces) do
                    if string.sub(n_down.name, 1, string.len(s.name)) == s.name and (math.random(1, 1000) > (1000 - s.odds)) then
                        --check if the plant grows
                        if s.max_height > 1 then
                            --calculate the actual height
                            cur_height = plant_height (pos.x, pos.y, pos.z, node.name)
                            --get potential grow point
                            grownodepos = {x = pos.x, y = pos.y + cur_height, z = pos.z}
                            grownode = minetest.env:get_node(grownodepos)
                            --get light level for the potential growth block
                            local light = minetest.env:get_node_light(grownodepos, nil)
                            -- replace nil by 0 if needed
                            if light == nil then
                                light = 0
                            end
                            -- check the light level, the height and the growth possibility
                            if (cur_height < s.max_height) and (light >= s.minimal_light) and grownode.name == "air" then
                                --place a new block on top
                                minetest.env:add_node(grownodepos, {name = node.name})
                            end
                        end   
                        if s.maturing == true then
                            --calculate the height
                            cur_height = plant_height (pos.x, pos.y, pos.z, node.name)
                            if cur_height >= s.maturing_height then
                                while cur_height > 0 do
                                    maturing_node= {x = pos.x, y = pos.y + cur_height - 1, z = pos.z}
                                    minetest.env:add_node(maturing_node,{type="node",name= s.matured_node})
                                    cur_height = cur_height - 1
                                end
                            end
                        end
                    end
                end
            end
        end
    })
    end
Last edited by Belgac on Fri Aug 10, 2012 20:52, edited 1 time in total.
Contributor: Plant aging library
Creator: (soon)
 

User avatar
Casimir
Member
 
Posts: 1101
Joined: Fri Aug 03, 2012 16:59

by Casimir » Sun Sep 16, 2012 13:59

I didn't get Belgac's version to work for me, so I continued using the old one. So my "updated" version is still the old one with two changes: the growing slows down as the plant gets bigger. And I included the timbermod (only for papyrus and cactus).

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
--[[
-- The growable table is to be used as following:
--   name describes the node that is to grow
-- interval is the interval of the grow abm
-- chance is the chance of the grow abm
--   surfaces is a table of:
--     the name of the node the said node is allowed to grow
--     the odds it has over 1000 to grow at each callback cycle
--       the minimal_light needed to grow on this surface
--     the maximal height of the plant on this surface
--]]
growable = {
    {
        name = "default:papyrus",
        interval = 271,
        chance = 2,
        surfaces =
        {
            -- Papyrus will grow normally on dirt,
            -- it has 100/1000 chances of growing on a cycle
            {name = "default:dirt", odds = 110, minimal_light = 12, max_height = 5},
            -- Papyrus won't grow very well on sand
            {name = "default:sand", odds = 22,    minimal_light = 14, max_height = 4}
        }
    },
    {
        name = "default:cactus",
        interval = 271,
        chance = 2,
        surfaces =
        {
            {name = "default:desert_sand", odds = 110, minimal_light = 12, max_height = 5},
            {name = "default:sand", odds = 89, minimal_light = 14, max_height = 4}
        }
    }
}

for _, e in ipairs(growable) do
    minetest.register_abm(
    {
        nodenames = { e.name },
        interval = e.interval,
        chance = e.chance,
        action = function(pos, node, active_object_count, active_object_count_wider)
       
            -- First check if there is space above to grow
            p_top = {x = pos.x, y = pos.y + 1, z = pos.z}
            n_top = minetest.env:get_node(p_top)
            if n_top.name == "air" then
           
                --Get light level
                local light = minetest.env:get_node_light(p_top, nil)
                if light == nil then light = 0 end
               
                -- Calc current height
                cur_height = 1
                p_next = {x = pos.x, y = pos.y - 1, z = pos.z}
                n_next  = minetest.env:get_node(p_next);
                while true do
                    if n_next.name ~= node.name then
                        break
                    end
                    cur_height = cur_height + 1
                    p_next = {x = p_next.x, y = p_next.y - 1, z = p_next.z}
                    n_next = minetest.env:get_node(p_next)
                end
               
                --analyze surface properties
                for _, s in ipairs(e.surfaces) do
                    if string.sub(n_next.name, 1, string.len(s.name)) == s.name and (math.random(1, 1000) > (1000 - s.odds)) then
                        if (cur_height < s.max_height) and (light >= s.minimal_light) then
                            if (math.random(1, (s.max_height+1)) > cur_height) then --[[ this slows down the growth as the plant gets bigger ]]
                                minetest.env:add_node(p_top, {name = node.name})
                            end
                        end
                    end
                end
               
            end
        end
 })
end

-- copy-past of the timbermod by Jejia and kddekadenz (original license: GPLv3)
local timber_nodenames={"default:papyrus", "default:cactus"}

minetest.register_on_dignode(function(pos, node, digger)
    local i=1
    while timber_nodenames[i]~=nil do
        if node.name==timber_nodenames[i] then
            np={x=pos.x, y=pos.y+1, z=pos.z}
            while minetest.env:get_node(np).name==timber_nodenames[i] do
                minetest.env:remove_node(np)
                digger:get_inventory():add_item('main', timber_nodenames[i])
                np={x=np.x, y=np.y+1, z=np.z}
            end
        end
        i=i+1
    end
end)


I would upload it as a working mod, if I could find a filehoster where you can upload without registering, and without deleting the file to soon. Alternatively I could upload it to freenet, but that would make it more complicated for you than pasting the code into a init.lua.
Last edited by Casimir on Sun Sep 16, 2012 14:01, edited 1 time in total.
 

Belgac
Member
 
Posts: 57
Joined: Wed Aug 08, 2012 15:27

by Belgac » Sun Sep 16, 2012 14:21

What's the problem with my version? did you download it from here or from my official post

Nice improvements
Contributor: Plant aging library
Creator: (soon)
 

User avatar
Casimir
Member
 
Posts: 1101
Joined: Fri Aug 03, 2012 16:59

by Casimir » Sun Sep 16, 2012 15:00

I don't know how to set it up. I always get "attempt to call global 'plantaging' <a nil value>".
 

User avatar
Casimir
Member
 
Posts: 1101
Joined: Fri Aug 03, 2012 16:59

by Casimir » Sat Oct 27, 2012 19:52

New version:
http://ompldr.org/vZzFwaA/growing%2020121027.zip
Now it checks for water nearby.
 


Return to WIP Mods

Who is online

Users browsing this forum: No registered users and 19 guests

cron