Issues with Porting Rope Mod

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

Issues with Porting Rope Mod

by Temperest » Post

Trying to port the Rope mod to work with ItemDef. Although it is functional now, I'm having trouble removing the rope from the player's inventory after placing a rope. Here is the code:

Code: Select all

-- Rope mod. By Mirko K.
--
-- Three tree block in a vertical row = 9 meter of rope.
-- Placement automatically adds rope downwards until it runs out or some
-- non-air block is in the way.
-- Push (single left-click) cuts the rope at that position. Digging removes
-- the whole rope.
--
-- Licence:
--   Code: GPL
--   Texture: CC-BY-SA

minetest.register_on_placenode(function(pos, newnode, placer)
    if newnode.name == "ropes:rope" then
        place_rope(pos, newnode, placer)
    end
    end
)

minetest.register_on_dignode(function(pos, oldnode, digger)
    if oldnode.name == "ropes:rope" then
        remove_rope(pos, oldnode, digger, true)
        end
    end
)

minetest.register_on_punchnode(function(pos, oldnode, digger)
    if oldnode.name == "ropes:rope" then
        remove_rope(pos, oldnode, digger, false)
        end
    end
)

place_rope = function (pos, newnode, placer)
    while placer:get_inventory():contains_item("main", "ropes:rope") do
    pos.y = pos.y - 1
    if minetest.env:get_node(pos).name ~= "air" then
        break
    end
    placer:get_inventory():remove_item("main", "ropes:rope") --remove rope
    minetest.env:add_node(pos, {name="ropes:rope", param2=newnode.param2})
    end
end

remove_rope = function(pos, oldnode, digger, completely)
    local num = 0
    local above = {x=pos.x,y=pos.y+1,z=pos.z}
    if completely == true then
    while minetest.env:get_node(above).name == "ropes:rope" do
        minetest.env:remove_node(above)
        above.y = above.y + 1
        num = num + 1
    end
    end
    local below = {x=pos.x,y=pos.y-1,z=pos.z}
    while minetest.env:get_node(below).name == "ropes:rope" do
    minetest.env:remove_node(below)
    below.y = below.y -1
    num = num + 1
    end
    if num ~= 0 then
    digger:get_inventory():add_item("main", '"ropes:rope" '..num)
    end
    return true
end

minetest.register_craft({
    output = '"ropes:rope" 9',
    recipe = {
        {'', 'tree', ''},
        {'', 'tree', ''},
        {'', 'tree', ''},
    }
})

minetest.register_node("ropes:rope", {
    description = "Rope",
    drawtype = "signlike",
    tile_images = {"rope.png"},
    inventory_image = "rope.png",
    light_propagates = true,
    paramtype = "light",
    paramtype2 = "wallmounted",
    legacy_wall_mounted = true,
    is_ground_content = true,
    walkable = false,
    climbable = true,
    selection_box = {
        type = "wallmounted",
    --wall_top = = <default>
    --wall_bottom = = <default>
    --wall_side = = <default>
    },
    furnace_burntime = 5,
    material = {
    diggablity = "normal",
    cuttability = 1.5,
    },
})
Does anyone know what I'm doing wrong?
WorldEdit 1.0 released

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

kahrl
Member
Posts: 236
Joined: Fri Sep 02, 2011 07:51
Location: Rös̓̇chenhof

by kahrl » Post

The intent is that when n rope blocks are placed, it should remove n rope items from the inventory, is that right?

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

by Temperest » Post

Yes, that is correct.

Specifically, the issue is with the place_rope function, where it says digger:get_inventory():remove_item...". It doesn't seem to remove the item no matter what I try.
WorldEdit 1.0 released

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

kahrl
Member
Posts: 236
Joined: Fri Sep 02, 2011 07:51
Location: Rös̓̇chenhof

by kahrl » Post

Yes, it's a design limitation in itemdef, on_placenode can't modify the wielded item. But you could redefine the more low-level (and more complicated) on_place callback, untested:

Code: Select all


-- remove the register_on_placenode call

...

place_rope = function(itemstack, placer, pointed_thing)
    if pointed_thing.type == "node" then
        -- Calculate wall-mount direction
        local under = pointed_thing.under
        local above = pointed_thing.above
        local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}
        local param2_wallmounted = minetest.dir_to_wallmounted(dir)

        local pos = above
        local oldnode = minetest.env:get_node(pos)
        local olddef = ItemStack({name=oldnode.name}):get_definition()

        while olddef.buildable_to and not itemstack:is_empty() do
            minetest.log("action", placer:get_player_name() .. " places rope "
                .. " at " .. minetest.pos_to_string(pos))

            -- Place the rope
            local newnode = {name = "ropes:rope", param1 = 0, param2 = param2_wallmounted}
            minetest.env:add_node(pos, newnode)
            itemstack:take_item()

            -- if you want, call all callbacks in minetest.registered_on_placenodes here
            -- see minetest.item_place_node in builtin.lua

            -- Go down
            pos.y = pos.y - 1
            oldnode = minetest.env:get_node(pos)
            olddef = ItemStack({name=oldnode.name}):get_definition()
        end
    end
    return itemstack
end

...

minetest.register_node("ropes:rope", {
    ...
    on_place = place_rope,
    ...
})
There are some more or less important differences: first, the rope extends to anywhere that is buildable, in particular into water and other liquids. If you don't want that, simply replace the check for buildable_to with a check whether oldnode.name == "air". Second, if a stack of (let's say) 10 ropes is in your hand and another stack of 5 somewhere else in the inventory, the rope will only go down up to 10 nodes, unlike before where it tried to place all 15.

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

by randomproof » Post

'furnace_burntime = 5,' is deprecated:

Code: Select all

minetest.register_craft({
    type = "fuel",
    recipe = "ropes:rope",
    burntime = 5,
})
And you don't need the extra quotes in the output:

Code: Select all

minetest.register_craft({
    output = 'ropes:rope 9',
    recipe = {
        {'', 'tree', ''},
        {'', 'tree', ''},
        {'', 'tree', ''},
    }
})
Also, I use papyrus instead of wood for the crafting recipe, but whatever.

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

by Temperest » Post

@kahrl: thanks, that worked great!

Seems like the folks behind RTMMP have added these changes in already:

https://github.com/Hackeridze/ru-true_m ... s/init.lua

I'll see what I can do about adding randomproof's suggestions.

Edit: Here is the new version:

Code: Select all

-- Rope mod. By Mirko K.
--
-- Three papyrus block in a vertical row = 9 meter of rope.
-- Placement automatically adds rope downwards until it runs out or some
-- non-air block is in the way.
-- Push (single left-click) cuts the rope at that position. Digging removes
-- the whole rope.
--
-- Licence:
--   Code: GPL
--   Texture: CC-BY-SA

minetest.register_on_dignode(function(pos, oldnode, digger)
    if oldnode.name == "ropes:rope" then
        remove_rope(pos, oldnode, digger, true)
        end
    end
)

minetest.register_on_punchnode(function(pos, oldnode, digger)
    if oldnode.name == "ropes:rope" then
        remove_rope(pos, oldnode, digger, false)
        end
    end
)

place_rope = function(itemstack, placer, pointed_thing)
    if pointed_thing.type == "node" then
        -- Calculate wall-mount direction
        local under = pointed_thing.under
        local above = pointed_thing.above
        local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}
        local param2_wallmounted = minetest.dir_to_wallmounted(dir)

        local pos = above
        local oldnode = minetest.env:get_node(pos)
        local olddef = ItemStack({name=oldnode.name}):get_definition()

        while oldnode.name == "air" and not itemstack:is_empty() do
            minetest.log("action", placer:get_player_name() .. " places rope "
                .. " at " .. minetest.pos_to_string(pos))

            -- Place the rope
            local newnode = {name = "ropes:rope", param1 = 0, param2 = param2_wallmounted}
            minetest.env:add_node(pos, newnode)
            itemstack:take_item()

            -- if you want, call all callbacks in minetest.registered_on_placenodes here
            -- see minetest.item_place_node in builtin.lua

            -- Go down
            pos.y = pos.y - 1
            oldnode = minetest.env:get_node(pos)
            olddef = ItemStack({name=oldnode.name}):get_definition()
        end
    end
    return itemstack
end

remove_rope = function(pos, oldnode, digger, completely)
    local num = 0
    local above = {x=pos.x,y=pos.y+1,z=pos.z}
    if completely == true then
    while minetest.env:get_node(above).name == "ropes:rope" do
        minetest.env:remove_node(above)
        above.y = above.y + 1
        num = num + 1
    end
    end
    local below = {x=pos.x,y=pos.y-1,z=pos.z}
    while minetest.env:get_node(below).name == "ropes:rope" do
    minetest.env:remove_node(below)
    below.y = below.y -1
    num = num + 1
    end
    if num ~= 0 then
    digger:get_inventory():add_item("main", '"ropes:rope" '..num)
    end
    return true
end

minetest.register_craft({
    output = '"ropes:rope" 9',
    recipe = {
        {'default:papyrus'},
        {'default:papyrus'},
        {'default:papyrus'},
    }
})

minetest.register_node("ropes:rope", {
    description = "Rope",
    drawtype = "signlike",
    tile_images = {"rope.png"},
    inventory_image = "rope.png",
    light_propagates = true,
    paramtype = "light",
    paramtype2 = "wallmounted",
    legacy_wall_mounted = true,
    is_ground_content = true,
    walkable = false,
    climbable = true,
    selection_box = {
        type = "wallmounted",
    --wall_top = = <default>
    --wall_bottom = = <default>
    --wall_side = = <default>
    },
    on_place = place_rope,
    burntime = 5,
    material = {
    diggablity = "normal",
    cuttability = 1.5,
    },
})
Last edited by Temperest on Wed Feb 01, 2012 16:16, edited 1 time in total.
WorldEdit 1.0 released

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

User avatar
sdzen
Member
Posts: 1170
Joined: Fri Aug 05, 2011 22:33
Location: Paradise (your not allowed)

by sdzen » Post

randomproof wrote: Also, I use papyrus instead of wood for the crafting recipe, but whatever.
Why not junglewood or leaves and jungle wood
While this topic is here i was trying to update the secret passages and fix a spelling error i noticed but its having trouble around the register craft area help would be liked

Code: Select all

minetest.register_node('secret_passage:bookshelf', {
    drawtype = 'allfaces',
    description = "FalseShelf",
    tile_images = {'sp_bookshelf.png'},
    inventory_image = 'sp_bookshelf.png',
    sunlight_propagates = true,
    paramtype = 'light',
    walkable = false,
    climable = false,
    selection_box = {
        type = "fixed",
        fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
    },
    material = minetest.digprop_constanttime(1.0),
    drop = "secret_passage:bookshelf",
})

minetest.register_node('secret_passage:wood', {
    drawtype = 'allfaces',
    description = "falsewood",
    tile_images = {'sp_wood.png'},
    inventory_image = 'sp_wood.png',
    sunlight_propagates = true,
    paramtype = 'light',
    walkable = false,
    climable = false,
    selection_box = {
        type = "fixed",
        fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
    },
    material = minetest.digprop_constanttime(1.0),
    drop = "secret_passage:wood",
})

minetest.register_node('secret_passage:brick', {
    drawtype = 'allfaces',
    description = "FalseBrick",
    tile_images = {'sp_brick.png'},
    inventory_image = 'sp_brick.png',
    sunlight_propagates = true,
    paramtype = 'light',
    walkable = false,
    climable = false,
    selection_box = {
        type = "fixed",
        fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
    },
    material = minetest.digprop_constanttime(1.0),
    drop = "secret_passage:brick",
})

minetest.register_node('secret_passage:cobble', {
    drawtype = 'allfaces',
    description = "FalseCobble",
    tile_images = {'sp_cobble.png'},
    inventory_image = 'sp_cobble.png',
    sunlight_propagates = true,
    paramtype = 'light',
    walkable = false,
    climable = false,
    selection_box = {
        type = "fixed",
        fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
    },
    material = minetest.digprop_constanttime(1.0),
    drop = "secret_passage:cobble",
})

minetest.register_node('secret_passage:component', {
    drawtype = 'allfaces',
    description = "Component",
    tile_images = {'sp_compoent.png'},
    inventory_image = 'sp_compoent.png',
    sunlight_propagates = true,
    paramtype = 'light',
    walkable = false,
    climable = false,
    selection_box = {
        type = "fixed",
        fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
    },
    material = minetest.digprop_constanttime(1.0),
    drop = 'secret_passage:component',
})

minetest.register_craft({
    output = 'secret_passage:component',
    recipe = {
        {"default:glass", "default:glass", "default:glass"},
        {"default:dirt"},
    }
}) 

minetest.register_craft({
    output = "secret_passage:bookshelf",
    recipe = {
        {"secret_passage:component", "default:bookshelf", "secret_passage:component"},
        {"secret_passage:component", "default:bookshelf", "secret_passage:component"},
    }
})

minetest.register_craft({
    output = "secret_passage:wood",
    recipe = {
        {"secret_passage:component", "default:wood", "secret_passage:component"},
        {"secret_passage:component", "default:wood", "secret_passage:component"},
    }
})

minetest.register_craft({
    output = "secret_passage:cobble",
    recipe = {
        {"secret_passage:component", "default:cobble", "secret_passage:component"},
        {"secret_passage:component", "default:cobble", "secret_passage:component"},
    }
})

minetest.register_craft({
    output = "secret_passage:brick",
    recipe = {
        {"secret_passage:component", "default:brick", "secret_passage:component"},
        {"secret_passage:component", "default:brick", "secret_passage:component"},
    }
})
Last edited by sdzen on Wed Feb 01, 2012 22:35, edited 1 time in total.

Zen S.D.

The next generation of tranquility!
malheureusement mon français n'est pas bon :<
Owner of the Zelo's
In game name: MuadTralk, spdtainted, sdzen, sd zen, sdzeno

User avatar
dannydark
Member
Posts: 428
Joined: Fri Aug 12, 2011 21:28
Location: Manchester, UK

by dannydark » Post

@sdzen:

Your top recipe is incorrect is should be:

Code: Select all

minetest.register_craft({
    output = 'secret_passage:component',
    recipe = {
        {'default:glass', 'default:glass', 'default:glass'},
        {'default:dirt', '', ''},
    }
}) 
You where missing the two empty fields on the 2nd row, because you use all 3 fields on the top row you must make sure you add all 3 fields to each row there after.
Last edited by dannydark on Thu Feb 02, 2012 00:20, edited 1 time in total.

User avatar
sdzen
Member
Posts: 1170
Joined: Fri Aug 05, 2011 22:33
Location: Paradise (your not allowed)

by sdzen » Post

thanks worst mistake ive mad in awhile
0 Days with out incident
Last edited by sdzen on Thu Feb 02, 2012 21:16, edited 1 time in total.

Zen S.D.

The next generation of tranquility!
malheureusement mon français n'est pas bon :<
Owner of the Zelo's
In game name: MuadTralk, spdtainted, sdzen, sd zen, sdzeno

wulfsdad
Member
Posts: 45
Joined: Tue Dec 04, 2012 10:38
GitHub: hildigerr

by wulfsdad » Post

I noticed that the remove_rope() function never removes the rope at pos.y, only above and below it. Also, when you dig a node it gets punched and so the function is never passed a true value for completely. I also wanted to support the vine-like rope from moreblocks, and use cotton from flowers or wool (or curtains) in the recipes, instead of wood or papyrus. So, I modified the code:

Code: Select all

-- Rope mod. By Mirko K.
--        modified by Temperest <http://minetest.net/forum/profile.php?id=640> [FEB 2012]
--        modified by Wulfsdad <http://minetest.net/forum/profile.php?id=3738> [DEC 2012]
--        
-- Placement automatically adds rope downwards until it runs out or some
-- non-air block is in the way.
-- Push (single left-click) cuts the rope at that position. Digging removes
-- the whole rope.
--
-- Licence:
--   Code: GPL
--   Texture: CC-BY-SA


minetest.register_on_punchnode(function(pos, oldnode, digger)
    if oldnode.name == "ropes:rope" then
        remove_rope(pos, oldnode, digger, "ropes:rope")
     elseif oldnode.name == "moreblocks:rope" then
        remove_rope(pos, oldnode, digger, "moreblocks:rope")
     end
end)

place_rope = function(itemstack, placer, pointed_thing)
    if pointed_thing.type == "node" then
        -- Calculate wall-mount direction
        local under = pointed_thing.under
        local above = pointed_thing.above
        local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}
        local param2_wallmounted = minetest.dir_to_wallmounted(dir)

        local pos = above
        local oldnode = minetest.env:get_node(pos)
        local olddef = ItemStack({name=oldnode.name}):get_definition()

        while oldnode.name == "air" and not itemstack:is_empty() do
            minetest.log("action", placer:get_player_name() .. " places rope "
                .. " at " .. minetest.pos_to_string(pos))

            -- Place the rope
                local newnode = {name = itemstack:get_name(), param1 = 0, param2 = param2_wallmounted}
            minetest.env:add_node(pos, newnode)
            itemstack:take_item()

            -- if you want, call all callbacks in minetest.registered_on_placenodes here
            -- see minetest.item_place_node in builtin.lua

            -- Go down
            pos.y = pos.y - 1
            oldnode = minetest.env:get_node(pos)
            olddef = ItemStack({name=oldnode.name}):get_definition()
        end
    end
    return itemstack
end

remove_rope = function(pos, oldnode, digger, rope_name)
    local num = 0
    local below = {x=pos.x,y=pos.y,z=pos.z}
    while minetest.env:get_node(below).name == rope_name do
        minetest.env:remove_node(below)
        below.y = below.y -1
        num = num + 1
    end
    if num ~= 0 then
        digger:get_inventory():add_item("main", rope_name..' '..num)
    end
    return true
end

minetest.register_craft({
    output = '"ropes:rope" 2',
    recipe = {
        {'flowers:cotton'},
        {'flowers:cotton'},
        {'flowers:cotton'},
    }
})

minetest.register_craft({
    output = '"ropes:rope" 6',
    recipe = {
        {'wool:white','',''},
        {'','wool:white',''},
        {'','','wool:white'},
    }
})

minetest.register_craft({
    output = '"ropes:rope" 6',
    recipe = {
        {'','','wool:white'},
        {'','wool:white',''},
        {'wool:white','',''},
    }
})

minetest.register_craft({
    output = '"ropes:rope" 6',
    recipe = {
        {'homedecor:curtain_white'},
        {'homedecor:curtain_white'},
        {'homedecor:curtain_white'},
    }
})

minetest.register_node("ropes:rope", {
    description = "Rope",
    drawtype = "signlike",
    tile_images = {"rope.png"},
    inventory_image = "rope.png",
     wield_image = "rope.png",
    light_propagates = true,
    paramtype = "light",
    paramtype2 = "wallmounted",
    legacy_wall_mounted = true,
    is_ground_content = true,
    walkable = false,
    climbable = true,
    selection_box = {
        type = "wallmounted",
    --wall_top = = <default>
    --wall_bottom = = <default>
    --wall_side = = <default>
    },
    on_place = place_rope,
--     burntime = 5,
--     material = {
--     diggablity = "normal",
--     cuttability = 1.5,
--     },
    groups = {flammable=2},
})

minetest.register_node(":moreblocks:rope", {
    description = "Rope",
    drawtype = "signlike",
    tiles = {"moreblocks_rope.png"},
    inventory_image = "moreblocks_rope.png",
    wield_image = "moreblocks_rope.png",
    light_propagates = true,
    paramtype = "light",
    paramtype2 = "wallmounted",
    legacy_wall_mounted = true,
    is_ground_content = true,
    walkable = false,
    climbable = true,
    selection_box = {
        type = "wallmounted",
    },
    on_place = place_rope,
    groups = {snappy=3,flammable=2},
    sounds = default.node_sound_leaves_defaults(),
})
In order for the vine-like ropes to work, I had to include a depends.txt file to depend on moreblocks.

Post Reply

Who is online

Users browsing this forum: No registered users and 36 guests