Page 1 of 1

help making a sound play when a certain item is detected in a formspec

PostPosted: Fri May 10, 2013 01:25
by 12Me21
I was trying to make a cd player mod (like the music disk player in minecraft), and I got the formspec to work, but I can't get it to play a sound when the item is detected. Here's the code:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
minetest.register_node("cd_player:player", {
    description = "CD Player",
    tiles = {"cd_player_top.png", "cd_player_bottom.png", "cd_player_sides.png", "cd_player_sides.png", "cd_player_sides.png", "cd_player_front.png"},
    paramtype2 = "facedir",
    groups = {snappy=3,choppy=1,oddly_breakable_by_hand=2},
    legacy_facedir_simple = true,
    sounds = default.node_sound_defaults(),
    on_construct = function(pos)
        local meta = minetest.env:get_meta(pos)
        meta:set_string("formspec",
                "size[8,5.5]"..
                "list[current_name;main;3.5,;1,1;]"..
                "list[current_player;main;0,1.5;8,4;]")
        meta:set_string("infotext", "CD Player")
        local inv = meta:get_inventory()
        inv:set_size("main", 1)
    end,
    can_dig = function(pos,player)
        local meta = minetest.env:get_meta(pos);
        local inv = meta:get_inventory()
        return inv:is_empty("main")
    end,
   
    on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
        minetest.log("action", player:get_player_name()..
                " moves stuff in cd player at "..minetest.pos_to_string(pos))
    end,
    on_metadata_inventory_put = function(pos, listname, index, stack, player)
        minetest.log("action", player:get_player_name()..
                " moves stuff to cd player at "..minetest.pos_to_string(pos))
    end,
    on_metadata_inventory_take = function(pos, listname, index, stack, player)
        minetest.log("action", player:get_player_name()..
                " takes stuff from cd player at "..minetest.pos_to_string(pos))
end,
    on_metadata_inventory_put = function(pos, node, listname, index, stack, player)
    local meta = minetest.env:get_meta(node)
    local inv = meta:get_inventory()
    if inv:contains_item("cd_player:cd_1") then
        minetest.sound_play("cd_player_1.ogg", {gain = 0.5, max_hear_distance = 25})
        end
   
    end,
})

minetest.register_craftitem("cd_player:cd_1", {
    image = "cd_player_cd_1.png",
        description="CD 1",
})

When I try to put the CD into the cd player, It says:
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
19:58:42: ERROR[main]: ServerError: LuaError: error: ...netest-0.4.6\bin\..\mods\minetest\cd_player\init.lua:37: bad argument #1 to 'get_meta' (table expected, got string)
19:58:42: ERROR[main]: stack traceback:
19:58:42: ERROR[main]: InventoryMenu: The selected inventory location "nodemeta:-454,3,468" doesn't exist
In trans_func.
Access violation at 00000000 write?=8 address=0
19:58:42: ERROR[main]: Some exception: "Access violation"


I haven't (successfully) done any mods using formspecs, so I have no idea how to fix it. Can someone please help?

EDIT: I think where I'm doing it wrong is the part where it (is supposed to) detect whether there is a cd in the formspec.

PostPosted: Fri May 10, 2013 03:03
by kaeza
Move the get_meta() and related calls to after_place_node callback

PostPosted: Fri May 10, 2013 03:26
by kahrl
You defined on_metadata_inventory_put twice (the second time with an extraneous "node" parameter). Move the code from the second definition to the first and delete the second definition. Also you will have to change get_meta(node) to get_meta(pos).

PostPosted: Fri May 10, 2013 12:32
by BlockMen
1.) umm...[Mod] Jukebox [1.0] [jukebox]

2.) You dont have to use the formspec for that. Just take the itemstack of the clicker and put the disc into the meta:get_inventory(). Then just a function for ejecting the disc again, done.

PostPosted: Fri May 10, 2013 19:10
by 12Me21
kahrl wrote:You defined on_metadata_inventory_put twice (the second time with an extraneous "node" parameter). Move the code from the second definition to the first and delete the second definition. Also you will have to change get_meta(node) to get_meta(pos).


I have to define it at least twice, once for detecting if the node can be removed (so you don't remove it with a disk in it and destroy the disk) and again for each different CD.
I originally had it saying (pos) but it didn't work so I tried it with (node) and it still didn't work, and I didn't bother changing it back.