Filth Mod

ashenk69
Member
Posts: 230
Joined: Tue Jul 03, 2012 00:08

Filth Mod

by ashenk69 » Post

I was thinking of something that would stand out as something that hasn't been introduced into the modding part already. That's when I had an idea of adding a system into the game that when a player walks on dirt he is given a filth number and when he walks off of dirt and for example onto a wood plank flooring he begins to dispense his filth onto the flooring in the form of a custom node. This makes it so you would have to keep your home clean in order to expand it because if there is filth on the ground you can't place things directly onto the floor. This is just an idea for right now as I am working on the code currently to make it work.

Items to keep the house clean:
Sweeper (saw one of those in I believe the madblocks mod but it was used for a little different purpose)
Door mat to clean peoples feet off

jin_xi
Member
Posts: 165
Joined: Mon Jul 02, 2012 18:19

by jin_xi » Post

nice ideas!

User avatar
Casimir
Member
Posts: 1204
Joined: Fri Aug 03, 2012 16:59
GitHub: CasimirKaPazi

by Casimir » Post

I had quite a similar idea for making desire paths (is this the right expression? desire?). When walking over grass it turns to dirt and things like that.
It would make sense to combine those ideas.

ashenk69
Member
Posts: 230
Joined: Tue Jul 03, 2012 00:08

by ashenk69 » Post

It is sort of similar in that your affecting the nodes that the player walks on. I think the word you might be looking for is deteriorate. After walking on dirt for so long it decays the grass away because it has more wear on it. I think your idea is really cool and the execution would almost be the same so it would be beneficial to combine them.

User avatar
Casimir
Member
Posts: 1204
Joined: Fri Aug 03, 2012 16:59
GitHub: CasimirKaPazi

by Casimir » Post

The thing with the word is, I wasn't sure what the German "Trampelpfad" is in English, so I looked it up in the wikipedia. But "desire path" sounds strange.

Done so far:

Code: Select all

-- first part is copied from another mod
local players = {}

minetest.register_on_joinplayer(function(player)
    table.insert(players, player)
end)

minetest.register_on_leaveplayer(function(player)
    table.remove(players, player)
end)

-- chance for deterioate for x of 100, but on every global step
local odd = 10

minetest.register_globalstep(function(dtime)
    for i,player in ipairs(players) do
        local pos = player:getpos()
        local p_ground = { x=math.floor(pos.x+0.5), y=math.floor(pos.y), z=math.floor(pos.z+0.5) }
        local n_ground  = minetest.env:get_node(p_ground)
        if n_ground.name == "default:dirt_with_grass" then
            if math.random(1, 100) <= odd then
                minetest.env:add_node(p_ground,{type="node",name="default:dirt"})
            end
        end
    end
end)
needs to be done next:
- check if the node is the one before (so nothing changes when you just stand there)
- "remembering" the dirt on the shoos

I'm not sure if I have time to continue tomorrow.

leo_rockway
Member
Posts: 211
Joined: Tue Jul 31, 2012 20:37

by leo_rockway » Post

This sounds interesting. I'll be checking this thread to see what you guys come up with =]
Try Skyblock for MineClone 2
Listen to this sound and music pack!

ashenk69
Member
Posts: 230
Joined: Tue Jul 03, 2012 00:08

by ashenk69 » Post

Your code is almost exactly what I had first started with. I looked at how mesecons was able to get their pressure plates to work and they used ABMs to check for the player. I am not sure if using a global step or an ABM is more efficient for the processor since with an ABM you can set the time check but the global step is called every half second or so. I'll try and post some code from what I came up with.

ashenk69
Member
Posts: 230
Joined: Tue Jul 03, 2012 00:08

by ashenk69 » Post

I still need to add different nodes so it has a gradient effect to the filth that is created. Also adding gradual reduction of filth numbers.

Code: Select all

local playersFilth = {}
minetest.register_node("filth:dirt", {
    drawtype = "nodebox",
    tile_images = {"filth_dirt.png"},
    paramtype = "light",
    is_ground_content = true,
    walkable = false,
    node_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    selection_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    groups = {crumbly=2,oddly_breakable_by_hand=1},
    drop = "",
})

minetest.register_abm(
    {nodenames = {"default:dirt","default:dirt_with_grass","default:dirt_with_grass_footsteps"},
    interval = 1.0,
    chance = 1,
    action = function(pos, node, active_object_count, active_object_count_wider)
        local objs = minetest.env:get_objects_inside_radius(pos, 1)
        for k, obj in pairs(objs) do
            if obj:is_player() and obj:getpos().y > pos.y+.25 then
                playersFilth[obj:get_player_name()] = 10
            end
        end    
    end,
})
minetest.register_abm(
    {nodenames = {"default:wood"},
    interval = .5,
    chance = 1,
    action = function(pos, node, active_object_count, active_object_count_wider)
        local objs = minetest.env:get_objects_inside_radius(pos, 1)
        for k, obj in pairs(objs) do
            if obj:is_player() and playersFilth[obj:get_player_name()] > 0 and obj:getpos().y > pos.y+.25 then
                local nPos = {x=pos.x,y=pos.y+1,z=pos.z}
                playersFilth[obj:get_player_name()] = 0
                minetest.env:add_node(nPos, {name="filth:dirt"})
            end
        end    
    end,
})
minetest.register_on_joinplayer(function(obj)
    playersFilth[obj:get_player_name()] = 0
end)

User avatar
Linxx
Member
Posts: 406
Joined: Wed May 16, 2012 00:37

by Linxx » Post

this could be done for snow too :) nice idea

User avatar
Casimir
Member
Posts: 1204
Joined: Fri Aug 03, 2012 16:59
GitHub: CasimirKaPazi

by Casimir » Post

ashenk69 wrote:I am not sure if using a global step or an ABM is more efficient for the processor since with an ABM you can set the time check but the global step is called every half second or so.
I'm not sure either. I thought an ABM is executed for all the relevant nodes. So with one pressure plate it's just a little bit, but with tons of dirt it's more. In the walking_light mod it is done without ABM.

I don't understand everything you did, but I tried to combine them.

Code: Select all

local players = {}
local playersFilth = {}

minetest.register_on_joinplayer(function(player)
    table.insert(players, player)
    playersFilth[player:get_player_name()] = 0
end)

minetest.register_on_leaveplayer(function(player)
    table.remove(players, player)
    playersFilth[player:get_player_name()] = nil
end)

-- chance for deterioate for x of 100, but on every global step <--- needs to be changed
local odd = 10
local max_distance = 5

minetest.register_node("filth:dirt", {
    drawtype = "nodebox",
    tile_images = {"filth_dirt.png"},
    paramtype = "light",
    is_ground_content = true,
    walkable = false,
    node_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    selection_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    groups = {crumbly=2,oddly_breakable_by_hand=1},
    drop = "",
})

minetest.register_globalstep(function(dtime)
    for i,player in ipairs(players) do
        local pos = player:getpos()
        local p_ground = { x=math.floor(pos.x+0.5), y=math.floor(pos.y), z=math.floor(pos.z+0.5) }
        local n_ground  = minetest.env:get_node(p_ground)
        -- checking if the node is the previous node
        if p_ground ~= p_ground_previous then
            if n_ground.name == "default:dirt_with_grass" then
                if math.random(1, 100) <= odd then
                    minetest.env:add_node(p_ground,{type="node",name="default:dirt"})
                end
                -- increase the players filth on a logarithmic scale.
                -- starting with 1
                if playersFilth[player:get_player_name()] < 1 then
                    playersFilth[player:get_player_name()] = 1
                -- (X+5)/2 aproximates 5
                elseif playersFilth[player:get_player_name()] >= 1 then
                    playersFilth[player:get_player_name()] = math.floor((playersFilth[player:get_player_name()] + max_distance) /2 )
                end
            end
        end
        -- making node to previous node
        local p_ground_previous = p_ground
    end
end)

minetest.register_globalstep(function(dtime)
    for i,player in ipairs(players) do
        local pos = player:getpos()
        local p_ground = { x=math.floor(pos.x+0.5), y=math.floor(pos.y), z=math.floor(pos.z+0.5) }
        local n_ground  = minetest.env:get_node(p_ground)
        -- checking if the node is the previous node
        if p_ground ~= p_ground_previous then
            if n_ground.name == "default:wood" then
                if playersFilth[player:get_player_name()] > 0 then
                    local p_add_filth = { x=p_ground.x, y=p_ground.y+1, z=p_ground.z }
                    local n_add_filth  = minetest.env:get_node(p_add_filth)
                        -- to not replace doors with filth
                        if n_add_filth.name == "air" then
                            minetest.env:add_node(p_add_filth,{type="node",name="filth:dirt"})
                        end
                    -- I think thats not the right place for this line
                    playersFilth[player:get_player_name()] = playersFilth[player:get_player_name()] - 1
                end
            end
        end
        -- making node to previous node
        local p_ground_previous = p_ground
    end
end)
The part with checking for the previous node isn't working. I don't know why. Although it leaves only one first filthpatch when walking on wood.

User avatar
Echo
Member
Posts: 122
Joined: Tue Jul 31, 2012 08:11
Location: Germany

by Echo » Post

Casimir wrote:[...]I'm not sure either. I thought an ABM is executed for all the relevant nodes. So with one pressure plate it's just a little bit, but with tons of dirt it's more. In the walking_light mod it is done without ABM.[...]
Right, it would be nice if there was an event every time a step is made. It's really inefficient to call the functions every 0.05 sec, for my walking_light mod, too.
Hmmmm, I'm new to programming mods for minetest, is there such an event?

ashenk69
Member
Posts: 230
Joined: Tue Jul 03, 2012 00:08

by ashenk69 » Post

Echo wrote:Right, it would be nice if there was an event every time a step is made. It's really inefficient to call the functions every 0.05 sec, for my walking_light mod, too.
Hmmmm, I'm new to programming mods for minetest, is there such an event?
I think a function that would be awesome to have is one that checks if the player has moved onto a new node. That would make doing these mods extremely easy. It would also make pressure plates more responsive too.

ashenk69
Member
Posts: 230
Joined: Tue Jul 03, 2012 00:08

by ashenk69 » Post

@Casimir
I have been testing with ABMs in a very heavy dirt world and I haven't noticed any noticeable strain on the system.

If you store the previous node into an array just like the playersFilth array then you don't have to do tricky position checks. You would just have to check if the position of the previous node is different from the current one it is on.

The reason it only creates one filth patch is just for testing purposes. I wanted to see if it was actually possible to make it work. Now I am getting gradual growth done so there will be different levels of filth.

User avatar
Casimir
Member
Posts: 1204
Joined: Fri Aug 03, 2012 16:59
GitHub: CasimirKaPazi

by Casimir » Post

I now cleaned up the code, but checking if the player is on another node still isn't working.

Code: Select all

local players = {}
local playersFilth = {}

minetest.register_on_joinplayer(function(player)
    table.insert(players, player)
    playersFilth[player:get_player_name()] = 0
end)

minetest.register_on_leaveplayer(function(player)
    table.remove(players, player)
    playersFilth[player:get_player_name()] = nil
end)

-- chance for deterioate for x of 100, but on every global step <--- needs to be changed
local odd = 10
local max_distance = 5

minetest.register_node("filth:dirt", {
    drawtype = "nodebox",
    tile_images = {"filth_dirt.png"},
    paramtype = "light",
    is_ground_content = true,
    walkable = false,
    node_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    selection_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    groups = {crumbly=2, oddly_breakable_by_hand=1, falling_node=1},
    drop = "",
})

minetest.register_globalstep(function(dtime)
    for i,player in ipairs(players) do
        local pos = player:getpos()
        local player_pos = { x=math.floor(pos.x+0.5), y=math.floor(pos.y+0.5), z=math.floor(pos.z+0.5) }
        local p_ground = { x=math.floor(pos.x+0.5), y=math.floor(pos.y+0.5)-1, z=math.floor(pos.z+0.5) }
        local n_ground  = minetest.env:get_node(p_ground)
        
        -- checking if the node is the previous node
        if player_pos ~= player_pos_previous then
        
            -- gettin your feet dirty when walking on blanc dirt
            if n_ground.name == "default:dirt" then
                -- increase the players filth on a logarithmic scale.
                -- starting with 1
                if playersFilth[player:get_player_name()] < 1 then
                    playersFilth[player:get_player_name()] = 1
                    print (playersFilth[player:get_player_name()]) -- for debuging
                -- (X+5)/2 aproximates 5
                elseif playersFilth[player:get_player_name()] >= 1 then
                    playersFilth[player:get_player_name()] = math.floor((playersFilth[player:get_player_name()] + max_distance) /2 )
                    print (playersFilth[player:get_player_name()]) -- for debuging
                end
            end
            
            -- turning grass into dirt
            if n_ground.name == "default:dirt_with_grass" then
                if math.random(1, 100) <= odd then
                    minetest.env:add_node(p_ground,{type="node",name="default:dirt"})
                end
            end
            
            -- reducing filth when not walking on dirt
            if n_ground.name ~= "default:dirt" then
                if playersFilth[player:get_player_name()] > 0 then
                    -- I think thats not the right place for this line
                    playersFilth[player:get_player_name()] = playersFilth[player:get_player_name()] - 1
                    print (playersFilth[player:get_player_name()]) -- for debuging
                end
            end

            -- making filth when walking on wood
            if n_ground.name == "default:wood" then
                if playersFilth[player:get_player_name()] > 0 then
                    local p_add_filth = { x=p_ground.x, y=p_ground.y+1, z=p_ground.z }
                    local n_add_filth  = minetest.env:get_node(p_add_filth)
                    -- to not replace doors with filth
                    if n_add_filth.name == "air" then
                        minetest.env:add_node(p_add_filth,{type="node",name="filth:dirt"})
                    end
                end
            end
        end
        
        -- making node to previous node
        local player_pos_previous =  player_pos
    end
end)
And when I try it with arrays I get an error. Line 41 unexpected symbol near "[". It has to be an obvious mistake, but I can't find it.
With arrays it is the following. [edit]fixed[/edit]

Code: Select all

local players = {}
local playersFilth = {}
local player_pos = {}
local player_pos_previous = {}

minetest.register_on_joinplayer(function(player)
    table.insert(players, player)
    playersFilth[player:get_player_name()] = 0
end)

minetest.register_on_leaveplayer(function(player)
    table.remove(players, player)
    playersFilth[player:get_player_name()] = nil
end)

-- chance for deterioate for x of 100, but on every global step <--- needs to be changed
local odd = 10
local max_distance = 5

minetest.register_node("filth:dirt", {
    drawtype = "nodebox",
    tile_images = {"filth_dirt.png"},
    paramtype = "light",
    is_ground_content = true,
    walkable = false,
    node_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    selection_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    groups = {crumbly=2, oddly_breakable_by_hand=1, falling_node=1},
    drop = "",
})

minetest.register_globalstep(function(dtime)
    for i,player in ipairs(players) do
        local pos = player:getpos()
        player_pos[player:get_player_name()] = { x=math.floor(pos.x+0.5), y=math.floor(pos.y+0.5), z=math.floor(pos.z+0.5) }
        local p_ground = { x=math.floor(pos.x+0.5), y=math.floor(pos.y+0.5)-1, z=math.floor(pos.z+0.5) }
        local n_ground  = minetest.env:get_node(p_ground)
        
        -- checking if the node is the previous node
        if player_pos[player:get_player_name()] ~= player_pos_previous[player:get_player_name()] then
        
            -- gettin your feet dirty when walking on blanc dirt
            if n_ground.name == "default:dirt" then
                -- increase the players filth on a logarithmic scale.
                -- starting with 1
                if playersFilth[player:get_player_name()] < 1 then
                    playersFilth[player:get_player_name()] = 1
                    print (playersFilth[player:get_player_name()]) -- for debuging
                -- (X+5)/2 aproximates 5
                elseif playersFilth[player:get_player_name()] >= 1 then
                    playersFilth[player:get_player_name()] = math.floor((playersFilth[player:get_player_name()] + max_distance) /2 )
                    print (playersFilth[player:get_player_name()]) -- for debuging
                end
            end
            
            -- turning grass into dirt
            if n_ground.name == "default:dirt_with_grass" then
                if math.random(1, 100) <= odd then
                    minetest.env:add_node(p_ground,{type="node",name="default:dirt"})
                end
            end
            
            -- reducing filth when not walking on dirt
            if n_ground.name ~= "default:dirt" then
                if playersFilth[player:get_player_name()] > 0 then
                    -- I think thats not the right place for this line
                    playersFilth[player:get_player_name()] = playersFilth[player:get_player_name()] - 1
                    print (playersFilth[player:get_player_name()]) -- for debuging
                end
            end

            -- making filth when walking on wood
            if n_ground.name == "default:wood" then
                if playersFilth[player:get_player_name()] > 0 then
                    local p_add_filth = { x=p_ground.x, y=p_ground.y+1, z=p_ground.z }
                    local n_add_filth  = minetest.env:get_node(p_add_filth)
                    -- to not replace doors with filth
                    if n_add_filth.name == "air" then
                        minetest.env:add_node(p_add_filth,{type="node",name="filth:dirt"})
                    end
                end
            end
        end
        
        -- making node to previous node
        player_pos_previous[player:get_player_name()] =  player_pos[player:get_player_name()]
    end
end)
Last edited by Casimir on Mon Aug 13, 2012 21:51, edited 1 time in total.

ashenk69
Member
Posts: 230
Joined: Tue Jul 03, 2012 00:08

by ashenk69 » Post

On line 41 get rid of the word "local". You already have that variable declared where it can be accessed.

User avatar
Casimir
Member
Posts: 1204
Joined: Fri Aug 03, 2012 16:59
GitHub: CasimirKaPazi

by Casimir » Post

Thanks. Now it works. And I although found the problem with recognising the nodesteps. When executed once it works, done a second time the position is the previous one. I'll fix that tomorrow.

User avatar
Nexdah
Member
Posts: 42
Joined: Fri Jul 06, 2012 22:35
Location: New Minetestia

by Nexdah » Post

Do you have crafting recipies for the sweeper yet??? if not, may I suggest,
_Stick_
_Stick_
W W W
with W being wool???
This is a Signature.


First ever Astronaut in Minetest.

User avatar
Casimir
Member
Posts: 1204
Joined: Fri Aug 03, 2012 16:59
GitHub: CasimirKaPazi

by Casimir » Post

Wool is a problem as long as you have no access to it in the default game. I now made a Broom, but this will change.
Crafting:
stick
stick
leaves

Finally I got it to work. I added a few things just for experimenting. The gravel and sand stuff, will eventually change completely. The Broom, I don't know. And the rest should work.

Code: Select all

local players = {}
local playersFilth = {}
local playersSand = {}
local playersGravel = {}
local player_pos = {}
local player_pos_previous = {}

minetest.register_on_joinplayer(function(player)
    table.insert(players, player)
    playersFilth[player:get_player_name()] = 0
    playersSand[player:get_player_name()] = 0
    playersGravel[player:get_player_name()] = 0
    player_pos_previous[player:get_player_name()] = { x=0, y=0, z=0 }
end)

minetest.register_on_leaveplayer(function(player)
    table.remove(players, player)
    playersFilth[player:get_player_name()] = nil
    playersSand[player:get_player_name()] = nil
    playersGravel[player:get_player_name()] = nil
    player_pos_previous[player:get_player_name()] = nil
end)

-- chance for deterioate for x of 100
local odd = 20
local max_distance = 5

-- the filth you leave behind
minetest.register_node("filth:dirt", {
    drawtype = "nodebox",
    tile_images = {"default_dirt.png"},
    paramtype = "light",
    is_ground_content = true,
    walkable = false,
    node_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    selection_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    groups = {crumbly=3, falling_node=1, filthy=2},
    drop = "",
})

minetest.register_node("filth:sand", {
    drawtype = "nodebox",
    tile_images = {"default_sand.png"},
    paramtype = "light",
    is_ground_content = true,
    walkable = false,
    node_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    selection_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    groups = {crumbly=3, falling_node=1, filthy=3},
    drop = "",
})

minetest.register_node("filth:gravel", {
    drawtype = "nodebox",
    tile_images = {"default_gravel.png"},
    paramtype = "light",
    is_ground_content = true,
    walkable = false,
    node_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    selection_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    groups = {crumbly=2, falling_node=1, filthy=1},
    drop = "",
})

-- "invisible" extra nodes for crating the path
--[[ the order when walking over it is:
grass,
grass_walked,
dirt,
dirt_walked
--]]

minetest.register_node("filth:dirt_with_grass_walked", {
    description = "Dirt with Grass - you walked over it",
    tiles = {"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
    is_ground_content = true,
    groups = {crumbly=3},
    drop = 'default:dirt',
-- sound missing
})

minetest.register_node("filth:dirt_walked", {
    description = "Dirt - you walked over it",
    tiles = {"default_dirt.png"},
    is_ground_content = true,
    groups = {crumbly=3},
    drop = 'default:dirt',
-- sound missing
})

minetest.register_abm(
    {nodenames = {"filth:dirt_with_grass_walked"},
    interval = 37,
    chance = 13,
    action = function(pos)
        minetest.env:add_node(pos, {name="default:dirt_with_grass"})
    end,
})

minetest.register_abm(
    {nodenames = {"filth:dirt_walked"},
    interval = 37,
    chance = 13,
    action = function(pos)
        minetest.env:add_node(pos, {name="default:dirt"})
    end,
})

-- the broom (not finished)
minetest.register_tool("filth:broom", {
    description = "Broom",
    inventory_image = "default:stick.png",
    tool_capabilities = {
        max_drop_level=0,
        groupcaps={
            filthy={times={[1]=0.80, [2]=0.40, [3]=0.20}, uses=30, maxlevel=1}
        }
    },
})

minetest.register_craft({
    output = 'filth:broom',
    recipe = {
        {'default:stick'},
        {'default:stick'},
        {'default:leaves'},
    }
})



minetest.register_globalstep(function(dtime)
    for i,player in ipairs(players) do
        local pos = player:getpos()
        player_pos[player:get_player_name()] = { x=math.floor(pos.x+0.5), y=math.floor(pos.y+0.5), z=math.floor(pos.z+0.5) }
        local p_ground = { x=math.floor(pos.x+0.5), y=math.floor(pos.y+0.5)-1, z=math.floor(pos.z+0.5) }
        local n_ground  = minetest.env:get_node(p_ground)
        
        -- checking if the node is the previous node
        if player_pos[player:get_player_name()].x ~= player_pos_previous[player:get_player_name()].x or player_pos[player:get_player_name()].y ~= player_pos_previous[player:get_player_name()].y or player_pos[player:get_player_name()].z ~= player_pos_previous[player:get_player_name()].z then
        
            -- gettin your feet dirty when walking on blanc dirt
            if n_ground.name == "default:dirt" or n_ground.name == "filth:dirt_walked" then
                -- increase the players filth on a logarithmic scale.
                -- starting with 1
                if playersFilth[player:get_player_name()] < 1 then
                    playersFilth[player:get_player_name()] = 1
                    -- print (playersFilth[player:get_player_name()]) -- for debuging
                -- (X+5)/2 aproximates 5
                elseif playersFilth[player:get_player_name()] >= 1 then
                    playersFilth[player:get_player_name()] = math.floor((playersFilth[player:get_player_name()] + max_distance) /2 )
                    -- print (playersFilth[player:get_player_name()]) -- for debuging
                end
            end
            
            -- gettin your feet dirty when walking on sand
            if n_ground.name == "default:sand" then
                -- increase the players filth on a logarithmic scale.
                -- starting with 1
                if playersSand[player:get_player_name()] < 1 then
                    playersSand[player:get_player_name()] = 1
                -- (X+5)/2 aproximates 5
                elseif playersSand[player:get_player_name()] >= 1 then
                    playersSand[player:get_player_name()] = math.floor((playersSand[player:get_player_name()] + max_distance) /2 )
                end
            end
            
            -- gettin your feet dirty when walking on gravel
            if n_ground.name == "default:gravel" then
                -- increase the players filth on a logarithmic scale.
                -- starting with 1
                if playersGravel[player:get_player_name()] < 1 then
                    playersGravel[player:get_player_name()] = 1
                -- (X+5)/2 aproximates 5
                elseif playersGravel[player:get_player_name()] >= 1 then
                    playersGravel[player:get_player_name()] = math.floor((playersGravel[player:get_player_name()] + max_distance) /2 )
                end
            end
            
            -- turning grass into dirt
            if n_ground.name == "default:dirt_with_grass" then
                if math.random(1, 100) <= odd then
                    minetest.env:add_node(p_ground,{type="node",name="filth:dirt_with_grass_walked"})
                end
            end
            
            if n_ground.name == "filth:dirt_with_grass_walked" then
                if math.random(1, 100) <= odd then
                    minetest.env:add_node(p_ground,{type="node",name="default:dirt"})
                end
            end
            
            if n_ground.name == "default:dirt" then
                if math.random(1, 100) <= odd then
                    minetest.env:add_node(p_ground,{type="node",name="filth:dirt_walked"})
                end
            end
            
            -- reducing filth when not walking on dirt
            if n_ground.name ~= "default:dirt" and n_ground.name ~= "filth:dirt_walked" then
                if playersFilth[player:get_player_name()] > 0 then
                    playersFilth[player:get_player_name()] = playersFilth[player:get_player_name()] - 1
                    -- print (playersFilth[player:get_player_name()]) -- for debuging
                end
            end

            -- reducing sand
            if n_ground.name ~= "default:sand" then
                if playersSand[player:get_player_name()] > 0 then
                    playersSand[player:get_player_name()] = playersSand[player:get_player_name()] - 1
                end
            end
            
            -- reducing gravel
            if n_ground.name ~= "default:gravel" then
                if playersGravel[player:get_player_name()] > 0 then
                    playersGravel[player:get_player_name()] = playersGravel[player:get_player_name()] - 1
                end
            end
            
            -- making filth
            if n_ground.name == "default:wood"  or n_ground.name == "default:stone" or n_ground.name == "default:cobble" or n_ground.name == "default:sand" or n_ground.name == "default:gravel" then
                if playersFilth[player:get_player_name()] > 0 then
                    if math.random(1, 100) <= odd then
                        local p_add_filth = { x=p_ground.x, y=p_ground.y+1, z=p_ground.z }
                        local n_add_filth  = minetest.env:get_node(p_add_filth)
                        -- to not replace doors with filth
                        if n_add_filth.name == "air" then
                            minetest.env:add_node(p_add_filth,{type="node",name="filth:dirt"})
                        end
                    end
                end
            end
            
            -- making sand when walking on wood
            if n_ground.name == "default:wood" or n_ground.name == "default:stone" or n_ground.name == "default:cobble" or n_ground.name == "default:dirt" or n_ground.name == "default:dirt_with_grass" or n_ground.name == "default:gravel" then
                if playersSand[player:get_player_name()] > 0 then
                    if math.random(1, 100) <= odd then
                        local p_add_sand = { x=p_ground.x, y=p_ground.y+1, z=p_ground.z }
                        local n_add_sand  = minetest.env:get_node(p_add_sand)
                        -- to not replace doors with filth
                        if n_add_sand.name == "air" then
                            minetest.env:add_node(p_add_sand,{type="node",name="filth:sand"})
                        end
                    end
                end
            end
            
            -- making gravel when walking on wood
            if n_ground.name == "default:wood"  or n_ground.name == "default:stone" or n_ground.name == "default:cobble"  or n_ground.name == "default:dirt" or n_ground.name == "default:dirt_with_grass" or n_ground.name == "default:sand" then
                if playersGravel[player:get_player_name()] > 0 then
                    if math.random(1, 100) <= odd then
                        local p_add_gravel = { x=p_ground.x, y=p_ground.y+1, z=p_ground.z }
                        local n_add_gravel  = minetest.env:get_node(p_add_gravel)
                        -- to not replace doors with filth
                        if n_add_gravel.name == "air" then
                            minetest.env:add_node(p_add_gravel,{type="node",name="filth:gravel"})
                        end
                    end
                end
            end
        end
        
        -- making node to previous node
        player_pos_previous[player:get_player_name()] =  { x=player_pos[player:get_player_name()].x, y=player_pos[player:get_player_name()].y, z=player_pos[player:get_player_name()].z }
    end
end)

User avatar
rubenwardy
Moderator
Posts: 6969
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: Bristol, United Kingdom
Contact:

by rubenwardy » Post

The only thing i can add is that you can use metadata to record deteration

Everytime a player walks over, the number goes down (from 10?)

When it reaches 0 it changes to dirt and then the number goes to 10 again.
Renewed Tab (my browser add-on) | Donate | Mods | Minetest Modding Book

Hello profile reader

User avatar
Casimir
Member
Posts: 1204
Joined: Fri Aug 03, 2012 16:59
GitHub: CasimirKaPazi

by Casimir » Post

Working with metadata seems to complicated for me, just to save one block. But you are free to do it if you want to.

Yet another version, close to finish.

Sand, gravel and dirt mix up when walking over. So your path to the beach gets sandy within time.
There is a Super-Mop for cleaning up.
Crafting:

Code: Select all

x | x
x | U
# # #
x=nothing, |=stick, #=wool, U=bucket of water

And a mat for getting your feet clean.

Code: Select all

p p p
w w w
p=papyrus w=wood

Code: Select all

local players = {}
local playersFilth = {}
local playersSand = {}
local playersGravel = {}
local player_pos = {}
local player_pos_previous = {}

minetest.register_on_joinplayer(function(player)
    table.insert(players, player)
    playersFilth[player:get_player_name()] = 0
    playersSand[player:get_player_name()] = 0
    playersGravel[player:get_player_name()] = 0
    player_pos_previous[player:get_player_name()] = { x=0, y=0, z=0 }
end)

minetest.register_on_leaveplayer(function(player)
    table.remove(players, player)
    playersFilth[player:get_player_name()] = nil
    playersSand[player:get_player_name()] = nil
    playersGravel[player:get_player_name()] = nil
    player_pos_previous[player:get_player_name()] = nil
end)

-- chance for deterioate for x of 100
local odd = 37
local max_distance = 5

-- the filth you leave behind
minetest.register_node("filth:dirt", {
    drawtype = "nodebox",
    tile_images = {"default_dirt.png"},
    paramtype = "light",
    is_ground_content = true,
    walkable = false,
    node_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    selection_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    groups = {crumbly=3, falling_node=1, filthy=2},
    drop = "",
})

-- "invisible" extra nodes for crating the path
--[[ the order when walking over it is:
grass,
grass_walked,
dirt,
dirt_walked
--]]

minetest.register_node("filth:dirt_with_grass_walked", {
    description = "Dirt with Grass - you walked over it",
    tiles = {"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
    is_ground_content = true,
    groups = {crumbly=3},
    drop = 'default:dirt',
-- sound missing
})

minetest.register_node("filth:dirt_walked", {
    description = "Dirt - you walked over it",
    tiles = {"default_dirt.png"},
    is_ground_content = true,
    groups = {crumbly=3},
    drop = 'default:dirt',
-- sound missing
})

minetest.register_abm(
    {nodenames = {"filth:dirt_with_grass_walked"},
    interval = 53,
    chance = 31,
    action = function(pos)
        minetest.env:add_node(pos, {name="default:dirt_with_grass"})
    end,
})

minetest.register_abm(
    {nodenames = {"filth:dirt_walked"},
    interval = 53,
    chance = 31,
    action = function(pos)
        minetest.env:add_node(pos, {name="default:dirt"})
    end,
})

-- things for cleaning up
minetest.register_tool("filth:broom", {
    description = "Broom",
    inventory_image = "filth_tool_broom.png",
    tool_capabilities = {
        max_drop_level=0,
        groupcaps={
            filthy={times={[1]=0.80, [2]=0.40, [3]=0.20}, uses=90, maxlevel=1}
        }
    },
})

minetest.register_tool("filth:mop", {
    description = "super Mop!",
    inventory_image = "filth_tool_mop.png",
    tool_capabilities = {
        max_drop_level=0,
        groupcaps={
            filthy={times={[1]=0.70, [2]=0.30, [3]=0.10}, uses=5, maxlevel=1}
        }
    },
})

minetest.register_node("filth:mat", {
    description = "Home sweet Home",
    drawtype = "nodebox",
    tile_images = {"filth_mat.png"},
    paramtype = "light",
    is_ground_content = true,
    walkable = false,
    node_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    selection_box = {
        type = "fixed",
        fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
    },
    groups = {snappy=2,choppy=2,oddly_breakable_by_hand=3,flammable=3},
})

minetest.register_craft({
    output = 'filth:broom',
    recipe = {
        {'default:stick'},
        {'default:stick'},
        {'default:leaves'},
    }
})

minetest.register_craft({
    output = 'filth:mop',
    recipe = {
        {'', 'default:stick', ''},
        {'', 'default:stick', 'bucket:bucket_water'},
        {'wool:white', 'wool:white', 'wool:white'},
    }
})

minetest.register_craft({
    output = 'filth:mat',
    recipe = {
        {'default:papyrus', 'default:papyrus', 'default:papyrus'},
        {'default:wood', 'default:wood', 'default:wood'},
    }
})

minetest.register_globalstep(function(dtime)
    for i,player in ipairs(players) do
        local pos = player:getpos()
        player_pos[player:get_player_name()] = { x=math.floor(pos.x+0.5), y=math.floor(pos.y+0.5), z=math.floor(pos.z+0.5) }
        local p_ground = { x=math.floor(pos.x+0.5), y=math.floor(pos.y+0.5)-1, z=math.floor(pos.z+0.5) }
        local n_ground  = minetest.env:get_node(p_ground)
        
        -- checking if the node is the previous node
        if player_pos[player:get_player_name()].x ~= player_pos_previous[player:get_player_name()].x or player_pos[player:get_player_name()].y ~= player_pos_previous[player:get_player_name()].y or player_pos[player:get_player_name()].z ~= player_pos_previous[player:get_player_name()].z then
        
            -- gettin your feet dirty when walking on blanc dirt
            if n_ground.name == "default:dirt" or n_ground.name == "filth:dirt_walked" then
                -- increase the players filth on a logarithmic scale.
                -- starting with 1
                if playersFilth[player:get_player_name()] < 1 then
                    playersFilth[player:get_player_name()] = 1
                    -- print (playersFilth[player:get_player_name()]) -- for debuging
                -- (X+5)/2 aproximates 5
                elseif playersFilth[player:get_player_name()] >= 1 then
                    playersFilth[player:get_player_name()] = math.floor((playersFilth[player:get_player_name()] + max_distance) /2 )
                    -- print (playersFilth[player:get_player_name()]) -- for debuging
                end
            end
            
            -- gettin your feet dirty when walking on sand
            if n_ground.name == "default:sand" then
                -- increase the players filth on a logarithmic scale.
                -- starting with 1
                if playersSand[player:get_player_name()] < 1 then
                    playersSand[player:get_player_name()] = 1
                -- (X+5)/2 aproximates 5
                elseif playersSand[player:get_player_name()] >= 1 then
                    playersSand[player:get_player_name()] = math.floor((playersSand[player:get_player_name()] + max_distance) /2 )
                end
            end
            
            -- gettin your feet dirty when walking on gravel
            if n_ground.name == "default:gravel" then
                -- increase the players filth on a logarithmic scale.
                -- starting with 1
                if playersGravel[player:get_player_name()] < 1 then
                    playersGravel[player:get_player_name()] = 1
                -- (X+5)/2 aproximates 5
                elseif playersGravel[player:get_player_name()] >= 1 then
                    playersGravel[player:get_player_name()] = math.floor((playersGravel[player:get_player_name()] + max_distance) /2 )
                end
            end
            
            -- turning grass into dirt
            if n_ground.name == "default:dirt_with_grass" then
                if math.random(1, 100) <= odd then
                    minetest.env:add_node(p_ground,{type="node",name="filth:dirt_with_grass_walked"})
                end
            end
            
            if n_ground.name == "filth:dirt_with_grass_walked" then
                if math.random(1, 100) <= odd then
                    minetest.env:add_node(p_ground,{type="node",name="default:dirt"})
                end
            end
            
            if n_ground.name == "default:dirt" then
                if math.random(1, 100) <= odd then
                    minetest.env:add_node(p_ground,{type="node",name="filth:dirt_walked"})
                end
            end
            
            -- reducing filth when not walking on dirt
            if n_ground.name ~= "default:dirt" and n_ground.name ~= "filth:dirt_walked" then
                if playersFilth[player:get_player_name()] > 0 then
                    playersFilth[player:get_player_name()] = playersFilth[player:get_player_name()] - 1
                    -- print (playersFilth[player:get_player_name()]) -- for debuging
                end
            end

            -- reducing sand
            if n_ground.name ~= "default:sand" then
                if playersSand[player:get_player_name()] > 0 then
                    playersSand[player:get_player_name()] = playersSand[player:get_player_name()] - 1
                end
            end
            
            -- reducing gravel
            if n_ground.name ~= "default:gravel" then
                if playersGravel[player:get_player_name()] > 0 then
                    playersGravel[player:get_player_name()] = playersGravel[player:get_player_name()] - 1
                end
            end
            
            local n_playerpos = minetest.env:get_node(player_pos[player:get_player_name()])
            if n_playerpos.name == "filth:mat" then
                playersFilth[player:get_player_name()] = 0
                playersSand[player:get_player_name()] = 0
                playersGravel[player:get_player_name()] = 0
            else                
                -- making filth
                if n_ground.name == "default:wood"  or n_ground.name == "default:stone" or n_ground.name == "default:cobble" then
                    if playersFilth[player:get_player_name()] > 0 then
                        if math.random(1, 100) <= odd then
                            local p_add_filth = { x=p_ground.x, y=p_ground.y+1, z=p_ground.z }
                            local n_add_filth  = minetest.env:get_node(p_add_filth)
                            -- to not replace doors with filth
                            if n_add_filth.name == "air" then
                                minetest.env:add_node(p_add_filth,{type="node",name="filth:dirt"})
                            end
                        end
                    end
                end
            
                -- turning dirt and gravel into sand
                if n_ground.name == "default:dirt" or n_ground.name == "default:gravel" or n_ground.name == "filth:dirt_walked" then
                    if playersSand[player:get_player_name()] > 0 then
                        local r_number = math.random(1, (200*max_distance))
                        local odd_temp = odd * playersSand[player:get_player_name()]
                        if r_number <= odd_temp then
                                minetest.env:add_node(p_ground,{type="node",name="default:sand"})
                        end
                    end
                end
            
                -- turning dirt and sand into gravel
                if n_ground.name == "default:dirt" or n_ground.name == "default:sand" or n_ground.name == "filth:dirt_walked" then
                    if playersGravel[player:get_player_name()] > 0 then
                        local r_number = math.random(1, (200*max_distance))
                        local odd_temp = odd * playersGravel[player:get_player_name()]
                        if r_number <= odd_temp then
                                minetest.env:add_node(p_ground,{type="node",name="default:gravel"})
                        end
                    end
                end
                
                -- turning gravel and sand into dirt
                if n_ground.name == "default:gravel" or n_ground.name == "default:sand" then
                    if playersFilth[player:get_player_name()] > 0 then
                        local r_number = math.random(1, (200*max_distance))
                        local odd_temp = odd * playersFilth[player:get_player_name()]
                        if r_number <= odd_temp then
                                minetest.env:add_node(p_ground,{type="node",name="default:dirt"})
                        end
                    end
                end
                
            end
        end
        
        -- making node to previous node
        player_pos_previous[player:get_player_name()] =  { x=player_pos[player:get_player_name()].x, y=player_pos[player:get_player_name()].y, z=player_pos[player:get_player_name()].z }
    end
end)
If now somebody tells me how to get the sound working, it could make it to release.
Last edited by Casimir on Fri Aug 17, 2012 15:47, edited 1 time in total.

User avatar
rubenwardy
Moderator
Posts: 6969
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: Bristol, United Kingdom
Contact:

by rubenwardy » Post

Casimir wrote:Working with metadata seems to complicated for me, just to save one block. But you are free to do it if you want to.

Yet another version, close to finish.

Sand, gravel and dirt mix up when walking over. So your path to the beach gets sandy within time.
There is a Super-Mop for cleaning up.
Crafting:

Code: Select all

x | x
x | U
# # #
x=nothing, |=stick, #=wool, U=bucket of water

And a mat for getting your feet clean.

Code: Select all

p p p
w w w
p=papyrus w=wood

Code: Select all

-------Removed Code------
If now somebody tells me how to get the sound working, it could make it to release.
Sorry, i meant the thing signs use to store data, not metadata
Last edited by rubenwardy on Fri Aug 17, 2012 17:40, edited 1 time in total.
Renewed Tab (my browser add-on) | Donate | Mods | Minetest Modding Book

Hello profile reader

User avatar
Echo
Member
Posts: 122
Joined: Tue Jul 31, 2012 08:11
Location: Germany

by Echo » Post

@Casimir: you use

Code: Select all

minetest.register_on_leaveplayer(function(player)
    table.remove(players, player)
end)
That's wrong. I used it in my mod, too. (I copied these three lines from here) ;-).
You have to declare a position, not a value.
Use this:

Code: Select all

minetest.register_on_leaveplayer(function(player)
    for i,v in ipairs(players) do
        if v == player then 
            table.remove(players, i)
        end
    end
end)

User avatar
PilzAdam
Member
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
GitHub: PilzAdam
IRC: PilzAdam
Location: Germany

by PilzAdam » Post

Echo wrote:@Casimir: you use

Code: Select all

minetest.register_on_leaveplayer(function(player)
    table.remove(players, player)
end)
That's wrong. I used it in my mod, too. (I copied these three lines from here) ;-).
You have to declare a position, not a value.
Use this:

Code: Select all

minetest.register_on_leaveplayer(function(player)
    for i,v in ipairs(players) do
        if v == player then 
            table.remove(players, i)
        end
    end
end)
You dont need this at all if you use

Code: Select all

minetest.get_connected_players()

User avatar
Casimir
Member
Posts: 1204
Joined: Fri Aug 03, 2012 16:59
GitHub: CasimirKaPazi

by Casimir » Post

Echo wrote:That's wrong. I used it in my mod, too. (I copied these three lines from here) ;-).
And I taught I copied it from you...

@ PilzAdam
Can you tell me how exactly to use this?
Then I would fix the drowning-mod too. It has bugs over and over.

User avatar
PilzAdam
Member
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
GitHub: PilzAdam
IRC: PilzAdam
Location: Germany

by PilzAdam » Post

Casimir wrote:
Echo wrote:That's wrong. I used it in my mod, too. (I copied these three lines from here) ;-).
And I taught I copied it from you...

@ PilzAdam
Can you tell me how exactly to use this?
Then I would fix the drowning-mod too. It has bugs over and over.

Code: Select all

for _,player in ipairs(minetest.get_connected_players()) do
    [code here]
end
With this you dont have to use register_on_joinplayer/leaveplayer anymore.

Post Reply

Who is online

Users browsing this forum: No registered users and 9 guests