Filth Mod

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

Filth Mod

by ashenk69 » Wed Aug 08, 2012 15:21

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 » Wed Aug 08, 2012 15:28

nice ideas!
 

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

by Casimir » Wed Aug 08, 2012 17:38

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 » Wed Aug 08, 2012 20:05

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: 1101
Joined: Fri Aug 03, 2012 16:59

by Casimir » Wed Aug 08, 2012 21:22

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:
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
-- 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: 131
Joined: Tue Jul 31, 2012 20:37

by leo_rockway » Wed Aug 08, 2012 22:09

This sounds interesting. I'll be checking this thread to see what you guys come up with =]
 

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

by ashenk69 » Wed Aug 08, 2012 23:05

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 » Thu Aug 09, 2012 00:26

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.

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
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: 401
Joined: Wed May 16, 2012 00:37

by Linxx » Thu Aug 09, 2012 05:19

this could be done for snow too :) nice idea
 

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

by Casimir » Thu Aug 09, 2012 11:00

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.
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
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: 121
Joined: Tue Jul 31, 2012 08:11

by Echo » Thu Aug 09, 2012 11:08

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 » Thu Aug 09, 2012 14:35

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 » Thu Aug 09, 2012 14:43

@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: 1101
Joined: Fri Aug 03, 2012 16:59

by Casimir » Mon Aug 13, 2012 20:01

I now cleaned up the code, but checking if the player is on another node still isn't working.
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
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]
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
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 » Mon Aug 13, 2012 21:35

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: 1101
Joined: Fri Aug 03, 2012 16:59

by Casimir » Mon Aug 13, 2012 21:57

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

by Nexdah » Mon Aug 13, 2012 22:47

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: 1101
Joined: Fri Aug 03, 2012 16:59

by Casimir » Wed Aug 15, 2012 14:30

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.
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
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
Member
 
Posts: 4500
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

by rubenwardy » Wed Aug 15, 2012 17:33

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.
 

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

by Casimir » Fri Aug 17, 2012 15:47

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:
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
x | x
x | U
# # #

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

And a mat for getting your feet clean.
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
p p p
w w w

p=papyrus w=wood

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
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
Member
 
Posts: 4500
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

by rubenwardy » Fri Aug 17, 2012 17:39

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:
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
x | x
x | U
# # #

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

And a mat for getting your feet clean.
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
p p p
w w w

p=papyrus w=wood

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
-------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.
 

User avatar
Echo
Member
 
Posts: 121
Joined: Tue Jul 31, 2012 08:11

by Echo » Thu Aug 23, 2012 19:06

@Casimir: you use
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_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:
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_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

by PilzAdam » Fri Aug 24, 2012 10:22

Echo wrote:@Casimir: you use
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_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:
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_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
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.get_connected_players()
 

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

by Casimir » Wed Aug 29, 2012 17:17

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

by PilzAdam » Wed Aug 29, 2012 17:22

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.

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
for _,player in ipairs(minetest.get_connected_players()) do
    [code here]
end

With this you dont have to use register_on_joinplayer/leaveplayer anymore.
 

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

by Casimir » Sun Sep 16, 2012 18:32

PilzAdam's suggestion included. Now it works for multiplayer too. Desertsand added.
But I still have problems with the sound. As soon as somebody tells me how to make sound when walking over dirt, I will make the first release.
 


Return to WIP Mods

Who is online

Users browsing this forum: No registered users and 13 guests

cron