Page 1 of 1

Question listname

PostPosted: Fri Mar 30, 2012 16:59
by wokste
I was trying to make a dead penatly function
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_dieplayer(function(player)
    IList = player:get_inventory():get_list(player:get_wield_list())
    for num, item in pairs(IList) do
        item:clear() -- this line crashes
    end
end)

However, it crashes abrubtly. Error log:
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
18:57:54: INFO[ServerThread]: Server::DiePlayer(): Player singleplayer dies
18:57:54: ERROR[ServerThread]: ERROR: An unhandled exception occurred: LuaError: error: .../c55/bin/../games/minequest/mods/give_stuff/init.lua:13: attempt to call method 'clear' (a nil value)
18:57:54: ERROR[ServerThread]: stack traceback:

In thread b45ffb70:
/home/wokste/projects/minetest/c55/src/server.cpp:118: virtual void* ServerThread::Thread(): Assertion '0' failed.
Debug stacks:
DEBUG STACK FOR THREAD b1376b70:
#0  virtual void* MeshUpdateThread::Thread()
DEBUG STACK FOR THREAD b27fab70:
#0  virtual void* EmergeThread::Thread()
#1  MapBlock* ServerMap::loadBlock(v3s16)
#2  void ServerMap::loadBlock(std::string*, v3s16, MapSector*, bool)
DEBUG STACK FOR THREAD b45ffb70:
#0  virtual void* ServerThread::Thread()
(Leftover data: #1  void Server::Receive())
(Leftover data: #2  void Server::ProcessData(irr::u8*, irr::u32, irr::u16))
(Leftover data: #3  void ItemStack::serialize(std::ostream&) const)
(Leftover data: #4  void BlockEmergeQueue::addBlock(irr::u16, v3s16, irr::u8))
DEBUG STACK FOR THREAD b5b26720:
#0  int main(int, char**)
(Leftover data: #1  void ClientMap::renderMap(irr::video::IVideoDriver*, irr::s32))
(Leftover data: #2  void Client::sendDamage(irr::u8))
(Leftover data: #3  void Client::Receive())
(Leftover data: #4  void Client::ProcessData(irr::u8*, irr::u32, irr::u16))
(Leftover data: #5  void MeshUpdateQueue::addBlock(v3s16, MeshMakeData*, bool, bool))

How can I fix my script?

PostPosted: Fri Mar 30, 2012 17:33
by bgsmithjr
remove the stack from the inventory, player:get_inventory():remove_item("main", i) or whatever.

PostPosted: Fri Mar 30, 2012 17:43
by sfan5
" attempt to call method 'clear' (a nil value)"
There is no Method clear

PostPosted: Fri Mar 30, 2012 17:49
by bgsmithjr
wokste wrote:I was trying to make a dead penatly function
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_dieplayer(function(player)
    IList = player:get_inventory():get_list(player:get_wield_list())
    for num, item in pairs(IList) do
        item:clear() -- this line crashes
    end
end)


get_wield_list returns the list a wielded object is in which is a table
and for that to happen you need to use the code with an object. You are, 'player' is your object, whom is not in a list. So player:get_wield_list() cannot work because you would be search for player in a list which he is not in.Also get_inventory is for generic nodes. The player is not a node nor generic, so I do not understand how get_inventory can be used.
You should try things like object = minetest.env:get_node(yourpos)
object:get_wield_list()

PostPosted: Fri Mar 30, 2012 18:49
by kahrl
@bgsmithjr

Umm... I'm sorry, but your post makes zero sense.

PostPosted: Fri Mar 30, 2012 18:51
by Jordach
kahrl wrote:@bgsmithjr

Umm... I'm sorry, but your post makes zero sense.

Actually I do, you might want to read it through a few times and (even I am also known to be abstract at times.)

PostPosted: Fri Mar 30, 2012 18:53
by wokste
Thanks everybody, I have found the bug.
Item is a string containing the item defenition. e.g. 'default:dirt 98'. I assumed wrongly it was an ItemStack.

I will try to put the final script here tomorrow. (for those who want to play with death penalty)

PostPosted: Fri Mar 30, 2012 18:59
by Jordach
wokste wrote:Thanks everybody, I have found the bug.
Item is a string containing the item defenition. e.g. 'default:dirt 98'. I assumed wrongly it was an ItemStack.

I will try to put the final script here tomorrow. (for those who want to play with death penalty)

We must not be careful to clone Notch's mistakes, you are making one.

PostPosted: Fri Mar 30, 2012 19:05
by bgsmithjr
Ok I'll copy and past from lua_api.txt

-- ObjectRef methods:
-- - get_wield_list(): returns the name of the inventory list the wielded item is in

(notice objectref which means object reference or a reference to an object, the player as per his code)
so player:get_wield_list() would return the list the player is on. as it states above. The player is not on an inventory list. so this should not work.

-- Generic node metadata specific:(i.e. metadata for generic block
-- - get_inventory() -> InvRef
So get_inventory should be used with generic node metadata, player, is not a generic node, therefore
player:get_inventory() should not work. meta = minetest.env:get_node(pos)
meta:get_inventory() should return a table of inventory data for the generic node as the documentation suggests.

-- InvRef methods: (InvRef = reference to inventory(which should be of a generic node)
-- - get_list(listname): return full list --> a table
used as myinv = meta:get_inventory()
myinv:get_list('listname'')

player is an entity, but the beds mod, uses it as an object
so player:get_wield_list() is objectref:get_wield_list() but the function gets the list the wielded object: is in, or so the documentation states, but player is not on a list, so technically this shouldn't work. Because the function doesn't return the list entitled wield, it can return any list, the one that the item you give it is on is the one it will return, but do you see player in your inventory?

PostPosted: Fri Mar 30, 2012 19:47
by kahrl
Look at ObjectRef again, it has a get_inventory(), too. For player objects get_wield_list() always returns "main". The other inventory list names of players are "craft", "craftpreview", "craftresult", but you can't wield any item from those lists so get_wield_list() will never return anything other than "main".

player:get_inventory():get_list("main") returns the contents of the main list as a lua table, which as wokste discovered contains strings, not ItemStacks. This could be considered a bug.

@wokste
Bug or intentional? A player could move items that are especially valuable to the crafting grid, and your mod would not remove them on death.

PostPosted: Fri Mar 30, 2012 20:22
by bgsmithjr
minetest.register_on_dieplayer(function(player)
--> IList = player:get_inventory():get_list(player:get_wield_list()) <--
for num, item in pairs(IList) do
item:clear() -- this line crashes
end
end)


So this will never work because he wants it to return a table and all it will ever return is the string 'main'.
Thats not good to have get_wield_list() as a function as if there were more options than one for it to return.

EDIT: I read it wrong, sorry but you could just replace player:get_wield_list()) with
get_list('main')

PostPosted: Fri Mar 30, 2012 22:01
by kahrl
get_wield_list() was added so wielding could later be added for more objects (entities, for example), regardless of whether they happen to have a 'main' list or not. That's interface design. But yeah, if you know it is a player it doesn't matter.

PostPosted: Sat Mar 31, 2012 07:44
by wokste
Here is 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_on_dieplayer(function(player)
    listnames = {'main', 'craft', 'craftpreview', 'craftresult'}
    for listnum, listname in pairs(listnames) do
        IList = player:get_inventory():get_list(listname)
        for num, item in pairs(IList) do
            if item ~= nil and item ~= "" then
                player:get_inventory():remove_item(listname, item)
            end
        end
    end
end)

I still have to tune it for gameplay reasons

PostPosted: Sat Mar 31, 2012 13:35
by bgsmithjr
What are you doing?