added testing code for Minetest Issue #944

master
Sokomine 2014-08-30 20:58:48 +02:00
commit abb749c495
2 changed files with 163 additions and 0 deletions

52
README.md Normal file
View File

@ -0,0 +1,52 @@
Procedure for testing:
1. /giveme experimental:inv_move_demo
2. Place the demo object somewhere (looks like a chest with a ladder)
3. Right-click the demo-object.
4. Take a stack out of one of the inventory slots of the demo-object and put it
into an *empty* receiving slot in your player-inventory.
Expected result: stack removed from demo-object and moved into your inventory;
allow_metadata_inventory_take is called and ALLOWS the move
Observed behaviour: OK - works as expected
With patch: OK - works as expected
5. Try to take a stack from your inventory and put it into an *empty* slot of the demo object.
Expected result: move denied
stack will appear back in your inventory
allow_metadata_inventory_put is called and DENIES the move
Observed behaviour: OK
With patch: OK
6. Try to take a stack out of the demo-object and place it on a slot in your player
inventory that *already contains* a diffrent stack.
Expected result: move denied - the destination inventory slot is occupied, and the output slot
of the demo object does not want any input
Observed behaviour: allow_metadata_inventory_take is called and allows taking the stack out of the demo-object;
The stack in the receiving slot never appears as a parameter in any api call.
The stack in the receiving slot is PUT (swpapped) into the output-only-slot of the demo object.
The demo object does not receive any information at all about the new stack in its output-only-slot.
With patch: OK
So far, so good. Bug fixed. But: An undesired side-effect shows up which is bad for gameplay:
7. Place a normal chest. (default:chest)
8. Put a stack of something into the chest.
9. As in 6., take the stack back out of the chest and try to place it in a slot of your inventory that already contains
a diffrent stack.
Expected result: The stack out of the chest is placed into your inventory slot.
The stack that occupied your inventory slot before is placed in the chest.
Observed behaviour: OK - The old stack from your inventory gets put into the chest, and the new stack will stick to your mouse,
ready to be put into the - now empty - slot in your inventory.
With patch: Move denied.
Possible solution:
Extend allow_metadata_inventory_take = function(pos, listname, index, stack, player)
by adding a new parameter that provides information about the RECEIVING slot:
allow_metadata_inventory_take = function(pos, listname, index, stack, player, will_swap )
If the destination inventory cannot (fully) take the stack, will_swap is true. Else false.

111
init.lua Normal file
View File

@ -0,0 +1,111 @@
minetest.register_node( 'experimental:inv_move_demo', {
description = 'Demo node for node inventory related calls in the lua api',
name = 'demo',
tiles = {'default_chest_front.png^default_ladder.png'},
groups = {cracky=3,oddly_breakable_by_hand=3},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec",
"size[8,9]"..
"list[current_name;main;1,1;6,1;]"..
"list[current_player;main;0,4;8,4;]" );
meta:set_string("infotext", "Demo node for node inventory related calls in the lua api")
local inv = meta:get_inventory()
inv:set_size("main", 6) -- so that moving inventory around is possible
-- fill with items for testing
inv:set_stack("main", 2, "default:brick 1")
inv:set_stack("main", 3, "default:sandstone 2")
inv:set_stack("main", 4, "default:wood 10")
inv:set_stack("main", 5, "default:stone 20")
inv:set_stack("main", 6, "default:mese 99")
end,
--^ Called when a player wants to move items inside the inventory
--^ Return value: number of items allowed to move
allow_metadata_inventory_move = function(pos, from_list, from_index,
to_list, to_index, count, player)
minetest.chat_send_player( player:get_player_name(),
'allow_metadata_inventory_move called with parameters: '..
minetest.serialize( {
pos=pos, from_list=from_list, from_index=from_index,
to_list=to_list, to_index=to_index, count=count,
player=player:get_player_name() }));
return 0; -- deny all moves
end,
--^ Called when a player wants to put something into the inventory
--^ Return value: number of items allowed to put
--^ Return value: -1: Allow and don't modify item count in inventory
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
minetest.chat_send_player( player:get_player_name(),
'allow_metadata_inventory_put called with parameters: '..
minetest.serialize( {
pos=pos, listname=listname, index=index,
stack={stack=stack:get_name(), count=stack:get_count()},
player=player:get_player_name() }));
return 0; -- deny all attempts to put anything
end,
--^ Called when a player wants to take something out of the inventory
--^ Return value: number of items allowed to take
--^ Return value: -1: Allow and don't modify item count in inventory
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
minetest.chat_send_player( player:get_player_name(),
'allow_metadata_inventory_take called with parameters: '..
minetest.serialize( {
pos=pos, listname=listname, index=index,
stack={stack=stack:get_name(), count=stack:get_count()},
player=player:get_player_name() }));
return stack:get_count(); -- allow to take all
end,
-- ^ Called after the actual action has happened, according to what was allowed.
-- ^ No return value
on_metadata_inventory_move = function(pos, from_list, from_index,
to_list, to_index, count, player)
minetest.chat_send_player( player:get_player_name(),
'on_metadata_inventory_move called with parameters: '..
minetest.serialize( {
pos=pos, from_list=from_list, from_index=from_index,
to_list=to_list, to_index = to_index, count=count,
player=player:get_player_name() }));
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
minetest.chat_send_player( player:get_player_name(),
'on_metadata_inventory_put called with parameters: '..
minetest.serialize( {
pos=pos, listname=listname, index=index,
stack={stack=stack:get_name(), count=stack:get_count()},
player=player:get_player_name() }));
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
minetest.chat_send_player( player:get_player_name(),
'on_metadata_inventory_take called with parameters: '..
minetest.serialize( {
pos=pos, listname=listname, index=index,
stack={stack=stack:get_name(), count=stack:get_count()},
player=player:get_player_name() }));
end,
-- ^ fields = {name1 = value1, name2 = value2, ...}
-- ^ Called when an UI form (e.g. sign text input) returns data
-- ^ default: nil
on_receive_fields = function(pos, formname, fields, sender)
minetest.chat_send_player( sender:get_player_name(),
'on_receive_fields called with parameters: '..
minetest.serialize( {
pos=pos, formname=formname, fields=fields,
sender=sender:get_player_name() }));
end,
})